From c939e92e5b219456cd5021e88ffa8b6a54315afb Mon Sep 17 00:00:00 2001 From: Milco Kats Date: Fri, 9 Feb 2024 20:35:21 +0100 Subject: [PATCH 01/11] sync with main repo --- .../build/lsp/erlang/gleam_version | 1 + .../build/packages/gleam_bitwise/LICENSE | 191 ++ .../build/packages/gleam_bitwise/README.md | 24 + .../build/packages/gleam_bitwise/gleam.toml | 16 + .../gleam_bitwise/src/gleam/bitwise.gleam | 91 + .../gleam_bitwise/src/gleam@bitwise.erl | 28 + .../gleam_bitwise/src/gleam_bitwise.app.src | 8 + .../gleam_bitwise/src/gleam_bitwise.mjs | 28 + .../packages/gleam_community_ansi/LICENCE | 190 ++ .../packages/gleam_community_ansi/README.md | 72 + .../packages/gleam_community_ansi/gleam.toml | 13 + .../src/gleam_community/ansi.gleam | 2318 +++++++++++++++++ .../src/gleam_community@ansi.erl | 263 ++ .../src/gleam_community_ansi.app.src | 10 + .../packages/gleam_community_colour/LICENCE | 190 ++ .../packages/gleam_community_colour/README.md | 36 + .../gleam_community_colour/gleam.toml | 12 + .../include/gleam_community@colour_Hsla.hrl | 1 + .../include/gleam_community@colour_Rgba.hrl | 1 + .../src/gleam_community/colour.gleam | 1127 ++++++++ .../colour/accessibility.gleam | 173 ++ .../src/gleam_community@colour.erl | 525 ++++ .../gleam_community@colour@accessibility.erl | 75 + .../src/gleam_community_colour.app.src | 10 + .../build/packages/gleam_cors/LICENSE | 21 + .../build/packages/gleam_cors/README.md | 38 + .../build/packages/gleam_cors/gleam.toml | 13 + .../gleam_cors/src/gleam/http/cors.gleam | 227 ++ .../gleam_cors/src/gleam@http@cors.erl | 243 ++ .../gleam_cors/src/gleam_cors.app.src | 9 + .../build/packages/gleam_crypto/LICENSE | 191 ++ .../build/packages/gleam_crypto/README.md | 13 + .../build/packages/gleam_crypto/gleam.toml | 17 + .../gleam_crypto/src/gleam/crypto.gleam | 135 + .../gleam_crypto/src/gleam@crypto.erl | 135 + .../gleam_crypto/src/gleam_crypto.app.src | 9 + .../build/packages/gleam_erlang/LICENSE | 191 ++ .../build/packages/gleam_erlang/README.md | 34 + .../build/packages/gleam_erlang/gleam.toml | 17 + .../include/gleam@erlang@file_FileInfo.hrl | 15 + .../include/gleam@erlang@process_Abnormal.hrl | 1 + .../gleam@erlang@process_CalleeDown.hrl | 1 + .../gleam@erlang@process_Cancelled.hrl | 1 + .../gleam@erlang@process_ExitMessage.hrl | 4 + .../gleam@erlang@process_ProcessDown.hrl | 4 + .../gleam@erlang@process_ProcessMonitor.hrl | 1 + .../include/gleam@erlang@process_Subject.hrl | 4 + .../gleam@erlang_ApplicationFailedToStart.hrl | 4 + .../gleam@erlang_UnknownApplication.hrl | 1 + .../gleam_erlang/src/gleam/erlang.gleam | 143 + .../gleam_erlang/src/gleam/erlang/atom.gleam | 79 + .../src/gleam/erlang/charlist.gleam | 25 + .../gleam_erlang/src/gleam/erlang/file.gleam | 713 +++++ .../gleam_erlang/src/gleam/erlang/os.gleam | 95 + .../src/gleam/erlang/process.gleam | 716 +++++ .../gleam_erlang/src/gleam@erlang.erl | 86 + .../gleam_erlang/src/gleam@erlang@atom.erl | 26 + .../src/gleam@erlang@charlist.erl | 15 + .../gleam_erlang/src/gleam@erlang@file.erl | 190 ++ .../gleam_erlang/src/gleam@erlang@os.erl | 27 + .../gleam_erlang/src/gleam@erlang@process.erl | 362 +++ .../gleam_erlang/src/gleam_erlang.app.src | 13 + .../gleam_erlang/src/gleam_erlang_ffi.erl | 218 ++ .../build/packages/gleam_http/LICENSE | 191 ++ .../build/packages/gleam_http/README.md | 65 + .../build/packages/gleam_http/gleam.toml | 16 + .../include/gleam@http@cookie_Attributes.hrl | 8 + .../include/gleam@http@request_Request.hrl | 10 + .../include/gleam@http@response_Response.hrl | 5 + .../packages/gleam_http/src/gleam/http.gleam | 122 + .../gleam_http/src/gleam/http/cookie.gleam | 128 + .../gleam_http/src/gleam/http/request.gleam | 258 ++ .../gleam_http/src/gleam/http/response.gleam | 141 + .../gleam_http/src/gleam/http/service.gleam | 82 + .../packages/gleam_http/src/gleam@http.erl | 124 + .../gleam_http/src/gleam@http@cookie.erl | 153 ++ .../gleam_http/src/gleam@http@request.erl | 202 ++ .../gleam_http/src/gleam@http@response.erl | 97 + .../gleam_http/src/gleam@http@service.erl | 82 + .../gleam_http/src/gleam_http.app.src | 12 + .../gleam_http/src/gleam_http_native.erl | 88 + .../gleam_http/src/gleam_http_native.mjs | 38 + .../build/packages/gleam_otp/LICENCE | 191 ++ .../build/packages/gleam_otp/README.md | 91 + .../build/packages/gleam_otp/gleam.toml | 17 + .../include/gleam@otp@actor_Ready.hrl | 1 + .../include/gleam@otp@actor_Spec.hrl | 5 + ...otp@intensity_tracker_IntensityTracker.hrl | 5 + .../gleam@otp@supervisor_ChildSpec.hrl | 5 + .../include/gleam@otp@supervisor_Spec.hrl | 6 + .../include/gleam@otp@system_StatusInfo.hrl | 7 + .../gleam_otp/include/gleam@otp@task_Exit.hrl | 1 + .../gleam_otp/include/gleam@otp@task_Task.hrl | 6 + .../gleam_otp/src/gleam/otp/actor.gleam | 473 ++++ .../src/gleam/otp/intensity_tracker.gleam | 46 + .../gleam_otp/src/gleam/otp/node.gleam | 1 + .../gleam_otp/src/gleam/otp/port.gleam | 9 + .../gleam_otp/src/gleam/otp/supervisor.gleam | 403 +++ .../gleam_otp/src/gleam/otp/system.gleam | 89 + .../gleam_otp/src/gleam/otp/task.gleam | 151 ++ .../gleam_otp/src/gleam@otp@actor.erl | 233 ++ .../src/gleam@otp@intensity_tracker.erl | 53 + .../packages/gleam_otp/src/gleam@otp@node.erl | 8 + .../packages/gleam_otp/src/gleam@otp@port.erl | 8 + .../gleam_otp/src/gleam@otp@supervisor.erl | 322 +++ .../gleam_otp/src/gleam@otp@system.erl | 43 + .../packages/gleam_otp/src/gleam@otp@task.erl | 111 + .../packages/gleam_otp/src/gleam_otp.app.src | 15 + .../gleam_otp/src/gleam_otp_external.erl | 43 + .../build/packages/gleam_stdlib/LICENCE | 191 ++ .../build/packages/gleam_stdlib/README.md | 39 + .../build/packages/gleam_stdlib/gleam.toml | 19 + .../include/gleam@dynamic_DecodeError.hrl | 5 + .../include/gleam@iterator_Iterator.hrl | 1 + .../include/gleam@iterator_Next.hrl | 1 + .../include/gleam@queue_Queue.hrl | 1 + .../include/gleam@regex_CompileError.hrl | 1 + .../include/gleam@regex_Match.hrl | 4 + .../include/gleam@regex_Options.hrl | 1 + .../gleam_stdlib/include/gleam@set_Set.hrl | 1 + .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 + .../gleam_stdlib/src/gleam/base.gleam | 59 + .../gleam_stdlib/src/gleam/bit_builder.gleam | 276 ++ .../gleam_stdlib/src/gleam/bit_string.gleam | 155 ++ .../gleam_stdlib/src/gleam/bool.gleam | 388 +++ .../gleam_stdlib/src/gleam/dynamic.gleam | 1613 ++++++++++++ .../gleam_stdlib/src/gleam/float.gleam | 589 +++++ .../gleam_stdlib/src/gleam/function.gleam | 162 ++ .../packages/gleam_stdlib/src/gleam/int.gleam | 854 ++++++ .../packages/gleam_stdlib/src/gleam/io.gleam | 147 ++ .../gleam_stdlib/src/gleam/iterator.gleam | 1442 ++++++++++ .../gleam_stdlib/src/gleam/list.gleam | 2075 +++++++++++++++ .../packages/gleam_stdlib/src/gleam/map.gleam | 593 +++++ .../gleam_stdlib/src/gleam/option.gleam | 346 +++ .../gleam_stdlib/src/gleam/order.gleam | 119 + .../gleam_stdlib/src/gleam/pair.gleam | 85 + .../gleam_stdlib/src/gleam/queue.gleam | 292 +++ .../gleam_stdlib/src/gleam/regex.gleam | 233 ++ .../gleam_stdlib/src/gleam/result.gleam | 483 ++++ .../packages/gleam_stdlib/src/gleam/set.gleam | 264 ++ .../gleam_stdlib/src/gleam/string.gleam | 1046 ++++++++ .../src/gleam/string_builder.gleam | 356 +++ .../packages/gleam_stdlib/src/gleam/uri.gleam | 476 ++++ .../packages/gleam_stdlib/src/gleam@base.erl | 45 + .../gleam_stdlib/src/gleam@bit_builder.erl | 63 + .../gleam_stdlib/src/gleam@bit_string.erl | 56 + .../packages/gleam_stdlib/src/gleam@bool.erl | 152 ++ .../gleam_stdlib/src/gleam@dynamic.erl | 794 ++++++ .../packages/gleam_stdlib/src/gleam@float.erl | 193 ++ .../gleam_stdlib/src/gleam@function.erl | 67 + .../packages/gleam_stdlib/src/gleam@int.erl | 323 +++ .../packages/gleam_stdlib/src/gleam@io.erl | 27 + .../gleam_stdlib/src/gleam@iterator.erl | 707 +++++ .../packages/gleam_stdlib/src/gleam@list.erl | 1082 ++++++++ .../packages/gleam_stdlib/src/gleam@map.erl | 97 + .../gleam_stdlib/src/gleam@option.erl | 147 ++ .../packages/gleam_stdlib/src/gleam@order.erl | 75 + .../packages/gleam_stdlib/src/gleam@pair.erl | 33 + .../packages/gleam_stdlib/src/gleam@queue.erl | 121 + .../packages/gleam_stdlib/src/gleam@regex.erl | 33 + .../gleam_stdlib/src/gleam@result.erl | 201 ++ .../packages/gleam_stdlib/src/gleam@set.erl | 85 + .../gleam_stdlib/src/gleam@string.erl | 393 +++ .../gleam_stdlib/src/gleam@string_builder.erl | 91 + .../packages/gleam_stdlib/src/gleam@uri.erl | 255 ++ .../gleam_stdlib/src/gleam_stdlib.app.src | 28 + .../gleam_stdlib/src/gleam_stdlib.erl | 441 ++++ .../gleam_stdlib/src/gleam_stdlib.mjs | 739 ++++++ .../gleam_stdlib/src/persistent-hash-map.mjs | 957 +++++++ .../packages/gleamy_structures/README.md | 27 + .../packages/gleamy_structures/gleam.toml | 15 + ...eamy_structures@heap@leftist_heap_Heap.hrl | 4 + ...eamy_structures@heap@pairing_heap_Heap.hrl | 4 + .../gleamy_structures@non_empty_list_End.hrl | 1 + .../gleamy_structures@non_empty_list_Next.hrl | 4 + ...tructures@tree@binary_search_tree_Tree.hrl | 4 + ...my_structures@tree@red_black_tree_Tree.hrl | 4 + ...structures@tree@red_black_tree_kv_Tree.hrl | 4 + .../src/gleamy_structures.app.src | 16 + .../gleamy_structures/heap/leftist_heap.gleam | 61 + .../gleamy_structures/heap/pairing_heap.gleam | 55 + .../src/gleamy_structures/map.gleam | 85 + .../gleamy_structures/non_empty_list.gleam | 63 + .../gleamy_structures/priority_queue.gleam | 54 + .../src/gleamy_structures/set.gleam | 91 + .../tree/binary_search_tree.gleam | 123 + .../tree/red_black_tree.gleam | 224 ++ .../tree/red_black_tree_kv.gleam | 232 ++ .../gleamy_structures@heap@leftist_heap.erl | 90 + .../gleamy_structures@heap@pairing_heap.erl | 75 + .../src/gleamy_structures@map.erl | 121 + .../src/gleamy_structures@non_empty_list.erl | 77 + .../src/gleamy_structures@priority_queue.erl | 74 + .../src/gleamy_structures@set.erl | 123 + ...amy_structures@tree@binary_search_tree.erl | 167 ++ .../gleamy_structures@tree@red_black_tree.erl | 326 +++ ...eamy_structures@tree@red_black_tree_kv.erl | 336 +++ .../build/packages/gleeunit/LICENCE | 191 ++ .../build/packages/gleeunit/README.md | 52 + .../build/packages/gleeunit/gleam.toml | 17 + .../packages/gleeunit/src/gleeunit.app.src | 8 + .../build/packages/gleeunit/src/gleeunit.erl | 59 + .../packages/gleeunit/src/gleeunit.gleam | 80 + .../gleeunit/src/gleeunit/should.gleam | 83 + .../packages/gleeunit/src/gleeunit@should.erl | 34 + .../packages/gleeunit/src/gleeunit_ffi.erl | 24 + .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 + .../gleeunit/src/gleeunit_progress.erl | 607 +++++ .../build/packages/glenvy/LICENSE | 21 + .../build/packages/glenvy/README.md | 31 + .../build/packages/glenvy/gleam.toml | 13 + .../glenvy/include/glenvy@error_Io.hrl | 1 + .../build/packages/glenvy/src/glenvy.app.src | 16 + .../packages/glenvy/src/glenvy/dotenv.gleam | 42 + .../packages/glenvy/src/glenvy/env.gleam | 81 + .../packages/glenvy/src/glenvy/error.gleam | 5 + .../glenvy/src/glenvy/internal/file.gleam | 15 + .../glenvy/src/glenvy/internal/os.gleam | 26 + .../glenvy/src/glenvy/internal/parser.gleam | 69 + .../glenvy/src/glenvy/internal/string.gleam | 33 + .../packages/glenvy/src/glenvy@dotenv.erl | 40 + .../build/packages/glenvy/src/glenvy@env.erl | 69 + .../packages/glenvy/src/glenvy@error.erl | 8 + .../glenvy/src/glenvy@internal@file.erl | 9 + .../glenvy/src/glenvy@internal@os.erl | 16 + .../glenvy/src/glenvy@internal@parser.erl | 75 + .../glenvy/src/glenvy@internal@string.erl | 40 + .../build/packages/glenvy/src/glenvy_ffi.mjs | 32 + .../build/packages/glerm/README.md | 44 + .../gleam_community@ansi.cache | Bin 0 -> 62841 bytes .../gleam_community@ansi.cache_meta | Bin 0 -> 114 bytes .../gleam_community@colour.cache | Bin 0 -> 27832 bytes .../gleam_community@colour.cache_meta | Bin 0 -> 123 bytes ...gleam_community@colour@accessibility.cache | Bin 0 -> 3072 bytes ..._community@colour@accessibility.cache_meta | Bin 0 -> 96 bytes .../_gleam_artefacts/gleam@erlang.cache | Bin 0 -> 8464 bytes .../_gleam_artefacts/gleam@erlang.cache_meta | Bin 0 -> 122 bytes .../_gleam_artefacts/gleam@erlang@atom.cache | Bin 0 -> 2814 bytes .../gleam@erlang@atom.cache_meta | Bin 0 -> 50 bytes .../gleam@erlang@charlist.cache | Bin 0 -> 789 bytes .../gleam@erlang@charlist.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@erlang@file.cache | Bin 0 -> 27622 bytes .../gleam@erlang@file.cache_meta | Bin 0 -> 72 bytes .../_gleam_artefacts/gleam@erlang@node.cache | Bin 0 -> 2992 bytes .../gleam@erlang@node.cache_meta | Bin 0 -> 54 bytes .../_gleam_artefacts/gleam@erlang@os.cache | Bin 0 -> 3171 bytes .../gleam@erlang@os.cache_meta | Bin 0 -> 46 bytes .../gleam@erlang@process.cache | Bin 0 -> 30881 bytes .../gleam@erlang@process.cache_meta | Bin 0 -> 115 bytes .../_gleam_artefacts/gleam@otp@actor.cache | Bin 0 -> 12240 bytes .../gleam@otp@actor.cache_meta | Bin 0 -> 196 bytes .../gleam@otp@intensity_tracker.cache | Bin 0 -> 2254 bytes .../gleam@otp@intensity_tracker.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@otp@port.cache | Bin 0 -> 273 bytes .../gleam@otp@port.cache_meta | Bin 0 -> 29 bytes .../gleam@otp@supervisor.cache | Bin 0 -> 14883 bytes .../gleam@otp@supervisor.cache_meta | Bin 0 -> 200 bytes .../_gleam_artefacts/gleam@otp@system.cache | Bin 0 -> 5222 bytes .../gleam@otp@system.cache_meta | Bin 0 -> 103 bytes .../_gleam_artefacts/gleam@otp@task.cache | Bin 0 -> 3940 bytes .../gleam@otp@task.cache_meta | Bin 0 -> 78 bytes .../_gleam_artefacts/gleam_otp.cache | Bin 0 -> 650 bytes .../_gleam_artefacts/gleam_otp.cache_meta | Bin 0 -> 130 bytes .../_gleam_artefacts/gleam@base.cache | Bin 0 -> 1223 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 0 -> 52 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 0 -> 4956 bytes .../gleam@bit_array.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 0 -> 4184 bytes .../gleam@bit_builder.cache_meta | Bin 0 -> 84 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 0 -> 1934 bytes .../gleam@bit_string.cache_meta | Bin 0 -> 52 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 0 -> 7081 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 0 -> 48 bytes .../gleam@bytes_builder.cache | Bin 0 -> 6045 bytes .../gleam@bytes_builder.cache_meta | Bin 0 -> 98 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 0 -> 12265 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 0 -> 49248 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 0 -> 173 bytes .../_gleam_artefacts/gleam@float.cache | Bin 0 -> 11372 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 0 -> 48 bytes .../_gleam_artefacts/gleam@function.cache | Bin 0 -> 5798 bytes .../gleam@function.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@int.cache | Bin 0 -> 18139 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 0 -> 67 bytes .../_gleam_artefacts/gleam@io.cache | Bin 0 -> 2856 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 0 -> 37907 bytes .../gleam@iterator.cache_meta | Bin 0 -> 141 bytes .../_gleam_artefacts/gleam@list.cache | Bin 0 -> 46246 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 0 -> 120 bytes .../_gleam_artefacts/gleam@map.cache | Bin 0 -> 4740 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 0 -> 67 bytes .../_gleam_artefacts/gleam@option.cache | Bin 0 -> 7258 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@order.cache | Bin 0 -> 2702 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 0 -> 1882 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 0 -> 7021 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 0 -> 6600 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@result.cache | Bin 0 -> 10378 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@set.cache | Bin 0 -> 6383 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 0 -> 85 bytes .../_gleam_artefacts/gleam@string.cache | Bin 0 -> 21827 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 0 -> 136 bytes .../gleam@string_builder.cache | Bin 0 -> 10568 bytes .../gleam@string_builder.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 0 -> 7764 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 0 -> 132 bytes .../glerm/build/lsp/erlang/gleam_version | 1 + .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 0 -> 3252 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 0 -> 108 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 0 -> 1132 bytes .../gleeunit@should.cache_meta | Bin 0 -> 29 bytes .../packages/gleam_community_ansi/LICENCE | 190 ++ .../packages/gleam_community_ansi/README.md | 72 + .../packages/gleam_community_ansi/gleam.toml | 13 + .../src/gleam_community/ansi.gleam | 2317 ++++++++++++++++ .../src/gleam_community@ansi.erl | 263 ++ .../src/gleam_community_ansi.app.src | 9 + .../packages/gleam_community_colour/LICENCE | 190 ++ .../packages/gleam_community_colour/README.md | 36 + .../gleam_community_colour/gleam.toml | 11 + .../include/gleam_community@colour_Hsla.hrl | 1 + .../include/gleam_community@colour_Rgba.hrl | 1 + .../src/gleam_community/colour.gleam | 1126 ++++++++ .../colour/accessibility.gleam | 173 ++ .../src/gleam_community@colour.erl | 511 ++++ .../gleam_community@colour@accessibility.erl | 73 + .../src/gleam_community_colour.app.src | 9 + .../glerm/build/packages/gleam_erlang/LICENSE | 191 ++ .../build/packages/gleam_erlang/README.md | 37 + .../build/packages/gleam_erlang/gleam.toml | 18 + .../include/gleam@erlang@file_FileInfo.hrl | 15 + .../include/gleam@erlang@process_Abnormal.hrl | 1 + .../gleam@erlang@process_CalleeDown.hrl | 1 + .../gleam@erlang@process_Cancelled.hrl | 1 + .../gleam@erlang@process_ExitMessage.hrl | 4 + .../gleam@erlang@process_ProcessDown.hrl | 4 + .../gleam@erlang@process_ProcessMonitor.hrl | 1 + .../include/gleam@erlang@process_Subject.hrl | 4 + .../gleam@erlang_ApplicationFailedToStart.hrl | 4 + .../gleam@erlang_UnknownApplication.hrl | 1 + .../gleam_erlang/src/gleam/erlang.gleam | 158 ++ .../gleam_erlang/src/gleam/erlang/atom.gleam | 79 + .../src/gleam/erlang/charlist.gleam | 25 + .../gleam_erlang/src/gleam/erlang/file.gleam | 737 ++++++ .../gleam_erlang/src/gleam/erlang/node.gleam | 62 + .../gleam_erlang/src/gleam/erlang/os.gleam | 95 + .../src/gleam/erlang/process.gleam | 744 ++++++ .../gleam_erlang/src/gleam@erlang.erl | 90 + .../gleam_erlang/src/gleam@erlang@atom.erl | 26 + .../src/gleam@erlang@charlist.erl | 15 + .../gleam_erlang/src/gleam@erlang@file.erl | 190 ++ .../gleam_erlang/src/gleam@erlang@node.erl | 33 + .../gleam_erlang/src/gleam@erlang@os.erl | 27 + .../gleam_erlang/src/gleam@erlang@process.erl | 374 +++ .../gleam_erlang/src/gleam_erlang.app.src | 14 + .../gleam_erlang/src/gleam_erlang_ffi.erl | 263 ++ .../glerm/build/packages/gleam_otp/LICENCE | 191 ++ .../glerm/build/packages/gleam_otp/README.md | 91 + .../glerm/build/packages/gleam_otp/gleam.toml | 19 + .../include/gleam@otp@actor_Continue.hrl | 4 + .../include/gleam@otp@actor_Ready.hrl | 1 + .../include/gleam@otp@actor_Spec.hrl | 5 + ...otp@intensity_tracker_IntensityTracker.hrl | 5 + .../gleam@otp@supervisor_ChildSpec.hrl | 5 + .../include/gleam@otp@supervisor_Spec.hrl | 6 + .../include/gleam@otp@system_StatusInfo.hrl | 7 + .../gleam_otp/include/gleam@otp@task_Exit.hrl | 1 + .../gleam_otp/include/gleam@otp@task_Task.hrl | 6 + .../gleam_otp/src/gleam/otp/actor.gleam | 504 ++++ .../src/gleam/otp/intensity_tracker.gleam | 46 + .../gleam_otp/src/gleam/otp/port.gleam | 9 + .../gleam_otp/src/gleam/otp/supervisor.gleam | 410 +++ .../gleam_otp/src/gleam/otp/system.gleam | 89 + .../gleam_otp/src/gleam/otp/task.gleam | 151 ++ .../gleam_otp/src/gleam@otp@actor.erl | 273 ++ .../src/gleam@otp@intensity_tracker.erl | 53 + .../packages/gleam_otp/src/gleam@otp@port.erl | 8 + .../gleam_otp/src/gleam@otp@supervisor.erl | 322 +++ .../gleam_otp/src/gleam@otp@system.erl | 43 + .../packages/gleam_otp/src/gleam@otp@task.erl | 111 + .../packages/gleam_otp/src/gleam_otp.app.src | 15 + .../packages/gleam_otp/src/gleam_otp.erl | 28 + .../packages/gleam_otp/src/gleam_otp.gleam | 27 + .../gleam_otp/src/gleam_otp_external.erl | 43 + .../glerm/build/packages/gleam_stdlib/LICENCE | 191 ++ .../build/packages/gleam_stdlib/README.md | 39 + .../build/packages/gleam_stdlib/gleam.toml | 16 + .../include/gleam@dynamic_DecodeError.hrl | 5 + .../include/gleam@iterator_Iterator.hrl | 1 + .../include/gleam@iterator_Next.hrl | 1 + .../include/gleam@queue_Queue.hrl | 1 + .../include/gleam@regex_CompileError.hrl | 1 + .../include/gleam@regex_Match.hrl | 4 + .../include/gleam@regex_Options.hrl | 1 + .../gleam_stdlib/include/gleam@set_Set.hrl | 1 + .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 + .../build/packages/gleam_stdlib/src/dict.mjs | 957 +++++++ .../gleam_stdlib/src/gleam/base.gleam | 21 + .../gleam_stdlib/src/gleam/bit_array.gleam | 157 ++ .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 + .../gleam_stdlib/src/gleam/bit_string.gleam | 43 + .../gleam_stdlib/src/gleam/bool.gleam | 428 +++ .../src/gleam/bytes_builder.gleam | 197 ++ .../gleam_stdlib/src/gleam/dict.gleam | 544 ++++ .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 +++++++++++ .../gleam_stdlib/src/gleam/float.gleam | 546 ++++ .../gleam_stdlib/src/gleam/function.gleam | 162 ++ .../packages/gleam_stdlib/src/gleam/int.gleam | 874 +++++++ .../packages/gleam_stdlib/src/gleam/io.gleam | 117 + .../gleam_stdlib/src/gleam/iterator.gleam | 1530 +++++++++++ .../gleam_stdlib/src/gleam/list.gleam | 2154 +++++++++++++++ .../packages/gleam_stdlib/src/gleam/map.gleam | 127 + .../gleam_stdlib/src/gleam/option.gleam | 346 +++ .../gleam_stdlib/src/gleam/order.gleam | 133 + .../gleam_stdlib/src/gleam/pair.gleam | 85 + .../gleam_stdlib/src/gleam/queue.gleam | 292 +++ .../gleam_stdlib/src/gleam/regex.gleam | 214 ++ .../gleam_stdlib/src/gleam/result.gleam | 482 ++++ .../packages/gleam_stdlib/src/gleam/set.gleam | 264 ++ .../gleam_stdlib/src/gleam/string.gleam | 913 +++++++ .../src/gleam/string_builder.gleam | 298 +++ .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ++++ .../packages/gleam_stdlib/src/gleam@base.erl | 20 + .../gleam_stdlib/src/gleam@bit_array.erl | 102 + .../gleam_stdlib/src/gleam@bit_builder.erl | 66 + .../gleam_stdlib/src/gleam@bit_string.erl | 33 + .../packages/gleam_stdlib/src/gleam@bool.erl | 162 ++ .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 + .../packages/gleam_stdlib/src/gleam@dict.erl | 97 + .../gleam_stdlib/src/gleam@dynamic.erl | 808 ++++++ .../packages/gleam_stdlib/src/gleam@float.erl | 181 ++ .../gleam_stdlib/src/gleam@function.erl | 67 + .../packages/gleam_stdlib/src/gleam@int.erl | 332 +++ .../packages/gleam_stdlib/src/gleam@io.erl | 27 + .../gleam_stdlib/src/gleam@iterator.erl | 744 ++++++ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 ++++++++ .../packages/gleam_stdlib/src/gleam@map.erl | 76 + .../gleam_stdlib/src/gleam@option.erl | 147 ++ .../packages/gleam_stdlib/src/gleam@order.erl | 79 + .../packages/gleam_stdlib/src/gleam@pair.erl | 33 + .../packages/gleam_stdlib/src/gleam@queue.erl | 121 + .../packages/gleam_stdlib/src/gleam@regex.erl | 33 + .../gleam_stdlib/src/gleam@result.erl | 201 ++ .../packages/gleam_stdlib/src/gleam@set.erl | 85 + .../gleam_stdlib/src/gleam@string.erl | 352 +++ .../gleam_stdlib/src/gleam@string_builder.erl | 91 + .../packages/gleam_stdlib/src/gleam@uri.erl | 252 ++ .../gleam_stdlib/src/gleam_stdlib.app.src | 31 + .../gleam_stdlib/src/gleam_stdlib.erl | 529 ++++ .../gleam_stdlib/src/gleam_stdlib.mjs | 878 +++++++ .../glerm/build/packages/gleeunit/LICENCE | 191 ++ .../glerm/build/packages/gleeunit/README.md | 52 + .../glerm/build/packages/gleeunit/gleam.toml | 17 + .../packages/gleeunit/src/gleeunit.app.src | 8 + .../build/packages/gleeunit/src/gleeunit.erl | 59 + .../packages/gleeunit/src/gleeunit.gleam | 92 + .../gleeunit/src/gleeunit/should.gleam | 90 + .../packages/gleeunit/src/gleeunit@should.erl | 34 + .../packages/gleeunit/src/gleeunit_ffi.erl | 24 + .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 + .../gleeunit/src/gleeunit_progress.erl | 607 +++++ .../glerm/build/packages/packages.toml | 7 + .../build/packages/glerm/gleam.toml | 17 + .../packages/glerm/include/glerm_Drag.hrl | 4 + .../packages/glerm/include/glerm_Focus.hrl | 1 + .../packages/glerm/include/glerm_Key.hrl | 4 + .../glerm/include/glerm_ListenerSpec.hrl | 5 + .../packages/glerm/include/glerm_Mouse.hrl | 1 + .../glerm/include/glerm_MouseDown.hrl | 4 + .../packages/glerm/include/glerm_MouseUp.hrl | 4 + .../packages/glerm/include/glerm_Unknown.hrl | 1 + .../build/packages/glerm/manifest.toml | 18 + .../packages/glerm/priv/linux/libglerm.so | Bin 0 -> 4550752 bytes .../packages/glerm/priv/windows/libglerm.dll | Bin 0 -> 352768 bytes .../build/packages/glerm/src/glerm.app.src | 11 + .../build/packages/glerm/src/glerm.erl | 397 +++ .../build/packages/glerm/src/glerm.gleam | 354 +++ .../build/packages/glerm/src/glerm_ffi.erl | 67 + .../build/packages/gliew/README.md | 393 +++ .../build/packages/gliew/gleam.toml | 16 + .../gliew@internal@event_LiveMount.hrl | 3 + .../gliew@internal@manager_GetWorker.hrl | 7 + .../gliew@internal@manager_ProcessTree.hrl | 5 + .../gliew@internal@worker_ConnectSocket.hrl | 3 + ...gliew@internal@worker_DisconnectSocket.hrl | 3 + .../gliew@internal@worker_LiveUpdate.hrl | 1 + .../packages/gliew/include/gliew_Response.hrl | 5 + .../packages/gliew/include/gliew_Server.hrl | 5 + .../packages/gliew/include/gliew_View.hrl | 5 + .../build/packages/gliew/src/gliew.app.src | 17 + .../build/packages/gliew/src/gliew.erl | 495 ++++ .../build/packages/gliew/src/gliew.gleam | 477 ++++ .../gliew/src/gliew/internal/event.gleam | 20 + .../gliew/src/gliew/internal/manager.gleam | 222 ++ .../gliew/src/gliew/internal/util.gleam | 18 + .../gliew/src/gliew/internal/worker.gleam | 128 + .../gliew/src/gliew@internal@event.erl | 11 + .../gliew/src/gliew@internal@manager.erl | 216 ++ .../gliew/src/gliew@internal@util.erl | 23 + .../gliew/src/gliew@internal@worker.erl | 129 + .../build/packages/glisten/README.md | 132 + .../build/packages/glisten/gleam.toml | 13 + .../glisten@acceptor_AcceptorState.hrl | 5 + .../glisten/include/glisten@acceptor_Pool.hrl | 9 + .../include/glisten@handler_Handler.hrl | 8 + .../include/glisten@handler_LoopState.hrl | 6 + .../glisten/include/glisten@handler_Ssl.hrl | 1 + .../glisten/include/glisten@handler_Tcp.hrl | 1 + .../include/glisten@socket@transport_Ssl.hrl | 34 + .../include/glisten@socket@transport_Tcp.hrl | 34 + .../packages/glisten/src/glisten.app.src | 18 + .../build/packages/glisten/src/glisten.erl | 102 + .../build/packages/glisten/src/glisten.gleam | 85 + .../glisten/src/glisten/acceptor.gleam | 204 ++ .../glisten/src/glisten/handler.gleam | 160 ++ .../packages/glisten/src/glisten/logger.gleam | 8 + .../packages/glisten/src/glisten/socket.gleam | 93 + .../glisten/src/glisten/socket/options.gleam | 83 + .../src/glisten/socket/transport.gleam | 122 + .../packages/glisten/src/glisten/ssl.gleam | 93 + .../packages/glisten/src/glisten/tcp.gleam | 94 + .../packages/glisten/src/glisten@acceptor.erl | 232 ++ .../packages/glisten/src/glisten@handler.erl | 234 ++ .../packages/glisten/src/glisten@logger.erl | 8 + .../packages/glisten/src/glisten@socket.erl | 90 + .../glisten/src/glisten@socket@options.erl | 79 + .../glisten/src/glisten@socket@transport.erl | 102 + .../packages/glisten/src/glisten@ssl.erl | 94 + .../packages/glisten/src/glisten@tcp.erl | 96 + .../build/packages/glisten/src/ssl_ffi.erl | 60 + .../build/packages/glisten/src/tcp_ffi.erl | 32 + .../build/packages/globe/LICENSE | 21 + .../build/packages/globe/README.md | 26 + .../build/packages/globe/gleam.toml | 12 + .../build/packages/globe/src/globe.app.src | 8 + .../build/packages/globe/src/globe.erl | 8 + .../build/packages/globe/src/globe.gleam | 5 + .../build/packages/gloml/README.md | 40 + .../build/packages/gloml/gleam.toml | 16 + .../packages/gloml/priv/package-lock.json | 18 + .../build/packages/gloml/priv/package.json | 5 + .../build/packages/gloml/src/TomlFFI.ex | 5 + .../build/packages/gloml/src/gloml.app.src | 9 + .../build/packages/gloml/src/gloml.erl | 44 + .../build/packages/gloml/src/gloml.gleam | 77 + .../build/packages/gloml/src/toml_ffi.mjs | 14 + .../build/packages/glove/LICENSE | 21 + .../build/packages/glove/README.md | 40 + .../build/packages/glove/gleam.toml | 11 + .../packages/glove/include/glove_Block.hrl | 1 + .../packages/glove/include/glove_Const.hrl | 1 + .../packages/glove/include/glove_DataDef.hrl | 6 + .../packages/glove/include/glove_Function.hrl | 7 + .../packages/glove/include/glove_Global.hrl | 1 + .../packages/glove/include/glove_Linkage.hrl | 5 + .../packages/glove/include/glove_Module.hrl | 5 + .../glove/include/glove_Temporary.hrl | 1 + .../packages/glove/include/glove_TypeDef.hrl | 5 + .../build/packages/glove/src/glove.app.src | 8 + .../build/packages/glove/src/glove.erl | 640 +++++ .../build/packages/glove/src/glove.gleam | 563 ++++ .../build/packages/glx/LICENSE | 21 + .../build/packages/glx/README.md | 12 + .../_gleam_artefacts/gleam@base.cache | Bin 0 -> 1223 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 0 -> 52 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 0 -> 4959 bytes .../gleam@bit_array.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 0 -> 4184 bytes .../gleam@bit_builder.cache_meta | Bin 0 -> 84 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 0 -> 1934 bytes .../gleam@bit_string.cache_meta | Bin 0 -> 52 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 0 -> 7081 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 0 -> 48 bytes .../gleam@bytes_builder.cache | Bin 0 -> 6045 bytes .../gleam@bytes_builder.cache_meta | Bin 0 -> 98 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 0 -> 12276 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 0 -> 49265 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 0 -> 173 bytes .../_gleam_artefacts/gleam@float.cache | Bin 0 -> 11362 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 0 -> 48 bytes .../_gleam_artefacts/gleam@function.cache | Bin 0 -> 5793 bytes .../gleam@function.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@int.cache | Bin 0 -> 18155 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 0 -> 67 bytes .../_gleam_artefacts/gleam@io.cache | Bin 0 -> 2856 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 0 -> 37897 bytes .../gleam@iterator.cache_meta | Bin 0 -> 141 bytes .../_gleam_artefacts/gleam@list.cache | Bin 0 -> 46265 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 0 -> 120 bytes .../_gleam_artefacts/gleam@map.cache | Bin 0 -> 4750 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 0 -> 67 bytes .../_gleam_artefacts/gleam@option.cache | Bin 0 -> 7259 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@order.cache | Bin 0 -> 2704 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 0 -> 1879 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 0 -> 7006 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 0 -> 6599 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@result.cache | Bin 0 -> 10381 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@set.cache | Bin 0 -> 6395 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 0 -> 85 bytes .../_gleam_artefacts/gleam@string.cache | Bin 0 -> 21839 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 0 -> 136 bytes .../gleam@string_builder.cache | Bin 0 -> 10571 bytes .../gleam@string_builder.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 0 -> 7769 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 0 -> 132 bytes .../glx/build/lsp/erlang/gleam_version | 1 + .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 0 -> 3252 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 0 -> 108 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 0 -> 1132 bytes .../gleeunit@should.cache_meta | Bin 0 -> 29 bytes .../glx/_gleam_artefacts/glx@stringx.cache | Bin 0 -> 552 bytes .../_gleam_artefacts/glx@stringx.cache_meta | Bin 0 -> 104 bytes .../glx/build/packages/gleam_stdlib/LICENCE | 191 ++ .../glx/build/packages/gleam_stdlib/README.md | 39 + .../build/packages/gleam_stdlib/gleam.toml | 16 + .../include/gleam@dynamic_DecodeError.hrl | 5 + .../include/gleam@iterator_Iterator.hrl | 1 + .../include/gleam@iterator_Next.hrl | 1 + .../include/gleam@queue_Queue.hrl | 1 + .../include/gleam@regex_CompileError.hrl | 1 + .../include/gleam@regex_Match.hrl | 4 + .../include/gleam@regex_Options.hrl | 1 + .../gleam_stdlib/include/gleam@set_Set.hrl | 1 + .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 + .../build/packages/gleam_stdlib/src/dict.mjs | 957 +++++++ .../gleam_stdlib/src/gleam/base.gleam | 21 + .../gleam_stdlib/src/gleam/bit_array.gleam | 157 ++ .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 + .../gleam_stdlib/src/gleam/bit_string.gleam | 43 + .../gleam_stdlib/src/gleam/bool.gleam | 428 +++ .../src/gleam/bytes_builder.gleam | 197 ++ .../gleam_stdlib/src/gleam/dict.gleam | 544 ++++ .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 +++++++++++ .../gleam_stdlib/src/gleam/float.gleam | 546 ++++ .../gleam_stdlib/src/gleam/function.gleam | 162 ++ .../packages/gleam_stdlib/src/gleam/int.gleam | 874 +++++++ .../packages/gleam_stdlib/src/gleam/io.gleam | 117 + .../gleam_stdlib/src/gleam/iterator.gleam | 1530 +++++++++++ .../gleam_stdlib/src/gleam/list.gleam | 2154 +++++++++++++++ .../packages/gleam_stdlib/src/gleam/map.gleam | 127 + .../gleam_stdlib/src/gleam/option.gleam | 346 +++ .../gleam_stdlib/src/gleam/order.gleam | 133 + .../gleam_stdlib/src/gleam/pair.gleam | 85 + .../gleam_stdlib/src/gleam/queue.gleam | 292 +++ .../gleam_stdlib/src/gleam/regex.gleam | 214 ++ .../gleam_stdlib/src/gleam/result.gleam | 482 ++++ .../packages/gleam_stdlib/src/gleam/set.gleam | 264 ++ .../gleam_stdlib/src/gleam/string.gleam | 913 +++++++ .../src/gleam/string_builder.gleam | 298 +++ .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ++++ .../packages/gleam_stdlib/src/gleam@base.erl | 20 + .../gleam_stdlib/src/gleam@bit_array.erl | 102 + .../gleam_stdlib/src/gleam@bit_builder.erl | 66 + .../gleam_stdlib/src/gleam@bit_string.erl | 33 + .../packages/gleam_stdlib/src/gleam@bool.erl | 162 ++ .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 + .../packages/gleam_stdlib/src/gleam@dict.erl | 97 + .../gleam_stdlib/src/gleam@dynamic.erl | 808 ++++++ .../packages/gleam_stdlib/src/gleam@float.erl | 181 ++ .../gleam_stdlib/src/gleam@function.erl | 67 + .../packages/gleam_stdlib/src/gleam@int.erl | 332 +++ .../packages/gleam_stdlib/src/gleam@io.erl | 27 + .../gleam_stdlib/src/gleam@iterator.erl | 744 ++++++ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 ++++++++ .../packages/gleam_stdlib/src/gleam@map.erl | 76 + .../gleam_stdlib/src/gleam@option.erl | 147 ++ .../packages/gleam_stdlib/src/gleam@order.erl | 79 + .../packages/gleam_stdlib/src/gleam@pair.erl | 33 + .../packages/gleam_stdlib/src/gleam@queue.erl | 121 + .../packages/gleam_stdlib/src/gleam@regex.erl | 33 + .../gleam_stdlib/src/gleam@result.erl | 201 ++ .../packages/gleam_stdlib/src/gleam@set.erl | 85 + .../gleam_stdlib/src/gleam@string.erl | 352 +++ .../gleam_stdlib/src/gleam@string_builder.erl | 91 + .../packages/gleam_stdlib/src/gleam@uri.erl | 252 ++ .../gleam_stdlib/src/gleam_stdlib.app.src | 31 + .../gleam_stdlib/src/gleam_stdlib.erl | 529 ++++ .../gleam_stdlib/src/gleam_stdlib.mjs | 878 +++++++ .../glx/build/packages/gleeunit/LICENCE | 191 ++ .../glx/build/packages/gleeunit/README.md | 52 + .../_gleam_artefacts/gleam@base.cache | Bin 0 -> 1223 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 0 -> 52 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 0 -> 4962 bytes .../gleam@bit_array.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 0 -> 4184 bytes .../gleam@bit_builder.cache_meta | Bin 0 -> 84 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 0 -> 1934 bytes .../gleam@bit_string.cache_meta | Bin 0 -> 52 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 0 -> 7078 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 0 -> 48 bytes .../gleam@bytes_builder.cache | Bin 0 -> 6050 bytes .../gleam@bytes_builder.cache_meta | Bin 0 -> 98 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 0 -> 12268 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 0 -> 49216 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 0 -> 173 bytes .../_gleam_artefacts/gleam@float.cache | Bin 0 -> 11377 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 0 -> 48 bytes .../_gleam_artefacts/gleam@function.cache | Bin 0 -> 5806 bytes .../gleam@function.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@int.cache | Bin 0 -> 18138 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 0 -> 67 bytes .../_gleam_artefacts/gleam@io.cache | Bin 0 -> 2856 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 0 -> 37904 bytes .../gleam@iterator.cache_meta | Bin 0 -> 141 bytes .../_gleam_artefacts/gleam@list.cache | Bin 0 -> 46259 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 0 -> 120 bytes .../_gleam_artefacts/gleam@map.cache | Bin 0 -> 4737 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 0 -> 67 bytes .../_gleam_artefacts/gleam@option.cache | Bin 0 -> 7261 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@order.cache | Bin 0 -> 2704 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 0 -> 1880 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 0 -> 29 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 0 -> 7006 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 0 -> 6607 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 0 -> 49 bytes .../_gleam_artefacts/gleam@result.cache | Bin 0 -> 10388 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@set.cache | Bin 0 -> 6402 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 0 -> 85 bytes .../_gleam_artefacts/gleam@string.cache | Bin 0 -> 21832 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 0 -> 136 bytes .../gleam@string_builder.cache | Bin 0 -> 10562 bytes .../gleam@string_builder.cache_meta | Bin 0 -> 47 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 0 -> 7759 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 0 -> 132 bytes .../gleeunit/build/lsp/erlang/gleam_version | 1 + .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 0 -> 3254 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 0 -> 108 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 0 -> 1134 bytes .../gleeunit@should.cache_meta | Bin 0 -> 29 bytes .../build/packages/gleam_stdlib/LICENCE | 191 ++ .../build/packages/gleam_stdlib/README.md | 39 + .../build/packages/gleam_stdlib/gleam.toml | 16 + .../include/gleam@dynamic_DecodeError.hrl | 5 + .../include/gleam@iterator_Iterator.hrl | 1 + .../include/gleam@iterator_Next.hrl | 1 + .../include/gleam@queue_Queue.hrl | 1 + .../include/gleam@regex_CompileError.hrl | 1 + .../include/gleam@regex_Match.hrl | 4 + .../include/gleam@regex_Options.hrl | 1 + .../gleam_stdlib/include/gleam@set_Set.hrl | 1 + .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 + .../build/packages/gleam_stdlib/src/dict.mjs | 957 +++++++ .../gleam_stdlib/src/gleam/base.gleam | 21 + .../gleam_stdlib/src/gleam/bit_array.gleam | 157 ++ .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 + .../gleam_stdlib/src/gleam/bit_string.gleam | 43 + .../gleam_stdlib/src/gleam/bool.gleam | 428 +++ .../src/gleam/bytes_builder.gleam | 197 ++ .../gleam_stdlib/src/gleam/dict.gleam | 544 ++++ .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 +++++++++++ .../gleam_stdlib/src/gleam/float.gleam | 546 ++++ .../gleam_stdlib/src/gleam/function.gleam | 162 ++ .../packages/gleam_stdlib/src/gleam/int.gleam | 874 +++++++ .../packages/gleam_stdlib/src/gleam/io.gleam | 117 + .../gleam_stdlib/src/gleam/iterator.gleam | 1530 +++++++++++ .../gleam_stdlib/src/gleam/list.gleam | 2154 +++++++++++++++ .../packages/gleam_stdlib/src/gleam/map.gleam | 127 + .../gleam_stdlib/src/gleam/option.gleam | 346 +++ .../gleam_stdlib/src/gleam/order.gleam | 133 + .../gleam_stdlib/src/gleam/pair.gleam | 85 + .../gleam_stdlib/src/gleam/queue.gleam | 292 +++ .../gleam_stdlib/src/gleam/regex.gleam | 214 ++ .../gleam_stdlib/src/gleam/result.gleam | 482 ++++ .../packages/gleam_stdlib/src/gleam/set.gleam | 264 ++ .../gleam_stdlib/src/gleam/string.gleam | 913 +++++++ .../src/gleam/string_builder.gleam | 298 +++ .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ++++ .../packages/gleam_stdlib/src/gleam@base.erl | 20 + .../gleam_stdlib/src/gleam@bit_array.erl | 102 + .../gleam_stdlib/src/gleam@bit_builder.erl | 66 + .../gleam_stdlib/src/gleam@bit_string.erl | 33 + .../packages/gleam_stdlib/src/gleam@bool.erl | 162 ++ .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 + .../packages/gleam_stdlib/src/gleam@dict.erl | 97 + .../gleam_stdlib/src/gleam@dynamic.erl | 808 ++++++ .../packages/gleam_stdlib/src/gleam@float.erl | 181 ++ .../gleam_stdlib/src/gleam@function.erl | 67 + .../packages/gleam_stdlib/src/gleam@int.erl | 332 +++ .../packages/gleam_stdlib/src/gleam@io.erl | 27 + .../gleam_stdlib/src/gleam@iterator.erl | 744 ++++++ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 ++++++++ .../packages/gleam_stdlib/src/gleam@map.erl | 76 + .../gleam_stdlib/src/gleam@option.erl | 147 ++ .../packages/gleam_stdlib/src/gleam@order.erl | 79 + .../packages/gleam_stdlib/src/gleam@pair.erl | 33 + .../packages/gleam_stdlib/src/gleam@queue.erl | 121 + .../packages/gleam_stdlib/src/gleam@regex.erl | 33 + .../gleam_stdlib/src/gleam@result.erl | 201 ++ .../packages/gleam_stdlib/src/gleam@set.erl | 85 + .../gleam_stdlib/src/gleam@string.erl | 352 +++ .../gleam_stdlib/src/gleam@string_builder.erl | 91 + .../packages/gleam_stdlib/src/gleam@uri.erl | 252 ++ .../gleam_stdlib/src/gleam_stdlib.app.src | 31 + .../gleam_stdlib/src/gleam_stdlib.erl | 529 ++++ .../gleam_stdlib/src/gleam_stdlib.mjs | 878 +++++++ .../gleeunit/build/packages/packages.toml | 2 + .../glx/build/packages/gleeunit/gleam.toml | 17 + .../glx/build/packages/gleeunit/manifest.toml | 9 + .../packages/gleeunit/src/gleeunit.app.src | 8 + .../build/packages/gleeunit/src/gleeunit.erl | 59 + .../packages/gleeunit/src/gleeunit.gleam | 92 + .../gleeunit/src/gleeunit/should.gleam | 90 + .../packages/gleeunit/src/gleeunit@should.erl | 34 + .../packages/gleeunit/src/gleeunit_ffi.erl | 24 + .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 + .../gleeunit/src/gleeunit_progress.erl | 607 +++++ .../packages/glx/build/packages/packages.toml | 3 + .../build/packages/glx/gleam.toml | 11 + .../build/packages/glx/manifest.toml | 11 + .../build/packages/glx/src/glx.app.src | 8 + .../build/packages/glx/src/glx/stringx.gleam | 31 + .../build/packages/glx/src/glx@stringx.erl | 24 + .../build/packages/gsv/README.md | 45 + .../build/packages/gsv/gleam.toml | 20 + .../include/gsv@internal@token_Textdata.hrl | 1 + .../build/packages/gsv/src/gsv.app.src | 10 + .../build/packages/gsv/src/gsv.erl | 58 + .../build/packages/gsv/src/gsv.gleam | 62 + .../packages/gsv/src/gsv/internal/ast.gleam | 140 + .../packages/gsv/src/gsv/internal/token.gleam | 54 + .../packages/gsv/src/gsv@internal@ast.erl | 125 + .../packages/gsv/src/gsv@internal@token.erl | 59 + .../build/packages/hug/README.md | 47 + .../build/packages/hug/gleam.toml | 16 + .../build/packages/hug/src/hug.app.src | 10 + .../build/packages/hug/src/hug.erl | 303 +++ .../build/packages/hug/src/hug.gleam | 405 +++ .../build/packages/mist/README.md | 202 ++ .../build/packages/mist/gleam.toml | 17 + .../mist@internal@handler_Response.hrl | 3 + .../include/mist@internal@handler_State.hrl | 4 + .../include/mist@internal@http_Buffer.hrl | 1 + .../include/mist@internal@http_FileBody.hrl | 6 + .../mist/include/mist@internal@http_Read.hrl | 1 + .../include/mist@internal@http_Unread.hrl | 1 + .../mist@internal@websocket_BinaryFrame.hrl | 1 + .../mist@internal@websocket_BinaryMessage.hrl | 1 + .../mist@internal@websocket_CloseFrame.hrl | 1 + .../mist@internal@websocket_PingFrame.hrl | 1 + .../mist@internal@websocket_PongFrame.hrl | 1 + .../mist@internal@websocket_TextFrame.hrl | 1 + .../mist@internal@websocket_TextMessage.hrl | 1 + ...st@internal@websocket_WebsocketHandler.hrl | 7 + .../build/packages/mist/src/mist.app.src | 20 + .../build/packages/mist/src/mist.erl | 116 + .../build/packages/mist/src/mist.gleam | 165 ++ .../mist/src/mist/internal/encoder.gleam | 104 + .../mist/src/mist/internal/file.gleam | 26 + .../mist/src/mist/internal/handler.gleam | 350 +++ .../mist/src/mist/internal/http.gleam | 393 +++ .../mist/src/mist/internal/logger.gleam | 8 + .../mist/src/mist/internal/websocket.gleam | 167 ++ .../packages/mist/src/mist/websocket.gleam | 51 + .../mist/src/mist@internal@encoder.erl | 209 ++ .../packages/mist/src/mist@internal@file.erl | 27 + .../mist/src/mist@internal@handler.erl | 577 ++++ .../packages/mist/src/mist@internal@http.erl | 591 +++++ .../mist/src/mist@internal@logger.erl | 8 + .../mist/src/mist@internal@websocket.erl | 359 +++ .../packages/mist/src/mist@websocket.erl | 52 + .../build/packages/mist/src/mist_ffi.erl | 47 + .../build/packages/nakai/LICENSE | 22 + .../build/packages/nakai/README.md | 46 + .../build/packages/nakai/gleam.toml | 20 + .../nakai/include/nakai@html@attrs_Attr.hrl | 1 + .../nakai/include/nakai@html@attrs_Event.hrl | 1 + .../nakai/include/nakai@html_Body.hrl | 4 + .../nakai/include/nakai@html_Comment.hrl | 1 + .../nakai/include/nakai@html_Doctype.hrl | 1 + .../nakai/include/nakai@html_Element.hrl | 5 + .../nakai/include/nakai@html_Fragment.hrl | 1 + .../nakai/include/nakai@html_Head.hrl | 1 + .../nakai/include/nakai@html_Html.hrl | 4 + .../nakai/include/nakai@html_LeafElement.hrl | 4 + .../nakai/include/nakai@html_Script.hrl | 1 + .../nakai/include/nakai@html_Text.hrl | 1 + .../nakai/include/nakai@html_UnsafeText.hrl | 1 + .../nakai@internal@document_Document.hrl | 8 + .../build/packages/nakai/src/nakai.app.src | 18 + .../build/packages/nakai/src/nakai.erl | 22 + .../build/packages/nakai/src/nakai.gleam | 60 + .../nakai/src/nakai/experimental/head.gleam | 22 + .../nakai/src/nakai/experimental/on.gleam | 5 + .../nakai/experimental/web_components.gleam | 10 + .../build/packages/nakai/src/nakai/html.gleam | 1164 +++++++++ .../packages/nakai/src/nakai/html/attrs.gleam | 203 ++ .../nakai/src/nakai/internal/document.gleam | 97 + .../nakai/src/nakai/internal/render.gleam | 211 ++ .../nakai/src/nakai@experimental@head.erl | 34 + .../nakai/src/nakai@experimental@on.erl | 8 + .../src/nakai@experimental@web_components.erl | 12 + .../build/packages/nakai/src/nakai@html.erl | 830 ++++++ .../packages/nakai/src/nakai@html@attrs.erl | 191 ++ .../nakai/src/nakai@internal@document.erl | 117 + .../nakai/src/nakai@internal@render.erl | 297 +++ .../build/packages/nibble/LICENSE | 18 + .../build/packages/nibble/README.md | 46 + .../build/packages/nibble/gleam.toml | 15 + .../nibble/include/nibble@pratt_Config.hrl | 5 + .../nibble/include/nibble_DeadEnd.hrl | 6 + .../nibble/include/nibble_Located.hrl | 1 + .../build/packages/nibble/src/nibble.app.src | 10 + .../build/packages/nibble/src/nibble.erl | 517 ++++ .../build/packages/nibble/src/nibble.gleam | 519 ++++ .../packages/nibble/src/nibble/pratt.gleam | 113 + .../nibble/src/nibble/predicates.gleam | 59 + .../packages/nibble/src/nibble@pratt.erl | 120 + .../packages/nibble/src/nibble@predicates.erl | 234 ++ .../build/packages/non_empty_list/LICENSE | 201 ++ .../build/packages/non_empty_list/README.md | 40 + .../build/packages/non_empty_list/gleam.toml | 13 + .../include/non_empty_list_NonEmptyList.hrl | 1 + .../non_empty_list/src/non_empty_list.app.src | 8 + .../non_empty_list/src/non_empty_list.erl | 304 +++ .../non_empty_list/src/non_empty_list.gleam | 607 +++++ .../build/packages/packages.toml | 30 + .../build/packages/ream/LICENSE | 201 ++ .../build/packages/ream/README.md | 64 + .../build/packages/ream/gleam.toml | 27 + .../include/ream@storage@file@close_Error.hrl | 1 + .../include/ream@storage@file@read_Error.hrl | 1 + .../include/ream@storage@file@read_Ok.hrl | 1 + .../include/ream@storage@file@write_Error.hrl | 1 + .../ream@storage@file_DelayedWrite.hrl | 1 + .../include/ream@storage@file_Encoding.hrl | 1 + .../include/ream@storage@file_ReadAhead.hrl | 1 + .../ream@storage@kv@memtable_MemTable.hrl | 5 + ...ream@storage@kv@memtable_MemTableEntry.hrl | 4 + .../include/ream@storage@kv@value_Value.hrl | 6 + .../ream@storage@kv@value_ValueFile.hrl | 7 + .../ream@storage@kv@value_ValueFileInfo.hrl | 7 + .../ream/include/ream@storage@kv_KV.hrl | 11 + .../ream/include/ream@storage@kv_KVInfo.hrl | 12 + .../include/ream@storage@kv_MemTableRange.hrl | 5 + .../ream@storage@stream@event_Event.hrl | 1 + .../ream@storage@stream@event_EventFile.hrl | 6 + .../ream@storage@stream@index_Index.hrl | 1 + .../ream@storage@stream@index_IndexFile.hrl | 5 + .../include/ream@storage@stream_Stream.hrl | 7 + .../build/packages/ream/src/ream.app.src | 24 + .../build/packages/ream/src/ream.erl | 1 + .../build/packages/ream/src/ream.gleam | 1 + .../packages/ream/src/ream/storage/file.gleam | 103 + .../ream/src/ream/storage/file/close.gleam | 6 + .../ream/src/ream/storage/file/read.gleam | 7 + .../ream/src/ream/storage/file/write.gleam | 6 + .../packages/ream/src/ream/storage/kv.gleam | 430 +++ .../ream/src/ream/storage/kv/memtable.gleam | 287 ++ .../ream/src/ream/storage/kv/sstable.gleam | 54 + .../ream/src/ream/storage/kv/value.gleam | 206 ++ .../ream/src/ream/storage/stream.gleam | 139 + .../ream/src/ream/storage/stream/event.gleam | 95 + .../ream/src/ream/storage/stream/index.gleam | 153 ++ .../build/packages/ream/src/ream/uuid.gleam | 48 + .../packages/ream/src/ream@storage@file.erl | 123 + .../ream/src/ream@storage@file@close.erl | 8 + .../ream/src/ream@storage@file@read.erl | 8 + .../ream/src/ream@storage@file@write.erl | 8 + .../packages/ream/src/ream@storage@kv.erl | 901 +++++++ .../ream/src/ream@storage@kv@memtable.erl | 277 ++ .../ream/src/ream@storage@kv@sstable.erl | 136 + .../ream/src/ream@storage@kv@value.erl | 326 +++ .../packages/ream/src/ream@storage@stream.erl | 272 ++ .../ream/src/ream@storage@stream@event.erl | 186 ++ .../ream/src/ream@storage@stream@index.erl | 234 ++ .../build/packages/ream/src/ream@uuid.erl | 53 + .../build/packages/simplifile/README.md | 35 + .../build/packages/simplifile/gleam.toml | 19 + .../build/packages/simplifile/src/file.mjs | 84 + .../simplifile/src/gleam_erlang_ffi.erl | 218 ++ .../simplifile/src/simplifile.app.src | 8 + .../packages/simplifile/src/simplifile.erl | 131 + .../packages/simplifile/src/simplifile.gleam | 359 +++ .../build/packages/toml/LICENSE | 176 ++ .../build/packages/toml/README.md | 338 +++ .../build/packages/toml/lib/builder.ex | 413 +++ .../build/packages/toml/lib/decoder.ex | 1055 ++++++++ .../build/packages/toml/lib/document.ex | 182 ++ .../build/packages/toml/lib/error.ex | 143 + .../build/packages/toml/lib/lexer.ex | 392 +++ .../build/packages/toml/lib/lexer/guards.ex | 21 + .../build/packages/toml/lib/lexer/string.ex | 294 +++ .../build/packages/toml/lib/provider.ex | 227 ++ .../build/packages/toml/lib/toml.ex | 94 + .../build/packages/toml/lib/transform.ex | 127 + .../build/packages/toml/mix.exs | 125 + .../build/packages/trie_again/LICENSE | 201 ++ .../build/packages/trie_again/README.md | 62 + .../build/packages/trie_again/gleam.toml | 12 + .../packages/trie_again/include/trie_Trie.hrl | 4 + .../build/packages/trie_again/src/trie.erl | 232 ++ .../build/packages/trie_again/src/trie.gleam | 466 ++++ .../trie_again/src/trie_again.app.src | 8 + 1014 files changed, 138937 insertions(+) create mode 100644 test-community-packages-javascript/build/lsp/erlang/gleam_version create mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE create mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs create mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE create mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_cors/LICENSE create mode 100644 test-community-packages-javascript/build/packages/gleam_cors/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_cors/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/LICENSE create mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/LICENSE create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/LICENSE create mode 100644 test-community-packages-javascript/build/packages/gleam_http/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_http/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/LICENCE create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/README.md create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs create mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/README.md create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl create mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl create mode 100644 test-community-packages-javascript/build/packages/gleeunit/LICENCE create mode 100644 test-community-packages-javascript/build/packages/gleeunit/README.md create mode 100644 test-community-packages-javascript/build/packages/gleeunit/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs create mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/LICENSE create mode 100644 test-community-packages-javascript/build/packages/glenvy/README.md create mode 100644 test-community-packages-javascript/build/packages/glenvy/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl create mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs create mode 100644 test-community-packages-javascript/build/packages/glerm/README.md create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache create mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl create mode 100644 test-community-packages-javascript/build/packages/glerm/manifest.toml create mode 100755 test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so create mode 100644 test-community-packages-javascript/build/packages/glerm/priv/windows/libglerm.dll create mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.app.src create mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.erl create mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.gleam create mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/gliew/README.md create mode 100644 test-community-packages-javascript/build/packages/gliew/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.app.src create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.erl create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.gleam create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl create mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/README.md create mode 100644 test-community-packages-javascript/build/packages/glisten/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.app.src create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/globe/LICENSE create mode 100644 test-community-packages-javascript/build/packages/globe/README.md create mode 100644 test-community-packages-javascript/build/packages/globe/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.app.src create mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.erl create mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.gleam create mode 100644 test-community-packages-javascript/build/packages/gloml/README.md create mode 100644 test-community-packages-javascript/build/packages/gloml/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gloml/priv/package-lock.json create mode 100644 test-community-packages-javascript/build/packages/gloml/priv/package.json create mode 100644 test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex create mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.app.src create mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.erl create mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.gleam create mode 100644 test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs create mode 100644 test-community-packages-javascript/build/packages/glove/LICENSE create mode 100644 test-community-packages-javascript/build/packages/glove/README.md create mode 100644 test-community-packages-javascript/build/packages/glove/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl create mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.app.src create mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.erl create mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/LICENSE create mode 100644 test-community-packages-javascript/build/packages/glx/README.md create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl create mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/packages.toml create mode 100644 test-community-packages-javascript/build/packages/glx/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/glx/manifest.toml create mode 100644 test-community-packages-javascript/build/packages/glx/src/glx.app.src create mode 100644 test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam create mode 100644 test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl create mode 100644 test-community-packages-javascript/build/packages/gsv/README.md create mode 100644 test-community-packages-javascript/build/packages/gsv/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl create mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.app.src create mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.erl create mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.gleam create mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam create mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam create mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl create mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl create mode 100644 test-community-packages-javascript/build/packages/hug/README.md create mode 100644 test-community-packages-javascript/build/packages/hug/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.app.src create mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.erl create mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/README.md create mode 100644 test-community-packages-javascript/build/packages/mist/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.app.src create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl create mode 100644 test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/LICENSE create mode 100644 test-community-packages-javascript/build/packages/nakai/README.md create mode 100644 test-community-packages-javascript/build/packages/nakai/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.app.src create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl create mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl create mode 100644 test-community-packages-javascript/build/packages/nibble/LICENSE create mode 100644 test-community-packages-javascript/build/packages/nibble/README.md create mode 100644 test-community-packages-javascript/build/packages/nibble/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl create mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl create mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl create mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.app.src create mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.erl create mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.gleam create mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam create mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam create mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl create mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl create mode 100644 test-community-packages-javascript/build/packages/non_empty_list/LICENSE create mode 100644 test-community-packages-javascript/build/packages/non_empty_list/README.md create mode 100644 test-community-packages-javascript/build/packages/non_empty_list/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl create mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src create mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl create mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam create mode 100644 test-community-packages-javascript/build/packages/packages.toml create mode 100644 test-community-packages-javascript/build/packages/ream/LICENSE create mode 100644 test-community-packages-javascript/build/packages/ream/README.md create mode 100644 test-community-packages-javascript/build/packages/ream/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.app.src create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl create mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl create mode 100644 test-community-packages-javascript/build/packages/simplifile/README.md create mode 100644 test-community-packages-javascript/build/packages/simplifile/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/simplifile/src/file.mjs create mode 100644 test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl create mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src create mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl create mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam create mode 100644 test-community-packages-javascript/build/packages/toml/LICENSE create mode 100644 test-community-packages-javascript/build/packages/toml/README.md create mode 100644 test-community-packages-javascript/build/packages/toml/lib/builder.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/decoder.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/document.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/error.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/provider.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/toml.ex create mode 100644 test-community-packages-javascript/build/packages/toml/lib/transform.ex create mode 100644 test-community-packages-javascript/build/packages/toml/mix.exs create mode 100644 test-community-packages-javascript/build/packages/trie_again/LICENSE create mode 100644 test-community-packages-javascript/build/packages/trie_again/README.md create mode 100644 test-community-packages-javascript/build/packages/trie_again/gleam.toml create mode 100644 test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl create mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie.erl create mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie.gleam create mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src diff --git a/test-community-packages-javascript/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/lsp/erlang/gleam_version new file mode 100644 index 00000000000..7dd8dc5809e --- /dev/null +++ b/test-community-packages-javascript/build/lsp/erlang/gleam_version @@ -0,0 +1 @@ +0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE b/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE new file mode 100644 index 00000000000..59e1345ab47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/README.md b/test-community-packages-javascript/build/packages/gleam_bitwise/README.md new file mode 100644 index 00000000000..6838e2232b1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_bitwise/README.md @@ -0,0 +1,24 @@ +# bitwise + +[![Package Version](https://img.shields.io/hexpm/v/gleam_bitwise)](https://hex.pm/packages/gleam_bitwise) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_bitwise/) + +🍓 Bitwise operations on integers. + +## Quick start + +```sh +gleam run # Run the project +gleam test # Run the tests +gleam shell # Run an Erlang shell +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add gleam_bitwise +``` + +and its documentation can be found at . diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml b/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml new file mode 100644 index 00000000000..dd8cd839a87 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml @@ -0,0 +1,16 @@ +name = "gleam_bitwise" +version = "1.2.0" +licences = ["Apache-2.0"] +description = "Bitwise operations on integers" + +repository = { type = "github", user = "gleam-lang", repo = "bitwise" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[dependencies] +gleam_stdlib = "~> 0.21" + +[dev-dependencies] +gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam new file mode 100644 index 00000000000..662f9104da6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam @@ -0,0 +1,91 @@ +//// A set of functions for bitwise operations on integers. + +/// Calculates the bitwise AND of its arguments. +pub fn and(x: Int, y: Int) -> Int { + do_and(x, y) +} + +if erlang { + external fn do_and(Int, Int) -> Int = + "erlang" "band" +} + +if javascript { + external fn do_and(Int, Int) -> Int = + "../gleam_bitwise.mjs" "and" +} + +/// Calculates the bitwise NOT of its argument. +pub fn not(x: Int) -> Int { + do_not(x) +} + +if erlang { + external fn do_not(Int) -> Int = + "erlang" "bnot" +} + +if javascript { + external fn do_not(Int) -> Int = + "../gleam_bitwise.mjs" "not" +} + +/// Calculates the bitwise OR of its arguments. +pub fn or(x: Int, y: Int) -> Int { + do_or(x, y) +} + +if erlang { + external fn do_or(Int, Int) -> Int = + "erlang" "bor" +} + +if javascript { + external fn do_or(Int, Int) -> Int = + "../gleam_bitwise.mjs" "or" +} + +/// Calculates the bitwise XOR of its arguments. +pub fn exclusive_or(x: Int, y: Int) -> Int { + do_exclusive_or(x, y) +} + +if erlang { + external fn do_exclusive_or(Int, Int) -> Int = + "erlang" "bxor" +} + +if javascript { + external fn do_exclusive_or(Int, Int) -> Int = + "../gleam_bitwise.mjs" "exclusive_or" +} + +/// Calculates the result of an arithmetic left bitshift. +pub fn shift_left(x: Int, y: Int) -> Int { + do_shift_left(x, y) +} + +if erlang { + external fn do_shift_left(Int, Int) -> Int = + "erlang" "bsl" +} + +if javascript { + external fn do_shift_left(Int, Int) -> Int = + "../gleam_bitwise.mjs" "shift_left" +} + +/// Calculates the result of an arithmetic right bitshift. +pub fn shift_right(x: Int, y: Int) -> Int { + do_shift_right(x, y) +} + +if erlang { + external fn do_shift_right(Int, Int) -> Int = + "erlang" "bsr" +} + +if javascript { + external fn do_shift_right(Int, Int) -> Int = + "../gleam_bitwise.mjs" "shift_right" +} diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl new file mode 100644 index 00000000000..57d63544e64 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl @@ -0,0 +1,28 @@ +-module(gleam@bitwise). +-compile(no_auto_import). + +-export(['and'/2, 'not'/1, 'or'/2, exclusive_or/2, shift_left/2, shift_right/2]). + +-spec 'and'(integer(), integer()) -> integer(). +'and'(X, Y) -> + erlang:'band'(X, Y). + +-spec 'not'(integer()) -> integer(). +'not'(X) -> + erlang:'bnot'(X). + +-spec 'or'(integer(), integer()) -> integer(). +'or'(X, Y) -> + erlang:'bor'(X, Y). + +-spec exclusive_or(integer(), integer()) -> integer(). +exclusive_or(X, Y) -> + erlang:'bxor'(X, Y). + +-spec shift_left(integer(), integer()) -> integer(). +shift_left(X, Y) -> + erlang:'bsl'(X, Y). + +-spec shift_right(integer(), integer()) -> integer(). +shift_right(X, Y) -> + erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src new file mode 100644 index 00000000000..bd9497aca13 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src @@ -0,0 +1,8 @@ +{application, gleam_bitwise, [ + {vsn, "1.2.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Bitwise operations on integers"}, + {modules, [gleam@bitwise]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs new file mode 100644 index 00000000000..4f928cbc42e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs @@ -0,0 +1,28 @@ +// In Javascript bitwise operations convert numbers to a sequence of 32 bits +// while Erlang uses arbitrary precision. +// To get around this problem and get consistent results use BigInt and then +// downcast the value back to a Number value. + +export function and(x, y) { + return Number(BigInt(x) & BigInt(y)); +} + +export function not(x) { + return Number(~BigInt(x)); +} + +export function or(x, y) { + return Number(BigInt(x) | BigInt(y)); +} + +export function exclusive_or(x, y) { + return Number(BigInt(x) ^ BigInt(y)); +} + +export function shift_left(x, y) { + return Number(BigInt(x) << BigInt(y)); +} + +export function shift_right(x, y) { + return Number(BigInt(x) >> BigInt(y)); +} diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE b/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE new file mode 100644 index 00000000000..a84f0ec1d35 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE @@ -0,0 +1,190 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2023 Gleam Community Contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md b/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md new file mode 100644 index 00000000000..90ab0d56c57 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md @@ -0,0 +1,72 @@ +# gleam-community/ansi + +Format text with ANSI escape sequences. + +[![Package Version](https://img.shields.io/hexpm/v/gleam_community_ansi)](https://hex.pm/packages/gleam_community_ansi) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_ansi/) + +✨ This project is written in _pure Gleam_ so you can use it anywhere Gleam runs: +Erlang, Elixir, Node, Deno, even [some browsers](https://bit.ly/devtools-console-ansi-support)! + +--- + +## Quickstart + +```gleam +import gleam/io +import gleam_community/ansi + +pub fn main() { + let greeting = "Hello, " <> ansi.pink("world") <> "!" + + greeting + |> ansi.bg_white + |> io.println +} + +``` + +## Installation + +`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_ansi) +with the prefix `gleam_community_`. You can add them to your Gleam projects directly: + +```sh +gleam add gleam_community_ansi +``` + +The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_ansi). + +## ANSI-what? + +ANSI escape sequences date back to the 70s as a standard way to format text on +various video text terminals. Since then they have been adopted by many software +terminal emulators and platforms, including some Web browsers, and are a simple +way to format text without platform-specific APIs. + +The point of this package is to abstract the specific codes away and give you an +easy-to-understand API for formatting and colouring terminal text. Still, here is +a quick couple of examples of what's happening under the hood. + +You can copy these examples straight into your terminal to see them in action! + +- Colour text yellow: + + ```shell + $ echo "\e[33mhello" + ``` + +- Colour the background pink: + + ```shell + $ echo "\e[45mhello" + ``` + +- Render text italic: + + ```shell + $ echo "\e[3mhello\e[23m" + ``` + +As you can see, the escape sequences are a bit obscure. Sure, you could hard code +them, or you could use this package! diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml b/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml new file mode 100644 index 00000000000..026a2d2baa0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml @@ -0,0 +1,13 @@ +name = "gleam_community_ansi" +version = "1.1.0" +licences = ["Apache-2.0"] +description = "ANSI colours, formatting, and control codes" +repository = { type = "github", user = "gleam-community", repo = "ansi" } + +[dependencies] +gleam_bitwise = "~> 1.2" +gleam_stdlib = "~> 0.25" +gleam_community_colour = "~> 1.0" + +[dev-dependencies] +gleeunit = "~> 0.7" diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam new file mode 100644 index 00000000000..045273abd09 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam @@ -0,0 +1,2318 @@ +//// +//// - **Text style** +//// - [`bold`](#bold) +//// - [`italic`](#italic) +//// - [`underline`](#underline) +//// - [`strikethrough`](#strikethrough) +//// - [`inverse`](#inverse) +//// - [`dim`](#dim) +//// - [`hidden`](#hidden) +//// - [`reset`](#reset) +//// - **Text colour** +//// - [`black`](#black) +//// - [`red`](#red) +//// - [`green`](#green) +//// - [`yellow`](#yellow) +//// - [`blue`](#blue) +//// - [`magenta`](#magenta) +//// - [`cyan`](#cyan) +//// - [`white`](#white) +//// - [`pink`](#pink) +//// - [`grey`](#grey) +//// - [`gray`](#gray) +//// - [`bright_black`](#bright_black) +//// - [`bright_red`](#bright_red) +//// - [`bright_green`](#bright_green) +//// - [`bright_yellow`](#bright_yellow) +//// - [`bright_blue`](#bright_blue) +//// - [`bright_magenta`](#bright_magenta) +//// - [`bright_cyan`](#bright_cyan) +//// - [`bright_white`](#bright_white) +//// - [`hex`](#hex) +//// - [`colour`](#colour) +//// - [`color`](#color) +//// - **Background colour** +//// - [`bg_black`](#bg_black) +//// - [`bg_red`](#bg_red) +//// - [`bg_green`](#bg_green) +//// - [`bg_yellow`](#bg_yellow) +//// - [`bg_blue`](#bg_blue) +//// - [`bg_magenta`](#bg_magenta) +//// - [`bg_cyan`](#bg_cyan) +//// - [`bg_white`](#bg_white) +//// - [`bg_pink`](#bg_pink) +//// - [`bg_bright_black`](#bg_bright_black) +//// - [`bg_bright_red`](#bg_bright_red) +//// - [`bg_bright_green`](#bg_bright_green) +//// - [`bg_bright_yellow`](#bg_bright_yellow) +//// - [`bg_bright_blue`](#bg_bright_blue) +//// - [`bg_bright_magenta`](#bg_bright_magenta) +//// - [`bg_bright_cyan`](#bg_bright_cyan) +//// - [`bg_bright_white`](#bg_bright_white) +//// - [`bg_hex`](#bg_hex) +//// - [`bg_colour`](#bg_colour) +//// - [`bg_color`](#bg_color) +//// +//// --- +//// +//// This package was heavily inspired by the `colours` module in the Deno standard +//// library. The original source code can be found +//// here. +//// +////
+//// The license of that package is produced below: +//// +//// +//// > MIT License +//// +//// > Copyright 2018-2022 the Deno authors. +//// +//// > Permission is hereby granted, free of charge, to any person obtaining a copy +//// of this software and associated documentation files (the "Software"), to deal +//// in the Software without restriction, including without limitation the rights +//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//// copies of the Software, and to permit persons to whom the Software is +//// furnished to do so, subject to the following conditions: +//// +//// > The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +////
+//// + +// Just in case we decide in the future to no longer include the above reference +// and license, this package was initially a port of the Deno `colours` module: +// +// https://deno.land/std@0.167.0/fmt/colours.ts +// + +// This seems like a really handy reference if/when we want to expand this beyond +// formatting escape sequences: +// +// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 +// + +// IMPORTS -------------------------------------------------------------------- + +import gleam/bitwise +import gleam/int +import gleam/list +import gleam/string +import gleam_community/colour.{Colour} as gc_colour + +// CONSTS --------------------------------------------------------------------- + +const asci_escape_character = "" + +// TYPES ---------------------------------------------------------------------- + +type Code { + Code(open: String, close: String, regexp: String) +} + +// UTILITY -------------------------------------------------------------------- + +/// Builds colour code +fn code(open: List(Int), close: Int) -> Code { + let close_str = int.to_string(close) + let open_strs = list.map(open, int.to_string) + + Code( + open: asci_escape_character <> "[" <> string.join(open_strs, ";") <> "m", + close: asci_escape_character <> "[" <> close_str <> "m", + regexp: asci_escape_character <> "[" <> close_str <> "m", + ) +} + +/// Applies colour and background based on colour code and its associated text +fn run(text: String, code: Code) -> String { + code.open <> string.replace(text, code.regexp, code.open) <> code.close +} + +// STYLES --------------------------------------------------------------------- + +/// Reset the text modified +pub fn reset(text: String) -> String { + run(text, code([0], 0)) +} + +/// Style the given text bold. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bold("lucy") +/// // => "\x1B[1mlucy\x1B[22m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code +/// for the "default" bold/dim style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bold(text: String) -> String { + run(text, code([1], 22)) +} + +/// Style the given text's colour to be dimmer. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("lucy") +/// // => "\x1B[2mlucy\x1B[22m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code +/// for the "default" bold/dim style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn dim(text: String) -> String { + run(text, code([2], 22)) +} + +/// Style the given text italic. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.italic("lucy") +/// // => "\x1B[3mlucy\x1B[23m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[23m"` added to the string. This is the escape code +/// for the "default" italic style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.underline("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be underlined but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn italic(text: String) -> String { + run(text, code([3], 23)) +} + +/// Style the given text's colour to be dimmer. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.underline("lucy") +/// // => "\x1B[4mlucy\x1B[24m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[24m"` added to the string. This is the escape code +/// for the "default" underline style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn underline(text: String) -> String { + run(text, code([4], 24)) +} + +/// Inverse the given text's colour, and background colour. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.inverse("lucy") +/// // => "\x1B[7mlucy\x1B[27m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[27m"` added to the string. This is the escape code +/// for the "default" inverse style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn inverse(text: String) -> String { + run(text, code([7], 27)) +} + +/// Style the given text to be hidden. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.hidden("lucy") +/// // => "\x1B[8mlucy\x1B[28m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[28m"` added to the string. This is the escape code +/// for the "default" hidden style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn hidden(text: String) -> String { + run(text, code([8], 28)) +} + +/// Style the given text to be striked through. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.strikethrough("lucy") +/// // => "\x1B[9mlucy\x1B[29m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[29m"` added to the string. This is the escape code +/// for the "default" strikethrough style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn strikethrough(text: String) -> String { + run(text, code([9], 29)) +} + +// FOREGROUND ----------------------------------------------------------------- + +/// Colour the given text black. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.black("lucy") +/// // => "\x1B[30mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn black(text: String) -> String { + run(text, code([30], 39)) +} + +/// Colour the given text red. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.red("lucy") +/// // => "\x1B[31mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn red(text: String) -> String { + run(text, code([31], 39)) +} + +/// Colour the given text green. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.green("lucy") +/// // => "\x1B[32mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn green(text: String) -> String { + run(text, code([32], 39)) +} + +/// Colour the given text yellow. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("lucy") +/// // => "\x1B[33mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn yellow(text: String) -> String { + run(text, code([33], 39)) +} + +/// Colour the given text blue. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.blue("lucy") +/// // => "\x1B[34mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn blue(text: String) -> String { + run(text, code([34], 39)) +} + +/// Colour the given text magenta. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.magenta("lucy") +/// // => "\x1B[35mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn magenta(text: String) -> String { + run(text, code([35], 39)) +} + +/// Colour the given text cyan. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.cyan("lucy") +/// // => "\x1B[36mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn cyan(text: String) -> String { + run(text, code([36], 39)) +} + +/// Colour the given text white. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.white("lucy") +/// // => "\x1B[37mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn white(text: String) -> String { + run(text, code([37], 39)) +} + +/// Colour the given text gray. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.gray("lucy") +/// // => "\x1B[90mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn grey(text: String) -> String { + bright_black(text) +} + +/// This is an alias for [`grey`](#grey) for those who prefer the American English +/// spelling. +/// +pub fn gray(text: String) -> String { + bright_black(text) +} + +/// Colour the given text bright black. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bright_black("lucy") +/// // => "\x1B[90mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_black(text: String) -> String { + run(text, code([90], 39)) +} + +/// Colour the given text bright red. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bright_red("lucy") +/// // => "\x1B[91mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_red(text: String) -> String { + run(text, code([91], 39)) +} + +/// Colour the given text bright green. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_green("lucy") +/// // => "\x1B[92mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_green(text: String) -> String { + run(text, code([92], 39)) +} + +/// Colour the given text bright yellow. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_yellow("lucy") +/// // => "\x1B[93mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_yellow(text: String) -> String { + run(text, code([93], 39)) +} + +/// Colour the given text bright blue. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_blue("lucy") +/// // => "\x1B[94mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_blue(text: String) -> String { + run(text, code([94], 39)) +} + +/// Colour the given text bright gremagentaen. This should increase the luminosity +/// of the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_magenta("lucy") +/// // => "\x1B[95mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_magenta(text: String) -> String { + run(text, code([95], 39)) +} + +/// Colour the given text bright cyan. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_cyan("lucy") +/// // => "\x1B[96mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_cyan(text: String) -> String { + run(text, code([96], 39)) +} + +/// Colour the given text bright white. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_white("lucy") +/// // => "\x1B[97mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bright_white(text: String) -> String { + run(text, code([97], 39)) +} + +/// Colour the given text pink. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.pink("lucy") +/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn pink(text: String) -> String { + hex(text, 0xffaff3) +} + +/// Colour the given text the given colour represented by a hex `Int`. +/// +/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). +/// +/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the +/// colour will be set to black and white respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.hex("lucy", 0xffaff3) +/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn hex(text: String, colour: Int) -> String { + let colour = int.clamp(colour, max: 0xffffff, min: 0x0) + run( + text, + code( + [ + 38, + 2, + bitwise.shift_right(colour, 16) + |> bitwise.and(0xff), + bitwise.shift_right(colour, 8) + |> bitwise.and(0xff), + bitwise.and(colour, 0xff), + ], + 39, + ), + ) +} + +/// Colour the given text the given colour represented by a `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// import gleam_community/colour.{Colour} +/// +/// fn example() { +/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) +/// ansi.colour("lucy", pink) +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn colour(text: String, colour: Colour) -> String { + let hex_colour = gc_colour.to_rgb_hex(colour) + hex(text, hex_colour) +} + +/// This is an alias for [`colour`](#colour) for those who prefer the American English +/// spelling. +/// +pub fn color(text: String, color: Colour) -> String { + colour(text, color) +} + +// BACKGROUND ----------------------------------------------------------------- + +/// Colour the given text's background black. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_black("lucy") +/// // => "\x1B[40mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_black(text: String) -> String { + run(text, code([40], 49)) +} + +/// Colour the given text's background red. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_red("lucy") +/// // => "\x1B[41mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_red(text: String) -> String { + run(text, code([41], 49)) +} + +/// Colour the given text's background green. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_green("lucy") +/// // => "\x1B[42mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_green(text: String) -> String { + run(text, code([42], 49)) +} + +/// Colour the given text's background yellow. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_yellow("lucy") +/// // => "\x1B[43mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_yellow(text: String) -> String { + run(text, code([43], 49)) +} + +/// Colour the given text's background blue. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_blue("lucy") +/// // => "\x1B[44mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_blue(text: String) -> String { + run(text, code([44], 49)) +} + +/// Colour the given text's background magenta. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_magenta("lucy") +/// // => "\x1B[45mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_magenta(text: String) -> String { + run(text, code([45], 49)) +} + +/// Colour the given text's background cyan. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_cyan("lucy") +/// // => "\x1B[46mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_cyan(text: String) -> String { + run(text, code([46], 49)) +} + +/// Colour the given text's background white. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_white("lucy") +/// // => "\x1B[47mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_white(text: String) -> String { + run(text, code([47], 49)) +} + +/// Colour the given text's background bright black. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_black("lucy") +/// // => "\x1B[100mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_black(text: String) -> String { + run(text, code([100], 49)) +} + +/// Colour the given text's background bright red. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_red("lucy") +/// // => "\x1B[101mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_red(text: String) -> String { + run(text, code([101], 49)) +} + +/// Colour the given text's background bright green. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_green("lucy") +/// // => "\x1B[102mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_green(text: String) -> String { + run(text, code([102], 49)) +} + +/// Colour the given text's background bright yellow. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_yellow("lucy") +/// // => "\x1B[103mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_yellow(text: String) -> String { + run(text, code([103], 49)) +} + +/// Colour the given text's background bright blue. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_blue("lucy") +/// // => "\x1B[104mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_blue(text: String) -> String { + run(text, code([104], 49)) +} + +/// Colour the given text's background bright magenta. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_magenta("lucy") +/// // => "\x1B[105mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_magenta(text: String) -> String { + run(text, code([105], 49)) +} + +/// Colour the given text's background bright cyan. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_cyan("lucy") +/// // => "\x1B[106mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_cyan(text: String) -> String { + run(text, code([106], 49)) +} + +/// Colour the given text's background bright white. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_white("lucy") +/// // => "\x1B[107mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_bright_white(text: String) -> String { + run(text, code([107], 49)) +} + +/// Colour the given text's background pink. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_pink("lucy") +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_pink(text: String) -> String { + bg_hex(text, 0xffaff3) +} + +/// Colour the given text's background the given colour represented by a hex `Int`. +/// +/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). +/// +/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the +/// colour will be set to black and white respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.hex("lucy", 0xffaff3) +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_hex(text: String, colour: Int) -> String { + run( + text, + code( + [ + 48, + 2, + bitwise.shift_right(colour, 16) + |> bitwise.and(0xff), + bitwise.shift_right(colour, 8) + |> bitwise.and(0xff), + bitwise.and(colour, 0xff), + ], + 49, + ), + ) +} + +/// Colour the given text's background with the given colour represented by a `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// import gleam_community/colour.{Colour} +/// +/// fn example() { +/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) +/// ansi.bg_colour("lucy", pink) +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn bg_colour(text: String, colour: Colour) -> String { + let hex_colour = gc_colour.to_rgb_hex(colour) + bg_hex(text, hex_colour) +} + +/// This is an alias for [`bg_colour`](#bg_colour) for those who prefer the American English +/// spelling. +/// +pub fn bg_color(text: String, colour: Colour) -> String { + bg_colour(text, colour) +} diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl new file mode 100644 index 00000000000..0db99ed781b --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl @@ -0,0 +1,263 @@ +-module(gleam_community@ansi). +-compile(no_auto_import). + +-export([reset/1, bold/1, dim/1, italic/1, underline/1, inverse/1, hidden/1, strikethrough/1, black/1, red/1, green/1, yellow/1, blue/1, magenta/1, cyan/1, white/1, grey/1, gray/1, bright_black/1, bright_red/1, bright_green/1, bright_yellow/1, bright_blue/1, bright_magenta/1, bright_cyan/1, bright_white/1, pink/1, hex/2, colour/2, color/2, bg_black/1, bg_red/1, bg_green/1, bg_yellow/1, bg_blue/1, bg_magenta/1, bg_cyan/1, bg_white/1, bg_bright_black/1, bg_bright_red/1, bg_bright_green/1, bg_bright_yellow/1, bg_bright_blue/1, bg_bright_magenta/1, bg_bright_cyan/1, bg_bright_white/1, bg_pink/1, bg_hex/2, bg_colour/2, bg_color/2]). +-export_type([code/0]). + +-type code() :: {code, binary(), binary(), binary()}. + +-spec code(list(integer()), integer()) -> code(). +code(Open, Close) -> + Close_str = gleam@int:to_string(Close), + Open_strs = gleam@list:map(Open, fun gleam@int:to_string/1), + {code, + <<<<<<""/utf8, "["/utf8>>/binary, + (gleam@string:join(Open_strs, <<";"/utf8>>))/binary>>/binary, + "m"/utf8>>, + <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>, + <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>}. + +-spec run(binary(), code()) -> binary(). +run(Text, Code) -> + <<<<(erlang:element(2, Code))/binary, + (gleam@string:replace( + Text, + erlang:element(4, Code), + erlang:element(2, Code) + ))/binary>>/binary, + (erlang:element(3, Code))/binary>>. + +-spec reset(binary()) -> binary(). +reset(Text) -> + run(Text, code([0], 0)). + +-spec bold(binary()) -> binary(). +bold(Text) -> + run(Text, code([1], 22)). + +-spec dim(binary()) -> binary(). +dim(Text) -> + run(Text, code([2], 22)). + +-spec italic(binary()) -> binary(). +italic(Text) -> + run(Text, code([3], 23)). + +-spec underline(binary()) -> binary(). +underline(Text) -> + run(Text, code([4], 24)). + +-spec inverse(binary()) -> binary(). +inverse(Text) -> + run(Text, code([7], 27)). + +-spec hidden(binary()) -> binary(). +hidden(Text) -> + run(Text, code([8], 28)). + +-spec strikethrough(binary()) -> binary(). +strikethrough(Text) -> + run(Text, code([9], 29)). + +-spec black(binary()) -> binary(). +black(Text) -> + run(Text, code([30], 39)). + +-spec red(binary()) -> binary(). +red(Text) -> + run(Text, code([31], 39)). + +-spec green(binary()) -> binary(). +green(Text) -> + run(Text, code([32], 39)). + +-spec yellow(binary()) -> binary(). +yellow(Text) -> + run(Text, code([33], 39)). + +-spec blue(binary()) -> binary(). +blue(Text) -> + run(Text, code([34], 39)). + +-spec magenta(binary()) -> binary(). +magenta(Text) -> + run(Text, code([35], 39)). + +-spec cyan(binary()) -> binary(). +cyan(Text) -> + run(Text, code([36], 39)). + +-spec white(binary()) -> binary(). +white(Text) -> + run(Text, code([37], 39)). + +-spec grey(binary()) -> binary(). +grey(Text) -> + bright_black(Text). + +-spec gray(binary()) -> binary(). +gray(Text) -> + bright_black(Text). + +-spec bright_black(binary()) -> binary(). +bright_black(Text) -> + run(Text, code([90], 39)). + +-spec bright_red(binary()) -> binary(). +bright_red(Text) -> + run(Text, code([91], 39)). + +-spec bright_green(binary()) -> binary(). +bright_green(Text) -> + run(Text, code([92], 39)). + +-spec bright_yellow(binary()) -> binary(). +bright_yellow(Text) -> + run(Text, code([93], 39)). + +-spec bright_blue(binary()) -> binary(). +bright_blue(Text) -> + run(Text, code([94], 39)). + +-spec bright_magenta(binary()) -> binary(). +bright_magenta(Text) -> + run(Text, code([95], 39)). + +-spec bright_cyan(binary()) -> binary(). +bright_cyan(Text) -> + run(Text, code([96], 39)). + +-spec bright_white(binary()) -> binary(). +bright_white(Text) -> + run(Text, code([97], 39)). + +-spec pink(binary()) -> binary(). +pink(Text) -> + hex(Text, 16#ffaff3). + +-spec hex(binary(), integer()) -> binary(). +hex(Text, Colour) -> + Colour@1 = gleam@int:clamp(Colour, 16#0, 16#ffffff), + run( + Text, + code( + [38, + 2, + begin + _pipe = gleam@bitwise:shift_right(Colour@1, 16), + gleam@bitwise:'and'(_pipe, 16#ff) + end, + begin + _pipe@1 = gleam@bitwise:shift_right(Colour@1, 8), + gleam@bitwise:'and'(_pipe@1, 16#ff) + end, + gleam@bitwise:'and'(Colour@1, 16#ff)], + 39 + ) + ). + +-spec colour(binary(), gleam_community@colour:colour()) -> binary(). +colour(Text, Colour) -> + Hex_colour = gleam_community@colour:to_rgb_hex(Colour), + hex(Text, Hex_colour). + +-spec color(binary(), gleam_community@colour:colour()) -> binary(). +color(Text, Color) -> + colour(Text, Color). + +-spec bg_black(binary()) -> binary(). +bg_black(Text) -> + run(Text, code([40], 49)). + +-spec bg_red(binary()) -> binary(). +bg_red(Text) -> + run(Text, code([41], 49)). + +-spec bg_green(binary()) -> binary(). +bg_green(Text) -> + run(Text, code([42], 49)). + +-spec bg_yellow(binary()) -> binary(). +bg_yellow(Text) -> + run(Text, code([43], 49)). + +-spec bg_blue(binary()) -> binary(). +bg_blue(Text) -> + run(Text, code([44], 49)). + +-spec bg_magenta(binary()) -> binary(). +bg_magenta(Text) -> + run(Text, code([45], 49)). + +-spec bg_cyan(binary()) -> binary(). +bg_cyan(Text) -> + run(Text, code([46], 49)). + +-spec bg_white(binary()) -> binary(). +bg_white(Text) -> + run(Text, code([47], 49)). + +-spec bg_bright_black(binary()) -> binary(). +bg_bright_black(Text) -> + run(Text, code([100], 49)). + +-spec bg_bright_red(binary()) -> binary(). +bg_bright_red(Text) -> + run(Text, code([101], 49)). + +-spec bg_bright_green(binary()) -> binary(). +bg_bright_green(Text) -> + run(Text, code([102], 49)). + +-spec bg_bright_yellow(binary()) -> binary(). +bg_bright_yellow(Text) -> + run(Text, code([103], 49)). + +-spec bg_bright_blue(binary()) -> binary(). +bg_bright_blue(Text) -> + run(Text, code([104], 49)). + +-spec bg_bright_magenta(binary()) -> binary(). +bg_bright_magenta(Text) -> + run(Text, code([105], 49)). + +-spec bg_bright_cyan(binary()) -> binary(). +bg_bright_cyan(Text) -> + run(Text, code([106], 49)). + +-spec bg_bright_white(binary()) -> binary(). +bg_bright_white(Text) -> + run(Text, code([107], 49)). + +-spec bg_pink(binary()) -> binary(). +bg_pink(Text) -> + bg_hex(Text, 16#ffaff3). + +-spec bg_hex(binary(), integer()) -> binary(). +bg_hex(Text, Colour) -> + run( + Text, + code( + [48, + 2, + begin + _pipe = gleam@bitwise:shift_right(Colour, 16), + gleam@bitwise:'and'(_pipe, 16#ff) + end, + begin + _pipe@1 = gleam@bitwise:shift_right(Colour, 8), + gleam@bitwise:'and'(_pipe@1, 16#ff) + end, + gleam@bitwise:'and'(Colour, 16#ff)], + 49 + ) + ). + +-spec bg_colour(binary(), gleam_community@colour:colour()) -> binary(). +bg_colour(Text, Colour) -> + Hex_colour = gleam_community@colour:to_rgb_hex(Colour), + bg_hex(Text, Hex_colour). + +-spec bg_color(binary(), gleam_community@colour:colour()) -> binary(). +bg_color(Text, Colour) -> + bg_colour(Text, Colour). diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src new file mode 100644 index 00000000000..75be12e5003 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src @@ -0,0 +1,10 @@ +{application, gleam_community_ansi, [ + {vsn, "1.1.0"}, + {applications, [gleam_bitwise, + gleam_community_colour, + gleam_stdlib, + gleeunit]}, + {description, "ANSI colours, formatting, and control codes"}, + {modules, [gleam_community@ansi]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE b/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE new file mode 100644 index 00000000000..a84f0ec1d35 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE @@ -0,0 +1,190 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2023 Gleam Community Contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/README.md b/test-community-packages-javascript/build/packages/gleam_community_colour/README.md new file mode 100644 index 00000000000..0eccdd7dd50 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/README.md @@ -0,0 +1,36 @@ +# gleam-community/colour + +A package for a standard Colour type, conversions, and other utilities. + +[![Package Version](https://img.shields.io/hexpm/v/gleam_community_colour)](https://hex.pm/packages/gleam_community_colour) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_colour/) + +✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! + +--- + +## Quickstart + +```gleam +import gleam_community/colour +import gleam_community/colour/accessibility + +pub fn main() { + let foreground = colour.from_hsl(h: 0.858, s: 1.0, l: 0.843) + + let background_options = [colour.light_grey, colour.dark_grey] + + let background = accessibility.maximum_contrast(foreground, background_options) +} +``` + +## Installation + +`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_colour) +with the prefix `gleam_community_`. You can add them to your Gleam projects directly: + +```sh +gleam add gleam_community_colour +``` + +The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_colour). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml b/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml new file mode 100644 index 00000000000..36aa4270553 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml @@ -0,0 +1,12 @@ +name = "gleam_community_colour" +version = "1.1.0" +licences = ["Apache-2.0"] +description = "Colour types, conversions, and other utilities" +repository = { type = "github", user = "gleam-community", repo = "colour" } + +[dependencies] +gleam_bitwise = "~> 1.2" +gleam_stdlib = "~> 0.27" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl new file mode 100644 index 00000000000..06116dfe288 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl @@ -0,0 +1 @@ +-record(hsla, {h :: float(), s :: float(), l :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl new file mode 100644 index 00000000000..fff139e06ac --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl @@ -0,0 +1 @@ +-record(rgba, {r :: float(), g :: float(), b :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam new file mode 100644 index 00000000000..50244b5ab4f --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam @@ -0,0 +1,1127 @@ +//// +//// - **Types** +//// - [`Colour`](#Colour) +//// - [`Color`](#Color) +//// - **Constructors** +//// - [`from_rgb255`](#from_rgb255) +//// - [`from_rgb`](#from_rgb) +//// - [`from_rgba`](#from_rgba) +//// - [`from_hsl`](#from_hsl) +//// - [`from_hsla`](#from_hsla) +//// - [`from_rgb_hex`](#from_rgb_hex) +//// - [`from_rgba_hex`](#from_rgba_hex) +//// - [`from_rgb_hex_string`](#from_rgb_hex_string) +//// - [`from_rgba_hex_string`](#from_rgba_hex_string) +//// - **Conversions** +//// - [`to_rgba`](#to_rgba) +//// - [`to_hsla`](#hsla) +//// - [`to_css_rgba_string`](#to_css_rgba_string) +//// - [`to_rgba_hex_string`](#to_rgba_hex_string) +//// - [`to_rgb_hex_string`](#to_rgb_hex_string) +//// - [`to_rgba_hex`](#to_rgba_hex) +//// - [`to_rgb_hex`](#to_rgb_hex) +//// - **Colours** +//// - [`light_red`](#light_red) +//// - [`red`](#red) +//// - [`dark_red`](#dark_red) +//// - [`light_orange`](#light_orange) +//// - [`orange`](#orange) +//// - [`dark_orange`](#dark_orange) +//// - [`light_yellow`](#light_yellow) +//// - [`yellow`](#yellow) +//// - [`dark_yellow`](#dark_yellow) +//// - [`light_green`](#light_green) +//// - [`green`](#green) +//// - [`dark_green`](#dark_green) +//// - [`light_blue`](#light_blue) +//// - [`blue`](#blue) +//// - [`dark_blue`](#dark_blue) +//// - [`light_purple`](#light_purple) +//// - [`purple`](#purple) +//// - [`dark_purple`](#dark_purple) +//// - [`light_brown`](#light_brown) +//// - [`brown`](#brown) +//// - [`dark_brown`](#dark_brown) +//// - [`black`](#black) +//// - [`white`](#white) +//// - [`light_grey`](#light_grey) +//// - [`grey`](#grey) +//// - [`dark_grey`](#dark_grey) +//// - [`light_gray`](#light_gray) +//// - [`gray`](#gray) +//// - [`dark_gray`](#dark_gray) +//// - [`light_charcoal`](#light_charcoal) +//// - [`charcoal`](#charcoal) +//// - [`dark_charcoal`](#dark_charcoal) +//// - [`pink`](#pink) +//// +//// --- +//// +//// This package was heavily inspired by the `elm-color` module. +//// The original source code can be found +//// here. +//// +////
+//// The license of that package is produced below: +//// +//// +//// > MIT License +//// +//// > Copyright 2018 Aaron VonderHaar +//// +//// > Redistribution and use in source and binary forms, with or without modification, +//// are permitted provided that the following conditions are met: +//// +//// 1. Redistributions of source code must retain the above copyright notice, +//// this list of conditions and the following disclaimer. +//// +//// 2. Redistributions in binary form must reproduce the above copyright notice, +//// this list of conditions and the following disclaimer in the documentation +//// and/or other materials provided with the distribution. +//// +//// 3. Neither the name of the copyright holder nor the names of its contributors +//// may be used to endorse or promote products derived from this software without +//// specific prior written permission. +//// +//// > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +//// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +//// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +//// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +//// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +//// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +//// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//// +//// > The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +////
+//// + +// Just in case we decide in the future to no longer include the above reference +// and license, this package was initially a port of the `elm-color` module: +// +// https://github.com/avh4/elm-color/ +// + +// IMPORTS -------------------------------------------------------------------- + +import gleam/bitwise +import gleam/int +import gleam/float +import gleam/result +import gleam/string +import gleam/list + +// TYPES ---------------------------------------------------------------------- + +/// A representation of a colour that can be converted to RGBA or HSLA format. +/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+///
+/// +pub opaque type Colour { + Rgba(r: Float, g: Float, b: Float, a: Float) + Hsla(h: Float, s: Float, l: Float, a: Float) +} + +/// Type alias for `Colour` +/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+///
+/// +pub type Color = + Colour + +// UTILITY -------------------------------------------------------------------- + +fn valid_colour_value(c: Float) -> Result(Float, Nil) { + case c >. 1.0 || c <. 0.0 { + True -> Error(Nil) + False -> Ok(c) + } +} + +fn hue_to_rgb(hue: Float, m1: Float, m2: Float) -> Float { + let h = case hue { + _ if hue <. 0.0 -> hue +. 1.0 + _ if hue >. 1.0 -> hue -. 1.0 + _ -> hue + } + + let h_t_6 = h *. 6.0 + let h_t_2 = h *. 2.0 + let h_t_3 = h *. 3.0 + + case h { + _ if h_t_6 <. 1.0 -> m1 +. { m2 -. m1 } *. h *. 6.0 + _ if h_t_2 <. 1.0 -> m2 + _ if h_t_3 <. 2.0 -> m1 +. { m2 -. m1 } *. { 2.0 /. 3.0 -. h } *. 6.0 + _ -> m1 + } +} + +fn hex_string_to_int(hex_string: String) -> Result(Int, Nil) { + let hex = case hex_string { + "#" <> hex_number -> hex_number + "0x" <> hex_number -> hex_number + _ -> hex_string + } + + hex + |> string.lowercase() + |> string.to_graphemes() + |> list.reverse() + |> list.index_fold( + Ok(0), + fn(total, char, index) { + case total { + Error(Nil) -> Error(Nil) + Ok(v) -> { + use num <- result.then(case char { + "a" -> Ok(10) + "b" -> Ok(11) + "c" -> Ok(12) + "d" -> Ok(13) + "e" -> Ok(14) + "f" -> Ok(15) + _ -> int.parse(char) + }) + use base <- result.then(int.power(16, int.to_float(index))) + Ok(v + float.round(int.to_float(num) *. base)) + } + } + }, + ) +} + +fn hsla_to_rgba( + h: Float, + s: Float, + l: Float, + a: Float, +) -> #(Float, Float, Float, Float) { + let m2 = case l <=. 0.5 { + True -> l *. { s +. 1.0 } + False -> l +. s -. l *. s + } + + let m1 = l *. 2.0 -. m2 + + let r = hue_to_rgb(h +. 1.0 /. 3.0, m1, m2) + let g = hue_to_rgb(h, m1, m2) + let b = hue_to_rgb(h -. 1.0 /. 3.0, m1, m2) + + #(r, g, b, a) +} + +fn rgba_to_hsla( + r: Float, + g: Float, + b: Float, + a: Float, +) -> #(Float, Float, Float, Float) { + let min_colour = float.min(r, float.min(g, b)) + + let max_colour = float.max(r, float.max(g, b)) + + let h1 = case True { + _ if max_colour == r -> float.divide(g -. b, max_colour -. min_colour) + _ if max_colour == g -> + float.divide(b -. r, max_colour -. min_colour) + |> result.then(fn(d) { Ok(2.0 +. d) }) + _ -> + float.divide(r -. g, max_colour -. min_colour) + |> result.then(fn(d) { Ok(4.0 +. d) }) + } + + let h2 = case h1 { + Ok(v) -> Ok(v *. { 1.0 /. 6.0 }) + _ -> h1 + } + + let h3 = case h2 { + Ok(v) if v <. 0.0 -> v +. 1.0 + Ok(v) -> v + _ -> 0.0 + } + + let l = { min_colour +. max_colour } /. 2.0 + + let s = case True { + _ if min_colour == max_colour -> 0.0 + _ if l <. 0.5 -> + { max_colour -. min_colour } /. { max_colour +. min_colour } + _ -> { max_colour -. min_colour } /. { 2.0 -. max_colour -. min_colour } + } + + #(h3, s, l, a) +} + +// CONSTRUCTORS --------------------------------------------------------------- + +/// Returns a `Result(Colour)` created from the given 8 bit RGB values. +/// +/// Returns `Error(Nil)` if the supplied RGB values are greater than 255 or less than 0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_rgb255(r red: Int, g green: Int, b blue: Int) -> Result(Colour, Nil) { + use r <- result.then( + red + |> int.to_float() + |> float.divide(255.0) + |> result.then(valid_colour_value), + ) + + use g <- result.then( + green + |> int.to_float() + |> float.divide(255.0) + |> result.then(valid_colour_value), + ) + + use b <- result.then( + blue + |> int.to_float() + |> float.divide(255.0) + |> result.then(valid_colour_value), + ) + + Ok(Rgba(r: r, g: g, b: b, a: 1.0)) +} + +/// Returns `Result(Colour)` created from the given RGB values. +/// +/// If the supplied RGB values are greater than 1.0 or less than 0.0 returns `Error(Nil)` +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb(1.0, 0.0, 0.0) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_rgb( + r red: Float, + g green: Float, + b blue: Float, +) -> Result(Colour, Nil) { + use r <- result.then(valid_colour_value(red)) + use g <- result.then(valid_colour_value(green)) + use b <- result.then(valid_colour_value(blue)) + + Ok(Rgba(r: r, g: g, b: b, a: 1.0)) +} + +/// Returns `Result(Colour)` created from the given RGBA values. +/// +/// Returns `Error(Nil)` if the supplied RGBA values are greater than 1.0 or less than 0.0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_rbga(1.0, 0.0, 0.0, 0.5) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_rgba( + r red: Float, + g green: Float, + b blue: Float, + a alpha: Float, +) -> Result(Colour, Nil) { + use r <- result.then(valid_colour_value(red)) + use g <- result.then(valid_colour_value(green)) + use b <- result.then(valid_colour_value(blue)) + use a <- result.then(valid_colour_value(alpha)) + + Ok(Rgba(r: r, g: g, b: b, a: a)) +} + +/// Returns `Result(Colour)` created from the given HSLA values. +/// +/// Returns `Error(Nil)`f the supplied HSLA values are greater than 1.0 or less than 0.0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_hsla(0.0, 1.0, 0.5, 0.5) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_hsla( + h hue: Float, + s saturation: Float, + l lightness: Float, + a alpha: Float, +) -> Result(Colour, Nil) { + use h <- result.then(valid_colour_value(hue)) + use s <- result.then(valid_colour_value(saturation)) + use l <- result.then(valid_colour_value(lightness)) + use a <- result.then(valid_colour_value(alpha)) + + Ok(Hsla(h: h, s: s, l: l, a: a)) +} + +/// Returns `Result(Colour)` created from the given HSL values. +/// +/// Returns `Error(Nil)` if the supplied HSL values are greater than 1.0 or less than 0.0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_hsla(0.0, 1.0, 0.5) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_hsl( + h hue: Float, + s saturation: Float, + l lightness: Float, +) -> Result(Colour, Nil) { + from_hsla(hue, saturation, lightness, 1.0) +} + +/// Returns a `Result(Colour)` created from the given hex `Int`. +/// +/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffff or less than 0x0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb_hex(0xff0000) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_rgb_hex(hex: Int) -> Result(Colour, Nil) { + case hex > 0xffffff || hex < 0 { + True -> Error(Nil) + False -> { + let r = + bitwise.shift_right(hex, 16) + |> bitwise.and(0xff) + let g = + bitwise.shift_right(hex, 8) + |> bitwise.and(0xff) + let b = bitwise.and(hex, 0xff) + from_rgb255(r, g, b) + } + } +} + +/// Returns a `Result(Colour)` created from the given RGB hex `String`. +/// +/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffff" or less than `"#0"` +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb_hex_string("#ff0000") +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_rgb_hex_string(hex_string: String) -> Result(Colour, Nil) { + use hex_int <- result.then(hex_string_to_int(hex_string)) + + from_rgb_hex(hex_int) +} + +/// Returns a `Result(Colour)` created from the given RGBA hex `String`. +/// +/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffffff" or less than `"#0"` +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_rgba_hex_string("#ff00007f") +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_rgba_hex_string(hex_string: String) -> Result(Colour, Nil) { + use hex_int <- result.then(hex_string_to_int(hex_string)) + + from_rgba_hex(hex_int) +} + +/// Returns a `Result(Colour)` created from the given hex `Int`. +/// +/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffffff or less than 0x0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_rgba_hex(0xff00007f) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn from_rgba_hex(hex: Int) -> Result(Colour, Nil) { + case hex > 0xffffffff || hex < 0 { + True -> Error(Nil) + False -> { + // This won't fail because we are always dividing by 255.0 + let assert Ok(r) = + bitwise.shift_right(hex, 24) + |> bitwise.and(0xff) + |> int.to_float() + |> float.divide(255.0) + // This won't fail because we are always dividing by 255.0 + let assert Ok(g) = + bitwise.shift_right(hex, 16) + |> bitwise.and(0xff) + |> int.to_float() + |> float.divide(255.0) + // This won't fail because we are always dividing by 255.0 + let assert Ok(b) = + bitwise.shift_right(hex, 8) + |> bitwise.and(0xff) + |> int.to_float() + |> float.divide(255.0) + // This won't fail because we are always dividing by 255.0 + let assert Ok(a) = + bitwise.and(hex, 0xff) + |> int.to_float() + |> float.divide(255.0) + from_rgba(r, g, b, a) + } + } +} + +// CONVERSIONS ---------------------------------------------------------------- + +/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s +/// R, G, B, and A values respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// let #(r, g, b, a) = to_rgba(red) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn to_rgba(colour: Colour) -> #(Float, Float, Float, Float) { + case colour { + Rgba(r, g, b, a) -> #(r, g, b, a) + Hsla(h, s, l, a) -> hsla_to_rgba(h, s, l, a) + } +} + +/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s +/// H, S, L, and A values respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// let #(h, s, l, a) = to_hsla(red) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn to_hsla(colour: Colour) -> #(Float, Float, Float, Float) { + case colour { + Hsla(h, s, l, a) -> #(h, s, l, a) + Rgba(r, g, b, a) -> rgba_to_hsla(r, g, b, a) + } +} + +/// Returns an rgba formatted CSS `String` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// let css_red = to_css_rgba_string(red) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn to_css_rgba_string(colour: Colour) -> String { + let #(r, g, b, a) = to_rgba(colour) + + let percent = fn(x: Float) -> Float { + // This won't fail because we are always dividing by 100.0 + let assert Ok(p) = + x + |> float.multiply(10_000.0) + |> float.round() + |> int.to_float() + |> float.divide(100.0) + + p + } + + let round_to = fn(x: Float) -> Float { + // This won't fail because we are always dividing by 1000.0 + let assert Ok(r) = + x + |> float.multiply(1000.0) + |> float.round() + |> int.to_float() + |> float.divide(1000.0) + + r + } + + string.join( + [ + "rgba(", + float.to_string(percent(r)) <> "%,", + float.to_string(percent(g)) <> "%,", + float.to_string(percent(b)) <> "%,", + float.to_string(round_to(a)), + ")", + ], + "", + ) +} + +/// Returns an rgba hex formatted `String` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) +/// let red_hex = to_rgba_hex_string(red) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn to_rgba_hex_string(colour: Colour) -> String { + to_rgba_hex(colour) + |> int.to_base16() +} + +/// Returns an rgb hex formatted `String` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(255, 0, 0) +/// let red_hex = to_rgb_hex_string(red) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn to_rgb_hex_string(colour: Colour) -> String { + to_rgb_hex(colour) + |> int.to_base16() +} + +/// Returns an hex `Int` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) +/// let red_hex_int = to_rgba_hex(red) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn to_rgba_hex(colour: Colour) -> Int { + let #(r, g, b, a) = to_rgba(colour) + + let red = + r *. 255.0 + |> float.round() + |> bitwise.shift_left(24) + + let green = + g *. 255.0 + |> float.round() + |> bitwise.shift_left(16) + + let blue = + b *. 255.0 + |> float.round() + |> bitwise.shift_left(8) + + let alpha = + a *. 255.0 + |> float.round() + + red + green + blue + alpha +} + +/// Returns a rgb hex `Int` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(255, 0, 0) +/// let red_hex_int = to_rgb_hex(red) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn to_rgb_hex(colour: Colour) -> Int { + let #(r, g, b, _) = to_rgba(colour) + + let red = + r *. 255.0 + |> float.round() + |> bitwise.shift_left(16) + + let green = + g *. 255.0 + |> float.round() + |> bitwise.shift_left(8) + + let blue = + b *. 255.0 + |> float.round() + + red + green + blue +} + +// COLOURS -------------------------------------------------------------------- + +/// A `Colour` reprsenting the colour RGBA(239, 41, 41, 1.0) +pub const light_red = Rgba( + r: 0.9372549019607843, + g: 0.1607843137254902, + b: 0.1607843137254902, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(204, 0, 0, 1.0) +pub const red = Rgba(r: 0.8, g: 0.0, b: 0.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(164, 0, 0, 1.0) +pub const dark_red = Rgba(r: 0.6431372549019608, g: 0.0, b: 0.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(252, 175, 62, 1.0) +pub const light_orange = Rgba( + r: 0.9882352941176471, + g: 0.6862745098039216, + b: 0.24313725490196078, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(245, 121, 0, 1.0) +pub const orange = Rgba( + r: 0.9607843137254902, + g: 0.4745098039215686, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(206, 92, 0, 1.0) +pub const dark_orange = Rgba( + r: 0.807843137254902, + g: 0.3607843137254902, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(255, 233, 79, 1.0) +pub const light_yellow = Rgba( + r: 1.0, + g: 0.9137254901960784, + b: 0.30980392156862746, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(237, 212, 0, 1.0) +pub const yellow = Rgba( + r: 0.9294117647058824, + g: 0.8313725490196079, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(196, 160, 0, 1.0) +pub const dark_yellow = Rgba( + r: 0.7686274509803922, + g: 0.6274509803921569, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(138, 226, 52, 1.0) +pub const light_green = Rgba( + r: 0.5411764705882353, + g: 0.8862745098039215, + b: 0.20392156862745098, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(115, 210, 22, 1.0) +pub const green = Rgba( + r: 0.45098039215686275, + g: 0.8235294117647058, + b: 0.08627450980392157, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(78, 154, 6, 1.0) +pub const dark_green = Rgba( + r: 0.3058823529411765, + g: 0.6039215686274509, + b: 0.023529411764705882, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(114, 159, 207, 1.0) +pub const light_blue = Rgba( + r: 0.4470588235294118, + g: 0.6235294117647059, + b: 0.8117647058823529, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(52, 101, 164, 1.0) +pub const blue = Rgba( + r: 0.20392156862745098, + g: 0.396078431372549, + b: 0.6431372549019608, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(32, 74, 135, 1.0) +pub const dark_blue = Rgba( + r: 0.12549019607843137, + g: 0.2901960784313726, + b: 0.5294117647058824, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(173, 127, 168, 1.0) +pub const light_purple = Rgba( + r: 0.6784313725490196, + g: 0.4980392156862745, + b: 0.6588235294117647, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(117, 80, 123, 1.0) +pub const purple = Rgba( + r: 0.4588235294117647, + g: 0.3137254901960784, + b: 0.4823529411764706, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(92, 53, 102, 1.0) +pub const dark_purple = Rgba( + r: 0.3607843137254902, + g: 0.20784313725490197, + b: 0.4, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(233, 185, 110, 1.0) +pub const light_brown = Rgba( + r: 0.9137254901960784, + g: 0.7254901960784313, + b: 0.43137254901960786, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(193, 125, 17, 1.0) +pub const brown = Rgba( + r: 0.7568627450980392, + g: 0.49019607843137253, + b: 0.06666666666666667, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(143, 89, 2, 1.0) +pub const dark_brown = Rgba( + r: 0.5607843137254902, + g: 0.34901960784313724, + b: 0.00784313725490196, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(0, 0, 0, 1.0) +pub const black = Rgba(r: 0.0, g: 0.0, b: 0.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(255, 255, 255, 1.0) +pub const white = Rgba(r: 1.0, g: 1.0, b: 1.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) +pub const light_grey = Rgba( + r: 0.9333333333333333, + g: 0.9333333333333333, + b: 0.9254901960784314, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) +pub const grey = Rgba( + r: 0.8274509803921568, + g: 0.8431372549019608, + b: 0.8117647058823529, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) +pub const dark_grey = Rgba( + r: 0.7294117647058823, + g: 0.7411764705882353, + b: 0.7137254901960784, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) +pub const light_gray = Rgba( + r: 0.9333333333333333, + g: 0.9333333333333333, + b: 0.9254901960784314, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) +pub const gray = Rgba( + r: 0.8274509803921568, + g: 0.8431372549019608, + b: 0.8117647058823529, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) +pub const dark_gray = Rgba( + r: 0.7294117647058823, + g: 0.7411764705882353, + b: 0.7137254901960784, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(136, 138, 133, 1.0) +pub const light_charcoal = Rgba( + r: 0.5333333333333333, + g: 0.5411764705882353, + b: 0.5215686274509804, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(85, 87, 83, 1.0) +pub const charcoal = Rgba( + r: 0.3333333333333333, + g: 0.3411764705882353, + b: 0.3254901960784314, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(46, 52, 54, 1.0) +pub const dark_charcoal = Rgba( + r: 0.1803921568627451, + g: 0.20392156862745098, + b: 0.21176470588235294, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(255, 175, 243, 1.0) +pub const pink = Rgba( + r: 1.0, + g: 0.6862745098039216, + b: 0.9529411764705882, + a: 1.0, +) diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam new file mode 100644 index 00000000000..471685732f9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam @@ -0,0 +1,173 @@ +//// +//// - **Accessibility** +//// - [`luminance`](#luminance) +//// - [`contrast_ratio`](#contrast_ratio) +//// - [`maximum_contrast`](#maximum_contrast) +//// +//// --- +//// +//// This package was heavily inspired by the `elm-color-extra` module. +//// The original source code can be found +//// here. +//// +////
+//// The license of that package is produced below: +//// +//// +//// > MIT License +//// +//// > Copyright (c) 2016 Andreas Köberle +//// +//// > Permission is hereby granted, free of charge, to any person obtaining a copy +//// of this software and associated documentation files (the "Software"), to deal +//// in the Software without restriction, including without limitation the rights +//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//// copies of the Software, and to permit persons to whom the Software is +//// furnished to do so, subject to the following conditions: +//// +//// > The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +//// +//// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +//// SOFTWARE. +//// +////
+//// + +// Just in case we decide in the future to no longer include the above reference +// and license, this package was initially a port of the `elm-color-extra` module: +// +// https://github.com/noahzgordon/elm-color-extra +// + +// IMPORTS -------------------------------------------------------------------- + +import gleam/float +import gleam/list +import gleam_community/colour.{Colour} + +// UTILITIES ------------------------------------------------------------------ + +fn intensity(colour_value: Float) -> Float { + // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef + case True { + _ if colour_value <=. 0.03928 -> colour_value /. 12.92 + _ -> { + // Is this guaranteed to be `OK`? + let assert Ok(i) = float.power({ colour_value +. 0.055 } /. 1.055, 2.4) + i + } + } +} + +// ACCESSIBILITY -------------------------------------------------------------- + +/// Returns the relative brightness of the given `Colour` as a `Float` between +/// 0.0, and 1.0 with 0.0 being the darkest possible colour and 1.0 being the lightest. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// luminance(colour.white) // 1.0 +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn luminance(colour: Colour) -> Float { + // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef + let #(r, g, b, _) = colour.to_rgba(colour) + + let r_intensity = intensity(r) + let g_intensity = intensity(g) + let b_intensity = intensity(b) + + 0.2126 *. r_intensity +. 0.7152 *. g_intensity +. 0.0722 *. b_intensity +} + +/// Returns the contrast between two `Colour` values as a `Float` between 1.0, +/// and 21.0 with 1.0 being no contrast and, 21.0 being the highest possible contrast. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// contrast_ratio(between: colour.white, and: colour.black) // 21.0 +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn contrast_ratio(between colour_a: Colour, and colour_b: Colour) -> Float { + // Calculation taken from https://www.w3.org/TR/WCAG20/#contrast-ratiodef + let luminance_a = luminance(colour_a) +. 0.05 + let luminance_b = luminance(colour_b) +. 0.05 + + case luminance_a >. luminance_b { + True -> luminance_a /. luminance_b + False -> luminance_b /. luminance_a + } +} + +/// Returns the `Colour` with the highest contrast between the base `Colour`, +/// and and the other provided `Colour` values. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// maximum_contrast( +/// colour.yellow, +/// [colour.white, colour.dark_blue, colour.green], +/// ) +/// } +/// ``` +///
+/// +///
+/// +/// Spot a typo? Open an issue! +/// +/// +/// Back to top ↑ +/// +///
+/// +pub fn maximum_contrast( + base: Colour, + colours: List(Colour), +) -> Result(Colour, Nil) { + colours + |> list.sort(fn(colour_a, colour_b) { + let contrast_a = contrast_ratio(base, colour_a) + let contrast_b = contrast_ratio(base, colour_b) + + float.compare(contrast_b, contrast_a) + }) + |> list.first() +} diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl new file mode 100644 index 00000000000..6b3063f7aa0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl @@ -0,0 +1,525 @@ +-module(gleam_community@colour). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([from_rgb255/3, from_rgb/3, from_rgba/4, from_hsla/4, from_hsl/3, from_rgb_hex/1, from_rgb_hex_string/1, from_rgba_hex/1, from_rgba_hex_string/1, to_rgba/1, to_hsla/1, to_css_rgba_string/1, to_rgba_hex/1, to_rgba_hex_string/1, to_rgb_hex/1, to_rgb_hex_string/1]). +-export_type([colour/0]). + +-opaque colour() :: {rgba, float(), float(), float(), float()} | + {hsla, float(), float(), float(), float()}. + +-spec valid_colour_value(float()) -> {ok, float()} | {error, nil}. +valid_colour_value(C) -> + case (C > 1.0) orelse (C < 0.0) of + true -> + {error, nil}; + + false -> + {ok, C} + end. + +-spec hue_to_rgb(float(), float(), float()) -> float(). +hue_to_rgb(Hue, M1, M2) -> + H = case Hue of + _ when Hue < 0.0 -> + Hue + 1.0; + + _ when Hue > 1.0 -> + Hue - 1.0; + + _ -> + Hue + end, + H_t_6 = H * 6.0, + H_t_2 = H * 2.0, + H_t_3 = H * 3.0, + case H of + _ when H_t_6 < 1.0 -> + M1 + (((M2 - M1) * H) * 6.0); + + _ when H_t_2 < 1.0 -> + M2; + + _ when H_t_3 < 2.0 -> + M1 + (((M2 - M1) * ((2.0 / 3.0) - H)) * 6.0); + + _ -> + M1 + end. + +-spec hex_string_to_int(binary()) -> {ok, integer()} | {error, nil}. +hex_string_to_int(Hex_string) -> + Hex = case Hex_string of + <<"#"/utf8, Hex_number/binary>> -> + Hex_number; + + <<"0x"/utf8, Hex_number@1/binary>> -> + Hex_number@1; + + _ -> + Hex_string + end, + _pipe = Hex, + _pipe@1 = gleam@string:lowercase(_pipe), + _pipe@2 = gleam@string:to_graphemes(_pipe@1), + _pipe@3 = gleam@list:reverse(_pipe@2), + gleam@list:index_fold( + _pipe@3, + {ok, 0}, + fun(Total, Char, Index) -> case Total of + {error, nil} -> + {error, nil}; + + {ok, V} -> + gleam@result:then(case Char of + <<"a"/utf8>> -> + {ok, 10}; + + <<"b"/utf8>> -> + {ok, 11}; + + <<"c"/utf8>> -> + {ok, 12}; + + <<"d"/utf8>> -> + {ok, 13}; + + <<"e"/utf8>> -> + {ok, 14}; + + <<"f"/utf8>> -> + {ok, 15}; + + _ -> + gleam@int:parse(Char) + end, fun(Num) -> + gleam@result:then( + gleam@int:power(16, gleam@int:to_float(Index)), + fun(Base) -> + {ok, + V + + gleam@float:round( + gleam@int:to_float(Num) + * Base + )} + end + ) + end) + end end + ). + +-spec hsla_to_rgba(float(), float(), float(), float()) -> {float(), + float(), + float(), + float()}. +hsla_to_rgba(H, S, L, A) -> + M2 = case L =< 0.5 of + true -> + L * (S + 1.0); + + false -> + (L + S) - (L * S) + end, + M1 = (L * 2.0) - M2, + R = hue_to_rgb(H + (1.0 / 3.0), M1, M2), + G = hue_to_rgb(H, M1, M2), + B = hue_to_rgb(H - (1.0 / 3.0), M1, M2), + {R, G, B, A}. + +-spec rgba_to_hsla(float(), float(), float(), float()) -> {float(), + float(), + float(), + float()}. +rgba_to_hsla(R, G, B, A) -> + Min_colour = gleam@float:min(R, gleam@float:min(G, B)), + Max_colour = gleam@float:max(R, gleam@float:max(G, B)), + H1 = case true of + _ when Max_colour =:= R -> + gleam@float:divide(G - B, Max_colour - Min_colour); + + _ when Max_colour =:= G -> + _pipe = gleam@float:divide(B - R, Max_colour - Min_colour), + gleam@result:then(_pipe, fun(D) -> {ok, 2.0 + D} end); + + _ -> + _pipe@1 = gleam@float:divide(R - G, Max_colour - Min_colour), + gleam@result:then(_pipe@1, fun(D@1) -> {ok, 4.0 + D@1} end) + end, + H2 = case H1 of + {ok, V} -> + {ok, V * (1.0 / 6.0)}; + + _ -> + H1 + end, + H3 = case H2 of + {ok, V@1} when V@1 < 0.0 -> + V@1 + 1.0; + + {ok, V@2} -> + V@2; + + _ -> + 0.0 + end, + L = (Min_colour + Max_colour) / 2.0, + S = case true of + _ when Min_colour =:= Max_colour -> + 0.0; + + _ when L < 0.5 -> + case (Max_colour + Min_colour) of + 0.0 -> 0.0; + Gleam@denominator -> (Max_colour - Min_colour) / Gleam@denominator + end; + + _ -> + case ((2.0 - Max_colour) - Min_colour) of + 0.0 -> 0.0; + Gleam@denominator@1 -> (Max_colour - Min_colour) / Gleam@denominator@1 + end + end, + {H3, S, L, A}. + +-spec from_rgb255(integer(), integer(), integer()) -> {ok, colour()} | + {error, nil}. +from_rgb255(Red, Green, Blue) -> + gleam@result:then( + begin + _pipe = Red, + _pipe@1 = gleam@int:to_float(_pipe), + _pipe@2 = gleam@float:divide(_pipe@1, 255.0), + gleam@result:then(_pipe@2, fun valid_colour_value/1) + end, + fun(R) -> + gleam@result:then( + begin + _pipe@3 = Green, + _pipe@4 = gleam@int:to_float(_pipe@3), + _pipe@5 = gleam@float:divide(_pipe@4, 255.0), + gleam@result:then(_pipe@5, fun valid_colour_value/1) + end, + fun(G) -> + gleam@result:then( + begin + _pipe@6 = Blue, + _pipe@7 = gleam@int:to_float(_pipe@6), + _pipe@8 = gleam@float:divide(_pipe@7, 255.0), + gleam@result:then(_pipe@8, fun valid_colour_value/1) + end, + fun(B) -> + {ok, {rgba, R, G, B, 1.0}} + end + ) + end + ) + end + ). + +-spec from_rgb(float(), float(), float()) -> {ok, colour()} | {error, nil}. +from_rgb(Red, Green, Blue) -> + gleam@result:then( + valid_colour_value(Red), + fun(R) -> + gleam@result:then( + valid_colour_value(Green), + fun(G) -> + gleam@result:then( + valid_colour_value(Blue), + fun(B) -> + {ok, {rgba, R, G, B, 1.0}} + end + ) + end + ) + end + ). + +-spec from_rgba(float(), float(), float(), float()) -> {ok, colour()} | + {error, nil}. +from_rgba(Red, Green, Blue, Alpha) -> + gleam@result:then( + valid_colour_value(Red), + fun(R) -> + gleam@result:then( + valid_colour_value(Green), + fun(G) -> + gleam@result:then( + valid_colour_value(Blue), + fun(B) -> + gleam@result:then( + valid_colour_value(Alpha), + fun(A) -> + {ok, {rgba, R, G, B, A}} + end + ) + end + ) + end + ) + end + ). + +-spec from_hsla(float(), float(), float(), float()) -> {ok, colour()} | + {error, nil}. +from_hsla(Hue, Saturation, Lightness, Alpha) -> + gleam@result:then( + valid_colour_value(Hue), + fun(H) -> + gleam@result:then( + valid_colour_value(Saturation), + fun(S) -> + gleam@result:then( + valid_colour_value(Lightness), + fun(L) -> + gleam@result:then( + valid_colour_value(Alpha), + fun(A) -> + {ok, {hsla, H, S, L, A}} + end + ) + end + ) + end + ) + end + ). + +-spec from_hsl(float(), float(), float()) -> {ok, colour()} | {error, nil}. +from_hsl(Hue, Saturation, Lightness) -> + from_hsla(Hue, Saturation, Lightness, 1.0). + +-spec from_rgb_hex(integer()) -> {ok, colour()} | {error, nil}. +from_rgb_hex(Hex) -> + case (Hex > 16#ffffff) orelse (Hex < 0) of + true -> + {error, nil}; + + false -> + R = begin + _pipe = gleam@bitwise:shift_right(Hex, 16), + gleam@bitwise:'and'(_pipe, 16#ff) + end, + G = begin + _pipe@1 = gleam@bitwise:shift_right(Hex, 8), + gleam@bitwise:'and'(_pipe@1, 16#ff) + end, + B = gleam@bitwise:'and'(Hex, 16#ff), + from_rgb255(R, G, B) + end. + +-spec from_rgb_hex_string(binary()) -> {ok, colour()} | {error, nil}. +from_rgb_hex_string(Hex_string) -> + gleam@result:then( + hex_string_to_int(Hex_string), + fun(Hex_int) -> + from_rgb_hex(Hex_int) + end + ). + +-spec from_rgba_hex(integer()) -> {ok, colour()} | {error, nil}. +from_rgba_hex(Hex) -> + case (Hex > 16#ffffffff) orelse (Hex < 0) of + true -> + {error, nil}; + + false -> + _assert_subject = begin + _pipe = gleam@bitwise:shift_right(Hex, 24), + _pipe@1 = gleam@bitwise:'and'(_pipe, 16#ff), + _pipe@2 = gleam@int:to_float(_pipe@1), + gleam@float:divide(_pipe@2, 255.0) + end, + {ok, R} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 589}) + end, + _assert_subject@1 = begin + _pipe@3 = gleam@bitwise:shift_right(Hex, 16), + _pipe@4 = gleam@bitwise:'and'(_pipe@3, 16#ff), + _pipe@5 = gleam@int:to_float(_pipe@4), + gleam@float:divide(_pipe@5, 255.0) + end, + {ok, G} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 595}) + end, + _assert_subject@2 = begin + _pipe@6 = gleam@bitwise:shift_right(Hex, 8), + _pipe@7 = gleam@bitwise:'and'(_pipe@6, 16#ff), + _pipe@8 = gleam@int:to_float(_pipe@7), + gleam@float:divide(_pipe@8, 255.0) + end, + {ok, B} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 601}) + end, + _assert_subject@3 = begin + _pipe@9 = gleam@bitwise:'and'(Hex, 16#ff), + _pipe@10 = gleam@int:to_float(_pipe@9), + gleam@float:divide(_pipe@10, 255.0) + end, + {ok, A} = case _assert_subject@3 of + {ok, _} -> _assert_subject@3; + _assert_fail@3 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 607}) + end, + from_rgba(R, G, B, A) + end. + +-spec from_rgba_hex_string(binary()) -> {ok, colour()} | {error, nil}. +from_rgba_hex_string(Hex_string) -> + gleam@result:then( + hex_string_to_int(Hex_string), + fun(Hex_int) -> + from_rgba_hex(Hex_int) + end + ). + +-spec to_rgba(colour()) -> {float(), float(), float(), float()}. +to_rgba(Colour) -> + case Colour of + {rgba, R, G, B, A} -> + {R, G, B, A}; + + {hsla, H, S, L, A@1} -> + hsla_to_rgba(H, S, L, A@1) + end. + +-spec to_hsla(colour()) -> {float(), float(), float(), float()}. +to_hsla(Colour) -> + case Colour of + {hsla, H, S, L, A} -> + {H, S, L, A}; + + {rgba, R, G, B, A@1} -> + rgba_to_hsla(R, G, B, A@1) + end. + +-spec to_css_rgba_string(colour()) -> binary(). +to_css_rgba_string(Colour) -> + {R, G, B, A} = to_rgba(Colour), + Percent = fun(X) -> + _assert_subject = begin + _pipe = X, + _pipe@1 = gleam@float:multiply(_pipe, 10000.0), + _pipe@2 = gleam@float:round(_pipe@1), + _pipe@3 = gleam@int:to_float(_pipe@2), + gleam@float:divide(_pipe@3, 100.0) + end, + {ok, P} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam_community/colour"/utf8>>, + function => <<"to_css_rgba_string"/utf8>>, + line => 705}) + end, + P + end, + Round_to = fun(X@1) -> + _assert_subject@1 = begin + _pipe@4 = X@1, + _pipe@5 = gleam@float:multiply(_pipe@4, 1000.0), + _pipe@6 = gleam@float:round(_pipe@5), + _pipe@7 = gleam@int:to_float(_pipe@6), + gleam@float:divide(_pipe@7, 1000.0) + end, + {ok, R@1} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"gleam_community/colour"/utf8>>, + function => <<"to_css_rgba_string"/utf8>>, + line => 717}) + end, + R@1 + end, + gleam@string:join( + [<<"rgba("/utf8>>, + <<(gleam@float:to_string(Percent(R)))/binary, "%,"/utf8>>, + <<(gleam@float:to_string(Percent(G)))/binary, "%,"/utf8>>, + <<(gleam@float:to_string(Percent(B)))/binary, "%,"/utf8>>, + gleam@float:to_string(Round_to(A)), + <<")"/utf8>>], + <<""/utf8>> + ). + +-spec to_rgba_hex(colour()) -> integer(). +to_rgba_hex(Colour) -> + {R, G, B, A} = to_rgba(Colour), + Red = begin + _pipe = R * 255.0, + _pipe@1 = gleam@float:round(_pipe), + gleam@bitwise:shift_left(_pipe@1, 24) + end, + Green = begin + _pipe@2 = G * 255.0, + _pipe@3 = gleam@float:round(_pipe@2), + gleam@bitwise:shift_left(_pipe@3, 16) + end, + Blue = begin + _pipe@4 = B * 255.0, + _pipe@5 = gleam@float:round(_pipe@4), + gleam@bitwise:shift_left(_pipe@5, 8) + end, + Alpha = begin + _pipe@6 = A * 255.0, + gleam@float:round(_pipe@6) + end, + ((Red + Green) + Blue) + Alpha. + +-spec to_rgba_hex_string(colour()) -> binary(). +to_rgba_hex_string(Colour) -> + _pipe = to_rgba_hex(Colour), + gleam@int:to_base16(_pipe). + +-spec to_rgb_hex(colour()) -> integer(). +to_rgb_hex(Colour) -> + {R, G, B, _} = to_rgba(Colour), + Red = begin + _pipe = R * 255.0, + _pipe@1 = gleam@float:round(_pipe), + gleam@bitwise:shift_left(_pipe@1, 16) + end, + Green = begin + _pipe@2 = G * 255.0, + _pipe@3 = gleam@float:round(_pipe@2), + gleam@bitwise:shift_left(_pipe@3, 8) + end, + Blue = begin + _pipe@4 = B * 255.0, + gleam@float:round(_pipe@4) + end, + (Red + Green) + Blue. + +-spec to_rgb_hex_string(colour()) -> binary(). +to_rgb_hex_string(Colour) -> + _pipe = to_rgb_hex(Colour), + gleam@int:to_base16(_pipe). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl new file mode 100644 index 00000000000..cacebf288c5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl @@ -0,0 +1,75 @@ +-module(gleam_community@colour@accessibility). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([luminance/1, contrast_ratio/2, maximum_contrast/2]). + +-spec intensity(float()) -> float(). +intensity(Colour_value) -> + case true of + _ when Colour_value =< 0.03928 -> + Colour_value / 12.92; + + _ -> + _assert_subject = gleam@float:power( + (Colour_value + + 0.055) + / 1.055, + 2.4 + ), + {ok, I} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam_community/colour/accessibility"/utf8>>, + function => <<"intensity"/utf8>>, + line => 62}) + end, + I + end. + +-spec luminance(gleam_community@colour:colour()) -> float(). +luminance(Colour) -> + {R, G, B, _} = gleam_community@colour:to_rgba(Colour), + R_intensity = intensity(R), + G_intensity = intensity(G), + B_intensity = intensity(B), + ((0.2126 * R_intensity) + (0.7152 * G_intensity)) + (0.0722 * B_intensity). + +-spec contrast_ratio( + gleam_community@colour:colour(), + gleam_community@colour:colour() +) -> float(). +contrast_ratio(Colour_a, Colour_b) -> + Luminance_a = luminance(Colour_a) + 0.05, + Luminance_b = luminance(Colour_b) + 0.05, + case Luminance_a > Luminance_b of + true -> + case Luminance_b of + 0.0 -> 0.0; + Gleam@denominator -> Luminance_a / Gleam@denominator + end; + + false -> + case Luminance_a of + 0.0 -> 0.0; + Gleam@denominator@1 -> Luminance_b / Gleam@denominator@1 + end + end. + +-spec maximum_contrast( + gleam_community@colour:colour(), + list(gleam_community@colour:colour()) +) -> {ok, gleam_community@colour:colour()} | {error, nil}. +maximum_contrast(Base, Colours) -> + _pipe = Colours, + _pipe@1 = gleam@list:sort( + _pipe, + fun(Colour_a, Colour_b) -> + Contrast_a = contrast_ratio(Base, Colour_a), + Contrast_b = contrast_ratio(Base, Colour_b), + gleam@float:compare(Contrast_b, Contrast_a) + end + ), + gleam@list:first(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src new file mode 100644 index 00000000000..4755b196289 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src @@ -0,0 +1,10 @@ +{application, gleam_community_colour, [ + {vsn, "1.1.0"}, + {applications, [gleam_bitwise, + gleam_stdlib, + gleeunit]}, + {description, "Colour types, conversions, and other utilities"}, + {modules, [gleam_community@colour, + gleam_community@colour@accessibility]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/LICENSE b/test-community-packages-javascript/build/packages/gleam_cors/LICENSE new file mode 100644 index 00000000000..728cade93fb --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_cors/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Filip Figiel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/README.md b/test-community-packages-javascript/build/packages/gleam_cors/README.md new file mode 100644 index 00000000000..d753b8da638 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_cors/README.md @@ -0,0 +1,38 @@ +# gleam_cors + +[![Package Version](https://img.shields.io/hexpm/v/gleam_cors)](https://hex.pm/packages/gleam_cors) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_cors/) + +Unofficial CORS middleware for the [`gleam_http`](https://hexdocs.pm/gleam_http/index.html) library. + +## Installation + +```sh +gleam add gleam_cors +``` + +## Usage + +Use the `middleware` function to set up CORS for your application. This middleware should be +placed early in your middleware stack (late in the pipeline). + +```diff ++import gleam/http/cors ++import gleam/http + import myproject/web/middleware + + pub fn stack() { + service + |> middleware.rescue + |> middleware.log ++ |> cors.middleware( ++ origins: ["http://localhost:8000"], ++ methods: [http.Get, http.Post, http.Delete], ++ headers: ["Authorization", "Content-Type"], ++ ) + } +``` + +## Changelog + +See [CHANGELOG.md](CHANGELOG.md) in the project repository diff --git a/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml b/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml new file mode 100644 index 00000000000..c6861872847 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml @@ -0,0 +1,13 @@ +name = "gleam_cors" +version = "0.2.0" + +licences = ["MIT"] +description = "A CORS middleware for Gleam" +repository = { type = "github", user = "megapctr", repo = "gleam_cors" } + +[dependencies] +gleam_stdlib = "~> 0.29" +gleam_http = "~> 3.2" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam new file mode 100644 index 00000000000..42a869b6441 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam @@ -0,0 +1,227 @@ +import gleam/http.{Method, Options} +import gleam/http/request.{Request} +import gleam/http/response +import gleam/http/service.{Middleware} +import gleam/bit_builder.{BitBuilder} +import gleam/result.{try} +import gleam/list +import gleam/set.{Set} +import gleam/function +import gleam/string + +type Config { + Config( + allowed_origins: AllowedOrigins, + allowed_methods: AllowedMethods, + allowed_headers: AllowedHeaders, + ) +} + +type AllowedOrigins { + AllowAll + AllowSome(Set(String)) +} + +type AllowedMethods = + Set(Method) + +type AllowedHeaders = + Set(String) + +const allow_origin_header = "Access-Control-Allow-Origin" + +const allow_all_origins = "*" + +const request_method_header = "Access-Control-Request-Method" + +const request_headers_header = "Access-Control-Request-Headers" + +const allow_headers_header = "Access-Control-Allow-Headers" + +fn parse_config( + allowed_origins: List(String), + allowed_methods: List(Method), + allowed_headers: List(String), +) -> Result(Config, Nil) { + use allowed_origins <- try(parse_allowed_origins(allowed_origins)) + use allowed_methods <- try(parse_allowed_methods(allowed_methods)) + use allowed_headers <- try(parse_allowed_headers(allowed_headers)) + Config(allowed_origins, allowed_methods, allowed_headers) + |> Ok +} + +fn parse_allowed_origins(l: List(String)) -> Result(AllowedOrigins, Nil) { + case list.contains(l, allow_all_origins), l { + True, _ -> Ok(AllowAll) + _, origins -> { + let origins_set = + origins + |> list.map(string.lowercase) + |> set.from_list + // `handler` relies on "" not being in the set, "" is not a valid origin anyway + |> set.delete("") + case set.size(origins_set) { + 0 -> Error(Nil) + _ -> + AllowSome(origins_set) + |> Ok + } + } + } +} + +fn parse_allowed_methods(l: List(Method)) -> Result(AllowedMethods, Nil) { + let methods_set = set.from_list(l) + case set.size(methods_set) { + 0 -> Error(Nil) + _ -> Ok(methods_set) + } +} + +fn parse_allowed_headers(l: List(String)) -> Result(AllowedHeaders, Nil) { + let headers_set = + l + |> list.map(string.lowercase) + |> set.from_list + Ok(headers_set) +} + +type Response = + response.Response(BitBuilder) + +/// A middleware that adds CORS headers to responses based on the given configuration. +/// +/// ## Examples +/// +/// service +/// |> cors.middleware( +/// origins: ["https://staging.example.com", "http://localhost:8000"], +/// methods: [Get, Post, Delete], +/// headers: ["Authorization", "Content-Type"], +/// ) +pub fn middleware( + origins allowed_origins: List(String), + methods allowed_methods: List(Method), + headers allowed_headers: List(String), +) -> Middleware(a, BitBuilder, a, BitBuilder) { + case parse_config(allowed_origins, allowed_methods, allowed_headers) { + Ok(config) -> middleware_from_config(config) + Error(_) -> function.identity + } +} + +fn middleware_from_config( + config: Config, +) -> Middleware(a, BitBuilder, a, BitBuilder) { + fn(service) { + fn(request: Request(a)) -> Response { + case request.method { + Options -> handle_options_request(request, config) + _ -> handle_other_request(service, request, config.allowed_origins) + } + } + } +} + +/// For OPTIONS requests, we must check if request origin, request method and request headers are +/// allowed, and include CORS headers for allowed origin and allowed headers. +fn handle_options_request(request: Request(a), config: Config) -> Response { + let response = + response.new(200) + |> response.set_body(bit_builder.new()) + + let origin = get_origin(request) + + let ac_request_method = + request.get_header(request, request_method_header) + |> result.then(http.parse_method) + |> result.unwrap(http.Other("")) + + let ac_request_headers = + request.get_header(request, request_headers_header) + |> result.map(string.split(_, ", ")) + |> result.unwrap([]) + + let is_request_allowed = + is_origin_allowed(origin, config.allowed_origins) && is_method_allowed( + ac_request_method, + config.allowed_methods, + ) && are_headers_allowed(ac_request_headers, config.allowed_headers) + case is_request_allowed { + True -> + response + |> prepend_allow_origin_header(origin, config.allowed_origins) + |> prepend_allow_headers_header(ac_request_headers) + False -> response + } +} + +/// For other requests, if the request Origin header matches allowed origins, we must include the CORS header for allowed origin. +fn handle_other_request( + service, + request: Request(a), + allowed_origins: AllowedOrigins, +) -> Response { + let origin = get_origin(request) + let response = service(request) + case is_origin_allowed(origin, allowed_origins) { + True -> + response + |> prepend_allow_origin_header(origin, allowed_origins) + False -> response + } +} + +fn get_origin(request: Request(a)) -> String { + request.get_header(request, "origin") + |> result.unwrap("") +} + +fn is_origin_allowed(origin: String, allowed_origins: AllowedOrigins) -> Bool { + case allowed_origins { + AllowAll -> True + AllowSome(origins) -> set.contains(origins, string.lowercase(origin)) + } +} + +fn is_method_allowed(method: Method, allowed_methods: AllowedMethods) -> Bool { + set.contains(allowed_methods, method) +} + +fn are_headers_allowed( + request_headers: List(String), + allowed_headers: AllowedHeaders, +) -> Bool { + list.all( + request_headers, + fn(header) { set.contains(allowed_headers, string.lowercase(header)) }, + ) +} + +fn prepend_allow_origin_header( + response: Response, + origin: String, + allowed_origins: AllowedOrigins, +) -> Response { + case allowed_origins { + AllowAll -> + response + |> response.prepend_header(allow_origin_header, allow_all_origins) + AllowSome(_) -> + response + |> response.prepend_header(allow_origin_header, origin) + |> response.prepend_header("Vary", "Origin") + } +} + +fn prepend_allow_headers_header( + response: Response, + headers: List(String), +) -> Response { + case list.length(headers) { + 0 -> response + _ -> + string.join(headers, ", ") + |> response.prepend_header(response, allow_headers_header, _) + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl new file mode 100644 index 00000000000..0f9d5b47cd9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl @@ -0,0 +1,243 @@ +-module(gleam@http@cors). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([middleware/3]). +-export_type([config/0, allowed_origins/0]). + +-type config() :: {config, + allowed_origins(), + gleam@set:set(gleam@http:method()), + gleam@set:set(binary())}. + +-type allowed_origins() :: allow_all | {allow_some, gleam@set:set(binary())}. + +-spec parse_allowed_origins(list(binary())) -> {ok, allowed_origins()} | + {error, nil}. +parse_allowed_origins(L) -> + case {gleam@list:contains(L, <<"*"/utf8>>), L} of + {true, _} -> + {ok, allow_all}; + + {_, Origins} -> + Origins_set = begin + _pipe = Origins, + _pipe@1 = gleam@list:map(_pipe, fun gleam@string:lowercase/1), + _pipe@2 = gleam@set:from_list(_pipe@1), + gleam@set:delete(_pipe@2, <<""/utf8>>) + end, + case gleam@set:size(Origins_set) of + 0 -> + {error, nil}; + + _ -> + _pipe@3 = {allow_some, Origins_set}, + {ok, _pipe@3} + end + end. + +-spec parse_allowed_methods(list(gleam@http:method())) -> {ok, + gleam@set:set(gleam@http:method())} | + {error, nil}. +parse_allowed_methods(L) -> + Methods_set = gleam@set:from_list(L), + case gleam@set:size(Methods_set) of + 0 -> + {error, nil}; + + _ -> + {ok, Methods_set} + end. + +-spec parse_allowed_headers(list(binary())) -> {ok, gleam@set:set(binary())} | + {error, nil}. +parse_allowed_headers(L) -> + Headers_set = begin + _pipe = L, + _pipe@1 = gleam@list:map(_pipe, fun gleam@string:lowercase/1), + gleam@set:from_list(_pipe@1) + end, + {ok, Headers_set}. + +-spec parse_config(list(binary()), list(gleam@http:method()), list(binary())) -> {ok, + config()} | + {error, nil}. +parse_config(Allowed_origins, Allowed_methods, Allowed_headers) -> + gleam@result:'try'( + parse_allowed_origins(Allowed_origins), + fun(Allowed_origins@1) -> + gleam@result:'try'( + parse_allowed_methods(Allowed_methods), + fun(Allowed_methods@1) -> + gleam@result:'try'( + parse_allowed_headers(Allowed_headers), + fun(Allowed_headers@1) -> + _pipe = {config, + Allowed_origins@1, + Allowed_methods@1, + Allowed_headers@1}, + {ok, _pipe} + end + ) + end + ) + end + ). + +-spec get_origin(gleam@http@request:request(any())) -> binary(). +get_origin(Request) -> + _pipe = gleam@http@request:get_header(Request, <<"origin"/utf8>>), + gleam@result:unwrap(_pipe, <<""/utf8>>). + +-spec is_origin_allowed(binary(), allowed_origins()) -> boolean(). +is_origin_allowed(Origin, Allowed_origins) -> + case Allowed_origins of + allow_all -> + true; + + {allow_some, Origins} -> + gleam@set:contains(Origins, gleam@string:lowercase(Origin)) + end. + +-spec is_method_allowed(gleam@http:method(), gleam@set:set(gleam@http:method())) -> boolean(). +is_method_allowed(Method, Allowed_methods) -> + gleam@set:contains(Allowed_methods, Method). + +-spec are_headers_allowed(list(binary()), gleam@set:set(binary())) -> boolean(). +are_headers_allowed(Request_headers, Allowed_headers) -> + gleam@list:all( + Request_headers, + fun(Header) -> + gleam@set:contains(Allowed_headers, gleam@string:lowercase(Header)) + end + ). + +-spec prepend_allow_origin_header( + gleam@http@response:response(gleam@bit_builder:bit_builder()), + binary(), + allowed_origins() +) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). +prepend_allow_origin_header(Response, Origin, Allowed_origins) -> + case Allowed_origins of + allow_all -> + _pipe = Response, + gleam@http@response:prepend_header( + _pipe, + <<"Access-Control-Allow-Origin"/utf8>>, + <<"*"/utf8>> + ); + + {allow_some, _} -> + _pipe@1 = Response, + _pipe@2 = gleam@http@response:prepend_header( + _pipe@1, + <<"Access-Control-Allow-Origin"/utf8>>, + Origin + ), + gleam@http@response:prepend_header( + _pipe@2, + <<"Vary"/utf8>>, + <<"Origin"/utf8>> + ) + end. + +-spec handle_other_request( + fun((gleam@http@request:request(FTP)) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), + gleam@http@request:request(FTP), + allowed_origins() +) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). +handle_other_request(Service, Request, Allowed_origins) -> + Origin = get_origin(Request), + Response = Service(Request), + case is_origin_allowed(Origin, Allowed_origins) of + true -> + _pipe = Response, + prepend_allow_origin_header(_pipe, Origin, Allowed_origins); + + false -> + Response + end. + +-spec prepend_allow_headers_header( + gleam@http@response:response(gleam@bit_builder:bit_builder()), + list(binary()) +) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). +prepend_allow_headers_header(Response, Headers) -> + case gleam@list:length(Headers) of + 0 -> + Response; + + _ -> + _pipe = gleam@string:join(Headers, <<", "/utf8>>), + gleam@http@response:prepend_header( + Response, + <<"Access-Control-Allow-Headers"/utf8>>, + _pipe + ) + end. + +-spec handle_options_request(gleam@http@request:request(any()), config()) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). +handle_options_request(Request, Config) -> + Response = begin + _pipe = gleam@http@response:new(200), + gleam@http@response:set_body(_pipe, gleam@bit_builder:new()) + end, + Origin = get_origin(Request), + Ac_request_method = begin + _pipe@1 = gleam@http@request:get_header( + Request, + <<"Access-Control-Request-Method"/utf8>> + ), + _pipe@2 = gleam@result:then(_pipe@1, fun gleam@http:parse_method/1), + gleam@result:unwrap(_pipe@2, {other, <<""/utf8>>}) + end, + Ac_request_headers = begin + _pipe@3 = gleam@http@request:get_header( + Request, + <<"Access-Control-Request-Headers"/utf8>> + ), + _pipe@4 = gleam@result:map( + _pipe@3, + fun(_capture) -> gleam@string:split(_capture, <<", "/utf8>>) end + ), + gleam@result:unwrap(_pipe@4, []) + end, + Is_request_allowed = (is_origin_allowed(Origin, erlang:element(2, Config)) + andalso is_method_allowed(Ac_request_method, erlang:element(3, Config))) + andalso are_headers_allowed(Ac_request_headers, erlang:element(4, Config)), + case Is_request_allowed of + true -> + _pipe@5 = Response, + _pipe@6 = prepend_allow_origin_header( + _pipe@5, + Origin, + erlang:element(2, Config) + ), + prepend_allow_headers_header(_pipe@6, Ac_request_headers); + + false -> + Response + end. + +-spec middleware_from_config(config()) -> fun((fun((gleam@http@request:request(FTH)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))) -> fun((gleam@http@request:request(FTH)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))). +middleware_from_config(Config) -> + fun(Service) -> fun(Request) -> case erlang:element(2, Request) of + options -> + handle_options_request(Request, Config); + + _ -> + handle_other_request( + Service, + Request, + erlang:element(2, Config) + ) + end end end. + +-spec middleware(list(binary()), list(gleam@http:method()), list(binary())) -> fun((fun((gleam@http@request:request(FTC)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))) -> fun((gleam@http@request:request(FTC)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))). +middleware(Allowed_origins, Allowed_methods, Allowed_headers) -> + case parse_config(Allowed_origins, Allowed_methods, Allowed_headers) of + {ok, Config} -> + middleware_from_config(Config); + + {error, _} -> + fun gleam@function:identity/1 + end. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src new file mode 100644 index 00000000000..3a52ceb19fa --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src @@ -0,0 +1,9 @@ +{application, gleam_cors, [ + {vsn, "0.2.0"}, + {applications, [gleam_http, + gleam_stdlib, + gleeunit]}, + {description, "A CORS middleware for Gleam"}, + {modules, [gleam@http@cors]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE b/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE new file mode 100644 index 00000000000..59e1345ab47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/README.md b/test-community-packages-javascript/build/packages/gleam_crypto/README.md new file mode 100644 index 00000000000..c499e15941c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_crypto/README.md @@ -0,0 +1,13 @@ +# crypto + +GitHub release +Discord chat +![CI](https://github.com/gleam-experiments/crypto/workflows/test/badge.svg?branch=main) + +Gleam bindings to the BEAM cryptography functions. + +## Installation + +``` +gleam add gleam_crypto +``` diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml b/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml new file mode 100644 index 00000000000..b5fec372ee5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml @@ -0,0 +1,17 @@ +name = "gleam_crypto" +version = "0.3.1" +licences = ["Apache-2.0"] +description = "Gleam bindings to the BEAM cryptography functions" + +repository = { type = "github", user = "gleam-experiments", repo = "crypto" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[dependencies] +gleam_stdlib = "~> 0.19" +gleam_bitwise = "~> 1.1" + +[dev-dependencies] +gleeunit = "~> 0.5" diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam new file mode 100644 index 00000000000..94223390f0c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam @@ -0,0 +1,135 @@ +//// Set of cryptographic functions. + +import gleam/bit_string +import gleam/bitwise +import gleam/string +import gleam/base +import gleam/result + +/// Generates N bytes randomly uniform 0..255, and returns the result in a binary. +/// +/// Uses a cryptographically secure prng seeded and periodically mixed with +/// operating system provided entropy. +/// By default this is the RAND_bytes method from OpenSSL. +/// +/// https://erlang.org/doc/man/crypto.html#strong_rand_bytes-1 +pub external fn strong_random_bytes(Int) -> BitString = + "crypto" "strong_rand_bytes" + +pub type HashAlgorithm { + Sha224 + Sha256 + Sha384 + Sha512 +} + +/// Computes a digest of the input bit string. +pub external fn hash(HashAlgorithm, BitString) -> BitString = + "crypto" "hash" + +type Hmac { + Hmac +} + +external fn erl_hmac(Hmac, HashAlgorithm, BitString, BitString) -> BitString = + "crypto" "mac" + +/// Calculates the HMAC (hash-based message authentication code) for a bit +/// string. +/// +/// Based on the Erlang [`crypto:mac`](https://www.erlang.org/doc/man/crypto.html#mac-4) +/// function. +/// +pub fn hmac(data: BitString, algorithm: HashAlgorithm, key: BitString) { + erl_hmac(Hmac, algorithm, key, data) +} + +fn do_secure_compare( + left: BitString, + right: BitString, + accumulator: Int, +) -> Bool { + case left, right { + <>, <> -> { + let accumulator = bitwise.or(accumulator, bitwise.exclusive_or(x, y)) + do_secure_compare(left, right, accumulator) + } + <<>>, <<>> -> accumulator == 0 + } +} + +/// Compares the two binaries in constant-time to avoid timing attacks. +/// +/// For more details see: http://codahale.com/a-lesson-in-timing-attacks/ +/// +pub fn secure_compare(left: BitString, right: BitString) -> Bool { + case bit_string.byte_size(left) == bit_string.byte_size(right) { + True -> do_secure_compare(left, right, 0) + False -> False + } +} + +// Based off of https://github.com/elixir-plug/plug_crypto/blob/v1.2.1/lib/plug/crypto/message_verifier.ex#L1 +// +/// Sign a message which can later be verified using the `verify_signed_message` +/// function to detect if the message has been tampered with. +/// +/// A web application could use this verifier to sign HTTP cookies. The data can +/// be read by the user, but cannot be tampered with. +/// +pub fn sign_message( + message: BitString, + secret: BitString, + digest_type: HashAlgorithm, +) -> String { + let input = signing_input(digest_type, message) + let signature = hmac(<>, digest_type, secret) + + string.concat([input, ".", base.url_encode64(signature, False)]) +} + +fn signing_input(digest_type: HashAlgorithm, message: BitString) -> String { + let protected = case digest_type { + Sha224 -> "HS224" + Sha256 -> "HS256" + Sha384 -> "HS384" + Sha512 -> "HS512" + } + string.concat([ + base.url_encode64(<>, False), + ".", + base.url_encode64(message, False), + ]) +} + +// Based off of https://github.com/elixir-plug/plug_crypto/blob/v1.2.1/lib/plug/crypto/message_verifier.ex#L1 +// +/// Verify a message created by the `sign_message` function. +/// +pub fn verify_signed_message( + message: String, + secret: BitString, +) -> Result(BitString, Nil) { + use #(protected, payload, signature) <- result.then(case + string.split(message, on: ".") + { + [a, b, c] -> Ok(#(a, b, c)) + _ -> Error(Nil) + }) + let text = string.concat([protected, ".", payload]) + use payload <- result.then(base.url_decode64(payload)) + use signature <- result.then(base.url_decode64(signature)) + use protected <- result.then(base.url_decode64(protected)) + use digest_type <- result.then(case protected { + <<"HS224":utf8>> -> Ok(Sha224) + <<"HS256":utf8>> -> Ok(Sha256) + <<"HS384":utf8>> -> Ok(Sha384) + <<"HS512":utf8>> -> Ok(Sha512) + _ -> Error(Nil) + }) + let challenge = hmac(<>, digest_type, secret) + case secure_compare(challenge, signature) { + True -> Ok(payload) + False -> Error(Nil) + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl new file mode 100644 index 00000000000..b3b97bcf73d --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl @@ -0,0 +1,135 @@ +-module(gleam@crypto). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([strong_random_bytes/1, hash/2, hmac/3, sign_message/3, secure_compare/2, verify_signed_message/2]). +-export_type([hash_algorithm/0, hmac/0]). + +-type hash_algorithm() :: sha224 | sha256 | sha384 | sha512. + +-type hmac() :: hmac. + +-spec signing_input(hash_algorithm(), bitstring()) -> binary(). +signing_input(Digest_type, Message) -> + Protected = case Digest_type of + sha224 -> + <<"HS224"/utf8>>; + + sha256 -> + <<"HS256"/utf8>>; + + sha384 -> + <<"HS384"/utf8>>; + + sha512 -> + <<"HS512"/utf8>> + end, + gleam@string:concat( + [gleam@base:url_encode64(<>, false), + <<"."/utf8>>, + gleam@base:url_encode64(Message, false)] + ). + +-spec strong_random_bytes(integer()) -> bitstring(). +strong_random_bytes(Field@0) -> + crypto:strong_rand_bytes(Field@0). + +-spec hash(hash_algorithm(), bitstring()) -> bitstring(). +hash(Field@0, Field@1) -> + crypto:hash(Field@0, Field@1). + +-spec hmac(bitstring(), hash_algorithm(), bitstring()) -> bitstring(). +hmac(Data, Algorithm, Key) -> + crypto:mac(hmac, Algorithm, Key, Data). + +-spec sign_message(bitstring(), bitstring(), hash_algorithm()) -> binary(). +sign_message(Message, Secret, Digest_type) -> + Input = signing_input(Digest_type, Message), + Signature = hmac(<>, Digest_type, Secret), + gleam@string:concat( + [Input, <<"."/utf8>>, gleam@base:url_encode64(Signature, false)] + ). + +-spec do_secure_compare(bitstring(), bitstring(), integer()) -> boolean(). +do_secure_compare(Left, Right, Accumulator) -> + case {Left, Right} of + {<>, <>} -> + Accumulator@1 = gleam@bitwise:'or'( + Accumulator, + gleam@bitwise:exclusive_or(X, Y) + ), + do_secure_compare(Left@1, Right@1, Accumulator@1); + + {<<>>, <<>>} -> + Accumulator =:= 0 + end. + +-spec secure_compare(bitstring(), bitstring()) -> boolean(). +secure_compare(Left, Right) -> + case gleam@bit_string:byte_size(Left) =:= gleam@bit_string:byte_size(Right) of + true -> + do_secure_compare(Left, Right, 0); + + false -> + false + end. + +-spec verify_signed_message(binary(), bitstring()) -> {ok, bitstring()} | + {error, nil}. +verify_signed_message(Message, Secret) -> + gleam@result:then(case gleam@string:split(Message, <<"."/utf8>>) of + [A, B, C] -> + {ok, {A, B, C}}; + + _ -> + {error, nil} + end, fun(_use0) -> + {Protected, Payload, Signature} = _use0, + Text = gleam@string:concat([Protected, <<"."/utf8>>, Payload]), + gleam@result:then( + gleam@base:url_decode64(Payload), + fun(Payload@1) -> + gleam@result:then( + gleam@base:url_decode64(Signature), + fun(Signature@1) -> + gleam@result:then( + gleam@base:url_decode64(Protected), + fun(Protected@1) -> + gleam@result:then(case Protected@1 of + <<"HS224"/utf8>> -> + {ok, sha224}; + + <<"HS256"/utf8>> -> + {ok, sha256}; + + <<"HS384"/utf8>> -> + {ok, sha384}; + + <<"HS512"/utf8>> -> + {ok, sha512}; + + _ -> + {error, nil} + end, fun(Digest_type) -> + Challenge = hmac( + <>, + Digest_type, + Secret + ), + case secure_compare( + Challenge, + Signature@1 + ) of + true -> + {ok, Payload@1}; + + false -> + {error, nil} + end + end) + end + ) + end + ) + end + ) + end). diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src new file mode 100644 index 00000000000..f62b69f0512 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src @@ -0,0 +1,9 @@ +{application, gleam_crypto, [ + {vsn, "0.3.1"}, + {applications, [gleam_bitwise, + gleam_stdlib, + gleeunit]}, + {description, "Gleam bindings to the BEAM cryptography functions"}, + {modules, [gleam@crypto]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE b/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE new file mode 100644 index 00000000000..59e1345ab47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/README.md b/test-community-packages-javascript/build/packages/gleam_erlang/README.md new file mode 100644 index 00000000000..e91ad24d748 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/README.md @@ -0,0 +1,34 @@ +# Gleam Erlang 🐙 + +A library for making use of Erlang specific code! + +## Features + +- Typed Erlang processes and message sending. +- Erlang binary format (de)serialisation. +- Functions for working with Erlang's charlists. +- Reading, writing, and deletion of files. + +## Usage + +Add this library to your Gleam project + +```shell +gleam add gleam_erlang +``` + +And then use it in your code + +```gleam +import gleam/io +import gleam/erlang/file + +pub fn main() { + assert Ok(contents) = file.read("pokedex.txt") + io.println(contents) +} +``` + +Documentation can be found at . + +This library requires OTP 23.0 or higher. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml b/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml new file mode 100644 index 00000000000..8f978f6781a --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml @@ -0,0 +1,17 @@ +name = "gleam_erlang" + +version = "0.19.0" +licences = ["Apache-2.0"] +description = "A Gleam library for working with Erlang" + +repository = { type = "github", user = "gleam-lang", repo = "erlang" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[dependencies] +gleam_stdlib = "~> 0.27" + +[dev-dependencies] +gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl new file mode 100644 index 00000000000..b38d11e0f65 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl @@ -0,0 +1,15 @@ +-record(file_info, { + size :: integer(), + file_type :: gleam@erlang@file:file_type(), + access :: gleam@erlang@file:access(), + atime :: integer(), + mtime :: integer(), + ctime :: integer(), + mode :: integer(), + links :: integer(), + major_device :: integer(), + minor_device :: integer(), + inode :: integer(), + user_id :: integer(), + group_id :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl new file mode 100644 index 00000000000..4cd04529eb4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl @@ -0,0 +1 @@ +-record(abnormal, {reason :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl new file mode 100644 index 00000000000..7fe79877634 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl @@ -0,0 +1 @@ +-record(callee_down, {reason :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl new file mode 100644 index 00000000000..b82b49fc597 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl @@ -0,0 +1 @@ +-record(cancelled, {time_remaining :: integer()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl new file mode 100644 index 00000000000..c476308c591 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl @@ -0,0 +1,4 @@ +-record(exit_message, { + pid :: gleam@erlang@process:pid_(), + reason :: gleam@erlang@process:exit_reason() +}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl new file mode 100644 index 00000000000..8c75d5913d8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl @@ -0,0 +1,4 @@ +-record(process_down, { + pid :: gleam@erlang@process:pid_(), + reason :: gleam@dynamic:dynamic() +}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl new file mode 100644 index 00000000000..ce552e209e6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl @@ -0,0 +1 @@ +-record(process_monitor, {tag :: gleam@erlang:reference_()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl new file mode 100644 index 00000000000..abc46b2ecd4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl @@ -0,0 +1,4 @@ +-record(subject, { + owner :: gleam@erlang@process:pid_(), + tag :: gleam@erlang:reference_() +}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl new file mode 100644 index 00000000000..aeba26d8240 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl @@ -0,0 +1,4 @@ +-record(application_failed_to_start, { + name :: gleam@erlang@atom:atom_(), + reason :: gleam@dynamic:dynamic() +}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl new file mode 100644 index 00000000000..fde3c61706e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl @@ -0,0 +1 @@ +-record(unknown_application, {name :: gleam@erlang@atom:atom_()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam new file mode 100644 index 00000000000..7720a71c616 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam @@ -0,0 +1,143 @@ +import gleam/dynamic.{Dynamic} +import gleam/list +import gleam/erlang/atom.{Atom} +import gleam/erlang/charlist.{Charlist} + +external fn erl_format(String, List(a)) -> Charlist = + "io_lib" "format" + +/// Return a string representation of any term +pub fn format(term: any) -> String { + charlist.to_string(erl_format("~p", [term])) +} + +pub external fn term_to_binary(a) -> BitString = + "erlang" "term_to_binary" + +type Safe { + Safe +} + +external fn erl_binary_to_term(BitString, List(Safe)) -> Dynamic = + "erlang" "binary_to_term" + +pub fn binary_to_term(binary: BitString) -> Result(Dynamic, Nil) { + case rescue(fn() { erl_binary_to_term(binary, [Safe]) }) { + Ok(term) -> Ok(term) + Error(_) -> Error(Nil) + } +} + +pub fn unsafe_binary_to_term(binary: BitString) -> Result(Dynamic, Nil) { + case rescue(fn() { erl_binary_to_term(binary, []) }) { + Ok(term) -> Ok(term) + Error(_) -> Error(Nil) + } +} + +/// Error value returned by `get_line` function +/// +pub type GetLineError { + Eof + NoData +} + +/// Reads a line from standard input with the given prompt. +/// +/// # Example +/// +/// > get_line("Language: ") +/// // -> Language: <- gleam +/// Ok("gleam\n") +/// +pub external fn get_line(prompt: String) -> Result(String, GetLineError) = + "gleam_erlang_ffi" "get_line" + +pub type TimeUnit { + Second + Millisecond + Microsecond + Nanosecond +} + +/// Returns the current OS system time. +/// +/// +pub external fn system_time(TimeUnit) -> Int = + "os" "system_time" + +/// Returns the current OS system time as a tuple of Ints +/// +/// http://erlang.org/doc/man/os.html#timestamp-0 +pub external fn erlang_timestamp() -> #(Int, Int, Int) = + "os" "timestamp" + +/// Gleam doesn't offer any way to raise exceptions, but they may still occur +/// due to bugs when working with unsafe code, such as when calling Erlang +/// function. +/// +/// This function will catch any error thrown and convert it into a result +/// rather than crashing the process. +/// +pub external fn rescue(fn() -> a) -> Result(a, Crash) = + "gleam_erlang_ffi" "rescue" + +pub type Crash { + Exited(Dynamic) + Thrown(Dynamic) + Errored(Dynamic) +} + +external fn get_start_arguments() -> List(Charlist) = + "init" "get_plain_arguments" + +/// Get the arguments given to the program when it was started. +/// +/// This is sometimes called `argv` in other languages. +pub fn start_arguments() -> List(String) { + get_start_arguments() + |> list.map(charlist.to_string) +} + +/// Starts an OTP application's process tree in the background, as well as +/// the trees of any applications that the given application depends upon. An +/// OTP application typically maps onto a Gleam or Hex package. +/// +/// Returns a list of the applications that were started. Calling this function +/// for application that have already been started is a no-op so you do not need +/// to check the application state beforehand. +/// +/// In Gleam we prefer to not use these implicit background process trees, but +/// you will likely still need to start the trees of OTP applications written in +/// other BEAM languages such as Erlang or Elixir, including those included by +/// default with Erlang/OTP. +/// +/// For more information see the OTP documentation. +/// - +/// - +/// +pub external fn ensure_all_started( + application: Atom, +) -> Result(List(Atom), EnsureAllStartedError) = + "gleam_erlang_ffi" "ensure_all_started" + +pub type EnsureAllStartedError { + UnknownApplication(name: Atom) + ApplicationFailedToStart(name: Atom, reason: Dynamic) +} + +/// A unique reference value. +/// +/// It holds no particular meaning or value, but unique values are often useful +/// in programs are used heavily within both Gleam and Erlang's OTP frameworks. +/// +/// More can be read about refernces in the [Erlang documentation][1]. +/// +/// [1]: https://www.erlang.org/doc/efficiency_guide/advanced.html#unique_references +/// +pub external type Reference + +/// Create a new unique reference. +/// +pub external fn make_reference() -> Reference = + "erlang" "make_ref" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam new file mode 100644 index 00000000000..1e0aac62a9c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam @@ -0,0 +1,79 @@ +import gleam/dynamic.{DecodeErrors, Dynamic} + +/// Atom is a special string-like data-type that is most commonly used for +/// interfacing with code written in other BEAM languages such as Erlang and +/// Elixir. It is preferable to define your own custom types to use instead of +/// atoms where possible. +/// +/// Atoms are not used much in typical Gleam code! +/// +/// ## Creating atoms +/// +/// We can create atoms with the the [`create_from_string`](#create_from_string) +/// function, though we must be careful when doing so as atoms are never +/// garbage collected. If we create too many atoms (for example, if we convert +/// user input into atoms) we may hit the max limit of atoms and cause the +/// virtual machine to crash. +/// +pub external type Atom + +/// An error returned when no atom is found in the virtual machine's atom table +/// for a given string when calling the [`from_string`](#from_string) function. +pub type FromStringError { + AtomNotLoaded +} + +/// Finds an existing Atom for the given String. +/// +/// If no atom is found in the virtual machine's atom table for the String then +/// an error is returned. +/// +/// ## Examples +/// +/// > from_string("ok") +/// Ok(create_from_string("ok")) +/// +/// > from_string("some_new_atom") +/// Error(AtomNotLoaded) +/// +pub external fn from_string(String) -> Result(Atom, FromStringError) = + "gleam_erlang_ffi" "atom_from_string" + +/// Creates an atom from a string, inserting a new value into the virtual +/// machine's atom table if an atom does not already exist for the given +/// string. +/// +/// We must be careful when using this function as there is a limit to the +/// number of atom that can fit in the virtual machine's atom table. Never +/// convert user input into atoms as filling the atom table will cause the +/// virtual machine to crash! +/// +pub external fn create_from_string(String) -> Atom = + "erlang" "binary_to_atom" + +/// Retuns a `String` corresponding to the text representation of the given +/// `Atom`. +/// +/// ## Examples +/// +/// > let ok_atom = create_from_string("ok") +/// > to_string(ok_atom) +/// "ok" +/// +pub external fn to_string(Atom) -> String = + "erlang" "atom_to_binary" + +/// Checks to see whether a `Dynamic` value is an atom, and return the atom if +/// it is. +/// +/// ## Examples +/// +/// > import gleam/dynamic +/// > from_dynamic(dynamic.from(create_from_string("hello"))) +/// Ok(create_from_string("hello")) +/// +/// > from_dynamic(dynamic.from(123)) +/// Error([DecodeError(expected: "Atom", found: "Int", path: [])]) +/// +pub external fn from_dynamic(from: Dynamic) -> Result(Atom, DecodeErrors) = + "gleam_erlang_ffi" "atom_from_dynamic" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam new file mode 100644 index 00000000000..a88c57fa7a8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam @@ -0,0 +1,25 @@ +//// A charlist is a list of integers where all the integers are valid code +//// points. +//// +//// In practice, you will not come across them often, except perhaps when +//// interfacing with Erlang, in particular when using older libraries that do +//// not accept binaries as arguments. + +/// A list of characters represented as ints. Commonly used by older Erlang +/// modules. +pub external type Charlist + +/// Transform a charlist to a string +pub external fn to_string(Charlist) -> String = + "unicode" "characters_to_binary" + +// Calls `unicode:characters_to_binary(Data, unicode, unicode)` +// Note: `unicode is an alias for utf8` +// See + +/// Transform a string to a charlist +pub external fn from_string(String) -> Charlist = + "unicode" "characters_to_list" +// Calls `unicode:characters_to_list(Data, unicode)` +// Note: `unicode is an alias for utf8` +// See diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam new file mode 100644 index 00000000000..2e780518726 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam @@ -0,0 +1,713 @@ +//// Working with files on the filesystem. +//// +//// The functions included in this module are for high-level concepts such as +//// reading and writing. + +import gleam/bit_string +import gleam/result + +/// Reason represents all of the reasons that Erlang surfaces of why a file +/// system operation could fail. Most of these reasons are POSIX errors, which +/// come from the operating system and start with `E`. Others have been added to +/// represent other issues that may arise. +pub type Reason { + /// Permission denied. + Eacces + /// Resource temporarily unavailable. + Eagain + /// Bad file number + Ebadf + /// Bad message. + Ebadmsg + /// File busy. + Ebusy + /// Resource deadlock avoided. + Edeadlk + /// On most architectures, same as `Edeadlk`. On some architectures, it + /// means "File locking deadlock error." + Edeadlock + /// Disk quota exceeded. + Edquot + /// File already exists. + Eexist + /// Bad address in system call argument. + Efault + /// File too large. + Efbig + /// Inappropriate file type or format. Usually caused by trying to set the + /// "sticky bit" on a regular file (not a directory). + Eftype + /// Interrupted system call. + Eintr + /// Invalid argument. + Einval + /// I/O error. + Eio + /// Illegal operation on a directory. + Eisdir + /// Too many levels of symbolic links. + Eloop + /// Too many open files. + Emfile + /// Too many links. + Emlink + /// Multihop attempted. + Emultihop + /// Filename too long + Enametoolong + /// File table overflow + Enfile + /// No buffer space available. + Enobufs + /// No such device. + Enodev + /// No locks available. + Enolck + /// Link has been severed. + Enolink + /// No such file or directory. + Enoent + /// Not enough memory. + Enomem + /// No space left on device. + Enospc + /// No STREAM resources. + Enosr + /// Not a STREAM. + Enostr + /// Function not implemented. + Enosys + /// Block device required. + Enotblk + /// Not a directory. + Enotdir + /// Operation not supported. + Enotsup + /// No such device or address. + Enxio + /// Operation not supported on socket. + Eopnotsupp + /// Value too large to be stored in data type. + Eoverflow + /// Not owner. + Eperm + /// Broken pipe. + Epipe + /// Result too large. + Erange + /// Read-only file system. + Erofs + /// Invalid seek. + Espipe + /// No such process. + Esrch + /// Stale remote file handle. + Estale + /// Text file busy. + Etxtbsy + /// Cross-domain link. + Exdev + /// File was requested to be read as UTF-8, but is not UTF-8 encoded. + NotUtf8 +} + +/// The type of file found by `file_info` or `link_info`. +/// +pub type FileType { + Device + Directory + Other + Regular + Symlink +} + +/// The read/write permissions a user can have for a file. +/// +pub type Access { + NoAccess + Read + ReadWrite + Write +} + +/// Meta information for a file. +/// +/// Timestamps are in seconds before or after the Unix time epoch, +/// `1970-01-01 00:00:00 UTC`. +/// +pub type FileInfo { + FileInfo( + /// File size in bytes. + /// + size: Int, + /// `Regular`, `Directory`, `Symlink`, `Device`, or `Other`. + /// + file_type: FileType, + /// `ReadWrite`, `Read`, `Write`, or `NoAccess`. + /// + access: Access, + /// Timestamp of most recent access. + /// + atime: Int, + /// Timestamp of most recent modification. + /// + mtime: Int, + /// Timestamp of most recent change (or file creation, depending on + /// operating system). + /// + ctime: Int, + /// File permissions encoded as a sum of bit values, including but not + /// limited to: + /// + /// Owner read, write, execute. + /// + /// `0o400`, `0o200`, `0o100` + /// + /// Group read, write, execute. + /// + /// `0o40`, `0o20`, `0o10` + /// + /// Other read, write, execute. + /// + /// `0o4`, `0o2`, `0o1` + /// + /// Set user ID, group ID on execution. + /// + /// `0x800`, `0x400` + /// + mode: Int, + /// Total links to a file (always `1` for file systems without links). + /// + links: Int, + /// The file system where a file is located (`0` for drive `A:` on Windows, + /// `1` for `B:`, etc.). + /// + major_device: Int, + /// Character device (or `0` on non-Unix systems). + /// + minor_device: Int, + /// The `inode` number for a file (always `0` on non-Unix file systems). + /// + inode: Int, + /// The owner of a file (always `0` on non-Unix file systems). + /// + user_id: Int, + /// The group id of a file (always `0` on non-Unix file systems). + /// + group_id: Int, + ) +} + +/// Results in `FileInfo` about the given `path` on success, otherwise a +/// `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// To get `FileInfo` about a symlink itself, use `link_info`. +/// +/// ## Examples +/// +/// ```gleam +/// > file_info("gleam.toml") +/// Ok(FileInfo( +/// size: 430, +/// file_type: Regular, +/// access: ReadWrite, +/// atime: 1680580321, +/// mtime: 1680580272, +/// ctime: 1680580272, +/// mode: 33188, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 469028, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > file_info("/root") +/// Ok(FileInfo( +/// size: 16, +/// file_type: Directory, +/// access: Read, +/// atime: 1677789967, +/// mtime: 1664561240, +/// ctime: 1664561240, +/// mode: 16877, +/// links: 11, +/// major_device: 54, +/// minor_device: 0, +/// inode: 34, +/// user_id: 0, +/// group_id: 0, +/// )) +/// +/// > file_info("./build/dev/erlang/rad/priv") +/// Ok(FileInfo( +/// size: 140, +/// file_type: Directory, +/// access: ReadWrite, +/// atime: 1680580321, +/// mtime: 1680580272, +/// ctime: 1680580272, +/// mode: 33188, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 469028, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > file_info("/does_not_exist") +/// Error(Enoent) +/// +/// > file_info("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +pub external fn file_info(String) -> Result(FileInfo, Reason) = + "gleam_erlang_ffi" "file_info" + +/// Results in `FileInfo` about the given `path` on success, otherwise a +/// `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link itself. +/// To get `FileInfo` about a symlink's target, use `file_info`. +/// +/// ## Examples +/// +/// ```gleam +/// > link_info("gleam.toml") +/// Ok(FileInfo( +/// size: 430, +/// file_type: Regular, +/// access: ReadWrite, +/// atime: 1680580321, +/// mtime: 1680580272, +/// ctime: 1680580272, +/// mode: 33188, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 469028, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > link_info("/root") +/// Ok(FileInfo( +/// size: 16, +/// file_type: Directory, +/// access: Read, +/// atime: 1677789967, +/// mtime: 1664561240, +/// ctime: 1664561240, +/// mode: 16877, +/// links: 11, +/// major_device: 54, +/// minor_device: 0, +/// inode: 34, +/// user_id: 0, +/// group_id: 0, +/// )) +/// +/// > link_info("./build/dev/erlang/rad/priv") +/// Ok(FileInfo( +/// size: 41, +/// file_type: Symlink, +/// access: ReadWrite, +/// atime: 1680581150, +/// mtime: 1680581150, +/// ctime: 1680581150, +/// mode: 41471, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 471587, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > link_info("/does_not_exist") +/// Error(Enoent) +/// +/// > link_info("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +pub external fn link_info(String) -> Result(FileInfo, Reason) = + "gleam_erlang_ffi" "link_info" + +/// Results in a `Bool` on success that indicates whether the given `path` has +/// a `Directory` `FileType`, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// +/// ## Examples +/// +/// ```gleam +/// > is_directory("/tmp") +/// Ok(True) +/// +/// > is_directory("resume.pdf") +/// Ok(False) +/// +/// > is_directory("/does_not_exist") +/// Error(Enoent) +/// ``` +/// +pub fn is_directory(path: String) -> Result(Bool, Reason) { + use FileInfo(file_type: file_type, ..) <- result.map(over: file_info(path)) + file_type == Directory +} + +/// Results in a `Bool` on success that indicates whether the given `path` has +/// a `Regular` `FileType`, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// +/// ## Examples +/// +/// ```gleam +/// > is_regular("resume.pdf") +/// Ok(True) +/// +/// > is_regular("/tmp") +/// Ok(False) +/// +/// > is_regular("/does_not_exist.txt") +/// Error(Enoent) +/// ``` +/// +pub fn is_regular(path: String) -> Result(Bool, Reason) { + use FileInfo(file_type: file_type, ..) <- result.map(over: file_info(path)) + file_type == Regular +} + +/// Results in a `Bool` on success that indicates whether the given `path` +/// exists, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// To find whether a symlink itself exists, use `link_exists`. +/// +/// ## Examples +/// +/// ```gleam +/// > file_exists("resume.pdf") +/// Ok(True) +/// +/// > file_exists("/tmp") +/// Ok(True) +/// +/// > file_exists("/does_not_exist") +/// Ok(False) +/// +/// > file_exists("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +pub fn file_exists(path: String) -> Result(Bool, Reason) { + let result = + path + |> file_info + |> result.replace(True) + case result { + Error(Enoent) -> Ok(False) + _ -> result + } +} + +/// Results in a `Bool` on success that indicates whether the given `path` +/// exists, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link itself. +/// To find whether a symlink's target exists, use `file_exists`. +/// +/// ## Examples +/// +/// ```gleam +/// > link_exists("resume.pdf") +/// Ok(True) +/// +/// > link_exists("/tmp") +/// Ok(True) +/// +/// > link_exists("/does_not_exist") +/// Ok(False) +/// +/// > link_exists("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +pub fn link_exists(path: String) -> Result(Bool, Reason) { + let result = + path + |> link_info + |> result.replace(True) + case result { + Error(Enoent) -> Ok(False) + _ -> result + } +} + +/// Tries to create a directory. Missing parent directories are not created. +/// +/// Returns a Result of nil if the directory is created or Reason if the +/// operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > make_directory("/tmp/foo") +/// Ok(Nil) +/// +/// > make_directory("relative_directory") +/// Ok(Nil) +/// +/// > make_directory("/tmp/missing_intermediate_directory/foo") +/// Error(Enoent) +/// ``` +/// +pub external fn make_directory(String) -> Result(Nil, Reason) = + "gleam_erlang_ffi" "make_directory" + +/// Lists all files in a directory, except files with +/// [raw filenames](https://www.erlang.org/doc/apps/stdlib/unicode_usage.html#notes-about-raw-filenames). +/// +/// Returns a Result containing the list of filenames in the directory, or Reason +/// if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > list_directory("/tmp") +/// Ok(["FB01293B-8597-4359-80D5-130140A0C0DE","AlTest2.out"]) +/// +/// > list_directory("resume.docx") +/// Error(Enotdir) +/// ``` +/// +pub external fn list_directory(String) -> Result(List(String), Reason) = + "gleam_erlang_ffi" "list_directory" + +/// Deletes a directory. +/// +/// The directory must be empty before it can be deleted. Returns a nil Success +/// or Reason if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > delete_directory("foo") +/// Ok(Nil) +/// +/// > delete_directory("does_not_exist/") +/// Error(Enoent) +/// ``` +/// +pub external fn delete_directory(String) -> Result(Nil, Reason) = + "gleam_erlang_ffi" "delete_directory" + +/// Deletes a file or directory recursively. +/// +/// Returns a nil Success or Reason if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > recursive_delete("foo") +/// Ok(Nil) +/// +/// > recursive_delete("/bar") +/// Ok(Nil) +/// +/// > recursive_delete("does_not_exist/") +/// Error(Enoent) +/// ``` +/// +pub external fn recursive_delete(String) -> Result(Nil, Reason) = + "gleam_erlang_ffi" "recursive_delete" + +/// Read the contents of the given file as a String +/// +/// Assumes the file is UTF-8 encoded. Returns a Result containing the file's +/// contents as a String if the operation was successful, or Reason if the file +/// operation failed. If the file is not UTF-8 encoded, the `NotUTF8` variant +/// will be returned. +/// +/// ## Examples +/// +/// ```gleam +/// > read("example.txt") +/// Ok("Hello, World!") +/// +/// > read(from: "example.txt") +/// Ok("Hello, World!") +/// +/// > read("does_not_exist.txt") +/// Error(Enoent) +/// +/// > read("cat.gif") +/// Error(NotUTF8) +/// ``` +/// +pub fn read(from path: String) -> Result(String, Reason) { + path + |> do_read_bits() + |> result.then(fn(content) { + case bit_string.to_string(content) { + Ok(string) -> Ok(string) + Error(Nil) -> Error(NotUtf8) + } + }) +} + +/// Read the contents of the given file as a BitString +/// +/// Returns a Result containing the file's contents as a BitString if the +/// operation was successful, or Reason if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > read_bits("example.txt") +/// Ok(<<"Hello, World!">>) +/// +/// > read_bits(from: "cat.gif") +/// Ok(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) +/// +/// > read_bits("does_not_exist.txt") +/// Error(Enoent) +/// ``` +/// +pub fn read_bits(from path: String) -> Result(BitString, Reason) { + do_read_bits(path) +} + +external fn do_read_bits(path) -> Result(BitString, Reason) = + "gleam_erlang_ffi" "read_file" + +/// Write the given String contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > write("Hello, World!", "file.txt") +/// Ok(Nil) +/// +/// > write(to: "file.txt", contents: "Hello, World!") +/// Ok(Nil) +/// +/// > write("Hello, World!", "does_not_exist/file.txt") +/// Error(Enoent) +/// ``` +/// +pub fn write(contents contents: String, to path: String) -> Result(Nil, Reason) { + contents + |> bit_string.from_string + |> do_write_bits(path) +} + +/// Write the given BitString contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") +/// Ok(Nil) +/// +/// > write_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) +/// Ok(Nil) +/// +/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") +/// Error(Enoent) +/// ``` +/// +pub fn write_bits( + contents contents: BitString, + to path: String, +) -> Result(Nil, Reason) { + do_write_bits(contents, path) +} + +external fn do_write_bits(BitString, String) -> Result(Nil, Reason) = + "gleam_erlang_ffi" "write_file" + +/// Append the given String contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > append("Hello, World!", "file.txt") +/// Ok(Nil) +/// +/// > append(to: "file.txt", contents: "Hello, World!") +/// Ok(Nil) +/// +/// > append("Hello, World!", "does_not_exist/file.txt") +/// Error(Enoent) +/// ``` +/// +pub fn append(contents contents: String, to path: String) -> Result(Nil, Reason) { + contents + |> bit_string.from_string + |> do_append_bits(path) +} + +/// Append the given BitString contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") +/// Ok(Nil) +/// +/// > append_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) +/// Ok(Nil) +/// +/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") +/// Error(Enoent) +/// ``` +/// +pub fn append_bits( + contents contents: BitString, + to path: String, +) -> Result(Nil, Reason) { + do_append_bits(contents, path) +} + +external fn do_append_bits( + contents: BitString, + path: String, +) -> Result(Nil, Reason) = + "gleam_erlang_ffi" "append_file" + +/// Delete the given file. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > delete("file.txt") +/// Ok(Nil) +/// +/// > delete("does_not_exist.txt") +/// Error(Enoent) +/// ``` +/// +pub external fn delete(String) -> Result(Nil, Reason) = + "gleam_erlang_ffi" "delete_file" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam new file mode 100644 index 00000000000..68326962a71 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam @@ -0,0 +1,95 @@ +//// Access to the shell's environment variables + +import gleam/map.{Map} + +/// Returns the list of all available environment variables as a list of key, +/// tuples. +/// +/// ## Examples +/// +/// > get_all_env() +/// map.from_list([ +/// #("SHELL", "/bin/bash"), +/// #("PWD", "/home/j3rn"), +/// ... +/// ]) +/// +pub external fn get_all_env() -> Map(String, String) = + "gleam_erlang_ffi" "get_all_env" + +/// Returns the value associated with the given environment variable name. +/// +/// ## Examples +/// +/// > get_env("SHELL") +/// "/bin/bash" +/// +/// > get_env(name: "PWD") +/// "/home/j3rn" +/// +pub external fn get_env(name: String) -> Result(String, Nil) = + "gleam_erlang_ffi" "get_env" + +/// Associates the given value with the given environment variable name. +/// +/// ## Examples +/// +/// > set_env("MYVAR", "MYVALUE") +/// Nil +/// > get_env("MYVAR") +/// "MYVALUE" +/// +/// > set_env(value: "MYVALUE", name: "MYVAR") +/// Nil +/// +pub external fn set_env(name: String, value: String) -> Nil = + "gleam_erlang_ffi" "set_env" + +/// Removes the environment variable with the given name. +/// +/// Returns Nil regardless of whether the variable ever existed. +/// +/// ## Examples +/// +/// > get_env("MYVAR") +/// Ok("MYVALUE") +/// > unset_env("MYVAR") +/// Nil +/// > get_env("MYVAR") +/// Error(Nil) +/// +/// > unset_env(name: "MYVAR") +/// Nil +/// +pub external fn unset_env(name: String) -> Nil = + "gleam_erlang_ffi" "unset_env" + +/// Represents operating system kernels +pub type OsFamily { + // The family which includes modern versions of the Windows operating system. + WindowsNt + // The family of operating systems based on the open source Linux kernel. + Linux + // The family of Apple operating systems such as macOS and iOS. + Darwin + // The family of operating systems based on the FreeBSD kernel. + FreeBsd + // An operating system kernel other than Linux, Darwin, FreeBSD, or NT. + Other(String) +} + +/// Returns the kernel of the host operating system. +/// +/// Unknown kernels are reported as `Other(String)`; e.g. `Other("sunos")`. +/// +/// ## Examples +/// +/// > family() +/// Linux +/// > family() +/// Darwin +/// > family() +/// Other("sunos") +/// +pub external fn family() -> OsFamily = + "gleam_erlang_ffi" "os_family" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam new file mode 100644 index 00000000000..6e7e03f66c7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam @@ -0,0 +1,716 @@ +import gleam/string +import gleam/dynamic.{Dynamic} +import gleam/erlang.{Reference} +import gleam/erlang/atom.{Atom} + +/// A `Pid` (or Process identifier) is a reference to an Erlang process. Each +/// process has a `Pid` and it is one of the lowest level building blocks of +/// inter-process communication in the Erlang and Gleam OTP frameworks. +/// +pub external type Pid + +/// Get the `Pid` for the current process. +pub external fn self() -> Pid = + "erlang" "self" + +/// Create a new Erlang process that runs concurrently to the creator. In other +/// languages this might be called a fibre, a green thread, or a coroutine. +/// +/// If `linked` is `True` then the created process is linked to the creator +/// process. When a process terminates an exit signal is sent to all other +/// processes that are linked to it, causing the process to either terminate or +/// have to handle the signal. +/// +/// More can be read about processes and links in the [Erlang documentation][1]. +/// +/// [1]: https://www.erlang.org/doc/reference_manual/processes.html +/// +pub fn start(running implementation: fn() -> anything, linked link: Bool) -> Pid { + case link { + True -> spawn_link(implementation) + False -> spawn(implementation) + } +} + +external fn spawn(fn() -> anything) -> Pid = + "erlang" "spawn" + +external fn spawn_link(fn() -> anything) -> Pid = + "erlang" "spawn_link" + +/// A `Subject` is a value that processes can use to send and receive messages +/// to and from each other in a well typed way. +/// +/// Each subject is "owned" by the process that created it. Any process can use +/// the `send` function to sent a message of the correct type to the process +/// that owns the subject, and the owner can use the `receive` function or the +/// `Selector` type to receive these messages. +/// +/// The `Subject` type is similar to the "channel" types found in other +/// languages and the "topic" concept found in some pub-sub systems. +/// +/// # Examples +/// +/// ```gleam +/// let subject = new_subject() +/// +/// // Send a message with the subject +/// send(subject, "Hello, Joe!") +/// +/// // Receive the message +/// receive(subject, within: 10) +/// ``` +/// +pub opaque type Subject(message) { + Subject(owner: Pid, tag: Reference) +} + +/// Create a new `Subject` owned by the current process. +/// +pub fn new_subject() -> Subject(message) { + Subject(owner: self(), tag: erlang.make_reference()) +} + +/// Get the owner process for a `Subject`. This is the process that created the +/// `Subject` and will receive messages sent with it. +/// +pub fn subject_owner(subject: Subject(message)) -> Pid { + subject.owner +} + +external type DoNotLeak + +external fn raw_send(Pid, message) -> DoNotLeak = + "erlang" "send" + +/// Send a message to a process using a `Subject`. The message must be of the +/// type that the `Subject` accepts. +/// +/// This function does not wait for the `Subject` owner process to call the +/// `receive` function, instead it returns once the message has been placed in +/// the process' mailbox. +/// +/// # Ordering +/// +/// If process P1 sends two messages to process P2 it is guarenteed that process +/// P1 will receive the messages in the order they were sent. +/// +/// If you wish to receive the messages in a different order you can send them +/// on two different subjects and the receiver function can call the `receive` +/// function for each subject in the desired order, or you can write some Erlang +/// code to perform a selective receive. +/// +/// # Examples +/// +/// ```gleam +/// let subject = new_subject() +/// send(subject, "Hello, Joe!") +/// ``` +/// +pub fn send(subject: Subject(message), message: message) -> Nil { + raw_send(subject.owner, #(subject.tag, message)) + Nil +} + +/// Receive a message that has been sent to current process using the `Subject`. +/// +/// If there is not an existing message for the `Subject` in the process' +/// mailbox or one does not arrive `within` the permitted timeout then the +/// `Error(Nil)` is returned. +/// +/// Only the process that is owner of the `Subject` can receive a message using +/// it. If a process that does not own the `Subject` attempts to receive with it +/// then it will not receive a message. +/// +/// To wait for messages from multiple `Subject`s at the same time see the +/// `Selector` type. +/// +pub fn receive( + from subject: Subject(message), + within milliseconds: Int, +) -> Result(message, Nil) { + new_selector() + |> selecting(subject, fn(x) { x }) + |> select(within: milliseconds) +} + +/// A type that enables a process to wait for messages from multiple `Subject`s +/// at the same time, returning whichever message arrives first. +/// +/// Used with the `new_selector`, `selecting`, and `select` functions. +/// +/// # Examples +/// +/// ```gleam +/// > let int_subject = new_subject() +/// > let float_subject = new_subject() +/// > send(int_subject, 1) +/// > +/// > let selector = +/// > new_selector() +/// > |> selecting(int_subject, int.to_string) +/// > |> selecting(float_subject, float.to_string) +/// > +/// > select(selector) +/// Ok("1") +/// ``` +/// +pub external type Selector(payload) + +/// Create a new `Selector` which can be used to receive messages on multiple +/// `Subject`s at once. +/// +pub external fn new_selector() -> Selector(payload) = + "gleam_erlang_ffi" "new_selector" + +/// Receive a message that has been sent to current process using any of the +/// `Subject`s that have been added to the `Selector` with the `selecting` +/// function. +/// +/// If there is not an existing message for the `Selector` in the process' +/// mailbox or one does not arrive `within` the permitted timeout then the +/// `Error(Nil)` is returned. +/// +/// Only the process that is owner of the `Subject`s can receive a message using +/// them. If a process that does not own the a `Subject` attempts to receive +/// with it then it will not receive a message. +/// +/// To wait forever for the next message rather than for a limited amount of +/// time see the `select_forever` function. +/// +pub external fn select( + from: Selector(payload), + within: Int, +) -> Result(payload, Nil) = + "gleam_erlang_ffi" "select" + +/// Similar to the `select` function but will wait forever for a message to +/// arrive rather than timing out after a specified amount of time. +/// +pub external fn select_forever(from: Selector(payload)) -> payload = + "gleam_erlang_ffi" "select" + +/// Add a transformation function to a selector. When a message is received +/// using this selector the tranformation function is applied to the message. +/// +/// This function can be used to change the type of messages received and may +/// be useful when combined with the `merge_selector` function. +/// +pub external fn map_selector(Selector(a), fn(a) -> b) -> Selector(b) = + "gleam_erlang_ffi" "map_selector" + +/// Merge one selector into another, producing a selector that contains the +/// message handlers of both. +/// +/// If a subject is handled by both selectors the handler function of the +/// second selector is used. +/// +pub external fn merge_selector(Selector(a), Selector(a)) -> Selector(a) = + "gleam_erlang_ffi" "merge_selector" + +pub type ExitMessage { + ExitMessage(pid: Pid, reason: ExitReason) +} + +pub type ExitReason { + Normal + Killed + Abnormal(reason: String) +} + +/// Add a handler for trapped exit messages. In order for these messages to be +/// sent to the process when a linked process exits the process must call the +/// `trap_exit` beforehand. +/// +pub fn selecting_trapped_exits( + selector: Selector(a), + handler: fn(ExitMessage) -> a, +) -> Selector(a) { + let tag = atom.create_from_string("EXIT") + let handler = fn(message: #(Atom, Pid, Dynamic)) -> a { + let reason = message.2 + let normal = dynamic.from(Normal) + let killed = dynamic.from(Killed) + let reason = case dynamic.string(reason) { + _ if reason == normal -> Normal + _ if reason == killed -> Killed + Ok(reason) -> Abnormal(reason) + Error(_) -> Abnormal(string.inspect(reason)) + } + handler(ExitMessage(message.1, reason)) + } + insert_selector_handler(selector, #(tag, 3), handler) +} + +// TODO: implement in Gleam +/// Discard all messages in the current process' mailbox. +/// +/// Warning: This function may cause other processes to crash if they sent a +/// message to the current process and are waiting for a response, so use with +/// caution. +/// +pub external fn flush_messages() -> Nil = + "gleam_erlang_ffi" "flush_messages" + +/// Add a new `Subject` to the `Selector` to that it's messages can be received. +/// +/// The `mapping` function provided with the `Subject` can be used to convert +/// the type of messages received using this `Subject`. This is useful for when +/// you wish to add multiple `Subject`s to a `Seletor` when they have differing +/// message types. If you do not wish to transform the incoming messages in any +/// way then the `identity` function can be given. +/// +pub fn selecting( + selector: Selector(payload), + for subject: Subject(message), + mapping transform: fn(message) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(Reference, message)) { transform(message.1) } + insert_selector_handler(selector, #(subject.tag, 2), handler) +} + +/// Add a handler to a selector for 2 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record2( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic)) { transform(message.1) } + insert_selector_handler(selector, #(tag, 2), handler) +} + +/// Add a handler to a selector for 3 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record3( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic)) { + transform(message.1, message.2) + } + insert_selector_handler(selector, #(tag, 3), handler) +} + +/// Add a handler to a selector for 4 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record4( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic)) { + transform(message.1, message.2, message.3) + } + insert_selector_handler(selector, #(tag, 4), handler) +} + +/// Add a handler to a selector for 5 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record5( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic)) { + transform(message.1, message.2, message.3, message.4) + } + insert_selector_handler(selector, #(tag, 5), handler) +} + +/// Add a handler to a selector for 6 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record6( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic)) { + transform(message.1, message.2, message.3, message.4, message.5) + } + insert_selector_handler(selector, #(tag, 6), handler) +} + +/// Add a handler to a selector for 7 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record7( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> + payload, +) -> Selector(payload) { + let handler = fn( + message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), + ) { + transform(message.1, message.2, message.3, message.4, message.5, message.6) + } + insert_selector_handler(selector, #(tag, 7), handler) +} + +/// Add a handler to a selector for 8 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record8( + selector: Selector(payload), + tag: tag, + mapping transform: fn( + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + ) -> + payload, +) -> Selector(payload) { + let handler = fn( + message: #( + tag, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + ), + ) { + transform( + message.1, + message.2, + message.3, + message.4, + message.5, + message.6, + message.7, + ) + } + insert_selector_handler(selector, #(tag, 8), handler) +} + +type AnythingSelectorTag { + Anything +} + +/// Add a catch-all handler to a selector that will be used when no other +/// handler in a selector is suitable for a given message. +/// +/// This may be useful for when you want to ensure that any message in the inbox +/// is handled, or when you need to handle messages from other BEAM languages +/// which do not use subjects or record format messages. +/// +pub fn selecting_anything( + selector: Selector(payload), + mapping handler: fn(Dynamic) -> payload, +) -> Selector(payload) { + insert_selector_handler(selector, Anything, handler) +} + +external fn insert_selector_handler( + Selector(payload), + for: tag, + mapping: fn(message) -> payload, +) -> Selector(payload) = + "gleam_erlang_ffi" "insert_selector_handler" + +/// Suspends the process calling this function for the specified number of +/// milliseconds. +/// +pub external fn sleep(Int) -> Nil = + "gleam_erlang_ffi" "sleep" + +/// Suspends the process forever! This may be useful for suspending the main +/// process in a Gleam program when it has no more work to do but we want other +/// processes to continue to work. +/// +pub external fn sleep_forever() -> Nil = + "gleam_erlang_ffi" "sleep_forever" + +/// Check to see whether the process for a given `Pid` is alive. +/// +/// See the [Erlang documentation][1] for more information. +/// +/// [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1 +/// +pub external fn is_alive(Pid) -> Bool = + "erlang" "is_process_alive" + +type ProcessMonitorFlag { + Process +} + +external fn erlang_monitor_process(ProcessMonitorFlag, Pid) -> Reference = + "erlang" "monitor" + +pub opaque type ProcessMonitor { + ProcessMonitor(tag: Reference) +} + +/// A message received when a monitored process exits. +/// +pub type ProcessDown { + ProcessDown(pid: Pid, reason: Dynamic) +} + +/// Start monitoring a process so that when the monitored process exits a +/// message is to the monitoring process. +/// +/// The message is only sent once, when the target process exits. If the +/// process was not alive when this function is called the message will never +/// be received. +/// +/// The down message can be received with a `Selector` and the +/// `selecting_process_down` function. +/// +/// The process can be demonitored with the `demonitor_process` function. +/// +pub fn monitor_process(pid: Pid) -> ProcessMonitor { + Process + |> erlang_monitor_process(pid) + |> ProcessMonitor +} + +/// Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can +/// be received using the `Selector` and the `select` function. +/// +pub fn selecting_process_down( + selector: Selector(payload), + monitor: ProcessMonitor, + mapping: fn(ProcessDown) -> payload, +) -> Selector(payload) { + insert_selector_handler(selector, monitor.tag, mapping) +} + +/// Remove the monitor for a process so that when the monitor process exits a +/// `ProcessDown` message is not sent to the monitoring process. +/// +/// If the message has already been sent it is removed from the monitoring +/// process' mailbox. +/// +pub external fn demonitor_process(monitor: ProcessMonitor) -> Nil = + "gleam_erlang_ffi" "demonitor" + +/// An error returned when making a call to a process. +/// +pub type CallError(msg) { + /// The process being called exited before it sent a response. + /// + CalleeDown(reason: Dynamic) + + /// The process being called did not response within the permitted amount of + /// time. + /// + CallTimeout +} + +// This function is based off of Erlang's gen:do_call/4. +/// Send a message to a process and wait for a reply. +/// +/// If the receiving process exits or does not reply within the allowed amount +/// of time then an error is returned. +/// +pub fn try_call( + subject: Subject(request), + make_request: fn(Subject(response)) -> request, + within timeout: Int, +) -> Result(response, CallError(response)) { + let reply_subject = new_subject() + + // Monitor the callee process so we can tell if it goes down (meaning we + // won't get a reply) + let monitor = monitor_process(subject_owner(subject)) + + // Send the request to the process over the channel + send(subject, make_request(reply_subject)) + + // Await a reply or handle failure modes (timeout, process down, etc) + let result = + new_selector() + |> selecting(reply_subject, Ok) + |> selecting_process_down( + monitor, + fn(down: ProcessDown) { Error(CalleeDown(reason: down.reason)) }, + ) + |> select(timeout) + + // Demonitor the process and close the channels as we're done + demonitor_process(monitor) + + // Prepare an appropriate error (if present) for the caller + case result { + Error(Nil) -> Error(CallTimeout) + Ok(res) -> res + } +} + +/// Send a message to a process and wait for a reply. +/// +/// If the receiving process exits or does not reply within the allowed amount +/// of time the calling process crashes. If you wish an error to be returned +/// instead see the `try_call` function. +/// +pub fn call( + subject: Subject(request), + make_request: fn(Subject(response)) -> request, + within timeout: Int, +) -> response { + let assert Ok(resp) = try_call(subject, make_request, timeout) + resp +} + +/// Creates a link between the calling process and another process. +/// +/// When a process crashes any linked processes will also crash. This is useful +/// to ensure that groups of processes that depend on each other all either +/// succeed or fail together. +/// +/// Returns `True` if the link was created successfully, returns `False` if the +/// process was not alive and as such could not be linked. +/// +pub external fn link(pid: Pid) -> Bool = + "gleam_erlang_ffi" "link" + +external fn erlang_unlink(pid: Pid) -> Bool = + "erlang" "unlink" + +/// Removes any existing link between the caller process and the target process. +/// +pub fn unlink(pid: Pid) -> Nil { + erlang_unlink(pid) + Nil +} + +pub external type Timer + +external fn erlang_send_after(Int, Pid, msg) -> Timer = + "erlang" "send_after" + +/// Send a message over a channel after a specified number of milliseconds. +/// +pub fn send_after(subject: Subject(msg), delay: Int, message: msg) -> Timer { + erlang_send_after(delay, subject.owner, #(subject.tag, message)) +} + +external fn erlang_cancel_timer(Timer) -> Dynamic = + "erlang" "cancel_timer" + +/// Values returned when a timer is cancelled. +/// +pub type Cancelled { + /// The timer could not be found. It likely has already triggered. + /// + TimerNotFound + + /// The timer was found and cancelled before it triggered. + /// + /// The amount of remaining time before the timer was due to be triggered is + /// returned in milliseconds. + /// + Cancelled(time_remaining: Int) +} + +/// Cancel a given timer, causing it not to trigger if it has not done already. +/// +pub fn cancel_timer(timer: Timer) -> Cancelled { + case dynamic.int(erlang_cancel_timer(timer)) { + Ok(i) -> Cancelled(i) + Error(_) -> TimerNotFound + } +} + +type KillFlag { + Kill +} + +external fn erlang_kill(to: Pid, because: KillFlag) -> Bool = + "erlang" "exit" + +// Go, my pretties. Kill! Kill! +// - Bart Simpson +// +/// Send an untrappable `kill` exit signal to the target process. +/// +/// See the documentation for the Erlang [`erlang:exit`][1] function for more +/// information. +/// +/// [1]: https://erlang.org/doc/man/erlang.html#exit-1 +/// +pub fn kill(pid: Pid) -> Nil { + erlang_kill(pid, Kill) + Nil +} + +external fn erlang_send_exit(to: Pid, because: whatever) -> Bool = + "erlang" "exit" + +// TODO: test +/// Sends an exit signal to a process, indicating that the process is to shut +/// down. +/// +/// See the [Erlang documentation][erl] for more information. +/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 +/// +pub fn send_exit(to pid: Pid) -> Nil { + erlang_send_exit(pid, Normal) + Nil +} + +/// Sends an exit signal to a process, indicating that the process is to shut +/// down due to an abnormal reason such as a failure. +/// +/// See the [Erlang documentation][erl] for more information. +/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 +/// +pub fn send_abnormal_exit(pid: Pid, reason: String) -> Nil { + erlang_send_exit(pid, Abnormal(reason)) + Nil +} + +/// Set whether the current process is to trap exit signals or not. +/// +/// When not trapping exits if a linked process crashes the exit signal +/// propagates to the process which will also crash. +/// This is the normal behaviour before this function is called. +/// +/// When trapping exits (after this function is called) if a linked process +/// crashes an exit message is sent to the process instead. These messages can +/// be handled with the `selecting_trapped_exits` function. +/// +pub external fn trap_exits(Bool) -> Nil = + "gleam_erlang_ffi" "trap_exits" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl new file mode 100644 index 00000000000..39fdc1855ed --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl @@ -0,0 +1,86 @@ +-module(gleam@erlang). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0]). +-export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]). + +-type safe() :: safe. + +-type get_line_error() :: eof | no_data. + +-type time_unit() :: second | millisecond | microsecond | nanosecond. + +-type crash() :: {exited, gleam@dynamic:dynamic()} | + {thrown, gleam@dynamic:dynamic()} | + {errored, gleam@dynamic:dynamic()}. + +-type ensure_all_started_error() :: {unknown_application, + gleam@erlang@atom:atom_()} | + {application_failed_to_start, + gleam@erlang@atom:atom_(), + gleam@dynamic:dynamic()}. + +-type reference_() :: any(). + +-spec format(any()) -> binary(). +format(Term) -> + unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])). + +-spec term_to_binary(any()) -> bitstring(). +term_to_binary(Field@0) -> + erlang:term_to_binary(Field@0). + +-spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. +get_line(Field@0) -> + gleam_erlang_ffi:get_line(Field@0). + +-spec system_time(time_unit()) -> integer(). +system_time(Field@0) -> + os:system_time(Field@0). + +-spec erlang_timestamp() -> {integer(), integer(), integer()}. +erlang_timestamp() -> + os:timestamp(). + +-spec rescue(fun(() -> EYG)) -> {ok, EYG} | {error, crash()}. +rescue(Field@0) -> + gleam_erlang_ffi:rescue(Field@0). + +-spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic()} | + {error, nil}. +binary_to_term(Binary) -> + case gleam_erlang_ffi:rescue( + fun() -> erlang:binary_to_term(Binary, [safe]) end + ) of + {ok, Term} -> + {ok, Term}; + + {error, _} -> + {error, nil} + end. + +-spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic()} | + {error, nil}. +unsafe_binary_to_term(Binary) -> + case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of + {ok, Term} -> + {ok, Term}; + + {error, _} -> + {error, nil} + end. + +-spec start_arguments() -> list(binary()). +start_arguments() -> + _pipe = init:get_plain_arguments(), + gleam@list:map(_pipe, fun gleam@erlang@charlist:to_string/1). + +-spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok, + list(gleam@erlang@atom:atom_())} | + {error, ensure_all_started_error()}. +ensure_all_started(Field@0) -> + gleam_erlang_ffi:ensure_all_started(Field@0). + +-spec make_reference() -> reference_(). +make_reference() -> + erlang:make_ref(). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl new file mode 100644 index 00000000000..70b92f520e7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl @@ -0,0 +1,26 @@ +-module(gleam@erlang@atom). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]). +-export_type([from_string_error/0, atom_/0]). + +-type from_string_error() :: atom_not_loaded. + +-type atom_() :: any(). + +-spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}. +from_string(Field@0) -> + gleam_erlang_ffi:atom_from_string(Field@0). + +-spec create_from_string(binary()) -> atom_(). +create_from_string(Field@0) -> + erlang:binary_to_atom(Field@0). + +-spec to_string(atom_()) -> binary(). +to_string(Field@0) -> + erlang:atom_to_binary(Field@0). + +-spec from_dynamic(gleam@dynamic:dynamic()) -> {ok, atom_()} | + {error, list(gleam@dynamic:decode_error())}. +from_dynamic(Field@0) -> + gleam_erlang_ffi:atom_from_dynamic(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl new file mode 100644 index 00000000000..8dbbd144055 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl @@ -0,0 +1,15 @@ +-module(gleam@erlang@charlist). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_string/1, from_string/1]). +-export_type([charlist/0]). + +-type charlist() :: any(). + +-spec to_string(charlist()) -> binary(). +to_string(Field@0) -> + unicode:characters_to_binary(Field@0). + +-spec from_string(binary()) -> charlist(). +from_string(Field@0) -> + unicode:characters_to_list(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl new file mode 100644 index 00000000000..829b69aa304 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl @@ -0,0 +1,190 @@ +-module(gleam@erlang@file). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([file_info/1, is_directory/1, is_regular/1, file_exists/1, link_info/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]). +-export_type([reason/0, file_type/0, access/0, file_info/0]). + +-type reason() :: eacces | + eagain | + ebadf | + ebadmsg | + ebusy | + edeadlk | + edeadlock | + edquot | + eexist | + efault | + efbig | + eftype | + eintr | + einval | + eio | + eisdir | + eloop | + emfile | + emlink | + emultihop | + enametoolong | + enfile | + enobufs | + enodev | + enolck | + enolink | + enoent | + enomem | + enospc | + enosr | + enostr | + enosys | + enotblk | + enotdir | + enotsup | + enxio | + eopnotsupp | + eoverflow | + eperm | + epipe | + erange | + erofs | + espipe | + esrch | + estale | + etxtbsy | + exdev | + not_utf8. + +-type file_type() :: device | directory | other | regular | symlink. + +-type access() :: no_access | read | read_write | write. + +-type file_info() :: {file_info, + integer(), + file_type(), + access(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer()}. + +-spec file_info(binary()) -> {ok, file_info()} | {error, reason()}. +file_info(Field@0) -> + gleam_erlang_ffi:file_info(Field@0). + +-spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}. +is_directory(Path) -> + gleam@result:map( + gleam_erlang_ffi:file_info(Path), + fun(_use0) -> + {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, + File_type =:= directory + end + ). + +-spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}. +is_regular(Path) -> + gleam@result:map( + gleam_erlang_ffi:file_info(Path), + fun(_use0) -> + {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, + File_type =:= regular + end + ). + +-spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}. +file_exists(Path) -> + Result = begin + _pipe = Path, + _pipe@1 = gleam_erlang_ffi:file_info(_pipe), + gleam@result:replace(_pipe@1, true) + end, + case Result of + {error, enoent} -> + {ok, false}; + + _ -> + Result + end. + +-spec link_info(binary()) -> {ok, file_info()} | {error, reason()}. +link_info(Field@0) -> + gleam_erlang_ffi:link_info(Field@0). + +-spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}. +link_exists(Path) -> + Result = begin + _pipe = Path, + _pipe@1 = gleam_erlang_ffi:link_info(_pipe), + gleam@result:replace(_pipe@1, true) + end, + case Result of + {error, enoent} -> + {ok, false}; + + _ -> + Result + end. + +-spec make_directory(binary()) -> {ok, nil} | {error, reason()}. +make_directory(Field@0) -> + gleam_erlang_ffi:make_directory(Field@0). + +-spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}. +list_directory(Field@0) -> + gleam_erlang_ffi:list_directory(Field@0). + +-spec delete_directory(binary()) -> {ok, nil} | {error, reason()}. +delete_directory(Field@0) -> + gleam_erlang_ffi:delete_directory(Field@0). + +-spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}. +recursive_delete(Field@0) -> + gleam_erlang_ffi:recursive_delete(Field@0). + +-spec read(binary()) -> {ok, binary()} | {error, reason()}. +read(Path) -> + _pipe = Path, + _pipe@1 = gleam_erlang_ffi:read_file(_pipe), + gleam@result:then( + _pipe@1, + fun(Content) -> case gleam@bit_string:to_string(Content) of + {ok, String} -> + {ok, String}; + + {error, nil} -> + {error, not_utf8} + end end + ). + +-spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}. +read_bits(Path) -> + gleam_erlang_ffi:read_file(Path). + +-spec write(binary(), binary()) -> {ok, nil} | {error, reason()}. +write(Contents, Path) -> + _pipe = Contents, + _pipe@1 = gleam@bit_string:from_string(_pipe), + gleam_erlang_ffi:write_file(_pipe@1, Path). + +-spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. +write_bits(Contents, Path) -> + gleam_erlang_ffi:write_file(Contents, Path). + +-spec append(binary(), binary()) -> {ok, nil} | {error, reason()}. +append(Contents, Path) -> + _pipe = Contents, + _pipe@1 = gleam@bit_string:from_string(_pipe), + gleam_erlang_ffi:append_file(_pipe@1, Path). + +-spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. +append_bits(Contents, Path) -> + gleam_erlang_ffi:append_file(Contents, Path). + +-spec delete(binary()) -> {ok, nil} | {error, reason()}. +delete(Field@0) -> + gleam_erlang_ffi:delete_file(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl new file mode 100644 index 00000000000..8bfcc227db3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl @@ -0,0 +1,27 @@ +-module(gleam@erlang@os). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]). +-export_type([os_family/0]). + +-type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}. + +-spec get_all_env() -> gleam@map:map_(binary(), binary()). +get_all_env() -> + gleam_erlang_ffi:get_all_env(). + +-spec get_env(binary()) -> {ok, binary()} | {error, nil}. +get_env(Field@0) -> + gleam_erlang_ffi:get_env(Field@0). + +-spec set_env(binary(), binary()) -> nil. +set_env(Field@0, Field@1) -> + gleam_erlang_ffi:set_env(Field@0, Field@1). + +-spec unset_env(binary()) -> nil. +unset_env(Field@0) -> + gleam_erlang_ffi:unset_env(Field@0). + +-spec family() -> os_family(). +family() -> + gleam_erlang_ffi:os_family(). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl new file mode 100644 index 00000000000..56f787e638a --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl @@ -0,0 +1,362 @@ +-module(gleam@erlang@process). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([subject_owner/1, self/0, new_subject/0, start/2, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, selecting_process_down/3, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1]). +-export_type([subject/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, cancelled/0, kill_flag/0, pid_/0, do_not_leak/0, selector/1, timer/0]). + +-opaque subject(EZP) :: {subject, pid_(), gleam@erlang:reference_()} | + {gleam_phantom, EZP}. + +-type exit_message() :: {exit_message, pid_(), exit_reason()}. + +-type exit_reason() :: normal | killed | {abnormal, binary()}. + +-type anything_selector_tag() :: anything. + +-type process_monitor_flag() :: process. + +-opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}. + +-type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic()}. + +-type call_error(EZQ) :: {callee_down, gleam@dynamic:dynamic()} | + call_timeout | + {gleam_phantom, EZQ}. + +-type cancelled() :: timer_not_found | {cancelled, integer()}. + +-type kill_flag() :: kill. + +-type pid_() :: any(). + +-type do_not_leak() :: any(). + +-type selector(Payload) :: any() | {gleam_phantom, Payload}. + +-type timer() :: any(). + +-spec subject_owner(subject(any())) -> pid_(). +subject_owner(Subject) -> + erlang:element(2, Subject). + +-spec self() -> pid_(). +self() -> + erlang:self(). + +-spec new_subject() -> subject(any()). +new_subject() -> + {subject, erlang:self(), erlang:make_ref()}. + +-spec start(fun(() -> any()), boolean()) -> pid_(). +start(Implementation, Link) -> + case Link of + true -> + erlang:spawn_link(Implementation); + + false -> + erlang:spawn(Implementation) + end. + +-spec send(subject(EZW), EZW) -> nil. +send(Subject, Message) -> + erlang:send( + erlang:element(2, Subject), + {erlang:element(3, Subject), Message} + ), + nil. + +-spec new_selector() -> selector(any()). +new_selector() -> + gleam_erlang_ffi:new_selector(). + +-spec select(selector(FCK), integer()) -> {ok, FCK} | {error, nil}. +select(Field@0, Field@1) -> + gleam_erlang_ffi:select(Field@0, Field@1). + +-spec select_forever(selector(FCO)) -> FCO. +select_forever(Field@0) -> + gleam_erlang_ffi:select(Field@0). + +-spec map_selector(selector(FCS), fun((FCS) -> FCQ)) -> selector(FCQ). +map_selector(Field@0, Field@1) -> + gleam_erlang_ffi:map_selector(Field@0, Field@1). + +-spec merge_selector(selector(FCU), selector(FCU)) -> selector(FCU). +merge_selector(Field@0, Field@1) -> + gleam_erlang_ffi:merge_selector(Field@0, Field@1). + +-spec flush_messages() -> nil. +flush_messages() -> + gleam_erlang_ffi:flush_messages(). + +-spec selecting_trapped_exits(selector(FAC), fun((exit_message()) -> FAC)) -> selector(FAC). +selecting_trapped_exits(Selector, Handler) -> + Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>), + Handler@1 = fun(Message) -> + Reason = erlang:element(3, Message), + Normal = gleam@dynamic:from(normal), + Killed = gleam@dynamic:from(killed), + Reason@2 = case gleam@dynamic:string(Reason) of + _ when Reason =:= Normal -> + normal; + + _ when Reason =:= Killed -> + killed; + + {ok, Reason@1} -> + {abnormal, Reason@1}; + + {error, _} -> + {abnormal, gleam@string:inspect(Reason)} + end, + Handler({exit_message, erlang:element(2, Message), Reason@2}) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1). + +-spec selecting(selector(FAF), subject(FAH), fun((FAH) -> FAF)) -> selector(FAF). +selecting(Selector, Subject, Transform) -> + Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, + gleam_erlang_ffi:insert_selector_handler( + Selector, + {erlang:element(3, Subject), 2}, + Handler + ). + +-spec 'receive'(subject(EZY), integer()) -> {ok, EZY} | {error, nil}. +'receive'(Subject, Milliseconds) -> + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end), + gleam_erlang_ffi:select(_pipe@1, Milliseconds). + +-spec selecting_record2( + selector(FAK), + any(), + fun((gleam@dynamic:dynamic()) -> FAK) +) -> selector(FAK). +selecting_record2(Selector, Tag, Transform) -> + Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler). + +-spec selecting_record3( + selector(FAO), + any(), + fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAO) +) -> selector(FAO). +selecting_record3(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform(erlang:element(2, Message), erlang:element(3, Message)) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler). + +-spec selecting_record4( + selector(FAS), + any(), + fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAS) +) -> selector(FAS). +selecting_record4(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler). + +-spec selecting_record5( + selector(FAW), + any(), + fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAW) +) -> selector(FAW). +selecting_record5(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler). + +-spec selecting_record6( + selector(FBA), + any(), + fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBA) +) -> selector(FBA). +selecting_record6(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message), + erlang:element(6, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler). + +-spec selecting_record7( + selector(FBE), + any(), + fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBE) +) -> selector(FBE). +selecting_record7(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message), + erlang:element(6, Message), + erlang:element(7, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler). + +-spec selecting_record8( + selector(FBI), + any(), + fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBI) +) -> selector(FBI). +selecting_record8(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message), + erlang:element(6, Message), + erlang:element(7, Message), + erlang:element(8, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler). + +-spec selecting_anything(selector(FBM), fun((gleam@dynamic:dynamic()) -> FBM)) -> selector(FBM). +selecting_anything(Selector, Handler) -> + gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler). + +-spec selecting_process_down( + selector(FBP), + process_monitor(), + fun((process_down()) -> FBP) +) -> selector(FBP). +selecting_process_down(Selector, Monitor, Mapping) -> + gleam_erlang_ffi:insert_selector_handler( + Selector, + erlang:element(2, Monitor), + Mapping + ). + +-spec sleep(integer()) -> nil. +sleep(Field@0) -> + gleam_erlang_ffi:sleep(Field@0). + +-spec sleep_forever() -> nil. +sleep_forever() -> + gleam_erlang_ffi:sleep_forever(). + +-spec is_alive(pid_()) -> boolean(). +is_alive(Field@0) -> + erlang:is_process_alive(Field@0). + +-spec monitor_process(pid_()) -> process_monitor(). +monitor_process(Pid) -> + _pipe = process, + _pipe@1 = erlang:monitor(_pipe, Pid), + {process_monitor, _pipe@1}. + +-spec demonitor_process(process_monitor()) -> nil. +demonitor_process(Field@0) -> + gleam_erlang_ffi:demonitor(Field@0). + +-spec try_call(subject(FBS), fun((subject(FBU)) -> FBS), integer()) -> {ok, FBU} | + {error, call_error(FBU)}. +try_call(Subject, Make_request, Timeout) -> + Reply_subject = new_subject(), + Monitor = monitor_process(subject_owner(Subject)), + send(Subject, Make_request(Reply_subject)), + Result = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = selecting( + _pipe, + Reply_subject, + fun(Field@0) -> {ok, Field@0} end + ), + _pipe@2 = selecting_process_down( + _pipe@1, + Monitor, + fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end + ), + gleam_erlang_ffi:select(_pipe@2, Timeout) + end, + gleam_erlang_ffi:demonitor(Monitor), + case Result of + {error, nil} -> + {error, call_timeout}; + + {ok, Res} -> + Res + end. + +-spec call(subject(FBZ), fun((subject(FCB)) -> FBZ), integer()) -> FCB. +call(Subject, Make_request, Timeout) -> + _assert_subject = try_call(Subject, Make_request, Timeout), + {ok, Resp} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/erlang/process"/utf8>>, + function => <<"call"/utf8>>, + line => 593}) + end, + Resp. + +-spec link(pid_()) -> boolean(). +link(Field@0) -> + gleam_erlang_ffi:link(Field@0). + +-spec unlink(pid_()) -> nil. +unlink(Pid) -> + erlang:unlink(Pid), + nil. + +-spec send_after(subject(FCD), integer(), FCD) -> timer(). +send_after(Subject, Delay, Message) -> + erlang:send_after( + Delay, + erlang:element(2, Subject), + {erlang:element(3, Subject), Message} + ). + +-spec cancel_timer(timer()) -> cancelled(). +cancel_timer(Timer) -> + case gleam@dynamic:int(erlang:cancel_timer(Timer)) of + {ok, I} -> + {cancelled, I}; + + {error, _} -> + timer_not_found + end. + +-spec kill(pid_()) -> nil. +kill(Pid) -> + erlang:exit(Pid, kill), + nil. + +-spec send_exit(pid_()) -> nil. +send_exit(Pid) -> + erlang:exit(Pid, normal), + nil. + +-spec send_abnormal_exit(pid_(), binary()) -> nil. +send_abnormal_exit(Pid, Reason) -> + erlang:exit(Pid, {abnormal, Reason}), + nil. + +-spec trap_exits(boolean()) -> nil. +trap_exits(Field@0) -> + gleam_erlang_ffi:trap_exits(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src new file mode 100644 index 00000000000..7682a9cebe8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src @@ -0,0 +1,13 @@ +{application, gleam_erlang, [ + {vsn, "0.19.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "A Gleam library for working with Erlang"}, + {modules, [gleam@erlang, + gleam@erlang@atom, + gleam@erlang@charlist, + gleam@erlang@file, + gleam@erlang@os, + gleam@erlang@process]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl new file mode 100644 index 00000000000..2c6bd5f09d5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl @@ -0,0 +1,218 @@ +-module(gleam_erlang_ffi). +-export([ + atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, + ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, + append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, + set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, + list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, + insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, + merge_selector/2, flush_messages/0, file_info/1, link_info/1 +]). + +-define(is_posix_error(Error), + Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse + Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse + Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse + Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse + Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse + Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse + Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse + Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse + Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse + Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse + Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse + Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse + Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse + Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse + Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse + Error =:= etxtbsy orelse Error =:= exdev +). + +-spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. +atom_from_string(S) -> + try {ok, binary_to_existing_atom(S)} + catch error:badarg -> {error, atom_not_loaded} + end. + +atom_from_dynamic(Data) when is_atom(Data) -> + {ok, Data}; +atom_from_dynamic(Data) -> + {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. + +-spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. +get_line(Prompt) -> + case io:get_line(Prompt) of + eof -> {error, eof}; + {error, _} -> {error, no_data}; + Data when is_binary(Data) -> {ok, Data}; + Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} + end. + +rescue(F) -> + try {ok, F()} + catch + throw:X -> {error, {thrown, X}}; + error:X -> {error, {errored, X}}; + exit:X -> {error, {exited, X}} + end. + +ensure_all_started(Application) -> + case application:ensure_all_started(Application) of + {ok, _} = Ok -> Ok; + + {error, {ProblemApp, {"no such file or directory", _}}} -> + {error, {unknown_application, ProblemApp}} + end. + +sleep(Microseconds) -> + timer:sleep(Microseconds), + nil. + +sleep_forever() -> + timer:sleep(infinity), + nil. + +file_info_result(Result) -> + case Result of + {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> + {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; + {ok, _} -> + Result; + {error, Reason} when ?is_posix_error(Reason) -> + Result + end. + +file_info(Filename) -> + file_info_result(file:read_file_info(Filename, [{time, posix}])). + +link_info(Filename) -> + file_info_result(file:read_link_info(Filename, [{time, posix}])). + +posix_result(Result) -> + case Result of + ok -> {ok, nil}; + {ok, Value} -> {ok, Value}; + {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} + end. + +read_file(Filename) -> + posix_result(file:read_file(Filename)). + +write_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents)). + +append_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents, [append])). + +delete_file(Filename) -> + posix_result(file:delete(Filename)). + +make_directory(Dir) -> + posix_result(file:make_dir(Dir)). + +list_directory(Dir) -> + case file:list_dir(Dir) of + {ok, Filenames} -> + {ok, [list_to_binary(Filename) || Filename <- Filenames]}; + {error, Reason} when ?is_posix_error(Reason) -> + {error, Reason} + end. + +delete_directory(Dir) -> + posix_result(file:del_dir(Dir)). + +recursive_delete(Dir) -> + posix_result(file:del_dir_r(Dir)). + +get_all_env() -> + BinVars = lists:map(fun(VarString) -> + [VarName, VarVal] = string:split(VarString, "="), + {list_to_binary(VarName), list_to_binary(VarVal)} + end, os:getenv()), + maps:from_list(BinVars). + +get_env(Name) -> + case os:getenv(binary_to_list(Name)) of + false -> {error, nil}; + Value -> {ok, list_to_binary(Value)} + end. + +set_env(Name, Value) -> + os:putenv(binary_to_list(Name), binary_to_list(Value)), + nil. + +unset_env(Name) -> + os:unsetenv(binary_to_list(Name)), + nil. + +os_family() -> + case os:type() of + {win32, nt} -> + windows_nt; + {unix, linux} -> + linux; + {unix, darwin} -> + darwin; + {unix, freebsd} -> + free_bsd; + {_, Other} -> + {other, atom_to_binary(Other, utf8)} + end. + +new_selector() -> + {selector, #{}}. + +map_selector({selector, Handlers}, Fn) -> + MappedHandlers = maps:map(fun(_Tag, Handler) -> + fun(Message) -> Fn(Handler(Message)) end + end, Handlers), + {selector, MappedHandlers}. + +merge_selector({selector, HandlersA}, {selector, HandlersB}) -> + {selector, maps:merge(HandlersA, HandlersB)}. + +insert_selector_handler({selector, Handlers}, Tag, Fn) -> + {selector, Handlers#{Tag => Fn}}. + +select(Selector) -> + {ok, Message} = select(Selector, infinity), + Message. + +select({selector, Handlers}, Timeout) -> + AnythingHandler = maps:get(anything, Handlers, undefined), + receive + % Monitored process down messages. + % This is special cased so we can selectively receive based on the + % reference as well as the record tag. + {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> + Fn = maps:get(Ref, Handlers), + {ok, Fn({process_down, Pid, Reason})}; + + Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> + Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), + {ok, Fn(Msg)}; + + Msg when AnythingHandler =/= undefined -> + {ok, AnythingHandler(Msg)} + after Timeout -> + {error, nil} + end. + +demonitor({_, Reference}) -> + erlang:demonitor(Reference, [flush]). + +link(Pid) -> + try + erlang:link(Pid) + catch + error:_ -> false + end. + +trap_exits(ShouldTrap) -> + erlang:process_flag(trap_exit, ShouldTrap), + nil. + +flush_messages() -> + receive _Message -> flush_messages() + after 0 -> nil + end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/LICENSE b/test-community-packages-javascript/build/packages/gleam_http/LICENSE new file mode 100644 index 00000000000..619ec77e6e1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/LICENSE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2019, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/gleam_http/README.md b/test-community-packages-javascript/build/packages/gleam_http/README.md new file mode 100644 index 00000000000..5c0a7f685a3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/README.md @@ -0,0 +1,65 @@ +# Gleam HTTP + +Types and functions for HTTP clients and servers! + +## HTTP Service Example + +```gleam +import gleam/http/elli +import gleam/http/response.{Response} +import gleam/http/request.{Request} +import gleam/bit_builder.{BitBuilder} + +// Define a HTTP service +// +pub fn my_service(request: Request(t)) -> Response(BitBuilder) { + let body = bit_builder.from_string("Hello, world!") + + response.new(200) + |> response.prepend_header("made-with", "Gleam") + |> response.set_body(body) +} + +// Start it on port 3000 using the Elli web server +// +pub fn main() { + elli.become(my_service, on_port: 3000) +} +``` + +## Server adapters + +In the example above the Elli Erlang web server is used to run the Gleam HTTP +service. Here's a full list of the server adapters available, sorted +alphabetically. + +| Adapter | About | +| --- | --- | +| [gleam_cowboy][cowboy-adapter] | [Cowboy][cowboy] is an Erlang HTTP2 & HTTP1.1 web server | +| [gleam_elli][elli-adapter] | [Elli][elli] is an Erlang HTTP1.1 web server | +| [gleam_plug][plug-adapter] | [Plug][plug] is an Elixir web application interface | + +[cowboy]:https://github.com/ninenines/cowboy +[cowboy-adapter]: https://github.com/gleam-lang/cowboy +[elli]:https://github.com/elli-lib/elli +[elli-adapter]: https://github.com/gleam-lang/elli +[plug]:https://github.com/elixir-plug/plug +[plug-adapter]: https://github.com/gleam-lang/plug + +## Client adapters + +Client adapters are used to send HTTP requests to services over the network. +Here's a full list of the client adapters available, sorted alphabetically. + +| Adapter | About | +| --- | --- | +| [gleam_fetch][fetch-adapter] | [fetch][fetch] is a HTTP client included with JavaScript | +| [gleam_hackney][hackney-adapter] | [Hackney][hackney] is a simple HTTP client for Erlang | +| [gleam_httpc][httpc-adapter] | [httpc][httpc] is a HTTP client included with Erlang | + +[hackney]: https://github.com/benoitc/hackney +[hackney-adapter]: https://github.com/gleam-lang/hackney +[httpc]: https://erlang.org/doc/man/httpc.html +[httpc-adapter]: https://github.com/gleam-lang/httpc +[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API +[fetch-adapter]: https://github.com/gleam-lang/fetch diff --git a/test-community-packages-javascript/build/packages/gleam_http/gleam.toml b/test-community-packages-javascript/build/packages/gleam_http/gleam.toml new file mode 100644 index 00000000000..6955a79b2ed --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/gleam.toml @@ -0,0 +1,16 @@ +name = "gleam_http" +version = "3.2.0" +licences = ["Apache-2.0"] +description = "Types and functions for Gleam HTTP clients and servers" + +repository = { type = "github", user = "gleam-lang", repo = "http" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[dependencies] +gleam_stdlib = "~> 0.18" + +[dev-dependencies] +gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl new file mode 100644 index 00000000000..78a7d02c930 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl @@ -0,0 +1,8 @@ +-record(attributes, { + max_age :: gleam@option:option(integer()), + domain :: gleam@option:option(binary()), + path :: gleam@option:option(binary()), + secure :: boolean(), + http_only :: boolean(), + same_site :: gleam@option:option(gleam@http@cookie:same_site_policy()) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl new file mode 100644 index 00000000000..c8bbae649d5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl @@ -0,0 +1,10 @@ +-record(request, { + method :: gleam@http:method(), + headers :: list({binary(), binary()}), + body :: any(), + scheme :: gleam@http:scheme(), + host :: binary(), + port :: gleam@option:option(integer()), + path :: binary(), + 'query' :: gleam@option:option(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl new file mode 100644 index 00000000000..ba6f07701c7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl @@ -0,0 +1,5 @@ +-record(response, { + status :: integer(), + headers :: list({binary(), binary()}), + body :: any() +}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam new file mode 100644 index 00000000000..ec17246b90f --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam @@ -0,0 +1,122 @@ +//// Functions for working with HTTP data structures in Gleam. +//// +//// This module makes it easy to create and modify Requests and Responses, data types. +//// A general HTTP message type is defined that enables functions to work on both requests and responses. +//// +//// This module does not implement a HTTP client or HTTP server, but it can be used as a base for them. + +import gleam/dynamic.{DecodeError, Dynamic} +import gleam/string + +/// HTTP standard method as defined by [RFC 2616](https://tools.ietf.org/html/rfc2616), +/// and PATCH which is defined by [RFC 5789](https://tools.ietf.org/html/rfc5789). +pub type Method { + Get + Post + Head + Put + Delete + Trace + Connect + Options + Patch + + /// Non-standard but valid HTTP methods. + Other(String) +} + +// TODO: check if the a is a valid HTTP method (i.e. it is a token, as per the +// spec) and return Ok(Other(s)) if so. +pub fn parse_method(s) -> Result(Method, Nil) { + case string.lowercase(s) { + "connect" -> Ok(Connect) + "delete" -> Ok(Delete) + "get" -> Ok(Get) + "head" -> Ok(Head) + "options" -> Ok(Options) + "patch" -> Ok(Patch) + "post" -> Ok(Post) + "put" -> Ok(Put) + "trace" -> Ok(Trace) + _ -> Error(Nil) + } +} + +pub fn method_to_string(method: Method) -> String { + case method { + Connect -> "connect" + Delete -> "delete" + Get -> "get" + Head -> "head" + Options -> "options" + Patch -> "patch" + Post -> "post" + Put -> "put" + Trace -> "trace" + Other(s) -> s + } +} + +/// The two URI schemes for HTTP +/// +pub type Scheme { + Http + Https +} + +/// Convert a scheme into a string. +/// +/// # Examples +/// +/// > scheme_to_string(Http) +/// "http" +/// +/// > scheme_to_string(Https) +/// "https" +/// +pub fn scheme_to_string(scheme: Scheme) -> String { + case scheme { + Http -> "http" + Https -> "https" + } +} + +/// Parse a HTTP scheme from a string +/// +/// # Examples +/// +/// > scheme_to_string("http") +/// Ok(Http) +/// +/// > scheme_to_string("ftp") +/// Error(Nil) +/// +pub fn scheme_from_string(scheme: String) -> Result(Scheme, Nil) { + case string.lowercase(scheme) { + "http" -> Ok(Http) + "https" -> Ok(Https) + _ -> Error(Nil) + } +} + +pub fn method_from_dynamic(value: Dynamic) -> Result(Method, List(DecodeError)) { + case do_method_from_dynamic(value) { + Ok(method) -> Ok(method) + Error(_) -> Error([DecodeError("HTTP method", dynamic.classify(value), [])]) + } +} + +if erlang { + external fn do_method_from_dynamic(Dynamic) -> Result(Method, nil) = + "gleam_http_native" "decode_method" +} + +if javascript { + external fn do_method_from_dynamic(Dynamic) -> Result(Method, Nil) = + "../gleam_http_native.mjs" "decode_method" +} + +/// A HTTP header is a key-value pair. Header keys should be all lowercase +/// characters. +pub type Header = + #(String, String) diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam new file mode 100644 index 00000000000..79c9faf4917 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam @@ -0,0 +1,128 @@ +import gleam/result +import gleam/int +import gleam/list +import gleam/regex +import gleam/string +import gleam/option.{Option, Some} +import gleam/http.{Scheme} + +/// Policy options for the SameSite cookie attribute +/// +/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite +pub type SameSitePolicy { + Lax + Strict + None +} + +fn same_site_to_string(policy) { + case policy { + Lax -> "Lax" + Strict -> "Strict" + None -> "None" + } +} + +/// Attributes of a cookie when sent to a client in the `set-cookie` header. +pub type Attributes { + Attributes( + max_age: Option(Int), + domain: Option(String), + path: Option(String), + secure: Bool, + http_only: Bool, + same_site: Option(SameSitePolicy), + ) +} + +/// Helper to create sensible default attributes for a set cookie. +/// +/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Attributes +pub fn defaults(scheme: Scheme) { + Attributes( + max_age: option.None, + domain: option.None, + path: option.Some("/"), + secure: scheme == http.Https, + http_only: True, + same_site: Some(Lax), + ) +} + +const epoch = "Expires=Thu, 01 Jan 1970 00:00:00 GMT" + +fn cookie_attributes_to_list(attributes) { + let Attributes( + max_age: max_age, + domain: domain, + path: path, + secure: secure, + http_only: http_only, + same_site: same_site, + ) = attributes + [ + // Expires is a deprecated attribute for cookies, it has been replaced with MaxAge + // MaxAge is widely supported and so Expires values are not set. + // Only when deleting cookies is the exception made to use the old format, + // to ensure complete clearup of cookies if required by an application. + case max_age { + option.Some(0) -> option.Some([epoch]) + _ -> option.None + }, + option.map(max_age, fn(max_age) { ["Max-Age=", int.to_string(max_age)] }), + option.map(domain, fn(domain) { ["Domain=", domain] }), + option.map(path, fn(path) { ["Path=", path] }), + case secure { + True -> option.Some(["Secure"]) + False -> option.None + }, + case http_only { + True -> option.Some(["HttpOnly"]) + False -> option.None + }, + option.map( + same_site, + fn(same_site) { ["SameSite=", same_site_to_string(same_site)] }, + ), + ] + |> list.filter_map(option.to_result(_, Nil)) +} + +pub fn set_header(name: String, value: String, attributes: Attributes) -> String { + [[name, "=", value], ..cookie_attributes_to_list(attributes)] + |> list.map(string.join(_, "")) + |> string.join("; ") +} + +/// Parse a list of cookies from a header string. Any malformed cookies will be +/// discarded. +/// +pub fn parse(cookie_string: String) -> List(#(String, String)) { + let assert Ok(re) = regex.from_string("[,;]") + regex.split(re, cookie_string) + |> list.filter_map(fn(pair) { + case string.split_once(string.trim(pair), "=") { + Ok(#("", _)) -> Error(Nil) + Ok(#(key, value)) -> { + let key = string.trim(key) + let value = string.trim(value) + use _ <- result.then(check_token(key)) + use _ <- result.then(check_token(value)) + Ok(#(key, value)) + } + Error(Nil) -> Error(Nil) + } + }) +} + +fn check_token(token: String) -> Result(Nil, Nil) { + case string.pop_grapheme(token) { + Error(Nil) -> Ok(Nil) + Ok(#(" ", _)) -> Error(Nil) + Ok(#("\t", _)) -> Error(Nil) + Ok(#("\r", _)) -> Error(Nil) + Ok(#("\n", _)) -> Error(Nil) + Ok(#("\f", _)) -> Error(Nil) + Ok(#(_, rest)) -> check_token(rest) + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam new file mode 100644 index 00000000000..f4fbe9bc30c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam @@ -0,0 +1,258 @@ +import gleam/result +// TODO: validate_req +import gleam/http.{Get, Header, Method, Scheme} +import gleam/http/cookie +import gleam/option.{None, Option, Some} +import gleam/uri.{Uri} +import gleam/list +import gleam/string +import gleam/string_builder + +// TODO: document +pub type Request(body) { + Request( + method: Method, + headers: List(Header), + body: body, + scheme: Scheme, + host: String, + port: Option(Int), + path: String, + query: Option(String), + ) +} + +/// Return the uri that a request was sent to. +/// +pub fn to_uri(request: Request(a)) -> Uri { + Uri( + scheme: option.Some(http.scheme_to_string(request.scheme)), + userinfo: option.None, + host: option.Some(request.host), + port: request.port, + path: request.path, + query: request.query, + fragment: option.None, + ) +} + +/// Construct a request from a URI. +/// +pub fn from_uri(uri: Uri) -> Result(Request(String), Nil) { + use scheme <- result.then( + uri.scheme + |> option.unwrap("") + |> http.scheme_from_string, + ) + use host <- result.then( + uri.host + |> option.to_result(Nil), + ) + let req = + Request( + method: Get, + headers: [], + body: "", + scheme: scheme, + host: host, + port: uri.port, + path: uri.path, + query: uri.query, + ) + Ok(req) +} + +/// Get the value for a given header. +/// +/// If the request does not have that header then `Error(Nil)` is returned. +/// +pub fn get_header(request: Request(body), key: String) -> Result(String, Nil) { + list.key_find(request.headers, string.lowercase(key)) +} + +/// Set the header with the given value under the given header key. +/// +/// If already present, it is replaced. +pub fn set_header( + request: Request(body), + key: String, + value: String, +) -> Request(body) { + let headers = list.key_set(request.headers, string.lowercase(key), value) + Request(..request, headers: headers) +} + +/// Prepend the header with the given value under the given header key. +/// +/// Similar to `set_header` except if the header already exists it prepends +/// another header with the same key. +pub fn prepend_header( + request: Request(body), + key: String, + value: String, +) -> Request(body) { + let headers = [#(string.lowercase(key), value), ..request.headers] + Request(..request, headers: headers) +} + +// TODO: record update syntax, which can't be done currently as body type changes +/// Set the body of the request, overwriting any existing body. +/// +pub fn set_body(req: Request(old_body), body: new_body) -> Request(new_body) { + let Request( + method: method, + headers: headers, + scheme: scheme, + host: host, + port: port, + path: path, + query: query, + .., + ) = req + Request( + method: method, + headers: headers, + body: body, + scheme: scheme, + host: host, + port: port, + path: path, + query: query, + ) +} + +/// Update the body of a request using a given function. +/// +pub fn map( + request: Request(old_body), + transform: fn(old_body) -> new_body, +) -> Request(new_body) { + request.body + |> transform + |> set_body(request, _) +} + +/// Return the non-empty segments of a request path. +/// +pub fn path_segments(request: Request(body)) -> List(String) { + request.path + |> uri.path_segments +} + +/// Decode the query of a request. +pub fn get_query(request: Request(body)) -> Result(List(#(String, String)), Nil) { + case request.query { + option.Some(query_string) -> uri.parse_query(query_string) + option.None -> Ok([]) + } +} + +// TODO: escape +/// Set the query of the request. +/// +pub fn set_query( + req: Request(body), + query: List(#(String, String)), +) -> Request(body) { + let pair = fn(t: #(String, String)) { + string_builder.from_strings([t.0, "=", t.1]) + } + let query = + query + |> list.map(pair) + |> list.intersperse(string_builder.from_string("&")) + |> string_builder.concat + |> string_builder.to_string + |> option.Some + Request(..req, query: query) +} + +/// Set the method of the request. +/// +pub fn set_method(req: Request(body), method: Method) -> Request(body) { + Request(..req, method: method) +} + +/// A request with commonly used default values. This request can be used as +/// an initial value and then update to create the desired request. +/// +pub fn new() -> Request(String) { + Request( + method: Get, + headers: [], + body: "", + scheme: http.Https, + host: "localhost", + port: option.None, + path: "", + query: option.None, + ) +} + +/// Construct a request from a URL string +/// +pub fn to(url: String) -> Result(Request(String), Nil) { + url + |> uri.parse + |> result.then(from_uri) +} + +/// Set the scheme (protocol) of the request. +/// +pub fn set_scheme(req: Request(body), scheme: Scheme) -> Request(body) { + Request(..req, scheme: scheme) +} + +/// Set the method of the request. +/// +pub fn set_host(req: Request(body), host: String) -> Request(body) { + Request(..req, host: host) +} + +/// Set the port of the request. +/// +pub fn set_port(req: Request(body), port: Int) -> Request(body) { + Request(..req, port: option.Some(port)) +} + +/// Set the path of the request. +/// +pub fn set_path(req: Request(body), path: String) -> Request(body) { + Request(..req, path: path) +} + +/// Send a cookie with a request +/// +/// Multiple cookies are added to the same cookie header. +pub fn set_cookie(req: Request(body), name: String, value: String) { + let new_cookie_string = string.join([name, value], "=") + + let #(cookies_string, headers) = case list.key_pop(req.headers, "cookie") { + Ok(#(cookies_string, headers)) -> { + let cookies_string = + string.join([cookies_string, new_cookie_string], "; ") + #(cookies_string, headers) + } + Error(Nil) -> #(new_cookie_string, req.headers) + } + + Request(..req, headers: [#("cookie", cookies_string), ..headers]) +} + +/// Fetch the cookies sent in a request. +/// +/// Note badly formed cookie pairs will be ignored. +/// RFC6265 specifies that invalid cookie names/attributes should be ignored. +pub fn get_cookies(req) -> List(#(String, String)) { + let Request(headers: headers, ..) = req + + headers + |> list.filter_map(fn(header) { + let #(name, value) = header + case name { + "cookie" -> Ok(cookie.parse(value)) + _ -> Error(Nil) + } + }) + |> list.flatten() +} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam new file mode 100644 index 00000000000..56f42d19b2c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam @@ -0,0 +1,141 @@ +import gleam/result +import gleam/http.{Header} +import gleam/http/cookie +import gleam/list +import gleam/string +import gleam/option + +// TODO: document +pub type Response(body) { + Response(status: Int, headers: List(Header), body: body) +} + +/// Update the body of a response using a given result returning function. +/// +/// If the given function returns an `Ok` value the body is set, if it returns +/// an `Error` value then the error is returned. +/// +pub fn try_map( + response: Response(old_body), + transform: fn(old_body) -> Result(new_body, error), +) -> Result(Response(new_body), error) { + use body <- result.then(transform(response.body)) + Ok(set_body(response, body)) +} + +/// Construct an empty Response. +/// +/// The body type of the returned response is `String` and could be set with a +/// call to `set_body`. +/// +pub fn new(status: Int) -> Response(String) { + Response(status: status, headers: [], body: "") +} + +/// Get the value for a given header. +/// +/// If the response does not have that header then `Error(Nil)` is returned. +/// +pub fn get_header(response: Response(body), key: String) -> Result(String, Nil) { + list.key_find(response.headers, string.lowercase(key)) +} + +/// Set the header with the given value under the given header key. +/// +/// If the response already has that key, it is replaced. +pub fn set_header( + response: Response(body), + key: String, + value: String, +) -> Response(body) { + let headers = list.key_set(response.headers, key, string.lowercase(value)) + Response(..response, headers: headers) +} + +/// Prepend the header with the given value under the given header key. +/// +/// Similar to `set_header` except if the header already exists it prepends +/// another header with the same key. +pub fn prepend_header( + response: Response(body), + key: String, + value: String, +) -> Response(body) { + let headers = [#(string.lowercase(key), value), ..response.headers] + Response(..response, headers: headers) +} + +/// Set the body of the response, overwriting any existing body. +/// +pub fn set_body( + response: Response(old_body), + body: new_body, +) -> Response(new_body) { + let Response(status: status, headers: headers, ..) = response + Response(status: status, headers: headers, body: body) +} + +/// Update the body of a response using a given function. +/// +pub fn map( + response: Response(old_body), + transform: fn(old_body) -> new_body, +) -> Response(new_body) { + response.body + |> transform + |> set_body(response, _) +} + +/// Create a response that redirects to the given uri. +/// +pub fn redirect(uri: String) -> Response(String) { + Response( + status: 303, + headers: [#("location", uri)], + body: string.append("You are being redirected to ", uri), + ) +} + +/// Fetch the cookies sent in a response. +/// +/// Badly formed cookies will be discarded. +/// +pub fn get_cookies(resp) -> List(#(String, String)) { + let Response(headers: headers, ..) = resp + headers + |> list.filter_map(fn(header) { + let #(name, value) = header + case name { + "set-cookie" -> Ok(cookie.parse(value)) + _ -> Error(Nil) + } + }) + |> list.flatten() +} + +/// Set a cookie value for a client +/// +pub fn set_cookie( + response: Response(t), + name: String, + value: String, + attributes: cookie.Attributes, +) -> Response(t) { + prepend_header( + response, + "set-cookie", + cookie.set_header(name, value, attributes), + ) +} + +/// Expire a cookie value for a client +/// +/// Note: The attributes value should be the same as when the response cookie was set. +pub fn expire_cookie( + response: Response(t), + name: String, + attributes: cookie.Attributes, +) -> Response(t) { + let attrs = cookie.Attributes(..attributes, max_age: option.Some(0)) + set_cookie(response, name, "", attrs) +} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam new file mode 100644 index 00000000000..fddf362b525 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam @@ -0,0 +1,82 @@ +import gleam/http.{Delete, Patch, Post, Put} +import gleam/http/request.{Request} +import gleam/http/response.{Response} +import gleam/list +import gleam/result + +// TODO: document +pub type Service(in, out) = + fn(Request(in)) -> Response(out) + +pub type Middleware(before_req, before_resp, after_req, after_resp) = + fn(Service(before_req, before_resp)) -> Service(after_req, after_resp) + +/// A middleware that transform the response body returned by the service using +/// a given function. +/// +pub fn map_response_body( + service: Service(req, a), + with mapper: fn(a) -> b, +) -> Service(req, b) { + fn(req) { + req + |> service + |> response.map(mapper) + } +} + +/// A middleware that prepends a header to the request. +/// +pub fn prepend_response_header( + service: Service(req, resp), + key: String, + value: String, +) -> Service(req, resp) { + fn(req) { + req + |> service + |> response.prepend_header(key, value) + } +} + +fn ensure_post(req: Request(a)) { + case req.method { + Post -> Ok(req) + _ -> Error(Nil) + } +} + +fn get_override_method(request: Request(t)) -> Result(http.Method, Nil) { + use query_params <- result.then(request.get_query(request)) + use method <- result.then(list.key_find(query_params, "_method")) + use method <- result.then(http.parse_method(method)) + case method { + Put | Patch | Delete -> Ok(method) + _ -> Error(Nil) + } +} + +/// A middleware that overrides an incoming POST request with a method given in +/// the request's `_method` query paramerter. This is useful as web browsers +/// typically only support GET and POST requests, but our application may +/// expect other HTTP methods that are more semantically correct. +/// +/// The methods PUT, PATCH, and DELETE are accepted for overriding, all others +/// are ignored. +/// +/// The `_method` query paramerter can be specified in a HTML form like so: +/// +///
+/// +///
+/// +pub fn method_override(service: Service(req, resp)) -> Service(req, resp) { + fn(request) { + request + |> ensure_post + |> result.then(get_override_method) + |> result.map(request.set_method(request, _)) + |> result.unwrap(request) + |> service + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl new file mode 100644 index 00000000000..3baae58a314 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl @@ -0,0 +1,124 @@ +-module(gleam@http). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([parse_method/1, method_to_string/1, scheme_to_string/1, scheme_from_string/1, method_from_dynamic/1]). +-export_type([method/0, scheme/0]). + +-type method() :: get | + post | + head | + put | + delete | + trace | + connect | + options | + patch | + {other, binary()}. + +-type scheme() :: http | https. + +-spec parse_method(binary()) -> {ok, method()} | {error, nil}. +parse_method(S) -> + case gleam@string:lowercase(S) of + <<"connect"/utf8>> -> + {ok, connect}; + + <<"delete"/utf8>> -> + {ok, delete}; + + <<"get"/utf8>> -> + {ok, get}; + + <<"head"/utf8>> -> + {ok, head}; + + <<"options"/utf8>> -> + {ok, options}; + + <<"patch"/utf8>> -> + {ok, patch}; + + <<"post"/utf8>> -> + {ok, post}; + + <<"put"/utf8>> -> + {ok, put}; + + <<"trace"/utf8>> -> + {ok, trace}; + + _ -> + {error, nil} + end. + +-spec method_to_string(method()) -> binary(). +method_to_string(Method) -> + case Method of + connect -> + <<"connect"/utf8>>; + + delete -> + <<"delete"/utf8>>; + + get -> + <<"get"/utf8>>; + + head -> + <<"head"/utf8>>; + + options -> + <<"options"/utf8>>; + + patch -> + <<"patch"/utf8>>; + + post -> + <<"post"/utf8>>; + + put -> + <<"put"/utf8>>; + + trace -> + <<"trace"/utf8>>; + + {other, S} -> + S + end. + +-spec scheme_to_string(scheme()) -> binary(). +scheme_to_string(Scheme) -> + case Scheme of + http -> + <<"http"/utf8>>; + + https -> + <<"https"/utf8>> + end. + +-spec scheme_from_string(binary()) -> {ok, scheme()} | {error, nil}. +scheme_from_string(Scheme) -> + case gleam@string:lowercase(Scheme) of + <<"http"/utf8>> -> + {ok, http}; + + <<"https"/utf8>> -> + {ok, https}; + + _ -> + {error, nil} + end. + +-spec method_from_dynamic(gleam@dynamic:dynamic()) -> {ok, method()} | + {error, list(gleam@dynamic:decode_error())}. +method_from_dynamic(Value) -> + case gleam_http_native:decode_method(Value) of + {ok, Method} -> + {ok, Method}; + + {error, _} -> + {error, + [{decode_error, + <<"HTTP method"/utf8>>, + gleam@dynamic:classify(Value), + []}]} + end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl new file mode 100644 index 00000000000..f7451c7ada6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl @@ -0,0 +1,153 @@ +-module(gleam@http@cookie). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([defaults/1, set_header/3, parse/1]). +-export_type([same_site_policy/0, attributes/0]). + +-type same_site_policy() :: lax | strict | none. + +-type attributes() :: {attributes, + gleam@option:option(integer()), + gleam@option:option(binary()), + gleam@option:option(binary()), + boolean(), + boolean(), + gleam@option:option(same_site_policy())}. + +-spec same_site_to_string(same_site_policy()) -> binary(). +same_site_to_string(Policy) -> + case Policy of + lax -> + <<"Lax"/utf8>>; + + strict -> + <<"Strict"/utf8>>; + + none -> + <<"None"/utf8>> + end. + +-spec defaults(gleam@http:scheme()) -> attributes(). +defaults(Scheme) -> + {attributes, + none, + none, + {some, <<"/"/utf8>>}, + Scheme =:= https, + true, + {some, lax}}. + +-spec cookie_attributes_to_list(attributes()) -> list(list(binary())). +cookie_attributes_to_list(Attributes) -> + {attributes, Max_age, Domain, Path, Secure, Http_only, Same_site} = Attributes, + _pipe = [case Max_age of + {some, 0} -> + {some, [<<"Expires=Thu, 01 Jan 1970 00:00:00 GMT"/utf8>>]}; + + _ -> + none + end, gleam@option:map( + Max_age, + fun(Max_age@1) -> + [<<"Max-Age="/utf8>>, gleam@int:to_string(Max_age@1)] + end + ), gleam@option:map( + Domain, + fun(Domain@1) -> [<<"Domain="/utf8>>, Domain@1] end + ), gleam@option:map(Path, fun(Path@1) -> [<<"Path="/utf8>>, Path@1] end), case Secure of + true -> + {some, [<<"Secure"/utf8>>]}; + + false -> + none + end, case Http_only of + true -> + {some, [<<"HttpOnly"/utf8>>]}; + + false -> + none + end, gleam@option:map( + Same_site, + fun(Same_site@1) -> + [<<"SameSite="/utf8>>, same_site_to_string(Same_site@1)] + end + )], + gleam@list:filter_map( + _pipe, + fun(_capture) -> gleam@option:to_result(_capture, nil) end + ). + +-spec set_header(binary(), binary(), attributes()) -> binary(). +set_header(Name, Value, Attributes) -> + _pipe = [[Name, <<"="/utf8>>, Value] | + cookie_attributes_to_list(Attributes)], + _pipe@1 = gleam@list:map( + _pipe, + fun(_capture) -> gleam@string:join(_capture, <<""/utf8>>) end + ), + gleam@string:join(_pipe@1, <<"; "/utf8>>). + +-spec check_token(binary()) -> {ok, nil} | {error, nil}. +check_token(Token) -> + case gleam@string:pop_grapheme(Token) of + {error, nil} -> + {ok, nil}; + + {ok, {<<" "/utf8>>, _}} -> + {error, nil}; + + {ok, {<<"\t"/utf8>>, _}} -> + {error, nil}; + + {ok, {<<"\r"/utf8>>, _}} -> + {error, nil}; + + {ok, {<<"\n"/utf8>>, _}} -> + {error, nil}; + + {ok, {<<"\f"/utf8>>, _}} -> + {error, nil}; + + {ok, {_, Rest}} -> + check_token(Rest) + end. + +-spec parse(binary()) -> list({binary(), binary()}). +parse(Cookie_string) -> + _assert_subject = gleam@regex:from_string(<<"[,;]"/utf8>>), + {ok, Re} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/http/cookie"/utf8>>, + function => <<"parse"/utf8>>, + line => 101}) + end, + _pipe = gleam@regex:split(Re, Cookie_string), + gleam@list:filter_map( + _pipe, + fun(Pair) -> + case gleam@string:split_once(gleam@string:trim(Pair), <<"="/utf8>>) of + {ok, {<<""/utf8>>, _}} -> + {error, nil}; + + {ok, {Key, Value}} -> + Key@1 = gleam@string:trim(Key), + Value@1 = gleam@string:trim(Value), + gleam@result:then( + check_token(Key@1), + fun(_) -> + gleam@result:then( + check_token(Value@1), + fun(_) -> {ok, {Key@1, Value@1}} end + ) + end + ); + + {error, nil} -> + {error, nil} + end + end + ). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl new file mode 100644 index 00000000000..97616ed4506 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl @@ -0,0 +1,202 @@ +-module(gleam@http@request). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_uri/1, from_uri/1, get_header/2, set_header/3, prepend_header/3, set_body/2, map/2, path_segments/1, get_query/1, set_query/2, set_method/2, new/0, to/1, set_scheme/2, set_host/2, set_port/2, set_path/2, set_cookie/3, get_cookies/1]). +-export_type([request/1]). + +-type request(FBL) :: {request, + gleam@http:method(), + list({binary(), binary()}), + FBL, + gleam@http:scheme(), + binary(), + gleam@option:option(integer()), + binary(), + gleam@option:option(binary())}. + +-spec to_uri(request(any())) -> gleam@uri:uri(). +to_uri(Request) -> + {uri, + {some, gleam@http:scheme_to_string(erlang:element(5, Request))}, + none, + {some, erlang:element(6, Request)}, + erlang:element(7, Request), + erlang:element(8, Request), + erlang:element(9, Request), + none}. + +-spec from_uri(gleam@uri:uri()) -> {ok, request(binary())} | {error, nil}. +from_uri(Uri) -> + gleam@result:then( + begin + _pipe = erlang:element(2, Uri), + _pipe@1 = gleam@option:unwrap(_pipe, <<""/utf8>>), + gleam@http:scheme_from_string(_pipe@1) + end, + fun(Scheme) -> + gleam@result:then( + begin + _pipe@2 = erlang:element(4, Uri), + gleam@option:to_result(_pipe@2, nil) + end, + fun(Host) -> + Req = {request, + get, + [], + <<""/utf8>>, + Scheme, + Host, + erlang:element(5, Uri), + erlang:element(6, Uri), + erlang:element(7, Uri)}, + {ok, Req} + end + ) + end + ). + +-spec get_header(request(any()), binary()) -> {ok, binary()} | {error, nil}. +get_header(Request, Key) -> + gleam@list:key_find(erlang:element(3, Request), gleam@string:lowercase(Key)). + +-spec set_header(request(FBV), binary(), binary()) -> request(FBV). +set_header(Request, Key, Value) -> + Headers = gleam@list:key_set( + erlang:element(3, Request), + gleam@string:lowercase(Key), + Value + ), + erlang:setelement(3, Request, Headers). + +-spec prepend_header(request(FBY), binary(), binary()) -> request(FBY). +prepend_header(Request, Key, Value) -> + Headers = [{gleam@string:lowercase(Key), Value} | + erlang:element(3, Request)], + erlang:setelement(3, Request, Headers). + +-spec set_body(request(any()), FCD) -> request(FCD). +set_body(Req, Body) -> + {request, Method, Headers, _, Scheme, Host, Port, Path, Query} = Req, + {request, Method, Headers, Body, Scheme, Host, Port, Path, Query}. + +-spec map(request(FCF), fun((FCF) -> FCH)) -> request(FCH). +map(Request, Transform) -> + _pipe = erlang:element(4, Request), + _pipe@1 = Transform(_pipe), + set_body(Request, _pipe@1). + +-spec path_segments(request(any())) -> list(binary()). +path_segments(Request) -> + _pipe = erlang:element(8, Request), + gleam@uri:path_segments(_pipe). + +-spec get_query(request(any())) -> {ok, list({binary(), binary()})} | + {error, nil}. +get_query(Request) -> + case erlang:element(9, Request) of + {some, Query_string} -> + gleam@uri:parse_query(Query_string); + + none -> + {ok, []} + end. + +-spec set_query(request(FCR), list({binary(), binary()})) -> request(FCR). +set_query(Req, Query) -> + Pair = fun(T) -> + gleam@string_builder:from_strings( + [erlang:element(1, T), <<"="/utf8>>, erlang:element(2, T)] + ) + end, + Query@1 = begin + _pipe = Query, + _pipe@1 = gleam@list:map(_pipe, Pair), + _pipe@2 = gleam@list:intersperse( + _pipe@1, + gleam@string_builder:from_string(<<"&"/utf8>>) + ), + _pipe@3 = gleam@string_builder:concat(_pipe@2), + _pipe@4 = gleam@string_builder:to_string(_pipe@3), + {some, _pipe@4} + end, + erlang:setelement(9, Req, Query@1). + +-spec set_method(request(FCV), gleam@http:method()) -> request(FCV). +set_method(Req, Method) -> + erlang:setelement(2, Req, Method). + +-spec new() -> request(binary()). +new() -> + {request, + get, + [], + <<""/utf8>>, + https, + <<"localhost"/utf8>>, + none, + <<""/utf8>>, + none}. + +-spec to(binary()) -> {ok, request(binary())} | {error, nil}. +to(Url) -> + _pipe = Url, + _pipe@1 = gleam@uri:parse(_pipe), + gleam@result:then(_pipe@1, fun from_uri/1). + +-spec set_scheme(request(FDC), gleam@http:scheme()) -> request(FDC). +set_scheme(Req, Scheme) -> + erlang:setelement(5, Req, Scheme). + +-spec set_host(request(FDF), binary()) -> request(FDF). +set_host(Req, Host) -> + erlang:setelement(6, Req, Host). + +-spec set_port(request(FDI), integer()) -> request(FDI). +set_port(Req, Port) -> + erlang:setelement(7, Req, {some, Port}). + +-spec set_path(request(FDL), binary()) -> request(FDL). +set_path(Req, Path) -> + erlang:setelement(8, Req, Path). + +-spec set_cookie(request(FDO), binary(), binary()) -> request(FDO). +set_cookie(Req, Name, Value) -> + New_cookie_string = gleam@string:join([Name, Value], <<"="/utf8>>), + {Cookies_string@2, Headers@1} = case gleam@list:key_pop( + erlang:element(3, Req), + <<"cookie"/utf8>> + ) of + {ok, {Cookies_string, Headers}} -> + Cookies_string@1 = gleam@string:join( + [Cookies_string, New_cookie_string], + <<"; "/utf8>> + ), + {Cookies_string@1, Headers}; + + {error, nil} -> + {New_cookie_string, erlang:element(3, Req)} + end, + erlang:setelement( + 3, + Req, + [{<<"cookie"/utf8>>, Cookies_string@2} | Headers@1] + ). + +-spec get_cookies(request(any())) -> list({binary(), binary()}). +get_cookies(Req) -> + {request, _, Headers, _, _, _, _, _, _} = Req, + _pipe = Headers, + _pipe@1 = gleam@list:filter_map( + _pipe, + fun(Header) -> + {Name, Value} = Header, + case Name of + <<"cookie"/utf8>> -> + {ok, gleam@http@cookie:parse(Value)}; + + _ -> + {error, nil} + end + end + ), + gleam@list:flatten(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl new file mode 100644 index 00000000000..1769c814143 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl @@ -0,0 +1,97 @@ +-module(gleam@http@response). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, get_header/2, set_header/3, prepend_header/3, set_body/2, try_map/2, map/2, redirect/1, get_cookies/1, set_cookie/4, expire_cookie/3]). +-export_type([response/1]). + +-type response(FIP) :: {response, integer(), list({binary(), binary()}), FIP}. + +-spec new(integer()) -> response(binary()). +new(Status) -> + {response, Status, [], <<""/utf8>>}. + +-spec get_header(response(any()), binary()) -> {ok, binary()} | {error, nil}. +get_header(Response, Key) -> + gleam@list:key_find( + erlang:element(3, Response), + gleam@string:lowercase(Key) + ). + +-spec set_header(response(FJE), binary(), binary()) -> response(FJE). +set_header(Response, Key, Value) -> + Headers = gleam@list:key_set( + erlang:element(3, Response), + Key, + gleam@string:lowercase(Value) + ), + erlang:setelement(3, Response, Headers). + +-spec prepend_header(response(FJH), binary(), binary()) -> response(FJH). +prepend_header(Response, Key, Value) -> + Headers = [{gleam@string:lowercase(Key), Value} | + erlang:element(3, Response)], + erlang:setelement(3, Response, Headers). + +-spec set_body(response(any()), FJM) -> response(FJM). +set_body(Response, Body) -> + {response, Status, Headers, _} = Response, + {response, Status, Headers, Body}. + +-spec try_map(response(FIQ), fun((FIQ) -> {ok, FIS} | {error, FIT})) -> {ok, + response(FIS)} | + {error, FIT}. +try_map(Response, Transform) -> + gleam@result:then( + Transform(erlang:element(4, Response)), + fun(Body) -> {ok, set_body(Response, Body)} end + ). + +-spec map(response(FJO), fun((FJO) -> FJQ)) -> response(FJQ). +map(Response, Transform) -> + _pipe = erlang:element(4, Response), + _pipe@1 = Transform(_pipe), + set_body(Response, _pipe@1). + +-spec redirect(binary()) -> response(binary()). +redirect(Uri) -> + {response, + 303, + [{<<"location"/utf8>>, Uri}], + gleam@string:append(<<"You are being redirected to "/utf8>>, Uri)}. + +-spec get_cookies(response(any())) -> list({binary(), binary()}). +get_cookies(Resp) -> + {response, _, Headers, _} = Resp, + _pipe = Headers, + _pipe@1 = gleam@list:filter_map( + _pipe, + fun(Header) -> + {Name, Value} = Header, + case Name of + <<"set-cookie"/utf8>> -> + {ok, gleam@http@cookie:parse(Value)}; + + _ -> + {error, nil} + end + end + ), + gleam@list:flatten(_pipe@1). + +-spec set_cookie( + response(FJV), + binary(), + binary(), + gleam@http@cookie:attributes() +) -> response(FJV). +set_cookie(Response, Name, Value, Attributes) -> + prepend_header( + Response, + <<"set-cookie"/utf8>>, + gleam@http@cookie:set_header(Name, Value, Attributes) + ). + +-spec expire_cookie(response(FJY), binary(), gleam@http@cookie:attributes()) -> response(FJY). +expire_cookie(Response, Name, Attributes) -> + Attrs = erlang:setelement(2, Attributes, {some, 0}), + set_cookie(Response, Name, <<""/utf8>>, Attrs). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl new file mode 100644 index 00000000000..bb7ef2ef6a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl @@ -0,0 +1,82 @@ +-module(gleam@http@service). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([map_response_body/2, prepend_response_header/3, method_override/1]). + +-spec map_response_body( + fun((gleam@http@request:request(FMN)) -> gleam@http@response:response(FMO)), + fun((FMO) -> FMR) +) -> fun((gleam@http@request:request(FMN)) -> gleam@http@response:response(FMR)). +map_response_body(Service, Mapper) -> + fun(Req) -> _pipe = Req, + _pipe@1 = Service(_pipe), + gleam@http@response:map(_pipe@1, Mapper) end. + +-spec prepend_response_header( + fun((gleam@http@request:request(FMU)) -> gleam@http@response:response(FMV)), + binary(), + binary() +) -> fun((gleam@http@request:request(FMU)) -> gleam@http@response:response(FMV)). +prepend_response_header(Service, Key, Value) -> + fun(Req) -> _pipe = Req, + _pipe@1 = Service(_pipe), + gleam@http@response:prepend_header(_pipe@1, Key, Value) end. + +-spec ensure_post(gleam@http@request:request(FNA)) -> {ok, + gleam@http@request:request(FNA)} | + {error, nil}. +ensure_post(Req) -> + case erlang:element(2, Req) of + post -> + {ok, Req}; + + _ -> + {error, nil} + end. + +-spec get_override_method(gleam@http@request:request(any())) -> {ok, + gleam@http:method()} | + {error, nil}. +get_override_method(Request) -> + gleam@result:then( + gleam@http@request:get_query(Request), + fun(Query_params) -> + gleam@result:then( + gleam@list:key_find(Query_params, <<"_method"/utf8>>), + fun(Method) -> + gleam@result:then( + gleam@http:parse_method(Method), + fun(Method@1) -> case Method@1 of + put -> + {ok, Method@1}; + + patch -> + {ok, Method@1}; + + delete -> + {ok, Method@1}; + + _ -> + {error, nil} + end end + ) + end + ) + end + ). + +-spec method_override( + fun((gleam@http@request:request(FNH)) -> gleam@http@response:response(FNI)) +) -> fun((gleam@http@request:request(FNH)) -> gleam@http@response:response(FNI)). +method_override(Service) -> + fun(Request) -> _pipe = Request, + _pipe@1 = ensure_post(_pipe), + _pipe@2 = gleam@result:then(_pipe@1, fun get_override_method/1), + _pipe@3 = gleam@result:map( + _pipe@2, + fun(_capture) -> + gleam@http@request:set_method(Request, _capture) + end + ), + _pipe@4 = gleam@result:unwrap(_pipe@3, Request), + Service(_pipe@4) end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src new file mode 100644 index 00000000000..8d43953c74e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src @@ -0,0 +1,12 @@ +{application, gleam_http, [ + {vsn, "3.2.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Types and functions for Gleam HTTP clients and servers"}, + {modules, [gleam@http, + gleam@http@cookie, + gleam@http@request, + gleam@http@response, + gleam@http@service]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl new file mode 100644 index 00000000000..bb499bb57fd --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl @@ -0,0 +1,88 @@ +-module(gleam_http_native). +-export([decode_method/1]). + +decode_method(Term) -> + case Term of + "connect" -> {ok, connect}; + "delete" -> {ok, delete}; + "get" -> {ok, get}; + "head" -> {ok, head}; + "options" -> {ok, options}; + "patch" -> {ok, patch}; + "post" -> {ok, post}; + "put" -> {ok, put}; + "trace" -> {ok, trace}; + "CONNECT" -> {ok, connect}; + "DELETE" -> {ok, delete}; + "GET" -> {ok, get}; + "HEAD" -> {ok, head}; + "OPTIONS" -> {ok, options}; + "PATCH" -> {ok, patch}; + "POST" -> {ok, post}; + "PUT" -> {ok, put}; + "TRACE" -> {ok, trace}; + "Connect" -> {ok, connect}; + "Delete" -> {ok, delete}; + "Get" -> {ok, get}; + "Head" -> {ok, head}; + "Options" -> {ok, options}; + "Patch" -> {ok, patch}; + "Post" -> {ok, post}; + "Put" -> {ok, put}; + "Trace" -> {ok, trace}; + 'connect' -> {ok, connect}; + 'delete' -> {ok, delete}; + 'get' -> {ok, get}; + 'head' -> {ok, head}; + 'options' -> {ok, options}; + 'patch' -> {ok, patch}; + 'post' -> {ok, post}; + 'put' -> {ok, put}; + 'trace' -> {ok, trace}; + 'CONNECT' -> {ok, connect}; + 'DELETE' -> {ok, delete}; + 'GET' -> {ok, get}; + 'HEAD' -> {ok, head}; + 'OPTIONS' -> {ok, options}; + 'PATCH' -> {ok, patch}; + 'POST' -> {ok, post}; + 'PUT' -> {ok, put}; + 'TRACE' -> {ok, trace}; + 'Connect' -> {ok, connect}; + 'Delete' -> {ok, delete}; + 'Get' -> {ok, get}; + 'Head' -> {ok, head}; + 'Options' -> {ok, options}; + 'Patch' -> {ok, patch}; + 'Post' -> {ok, post}; + 'Put' -> {ok, put}; + 'Trace' -> {ok, trace}; + <<"connect">> -> {ok, connect}; + <<"delete">> -> {ok, delete}; + <<"get">> -> {ok, get}; + <<"head">> -> {ok, head}; + <<"options">> -> {ok, options}; + <<"patch">> -> {ok, patch}; + <<"post">> -> {ok, post}; + <<"put">> -> {ok, put}; + <<"trace">> -> {ok, trace}; + <<"CONNECT">> -> {ok, connect}; + <<"DELETE">> -> {ok, delete}; + <<"GET">> -> {ok, get}; + <<"HEAD">> -> {ok, head}; + <<"OPTIONS">> -> {ok, options}; + <<"PATCH">> -> {ok, patch}; + <<"POST">> -> {ok, post}; + <<"PUT">> -> {ok, put}; + <<"TRACE">> -> {ok, trace}; + <<"Connect">> -> {ok, connect}; + <<"Delete">> -> {ok, delete}; + <<"Get">> -> {ok, get}; + <<"Head">> -> {ok, head}; + <<"Options">> -> {ok, options}; + <<"Patch">> -> {ok, patch}; + <<"Post">> -> {ok, post}; + <<"Put">> -> {ok, put}; + <<"Trace">> -> {ok, trace}; + _ -> {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs new file mode 100644 index 00000000000..c871a8b9514 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs @@ -0,0 +1,38 @@ +import { Ok, Error } from "./gleam.mjs"; +import { + Get, + Post, + Head, + Put, + Delete, + Trace, + Connect, + Options, + Patch, +} from "./gleam/http.mjs"; + +export function decode_method(value) { + try { + switch (value.toLowerCase()) { + case "get": + return new Ok(new Get()); + case "post": + return new Ok(new Post()); + case "head": + return new Ok(new Head()); + case "put": + return new Ok(new Put()); + case "delete": + return new Ok(new Delete()); + case "trace": + return new Ok(new Trace()); + case "connect": + return new Ok(new Connect()); + case "options": + return new Ok(new Options()); + case "patch": + return new Ok(new Patch()); + } + } catch {} + return new Error(undefined); +} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/LICENCE b/test-community-packages-javascript/build/packages/gleam_otp/LICENCE new file mode 100644 index 00000000000..619ec77e6e1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/LICENCE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2019, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/gleam_otp/README.md b/test-community-packages-javascript/build/packages/gleam_otp/README.md new file mode 100644 index 00000000000..3c313a1c8c9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/README.md @@ -0,0 +1,91 @@ +# Gleam OTP + +GitHub release +Discord chat +![CI](https://github.com/gleam-lang/otp/workflows/test/badge.svg?branch=main) + +A Gleam library for building fault tolerant multi-core programs using the +actor model. It is compatible with Erlang's OTP framework. + +This library is experimental and will likely have many breaking changes in the +future! + +Gleam’s actor system is built with a few primary goals: + +- Full type safety of actors and messages. +- Be compatible with Erlang’s OTP actor framework. +- Provide fault tolerance and self-healing through supervisors. +- Have equivalent performance to Erlang’s OTP. + +This library documents its abstractions and functionality, but you may also wish +to read the documentation or other material on Erlang’s OTP framework to get a +fuller understanding of OTP, the problems it solves, and and the motivations for +its design. + +## Usage + +Add this library to your Gleam project. + +```shell +gleam add gleam_otp +``` + +## Actor hierarchy + +This library provides several different types of actor that can be used in +Gleam programs. + +### Process + +The process is the lowest level building block of OTP, all other actors are +built on top of processes either directly or indirectly. Typically this +abstraction would be not be used very often in Gleam applications, favour +other actor types that provide more functionality. + +Gleam's process module is defined in the `gleam_erlang` library. + +[[Documentation]](https://hexdocs.pm/gleam_erlang/gleam/erlang/process.html) + +### Actor + +The `actor` is the most commonly used process type in Gleam and serves as a good +building block for other abstractions. Like Erlang's `gen_server` it handles +OTP's system messages automatically to enable OTP's debugging and tracing +functionality. + +[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/actor.html) + +### Task + +A task is a kind of process that performs a single task and then shuts down. +Commonly tasks are used to convert sequential code into concurrent code by +performing computation in another process. + +[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/task.html) + +### Supervisor + +Supervisors is a process that starts and then supervises a group of processes, +restarting them if they crash. Supervisors can start other supervisors, +resulting in a hierarchical process structure called a supervision tree, +providing fault tolerance to a Gleam application. + +[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/supervisor.html) + +## Limitations and known issues + +This library is experimental there are some limitations that not yet been resolved. + +- There is no support for named processes. They are untyped global mutable + variables which may be uninitialized, more research is needed to find a + suitable type safe alternative. +- There are relatively few actor abstractions provided by this library. More + will be added in the future. +- Actors do not yet support all OTP system messages. Unsupported messages are + dropped. +- Supervisors do not yet support different shutdown periods per child. In + practice this means that children that are supervisors do not get an + unlimited amount of time to shut down, as is expected in Erlang or Elixir. +- This library has not seen much testing compared to the Erlang OTP + libraries, both in terms of unit tests and real world testing in + applications. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml b/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml new file mode 100644 index 00000000000..849e41ed186 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml @@ -0,0 +1,17 @@ +name = "gleam_otp" +version = "0.5.3" +licences = ["Apache-2.0"] +description = "Fault tolerant multicore Gleam programs with OTP" + +repository = { type = "github", user = "gleam-lang", repo = "otp" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[dependencies] +gleam_stdlib = "~> 0.19" +gleam_erlang = "~> 0.2" + +[dev-dependencies] +gleeunit = "~> 0.5" diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl new file mode 100644 index 00000000000..75faa95149f --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl @@ -0,0 +1 @@ +-record(ready, {state :: any(), selector :: gleam@erlang@process:selector(any())}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl new file mode 100644 index 00000000000..05f87d87d7b --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl @@ -0,0 +1,5 @@ +-record(spec, { + init :: fun(() -> gleam@otp@actor:init_result(any(), any())), + init_timeout :: integer(), + loop :: fun((any(), any()) -> gleam@otp@actor:next(any())) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl new file mode 100644 index 00000000000..3ed0b0122d4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl @@ -0,0 +1,5 @@ +-record(intensity_tracker, { + limit :: integer(), + period :: integer(), + events :: list(integer()) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl new file mode 100644 index 00000000000..7afd07f0319 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl @@ -0,0 +1,5 @@ +-record(child_spec, { + start :: fun((any()) -> {ok, gleam@erlang@process:subject(any())} | + {error, gleam@otp@actor:start_error()}), + returning :: fun((any(), gleam@erlang@process:subject(any())) -> any()) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl new file mode 100644 index 00000000000..b10bd9fa3f7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl @@ -0,0 +1,6 @@ +-record(spec, { + argument :: any(), + max_frequency :: integer(), + frequency_period :: integer(), + init :: fun((gleam@otp@supervisor:children(any())) -> gleam@otp@supervisor:children(any())) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl new file mode 100644 index 00000000000..de1c1ac340e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl @@ -0,0 +1,7 @@ +-record(status_info, { + module :: gleam@erlang@atom:atom_(), + parent :: gleam@erlang@process:pid_(), + mode :: gleam@otp@system:mode(), + debug_state :: gleam@otp@system:debug_state(), + state :: gleam@dynamic:dynamic() +}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl new file mode 100644 index 00000000000..8d84d3fc503 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl @@ -0,0 +1 @@ +-record(exit, {reason :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl new file mode 100644 index 00000000000..959bea8e9b9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl @@ -0,0 +1,6 @@ +-record(task, { + owner :: gleam@erlang@process:pid_(), + pid :: gleam@erlang@process:pid_(), + monitor :: gleam@erlang@process:process_monitor(), + selector :: gleam@erlang@process:selector(gleam@otp@task:message(any())) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam new file mode 100644 index 00000000000..4a4ca5ed712 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam @@ -0,0 +1,473 @@ +//// This module provides the _Actor_ abstraction, one of the most common +//// building blocks of Gleam OTP programs. +//// +//// An Actor is a process like any other BEAM process and can be be used to hold +//// state, execute code, and communicate with other processes by sending and +//// receiving messages. The advantage of using the actor abstraction over a bare +//// process is that it provides a single interface for commonly needed +//// functionality, including support for the [tracing and debugging +//// features in OTP](erlang-sys). +//// +//// Gleam's Actor is similar to Erlang's `gen_server` and Elixir's `GenServer` +//// but differs in that it offers a fully typed interface. This different API is +//// why Gleam uses the name Actor rather than some variation of generic-server. +//// +//// [erlang-sys]: https://www.erlang.org/doc/man/sys.html +//// +//// ## Example +//// +//// An Actor can be used to create a client-server interaction between an Actor +//// (the server) and other processes (the clients). In this example we have an +//// Actor that works as a stack, allowing clients to push and pop elements. +//// +//// ```gleam +//// pub fn main() { +//// // Start the actor with initial state of an empty list, and the +//// // `handle_message` callback function (defined below). +//// // We assert that it starts successfully. +//// // +//// // In real-world Gleam OTP programs we would likely write a wrapper functions +//// // called `start`, `push` `pop`, `shutdown` to start and interact with the +//// // Actor. We are not doing that here for the sake of showing how the Actor +//// // API works. +//// let assert Ok(actor) = actor.start([], handle_message) +//// +//// // We can send a message to the actor to push elements onto the stack. +//// process.send(actor, Push("Joe")) +//// process.send(actor, Push("Mike")) +//// process.send(actor, Push("Robert")) +//// +//// // The `Push` message expects no response, these messages are sent purely for +//// // the side effect of mutating the state held by the actor. +//// // +//// // We can also send the `Pop` message to take a value off of the actor's +//// // stack. This message expects a response, so we use `process.call` to send a +//// // message and wait until a reply is received. +//// // +//// // In this instance we are giving the actor 10 milliseconds to reply, if the +//// // `call` function doesn't get a reply within this time it will panic and +//// // crash the client process. +//// let assert Ok("Robert") = process.call(actor, Pop, 10) +//// let assert Ok("Mike") = process.call(actor, Pop, 10) +//// let assert Ok("Joe") = process.call(actor, Pop, 10) +//// +//// // The stack is now empty, so if we pop again the actor replies with an error. +//// let assert Error(Nil) = process.call(actor, Pop, 10) +//// +//// // Lastly, we can send a message to the actor asking it to shut down. +//// process.send(actor, Shutdown) +//// } +//// ``` +//// +//// Here is the code that is used to implement this actor: +//// +//// ```gleam +//// // First step of implementing the stack Actor is to define the message type that +//// // it can receive. +//// // +//// // The type of the elements in the stack is no fixed so a type parameter is used +//// // for it instead of a concrete type such as `String` or `Int`. +//// pub type Message(element) { +//// // The `Shutdown` message is used to tell the actor to stop. +//// // It is the simplest message type, it contains no data. +//// Shutdown +//// +//// // The `Push` message is used to add a new element to the stack. +//// // It contains the item to add, the type of which is the `element` +//// // parameterised type. +//// Push(push: element) +//// +//// // The `Pop` message is used to remove an element from the stack. +//// // It contains a `Subject`, which is used to send the response back to the +//// // message sender. In this case the reply is of type `Result(element, Nil)`. +//// Pop(reply_with: Subject(Result(element, Nil))) +//// } +//// +//// // The last part is to implement the `handle_message` callback function. +//// // +//// // This function is called by the Actor each for each message it receives. +//// // Actor is single threaded only does one thing at a time, so it handles +//// // messages sequentially and one at a time, in the order they are received. +//// // +//// // The function takes the message and the current state, and returns a data +//// // structure that indicates what to do next, along with the new state. +//// fn handle_message(message: Message(e), stack: List(e)) -> actor.Next(List(e)) { +//// case message { +//// // For the `Shutdown` message we return the `actor.Stop` value, which causes +//// // the actor to discard any remaining messages and stop. +//// Shutdown -> actor.Stop(process.Normal) +//// +//// // For the `Push` message we add the new element to the stack and return +//// // `actor.Continue` with this new stack, causing the actor to process any +//// // queued messages or wait for more. +//// Push(value) -> { +//// let new_state = [value, ..stack] +//// actor.Continue(new_state) +//// } +//// +//// // For the `Pop` message we attempt to remove an element from the stack, +//// // sending it or an error back to the caller, before continuing. +//// Pop(client) -> +//// case stack { +//// [] -> { +//// // When the stack is empty we can't pop an element, so we send an +//// // error back. +//// process.send(client, Error(Nil)) +//// actor.Continue([]) +//// } +//// +//// [first, ..rest] -> { +//// // Otherwise we send the first element back and use the remaining +//// // elements as the new state. +//// process.send(client, Ok(first)) +//// actor.Continue(rest) +//// } +//// } +//// } +//// } +//// ``` + +import gleam/erlang/process.{Abnormal, ExitReason, Pid, Selector, Subject} +import gleam/erlang/charlist.{Charlist} +import gleam/otp/system.{ + DebugState, GetState, GetStatus, Mode, Resume, Running, StatusInfo, Suspend, + Suspended, SystemMessage, +} +import gleam/string +import gleam/dynamic.{Dynamic} +import gleam/erlang/atom + +type Message(message) { + /// A regular message excepted by the process + Message(message) + + /// An OTP system message, for debugging or maintenance + System(SystemMessage) + + /// An unexpected message + Unexpected(Dynamic) +} + +/// The type used to indicate what to do after handling a message. +/// +pub type Next(state) { + /// Continue handling messages. + /// + Continue(state) + + /// Stop handling messages and shut down. + /// + Stop(ExitReason) +} + +/// The type used to indicate whether an actor has started successfully or not. +/// +pub type InitResult(state, message) { + /// The actor has successfully initialised. The actor can start handling + /// messages and actor's channel sender can be returned to the parent + /// process. + /// + Ready(state: state, selector: Selector(message)) + + /// The actor has failed to initialise. The actor shuts down and an error is + /// returned to the parent process. + /// + Failed(String) +} + +type Self(state, msg) { + Self( + mode: Mode, + parent: Pid, + state: state, + selector: Selector(Message(msg)), + debug_state: DebugState, + message_handler: fn(msg, state) -> Next(state), + ) +} + +/// This data structure holds all the values required by the `start_spec` +/// function in order to create an actor. +/// +/// If you do not need to configure the initialisation behaviour of your actor +/// consider using the `start` function. +/// +pub type Spec(state, msg) { + Spec( + /// The initialisation functionality for the actor. This function is called + /// just after the actor starts but before the channel sender is returned + /// to the parent. + /// + /// This function is used to ensure that any required data or state is + /// correct. If this function returns an error it means that the actor has + /// failed to start and an error is returned to the parent. + /// + init: fn() -> InitResult(state, msg), + /// How many milliseconds the `init` function has to return before it is + /// considered to have taken too long and failed. + /// + init_timeout: Int, + /// This function is called to handle each message that the actor receives. + /// + loop: fn(msg, state) -> Next(state), + ) +} + +// TODO: Check needed functionality here to be OTP compatible +fn exit_process(reason: ExitReason) -> ExitReason { + // TODO + reason +} + +fn receive_message(self: Self(state, msg)) -> Message(msg) { + let selector = case self.mode { + // When suspended we only respond to system messages + Suspended -> + process.new_selector() + |> selecting_system_messages + + // When running we respond to all messages + Running -> + // We add the handler for unexpected messages first so that the user + // supplied selector can override it if desired + process.new_selector() + |> process.selecting_anything(Unexpected) + |> process.merge_selector(self.selector) + |> selecting_system_messages + } + + process.select_forever(selector) +} + +fn selecting_system_messages( + selector: Selector(Message(msg)), +) -> Selector(Message(msg)) { + selector + |> process.selecting_record3( + atom.create_from_string("system"), + convert_system_message, + ) +} + +external fn convert_system_message(Dynamic, Dynamic) -> Message(msg) = + "gleam_otp_external" "convert_system_message" + +fn process_status_info(self: Self(state, msg)) -> StatusInfo { + StatusInfo( + module: atom.create_from_string("gleam@otp@actor"), + parent: self.parent, + mode: self.mode, + debug_state: self.debug_state, + state: dynamic.from(self.state), + ) +} + +fn loop(self: Self(state, msg)) -> ExitReason { + case receive_message(self) { + System(system) -> + case system { + GetState(callback) -> { + callback(dynamic.from(self.state)) + loop(self) + } + Resume(callback) -> { + callback() + loop(Self(..self, mode: Running)) + } + Suspend(callback) -> { + callback() + loop(Self(..self, mode: Suspended)) + } + GetStatus(callback) -> { + callback(process_status_info(self)) + loop(self) + } + } + + Unexpected(message) -> { + log_warning( + charlist.from_string("Actor discarding unexpected message: ~s"), + [charlist.from_string(string.inspect(message))], + ) + loop(self) + } + + Message(msg) -> + case self.message_handler(msg, self.state) { + Stop(reason) -> exit_process(reason) + Continue(state) -> loop(Self(..self, state: state)) + } + } +} + +// TODO: replace this when we have Gleam bindings to the logger +external fn log_warning(Charlist, List(Charlist)) -> Nil = + "logger" "warning" + +fn initialise_actor( + spec: Spec(state, msg), + ack: Subject(Result(Subject(msg), ExitReason)), +) { + let subject = process.new_subject() + case spec.init() { + Ready(state, selector) -> { + let selector = + process.new_selector() + |> process.selecting(subject, Message) + |> process.merge_selector(process.map_selector(selector, Message)) + // Signal to parent that the process has initialised successfully + process.send(ack, Ok(subject)) + // Start message receive loop + let self = + Self( + state: state, + parent: process.subject_owner(ack), + selector: selector, + message_handler: spec.loop, + debug_state: system.debug_state([]), + mode: Running, + ) + loop(self) + } + + Failed(reason) -> { + process.send(ack, Error(Abnormal(reason))) + exit_process(Abnormal(reason)) + } + } +} + +pub type StartError { + InitTimeout + InitFailed(ExitReason) + InitCrashed(Dynamic) +} + +/// The result of starting a Gleam actor. +/// +/// This type is compatible with Gleam supervisors. If you wish to convert it +/// to a type compatible with Erlang supervisors see the `ErlangStartResult` +/// type and `erlang_start_result` function. +/// +pub type StartResult(msg) = + Result(Subject(msg), StartError) + +/// An Erlang supervisor compatible process start result. +/// +/// If you wish to convert this into a `StartResult` compatible with Gleam +/// supervisors see the `from_erlang_start_result` and `wrap_erlang_starter` +/// functions. +/// +pub type ErlangStartResult = + Result(Pid, Dynamic) + +/// Convert a Gleam actor start result into an Erlang supervisor compatible +/// process start result. +/// +pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { + case res { + Ok(x) -> Ok(process.subject_owner(x)) + Error(x) -> Error(dynamic.from(x)) + } +} + +type StartInitMessage(msg) { + Ack(Result(Subject(msg), ExitReason)) + Mon(process.ProcessDown) +} + +// TODO: test init_timeout. Currently if we test it eunit prints an error from +// the process death. How do we avoid this? +// +/// Start an actor from a given specification. If the actor's `init` function +/// returns an error or does not return within `init_timeout` then an error is +/// returned. +/// +/// If you do not need to specify the initialisation behaviour of your actor +/// consider using the `start` function. +/// +pub fn start_spec(spec: Spec(state, msg)) -> Result(Subject(msg), StartError) { + let ack_subject = process.new_subject() + + let child = + process.start( + linked: True, + running: fn() { initialise_actor(spec, ack_subject) }, + ) + + let monitor = process.monitor_process(child) + let selector = + process.new_selector() + |> process.selecting(ack_subject, Ack) + |> process.selecting_process_down(monitor, Mon) + + let result = case process.select(selector, spec.init_timeout) { + // Child started OK + Ok(Ack(Ok(channel))) -> Ok(channel) + + // Child initialiser returned an error + Ok(Ack(Error(reason))) -> Error(InitFailed(reason)) + + // Child went down while initialising + Ok(Mon(down)) -> Error(InitCrashed(down.reason)) + + // Child did not finish initialising in time + Error(Nil) -> { + process.kill(child) + Error(InitTimeout) + } + } + + // Remove the monitor used for the starting of the actor as to avoid an extra + // message arriving at the parent if the child dies later. + process.demonitor_process(monitor) + + result +} + +/// Start an actor with a given initial state and message handling loop +/// function. +/// +/// This function returns a `Result` but it will always be `Ok` so it is safe +/// to use with `assert` if you are not starting this actor as part of a +/// supervision tree. +/// +/// If you wish to configure the initialisation behaviour of a new actor see +/// the `Spec` record and the `start_spec` function. +/// +pub fn start( + state: state, + loop: fn(msg, state) -> Next(state), +) -> Result(Subject(msg), StartError) { + start_spec(Spec( + init: fn() { Ready(state, process.new_selector()) }, + loop: loop, + init_timeout: 5000, + )) +} + +/// Send a message over a given channel. +/// +/// This is a re-export of `process.send`, for the sake of convenience. +/// +pub fn send(subject: Subject(msg), msg: msg) -> Nil { + process.send(subject, msg) +} + +// TODO: test +/// Send a synchronous message and wait for a response from the receiving +/// process. +/// +/// If a reply is not received within the given timeout then the sender process +/// crashes. If you wish receive a `Result` rather than crashing see the +/// `process.try_call` function. +/// +/// This is a re-export of `process.call`, for the sake of convenience. +/// +pub fn call( + selector: Subject(message), + make_message: fn(Subject(reply)) -> message, + timeout: Int, +) -> reply { + process.call(selector, make_message, timeout) +} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam new file mode 100644 index 00000000000..b53e1006325 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam @@ -0,0 +1,46 @@ +//// The intensity tracker is used to monitor how frequently an event happens, +//// erroring if it happens too many times within a period of time. + +import gleam/list + +// TODO: test +pub opaque type IntensityTracker { + IntensityTracker(limit: Int, period: Int, events: List(Int)) +} + +pub type TooIntense { + TooIntense +} + +pub fn new(limit limit: Int, period period: Int) -> IntensityTracker { + IntensityTracker(limit: limit, period: period, events: []) +} + +external fn monotonic_time(Int) -> Int = + "erlang" "monotonic_time" + +fn now_seconds() -> Int { + monotonic_time(1) +} + +pub fn trim_window(events: List(Int), now: Int, period: Int) -> List(Int) { + case events { + [] -> [] + [event, ..events] -> + case now >= event + period { + True -> [event, ..trim_window(events, now, period)] + False -> [] + } + } +} + +pub fn add_event( + tracker: IntensityTracker, +) -> Result(IntensityTracker, TooIntense) { + let now = now_seconds() + let events = trim_window([now, ..tracker.events], now, tracker.period) + case list.length(events) >= tracker.limit { + True -> Error(TooIntense) + False -> Ok(IntensityTracker(..tracker, events: events)) + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam new file mode 100644 index 00000000000..19c77fa6a58 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam @@ -0,0 +1 @@ +pub external type Node diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam new file mode 100644 index 00000000000..c312494d733 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam @@ -0,0 +1,9 @@ +/// Ports are how code running on the Erlang virtual machine interacts with +/// the outside world. Bytes of data can be sent to and read from ports, +/// providing a form of message passing to an external program or resource. +/// +/// For more information on ports see the [Erlang ports documentation][1]. +/// +/// [1]: https://erlang.org/doc/reference_manual/ports.html +/// +pub external type Port diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam new file mode 100644 index 00000000000..f710b05c155 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam @@ -0,0 +1,403 @@ +// TODO: specify amount of time permitted for shut-down +import gleam/result +import gleam/string +import gleam/option.{None, Option, Some} +import gleam/erlang/process.{Pid, Subject} +import gleam/otp/actor.{StartError} +import gleam/otp/intensity_tracker.{IntensityTracker} +import gleam/otp/node.{Node} + +/// This data structure holds all the values required by the `start_spec` +/// function in order to create an supervisor. +/// +/// If you do not need to configure the behaviour of your supervisor consider +/// using the `start` function. +/// +pub type Spec(argument, return) { + Spec( + argument: argument, + max_frequency: Int, + frequency_period: Int, + init: fn(Children(argument)) -> Children(return), + ) +} + +/// This type represents the starting children of a supervisor within the +/// `init` function. +/// +pub opaque type Children(argument) { + Ready(Starter(argument)) + Failed(ChildStartError) +} + +/// This type contains all the information required to start a new child and +/// add it to the `Children`. +/// +/// This is typically created with the `worker` function. +/// +pub opaque type ChildSpec(msg, argument, returning) { + ChildSpec( + // TODO: merge this into one field + start: fn(argument) -> Result(Subject(msg), StartError), + returning: fn(argument, Subject(msg)) -> returning, + ) +} + +type ChildStartError { + ChildStartError(previous_pid: Option(Pid), error: StartError) +} + +pub opaque type Message { + Exit(process.ExitMessage) + RetryRestart(Pid) +} + +type Instruction { + StartAll + StartFrom(Pid) +} + +type State(a) { + State( + restarts: IntensityTracker, + starter: Starter(a), + retry_restarts: Subject(Pid), + ) +} + +type Starter(argument) { + Starter( + argument: argument, + exec: Option( + fn(Instruction) -> + Result(#(Starter(argument), Instruction), ChildStartError), + ), + ) +} + +type Child(argument) { + Child(pid: Pid, argument: argument) +} + +fn start_child( + child_spec: ChildSpec(msg, argument_in, argument_out), + argument: argument_in, +) -> Result(Child(argument_out), ChildStartError) { + use subject <- result.then( + child_spec.start(argument) + |> result.map_error(ChildStartError(None, _)), + ) + + Ok(Child( + pid: process.subject_owner(subject), + // Merge the new child's pid into the argument to produce the new argument + // used to start any remaining children. + argument: child_spec.returning(argument, subject), + )) +} + +// TODO: more sophsiticated stopping of processes. i.e. give supervisors +// more time to shut down. +fn shutdown_child(pid: Pid, _spec: ChildSpec(msg, arg_1, arg_2)) -> Nil { + process.send_exit(pid) +} + +fn perform_instruction_for_child( + argument: argument_in, + instruction: Instruction, + child_spec: ChildSpec(msg, argument_in, argument_out), + child: Child(argument_out), +) -> Result(#(Child(argument_out), Instruction), ChildStartError) { + let current = child.pid + case instruction { + // This child is older than the StartFrom target, we don't need to + // restart it + StartFrom(target) if target != current -> Ok(#(child, instruction)) + + // This pid either is the cause of the problem, or we have the StartAll + // instruction. Either way it and its younger siblings need to be restarted. + _ -> { + shutdown_child(current, child_spec) + use child <- result.then(start_child(child_spec, argument)) + Ok(#(child, StartAll)) + } + } +} + +fn add_child_to_starter( + starter: Starter(argument_in), + child_spec: ChildSpec(msg, argument_in, argument_out), + child: Child(argument_out), +) -> Starter(argument_out) { + let starter = fn(instruction) { + // Restart the older children. We use `try` to return early if the older + // children failed to start + use #(starter, instruction) <- result.then(case starter.exec { + Some(start) -> start(instruction) + None -> Ok(#(starter, instruction)) + }) + + // Perform the instruction, restarting the child as required + use #(child, instruction) <- result.then(perform_instruction_for_child( + starter.argument, + instruction, + child_spec, + child, + )) + + // Create a new starter for the next time the supervisor needs to restart + let starter = add_child_to_starter(starter, child_spec, child) + + Ok(#(starter, instruction)) + } + + Starter(exec: Some(starter), argument: child.argument) +} + +fn start_and_add_child( + state: Starter(argument_0), + child_spec: ChildSpec(msg, argument_0, argument_1), +) -> Children(argument_1) { + case start_child(child_spec, state.argument) { + Ok(child) -> Ready(add_child_to_starter(state, child_spec, child)) + Error(reason) -> Failed(reason) + } +} + +/// Add a child to the collection of children of the supervisor +/// +/// This function starts the child from the child spec. +/// +pub fn add( + children: Children(argument), + child_spec: ChildSpec(msg, argument, new_argument), +) -> Children(new_argument) { + case children { + // If one of the previous children has failed then we cannot continue + Failed(fail) -> Failed(fail) + + // If everything is OK so far then we can add the child + Ready(state) -> start_and_add_child(state, child_spec) + } +} + +// TODO: test +// TODO: unlimitd shut down duration +/// Prepare a new supervisor type child. +/// +/// If you wish to prepare a new non-supervisor type child see the `worker` +/// function. +/// +/// If you wish to change the type of the argument for later children see the +/// `returning` function. +/// +/// Note: Gleam supervisors do not yet support different shutdown periods per +/// child so this function is currently identical in behaviour to `worker`. It is +/// recommended to use this function for supervisor children nevertheless so the +/// correct shut down behaviour is used in later releases of this library. +/// +pub fn supervisor( + start: fn(argument) -> Result(Subject(msg), StartError), +) -> ChildSpec(msg, argument, argument) { + ChildSpec(start: start, returning: fn(argument, _channel) { argument }) +} + +/// Prepare a new worker type child. +/// +/// If you wish to prepare a new supervisor type child see the `supervisor` +/// function. +/// +/// If you wish to change the type of the argument for later children see the +/// `returning` function. +/// +pub fn worker( + start: fn(argument) -> Result(Subject(msg), StartError), +) -> ChildSpec(msg, argument, argument) { + ChildSpec(start: start, returning: fn(argument, _channel) { argument }) +} + +// TODO: test +/// As each child is added to a supervisors children a new argument is prepared +/// with which to start the next child. By default argument is the same as the +/// previous argument, but this function can be used to change it to something +/// else by passing a function that takes the previous argument and the sender +/// of the previous child. +/// +pub fn returning( + child: ChildSpec(msg, argument_a, argument_b), + updater: fn(argument_a, Subject(msg)) -> argument_c, +) -> ChildSpec(msg, argument_a, argument_c) { + ChildSpec(start: child.start, returning: updater) +} + +fn init( + spec: Spec(argument, return), +) -> actor.InitResult(State(return), Message) { + // Create a subject so that we can asynchronously retry restarting when we + // fail to bring an exited child + let retry = process.new_subject() + + // Trap exits so that we get a message when a child crashes + process.trap_exits(True) + + // Combine selectors + let selector = + process.new_selector() + |> process.selecting(retry, RetryRestart) + |> process.selecting_trapped_exits(Exit) + + // Start any children + let result = + Starter(argument: spec.argument, exec: None) + |> Ready + |> spec.init + + // Pass back up the result + case result { + Ready(starter) -> { + let restarts = + intensity_tracker.new( + limit: spec.max_frequency, + period: spec.frequency_period, + ) + let state = + State(starter: starter, restarts: restarts, retry_restarts: retry) + actor.Ready(state, selector) + } + + Failed(error) -> + actor.Failed(case error.error { + actor.InitTimeout -> "Child initialisation timed out" + actor.InitCrashed(reason) -> + string.append( + "Child crashed during initialisation: ", + string.inspect(reason), + ) + actor.InitFailed(reason) -> + string.append( + "Child failed to start during initialisation: ", + string.inspect(reason), + ) + }) + } +} + +type HandleExitError { + RestartFailed(pid: Pid, restarts: IntensityTracker) + TooManyRestarts +} + +fn handle_exit(pid: Pid, state: State(a)) -> actor.Next(State(a)) { + let outcome = { + // If we are handling an exit then we must have some children + let assert Some(start) = state.starter.exec + + // Check to see if there has been too many restarts in this period + use restarts <- result.then( + state.restarts + |> intensity_tracker.add_event + |> result.map_error(fn(_) { TooManyRestarts }), + ) + + // Restart the exited child and any following children + use #(starter, _) <- result.then( + start(StartFrom(pid)) + |> result.map_error(fn(e: ChildStartError) { + RestartFailed(option.unwrap(e.previous_pid, pid), restarts) + }), + ) + + Ok(State(..state, starter: starter, restarts: restarts)) + } + + case outcome { + Ok(state) -> actor.Continue(state) + Error(RestartFailed(failed_child, restarts)) -> { + // Asynchronously enqueue the restarting of this child again as we were + // unable to restart them this time. We do this asynchronously as we want + // to have a chance to handle any system messages that have come in. + process.send(state.retry_restarts, failed_child) + let state = State(..state, restarts: restarts) + actor.Continue(state) + } + Error(TooManyRestarts) -> + actor.Stop(process.Abnormal( + "Child processes restarted too many times within allowed period", + )) + } +} + +fn loop(message: Message, state: State(argument)) -> actor.Next(State(argument)) { + case message { + Exit(exit_message) -> handle_exit(exit_message.pid, state) + RetryRestart(pid) -> handle_exit(pid, state) + } +} + +/// Start a supervisor from a given specification. +/// +pub fn start_spec(spec: Spec(a, b)) -> Result(Subject(Message), StartError) { + actor.start_spec(actor.Spec( + init: fn() { init(spec) }, + loop: loop, + init_timeout: 60_000, + )) +} + +/// Start a supervisor from a given `init` function. +/// +/// If you wish to have more control over the configuration of the supervisor +/// see the `start_spec` function. +/// +pub fn start( + init: fn(Children(Nil)) -> Children(a), +) -> Result(Subject(Message), StartError) { + start_spec(Spec( + init: init, + argument: Nil, + max_frequency: 5, + frequency_period: 1, + )) +} + +/// A type used to describe the situation in which an Erlang based application +/// is starting. +/// +/// For more information see the [Erlang distributed application +/// documentation][1] and the Learn Your Some Erlang chapter on [distributed +/// applications][2]. +/// +/// [1]: https://erlang.org/doc/design_principles/distributed_applications.html +/// [2]: https://learnyousomeerlang.com/distributed-otp-applications +/// +pub type ApplicationStartMode { + Normal + Takeover(Node) + Failover(Node) +} + +pub external type ApplicationStop + +pub external fn application_stopped() -> ApplicationStop = + "gleam_otp_external" "application_stopped" + +/// The result of starting a Gleam actor. +/// +/// This type is compatible with Gleam supervisors. If you wish to convert it +/// to a type compatible with Erlang supervisors see the `ErlangStartResult` +/// type and `erlang_start_result` function. +/// +pub type StartResult(msg) = + actor.StartResult(msg) + +/// An Erlang supervisor compatible process start result. +/// +pub type ErlangStartResult = + actor.ErlangStartResult + +/// Convert a Gleam actor start result into an Erlang supervisor compatible +/// process start result. +/// +pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { + actor.to_erlang_start_result(res) +} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam new file mode 100644 index 00000000000..895c3409458 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam @@ -0,0 +1,89 @@ +import gleam/dynamic.{Dynamic} +import gleam/erlang/atom.{Atom} +import gleam/erlang/process.{Pid} + +pub type Mode { + Running + Suspended +} + +pub type DebugOption { + NoDebug +} + +pub external type DebugState + +pub external fn debug_state(List(DebugOption)) -> DebugState = + "sys" "debug_options" + +pub type StatusInfo { + StatusInfo( + module: Atom, + parent: Pid, + mode: Mode, + debug_state: DebugState, + state: Dynamic, + ) +} + +// TODO: document +// TODO: implement remaining messages +pub type SystemMessage { + // {replace_state, StateFn} + // {change_code, Mod, Vsn, Extra} + // {terminate, Reason} + // {debug, {log, Flag}} + // {debug, {trace, Flag}} + // {debug, {log_to_file, FileName}} + // {debug, {statistics, Flag}} + // {debug, no_debug} + // {debug, {install, {Func, FuncState}}} + // {debug, {install, {FuncId, Func, FuncState}}} + // {debug, {remove, FuncOrId}} + Resume(fn() -> Nil) + Suspend(fn() -> Nil) + GetState(fn(Dynamic) -> Nil) + GetStatus(fn(StatusInfo) -> Nil) +} + +external type DoNotLeak + +/// Get the state of a given OTP compatible process. This function is only +/// intended for debugging. +/// +/// For more information see the [Erlang documentation][1]. +/// +/// [1]: https://erlang.org/doc/man/sys.html#get_state-1 +/// +pub external fn get_state(from: Pid) -> Dynamic = + "sys" "get_state" + +external fn erl_suspend(Pid) -> DoNotLeak = + "sys" "suspend" + +/// Request an OTP compatible process to suspend, causing it to only handle +/// system messages. +/// +/// For more information see the [Erlang documentation][1]. +/// +/// [1]: https://erlang.org/doc/man/sys.html#suspend-1 +/// +pub fn suspend(pid: Pid) -> Nil { + erl_suspend(pid) + Nil +} + +external fn erl_resume(from: Pid) -> DoNotLeak = + "sys" "resume" + +/// Request a suspended OTP compatible process to result, causing it to handle +/// all messages rather than only system messages. +/// +/// For more information see the [Erlang documentation][1]. +/// +/// [1]: https://erlang.org/doc/man/sys.html#resume-1 +/// +pub fn resume(pid: Pid) -> Nil { + erl_resume(pid) + Nil +} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam new file mode 100644 index 00000000000..c9adc952f88 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam @@ -0,0 +1,151 @@ +//// A task is a kind of process that performs a single task and then shuts +//// down. Commonly tasks are used to convert sequential code into concurrent +//// code by performing computation in another process. +//// +//// let task = task.async(fn() { do_some_work() }) +//// let value = do_some_other_work() +//// value + task.await(task, 100) +//// +//// Tasks spawned with async can be awaited on by their caller process (and +//// only their caller) as shown in the example above. They are implemented by +//// spawning a process that sends a message to the caller once the given +//// computation is performed. +//// +//// There are two important things to consider when using `async`: +//// +//// 1. If you are using async tasks, you must await a reply as they are always +//// sent. +//// +//// 2. async tasks link the caller and the spawned process. This means that, +//// if the caller crashes, the task will crash too and vice-versa. This is +//// on purpose: if the process meant to receive the result no longer +//// exists, there is no purpose in completing the computation. +//// +//// This module is inspired by Elixir's [Task module][1]. +//// +//// [1]: https://hexdocs.pm/elixir/master/Task.html +//// + +// TODO: await_many +import gleam/erlang/process.{Pid, ProcessMonitor, Selector} +import gleam/dynamic.{Dynamic} + +pub opaque type Task(value) { + Task( + owner: Pid, + pid: Pid, + monitor: ProcessMonitor, + selector: Selector(Message(value)), + ) +} + +// TODO: test +/// Spawn a task process that calls a given function in order to perform some +/// work. The result of this function is send back to the parent and can be +/// received using the `await` function. +/// +/// See the top level module documentation for more information on async/await. +/// +pub fn async(work: fn() -> value) -> Task(value) { + let owner = process.self() + let subject = process.new_subject() + let pid = + process.start(linked: True, running: fn() { process.send(subject, work()) }) + let monitor = process.monitor_process(pid) + let selector = + process.new_selector() + |> process.selecting_process_down(monitor, FromMonitor) + |> process.selecting(subject, FromSubject) + Task(owner: owner, pid: pid, monitor: monitor, selector: selector) +} + +pub type AwaitError { + Timeout + Exit(reason: Dynamic) +} + +// We can only wait on a task if we are the owner of it so crash if we are +// waiting on a task we don't own. +fn assert_owner(task: Task(a)) -> Nil { + let self = process.self() + case task.owner == self { + True -> Nil + False -> + process.send_abnormal_exit( + self, + "awaited on a task that does not belong to this process", + ) + } +} + +type Message(value) { + FromMonitor(process.ProcessDown) + FromSubject(value) +} + +// TODO: test +/// Wait for the value computed by a task. +/// +/// If the a value is not received before the timeout has elapsed or if the +/// task process crashes then an error is returned. +/// +pub fn try_await(task: Task(value), timeout: Int) -> Result(value, AwaitError) { + assert_owner(task) + case process.select(task.selector, timeout) { + // The task process has sent back a value + Ok(FromSubject(x)) -> { + process.demonitor_process(task.monitor) + Ok(x) + } + + // The task process crashed without sending a value + Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) -> + Error(Exit(reason)) + + // The task process is alive but has not sent a value yet + Error(Nil) -> Error(Timeout) + } +} + +// TODO: test +/// Wait for the value computed by a task. +/// +/// If the a value is not received before the timeout has elapsed or if the +/// task process crashes then this function crashes. +/// +pub fn await(task: Task(value), timeout: Int) -> value { + let assert Ok(value) = try_await(task, timeout) + value +} + +/// Wait endlessly for the value computed by a task. +/// +/// Be Careful! This function does not return until there is a value to +/// receive. If a value is not received then the process will be stuck waiting +/// forever. +/// +pub fn try_await_forever(task: Task(value)) -> Result(value, AwaitError) { + assert_owner(task) + case process.select_forever(task.selector) { + // The task process has sent back a value + FromSubject(x) -> { + process.demonitor_process(task.monitor) + Ok(x) + } + + // The task process crashed without sending a value + FromMonitor(process.ProcessDown(reason: reason, ..)) -> Error(Exit(reason)) + } +} + +/// Wait endlessly for the value computed by a task. +/// +/// Be Careful! Like `try_await_forever`, this function does not return until there is a value to +/// receive. +/// +/// If the task process crashes then this function crashes. +/// +pub fn await_forever(task: Task(value)) -> value { + let assert Ok(value) = try_await_forever(task) + value +} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl new file mode 100644 index 00000000000..40e16f7a820 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl @@ -0,0 +1,233 @@ +-module(gleam@otp@actor). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_erlang_start_result/1, send/2, call/3, start_spec/1, start/2]). +-export_type([message/1, next/1, init_result/2, self/2, spec/2, start_error/0, start_init_message/1]). + +-type message(FIS) :: {message, FIS} | + {system, gleam@otp@system:system_message()} | + {unexpected, gleam@dynamic:dynamic()}. + +-type next(FIT) :: {continue, FIT} | {stop, gleam@erlang@process:exit_reason()}. + +-type init_result(FIU, FIV) :: {ready, FIU, gleam@erlang@process:selector(FIV)} | + {failed, binary()}. + +-type self(FIW, FIX) :: {self, + gleam@otp@system:mode(), + gleam@erlang@process:pid_(), + FIW, + gleam@erlang@process:selector(message(FIX)), + gleam@otp@system:debug_state(), + fun((FIX, FIW) -> next(FIW))}. + +-type spec(FIY, FIZ) :: {spec, + fun(() -> init_result(FIY, FIZ)), + integer(), + fun((FIZ, FIY) -> next(FIY))}. + +-type start_error() :: init_timeout | + {init_failed, gleam@erlang@process:exit_reason()} | + {init_crashed, gleam@dynamic:dynamic()}. + +-type start_init_message(FJA) :: {ack, + {ok, gleam@erlang@process:subject(FJA)} | + {error, gleam@erlang@process:exit_reason()}} | + {mon, gleam@erlang@process:process_down()}. + +-spec exit_process(gleam@erlang@process:exit_reason()) -> gleam@erlang@process:exit_reason(). +exit_process(Reason) -> + Reason. + +-spec process_status_info(self(any(), any())) -> gleam@otp@system:status_info(). +process_status_info(Self) -> + {status_info, + erlang:binary_to_atom(<<"gleam@otp@actor"/utf8>>), + erlang:element(3, Self), + erlang:element(2, Self), + erlang:element(6, Self), + gleam@dynamic:from(erlang:element(4, Self))}. + +-spec to_erlang_start_result( + {ok, gleam@erlang@process:subject(any())} | {error, start_error()} +) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic()}. +to_erlang_start_result(Res) -> + case Res of + {ok, X} -> + {ok, gleam@erlang@process:subject_owner(X)}; + + {error, X@1} -> + {error, gleam@dynamic:from(X@1)} + end. + +-spec send(gleam@erlang@process:subject(FKX), FKX) -> nil. +send(Subject, Msg) -> + gleam@erlang@process:send(Subject, Msg). + +-spec call( + gleam@erlang@process:subject(FKZ), + fun((gleam@erlang@process:subject(FLB)) -> FKZ), + integer() +) -> FLB. +call(Selector, Make_message, Timeout) -> + gleam@erlang@process:call(Selector, Make_message, Timeout). + +-spec selecting_system_messages(gleam@erlang@process:selector(message(FJM))) -> gleam@erlang@process:selector(message(FJM)). +selecting_system_messages(Selector) -> + _pipe = Selector, + gleam@erlang@process:selecting_record3( + _pipe, + erlang:binary_to_atom(<<"system"/utf8>>), + fun gleam_otp_external:convert_system_message/2 + ). + +-spec receive_message(self(any(), FJI)) -> message(FJI). +receive_message(Self) -> + Selector = case erlang:element(2, Self) of + suspended -> + _pipe = gleam_erlang_ffi:new_selector(), + selecting_system_messages(_pipe); + + running -> + _pipe@1 = gleam_erlang_ffi:new_selector(), + _pipe@2 = gleam@erlang@process:selecting_anything( + _pipe@1, + fun(Field@0) -> {unexpected, Field@0} end + ), + _pipe@3 = gleam_erlang_ffi:merge_selector( + _pipe@2, + erlang:element(5, Self) + ), + selecting_system_messages(_pipe@3) + end, + gleam_erlang_ffi:select(Selector). + +-spec loop(self(any(), any())) -> gleam@erlang@process:exit_reason(). +loop(Self) -> + case receive_message(Self) of + {system, System} -> + case System of + {get_state, Callback} -> + Callback(gleam@dynamic:from(erlang:element(4, Self))), + loop(Self); + + {resume, Callback@1} -> + Callback@1(), + loop(erlang:setelement(2, Self, running)); + + {suspend, Callback@2} -> + Callback@2(), + loop(erlang:setelement(2, Self, suspended)); + + {get_status, Callback@3} -> + Callback@3(process_status_info(Self)), + loop(Self) + end; + + {unexpected, Message} -> + logger:warning( + unicode:characters_to_list( + <<"Actor discarding unexpected message: ~s"/utf8>> + ), + [unicode:characters_to_list(gleam@string:inspect(Message))] + ), + loop(Self); + + {message, Msg} -> + case (erlang:element(7, Self))(Msg, erlang:element(4, Self)) of + {stop, Reason} -> + exit_process(Reason); + + {continue, State} -> + loop(erlang:setelement(4, Self, State)) + end + end. + +-spec initialise_actor( + spec(any(), FKA), + gleam@erlang@process:subject({ok, gleam@erlang@process:subject(FKA)} | + {error, gleam@erlang@process:exit_reason()}) +) -> gleam@erlang@process:exit_reason(). +initialise_actor(Spec, Ack) -> + Subject = gleam@erlang@process:new_subject(), + case (erlang:element(2, Spec))() of + {ready, State, Selector} -> + Selector@1 = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Subject, + fun(Field@0) -> {message, Field@0} end + ), + gleam_erlang_ffi:merge_selector( + _pipe@1, + gleam_erlang_ffi:map_selector( + Selector, + fun(Field@0) -> {message, Field@0} end + ) + ) + end, + gleam@erlang@process:send(Ack, {ok, Subject}), + Self = {self, + running, + gleam@erlang@process:subject_owner(Ack), + State, + Selector@1, + sys:debug_options([]), + erlang:element(4, Spec)}, + loop(Self); + + {failed, Reason} -> + gleam@erlang@process:send(Ack, {error, {abnormal, Reason}}), + exit_process({abnormal, Reason}) + end. + +-spec start_spec(spec(any(), FKL)) -> {ok, gleam@erlang@process:subject(FKL)} | + {error, start_error()}. +start_spec(Spec) -> + Ack_subject = gleam@erlang@process:new_subject(), + Child = gleam@erlang@process:start( + fun() -> initialise_actor(Spec, Ack_subject) end, + true + ), + Monitor = gleam@erlang@process:monitor_process(Child), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Ack_subject, + fun(Field@0) -> {ack, Field@0} end + ), + gleam@erlang@process:selecting_process_down( + _pipe@1, + Monitor, + fun(Field@0) -> {mon, Field@0} end + ) + end, + Result = case gleam_erlang_ffi:select(Selector, erlang:element(3, Spec)) of + {ok, {ack, {ok, Channel}}} -> + {ok, Channel}; + + {ok, {ack, {error, Reason}}} -> + {error, {init_failed, Reason}}; + + {ok, {mon, Down}} -> + {error, {init_crashed, erlang:element(3, Down)}}; + + {error, nil} -> + gleam@erlang@process:kill(Child), + {error, init_timeout} + end, + gleam_erlang_ffi:demonitor(Monitor), + Result. + +-spec start(FKR, fun((FKS, FKR) -> next(FKR))) -> {ok, + gleam@erlang@process:subject(FKS)} | + {error, start_error()}. +start(State, Loop) -> + start_spec( + {spec, + fun() -> {ready, State, gleam_erlang_ffi:new_selector()} end, + 5000, + Loop} + ). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl new file mode 100644 index 00000000000..63a73ea9462 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl @@ -0,0 +1,53 @@ +-module(gleam@otp@intensity_tracker). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/2, trim_window/3, add_event/1]). +-export_type([intensity_tracker/0, too_intense/0]). + +-opaque intensity_tracker() :: {intensity_tracker, + integer(), + integer(), + list(integer())}. + +-type too_intense() :: too_intense. + +-spec new(integer(), integer()) -> intensity_tracker(). +new(Limit, Period) -> + {intensity_tracker, Limit, Period, []}. + +-spec now_seconds() -> integer(). +now_seconds() -> + erlang:monotonic_time(1). + +-spec trim_window(list(integer()), integer(), integer()) -> list(integer()). +trim_window(Events, Now, Period) -> + case Events of + [] -> + []; + + [Event | Events@1] -> + case Now >= (Event + Period) of + true -> + [Event | trim_window(Events@1, Now, Period)]; + + false -> + [] + end + end. + +-spec add_event(intensity_tracker()) -> {ok, intensity_tracker()} | + {error, too_intense()}. +add_event(Tracker) -> + Now = now_seconds(), + Events = trim_window( + [Now | erlang:element(4, Tracker)], + Now, + erlang:element(3, Tracker) + ), + case gleam@list:length(Events) >= erlang:element(2, Tracker) of + true -> + {error, too_intense}; + + false -> + {ok, erlang:setelement(4, Tracker, Events)} + end. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl new file mode 100644 index 00000000000..4176b6ffad7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl @@ -0,0 +1,8 @@ +-module(gleam@otp@node). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([node_/0]). + +-type node_() :: any(). + + diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl new file mode 100644 index 00000000000..4ca9f538511 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl @@ -0,0 +1,8 @@ +-module(gleam@otp@port). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([port_/0]). + +-type port_() :: any(). + + diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl new file mode 100644 index 00000000000..a7f39e5fbe2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl @@ -0,0 +1,322 @@ +-module(gleam@otp@supervisor). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([supervisor/1, worker/1, returning/2, start_spec/1, start/1, to_erlang_start_result/1, application_stopped/0, add/2]). +-export_type([spec/2, children/1, child_spec/3, child_start_error/0, message/0, instruction/0, state/1, starter/1, child/1, handle_exit_error/0, application_start_mode/0, application_stop/0]). + +-type spec(FRW, FRX) :: {spec, + FRW, + integer(), + integer(), + fun((children(FRW)) -> children(FRX))}. + +-opaque children(FRY) :: {ready, starter(FRY)} | {failed, child_start_error()}. + +-opaque child_spec(FRZ, FSA, FSB) :: {child_spec, + fun((FSA) -> {ok, gleam@erlang@process:subject(FRZ)} | + {error, gleam@otp@actor:start_error()}), + fun((FSA, gleam@erlang@process:subject(FRZ)) -> FSB)}. + +-type child_start_error() :: {child_start_error, + gleam@option:option(gleam@erlang@process:pid_()), + gleam@otp@actor:start_error()}. + +-opaque message() :: {exit, gleam@erlang@process:exit_message()} | + {retry_restart, gleam@erlang@process:pid_()}. + +-type instruction() :: start_all | {start_from, gleam@erlang@process:pid_()}. + +-type state(FSC) :: {state, + gleam@otp@intensity_tracker:intensity_tracker(), + starter(FSC), + gleam@erlang@process:subject(gleam@erlang@process:pid_())}. + +-type starter(FSD) :: {starter, + FSD, + gleam@option:option(fun((instruction()) -> {ok, + {starter(FSD), instruction()}} | + {error, child_start_error()}))}. + +-type child(FSE) :: {child, gleam@erlang@process:pid_(), FSE}. + +-type handle_exit_error() :: {restart_failed, + gleam@erlang@process:pid_(), + gleam@otp@intensity_tracker:intensity_tracker()} | + too_many_restarts. + +-type application_start_mode() :: normal | + {takeover, gleam@otp@node:node_()} | + {failover, gleam@otp@node:node_()}. + +-type application_stop() :: any(). + +-spec start_child(child_spec(any(), FSI, FSJ), FSI) -> {ok, child(FSJ)} | + {error, child_start_error()}. +start_child(Child_spec, Argument) -> + gleam@result:then( + begin + _pipe = (erlang:element(2, Child_spec))(Argument), + gleam@result:map_error( + _pipe, + fun(_capture) -> {child_start_error, none, _capture} end + ) + end, + fun(Subject) -> + {ok, + {child, + gleam@erlang@process:subject_owner(Subject), + (erlang:element(3, Child_spec))(Argument, Subject)}} + end + ). + +-spec shutdown_child( + gleam@erlang@process:pid_(), + child_spec(any(), any(), any()) +) -> nil. +shutdown_child(Pid, _) -> + gleam@erlang@process:send_exit(Pid). + +-spec perform_instruction_for_child( + FSW, + instruction(), + child_spec(any(), FSW, FSY), + child(FSY) +) -> {ok, {child(FSY), instruction()}} | {error, child_start_error()}. +perform_instruction_for_child(Argument, Instruction, Child_spec, Child) -> + Current = erlang:element(2, Child), + case Instruction of + {start_from, Target} when Target =/= Current -> + {ok, {Child, Instruction}}; + + _ -> + shutdown_child(Current, Child_spec), + gleam@result:then( + start_child(Child_spec, Argument), + fun(Child@1) -> {ok, {Child@1, start_all}} end + ) + end. + +-spec supervisor( + fun((FUF) -> {ok, gleam@erlang@process:subject(FUG)} | + {error, gleam@otp@actor:start_error()}) +) -> child_spec(FUG, FUF, FUF). +supervisor(Start) -> + {child_spec, Start, fun(Argument, _) -> Argument end}. + +-spec worker( + fun((FUN) -> {ok, gleam@erlang@process:subject(FUO)} | + {error, gleam@otp@actor:start_error()}) +) -> child_spec(FUO, FUN, FUN). +worker(Start) -> + {child_spec, Start, fun(Argument, _) -> Argument end}. + +-spec returning( + child_spec(FUV, FUW, any()), + fun((FUW, gleam@erlang@process:subject(FUV)) -> FVC) +) -> child_spec(FUV, FUW, FVC). +returning(Child, Updater) -> + {child_spec, erlang:element(2, Child), Updater}. + +-spec init(spec(any(), FVH)) -> gleam@otp@actor:init_result(state(FVH), message()). +init(Spec) -> + Retry = gleam@erlang@process:new_subject(), + gleam_erlang_ffi:trap_exits(true), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Retry, + fun(Field@0) -> {retry_restart, Field@0} end + ), + gleam@erlang@process:selecting_trapped_exits( + _pipe@1, + fun(Field@0) -> {exit, Field@0} end + ) + end, + Result = begin + _pipe@2 = {starter, erlang:element(2, Spec), none}, + _pipe@3 = {ready, _pipe@2}, + (erlang:element(5, Spec))(_pipe@3) + end, + case Result of + {ready, Starter} -> + Restarts = gleam@otp@intensity_tracker:new( + erlang:element(3, Spec), + erlang:element(4, Spec) + ), + State = {state, Restarts, Starter, Retry}, + {ready, State, Selector}; + + {failed, Error} -> + {failed, case erlang:element(3, Error) of + init_timeout -> + <<"Child initialisation timed out"/utf8>>; + + {init_crashed, Reason} -> + gleam@string:append( + <<"Child crashed during initialisation: "/utf8>>, + gleam@string:inspect(Reason) + ); + + {init_failed, Reason@1} -> + gleam@string:append( + <<"Child failed to start during initialisation: "/utf8>>, + gleam@string:inspect(Reason@1) + ) + end} + end. + +-spec handle_exit(gleam@erlang@process:pid_(), state(FVN)) -> gleam@otp@actor:next(state(FVN)). +handle_exit(Pid, State) -> + Outcome = begin + _assert_subject = erlang:element(3, erlang:element(3, State)), + {some, Start} = case _assert_subject of + {some, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/otp/supervisor"/utf8>>, + function => <<"handle_exit"/utf8>>, + line => 293}) + end, + gleam@result:then( + begin + _pipe = erlang:element(2, State), + _pipe@1 = gleam@otp@intensity_tracker:add_event(_pipe), + gleam@result:map_error(_pipe@1, fun(_) -> too_many_restarts end) + end, + fun(Restarts) -> + gleam@result:then( + begin + _pipe@2 = Start({start_from, Pid}), + gleam@result:map_error( + _pipe@2, + fun(E) -> + {restart_failed, + gleam@option:unwrap( + erlang:element(2, E), + Pid + ), + Restarts} + end + ) + end, + fun(_use0) -> + {Starter, _} = _use0, + {ok, + erlang:setelement( + 2, + erlang:setelement(3, State, Starter), + Restarts + )} + end + ) + end + ) + end, + case Outcome of + {ok, State@1} -> + {continue, State@1}; + + {error, {restart_failed, Failed_child, Restarts@1}} -> + gleam@erlang@process:send(erlang:element(4, State), Failed_child), + State@2 = erlang:setelement(2, State, Restarts@1), + {continue, State@2}; + + {error, too_many_restarts} -> + {stop, + {abnormal, + <<"Child processes restarted too many times within allowed period"/utf8>>}} + end. + +-spec loop(message(), state(FVR)) -> gleam@otp@actor:next(state(FVR)). +loop(Message, State) -> + case Message of + {exit, Exit_message} -> + handle_exit(erlang:element(2, Exit_message), State); + + {retry_restart, Pid} -> + handle_exit(Pid, State) + end. + +-spec start_spec(spec(any(), any())) -> {ok, + gleam@erlang@process:subject(message())} | + {error, gleam@otp@actor:start_error()}. +start_spec(Spec) -> + gleam@otp@actor:start_spec( + {spec, fun() -> init(Spec) end, 60000, fun loop/2} + ). + +-spec start(fun((children(nil)) -> children(any()))) -> {ok, + gleam@erlang@process:subject(message())} | + {error, gleam@otp@actor:start_error()}. +start(Init) -> + start_spec({spec, nil, 5, 1, Init}). + +-spec to_erlang_start_result( + {ok, gleam@erlang@process:subject(any())} | + {error, gleam@otp@actor:start_error()} +) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic()}. +to_erlang_start_result(Res) -> + gleam@otp@actor:to_erlang_start_result(Res). + +-spec application_stopped() -> application_stop(). +application_stopped() -> + gleam_otp_external:application_stopped(). + +-spec add_child_to_starter( + starter(FTG), + child_spec(any(), FTG, FTJ), + child(FTJ) +) -> starter(FTJ). +add_child_to_starter(Starter, Child_spec, Child) -> + Starter@3 = fun(Instruction) -> + gleam@result:then(case erlang:element(3, Starter) of + {some, Start} -> + Start(Instruction); + + none -> + {ok, {Starter, Instruction}} + end, fun(_use0) -> + {Starter@1, Instruction@1} = _use0, + gleam@result:then( + perform_instruction_for_child( + erlang:element(2, Starter@1), + Instruction@1, + Child_spec, + Child + ), + fun(_use0@1) -> + {Child@1, Instruction@2} = _use0@1, + Starter@2 = add_child_to_starter( + Starter@1, + Child_spec, + Child@1 + ), + {ok, {Starter@2, Instruction@2}} + end + ) + end) + end, + {starter, erlang:element(3, Child), {some, Starter@3}}. + +-spec start_and_add_child(starter(FTP), child_spec(any(), FTP, FTS)) -> children(FTS). +start_and_add_child(State, Child_spec) -> + case start_child(Child_spec, erlang:element(2, State)) of + {ok, Child} -> + {ready, add_child_to_starter(State, Child_spec, Child)}; + + {error, Reason} -> + {failed, Reason} + end. + +-spec add(children(FTX), child_spec(any(), FTX, FUA)) -> children(FUA). +add(Children, Child_spec) -> + case Children of + {failed, Fail} -> + {failed, Fail}; + + {ready, State} -> + start_and_add_child(State, Child_spec) + end. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl new file mode 100644 index 00000000000..aa5fabd94c8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl @@ -0,0 +1,43 @@ +-module(gleam@otp@system). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([debug_state/1, get_state/1, suspend/1, resume/1]). +-export_type([mode/0, debug_option/0, status_info/0, system_message/0, debug_state/0, do_not_leak/0]). + +-type mode() :: running | suspended. + +-type debug_option() :: no_debug. + +-type status_info() :: {status_info, + gleam@erlang@atom:atom_(), + gleam@erlang@process:pid_(), + mode(), + debug_state(), + gleam@dynamic:dynamic()}. + +-type system_message() :: {resume, fun(() -> nil)} | + {suspend, fun(() -> nil)} | + {get_state, fun((gleam@dynamic:dynamic()) -> nil)} | + {get_status, fun((status_info()) -> nil)}. + +-type debug_state() :: any(). + +-type do_not_leak() :: any(). + +-spec debug_state(list(debug_option())) -> debug_state(). +debug_state(Field@0) -> + sys:debug_options(Field@0). + +-spec get_state(gleam@erlang@process:pid_()) -> gleam@dynamic:dynamic(). +get_state(Field@0) -> + sys:get_state(Field@0). + +-spec suspend(gleam@erlang@process:pid_()) -> nil. +suspend(Pid) -> + sys:suspend(Pid), + nil. + +-spec resume(gleam@erlang@process:pid_()) -> nil. +resume(Pid) -> + sys:resume(Pid), + nil. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl new file mode 100644 index 00000000000..b475694cbfc --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl @@ -0,0 +1,111 @@ +-module(gleam@otp@task). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([async/1, try_await/2, await/2, try_await_forever/1, await_forever/1]). +-export_type([task/1, await_error/0, message/1]). + +-opaque task(FFD) :: {task, + gleam@erlang@process:pid_(), + gleam@erlang@process:pid_(), + gleam@erlang@process:process_monitor(), + gleam@erlang@process:selector(message(FFD))}. + +-type await_error() :: timeout | {exit, gleam@dynamic:dynamic()}. + +-type message(FFE) :: {from_monitor, gleam@erlang@process:process_down()} | + {from_subject, FFE}. + +-spec async(fun(() -> FFF)) -> task(FFF). +async(Work) -> + Owner = erlang:self(), + Subject = gleam@erlang@process:new_subject(), + Pid = gleam@erlang@process:start( + fun() -> gleam@erlang@process:send(Subject, Work()) end, + true + ), + Monitor = gleam@erlang@process:monitor_process(Pid), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting_process_down( + _pipe, + Monitor, + fun(Field@0) -> {from_monitor, Field@0} end + ), + gleam@erlang@process:selecting( + _pipe@1, + Subject, + fun(Field@0) -> {from_subject, Field@0} end + ) + end, + {task, Owner, Pid, Monitor, Selector}. + +-spec assert_owner(task(any())) -> nil. +assert_owner(Task) -> + Self = erlang:self(), + case erlang:element(2, Task) =:= Self of + true -> + nil; + + false -> + gleam@erlang@process:send_abnormal_exit( + Self, + <<"awaited on a task that does not belong to this process"/utf8>> + ) + end. + +-spec try_await(task(FFJ), integer()) -> {ok, FFJ} | {error, await_error()}. +try_await(Task, Timeout) -> + assert_owner(Task), + case gleam_erlang_ffi:select(erlang:element(5, Task), Timeout) of + {ok, {from_subject, X}} -> + gleam_erlang_ffi:demonitor(erlang:element(4, Task)), + {ok, X}; + + {ok, {from_monitor, {process_down, _, Reason}}} -> + {error, {exit, Reason}}; + + {error, nil} -> + {error, timeout} + end. + +-spec await(task(FFN), integer()) -> FFN. +await(Task, Timeout) -> + _assert_subject = try_await(Task, Timeout), + {ok, Value} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/otp/task"/utf8>>, + function => <<"await"/utf8>>, + line => 117}) + end, + Value. + +-spec try_await_forever(task(FFP)) -> {ok, FFP} | {error, await_error()}. +try_await_forever(Task) -> + assert_owner(Task), + case gleam_erlang_ffi:select(erlang:element(5, Task)) of + {from_subject, X} -> + gleam_erlang_ffi:demonitor(erlang:element(4, Task)), + {ok, X}; + + {from_monitor, {process_down, _, Reason}} -> + {error, {exit, Reason}} + end. + +-spec await_forever(task(FFT)) -> FFT. +await_forever(Task) -> + _assert_subject = try_await_forever(Task), + {ok, Value} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/otp/task"/utf8>>, + function => <<"await_forever"/utf8>>, + line => 149}) + end, + Value. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src new file mode 100644 index 00000000000..79ddc8769ca --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src @@ -0,0 +1,15 @@ +{application, gleam_otp, [ + {vsn, "0.5.3"}, + {applications, [gleam_erlang, + gleam_stdlib, + gleeunit]}, + {description, "Fault tolerant multicore Gleam programs with OTP"}, + {modules, [gleam@otp@actor, + gleam@otp@intensity_tracker, + gleam@otp@node, + gleam@otp@port, + gleam@otp@supervisor, + gleam@otp@system, + gleam@otp@task]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl new file mode 100644 index 00000000000..8910a67d7e2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl @@ -0,0 +1,43 @@ +-module(gleam_otp_external). + +-export([application_stopped/0, convert_system_message/2]). + +% TODO: support other system messages +% {replace_state, StateFn} +% {change_code, Mod, Vsn, Extra} +% {terminate, Reason} +% {debug, {log, Flag}} +% {debug, {trace, Flag}} +% {debug, {log_to_file, FileName}} +% {debug, {statistics, Flag}} +% {debug, no_debug} +% {debug, {install, {Func, FuncState}}} +% {debug, {install, {FuncId, Func, FuncState}}} +% {debug, {remove, FuncOrId}} +% GetStatus(Subject(StatusInfo)) +convert_system_message({From, Ref}, Request) when is_pid(From) -> + Reply = fun(Msg) -> + erlang:send(From, {Ref, Msg}), + nil + end, + System = fun(Callback) -> + {system, {Request, Callback}} + end, + case Request of + get_status -> System(fun(Status) -> Reply(process_status(Status)) end); + get_state -> System(Reply); + suspend -> System(fun() -> Reply(ok) end); + resume -> System(fun() -> Reply(ok) end); + Other -> {unexpeceted, Other} + end. + +process_status({status_info, Module, Parent, Mode, DebugState, State}) -> + Data = [ + get(), Mode, Parent, DebugState, + [{header, "Status for Gleam process " ++ pid_to_list(self())}, + {data, [{'Status', Mode}, {'Parent', Parent}, {'State', State}]}] + ], + {status, self(), {module, Module}, Data}. + +application_stopped() -> + ok. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE new file mode 100644 index 00000000000..c1dabd08e3d --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2018, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/gleam_stdlib/README.md new file mode 100644 index 00000000000..05c68ca9075 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/README.md @@ -0,0 +1,39 @@ +# stdlib + +GitHub release +Discord chat +![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) + +Gleam's standard library! +Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). + +## Installation + +Add `gleam_stdlib` to your Gleam project. + +```sh +gleam add gleam_stdlib +``` + +## Usage + +Import the modules you want to use and write some code! + +```gleam +import gleam/string + +pub fn greet(name: String) -> String { + string.concat(["Hello ", name, "!"]) +} +``` + +## Targets + +Gleam's standard library supports both targets: Erlang and JavaScript. + +### Compatibility + +This library is compatible with all versions of Erlang/OTP, NodeJS, and +major browsers that are currently supported by their maintainers. If you +have a compatibility issue with any platform open an issue and we'll see +what we can do to help. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml new file mode 100644 index 00000000000..44a866e2643 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml @@ -0,0 +1,19 @@ +name = "gleam_stdlib" +version = "0.29.2" +licences = ["Apache-2.0"] +description = "A standard library for the Gleam programming language" + +repository = { type = "github", user = "gleam-lang", repo = "stdlib" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[dependencies] + +[dev-dependencies] + +[javascript.deno] +allow_read = [ + "./", +] diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl new file mode 100644 index 00000000000..b1135f2dea0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl @@ -0,0 +1,5 @@ +-record(decode_error, { + expected :: binary(), + found :: binary(), + path :: list(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl new file mode 100644 index 00000000000..b0d08dc71a3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl @@ -0,0 +1 @@ +-record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl new file mode 100644 index 00000000000..1f61922beda --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl @@ -0,0 +1 @@ +-record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl new file mode 100644 index 00000000000..88ac25ed0a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl @@ -0,0 +1 @@ +-record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl new file mode 100644 index 00000000000..ad5511eb103 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl @@ -0,0 +1 @@ +-record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl new file mode 100644 index 00000000000..42166198699 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl @@ -0,0 +1,4 @@ +-record(match, { + content :: binary(), + submatches :: list(gleam@option:option(binary())) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl new file mode 100644 index 00000000000..0074603b961 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl @@ -0,0 +1 @@ +-record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl new file mode 100644 index 00000000000..9c903123849 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl @@ -0,0 +1 @@ +-record(set, {map :: gleam@map:map_(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl new file mode 100644 index 00000000000..50150f476b1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl @@ -0,0 +1,9 @@ +-record(uri, { + scheme :: gleam@option:option(binary()), + userinfo :: gleam@option:option(binary()), + host :: gleam@option:option(binary()), + port :: gleam@option:option(integer()), + path :: binary(), + 'query' :: gleam@option:option(binary()), + fragment :: gleam@option:option(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam new file mode 100644 index 00000000000..7ec15580d7c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam @@ -0,0 +1,59 @@ +import gleam/bit_string +import gleam/string + +/// Encodes a BitString into a base 64 encoded string. +/// +pub fn encode64(input: BitString, padding: Bool) -> String { + let encoded = do_encode64(input) + case padding { + True -> encoded + False -> string.replace(encoded, "=", "") + } +} + +if erlang { + external fn do_encode64(BitString) -> String = + "base64" "encode" +} + +if javascript { + external fn do_encode64(BitString) -> String = + "../gleam_stdlib.mjs" "encode64" +} + +/// Decodes a base 64 encoded string into a `BitString`. +/// +pub fn decode64(encoded: String) -> Result(BitString, Nil) { + let padded = case bit_string.byte_size(bit_string.from_string(encoded)) % 4 { + 0 -> encoded + n -> string.append(encoded, string.repeat("=", 4 - n)) + } + do_decode64(padded) +} + +if erlang { + external fn do_decode64(String) -> Result(BitString, Nil) = + "gleam_stdlib" "base_decode64" +} + +if javascript { + external fn do_decode64(String) -> Result(BitString, Nil) = + "../gleam_stdlib.mjs" "decode64" +} + +/// Encodes a `BitString` into a base 64 encoded string with URL and filename safe alphabet. +/// +pub fn url_encode64(input: BitString, padding: Bool) -> String { + encode64(input, padding) + |> string.replace("+", "-") + |> string.replace("/", "_") +} + +/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitString`. +/// +pub fn url_decode64(encoded: String) -> Result(BitString, Nil) { + encoded + |> string.replace("-", "+") + |> string.replace("_", "/") + |> decode64() +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam new file mode 100644 index 00000000000..960d6655559 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam @@ -0,0 +1,276 @@ +//// BitBuilder is a type used for efficiently concatenating bits to create bit +//// strings. +//// +//// If we append one bit string to another the bit strings must be copied to a +//// new location in memory so that they can sit together. This behaviour +//// enables efficient reading of the string but copying can be expensive, +//// especially if we want to join many bit strings together. +//// +//// BitBuilder is different in that it can be joined together in constant +//// time using minimal memory, and then can be efficiently converted to a +//// bit string using the `to_bit_string` function. +//// +//// On Erlang this type is compatible with Erlang's iolists. + +import gleam/string_builder.{StringBuilder} + +if javascript { + import gleam/list + import gleam/bit_string +} + +if erlang { + pub external type BitBuilder +} + +if javascript { + pub opaque type BitBuilder { + Bits(BitString) + Text(StringBuilder) + Many(List(BitBuilder)) + } +} + +/// Create an empty `BitBuilder`. Useful as the start of a pipe chaning many +/// builders together. +/// +pub fn new() -> BitBuilder { + do_concat([]) +} + +/// Prepends a bit string to the start of a builder. +/// +/// Runs in constant time. +/// +pub fn prepend(to: BitBuilder, prefix: BitString) -> BitBuilder { + append_builder(from_bit_string(prefix), to) +} + +/// Appends a bit string to the end of a builder. +/// +/// Runs in constant time. +/// +pub fn append(to: BitBuilder, suffix: BitString) -> BitBuilder { + append_builder(to, from_bit_string(suffix)) +} + +/// Prepends a builder onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { + append_builder(prefix, to) +} + +/// Appends a builder onto the end of another. +/// +/// Runs in constant time. +/// +pub fn append_builder( + to first: BitBuilder, + suffix second: BitBuilder, +) -> BitBuilder { + do_append_builder(first, second) +} + +if erlang { + external fn do_append_builder( + to: BitBuilder, + suffix: BitBuilder, + ) -> BitBuilder = + "gleam_stdlib" "iodata_append" +} + +if javascript { + fn do_append_builder(first: BitBuilder, second: BitBuilder) -> BitBuilder { + case second { + Many(builders) -> Many([first, ..builders]) + _ -> Many([first, second]) + } + } +} + +/// Prepends a string onto the start of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { + append_builder(from_string(prefix), to) +} + +/// Appends a string onto the end of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { + append_builder(to, from_string(suffix)) +} + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +pub fn concat(builders: List(BitBuilder)) -> BitBuilder { + do_concat(builders) +} + +if erlang { + external fn do_concat(List(BitBuilder)) -> BitBuilder = + "gleam_stdlib" "identity" +} + +if javascript { + fn do_concat(builders: List(BitBuilder)) -> BitBuilder { + Many(builders) + } +} + +/// Joins a list of bit strings into a single builder. +/// +/// Runs in constant time. +/// +pub fn concat_bit_strings(bits: List(BitString)) -> BitBuilder { + do_concat_bit_strings(bits) +} + +if erlang { + external fn do_concat_bit_strings(List(BitString)) -> BitBuilder = + "gleam_stdlib" "identity" +} + +if javascript { + fn do_concat_bit_strings(bits: List(BitString)) -> BitBuilder { + bits + |> list.map(fn(b) { from_bit_string(b) }) + |> concat() + } +} + +/// Creates a new builder from a string. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +pub fn from_string(string: String) -> BitBuilder { + do_from_string(string) +} + +if erlang { + external fn do_from_string(String) -> BitBuilder = + "gleam_stdlib" "wrap_list" +} + +if javascript { + fn do_from_string(string: String) -> BitBuilder { + Text(string_builder.from_string(string)) + } +} + +/// Creates a new builder from a string builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { + do_from_string_builder(builder) +} + +if erlang { + external fn do_from_string_builder(StringBuilder) -> BitBuilder = + "gleam_stdlib" "wrap_list" +} + +if javascript { + fn do_from_string_builder(builder: StringBuilder) -> BitBuilder { + Text(builder) + } +} + +/// Creates a new builder from a bit string. +/// +/// Runs in constant time. +/// +pub fn from_bit_string(bits: BitString) -> BitBuilder { + do_from_bit_string(bits) +} + +if erlang { + external fn do_from_bit_string(BitString) -> BitBuilder = + "gleam_stdlib" "wrap_list" +} + +if javascript { + fn do_from_bit_string(bits: BitString) -> BitBuilder { + Bits(bits) + } +} + +/// Turns an builder into a bit string. +/// +/// Runs in linear time. +/// +/// When running on Erlang this function is implemented natively by the +/// virtual machine and is highly optimised. +/// +pub fn to_bit_string(builder: BitBuilder) -> BitString { + do_to_bit_string(builder) +} + +if erlang { + external fn do_to_bit_string(BitBuilder) -> BitString = + "erlang" "list_to_bitstring" +} + +if javascript { + fn do_to_bit_string(builder: BitBuilder) -> BitString { + [[builder]] + |> to_list([]) + |> list.reverse + |> bit_string.concat + } + + fn to_list( + stack: List(List(BitBuilder)), + acc: List(BitString), + ) -> List(BitString) { + case stack { + [] -> acc + + [[], ..remaining_stack] -> to_list(remaining_stack, acc) + + [[Bits(bits), ..rest], ..remaining_stack] -> + to_list([rest, ..remaining_stack], [bits, ..acc]) + + [[Text(builder), ..rest], ..remaining_stack] -> { + let bits = bit_string.from_string(string_builder.to_string(builder)) + to_list([rest, ..remaining_stack], [bits, ..acc]) + } + + [[Many(builders), ..rest], ..remaining_stack] -> + to_list([builders, rest, ..remaining_stack], acc) + } + } +} + +/// Returns the size of the builder's content in bytes. +/// +/// Runs in linear time. +/// +pub fn byte_size(builder: BitBuilder) -> Int { + do_byte_size(builder) +} + +if erlang { + external fn do_byte_size(BitBuilder) -> Int = + "erlang" "iolist_size" +} + +if javascript { + fn do_byte_size(builder: BitBuilder) -> Int { + [[builder]] + |> to_list([]) + |> list.fold(0, fn(acc, builder) { bit_string.byte_size(builder) + acc }) + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam new file mode 100644 index 00000000000..6a67028f16d --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam @@ -0,0 +1,155 @@ +//// Working with raw bit string data. +//// The `BitString` type should be used instead of a String type when not utf8 +//// encoded. + +/// Converts a UTF-8 `String` type into a raw `BitString` type. +/// +pub fn from_string(x: String) -> BitString { + do_from_string(x) +} + +if erlang { + external fn do_from_string(String) -> BitString = + "gleam_stdlib" "identity" +} + +if javascript { + external fn do_from_string(String) -> BitString = + "../gleam_stdlib.mjs" "bit_string_from_string" +} + +/// Returns an integer which is the number of bytes in the bit string. +/// +pub fn byte_size(x: BitString) -> Int { + do_byte_size(x) +} + +if erlang { + external fn do_byte_size(BitString) -> Int = + "erlang" "byte_size" +} + +if javascript { + external fn do_byte_size(BitString) -> Int = + "../gleam_stdlib.mjs" "length" +} + +/// Creates a new bit string by joining two binaries. +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: from_string("butter"), suffix: from_string("fly")) +/// from_string("butterfly") +/// ``` +/// +pub fn append(to first: BitString, suffix second: BitString) -> BitString { + concat([first, second]) +} + +/// Extracts a sub-section of a bit string. +/// +/// The slice will start at given position and continue up to specified +/// length. +/// A negative length can be used to extract bytes at the end of a bit string. +/// +/// This function runs in constant time. +/// +pub fn slice( + from string: BitString, + at position: Int, + take length: Int, +) -> Result(BitString, Nil) { + do_slice(string, position, length) +} + +if erlang { + external fn do_slice( + string: BitString, + position: Int, + length: Int, + ) -> Result(BitString, Nil) = + "gleam_stdlib" "bit_string_slice" +} + +if javascript { + external fn do_slice( + string: BitString, + position: Int, + length: Int, + ) -> Result(BitString, Nil) = + "../gleam_stdlib.mjs" "bit_string_slice" +} + +/// Tests to see whether a bit string is valid UTF-8. +/// +pub fn is_utf8(bits: BitString) -> Bool { + do_is_utf8(bits) +} + +if erlang { + fn do_is_utf8(bits: BitString) -> Bool { + case bits { + <<>> -> True + <<_:utf8, rest:binary>> -> do_is_utf8(rest) + _ -> False + } + } +} + +if javascript { + fn do_is_utf8(bits: BitString) -> Bool { + case to_string(bits) { + Ok(_) -> True + _ -> False + } + } +} + +/// Converts a bit string to a string. +/// +/// Returns an error if the bit string is invalid UTF-8 data. +/// +pub fn to_string(bits: BitString) -> Result(String, Nil) { + do_to_string(bits) +} + +if erlang { + external fn unsafe_to_string(BitString) -> String = + "gleam_stdlib" "identity" + + fn do_to_string(bits: BitString) -> Result(String, Nil) { + case is_utf8(bits) { + True -> Ok(unsafe_to_string(bits)) + False -> Error(Nil) + } + } +} + +if javascript { + external fn do_to_string(BitString) -> Result(String, Nil) = + "../gleam_stdlib.mjs" "bit_string_to_string" +} + +/// Creates a new bit string by joining multiple binaries. +/// +/// ## Examples +/// +/// ```gleam +/// > concat([from_string("butter"), from_string("fly")]) +/// from_string("butterfly") +/// ``` +/// +pub fn concat(bit_strings: List(BitString)) -> BitString { + do_concat(bit_strings) +} + +if erlang { + external fn do_concat(List(BitString)) -> BitString = + "gleam_stdlib" "bit_string_concat" +} + +if javascript { + external fn do_concat(List(BitString)) -> BitString = + "../gleam_stdlib.mjs" "bit_string_concat" +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam new file mode 100644 index 00000000000..66200a8a5b4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam @@ -0,0 +1,388 @@ +//// A type with two possible values, `True` and `False`. Used to indicate whether +//// things are... true or false! +//// +//// Often is it clearer and offers more type safety to define a custom type +//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` +//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom +//// type that can be either `Student` or `Teacher`. + +import gleam/order.{Order} + +/// Returns the and of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `&&` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > and(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > and(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > False |> and(True) +/// False +/// ``` +/// +pub fn and(a: Bool, b: Bool) -> Bool { + a && b +} + +/// Returns the or of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `||` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > or(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > False |> or(True) +/// True +/// ``` +/// +pub fn or(a: Bool, b: Bool) -> Bool { + a || b +} + +/// Returns the opposite bool value. +/// +/// This is the same as the `!` or `not` operators in some other languages. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(True) +/// False +/// ``` +/// +/// ```gleam +/// > negate(False) +/// True +/// ``` +/// +pub fn negate(bool: Bool) -> Bool { + case bool { + True -> False + False -> True + } +} + +/// Returns the nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, True) +/// False +/// ``` +/// +pub fn nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> False + } +} + +/// Returns the nand of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nand(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, True) +/// False +/// ``` +/// +pub fn nand(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive or of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_or(False, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, True) +/// False +/// ``` +/// +pub fn exclusive_or(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> False + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, True) +/// True +/// ``` +/// +pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> True + } +} + +/// Compares two bools and returns the first value's `Order` to the second. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/order +/// > compare(True, False) +/// order.Gt +/// ``` +/// +pub fn compare(a: Bool, with b: Bool) -> Order { + case a, b { + True, True -> order.Eq + True, False -> order.Gt + False, False -> order.Eq + False, True -> order.Lt + } +} + +/// Returns `True` if either argument's value is `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > max(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, False) +/// False +/// ``` +/// +pub fn max(a: Bool, b: Bool) -> Bool { + case a { + True -> True + False -> b + } +} + +/// Returns `False` if either bool value is `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > min(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > min(False, True) +/// False +/// +/// > min(False, False) +/// False +/// ``` +/// +pub fn min(a: Bool, b: Bool) -> Bool { + case a { + False -> False + True -> b + } +} + +/// Returns a numeric representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(True) +/// 1 +/// +/// > to_int(False) +/// 0 +/// ``` +/// +pub fn to_int(bool: Bool) -> Int { + case bool { + False -> 0 + True -> 1 + } +} + +/// Returns a string representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(True) +/// "True" +/// ``` +/// +/// ```gleam +/// > to_string(False) +/// "False" +/// ``` +/// +pub fn to_string(bool: Bool) -> String { + case bool { + False -> "False" + True -> "True" + } +} + +/// Run a callback function if the given bool is `False`, otherwise return a +/// default value. +/// +/// With a `use` expression this function can simulate the early-return pattern +/// found in some other programming languages. +/// +/// In a procedural language: +/// +/// ```js +/// if (predicate) return value; +/// // ... +/// ``` +/// +/// In Gleam with a `use` expression: +/// +/// ```gleam +/// use <- guard(when: predicate, return: value) +/// // ... +/// ``` +/// +/// Like everything in Gleam `use` is an expression, so it short circuits the +/// current block, not the entire function. As a result you can assign the value +/// to a variable: +/// +/// ```gleam +/// let x = { +/// use <- guard(when: predicate, return: value) +/// // ... +/// } +/// ``` +/// +/// Note that unlike in procedural languages the `return` value is evaluated +/// even when the predicate is `False`, so it is advisable not to perform +/// expensive computation there. +/// +/// +/// ## Examples +/// +/// ```gleam +/// > let name = "" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Welcome!" +/// ``` +/// +/// ```gleam +/// > let name = "Kamaka" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Hello, Kamaka" +/// ``` +/// +pub fn guard( + when requirement: Bool, + return consequence: t, + otherwise alternative: fn() -> t, +) -> t { + case requirement { + True -> consequence + False -> alternative() + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam new file mode 100644 index 00000000000..86055a003e4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam @@ -0,0 +1,1613 @@ +import gleam/int +import gleam/list +import gleam/map.{Map} +import gleam/option.{Option} +import gleam/result +import gleam/string_builder + +if erlang { + import gleam/bit_string +} + +/// `Dynamic` data is data that we don't know the type of yet. +/// We likely get data like this from interop with Erlang, or from +/// IO with the outside world. +/// +pub external type Dynamic + +/// Error returned when unexpected data is encountered +/// +pub type DecodeError { + DecodeError(expected: String, found: String, path: List(String)) +} + +pub type DecodeErrors = + List(DecodeError) + +pub type Decoder(t) = + fn(Dynamic) -> Result(t, DecodeErrors) + +/// Converts any Gleam data into `Dynamic` data. +/// +pub fn from(a) -> Dynamic { + do_from(a) +} + +if erlang { + external fn do_from(anything) -> Dynamic = + "gleam_stdlib" "identity" +} + +if javascript { + external fn do_from(anything) -> Dynamic = + "../gleam_stdlib.mjs" "identity" +} + +/// Unsafely casts a Dynamic value into any other type. +/// +/// This is an escape hatch for the type system that may be useful when wrapping +/// native Erlang APIs. It is to be used as a last measure only! +/// +/// If you can avoid using this function, do! +/// +pub fn unsafe_coerce(a: Dynamic) -> anything { + do_unsafe_coerce(a) +} + +if erlang { + external fn do_unsafe_coerce(Dynamic) -> a = + "gleam_stdlib" "identity" +} + +if javascript { + external fn do_unsafe_coerce(Dynamic) -> a = + "../gleam_stdlib.mjs" "identity" +} + +/// Decodes a `Dynamic` value from a `Dynamic` value. +/// +/// This function doesn't seem very useful at first, but it can be convenient +/// when you need to give a decoder function but you don't actually care what +/// the to-decode value is. +/// +pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { + Ok(value) +} + +/// Checks to see whether a `Dynamic` value is a bit_string, and returns that bit string if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bit_string(from("Hello")) == bit_string.from_string("Hello") +/// True +/// ``` +/// +/// ```gleam +/// > bit_string(from(123)) +/// Error([DecodeError(expected: "BitString", found: "Int", path: [])]) +/// ``` +/// +pub fn bit_string(from data: Dynamic) -> Result(BitString, DecodeErrors) { + decode_bit_string(data) +} + +if erlang { + external fn decode_bit_string(Dynamic) -> Result(BitString, DecodeErrors) = + "gleam_stdlib" "decode_bit_string" +} + +if javascript { + external fn decode_bit_string(Dynamic) -> Result(BitString, DecodeErrors) = + "../gleam_stdlib.mjs" "decode_bit_string" +} + +/// Checks to see whether a `Dynamic` value is a string, and returns that string if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > string(from("Hello")) +/// Ok("Hello") +/// ``` +/// +/// ```gleam +/// > string(from(123)) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { + decode_string(data) +} + +fn map_errors( + result: Result(t, DecodeErrors), + f: fn(DecodeError) -> DecodeError, +) -> Result(t, DecodeErrors) { + result.map_error(result, list.map(_, f)) +} + +if erlang { + fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { + bit_string(data) + |> map_errors(put_expected(_, "String")) + |> result.try(fn(raw) { + case bit_string.to_string(raw) { + Ok(string) -> Ok(string) + Error(Nil) -> + Error([DecodeError(expected: "String", found: "BitString", path: [])]) + } + }) + } + + fn put_expected(error: DecodeError, expected: String) -> DecodeError { + DecodeError(..error, expected: expected) + } +} + +if javascript { + external fn decode_string(Dynamic) -> Result(String, DecodeErrors) = + "../gleam_stdlib.mjs" "decode_string" +} + +/// Return a string indicating the type of the dynamic value. +/// +/// ```gleam +/// > classify(from("Hello")) +/// "String" +/// ``` +/// +pub fn classify(data: Dynamic) -> String { + do_classify(data) +} + +if erlang { + external fn do_classify(Dynamic) -> String = + "gleam_stdlib" "classify_dynamic" +} + +if javascript { + external fn do_classify(Dynamic) -> String = + "../gleam_stdlib.mjs" "classify_dynamic" +} + +/// Checks to see whether a `Dynamic` value is an int, and returns that int if it +/// is. +/// +/// ## Examples +/// +/// ```gleam +/// > int(from(123)) +/// Ok(123) +/// ``` +/// +/// ```gleam +/// > int(from("Hello")) +/// Error([DecodeError(expected: "Int", found: "String", path: [])]) +/// ``` +/// +pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { + decode_int(data) +} + +if erlang { + external fn decode_int(Dynamic) -> Result(Int, DecodeErrors) = + "gleam_stdlib" "decode_int" +} + +if javascript { + external fn decode_int(Dynamic) -> Result(Int, DecodeErrors) = + "../gleam_stdlib.mjs" "decode_int" +} + +/// Checks to see whether a `Dynamic` value is a float, and returns that float if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > float(from(2.0)) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > float(from(123)) +/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) +/// ``` +/// +pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { + decode_float(data) +} + +if erlang { + external fn decode_float(Dynamic) -> Result(Float, DecodeErrors) = + "gleam_stdlib" "decode_float" +} + +if javascript { + external fn decode_float(Dynamic) -> Result(Float, DecodeErrors) = + "../gleam_stdlib.mjs" "decode_float" +} + +/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bool(from(True)) +/// Ok(True) +/// ``` +/// +/// ```gleam +/// > bool(from(123)) +/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) +/// ``` +/// +pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { + decode_bool(data) +} + +if erlang { + external fn decode_bool(Dynamic) -> Result(Bool, DecodeErrors) = + "gleam_stdlib" "decode_bool" +} + +if javascript { + external fn decode_bool(Dynamic) -> Result(Bool, DecodeErrors) = + "../gleam_stdlib.mjs" "decode_bool" +} + +/// Checks to see whether a `Dynamic` value is a list, and returns that list if it +/// is. The types of the elements are not checked. +/// +/// If you wish to decode all the elements in the list use the `list` function +/// instead. +/// +/// ## Examples +/// +/// ```gleam +/// > shallow_list(from(["a", "b", "c"])) +/// Ok([from("a"), from("b"), from("c")]) +/// ``` +/// +/// ```gleam +/// > shallow_list(1) +/// Error([DecodeError(expected: "List", found: "Int", path: [])]) +/// ``` +/// +pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { + decode_list(value) +} + +if erlang { + external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeErrors) = + "gleam_stdlib" "decode_list" +} + +if javascript { + external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_list" +} + +if erlang { + external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeErrors) = + "gleam_stdlib" "decode_result" +} + +if javascript { + external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_result" +} + +/// Checks to see whether a `Dynamic` value is a result of a particular type, and +/// returns that result if it is. +/// +/// The `ok` and `error` arguments are decoders for decoding the `Ok` and +/// `Error` values of the result. +/// +/// ## Examples +/// +/// ```gleam +/// > from(Ok(1)) +/// > |> result(ok: int, error: string) +/// Ok(Ok(1)) +/// ``` +/// +/// ```gleam +/// > from(Error("boom")) +/// > |> result(ok: int, error: string) +/// Ok(Error("boom")) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> result(ok: int, error: string) +/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) +/// ``` +/// +pub fn result( + ok decode_ok: Decoder(a), + error decode_error: Decoder(e), +) -> Decoder(Result(a, e)) { + fn(value) { + use inner_result <- result.try(decode_result(value)) + + case inner_result { + Ok(raw) -> { + use value <- result.try( + decode_ok(raw) + |> map_errors(push_path(_, "ok")), + ) + Ok(Ok(value)) + } + Error(raw) -> { + use value <- result.try( + decode_error(raw) + |> map_errors(push_path(_, "error")), + ) + Ok(Error(value)) + } + } + } +} + +/// Checks to see whether a `Dynamic` value is a list of a particular type, and +/// returns that list if it is. +/// +/// The second argument is a decoder function used to decode the elements of +/// the list. The list is only decoded if all elements in the list can be +/// successfully decoded using this function. +/// +/// If you do not wish to decode all the elements in the list use the `shallow_list` +/// function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > from(["a", "b", "c"]) +/// > |> list(of: string) +/// Ok(["a", "b", "c"]) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> list(of: string) +/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) +/// ``` +/// +/// ```gleam +/// > from("ok") +/// > |> list(of: string) +/// Error([DecodeError(expected: "List", found: "String", path: [])]) +/// ``` +/// +pub fn list( + of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), +) -> Decoder(List(inner)) { + fn(dynamic) { + use list <- result.try(shallow_list(dynamic)) + list + |> list.try_map(decoder_type) + |> map_errors(push_path(_, "*")) + } +} + +/// Checks to see if a `Dynamic` value is a nullable version of a particular +/// type, and returns a corresponding `Option` if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("null")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("nil")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("undefined")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> optional(string) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { + fn(value) { decode_optional(value, decode) } +} + +if erlang { + external fn decode_optional( + Dynamic, + Decoder(a), + ) -> Result(Option(a), DecodeErrors) = + "gleam_stdlib" "decode_option" +} + +if javascript { + external fn decode_optional( + Dynamic, + Decoder(a), + ) -> Result(Option(a), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_option" +} + +/// Checks to see if a `Dynamic` value is a map with a specific field, and returns +/// the value of that field if it is. +/// +/// This will not succeed on a record. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/map +/// > map.new() +/// > |> map.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok("World") +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { + fn(value) { + let missing_field_error = + DecodeError(expected: "field", found: "nothing", path: []) + + use maybe_inner <- result.try(decode_field(value, name)) + maybe_inner + |> option.to_result([missing_field_error]) + |> result.try(inner_type) + |> map_errors(push_path(_, name)) + } +} + +/// Checks to see if a `Dynamic` value is a map with a specific field. +/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, +/// returns the decoded field wrapped in `Some(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/map +/// > map.new() +/// > |> map.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(Some("World")) +/// ``` +/// +/// ```gleam +/// > import gleam/map +/// > map.new() +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn optional_field( + named name: a, + of inner_type: Decoder(t), +) -> Decoder(Option(t)) { + fn(value) { + use maybe_inner <- result.try(decode_field(value, name)) + case maybe_inner { + option.None -> Ok(option.None) + option.Some(dynamic_inner) -> + dynamic_inner + |> decode_optional(inner_type) + |> map_errors(push_path(_, name)) + } + } +} + +if erlang { + external fn decode_field( + Dynamic, + name, + ) -> Result(Option(Dynamic), DecodeErrors) = + "gleam_stdlib" "decode_field" +} + +if javascript { + external fn decode_field( + Dynamic, + name, + ) -> Result(Option(Dynamic), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_field" +} + +/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain +/// index, and returns the value of that index if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(0, int) +/// Ok(from(1)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(2, int) +/// Error([ +/// DecodeError( +/// expected: "Tuple of at least 3 elements", +/// found: "Tuple of 2 elements", +/// path: [], +/// ), +/// ]) +/// ``` +/// +pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { + fn(data: Dynamic) { + use tuple <- result.try(decode_tuple(data)) + let size = tuple_size(tuple) + use data <- result.try(case index >= 0 { + True -> + case index < size { + True -> tuple_get(tuple, index) + False -> at_least_decode_tuple_error(index + 1, data) + } + False -> + case int.absolute_value(index) <= size { + True -> tuple_get(tuple, size + index) + False -> at_least_decode_tuple_error(int.absolute_value(index), data) + } + }) + inner_type(data) + |> map_errors(push_path(_, index)) + } +} + +fn at_least_decode_tuple_error( + size: Int, + data: Dynamic, +) -> Result(a, DecodeErrors) { + let s = case size { + 1 -> "" + _ -> "s" + } + let error = + ["Tuple of at least ", int.to_string(size), " element", s] + |> string_builder.from_strings + |> string_builder.to_string + |> DecodeError(found: classify(data), path: []) + Error([error]) +} + +// A tuple of unknown size +external type UnknownTuple + +if erlang { + external fn decode_tuple(Dynamic) -> Result(UnknownTuple, DecodeErrors) = + "gleam_stdlib" "decode_tuple" + + external fn decode_tuple2( + Dynamic, + ) -> Result(#(Dynamic, Dynamic), DecodeErrors) = + "gleam_stdlib" "decode_tuple2" + + external fn decode_tuple3( + Dynamic, + ) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) = + "gleam_stdlib" "decode_tuple3" + + external fn decode_tuple4( + Dynamic, + ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = + "gleam_stdlib" "decode_tuple4" + + external fn decode_tuple5( + Dynamic, + ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = + "gleam_stdlib" "decode_tuple5" + + external fn decode_tuple6( + Dynamic, + ) -> Result( + #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), + DecodeErrors, + ) = + "gleam_stdlib" "decode_tuple6" + + external fn tuple_get(UnknownTuple, Int) -> Result(Dynamic, DecodeErrors) = + "gleam_stdlib" "tuple_get" + + external fn tuple_size(UnknownTuple) -> Int = + "gleam_stdlib" "size_of_tuple" +} + +if javascript { + external fn decode_tuple(Dynamic) -> Result(UnknownTuple, DecodeErrors) = + "../gleam_stdlib.mjs" "decode_tuple" + + external fn decode_tuple2( + Dynamic, + ) -> Result(#(Dynamic, Dynamic), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_tuple2" + + external fn decode_tuple3( + Dynamic, + ) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_tuple3" + + external fn decode_tuple4( + Dynamic, + ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_tuple4" + + external fn decode_tuple5( + Dynamic, + ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_tuple5" + + external fn decode_tuple6( + Dynamic, + ) -> Result( + #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), + DecodeErrors, + ) = + "../gleam_stdlib.mjs" "decode_tuple6" + + external fn tuple_get(UnknownTuple, Int) -> Result(Dynamic, DecodeErrors) = + "../gleam_stdlib.mjs" "tuple_get" + + external fn tuple_size(UnknownTuple) -> Int = + "../gleam_stdlib.mjs" "length" +} + +fn tuple_errors( + result: Result(a, List(DecodeError)), + name: String, +) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> list.map(errors, push_path(_, name)) + } +} + +fn push_path(error: DecodeError, name: t) -> DecodeError { + let name = from(name) + let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) + let name = case decoder(name) { + Ok(name) -> name + Error(_) -> + ["<", classify(name), ">"] + |> string_builder.from_strings + |> string_builder.to_string + } + DecodeError(..error, path: [name, ..error.path]) +} + +/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0)) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from([1, 2]) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0)]) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple2(int, float) +/// Error([ +/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple2(int, float) +/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple2( + first decode1: Decoder(a), + second decode2: Decoder(b), +) -> Decoder(#(a, b)) { + fn(value) { + use #(a, b) <- result.try(decode_tuple2(value)) + case decode1(a), decode2(b) { + Ok(a), Ok(b) -> Ok(#(a, b)) + a, b -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3")]) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple3( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), +) -> Decoder(#(a, b, c)) { + fn(value) { + use #(a, b, c) <- result.try(decode_tuple3(value)) + case decode1(a), decode2(b), decode3(c) { + Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) + a, b, c -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4)) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4)) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// +/// ```gleam +/// > from([1, 2, 3, 4]) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4)]) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// ``` +/// +/// > from(#(1, 2)) +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple4( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), +) -> Decoder(#(a, b, c, d)) { + fn(value) { + use #(a, b, c, d) <- result.try(decode_tuple4(value)) + case decode1(a), decode2(b), decode3(c), decode4(d) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) + a, b, c, d -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5)) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5)) +/// > |> tuple5(int, float, string, int, int) +/// Ok(#(1, 2.0, "3", 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5]) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) +/// > |> tuple5(int, float, string, int, bool) +/// Ok(#(1, 2.0, "3", 4, True)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple5(int, float, string, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// +/// > from("") +/// > |> tuple5(int, float, string, int, int) +/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple5( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), +) -> Decoder(#(a, b, c, d, e)) { + fn(value) { + use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) + case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) + a, b, c, d, e -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5, 6)) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5, 6)) +/// > |> tuple6(int, float, string, int, int) +/// Ok(#(1, 2.0, "3", 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5, 6]) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) +/// > |> tuple6(int, float, string, int, bool, bool) +/// Ok(#(1, 2.0, "3", 4, True, False)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple6(int, float, string, int, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple6(int, float, string, int, int, int) +/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple6( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), + sixth decode6: Decoder(f), +) -> Decoder(#(a, b, c, d, e, f)) { + fn(value) { + use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) + case + decode1(a), + decode2(b), + decode3(c), + decode4(d), + decode5(e), + decode6(f) + { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) + a, b, c, d, e, f -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> list.append(tuple_errors(f, "5")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a map. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/map +/// > map.new() |> from |> map(string, int) +/// Ok(map.new()) +/// ``` +/// +/// ```gleam +/// > from(1) |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "Int", path: [])) +/// ``` +/// +/// ```gleam +/// > from("") |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "String", path: [])) +/// ``` +/// +pub fn map( + of key_type: Decoder(k), + to value_type: Decoder(v), +) -> Decoder(Map(k, v)) { + fn(value) { + use map <- result.try(decode_map(value)) + use pairs <- result.try( + map + |> map.to_list + |> list.try_map(fn(pair) { + let #(k, v) = pair + use k <- result.try( + key_type(k) + |> map_errors(push_path(_, "keys")), + ) + use v <- result.try( + value_type(v) + |> map_errors(push_path(_, "values")), + ) + Ok(#(k, v)) + }), + ) + Ok(map.from_list(pairs)) + } +} + +if erlang { + external fn decode_map(Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) = + "gleam_stdlib" "decode_map" +} + +if javascript { + external fn decode_map(Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) = + "../gleam_stdlib.mjs" "decode_map" +} + +/// Joins multiple decoders into one. When run they will each be tried in turn +/// until one succeeds, or they all fail. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/result +/// > let bool_or_string = any(of: [ +/// > string, +/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } +/// > ]) +/// > bool_or_string(from("ok")) +/// Ok("ok") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(True)) +/// Ok("a bool") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(1)) +/// Error(DecodeError(expected: "another type", found: "Int", path: [])) +/// ``` +/// +pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { + fn(data) { + case decoders { + [] -> + Error([ + DecodeError(found: classify(data), expected: "another type", path: []), + ]) + + [decoder, ..decoders] -> + case decoder(data) { + Ok(decoded) -> Ok(decoded) + Error(_) -> any(decoders)(data) + } + } + } +} + +/// Decode 1 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode1(MyRecord, element(0, int)) +/// Ok(MyRecord(1)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode1(MyRecord, element(0, int)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// ]) +/// ``` +/// +pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { + fn(value) { + case t1(value) { + Ok(a) -> Ok(constructor(a)) + a -> Error(all_errors(a)) + } + } +} + +/// Decode 2 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Ok(MyRecord(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode2( + constructor: fn(t1, t2) -> t, + t1: Decoder(t1), + t2: Decoder(t2), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value) { + Ok(a), Ok(b) -> Ok(constructor(a, b)) + a, b -> Error(list.flatten([all_errors(a), all_errors(b)])) + } + } +} + +/// Decode 3 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Ok(MyRecord(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode3( + constructor: fn(t1, t2, t3) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value), t3(value) { + Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) + a, b, c -> + Error(list.flatten([all_errors(a), all_errors(b), all_errors(c)])) + } + } +} + +/// Decode 4 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode4( + constructor: fn(t1, t2, t3, t4) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) + a, b, c, d -> + Error(list.flatten([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + ])) + } + } +} + +/// Decode 5 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode5( + constructor: fn(t1, t2, t3, t4, t5) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) + a, b, c, d, e -> + Error(list.flatten([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + ])) + } + } +} + +/// Decode 6 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode6( + constructor: fn(t1, t2, t3, t4, t5, t6) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> + Ok(constructor(a, b, c, d, e, f)) + a, b, c, d, e, f -> + Error(list.flatten([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + ])) + } + } +} + +/// Decode 7 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode7( + constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> + Ok(constructor(a, b, c, d, e, f, g)) + a, b, c, d, e, f, g -> + Error(list.flatten([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + ])) + } + } +} + +/// Decode 8 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode8( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> + Ok(constructor(a, b, c, d, e, f, g, h)) + a, b, c, d, e, f, g, h -> + Error(list.flatten([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + ])) + } + } +} + +/// Decode 9 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "", "")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode9( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), + t9: Decoder(t9), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> + Ok(constructor(a, b, c, d, e, f, g, h, i)) + a, b, c, d, e, f, g, h, i -> + Error(list.flatten([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + all_errors(i), + ])) + } + } +} + +fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> errors + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam new file mode 100644 index 00000000000..1ee175cf7a2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam @@ -0,0 +1,589 @@ +import gleam/order.{Order} + +/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was +/// not possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2.3") +/// Ok(2.3) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Float, Nil) { + do_parse(string) +} + +if erlang { + external fn do_parse(String) -> Result(Float, Nil) = + "gleam_stdlib" "parse_float" +} + +if javascript { + external fn do_parse(String) -> Result(Float, Nil) = + "../gleam_stdlib.mjs" "parse_float" +} + +/// Returns the string representation of the provided `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2.3) +/// "2.3" +/// ``` +/// +pub fn to_string(x: Float) -> String { + do_to_string(x) +} + +if erlang { + external fn do_to_string(Float) -> String = + "gleam_stdlib" "float_to_string" +} + +if javascript { + external fn do_to_string(Float) -> String = + "../gleam_stdlib.mjs" "float_to_string" +} + +/// Restricts a `Float` between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(1.2, min: 1.4, max: 1.6) +/// 1.4 +/// ``` +/// +pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two `Float`s, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2.0, 2.3) +/// Lt +/// ``` +/// +/// To handle +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) +/// you may use [`loosely_compare`](#loosely_compare) instead. +/// +pub fn compare(a: Float, with b: Float) -> Order { + case a == b { + True -> order.Eq + False -> + case a <. b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two `Float`s within a tolerance, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) +/// Eq +/// ``` +/// +/// If you want to check only for equality you may use +/// [`loosely_equals`](#loosely_equals) instead. +/// +pub fn loosely_compare( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Order { + let difference = absolute_value(a -. b) + case difference <=. tolerance { + True -> order.Eq + False -> compare(a, b) + } +} + +/// Checks for equality of two `Float`s within a tolerance, +/// returning an `Bool`. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) +/// True +/// ``` +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) +/// False +/// ``` +/// +pub fn loosely_equals( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Bool { + let difference = absolute_value(a -. b) + difference <=. tolerance +} + +/// Compares two `Float`s, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2.0, 2.3) +/// 2.0 +/// ``` +/// +pub fn min(a: Float, b: Float) -> Float { + case a <. b { + True -> a + False -> b + } +} + +/// Compares two `Float`s, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2.0, 2.3) +/// 2.3 +/// ``` +/// +pub fn max(a: Float, b: Float) -> Float { + case a >. b { + True -> a + False -> b + } +} + +/// Rounds the value to the next highest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > ceiling(2.3) +/// 3.0 +/// ``` +/// +pub fn ceiling(x: Float) -> Float { + do_ceiling(x) +} + +if erlang { + external fn do_ceiling(Float) -> Float = + "math" "ceil" +} + +if javascript { + external fn do_ceiling(Float) -> Float = + "../gleam_stdlib.mjs" "ceiling" +} + +/// Rounds the value to the next lowest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor(2.3) +/// 2.0 +/// ``` +/// +pub fn floor(x: Float) -> Float { + do_floor(x) +} + +if erlang { + external fn do_floor(Float) -> Float = + "math" "floor" +} + +if javascript { + external fn do_floor(Float) -> Float = + "../gleam_stdlib.mjs" "floor" +} + +/// Rounds the value to the nearest whole number as an `Int`. +/// +/// ## Examples +/// +/// ```gleam +/// > round(2.3) +/// 2 +/// ``` +/// +/// ```gleam +/// > round(2.5) +/// 3 +/// ``` +/// +pub fn round(x: Float) -> Int { + do_round(x) +} + +if erlang { + external fn do_round(Float) -> Int = + "erlang" "round" +} + +if javascript { + fn do_round(x: Float) -> Int { + case x >=. 0.0 { + True -> js_round(x) + _ -> 0 - js_round(negate(x)) + } + } + + external fn js_round(Float) -> Int = + "../gleam_stdlib.mjs" "round" +} + +/// Returns the value as an `Int`, truncating all decimal digits. +/// +/// ## Examples +/// +/// ```gleam +/// > truncate(2.4343434847383438) +/// 2 +/// ``` +/// +pub fn truncate(x: Float) -> Int { + do_truncate(x) +} + +if erlang { + external fn do_truncate(Float) -> Int = + "erlang" "trunc" +} + +if javascript { + external fn do_truncate(Float) -> Int = + "../gleam_stdlib.mjs" "truncate" +} + +/// Returns the absolute value of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12.5) +/// 12.5 +/// ``` +/// +/// ```gleam +/// > absolute_value(10.2) +/// 10.2 +/// ``` +/// +pub fn absolute_value(x: Float) -> Float { + case x >=. 0.0 { + True -> x + _ -> 0.0 -. x + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2.0, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2.0, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8.0, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4.0 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1.0, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { + let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 + // In the following check: + // 1. If the base is negative and the exponent is fractional then + // return an error as it will otherwise be an imaginary number + // 2. If the base is 0 and the exponent is negative then the expression + // is equivalent to the exponent divided by 0 and an error should be + // returned + case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { + True -> Error(Nil) + False -> Ok(do_power(base, exponent)) + } +} + +if erlang { + external fn do_power(Float, Float) -> Float = + "math" "pow" +} + +if javascript { + external fn do_power(Float, Float) -> Float = + "../gleam_stdlib.mjs" "power" +} + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4.0) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16.0) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Float) -> Result(Float, Nil) { + power(x, 0.5) +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1.0) +/// -1.0 +/// ``` +/// +pub fn negate(x: Float) -> Float { + -1.0 *. x +} + +/// Sums a list of `Float`s. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1.0, 2.2, 3.3]) +/// 6.5 +/// ``` +/// +pub fn sum(numbers: List(Float)) -> Float { + numbers + |> do_sum(0.0) +} + +fn do_sum(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x +. initial) + } +} + +/// Multiplies a list of `Float`s and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2.5, 3.2, 4.2]) +/// 33.6 +/// ``` +/// +pub fn product(numbers: List(Float)) -> Float { + case numbers { + [] -> 1.0 + _ -> do_product(numbers, 1.0) + } +} + +fn do_product(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x *. initial) + } +} + +/// Returns `0.0` if `boundary_a` and `boundary_b` are equal, +/// otherwise returns a `Float x` where `lower_boundary =< x < upper_boundary`. +/// +/// ## Examples +/// +/// ```gleam +/// > random(1.0, 5.0) +/// 2.646355926896028 +/// ``` +/// +pub fn random(boundary_a: Float, boundary_b: Float) -> Float { + // Based on: + // + // ```javascript + // return Math.random() * (max - min) + min; // The minimum is inclusive and the maximum is exclusive + // ``` + // + // See: + let #(min, max) = case boundary_a, boundary_b { + a, b if a <=. b -> #(a, b) + a, b if a >. b -> #(b, a) + } + case min, max { + min, _max if min == max -> min + min, max -> do_random_uniform() *. { max -. min } +. min + } +} + +if erlang { + /// Returns a random float uniformly distributed in the value range + /// 0.0 =< X < 1.0 and updates the state in the process dictionary. + /// See: + /// + external fn do_random_uniform() -> Float = + "rand" "uniform" +} + +if javascript { + external fn do_random_uniform() -> Float = + "../gleam_stdlib.mjs" "random_uniform" +} + +/// Returns division of the inputs as a `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0.0, 1.0) +/// Ok(1.0) +/// ``` +/// +/// ```gleam +/// > divide(1.0, 0.0) +/// Error(Nil) +/// ``` +/// +pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { + case b { + 0.0 -> Error(Nil) + b -> Ok(a /. b) + } +} + +/// Adds two floats together. +/// +/// It's the function equivalent of the `+.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1.0, 2.0) +/// 3.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 0.0, add) +/// 6.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> add(2.0) +/// 5.0 +/// ``` +/// +pub fn add(a: Float, b: Float) -> Float { + a +. b +} + +/// Multiplies two floats together. +/// +/// It's the function equivalent of the `*.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2.0, 4.0) +/// 8.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) +/// 24.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> multiply(2.0) +/// 6.0 +/// ``` +/// +pub fn multiply(a: Float, b: Float) -> Float { + a *. b +} + +/// Subtracts one float from another. +/// +/// It's the function equivalent of the `-.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3.0, 1.0) +/// 2.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) +/// 4.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(_, 2.0) +/// 1.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(2.0, _) +/// -1.0 +/// ``` +/// +pub fn subtract(a: Float, b: Float) -> Float { + a -. b +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam new file mode 100644 index 00000000000..daa997de92a --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam @@ -0,0 +1,162 @@ +/// Takes two functions and chains them together to form one function that +/// takes the input from the first and returns the output of the second. +/// +pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { + fn(a) { fun2(fun1(a)) } +} + +/// Takes a function with `2` arguments (an arity of `2`), and returns the +/// curried equivalent. +/// +/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. +/// +/// ## Examples +/// +/// *Currying* creates a new function that is identical to the given function +/// except that arguments must now be supplied one by one over several function +/// calls. It thus is the process of taking a function with `n` arguments +/// and producing a sequence of `n` single-argument functions. Given: +/// +/// ```gleam +/// > fn my_fun(i: Int, s: String) -> String { ... } +/// ``` +/// +/// …calling `curry2(my_fun)` would return the curried equivalent, like so: +/// +/// ```gleam +/// > curry2(my_fun) +/// fn(Int) -> fn(String) -> String +/// ``` +/// +/// Currying is useful when you want to partially apply a function with +/// some arguments and then pass it somewhere else, for example: +/// +/// ```gleam +/// > import gleam/list +/// > let multiply = curry2(fn(x, y) { x * y }) +/// > let doubles = list.map([1, 2, 3], multiply(2)) +/// [2, 4, 6] +/// ``` +/// +pub fn curry2(fun: fn(a, b) -> value) { + fn(a) { fn(b) { fun(a, b) } } +} + +/// Takes a function with `3` arguments (an arity of `3`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry3(fun: fn(a, b, c) -> value) { + fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } +} + +/// Takes a function with `4` arguments (an arity of `4`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry4(fun: fn(a, b, c, d) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } +} + +/// Takes a function with `5` arguments (an arity of `5`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e) -> f` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry5(fun: fn(a, b, c, d, e) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } +} + +/// Takes a function with `6` arguments (an arity of `6`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e, f) -> g` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { + fn(a) { + fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } + } +} + +/// Takes a function that takes two arguments and returns a new function that +/// takes the same two arguments, but in reverse order. +/// +pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { + fn(b, a) { fun(a, b) } +} + +/// Takes a single argument and always returns its input value. +/// +pub fn identity(x: a) -> a { + x +} + +/// Takes a single argument and returns a new function that +/// ignores its argument and always returns the input value. +/// +pub fn constant(value: a) -> fn(b) -> a { + fn(_) { value } +} + +/// Takes an argument and a single function, +/// calls that function with that argument +/// and returns that argument instead of the function return value. +/// Useful for running synchronous side effects in a pipeline. +/// +pub fn tap(arg: a, effect: fn(a) -> b) -> a { + effect(arg) + arg +} + +/// Takes a function with arity one and an argument, +/// calls that function with the argument and returns the function return value. +/// +/// Useful for concisely calling functions returned as a part of a pipeline. +/// +/// ## Example +/// +/// ```gleam +/// > let doubler = fn() { +/// > fn(x: Int) { x * 2 } +/// > } +/// > +/// > doubler() +/// > |> apply1(2) +/// 4 +/// ``` +/// +pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { + fun(arg1) +} + +/// Takes a function with arity two and two arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { + fun(arg1, arg2) +} + +/// Takes a function with arity three and three arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { + fun(arg1, arg2, arg3) +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam new file mode 100644 index 00000000000..793a85e71a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam @@ -0,0 +1,854 @@ +import gleam/float +import gleam/order.{Order} + +/// Returns the absolute value of the input. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12) +/// 12 +/// ``` +/// +/// ```gleam +/// > absolute_value(10) +/// 10 +/// ``` +/// +pub fn absolute_value(x: Int) -> Int { + case x >= 0 { + True -> x + False -> x * -1 + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { + base + |> to_float() + |> float.power(exponent) +} + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Int) -> Result(Float, Nil) { + x + |> to_float() + |> float.square_root() +} + +/// Parses a given string as an int if possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2") +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Int, Nil) { + do_parse(string) +} + +if erlang { + external fn do_parse(String) -> Result(Int, Nil) = + "gleam_stdlib" "parse_int" +} + +if javascript { + external fn do_parse(String) -> Result(Int, Nil) = + "../gleam_stdlib.mjs" "parse_int" +} + +/// Parses a given string as an int in a given base if possible. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > base_parse("10", 2) +/// Ok(2) +/// +/// > base_parse("30", 16) +/// Ok(48) +/// +/// > base_parse("1C", 36) +/// Ok(48) +/// +/// > base_parse("48", 1) +/// Error(Nil) +/// +/// > base_parse("48", 37) +/// Error(Nil) +/// ``` +/// +pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { + case base >= 2 && base <= 36 { + True -> do_base_parse(string, base) + False -> Error(Nil) + } +} + +if erlang { + external fn do_base_parse(String, Int) -> Result(Int, Nil) = + "gleam_stdlib" "int_from_base_string" +} + +if javascript { + external fn do_base_parse(String, Int) -> Result(Int, Nil) = + "../gleam_stdlib.mjs" "int_from_base_string" +} + +/// Prints a given int to a string. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2) +/// "2" +/// ``` +/// +pub fn to_string(x: Int) { + do_to_string(x) +} + +if erlang { + external fn do_to_string(Int) -> String = + "erlang" "integer_to_binary" +} + +if javascript { + external fn do_to_string(Int) -> String = + "../gleam_stdlib.mjs" "to_string" +} + +/// Error value when trying to operate with a base out of the allowed range. +/// +pub type InvalidBase { + InvalidBase +} + +/// Prints a given int to a string using the base number provided. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. +/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base_string(2, 2) +/// Ok("10") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 16) +/// Ok("30") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 36) +/// Ok("1C") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 37) +/// Error(InvalidBase) +/// ``` +/// +pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { + case base >= 2 && base <= 36 { + True -> Ok(do_to_base_string(x, base)) + False -> Error(InvalidBase) + } +} + +if erlang { + external fn do_to_base_string(Int, Int) -> String = + "erlang" "integer_to_binary" +} + +if javascript { + external fn do_to_base_string(Int, Int) -> String = + "../gleam_stdlib.mjs" "int_to_base_string" +} + +/// Prints a given int to a string using base-2. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base2(2) +/// "10" +/// ``` +/// +pub fn to_base2(x: Int) -> String { + do_to_base_string(x, 2) +} + +/// Prints a given int to a string using base-8. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base8(15) +/// "17" +/// ``` +/// +pub fn to_base8(x: Int) -> String { + do_to_base_string(x, 8) +} + +/// Prints a given int to a string using base-16. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base16(48) +/// "30" +/// ``` +/// +pub fn to_base16(x: Int) -> String { + do_to_base_string(x, 16) +} + +/// Prints a given int to a string using base-36. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base36(48) +/// "1C" +/// ``` +/// +pub fn to_base36(x: Int) -> String { + do_to_base_string(x, 36) +} + +/// Takes an int and returns its value as a float. +/// +/// ## Examples +/// +/// ```gleam +/// > to_float(5) +/// 5.0 +/// ``` +/// +/// ```gleam +/// > to_float(0) +/// 0.0 +/// ``` +/// +/// ```gleam +/// > to_float(-3) +/// -3.0 +/// ``` +/// +pub fn to_float(x: Int) -> Float { + do_to_float(x) +} + +if erlang { + external fn do_to_float(Int) -> Float = + "erlang" "float" +} + +if javascript { + external fn do_to_float(Int) -> Float = + "../gleam_stdlib.mjs" "identity" +} + +/// Restricts an int between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(40, min: 50, max: 60) +/// 50 +/// ``` +/// +pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two ints, returning an order. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2, 3) +/// Lt +/// ``` +/// +/// ```gleam +/// > compare(4, 3) +/// Gt +/// ``` +/// +/// ```gleam +/// > compare(3, 3) +/// Eq +/// ``` +/// +pub fn compare(a: Int, with b: Int) -> Order { + case a == b { + True -> order.Eq + False -> + case a < b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two ints, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2, 3) +/// 2 +/// ``` +/// +pub fn min(a: Int, b: Int) -> Int { + case a < b { + True -> a + False -> b + } +} + +/// Compares two ints, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2, 3) +/// 3 +/// ``` +/// +pub fn max(a: Int, b: Int) -> Int { + case a > b { + True -> a + False -> b + } +} + +/// Returns whether the value provided is even. +/// +/// ## Examples +/// +/// ```gleam +/// > is_even(2) +/// True +/// ``` +/// +/// ```gleam +/// > is_even(3) +/// False +/// ``` +/// +pub fn is_even(x: Int) -> Bool { + x % 2 == 0 +} + +/// Returns whether the value provided is odd. +/// +/// ## Examples +/// +/// ```gleam +/// > is_odd(3) +/// True +/// ``` +/// +/// ```gleam +/// > is_odd(2) +/// False +/// ``` +/// +pub fn is_odd(x: Int) -> Bool { + x % 2 != 0 +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1) +/// -1 +/// ``` +/// +pub fn negate(x: Int) -> Int { + -1 * x +} + +/// Sums a list of ints. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1, 2, 3]) +/// 6 +/// ``` +/// +pub fn sum(numbers: List(Int)) -> Int { + numbers + |> do_sum(0) +} + +fn do_sum(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x + initial) + } +} + +/// Multiplies a list of ints and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2, 3, 4]) +/// 24 +/// ``` +/// +pub fn product(numbers: List(Int)) -> Int { + case numbers { + [] -> 1 + _ -> do_product(numbers, 1) + } +} + +fn do_product(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x * initial) + } +} + +/// Splits an integer into its digit representation in the specified base +/// +/// ## Examples +/// +/// ```gleam +/// > digits(234, 10) +/// Ok([2,3,4]) +/// ``` +/// +/// ```gleam +/// > digits(234, 1) +/// Error(InvalidBase) +/// ``` +/// +pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> Ok(do_digits(x, base, [])) + } +} + +fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { + case absolute_value(x) < base { + True -> [x, ..acc] + False -> do_digits(x / base, base, [x % base, ..acc]) + } +} + +/// Joins a list of digits into a single value. +/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. +/// +/// ## Examples +/// +/// ```gleam +/// > undigits([2,3,4], 10) +/// Ok(234) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 2) +/// Error(InvalidBase) +/// ``` +/// +pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> do_undigits(numbers, base, 0) + } +} + +fn do_undigits( + numbers: List(Int), + base: Int, + acc: Int, +) -> Result(Int, InvalidBase) { + case numbers { + [] -> Ok(acc) + [digit, ..] if digit >= base -> Error(InvalidBase) + [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) + } +} + +/// Returns `0` if `boundary_a` and `boundary_b` are equal, +/// otherwise returns an `Int x` where `lower_boundary =< x < upper_boundary`. +/// +/// ## Examples +/// +/// ```gleam +/// > random(1, 5) +/// 2 +/// ``` +/// +pub fn random(boundary_a: Int, boundary_b: Int) -> Int { + // Based on: + // + // ```javascript + // min = Math.ceil(min); + // max = Math.floor(max); + // return Math.floor(Math.random() * (max - min) + min); // The minimum is inclusive and the maximum is exclusive + // ``` + // + // See: + let #(min, max) = case boundary_a, boundary_b { + a, b if a <= b -> #(a, b) + a, b if a > b -> #(b, a) + } + + let min = + to_float(min) + |> float.ceiling() + let max = + to_float(max) + |> float.floor() + + float.random(min, max) + |> float.floor() + |> float.round() +} + +/// Performs a truncated integer division. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0, 1) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > divide(-99, 2) +/// Ok(-49) +/// ``` +/// +pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend / divisor) + } +} + +/// Computes the remainder of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > remainder(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > remainder(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: 3) +/// Ok(-1) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: -3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend % divisor) + } +} + +/// Computes the modulo of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > modulo(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > modulo(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: 3) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: -3) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + _ -> { + let remainder = dividend % divisor + case remainder * divisor < 0 { + True -> Ok(remainder + divisor) + False -> Ok(remainder) + } + } + } +} + +/// Performs a *floored* integer division, which means that the result will +/// always be rounded towards negative infinity. +/// +/// If you want to perform truncated integer division (rounding towards zero), +/// use `int.divide()` or the `/` operator instead. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor_divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > floor_divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > floor_divide(6, -4) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > floor_divide(-99, 2) +/// Ok(-50) +/// ``` +/// +pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> + case dividend * divisor < 0 && dividend % divisor != 0 { + True -> Ok(dividend / divisor - 1) + False -> Ok(dividend / divisor) + } + } +} + +/// Adds two integers together. +/// +/// It's the function equivalent of the `+` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1, 2) +/// 3 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 0, add) +/// 6 +/// ``` +/// +/// ```gleam +/// > 3 |> add(2) +/// 5 +/// ``` +/// +pub fn add(a: Int, b: Int) -> Int { + a + b +} + +/// Multiplies two integers together. +/// +/// It's the function equivalent of the `*` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2, 4) +/// 8 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2, 3, 4], 1, multiply) +/// 24 +/// ``` +/// +/// ```gleam +/// > 3 |> multiply(2) +/// 6 +/// ``` +/// +pub fn multiply(a: Int, b: Int) -> Int { + a * b +} + +/// Subtracts one int from another. +/// +/// It's the function equivalent of the `-` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3, 1) +/// 2.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 10, subtract) +/// 4 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2) +/// 1 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2, _) +/// -1 +/// ``` +/// +pub fn subtract(a: Int, b: Int) -> Int { + a - b +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam new file mode 100644 index 00000000000..c8524f15d93 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam @@ -0,0 +1,147 @@ +import gleam/string + +/// Writes a string to standard output. +/// +/// If you want your output to be printed on its own line see `println`. +/// +/// ## Example +/// +/// ```gleam +/// > io.print("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn print(string: String) -> Nil { + do_print(string) +} + +if erlang { + external fn do_print(string: String) -> Nil = + "gleam_stdlib" "print" +} + +if javascript { + external fn do_print(String) -> Nil = + "../gleam_stdlib.mjs" "print" +} + +/// Writes a string to standard error. +/// +/// If you want your output to be printed on its own line see `println_error`. +/// +/// ## Example +/// +/// ``` +/// > io.print_error("Hi pop") +/// // -> Hi pop +/// Nil +/// ``` +/// +pub fn print_error(string: String) -> Nil { + do_print_error(string) +} + +if erlang { + external fn do_print_error(string: String) -> Nil = + "gleam_stdlib" "print_error" +} + +if javascript { + external fn do_print_error(String) -> Nil = + "../gleam_stdlib.mjs" "print_error" +} + +/// Writes a string to standard output, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println(string: String) -> Nil { + do_println(string) +} + +if erlang { + external fn do_println(string: String) -> Nil = + "gleam_stdlib" "println" +} + +if javascript { + external fn do_println(String) -> Nil = + "../gleam_stdlib.mjs" "console_log" +} + +/// Writes a string to standard error, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println_error("Hi pop") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println_error(string: String) -> Nil { + do_println_error(string) +} + +if erlang { + external fn do_println_error(string: String) -> Nil = + "gleam_stdlib" "println_error" +} + +if javascript { + external fn do_println_error(String) -> Nil = + "../gleam_stdlib.mjs" "console_error" +} + +/// Prints a value to standard error (stderr) yielding Gleam syntax. +/// +/// The value is returned after being printed so it can be used in pipelines. +/// +/// ## Example +/// +/// ```gleam +/// > debug("Hi mum") +/// // -> <<"Hi mum">> +/// "Hi mum" +/// ``` +/// +/// ```gleam +/// > debug(Ok(1)) +/// // -> {ok, 1} +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > import list +/// > [1, 2] +/// > |> list.map(fn(x) { x + 1 }) +/// > |> debug +/// > |> list.map(fn(x) { x * 2 }) +/// // -> [2, 3] +/// [4, 6] +/// ``` +/// +pub fn debug(term: anything) -> anything { + term + |> string.inspect + |> do_debug_println + + term +} + +if erlang { + external fn do_debug_println(string: String) -> Nil = + "gleam_stdlib" "println_error" +} + +if javascript { + external fn do_debug_println(String) -> Nil = + "../gleam_stdlib.mjs" "print_debug" +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam new file mode 100644 index 00000000000..4e5a752c8a8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam @@ -0,0 +1,1442 @@ +import gleam/result +import gleam/int +import gleam/list +import gleam/map.{Map} +import gleam/option.{None, Option, Some} +import gleam/order + +// Internal private representation of an Iterator +type Action(element) { + // Dedicated to Electric Six + // https://youtu.be/_30t2dzEgiw?t=162 + Stop + Continue(element, fn() -> Action(element)) +} + +/// An iterator is a lazily evaluated sequence of element. +/// +/// Iterators are useful when working with collections that are too large to +/// fit in memory (or those that are infinite in size) as they only require the +/// elements currently being processed to be in memory. +/// +/// As a lazy data structure no work is done when an iterator is filters, +/// mapped, etc, instead a new iterator is returned with these transformations +/// applied to the stream. Once the stream has all the required transformations +/// applied it can be evaluated using functions such as `fold` and `to_list`. +/// +pub opaque type Iterator(element) { + Iterator(continuation: fn() -> Action(element)) +} + +// Public API for iteration +pub type Step(element, accumulator) { + Next(element: element, accumulator: accumulator) + Done +} + +// Shortcut for an empty iterator. +fn stop() -> Action(element) { + Stop +} + +// Creating Iterators +fn do_unfold( + initial: acc, + f: fn(acc) -> Step(element, acc), +) -> fn() -> Action(element) { + fn() { + case f(initial) { + Next(x, acc) -> Continue(x, do_unfold(acc, f)) + Done -> Stop + } + } +} + +/// Creates an iterator from a given function and accumulator. +/// +/// The function is called on the accumulator and returns either `Done`, +/// indicating the iterator has no more elements, or `Next` which contains a +/// new element and accumulator. The element is yielded by the iterator and the +/// new accumulator is used with the function to compute the next element in +/// the sequence. +/// +/// ## Examples +/// +/// ```gleam +/// > unfold(from: 5, with: fn(n) { +/// > case n { +/// > 0 -> Done +/// > n -> Next(element: n, accumulator: n - 1) +/// > } +/// > }) +/// > |> to_list +/// [5, 4, 3, 2, 1] +/// ``` +/// +pub fn unfold( + from initial: acc, + with f: fn(acc) -> Step(element, acc), +) -> Iterator(element) { + initial + |> do_unfold(f) + |> Iterator +} + +// TODO: test +/// Creates an iterator that yields values created by calling a given function +/// repeatedly. +/// +pub fn repeatedly(f: fn() -> element) -> Iterator(element) { + unfold(Nil, fn(_) { Next(f(), Nil) }) +} + +/// Creates an iterator that returns the same value infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat(10) +/// > |> take(4) +/// > |> to_list +/// [10, 10, 10, 10] +/// ``` +/// +pub fn repeat(x: element) -> Iterator(element) { + repeatedly(fn() { x }) +} + +/// Creates an iterator that yields each element from the given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn from_list(list: List(element)) -> Iterator(element) { + let yield = fn(acc) { + case acc { + [] -> Done + [head, ..tail] -> Next(head, tail) + } + } + unfold(list, yield) +} + +// Consuming Iterators +fn do_transform( + continuation: fn() -> Action(a), + state: acc, + f: fn(acc, a) -> Step(b, acc), +) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> + case f(state, el) { + Done -> Stop + Next(yield, next_state) -> + Continue(yield, do_transform(next, next_state, f)) + } + } + } +} + +/// Creates an iterator from an existing iterator +/// and a stateful function that may short-circuit. +/// +/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, +/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. +/// +/// ## Examples +/// +/// Approximate implementation of `index` in terms of `transform`: +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) +/// > |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +pub fn transform( + over iterator: Iterator(a), + from initial: acc, + with f: fn(acc, a) -> Step(b, acc), +) -> Iterator(b) { + do_transform(iterator.continuation, initial, f) + |> Iterator +} + +fn do_fold( + continuation: fn() -> Action(e), + f: fn(acc, e) -> acc, + accumulator: acc, +) -> acc { + case continuation() { + Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) + Stop -> accumulator + } +} + +/// Reduces an iterator of elements into a single value by calling a given +/// function on each element in turn. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// If you do not care about the end value and only wish to evaluate the +/// iterator for side effects consider using the `run` function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) +/// 10 +/// ``` +/// +pub fn fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> acc, +) -> acc { + iterator.continuation + |> do_fold(f, initial) +} + +// TODO: test +/// Evaluates all elements emitted by the given iterator. This function is useful for when +/// you wish to trigger any side effects that would occur when evaluating +/// the iterator. +/// +pub fn run(iterator: Iterator(e)) -> Nil { + fold(iterator, Nil, fn(_, _) { Nil }) +} + +/// Evaluates an iterator and returns all the elements as a list. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn to_list(iterator: Iterator(element)) -> List(element) { + iterator + |> fold([], fn(acc, e) { [e, ..acc] }) + |> list.reverse +} + +/// Eagerly accesses the first value of an iterator, returning a `Next` +/// that contains the first value and the rest of the iterator. +/// +/// If called on an empty iterator, `Done` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Next(first, rest) = [1, 2, 3, 4] +/// > |> from_list +/// > |> step +/// > first +/// 1 +/// ``` +/// +/// ```gleam +/// > rest |> to_list +/// [2, 3, 4] +/// ``` +/// +/// ```gleam +/// > empty() |> step +/// Done +/// ``` +/// +pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { + case iterator.continuation() { + Stop -> Done + Continue(e, a) -> Next(e, Iterator(a)) + } +} + +fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { + fn() { + case desired > 0 { + False -> Stop + True -> + case continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, do_take(next, desired - 1)) + } + } + } +} + +/// Creates an iterator that only yields the first `desired` elements. +/// +/// If the iterator does not have enough elements all of them are yielded. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2, 3] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + iterator.continuation + |> do_take(desired) + |> Iterator +} + +fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case desired > 0 { + True -> do_drop(next, desired - 1) + False -> Continue(e, next) + } + } +} + +/// Evaluates and discards the first N elements in an iterator, returning a new +/// iterator. +/// +/// If the iterator does not have enough elements an empty iterator is +/// returned. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [4, 5] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [] +/// ``` +/// +pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + fn() { do_drop(iterator.continuation, desired) } + |> Iterator +} + +fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) + } + } +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { + iterator.continuation + |> do_map(f) + |> Iterator +} + +fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { + case first() { + Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) + Stop -> second() + } +} + +/// Appends two iterators, producing a new iterator. +/// +/// This function does not evaluate the elements of the iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> append([3, 4] |> from_list) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { + fn() { do_append(first.continuation, second.continuation) } + |> Iterator +} + +fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { + case flattened() { + Stop -> Stop + Continue(it, next_iterator) -> + do_append(it.continuation, fn() { do_flatten(next_iterator) }) + } +} + +/// Flattens an iterator of iterators, creating a new iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([[1, 2], [3, 4]]) +/// > |> map(from_list) +/// > |> flatten +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { + fn() { do_flatten(iterator.continuation) } + |> Iterator +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator and then flattening the +/// results. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) +/// > |> to_list +/// [1, 2, 2, 3] +/// ``` +/// +pub fn flat_map( + over iterator: Iterator(a), + with f: fn(a) -> Iterator(b), +) -> Iterator(b) { + iterator + |> map(f) + |> flatten +} + +fn do_filter( + continuation: fn() -> Action(e), + predicate: fn(e) -> Bool, +) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, iterator) -> + case predicate(e) { + True -> Continue(e, fn() { do_filter(iterator, predicate) }) + False -> do_filter(iterator, predicate) + } + } +} + +/// Creates an iterator from an existing iterator and a predicate function. +/// +/// The new iterator will contain elements from the first iterator for which +/// the given function returns `True`. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> filter(int.is_even) +/// > |> to_list +/// [2, 4] +/// ``` +/// +pub fn filter( + iterator: Iterator(a), + for predicate: fn(a) -> Bool, +) -> Iterator(a) { + fn() { do_filter(iterator.continuation, predicate) } + |> Iterator +} + +/// Creates an iterator that repeats a given iterator infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> cycle +/// > |> take(6) +/// > |> to_list +/// [1, 2, 1, 2, 1, 2] +/// ``` +/// +pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { + repeat(iterator) + |> flatten +} + +/// Creates an iterator of ints, starting at a given start int and stepping by +/// one to a given end int. +/// +/// ## Examples +/// +/// ```gleam +/// > range(from: 1, to: 5) |> to_list +/// [1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(from: 1, to: -2) |> to_list +/// [1, 0, -1, -2] +/// ``` +/// +/// ```gleam +/// > range(from: 0, to: 0) |> to_list +/// [0] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { + case int.compare(start, stop) { + order.Eq -> once(fn() { start }) + order.Gt -> + unfold( + from: start, + with: fn(current) { + case current < stop { + False -> Next(current, current - 1) + True -> Done + } + }, + ) + + order.Lt -> + unfold( + from: start, + with: fn(current) { + case current > stop { + False -> Next(current, current + 1) + True -> Done + } + }, + ) + } +} + +fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { + case continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + case f(e) { + True -> Ok(e) + False -> do_find(next, f) + } + } +} + +/// Finds the first element in a given iterator for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if the function does not return `True` for any of the +/// elements. +/// +/// ## Examples +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find(empty(), fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: Iterator(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + haystack.continuation + |> do_find(is_desired) +} + +fn do_index( + continuation: fn() -> Action(element), + next: Int, +) -> fn() -> Action(#(Int, element)) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> + Continue(#(next, e), do_index(continuation, next + 1)) + } + } +} + +/// Wraps values yielded from an iterator with indices, starting from 0. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) |> index |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +/// +pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { + iterator.continuation + |> do_index(0) + |> Iterator +} + +/// Creates an iterator that inifinitely applies a function to a value. +/// +/// ## Examples +/// +/// ```gleam +/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list +/// [1, 3, 9, 27, 81] +/// ``` +/// +pub fn iterate( + from initial: element, + with f: fn(element) -> element, +) -> Iterator(element) { + unfold(initial, fn(element) { Next(element, f(element)) }) +} + +fn do_take_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> fn() -> Action(element) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Stop + True -> Continue(e, do_take_while(next, predicate)) + } + } + } +} + +/// Creates an iterator that yields elements while the predicate returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 2, 4]) +/// > |> take_while(satisfying: fn(x) { x < 3 }) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + iterator.continuation + |> do_take_while(predicate) + |> Iterator +} + +fn do_drop_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Continue(e, next) + True -> do_drop_while(next, predicate) + } + } +} + +/// Creates an iterator that drops elements while the predicate returns `True`, +/// and then yields the remaining elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 2, 5]) +/// > |> drop_while(satisfying: fn(x) { x < 4 }) +/// > |> to_list +/// [4, 2, 5] +/// ``` +/// +pub fn drop_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + fn() { do_drop_while(iterator.continuation, predicate) } + |> Iterator +} + +fn do_scan( + continuation: fn() -> Action(element), + f: fn(acc, element) -> acc, + accumulator: acc, +) -> fn() -> Action(acc) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> { + let accumulated = f(accumulator, el) + Continue(accumulated, do_scan(next, f, accumulated)) + } + } + } +} + +/// Creates an iterator from an existing iterator and a stateful function. +/// +/// Specifically, this behaves like `fold`, but yields intermediate results. +/// +/// ## Examples +/// +/// ```gleam +/// // Generate a sequence of partial sums +/// > from_list([1, 2, 3, 4, 5]) +/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) +/// > |> to_list +/// [1, 3, 6, 10, 15] +/// ``` +/// +pub fn scan( + over iterator: Iterator(element), + from initial: acc, + with f: fn(acc, element) -> acc, +) -> Iterator(acc) { + iterator.continuation + |> do_scan(f, initial) + |> Iterator +} + +fn do_zip( + left: fn() -> Action(a), + right: fn() -> Action(b), +) -> fn() -> Action(#(a, b)) { + fn() { + case left() { + Stop -> Stop + Continue(el_left, next_left) -> + case right() { + Stop -> Stop + Continue(el_right, next_right) -> + Continue(#(el_left, el_right), do_zip(next_left, next_right)) + } + } + } +} + +/// Zips two iterators together, emitting values from both +/// until the shorter one runs out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> zip(range(20, 30)) +/// > |> to_list +/// [#("a", 20), #("b", 21), #("c", 22)] +/// ``` +/// +pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { + do_zip(left.continuation, right.continuation) + |> Iterator +} + +// Result of collecting a single chunk by key +type Chunk(element, key) { + AnotherBy(List(element), key, element, fn() -> Action(element)) + LastBy(List(element)) +} + +fn next_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + current_chunk: List(element), +) -> Chunk(element, key) { + case continuation() { + Stop -> LastBy(list.reverse(current_chunk)) + Continue(e, next) -> { + let key = f(e) + case key == previous_key { + True -> next_chunk(next, f, key, [e, ..current_chunk]) + False -> AnotherBy(list.reverse(current_chunk), key, e, next) + } + } + } +} + +fn do_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + previous_element: element, +) -> Action(List(element)) { + case next_chunk(continuation, f, previous_key, [previous_element]) { + LastBy(chunk) -> Continue(chunk, stop) + AnotherBy(chunk, key, el, next) -> + Continue(chunk, fn() { do_chunk(next, f, key, el) }) + } +} + +/// Creates an iterator that emits chunks of elements +/// for which `f` returns the same value. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) +/// > |> chunk(by: fn(n) { n % 2 }) +/// > |> to_list +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk( + over iterator: Iterator(element), + by f: fn(element) -> key, +) -> Iterator(List(element)) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> do_chunk(next, f, f(e), e) + } + } + |> Iterator +} + +// Result of collecting a single sized chunk +type SizedChunk(element) { + Another(List(element), fn() -> Action(element)) + Last(List(element)) + NoMore +} + +fn next_sized_chunk( + continuation: fn() -> Action(element), + left: Int, + current_chunk: List(element), +) -> SizedChunk(element) { + case continuation() { + Stop -> + case current_chunk { + [] -> NoMore + remaining -> Last(list.reverse(remaining)) + } + Continue(e, next) -> { + let chunk = [e, ..current_chunk] + case left > 1 { + False -> Another(list.reverse(chunk), next) + True -> next_sized_chunk(next, left - 1, chunk) + } + } + } +} + +fn do_sized_chunk( + continuation: fn() -> Action(element), + count: Int, +) -> fn() -> Action(List(element)) { + fn() { + case next_sized_chunk(continuation, count, []) { + NoMore -> Stop + Last(chunk) -> Continue(chunk, stop) + Another(chunk, next_element) -> + Continue(chunk, do_sized_chunk(next_element, count)) + } + } +} + +/// Creates an iterator that emits chunks of given size. +/// +/// If the last chunk does not have `count` elements, it is yielded +/// as a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) +/// > |> sized_chunk(into: 2) +/// > |> to_list +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) +/// > |> sized_chunk(into: 3) +/// > |> to_list +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk( + over iterator: Iterator(element), + into count: Int, +) -> Iterator(List(element)) { + iterator.continuation + |> do_sized_chunk(count) + |> Iterator +} + +fn do_intersperse( + continuation: fn() -> Action(element), + separator: element, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> { + let next_interspersed = fn() { do_intersperse(next, separator) } + Continue(separator, fn() { Continue(e, next_interspersed) }) + } + } +} + +/// Creates an iterator that yields the given `elem` element +/// between elements emitted by the underlying iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() +/// > |> intersperse(with: 0) +/// > |> to_list +/// [] +/// +/// > from_list([1]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1] +/// +/// > from_list([1, 2, 3, 4, 5]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1, 0, 2, 0, 3, 0, 4, 0, 5] +/// ``` +/// +pub fn intersperse( + over iterator: Iterator(element), + with elem: element, +) -> Iterator(element) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) + } + } + |> Iterator +} + +fn do_any( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> False + Continue(e, next) -> + case predicate(e) { + True -> True + False -> do_any(next, predicate) + } + } +} + +/// Returns `True` if any element emitted by the iterator satisfies the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a satisfying element. +/// +/// An empty iterator results in `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn any( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_any(predicate) +} + +fn do_all( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> True + Continue(e, next) -> + case predicate(e) { + True -> do_all(next, predicate) + False -> False + } + } +} + +/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a non-satisfying element. +/// +/// An empty iterator results in `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn all( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_all(predicate) +} + +fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { + fn(maybe_group) { + case maybe_group { + Some(group) -> [el, ..group] + None -> [el] + } + } +} + +fn group_updater( + f: fn(element) -> key, +) -> fn(Map(key, List(element)), element) -> Map(key, List(element)) { + fn(groups, elem) { + groups + |> map.update(f(elem), update_group_with(elem)) + } +} + +/// Returns a `Map(k, List(element))` of elements from the given iterator +/// grouped with the given key function. +/// +/// The order within each group is preserved from the iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) +/// map.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) +/// ``` +/// +pub fn group( + in iterator: Iterator(element), + by key: fn(element) -> key, +) -> Map(key, List(element)) { + iterator + |> fold(map.new(), group_updater(key)) + |> map.map_values(fn(_, group) { list.reverse(group) }) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first yielded element +/// and combines it with each subsequent element in turn using the given function. +/// The function is called as `f(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce( + over iterator: Iterator(e), + with f: fn(e, e) -> e, +) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + do_fold(next, f, e) + |> Ok + } +} + +/// Returns the last element in the given iterator. +/// +/// Returns `Error(Nil)` if the iterator is empty. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> last +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > range(1, 10) |> last +/// Ok(9) +/// ``` +/// +pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { + iterator + |> reduce(fn(_, elem) { elem }) +} + +/// Creates an iterator that yields no elements. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> to_list +/// [] +/// ``` +/// +pub fn empty() -> Iterator(element) { + Iterator(stop) +} + +/// Creates an iterator that yields exactly one element provided by calling the given function. +/// +/// ## Examples +/// +/// ```gleam +/// > once(fn() { 1 }) |> to_list +/// [1] +/// ``` +/// +pub fn once(f: fn() -> element) -> Iterator(element) { + fn() { Continue(f(), stop) } + |> Iterator +} + +/// Creates an iterator that yields the given element exactly once. +/// +/// ## Examples +/// +/// ```gleam +/// > single(1) |> to_list +/// [1] +/// ``` +/// +pub fn single(elem: element) -> Iterator(element) { + once(fn() { elem }) +} + +fn do_interleave( + current: fn() -> Action(element), + next: fn() -> Action(element), +) -> Action(element) { + case current() { + Stop -> next() + Continue(e, next_other) -> + Continue(e, fn() { do_interleave(next, next_other) }) + } +} + +/// Creates an iterator that alternates between the two given iterators +/// until both have run out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list +/// [1, 11, 2, 12, 3, 13, 4, 14] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list +/// [1, 100, 2, 3, 4] +/// ``` +/// +pub fn interleave( + left: Iterator(element), + with right: Iterator(element), +) -> Iterator(element) { + fn() { do_interleave(left.continuation, right.continuation) } + |> Iterator +} + +fn do_fold_until( + continuation: fn() -> Action(e), + f: fn(acc, e) -> list.ContinueOrStop(acc), + accumulator: acc, +) -> acc { + case continuation() { + Stop -> accumulator + Continue(elem, next) -> + case f(accumulator, elem) { + list.Continue(accumulator) -> do_fold_until(next, f, accumulator) + list.Stop(accumulator) -> accumulator + } + } +} + +/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given +/// function on each element in turn, but uses `list.ContinueOrStop` to determine +/// whether or not to keep iterating. +/// +/// If called on an iterator of infinite length then this function will only ever +/// return if the function returns `list.Stop`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > let f = fn(acc, e) { +/// > case e { +/// > _ if e < 4 -> list.Continue(e + acc) +/// > _ -> list.Stop(acc) +/// > } +/// > } +/// > +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold_until(from: acc, with: f) +/// 6 +/// ``` +/// +pub fn fold_until( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> list.ContinueOrStop(acc), +) -> acc { + iterator.continuation + |> do_fold_until(f, initial) +} + +fn do_try_fold( + over continuation: fn() -> Action(a), + with f: fn(acc, a) -> Result(acc, err), + from accumulator: acc, +) -> Result(acc, err) { + case continuation() { + Stop -> Ok(accumulator) + Continue(elem, next) -> { + use accumulator <- result.try(f(accumulator, elem)) + do_try_fold(next, f, accumulator) + } + } +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> iterator.from_list() +/// > |> try_fold(0, fn(acc, i) { +/// > case i < 3 { +/// > True -> Ok(acc + i) +/// > False -> Error(Nil) +/// > } +/// > }) +/// Error(Nil) +/// ``` +/// +pub fn try_fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> Result(acc, err), +) -> Result(acc, err) { + iterator.continuation + |> do_try_fold(f, initial) +} + +/// Returns the first element yielded by the given iterator, if it exists, +/// or `Error(Nil)` otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) |> first +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > empty() |> first +/// Error(Nil) +/// ``` +pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, _) -> Ok(e) + } +} + +/// Returns nth element yielded by the given iterator, where `0` means the first element. +/// +/// If there are not enough elements in the iterator, `Error(Nil)` is returned. +/// +/// For any `index` less than `0` this function behaves as if it was set to `0`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(2) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(4) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > empty() |> at(0) +/// Error(Nil) +/// ``` +/// +pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { + iterator + |> drop(index) + |> first +} + +fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { + case continuation() { + Stop -> length + Continue(_, next) -> do_length(next, length + 1) + } +} + +/// Counts the number of elements in the given iterator. +/// +/// This function has to traverse the entire iterator to count its elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> length +/// 0 +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> length +/// 4 +/// ``` +/// +pub fn length(over iterator: Iterator(e)) -> Int { + iterator.continuation + |> do_length(0) +} + +/// Traverse an iterator, calling a function on each element. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> each(io.println) +/// Nil +/// ``` +/// +/// ```gleam +/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) +/// // -> Tom +/// // -> Malory +/// // -> Louis +/// Nil +/// ``` +/// +pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { + iterator + |> map(f) + |> run +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam new file mode 100644 index 00000000000..72650163b18 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam @@ -0,0 +1,2075 @@ +//// Lists are an ordered sequence of elements and are one of the most common +//// data types in Gleam. +//// +//// New elements can be added and removed from the front of a list in +//// constant time, while adding and removing from the end requires traversing +//// the copying the whole list, so keep this in mind when designing your +//// programs. +//// +//// There is a dedicated syntax for prefixing to a list: +//// +//// ```gleam +//// let new_list = [1, 2, ..existing_list] +//// ``` +//// +//// And a matching syntax for getting the first elements of a list: +//// +//// ```gleam +//// case list { +//// [first_element, ..rest] -> first_element +//// _ -> "this pattern matches when the list is empty" +//// } +//// ``` +//// + +import gleam/int +import gleam/float +import gleam/order.{Order} +import gleam/pair +import gleam/map.{Map} + +/// An error value returned by the `strict_zip` function. +/// +pub type LengthMismatch { + LengthMismatch +} + +/// Counts the number of elements in a given list. +/// +/// This function has to traverse the list to determine the number of elements, +/// so it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > length([]) +/// 0 +/// ``` +/// +/// ```gleam +/// > length([1]) +/// 1 +/// ``` +/// +/// ```gleam +/// > length([1, 2]) +/// 2 +/// ``` +/// +pub fn length(of list: List(a)) -> Int { + do_length(list) +} + +if erlang { + external fn do_length(List(a)) -> Int = + "erlang" "length" +} + +if javascript { + fn do_length(list: List(a)) -> Int { + do_length_acc(list, 0) + } + + fn do_length_acc(list: List(a), count: Int) -> Int { + case list { + [_, ..list] -> do_length_acc(list, count + 1) + _ -> count + } + } +} + +/// Creates a new list from a given list containing the same elements but in the +/// opposite order. +/// +/// This function has to traverse the list to create the new reversed list, so +/// it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse([]) +/// [] +/// ``` +/// +/// ```gleam +/// > reverse([1]) +/// [1] +/// ``` +/// +/// ```gleam +/// > reverse([1, 2]) +/// [2, 1] +/// ``` +/// +pub fn reverse(xs: List(a)) -> List(a) { + do_reverse(xs) +} + +if erlang { + external fn do_reverse(List(a)) -> List(a) = + "lists" "reverse" +} + +if javascript { + fn do_reverse(list) { + do_reverse_acc(list, []) + } + + fn do_reverse_acc(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) + } + } +} + +/// Determines whether or not the list is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty([]) +/// True +/// ``` +/// +/// ```gleam +/// > is_empty([1]) +/// False +/// ``` +/// +/// ```gleam +/// > is_empty([1, 1]) +/// False +/// ``` +/// +pub fn is_empty(list: List(a)) -> Bool { + list == [] +} + +/// Determines whether or not a given element exists within a given list. +/// +/// This function traverses the list to find the element, so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [0] |> contains(any: 0) +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 0] |> contains(any: 0) +/// True +/// ``` +/// +pub fn contains(list: List(a), any elem: a) -> Bool { + case list { + [] -> False + [first, ..] if first == elem -> True + [_, ..rest] -> contains(rest, elem) + } +} + +/// Gets the first element from the start of the list, if there is one. +/// +/// ## Examples +/// +/// ```gleam +/// > first([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first([0]) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > first([1, 2]) +/// Ok(1) +/// ``` +/// +pub fn first(list: List(a)) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [x, ..] -> Ok(x) + } +} + +/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is +/// returned. +/// +/// This function runs in constant time and does not make a copy of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > rest([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > rest([0]) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > rest([1, 2]) +/// Ok([2]) +/// ``` +/// +pub fn rest(list: List(a)) -> Result(List(a), Nil) { + case list { + [] -> Error(Nil) + [_, ..xs] -> Ok(xs) + } +} + +fn update_group( + f: fn(element) -> key, +) -> fn(Map(key, List(element)), element) -> Map(key, List(element)) { + fn(groups, elem) { + case map.get(groups, f(elem)) { + Ok(existing) -> map.insert(groups, f(elem), [elem, ..existing]) + Error(_) -> map.insert(groups, f(elem), [elem]) + } + } +} + +/// Takes a list and groups the values by a key +/// which is built from a key function. +/// +/// Does not preserve the initial value order. +/// +/// ## Examples +/// +/// ```gleam +/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] +/// |> group(by: fn(i) { +/// case i { +/// Ok(_) -> "Successful" +/// Error(_) -> "Failed" +/// } +/// }) +/// |> map.to_list +/// +/// [ +/// #("Failed", [Error("Wrong")]), +/// #("Successful", [Ok(73), Ok(200), Ok(3)]) +/// ] +/// +/// > group(from: [1,2,3,4,5], with: fn(i) {fn(i) { i - i / 3 * 3 }}) +/// |> map.to_list +/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] +/// ``` +/// +pub fn group(list: List(v), by key: fn(v) -> k) -> Map(k, List(v)) { + fold(list, map.new(), update_group(key)) +} + +fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + True -> [x, ..acc] + False -> acc + } + do_filter(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) +/// [4, 6] +/// ``` +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) +/// [] +/// ``` +/// +pub fn filter(list: List(a), for predicate: fn(a) -> Bool) -> List(a) { + do_filter(list, predicate, []) +} + +fn do_filter_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + Ok(x) -> [x, ..acc] + Error(_) -> acc + } + do_filter_map(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `Ok(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], Error) +/// [] +/// ``` +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) +/// [3, 5, 7, 2] +/// ``` +/// +pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { + do_filter_map(list, fun, []) +} + +fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one. +/// +/// ## Examples +/// +/// ```gleam +/// > map([2, 4, 6], fn(x) { x * 2 }) +/// [4, 8, 12] +/// ``` +/// +pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { + do_map(list, fun, []) +} + +/// Similar to `map` but also lets you pass around an accumulated value. +/// +/// ## Examples +/// +/// ```gleam +/// > map_fold( +/// over: [1, 2, 3], +/// from: 100, +/// with: fn(memo, i) { #(memo + i, i * 2) } +/// ) +/// #(106, [2, 4, 6]) +/// ``` +/// +pub fn map_fold( + over list: List(a), + from acc: acc, + with fun: fn(acc, a) -> #(acc, b), +) -> #(acc, List(b)) { + fold( + over: list, + from: #(acc, []), + with: fn(acc, item) { + let #(current_acc, items) = acc + let #(next_acc, next_item) = fun(current_acc, item) + #(next_acc, [next_item, ..items]) + }, + ) + |> pair.map_second(reverse) +} + +fn do_index_map( + list: List(a), + fun: fn(Int, a) -> b, + index: Int, + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let acc = [fun(index, x), ..acc] + do_index_map(xs, fun, index + 1, acc) + } + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one and their index. +/// +/// The index starts at 0, so the first element is 0, the second is 1, and so +/// on. +/// +/// ## Examples +/// +/// ```gleam +/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) +/// [#(0, "a"), #(1, "b")] +/// ``` +/// +pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { + do_index_map(list, fun, 0, []) +} + +fn do_try_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> Result(List(b), e) { + case list { + [] -> Ok(reverse(acc)) + [x, ..xs] -> + case fun(x) { + Ok(y) -> do_try_map(xs, fun, [y, ..acc]) + Error(error) -> Error(error) + } + } +} + +/// Takes a function that returns a `Result` and applies it to each element in a +/// given list in turn. +/// +/// If the function returns `Ok(new_value)` for all elements in the list then a +/// list of the new values is returned. +/// +/// If the function returns `Error(reason)` for any of the elements then it is +/// returned immediately. None of the elements in the list are processed after +/// one returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) +/// Ok([3, 4, 5]) +/// ``` +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(_) { Error(0) }) +/// Error(0) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [2, 3]], first) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [], [2]], first) +/// Error(Nil) +/// ``` +/// +pub fn try_map( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(List(b), e) { + do_try_map(list, fun, []) +} + +/// Returns a list that is the given list with up to the given number of +/// elements removed from the front of the list. +/// +/// If the element has less than the number of elements an empty list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 2) +/// [3, 4] +/// ``` +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 9) +/// [] +/// ``` +/// +pub fn drop(from list: List(a), up_to n: Int) -> List(a) { + case n <= 0 { + True -> list + False -> + case list { + [] -> [] + [_, ..xs] -> drop(xs, n - 1) + } + } +} + +fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { + case n <= 0 { + True -> reverse(acc) + False -> + case list { + [] -> reverse(acc) + [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) + } + } +} + +/// Returns a list containing the first given number of elements from the given +/// list. +/// +/// If the element has less than the number of elements then the full list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > take([1, 2, 3, 4], 2) +/// [1, 2] +/// ``` +/// +/// ```gleam +/// > take([1, 2, 3, 4], 9) +/// [1, 2, 3, 4] +/// ``` +/// +pub fn take(from list: List(a), up_to n: Int) -> List(a) { + do_take(list, n, []) +} + +/// Returns a new empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// [] +/// ``` +/// +pub fn new() -> List(a) { + [] +} + +/// Joins one list onto the end of another. +/// +/// This function runs in linear time, and it traverses and copies the first +/// list. +/// +/// ## Examples +/// +/// ```gleam +/// > append([1, 2], [3]) +/// [1, 2, 3] +/// ``` +/// +pub fn append(first: List(a), second: List(a)) -> List(a) { + do_append(first, second) +} + +if erlang { + external fn do_append(List(a), List(a)) -> List(a) = + "lists" "append" +} + +if javascript { + fn do_append(first: List(a), second: List(a)) -> List(a) { + do_append_acc(reverse(first), second) + } + + fn do_append_acc(first: List(a), second: List(a)) -> List(a) { + case first { + [] -> second + [item, ..rest] -> do_append_acc(rest, [item, ..second]) + } + } +} + +/// Prefixes an item to a list. This can also be done using the dedicated +/// syntax instead +/// +/// ```gleam +/// let new_list = [1, ..existing_list] +/// ``` +/// +pub fn prepend(to list: List(a), this item: a) -> List(a) { + [item, ..list] +} + +// Reverses a list and prepends it to another list +fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { + case prefix { + [] -> suffix + [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) + } +} + +fn do_flatten(lists: List(List(a)), acc: List(a)) -> List(a) { + case lists { + [] -> reverse(acc) + [list, ..further_lists] -> + do_flatten(further_lists, reverse_and_prepend(list: list, to: acc)) + } +} + +/// Flattens a list of lists into a single list. +/// +/// This function traverses all elements twice. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten([[1], [2, 3], []]) +/// [1, 2, 3] +/// ``` +/// +pub fn flatten(lists: List(List(a))) -> List(a) { + do_flatten(lists, []) +} + +/// Maps the list with the given function and then flattens it. +/// +/// ## Examples +/// +/// ```gleam +/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) +/// [2, 3, 4, 5, 6, 7] +/// ``` +/// +pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { + map(list, fun) + |> flatten +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from left to right. +/// +/// `fold([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 1), 2), 3)`. +/// +/// This function runs in linear time. +/// +pub fn fold( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fold(rest, fun(initial, x), fun) + } +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from right to left. +/// +/// `fold_right([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 3), 2), 1)`. +/// +/// This function runs in linear time. +/// +/// Unlike `fold` this function is not tail recursive. Where possible use +/// `fold` instead as it will use less memory. +/// +pub fn fold_right( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fun(fold_right(rest, initial, fun), x) + } +} + +fn do_index_fold( + over: List(a), + acc: acc, + with: fn(acc, a, Int) -> acc, + index: Int, +) -> acc { + case over { + [] -> acc + [first, ..rest] -> + do_index_fold(rest, with(acc, first, index), with, index + 1) + } +} + +/// Like fold but the folding function also receives the index of the current element. +/// +/// ## Examples +/// +/// ```gleam +/// ["a", "b", "c"] +/// |> index_fold([], fn(acc, item, index) { ... }) +/// ``` +/// +pub fn index_fold( + over over: List(a), + from initial: acc, + with fun: fn(acc, a, Int) -> acc, +) -> acc { + do_index_fold(over, initial, fun, 0) +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> try_fold(0, fn(acc, i) { +/// case i < 3 { +/// True -> Ok(acc + i) +/// False -> Error(Nil) +/// } +/// }) +/// ``` +/// +pub fn try_fold( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> Result(acc, e), +) -> Result(acc, e) { + case collection { + [] -> Ok(accumulator) + [first, ..rest] -> + case fun(accumulator, first) { + Ok(result) -> try_fold(rest, result, fun) + Error(_) as error -> error + } + } +} + +pub type ContinueOrStop(a) { + Continue(a) + Stop(a) +} + +/// A variant of fold that allows to stop folding earlier. +/// +/// The folding function should return `ContinueOrStop(accumulator)`. +/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. +/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> fold_until(0, fn(acc, i) { +/// case i < 3 { +/// True -> Continue(acc + i) +/// False -> Stop(acc) +/// } +/// }) +/// ``` +/// +pub fn fold_until( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> ContinueOrStop(acc), +) -> acc { + case collection { + [] -> accumulator + [first, ..rest] -> + case fun(accumulator, first) { + Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) + Stop(b) -> b + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case is_desired(x) { + True -> Ok(x) + _ -> find(in: rest, one_that: is_desired) + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find_map([[], [2], [3]], first) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > find_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn find_map( + in haystack: List(a), + with fun: fn(a) -> Result(b, c), +) -> Result(b, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case fun(x) { + Ok(x) -> Ok(x) + _ -> find_map(in: rest, with: fun) + } + } +} + +/// Returns `True` if the given function returns `True` for all the elements in +/// the given list. If the function returns `False` for any of the elements it +/// immediately returns `False` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > all([], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 3], fn(x) { x > 3 }) +/// False +/// ``` +/// +pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> True + [first, ..rest] -> + case predicate(first) { + True -> all(rest, predicate) + False -> False + } + } +} + +/// Returns `True` if the given function returns `True` for any the elements in +/// the given list. If the function returns `True` for any of the elements it +/// immediately returns `True` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > any([], fn(x) { x > 3 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > any([4, 3], fn(x) { x > 4 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([3, 4], fn(x) { x > 3 }) +/// True +/// ``` +/// +pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> False + [first, ..rest] -> + case predicate(first) { + True -> True + False -> any(rest, predicate) + } + } +} + +fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { + case xs, ys { + [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) + _, _ -> reverse(acc) + } +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, the remaining elements from +/// the longer list are not used. +/// +/// ## Examples +/// +/// ```gleam +/// > zip([], []) +/// [] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1], [3, 4]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3, 4]) +/// [#(1, 3), #(2, 4)] +/// ``` +/// +pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { + do_zip(list, other, []) +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, an `Error` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > strict_zip([], []) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1], [3, 4]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3, 4]) +/// Ok([#(1, 3), #(2, 4)]) +/// ``` +/// +pub fn strict_zip( + list: List(a), + with other: List(b), +) -> Result(List(#(a, b)), LengthMismatch) { + case length(of: list) == length(of: other) { + True -> Ok(zip(list, other)) + False -> Error(LengthMismatch) + } +} + +fn do_unzip(input, xs, ys) { + case input { + [] -> #(reverse(xs), reverse(ys)) + [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) + } +} + +/// Takes a single list of 2-element tuples and returns two lists. +/// +/// ## Examples +/// +/// ```gleam +/// > unzip([#(1, 2), #(3, 4)]) +/// #([1, 3], [2, 4]) +/// ``` +/// +/// ```gleam +/// > unzip([]) +/// #([], []) +/// ``` +/// +pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { + do_unzip(input, [], []) +} + +fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) + } +} + +/// Inserts a given value between each existing element in a given list. +/// +/// This function runs in linear time and copies the list. +/// +/// ## Examples +/// +/// ```gleam +/// > intersperse([1, 1, 1], 2) +/// [1, 2, 1, 2, 1] +/// ``` +/// +/// ```gleam +/// > intersperse([], 2) +/// [] +/// ``` +/// +pub fn intersperse(list: List(a), with elem: a) -> List(a) { + case list { + [] | [_] -> list + [x, ..rest] -> do_intersperse(rest, elem, [x]) + } +} + +/// Returns the element in the Nth position in the list, with 0 being the first +/// position. +/// +/// `Error(Nil)` is returned if the list is not long enough for the given index +/// or if the index is less than 0. +/// +/// ## Examples +/// +/// ```gleam +/// > at([1, 2, 3], 1) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > at([1, 2, 3], 5) +/// Error(Nil) +/// ``` +/// +pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { + case index >= 0 { + True -> + list + |> drop(index) + |> first + False -> Error(Nil) + } +} + +/// Removes any duplicate elements from a given list. +/// +/// This function returns in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) +/// [1, 4, 7, 3] +/// ``` +/// +pub fn unique(list: List(a)) -> List(a) { + case list { + [] -> [] + [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] + } +} + +/// Merge lists `a` and `b` in ascending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_up( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(ax, bx) { + order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + } + } +} + +/// Merge lists `a` and `b` in descending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_down( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(bx, ax) { + order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + } + } +} + +/// Merge sort that alternates merging in ascending and descending order +/// because the merge process also reverses the list. +/// +/// Some copying is avoided by merging only a subset of the lists +/// instead of creating and merging new smaller lists. +/// +fn merge_sort( + l: List(a), + ln: Int, + compare: fn(a, a) -> Order, + down: Bool, +) -> List(a) { + let n = ln / 2 + let a = l + let b = drop(l, n) + case ln < 3 { + True -> + case down { + True -> merge_down(n, ln - n, a, b, [], compare) + False -> merge_up(n, ln - n, a, b, [], compare) + } + False -> + case down { + True -> + merge_down( + n, + ln - n, + merge_sort(a, n, compare, False), + merge_sort(b, ln - n, compare, False), + [], + compare, + ) + False -> + merge_up( + n, + ln - n, + merge_sort(a, n, compare, True), + merge_sort(b, ln - n, compare, True), + [], + compare, + ) + } + } +} + +/// Sorts from smallest to largest based upon the ordering specified by a given +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) +/// [1, 2, 3, 4, 4, 5, 6] +/// ``` +/// +pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { + merge_sort(list, length(list), compare, True) +} + +/// Creates a list of ints ranging from a given start and finish. +/// +/// ## Examples +/// +/// ```gleam +/// > range(0, 0) +/// [0] +/// ``` +/// +/// ```gleam +/// > range(0, 5) +/// [0, 1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(1, -5) +/// [1, 0, -1, -2, -3, -4, -5] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> List(Int) { + tail_recursive_range(start, stop, []) +} + +fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { + case int.compare(start, stop) { + order.Eq -> reverse([stop, ..acc]) + order.Gt -> tail_recursive_range(start - 1, stop, [start, ..acc]) + order.Lt -> tail_recursive_range(start + 1, stop, [start, ..acc]) + } +} + +fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { + case times <= 0 { + True -> acc + False -> do_repeat(a, times - 1, [a, ..acc]) + } +} + +/// Builds a list of a given value a given number of times. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("a", times: 0) +/// [] +/// ``` +/// +/// ```gleam +/// > repeat("a", times: 5) +/// ["a", "a", "a", "a", "a"] +/// ``` +/// +pub fn repeat(item a: a, times times: Int) -> List(a) { + do_repeat(a, times, []) +} + +fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { + case n <= 0 { + True -> #(reverse(taken), list) + False -> + case list { + [] -> #(reverse(taken), []) + [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) + } + } +} + +/// Splits a list in two before the given index. +/// +/// If the list is not long enough to have the given index the before list will +/// be the input list, and the after list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split([6, 7, 8, 9], 0) +/// #([], [6, 7, 8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 2) +/// #([6, 7], [8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 4) +/// #([6, 7, 8, 9], []) +/// ``` +/// +pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { + do_split(list, index, []) +} + +fn do_split_while( + list: List(a), + f: fn(a) -> Bool, + acc: List(a), +) -> #(List(a), List(a)) { + case list { + [] -> #(reverse(acc), []) + [x, ..xs] -> + case f(x) { + False -> #(reverse(acc), list) + _ -> do_split_while(xs, f, [x, ..acc]) + } + } +} + +/// Splits a list in two before the first element that a given function returns +/// `False` for. +/// +/// If the function returns `True` for all elements the first list will be the +/// input list, and the second list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) +/// #([1, 2, 3], [4, 5]) +/// ``` +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) +/// #([1, 2, 3, 4, 5], []) +/// ``` +/// +pub fn split_while( + list list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_split_while(list, predicate, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element and returns the second element. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// This function may be useful for interacting with Erlang code where lists of +/// tuples are common. +/// +/// ## Examples +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "b") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_find( + in keyword_list: List(#(k, v)), + find desired_key: k, +) -> Result(v, Nil) { + find_map( + keyword_list, + fn(keyword) { + let #(key, value) = keyword + case key == desired_key { + True -> Ok(value) + False -> Error(Nil) + } + }, + ) +} + +fn do_pop(haystack, predicate, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case predicate(x) { + True -> Ok(#(x, append(reverse(checked), rest))) + False -> do_pop(rest, predicate, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the predicate function returns `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 2 }) +/// Ok(#(3, [1, 2])) +/// ``` +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn pop( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(#(a, List(a)), Nil) { + do_pop(haystack, is_desired, []) +} + +fn do_pop_map(haystack, mapper, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case mapper(x) { + Ok(y) -> Ok(#(y, append(reverse(checked), rest))) + Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_map([[], [2], [3]], first) +/// Ok(#(2, [[], [3]])) +/// ``` +/// +/// ```gleam +/// > pop_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn pop_map( + in haystack: List(a), + one_that is_desired: fn(a) -> Result(b, c), +) -> Result(#(b, List(a)), Nil) { + do_pop_map(haystack, is_desired, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element. This function will return the second element +/// of the found tuple and list with tuple removed. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "a") +/// Ok(#(0, [#("b", 1)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "b") +/// Ok(#(1, [#("a", 0)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_pop( + haystack: List(#(k, v)), + key: k, +) -> Result(#(v, List(#(k, v))), Nil) { + pop_map( + haystack, + fn(entry) { + let #(k, v) = entry + case k { + k if k == key -> Ok(v) + _ -> Error(Nil) + } + }, + ) +} + +/// Given a list of 2-element tuples, inserts a key and value into the list. +/// +/// If there was already a tuple with the key then it is replaced, otherwise it +/// is added to the end of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 4, 100) +/// [#(5, 0), #(4, 100)] +/// ``` +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 1, 100) +/// [#(5, 0), #(4, 1), #(1, 100)] +/// ``` +/// +pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { + case list { + [] -> [#(key, value)] + [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] + [first, ..rest] -> [first, ..key_set(rest, key, value)] + } +} + +/// Calls a function for each element in a list, discarding the return value. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ```gleam +/// > list.each([1, 2, 3], io.println) +/// Nil +/// ``` +/// +pub fn each(list: List(a), f: fn(a) -> b) -> Nil { + case list { + [] -> Nil + [x, ..xs] -> { + f(x) + each(xs, f) + } + } +} + +/// Calls a `Result` returning function for each element in a list, discarding +/// the return value. If the function returns `Error` then the iteration is +/// stopped and the error is returned. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > try_each( +/// > over: [1, 2, 3], +/// > with: function_that_might_fail, +/// > ) +/// Ok(Nil) +/// ``` +/// +pub fn try_each( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(Nil, e) { + case list { + [] -> Ok(Nil) + [x, ..xs] -> + case fun(x) { + Ok(_) -> try_each(over: xs, with: fun) + Error(e) -> Error(e) + } + } +} + +fn do_partition(list, categorise, trues, falses) { + case list { + [] -> #(reverse(trues), reverse(falses)) + [x, ..xs] -> + case categorise(x) { + True -> do_partition(xs, categorise, [x, ..trues], falses) + False -> do_partition(xs, categorise, trues, [x, ..falses]) + } + } +} + +/// Partitions a list into a tuple/pair of lists +/// by a given categorisation function. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) +/// #([1, 3, 5], [2, 4]) +/// ``` +/// +pub fn partition( + list: List(a), + with categorise: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_partition(list, categorise, [], []) +} + +/// Returns all the permutations of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > permutations([1, 2]) +/// [[1, 2], [2, 1]] +/// ``` +/// +pub fn permutations(l: List(a)) -> List(List(a)) { + case l { + [] -> [[]] + _ -> + l + |> index_map(fn(i_idx, i) { + l + |> index_fold( + [], + fn(acc, j, j_idx) { + case i_idx == j_idx { + True -> acc + False -> [j, ..acc] + } + }, + ) + |> reverse + |> permutations + |> map(fn(permutation) { [i, ..permutation] }) + }) + |> flatten + } +} + +fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { + let window = take(l, n) + + case length(window) == n { + True -> do_window([window, ..acc], drop(l, 1), n) + False -> acc + } +} + +/// Returns a list of sliding windows. +/// +/// ## Examples +/// +/// ```gleam +/// > window([1,2,3,4,5], 3) +/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] +/// ``` +/// +/// ```gleam +/// > window([1, 2], 4) +/// [] +/// ``` +/// +pub fn window(l: List(a), by n: Int) -> List(List(a)) { + do_window([], l, n) + |> reverse +} + +/// Returns a list of tuples containing two contiguous elements. +/// +/// ## Examples +/// +/// ```gleam +/// > window_by_2([1,2,3,4]) +/// [#(1, 2), #(2, 3), #(3, 4)] +/// ``` +/// +/// ```gleam +/// > window_by_2([1]) +/// [] +/// ``` +/// +pub fn window_by_2(l: List(a)) -> List(#(a, a)) { + zip(l, drop(l, 1)) +} + +/// Drops the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) +/// [3, 4] +/// ``` +/// +pub fn drop_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + case list { + [] -> [] + [x, ..xs] -> + case predicate(x) { + True -> drop_while(xs, predicate) + False -> [x, ..xs] + } + } +} + +fn do_take_while( + list: List(a), + predicate: fn(a) -> Bool, + acc: List(a), +) -> List(a) { + case list { + [] -> reverse(acc) + [first, ..rest] -> + case predicate(first) { + True -> do_take_while(rest, predicate, [first, ..acc]) + False -> reverse(acc) + } + } +} + +/// Takes the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) +/// [1, 2] +/// ``` +/// +pub fn take_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + do_take_while(list, predicate, []) +} + +fn do_chunk( + list: List(a), + f: fn(a) -> key, + previous_key: key, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [first, ..rest] -> { + let key = f(first) + case key == previous_key { + False -> { + let new_acc = [reverse(current_chunk), ..acc] + do_chunk(rest, f, key, [first], new_acc) + } + _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) + } + } + _empty -> reverse([reverse(current_chunk), ..acc]) + } +} + +/// Returns a list of chunks in which +/// the return value of calling `f` on each element is the same. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { + case list { + [] -> [] + [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) + } +} + +fn do_sized_chunk( + list: List(a), + count: Int, + left: Int, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [] -> + case current_chunk { + [] -> reverse(acc) + remaining -> reverse([reverse(remaining), ..acc]) + } + [first, ..rest] -> { + let chunk = [first, ..current_chunk] + case left > 1 { + False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) + True -> do_sized_chunk(rest, count, left - 1, chunk, acc) + } + } + } +} + +/// Returns a list of chunks containing `count` elements each. +/// +/// If the last chunk does not have `count` elements, it is instead +/// a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { + do_sized_chunk(list, count, count, [], []) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first element in the list +/// and combines it with each subsequent element in turn using the given +/// function. The function is called as `fun(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an +/// empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [first, ..rest] -> Ok(fold(rest, first, fun)) + } +} + +fn do_scan( + list: List(a), + accumulator: acc, + accumulated: List(acc), + fun: fn(acc, a) -> acc, +) -> List(acc) { + case list { + [] -> reverse(accumulated) + [x, ..xs] -> { + let next = fun(accumulator, x) + do_scan(xs, next, [next, ..accumulated], fun) + } + } +} + +/// Similar to `fold`, but yields the state of the accumulator at each stage. +/// +/// ## Examples +/// +/// ```gleam +/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) +/// [101, 103, 106] +/// ``` +/// +pub fn scan( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> List(acc) { + do_scan(list, initial, [], fun) +} + +/// Returns the last element in the given list. +/// +/// Returns `Error(Nil)` if the list is empty. +/// +/// This function runs in linear time. +/// For a collection oriented around performant access at either end, +/// see `gleam/queue.Queue`. +/// +/// ## Examples +/// +/// ```gleam +/// > last([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last([1, 2, 3, 4, 5]) +/// Ok(5) +/// ``` +/// +pub fn last(list: List(a)) -> Result(a, Nil) { + list + |> reduce(fn(_, elem) { elem }) +} + +/// Return unique combinations of elements in the list. +/// +/// ## Examples +/// +/// ```gleam +/// > combinations([1, 2, 3], 2) +/// [[1, 2], [1, 3], [2, 3]] +/// ``` +/// +/// ```gleam +/// > combinations([1, 2, 3, 4], 3) +/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] +/// ``` +/// +pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { + case n { + 0 -> [[]] + _ -> + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = + map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) + |> reverse + fold( + first_combinations, + combinations(xs, n), + fn(acc, c) { [c, ..acc] }, + ) + } + } + } +} + +fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = map(xs, with: fn(other) { #(x, other) }) + [first_combinations, ..do_combination_pairs(xs)] + } + } +} + +/// Return unique pair combinations of elements in the list +/// +/// ## Examples +/// +/// ```gleam +/// > combination_pairs([1, 2, 3]) +/// [#(1, 2), #(1, 3), #(2, 3)] +/// ``` +/// +pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { + do_combination_pairs(items) + |> flatten +} + +/// Make a list alternating the elements from the given lists +/// +/// ## Examples +/// +/// ```gleam +/// > list.interleave([[1, 2], [101, 102], [201, 202]]) +/// [1, 101, 201, 2, 102, 202] +/// ``` +/// +pub fn interleave(list: List(List(a))) -> List(a) { + transpose(list) + |> flatten +} + +/// Transpose rows and columns of the list of lists. +/// +/// Notice: This function is not tail recursive, +/// and thus may exceed stack size if called, +/// with large lists (on target JavaScript). +/// +/// ## Examples +/// +/// ```gleam +/// > transpose([[1, 2, 3], [101, 102, 103]]) +/// [[1, 101], [2, 102], [3, 103]] +/// ``` +/// +pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { + let take_first = fn(list) { + case list { + [] -> [] + [f] -> [f] + [f, ..] -> [f] + } + } + + case list_of_list { + [] -> [] + [[], ..xss] -> transpose(xss) + rows -> { + let firsts = + rows + |> map(take_first) + |> flatten + let rest = transpose(map(rows, drop(_, 1))) + [firsts, ..rest] + } + } +} + +fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + _ -> { + let [elem_pair, ..enumerable] = list + do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) + } + } +} + +fn do_shuffle_by_pair_indexes( + list_of_pairs: List(#(Float, a)), +) -> List(#(Float, a)) { + sort( + list_of_pairs, + fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { + float.compare(a_pair.0, b_pair.0) + }, + ) +} + +/// Takes a list, randomly sorts all items and returns the shuffled list. +/// +/// This function uses Erlang's `:rand` module or Javascript's +/// `Math.random()` to calcuate the index shuffling. +/// +/// ## Example +/// +/// ```gleam +/// > range(1, 10) +/// > |> shuffle() +/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] +/// ``` +/// +pub fn shuffle(list: List(a)) -> List(a) { + list + |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) + |> do_shuffle_by_pair_indexes() + |> do_shuffle_pair_unwrap([]) +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam new file mode 100644 index 00000000000..6f963bceef2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam @@ -0,0 +1,593 @@ +import gleam/option.{Option} + +/// A dictionary of keys and values. +/// +/// Any type can be used for the keys and values of a map, but all the keys +/// must be of the same type and all the values must be of the same type. +/// +/// Each key can only be present in a map once. +/// +/// Maps are not ordered in any way, and any unintentional ordering is not to +/// be relied upon in your code as it may change in future versions of Erlang +/// or Gleam. +/// +/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more +/// information. +/// +pub external type Map(key, value) + +/// Determines the number of key-value pairs in the map. +/// This function runs in constant time and does not need to iterate the map. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> size() +/// 0 +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", "value") |> size() +/// 1 +/// ``` +/// +pub fn size(map: Map(k, v)) -> Int { + do_size(map) +} + +if erlang { + external fn do_size(Map(k, v)) -> Int = + "maps" "size" +} + +if javascript { + external fn do_size(Map(k, v)) -> Int = + "../gleam_stdlib.mjs" "map_size" +} + +/// Converts the map to a list of 2-element tuples `#(key, value)`, one for +/// each key-value pair in the map. +/// +/// The tuples in the list have no specific order. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> to_list() +/// [] +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", 0) |> to_list() +/// [#("key", 0)] +/// ``` +/// +pub fn to_list(map: Map(key, value)) -> List(#(key, value)) { + do_to_list(map) +} + +if erlang { + external fn do_to_list(Map(key, value)) -> List(#(key, value)) = + "maps" "to_list" +} + +if javascript { + external fn do_to_list(Map(key, value)) -> List(#(key, value)) = + "../gleam_stdlib.mjs" "map_to_list" +} + +/// Converts a list of 2-element tuples `#(key, value)` to a map. +/// +/// If two tuples have the same key the last one in the list will be the one +/// that is present in the map. +/// +pub fn from_list(list: List(#(k, v))) -> Map(k, v) { + do_from_list(list) +} + +if erlang { + external fn do_from_list(List(#(key, value))) -> Map(key, value) = + "maps" "from_list" +} + +if javascript { + fn fold_list_of_pair( + over list: List(#(k, v)), + from initial: Map(k, v), + ) -> Map(k, v) { + case list { + [] -> initial + [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) + } + } + + fn do_from_list(list: List(#(k, v))) -> Map(k, v) { + fold_list_of_pair(list, new()) + } +} + +/// Determines whether or not a value present in the map for a given key. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("a") +/// True +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("b") +/// False +/// ``` +/// +pub fn has_key(map: Map(k, v), key: k) -> Bool { + do_has_key(key, map) +} + +if erlang { + external fn do_has_key(key, Map(key, v)) -> Bool = + "maps" "is_key" +} + +if javascript { + fn do_has_key(key: k, map: Map(k, v)) -> Bool { + get(map, key) != Error(Nil) + } +} + +/// Creates a fresh map that contains no values. +/// +pub fn new() -> Map(key, value) { + do_new() +} + +if erlang { + external fn do_new() -> Map(key, value) = + "maps" "new" +} + +if javascript { + external fn do_new() -> Map(key, value) = + "../gleam_stdlib.mjs" "new_map" +} + +/// Fetches a value from a map for a given key. +/// +/// The map may not have a value for the key, so the value is wrapped in a +/// `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("b") +/// Error(Nil) +/// ``` +/// +pub fn get(from: Map(key, value), get: key) -> Result(value, Nil) { + do_get(from, get) +} + +if erlang { + external fn do_get(Map(key, value), key) -> Result(value, Nil) = + "gleam_stdlib" "map_get" +} + +if javascript { + external fn do_get(Map(key, value), key) -> Result(value, Nil) = + "../gleam_stdlib.mjs" "map_get" +} + +/// Inserts a value into the map with the given key. +/// +/// If the map already has a value for the given key then the value is +/// replaced with the new value. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> to_list +/// [#("a", 0)] +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list +/// [#("a", 5)] +/// ``` +/// +pub fn insert(into map: Map(k, v), for key: k, insert value: v) -> Map(k, v) { + do_insert(key, value, map) +} + +if erlang { + external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = + "maps" "put" +} + +if javascript { + external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = + "../gleam_stdlib.mjs" "map_insert" +} + +/// Updates all values in a given map by calling a given function on each key +/// and value. +/// +/// ## Examples +/// +/// ```gleam +/// > [#(3, 3), #(2, 4)] +/// > |> from_list +/// > |> map_values(fn(key, value) { key * value }) +/// [#(3, 9), #(2, 8)] +/// ``` +/// +pub fn map_values(in map: Map(k, v), with fun: fn(k, v) -> w) -> Map(k, w) { + do_map_values(fun, map) +} + +if erlang { + external fn do_map_values(fn(key, value) -> b, Map(key, value)) -> Map(key, b) = + "maps" "map" +} + +if javascript { + fn do_map_values(f: fn(key, value) -> b, map: Map(key, value)) -> Map(key, b) { + let f = fn(map, k, v) { insert(map, k, f(k, v)) } + map + |> fold(from: new(), with: f) + } +} + +/// Gets a list of all keys in a given map. +/// +/// Maps are not ordered so the keys are not returned in any specific order. Do +/// not write code that relies on the order keys are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > keys([#("a", 0), #("b", 1)]) +/// ["a", "b"] +/// ``` +/// +pub fn keys(map: Map(keys, v)) -> List(keys) { + do_keys(map) +} + +if erlang { + external fn do_keys(Map(keys, v)) -> List(keys) = + "maps" "keys" +} + +if javascript { + fn reverse_and_concat(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) + } + } + + fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) + } + } + + fn do_keys(map: Map(k, v)) -> List(k) { + let list_of_pairs = + map + |> to_list + do_keys_acc(list_of_pairs, []) + } +} + +/// Gets a list of all values in a given map. +/// +/// Maps are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order values are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > values(from_list([#("a", 0), #("b", 1)])) +/// [0, 1] +/// ``` +/// +pub fn values(map: Map(k, values)) -> List(values) { + do_values(map) +} + +if erlang { + external fn do_values(Map(k, values)) -> List(values) = + "maps" "values" +} + +if javascript { + fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) + } + } + + fn do_values(map: Map(k, v)) -> List(v) { + let list_of_pairs = + map + |> to_list + do_values_acc(list_of_pairs, []) + } +} + +/// Creates a new map from a given map, minus any entries that a given function +/// returns `False` for. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { value != 0 }) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { True }) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { + do_filter(property, map) +} + +if erlang { + external fn do_filter( + fn(key, value) -> Bool, + Map(key, value), + ) -> Map(key, value) = + "maps" "filter" +} + +if javascript { + fn do_filter( + f: fn(key, value) -> Bool, + map: Map(key, value), + ) -> Map(key, value) { + let insert = fn(map, k, v) { + case f(k, v) { + True -> insert(map, k, v) + _ -> map + } + } + map + |> fold(from: new(), with: insert) + } +} + +/// Creates a new map from a given map, only including any entries for which the +/// keys are in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["b"]) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["a", "b", "c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn take(from map: Map(k, v), keeping desired_keys: List(k)) -> Map(k, v) { + do_take(desired_keys, map) +} + +if erlang { + external fn do_take(List(k), Map(k, v)) -> Map(k, v) = + "maps" "with" +} + +if javascript { + fn insert_taken( + map: Map(k, v), + desired_keys: List(k), + acc: Map(k, v), + ) -> Map(k, v) { + let insert = fn(taken, key) { + case get(map, key) { + Ok(value) -> insert(taken, key, value) + _ -> taken + } + } + case desired_keys { + [] -> acc + [x, ..xs] -> insert_taken(map, xs, insert(acc, x)) + } + } + + fn do_take(desired_keys: List(k), map: Map(k, v)) -> Map(k, v) { + insert_taken(map, desired_keys, new()) + } +} + +/// Creates a new map from a pair of given maps by combining their entries. +/// +/// If there are entries with the same keys in both maps the entry from the +/// second map takes precedence. +/// +/// ## Examples +/// +/// ```gleam +/// > let a = from_list([#("a", 0), #("b", 1)]) +/// > let b = from_list([#("b", 2), #("c", 3)]) +/// > merge(a, b) +/// from_list([#("a", 0), #("b", 2), #("c", 3)]) +/// ``` +/// +pub fn merge(into map: Map(k, v), from new_entries: Map(k, v)) -> Map(k, v) { + do_merge(map, new_entries) +} + +if erlang { + external fn do_merge(Map(k, v), Map(k, v)) -> Map(k, v) = + "maps" "merge" +} + +if javascript { + fn insert_pair(map: Map(k, v), pair: #(k, v)) -> Map(k, v) { + insert(map, pair.0, pair.1) + } + + fn fold_inserts(new_entries: List(#(k, v)), map: Map(k, v)) -> Map(k, v) { + case new_entries { + [] -> map + [x, ..xs] -> fold_inserts(xs, insert_pair(map, x)) + } + } + + fn do_merge(map: Map(k, v), new_entries: Map(k, v)) -> Map(k, v) { + new_entries + |> to_list + |> fold_inserts(map) + } +} + +/// Creates a new map from a given map with all the same entries except for the +/// one with a given key, if it exists. +/// +/// ## Examples +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "a") +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "c") +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn delete(from map: Map(k, v), delete key: k) -> Map(k, v) { + do_delete(key, map) +} + +if erlang { + external fn do_delete(k, Map(k, v)) -> Map(k, v) = + "maps" "remove" +} + +if javascript { + external fn do_delete(k, Map(k, v)) -> Map(k, v) = + "../gleam_stdlib.mjs" "map_remove" +} + +/// Creates a new map from a given map with all the same entries except any with +/// keys found in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a"]) +/// from_list([#("b", 2)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], ["c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) +/// from_list([]) +/// ``` +/// +pub fn drop(from map: Map(k, v), drop disallowed_keys: List(k)) -> Map(k, v) { + case disallowed_keys { + [] -> map + [x, ..xs] -> drop(delete(map, x), xs) + } +} + +/// Creates a new map with one entry updated using a given function. +/// +/// If there was not an entry in the map for the given key then the function +/// gets `None` as its argument, otherwise it gets `Some(value)`. +/// +/// ## Example +/// +/// ```gleam +/// > let increment = fn(x) { +/// > case x { +/// > Some(i) -> i + 1 +/// > None -> 0 +/// > } +/// > } +/// > let map = from_list([#("a", 0)]) +/// > +/// > update(map, "a", increment) +/// from_list([#("a", 1)]) +/// ``` +/// +/// ```gleam +/// > update(map, "b", increment) +/// from_list([#("a", 0), #("b", 0)]) +/// ``` +/// +pub fn update( + in map: Map(k, v), + update key: k, + with fun: fn(Option(v)) -> v, +) -> Map(k, v) { + map + |> get(key) + |> option.from_result + |> fun + |> insert(map, key, _) +} + +fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { + case list { + [] -> initial + [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) + } +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Maps are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order entries are used by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > let map = from_list([#("a", 1), #("b", 3), #("c", 9)]) +/// > fold(map, 0, fn(accumulator, key, value) { accumulator + value }) +/// 13 +/// ``` +/// +/// ```gleam +/// > import gleam/string.{append} +/// > fold(map, "", fn(accumulator, key, value) { append(accumulator, key) }) +/// "abc" +/// ``` +/// +pub fn fold( + over map: Map(k, v), + from initial: acc, + with fun: fn(acc, k, v) -> acc, +) -> acc { + map + |> to_list + |> do_fold(initial, fun) +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam new file mode 100644 index 00000000000..6015c0fff8f --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam @@ -0,0 +1,346 @@ +/// `Option` represents a value that may be present or not. `Some` means the value is +/// present, `None` means the value is not. +/// +/// This is Gleam's alternative to having a value that could be Null, as is +/// possible in some other languages. +/// +pub type Option(a) { + Some(a) + None +} + +fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { + case list { + [] -> Some(acc) + [x, ..rest] -> { + let accumulate = fn(acc, item) { + case acc, item { + Some(values), Some(value) -> Some([value, ..values]) + _, _ -> None + } + } + accumulate(do_all(rest, acc), x) + } + } +} + +/// Combines a list of `Option`s into a single `Option`. +/// If all elements in the list are `Some` then returns a `Some` holding the list of values. +/// If any element is `None` then returns`None`. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Some(1), Some(2)]) +/// Some([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Some(1), None]) +/// None +/// ``` +/// +pub fn all(list: List(Option(a))) -> Option(List(a)) { + do_all(list, []) +} + +/// Checks whether the `Option` is a `Some` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_some(Some(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_some(None) +/// False +/// ``` +/// +pub fn is_some(option: Option(a)) -> Bool { + option != None +} + +/// Checks whether the `Option` is a `None` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_none(Some(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_none(None) +/// True +/// ``` +/// +pub fn is_none(option: Option(a)) -> Bool { + option == None +} + +/// Converts an `Option` type to a `Result` type. +/// +/// ## Examples +/// +/// ```gleam +/// > to_result(Some(1), "some_error") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > to_result(None, "some_error") +/// Error("some_error") +/// ``` +/// +pub fn to_result(option: Option(a), e) -> Result(a, e) { + case option { + Some(a) -> Ok(a) + _ -> Error(e) + } +} + +/// Converts a `Result` type to an `Option` type. +/// +/// ## Examples +/// +/// ```gleam +/// > from_result(Ok(1)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > from_result(Error("some_error")) +/// None +/// ``` +/// +pub fn from_result(result: Result(a, e)) -> Option(a) { + case result { + Ok(a) -> Some(a) + _ -> None + } +} + +/// Extracts the value from an `Option`, returning a default value if there is none. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Some(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(None, 0) +/// 0 +/// ``` +/// +pub fn unwrap(option: Option(a), or default: a) -> a { + case option { + Some(x) -> x + None -> default + } +} + +/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Some(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(None, fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { + case option { + Some(x) -> x + None -> default() + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it. +/// +/// If the `Option` is a `None` rather than `Some`, the function is not called and the +/// `Option` stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Some(1), with: fn(x) { x + 1 }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > map(over: None, with: fn(x) { x + 1 }) +/// None +/// ``` +/// +pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { + case option { + Some(x) -> Some(fun(x)) + None -> None + } +} + +/// Merges a nested `Option` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Some(Some(1))) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > flatten(Some(None)) +/// None +/// ``` +/// +/// ```gleam +/// > flatten(None) +/// None +/// ``` +/// +pub fn flatten(option: Option(Option(a))) -> Option(a) { + case option { + Some(x) -> x + None -> None + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it, where the given function also returns an `Option`. The two options are +/// then merged together into one `Option`. +/// +/// If the `Option` is a `None` rather than `Some` the function is not called and the +/// option stays the same. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that return `Option`. +/// +/// ## Examples +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(x + 1) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(#("a", x)) }) +/// Some(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(_) { None }) +/// None +/// ``` +/// +/// ```gleam +/// > then(None, fn(x) { Some(x + 1) }) +/// None +/// ``` +/// +pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { + case option { + Some(x) -> fun(x) + None -> None + } +} + +/// Returns the first value if it is `Some`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Some(1), Some(2)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(Some(1), None) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(None, Some(2)) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > or(None, None) +/// None +/// ``` +/// +pub fn or(first: Option(a), second: Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second + } +} + +/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { Some(2) }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { None }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { Some(2) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { None }) +/// None +/// ``` +/// +pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second() + } +} + +fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + [x, ..xs] -> { + let accumulate = fn(acc, item) { + case item { + Some(value) -> [value, ..acc] + None -> acc + } + } + accumulate(do_values(xs, acc), x) + } + } +} + +/// Given a list of `Option`s, +/// returns only the values inside `Some`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Some(1), None, Some(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(options: List(Option(a))) -> List(a) { + do_values(options, []) +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam new file mode 100644 index 00000000000..979c8c252ef --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam @@ -0,0 +1,119 @@ +/// Represents the result of a single comparison to determine the precise +/// ordering of two values. +/// +pub type Order { + /// Less-than + Lt + + /// Equal + Eq + + /// Greater than + Gt +} + +/// Inverts an order, so less-than becomes greater-than and greater-than +/// becomes less-than. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse(Lt) +/// Gt +/// ``` +/// +/// ```gleam +/// > reverse(Eq) +/// Eq +/// ``` +/// +/// ```gleam +/// > reverse(Lt) +/// Gt +/// ``` +/// +pub fn reverse(order: Order) -> Order { + case order { + Lt -> Gt + Eq -> Eq + Gt -> Lt + } +} + +/// Produces a numeric representation of the order. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(Lt) +/// -1 +/// ``` +/// +/// ```gleam +/// > to_int(Eq) +/// 0 +/// ``` +/// +/// ```gleam +/// > to_int(Gt) +/// 1 +/// ``` +/// +pub fn to_int(order: Order) -> Int { + case order { + Lt -> -1 + Eq -> 0 + Gt -> 1 + } +} + +/// Compares two `Order` values to one another, producing a new `Order`. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(Eq, with: Lt) +/// Gt +/// ``` +/// +pub fn compare(a: Order, with b: Order) -> Order { + case a, b { + x, y if x == y -> Eq + Lt, _ | Eq, Gt -> Lt + _, _ -> Gt + } +} + +/// Returns the largest of two orders. +/// +/// ## Examples +/// +/// ```gleam +/// > max(Eq, Lt) +/// Eq +/// ``` +/// +pub fn max(a: Order, b: Order) -> Order { + case a, b { + Gt, _ -> Gt + Eq, Lt -> Eq + _, _ -> b + } +} + +/// Returns the smallest of two orders. +/// +/// ## Examples +/// +/// ```gleam +/// > min(Eq, Lt) +/// Lt +/// ``` +/// +pub fn min(a: Order, b: Order) -> Order { + case a, b { + Lt, _ -> Lt + Eq, Gt -> Eq + _, _ -> b + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam new file mode 100644 index 00000000000..894e6a8d9f1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam @@ -0,0 +1,85 @@ +/// Returns the first element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > first(#(1, 2)) +/// 1 +/// ``` +/// +pub fn first(pair: #(a, b)) -> a { + let #(a, _) = pair + a +} + +/// Returns the second element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > second(#(1, 2)) +/// 2 +/// ``` +/// +pub fn second(pair: #(a, b)) -> b { + let #(_, a) = pair + a +} + +/// Returns a new pair with the elements swapped. +/// +/// ## Examples +/// +/// ```gleam +/// > swap(#(1, 2)) +/// #(2, 1) +/// ``` +/// +pub fn swap(pair: #(a, b)) -> #(b, a) { + let #(a, b) = pair + #(b, a) +} + +/// Returns a new pair with the first element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_first(fn(n) { n * 2 }) +/// #(2, 2) +/// ``` +/// +pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { + let #(a, b) = pair + #(fun(a), b) +} + +/// Returns a new pair with the second element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_second(fn(n) { n * 2 }) +/// #(1, 4) +/// ``` +/// +pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { + let #(a, b) = pair + #(a, fun(b)) +} + +/// Returns a new pair with the given elements. This can also be done using the dedicated +/// syntax instead: `new(1, 2) == #(1, 2)`. +/// +/// ## Examples +/// +/// ```gleam +/// > new(1, 2) +/// #(1, 2) +/// ``` +/// +pub fn new(first: a, second: b) -> #(a, b) { + #(first, second) +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam new file mode 100644 index 00000000000..5bf60c8a529 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam @@ -0,0 +1,292 @@ +import gleam/list + +/// A queue is an ordered collection of elements. It is similar to a list, but +/// unlike a list elements can be added to or removed from either the front or +/// the back in a performant fashion. +/// +/// The internal representation may be different for two queues with the same +/// elements in the same order if the queues were constructed in different +/// ways. This is the price paid for a queue's fast access at both the front +/// and the back. +/// +/// Because of unpredictable internal representation the equality operator `==` +/// may return surprising results, and the `is_equal` and `is_logically_equal` +/// functions are the recommended way to test queues for equality. +/// +pub opaque type Queue(element) { + Queue(in: List(element), out: List(element)) +} + +/// Creates a fresh queue that contains no values. +/// +pub fn new() -> Queue(a) { + Queue(in: [], out: []) +} + +/// Converts a list of elements into a queue of the same elements in the same +/// order. The first element in the list becomes the front element in the queue. +/// +/// This function runs in constant time. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2, 3] |> from_list |> length +/// 3 +/// ``` +/// +pub fn from_list(list: List(a)) -> Queue(a) { + Queue(in: [], out: list) +} + +/// Converts a queue of elements into a list of the same elements in the same +/// order. The front element in the queue becomes the first element in the list. +/// +/// This function runs in linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() |> push_back(1) |> push_back(2) |> to_list +/// [1, 2] +/// ``` +/// +pub fn to_list(queue: Queue(a)) -> List(a) { + queue.out + |> list.append(list.reverse(queue.in)) +} + +/// Determines whether or not the queue is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> is_empty +/// False +/// ``` +/// +pub fn is_empty(queue: Queue(a)) -> Bool { + queue.in == [] && queue.out == [] +} + +/// Counts the number of elements in a given queue. +/// +/// This function has to traverse the queue to determine the number of elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length(from_list([])) +/// 0 +/// ``` +/// +/// ```gleam +/// > length(from_list([1])) +/// 1 +/// ``` +/// +/// ```gleam +/// > length(from_list([1, 2])) +/// 2 +/// ``` +/// +pub fn length(queue: Queue(a)) -> Int { + list.length(queue.in) + list.length(queue.out) +} + +/// Pushes an element onto the back of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2] |> from_list |> push_back(3) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: [item, ..queue.in], out: queue.out) +} + +/// Pushes an element onto the front of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [0, 0] |> from_list |> push_front(1) |> to_list +/// [1, 0, 0] +/// ``` +/// +pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: queue.in, out: [item, ..queue.out]) +} + +/// Gets the last element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() +/// > |> push_back(0) +/// > |> push_back(1) +/// > |> pop_back() +/// Ok(#(1, push_front(new(), 0))) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> push_front(0) +/// > |> pop_back() +/// Ok(#(0, new())) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) + Queue(in: [first, ..rest], out: out) -> { + let queue = Queue(in: rest, out: out) + Ok(#(first, queue)) + } + } +} + +/// Gets the first element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_front(1) +/// > |> queue.push_front(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.push_back(queue.new(), 1))) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_back(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.new())) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) + Queue(in: in, out: [first, ..rest]) -> { + let queue = Queue(in: in, out: rest) + Ok(#(first, queue)) + } + } +} + +/// Creates a new queue from a given queue containing the same elements, but in +/// the opposite order. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> reverse |> to_list +/// [] +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> reverse |> to_list +/// [1] +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> reverse |> to_list +/// [2, 1] +/// ``` +/// +pub fn reverse(queue: Queue(a)) -> Queue(a) { + Queue(in: queue.out, out: queue.in) +} + +fn check_equal( + xs: List(t), + x_tail: List(t), + ys: List(t), + y_tail: List(t), + eq: fn(t, t) -> Bool, +) -> Bool { + case xs, x_tail, ys, y_tail { + [], [], [], [] -> True + [x, ..xs], _, [y, ..ys], _ -> + case eq(x, y) { + False -> False + True -> check_equal(xs, x_tail, ys, y_tail, eq) + } + [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) + _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) + _, _, _, _ -> False + } +} + +/// Checks whether two queues have equal elements in the same order, where the +/// equality of elements is determined by a given equality checking function. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time multiplied by the time taken by the +/// element equality checking function. +/// +pub fn is_logically_equal( + a: Queue(t), + to b: Queue(t), + checking element_is_equal: fn(t, t) -> Bool, +) -> Bool { + check_equal(a.out, a.in, b.out, b.in, element_is_equal) +} + +/// Checks whether two queues have the same elements in the same order. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time. +/// +pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { + check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam new file mode 100644 index 00000000000..f1161cc1b13 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam @@ -0,0 +1,233 @@ +//// This module contains regular expression matching functions for strings. +//// The matching algorithms of the library are based on the PCRE library, but not +//// all of the PCRE library is interfaced and some parts of the library go beyond +//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. + +import gleam/option.{Option} + +pub external type Regex + +/// The details about a particular match: +/// +pub type Match { + Match( + /// The full string of the match. + content: String, + /// A `Regex` can have subpatterns, sup-parts that are in parentheses. + submatches: List(Option(String)), + ) +} + +/// When a regular expression fails to compile: +/// +pub type CompileError { + CompileError( + /// The problem encountered that caused the compilation to fail + error: String, + /// The byte index into the string to where the problem was found + /// This value may not be correct in JavaScript environments. + byte_index: Int, + ) +} + +pub type Options { + Options(case_insensitive: Bool, multi_line: Bool) +} + +/// Creates a `Regex` with some additional options. +/// +/// ## Examples +/// +/// ```gleam +/// > let options = Options(case_insensitive: False, multi_line: True) +/// > let assert Ok(re) = compile("^[0-9]", with: options) +/// > check(re, "abc\n123") +/// True +/// ``` +/// +/// ```gleam +/// > let options = Options(case_insensitive: True, multi_line: False) +/// > let assert Ok(re) = compile("[A-Z]", with: options) +/// > check(re, "abc123") +/// True +/// ``` +/// +pub fn compile( + pattern: String, + with options: Options, +) -> Result(Regex, CompileError) { + do_compile(pattern, options) +} + +if erlang { + external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = + "gleam_stdlib" "compile_regex" +} + +if javascript { + external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = + "../gleam_stdlib.mjs" "compile_regex" +} + +/// Creates a new `Regex`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[0-9]") +/// > check(re, "abc123") +/// True +/// ``` +/// +/// ```gleam +/// > check(re, "abcxyz") +/// False +/// ``` +/// +/// ```gleam +/// > from_string("[0-9") +/// Error( +/// CompileError( +/// error: "missing terminating ] for character class", +/// byte_index: 4 +/// ) +/// ) +/// ``` +/// +pub fn from_string(pattern: String) -> Result(Regex, CompileError) { + compile(pattern, Options(case_insensitive: False, multi_line: False)) +} + +/// Returns a boolean indicating whether there was a match or not. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("^f.o.?") +/// > check(with: re, content: "foo") +/// True +/// ``` +/// +/// ```gleam +/// > check(with: re, content: "boo") +/// False +/// ``` +/// +pub fn check(with regex: Regex, content content: String) -> Bool { + do_check(regex, content) +} + +if erlang { + external fn do_check(Regex, String) -> Bool = + "gleam_stdlib" "regex_check" +} + +if javascript { + external fn do_check(Regex, String) -> Bool = + "../gleam_stdlib.mjs" "regex_check" +} + +/// Splits a string. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string(" *, *") +/// > split(with: re, content: "foo,32, 4, 9 ,0") +/// ["foo", "32", "4", "9", "0"] +/// ``` +/// +pub fn split(with regex: Regex, content string: String) -> List(String) { + do_split(regex, string) +} + +if erlang { + external fn do_split(Regex, String) -> List(String) = + "gleam_stdlib" "regex_split" +} + +if javascript { + fn do_split(regex, string) -> List(String) { + js_split(string, regex) + } + + external fn js_split(String, Regex) -> List(String) = + "../gleam_stdlib.mjs" "split" +} + +/// Collects all matches of the regular expression. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") +/// > scan(with: re, content: "I am on a boat in a lake.") +/// [ +/// Match( +/// content: "on a boat", +/// submatches: [Some("boat")] +/// ), +/// Match( +/// content: "in a lake", +/// submatches: [Some("lake")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") +/// > scan(with: re, content: "-36") +/// [ +/// Match( +/// content: "-36", +/// submatches: [Some("-"), Some("36")] +/// ) +/// ] +/// +/// > scan(with: re, content: "36") +/// [ +/// Match( +/// content: "36", +/// submatches: [None, Some("36")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") +/// > scan(with: re, content: "var age = 32") +/// [ +/// Match( +/// content: "var age = 32", +/// submatches: [Some("age"), None, Some("32")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") +/// > scan(with: re, content: "let age = 32") +/// [ +/// Match( +/// content: "let age = 32", +/// submatches: [Some("age"), Some("32")] +/// ) +/// ] +/// +/// > scan(with: re, content: "const age = 32") +/// [] +/// ``` +/// +pub fn scan(with regex: Regex, content string: String) -> List(Match) { + do_scan(regex, string) +} + +if erlang { + external fn do_scan(Regex, String) -> List(Match) = + "gleam_stdlib" "regex_scan" +} + +if javascript { + external fn do_scan(Regex, String) -> List(Match) = + "../gleam_stdlib.mjs" "regex_scan" +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam new file mode 100644 index 00000000000..d53b72b690e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam @@ -0,0 +1,483 @@ +//// Result represents the result of something that may succeed or not. +//// `Ok` means it was successful, `Error` means it was not successful. + +import gleam/list + +/// Checks whether the result is an `Ok` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_ok(Ok(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_ok(Error(Nil)) +/// False +/// ``` +/// +pub fn is_ok(result: Result(a, e)) -> Bool { + case result { + Error(_) -> False + Ok(_) -> True + } +} + +/// Checks whether the result is an `Error` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_error(Ok(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_error(Error(Nil)) +/// True +/// ``` +/// +pub fn is_error(result: Result(a, e)) -> Bool { + case result { + Ok(_) -> False + Error(_) -> True + } +} + +/// Updates a value held within the `Ok` of a result by calling a given function +/// on it. +/// +/// If the result is an `Error` rather than `Ok` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > map(over: Error(1), with: fn(x) { x + 1 }) +/// Error(1) +/// ``` +/// +pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { + case result { + Ok(x) -> Ok(fun(x)) + Error(e) -> Error(e) + } +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it. +/// +/// If the result is `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map_error(over: Error(1), with: fn(x) { x + 1 }) +/// Error(2) +/// ``` +/// +/// ```gleam +/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(1) +/// ``` +/// +pub fn map_error( + over result: Result(a, e), + with fun: fn(e) -> f, +) -> Result(a, f) { + case result { + Ok(x) -> Ok(x) + Error(error) -> Error(fun(error)) + } +} + +/// Merges a nested `Result` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Ok(Ok(1))) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > flatten(Ok(Error(""))) +/// Error("") +/// ``` +/// +/// ```gleam +/// > flatten(Error(Nil)) +/// Error(Nil) +/// ``` +/// +pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { + case result { + Ok(x) -> x + Error(error) -> Error(error) + } +} + +/// Updates a value held within the `Ok` of a result by calling a given function +/// on it, where the given function also returns a result. The two results are +/// then merged together into one result. +/// +/// If the result is an `Error` rather than `Ok` the function is not called and the +/// result stays the same. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that may fail. +/// +/// ## Examples +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(x + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) +/// Ok(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(_) { Error("Oh no") }) +/// Error("Oh no") +/// ``` +/// +/// ```gleam +/// > try(Error(Nil), fn(x) { Ok(x + 1) }) +/// Error(Nil) +/// ``` +/// +pub fn try( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + case result { + Ok(x) -> fun(x) + Error(e) -> Error(e) + } +} + +/// An alias for `try`. See the documentation for that function for more information. +/// +pub fn then( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + try(result, fun) +} + +/// Extracts the `Ok` value from a result, returning a default value if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Ok(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(Error(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap(result: Result(a, e), or default: a) -> a { + case result { + Ok(v) -> v + Error(_) -> default + } +} + +/// Extracts the `Ok` value from a result, evaluating the default function if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Ok(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(Error(""), fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { + case result { + Ok(v) -> v + Error(_) -> default() + } +} + +/// Extracts the `Error` value from a result, returning a default value if the result +/// is an `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_error(Error(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_error(Ok(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap_error(result: Result(a, e), or default: e) -> e { + case result { + Ok(_) -> default + Error(e) -> e + } +} + +/// Extracts the inner value from a result. Both the value and error must be of +/// the same type. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_both(Error(1)) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_both(Ok(2)) +/// 2 +/// ``` +/// +pub fn unwrap_both(result: Result(a, a)) -> a { + case result { + Ok(a) -> a + Error(a) -> a + } +} + +/// Transforms any error into `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > nil_error(Error(1)) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > nil_error(Ok(1)) +/// Ok(1) +/// ``` +/// +pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { + map_error(result, fn(_) { Nil }) +} + +/// Returns the first value if it is `Ok`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Ok(1), Ok(2)) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Ok(1), Error("Error 2")) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Ok(2)) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Error("Error 2")) +/// Error("Error 2") +/// ``` +/// +pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second + } +} + +/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Ok(2) }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Error("Error 2") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) +/// Error("Error 2") +/// ``` +/// +pub fn lazy_or( + first: Result(a, e), + second: fn() -> Result(a, e), +) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second() + } +} + +/// Combines a list of results into a single result. +/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. +/// If any element is `Error` then returns the first error. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Ok(1), Ok(2)]) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Ok(1), Error("e")]) +/// Error("e") +/// ``` +/// +pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { + list.try_map(results, fn(x) { x }) +} + +/// Given a list of results, returns a pair where the first element is a list +/// of all the values inside `Ok` and the second element is a list with all the +/// values inside `Error`. The values in both lists appear in reverse order with +/// respect to their position in the original list of results. +/// +/// ## Examples +/// +/// ```gleam +/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) +/// #([2, 1], ["b", "a"]) +/// ``` +/// +pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { + do_partition(results, [], []) +} + +fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { + case results { + [] -> #(oks, errors) + [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) + [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) + } +} + +/// Replace the value within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace(Ok(1), Nil) +/// Ok(Nil) +/// ``` +/// +/// ```gleam +/// > replace(Error(1), Nil) +/// Error(1) +/// ``` +/// +pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { + case result { + Ok(_) -> Ok(value) + Error(error) -> Error(error) + } +} + +/// Replace the error within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace_error(Error(1), Nil) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > replace_error(Ok(1), Nil) +/// Ok(1) +/// ``` +/// +pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { + case result { + Ok(x) -> Ok(x) + Error(_) -> Error(error) + } +} + +/// Given a list of results, returns only the values inside `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Ok(1), None, Ok(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(results: List(Result(a, e))) -> List(a) { + list.filter_map(results, fn(r) { r }) +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it, where the given function also returns a result. The two results are +/// then merged together into one result. +/// +/// If the result is an `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// This function is useful for chaining together computations that may fail +/// and trying to recover from possible errors. +/// +/// ## Examples +/// +/// ```gleam +/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) +/// Error("failed to recover") +/// ``` +/// +pub fn try_recover( + result: Result(a, e), + with fun: fn(e) -> Result(a, f), +) -> Result(a, f) { + case result { + Ok(value) -> Ok(value) + Error(error) -> fun(error) + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam new file mode 100644 index 00000000000..24409869575 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam @@ -0,0 +1,264 @@ +import gleam/list +import gleam/map.{Map} +import gleam/result + +if erlang { + // A list is used as the map value as an empty list has the smallest + // representation in Erlang's binary format + type Token = + List(Nil) + + const token = [] +} + +if javascript { + type Token = + Nil + + const token = Nil +} + +/// A set is a collection of unique members of the same type. +/// +/// It is implemented using the `gleam/map` module, so inserts and lookups have +/// logarithmic time complexity. +/// +pub opaque type Set(member) { + Set(map: Map(member, Token)) +} + +/// Creates a new empty set. +/// +pub fn new() -> Set(member) { + Set(map.new()) +} + +/// Gets the number of members in a set. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn size(set: Set(member)) -> Int { + map.size(set.map) +} + +/// Inserts an member into the set. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn insert(into set: Set(member), this member: member) -> Set(member) { + Set(map: map.insert(set.map, member, token)) +} + +/// Checks whether a set contains a given member. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(2) +/// True +/// ``` +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn contains(in set: Set(member), this member: member) -> Bool { + set.map + |> map.get(member) + |> result.is_ok +} + +/// Removes a member from a set. If the set does not contain the member then +/// the set is returned unchanged. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> delete(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn delete(from set: Set(member), this member: member) -> Set(member) { + Set(map: map.delete(set.map, member)) +} + +/// Converts the set into a list of the contained members. +/// +/// The list has no specific ordering, any unintentional ordering may change in +/// future versions of Gleam or Erlang. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert(2) |> to_list +/// [2] +/// ``` +/// +pub fn to_list(set: Set(member)) -> List(member) { + map.keys(set.map) +} + +/// Creates a new set of the members in a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort +/// [1, 3, 3, 4] +/// ``` +/// +pub fn from_list(members: List(member)) -> Set(member) { + let map = + list.fold( + over: members, + from: map.new(), + with: fn(m, k) { map.insert(m, k, token) }, + ) + Set(map) +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Sets are not ordered so the values are not returned in any specific order. +/// Do not write code that relies on the order entries are used by this +/// function as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > from_list([1, 3, 9]) +/// > |> fold(0, fn(member, accumulator) { accumulator + member }) +/// 13 +/// ``` +/// +pub fn fold( + over set: Set(member), + from initial: acc, + with reducer: fn(acc, member) -> acc, +) -> acc { + map.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) +} + +/// Creates a new set from an existing set, minus any members that a given +/// function returns `False` for. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > from_list([1, 4, 6, 3, 675, 44, 67]) +/// > |> filter(for: int.is_even) +/// > |> to_list +/// [4, 6, 44] +/// ``` +/// +pub fn filter( + in set: Set(member), + for property: fn(member) -> Bool, +) -> Set(member) { + Set(map.filter(in: set.map, for: fn(m, _) { property(m) })) +} + +pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { + list.fold(over: disallowed, from: set, with: delete) +} + +/// Creates a new map from a given map, only including any members which are in +/// a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) +/// > |> take([1, 3, 5]) +/// > |> to_list +/// [1, 3] +/// ``` +/// +pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { + Set(map.take(from: set.map, keeping: desired)) +} + +fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { + case map.size(first.map) > map.size(second.map) { + True -> #(first, second) + False -> #(second, first) + } +} + +/// Creates a new set that contains all members of both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { + let #(larger, smaller) = order(first, second) + fold(over: smaller, from: larger, with: insert) +} + +/// Creates a new set that contains members that are present in both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [2] +/// ``` +/// +pub fn intersection( + of first: Set(member), + and second: Set(member), +) -> Set(member) { + let #(larger, smaller) = order(first, second) + take(from: larger, keeping: to_list(smaller)) +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam new file mode 100644 index 00000000000..b20e7268671 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam @@ -0,0 +1,1046 @@ +//// Strings in Gleam are UTF-8 binaries. They can be written in your code as +//// text surrounded by `"double quotes"`. + +import gleam/iterator.{Iterator} +import gleam/list +import gleam/option.{None, Option, Some} +import gleam/order +import gleam/string_builder.{StringBuilder} + +if erlang { + import gleam/bit_string + import gleam/dynamic.{Dynamic} + import gleam/result +} + +/// Determines if a `String` is empty. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty("") +/// True +/// ``` +/// +/// ```gleam +/// > is_empty("the world") +/// False +/// ``` +/// +pub fn is_empty(str: String) -> Bool { + str == "" +} + +/// Gets the number of grapheme clusters in a given `String`. +/// +/// This function has to iterate across the whole string to count the number of +/// graphemes, so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length("Gleam") +/// 5 +/// ``` +/// +/// ```gleam +/// > length("ß↑e̊") +/// 3 +/// ``` +/// +/// ```gleam +/// > length("") +/// 0 +/// ``` +/// +pub fn length(string: String) -> Int { + do_length(string) +} + +if erlang { + external fn do_length(String) -> Int = + "string" "length" +} + +if javascript { + external fn do_length(String) -> Int = + "../gleam_stdlib.mjs" "string_length" +} + +/// Reverses a `String`. +/// +/// This function has to iterate across the whole `String` so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse("stressed") +/// "desserts" +/// ``` +/// +pub fn reverse(string: String) -> String { + do_reverse(string) +} + +if erlang { + fn do_reverse(string: String) -> String { + string + |> string_builder.from_string + |> string_builder.reverse + |> string_builder.to_string + } +} + +if javascript { + fn do_reverse(string: String) -> String { + string + |> to_graphemes + |> list.reverse + |> concat + } +} + +/// Creates a new `String` by replacing all occurrences of a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > replace("www.example.com", each: ".", with: "-") +/// "www-example-com" +/// ``` +/// +/// ```gleam +/// > replace("a,b,c,d,e", each: ",", with: "/") +/// "a/b/c/d/e" +/// ``` +/// +pub fn replace( + in string: String, + each pattern: String, + with substitute: String, +) -> String { + string + |> string_builder.from_string + |> string_builder.replace(each: pattern, with: substitute) + |> string_builder.to_string +} + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// lowercase. +/// +/// Useful for case-insensitive comparisons. +/// +/// ## Examples +/// +/// ```gleam +/// > lowercase("X-FILES") +/// "x-files" +/// ``` +/// +pub fn lowercase(string: String) -> String { + do_lowercase(string) +} + +if erlang { + external fn do_lowercase(String) -> String = + "string" "lowercase" +} + +if javascript { + external fn do_lowercase(String) -> String = + "../gleam_stdlib.mjs" "lowercase" +} + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// uppercase. +/// +/// Useful for case-insensitive comparisons and VIRTUAL YELLING. +/// +/// ## Examples +/// +/// ```gleam +/// > uppercase("skinner") +/// "SKINNER" +/// ``` +/// +pub fn uppercase(string: String) -> String { + do_uppercase(string) +} + +if erlang { + external fn do_uppercase(String) -> String = + "string" "uppercase" +} + +if javascript { + external fn do_uppercase(String) -> String = + "../gleam_stdlib.mjs" "uppercase" +} + +/// Compares two `String`s to see which is "larger" by comparing their graphemes. +/// +/// This does not compare the size or length of the given `String`s. +/// +/// ## Examples +/// +/// ```gleam +/// > compare("Anthony", "Anthony") +/// order.Eq +/// ``` +/// +/// ```gleam +/// > compare("A", "B") +/// order.Lt +/// ``` +/// +pub fn compare(a: String, b: String) -> order.Order { + case a == b { + True -> order.Eq + _ -> + case less_than(a, b) { + True -> order.Lt + _ -> order.Gt + } + } +} + +if erlang { + external fn less_than(String, String) -> Bool = + "gleam_stdlib" "less_than" +} + +if javascript { + external fn less_than(String, String) -> Bool = + "../gleam_stdlib.mjs" "less_than" +} + +/// Takes a substring given a start and end grapheme indexes. Negative indexes +/// are taken starting from the *end* of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 2) +/// "le" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 10) +/// "leam" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 10, length: 3) +/// "" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -2, length: 2) +/// "am" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -12, length: 2) +/// "" +/// ``` +/// +pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { + case len < 0 { + True -> "" + False -> + case idx < 0 { + True -> { + let translated_idx = length(string) + idx + case translated_idx < 0 { + True -> "" + False -> do_slice(string, translated_idx, len) + } + } + False -> do_slice(string, idx, len) + } + } +} + +if erlang { + external fn do_slice(String, Int, Int) -> String = + "string" "slice" +} + +if javascript { + fn do_slice(string: String, idx: Int, len: Int) -> String { + string + |> to_graphemes + |> list.drop(idx) + |> list.take(len) + |> concat + } +} + +/// Drops contents of the first `String` that occur before the second `String`. +/// If the `from` string does not contain the `before` string, `from` is returned unchanged. +/// +/// ## Examples +/// +/// ```gleam +/// > crop(from: "The Lone Gunmen", before: "Lone") +/// "Lone Gunmen" +/// ``` +/// +pub fn crop(from string: String, before substring: String) -> String { + do_crop(string, substring) +} + +if erlang { + fn do_crop(string: String, substring: String) -> String { + string + |> erl_contains(substring) + |> dynamic.string() + |> result.unwrap(string) + } + + external fn erl_contains(String, String) -> Dynamic = + "string" "find" +} + +if javascript { + external fn do_crop(String, String) -> String = + "../gleam_stdlib.mjs" "crop_string" +} + +/// Drops *n* graphemes from the left side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_left(from: "The Lone Gunmen", up_to: 2) +/// "e Lone Gunmen" +/// ``` +/// +pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, num_graphemes, length(string) - num_graphemes) + } +} + +/// Drops *n* graphemes from the right side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) +/// "Cigarette Smoking M" +/// ``` +/// +pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, 0, length(string) - num_graphemes) + } +} + +/// Checks if the first `String` contains the second. +/// +/// ## Examples +/// +/// ```gleam +/// > contains(does: "theory", contain: "ory") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "the") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "THE") +/// False +/// ``` +/// +pub fn contains(does haystack: String, contain needle: String) -> Bool { + do_contains(haystack, needle) +} + +if erlang { + fn do_contains(haystack: String, needle: String) -> Bool { + haystack + |> erl_contains(needle) + |> dynamic.bit_string + |> result.is_ok + } +} + +if javascript { + fn do_contains(haystack: String, needle: String) -> Bool { + index_of(haystack, needle) != -1 + } + + external fn index_of(String, String) -> Int = + "../gleam_stdlib.mjs" "index_of" +} + +/// Checks whether the first `String` starts with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > starts_with("theory", "ory") +/// False +/// ``` +/// +pub fn starts_with(string: String, prefix: String) -> Bool { + do_starts_with(string, prefix) +} + +if erlang { + external fn do_starts_with(String, String) -> Bool = + "gleam_stdlib" "string_starts_with" +} + +if javascript { + external fn do_starts_with(String, String) -> Bool = + "../gleam_stdlib.mjs" "starts_with" +} + +/// Checks whether the first `String` ends with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > ends_with("theory", "ory") +/// True +/// ``` +/// +pub fn ends_with(string: String, suffix: String) -> Bool { + do_ends_with(string, suffix) +} + +if erlang { + external fn do_ends_with(String, String) -> Bool = + "gleam_stdlib" "string_ends_with" +} + +if javascript { + external fn do_ends_with(String, String) -> Bool = + "../gleam_stdlib.mjs" "ends_with" +} + +/// Creates a list of `String`s by splitting a given string on a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > split("home/gleam/desktop/", on: "/") +/// ["home", "gleam", "desktop", ""] +/// ``` +/// +pub fn split(x: String, on substring: String) -> List(String) { + case substring { + "" -> to_graphemes(x) + _ -> + x + |> string_builder.from_string + |> string_builder.split(on: substring) + |> list.map(with: string_builder.to_string) + } +} + +/// Splits a `String` a single time on the given substring. +/// +/// Returns an `Error` if substring not present. +/// +/// ## Examples +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "/") +/// Ok(#("home", "gleam/desktop/")) +/// ``` +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "?") +/// Error(Nil) +/// ``` +/// +pub fn split_once( + x: String, + on substring: String, +) -> Result(#(String, String), Nil) { + do_split_once(x, substring) +} + +if erlang { + external fn erl_split(String, String) -> List(String) = + "string" "split" + + fn do_split_once( + x: String, + substring: String, + ) -> Result(#(String, String), Nil) { + case erl_split(x, substring) { + [first, rest] -> Ok(#(first, rest)) + _ -> Error(Nil) + } + } +} + +if javascript { + external fn do_split_once( + x: String, + substring: String, + ) -> Result(#(String, String), Nil) = + "../gleam_stdlib.mjs" "split_once" +} + +/// Creates a new `String` by joining two `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: "butter", suffix: "fly") +/// "butterfly" +/// ``` +/// +pub fn append(to first: String, suffix second: String) -> String { + first + |> string_builder.from_string + |> string_builder.append(second) + |> string_builder.to_string +} + +/// Creates a new `String` by joining many `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > concat(["never", "the", "less"]) +/// "nevertheless" +/// ``` +/// +pub fn concat(strings: List(String)) -> String { + strings + |> string_builder.from_strings + |> string_builder.to_string +} + +/// Creates a new `String` by repeating a `String` a given number of times. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("ha", times: 3) +/// "hahaha" +/// ``` +/// +pub fn repeat(string: String, times times: Int) -> String { + iterator.repeat(string) + |> iterator.take(times) + |> iterator.to_list + |> concat +} + +/// Joins many `String`s together with a given separator. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > join(["home","evan","Desktop"], with: "/") +/// "home/evan/Desktop" +/// ``` +/// +pub fn join(strings: List(String), with separator: String) -> String { + strings + |> list.intersperse(with: separator) + |> concat +} + +/// Pads a `String` on the left until it has at least given number of graphemes. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_left("121", to: 5, with: ".") +/// "..121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 3, with: ".") +/// "121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 2, with: ".") +/// "121" +/// ``` +/// +pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + padding(to_pad_length, pad_string) + |> iterator.append(iterator.single(string)) + |> iterator.to_list + |> concat +} + +/// Pads a `String` on the right until it has a given length. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_right("123", to: 5, with: ".") +/// "123.." +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 3, with: ".") +/// "123" +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 2, with: ".") +/// "123" +/// ``` +/// +pub fn pad_right( + string: String, + to desired_length: Int, + with pad_string: String, +) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + iterator.single(string) + |> iterator.append(padding(to_pad_length, pad_string)) + |> iterator.to_list + |> concat +} + +fn padding(size: Int, pad_string: String) -> Iterator(String) { + let pad_length = length(pad_string) + let num_pads = size / pad_length + let extra = size % pad_length + iterator.repeat(pad_string) + |> iterator.take(num_pads) + |> iterator.append(iterator.single(slice(pad_string, 0, extra))) +} + +/// Removes whitespace on both sides of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim(" hats \n") +/// "hats" +/// ``` +/// +pub fn trim(string: String) -> String { + do_trim(string) +} + +if erlang { + fn do_trim(string: String) -> String { + erl_trim(string, Both) + } + + type Direction { + Leading + Trailing + Both + } + + external fn erl_trim(String, Direction) -> String = + "string" "trim" +} + +if javascript { + external fn do_trim(string: String) -> String = + "../gleam_stdlib.mjs" "trim" +} + +/// Removes whitespace on the left of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_left(" hats \n") +/// "hats \n" +/// ``` +/// +pub fn trim_left(string: String) -> String { + do_trim_left(string) +} + +if erlang { + fn do_trim_left(string: String) -> String { + erl_trim(string, Leading) + } +} + +if javascript { + external fn do_trim_left(string: String) -> String = + "../gleam_stdlib.mjs" "trim_left" +} + +/// Removes whitespace on the right of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_right(" hats \n") +/// " hats" +/// ``` +/// +pub fn trim_right(string: String) -> String { + do_trim_right(string) +} + +if erlang { + fn do_trim_right(string: String) -> String { + erl_trim(string, Trailing) + } +} + +if javascript { + external fn do_trim_right(string: String) -> String = + "../gleam_stdlib.mjs" "trim_right" +} + +/// Splits a non-empty `String` into its head and tail. This lets you +/// pattern match on `String`s exactly as you would with lists. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_grapheme("gleam") +/// Ok(#("g", "leam")) +/// ``` +/// +/// ```gleam +/// > pop_grapheme("") +/// Error(Nil) +/// ``` +/// +pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { + do_pop_grapheme(string) +} + +if erlang { + external fn do_pop_grapheme(string: String) -> Result(#(String, String), Nil) = + "gleam_stdlib" "string_pop_grapheme" +} + +if javascript { + external fn do_pop_grapheme(string: String) -> Result(#(String, String), Nil) = + "../gleam_stdlib.mjs" "pop_grapheme" +} + +/// Converts a `String` to a list of +/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). +/// +/// ```gleam +/// > to_graphemes("abc") +/// ["a", "b", "c"] +/// ``` +/// +pub fn to_graphemes(string: String) -> List(String) { + do_to_graphemes(string, []) + |> list.reverse +} + +fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { + case pop_grapheme(string) { + Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) + _ -> acc + } +} + +if erlang { + external fn unsafe_int_to_utf_codepoint(Int) -> UtfCodepoint = + "gleam_stdlib" "identity" +} + +if javascript { + external fn unsafe_int_to_utf_codepoint(Int) -> UtfCodepoint = + "../gleam_stdlib.mjs" "codepoint" +} + +/// Converts a `String` to a `List` of `UtfCodepoint`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > "a" |> to_utf_codepoints +/// [UtfCodepoint(97)] +/// ``` +/// +/// ```gleam +/// // Semantically the same as: +/// // ["🏳", "️", "‍", "🌈"] or: +/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] +/// > "🏳️‍🌈" |> to_utf_codepoints +/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] +/// ``` +/// +pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints(string) +} + +if erlang { + fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints_impl(bit_string.from_string(string), []) + |> list.reverse + } + + fn do_to_utf_codepoints_impl( + bit_string: BitString, + acc: List(UtfCodepoint), + ) -> List(UtfCodepoint) { + case bit_string { + <> -> + do_to_utf_codepoints_impl(rest, [first, ..acc]) + <<>> -> acc + } + } +} + +if javascript { + fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + string + |> string_to_codepoint_integer_list + |> list.map(unsafe_int_to_utf_codepoint) + } + + external fn string_to_codepoint_integer_list(String) -> List(Int) = + "../gleam_stdlib.mjs" "string_to_codepoint_integer_list" +} + +/// Converts a `List` of `UtfCodepoint`s to a `String`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > { +/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( +/// > utf_codepoint(97), +/// > utf_codepoint(98), +/// > utf_codepoint(99), +/// > ) +/// > [a, b, c] +/// > } +/// > |> from_utf_codepoints +/// "abc" +/// ``` +/// +pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { + do_from_utf_codepoints(utf_codepoints) +} + +if erlang { + fn do_from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { + let assert Ok(string) = + do_from_utf_codepoints_impl(utf_codepoints, bit_string.from_string("")) + |> bit_string.to_string + string + } + + fn do_from_utf_codepoints_impl( + utf_codepoints: List(UtfCodepoint), + acc: BitString, + ) -> BitString { + case utf_codepoints { + [first, ..rest] -> + do_from_utf_codepoints_impl( + rest, + <>, + ) + [] -> acc + } + } +} + +if javascript { + fn do_from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { + utf_codepoint_list_to_string(utf_codepoints) + } + + external fn utf_codepoint_list_to_string(List(UtfCodepoint)) -> String = + "../gleam_stdlib.mjs" "utf_codepoint_list_to_string" +} + +/// Converts an integer to a `UtfCodepoint`. +/// +/// Returns an `Error` if the integer does not represent a valid UTF codepoint. +/// +pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { + case value { + i if i > 1_114_111 -> Error(Nil) + 65_534 | 65_535 -> Error(Nil) + i if i >= 55_296 && i <= 57_343 -> Error(Nil) + i -> Ok(unsafe_int_to_utf_codepoint(i)) + } +} + +/// Converts an UtfCodepoint to its ordinal code point value. +/// +/// ## Examples +/// +/// ```gleam +/// > utf_codepoint_to_int(128013) |> to_utf_codepoint_int +/// 128013 +/// ``` +/// +pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { + do_utf_codepoint_to_int(cp) +} + +if erlang { + external fn do_utf_codepoint_to_int(cp: UtfCodepoint) -> Int = + "gleam_stdlib" "identity" +} + +if javascript { + external fn do_utf_codepoint_to_int(cp: UtfCodepoint) -> Int = + "../gleam_stdlib.mjs" "utf_codepoint_to_int" +} + +/// Converts a `String` into `Option(String)` where an empty `String` becomes +/// `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_option("") +/// None +/// ``` +/// +/// ```gleam +/// > to_option("hats") +/// Some("hats") +/// ``` +/// +pub fn to_option(s: String) -> Option(String) { + case s { + "" -> None + _ -> Some(s) + } +} + +/// Returns the first grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > first("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first("icecream") +/// Ok("i") +/// ``` +/// +pub fn first(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, _)) -> Ok(first) + Error(e) -> Error(e) + } +} + +/// Returns the last grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > last("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last("icecream") +/// Ok("m") +/// ``` +/// +pub fn last(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, "")) -> Ok(first) + Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) + Error(e) -> Error(e) + } +} + +/// Creates a new `String` with the first grapheme in the input `String` +/// converted to uppercase and the remaining graphemes to lowercase. +/// +/// ## Examples +/// +/// ```gleam +/// > capitalise("mamouna") +/// "Mamouna" +/// ``` +/// +pub fn capitalise(s: String) -> String { + case pop_grapheme(s) { + Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) + _ -> "" + } +} + +/// Returns a `String` representation of a term in Gleam syntax. +/// +pub fn inspect(term: anything) -> String { + do_inspect(term) + |> string_builder.to_string +} + +if javascript { + external fn do_inspect(term: anything) -> StringBuilder = + "../gleam.mjs" "inspect" +} + +if erlang { + external fn do_inspect(term: anything) -> StringBuilder = + "gleam_stdlib" "inspect" +} + +/// Returns the number of bytes in a `String`. +/// +/// This function runs in constant time on Erlang and in linear time on +/// JavaScript. +/// +pub fn byte_size(string: String) -> Int { + do_byte_size(string) +} + +if javascript { + external fn do_byte_size(String) -> Int = + "../gleam_stdlib.mjs" "byte_size" +} + +if erlang { + external fn do_byte_size(String) -> Int = + "erlang" "byte_size" +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam new file mode 100644 index 00000000000..6137910c551 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam @@ -0,0 +1,356 @@ +import gleam/list + +/// `StringBuilder` is a type used for efficiently building strings. +/// +/// When we append one string to another the strings must be copied to a +/// new location in memory so that they can sit together. This behaviour +/// enables efficient reading of the string but copying can be expensive, +/// especially if we want to join many strings together. +/// +/// `StringBuilder` is different in that it can be joined together in constant time +/// using minimal memory, and then can be efficiently converted to a string +/// using the `to_string` function. +/// +/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this +/// type is compatible with normal strings. +/// +pub external type StringBuilder + +/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many +/// builders together. +/// +pub fn new() -> StringBuilder { + do_from_strings([]) +} + +/// Prepends a `String` onto the start of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn prepend( + to builder: StringBuilder, + prefix prefix: String, +) -> StringBuilder { + append_builder(from_string(prefix), builder) +} + +/// Appends a `String` onto the end of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { + append_builder(builder, from_string(second)) +} + +/// Prepends some `StringBuilder` onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder( + to builder: StringBuilder, + prefix prefix: StringBuilder, +) -> StringBuilder { + do_append(prefix, builder) +} + +/// Appends some `StringBuilder` onto the end of another. +/// +/// Runs in constant time. +/// +pub fn append_builder( + to builder: StringBuilder, + suffix suffix: StringBuilder, +) -> StringBuilder { + do_append(builder, suffix) +} + +if erlang { + external fn do_append(StringBuilder, StringBuilder) -> StringBuilder = + "gleam_stdlib" "iodata_append" +} + +if javascript { + external fn do_append(StringBuilder, StringBuilder) -> StringBuilder = + "../gleam_stdlib.mjs" "add" +} + +/// Converts a list of strings into a builder. +/// +/// Runs in constant time. +/// +pub fn from_strings(strings: List(String)) -> StringBuilder { + do_from_strings(strings) +} + +if erlang { + external fn do_from_strings(List(String)) -> StringBuilder = + "gleam_stdlib" "identity" +} + +if javascript { + external fn do_from_strings(List(String)) -> StringBuilder = + "../gleam_stdlib.mjs" "join" +} + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +pub fn concat(builders: List(StringBuilder)) -> StringBuilder { + do_concat(builders) +} + +if erlang { + external fn do_concat(List(StringBuilder)) -> StringBuilder = + "gleam_stdlib" "identity" +} + +if javascript { + external fn do_concat(List(StringBuilder)) -> StringBuilder = + "../gleam_stdlib.mjs" "join" +} + +/// Converts a string into a builder. +/// +/// Runs in constant time. +/// +pub fn from_string(string: String) -> StringBuilder { + do_from_string(string) +} + +if erlang { + external fn do_from_string(String) -> StringBuilder = + "gleam_stdlib" "identity" +} + +if javascript { + external fn do_from_string(String) -> StringBuilder = + "../gleam_stdlib.mjs" "identity" +} + +/// Turns an `StringBuilder` into a `String` +/// +/// This function is implemented natively by the virtual machine and is highly +/// optimised. +/// +pub fn to_string(builder: StringBuilder) -> String { + do_to_string(builder) +} + +if erlang { + external fn do_to_string(StringBuilder) -> String = + "unicode" "characters_to_binary" +} + +if javascript { + external fn do_to_string(StringBuilder) -> String = + "../gleam_stdlib.mjs" "identity" +} + +/// Returns the size of the `StringBuilder` in bytes. +/// +pub fn byte_size(builder: StringBuilder) -> Int { + do_byte_size(builder) +} + +if erlang { + external fn do_byte_size(StringBuilder) -> Int = + "erlang" "iolist_size" +} + +if javascript { + external fn do_byte_size(StringBuilder) -> Int = + "../gleam_stdlib.mjs" "length" +} + +/// Joins the given builders into a new builder separated with the given string +/// +pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { + builders + |> list.intersperse(from_string(sep)) + |> concat +} + +/// Converts a builder to a new builder where the contents have been +/// lowercased. +/// +pub fn lowercase(builder: StringBuilder) -> StringBuilder { + do_lowercase(builder) +} + +if erlang { + external fn do_lowercase(StringBuilder) -> StringBuilder = + "string" "lowercase" +} + +if javascript { + external fn do_lowercase(StringBuilder) -> StringBuilder = + "../gleam_stdlib.mjs" "lowercase" +} + +/// Converts a builder to a new builder where the contents have been +/// uppercased. +/// +pub fn uppercase(builder: StringBuilder) -> StringBuilder { + do_uppercase(builder) +} + +if erlang { + external fn do_uppercase(StringBuilder) -> StringBuilder = + "string" "uppercase" +} + +if javascript { + external fn do_uppercase(StringBuilder) -> StringBuilder = + "../gleam_stdlib.mjs" "uppercase" +} + +/// Converts a builder to a new builder with the contents reversed. +/// +pub fn reverse(builder: StringBuilder) -> StringBuilder { + do_reverse(builder) +} + +if erlang { + external fn do_reverse(StringBuilder) -> StringBuilder = + "string" "reverse" +} + +if javascript { + fn do_reverse(builder: StringBuilder) -> StringBuilder { + builder + |> to_string + |> do_to_graphemes + |> list.reverse + |> from_strings + } + + external fn do_to_graphemes(string: String) -> List(String) = + "../gleam_stdlib.mjs" "graphemes" +} + +/// Splits a builder on a given pattern into a list of builders. +/// +pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { + do_split(iodata, pattern) +} + +if erlang { + type Direction { + All + } + + external fn erl_split(StringBuilder, String, Direction) -> List(StringBuilder) = + "string" "split" + + fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { + erl_split(iodata, pattern, All) + } +} + +if javascript { + external fn do_split( + builder: StringBuilder, + pattern: String, + ) -> List(StringBuilder) = + "../gleam_stdlib.mjs" "split" +} + +/// Replaces all instances of a pattern with a given string substitute. +/// +pub fn replace( + in builder: StringBuilder, + each pattern: String, + with substitute: String, +) -> StringBuilder { + do_replace(builder, pattern, substitute) +} + +if erlang { + fn do_replace( + iodata: StringBuilder, + pattern: String, + substitute: String, + ) -> StringBuilder { + erl_replace(iodata, pattern, substitute, All) + } + + external fn erl_replace( + StringBuilder, + String, + String, + Direction, + ) -> StringBuilder = + "string" "replace" +} + +if javascript { + external fn do_replace(StringBuilder, String, String) -> StringBuilder = + "../gleam_stdlib.mjs" "string_replace" +} + +/// Compares two builders to determine if they have the same textual content. +/// +/// Comparing two iodata using the `==` operator may return `False` even if they +/// have the same content as they may have been build in different ways, so +/// using this function is often preferred. +/// +/// ## Examples +/// +/// ```gleam +/// > from_strings(["a", "b"]) == from_string("ab") +/// False +/// ``` +/// +/// ```gleam +/// > is_equal(from_strings(["a", "b"]), from_string("ab")) +/// True +/// ``` +/// +pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { + do_is_equal(a, b) +} + +if erlang { + external fn do_is_equal(StringBuilder, StringBuilder) -> Bool = + "string" "equal" +} + +if javascript { + external fn do_is_equal(StringBuilder, StringBuilder) -> Bool = + "../gleam_stdlib.mjs" "equal" +} + +/// Inspects a builder to determine if it is equivalent to an empty string. +/// +/// ## Examples +/// +/// ```gleam +/// > from_string("ok") |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > from_string("") |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > from_strings([]) |> is_empty +/// True +/// ``` +/// +pub fn is_empty(builder: StringBuilder) -> Bool { + do_is_empty(builder) +} + +if erlang { + external fn do_is_empty(StringBuilder) -> Bool = + "string" "is_empty" +} + +if javascript { + fn do_is_empty(builder: StringBuilder) -> Bool { + from_string("") == builder + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam new file mode 100644 index 00000000000..3fdfc6d5b14 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam @@ -0,0 +1,476 @@ +//// Utilities for working with URIs +//// +//// This module provides functions for working with URIs (for example, parsing +//// URIs or encoding query strings). The functions in this module are implemented +//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). +//// +//// Query encoding (Form encoding) is defined in the +//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). + +import gleam/int +import gleam/list +import gleam/option.{None, Option, Some} +import gleam/string +import gleam/string_builder.{StringBuilder} + +if javascript { + import gleam/pair + import gleam/regex + import gleam/result +} + +/// Type representing holding the parsed components of an URI. +/// All components of a URI are optional, except the path. +/// +pub type Uri { + Uri( + scheme: Option(String), + userinfo: Option(String), + host: Option(String), + port: Option(Int), + path: String, + query: Option(String), + fragment: Option(String), + ) +} + +/// Parses a compliant URI string into the `Uri` Type. +/// If the string is not a valid URI string then an error is returned. +/// +/// The opposite operation is `uri.to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("https://example.com:1234/a/b?query=true#fragment") +/// Ok( +/// Uri( +/// scheme: Some("https"), +/// userinfo: None, +/// host: Some("example.com"), +/// port: Some(1234), +/// path: "/a/b", +/// query: Some("query=true"), +/// fragment: Some("fragment") +/// ) +/// ) +/// ``` +/// +pub fn parse(uri_string: String) -> Result(Uri, Nil) { + do_parse(uri_string) +} + +if erlang { + external fn do_parse(String) -> Result(Uri, Nil) = + "gleam_stdlib" "uri_parse" +} + +if javascript { + fn do_parse(uri_string: String) -> Result(Uri, Nil) { + // From https://tools.ietf.org/html/rfc3986#appendix-B + let pattern = + // 12 3 4 5 6 7 8 + "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" + let matches = + pattern + |> regex_submatches(uri_string) + |> pad_list(8) + + let #(scheme, authority, path, query, fragment) = case matches { + [ + _scheme_with_colon, + scheme, + authority_with_slashes, + _authority, + path, + query_with_question_mark, + _query, + fragment, + ] -> #( + scheme, + authority_with_slashes, + path, + query_with_question_mark, + fragment, + ) + _ -> #(None, None, None, None, None) + } + + let scheme = noneify_empty_string(scheme) + let path = option.unwrap(path, "") + let query = noneify_query(query) + let #(userinfo, host, port) = split_authority(authority) + let fragment = + fragment + |> option.to_result(Nil) + |> result.try(string.pop_grapheme) + |> result.map(pair.second) + |> option.from_result + let scheme = + scheme + |> noneify_empty_string + |> option.map(string.lowercase) + Ok(Uri( + scheme: scheme, + userinfo: userinfo, + host: host, + port: port, + path: path, + query: query, + fragment: fragment, + )) + } + + fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { + pattern + |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) + |> result.nil_error + |> result.map(regex.scan(_, string)) + |> result.try(list.first) + |> result.map(fn(m: regex.Match) { m.submatches }) + |> result.unwrap([]) + } + + fn noneify_query(x: Option(String)) -> Option(String) { + case x { + None -> None + Some(x) -> + case string.pop_grapheme(x) { + Ok(#("?", query)) -> Some(query) + _ -> None + } + } + } + + fn noneify_empty_string(x: Option(String)) -> Option(String) { + case x { + Some("") | None -> None + Some(_) -> x + } + } + + // Split an authority into its userinfo, host and port parts. + fn split_authority( + authority: Option(String), + ) -> #(Option(String), Option(String), Option(Int)) { + case option.unwrap(authority, "") { + "" -> #(None, None, None) + "//" -> #(None, Some(""), None) + authority -> { + let matches = + "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" + |> regex_submatches(authority) + |> pad_list(6) + case matches { + [_, _, userinfo, host, _, port] -> { + let userinfo = noneify_empty_string(userinfo) + let host = noneify_empty_string(host) + let port = + port + |> option.unwrap("") + |> int.parse + |> option.from_result + #(userinfo, host, port) + } + _ -> #(None, None, None) + } + } + } + } + + fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { + list + |> list.append(list.repeat(None, extra_required(list, size))) + } + + fn extra_required(list: List(a), remaining: Int) -> Int { + case list { + _ if remaining == 0 -> 0 + [] -> remaining + [_, ..xs] -> extra_required(xs, remaining - 1) + } + } +} + +/// Parses an urlencoded query string into a list of key value pairs. +/// Returns an error for invalid encoding. +/// +/// The opposite operation is `uri.query_to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse_query("a=1&b=2") +/// Ok([#("a", "1"), #("b", "2")]) +/// ``` +/// +pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { + do_parse_query(query) +} + +if erlang { + external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = + "gleam_stdlib" "parse_query" +} + +if javascript { + external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = + "../gleam_stdlib.mjs" "parse_query" +} + +/// Encodes a list of key value pairs as a URI query string. +/// +/// The opposite operation is `uri.parse_query`. +/// +/// ## Examples +/// +/// ```gleam +/// > query_to_string([#("a", "1"), #("b", "2")]) +/// "a=1&b=2" +/// ``` +/// +pub fn query_to_string(query: List(#(String, String))) -> String { + query + |> list.map(query_pair) + |> list.intersperse(string_builder.from_string("&")) + |> string_builder.concat + |> string_builder.to_string +} + +fn query_pair(pair: #(String, String)) -> StringBuilder { + string_builder.from_strings([ + percent_encode(pair.0), + "=", + percent_encode(pair.1), + ]) +} + +/// Encodes a string into a percent encoded representation. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_encode("100% great") +/// "100%25%20great" +/// ``` +/// +pub fn percent_encode(value: String) -> String { + do_percent_encode(value) +} + +if erlang { + external fn do_percent_encode(String) -> String = + "gleam_stdlib" "percent_encode" +} + +if javascript { + external fn do_percent_encode(String) -> String = + "../gleam_stdlib.mjs" "percent_encode" +} + +/// Decodes a percent encoded string. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_decode("100%25+great") +/// Ok("100% great") +/// ``` +/// +pub fn percent_decode(value: String) -> Result(String, Nil) { + do_percent_decode(value) +} + +if erlang { + external fn do_percent_decode(String) -> Result(String, Nil) = + "gleam_stdlib" "percent_decode" +} + +if javascript { + external fn do_percent_decode(String) -> Result(String, Nil) = + "../gleam_stdlib.mjs" "percent_decode" +} + +fn do_remove_dot_segments( + input: List(String), + accumulator: List(String), +) -> List(String) { + case input { + [] -> list.reverse(accumulator) + [segment, ..rest] -> { + let accumulator = case segment, accumulator { + "", accumulator -> accumulator + ".", accumulator -> accumulator + "..", [] -> [] + "..", [_, ..accumulator] -> accumulator + segment, accumulator -> [segment, ..accumulator] + } + do_remove_dot_segments(rest, accumulator) + } + } +} + +fn remove_dot_segments(input: List(String)) -> List(String) { + do_remove_dot_segments(input, []) +} + +/// Splits the path section of a URI into it's constituent segments. +/// +/// Removes empty segments and resolves dot-segments as specified in +/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. +/// +/// ## Examples +/// +/// ```gleam +/// > path_segments("/users/1") +/// ["users" ,"1"] +/// ``` +/// +pub fn path_segments(path: String) -> List(String) { + remove_dot_segments(string.split(path, "/")) +} + +/// Encodes a `Uri` value as a URI string. +/// +/// The opposite operation is `uri.parse`. +/// +/// ## Examples +/// +/// ```gleam +/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) +/// > to_string(uri) +/// "http://example.com" +/// ``` +/// +pub fn to_string(uri: Uri) -> String { + let parts = case uri.fragment { + Some(fragment) -> ["#", fragment] + _ -> [] + } + let parts = case uri.query { + Some(query) -> ["?", query, ..parts] + _ -> parts + } + let parts = [uri.path, ..parts] + let parts = case uri.host, string.starts_with(uri.path, "/") { + Some(host), False if host != "" -> ["/", ..parts] + _, _ -> parts + } + let parts = case uri.host, uri.port { + Some(_), Some(port) -> [":", int.to_string(port), ..parts] + _, _ -> parts + } + let parts = case uri.scheme, uri.userinfo, uri.host { + Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] + Some(s), None, Some(h) -> [s, "://", h, ..parts] + Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] + None, None, Some(h) -> ["//", h, ..parts] + None, Some(_), None | None, None, None -> parts + } + string.concat(parts) +} + +/// Fetches the origin of a URI. +/// +/// Returns the origin of a uri as defined in +/// [RFC 6454](https://tools.ietf.org/html/rfc6454) +/// +/// The supported URI schemes are `http` and `https`. +/// URLs without a scheme will return `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") +/// > origin(uri) +/// Ok("http://example.com") +/// ``` +/// +pub fn origin(uri: Uri) -> Result(String, Nil) { + let Uri(scheme: scheme, host: host, port: port, ..) = uri + case scheme { + Some("https") if port == Some(443) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some("http") if port == Some(80) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some(s) if s == "http" || s == "https" -> { + let origin = Uri(scheme, None, host, port, "", None, None) + Ok(to_string(origin)) + } + _ -> Error(Nil) + } +} + +fn drop_last(elements: List(a)) -> List(a) { + list.take(from: elements, up_to: list.length(elements) - 1) +} + +fn join_segments(segments: List(String)) -> String { + string.join(["", ..segments], "/") +} + +/// Resolves a URI with respect to the given base URI. +/// +/// The base URI must be an absolute URI or this function will return an error. +/// The algorithm for merging uris is described in +/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). +/// +pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { + case base { + Uri(scheme: Some(_), host: Some(_), ..) -> + case relative { + Uri(host: Some(_), ..) -> { + let path = + string.split(relative.path, "/") + |> remove_dot_segments() + |> join_segments() + let resolved = + Uri( + option.or(relative.scheme, base.scheme), + None, + relative.host, + option.or(relative.port, base.port), + path, + relative.query, + relative.fragment, + ) + Ok(resolved) + } + Uri(scheme: None, host: None, ..) -> { + let #(new_path, new_query) = case relative.path { + "" -> #(base.path, option.or(relative.query, base.query)) + _ -> { + let path_segments = case string.starts_with(relative.path, "/") { + True -> string.split(relative.path, "/") + False -> + string.split(base.path, "/") + |> drop_last() + |> list.append(string.split(relative.path, "/")) + } + let path = + path_segments + |> remove_dot_segments() + |> join_segments() + #(path, relative.query) + } + } + let resolved = + Uri( + base.scheme, + None, + base.host, + base.port, + new_path, + new_query, + relative.fragment, + ) + Ok(resolved) + } + } + _ -> Error(Nil) + } +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl new file mode 100644 index 00000000000..65890cc439c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl @@ -0,0 +1,45 @@ +-module(gleam@base). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([encode64/2, url_encode64/2, decode64/1, url_decode64/1]). + +-spec encode64(bitstring(), boolean()) -> binary(). +encode64(Input, Padding) -> + Encoded = base64:encode(Input), + case Padding of + true -> + Encoded; + + false -> + gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) + end. + +-spec url_encode64(bitstring(), boolean()) -> binary(). +url_encode64(Input, Padding) -> + _pipe = encode64(Input, Padding), + _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), + gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). + +-spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. +decode64(Encoded) -> + Padded = case gleam@bit_string:byte_size( + gleam@bit_string:from_string(Encoded) + ) + rem 4 of + 0 -> + Encoded; + + N -> + gleam@string:append( + Encoded, + gleam@string:repeat(<<"="/utf8>>, 4 - N) + ) + end, + gleam_stdlib:base_decode64(Padded). + +-spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. +url_decode64(Encoded) -> + _pipe = Encoded, + _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), + _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), + decode64(_pipe@2). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl new file mode 100644 index 00000000000..8cc9d3263c3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl @@ -0,0 +1,63 @@ +-module(gleam@bit_builder). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([append_builder/2, prepend_builder/2, new/0, concat/1, concat_bit_strings/1, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_string/1, prepend/2, append/2, to_bit_string/1, byte_size/1]). +-export_type([bit_builder/0]). + +-type bit_builder() :: any(). + +-spec append_builder(bit_builder(), bit_builder()) -> bit_builder(). +append_builder(First, Second) -> + gleam_stdlib:iodata_append(First, Second). + +-spec prepend_builder(bit_builder(), bit_builder()) -> bit_builder(). +prepend_builder(To, Prefix) -> + append_builder(Prefix, To). + +-spec new() -> bit_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec concat(list(bit_builder())) -> bit_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec concat_bit_strings(list(bitstring())) -> bit_builder(). +concat_bit_strings(Bits) -> + gleam_stdlib:identity(Bits). + +-spec from_string(binary()) -> bit_builder(). +from_string(String) -> + gleam_stdlib:wrap_list(String). + +-spec prepend_string(bit_builder(), binary()) -> bit_builder(). +prepend_string(To, Prefix) -> + append_builder(from_string(Prefix), To). + +-spec append_string(bit_builder(), binary()) -> bit_builder(). +append_string(To, Suffix) -> + append_builder(To, from_string(Suffix)). + +-spec from_string_builder(gleam@string_builder:string_builder()) -> bit_builder(). +from_string_builder(Builder) -> + gleam_stdlib:wrap_list(Builder). + +-spec from_bit_string(bitstring()) -> bit_builder(). +from_bit_string(Bits) -> + gleam_stdlib:wrap_list(Bits). + +-spec prepend(bit_builder(), bitstring()) -> bit_builder(). +prepend(To, Prefix) -> + append_builder(from_bit_string(Prefix), To). + +-spec append(bit_builder(), bitstring()) -> bit_builder(). +append(To, Suffix) -> + append_builder(To, from_bit_string(Suffix)). + +-spec to_bit_string(bit_builder()) -> bitstring(). +to_bit_string(Builder) -> + erlang:list_to_bitstring(Builder). + +-spec byte_size(bit_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl new file mode 100644 index 00000000000..8896e3b7aed --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl @@ -0,0 +1,56 @@ +-module(gleam@bit_string). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([from_string/1, byte_size/1, slice/3, concat/1, append/2, is_utf8/1, to_string/1]). + +-spec from_string(binary()) -> bitstring(). +from_string(X) -> + gleam_stdlib:identity(X). + +-spec byte_size(bitstring()) -> integer(). +byte_size(X) -> + erlang:byte_size(X). + +-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | + {error, nil}. +slice(String, Position, Length) -> + gleam_stdlib:bit_string_slice(String, Position, Length). + +-spec concat(list(bitstring())) -> bitstring(). +concat(Bit_strings) -> + gleam_stdlib:bit_string_concat(Bit_strings). + +-spec append(bitstring(), bitstring()) -> bitstring(). +append(First, Second) -> + concat([First, Second]). + +-spec do_is_utf8(bitstring()) -> boolean(). +do_is_utf8(Bits) -> + case Bits of + <<>> -> + true; + + <<_/utf8, Rest/binary>> -> + do_is_utf8(Rest); + + _ -> + false + end. + +-spec is_utf8(bitstring()) -> boolean(). +is_utf8(Bits) -> + do_is_utf8(Bits). + +-spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. +do_to_string(Bits) -> + case is_utf8(Bits) of + true -> + {ok, gleam_stdlib:identity(Bits)}; + + false -> + {error, nil} + end. + +-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. +to_string(Bits) -> + do_to_string(Bits). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl new file mode 100644 index 00000000000..260e759517d --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl @@ -0,0 +1,152 @@ +-module(gleam@bool). +-compile([no_auto_import, nowarn_unused_vars]). + +-export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3]). + +-spec 'and'(boolean(), boolean()) -> boolean(). +'and'(A, B) -> + A andalso B. + +-spec 'or'(boolean(), boolean()) -> boolean(). +'or'(A, B) -> + A orelse B. + +-spec negate(boolean()) -> boolean(). +negate(Bool) -> + case Bool of + true -> + false; + + false -> + true + end. + +-spec nor(boolean(), boolean()) -> boolean(). +nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + false + end. + +-spec nand(boolean(), boolean()) -> boolean(). +nand(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_or(boolean(), boolean()) -> boolean(). +exclusive_or(A, B) -> + case {A, B} of + {false, false} -> + false; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_nor(boolean(), boolean()) -> boolean(). +exclusive_nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + true + end. + +-spec compare(boolean(), boolean()) -> gleam@order:order(). +compare(A, B) -> + case {A, B} of + {true, true} -> + eq; + + {true, false} -> + gt; + + {false, false} -> + eq; + + {false, true} -> + lt + end. + +-spec max(boolean(), boolean()) -> boolean(). +max(A, B) -> + case A of + true -> + true; + + false -> + B + end. + +-spec min(boolean(), boolean()) -> boolean(). +min(A, B) -> + case A of + false -> + false; + + true -> + B + end. + +-spec to_int(boolean()) -> integer(). +to_int(Bool) -> + case Bool of + false -> + 0; + + true -> + 1 + end. + +-spec to_string(boolean()) -> binary(). +to_string(Bool) -> + case Bool of + false -> + <<"False"/utf8>>; + + true -> + <<"True"/utf8>> + end. + +-spec guard(boolean(), EIA, fun(() -> EIA)) -> EIA. +guard(Requirement, Consequence, Alternative) -> + case Requirement of + true -> + Consequence; + + false -> + Alternative() + end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl new file mode 100644 index 00000000000..61849a790e0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl @@ -0,0 +1,794 @@ +-module(gleam@dynamic). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([dynamic/1, decode1/2, from/1, unsafe_coerce/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, result/2, any/1, string/1, list/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). +-export_type([decode_error/0, dynamic/0, unknown_tuple/0]). + +-type decode_error() :: {decode_error, binary(), binary(), list(binary())}. + +-type dynamic() :: any(). + +-type unknown_tuple() :: any(). + +-spec dynamic(dynamic()) -> {ok, dynamic()} | {error, list(decode_error())}. +dynamic(Value) -> + {ok, Value}. + +-spec put_expected(decode_error(), binary()) -> decode_error(). +put_expected(Error, Expected) -> + erlang:setelement(2, Error, Expected). + +-spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). +all_errors(Result) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + Errors + end. + +-spec decode1( + fun((CSZ) -> CTA), + fun((dynamic()) -> {ok, CSZ} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CTA} | {error, list(decode_error())}). +decode1(Constructor, T1) -> + fun(Value) -> case T1(Value) of + {ok, A} -> + {ok, Constructor(A)}; + + A@1 -> + {error, all_errors(A@1)} + end end. + +-spec from(any()) -> dynamic(). +from(A) -> + gleam_stdlib:identity(A). + +-spec unsafe_coerce(dynamic()) -> any(). +unsafe_coerce(A) -> + gleam_stdlib:identity(A). + +-spec bit_string(dynamic()) -> {ok, bitstring()} | {error, list(decode_error())}. +bit_string(Data) -> + gleam_stdlib:decode_bit_string(Data). + +-spec classify(dynamic()) -> binary(). +classify(Data) -> + gleam_stdlib:classify_dynamic(Data). + +-spec int(dynamic()) -> {ok, integer()} | {error, list(decode_error())}. +int(Data) -> + gleam_stdlib:decode_int(Data). + +-spec at_least_decode_tuple_error(integer(), dynamic()) -> {ok, any()} | + {error, list(decode_error())}. +at_least_decode_tuple_error(Size, Data) -> + S = case Size of + 1 -> + <<""/utf8>>; + + _ -> + <<"s"/utf8>> + end, + Error = begin + _pipe = [<<"Tuple of at least "/utf8>>, + gleam@int:to_string(Size), + <<" element"/utf8>>, + S], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + _pipe@2 = gleam@string_builder:to_string(_pipe@1), + {decode_error, _pipe@2, classify(Data), []} + end, + {error, [Error]}. + +-spec float(dynamic()) -> {ok, float()} | {error, list(decode_error())}. +float(Data) -> + gleam_stdlib:decode_float(Data). + +-spec bool(dynamic()) -> {ok, boolean()} | {error, list(decode_error())}. +bool(Data) -> + gleam_stdlib:decode_bool(Data). + +-spec shallow_list(dynamic()) -> {ok, list(dynamic())} | + {error, list(decode_error())}. +shallow_list(Value) -> + gleam_stdlib:decode_list(Value). + +-spec optional(fun((dynamic()) -> {ok, CPW} | {error, list(decode_error())})) -> fun((dynamic()) -> {ok, + gleam@option:option(CPW)} | + {error, list(decode_error())}). +optional(Decode) -> + fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. + +-spec result( + fun((dynamic()) -> {ok, CPK} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CPM} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, {ok, CPK} | {error, CPM}} | + {error, list(decode_error())}). +result(Decode_ok, Decode_error) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_result(Value), + fun(Inner_result) -> case Inner_result of + {ok, Raw} -> + gleam@result:'try'( + begin + _pipe = Decode_ok(Raw), + map_errors( + _pipe, + fun(_capture) -> + push_path(_capture, <<"ok"/utf8>>) + end + ) + end, + fun(Value@1) -> {ok, {ok, Value@1}} end + ); + + {error, Raw@1} -> + gleam@result:'try'( + begin + _pipe@1 = Decode_error(Raw@1), + map_errors( + _pipe@1, + fun(_capture@1) -> + push_path(_capture@1, <<"error"/utf8>>) + end + ) + end, + fun(Value@2) -> {ok, {error, Value@2}} end + ) + end end + ) + end. + +-spec any(list(fun((dynamic()) -> {ok, CSV} | {error, list(decode_error())}))) -> fun((dynamic()) -> {ok, + CSV} | + {error, list(decode_error())}). +any(Decoders) -> + fun(Data) -> case Decoders of + [] -> + {error, + [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; + + [Decoder | Decoders@1] -> + case Decoder(Data) of + {ok, Decoded} -> + {ok, Decoded}; + + {error, _} -> + (any(Decoders@1))(Data) + end + end end. + +-spec push_path(decode_error(), any()) -> decode_error(). +push_path(Error, Name) -> + Name@1 = from(Name), + Decoder = any( + [fun string/1, + fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] + ), + Name@3 = case Decoder(Name@1) of + {ok, Name@2} -> + Name@2; + + {error, _} -> + _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1) + end, + erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). + +-spec string(dynamic()) -> {ok, binary()} | {error, list(decode_error())}. +string(Data) -> + decode_string(Data). + +-spec decode_string(dynamic()) -> {ok, binary()} | {error, list(decode_error())}. +decode_string(Data) -> + _pipe = bit_string(Data), + _pipe@1 = map_errors( + _pipe, + fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end + ), + gleam@result:'try'( + _pipe@1, + fun(Raw) -> case gleam@bit_string:to_string(Raw) of + {ok, String} -> + {ok, String}; + + {error, nil} -> + {error, + [{decode_error, + <<"String"/utf8>>, + <<"BitString"/utf8>>, + []}]} + end end + ). + +-spec map_errors( + {ok, COU} | {error, list(decode_error())}, + fun((decode_error()) -> decode_error()) +) -> {ok, COU} | {error, list(decode_error())}. +map_errors(Result, F) -> + gleam@result:map_error( + Result, + fun(_capture) -> gleam@list:map(_capture, F) end + ). + +-spec list(fun((dynamic()) -> {ok, CPR} | {error, list(decode_error())})) -> fun((dynamic()) -> {ok, + list(CPR)} | + {error, list(decode_error())}). +list(Decoder_type) -> + fun(Dynamic) -> + gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, + _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end + ) end) + end. + +-spec field( + any(), + fun((dynamic()) -> {ok, CQB} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CQB} | {error, list(decode_error())}). +field(Name, Inner_type) -> + fun(Value) -> + Missing_field_error = {decode_error, + <<"field"/utf8>>, + <<"nothing"/utf8>>, + []}, + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> _pipe = Maybe_inner, + _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), + _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), + map_errors( + _pipe@2, + fun(_capture) -> push_path(_capture, Name) end + ) end + ) + end. + +-spec optional_field( + any(), + fun((dynamic()) -> {ok, CQF} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, gleam@option:option(CQF)} | + {error, list(decode_error())}). +optional_field(Name, Inner_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> case Maybe_inner of + none -> + {ok, none}; + + {some, Dynamic_inner} -> + _pipe = Dynamic_inner, + _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, Name) end + ) + end end + ) + end. + +-spec element( + integer(), + fun((dynamic()) -> {ok, CQJ} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CQJ} | {error, list(decode_error())}). +element(Index, Inner_type) -> + fun(Data) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple(Data), + fun(Tuple) -> + Size = gleam_stdlib:size_of_tuple(Tuple), + gleam@result:'try'(case Index >= 0 of + true -> + case Index < Size of + true -> + gleam_stdlib:tuple_get(Tuple, Index); + + false -> + at_least_decode_tuple_error(Index + 1, Data) + end; + + false -> + case gleam@int:absolute_value(Index) =< Size of + true -> + gleam_stdlib:tuple_get(Tuple, Size + Index); + + false -> + at_least_decode_tuple_error( + gleam@int:absolute_value(Index), + Data + ) + end + end, fun(Data@1) -> _pipe = Inner_type(Data@1), + map_errors( + _pipe, + fun(_capture) -> push_path(_capture, Index) end + ) end) + end + ) + end. + +-spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). +tuple_errors(Result, Name) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + gleam@list:map( + Errors, + fun(_capture) -> push_path(_capture, Name) end + ) + end. + +-spec tuple2( + fun((dynamic()) -> {ok, CQV} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CQX} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, {CQV, CQX}} | {error, list(decode_error())}). +tuple2(Decode1, Decode2) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple2(Value), + fun(_use0) -> + {A, B} = _use0, + case {Decode1(A), Decode2(B)} of + {{ok, A@1}, {ok, B@1}} -> + {ok, {A@1, B@1}}; + + {A@2, B@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + {error, _pipe@1} + end + end + ) + end. + +-spec tuple3( + fun((dynamic()) -> {ok, CRA} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRC} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRE} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, {CRA, CRC, CRE}} | {error, list(decode_error())}). +tuple3(Decode1, Decode2, Decode3) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple3(Value), + fun(_use0) -> + {A, B, C} = _use0, + case {Decode1(A), Decode2(B), Decode3(C)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> + {ok, {A@1, B@1, C@1}}; + + {A@2, B@2, C@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + {error, _pipe@2} + end + end + ) + end. + +-spec tuple4( + fun((dynamic()) -> {ok, CRH} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRJ} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRL} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRN} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, {CRH, CRJ, CRL, CRN}} | + {error, list(decode_error())}). +tuple4(Decode1, Decode2, Decode3, Decode4) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple4(Value), + fun(_use0) -> + {A, B, C, D} = _use0, + case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> + {ok, {A@1, B@1, C@1, D@1}}; + + {A@2, B@2, C@2, D@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + {error, _pipe@3} + end + end + ) + end. + +-spec tuple5( + fun((dynamic()) -> {ok, CRQ} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRS} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRU} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRW} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CRY} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, {CRQ, CRS, CRU, CRW, CRY}} | + {error, list(decode_error())}). +tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple5(Value), + fun(_use0) -> + {A, B, C, D, E} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1}}; + + {A@2, B@2, C@2, D@2, E@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + {error, _pipe@4} + end + end + ) + end. + +-spec tuple6( + fun((dynamic()) -> {ok, CSB} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CSD} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CSF} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CSH} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CSJ} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CSL} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, {CSB, CSD, CSF, CSH, CSJ, CSL}} | + {error, list(decode_error())}). +tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple6(Value), + fun(_use0) -> + {A, B, C, D, E, F} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E), + Decode6(F)} of + {{ok, A@1}, + {ok, B@1}, + {ok, C@1}, + {ok, D@1}, + {ok, E@1}, + {ok, F@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; + + {A@2, B@2, C@2, D@2, E@2, F@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + _pipe@5 = gleam@list:append( + _pipe@4, + tuple_errors(F@2, <<"5"/utf8>>) + ), + {error, _pipe@5} + end + end + ) + end. + +-spec map( + fun((dynamic()) -> {ok, CSO} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CSQ} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, gleam@map:map_(CSO, CSQ)} | + {error, list(decode_error())}). +map(Key_type, Value_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_map(Value), + fun(Map) -> + gleam@result:'try'( + begin + _pipe = Map, + _pipe@1 = gleam@map:to_list(_pipe), + gleam@list:try_map( + _pipe@1, + fun(Pair) -> + {K, V} = Pair, + gleam@result:'try'( + begin + _pipe@2 = Key_type(K), + map_errors( + _pipe@2, + fun(_capture) -> + push_path( + _capture, + <<"keys"/utf8>> + ) + end + ) + end, + fun(K@1) -> + gleam@result:'try'( + begin + _pipe@3 = Value_type(V), + map_errors( + _pipe@3, + fun(_capture@1) -> + push_path( + _capture@1, + <<"values"/utf8>> + ) + end + ) + end, + fun(V@1) -> {ok, {K@1, V@1}} end + ) + end + ) + end + ) + end, + fun(Pairs) -> {ok, gleam@map:from_list(Pairs)} end + ) + end + ) + end. + +-spec decode2( + fun((CTD, CTE) -> CTF), + fun((dynamic()) -> {ok, CTD} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CTE} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CTF} | {error, list(decode_error())}). +decode2(Constructor, T1, T2) -> + fun(Value) -> case {T1(Value), T2(Value)} of + {{ok, A}, {ok, B}} -> + {ok, Constructor(A, B)}; + + {A@1, B@1} -> + {error, gleam@list:flatten([all_errors(A@1), all_errors(B@1)])} + end end. + +-spec decode3( + fun((CTJ, CTK, CTL) -> CTM), + fun((dynamic()) -> {ok, CTJ} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CTK} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CTL} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CTM} | {error, list(decode_error())}). +decode3(Constructor, T1, T2, T3) -> + fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of + {{ok, A}, {ok, B}, {ok, C}} -> + {ok, Constructor(A, B, C)}; + + {A@1, B@1, C@1} -> + {error, + gleam@list:flatten( + [all_errors(A@1), all_errors(B@1), all_errors(C@1)] + )} + end end. + +-spec decode4( + fun((CTR, CTS, CTT, CTU) -> CTV), + fun((dynamic()) -> {ok, CTR} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CTS} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CTT} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CTU} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CTV} | {error, list(decode_error())}). +decode4(Constructor, T1, T2, T3, T4) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> + {ok, Constructor(A, B, C, D)}; + + {A@1, B@1, C@1, D@1} -> + {error, + gleam@list:flatten( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1)] + )} + end end. + +-spec decode5( + fun((CUB, CUC, CUD, CUE, CUF) -> CUG), + fun((dynamic()) -> {ok, CUB} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUC} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUD} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUE} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUF} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CUG} | {error, list(decode_error())}). +decode5(Constructor, T1, T2, T3, T4, T5) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> + {ok, Constructor(A, B, C, D, E)}; + + {A@1, B@1, C@1, D@1, E@1} -> + {error, + gleam@list:flatten( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1)] + )} + end end. + +-spec decode6( + fun((CUN, CUO, CUP, CUQ, CUR, CUS) -> CUT), + fun((dynamic()) -> {ok, CUN} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUO} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUP} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUQ} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUR} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CUS} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CUT} | {error, list(decode_error())}). +decode6(Constructor, T1, T2, T3, T4, T5, T6) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> + {ok, Constructor(A, B, C, D, E, F)}; + + {A@1, B@1, C@1, D@1, E@1, F@1} -> + {error, + gleam@list:flatten( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1)] + )} + end end. + +-spec decode7( + fun((CVB, CVC, CVD, CVE, CVF, CVG, CVH) -> CVI), + fun((dynamic()) -> {ok, CVB} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVC} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVD} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVE} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVF} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVG} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVH} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CVI} | {error, list(decode_error())}). +decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> + {ok, Constructor(A, B, C, D, E, F, G)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> + {error, + gleam@list:flatten( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1)] + )} + end end. + +-spec decode8( + fun((CVR, CVS, CVT, CVU, CVV, CVW, CVX, CVY) -> CVZ), + fun((dynamic()) -> {ok, CVR} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVS} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVT} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVU} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVV} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVW} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVX} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CVY} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CVZ} | {error, list(decode_error())}). +decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}} -> + {ok, Constructor(A, B, C, D, E, F, G, H)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> + {error, + gleam@list:flatten( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1)] + )} + end end. + +-spec decode9( + fun((CWJ, CWK, CWL, CWM, CWN, CWO, CWP, CWQ, CWR) -> CWS), + fun((dynamic()) -> {ok, CWJ} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWK} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWL} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWM} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWN} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWO} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWP} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWQ} | {error, list(decode_error())}), + fun((dynamic()) -> {ok, CWR} | {error, list(decode_error())}) +) -> fun((dynamic()) -> {ok, CWS} | {error, list(decode_error())}). +decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> + fun(X) -> + case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}, + {ok, I}} -> + {ok, Constructor(A, B, C, D, E, F, G, H, I)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> + {error, + gleam@list:flatten( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1), + all_errors(I@1)] + )} + end + end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl new file mode 100644 index 00000000000..f98da7c1365 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl @@ -0,0 +1,193 @@ +-module(gleam@float). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([compare/2, min/2, max/2, clamp/3, absolute_value/1, loosely_compare/3, loosely_equals/3, negate/1, divide/2, add/2, multiply/2, subtract/2, parse/1, to_string/1, ceiling/1, floor/1, round/1, truncate/1, power/2, square_root/1, random/2, sum/1, product/1]). + +-spec compare(float(), float()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(float(), float()) -> float(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(float(), float()) -> float(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(float(), float(), float()) -> float(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec absolute_value(float()) -> float(). +absolute_value(X) -> + case X >= 0.0 of + true -> + X; + + _ -> + 0.0 - X + end. + +-spec loosely_compare(float(), float(), float()) -> gleam@order:order(). +loosely_compare(A, B, Tolerance) -> + Difference = absolute_value(A - B), + case Difference =< Tolerance of + true -> + eq; + + false -> + compare(A, B) + end. + +-spec loosely_equals(float(), float(), float()) -> boolean(). +loosely_equals(A, B, Tolerance) -> + Difference = absolute_value(A - B), + Difference =< Tolerance. + +-spec negate(float()) -> float(). +negate(X) -> + -1.0 * X. + +-spec divide(float(), float()) -> {ok, float()} | {error, nil}. +divide(A, B) -> + case B of + 0.0 -> + {error, nil}; + + B@1 -> + {ok, case B@1 of + 0.0 -> 0.0; + Gleam@denominator -> A / Gleam@denominator + end} + end. + +-spec add(float(), float()) -> float(). +add(A, B) -> + A + B. + +-spec multiply(float(), float()) -> float(). +multiply(A, B) -> + A * B. + +-spec subtract(float(), float()) -> float(). +subtract(A, B) -> + A - B. + +-spec parse(binary()) -> {ok, float()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_float(String). + +-spec to_string(float()) -> binary(). +to_string(X) -> + gleam_stdlib:float_to_string(X). + +-spec ceiling(float()) -> float(). +ceiling(X) -> + math:ceil(X). + +-spec floor(float()) -> float(). +floor(X) -> + math:floor(X). + +-spec round(float()) -> integer(). +round(X) -> + erlang:round(X). + +-spec truncate(float()) -> integer(). +truncate(X) -> + erlang:trunc(X). + +-spec power(float(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + Fractional = (ceiling(Exponent) - Exponent) > 0.0, + case ((Base < 0.0) andalso Fractional) orelse ((Base =:= 0.0) andalso (Exponent + < 0.0)) of + true -> + {error, nil}; + + false -> + {ok, math:pow(Base, Exponent)} + end. + +-spec square_root(float()) -> {ok, float()} | {error, nil}. +square_root(X) -> + power(X, 0.5). + +-spec random(float(), float()) -> float(). +random(Boundary_a, Boundary_b) -> + {Min, Max} = case {Boundary_a, Boundary_b} of + {A, B} when A =< B -> + {A, B}; + + {A@1, B@1} when A@1 > B@1 -> + {B@1, A@1} + end, + case {Min, Max} of + {Min@1, _} when Min@1 =:= Max -> + Min@1; + + {Min@2, Max@1} -> + (rand:uniform() * (Max@1 - Min@2)) + Min@2 + end. + +-spec do_sum(list(float()), float()) -> float(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(float())) -> float(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, 0.0). + +-spec do_product(list(float()), float()) -> float(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(float())) -> float(). +product(Numbers) -> + case Numbers of + [] -> + 1.0; + + _ -> + do_product(Numbers, 1.0) + end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl new file mode 100644 index 00000000000..1b8c6d2168c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl @@ -0,0 +1,67 @@ +-module(gleam@function). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). + +-spec compose(fun((ESR) -> ESS), fun((ESS) -> EST)) -> fun((ESR) -> EST). +compose(Fun1, Fun2) -> + fun(A) -> Fun2(Fun1(A)) end. + +-spec curry2(fun((ESU, ESV) -> ESW)) -> fun((ESU) -> fun((ESV) -> ESW)). +curry2(Fun) -> + fun(A) -> fun(B) -> Fun(A, B) end end. + +-spec curry3(fun((ESY, ESZ, ETA) -> ETB)) -> fun((ESY) -> fun((ESZ) -> fun((ETA) -> ETB))). +curry3(Fun) -> + fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. + +-spec curry4(fun((ETD, ETE, ETF, ETG) -> ETH)) -> fun((ETD) -> fun((ETE) -> fun((ETF) -> fun((ETG) -> ETH)))). +curry4(Fun) -> + fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. + +-spec curry5(fun((ETJ, ETK, ETL, ETM, ETN) -> ETO)) -> fun((ETJ) -> fun((ETK) -> fun((ETL) -> fun((ETM) -> fun((ETN) -> ETO))))). +curry5(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end + end + end. + +-spec curry6(fun((ETQ, ETR, ETS, ETT, ETU, ETV) -> ETW)) -> fun((ETQ) -> fun((ETR) -> fun((ETS) -> fun((ETT) -> fun((ETU) -> fun((ETV) -> ETW)))))). +curry6(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> + fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end + end + end + end. + +-spec flip(fun((ETY, ETZ) -> EUA)) -> fun((ETZ, ETY) -> EUA). +flip(Fun) -> + fun(B, A) -> Fun(A, B) end. + +-spec identity(EUB) -> EUB. +identity(X) -> + X. + +-spec constant(EUC) -> fun((any()) -> EUC). +constant(Value) -> + fun(_) -> Value end. + +-spec tap(EUE, fun((EUE) -> any())) -> EUE. +tap(Arg, Effect) -> + Effect(Arg), + Arg. + +-spec apply1(fun((EUG) -> EUH), EUG) -> EUH. +apply1(Fun, Arg1) -> + Fun(Arg1). + +-spec apply2(fun((EUI, EUJ) -> EUK), EUI, EUJ) -> EUK. +apply2(Fun, Arg1, Arg2) -> + Fun(Arg1, Arg2). + +-spec apply3(fun((EUL, EUM, EUN) -> EUO), EUL, EUM, EUN) -> EUO. +apply3(Fun, Arg1, Arg2, Arg3) -> + Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl new file mode 100644 index 00000000000..4d3c513a1b2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl @@ -0,0 +1,323 @@ +-module(gleam@int). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([absolute_value/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, random/2, sum/1, product/1, digits/2, undigits/2]). +-export_type([invalid_base/0]). + +-type invalid_base() :: invalid_base. + +-spec absolute_value(integer()) -> integer(). +absolute_value(X) -> + case X >= 0 of + true -> + X; + + false -> + X * -1 + end. + +-spec compare(integer(), integer()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(integer(), integer()) -> integer(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(integer(), integer()) -> integer(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(integer(), integer(), integer()) -> integer(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec is_even(integer()) -> boolean(). +is_even(X) -> + (X rem 2) =:= 0. + +-spec is_odd(integer()) -> boolean(). +is_odd(X) -> + (X rem 2) /= 0. + +-spec negate(integer()) -> integer(). +negate(X) -> + -1 * X. + +-spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend div Gleam@denominator + end} + end. + +-spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. +remainder(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end} + end. + +-spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. +modulo(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + _ -> + Remainder = case Divisor of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end, + case (Remainder * Divisor) < 0 of + true -> + {ok, Remainder + Divisor}; + + false -> + {ok, Remainder} + end + end. + +-spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +floor_divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end) /= 0) of + true -> + {ok, (case Divisor@1 of + 0 -> 0; + Gleam@denominator@1 -> Dividend div Gleam@denominator@1 + end) - 1}; + + false -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator@2 -> Dividend div Gleam@denominator@2 + end} + end + end. + +-spec add(integer(), integer()) -> integer(). +add(A, B) -> + A + B. + +-spec multiply(integer(), integer()) -> integer(). +multiply(A, B) -> + A * B. + +-spec subtract(integer(), integer()) -> integer(). +subtract(A, B) -> + A - B. + +-spec parse(binary()) -> {ok, integer()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_int(String). + +-spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. +base_parse(String, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + gleam_stdlib:int_from_base_string(String, Base); + + false -> + {error, nil} + end. + +-spec to_string(integer()) -> binary(). +to_string(X) -> + erlang:integer_to_binary(X). + +-spec to_base_string(integer(), integer()) -> {ok, binary()} | + {error, invalid_base()}. +to_base_string(X, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + {ok, erlang:integer_to_binary(X, Base)}; + + false -> + {error, invalid_base} + end. + +-spec to_base2(integer()) -> binary(). +to_base2(X) -> + erlang:integer_to_binary(X, 2). + +-spec to_base8(integer()) -> binary(). +to_base8(X) -> + erlang:integer_to_binary(X, 8). + +-spec to_base16(integer()) -> binary(). +to_base16(X) -> + erlang:integer_to_binary(X, 16). + +-spec to_base36(integer()) -> binary(). +to_base36(X) -> + erlang:integer_to_binary(X, 36). + +-spec to_float(integer()) -> float(). +to_float(X) -> + erlang:float(X). + +-spec power(integer(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + _pipe = Base, + _pipe@1 = to_float(_pipe), + gleam@float:power(_pipe@1, Exponent). + +-spec square_root(integer()) -> {ok, float()} | {error, nil}. +square_root(X) -> + _pipe = X, + _pipe@1 = to_float(_pipe), + gleam@float:square_root(_pipe@1). + +-spec random(integer(), integer()) -> integer(). +random(Boundary_a, Boundary_b) -> + {Min, Max} = case {Boundary_a, Boundary_b} of + {A, B} when A =< B -> + {A, B}; + + {A@1, B@1} when A@1 > B@1 -> + {B@1, A@1} + end, + Min@1 = begin + _pipe = to_float(Min), + gleam@float:ceiling(_pipe) + end, + Max@1 = begin + _pipe@1 = to_float(Max), + gleam@float:floor(_pipe@1) + end, + _pipe@2 = gleam@float:random(Min@1, Max@1), + _pipe@3 = gleam@float:floor(_pipe@2), + gleam@float:round(_pipe@3). + +-spec do_sum(list(integer()), integer()) -> integer(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(integer())) -> integer(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, 0). + +-spec do_product(list(integer()), integer()) -> integer(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(integer())) -> integer(). +product(Numbers) -> + case Numbers of + [] -> + 1; + + _ -> + do_product(Numbers, 1) + end. + +-spec do_digits(integer(), integer(), list(integer())) -> list(integer()). +do_digits(X, Base, Acc) -> + case absolute_value(X) < Base of + true -> + [X | Acc]; + + false -> + do_digits(case Base of + 0 -> 0; + Gleam@denominator -> X div Gleam@denominator + end, Base, [case Base of + 0 -> 0; + Gleam@denominator@1 -> X rem Gleam@denominator@1 + end | Acc]) + end. + +-spec digits(integer(), integer()) -> {ok, list(integer())} | + {error, invalid_base()}. +digits(X, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + {ok, do_digits(X, Base, [])} + end. + +-spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | + {error, invalid_base()}. +do_undigits(Numbers, Base, Acc) -> + case Numbers of + [] -> + {ok, Acc}; + + [Digit | _] when Digit >= Base -> + {error, invalid_base}; + + [Digit@1 | Rest] -> + do_undigits(Rest, Base, (Acc * Base) + Digit@1) + end. + +-spec undigits(list(integer()), integer()) -> {ok, integer()} | + {error, invalid_base()}. +undigits(Numbers, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + do_undigits(Numbers, Base, 0) + end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl new file mode 100644 index 00000000000..16dced85238 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl @@ -0,0 +1,27 @@ +-module(gleam@io). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([print/1, print_error/1, println/1, println_error/1, debug/1]). + +-spec print(binary()) -> nil. +print(String) -> + gleam_stdlib:print(String). + +-spec print_error(binary()) -> nil. +print_error(String) -> + gleam_stdlib:print_error(String). + +-spec println(binary()) -> nil. +println(String) -> + gleam_stdlib:println(String). + +-spec println_error(binary()) -> nil. +println_error(String) -> + gleam_stdlib:println_error(String). + +-spec debug(ECD) -> ECD. +debug(Term) -> + _pipe = Term, + _pipe@1 = gleam@string:inspect(_pipe), + gleam_stdlib:println_error(_pipe@1), + Term. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl new file mode 100644 index 00000000000..82b4ff1ca55 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl @@ -0,0 +1,707 @@ +-module(gleam@iterator). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([step/1, empty/0, once/1, single/1, first/1, unfold/2, repeatedly/1, repeat/1, from_list/1, range/2, iterate/2, transform/3, fold/3, run/1, to_list/1, reduce/2, last/1, take/2, drop/2, at/2, map/2, group/2, each/2, append/2, flatten/1, flat_map/2, cycle/1, filter/2, find/2, index/1, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, interleave/2, fold_until/3, try_fold/3, length/1]). +-export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). + +-type action(BMM) :: stop | {continue, BMM, fun(() -> action(BMM))}. + +-opaque iterator(BMN) :: {iterator, fun(() -> action(BMN))}. + +-type step(BMO, BMP) :: {next, BMO, BMP} | done. + +-type chunk(BMQ, BMR) :: {another_by, + list(BMQ), + BMR, + BMQ, + fun(() -> action(BMQ))} | + {last_by, list(BMQ)}. + +-type sized_chunk(BMS) :: {another, list(BMS), fun(() -> action(BMS))} | + {last, list(BMS)} | + no_more. + +-spec stop() -> action(any()). +stop() -> + stop. + +-spec step(iterator(BOL)) -> step(BOL, iterator(BOL)). +step(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + done; + + {continue, E, A} -> + {next, E, {iterator, A}} + end. + +-spec update_group_with(BTZ) -> fun((gleam@option:option(list(BTZ))) -> list(BTZ)). +update_group_with(El) -> + fun(Maybe_group) -> case Maybe_group of + {some, Group} -> + [El | Group]; + + none -> + [El] + end end. + +-spec empty() -> iterator(any()). +empty() -> + {iterator, fun stop/0}. + +-spec once(fun(() -> BVB)) -> iterator(BVB). +once(F) -> + _pipe = fun() -> {continue, F(), fun stop/0} end, + {iterator, _pipe}. + +-spec single(BVD) -> iterator(BVD). +single(Elem) -> + once(fun() -> Elem end). + +-spec first(iterator(BWL)) -> {ok, BWL} | {error, nil}. +first(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, _} -> + {ok, E} + end. + +-spec do_unfold(BMV, fun((BMV) -> step(BMW, BMV))) -> fun(() -> action(BMW)). +do_unfold(Initial, F) -> + fun() -> case F(Initial) of + {next, X, Acc} -> + {continue, X, do_unfold(Acc, F)}; + + done -> + stop + end end. + +-spec unfold(BNA, fun((BNA) -> step(BNB, BNA))) -> iterator(BNB). +unfold(Initial, F) -> + _pipe = Initial, + _pipe@1 = do_unfold(_pipe, F), + {iterator, _pipe@1}. + +-spec repeatedly(fun(() -> BNF)) -> iterator(BNF). +repeatedly(F) -> + unfold(nil, fun(_) -> {next, F(), nil} end). + +-spec repeat(BNH) -> iterator(BNH). +repeat(X) -> + repeatedly(fun() -> X end). + +-spec from_list(list(BNJ)) -> iterator(BNJ). +from_list(List) -> + Yield = fun(Acc) -> case Acc of + [] -> + done; + + [Head | Tail] -> + {next, Head, Tail} + end end, + unfold(List, Yield). + +-spec range(integer(), integer()) -> iterator(integer()). +range(Start, Stop) -> + case gleam@int:compare(Start, Stop) of + eq -> + once(fun() -> Start end); + + gt -> + unfold(Start, fun(Current) -> case Current < Stop of + false -> + {next, Current, Current - 1}; + + true -> + done + end end); + + lt -> + unfold(Start, fun(Current@1) -> case Current@1 > Stop of + false -> + {next, Current@1, Current@1 + 1}; + + true -> + done + end end) + end. + +-spec iterate(BRD, fun((BRD) -> BRD)) -> iterator(BRD). +iterate(Initial, F) -> + unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). + +-spec do_transform( + fun(() -> action(BNM)), + BNO, + fun((BNO, BNM) -> step(BNP, BNO)) +) -> fun(() -> action(BNP)). +do_transform(Continuation, State, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + case F(State, El) of + done -> + stop; + + {next, Yield, Next_state} -> + {continue, Yield, do_transform(Next, Next_state, F)} + end + end end. + +-spec transform(iterator(BNT), BNV, fun((BNV, BNT) -> step(BNW, BNV))) -> iterator(BNW). +transform(Iterator, Initial, F) -> + _pipe = do_transform(erlang:element(2, Iterator), Initial, F), + {iterator, _pipe}. + +-spec do_fold(fun(() -> action(BOA)), fun((BOC, BOA) -> BOC), BOC) -> BOC. +do_fold(Continuation, F, Accumulator) -> + case Continuation() of + {continue, Elem, Next} -> + do_fold(Next, F, F(Accumulator, Elem)); + + stop -> + Accumulator + end. + +-spec fold(iterator(BOD), BOF, fun((BOF, BOD) -> BOF)) -> BOF. +fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold(_pipe, F, Initial). + +-spec run(iterator(any())) -> nil. +run(Iterator) -> + fold(Iterator, nil, fun(_, _) -> nil end). + +-spec to_list(iterator(BOI)) -> list(BOI). +to_list(Iterator) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), + gleam@list:reverse(_pipe@1). + +-spec reduce(iterator(BUR), fun((BUR, BUR) -> BUR)) -> {ok, BUR} | {error, nil}. +reduce(Iterator, F) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, Next} -> + _pipe = do_fold(Next, F, E), + {ok, _pipe} + end. + +-spec last(iterator(BUV)) -> {ok, BUV} | {error, nil}. +last(Iterator) -> + _pipe = Iterator, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec do_take(fun(() -> action(BOQ)), integer()) -> fun(() -> action(BOQ)). +do_take(Continuation, Desired) -> + fun() -> case Desired > 0 of + false -> + stop; + + true -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, do_take(Next, Desired - 1)} + end + end end. + +-spec take(iterator(BOT), integer()) -> iterator(BOT). +take(Iterator, Desired) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take(_pipe, Desired), + {iterator, _pipe@1}. + +-spec do_drop(fun(() -> action(BOW)), integer()) -> action(BOW). +do_drop(Continuation, Desired) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Desired > 0 of + true -> + do_drop(Next, Desired - 1); + + false -> + {continue, E, Next} + end + end. + +-spec drop(iterator(BOZ), integer()) -> iterator(BOZ). +drop(Iterator, Desired) -> + _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, + {iterator, _pipe}. + +-spec at(iterator(BWP), integer()) -> {ok, BWP} | {error, nil}. +at(Iterator, Index) -> + _pipe = Iterator, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1). + +-spec do_map(fun(() -> action(BPC)), fun((BPC) -> BPE)) -> fun(() -> action(BPE)). +do_map(Continuation, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, F(E), do_map(Continuation@1, F)} + end end. + +-spec map(iterator(BPG), fun((BPG) -> BPI)) -> iterator(BPI). +map(Iterator, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_map(_pipe, F), + {iterator, _pipe@1}. + +-spec group_updater(fun((BUD) -> BUE)) -> fun((gleam@map:map_(BUE, list(BUD)), BUD) -> gleam@map:map_(BUE, list(BUD))). +group_updater(F) -> + fun(Groups, Elem) -> _pipe = Groups, + gleam@map:update(_pipe, F(Elem), update_group_with(Elem)) end. + +-spec group(iterator(BUL), fun((BUL) -> BUN)) -> gleam@map:map_(BUN, list(BUL)). +group(Iterator, Key) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, gleam@map:new(), group_updater(Key)), + gleam@map:map_values( + _pipe@1, + fun(_, Group) -> gleam@list:reverse(Group) end + ). + +-spec each(iterator(BWX), fun((BWX) -> any())) -> nil. +each(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + run(_pipe@1). + +-spec do_append(fun(() -> action(BPK)), fun(() -> action(BPK))) -> action(BPK). +do_append(First, Second) -> + case First() of + {continue, E, First@1} -> + {continue, E, fun() -> do_append(First@1, Second) end}; + + stop -> + Second() + end. + +-spec append(iterator(BPO), iterator(BPO)) -> iterator(BPO). +append(First, Second) -> + _pipe = fun() -> + do_append(erlang:element(2, First), erlang:element(2, Second)) + end, + {iterator, _pipe}. + +-spec do_flatten(fun(() -> action(iterator(BPS)))) -> action(BPS). +do_flatten(Flattened) -> + case Flattened() of + stop -> + stop; + + {continue, It, Next_iterator} -> + do_append( + erlang:element(2, It), + fun() -> do_flatten(Next_iterator) end + ) + end. + +-spec flatten(iterator(iterator(BPW))) -> iterator(BPW). +flatten(Iterator) -> + _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, + {iterator, _pipe}. + +-spec flat_map(iterator(BQA), fun((BQA) -> iterator(BQC))) -> iterator(BQC). +flat_map(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + flatten(_pipe@1). + +-spec cycle(iterator(BQL)) -> iterator(BQL). +cycle(Iterator) -> + _pipe = repeat(Iterator), + flatten(_pipe). + +-spec do_filter(fun(() -> action(BQF)), fun((BQF) -> boolean())) -> action(BQF). +do_filter(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Iterator} -> + case Predicate(E) of + true -> + {continue, E, fun() -> do_filter(Iterator, Predicate) end}; + + false -> + do_filter(Iterator, Predicate) + end + end. + +-spec filter(iterator(BQI), fun((BQI) -> boolean())) -> iterator(BQI). +filter(Iterator, Predicate) -> + _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec do_find(fun(() -> action(BQP)), fun((BQP) -> boolean())) -> {ok, BQP} | + {error, nil}. +do_find(Continuation, F) -> + case Continuation() of + stop -> + {error, nil}; + + {continue, E, Next} -> + case F(E) of + true -> + {ok, E}; + + false -> + do_find(Next, F) + end + end. + +-spec find(iterator(BQT), fun((BQT) -> boolean())) -> {ok, BQT} | {error, nil}. +find(Haystack, Is_desired) -> + _pipe = erlang:element(2, Haystack), + do_find(_pipe, Is_desired). + +-spec do_index(fun(() -> action(BQX)), integer()) -> fun(() -> action({integer(), + BQX})). +do_index(Continuation, Next) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, {Next, E}, do_index(Continuation@1, Next + 1)} + end end. + +-spec index(iterator(BRA)) -> iterator({integer(), BRA}). +index(Iterator) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_index(_pipe, 0), + {iterator, _pipe@1}. + +-spec do_take_while(fun(() -> action(BRF)), fun((BRF) -> boolean())) -> fun(() -> action(BRF)). +do_take_while(Continuation, Predicate) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + stop; + + true -> + {continue, E, do_take_while(Next, Predicate)} + end + end end. + +-spec take_while(iterator(BRI), fun((BRI) -> boolean())) -> iterator(BRI). +take_while(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take_while(_pipe, Predicate), + {iterator, _pipe@1}. + +-spec do_drop_while(fun(() -> action(BRL)), fun((BRL) -> boolean())) -> action(BRL). +do_drop_while(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + {continue, E, Next}; + + true -> + do_drop_while(Next, Predicate) + end + end. + +-spec drop_while(iterator(BRO), fun((BRO) -> boolean())) -> iterator(BRO). +drop_while(Iterator, Predicate) -> + _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec do_scan(fun(() -> action(BRR)), fun((BRT, BRR) -> BRT), BRT) -> fun(() -> action(BRT)). +do_scan(Continuation, F, Accumulator) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + Accumulated = F(Accumulator, El), + {continue, Accumulated, do_scan(Next, F, Accumulated)} + end end. + +-spec scan(iterator(BRV), BRX, fun((BRX, BRV) -> BRX)) -> iterator(BRX). +scan(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_scan(_pipe, F, Initial), + {iterator, _pipe@1}. + +-spec do_zip(fun(() -> action(BRZ)), fun(() -> action(BSB))) -> fun(() -> action({BRZ, + BSB})). +do_zip(Left, Right) -> + fun() -> case Left() of + stop -> + stop; + + {continue, El_left, Next_left} -> + case Right() of + stop -> + stop; + + {continue, El_right, Next_right} -> + {continue, + {El_left, El_right}, + do_zip(Next_left, Next_right)} + end + end end. + +-spec zip(iterator(BSE), iterator(BSG)) -> iterator({BSE, BSG}). +zip(Left, Right) -> + _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), + {iterator, _pipe}. + +-spec next_chunk(fun(() -> action(BSJ)), fun((BSJ) -> BSL), BSL, list(BSJ)) -> chunk(BSJ, BSL). +next_chunk(Continuation, F, Previous_key, Current_chunk) -> + case Continuation() of + stop -> + {last_by, gleam@list:reverse(Current_chunk)}; + + {continue, E, Next} -> + Key = F(E), + case Key =:= Previous_key of + true -> + next_chunk(Next, F, Key, [E | Current_chunk]); + + false -> + {another_by, + gleam@list:reverse(Current_chunk), + Key, + E, + Next} + end + end. + +-spec do_chunk(fun(() -> action(BSP)), fun((BSP) -> BSR), BSR, BSP) -> action(list(BSP)). +do_chunk(Continuation, F, Previous_key, Previous_element) -> + case next_chunk(Continuation, F, Previous_key, [Previous_element]) of + {last_by, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another_by, Chunk@1, Key, El, Next} -> + {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} + end. + +-spec chunk(iterator(BSU), fun((BSU) -> any())) -> iterator(list(BSU)). +chunk(Iterator, F) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + do_chunk(Next, F, F(E), E) + end end, + {iterator, _pipe}. + +-spec next_sized_chunk(fun(() -> action(BSZ)), integer(), list(BSZ)) -> sized_chunk(BSZ). +next_sized_chunk(Continuation, Left, Current_chunk) -> + case Continuation() of + stop -> + case Current_chunk of + [] -> + no_more; + + Remaining -> + {last, gleam@list:reverse(Remaining)} + end; + + {continue, E, Next} -> + Chunk = [E | Current_chunk], + case Left > 1 of + false -> + {another, gleam@list:reverse(Chunk), Next}; + + true -> + next_sized_chunk(Next, Left - 1, Chunk) + end + end. + +-spec do_sized_chunk(fun(() -> action(BTD)), integer()) -> fun(() -> action(list(BTD))). +do_sized_chunk(Continuation, Count) -> + fun() -> case next_sized_chunk(Continuation, Count, []) of + no_more -> + stop; + + {last, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another, Chunk@1, Next_element} -> + {continue, Chunk@1, do_sized_chunk(Next_element, Count)} + end end. + +-spec sized_chunk(iterator(BTH), integer()) -> iterator(list(BTH)). +sized_chunk(Iterator, Count) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_sized_chunk(_pipe, Count), + {iterator, _pipe@1}. + +-spec do_intersperse(fun(() -> action(BTL)), BTL) -> action(BTL). +do_intersperse(Continuation, Separator) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + Next_interspersed = fun() -> do_intersperse(Next, Separator) end, + {continue, Separator, fun() -> {continue, E, Next_interspersed} end} + end. + +-spec intersperse(iterator(BTO), BTO) -> iterator(BTO). +intersperse(Iterator, Elem) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, fun() -> do_intersperse(Next, Elem) end} + end end, + {iterator, _pipe}. + +-spec do_any(fun(() -> action(BTR)), fun((BTR) -> boolean())) -> boolean(). +do_any(Continuation, Predicate) -> + case Continuation() of + stop -> + false; + + {continue, E, Next} -> + case Predicate(E) of + true -> + true; + + false -> + do_any(Next, Predicate) + end + end. + +-spec any(iterator(BTT), fun((BTT) -> boolean())) -> boolean(). +any(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_any(_pipe, Predicate). + +-spec do_all(fun(() -> action(BTV)), fun((BTV) -> boolean())) -> boolean(). +do_all(Continuation, Predicate) -> + case Continuation() of + stop -> + true; + + {continue, E, Next} -> + case Predicate(E) of + true -> + do_all(Next, Predicate); + + false -> + false + end + end. + +-spec all(iterator(BTX), fun((BTX) -> boolean())) -> boolean(). +all(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_all(_pipe, Predicate). + +-spec do_interleave(fun(() -> action(BVF)), fun(() -> action(BVF))) -> action(BVF). +do_interleave(Current, Next) -> + case Current() of + stop -> + Next(); + + {continue, E, Next_other} -> + {continue, E, fun() -> do_interleave(Next, Next_other) end} + end. + +-spec interleave(iterator(BVJ), iterator(BVJ)) -> iterator(BVJ). +interleave(Left, Right) -> + _pipe = fun() -> + do_interleave(erlang:element(2, Left), erlang:element(2, Right)) + end, + {iterator, _pipe}. + +-spec do_fold_until( + fun(() -> action(BVN)), + fun((BVP, BVN) -> gleam@list:continue_or_stop(BVP)), + BVP +) -> BVP. +do_fold_until(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + Accumulator; + + {continue, Elem, Next} -> + case F(Accumulator, Elem) of + {continue, Accumulator@1} -> + do_fold_until(Next, F, Accumulator@1); + + {stop, Accumulator@2} -> + Accumulator@2 + end + end. + +-spec fold_until( + iterator(BVR), + BVT, + fun((BVT, BVR) -> gleam@list:continue_or_stop(BVT)) +) -> BVT. +fold_until(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold_until(_pipe, F, Initial). + +-spec do_try_fold( + fun(() -> action(BVV)), + fun((BVX, BVV) -> {ok, BVX} | {error, BVY}), + BVX +) -> {ok, BVX} | {error, BVY}. +do_try_fold(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + {ok, Accumulator}; + + {continue, Elem, Next} -> + gleam@result:'try'( + F(Accumulator, Elem), + fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end + ) + end. + +-spec try_fold(iterator(BWD), BWF, fun((BWF, BWD) -> {ok, BWF} | {error, BWG})) -> {ok, + BWF} | + {error, BWG}. +try_fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_try_fold(_pipe, F, Initial). + +-spec do_length(fun(() -> action(any())), integer()) -> integer(). +do_length(Continuation, Length) -> + case Continuation() of + stop -> + Length; + + {continue, _, Next} -> + do_length(Next, Length + 1) + end. + +-spec length(iterator(any())) -> integer(). +length(Iterator) -> + _pipe = erlang:element(2, Iterator), + do_length(_pipe, 0). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl new file mode 100644 index 00000000000..6d28be2ad8e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl @@ -0,0 +1,1082 @@ +-module(gleam@list). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([is_empty/1, first/1, rest/1, new/0, prepend/2, length/1, reverse/1, append/2, contains/2, map/2, fold/3, group/2, map_fold/3, reduce/2, last/1, filter/2, filter_map/2, index_map/2, try_map/2, drop/2, at/2, take/2, flatten/1, flat_map/2, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, key_find/2, all/2, any/2, zip/2, strict_zip/2, window_by_2/1, unzip/1, intersperse/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, drop_while/2, take_while/2, chunk/2, sized_chunk/2, scan/3, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). +-export_type([length_mismatch/0, continue_or_stop/1]). + +-type length_mismatch() :: length_mismatch. + +-type continue_or_stop(SY) :: {continue, SY} | {stop, SY}. + +-spec is_empty(list(any())) -> boolean(). +is_empty(List) -> + List =:= []. + +-spec first(list(TI)) -> {ok, TI} | {error, nil}. +first(List) -> + case List of + [] -> + {error, nil}; + + [X | _] -> + {ok, X} + end. + +-spec rest(list(TM)) -> {ok, list(TM)} | {error, nil}. +rest(List) -> + case List of + [] -> + {error, nil}; + + [_ | Xs] -> + {ok, Xs} + end. + +-spec new() -> list(any()). +new() -> + []. + +-spec prepend(list(XH), XH) -> list(XH). +prepend(List, Item) -> + [Item | List]. + +-spec length(list(any())) -> integer(). +length(List) -> + erlang:length(List). + +-spec reverse(list(TB)) -> list(TB). +reverse(Xs) -> + lists:reverse(Xs). + +-spec append(list(XD), list(XD)) -> list(XD). +append(First, Second) -> + lists:append(First, Second). + +-spec contains(list(TG), TG) -> boolean(). +contains(List, Elem) -> + case List of + [] -> + false; + + [First | _] when First =:= Elem -> + true; + + [_ | Rest] -> + contains(Rest, Elem) + end. + +-spec do_map(list(VB), fun((VB) -> VD), list(VD)) -> list(VD). +do_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_map(Xs, Fun, [Fun(X) | Acc]) + end. + +-spec map(list(VG), fun((VG) -> VI)) -> list(VI). +map(List, Fun) -> + do_map(List, Fun, []). + +-spec update_group(fun((TR) -> TS)) -> fun((gleam@map:map_(TS, list(TR)), TR) -> gleam@map:map_(TS, list(TR))). +update_group(F) -> + fun(Groups, Elem) -> case gleam@map:get(Groups, F(Elem)) of + {ok, Existing} -> + gleam@map:insert(Groups, F(Elem), [Elem | Existing]); + + {error, _} -> + gleam@map:insert(Groups, F(Elem), [Elem]) + end end. + +-spec fold(list(YC), YE, fun((YE, YC) -> YE)) -> YE. +fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + fold(Rest, Fun(Initial, X), Fun) + end. + +-spec group(list(TZ), fun((TZ) -> UB)) -> gleam@map:map_(UB, list(TZ)). +group(List, Key) -> + fold(List, gleam@map:new(), update_group(Key)). + +-spec map_fold(list(VK), VM, fun((VM, VK) -> {VM, VN})) -> {VM, list(VN)}. +map_fold(List, Acc, Fun) -> + _pipe = fold( + List, + {Acc, []}, + fun(Acc@1, Item) -> + {Current_acc, Items} = Acc@1, + {Next_acc, Next_item} = Fun(Current_acc, Item), + {Next_acc, [Next_item | Items]} + end + ), + gleam@pair:map_second(_pipe, fun reverse/1). + +-spec reduce(list(AHZ), fun((AHZ, AHZ) -> AHZ)) -> {ok, AHZ} | {error, nil}. +reduce(List, Fun) -> + case List of + [] -> + {error, nil}; + + [First | Rest] -> + {ok, fold(Rest, First, Fun)} + end. + +-spec last(list(AIM)) -> {ok, AIM} | {error, nil}. +last(List) -> + _pipe = List, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec do_filter(list(UF), fun((UF) -> boolean()), list(UF)) -> list(UF). +do_filter(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + true -> + [X | Acc]; + + false -> + Acc + end, + do_filter(Xs, Fun, New_acc) + end. + +-spec filter(list(UJ), fun((UJ) -> boolean())) -> list(UJ). +filter(List, Predicate) -> + do_filter(List, Predicate, []). + +-spec do_filter_map(list(UM), fun((UM) -> {ok, UO} | {error, any()}), list(UO)) -> list(UO). +do_filter_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + {ok, X@1} -> + [X@1 | Acc]; + + {error, _} -> + Acc + end, + do_filter_map(Xs, Fun, New_acc) + end. + +-spec filter_map(list(UU), fun((UU) -> {ok, UW} | {error, any()})) -> list(UW). +filter_map(List, Fun) -> + do_filter_map(List, Fun, []). + +-spec do_index_map(list(VP), fun((integer(), VP) -> VR), integer(), list(VR)) -> list(VR). +do_index_map(List, Fun, Index, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + Acc@1 = [Fun(Index, X) | Acc], + do_index_map(Xs, Fun, Index + 1, Acc@1) + end. + +-spec index_map(list(VU), fun((integer(), VU) -> VW)) -> list(VW). +index_map(List, Fun) -> + do_index_map(List, Fun, 0, []). + +-spec do_try_map(list(VY), fun((VY) -> {ok, WA} | {error, WB}), list(WA)) -> {ok, + list(WA)} | + {error, WB}. +do_try_map(List, Fun, Acc) -> + case List of + [] -> + {ok, reverse(Acc)}; + + [X | Xs] -> + case Fun(X) of + {ok, Y} -> + do_try_map(Xs, Fun, [Y | Acc]); + + {error, Error} -> + {error, Error} + end + end. + +-spec try_map(list(WI), fun((WI) -> {ok, WK} | {error, WL})) -> {ok, list(WK)} | + {error, WL}. +try_map(List, Fun) -> + do_try_map(List, Fun, []). + +-spec drop(list(WR), integer()) -> list(WR). +drop(List, N) -> + case N =< 0 of + true -> + List; + + false -> + case List of + [] -> + []; + + [_ | Xs] -> + drop(Xs, N - 1) + end + end. + +-spec at(list(ABY), integer()) -> {ok, ABY} | {error, nil}. +at(List, Index) -> + case Index >= 0 of + true -> + _pipe = List, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1); + + false -> + {error, nil} + end. + +-spec do_take(list(WU), integer(), list(WU)) -> list(WU). +do_take(List, N, Acc) -> + case N =< 0 of + true -> + reverse(Acc); + + false -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_take(Xs, N - 1, [X | Acc]) + end + end. + +-spec take(list(WY), integer()) -> list(WY). +take(List, N) -> + do_take(List, N, []). + +-spec reverse_and_prepend(list(XK), list(XK)) -> list(XK). +reverse_and_prepend(Prefix, Suffix) -> + case Prefix of + [] -> + Suffix; + + [First | Rest] -> + reverse_and_prepend(Rest, [First | Suffix]) + end. + +-spec do_flatten(list(list(XO)), list(XO)) -> list(XO). +do_flatten(Lists, Acc) -> + case Lists of + [] -> + reverse(Acc); + + [List | Further_lists] -> + do_flatten(Further_lists, reverse_and_prepend(List, Acc)) + end. + +-spec flatten(list(list(XT))) -> list(XT). +flatten(Lists) -> + do_flatten(Lists, []). + +-spec flat_map(list(XX), fun((XX) -> list(XZ))) -> list(XZ). +flat_map(List, Fun) -> + _pipe = map(List, Fun), + flatten(_pipe). + +-spec fold_right(list(YF), YH, fun((YH, YF) -> YH)) -> YH. +fold_right(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + Fun(fold_right(Rest, Initial, Fun), X) + end. + +-spec do_index_fold(list(YI), YK, fun((YK, YI, integer()) -> YK), integer()) -> YK. +do_index_fold(Over, Acc, With, Index) -> + case Over of + [] -> + Acc; + + [First | Rest] -> + do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) + end. + +-spec index_fold(list(YL), YN, fun((YN, YL, integer()) -> YN)) -> YN. +index_fold(Over, Initial, Fun) -> + do_index_fold(Over, Initial, Fun, 0). + +-spec try_fold(list(YO), YQ, fun((YQ, YO) -> {ok, YQ} | {error, YR})) -> {ok, + YQ} | + {error, YR}. +try_fold(Collection, Accumulator, Fun) -> + case Collection of + [] -> + {ok, Accumulator}; + + [First | Rest] -> + case Fun(Accumulator, First) of + {ok, Result} -> + try_fold(Rest, Result, Fun); + + {error, _} = Error -> + Error + end + end. + +-spec fold_until(list(YW), YY, fun((YY, YW) -> continue_or_stop(YY))) -> YY. +fold_until(Collection, Accumulator, Fun) -> + case Collection of + [] -> + Accumulator; + + [First | Rest] -> + case Fun(Accumulator, First) of + {continue, Next_accumulator} -> + fold_until(Rest, Next_accumulator, Fun); + + {stop, B} -> + B + end + end. + +-spec find(list(AAA), fun((AAA) -> boolean())) -> {ok, AAA} | {error, nil}. +find(Haystack, Is_desired) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Is_desired(X) of + true -> + {ok, X}; + + _ -> + find(Rest, Is_desired) + end + end. + +-spec find_map(list(AAE), fun((AAE) -> {ok, AAG} | {error, any()})) -> {ok, AAG} | + {error, nil}. +find_map(Haystack, Fun) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Fun(X) of + {ok, X@1} -> + {ok, X@1}; + + _ -> + find_map(Rest, Fun) + end + end. + +-spec key_find(list({ADV, ADW}), ADV) -> {ok, ADW} | {error, nil}. +key_find(Keyword_list, Desired_key) -> + find_map( + Keyword_list, + fun(Keyword) -> + {Key, Value} = Keyword, + case Key =:= Desired_key of + true -> + {ok, Value}; + + false -> + {error, nil} + end + end + ). + +-spec all(list(AAM), fun((AAM) -> boolean())) -> boolean(). +all(List, Predicate) -> + case List of + [] -> + true; + + [First | Rest] -> + case Predicate(First) of + true -> + all(Rest, Predicate); + + false -> + false + end + end. + +-spec any(list(AAO), fun((AAO) -> boolean())) -> boolean(). +any(List, Predicate) -> + case List of + [] -> + false; + + [First | Rest] -> + case Predicate(First) of + true -> + true; + + false -> + any(Rest, Predicate) + end + end. + +-spec do_zip(list(AAQ), list(AAS), list({AAQ, AAS})) -> list({AAQ, AAS}). +do_zip(Xs, Ys, Acc) -> + case {Xs, Ys} of + {[X | Xs@1], [Y | Ys@1]} -> + do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); + + {_, _} -> + reverse(Acc) + end. + +-spec zip(list(AAW), list(AAY)) -> list({AAW, AAY}). +zip(List, Other) -> + do_zip(List, Other, []). + +-spec strict_zip(list(ABB), list(ABD)) -> {ok, list({ABB, ABD})} | + {error, length_mismatch()}. +strict_zip(List, Other) -> + case length(List) =:= length(Other) of + true -> + {ok, zip(List, Other)}; + + false -> + {error, length_mismatch} + end. + +-spec window_by_2(list(AGO)) -> list({AGO, AGO}). +window_by_2(L) -> + zip(L, drop(L, 1)). + +-spec do_unzip(list({ABM, ABN}), list(ABM), list(ABN)) -> {list(ABM), list(ABN)}. +do_unzip(Input, Xs, Ys) -> + case Input of + [] -> + {reverse(Xs), reverse(Ys)}; + + [{X, Y} | Rest] -> + do_unzip(Rest, [X | Xs], [Y | Ys]) + end. + +-spec unzip(list({ABM, ABN})) -> {list(ABM), list(ABN)}. +unzip(Input) -> + do_unzip(Input, [], []). + +-spec do_intersperse(list(ABR), ABR, list(ABR)) -> list(ABR). +do_intersperse(List, Separator, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Rest] -> + do_intersperse(Rest, Separator, [X, Separator | Acc]) + end. + +-spec intersperse(list(ABV), ABV) -> list(ABV). +intersperse(List, Elem) -> + case List of + [] -> + List; + + [_] -> + List; + + [X | Rest] -> + do_intersperse(Rest, Elem, [X]) + end. + +-spec unique(list(ACC)) -> list(ACC). +unique(List) -> + case List of + [] -> + []; + + [X | Rest] -> + [X | unique(filter(Rest, fun(Y) -> Y /= X end))] + end. + +-spec merge_up( + integer(), + integer(), + list(ACF), + list(ACF), + list(ACF), + fun((ACF, ACF) -> gleam@order:order()) +) -> list(ACF). +merge_up(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Ax@1, Bx@1) of + gt -> + merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); + + _ -> + merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) + end + end. + +-spec merge_down( + integer(), + integer(), + list(ACK), + list(ACK), + list(ACK), + fun((ACK, ACK) -> gleam@order:order()) +) -> list(ACK). +merge_down(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Bx@1, Ax@1) of + lt -> + merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); + + _ -> + merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) + end + end. + +-spec merge_sort( + list(ACP), + integer(), + fun((ACP, ACP) -> gleam@order:order()), + boolean() +) -> list(ACP). +merge_sort(L, Ln, Compare, Down) -> + N = Ln div 2, + A = L, + B = drop(L, N), + case Ln < 3 of + true -> + case Down of + true -> + merge_down(N, Ln - N, A, B, [], Compare); + + false -> + merge_up(N, Ln - N, A, B, [], Compare) + end; + + false -> + case Down of + true -> + merge_down( + N, + Ln - N, + merge_sort(A, N, Compare, false), + merge_sort(B, Ln - N, Compare, false), + [], + Compare + ); + + false -> + merge_up( + N, + Ln - N, + merge_sort(A, N, Compare, true), + merge_sort(B, Ln - N, Compare, true), + [], + Compare + ) + end + end. + +-spec sort(list(ACS), fun((ACS, ACS) -> gleam@order:order())) -> list(ACS). +sort(List, Compare) -> + merge_sort(List, length(List), Compare, true). + +-spec do_shuffle_by_pair_indexes(list({float(), AJO})) -> list({float(), AJO}). +do_shuffle_by_pair_indexes(List_of_pairs) -> + sort( + List_of_pairs, + fun(A_pair, B_pair) -> + gleam@float:compare( + erlang:element(1, A_pair), + erlang:element(1, B_pair) + ) + end + ). + +-spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). +tail_recursive_range(Start, Stop, Acc) -> + case gleam@int:compare(Start, Stop) of + eq -> + reverse([Stop | Acc]); + + gt -> + tail_recursive_range(Start - 1, Stop, [Start | Acc]); + + lt -> + tail_recursive_range(Start + 1, Stop, [Start | Acc]) + end. + +-spec range(integer(), integer()) -> list(integer()). +range(Start, Stop) -> + tail_recursive_range(Start, Stop, []). + +-spec do_repeat(ACY, integer(), list(ACY)) -> list(ACY). +do_repeat(A, Times, Acc) -> + case Times =< 0 of + true -> + Acc; + + false -> + do_repeat(A, Times - 1, [A | Acc]) + end. + +-spec repeat(ADB, integer()) -> list(ADB). +repeat(A, Times) -> + do_repeat(A, Times, []). + +-spec do_split(list(ADD), integer(), list(ADD)) -> {list(ADD), list(ADD)}. +do_split(List, N, Taken) -> + case N =< 0 of + true -> + {reverse(Taken), List}; + + false -> + case List of + [] -> + {reverse(Taken), []}; + + [X | Xs] -> + do_split(Xs, N - 1, [X | Taken]) + end + end. + +-spec split(list(ADI), integer()) -> {list(ADI), list(ADI)}. +split(List, Index) -> + do_split(List, Index, []). + +-spec do_split_while(list(ADM), fun((ADM) -> boolean()), list(ADM)) -> {list(ADM), + list(ADM)}. +do_split_while(List, F, Acc) -> + case List of + [] -> + {reverse(Acc), []}; + + [X | Xs] -> + case F(X) of + false -> + {reverse(Acc), List}; + + _ -> + do_split_while(Xs, F, [X | Acc]) + end + end. + +-spec split_while(list(ADR), fun((ADR) -> boolean())) -> {list(ADR), list(ADR)}. +split_while(List, Predicate) -> + do_split_while(List, Predicate, []). + +-spec do_pop(list(AEE), fun((AEE) -> boolean()), list(AEE)) -> {ok, + {AEE, list(AEE)}} | + {error, nil}. +do_pop(Haystack, Predicate, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Predicate(X) of + true -> + {ok, {X, append(reverse(Checked), Rest)}}; + + false -> + do_pop(Rest, Predicate, [X | Checked]) + end + end. + +-spec pop(list(AEE), fun((AEE) -> boolean())) -> {ok, {AEE, list(AEE)}} | + {error, nil}. +pop(Haystack, Is_desired) -> + do_pop(Haystack, Is_desired, []). + +-spec do_pop_map(list(AEN), fun((AEN) -> {ok, AEP} | {error, any()}), list(AEN)) -> {ok, + {AEP, list(AEN)}} | + {error, nil}. +do_pop_map(Haystack, Mapper, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Mapper(X) of + {ok, Y} -> + {ok, {Y, append(reverse(Checked), Rest)}}; + + {error, _} -> + do_pop_map(Rest, Mapper, [X | Checked]) + end + end. + +-spec pop_map(list(AEN), fun((AEN) -> {ok, AEP} | {error, any()})) -> {ok, + {AEP, list(AEN)}} | + {error, nil}. +pop_map(Haystack, Is_desired) -> + do_pop_map(Haystack, Is_desired, []). + +-spec key_pop(list({AEW, AEX}), AEW) -> {ok, {AEX, list({AEW, AEX})}} | + {error, nil}. +key_pop(Haystack, Key) -> + pop_map( + Haystack, + fun(Entry) -> + {K, V} = Entry, + case K of + K@1 when K@1 =:= Key -> + {ok, V}; + + _ -> + {error, nil} + end + end + ). + +-spec key_set(list({AFC, AFD}), AFC, AFD) -> list({AFC, AFD}). +key_set(List, Key, Value) -> + case List of + [] -> + [{Key, Value}]; + + [{K, _} | Rest] when K =:= Key -> + [{Key, Value} | Rest]; + + [First | Rest@1] -> + [First | key_set(Rest@1, Key, Value)] + end. + +-spec each(list(AFG), fun((AFG) -> any())) -> nil. +each(List, F) -> + case List of + [] -> + nil; + + [X | Xs] -> + F(X), + each(Xs, F) + end. + +-spec try_each(list(AFJ), fun((AFJ) -> {ok, any()} | {error, AFM})) -> {ok, nil} | + {error, AFM}. +try_each(List, Fun) -> + case List of + [] -> + {ok, nil}; + + [X | Xs] -> + case Fun(X) of + {ok, _} -> + try_each(Xs, Fun); + + {error, E} -> + {error, E} + end + end. + +-spec do_partition(list(AFW), fun((AFW) -> boolean()), list(AFW), list(AFW)) -> {list(AFW), + list(AFW)}. +do_partition(List, Categorise, Trues, Falses) -> + case List of + [] -> + {reverse(Trues), reverse(Falses)}; + + [X | Xs] -> + case Categorise(X) of + true -> + do_partition(Xs, Categorise, [X | Trues], Falses); + + false -> + do_partition(Xs, Categorise, Trues, [X | Falses]) + end + end. + +-spec partition(list(AFW), fun((AFW) -> boolean())) -> {list(AFW), list(AFW)}. +partition(List, Categorise) -> + do_partition(List, Categorise, [], []). + +-spec permutations(list(AGA)) -> list(list(AGA)). +permutations(L) -> + case L of + [] -> + [[]]; + + _ -> + _pipe = L, + _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, + _pipe@2 = index_fold( + _pipe@1, + [], + fun(Acc, J, J_idx) -> case I_idx =:= J_idx of + true -> + Acc; + + false -> + [J | Acc] + end end + ), + _pipe@3 = reverse(_pipe@2), + _pipe@4 = permutations(_pipe@3), + map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), + flatten(_pipe@5) + end. + +-spec do_window(list(list(AGE)), list(AGE), integer()) -> list(list(AGE)). +do_window(Acc, L, N) -> + Window = take(L, N), + case length(Window) =:= N of + true -> + do_window([Window | Acc], drop(L, 1), N); + + false -> + Acc + end. + +-spec window(list(AGK), integer()) -> list(list(AGK)). +window(L, N) -> + _pipe = do_window([], L, N), + reverse(_pipe). + +-spec drop_while(list(AGR), fun((AGR) -> boolean())) -> list(AGR). +drop_while(List, Predicate) -> + case List of + [] -> + []; + + [X | Xs] -> + case Predicate(X) of + true -> + drop_while(Xs, Predicate); + + false -> + [X | Xs] + end + end. + +-spec do_take_while(list(AGU), fun((AGU) -> boolean()), list(AGU)) -> list(AGU). +do_take_while(List, Predicate, Acc) -> + case List of + [] -> + reverse(Acc); + + [First | Rest] -> + case Predicate(First) of + true -> + do_take_while(Rest, Predicate, [First | Acc]); + + false -> + reverse(Acc) + end + end. + +-spec take_while(list(AGY), fun((AGY) -> boolean())) -> list(AGY). +take_while(List, Predicate) -> + do_take_while(List, Predicate, []). + +-spec do_chunk(list(AHB), fun((AHB) -> AHD), AHD, list(AHB), list(list(AHB))) -> list(list(AHB)). +do_chunk(List, F, Previous_key, Current_chunk, Acc) -> + case List of + [First | Rest] -> + Key = F(First), + case Key =:= Previous_key of + false -> + New_acc = [reverse(Current_chunk) | Acc], + do_chunk(Rest, F, Key, [First], New_acc); + + _ -> + do_chunk(Rest, F, Key, [First | Current_chunk], Acc) + end; + + _ -> + reverse([reverse(Current_chunk) | Acc]) + end. + +-spec chunk(list(AHJ), fun((AHJ) -> any())) -> list(list(AHJ)). +chunk(List, F) -> + case List of + [] -> + []; + + [First | Rest] -> + do_chunk(Rest, F, F(First), [First], []) + end. + +-spec do_sized_chunk( + list(AHO), + integer(), + integer(), + list(AHO), + list(list(AHO)) +) -> list(list(AHO)). +do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> + case List of + [] -> + case Current_chunk of + [] -> + reverse(Acc); + + Remaining -> + reverse([reverse(Remaining) | Acc]) + end; + + [First | Rest] -> + Chunk = [First | Current_chunk], + case Left > 1 of + false -> + do_sized_chunk( + Rest, + Count, + Count, + [], + [reverse(Chunk) | Acc] + ); + + true -> + do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) + end + end. + +-spec sized_chunk(list(AHV), integer()) -> list(list(AHV)). +sized_chunk(List, Count) -> + do_sized_chunk(List, Count, Count, [], []). + +-spec do_scan(list(AID), AIF, list(AIF), fun((AIF, AID) -> AIF)) -> list(AIF). +do_scan(List, Accumulator, Accumulated, Fun) -> + case List of + [] -> + reverse(Accumulated); + + [X | Xs] -> + Next = Fun(Accumulator, X), + do_scan(Xs, Next, [Next | Accumulated], Fun) + end. + +-spec scan(list(AII), AIK, fun((AIK, AII) -> AIK)) -> list(AIK). +scan(List, Initial, Fun) -> + do_scan(List, Initial, [], Fun). + +-spec combinations(list(AIQ), integer()) -> list(list(AIQ)). +combinations(Items, N) -> + case N of + 0 -> + [[]]; + + _ -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = begin + _pipe = map( + combinations(Xs, N - 1), + fun(Com) -> [X | Com] end + ), + reverse(_pipe) + end, + fold( + First_combinations, + combinations(Xs, N), + fun(Acc, C) -> [C | Acc] end + ) + end + end. + +-spec do_combination_pairs(list(AIU)) -> list(list({AIU, AIU})). +do_combination_pairs(Items) -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = map(Xs, fun(Other) -> {X, Other} end), + [First_combinations | do_combination_pairs(Xs)] + end. + +-spec combination_pairs(list(AIY)) -> list({AIY, AIY}). +combination_pairs(Items) -> + _pipe = do_combination_pairs(Items), + flatten(_pipe). + +-spec transpose(list(list(AJF))) -> list(list(AJF)). +transpose(List_of_list) -> + Take_first = fun(List) -> case List of + [] -> + []; + + [F] -> + [F]; + + [F@1 | _] -> + [F@1] + end end, + case List_of_list of + [] -> + []; + + [[] | Xss] -> + transpose(Xss); + + Rows -> + Firsts = begin + _pipe = Rows, + _pipe@1 = map(_pipe, Take_first), + flatten(_pipe@1) + end, + Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), + [Firsts | Rest] + end. + +-spec interleave(list(list(AJB))) -> list(AJB). +interleave(List) -> + _pipe = transpose(List), + flatten(_pipe). + +-spec do_shuffle_pair_unwrap(list({float(), AJK}), list(AJK)) -> list(AJK). +do_shuffle_pair_unwrap(List, Acc) -> + case List of + [] -> + Acc; + + _ -> + [Elem_pair | Enumerable] = List, + do_shuffle_pair_unwrap( + Enumerable, + [erlang:element(2, Elem_pair) | Acc] + ) + end. + +-spec shuffle(list(AJR)) -> list(AJR). +shuffle(List) -> + _pipe = List, + _pipe@1 = fold( + _pipe, + [], + fun(Acc, A) -> [{gleam@float:random(0.0, 1.0), A} | Acc] end + ), + _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), + do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl new file mode 100644 index 00000000000..a15f5599921 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl @@ -0,0 +1,97 @@ +-module(gleam@map). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, update/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, fold/3]). +-export_type([map_/2]). + +-type map_(Key, Value) :: any() | {gleam_phantom, Key, Value}. + +-spec size(map_(any(), any())) -> integer(). +size(Map) -> + maps:size(Map). + +-spec to_list(map_(KF, KG)) -> list({KF, KG}). +to_list(Map) -> + maps:to_list(Map). + +-spec from_list(list({KK, KL})) -> map_(KK, KL). +from_list(List) -> + maps:from_list(List). + +-spec has_key(map_(KP, any()), KP) -> boolean(). +has_key(Map, Key) -> + maps:is_key(Key, Map). + +-spec new() -> map_(any(), any()). +new() -> + maps:new(). + +-spec get(map_(KX, KY), KX) -> {ok, KY} | {error, nil}. +get(From, Get) -> + gleam_stdlib:map_get(From, Get). + +-spec insert(map_(LD, LE), LD, LE) -> map_(LD, LE). +insert(Map, Key, Value) -> + maps:put(Key, Value, Map). + +-spec update(map_(NI, NJ), NI, fun((gleam@option:option(NJ)) -> NJ)) -> map_(NI, NJ). +update(Map, Key, Fun) -> + _pipe = Map, + _pipe@1 = get(_pipe, Key), + _pipe@2 = gleam@option:from_result(_pipe@1), + _pipe@3 = Fun(_pipe@2), + insert(Map, Key, _pipe@3). + +-spec map_values(map_(LJ, LK), fun((LJ, LK) -> LN)) -> map_(LJ, LN). +map_values(Map, Fun) -> + maps:map(Fun, Map). + +-spec keys(map_(LQ, any())) -> list(LQ). +keys(Map) -> + maps:keys(Map). + +-spec values(map_(any(), LW)) -> list(LW). +values(Map) -> + maps:values(Map). + +-spec filter(map_(MA, MB), fun((MA, MB) -> boolean())) -> map_(MA, MB). +filter(Map, Property) -> + maps:filter(Property, Map). + +-spec take(map_(MG, MH), list(MG)) -> map_(MG, MH). +take(Map, Desired_keys) -> + maps:with(Desired_keys, Map). + +-spec merge(map_(MN, MO), map_(MN, MO)) -> map_(MN, MO). +merge(Map, New_entries) -> + maps:merge(Map, New_entries). + +-spec delete(map_(MV, MW), MV) -> map_(MV, MW). +delete(Map, Key) -> + maps:remove(Key, Map). + +-spec drop(map_(NB, NC), list(NB)) -> map_(NB, NC). +drop(Map, Disallowed_keys) -> + case Disallowed_keys of + [] -> + Map; + + [X | Xs] -> + drop(delete(Map, X), Xs) + end. + +-spec do_fold(list({NP, NQ}), NS, fun((NS, NP, NQ) -> NS)) -> NS. +do_fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [{K, V} | Rest] -> + do_fold(Rest, Fun(Initial, K, V), Fun) + end. + +-spec fold(map_(NT, NU), NX, fun((NX, NT, NU) -> NX)) -> NX. +fold(Map, Initial, Fun) -> + _pipe = Map, + _pipe@1 = to_list(_pipe), + do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl new file mode 100644 index 00000000000..04e9e354829 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl @@ -0,0 +1,147 @@ +-module(gleam@option). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, all/1, values/1]). +-export_type([option/1]). + +-type option(FI) :: {some, FI} | none. + +-spec is_some(option(any())) -> boolean(). +is_some(Option) -> + Option /= none. + +-spec is_none(option(any())) -> boolean(). +is_none(Option) -> + Option =:= none. + +-spec to_result(option(FY), GB) -> {ok, FY} | {error, GB}. +to_result(Option, E) -> + case Option of + {some, A} -> + {ok, A}; + + _ -> + {error, E} + end. + +-spec from_result({ok, GE} | {error, any()}) -> option(GE). +from_result(Result) -> + case Result of + {ok, A} -> + {some, A}; + + _ -> + none + end. + +-spec unwrap(option(GJ), GJ) -> GJ. +unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default + end. + +-spec lazy_unwrap(option(GL), fun(() -> GL)) -> GL. +lazy_unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default() + end. + +-spec map(option(GN), fun((GN) -> GP)) -> option(GP). +map(Option, Fun) -> + case Option of + {some, X} -> + {some, Fun(X)}; + + none -> + none + end. + +-spec flatten(option(option(GR))) -> option(GR). +flatten(Option) -> + case Option of + {some, X} -> + X; + + none -> + none + end. + +-spec then(option(GV), fun((GV) -> option(GX))) -> option(GX). +then(Option, Fun) -> + case Option of + {some, X} -> + Fun(X); + + none -> + none + end. + +-spec 'or'(option(HA), option(HA)) -> option(HA). +'or'(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second + end. + +-spec lazy_or(option(HE), fun(() -> option(HE))) -> option(HE). +lazy_or(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second() + end. + +-spec do_all(list(option(FJ)), list(FJ)) -> option(list(FJ)). +do_all(List, Acc) -> + case List of + [] -> + {some, Acc}; + + [X | Rest] -> + Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of + {{some, Values}, {some, Value}} -> + {some, [Value | Values]}; + + {_, _} -> + none + end end, + Accumulate(do_all(Rest, Acc), X) + end. + +-spec all(list(option(FP))) -> option(list(FP)). +all(List) -> + do_all(List, []). + +-spec do_values(list(option(HI)), list(HI)) -> list(HI). +do_values(List, Acc) -> + case List of + [] -> + Acc; + + [X | Xs] -> + Accumulate = fun(Acc@1, Item) -> case Item of + {some, Value} -> + [Value | Acc@1]; + + none -> + Acc@1 + end end, + Accumulate(do_values(Xs, Acc), X) + end. + +-spec values(list(option(HN))) -> list(HN). +values(Options) -> + do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl new file mode 100644 index 00000000000..2f7d2e07100 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl @@ -0,0 +1,75 @@ +-module(gleam@order). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([reverse/1, to_int/1, compare/2, max/2, min/2]). +-export_type([order/0]). + +-type order() :: lt | eq | gt. + +-spec reverse(order()) -> order(). +reverse(Order) -> + case Order of + lt -> + gt; + + eq -> + eq; + + gt -> + lt + end. + +-spec to_int(order()) -> integer(). +to_int(Order) -> + case Order of + lt -> + -1; + + eq -> + 0; + + gt -> + 1 + end. + +-spec compare(order(), order()) -> order(). +compare(A, B) -> + case {A, B} of + {X, Y} when X =:= Y -> + eq; + + {lt, _} -> + lt; + + {eq, gt} -> + lt; + + {_, _} -> + gt + end. + +-spec max(order(), order()) -> order(). +max(A, B) -> + case {A, B} of + {gt, _} -> + gt; + + {eq, lt} -> + eq; + + {_, _} -> + B + end. + +-spec min(order(), order()) -> order(). +min(A, B) -> + case {A, B} of + {lt, _} -> + lt; + + {eq, gt} -> + eq; + + {_, _} -> + B + end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl new file mode 100644 index 00000000000..2659d329392 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl @@ -0,0 +1,33 @@ +-module(gleam@pair). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). + +-spec first({ET, any()}) -> ET. +first(Pair) -> + {A, _} = Pair, + A. + +-spec second({any(), EW}) -> EW. +second(Pair) -> + {_, A} = Pair, + A. + +-spec swap({EX, EY}) -> {EY, EX}. +swap(Pair) -> + {A, B} = Pair, + {B, A}. + +-spec map_first({EZ, FA}, fun((EZ) -> FB)) -> {FB, FA}. +map_first(Pair, Fun) -> + {A, B} = Pair, + {Fun(A), B}. + +-spec map_second({FC, FD}, fun((FD) -> FE)) -> {FC, FE}. +map_second(Pair, Fun) -> + {A, B} = Pair, + {A, Fun(B)}. + +-spec new(FF, FG) -> {FF, FG}. +new(First, Second) -> + {First, Second}. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl new file mode 100644 index 00000000000..6738efd4d7e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl @@ -0,0 +1,121 @@ +-module(gleam@queue). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, reverse/1, pop_back/1, pop_front/1, is_logically_equal/3, is_equal/2]). +-export_type([queue/1]). + +-opaque queue(ECR) :: {queue, list(ECR), list(ECR)}. + +-spec new() -> queue(any()). +new() -> + {queue, [], []}. + +-spec from_list(list(ECU)) -> queue(ECU). +from_list(List) -> + {queue, [], List}. + +-spec to_list(queue(ECX)) -> list(ECX). +to_list(Queue) -> + _pipe = erlang:element(3, Queue), + gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). + +-spec is_empty(queue(any())) -> boolean(). +is_empty(Queue) -> + (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). + +-spec length(queue(any())) -> integer(). +length(Queue) -> + gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( + erlang:element(3, Queue) + ). + +-spec push_back(queue(EDE), EDE) -> queue(EDE). +push_back(Queue, Item) -> + {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. + +-spec push_front(queue(EDH), EDH) -> queue(EDH). +push_front(Queue, Item) -> + {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. + +-spec reverse(queue(EDU)) -> queue(EDU). +reverse(Queue) -> + {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. + +-spec pop_back(queue(EDK)) -> {ok, {EDK, queue(EDK)}} | {error, nil}. +pop_back(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, [], Out} -> + pop_back({queue, gleam@list:reverse(Out), []}); + + {queue, [First | Rest], Out@1} -> + Queue@1 = {queue, Rest, Out@1}, + {ok, {First, Queue@1}} + end. + +-spec pop_front(queue(EDP)) -> {ok, {EDP, queue(EDP)}} | {error, nil}. +pop_front(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, In, []} -> + pop_front({queue, [], gleam@list:reverse(In)}); + + {queue, In@1, [First | Rest]} -> + Queue@1 = {queue, In@1, Rest}, + {ok, {First, Queue@1}} + end. + +-spec check_equal( + list(EDX), + list(EDX), + list(EDX), + list(EDX), + fun((EDX, EDX) -> boolean()) +) -> boolean(). +check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> + case {Xs, X_tail, Ys, Y_tail} of + {[], [], [], []} -> + true; + + {[X | Xs@1], _, [Y | Ys@1], _} -> + case Eq(X, Y) of + false -> + false; + + true -> + check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) + end; + + {[], [_ | _], _, _} -> + check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); + + {_, _, [], [_ | _]} -> + check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); + + {_, _, _, _} -> + false + end. + +-spec is_logically_equal(queue(EEC), queue(EEC), fun((EEC, EEC) -> boolean())) -> boolean(). +is_logically_equal(A, B, Element_is_equal) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + Element_is_equal + ). + +-spec is_equal(queue(EEF), queue(EEF)) -> boolean(). +is_equal(A, B) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + fun(A@1, B@1) -> A@1 =:= B@1 end + ). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl new file mode 100644 index 00000000000..f9c649685ee --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl @@ -0,0 +1,33 @@ +-module(gleam@regex). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([compile/2, from_string/1, check/2, split/2, scan/2]). +-export_type([match/0, compile_error/0, options/0, regex/0]). + +-type match() :: {match, binary(), list(gleam@option:option(binary()))}. + +-type compile_error() :: {compile_error, binary(), integer()}. + +-type options() :: {options, boolean(), boolean()}. + +-type regex() :: any(). + +-spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. +compile(Pattern, Options) -> + gleam_stdlib:compile_regex(Pattern, Options). + +-spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. +from_string(Pattern) -> + compile(Pattern, {options, false, false}). + +-spec check(regex(), binary()) -> boolean(). +check(Regex, Content) -> + gleam_stdlib:regex_check(Regex, Content). + +-spec split(regex(), binary()) -> list(binary()). +split(Regex, String) -> + gleam_stdlib:regex_split(Regex, String). + +-spec scan(regex(), binary()) -> list(match()). +scan(Regex, String) -> + gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl new file mode 100644 index 00000000000..e6c72ebab25 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl @@ -0,0 +1,201 @@ +-module(gleam@result). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, replace/2, replace_error/2, values/1, try_recover/2, partition/1]). + +-spec is_ok({ok, any()} | {error, any()}) -> boolean(). +is_ok(Result) -> + case Result of + {error, _} -> + false; + + {ok, _} -> + true + end. + +-spec is_error({ok, any()} | {error, any()}) -> boolean(). +is_error(Result) -> + case Result of + {ok, _} -> + false; + + {error, _} -> + true + end. + +-spec map({ok, BCT} | {error, BCU}, fun((BCT) -> BCX)) -> {ok, BCX} | + {error, BCU}. +map(Result, Fun) -> + case Result of + {ok, X} -> + {ok, Fun(X)}; + + {error, E} -> + {error, E} + end. + +-spec map_error({ok, BDA} | {error, BDB}, fun((BDB) -> BDE)) -> {ok, BDA} | + {error, BDE}. +map_error(Result, Fun) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, Error} -> + {error, Fun(Error)} + end. + +-spec flatten({ok, {ok, BDH} | {error, BDI}} | {error, BDI}) -> {ok, BDH} | + {error, BDI}. +flatten(Result) -> + case Result of + {ok, X} -> + X; + + {error, Error} -> + {error, Error} + end. + +-spec 'try'({ok, BDP} | {error, BDQ}, fun((BDP) -> {ok, BDT} | {error, BDQ})) -> {ok, + BDT} | + {error, BDQ}. +'try'(Result, Fun) -> + case Result of + {ok, X} -> + Fun(X); + + {error, E} -> + {error, E} + end. + +-spec then({ok, BDY} | {error, BDZ}, fun((BDY) -> {ok, BEC} | {error, BDZ})) -> {ok, + BEC} | + {error, BDZ}. +then(Result, Fun) -> + 'try'(Result, Fun). + +-spec unwrap({ok, BEH} | {error, any()}, BEH) -> BEH. +unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default + end. + +-spec lazy_unwrap({ok, BEL} | {error, any()}, fun(() -> BEL)) -> BEL. +lazy_unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default() + end. + +-spec unwrap_error({ok, any()} | {error, BEQ}, BEQ) -> BEQ. +unwrap_error(Result, Default) -> + case Result of + {ok, _} -> + Default; + + {error, E} -> + E + end. + +-spec unwrap_both({ok, BET} | {error, BET}) -> BET. +unwrap_both(Result) -> + case Result of + {ok, A} -> + A; + + {error, A@1} -> + A@1 + end. + +-spec nil_error({ok, BEW} | {error, any()}) -> {ok, BEW} | {error, nil}. +nil_error(Result) -> + map_error(Result, fun(_) -> nil end). + +-spec 'or'({ok, BFC} | {error, BFD}, {ok, BFC} | {error, BFD}) -> {ok, BFC} | + {error, BFD}. +'or'(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second + end. + +-spec lazy_or({ok, BFK} | {error, BFL}, fun(() -> {ok, BFK} | {error, BFL})) -> {ok, + BFK} | + {error, BFL}. +lazy_or(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second() + end. + +-spec all(list({ok, BFS} | {error, BFT})) -> {ok, list(BFS)} | {error, BFT}. +all(Results) -> + gleam@list:try_map(Results, fun(X) -> X end). + +-spec replace({ok, any()} | {error, BGQ}, BGT) -> {ok, BGT} | {error, BGQ}. +replace(Result, Value) -> + case Result of + {ok, _} -> + {ok, Value}; + + {error, Error} -> + {error, Error} + end. + +-spec replace_error({ok, BGW} | {error, any()}, BHA) -> {ok, BGW} | {error, BHA}. +replace_error(Result, Error) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, _} -> + {error, Error} + end. + +-spec values(list({ok, BHD} | {error, any()})) -> list(BHD). +values(Results) -> + gleam@list:filter_map(Results, fun(R) -> R end). + +-spec try_recover( + {ok, BHJ} | {error, BHK}, + fun((BHK) -> {ok, BHJ} | {error, BHN}) +) -> {ok, BHJ} | {error, BHN}. +try_recover(Result, Fun) -> + case Result of + {ok, Value} -> + {ok, Value}; + + {error, Error} -> + Fun(Error) + end. + +-spec do_partition(list({ok, BGH} | {error, BGI}), list(BGH), list(BGI)) -> {list(BGH), + list(BGI)}. +do_partition(Results, Oks, Errors) -> + case Results of + [] -> + {Oks, Errors}; + + [{ok, A} | Rest] -> + do_partition(Rest, [A | Oks], Errors); + + [{error, E} | Rest@1] -> + do_partition(Rest@1, Oks, [E | Errors]) + end. + +-spec partition(list({ok, BGA} | {error, BGB})) -> {list(BGA), list(BGB)}. +partition(Results) -> + do_partition(Results, [], []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl new file mode 100644 index 00000000000..bc905e1881e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl @@ -0,0 +1,85 @@ +-module(gleam@set). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). +-export_type([set/1]). + +-opaque set(EOC) :: {set, gleam@map:map_(EOC, list(nil))}. + +-spec new() -> set(any()). +new() -> + {set, gleam@map:new()}. + +-spec size(set(any())) -> integer(). +size(Set) -> + gleam@map:size(erlang:element(2, Set)). + +-spec insert(set(EOI), EOI) -> set(EOI). +insert(Set, Member) -> + {set, gleam@map:insert(erlang:element(2, Set), Member, [])}. + +-spec contains(set(EOL), EOL) -> boolean(). +contains(Set, Member) -> + _pipe = erlang:element(2, Set), + _pipe@1 = gleam@map:get(_pipe, Member), + gleam@result:is_ok(_pipe@1). + +-spec delete(set(EON), EON) -> set(EON). +delete(Set, Member) -> + {set, gleam@map:delete(erlang:element(2, Set), Member)}. + +-spec to_list(set(EOQ)) -> list(EOQ). +to_list(Set) -> + gleam@map:keys(erlang:element(2, Set)). + +-spec from_list(list(EOT)) -> set(EOT). +from_list(Members) -> + Map = gleam@list:fold( + Members, + gleam@map:new(), + fun(M, K) -> gleam@map:insert(M, K, []) end + ), + {set, Map}. + +-spec fold(set(EOW), EOY, fun((EOY, EOW) -> EOY)) -> EOY. +fold(Set, Initial, Reducer) -> + gleam@map:fold( + erlang:element(2, Set), + Initial, + fun(A, K, _) -> Reducer(A, K) end + ). + +-spec filter(set(EOZ), fun((EOZ) -> boolean())) -> set(EOZ). +filter(Set, Property) -> + {set, + gleam@map:filter(erlang:element(2, Set), fun(M, _) -> Property(M) end)}. + +-spec drop(set(EPC), list(EPC)) -> set(EPC). +drop(Set, Disallowed) -> + gleam@list:fold(Disallowed, Set, fun delete/2). + +-spec take(set(EPG), list(EPG)) -> set(EPG). +take(Set, Desired) -> + {set, gleam@map:take(erlang:element(2, Set), Desired)}. + +-spec order(set(EPK), set(EPK)) -> {set(EPK), set(EPK)}. +order(First, Second) -> + case gleam@map:size(erlang:element(2, First)) > gleam@map:size( + erlang:element(2, Second) + ) of + true -> + {First, Second}; + + false -> + {Second, First} + end. + +-spec union(set(EPP), set(EPP)) -> set(EPP). +union(First, Second) -> + {Larger, Smaller} = order(First, Second), + fold(Smaller, Larger, fun insert/2). + +-spec intersection(set(EPT), set(EPT)) -> set(EPT). +intersection(First, Second) -> + {Larger, Smaller} = order(First, Second), + take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl new file mode 100644 index 00000000000..275e67ea190 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl @@ -0,0 +1,393 @@ +-module(gleam@string). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([is_empty/1, reverse/1, replace/3, append/2, concat/1, repeat/2, join/2, to_option/1, length/1, lowercase/1, uppercase/1, compare/2, slice/3, drop_left/2, drop_right/2, pad_left/3, pad_right/3, crop/2, contains/2, starts_with/2, ends_with/2, split_once/2, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, first/1, last/1, capitalise/1, utf_codepoint/1, utf_codepoint_to_int/1, inspect/1, byte_size/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1]). +-export_type([direction/0]). + +-type direction() :: leading | trailing | both. + +-spec is_empty(binary()) -> boolean(). +is_empty(Str) -> + Str =:= <<""/utf8>>. + +-spec do_reverse(binary()) -> binary(). +do_reverse(String) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:reverse(_pipe@1), + gleam@string_builder:to_string(_pipe@2). + +-spec reverse(binary()) -> binary(). +reverse(String) -> + do_reverse(String). + +-spec replace(binary(), binary(), binary()) -> binary(). +replace(String, Pattern, Substitute) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), + gleam@string_builder:to_string(_pipe@2). + +-spec append(binary(), binary()) -> binary(). +append(First, Second) -> + _pipe = First, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:append(_pipe@1, Second), + gleam@string_builder:to_string(_pipe@2). + +-spec concat(list(binary())) -> binary(). +concat(Strings) -> + _pipe = Strings, + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1). + +-spec repeat(binary(), integer()) -> binary(). +repeat(String, Times) -> + _pipe = gleam@iterator:repeat(String), + _pipe@1 = gleam@iterator:take(_pipe, Times), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec join(list(binary()), binary()) -> binary(). +join(Strings, Separator) -> + _pipe = Strings, + _pipe@1 = gleam@list:intersperse(_pipe, Separator), + concat(_pipe@1). + +-spec to_option(binary()) -> gleam@option:option(binary()). +to_option(S) -> + case S of + <<""/utf8>> -> + none; + + _ -> + {some, S} + end. + +-spec length(binary()) -> integer(). +length(String) -> + string:length(String). + +-spec lowercase(binary()) -> binary(). +lowercase(String) -> + string:lowercase(String). + +-spec uppercase(binary()) -> binary(). +uppercase(String) -> + string:uppercase(String). + +-spec compare(binary(), binary()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + _ -> + case gleam_stdlib:less_than(A, B) of + true -> + lt; + + _ -> + gt + end + end. + +-spec slice(binary(), integer(), integer()) -> binary(). +slice(String, Idx, Len) -> + case Len < 0 of + true -> + <<""/utf8>>; + + false -> + case Idx < 0 of + true -> + Translated_idx = length(String) + Idx, + case Translated_idx < 0 of + true -> + <<""/utf8>>; + + false -> + string:slice(String, Translated_idx, Len) + end; + + false -> + string:slice(String, Idx, Len) + end + end. + +-spec drop_left(binary(), integer()) -> binary(). +drop_left(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, Num_graphemes, length(String) - Num_graphemes) + end. + +-spec drop_right(binary(), integer()) -> binary(). +drop_right(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, 0, length(String) - Num_graphemes) + end. + +-spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). +padding(Size, Pad_string) -> + Pad_length = length(Pad_string), + Num_pads = case Pad_length of + 0 -> 0; + Gleam@denominator -> Size div Gleam@denominator + end, + Extra = case Pad_length of + 0 -> 0; + Gleam@denominator@1 -> Size rem Gleam@denominator@1 + end, + _pipe = gleam@iterator:repeat(Pad_string), + _pipe@1 = gleam@iterator:take(_pipe, Num_pads), + gleam@iterator:append( + _pipe@1, + gleam@iterator:single(slice(Pad_string, 0, Extra)) + ). + +-spec pad_left(binary(), integer(), binary()) -> binary(). +pad_left(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = padding(To_pad_length, Pad_string), + _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec pad_right(binary(), integer(), binary()) -> binary(). +pad_right(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = gleam@iterator:single(String), + _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec do_crop(binary(), binary()) -> binary(). +do_crop(String, Substring) -> + _pipe = String, + _pipe@1 = string:find(_pipe, Substring), + _pipe@2 = gleam@dynamic:string(_pipe@1), + gleam@result:unwrap(_pipe@2, String). + +-spec crop(binary(), binary()) -> binary(). +crop(String, Substring) -> + do_crop(String, Substring). + +-spec do_contains(binary(), binary()) -> boolean(). +do_contains(Haystack, Needle) -> + _pipe = Haystack, + _pipe@1 = string:find(_pipe, Needle), + _pipe@2 = gleam@dynamic:bit_string(_pipe@1), + gleam@result:is_ok(_pipe@2). + +-spec contains(binary(), binary()) -> boolean(). +contains(Haystack, Needle) -> + do_contains(Haystack, Needle). + +-spec starts_with(binary(), binary()) -> boolean(). +starts_with(String, Prefix) -> + gleam_stdlib:string_starts_with(String, Prefix). + +-spec ends_with(binary(), binary()) -> boolean(). +ends_with(String, Suffix) -> + gleam_stdlib:string_ends_with(String, Suffix). + +-spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +do_split_once(X, Substring) -> + case string:split(X, Substring) of + [First, Rest] -> + {ok, {First, Rest}}; + + _ -> + {error, nil} + end. + +-spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +split_once(X, Substring) -> + do_split_once(X, Substring). + +-spec do_trim(binary()) -> binary(). +do_trim(String) -> + string:trim(String, both). + +-spec trim(binary()) -> binary(). +trim(String) -> + do_trim(String). + +-spec do_trim_left(binary()) -> binary(). +do_trim_left(String) -> + string:trim(String, leading). + +-spec trim_left(binary()) -> binary(). +trim_left(String) -> + do_trim_left(String). + +-spec do_trim_right(binary()) -> binary(). +do_trim_right(String) -> + string:trim(String, trailing). + +-spec trim_right(binary()) -> binary(). +trim_right(String) -> + do_trim_right(String). + +-spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. +pop_grapheme(String) -> + gleam_stdlib:string_pop_grapheme(String). + +-spec first(binary()) -> {ok, binary()} | {error, nil}. +first(S) -> + case pop_grapheme(S) of + {ok, {First, _}} -> + {ok, First}; + + {error, E} -> + {error, E} + end. + +-spec last(binary()) -> {ok, binary()} | {error, nil}. +last(S) -> + case pop_grapheme(S) of + {ok, {First, <<""/utf8>>}} -> + {ok, First}; + + {ok, {_, Rest}} -> + {ok, slice(Rest, -1, 1)}; + + {error, E} -> + {error, E} + end. + +-spec capitalise(binary()) -> binary(). +capitalise(S) -> + case pop_grapheme(S) of + {ok, {First, Rest}} -> + append(uppercase(First), lowercase(Rest)); + + _ -> + <<""/utf8>> + end. + +-spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. +utf_codepoint(Value) -> + case Value of + I when I > 1114111 -> + {error, nil}; + + 65534 -> + {error, nil}; + + 65535 -> + {error, nil}; + + I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> + {error, nil}; + + I@2 -> + {ok, gleam_stdlib:identity(I@2)} + end. + +-spec utf_codepoint_to_int(integer()) -> integer(). +utf_codepoint_to_int(Cp) -> + gleam_stdlib:identity(Cp). + +-spec inspect(any()) -> binary(). +inspect(Term) -> + _pipe = gleam_stdlib:inspect(Term), + gleam@string_builder:to_string(_pipe). + +-spec byte_size(binary()) -> integer(). +byte_size(String) -> + erlang:byte_size(String). + +-spec do_to_graphemes(binary(), list(binary())) -> list(binary()). +do_to_graphemes(String, Acc) -> + case pop_grapheme(String) of + {ok, {Grapheme, Rest}} -> + do_to_graphemes(Rest, [Grapheme | Acc]); + + _ -> + Acc + end. + +-spec to_graphemes(binary()) -> list(binary()). +to_graphemes(String) -> + _pipe = do_to_graphemes(String, []), + gleam@list:reverse(_pipe). + +-spec split(binary(), binary()) -> list(binary()). +split(X, Substring) -> + case Substring of + <<""/utf8>> -> + to_graphemes(X); + + _ -> + _pipe = X, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), + gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) + end. + +-spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). +do_to_utf_codepoints_impl(Bit_string, Acc) -> + case Bit_string of + <> -> + do_to_utf_codepoints_impl(Rest, [First | Acc]); + + <<>> -> + Acc + end. + +-spec do_to_utf_codepoints(binary()) -> list(integer()). +do_to_utf_codepoints(String) -> + _pipe = do_to_utf_codepoints_impl(gleam@bit_string:from_string(String), []), + gleam@list:reverse(_pipe). + +-spec to_utf_codepoints(binary()) -> list(integer()). +to_utf_codepoints(String) -> + do_to_utf_codepoints(String). + +-spec do_from_utf_codepoints_impl(list(integer()), bitstring()) -> bitstring(). +do_from_utf_codepoints_impl(Utf_codepoints, Acc) -> + case Utf_codepoints of + [First | Rest] -> + do_from_utf_codepoints_impl(Rest, <>); + + [] -> + Acc + end. + +-spec do_from_utf_codepoints(list(integer())) -> binary(). +do_from_utf_codepoints(Utf_codepoints) -> + _assert_subject = begin + _pipe = do_from_utf_codepoints_impl( + Utf_codepoints, + gleam@bit_string:from_string(<<""/utf8>>) + ), + gleam@bit_string:to_string(_pipe) + end, + {ok, String} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/string"/utf8>>, + function => <<"do_from_utf_codepoints"/utf8>>, + line => 860}) + end, + String. + +-spec from_utf_codepoints(list(integer())) -> binary(). +from_utf_codepoints(Utf_codepoints) -> + do_from_utf_codepoints(Utf_codepoints). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl new file mode 100644 index 00000000000..47364425ad7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl @@ -0,0 +1,91 @@ +-module(gleam@string_builder). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, join/2, to_string/1, byte_size/1, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). +-export_type([direction/0, string_builder/0]). + +-type direction() :: all. + +-type string_builder() :: any(). + +-spec prepend_builder(string_builder(), string_builder()) -> string_builder(). +prepend_builder(Builder, Prefix) -> + gleam_stdlib:iodata_append(Prefix, Builder). + +-spec append_builder(string_builder(), string_builder()) -> string_builder(). +append_builder(Builder, Suffix) -> + gleam_stdlib:iodata_append(Builder, Suffix). + +-spec new() -> string_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec from_strings(list(binary())) -> string_builder(). +from_strings(Strings) -> + gleam_stdlib:identity(Strings). + +-spec concat(list(string_builder())) -> string_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec from_string(binary()) -> string_builder(). +from_string(String) -> + gleam_stdlib:identity(String). + +-spec prepend(string_builder(), binary()) -> string_builder(). +prepend(Builder, Prefix) -> + append_builder(from_string(Prefix), Builder). + +-spec append(string_builder(), binary()) -> string_builder(). +append(Builder, Second) -> + append_builder(Builder, from_string(Second)). + +-spec join(list(string_builder()), binary()) -> string_builder(). +join(Builders, Sep) -> + _pipe = Builders, + _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), + concat(_pipe@1). + +-spec to_string(string_builder()) -> binary(). +to_string(Builder) -> + unicode:characters_to_binary(Builder). + +-spec byte_size(string_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). + +-spec lowercase(string_builder()) -> string_builder(). +lowercase(Builder) -> + string:lowercase(Builder). + +-spec uppercase(string_builder()) -> string_builder(). +uppercase(Builder) -> + string:uppercase(Builder). + +-spec reverse(string_builder()) -> string_builder(). +reverse(Builder) -> + string:reverse(Builder). + +-spec do_split(string_builder(), binary()) -> list(string_builder()). +do_split(Iodata, Pattern) -> + string:split(Iodata, Pattern, all). + +-spec split(string_builder(), binary()) -> list(string_builder()). +split(Iodata, Pattern) -> + do_split(Iodata, Pattern). + +-spec do_replace(string_builder(), binary(), binary()) -> string_builder(). +do_replace(Iodata, Pattern, Substitute) -> + string:replace(Iodata, Pattern, Substitute, all). + +-spec replace(string_builder(), binary(), binary()) -> string_builder(). +replace(Builder, Pattern, Substitute) -> + do_replace(Builder, Pattern, Substitute). + +-spec is_equal(string_builder(), string_builder()) -> boolean(). +is_equal(A, B) -> + string:equal(A, B). + +-spec is_empty(string_builder()) -> boolean(). +is_empty(Builder) -> + string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl new file mode 100644 index 00000000000..692193fd0c6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl @@ -0,0 +1,255 @@ +-module(gleam@uri). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_string/1, origin/1, parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, merge/2]). +-export_type([uri/0]). + +-type uri() :: {uri, + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(integer()), + binary(), + gleam@option:option(binary()), + gleam@option:option(binary())}. + +-spec to_string(uri()) -> binary(). +to_string(Uri) -> + Parts = case erlang:element(8, Uri) of + {some, Fragment} -> + [<<"#"/utf8>>, Fragment]; + + _ -> + [] + end, + Parts@1 = case erlang:element(7, Uri) of + {some, Query} -> + [<<"?"/utf8>>, Query | Parts]; + + _ -> + Parts + end, + Parts@2 = [erlang:element(6, Uri) | Parts@1], + Parts@3 = case {erlang:element(4, Uri), + gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of + {{some, Host}, false} when Host =/= <<""/utf8>> -> + [<<"/"/utf8>> | Parts@2]; + + {_, _} -> + Parts@2 + end, + Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of + {{some, _}, {some, Port}} -> + [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; + + {_, _} -> + Parts@3 + end, + Parts@5 = case {erlang:element(2, Uri), + erlang:element(3, Uri), + erlang:element(4, Uri)} of + {{some, S}, {some, U}, {some, H}} -> + [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; + + {{some, S@1}, none, {some, H@1}} -> + [S@1, <<"://"/utf8>>, H@1 | Parts@4]; + + {{some, S@2}, {some, _}, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {{some, S@2}, none, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {none, none, {some, H@2}} -> + [<<"//"/utf8>>, H@2 | Parts@4]; + + {none, {some, _}, none} -> + Parts@4; + + {none, none, none} -> + Parts@4 + end, + gleam@string:concat(Parts@5). + +-spec origin(uri()) -> {ok, binary()} | {error, nil}. +origin(Uri) -> + {uri, Scheme, _, Host, Port, _, _, _} = Uri, + case Scheme of + {some, <<"https"/utf8>>} when Port =:= {some, 443} -> + Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin)}; + + {some, <<"http"/utf8>>} when Port =:= {some, 80} -> + Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin@1)}; + + {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> + Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, + {ok, to_string(Origin@2)}; + + _ -> + {error, nil} + end. + +-spec drop_last(list(EJD)) -> list(EJD). +drop_last(Elements) -> + gleam@list:take(Elements, gleam@list:length(Elements) - 1). + +-spec join_segments(list(binary())) -> binary(). +join_segments(Segments) -> + gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). + +-spec parse(binary()) -> {ok, uri()} | {error, nil}. +parse(Uri_string) -> + gleam_stdlib:uri_parse(Uri_string). + +-spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. +parse_query(Query) -> + gleam_stdlib:parse_query(Query). + +-spec percent_encode(binary()) -> binary(). +percent_encode(Value) -> + gleam_stdlib:percent_encode(Value). + +-spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). +query_pair(Pair) -> + gleam@string_builder:from_strings( + [percent_encode(erlang:element(1, Pair)), + <<"="/utf8>>, + percent_encode(erlang:element(2, Pair))] + ). + +-spec query_to_string(list({binary(), binary()})) -> binary(). +query_to_string(Query) -> + _pipe = Query, + _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), + _pipe@2 = gleam@list:intersperse( + _pipe@1, + gleam@string_builder:from_string(<<"&"/utf8>>) + ), + _pipe@3 = gleam@string_builder:concat(_pipe@2), + gleam@string_builder:to_string(_pipe@3). + +-spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. +percent_decode(Value) -> + gleam_stdlib:percent_decode(Value). + +-spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). +do_remove_dot_segments(Input, Accumulator) -> + case Input of + [] -> + gleam@list:reverse(Accumulator); + + [Segment | Rest] -> + Accumulator@5 = case {Segment, Accumulator} of + {<<""/utf8>>, Accumulator@1} -> + Accumulator@1; + + {<<"."/utf8>>, Accumulator@2} -> + Accumulator@2; + + {<<".."/utf8>>, []} -> + []; + + {<<".."/utf8>>, [_ | Accumulator@3]} -> + Accumulator@3; + + {Segment@1, Accumulator@4} -> + [Segment@1 | Accumulator@4] + end, + do_remove_dot_segments(Rest, Accumulator@5) + end. + +-spec remove_dot_segments(list(binary())) -> list(binary()). +remove_dot_segments(Input) -> + do_remove_dot_segments(Input, []). + +-spec path_segments(binary()) -> list(binary()). +path_segments(Path) -> + remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). + +-spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. +merge(Base, Relative) -> + case Base of + {uri, {some, _}, _, {some, _}, _, _, _, _} -> + case Relative of + {uri, _, _, {some, _}, _, _, _, _} -> + Path = begin + _pipe = gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ), + _pipe@1 = remove_dot_segments(_pipe), + join_segments(_pipe@1) + end, + Resolved = {uri, + gleam@option:'or'( + erlang:element(2, Relative), + erlang:element(2, Base) + ), + none, + erlang:element(4, Relative), + gleam@option:'or'( + erlang:element(5, Relative), + erlang:element(5, Base) + ), + Path, + erlang:element(7, Relative), + erlang:element(8, Relative)}, + {ok, Resolved}; + + {uri, none, _, none, _, _, _, _} -> + {New_path, New_query} = case erlang:element(6, Relative) of + <<""/utf8>> -> + {erlang:element(6, Base), + gleam@option:'or'( + erlang:element(7, Relative), + erlang:element(7, Base) + )}; + + _ -> + Path_segments = case gleam@string:starts_with( + erlang:element(6, Relative), + <<"/"/utf8>> + ) of + true -> + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ); + + false -> + _pipe@2 = gleam@string:split( + erlang:element(6, Base), + <<"/"/utf8>> + ), + _pipe@3 = drop_last(_pipe@2), + gleam@list:append( + _pipe@3, + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ) + ) + end, + Path@1 = begin + _pipe@4 = Path_segments, + _pipe@5 = remove_dot_segments(_pipe@4), + join_segments(_pipe@5) + end, + {Path@1, erlang:element(7, Relative)} + end, + Resolved@1 = {uri, + erlang:element(2, Base), + none, + erlang:element(4, Base), + erlang:element(5, Base), + New_path, + New_query, + erlang:element(8, Relative)}, + {ok, Resolved@1} + end; + + _ -> + {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src new file mode 100644 index 00000000000..ed0fcac3f46 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src @@ -0,0 +1,28 @@ +{application, gleam_stdlib, [ + {vsn, "0.29.2"}, + {applications, []}, + {description, "A standard library for the Gleam programming language"}, + {modules, [gleam@base, + gleam@bit_builder, + gleam@bit_string, + gleam@bool, + gleam@dynamic, + gleam@float, + gleam@function, + gleam@int, + gleam@io, + gleam@iterator, + gleam@list, + gleam@map, + gleam@option, + gleam@order, + gleam@pair, + gleam@queue, + gleam@regex, + gleam@result, + gleam@set, + gleam@string, + gleam@string_builder, + gleam@uri]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl new file mode 100644 index 00000000000..6967cf4a607 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl @@ -0,0 +1,441 @@ +-module(gleam_stdlib). + +-export([map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, + decode_float/1, decode_list/1, decode_option/2, + decode_field/2, parse_int/1, parse_float/1, less_than/2, + string_pop_grapheme/1, string_starts_with/2, wrap_list/1, + string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, + bit_string_int_to_u32/1, bit_string_int_from_u32/1, decode_result/1, + bit_string_slice/3, decode_bit_string/1, compile_regex/2, regex_scan/2, + percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, + base_decode64/1, parse_query/1, bit_string_concat/1, size_of_tuple/1, + decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, + decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, + print/1, println/1, print_error/1, println_error/1, inspect/1, + float_to_string/1, int_from_base_string/2]). + +%% Taken from OTP's uri_string module +-define(DEC2HEX(X), + if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; + ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 + end). + +%% Taken from OTP's uri_string module +-define(HEX2DEC(X), + if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; + ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; + ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 + end). + +map_get(Map, Key) -> + case maps:find(Key, Map) of + error -> {error, nil}; + OkFound -> OkFound + end. + +iodata_append(Iodata, String) -> [Iodata, String]. + +identity(X) -> X. + +decode_error_msg(Expected, Data) when is_binary(Expected) -> + decode_error(Expected, classify_dynamic(Data)). +decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> + {error, [{decode_error, Expected, Got, []}]}. + +classify_dynamic(nil) -> <<"Nil">>; +classify_dynamic(X) when is_atom(X) -> <<"Atom">>; +classify_dynamic(X) when is_binary(X) -> <<"String">>; +classify_dynamic(X) when is_bitstring(X) -> <<"BitString">>; +classify_dynamic(X) when is_integer(X) -> <<"Int">>; +classify_dynamic(X) when is_float(X) -> <<"Float">>; +classify_dynamic(X) when is_list(X) -> <<"List">>; +classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; +classify_dynamic(X) when is_map(X) -> <<"Map">>; +classify_dynamic(X) when is_tuple(X) -> + iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); +classify_dynamic(X) when + is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse + is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse + is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse + is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse + is_function(X, 12) -> <<"Function">>; +classify_dynamic(_) -> <<"Some other type">>. + +decode_map(Data) when is_map(Data) -> {ok, Data}; +decode_map(Data) -> decode_error_msg(<<"Map">>, Data). + +decode_bit_string(Data) when is_bitstring(Data) -> {ok, Data}; +decode_bit_string(Data) -> decode_error_msg(<<"BitString">>, Data). + +decode_int(Data) when is_integer(Data) -> {ok, Data}; +decode_int(Data) -> decode_error_msg(<<"Int">>, Data). + +decode_float(Data) when is_float(Data) -> {ok, Data}; +decode_float(Data) -> decode_error_msg(<<"Float">>, Data). + +decode_bool(Data) when is_boolean(Data) -> {ok, Data}; +decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). + +decode_list(Data) when is_list(Data) -> {ok, Data}; +decode_list(Data) -> decode_error_msg(<<"List">>, Data). + +decode_field(Data, Key) when is_map(Data) -> + case Data of + #{Key := Value} -> {ok, {some, Value}}; + _ -> + {ok, none} + end; +decode_field(Data, _) -> + decode_error_msg(<<"Map">>, Data). + +size_of_tuple(Data) -> tuple_size(Data). + +tuple_get(_tup, Index) when Index < 0 -> {error, nil}; +tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; +tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. + +decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; +decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). + +decode_tuple2({_,_} = A) -> {ok, A}; +decode_tuple2([A,B]) -> {ok, {A,B}}; +decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). + +decode_tuple3({_,_,_} = A) -> {ok, A}; +decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; +decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). + +decode_tuple4({_,_,_,_} = A) -> {ok, A}; +decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; +decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). + +decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; +decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; +decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). + +decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; +decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; +decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). + +decode_option(Term, F) -> + Decode = fun(Inner) -> + case F(Inner) of + {ok, Decoded} -> {ok, {some, Decoded}}; + Error -> Error + end + end, + case Term of + undefined -> {ok, none}; + error -> {ok, none}; + null -> {ok, none}; + none -> {ok, none}; + nil -> {ok, none}; + {some, Inner} -> Decode(Inner); + _ -> Decode(Term) + end. + +decode_result(Term) -> + case Term of + {ok, Inner} -> {ok, {ok, Inner}}; + ok -> {ok, {ok, nil}}; + {error, Inner} -> {ok, {error, Inner}}; + error -> {ok, {error, nil}}; + _ -> decode_error_msg(<<"Result">>, Term) + end. + +int_from_base_string(String, Base) -> + case catch binary_to_integer(String, Base) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_int(String) -> + case catch binary_to_integer(String) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_float(String) -> + case catch binary_to_float(String) of + Float when is_float(Float) -> {ok, Float}; + _ -> {error, nil} + end. + +less_than(Lhs, Rhs) -> + Lhs < Rhs. + +string_starts_with(_, <<>>) -> true; +string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; +string_starts_with(String, Prefix) -> + PrefixSize = byte_size(Prefix), + Prefix == binary_part(String, 0, PrefixSize). + +string_ends_with(_, <<>>) -> true; +string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; +string_ends_with(String, Suffix) -> + SuffixSize = byte_size(Suffix), + Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). + +string_pad(String, Length, Dir, PadString) -> + Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), + case unicode:characters_to_binary(Chars) of + Bin when is_binary(Bin) -> Bin; + Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) + end. + +string_pop_grapheme(String) -> + case string:next_grapheme(String) of + [ Next | Rest ] -> + {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; + _ -> {error, nil} + end. + +bit_string_concat(BitStrings) -> + list_to_bitstring(BitStrings). + +bit_string_slice(Bin, Pos, Len) -> + try {ok, binary:part(Bin, Pos, Len)} + catch error:badarg -> {error, nil} + end. + +bit_string_int_to_u32(I) when 0 =< I, I < 4294967296 -> + {ok, <>}; +bit_string_int_to_u32(_) -> + {error, nil}. + +bit_string_int_from_u32(<>) -> + {ok, I}; +bit_string_int_from_u32(_) -> + {error, nil}. + +compile_regex(String, Options) -> + {options, Caseless, Multiline} = Options, + OptionsList = [ + unicode, + ucp, + Caseless andalso caseless, + Multiline andalso multiline + ], + FilteredOptions = [Option || Option <- OptionsList, Option /= false], + case re:compile(String, FilteredOptions) of + {ok, MP} -> {ok, MP}; + {error, {Str, Pos}} -> + {error, {compile_error, unicode:characters_to_binary(Str), Pos}} + end. + +regex_check(Regex, String) -> + re:run(String, Regex) /= nomatch. + +regex_split(Regex, String) -> + re:split(String, Regex). + +regex_submatches(_, {-1, 0}) -> none; +regex_submatches(String, {Start, Length}) -> + BinarySlice = binary:part(String, {Start, Length}), + case string:is_empty(binary_to_list(BinarySlice)) of + true -> none; + false -> {some, BinarySlice} + end. + +regex_matches(String, [{Start, Length} | Submatches]) -> + Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), + {match, binary:part(String, Start, Length), Submatches1}. + +regex_scan(Regex, String) -> + case re:run(String, Regex, [global]) of + {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); + nomatch -> [] + end. + +base_decode64(S) -> + try {ok, base64:decode(S)} + catch error:badarith -> {error, nil} + end. + +wrap_list(X) when is_list(X) -> X; +wrap_list(X) -> [X]. + +parse_query(Query) -> + case uri_string:dissect_query(Query) of + {error, _, _} -> {error, nil}; + Pairs -> + Pairs1 = lists:map(fun + ({K, true}) -> {K, <<"">>}; + (Pair) -> Pair + end, Pairs), + {ok, Pairs1} + end. + +percent_encode(B) -> percent_encode(B, <<>>). +percent_encode(<<>>, Acc) -> + Acc; +percent_encode(<>, Acc) -> + case percent_ok(H) of + true -> + percent_encode(T, <>); + false -> + <> = <>, + percent_encode(T, <>) + end. + +percent_decode(Cs) -> percent_decode(Cs, <<>>). +percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> + case is_hex_digit(C0) andalso is_hex_digit(C1) of + true -> + B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), + percent_decode(Cs, <>); + false -> + {error, nil} + end; +percent_decode(<>, Acc) -> + percent_decode(Cs, <>); +percent_decode(<<>>, Acc) -> + check_utf8(Acc). + +percent_ok($!) -> true; +percent_ok($$) -> true; +percent_ok($') -> true; +percent_ok($() -> true; +percent_ok($)) -> true; +percent_ok($*) -> true; +percent_ok($+) -> true; +percent_ok($-) -> true; +percent_ok($.) -> true; +percent_ok($_) -> true; +percent_ok($~) -> true; +percent_ok(C) when $0 =< C, C =< $9 -> true; +percent_ok(C) when $A =< C, C =< $Z -> true; +percent_ok(C) when $a =< C, C =< $z -> true; +percent_ok(_) -> false. + +is_hex_digit(C) -> + ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). + +check_utf8(Cs) -> + case unicode:characters_to_list(Cs) of + {incomplete, _, _} -> {error, nil}; + {error, _, _} -> {error, nil}; + _ -> {ok, Cs} + end. + +uri_parse(String) -> + case uri_string:parse(String) of + {error, _, _} -> {error, nil}; + Uri -> + {ok, {uri, + maps_get_optional(Uri, scheme), + maps_get_optional(Uri, userinfo), + maps_get_optional(Uri, host), + maps_get_optional(Uri, port), + maps_get_or(Uri, path, <<>>), + maps_get_optional(Uri, query), + maps_get_optional(Uri, fragment) + }} + end. + +maps_get_optional(Map, Key) -> + try {some, maps:get(Key, Map)} + catch _:_ -> none + end. + +maps_get_or(Map, Key, Default) -> + try maps:get(Key, Map) + catch _:_ -> Default + end. + +print(String) -> + io:put_chars(String), + nil. + +println(String) -> + io:put_chars([String, $\n]), + nil. + +print_error(String) -> + io:put_chars(standard_error, String), + nil. + +println_error(String) -> + io:put_chars(standard_error, [String, $\n]), + nil. + +inspect(true) -> + "True"; +inspect(false) -> + "False"; +inspect(Any) when is_atom(Any) -> + lists:map( + fun(Part) -> + [Head | Tail] = string:next_grapheme(unicode:characters_to_binary(Part)), + [string:uppercase([Head]), Tail] + end, + re:split(erlang:atom_to_list(Any), "_+", [{return, iodata}]) + ); +inspect(Any) when is_integer(Any) -> + erlang:integer_to_list(Any); +inspect(Any) when is_float(Any) -> + io_lib_format:fwrite_g(Any); +inspect(Binary) when is_binary(Binary) -> + case inspect_maybe_utf8_string(Binary, <<>>) of + {ok, InspectedUtf8String} -> InspectedUtf8String; + {error, not_a_utf8_string} -> + Segments = [erlang:integer_to_list(X) || <> <= Binary], + ["<<", lists:join(", ", Segments), ">>"] + end; +inspect(List) when is_list(List) -> + case inspect_list(List) of + {proper, Elements} -> ["[", Elements, "]"]; + {improper, Elements} -> ["//erl([", Elements, "])"] + end; +inspect(Any) when is_tuple(Any) % Record constructors + andalso is_atom(element(1, Any)) + andalso element(1, Any) =/= false + andalso element(1, Any) =/= true + andalso element(1, Any) =/= nil +-> + [Atom | ArgsList] = erlang:tuple_to_list(Any), + Args = lists:join(<<", ">>, + lists:map(fun inspect/1, ArgsList) + ), + [inspect(Atom), "(", Args, ")"]; +inspect(Tuple) when is_tuple(Tuple) -> + Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), + ["#(", lists:join(", ", Elements), ")"]; +inspect(Any) when is_function(Any) -> + {arity, Arity} = erlang:fun_info(Any, arity), + ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), + Args = lists:join(<<", ">>, + lists:map(fun(Arg) -> <> end, ArgsAsciiCodes) + ), + ["//fn(", Args, ") { ... }"]; +inspect(Any) -> + ["//erl(", io_lib:format("~p", [Any]), ")"]. + +inspect_list([]) -> + {proper, []}; +inspect_list([Head]) -> + {proper, [inspect(Head)]}; +inspect_list([First | Rest]) when is_list(Rest) -> + {Kind, Inspected} = inspect_list(Rest), + {Kind, [inspect(First), <<", ">> | Inspected]}; +inspect_list([First | ImproperTail]) -> + {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. + +inspect_maybe_utf8_string(Binary, Acc) -> + case Binary of + <<>> -> {ok, <<$", Acc/binary, $">>}; + <> -> + Escaped = case Head of + $" -> <<$\\, $">>; + $\\ -> <<$\\, $\\>>; + $\r -> <<$\\, $r>>; + $\n -> <<$\\, $n>>; + $\t -> <<$\\, $t>>; + Other -> <> + end, + inspect_maybe_utf8_string(Rest, <>); + _ -> {error, not_a_utf8_string} + end. + +float_to_string(Float) when is_float(Float) -> + erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs new file mode 100644 index 00000000000..4fd06d9b563 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs @@ -0,0 +1,739 @@ +import { + BitString, + Error, + List, + Ok, + Result, + UtfCodepoint, + inspect, + stringBits, + toBitString, +} from "./gleam.mjs"; +import { + CompileError as RegexCompileError, + Match as RegexMatch, +} from "./gleam/regex.mjs"; +import { DecodeError } from "./gleam/dynamic.mjs"; +import { Some, None } from "./gleam/option.mjs"; +import PMap from "./persistent-hash-map.mjs"; + +const Nil = undefined; +const NOT_FOUND = {}; + +export function identity(x) { + return x; +} + +export function parse_int(value) { + if (/^[-+]?(\d+)$/.test(value)) { + return new Ok(parseInt(value)); + } else { + return new Error(Nil); + } +} + +export function parse_float(value) { + if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { + return new Ok(parseFloat(value)); + } else { + return new Error(Nil); + } +} + +export function to_string(term) { + return term.toString(); +} + +export function float_to_string(float) { + const string = float.toString(); + if (string.indexOf(".") >= 0) { + return string; + } else { + return string + ".0"; + } +} + +export function int_to_base_string(int, base) { + return int.toString(base).toUpperCase(); +} + +const int_base_patterns = { + 2: /[^0-1]/, + 3: /[^0-2]/, + 4: /[^0-3]/, + 5: /[^0-4]/, + 6: /[^0-5]/, + 7: /[^0-6]/, + 8: /[^0-7]/, + 9: /[^0-8]/, + 10: /[^0-9]/, + 11: /[^0-9a]/, + 12: /[^0-9a-b]/, + 13: /[^0-9a-c]/, + 14: /[^0-9a-d]/, + 15: /[^0-9a-e]/, + 16: /[^0-9a-f]/, + 17: /[^0-9a-g]/, + 18: /[^0-9a-h]/, + 19: /[^0-9a-i]/, + 20: /[^0-9a-j]/, + 21: /[^0-9a-k]/, + 22: /[^0-9a-l]/, + 23: /[^0-9a-m]/, + 24: /[^0-9a-n]/, + 25: /[^0-9a-o]/, + 26: /[^0-9a-p]/, + 27: /[^0-9a-q]/, + 28: /[^0-9a-r]/, + 29: /[^0-9a-s]/, + 30: /[^0-9a-t]/, + 31: /[^0-9a-u]/, + 32: /[^0-9a-v]/, + 33: /[^0-9a-w]/, + 34: /[^0-9a-x]/, + 35: /[^0-9a-y]/, + 36: /[^0-9a-z]/, +}; + +export function int_from_base_string(string, base) { + if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { + return new Error(Nil); + } + + const result = parseInt(string, base); + + if (isNaN(result)) { + return new Error(Nil); + } + + return new Ok(result); +} + +export function string_replace(string, target, substitute) { + if (typeof string.replaceAll !== "undefined") { + return string.replaceAll(target, substitute); + } + // Fallback for older Node.js versions: + // 1. + // 2. + // TODO: This fallback could be remove once Node.js 14 is EOL + // aka on or after 2024-04-30 + return string.replace( + // $& means the whole matched string + new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), + substitute + ); +} + +export function string_reverse(string) { + return [...string].reverse().join(""); +} + +export function string_length(string) { + if (string === "") { + return 0; + } + const iterator = graphemes_iterator(string); + if (iterator) { + let i = 0; + for (const _ of iterator) { + i++; + } + return i; + } else { + return string.match(/./gsu).length; + } +} + +export function graphemes(string) { + return List.fromArray( + Array.from(graphemes_iterator(string)).map((item) => item.segment) + ); +} + +function graphemes_iterator(string) { + if (Intl && Intl.Segmenter) { + return new Intl.Segmenter().segment(string)[Symbol.iterator](); + } +} + +export function pop_grapheme(string) { + let first; + const iterator = graphemes_iterator(string); + if (iterator) { + first = iterator.next().value?.segment; + } else { + first = string.match(/./su)?.[0]; + } + if (first) { + return new Ok([first, string.slice(first.length)]); + } else { + return new Error(Nil); + } +} + +export function lowercase(string) { + return string.toLowerCase(); +} + +export function uppercase(string) { + return string.toUpperCase(); +} + +export function less_than(a, b) { + return a < b; +} + +export function add(a, b) { + return a + b; +} + +export function equal(a, b) { + return a === b; +} + +export function split(xs, pattern) { + return List.fromArray(xs.split(pattern)); +} + +export function join(xs) { + return xs.toArray().join(""); +} + +export function length(data) { + return data.length; +} + +export function crop_string(string, substring) { + return string.substring(string.indexOf(substring)); +} + +export function index_of(haystack, needle) { + return haystack.indexOf(needle) | 0; +} + +export function starts_with(haystack, needle) { + return haystack.startsWith(needle); +} + +export function ends_with(haystack, needle) { + return haystack.endsWith(needle); +} + +export function split_once(haystack, needle) { + const index = haystack.indexOf(needle); + if (index >= 0) { + const before = haystack.slice(0, index); + const after = haystack.slice(index + needle.length); + return new Ok([before, after]); + } else { + return new Error(Nil); + } +} + +export function trim(string) { + return string.trim(); +} + +export function trim_left(string) { + return string.trimLeft(); +} + +export function trim_right(string) { + return string.trimRight(); +} + +export function bit_string_from_string(string) { + return toBitString([stringBits(string)]); +} + +export function bit_string_concat(bit_strings) { + return toBitString(bit_strings.toArray().map((b) => b.buffer)); +} + +export function console_log(term) { + console.log(term); +} + +export function console_error(term) { + console.error(term); +} + +export function crash(message) { + throw new globalThis.Error(message); +} + +export function bit_string_to_string(bit_string) { + try { + const decoder = new TextDecoder("utf-8", { fatal: true }); + return new Ok(decoder.decode(bit_string.buffer)); + } catch (_error) { + return new Error(Nil); + } +} + +export function print(string) { + if (typeof process === "object") { + process.stdout.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.log(string); // We're in a browser. Newlines are mandated + } +} + +export function print_error(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.error(string); // We're in a browser. Newlines are mandated + } +} + +export function print_debug(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` + } else { + console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) + } +} + +export function ceiling(float) { + return Math.ceil(float); +} + +export function floor(float) { + return Math.floor(float); +} + +export function round(float) { + return Math.round(float); +} + +export function truncate(float) { + return Math.trunc(float); +} + +export function power(base, exponent) { + // It is checked in Gleam that: + // - The base is non-negative and that the exponent is not fractional. + // - The base is non-zero and the exponent is non-negative (otherwise + // the result will essentially be division by zero). + // It can thus be assumed that valid input is passed to the Math.pow + // function and a NaN or Infinity value will not be produced. + return Math.pow(base, exponent); +} + +export function random_uniform() { + const random_uniform_result = Math.random(); + // With round-to-nearest-even behavior, the ranges claimed for the functions below + // (excluding the one for Math.random() itself) aren't exact. + // If extremely large bounds are chosen (2^53 or higher), + // it's possible in extremely rare cases to calculate the usually-excluded upper bound. + // Note that as numbers in JavaScript are IEEE 754 floating point numbers + // See: + // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: + if (random_uniform_result === 1.0) { + return random_uniform(); + } + return random_uniform_result; +} + +export function bit_string_slice(bits, position, length) { + const start = Math.min(position, position + length); + const end = Math.max(position, position + length); + if (start < 0 || end > bits.length) return new Error(Nil); + const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); + return new Ok(new BitString(buffer)); +} + +export function codepoint(int) { + return new UtfCodepoint(int); +} + +export function string_to_codepoint_integer_list(string) { + return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); +} + +export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { + return utf_codepoint_integer_list + .toArray() + .map((x) => String.fromCodePoint(x.value)) + .join(""); +} + +export function utf_codepoint_to_int(utf_codepoint) { + return utf_codepoint.value; +} + +export function regex_check(regex, string) { + regex.lastIndex = 0; + return regex.test(string); +} + +export function compile_regex(pattern, options) { + try { + let flags = "gu"; + if (options.case_insensitive) flags += "i"; + if (options.multi_line) flags += "m"; + return new Ok(new RegExp(pattern, flags)); + } catch (error) { + const number = (error.columnNumber || 0) | 0; + return new Error(new RegexCompileError(error.message, number)); + } +} + +export function regex_scan(regex, string) { + const matches = Array.from(string.matchAll(regex)).map((match) => { + const content = match[0]; + const submatches = []; + for (let n = match.length - 1; n > 0; n--) { + if (match[n]) { + submatches[n - 1] = new Some(match[n]); + continue; + } + if (submatches.length > 0) { + submatches[n - 1] = new None(); + } + } + return new RegexMatch(content, List.fromArray(submatches)); + }); + return List.fromArray(matches); +} + +export function new_map() { + return PMap.new(); +} + +export function map_size(map) { + return map.size; +} + +export function map_to_list(map) { + return List.fromArray(map.entries()); +} + +export function map_remove(key, map) { + return map.delete(key); +} + +export function map_get(map, key) { + const value = map.get(key, NOT_FOUND); + if (value === NOT_FOUND) { + return new Error(Nil); + } + return new Ok(value); +} + +export function map_insert(key, value, map) { + return map.set(key, value); +} + +function unsafe_percent_decode(string) { + return decodeURIComponent((string || "").replace("+", " ")); +} + +export function percent_decode(string) { + try { + return new Ok(unsafe_percent_decode(string)); + } catch (_error) { + return new Error(Nil); + } +} + +export function percent_encode(string) { + return encodeURIComponent(string); +} + +export function parse_query(query) { + try { + const pairs = []; + for (const section of query.split("&")) { + const [key, value] = section.split("="); + if (!key) continue; + pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); + } + return new Ok(List.fromArray(pairs)); + } catch (_error) { + return new Error(Nil); + } +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function encode64(bit_string) { + const aBytes = bit_string.buffer; + let nMod3 = 2; + let sB64Enc = ""; + + for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { + nMod3 = nIdx % 3; + if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { + sB64Enc += "\r\n"; + } + nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); + if (nMod3 === 2 || aBytes.length - nIdx === 1) { + sB64Enc += String.fromCharCode( + uint6ToB64((nUint24 >>> 18) & 63), + uint6ToB64((nUint24 >>> 12) & 63), + uint6ToB64((nUint24 >>> 6) & 63), + uint6ToB64(nUint24 & 63) + ); + nUint24 = 0; + } + } + + return ( + sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + + (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") + ); +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function uint6ToB64(nUint6) { + return nUint6 < 26 + ? nUint6 + 65 + : nUint6 < 52 + ? nUint6 + 71 + : nUint6 < 62 + ? nUint6 - 4 + : nUint6 === 62 + ? 43 + : nUint6 === 63 + ? 47 + : 65; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function b64ToUint6(nChr) { + return nChr > 64 && nChr < 91 + ? nChr - 65 + : nChr > 96 && nChr < 123 + ? nChr - 71 + : nChr > 47 && nChr < 58 + ? nChr + 4 + : nChr === 43 + ? 62 + : nChr === 47 + ? 63 + : 0; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function decode64(sBase64) { + if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); + const sB64Enc = sBase64.replace(/=/g, ""); + const nInLen = sB64Enc.length; + const nOutLen = (nInLen * 3 + 1) >> 2; + const taBytes = new Uint8Array(nOutLen); + + for ( + let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; + nInIdx < nInLen; + nInIdx++ + ) { + nMod4 = nInIdx & 3; + nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); + if (nMod4 === 3 || nInLen - nInIdx === 1) { + for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { + taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; + } + nUint24 = 0; + } + } + + return new Ok(new BitString(taBytes)); +} + +export function classify_dynamic(data) { + if (typeof data === "string") { + return "String"; + } else if (Result.isResult(data)) { + return "Result"; + } else if (List.isList(data)) { + return "List"; + } else if (Number.isInteger(data)) { + return "Int"; + } else if (Array.isArray(data)) { + return `Tuple of ${data.length} elements`; + } else if (BitString.isBitString(data)) { + return "BitString"; + } else if (data instanceof PMap) { + return "Map"; + } else if (typeof data === "number") { + return "Float"; + } else if (data === null) { + return "Null"; + } else if (data === undefined) { + return "Nil"; + } else { + const type = typeof data; + return type.charAt(0).toUpperCase() + type.slice(1); + } +} + +function decoder_error(expected, got) { + return decoder_error_no_classify(expected, classify_dynamic(got)); +} + +function decoder_error_no_classify(expected, got) { + return new Error( + List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) + ); +} + +export function decode_string(data) { + return typeof data === "string" + ? new Ok(data) + : decoder_error("String", data); +} + +export function decode_int(data) { + return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); +} + +export function decode_float(data) { + return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); +} + +export function decode_bool(data) { + return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); +} + +export function decode_bit_string(data) { + if (BitString.isBitString(data)) { + return new Ok(data); + } + if (data instanceof Uint8Array) { + return new Ok(new BitString(data)); + } + return decoder_error("BitString", data); +} + +export function decode_tuple(data) { + return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); +} + +export function decode_tuple2(data) { + return decode_tupleN(data, 2); +} + +export function decode_tuple3(data) { + return decode_tupleN(data, 3); +} + +export function decode_tuple4(data) { + return decode_tupleN(data, 4); +} + +export function decode_tuple5(data) { + return decode_tupleN(data, 5); +} + +export function decode_tuple6(data) { + return decode_tupleN(data, 6); +} + +function decode_tupleN(data, n) { + if (Array.isArray(data) && data.length == n) { + return new Ok(data); + } + + let list = decode_exact_length_list(data, n); + if (list) return new Ok(list); + + return decoder_error(`Tuple of ${n} elements`, data); +} + +function decode_exact_length_list(data, n) { + if (!List.isList(data)) return; + + let elements = []; + let current = data; + + for (let i = 0; i < n; i++) { + if (current.isEmpty()) break; + elements.push(current.head); + current = current.tail; + } + + if (elements.length === n && current.isEmpty()) return elements; +} + +export function tuple_get(data, index) { + return index >= 0 && data.length > index + ? new Ok(data[index]) + : new Error(Nil); +} + +export function decode_list(data) { + if (Array.isArray(data)) { + return new Ok(List.fromArray(data)); + } + return List.isList(data) ? new Ok(data) : decoder_error("List", data); +} + +export function decode_result(data) { + return Result.isResult(data) ? new Ok(data) : decoder_error("Result", data); +} + +export function decode_map(data) { + if (data instanceof PMap) { + return new Ok(PMap.fromMap(data)); + } + if (data == null) { + return decoder_error("Map", data); + } + if (typeof data !== "object") { + return decoder_error("Map", data); + } + const proto = Object.getPrototypeOf(data); + if (proto === Object.prototype || proto === null) { + return new Ok(PMap.fromObject(data)); + } + return decoder_error("Map", data); +} + +export function decode_option(data, decoder) { + if (data === null || data === undefined || data instanceof None) + return new Ok(new None()); + if (data instanceof Some) data = data[0]; + const result = decoder(data); + if (result.isOk()) { + return new Ok(new Some(result[0])); + } else { + return result; + } +} + +export function decode_field(value, name) { + const not_a_map_error = () => decoder_error("Map", value); + + if ( + value instanceof PMap || + value instanceof WeakMap || + value instanceof Map + ) { + const entry = map_get(value, name); + return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); + } else if (Object.getPrototypeOf(value) == Object.prototype) { + return try_get_field(value, name, () => new Ok(new None())); + } else { + return try_get_field(value, name, not_a_map_error); + } +} + +function try_get_field(value, field, or_else) { + try { + return field in value ? new Ok(new Some(value[field])) : or_else(); + } catch { + return or_else(); + } +} + +export function byte_size(string) { + return new TextEncoder().encode(string).length; +} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs b/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs new file mode 100644 index 00000000000..ff849d8def9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs @@ -0,0 +1,957 @@ +/** + * This file uses jsdoc to annotate types. + * These types can be checked using the typescript compiler with "checkjs" option. + */ + +import { isEqual } from "./gleam.mjs"; + +const referenceMap = new WeakMap(); +const tempDataView = new DataView(new ArrayBuffer(8)); +let referenceUID = 0; +/** + * hash the object by reference using a weak map and incrementing uid + * @param {any} o + * @returns {number} + */ +function hashByReference(o) { + const known = referenceMap.get(o); + if (known !== undefined) { + return known; + } + const hash = referenceUID++; + if (referenceUID === 0x7fffffff) { + referenceUID = 0; + } + referenceMap.set(o, hash); + return hash; +} +/** + * merge two hashes in an order sensitive way + * @param {number} a + * @param {number} b + * @returns {number} + */ +function hashMerge(a, b) { + return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; +} +/** + * standard string hash popularised by java + * @param {string} s + * @returns {number} + */ +function hashString(s) { + let hash = 0; + const len = s.length; + for (let i = 0; i < len; i++) { + hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; + } + return hash; +} +/** + * hash a number by converting to two integers and do some jumbling + * @param {number} n + * @returns {number} + */ +function hashNumber(n) { + tempDataView.setFloat64(0, n); + const i = tempDataView.getInt32(0); + const j = tempDataView.getInt32(4); + return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; +} +/** + * hash a BigInt by converting it to a string and hashing that + * @param {BigInt} n + * @returns {number} + */ +function hashBigInt(n) { + return hashString(n.toString()); +} +/** + * hash any js object + * @param {any} o + * @returns {number} + */ +function hashObject(o) { + const proto = Object.getPrototypeOf(o); + if (proto !== null && typeof proto.hashCode === "function") { + try { + const code = o.hashCode(o); + if (typeof code === "number") { + return code; + } + } catch {} + } + if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { + return hashByReference(o); + } + if (o instanceof Date) { + return hashNumber(o.getTime()); + } + let h = 0; + if (o instanceof ArrayBuffer) { + o = new Uint8Array(o); + } + if (Array.isArray(o) || o instanceof Uint8Array) { + for (let i = 0; i < o.length; i++) { + h = (Math.imul(31, h) + getHash(o[i])) | 0; + } + } else if (o instanceof Set) { + o.forEach((v) => { + h = (h + getHash(v)) | 0; + }); + } else if (o instanceof Map) { + o.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + } else { + const keys = Object.keys(o); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + const v = o[k]; + h = (h + hashMerge(getHash(v), hashString(k))) | 0; + } + } + return h; +} +/** + * hash any js value + * @param {any} u + * @returns {number} + */ +export function getHash(u) { + if (u === null) return 0x42108422; + if (u === undefined) return 0x42108423; + if (u === true) return 0x42108421; + if (u === false) return 0x42108420; + switch (typeof u) { + case "number": + return hashNumber(u); + case "string": + return hashString(u); + case "bigint": + return hashBigInt(u); + case "object": + return hashObject(u); + case "symbol": + return hashByReference(u); + case "function": + return hashByReference(u); + default: + return 0; // should be unreachable + } +} +/** + * @template K,V + * @typedef {ArrayNode | IndexNode | CollisionNode} Node + */ +/** + * @template K,V + * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry + */ +/** + * @template K,V + * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry | Node)[] }} ArrayNode + */ +/** + * @template K,V + * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry | Node)[] }} IndexNode + */ +/** + * @template K,V + * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry[] }} CollisionNode + */ +/** + * @typedef {{ val: boolean }} Flag + */ +const SHIFT = 5; // number of bits you need to shift by to get the next bucket +const BUCKET_SIZE = Math.pow(2, SHIFT); +const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket +const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node +const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node +const ENTRY = 0; +const ARRAY_NODE = 1; +const INDEX_NODE = 2; +const COLLISION_NODE = 3; +/** @type {IndexNode} */ +const EMPTY = { + type: INDEX_NODE, + bitmap: 0, + array: [], +}; +/** + * Mask the hash to get only the bucket corresponding to shift + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function mask(hash, shift) { + return (hash >>> shift) & MASK; +} +/** + * Set only the Nth bit where N is the masked hash + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function bitpos(hash, shift) { + return 1 << mask(hash, shift); +} +/** + * Count the number of 1 bits in a number + * @param {number} x + * @returns {number} + */ +function bitcount(x) { + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x += x >> 8; + x += x >> 16; + return x & 0x7f; +} +/** + * Calculate the array index of an item in a bitmap index node + * @param {number} bitmap + * @param {number} bit + * @returns {number} + */ +function index(bitmap, bit) { + return bitcount(bitmap & (bit - 1)); +} +/** + * Efficiently copy an array and set one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function cloneAndSet(arr, at, val) { + const len = arr.length; + const out = new Array(len); + for (let i = 0; i < len; ++i) { + out[i] = arr[i]; + } + out[at] = val; + return out; +} +/** + * Efficiently copy an array and insert one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function spliceIn(arr, at, val) { + const len = arr.length; + const out = new Array(len + 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + out[g++] = val; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Efficiently copy an array and remove one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @returns {T[]} + */ +function spliceOut(arr, at) { + const len = arr.length; + const out = new Array(len - 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + ++i; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Create a new node containing two entries + * @template K,V + * @param {number} shift + * @param {K} key1 + * @param {V} val1 + * @param {number} key2hash + * @param {K} key2 + * @param {V} val2 + * @returns {Node} + */ +function createNode(shift, key1, val1, key2hash, key2, val2) { + const key1hash = getHash(key1); + if (key1hash === key2hash) { + return { + type: COLLISION_NODE, + hash: key1hash, + array: [ + { type: ENTRY, k: key1, v: val1 }, + { type: ENTRY, k: key2, v: val2 }, + ], + }; + } + const addedLeaf = { val: false }; + return assoc( + assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), + shift, + key2hash, + key2, + val2, + addedLeaf + ); +} +/** + * @template T,K,V + * @callback AssocFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @param {V} val + * @param {Flag} addedLeaf + * @returns {Node} + */ +/** + * Associate a node with a new entry, creating a new node + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assoc(root, shift, hash, key, val, addedLeaf) { + switch (root.type) { + case ARRAY_NODE: + return assocArray(root, shift, hash, key, val, addedLeaf); + case INDEX_NODE: + return assocIndex(root, shift, hash, key, val, addedLeaf); + case COLLISION_NODE: + return assocCollision(root, shift, hash, key, val, addedLeaf); + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocArray(root, shift, hash, key, val, addedLeaf) { + const idx = mask(hash, shift); + const node = root.array[idx]; + // if the corresponding index is empty set the index to a newly created node + if (node === undefined) { + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size + 1, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + if (node.type === ENTRY) { + // if keys are equal replace the entry + if (isEqual(key, node.k)) { + if (val === node.v) { + return root; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // otherwise upgrade the entry to a node and insert + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, node.k, node.v, hash, key, val) + ), + }; + } + // otherwise call assoc on the child node + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + // if the child node hasn't changed just return the old root + if (n === node) { + return root; + } + // otherwise set the index to the new node + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocIndex(root, shift, hash, key, val, addedLeaf) { + const bit = bitpos(hash, shift); + const idx = index(root.bitmap, bit); + // if there is already a item at this hash index.. + if ((root.bitmap & bit) !== 0) { + // if there is a node at the index (not an entry), call assoc on the child node + const node = root.array[idx]; + if (node.type !== ENTRY) { + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + if (n === node) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise there is an entry at the index + // if the keys are equal replace the entry with the updated value + const nodeKey = node.k; + if (isEqual(key, nodeKey)) { + if (val === node.v) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // if the keys are not equal, replace the entry with a new child node + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) + ), + }; + } else { + // else there is currently no item at the hash index + const n = root.array.length; + // if the number of nodes is at the maximum, expand this node into an array node + if (n >= MAX_INDEX_NODE) { + // create a 32 length array for the new array node (one for each bit in the hash) + const nodes = new Array(32); + // create and insert a node for the new entry + const jdx = mask(hash, shift); + nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); + let j = 0; + let bitmap = root.bitmap; + // place each item in the index node into the correct spot in the array node + // loop through all 32 bits / array positions + for (let i = 0; i < 32; i++) { + if ((bitmap & 1) !== 0) { + const node = root.array[j++]; + nodes[i] = node; + } + // shift the bitmap to process the next bit + bitmap = bitmap >>> 1; + } + return { + type: ARRAY_NODE, + size: n + 1, + array: nodes, + }; + } else { + // else there is still space in this index node + // simply insert a new entry at the hash index + const newArray = spliceIn(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }); + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap | bit, + array: newArray, + }; + } + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocCollision(root, shift, hash, key, val, addedLeaf) { + // if there is a hash collision + if (hash === root.hash) { + const idx = collisionIndexOf(root, key); + // if this key already exists replace the entry with the new value + if (idx !== -1) { + const entry = root.array[idx]; + if (entry.v === val) { + return root; + } + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + // otherwise insert the entry at the end of the array + const size = root.array.length; + addedLeaf.val = true; + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), + }; + } + // if there is no hash collision, upgrade to an index node + return assoc( + { + type: INDEX_NODE, + bitmap: bitpos(root.hash, shift), + array: [root], + }, + shift, + hash, + key, + val, + addedLeaf + ); +} +/** + * Find the index of a key in the collision node's array + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {number} + */ +function collisionIndexOf(root, key) { + const size = root.array.length; + for (let i = 0; i < size; i++) { + if (isEqual(key, root.array[i].k)) { + return i; + } + } + return -1; +} +/** + * @template T,K,V + * @callback FindFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Entry} + */ +/** + * Return the found entry or undefined if not present in the root + * @template K,V + * @type {FindFunction,K,V>} + */ +function find(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return findArray(root, shift, hash, key); + case INDEX_NODE: + return findIndex(root, shift, hash, key); + case COLLISION_NODE: + return findCollision(root, key); + } +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return undefined; + } + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return undefined; + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Entry} + */ +function findCollision(root, key) { + const idx = collisionIndexOf(root, key); + if (idx < 0) { + return undefined; + } + return root.array[idx]; +} +/** + * @template T,K,V + * @callback WithoutFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Node} + */ +/** + * Remove an entry from the root, returning the updated root. + * Returns undefined if the node should be removed from the parent. + * @template K,V + * @type {WithoutFunction,K,V>} + * */ +function without(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return withoutArray(root, shift, hash, key); + case INDEX_NODE: + return withoutIndex(root, shift, hash, key); + case COLLISION_NODE: + return withoutCollision(root, key); + } +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return root; // already empty + } + let n = undefined; + // if node is an entry and the keys are not equal there is nothing to remove + // if node is not an entry do a recursive call + if (node.type === ENTRY) { + if (!isEqual(node.k, key)) { + return root; // no changes + } + } else { + n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + } + // if the recursive call returned undefined the node should be removed + if (n === undefined) { + // if the number of child nodes is at the minimum, pack into an index node + if (root.size <= MIN_ARRAY_NODE) { + const arr = root.array; + const out = new Array(root.size - 1); + let i = 0; + let j = 0; + let bitmap = 0; + while (i < idx) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + ++i; // skip copying the removed node + while (i < arr.length) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + return { + type: INDEX_NODE, + bitmap: bitmap, + array: out, + }; + } + return { + type: ARRAY_NODE, + size: root.size - 1, + array: cloneAndSet(root.array, idx, n), + }; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return root; // already empty + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + // if the item is not an entry + if (node.type !== ENTRY) { + const n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + // if not undefined, the child node still has items, so update it + if (n !== undefined) { + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise the child node should be removed + // if it was the only child node, remove this node from the parent + if (root.bitmap === bit) { + return undefined; + } + // otherwise just remove the child node + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + // otherwise the item is an entry, remove it if the key matches + if (isEqual(key, node.k)) { + if (root.bitmap === bit) { + return undefined; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + return root; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Node} + */ +function withoutCollision(root, key) { + const idx = collisionIndexOf(root, key); + // if the key not found, no changes + if (idx < 0) { + return root; + } + // otherwise the entry was found, remove it + // if it was the only entry in this node, remove the whole node + if (root.array.length === 1) { + return undefined; + } + // otherwise just remove the entry + return { + type: COLLISION_NODE, + hash: root.hash, + array: spliceOut(root.array, idx), + }; +} +/** + * @template K,V + * @param {undefined | Node} root + * @param {(value:V,key:K)=>void} fn + * @returns {void} + */ +function forEach(root, fn) { + if (root === undefined) { + return; + } + const items = root.array; + const size = items.length; + for (let i = 0; i < size; i++) { + const item = items[i]; + if (item === undefined) { + continue; + } + if (item.type === ENTRY) { + fn(item.v, item.k); + continue; + } + forEach(item, fn); + } +} +/** + * Extra wrapper to keep track of map size and clean up the API + * @template K,V + */ +export default class PMap { + /** + * @template V + * @param {Record} o + * @returns {PMap} + */ + static fromObject(o) { + const keys = Object.keys(o); + /** @type PMap */ + let m = PMap.new(); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + m = m.set(k, o[k]); + } + return m; + } + /** + * @template K,V + * @param {Map} o + * @returns {PMap} + */ + static fromMap(o) { + /** @type PMap */ + let m = PMap.new(); + o.forEach((v, k) => { + m = m.set(k, v); + }); + return m; + } + static new() { + return new PMap(undefined, 0); + } + /** + * @param {undefined | Node} root + * @param {number} size + */ + constructor(root, size) { + this.root = root; + this.size = size; + } + /** + * @template NotFound + * @param {K} key + * @param {NotFound} notFound + * @returns {NotFound | V} + */ + get(key, notFound) { + if (this.root === undefined) { + return notFound; + } + const found = find(this.root, 0, getHash(key), key); + if (found === undefined) { + return notFound; + } + return found.v; + } + /** + * @param {K} key + * @param {V} val + * @returns {PMap} + */ + set(key, val) { + const addedLeaf = { val: false }; + const root = this.root === undefined ? EMPTY : this.root; + const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); + if (newRoot === this.root) { + return this; + } + return new PMap(newRoot, addedLeaf.val ? this.size + 1 : this.size); + } + /** + * @param {K} key + * @returns {PMap} + */ + delete(key) { + if (this.root === undefined) { + return this; + } + const newRoot = without(this.root, 0, getHash(key), key); + if (newRoot === this.root) { + return this; + } + if (newRoot === undefined) { + return PMap.new(); + } + return new PMap(newRoot, this.size - 1); + } + /** + * @param {K} key + * @returns {boolean} + */ + has(key) { + if (this.root === undefined) { + return false; + } + return find(this.root, 0, getHash(key), key) !== undefined; + } + /** + * @returns {[K,V][]} + */ + entries() { + if (this.root === undefined) { + return []; + } + /** @type [K,V][] */ + const result = []; + this.forEach((v, k) => result.push([k, v])); + return result; + } + /** + * + * @param {(val:V,key:K)=>void} fn + */ + forEach(fn) { + forEach(this.root, fn); + } + hashCode() { + let h = 0; + this.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + return h; + } + /** + * @param {unknown} o + * @returns {boolean} + */ + equals(o) { + if (!(o instanceof PMap)) { + return false; + } + let equal = true; + this.forEach((v, k) => { + equal = equal && isEqual(o.get(k, !v), v); + }); + return equal; + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/README.md b/test-community-packages-javascript/build/packages/gleamy_structures/README.md new file mode 100644 index 00000000000..4d7b812da21 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/README.md @@ -0,0 +1,27 @@ +# gleamy_structures + +[![Package Version](https://img.shields.io/hexpm/v/gleamy_structures)](https://hex.pm/packages/gleamy_structures) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleamy_structures/) + +Data structures in pure Gleam. + +## Quick start + +```sh +gleam run # Run the project +gleam test # Run the tests +gleam shell # Run an Erlang shell +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add gleamy_structures +``` + +and its documentation can be found at . + +## Contributions Welcome +Feel free to make PRs, issues, or requests for new data structures and functions :) Especially welcome would be more rigorous tests and reviews of the implementation compared to source materials. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml b/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml new file mode 100644 index 00000000000..270dfb77c9e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml @@ -0,0 +1,15 @@ +name = "gleamy_structures" +version = "0.3.0" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +licences = ["Apache-2.0"] +description = "Data structures in pure Gleam." +repository = { type = "github", user = "schurhammer", repo = "gleamy_structures" } +links = [{ title = "Website", href = "https://github.com/schurhammer/gleamy_structures" }] + +[dependencies] +gleam_stdlib = "~> 0.29.0" + +[dev-dependencies] +gleeunit = "~> 0.10.1" diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl new file mode 100644 index 00000000000..8bebbbf34a9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl @@ -0,0 +1,4 @@ +-record(heap, { + root :: gleamy_structures@heap@leftist_heap:t(any()), + compare :: fun((any(), any()) -> gleam@order:order()) +}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl new file mode 100644 index 00000000000..e4750eafa6f --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl @@ -0,0 +1,4 @@ +-record(heap, { + root :: gleamy_structures@heap@pairing_heap:t(any()), + compare :: fun((any(), any()) -> gleam@order:order()) +}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl new file mode 100644 index 00000000000..bc5cc269430 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl @@ -0,0 +1 @@ +-record('end', {first :: any()}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl new file mode 100644 index 00000000000..8b05f955f9c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl @@ -0,0 +1,4 @@ +-record(next, { + first :: any(), + rest :: gleamy_structures@non_empty_list:non_empty_list(any()) +}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl new file mode 100644 index 00000000000..680935c5c15 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl @@ -0,0 +1,4 @@ +-record(tree, { + root :: gleamy_structures@tree@binary_search_tree:node_(any()), + compare :: fun((any(), any()) -> gleam@order:order()) +}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl new file mode 100644 index 00000000000..b3310a80c4c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl @@ -0,0 +1,4 @@ +-record(tree, { + root :: gleamy_structures@tree@red_black_tree:node_(any()), + compare :: fun((any(), any()) -> gleam@order:order()) +}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl new file mode 100644 index 00000000000..2b57f9253ec --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl @@ -0,0 +1,4 @@ +-record(tree, { + root :: gleamy_structures@tree@red_black_tree_kv:node_(any(), any()), + compare :: fun((any(), any()) -> gleam@order:order()) +}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src new file mode 100644 index 00000000000..01611d955eb --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src @@ -0,0 +1,16 @@ +{application, gleamy_structures, [ + {vsn, "0.3.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Data structures in pure Gleam."}, + {modules, [gleamy_structures@heap@leftist_heap, + gleamy_structures@heap@pairing_heap, + gleamy_structures@map, + gleamy_structures@non_empty_list, + gleamy_structures@priority_queue, + gleamy_structures@set, + gleamy_structures@tree@binary_search_tree, + gleamy_structures@tree@red_black_tree, + gleamy_structures@tree@red_black_tree_kv]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam new file mode 100644 index 00000000000..7d1b51669a8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam @@ -0,0 +1,61 @@ +// Based on "Purely Functional Data Structures" by Okasaki (1998) + +import gleam/order.{Gt, Order} + +type T(a) { + E + T(Int, a, T(a), T(a)) +} + +pub opaque type Heap(a) { + Heap(root: T(a), compare: fn(a, a) -> Order) +} + +pub fn new(compare: fn(a, a) -> Order) -> Heap(a) { + Heap(E, compare) +} + +pub fn insert(heap: Heap(a), item: a) -> Heap(a) { + Heap(merge(T(1, item, E, E), heap.root, heap.compare), heap.compare) +} + +pub fn find_min(heap: Heap(a)) -> Result(a, Nil) { + case heap.root { + T(_, x, _, _) -> Ok(x) + E -> Error(Nil) + } +} + +pub fn delete_min(heap: Heap(a)) -> Result(#(a, Heap(a)), Nil) { + case heap.root { + T(_, x, a, b) -> Ok(#(x, Heap(merge(a, b, heap.compare), heap.compare))) + E -> Error(Nil) + } +} + +fn merge(h1: T(a), h2: T(a), compare: fn(a, a) -> Order) -> T(a) { + case h1, h2 { + h, E -> h + E, h -> h + T(_, x, a1, b1), T(_, y, a2, b2) -> + case compare(x, y) { + Gt -> make(y, a2, merge(h1, b2, compare)) + _ -> make(x, a1, merge(b1, h2, compare)) + } + } +} + +fn make(x, a, b) { + let rank_a = case a { + T(r, _, _, _) -> r + E -> 0 + } + let rank_b = case b { + T(r, _, _, _) -> r + E -> 0 + } + case rank_a < rank_b { + True -> T(rank_a + 1, x, b, a) + _ -> T(rank_b + 1, x, a, b) + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam new file mode 100644 index 00000000000..80f69a31e22 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam @@ -0,0 +1,55 @@ +// Based on "Purely Functional Data Structures" by Okasaki (1998) + +import gleam/order.{Gt, Order} + +type T(a) { + E + T(a, List(T(a))) +} + +pub opaque type Heap(a) { + Heap(root: T(a), compare: fn(a, a) -> Order) +} + +pub fn new(compare: fn(a, a) -> Order) -> Heap(a) { + Heap(E, compare) +} + +pub fn insert(heap: Heap(a), key: a) -> Heap(a) { + Heap(merge(T(key, []), heap.root, heap.compare), heap.compare) +} + +pub fn find_min(heap: Heap(a)) -> Result(a, Nil) { + case heap.root { + T(x, _) -> Ok(x) + E -> Error(Nil) + } +} + +pub fn delete_min(heap: Heap(a)) -> Result(#(a, Heap(a)), Nil) { + case heap.root { + T(x, xs) -> Ok(#(x, Heap(merge_pairs(xs, heap.compare), heap.compare))) + E -> Error(Nil) + } +} + +fn merge(x: T(a), y: T(a), compare: fn(a, a) -> Order) -> T(a) { + case x, y { + x, E -> x + E, y -> y + T(xk, xs), T(yk, ys) -> + case compare(xk, yk) { + Gt -> T(yk, [x, ..ys]) + _ -> T(xk, [y, ..xs]) + } + } +} + +fn merge_pairs(l: List(T(a)), compare: fn(a, a) -> Order) -> T(a) { + case l { + [] -> E + [h] -> h + [h1, h2, ..hs] -> + merge(merge(h1, h2, compare), merge_pairs(hs, compare), compare) + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam new file mode 100644 index 00000000000..a49180e19ee --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam @@ -0,0 +1,85 @@ +import gleam/order.{Order} +import gleam/list +import gleamy_structures/tree/red_black_tree_kv as tree + +type Map(k, v) = + tree.Tree(k, v) + +pub fn new(compare: fn(k, k) -> Order) -> Map(k, v) { + tree.new(compare) +} + +pub fn insert(into map: Map(k, v), key key: k, value value: v) -> Map(k, v) { + tree.insert(map, key, value) +} + +pub fn find(in map: Map(k, v), key key: k) -> Result(#(k, v), Nil) { + tree.find(map, key) +} + +pub fn has_key(in map: Map(k, v), key key: k) -> Bool { + case tree.find(map, key) { + Ok(_) -> True + Error(_) -> False + } +} + +pub fn delete(from map: Map(k, v), this key: k) -> Map(k, v) { + tree.delete(map, key) +} + +pub fn count(map: Map(k, v)) -> Int { + tree.fold(map, 0, fn(a, _, _) { a + 1 }) +} + +pub fn fold( + over map: Map(k, v), + from initial: a, + with reducer: fn(a, k, v) -> a, +) -> a { + tree.fold(map, initial, reducer) +} + +pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { + tree.fold( + map, + map, + fn(map, k, v) { + case property(k, v) { + True -> map + False -> tree.delete(map, k) + } + }, + ) +} + +pub fn merge(this first: Map(k, v), and second: Map(k, v)) -> Map(k, v) { + tree.fold(first, second, fn(a, k, v) { tree.insert(a, k, v) }) +} + +// return the map keeping only keys in the list +pub fn take(from map: Map(k, v), keeping desired: List(k)) -> Map(k, v) { + case desired { + [x, ..xs] -> + case tree.find(map, x) { + Ok(x) -> tree.insert(take(map, xs), x.0, x.1) + Error(_) -> take(map, xs) + } + [] -> tree.clear(map) + } +} + +pub fn from_list( + members: List(#(k, v)), + compare: fn(k, k) -> Order, +) -> Map(k, v) { + list.fold( + members, + tree.new(compare), + fn(tree, i) { tree.insert(tree, i.0, i.1) }, + ) +} + +pub fn to_list(map: Map(k, v)) -> List(#(k, v)) { + tree.foldr(map, [], fn(a, k, v) { [#(k, v), ..a] }) +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam new file mode 100644 index 00000000000..0ba26fd70c4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam @@ -0,0 +1,63 @@ +import gleam/list + +pub type NonEmptyList(a) { + End(first: a) + Next(first: a, rest: NonEmptyList(a)) +} + +pub fn fold( + over list: NonEmptyList(a), + from initial: b, + with fun: fn(b, a) -> b, +) -> b { + case list { + End(item) -> fun(initial, item) + Next(x, xs) -> fold(xs, fun(initial, x), fun) + } +} + +pub fn count(list: NonEmptyList(a)) -> Int { + fold(list, 0, fn(acc, _) { acc + 1 }) +} + +pub fn map(list: NonEmptyList(a), transform: fn(a) -> b) -> NonEmptyList(b) { + case list { + End(x) -> End(transform(x)) + Next(x, xs) -> + fold(xs, End(transform(x)), fn(acc, item) { Next(transform(item), acc) }) + |> reverse + } +} + +pub fn filter(list: NonEmptyList(a), predicate: fn(a) -> Bool) -> List(a) { + fold( + list, + [], + fn(acc, item) { + case predicate(item) { + True -> [item, ..acc] + False -> acc + } + }, + ) + |> list.reverse() +} + +pub fn to_list(list: NonEmptyList(a)) -> List(a) { + fold(list, [], fn(acc, item) { [item, ..acc] }) + |> list.reverse() +} + +pub fn from_list(list: List(a)) -> Result(NonEmptyList(a), Nil) { + case list { + [] -> Error(Nil) + [x, ..xs] -> Ok(list.fold(xs, End(x), fn(acc, item) { Next(item, acc) })) + } +} + +pub fn reverse(list: NonEmptyList(a)) -> NonEmptyList(a) { + case list { + End(_) -> list + Next(x, xs) -> fold(xs, End(x), fn(acc, x) { Next(x, acc) }) + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam new file mode 100644 index 00000000000..0bf0f8a5cc6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam @@ -0,0 +1,54 @@ +import gleam/order.{Order} +import gleam/list +import gleamy_structures/heap/pairing_heap as heap + +type Queue(a) = + heap.Heap(a) + +pub fn from_list(list: List(a), compare: fn(a, a) -> Order) -> Queue(a) { + list.fold(list, new(compare), heap.insert) +} + +pub fn is_empty(queue: Queue(a)) -> Bool { + case heap.find_min(queue) { + Ok(_) -> False + Error(_) -> True + } +} + +pub fn count(queue: Queue(a)) -> Int { + case heap.delete_min(queue) { + Ok(#(_, q)) -> count(q) + 1 + Error(_) -> 0 + } +} + +pub fn new(compare: fn(a, a) -> Order) -> Queue(a) { + heap.new(compare) +} + +pub fn pop(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + heap.delete_min(queue) +} + +pub fn peek(from queue: Queue(a)) -> Result(a, Nil) { + heap.find_min(queue) +} + +pub fn push(onto queue: Queue(a), this item: a) -> Queue(a) { + heap.insert(queue, item) +} + +pub fn reorder(queue: Queue(a), compare: fn(a, a) -> Order) -> Queue(a) { + case heap.delete_min(queue) { + Ok(#(x, q)) -> heap.insert(reorder(q, compare), x) + Error(_) -> heap.new(compare) + } +} + +pub fn to_list(queue: Queue(a)) -> List(a) { + case heap.delete_min(queue) { + Ok(#(x, q)) -> [x, ..to_list(q)] + Error(_) -> [] + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam new file mode 100644 index 00000000000..0448bfbbb24 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam @@ -0,0 +1,91 @@ +import gleam/order.{Order} +import gleam/list +import gleam/io +import gleam/string +import gleamy_structures/tree/red_black_tree as tree + +type Set(a) = + tree.Tree(a) + +pub fn contains(in set: Set(a), this member: a) -> Bool { + case tree.find(set, member) { + Ok(_) -> True + Error(_) -> False + } +} + +pub fn delete(from set: Set(a), this member: a) -> Set(a) { + tree.delete(set, member) +} + +pub fn filter(in set: Set(a), for property: fn(a) -> Bool) -> Set(a) { + tree.fold( + set, + set, + fn(set, i) { + case property(i) { + True -> set + False -> tree.delete(set, i) + } + }, + ) +} + +pub fn fold(over set: Set(a), from initial: b, with reducer: fn(b, a) -> b) -> b { + tree.fold(set, initial, reducer) +} + +pub fn from_list(members: List(a), compare: fn(a, a) -> Order) -> Set(a) { + list.fold(members, tree.new(compare), tree.insert) +} + +pub fn insert(into set: Set(a), this member: a) -> Set(a) { + tree.insert(set, member) +} + +pub fn intersection(of first: Set(a), and second: Set(a)) -> Set(a) { + tree.fold( + second, + tree.clear(first), + fn(a, i) { + case tree.find(first, i) { + Ok(_) -> tree.insert(a, i) + Error(_) -> a + } + }, + ) +} + +pub fn new(compare: fn(a, a) -> Order) -> Set(a) { + tree.new(compare) +} + +pub fn count(set: Set(a)) -> Int { + tree.fold(set, 0, fn(a, _) { a + 1 }) +} + +pub fn take(from set: Set(a), keeping desired: List(a)) -> Set(a) { + case desired { + [x, ..xs] -> + case tree.find(set, x) { + Ok(x) -> tree.insert(take(set, xs), x) + Error(_) -> take(set, xs) + } + [] -> tree.clear(set) + } +} + +pub fn to_list(set: Set(a)) -> List(a) { + tree.foldr( + set, + [], + fn(a, i) { + io.println(string.inspect(i)) + [i, ..a] + }, + ) +} + +pub fn union(of first: Set(a), and second: Set(a)) -> Set(a) { + tree.fold(first, second, fn(a, i) { tree.insert(a, i) }) +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam new file mode 100644 index 00000000000..fdae1f6e999 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam @@ -0,0 +1,123 @@ +import gleam/order.{Eq, Gt, Lt, Order} + +type Node(a) { + Empty + Node(l: Node(a), k: a, r: Node(a)) +} + +pub opaque type Tree(a) { + Tree(root: Node(a), compare: fn(a, a) -> Order) +} + +pub fn new(compare: fn(a, a) -> Order) -> Tree(a) { + Tree(Empty, compare) +} + +pub fn clear(tree: Tree(a)) -> Tree(a) { + Tree(Empty, tree.compare) +} + +pub fn insert(tree: Tree(a), key: a) -> Tree(a) { + Tree(do_insert(tree.root, key, tree.compare), tree.compare) +} + +pub fn delete(tree: Tree(a), key: a) -> Tree(a) { + Tree(do_delete(tree.root, key, tree.compare), tree.compare) +} + +pub fn find(tree: Tree(a), key: a) -> Result(a, Nil) { + do_find(tree.root, key, tree.compare) +} + +pub fn fold(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { + do_fold(tree.root, acc, fun) +} + +pub fn draw(tree: Tree(a), to_string: fn(a) -> String) { + do_draw(tree.root, 0, to_string) +} + +fn do_insert(node, key, compare) { + case node { + Node(l, k, r) -> + case compare(key, k) { + Lt -> Node(do_insert(l, key, compare), k, r) + Gt -> Node(l, k, do_insert(r, key, compare)) + Eq -> Node(l, key, r) + } + Empty -> Node(Empty, key, Empty) + } +} + +fn do_min(node, compare) { + case node { + Node(Node(_, _, _) as l, _, _) -> do_min(l, compare) + Node(Empty, _, _) -> node + Empty -> Empty + } +} + +fn do_delete(node, key, compare) { + case node { + Node(l, k, r) -> + case compare(key, k) { + Lt -> Node(do_delete(l, key, compare), k, r) + Gt -> Node(l, k, do_delete(r, key, compare)) + Eq -> + case node { + Node(Empty, _, r) -> r + Node(l, _, Empty) -> l + Node(l, _, r) -> + case do_min(r, compare) { + Node(_, mk, _) -> Node(l, mk, do_delete(r, mk, compare)) + Empty -> Empty + } + Empty -> Empty + } + } + Empty -> Empty + } +} + +fn do_find(node, key, compare) { + case node { + Node(l, k, r) -> + case compare(key, k) { + Lt -> do_find(l, key, compare) + Gt -> do_find(r, key, compare) + Eq -> Ok(k) + } + Empty -> Error(Nil) + } +} + +fn do_fold(node, acc, fun) { + case node { + Node(r, v, l) -> { + let acc = do_fold(r, acc, fun) + let acc = fun(acc, v) + let acc = do_fold(l, acc, fun) + acc + } + Empty -> acc + } +} + +fn do_indent(acc, i) { + case i { + 0 -> acc + i -> do_indent(". " <> acc, i - 1) + } +} + +fn do_draw(node, indent, to_string) { + case node { + Node(l, k, r) -> { + let ls = do_draw(l, indent + 1, to_string) + let ks = do_indent(to_string(k) <> "\n", indent) + let rs = do_draw(r, indent + 1, to_string) + ls <> ks <> rs + } + Empty -> "" + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam new file mode 100644 index 00000000000..96d9e823b91 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam @@ -0,0 +1,224 @@ +// Based on "Deletion: The curse of the red-black tree" by Germane (2014) + +import gleam/order.{Eq, Gt, Lt, Order} + +type Color { + R + B + BB +} + +type Node(a) { + E + EE + T(c: Color, l: Node(a), k: a, r: Node(a)) +} + +pub opaque type Tree(a) { + Tree(root: Node(a), compare: fn(a, a) -> Order) +} + +pub fn new(compare: fn(a, a) -> Order) -> Tree(a) { + Tree(E, compare) +} + +pub fn clear(tree: Tree(a)) -> Tree(a) { + Tree(E, tree.compare) +} + +pub fn insert(tree: Tree(a), key: a) -> Tree(a) { + Tree(blacken(ins(tree.root, key, tree.compare)), tree.compare) +} + +pub fn delete(tree: Tree(a), key: a) -> Tree(a) { + Tree(del(redden(tree.root), key, tree.compare), tree.compare) +} + +pub fn find(tree: Tree(a), key: a) -> Result(a, Nil) { + do_find(tree.root, key, tree.compare) +} + +pub fn fold(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { + do_fold(tree.root, acc, fun) +} + +pub fn foldr(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { + do_foldr(tree.root, acc, fun) +} + +pub fn draw(tree: Tree(a), to_string: fn(a) -> String) { + do_draw(tree.root, 0, to_string) +} + +fn ins(node, x, compare) { + case node { + E -> T(R, E, x, E) + T(c, a, y, b) -> + case compare(x, y) { + Lt -> balance(c, ins(a, x, compare), y, b) + Gt -> balance(c, a, y, ins(b, x, compare)) + Eq -> T(c, a, x, b) + } + _ -> node + } +} + +fn blacken(node: Node(a)) -> Node(a) { + case node { + T(R, T(R, _, _, _) as l, y, c) -> T(B, l, y, c) + T(R, a, x, T(R, _, _, _) as r) -> T(B, a, x, r) + t -> t + } +} + +fn balance(c: Color, l: Node(a), v: a, r: Node(a)) -> Node(a) { + case c, l, v, r { + B, T(R, T(R, a, x, b), y, c), z, d -> T(R, T(B, a, x, b), y, T(B, c, z, d)) + B, T(R, a, x, T(R, b, y, c)), z, d -> T(R, T(B, a, x, b), y, T(B, c, z, d)) + B, a, x, T(R, T(R, b, y, c), z, d) -> T(R, T(B, a, x, b), y, T(B, c, z, d)) + B, a, x, T(R, b, y, T(R, c, z, d)) -> T(R, T(B, a, x, b), y, T(B, c, z, d)) + BB, a, x, T(R, T(R, b, y, c), z, d) -> T(B, T(B, a, x, b), y, T(B, c, z, d)) + BB, T(R, a, x, T(R, b, y, c)), z, d -> T(B, T(B, a, x, b), y, T(B, c, z, d)) + c, a, x, b -> T(c, a, x, b) + } +} + +fn redden(node: Node(a)) -> Node(a) { + case node { + T(B, T(B, _, _, _) as l, y, T(B, _, _, _) as r) -> T(R, l, y, r) + t -> t + } +} + +fn del(node, x, compare) { + case node { + E -> node + T(R, E, y, E) -> + case compare(x, y) { + Eq -> E + _ -> node + } + T(B, E, y, E) -> + case compare(x, y) { + Eq -> EE + _ -> node + } + T(B, T(R, E, y, E) as l, z, E) -> + case compare(x, z) { + Lt -> T(B, del(l, x, compare), z, E) + Gt -> node + Eq -> T(B, E, y, E) + } + T(c, a, y, b) -> + case compare(x, y) { + Lt -> rotate(c, del(a, x, compare), y, b) + Gt -> rotate(c, a, y, del(b, x, compare)) + Eq -> + case min_del(b) { + Min(y1, b1) -> rotate(c, a, y1, b1) + None -> E + } + } + _ -> node + } +} + +fn rotate(c: Color, l: Node(a), v: a, r: Node(a)) -> Node(a) { + case c, l, v, r { + R, T(BB, a, x, b), y, T(B, c, z, d) -> + balance(B, T(R, T(B, a, x, b), y, c), z, d) + R, EE, y, T(B, c, z, d) -> balance(B, T(R, E, y, c), z, d) + R, T(B, a, x, b), y, T(BB, c, z, d) -> + balance(B, a, x, T(R, b, y, T(B, c, z, d))) + R, T(B, a, x, b), y, EE -> balance(B, a, x, T(R, b, y, E)) + B, T(BB, a, x, b), y, T(B, c, z, d) -> + balance(BB, T(R, T(B, a, x, b), y, c), z, d) + B, EE, y, T(B, c, z, d) -> balance(BB, T(R, E, y, c), z, d) + B, T(B, a, x, b), y, T(BB, c, z, d) -> + balance(BB, a, x, T(R, b, y, T(B, c, z, d))) + B, T(B, a, x, b), y, EE -> balance(BB, a, x, T(R, b, y, E)) + B, T(BB, a, w, b), x, T(R, T(B, c, y, d), z, e) -> + T(B, balance(B, T(R, T(B, a, w, b), x, c), y, d), z, e) + B, EE, x, T(R, T(B, c, y, d), z, e) -> + T(B, balance(B, T(R, E, x, c), y, d), z, e) + B, T(R, a, w, T(B, b, x, c)), y, T(BB, d, z, e) -> + T(B, a, w, balance(B, b, x, T(R, c, y, T(B, d, z, e)))) + B, T(R, a, w, T(B, b, x, c)), y, EE -> + T(B, a, w, balance(B, b, x, T(R, c, y, E))) + c, a, x, b -> T(c, a, x, b) + } +} + +type MinDel(a) { + Min(a, Node(a)) + None +} + +fn min_del(node) -> MinDel(a) { + case node { + T(R, E, x, E) -> Min(x, E) + T(B, E, x, E) -> Min(x, EE) + T(B, E, x, T(R, E, y, E)) -> Min(x, T(B, E, y, E)) + T(c, a, x, b) -> + case min_del(a) { + Min(x1, a1) -> Min(x1, rotate(c, a1, x, b)) + None -> None + } + _ -> None + } +} + +fn do_find(node, key, compare) { + case node { + T(_, l, k, r) -> + case compare(key, k) { + Lt -> do_find(l, key, compare) + Gt -> do_find(r, key, compare) + Eq -> Ok(k) + } + _ -> Error(Nil) + } +} + +fn do_fold(node, acc, fun) { + case node { + T(_, r, v, l) -> { + let acc = do_fold(r, acc, fun) + let acc = fun(acc, v) + let acc = do_fold(l, acc, fun) + acc + } + _ -> acc + } +} + +fn do_foldr(node, acc, fun) { + case node { + T(_, r, v, l) -> { + let acc = do_foldr(l, acc, fun) + let acc = fun(acc, v) + let acc = do_foldr(r, acc, fun) + acc + } + _ -> acc + } +} + +fn do_indent(acc, i) { + case i { + 0 -> acc + i -> do_indent(". " <> acc, i - 1) + } +} + +fn do_draw(node, indent, to_string) { + case node { + T(_, l, k, r) -> { + let ls = do_draw(l, indent + 1, to_string) + let ks = do_indent(to_string(k) <> "\n", indent) + let rs = do_draw(r, indent + 1, to_string) + ls <> ks <> rs + } + _ -> "" + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam new file mode 100644 index 00000000000..9a61ae14b11 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam @@ -0,0 +1,232 @@ +// Based on "Deletion: The curse of the red-black tree" by Germane (2014) + +import gleam/order.{Eq, Gt, Lt, Order} + +type Color { + R + B + BB +} + +type Node(k, v) { + E + EE + T(c: Color, l: Node(k, v), k: #(k, v), r: Node(k, v)) +} + +pub opaque type Tree(k, v) { + Tree(root: Node(k, v), compare: fn(k, k) -> Order) +} + +pub fn new(compare: fn(k, k) -> Order) -> Tree(k, v) { + Tree(E, compare) +} + +pub fn clear(tree: Tree(k, v)) -> Tree(k, v) { + Tree(E, tree.compare) +} + +pub fn insert(tree: Tree(k, v), key: k, value: v) -> Tree(k, v) { + Tree(blacken(ins(tree.root, #(key, value), tree.compare)), tree.compare) +} + +pub fn delete(tree: Tree(k, v), key: k) -> Tree(k, v) { + Tree(del(redden(tree.root), key, tree.compare), tree.compare) +} + +pub fn find(tree: Tree(k, v), key: k) -> Result(#(k, v), Nil) { + do_find(tree.root, key, tree.compare) +} + +pub fn fold(tree: Tree(k, v), acc: b, fun: fn(b, k, v) -> b) -> b { + do_fold(tree.root, acc, fun) +} + +pub fn foldr(tree: Tree(k, v), acc: b, fun: fn(b, k, v) -> b) -> b { + do_foldr(tree.root, acc, fun) +} + +pub fn draw(tree: Tree(k, v), to_string: fn(k, v) -> String) -> String { + do_draw(tree.root, 0, to_string) +} + +fn ins(node: Node(k, v), x: #(k, v), compare: fn(k, k) -> Order) -> Node(k, v) { + case node { + E -> T(R, E, x, E) + T(c, k, y, b) -> + case compare(x.0, y.0) { + Lt -> balance(c, ins(k, x, compare), y, b) + Gt -> balance(c, k, y, ins(b, x, compare)) + Eq -> T(c, k, x, b) + } + _ -> node + } +} + +fn blacken(node: Node(k, v)) -> Node(k, v) { + case node { + T(R, T(R, _, _, _) as l, y, c) -> T(B, l, y, c) + T(R, k, x, T(R, _, _, _) as r) -> T(B, k, x, r) + t -> t + } +} + +fn balance(c: Color, l: Node(k, v), v: #(k, v), r: Node(k, v)) -> Node(k, v) { + case c, l, v, r { + B, T(R, T(R, k, x, b), y, c), z, d -> T(R, T(B, k, x, b), y, T(B, c, z, d)) + B, T(R, k, x, T(R, b, y, c)), z, d -> T(R, T(B, k, x, b), y, T(B, c, z, d)) + B, k, x, T(R, T(R, b, y, c), z, d) -> T(R, T(B, k, x, b), y, T(B, c, z, d)) + B, k, x, T(R, b, y, T(R, c, z, d)) -> T(R, T(B, k, x, b), y, T(B, c, z, d)) + BB, k, x, T(R, T(R, b, y, c), z, d) -> T(B, T(B, k, x, b), y, T(B, c, z, d)) + BB, T(R, k, x, T(R, b, y, c)), z, d -> T(B, T(B, k, x, b), y, T(B, c, z, d)) + c, k, x, b -> T(c, k, x, b) + } +} + +fn redden(node: Node(k, v)) -> Node(k, v) { + case node { + T(B, T(B, _, _, _) as l, y, T(B, _, _, _) as r) -> T(R, l, y, r) + t -> t + } +} + +fn del(node: Node(k, v), x: k, compare: fn(k, k) -> Order) -> Node(k, v) { + case node { + E -> node + T(R, E, y, E) -> + case compare(x, y.0) { + Eq -> E + _ -> node + } + T(B, E, y, E) -> + case compare(x, y.0) { + Eq -> EE + _ -> node + } + T(B, T(R, E, y, E) as l, z, E) -> + case compare(x, z.0) { + Lt -> T(B, del(l, x, compare), z, E) + Gt -> node + Eq -> T(B, E, y, E) + } + T(c, k, y, b) -> + case compare(x, y.0) { + Lt -> rotate(c, del(k, x, compare), y, b) + Gt -> rotate(c, k, y, del(b, x, compare)) + Eq -> + case min_del(b) { + Min(y1, b1) -> rotate(c, k, y1, b1) + None -> E + } + } + _ -> node + } +} + +fn rotate(c: Color, l: Node(k, v), v: #(k, v), r: Node(k, v)) -> Node(k, v) { + case c, l, v, r { + R, T(BB, k, x, b), y, T(B, c, z, d) -> + balance(B, T(R, T(B, k, x, b), y, c), z, d) + R, EE, y, T(B, c, z, d) -> balance(B, T(R, E, y, c), z, d) + R, T(B, k, x, b), y, T(BB, c, z, d) -> + balance(B, k, x, T(R, b, y, T(B, c, z, d))) + R, T(B, k, x, b), y, EE -> balance(B, k, x, T(R, b, y, E)) + B, T(BB, k, x, b), y, T(B, c, z, d) -> + balance(BB, T(R, T(B, k, x, b), y, c), z, d) + B, EE, y, T(B, c, z, d) -> balance(BB, T(R, E, y, c), z, d) + B, T(B, k, x, b), y, T(BB, c, z, d) -> + balance(BB, k, x, T(R, b, y, T(B, c, z, d))) + B, T(B, k, x, b), y, EE -> balance(BB, k, x, T(R, b, y, E)) + B, T(BB, k, w, b), x, T(R, T(B, c, y, d), z, e) -> + T(B, balance(B, T(R, T(B, k, w, b), x, c), y, d), z, e) + B, EE, x, T(R, T(B, c, y, d), z, e) -> + T(B, balance(B, T(R, E, x, c), y, d), z, e) + B, T(R, k, w, T(B, b, x, c)), y, T(BB, d, z, e) -> + T(B, k, w, balance(B, b, x, T(R, c, y, T(B, d, z, e)))) + B, T(R, k, w, T(B, b, x, c)), y, EE -> + T(B, k, w, balance(B, b, x, T(R, c, y, E))) + c, k, x, b -> T(c, k, x, b) + } +} + +type MinDel(k, v) { + Min(#(k, v), Node(k, v)) + None +} + +fn min_del(node: Node(k, v)) -> MinDel(k, v) { + case node { + T(R, E, x, E) -> Min(x, E) + T(B, E, x, E) -> Min(x, EE) + T(B, E, x, T(R, E, y, E)) -> Min(x, T(B, E, y, E)) + T(c, k, x, b) -> + case min_del(k) { + Min(x1, a1) -> Min(x1, rotate(c, a1, x, b)) + None -> None + } + _ -> None + } +} + +fn do_find( + node: Node(k, v), + key: k, + compare: fn(k, k) -> Order, +) -> Result(#(k, v), Nil) { + case node { + T(_, l, k, r) -> + case compare(key, k.0) { + Lt -> do_find(l, key, compare) + Gt -> do_find(r, key, compare) + Eq -> Ok(k) + } + _ -> Error(Nil) + } +} + +fn do_fold(node: Node(k, v), acc: a, fun: fn(a, k, v) -> a) -> a { + case node { + T(_, r, v, l) -> { + let acc = do_fold(r, acc, fun) + let acc = fun(acc, v.0, v.1) + let acc = do_fold(l, acc, fun) + acc + } + _ -> acc + } +} + +fn do_foldr(node: Node(k, v), acc: a, fun: fn(a, k, v) -> a) -> a { + case node { + T(_, r, v, l) -> { + let acc = do_foldr(l, acc, fun) + let acc = fun(acc, v.0, v.1) + let acc = do_foldr(r, acc, fun) + acc + } + _ -> acc + } +} + +fn do_indent(acc: String, i: Int) -> String { + case i { + 0 -> acc + i -> do_indent(". " <> acc, i - 1) + } +} + +fn do_draw( + node: Node(k, v), + indent: Int, + to_string: fn(k, v) -> String, +) -> String { + case node { + T(_, l, k, r) -> { + let ls = do_draw(l, indent + 1, to_string) + let ks = do_indent(to_string(k.0, k.1) <> "\n", indent) + let rs = do_draw(r, indent + 1, to_string) + ls <> ks <> rs + } + _ -> "" + } +} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl new file mode 100644 index 00000000000..5f24df08bcb --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl @@ -0,0 +1,90 @@ +-module(gleamy_structures@heap@leftist_heap). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, find_min/1, insert/2, delete_min/1]). +-export_type([t/1, heap/1]). + +-type t(FXL) :: e | {t, integer(), FXL, t(FXL), t(FXL)}. + +-opaque heap(FXM) :: {heap, t(FXM), fun((FXM, FXM) -> gleam@order:order())}. + +-spec new(fun((FXN, FXN) -> gleam@order:order())) -> heap(FXN). +new(Compare) -> + {heap, e, Compare}. + +-spec find_min(heap(FXS)) -> {ok, FXS} | {error, nil}. +find_min(Heap) -> + case erlang:element(2, Heap) of + {t, _, X, _, _} -> + {ok, X}; + + e -> + {error, nil} + end. + +-spec make(FYX, t(FYX), t(FYX)) -> t(FYX). +make(X, A, B) -> + Rank_a = case A of + {t, R, _, _, _} -> + R; + + e -> + 0 + end, + Rank_b = case B of + {t, R@1, _, _, _} -> + R@1; + + e -> + 0 + end, + case Rank_a < Rank_b of + true -> + {t, Rank_a + 1, X, B, A}; + + _ -> + {t, Rank_b + 1, X, A, B} + end. + +-spec merge(t(FYB), t(FYB), fun((FYB, FYB) -> gleam@order:order())) -> t(FYB). +merge(H1, H2, Compare) -> + case {H1, H2} of + {H, e} -> + H; + + {e, H@1} -> + H@1; + + {{t, _, X, A1, B1}, {t, _, Y, A2, B2}} -> + case Compare(X, Y) of + gt -> + make(Y, A2, merge(H1, B2, Compare)); + + _ -> + make(X, A1, merge(B1, H2, Compare)) + end + end. + +-spec insert(heap(FXP), FXP) -> heap(FXP). +insert(Heap, Item) -> + {heap, + merge( + {t, 1, Item, e, e}, + erlang:element(2, Heap), + erlang:element(3, Heap) + ), + erlang:element(3, Heap)}. + +-spec delete_min(heap(FXW)) -> {ok, {FXW, heap(FXW)}} | {error, nil}. +delete_min(Heap) -> + case erlang:element(2, Heap) of + {t, _, X, A, B} -> + {ok, + {X, + {heap, + merge(A, B, erlang:element(3, Heap)), + erlang:element(3, Heap)}}}; + + e -> + {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl new file mode 100644 index 00000000000..8677af51636 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl @@ -0,0 +1,75 @@ +-module(gleamy_structures@heap@pairing_heap). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, find_min/1, insert/2, delete_min/1]). +-export_type([t/1, heap/1]). + +-type t(EWV) :: e | {t, EWV, list(t(EWV))}. + +-opaque heap(EWW) :: {heap, t(EWW), fun((EWW, EWW) -> gleam@order:order())}. + +-spec new(fun((EWX, EWX) -> gleam@order:order())) -> heap(EWX). +new(Compare) -> + {heap, e, Compare}. + +-spec find_min(heap(EXC)) -> {ok, EXC} | {error, nil}. +find_min(Heap) -> + case erlang:element(2, Heap) of + {t, X, _} -> + {ok, X}; + + e -> + {error, nil} + end. + +-spec merge(t(EXL), t(EXL), fun((EXL, EXL) -> gleam@order:order())) -> t(EXL). +merge(X, Y, Compare) -> + case {X, Y} of + {X@1, e} -> + X@1; + + {e, Y@1} -> + Y@1; + + {{t, Xk, Xs}, {t, Yk, Ys}} -> + case Compare(Xk, Yk) of + gt -> + {t, Yk, [X | Ys]}; + + _ -> + {t, Xk, [Y | Xs]} + end + end. + +-spec insert(heap(EWZ), EWZ) -> heap(EWZ). +insert(Heap, Key) -> + {heap, + merge({t, Key, []}, erlang:element(2, Heap), erlang:element(3, Heap)), + erlang:element(3, Heap)}. + +-spec merge_pairs(list(t(EXP)), fun((EXP, EXP) -> gleam@order:order())) -> t(EXP). +merge_pairs(L, Compare) -> + case L of + [] -> + e; + + [H] -> + H; + + [H1, H2 | Hs] -> + merge(merge(H1, H2, Compare), merge_pairs(Hs, Compare), Compare) + end. + +-spec delete_min(heap(EXG)) -> {ok, {EXG, heap(EXG)}} | {error, nil}. +delete_min(Heap) -> + case erlang:element(2, Heap) of + {t, X, Xs} -> + {ok, + {X, + {heap, + merge_pairs(Xs, erlang:element(3, Heap)), + erlang:element(3, Heap)}}}; + + e -> + {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl new file mode 100644 index 00000000000..9a5dd176288 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl @@ -0,0 +1,121 @@ +-module(gleamy_structures@map). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, insert/3, find/2, has_key/2, delete/2, count/1, fold/3, filter/2, merge/2, from_list/2, to_list/1, take/2]). + +-spec new(fun((GVO, GVO) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree_kv:tree(GVO, any()). +new(Compare) -> + gleamy_structures@tree@red_black_tree_kv:new(Compare). + +-spec insert(gleamy_structures@tree@red_black_tree_kv:tree(GVS, GVT), GVS, GVT) -> gleamy_structures@tree@red_black_tree_kv:tree(GVS, GVT). +insert(Map, Key, Value) -> + gleamy_structures@tree@red_black_tree_kv:insert(Map, Key, Value). + +-spec find(gleamy_structures@tree@red_black_tree_kv:tree(GVY, GVZ), GVY) -> {ok, + {GVY, GVZ}} | + {error, nil}. +find(Map, Key) -> + gleamy_structures@tree@red_black_tree_kv:find(Map, Key). + +-spec has_key(gleamy_structures@tree@red_black_tree_kv:tree(GWE, any()), GWE) -> boolean(). +has_key(Map, Key) -> + case gleamy_structures@tree@red_black_tree_kv:find(Map, Key) of + {ok, _} -> + true; + + {error, _} -> + false + end. + +-spec delete(gleamy_structures@tree@red_black_tree_kv:tree(GWI, GWJ), GWI) -> gleamy_structures@tree@red_black_tree_kv:tree(GWI, GWJ). +delete(Map, Key) -> + gleamy_structures@tree@red_black_tree_kv:delete(Map, Key). + +-spec count(gleamy_structures@tree@red_black_tree_kv:tree(any(), any())) -> integer(). +count(Map) -> + gleamy_structures@tree@red_black_tree_kv:fold( + Map, + 0, + fun(A, _, _) -> A + 1 end + ). + +-spec fold( + gleamy_structures@tree@red_black_tree_kv:tree(GWS, GWT), + GWW, + fun((GWW, GWS, GWT) -> GWW) +) -> GWW. +fold(Map, Initial, Reducer) -> + gleamy_structures@tree@red_black_tree_kv:fold(Map, Initial, Reducer). + +-spec filter( + gleamy_structures@tree@red_black_tree_kv:tree(GWX, GWY), + fun((GWX, GWY) -> boolean()) +) -> gleamy_structures@tree@red_black_tree_kv:tree(GWX, GWY). +filter(Map, Property) -> + gleamy_structures@tree@red_black_tree_kv:fold( + Map, + Map, + fun(Map@1, K, V) -> case Property(K, V) of + true -> + Map@1; + + false -> + gleamy_structures@tree@red_black_tree_kv:delete(Map@1, K) + end end + ). + +-spec merge( + gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE), + gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE) +) -> gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE). +merge(First, Second) -> + gleamy_structures@tree@red_black_tree_kv:fold( + First, + Second, + fun(A, K, V) -> + gleamy_structures@tree@red_black_tree_kv:insert(A, K, V) + end + ). + +-spec from_list(list({GXS, GXT}), fun((GXS, GXS) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree_kv:tree(GXS, GXT). +from_list(Members, Compare) -> + gleam@list:fold( + Members, + gleamy_structures@tree@red_black_tree_kv:new(Compare), + fun(Tree, I) -> + gleamy_structures@tree@red_black_tree_kv:insert( + Tree, + erlang:element(1, I), + erlang:element(2, I) + ) + end + ). + +-spec to_list(gleamy_structures@tree@red_black_tree_kv:tree(GXX, GXY)) -> list({GXX, + GXY}). +to_list(Map) -> + gleamy_structures@tree@red_black_tree_kv:foldr( + Map, + [], + fun(A, K, V) -> [{K, V} | A] end + ). + +-spec take(gleamy_structures@tree@red_black_tree_kv:tree(GXL, GXM), list(GXL)) -> gleamy_structures@tree@red_black_tree_kv:tree(GXL, GXM). +take(Map, Desired) -> + case Desired of + [X | Xs] -> + case gleamy_structures@tree@red_black_tree_kv:find(Map, X) of + {ok, X@1} -> + gleamy_structures@tree@red_black_tree_kv:insert( + take(Map, Xs), + erlang:element(1, X@1), + erlang:element(2, X@1) + ); + + {error, _} -> + take(Map, Xs) + end; + + [] -> + gleamy_structures@tree@red_black_tree_kv:clear(Map) + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl new file mode 100644 index 00000000000..838f1d99840 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl @@ -0,0 +1,77 @@ +-module(gleamy_structures@non_empty_list). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([from_list/1, fold/3, count/1, filter/2, to_list/1, reverse/1, map/2]). +-export_type([non_empty_list/1]). + +-type non_empty_list(HAU) :: {'end', HAU} | {next, HAU, non_empty_list(HAU)}. + +-spec from_list(list(HBK)) -> {ok, non_empty_list(HBK)} | {error, nil}. +from_list(List) -> + case List of + [] -> + {error, nil}; + + [X | Xs] -> + {ok, + gleam@list:fold( + Xs, + {'end', X}, + fun(Acc, Item) -> {next, Item, Acc} end + )} + end. + +-spec fold(non_empty_list(HAV), HAX, fun((HAX, HAV) -> HAX)) -> HAX. +fold(List, Initial, Fun) -> + case List of + {'end', Item} -> + Fun(Initial, Item); + + {next, X, Xs} -> + fold(Xs, Fun(Initial, X), Fun) + end. + +-spec count(non_empty_list(any())) -> integer(). +count(List) -> + fold(List, 0, fun(Acc, _) -> Acc + 1 end). + +-spec filter(non_empty_list(HBE), fun((HBE) -> boolean())) -> list(HBE). +filter(List, Predicate) -> + _pipe = fold(List, [], fun(Acc, Item) -> case Predicate(Item) of + true -> + [Item | Acc]; + + false -> + Acc + end end), + gleam@list:reverse(_pipe). + +-spec to_list(non_empty_list(HBH)) -> list(HBH). +to_list(List) -> + _pipe = fold(List, [], fun(Acc, Item) -> [Item | Acc] end), + gleam@list:reverse(_pipe). + +-spec reverse(non_empty_list(HBP)) -> non_empty_list(HBP). +reverse(List) -> + case List of + {'end', _} -> + List; + + {next, X, Xs} -> + fold(Xs, {'end', X}, fun(Acc, X@1) -> {next, X@1, Acc} end) + end. + +-spec map(non_empty_list(HBA), fun((HBA) -> HBC)) -> non_empty_list(HBC). +map(List, Transform) -> + case List of + {'end', X} -> + {'end', Transform(X)}; + + {next, X@1, Xs} -> + _pipe = fold( + Xs, + {'end', Transform(X@1)}, + fun(Acc, Item) -> {next, Transform(Item), Acc} end + ), + reverse(_pipe) + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl new file mode 100644 index 00000000000..7537469dd3c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl @@ -0,0 +1,74 @@ +-module(gleamy_structures@priority_queue). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([is_empty/1, new/1, from_list/2, pop/1, peek/1, push/2, count/1, reorder/2, to_list/1]). + +-spec is_empty(gleamy_structures@heap@pairing_heap:heap(any())) -> boolean(). +is_empty(Queue) -> + case gleamy_structures@heap@pairing_heap:find_min(Queue) of + {ok, _} -> + false; + + {error, _} -> + true + end. + +-spec new(fun((EZX, EZX) -> gleam@order:order())) -> gleamy_structures@heap@pairing_heap:heap(EZX). +new(Compare) -> + gleamy_structures@heap@pairing_heap:new(Compare). + +-spec from_list(list(EZQ), fun((EZQ, EZQ) -> gleam@order:order())) -> gleamy_structures@heap@pairing_heap:heap(EZQ). +from_list(List, Compare) -> + gleam@list:fold( + List, + new(Compare), + fun gleamy_structures@heap@pairing_heap:insert/2 + ). + +-spec pop(gleamy_structures@heap@pairing_heap:heap(EZZ)) -> {ok, + {EZZ, gleamy_structures@heap@pairing_heap:heap(EZZ)}} | + {error, nil}. +pop(Queue) -> + gleamy_structures@heap@pairing_heap:delete_min(Queue). + +-spec peek(gleamy_structures@heap@pairing_heap:heap(FAE)) -> {ok, FAE} | + {error, nil}. +peek(Queue) -> + gleamy_structures@heap@pairing_heap:find_min(Queue). + +-spec push(gleamy_structures@heap@pairing_heap:heap(FAI), FAI) -> gleamy_structures@heap@pairing_heap:heap(FAI). +push(Queue, Item) -> + gleamy_structures@heap@pairing_heap:insert(Queue, Item). + +-spec count(gleamy_structures@heap@pairing_heap:heap(any())) -> integer(). +count(Queue) -> + case gleamy_structures@heap@pairing_heap:delete_min(Queue) of + {ok, {_, Q}} -> + count(Q) + 1; + + {error, _} -> + 0 + end. + +-spec reorder( + gleamy_structures@heap@pairing_heap:heap(FAL), + fun((FAL, FAL) -> gleam@order:order()) +) -> gleamy_structures@heap@pairing_heap:heap(FAL). +reorder(Queue, Compare) -> + case gleamy_structures@heap@pairing_heap:delete_min(Queue) of + {ok, {X, Q}} -> + gleamy_structures@heap@pairing_heap:insert(reorder(Q, Compare), X); + + {error, _} -> + gleamy_structures@heap@pairing_heap:new(Compare) + end. + +-spec to_list(gleamy_structures@heap@pairing_heap:heap(FAO)) -> list(FAO). +to_list(Queue) -> + case gleamy_structures@heap@pairing_heap:delete_min(Queue) of + {ok, {X, Q}} -> + [X | to_list(Q)]; + + {error, _} -> + [] + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl new file mode 100644 index 00000000000..38ccc7a19a4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl @@ -0,0 +1,123 @@ +-module(gleamy_structures@set). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([contains/2, delete/2, filter/2, fold/3, from_list/2, insert/2, intersection/2, new/1, count/1, to_list/1, union/2, take/2]). + +-spec contains(gleamy_structures@tree@red_black_tree:tree(FTU), FTU) -> boolean(). +contains(Set, Member) -> + case gleamy_structures@tree@red_black_tree:find(Set, Member) of + {ok, _} -> + true; + + {error, _} -> + false + end. + +-spec delete(gleamy_structures@tree@red_black_tree:tree(FTW), FTW) -> gleamy_structures@tree@red_black_tree:tree(FTW). +delete(Set, Member) -> + gleamy_structures@tree@red_black_tree:delete(Set, Member). + +-spec filter( + gleamy_structures@tree@red_black_tree:tree(FTZ), + fun((FTZ) -> boolean()) +) -> gleamy_structures@tree@red_black_tree:tree(FTZ). +filter(Set, Property) -> + gleamy_structures@tree@red_black_tree:fold( + Set, + Set, + fun(Set@1, I) -> case Property(I) of + true -> + Set@1; + + false -> + gleamy_structures@tree@red_black_tree:delete(Set@1, I) + end end + ). + +-spec fold( + gleamy_structures@tree@red_black_tree:tree(FUC), + FUE, + fun((FUE, FUC) -> FUE) +) -> FUE. +fold(Set, Initial, Reducer) -> + gleamy_structures@tree@red_black_tree:fold(Set, Initial, Reducer). + +-spec from_list(list(FUF), fun((FUF, FUF) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree:tree(FUF). +from_list(Members, Compare) -> + gleam@list:fold( + Members, + gleamy_structures@tree@red_black_tree:new(Compare), + fun gleamy_structures@tree@red_black_tree:insert/2 + ). + +-spec insert(gleamy_structures@tree@red_black_tree:tree(FUI), FUI) -> gleamy_structures@tree@red_black_tree:tree(FUI). +insert(Set, Member) -> + gleamy_structures@tree@red_black_tree:insert(Set, Member). + +-spec intersection( + gleamy_structures@tree@red_black_tree:tree(FUL), + gleamy_structures@tree@red_black_tree:tree(FUL) +) -> gleamy_structures@tree@red_black_tree:tree(FUL). +intersection(First, Second) -> + gleamy_structures@tree@red_black_tree:fold( + Second, + gleamy_structures@tree@red_black_tree:clear(First), + fun(A, I) -> + case gleamy_structures@tree@red_black_tree:find(First, I) of + {ok, _} -> + gleamy_structures@tree@red_black_tree:insert(A, I); + + {error, _} -> + A + end + end + ). + +-spec new(fun((FUP, FUP) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree:tree(FUP). +new(Compare) -> + gleamy_structures@tree@red_black_tree:new(Compare). + +-spec count(gleamy_structures@tree@red_black_tree:tree(any())) -> integer(). +count(Set) -> + gleamy_structures@tree@red_black_tree:fold(Set, 0, fun(A, _) -> A + 1 end). + +-spec to_list(gleamy_structures@tree@red_black_tree:tree(FUX)) -> list(FUX). +to_list(Set) -> + gleamy_structures@tree@red_black_tree:foldr( + Set, + [], + fun(A, I) -> + gleam@io:println(gleam@string:inspect(I)), + [I | A] + end + ). + +-spec union( + gleamy_structures@tree@red_black_tree:tree(FVA), + gleamy_structures@tree@red_black_tree:tree(FVA) +) -> gleamy_structures@tree@red_black_tree:tree(FVA). +union(First, Second) -> + gleamy_structures@tree@red_black_tree:fold( + First, + Second, + fun(A, I) -> gleamy_structures@tree@red_black_tree:insert(A, I) end + ). + +-spec take(gleamy_structures@tree@red_black_tree:tree(FUT), list(FUT)) -> gleamy_structures@tree@red_black_tree:tree(FUT). +take(Set, Desired) -> + case Desired of + [X | Xs] -> + case gleamy_structures@tree@red_black_tree:find(Set, X) of + {ok, X@1} -> + gleamy_structures@tree@red_black_tree:insert( + take(Set, Xs), + X@1 + ); + + {error, _} -> + take(Set, Xs) + end; + + [] -> + gleamy_structures@tree@red_black_tree:clear(Set) + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl new file mode 100644 index 00000000000..296ea98d2e4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl @@ -0,0 +1,167 @@ +-module(gleamy_structures@tree@binary_search_tree). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, clear/1, insert/2, delete/2, find/2, fold/3, draw/2]). +-export_type([node_/1, tree/1]). + +-type node_(FCI) :: empty | {node, node_(FCI), FCI, node_(FCI)}. + +-opaque tree(FCJ) :: {tree, node_(FCJ), fun((FCJ, FCJ) -> gleam@order:order())}. + +-spec new(fun((FCK, FCK) -> gleam@order:order())) -> tree(FCK). +new(Compare) -> + {tree, empty, Compare}. + +-spec clear(tree(FCM)) -> tree(FCM). +clear(Tree) -> + {tree, empty, erlang:element(3, Tree)}. + +-spec do_insert(node_(FCP), FCP, fun((FCP, FCP) -> gleam@order:order())) -> node_(FCP). +do_insert(Node, Key, Compare) -> + case Node of + {node, L, K, R} -> + case Compare(Key, K) of + lt -> + {node, do_insert(L, Key, Compare), K, R}; + + gt -> + {node, L, K, do_insert(R, Key, Compare)}; + + eq -> + {node, L, Key, R} + end; + + empty -> + {node, empty, Key, empty} + end. + +-spec insert(tree(FCP), FCP) -> tree(FCP). +insert(Tree, Key) -> + {tree, + do_insert(erlang:element(2, Tree), Key, erlang:element(3, Tree)), + erlang:element(3, Tree)}. + +-spec do_delete(node_(FCS), FCS, fun((FCS, FCS) -> gleam@order:order())) -> node_(FCS). +do_delete(Node, Key, Compare) -> + case Node of + {node, L, K, R} -> + case Compare(Key, K) of + lt -> + {node, do_delete(L, Key, Compare), K, R}; + + gt -> + {node, L, K, do_delete(R, Key, Compare)}; + + eq -> + case Node of + {node, empty, _, R@1} -> + R@1; + + {node, L@1, _, empty} -> + L@1; + + {node, L@2, _, R@2} -> + case do_min(R@2, Compare) of + {node, _, Mk, _} -> + {node, L@2, Mk, do_delete(R@2, Mk, Compare)}; + + empty -> + empty + end; + + empty -> + empty + end + end; + + empty -> + empty + end. + +-spec delete(tree(FCS), FCS) -> tree(FCS). +delete(Tree, Key) -> + {tree, + do_delete(erlang:element(2, Tree), Key, erlang:element(3, Tree)), + erlang:element(3, Tree)}. + +-spec do_find(node_(FCV), FCV, fun((FCV, FCV) -> gleam@order:order())) -> {ok, + FCV} | + {error, nil}. +do_find(Node, Key, Compare) -> + case Node of + {node, L, K, R} -> + case Compare(Key, K) of + lt -> + do_find(L, Key, Compare); + + gt -> + do_find(R, Key, Compare); + + eq -> + {ok, K} + end; + + empty -> + {error, nil} + end. + +-spec find(tree(FCV), FCV) -> {ok, FCV} | {error, nil}. +find(Tree, Key) -> + do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). + +-spec do_fold(node_(FCZ), FDB, fun((FDB, FCZ) -> FDB)) -> FDB. +do_fold(Node, Acc, Fun) -> + case Node of + {node, R, V, L} -> + Acc@1 = do_fold(R, Acc, Fun), + Acc@2 = Fun(Acc@1, V), + Acc@3 = do_fold(L, Acc@2, Fun), + Acc@3; + + empty -> + Acc + end. + +-spec fold(tree(FCZ), FDB, fun((FDB, FCZ) -> FDB)) -> FDB. +fold(Tree, Acc, Fun) -> + do_fold(erlang:element(2, Tree), Acc, Fun). + +-spec do_draw(node_(FDC), integer(), fun((FDC) -> binary())) -> binary(). +do_draw(Node, Indent, To_string) -> + case Node of + {node, L, K, R} -> + Ls = do_draw(L, Indent + 1, To_string), + Ks = do_indent(<<(To_string(K))/binary, "\n"/utf8>>, Indent), + Rs = do_draw(R, Indent + 1, To_string), + <<<>/binary, Rs/binary>>; + + empty -> + <<""/utf8>> + end. + +-spec draw(tree(FDC), fun((FDC) -> binary())) -> binary(). +draw(Tree, To_string) -> + do_draw(erlang:element(2, Tree), 0, To_string). + +-spec do_min(node_(FCS), fun((FCS, FCS) -> gleam@order:order())) -> node_(FCS). +do_min(Node, Compare) -> + case Node of + {node, {node, _, _, _} = L, _, _} -> + do_min(L, Compare); + + {node, empty, _, _} -> + Node; + + empty -> + empty + end. + +-spec do_indent(binary(), integer()) -> binary(). +do_indent(Acc, I) -> + case I of + 0 -> + Acc; + + I@1 -> + do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl new file mode 100644 index 00000000000..c29bbebf903 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl @@ -0,0 +1,326 @@ +-module(gleamy_structures@tree@red_black_tree). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, clear/1, insert/2, delete/2, find/2, fold/3, foldr/3, draw/2]). +-export_type([color/0, node_/1, tree/1, min_del/1]). + +-type color() :: r | b | bb. + +-type node_(FHR) :: e | ee | {t, color(), node_(FHR), FHR, node_(FHR)}. + +-opaque tree(FHS) :: {tree, node_(FHS), fun((FHS, FHS) -> gleam@order:order())}. + +-type min_del(FHT) :: {min, FHT, node_(FHT)} | none. + +-spec new(fun((FHU, FHU) -> gleam@order:order())) -> tree(FHU). +new(Compare) -> + {tree, e, Compare}. + +-spec clear(tree(FHW)) -> tree(FHW). +clear(Tree) -> + {tree, e, erlang:element(3, Tree)}. + +-spec blacken(node_(FIW)) -> node_(FIW). +blacken(Node) -> + case Node of + {t, r, {t, r, _, _, _} = L, Y, C} -> + {t, b, L, Y, C}; + + {t, r, A, X, {t, r, _, _, _} = R} -> + {t, b, A, X, R}; + + T -> + T + end. + +-spec balance(color(), node_(FIZ), FIZ, node_(FIZ)) -> node_(FIZ). +balance(C, L, V, R) -> + case {C, L, V, R} of + {b, {t, r, {t, r, A, X, B}, Y, C@1}, Z, D} -> + {t, r, {t, b, A, X, B}, Y, {t, b, C@1, Z, D}}; + + {b, {t, r, A@1, X@1, {t, r, B@1, Y@1, C@2}}, Z@1, D@1} -> + {t, r, {t, b, A@1, X@1, B@1}, Y@1, {t, b, C@2, Z@1, D@1}}; + + {b, A@2, X@2, {t, r, {t, r, B@2, Y@2, C@3}, Z@2, D@2}} -> + {t, r, {t, b, A@2, X@2, B@2}, Y@2, {t, b, C@3, Z@2, D@2}}; + + {b, A@3, X@3, {t, r, B@3, Y@3, {t, r, C@4, Z@3, D@3}}} -> + {t, r, {t, b, A@3, X@3, B@3}, Y@3, {t, b, C@4, Z@3, D@3}}; + + {bb, A@4, X@4, {t, r, {t, r, B@4, Y@4, C@5}, Z@4, D@4}} -> + {t, b, {t, b, A@4, X@4, B@4}, Y@4, {t, b, C@5, Z@4, D@4}}; + + {bb, {t, r, A@5, X@5, {t, r, B@5, Y@5, C@6}}, Z@5, D@5} -> + {t, b, {t, b, A@5, X@5, B@5}, Y@5, {t, b, C@6, Z@5, D@5}}; + + {C@7, A@6, X@6, B@6} -> + {t, C@7, A@6, X@6, B@6} + end. + +-spec redden(node_(FJD)) -> node_(FJD). +redden(Node) -> + case Node of + {t, b, {t, b, _, _, _} = L, Y, {t, b, _, _, _} = R} -> + {t, r, L, Y, R}; + + T -> + T + end. + +-spec rotate(color(), node_(FJK), FJK, node_(FJK)) -> node_(FJK). +rotate(C, L, V, R) -> + case {C, L, V, R} of + {r, {t, bb, A, X, B}, Y, {t, b, C@1, Z, D}} -> + balance(b, {t, r, {t, b, A, X, B}, Y, C@1}, Z, D); + + {r, ee, Y@1, {t, b, C@2, Z@1, D@1}} -> + balance(b, {t, r, e, Y@1, C@2}, Z@1, D@1); + + {r, {t, b, A@1, X@1, B@1}, Y@2, {t, bb, C@3, Z@2, D@2}} -> + balance(b, A@1, X@1, {t, r, B@1, Y@2, {t, b, C@3, Z@2, D@2}}); + + {r, {t, b, A@2, X@2, B@2}, Y@3, ee} -> + balance(b, A@2, X@2, {t, r, B@2, Y@3, e}); + + {b, {t, bb, A@3, X@3, B@3}, Y@4, {t, b, C@4, Z@3, D@3}} -> + balance(bb, {t, r, {t, b, A@3, X@3, B@3}, Y@4, C@4}, Z@3, D@3); + + {b, ee, Y@5, {t, b, C@5, Z@4, D@4}} -> + balance(bb, {t, r, e, Y@5, C@5}, Z@4, D@4); + + {b, {t, b, A@4, X@4, B@4}, Y@6, {t, bb, C@6, Z@5, D@5}} -> + balance(bb, A@4, X@4, {t, r, B@4, Y@6, {t, b, C@6, Z@5, D@5}}); + + {b, {t, b, A@5, X@5, B@5}, Y@7, ee} -> + balance(bb, A@5, X@5, {t, r, B@5, Y@7, e}); + + {b, {t, bb, A@6, W, B@6}, X@6, {t, r, {t, b, C@7, Y@8, D@6}, Z@6, E}} -> + {t, + b, + balance(b, {t, r, {t, b, A@6, W, B@6}, X@6, C@7}, Y@8, D@6), + Z@6, + E}; + + {b, ee, X@7, {t, r, {t, b, C@8, Y@9, D@7}, Z@7, E@1}} -> + {t, b, balance(b, {t, r, e, X@7, C@8}, Y@9, D@7), Z@7, E@1}; + + {b, + {t, r, A@7, W@1, {t, b, B@7, X@8, C@9}}, + Y@10, + {t, bb, D@8, Z@8, E@2}} -> + {t, + b, + A@7, + W@1, + balance(b, B@7, X@8, {t, r, C@9, Y@10, {t, b, D@8, Z@8, E@2}})}; + + {b, {t, r, A@8, W@2, {t, b, B@8, X@9, C@10}}, Y@11, ee} -> + {t, b, A@8, W@2, balance(b, B@8, X@9, {t, r, C@10, Y@11, e})}; + + {C@11, A@9, X@10, B@9} -> + {t, C@11, A@9, X@10, B@9} + end. + +-spec ins(node_(FHZ), FHZ, fun((FHZ, FHZ) -> gleam@order:order())) -> node_(FHZ). +ins(Node, X, Compare) -> + case Node of + e -> + {t, r, e, X, e}; + + {t, C, A, Y, B} -> + case Compare(X, Y) of + lt -> + balance(C, ins(A, X, Compare), Y, B); + + gt -> + balance(C, A, Y, ins(B, X, Compare)); + + eq -> + {t, C, A, X, B} + end; + + _ -> + Node + end. + +-spec insert(tree(FHZ), FHZ) -> tree(FHZ). +insert(Tree, Key) -> + {tree, + blacken(ins(erlang:element(2, Tree), Key, erlang:element(3, Tree))), + erlang:element(3, Tree)}. + +-spec del(node_(FIC), FIC, fun((FIC, FIC) -> gleam@order:order())) -> node_(FIC). +del(Node, X, Compare) -> + case Node of + e -> + Node; + + {t, r, e, Y, e} -> + case Compare(X, Y) of + eq -> + e; + + _ -> + Node + end; + + {t, b, e, Y@1, e} -> + case Compare(X, Y@1) of + eq -> + ee; + + _ -> + Node + end; + + {t, b, {t, r, e, Y@2, e} = L, Z, e} -> + case Compare(X, Z) of + lt -> + {t, b, del(L, X, Compare), Z, e}; + + gt -> + Node; + + eq -> + {t, b, e, Y@2, e} + end; + + {t, C, A, Y@3, B} -> + case Compare(X, Y@3) of + lt -> + rotate(C, del(A, X, Compare), Y@3, B); + + gt -> + rotate(C, A, Y@3, del(B, X, Compare)); + + eq -> + case min_del(B) of + {min, Y1, B1} -> + rotate(C, A, Y1, B1); + + none -> + e + end + end; + + _ -> + Node + end. + +-spec delete(tree(FIC), FIC) -> tree(FIC). +delete(Tree, Key) -> + {tree, + del(redden(erlang:element(2, Tree)), Key, erlang:element(3, Tree)), + erlang:element(3, Tree)}. + +-spec do_find(node_(FIF), FIF, fun((FIF, FIF) -> gleam@order:order())) -> {ok, + FIF} | + {error, nil}. +do_find(Node, Key, Compare) -> + case Node of + {t, _, L, K, R} -> + case Compare(Key, K) of + lt -> + do_find(L, Key, Compare); + + gt -> + do_find(R, Key, Compare); + + eq -> + {ok, K} + end; + + _ -> + {error, nil} + end. + +-spec find(tree(FIF), FIF) -> {ok, FIF} | {error, nil}. +find(Tree, Key) -> + do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). + +-spec do_fold(node_(FIJ), FIL, fun((FIL, FIJ) -> FIL)) -> FIL. +do_fold(Node, Acc, Fun) -> + case Node of + {t, _, R, V, L} -> + Acc@1 = do_fold(R, Acc, Fun), + Acc@2 = Fun(Acc@1, V), + Acc@3 = do_fold(L, Acc@2, Fun), + Acc@3; + + _ -> + Acc + end. + +-spec fold(tree(FIJ), FIL, fun((FIL, FIJ) -> FIL)) -> FIL. +fold(Tree, Acc, Fun) -> + do_fold(erlang:element(2, Tree), Acc, Fun). + +-spec do_foldr(node_(FIM), FIO, fun((FIO, FIM) -> FIO)) -> FIO. +do_foldr(Node, Acc, Fun) -> + case Node of + {t, _, R, V, L} -> + Acc@1 = do_foldr(L, Acc, Fun), + Acc@2 = Fun(Acc@1, V), + Acc@3 = do_foldr(R, Acc@2, Fun), + Acc@3; + + _ -> + Acc + end. + +-spec foldr(tree(FIM), FIO, fun((FIO, FIM) -> FIO)) -> FIO. +foldr(Tree, Acc, Fun) -> + do_foldr(erlang:element(2, Tree), Acc, Fun). + +-spec do_draw(node_(FIP), integer(), fun((FIP) -> binary())) -> binary(). +do_draw(Node, Indent, To_string) -> + case Node of + {t, _, L, K, R} -> + Ls = do_draw(L, Indent + 1, To_string), + Ks = do_indent(<<(To_string(K))/binary, "\n"/utf8>>, Indent), + Rs = do_draw(R, Indent + 1, To_string), + <<<>/binary, Rs/binary>>; + + _ -> + <<""/utf8>> + end. + +-spec draw(tree(FIP), fun((FIP) -> binary())) -> binary(). +draw(Tree, To_string) -> + do_draw(erlang:element(2, Tree), 0, To_string). + +-spec min_del(node_(any())) -> min_del(any()). +min_del(Node) -> + case Node of + {t, r, e, X, e} -> + {min, X, e}; + + {t, b, e, X@1, e} -> + {min, X@1, ee}; + + {t, b, e, X@2, {t, r, e, Y, e}} -> + {min, X@2, {t, b, e, Y, e}}; + + {t, C, A, X@3, B} -> + case min_del(A) of + {min, X1, A1} -> + {min, X1, rotate(C, A1, X@3, B)}; + + none -> + none + end; + + _ -> + none + end. + +-spec do_indent(binary(), integer()) -> binary(). +do_indent(Acc, I) -> + case I of + 0 -> + Acc; + + I@1 -> + do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) + end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl new file mode 100644 index 00000000000..710e27d32c4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl @@ -0,0 +1,336 @@ +-module(gleamy_structures@tree@red_black_tree_kv). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, clear/1, insert/3, delete/2, find/2, fold/3, foldr/3, draw/2]). +-export_type([color/0, node_/2, tree/2, min_del/2]). + +-type color() :: r | b | bb. + +-type node_(GAH, GAI) :: e | + ee | + {t, color(), node_(GAH, GAI), {GAH, GAI}, node_(GAH, GAI)}. + +-opaque tree(GAJ, GAK) :: {tree, + node_(GAJ, GAK), + fun((GAJ, GAJ) -> gleam@order:order())}. + +-type min_del(GAL, GAM) :: {min, {GAL, GAM}, node_(GAL, GAM)} | none. + +-spec new(fun((GAN, GAN) -> gleam@order:order())) -> tree(GAN, any()). +new(Compare) -> + {tree, e, Compare}. + +-spec clear(tree(GAR, GAS)) -> tree(GAR, GAS). +clear(Tree) -> + {tree, e, erlang:element(3, Tree)}. + +-spec blacken(node_(GCJ, GCK)) -> node_(GCJ, GCK). +blacken(Node) -> + case Node of + {t, r, {t, r, _, _, _} = L, Y, C} -> + {t, b, L, Y, C}; + + {t, r, K, X, {t, r, _, _, _} = R} -> + {t, b, K, X, R}; + + T -> + T + end. + +-spec balance(color(), node_(GCP, GCQ), {GCP, GCQ}, node_(GCP, GCQ)) -> node_(GCP, GCQ). +balance(C, L, V, R) -> + case {C, L, V, R} of + {b, {t, r, {t, r, K, X, B}, Y, C@1}, Z, D} -> + {t, r, {t, b, K, X, B}, Y, {t, b, C@1, Z, D}}; + + {b, {t, r, K@1, X@1, {t, r, B@1, Y@1, C@2}}, Z@1, D@1} -> + {t, r, {t, b, K@1, X@1, B@1}, Y@1, {t, b, C@2, Z@1, D@1}}; + + {b, K@2, X@2, {t, r, {t, r, B@2, Y@2, C@3}, Z@2, D@2}} -> + {t, r, {t, b, K@2, X@2, B@2}, Y@2, {t, b, C@3, Z@2, D@2}}; + + {b, K@3, X@3, {t, r, B@3, Y@3, {t, r, C@4, Z@3, D@3}}} -> + {t, r, {t, b, K@3, X@3, B@3}, Y@3, {t, b, C@4, Z@3, D@3}}; + + {bb, K@4, X@4, {t, r, {t, r, B@4, Y@4, C@5}, Z@4, D@4}} -> + {t, b, {t, b, K@4, X@4, B@4}, Y@4, {t, b, C@5, Z@4, D@4}}; + + {bb, {t, r, K@5, X@5, {t, r, B@5, Y@5, C@6}}, Z@5, D@5} -> + {t, b, {t, b, K@5, X@5, B@5}, Y@5, {t, b, C@6, Z@5, D@5}}; + + {C@7, K@6, X@6, B@6} -> + {t, C@7, K@6, X@6, B@6} + end. + +-spec redden(node_(GCX, GCY)) -> node_(GCX, GCY). +redden(Node) -> + case Node of + {t, b, {t, b, _, _, _} = L, Y, {t, b, _, _, _} = R} -> + {t, r, L, Y, R}; + + T -> + T + end. + +-spec rotate(color(), node_(GDJ, GDK), {GDJ, GDK}, node_(GDJ, GDK)) -> node_(GDJ, GDK). +rotate(C, L, V, R) -> + case {C, L, V, R} of + {r, {t, bb, K, X, B}, Y, {t, b, C@1, Z, D}} -> + balance(b, {t, r, {t, b, K, X, B}, Y, C@1}, Z, D); + + {r, ee, Y@1, {t, b, C@2, Z@1, D@1}} -> + balance(b, {t, r, e, Y@1, C@2}, Z@1, D@1); + + {r, {t, b, K@1, X@1, B@1}, Y@2, {t, bb, C@3, Z@2, D@2}} -> + balance(b, K@1, X@1, {t, r, B@1, Y@2, {t, b, C@3, Z@2, D@2}}); + + {r, {t, b, K@2, X@2, B@2}, Y@3, ee} -> + balance(b, K@2, X@2, {t, r, B@2, Y@3, e}); + + {b, {t, bb, K@3, X@3, B@3}, Y@4, {t, b, C@4, Z@3, D@3}} -> + balance(bb, {t, r, {t, b, K@3, X@3, B@3}, Y@4, C@4}, Z@3, D@3); + + {b, ee, Y@5, {t, b, C@5, Z@4, D@4}} -> + balance(bb, {t, r, e, Y@5, C@5}, Z@4, D@4); + + {b, {t, b, K@4, X@4, B@4}, Y@6, {t, bb, C@6, Z@5, D@5}} -> + balance(bb, K@4, X@4, {t, r, B@4, Y@6, {t, b, C@6, Z@5, D@5}}); + + {b, {t, b, K@5, X@5, B@5}, Y@7, ee} -> + balance(bb, K@5, X@5, {t, r, B@5, Y@7, e}); + + {b, {t, bb, K@6, W, B@6}, X@6, {t, r, {t, b, C@7, Y@8, D@6}, Z@6, E}} -> + {t, + b, + balance(b, {t, r, {t, b, K@6, W, B@6}, X@6, C@7}, Y@8, D@6), + Z@6, + E}; + + {b, ee, X@7, {t, r, {t, b, C@8, Y@9, D@7}, Z@7, E@1}} -> + {t, b, balance(b, {t, r, e, X@7, C@8}, Y@9, D@7), Z@7, E@1}; + + {b, + {t, r, K@7, W@1, {t, b, B@7, X@8, C@9}}, + Y@10, + {t, bb, D@8, Z@8, E@2}} -> + {t, + b, + K@7, + W@1, + balance(b, B@7, X@8, {t, r, C@9, Y@10, {t, b, D@8, Z@8, E@2}})}; + + {b, {t, r, K@8, W@2, {t, b, B@8, X@9, C@10}}, Y@11, ee} -> + {t, b, K@8, W@2, balance(b, B@8, X@9, {t, r, C@10, Y@11, e})}; + + {C@11, K@9, X@10, B@9} -> + {t, C@11, K@9, X@10, B@9} + end. + +-spec ins(node_(GCD, GCE), {GCD, GCE}, fun((GCD, GCD) -> gleam@order:order())) -> node_(GCD, GCE). +ins(Node, X, Compare) -> + case Node of + e -> + {t, r, e, X, e}; + + {t, C, K, Y, B} -> + case Compare(erlang:element(1, X), erlang:element(1, Y)) of + lt -> + balance(C, ins(K, X, Compare), Y, B); + + gt -> + balance(C, K, Y, ins(B, X, Compare)); + + eq -> + {t, C, K, X, B} + end; + + _ -> + Node + end. + +-spec insert(tree(GAX, GAY), GAX, GAY) -> tree(GAX, GAY). +insert(Tree, Key, Value) -> + {tree, + blacken( + ins(erlang:element(2, Tree), {Key, Value}, erlang:element(3, Tree)) + ), + erlang:element(3, Tree)}. + +-spec del(node_(GDD, GDE), GDD, fun((GDD, GDD) -> gleam@order:order())) -> node_(GDD, GDE). +del(Node, X, Compare) -> + case Node of + e -> + Node; + + {t, r, e, Y, e} -> + case Compare(X, erlang:element(1, Y)) of + eq -> + e; + + _ -> + Node + end; + + {t, b, e, Y@1, e} -> + case Compare(X, erlang:element(1, Y@1)) of + eq -> + ee; + + _ -> + Node + end; + + {t, b, {t, r, e, Y@2, e} = L, Z, e} -> + case Compare(X, erlang:element(1, Z)) of + lt -> + {t, b, del(L, X, Compare), Z, e}; + + gt -> + Node; + + eq -> + {t, b, e, Y@2, e} + end; + + {t, C, K, Y@3, B} -> + case Compare(X, erlang:element(1, Y@3)) of + lt -> + rotate(C, del(K, X, Compare), Y@3, B); + + gt -> + rotate(C, K, Y@3, del(B, X, Compare)); + + eq -> + case min_del(B) of + {min, Y1, B1} -> + rotate(C, K, Y1, B1); + + none -> + e + end + end; + + _ -> + Node + end. + +-spec delete(tree(GBD, GBE), GBD) -> tree(GBD, GBE). +delete(Tree, Key) -> + {tree, + del(redden(erlang:element(2, Tree)), Key, erlang:element(3, Tree)), + erlang:element(3, Tree)}. + +-spec do_find(node_(GDX, GDY), GDX, fun((GDX, GDX) -> gleam@order:order())) -> {ok, + {GDX, GDY}} | + {error, nil}. +do_find(Node, Key, Compare) -> + case Node of + {t, _, L, K, R} -> + case Compare(Key, erlang:element(1, K)) of + lt -> + do_find(L, Key, Compare); + + gt -> + do_find(R, Key, Compare); + + eq -> + {ok, K} + end; + + _ -> + {error, nil} + end. + +-spec find(tree(GBJ, GBK), GBJ) -> {ok, {GBJ, GBK}} | {error, nil}. +find(Tree, Key) -> + do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). + +-spec do_fold(node_(GED, GEE), GEH, fun((GEH, GED, GEE) -> GEH)) -> GEH. +do_fold(Node, Acc, Fun) -> + case Node of + {t, _, R, V, L} -> + Acc@1 = do_fold(R, Acc, Fun), + Acc@2 = Fun(Acc@1, erlang:element(1, V), erlang:element(2, V)), + Acc@3 = do_fold(L, Acc@2, Fun), + Acc@3; + + _ -> + Acc + end. + +-spec fold(tree(GBP, GBQ), GBT, fun((GBT, GBP, GBQ) -> GBT)) -> GBT. +fold(Tree, Acc, Fun) -> + do_fold(erlang:element(2, Tree), Acc, Fun). + +-spec do_foldr(node_(GEI, GEJ), GEM, fun((GEM, GEI, GEJ) -> GEM)) -> GEM. +do_foldr(Node, Acc, Fun) -> + case Node of + {t, _, R, V, L} -> + Acc@1 = do_foldr(L, Acc, Fun), + Acc@2 = Fun(Acc@1, erlang:element(1, V), erlang:element(2, V)), + Acc@3 = do_foldr(R, Acc@2, Fun), + Acc@3; + + _ -> + Acc + end. + +-spec foldr(tree(GBU, GBV), GBY, fun((GBY, GBU, GBV) -> GBY)) -> GBY. +foldr(Tree, Acc, Fun) -> + do_foldr(erlang:element(2, Tree), Acc, Fun). + +-spec do_draw(node_(GEN, GEO), integer(), fun((GEN, GEO) -> binary())) -> binary(). +do_draw(Node, Indent, To_string) -> + case Node of + {t, _, L, K, R} -> + Ls = do_draw(L, Indent + 1, To_string), + Ks = do_indent( + <<(To_string(erlang:element(1, K), erlang:element(2, K)))/binary, + "\n"/utf8>>, + Indent + ), + Rs = do_draw(R, Indent + 1, To_string), + <<<>/binary, Rs/binary>>; + + _ -> + <<""/utf8>> + end. + +-spec draw(tree(GBZ, GCA), fun((GBZ, GCA) -> binary())) -> binary(). +draw(Tree, To_string) -> + do_draw(erlang:element(2, Tree), 0, To_string). + +-spec min_del(node_(GDR, GDS)) -> min_del(GDR, GDS). +min_del(Node) -> + case Node of + {t, r, e, X, e} -> + {min, X, e}; + + {t, b, e, X@1, e} -> + {min, X@1, ee}; + + {t, b, e, X@2, {t, r, e, Y, e}} -> + {min, X@2, {t, b, e, Y, e}}; + + {t, C, K, X@3, B} -> + case min_del(K) of + {min, X1, A1} -> + {min, X1, rotate(C, A1, X@3, B)}; + + none -> + none + end; + + _ -> + none + end. + +-spec do_indent(binary(), integer()) -> binary(). +do_indent(Acc, I) -> + case I of + 0 -> + Acc; + + I@1 -> + do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) + end. diff --git a/test-community-packages-javascript/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/gleeunit/LICENCE new file mode 100644 index 00000000000..c7967c32d6f --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/LICENCE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2021, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/gleeunit/README.md new file mode 100644 index 00000000000..2b685d9bc70 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/README.md @@ -0,0 +1,52 @@ +# gleeunit + +Gleam bindings to the Erlang EUnit test framework. + +A custom test runner is included for when compiled to JavaScript running on +either NodeJS or Deno. + +Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). + +## Usage + +Add this package to your Gleam project. + +```sh +gleam add gleeunit --dev +``` + +And then call the `gleeunit.main` function from your test main function. + +```gleam +// In test/yourapp_test.gleam +import gleeunit + +pub fn main() { + gleeunit.main() +} +``` + +Now any public function with a name ending in `_test` in the `test` directory +will be found and run as a test. + +```gleam +pub fn the_universe_test() { + assert 1 = 1 +} +``` + +Run the tests by entering `gleam test` in the command line. + +### Deno + +If using the Deno JavaScript runtime, you will need to add the following to your +`gleam.toml`. + +```toml +[javascript.deno] +allow_read = [ + "gleam.toml", + "test", + "build", +] +``` diff --git a/test-community-packages-javascript/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/gleeunit/gleam.toml new file mode 100644 index 00000000000..5438dd20a74 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/gleam.toml @@ -0,0 +1,17 @@ +name = "gleeunit" +version = "0.10.1" +licences = ["Apache-2.0"] +description = "Gleam bindings to Erlang's EUnit test framework" + +[javascript.deno] +allow_read = [ + "gleam.toml", + "test", + "build", +] + +[dependencies] +gleam_stdlib = "~> 0.19" + +[dev-dependencies] +# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src new file mode 100644 index 00000000000..f5525522d33 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src @@ -0,0 +1,8 @@ +{application, gleeunit, [ + {vsn, "0.10.1"}, + {applications, [gleam_stdlib]}, + {description, "Gleam bindings to Erlang's EUnit test framework"}, + {modules, [gleeunit, + gleeunit@should]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl new file mode 100644 index 00000000000..916082bcb17 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl @@ -0,0 +1,59 @@ +-module(gleeunit). +-compile(no_auto_import). + +-export([main/0]). +-export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). + +-type atom_() :: any(). + +-type encoding() :: utf8. + +-type report_module_name() :: gleeunit_progress. + +-type gleeunit_progress_option() :: {colored, boolean()}. + +-type eunit_option() :: verbose | + no_tty | + {report, {report_module_name(), list(gleeunit_progress_option())}}. + +-spec main() -> nil. +main() -> + do_main(). + +-spec do_main() -> nil. +do_main() -> + Options = [verbose, + no_tty, + {report, {gleeunit_progress, [{colored, true}]}}], + Result = begin + _pipe = gleeunit_ffi:find_files( + <<"**/*.{erl,gleam}"/utf8>>, + <<"test"/utf8>> + ), + _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), + _pipe@2 = gleam@list:map( + _pipe@1, + fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end + ), + _pipe@3 = eunit:test(_pipe@2, Options), + _pipe@4 = (gleam@dynamic:result( + fun gleam@dynamic:dynamic/1, + fun gleam@dynamic:dynamic/1 + ))(_pipe@3), + gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) + end, + Code = case Result of + {ok, _} -> + 0; + + {error, _} -> + 1 + end, + erlang:halt(Code). + +-spec gleam_to_erlang_module_name(binary()) -> binary(). +gleam_to_erlang_module_name(Path) -> + _pipe = Path, + _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), + _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), + gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam new file mode 100644 index 00000000000..751587a977a --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam @@ -0,0 +1,80 @@ +/// Find and run all test functions for the current project using Erlang's EUnit +/// test framework. +/// +/// Any Erlang or Gleam function in the `test` directory with a name editing in +/// `_test` is considered a test function and will be run. +/// +/// If running on JavaScript tests will be run with a custom test runner. +/// +pub fn main() -> Nil { + do_main() +} + +if javascript { + external fn do_main() -> Nil = + "./gleeunit_ffi.mjs" "main" +} + +if erlang { + import gleam/list + import gleam/result + import gleam/string + import gleam/dynamic.{Dynamic} + + fn do_main() -> Nil { + let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] + + let result = + find_files(matching: "**/*.{erl,gleam}", in: "test") + |> list.map(gleam_to_erlang_module_name) + |> list.map(dangerously_convert_string_to_atom(_, Utf8)) + |> run_eunit(options) + |> dynamic.result(dynamic.dynamic, dynamic.dynamic) + |> result.unwrap(Error(dynamic.from(Nil))) + + let code = case result { + Ok(_) -> 0 + Error(_) -> 1 + } + halt(code) + } + + external fn halt(Int) -> Nil = + "erlang" "halt" + + fn gleam_to_erlang_module_name(path: String) -> String { + path + |> string.replace(".gleam", "") + |> string.replace(".erl", "") + |> string.replace("/", "@") + } + + external fn find_files(matching: String, in: String) -> List(String) = + "gleeunit_ffi" "find_files" + + external type Atom + + type Encoding { + Utf8 + } + + external fn dangerously_convert_string_to_atom(String, Encoding) -> Atom = + "erlang" "binary_to_atom" + + type ReportModuleName { + GleeunitProgress + } + + type GleeunitProgressOption { + Colored(Bool) + } + + type EunitOption { + Verbose + NoTty + Report(#(ReportModuleName, List(GleeunitProgressOption))) + } + + external fn run_eunit(List(Atom), List(EunitOption)) -> Dynamic = + "eunit" "test" +} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam new file mode 100644 index 00000000000..fc80c7583fd --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam @@ -0,0 +1,83 @@ +//// A module for testing your Gleam code. The functions found here are +//// compatible with the Erlang eunit test framework. +//// +//// More information on running eunit can be found in [the rebar3 +//// documentation](https://rebar3.org/docs/testing/eunit/). + +if erlang { + pub external fn equal(a, a) -> Nil = + "gleeunit_ffi" "should_equal" + + pub external fn not_equal(a, a) -> Nil = + "gleeunit_ffi" "should_not_equal" + + pub external fn be_ok(Result(a, b)) -> a = + "gleeunit_ffi" "should_be_ok" + + pub external fn be_error(Result(a, b)) -> b = + "gleeunit_ffi" "should_be_error" +} + +if javascript { + import gleam/string + + external fn stringify(anything) -> String = + "../gleam.mjs" "inspect" + + external fn crash(String) -> anything = + "../gleeunit_ffi.mjs" "crash" + + pub fn equal(a, b) { + case a == b { + True -> Nil + _ -> + crash(string.concat([ + "\n\t", + stringify(a), + "\n\tshould equal \n\t", + stringify(b), + ])) + } + } + + pub fn not_equal(a, b) { + case a != b { + True -> Nil + _ -> + crash(string.concat([ + "\n", + stringify(a), + "\nshould not equal \n", + stringify(b), + ])) + } + } + + pub fn be_ok(a) { + case a { + Ok(value) -> value + _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) + } + } + + pub fn be_error(a) { + case a { + Error(error) -> error + _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) + } + } +} + +pub fn be_true(actual: Bool) -> Nil { + actual + |> equal(True) +} + +pub fn be_false(actual: Bool) -> Nil { + actual + |> equal(False) +} + +pub fn fail() -> Nil { + be_true(False) +} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl new file mode 100644 index 00000000000..eb04c98772c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl @@ -0,0 +1,34 @@ +-module(gleeunit@should). +-compile(no_auto_import). + +-export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). + +-spec equal(EIP, EIP) -> nil. +equal(Field@0, Field@1) -> + gleeunit_ffi:should_equal(Field@0, Field@1). + +-spec not_equal(EIQ, EIQ) -> nil. +not_equal(Field@0, Field@1) -> + gleeunit_ffi:should_not_equal(Field@0, Field@1). + +-spec be_ok({ok, EIR} | {error, any()}) -> EIR. +be_ok(Field@0) -> + gleeunit_ffi:should_be_ok(Field@0). + +-spec be_error({ok, any()} | {error, EIV}) -> EIV. +be_error(Field@0) -> + gleeunit_ffi:should_be_error(Field@0). + +-spec be_true(boolean()) -> nil. +be_true(Actual) -> + _pipe = Actual, + gleeunit_ffi:should_equal(_pipe, true). + +-spec be_false(boolean()) -> nil. +be_false(Actual) -> + _pipe = Actual, + gleeunit_ffi:should_equal(_pipe, false). + +-spec fail() -> nil. +fail() -> + be_true(false). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl new file mode 100644 index 00000000000..31f9ef9e2c9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl @@ -0,0 +1,24 @@ +-module(gleeunit_ffi). + +-export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, + should_be_error/1]). + +-include_lib("eunit/include/eunit.hrl"). + +find_files(Pattern, In) -> + Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), + lists:map(fun list_to_binary/1, Results). + + +should_equal(Actual, Expected) -> + ?assertEqual(Expected, Actual), + nil. +should_not_equal(Actual, Expected) -> + ?assertNotEqual(Expected, Actual), + nil. +should_be_ok(A) -> + ?assertMatch({ok, _}, A), + element(2, A). +should_be_error(A) -> + ?assertMatch({error, _}, A), + element(2, A). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs new file mode 100644 index 00000000000..339a843e5c5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs @@ -0,0 +1,101 @@ +async function* gleamFiles(directory) { + for (let entry of await read_dir(directory)) { + let path = join_path(directory, entry); + if (path.endsWith(".gleam")) { + yield path; + } else { + try { + yield* gleamFiles(path); + } catch (error) { + // Could not read directory, assume it's a file + } + } + } +} + +async function readRootPackageName() { + let toml = await read_file("gleam.toml", "utf-8"); + for (let line of toml.split("\n")) { + let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() + if (matches) return matches[1]; + } + throw new Error("Could not determine package name from gleam.toml"); +} + +export async function main() { + let passes = 0; + let failures = 0; + + let packageName = await readRootPackageName(); + let dist = `../${packageName}/`; + + for await (let path of await gleamFiles("test")) { + let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); + let module = await import(join_path(dist, js_path)); + for (let fnName of Object.keys(module)) { + if (!fnName.endsWith("_test")) continue; + try { + await module[fnName](); + write(`\u001b[32m.\u001b[0m`); + passes++; + } catch (error) { + let moduleName = "\n" + js_path.slice(0, -4); + let line = error.line ? `:${error.line}` : ""; + write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); + failures++; + } + } + } + + console.log(` +${passes + failures} tests, ${failures} failures`); + exit(failures ? 1 : 0); +} + +export function crash(message) { + throw new Error(message); +} + +function write(message) { + if (globalThis.Deno) { + Deno.stdout.writeSync(new TextEncoder().encode(message)); + } else { + process.stdout.write(message); + } +} + +function exit(code) { + if (globalThis.Deno) { + Deno.exit(code); + } else { + process.exit(code); + } +} + +async function read_dir(path) { + if (globalThis.Deno) { + let items = []; + for await (let item of Deno.readDir(path, { withFileTypes: true })) { + items.push(item.name); + } + return items; + } else { + let { readdir } = await import("fs/promises"); + return readdir(path); + } +} + +function join_path(a, b) { + if (a.endsWith("/")) return a + b; + return a + "/" + b; +} + +async function read_file(path) { + if (globalThis.Deno) { + return Deno.readTextFile(path); + } else { + let { readFile } = await import("fs/promises"); + let contents = await readFile(path); + return contents.toString(); + } +} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl new file mode 100644 index 00000000000..1f68eb95e58 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl @@ -0,0 +1,607 @@ +%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters + +%% @doc A listener/reporter for eunit that prints '.' for each +%% success, 'F' for each failure, and 'E' for each error. It can also +%% optionally summarize the failures at the end. +-compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). +-module(gleeunit_progress). +-behaviour(eunit_listener). +-define(NOTEST, true). +-include_lib("eunit/include/eunit.hrl"). + +-define(RED, "\e[0;31m"). +-define(GREEN, "\e[0;32m"). +-define(YELLOW, "\e[0;33m"). +-define(WHITE, "\e[0;37m"). +-define(CYAN, "\e[0;36m"). +-define(RESET, "\e[0m"). + +-record(node,{ + rank = 0 :: non_neg_integer(), + key :: term(), + value :: term(), + children = new() :: binomial_heap() + }). + +-export_type([binomial_heap/0, heap_node/0]). +-type binomial_heap() :: [ heap_node() ]. +-type heap_node() :: #node{}. + +%% eunit_listener callbacks +-export([ + init/1, + handle_begin/3, + handle_end/3, + handle_cancel/3, + terminate/2, + start/0, + start/1 + ]). + +%% -- binomial_heap.erl content start -- + +-record(state, { + status = dict:new() :: euf_dict(), + failures = [] :: [[pos_integer()]], + skips = [] :: [[pos_integer()]], + timings = new() :: binomial_heap(), + colored = true :: boolean(), + profile = false :: boolean() + }). + +-type euf_dict() :: dict:dict(). + +-spec new() -> binomial_heap(). +new() -> + []. + +% Inserts a new pair into the heap (or creates a new heap) +-spec insert(term(), term()) -> binomial_heap(). +insert(Key,Value) -> + insert(Key,Value,[]). + +-spec insert(term(), term(), binomial_heap()) -> binomial_heap(). +insert(Key,Value,Forest) -> + insTree(#node{key=Key,value=Value},Forest). + +% Merges two heaps +-spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). +merge(TS1,[]) when is_list(TS1) -> TS1; +merge([],TS2) when is_list(TS2) -> TS2; +merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> + if + R1 < R2 -> + [T1 | merge(TS1,F2)]; + R2 < R1 -> + [T2 | merge(F1, TS2)]; + true -> + insTree(link(T1,T2),merge(TS1,TS2)) + end. + +% Deletes the top entry from the heap and returns it +-spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. +delete(TS) -> + {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), + {{Key,Value},merge(lists:reverse(TS1),TS2)}. + +% Turns the heap into list in heap order +-spec to_list(binomial_heap()) -> [{term(), term()}]. +to_list([]) -> []; +to_list(List) when is_list(List) -> + to_list([],List). +to_list(Acc, []) -> + lists:reverse(Acc); +to_list(Acc,Forest) -> + {Next, Trees} = delete(Forest), + to_list([Next|Acc], Trees). + +% Take N elements from the top of the heap +-spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. +take(N,Trees) when is_integer(N), is_list(Trees) -> + take(N,Trees,[]). +take(0,_Trees,Acc) -> + lists:reverse(Acc); +take(_N,[],Acc)-> + lists:reverse(Acc); +take(N,Trees,Acc) -> + {Top,T2} = delete(Trees), + take(N-1,T2,[Top|Acc]). + +% Get an estimate of the size based on the binomial property +-spec size(binomial_heap()) -> non_neg_integer(). +size(Forest) -> + erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). + +%% Private API +-spec link(heap_node(), heap_node()) -> heap_node(). +link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> + case X1 < X2 of + true -> + T1#node{rank=R+1,children=[T2|C1]}; + _ -> + T2#node{rank=R+1,children=[T1|C2]} + end. + +insTree(Tree, []) -> + [Tree]; +insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> + case R1 < R2 of + true -> + [T1|TS]; + _ -> + insTree(link(T1,T2),Rest) + end. + +getMin([T]) -> + {T,[]}; +getMin([#node{key=K} = T|TS]) -> + {#node{key=K1} = T1,TS1} = getMin(TS), + case K < K1 of + true -> {T,TS}; + _ -> {T1,[T|TS1]} + end. + +%% -- binomial_heap.erl content end -- + +%% Startup +start() -> + start([]). + +start(Options) -> + eunit_listener:start(?MODULE, Options). + +%%------------------------------------------ +%% eunit_listener callbacks +%%------------------------------------------ +init(Options) -> + #state{colored=proplists:get_bool(colored, Options), + profile=proplists:get_bool(profile, Options)}. + +handle_begin(group, Data, St) -> + GID = proplists:get_value(id, Data), + Dict = St#state.status, + St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; +handle_begin(test, Data, St) -> + TID = proplists:get_value(id, Data), + Dict = St#state.status, + St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. + +handle_end(group, Data, St) -> + St#state{status=merge_on_end(Data, St#state.status)}; +handle_end(test, Data, St) -> + NewStatus = merge_on_end(Data, St#state.status), + St1 = print_progress(Data, St), + St2 = record_timing(Data, St1), + St2#state{status=NewStatus}. + +handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> + Status1 = merge_on_end(Data, Status), + ID = proplists:get_value(id, Data), + St#state{status=Status1, skips=[ID|Skips]}. + +terminate({ok, Data}, St) -> + print_failures(St), + print_pending(St), + print_profile(St), + print_timing(St), + print_results(Data, St); +terminate({error, Reason}, St) -> + io:nl(), io:nl(), + print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), + sync_end(error). + +sync_end(Result) -> + receive + {stop, Reference, ReplyTo} -> + ReplyTo ! {result, Reference, Result}, + ok + end. + +%%------------------------------------------ +%% Print and collect information during run +%%------------------------------------------ +print_progress(Data, St) -> + TID = proplists:get_value(id, Data), + case proplists:get_value(status, Data) of + ok -> + print_progress_success(St), + St; + {skipped, _Reason} -> + print_progress_skipped(St), + St#state{skips=[TID|St#state.skips]}; + {error, Exception} -> + print_progress_failed(Exception, St), + St#state{failures=[TID|St#state.failures]} + end. + +record_timing(Data, State=#state{timings=T, profile=true}) -> + TID = proplists:get_value(id, Data), + case lists:keyfind(time, 1, Data) of + {time, Int} -> + %% It's a min-heap, so we insert negative numbers instead + %% of the actuals and normalize when we report on them. + T1 = insert(-Int, TID, T), + State#state{timings=T1}; + false -> + State + end; +record_timing(_Data, State) -> + State. + +print_progress_success(St) -> + print_colored(".", ?GREEN, St). + +print_progress_skipped(St) -> + print_colored("*", ?YELLOW, St). + +print_progress_failed(_Exc, St) -> + print_colored("F", ?RED, St). + +merge_on_end(Data, Dict) -> + ID = proplists:get_value(id, Data), + dict:update(ID, + fun(Old) -> + orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) + end, Dict). + +merge_data(_K, undefined, X) -> X; +merge_data(_K, X, undefined) -> X; +merge_data(_K, _, X) -> X. + +%%------------------------------------------ +%% Print information at end of run +%%------------------------------------------ +print_failures(#state{failures=[]}) -> + ok; +print_failures(#state{failures=Fails}=State) -> + io:nl(), + io:fwrite("Failures:~n",[]), + lists:foldr(print_failure_fun(State), 1, Fails), + ok. + +print_failure_fun(#state{status=Status}=State) -> + fun(Key, Count) -> + TestData = dict:fetch(Key, Status), + TestId = format_test_identifier(TestData), + io:fwrite("~n ~p) ~ts~n", [Count, TestId]), + print_failure_reason(proplists:get_value(status, TestData), + proplists:get_value(output, TestData), + State), + io:nl(), + Count + 1 + end. + +print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> + X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), + print_colored(X, ?CYAN, State); +print_gleam_location(_, _) -> + ok. + +inspect(X) -> + gleam@string:inspect(X). + +print_gleam_failure_reason( + #{gleam_error := assert, message := Message, value := Value}, + State +) -> + print_colored(indent(5, "~s~n", [Message]), ?RED, State), + print_colored(indent(5, " value: ", []), ?RED, State), + print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); +print_gleam_failure_reason( + #{gleam_error := todo, message := Message}, + State +) -> + print_colored(indent(5, "todo expression run~n", []), ?RED, State), + print_colored(indent(5, " message: ", []), ?RED, State), + print_colored(indent(0, "~s~n", [Message]), ?RESET, State); +print_gleam_failure_reason(Error, State) -> + print_colored(indent(5, "~p~n", [Error]), ?RED, State). + +% New Gleeunit specific formatters +print_failure_reason( + {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State +) when is_list(Stack) -> + print_gleam_failure_reason(Error, State), + print_gleam_location(Error, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> + print_colored(indent(5, "No case clause matched~n", []), ?RED, State), + print_colored(indent(5, "Value: ", []), ?CYAN, State), + print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +% From the original Erlang version +print_failure_reason({skipped, Reason}, _Output, State) -> + print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), + ?RED, State); +print_failure_reason({error, {_Class, Term, _}}, Output, State) when + is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> + print_assertion_failure(Term, State), + print_failure_output(5, Output, State); +print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> + print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +print_failure_reason({error, Reason}, Output, State) -> + print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), + print_failure_output(5, Output, State). + +gleam_format_module_name(Module) -> + string:replace(atom_to_list(Module), "@", "/", all). + +print_stack(Stack, State) -> + print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), + print_stackframes(Stack, State). +print_stackframes([{eunit_test, _, _, _} | Stack], State) -> + print_stackframes(Stack, State); +print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> + print_stackframes(Stack, State); +print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> + GleamModule = gleam_format_module_name(Module), + print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), + print_stackframes(Stack, State); +print_stackframes([], _State) -> + ok. + + +print_failure_output(_, <<>>, _) -> ok; +print_failure_output(_, undefined, _) -> ok; +print_failure_output(Indent, Output, State) -> + print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). + +print_assertion_failure({Type, Props}, State) -> + FailureDesc = format_assertion_failure(Type, Props, 5), + print_colored(FailureDesc, ?RED, State), + io:nl(). + +print_pending(#state{skips=[]}) -> + ok; +print_pending(#state{status=Status, skips=Skips}=State) -> + io:nl(), + io:fwrite("Pending:~n", []), + lists:foreach(fun(ID) -> + Info = dict:fetch(ID, Status), + case proplists:get_value(reason, Info) of + undefined -> + ok; + Reason -> + print_pending_reason(Reason, Info, State) + end + end, lists:reverse(Skips)), + io:nl(). + +print_pending_reason(Reason0, Data, State) -> + Text = case proplists:get_value(type, Data) of + group -> + io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); + test -> + io_lib:format(" ~ts~n", [format_test_identifier(Data)]) + end, + Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), + print_colored(Text, ?YELLOW, State), + print_colored(Reason, ?CYAN, State). + +print_profile(#state{timings=T, status=Status, profile=true}=State) -> + TopN = take(10, T), + TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), + TLG = dict:fetch([], Status), + TotalTime = proplists:get_value(time, TLG), + if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> + TopNPct = (TopNTime / TotalTime) * 100, + io:nl(), io:nl(), + io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), + lists:foreach(print_timing_fun(State), TopN), + io:nl(); + true -> ok + end; +print_profile(#state{profile=false}) -> + ok. + +print_timing(#state{status=Status}) -> + TLG = dict:fetch([], Status), + Time = proplists:get_value(time, TLG), + io:nl(), + io:fwrite("Finished in ~ts~n", [format_time(Time)]), + ok. + +print_results(Data, State) -> + Pass = proplists:get_value(pass, Data, 0), + Fail = proplists:get_value(fail, Data, 0), + Skip = proplists:get_value(skip, Data, 0), + Cancel = proplists:get_value(cancel, Data, 0), + Total = Pass + Fail + Skip + Cancel, + {Color, Result} = if Fail > 0 -> {?RED, error}; + Skip > 0; Cancel > 0 -> {?YELLOW, error}; + Pass =:= 0 -> {?YELLOW, ok}; + true -> {?GREEN, ok} + end, + print_results(Color, Total, Fail, Skip, Cancel, State), + sync_end(Result). + +print_results(Color, 0, _, _, _, State) -> + print_colored(Color, "0 tests\n", State); +print_results(Color, Total, Fail, Skip, Cancel, State) -> + SkipText = format_optional_result(Skip, "skipped"), + CancelText = format_optional_result(Cancel, "cancelled"), + Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), + print_colored(Text, Color, State). + +print_timing_fun(#state{status=Status}=State) -> + fun({Time, Key}) -> + TestData = dict:fetch(Key, Status), + TestId = format_test_identifier(TestData), + io:nl(), + io:fwrite(" ~ts~n", [TestId]), + print_colored([" "|format_time(abs(Time))], ?CYAN, State) + end. + +%%------------------------------------------ +%% Print to the console with the given color +%% if enabled. +%%------------------------------------------ +print_colored(Text, Color, #state{colored=true}) -> + io:fwrite("~s~ts~s", [Color, Text, ?RESET]); +print_colored(Text, _Color, #state{colored=false}) -> + io:fwrite("~ts", [Text]). + +%%------------------------------------------ +%% Generic data formatters +%%------------------------------------------ +format_function_name(M, F) -> + M1 = gleam_format_module_name(M), + io_lib:format("~ts.~ts", [M1, F]). + +format_optional_result(0, _) -> + []; +format_optional_result(Count, Text) -> + io_lib:format(", ~p ~ts", [Count, Text]). + +format_test_identifier(Data) -> + {Mod, Fun, _} = proplists:get_value(source, Data), + Line = case proplists:get_value(line, Data) of + 0 -> ""; + L -> io_lib:format(":~p", [L]) + end, + Desc = case proplists:get_value(desc, Data) of + undefined -> ""; + DescText -> io_lib:format(": ~ts", [DescText]) + end, + io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). + +format_time(undefined) -> + "? seconds"; +format_time(Time) -> + io_lib:format("~.3f seconds", [Time / 1000]). + +format_pending_reason({module_not_found, M}) -> + M1 = gleam_format_module_name(M), + io_lib:format("Module '~ts' missing", [M1]); +format_pending_reason({no_such_function, {M,F,_}}) -> + M1 = gleam_format_module_name(M), + io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); +format_pending_reason({exit, Reason}) -> + io_lib:format("Related process exited with reason: ~p", [Reason]); +format_pending_reason(Reason) -> + io_lib:format("Unknown error: ~p", [Reason]). + +%% @doc Formats all the known eunit assertions, you're on your own if +%% you make an assertion yourself. +format_assertion_failure(Type, Props, I) when Type =:= assertion_failed + ; Type =:= assert -> + Keys = proplists:get_keys(Props), + HasEUnitProps = ([expression, value] -- Keys) =:= [], + HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], + if + HasEUnitProps -> + [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), + indent(I, " expected: true~n", []), + case proplists:get_value(value, Props) of + false -> + indent(I, " got: false", []); + {not_a_boolean, V} -> + indent(I, " got: ~p", [V]) + end]; + HasHamcrestProps -> + [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), + indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), + indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; + true -> + [indent(I, "Failure: unknown assert: ~p", [Props])] + end; + +format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed + ; Type =:= assertMatch -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + Value = proplists:get_value(value, Props), + [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), + indent(I, " expected: = ~ts~n", [Pattern]), + indent(I, " got: ~p", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed + ; Type =:= assertNotMatch -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + Value = proplists:get_value(value, Props), + [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), + indent(I, " expected not: = ~ts~n", [Pattern]), + indent(I, " got: ~p", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed + ; Type =:= assertEqual -> + Expected = inspect(proplists:get_value(expected, Props)), + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were not equal~n", []), + indent(I, "expected: ~ts~n", [Expected]), + indent(I, " got: ~ts", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed + ; Type =:= assertNotEqual -> + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were equal~n", []), + indent(I, "expected: not ~ts~n,", [Value]), + indent(I, " got: ~ts", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertException_failed + ; Type =:= assertException -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA + [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), + case proplists:is_defined(unexpected_success, Props) of + true -> + [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), + indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; + false -> + Ex = proplists:get_value(unexpected_exception, Props), + [indent(I, " expected: exception ~ts~n", [Pattern]), + indent(I, " got: exception ~p", [Ex])] + end]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed + ; Type =:= assertNotException -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT + Ex = proplists:get_value(unexpected_exception, Props), + [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), + indent(I, " expected not: exception ~ts~n", [Pattern]), + indent(I, " got: exception ~p", [Ex])]; + +format_assertion_failure(Type, Props, I) when Type =:= command_failed + ; Type =:= command -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_status, Props), + Status = proplists:get_value(status, Props), + [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: status ~p~n", [Expected]), + indent(I, " got: status ~p", [Status])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed + ; Type =:= assertCmd -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_status, Props), + Status = proplists:get_value(status, Props), + [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: status ~p~n", [Expected]), + indent(I, " got: status ~p", [Status])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed + ; Type =:= assertCmdOutput -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_output, Props), + Output = proplists:get_value(output, Props), + [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: ~p~n", [Expected]), + indent(I, " got: ~p", [Output])]; + +format_assertion_failure(Type, Props, I) -> + indent(I, "~p", [{Type, Props}]). + +indent(I, Fmt, Args) -> + io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). + +extract_exception_pattern(Str) -> + ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), + {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glenvy/LICENSE b/test-community-packages-javascript/build/packages/glenvy/LICENSE new file mode 100644 index 00000000000..b96ba24ed35 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Marshall Bowers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glenvy/README.md b/test-community-packages-javascript/build/packages/glenvy/README.md new file mode 100644 index 00000000000..ac251f80ec8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/README.md @@ -0,0 +1,31 @@ +# glenvy + +[![Package Version](https://img.shields.io/hexpm/v/glenvy)](https://hex.pm/packages/glenvy) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glenvy/) + +🏞️ A pleasant way to interact with your environment. + +## Installation + +```sh +gleam add glenvy +``` + +## Usage + +```gleam +import gleam/io +import gleam/result.{try} +import glenvy/dotenv +import glenvy/env + +pub fn main() { + let _ = dotenv.load() + + use hello <- try(env.get_string("HELLO")) + + io.println("HELLO=" <> hello) + + Ok(Nil) +} +``` diff --git a/test-community-packages-javascript/build/packages/glenvy/gleam.toml b/test-community-packages-javascript/build/packages/glenvy/gleam.toml new file mode 100644 index 00000000000..c1f7effe367 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/gleam.toml @@ -0,0 +1,13 @@ +name = "glenvy" +version = "0.4.0" +description = "A pleasant way to interact with your environment." +licences = ["MIT"] +repository = { type = "github", user = "maxdeviant", repo = "glenvy" } + +[dependencies] +gleam_stdlib = "~> 0.29" +gleam_erlang = "~> 0.19" +glx = "~> 0.2" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl b/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl new file mode 100644 index 00000000000..a6b1bdc2a61 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl @@ -0,0 +1 @@ +-record(io, {message :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src b/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src new file mode 100644 index 00000000000..5c82e5464a5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src @@ -0,0 +1,16 @@ +{application, glenvy, [ + {vsn, "0.4.0"}, + {applications, [gleam_erlang, + gleam_stdlib, + gleeunit, + glx]}, + {description, "A pleasant way to interact with your environment."}, + {modules, [glenvy@dotenv, + glenvy@env, + glenvy@error, + glenvy@internal@file, + glenvy@internal@os, + glenvy@internal@parser, + glenvy@internal@string]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam new file mode 100644 index 00000000000..9cda7d92bcc --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam @@ -0,0 +1,42 @@ +//// Support for `.env` files. + +import gleam/list +import gleam/map +import gleam/result.{try} +import glenvy/error.{Error} +import glenvy/internal/file +import glenvy/internal/os +import glenvy/internal/parser + +/// Loads the `.env` file. +pub fn load() -> Result(Nil, Error) { + load_from(".env") +} + +/// Loads the file at the specified path as a `.env` file. +pub fn load_from(path filepath: String) -> Result(Nil, Error) { + use env_file <- try(find(filepath)) + + let env_vars = + env_file + |> parser.parse_env_file + + env_vars + |> map.to_list + |> list.each(fn(env_var) { + let #(key, value) = env_var + + os.set_env(key, value) + }) + + Ok(Nil) +} + +fn find(filepath: String) -> Result(String, Error) { + use contents <- try( + file.read(filepath) + |> result.map_error(error.Io), + ) + + Ok(contents) +} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam new file mode 100644 index 00000000000..927a88e973a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam @@ -0,0 +1,81 @@ +//// Strongly-typed access to environment variables. + +import gleam/float +import gleam/int +import gleam/result.{try} +import gleam/string +import glenvy/internal/os + +/// Returns the value for the environment variable with the given name as a `String`. +pub fn get_string(name: String) -> Result(String, Nil) { + os.get_env(name) +} + +/// Returns the value for the environment variable with the given name. +/// +/// Uses the provided `parser` to parse the value. +/// +/// Returns `Error(Nil)` if the provided `parser` returns `Error(Nil)`. +pub fn get( + name: String, + parser parse: fn(String) -> Result(a, Nil), +) -> Result(a, Nil) { + use value <- try(get_string(name)) + + value + |> parse +} + +/// Returns the value for the environment variable with the given name as an `Int`. +/// +/// Returns `Error(Nil)` if the environment variable cannot be parsed as an `Int`. +pub fn get_int(name: String) -> Result(Int, Nil) { + name + |> get(parser: int.parse) +} + +/// Returns the value for the environment variable with the given name as a `Float`. +/// +/// Returns `Error(Nil)` if the environment variable cannot be parsed as a `Float`. +pub fn get_float(name: String) -> Result(Float, Nil) { + name + |> get(parser: float.parse) +} + +/// Returns the value for the environment variable with the given name as a `Bool`. +/// +/// The following values are parsed as `True`: +/// - `true` +/// - `t` +/// - `yes` +/// - `y` +/// - `1` +/// +/// The following values are pased as `False`: +/// - `false` +/// - `f` +/// - `no` +/// - `n` +/// - `0` +/// +/// The parsing is case-insensitive. +/// +/// Returns `Error(Nil)` if the environment variable cannot be parsed as a `Bool`. +/// +/// Use `get` if you want to provide your own parser. +pub fn get_bool(name: String) -> Result(Bool, Nil) { + let parse_bool = fn(value) { + let value = + value + |> string.lowercase + + case value { + "true" | "t" | "yes" | "y" | "1" -> Ok(True) + "false" | "f" | "no" | "n" | "0" -> Ok(False) + _ -> Error(Nil) + } + } + + name + |> get(parser: parse_bool) +} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam new file mode 100644 index 00000000000..bdd8726251a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam @@ -0,0 +1,5 @@ +/// An error that occurred while reading a `.env` file. +pub type Error { + /// An IO error. + Io(message: String) +} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam new file mode 100644 index 00000000000..125217a90fd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam @@ -0,0 +1,15 @@ +if erlang { + import gleam/erlang/file + import gleam/result + import gleam/string + + pub fn read(from path: String) -> Result(String, String) { + file.read(from: path) + |> result.map_error(string.inspect) + } +} + +if javascript { + pub external fn read(from: String) -> Result(String, String) = + "../../glenvy_ffi.mjs" "read_file" +} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam new file mode 100644 index 00000000000..898a91b7aa2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam @@ -0,0 +1,26 @@ +if erlang { + import gleam/erlang/os + + pub fn get_env(name: String) -> Result(String, Nil) { + os.get_env(name) + } + + pub fn set_env(name: String, value: String) -> Nil { + os.set_env(name, value) + } + + pub fn unset_env(name: String) -> Nil { + os.unset_env(name) + } +} + +if javascript { + pub external fn get_env(name: String) -> Result(String, Nil) = + "../../glenvy_ffi.mjs" "get_env" + + pub external fn set_env(name: String, value: String) -> Nil = + "../../glenvy_ffi.mjs" "set_env" + + pub external fn unset_env(name: String) -> Nil = + "../../glenvy_ffi.mjs" "unset_env" +} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam new file mode 100644 index 00000000000..a5d478386c4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam @@ -0,0 +1,69 @@ +//// A `.env` file parser. + +import gleam/list +import gleam/map.{Map} +import gleam/result.{try} +import gleam/string +import glenvy/internal/string as glenvy_string +import glx/stringx + +/// Parses a `.env` file into its contained environment variables. +pub fn parse_env_file(contents: String) -> Map(String, String) { + let lines = stringx.lines(contents) + + let env_vars = + lines + |> list.filter_map(parse_line) + |> map.from_list + + env_vars +} + +/// Parses a single line from a `.env` file into the key and the value. +fn parse_line(line: String) -> Result(#(String, String), Nil) { + use line <- try(skip_line_comment(line)) + + use #(key, value) <- try( + line + |> string.split_once(on: "="), + ) + + use value <- try(strip_comments(value)) + + let value = + value + |> string.trim + |> unquote(quote: "'") + |> unquote(quote: "\"") + + Ok(#(key, value)) +} + +/// Skips a line that starts with a comment. +fn skip_line_comment(line: String) -> Result(String, Nil) { + case + line + |> string.starts_with("#") + { + False -> Ok(line) + True -> Error(Nil) + } +} + +/// Strips the comments out of the given line. +fn strip_comments(line: String) -> Result(String, Nil) { + case + line + |> string.split_once(on: "#") + { + Ok(#(value, _)) -> Ok(value) + Error(Nil) -> Ok(line) + } +} + +/// Unquotes the given string using the specified quote character. +fn unquote(line: String, quote quote_char: String) -> String { + line + |> glenvy_string.trim_chars_left(quote_char) + |> glenvy_string.trim_chars_right(quote_char) +} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam new file mode 100644 index 00000000000..38d775ac6a5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam @@ -0,0 +1,33 @@ +//// Extensions to `gleam/string`. + +import gleam/string + +/// Returns the given string after trimming the indicated characters from the left. +pub fn trim_chars_left(value: String, trim chars_to_trim: String) -> String { + case + string.is_empty(chars_to_trim) || !string.starts_with(value, chars_to_trim) + { + True -> value + False -> + value + |> string.slice( + at_index: string.length(chars_to_trim), + length: string.length(value), + ) + } +} + +/// Returns the given string after trimming the indicated characters from the right. +pub fn trim_chars_right(value: String, trim chars_to_trim: String) -> String { + case + string.is_empty(chars_to_trim) || !string.ends_with(value, chars_to_trim) + { + True -> value + False -> + value + |> string.slice( + at_index: 0, + length: string.length(value) - string.length(chars_to_trim), + ) + } +} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl new file mode 100644 index 00000000000..e5405238329 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl @@ -0,0 +1,40 @@ +-module(glenvy@dotenv). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([load_from/1, load/0]). + +-spec find(binary()) -> {ok, binary()} | {error, glenvy@error:error()}. +find(Filepath) -> + gleam@result:'try'( + begin + _pipe = glenvy@internal@file:read(Filepath), + gleam@result:map_error(_pipe, fun(Field@0) -> {io, Field@0} end) + end, + fun(Contents) -> {ok, Contents} end + ). + +-spec load_from(binary()) -> {ok, nil} | {error, glenvy@error:error()}. +load_from(Filepath) -> + gleam@result:'try'( + find(Filepath), + fun(Env_file) -> + Env_vars = begin + _pipe = Env_file, + glenvy@internal@parser:parse_env_file(_pipe) + end, + _pipe@1 = Env_vars, + _pipe@2 = gleam@map:to_list(_pipe@1), + gleam@list:each( + _pipe@2, + fun(Env_var) -> + {Key, Value} = Env_var, + glenvy@internal@os:set_env(Key, Value) + end + ), + {ok, nil} + end + ). + +-spec load() -> {ok, nil} | {error, glenvy@error:error()}. +load() -> + load_from(<<".env"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl new file mode 100644 index 00000000000..a70577b44a5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl @@ -0,0 +1,69 @@ +-module(glenvy@env). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([get_string/1, get/2, get_int/1, get_float/1, get_bool/1]). + +-spec get_string(binary()) -> {ok, binary()} | {error, nil}. +get_string(Name) -> + glenvy@internal@os:get_env(Name). + +-spec get(binary(), fun((binary()) -> {ok, FNV} | {error, nil})) -> {ok, FNV} | + {error, nil}. +get(Name, Parse) -> + gleam@result:'try'(get_string(Name), fun(Value) -> _pipe = Value, + Parse(_pipe) end). + +-spec get_int(binary()) -> {ok, integer()} | {error, nil}. +get_int(Name) -> + _pipe = Name, + get(_pipe, fun gleam@int:parse/1). + +-spec get_float(binary()) -> {ok, float()} | {error, nil}. +get_float(Name) -> + _pipe = Name, + get(_pipe, fun gleam@float:parse/1). + +-spec get_bool(binary()) -> {ok, boolean()} | {error, nil}. +get_bool(Name) -> + Parse_bool = fun(Value) -> + Value@1 = begin + _pipe = Value, + gleam@string:lowercase(_pipe) + end, + case Value@1 of + <<"true"/utf8>> -> + {ok, true}; + + <<"t"/utf8>> -> + {ok, true}; + + <<"yes"/utf8>> -> + {ok, true}; + + <<"y"/utf8>> -> + {ok, true}; + + <<"1"/utf8>> -> + {ok, true}; + + <<"false"/utf8>> -> + {ok, false}; + + <<"f"/utf8>> -> + {ok, false}; + + <<"no"/utf8>> -> + {ok, false}; + + <<"n"/utf8>> -> + {ok, false}; + + <<"0"/utf8>> -> + {ok, false}; + + _ -> + {error, nil} + end + end, + _pipe@1 = Name, + get(_pipe@1, Parse_bool). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl new file mode 100644 index 00000000000..69e5d489294 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl @@ -0,0 +1,8 @@ +-module(glenvy@error). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([error/0]). + +-type error() :: {io, binary()}. + + diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl new file mode 100644 index 00000000000..d442cb7aa15 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl @@ -0,0 +1,9 @@ +-module(glenvy@internal@file). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([read/1]). + +-spec read(binary()) -> {ok, binary()} | {error, binary()}. +read(Path) -> + _pipe = gleam@erlang@file:read(Path), + gleam@result:map_error(_pipe, fun gleam@string:inspect/1). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl new file mode 100644 index 00000000000..9794d8dd6f7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl @@ -0,0 +1,16 @@ +-module(glenvy@internal@os). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([get_env/1, set_env/2, unset_env/1]). + +-spec get_env(binary()) -> {ok, binary()} | {error, nil}. +get_env(Name) -> + gleam_erlang_ffi:get_env(Name). + +-spec set_env(binary(), binary()) -> nil. +set_env(Name, Value) -> + gleam_erlang_ffi:set_env(Name, Value). + +-spec unset_env(binary()) -> nil. +unset_env(Name) -> + gleam_erlang_ffi:unset_env(Name). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl new file mode 100644 index 00000000000..c271f7e9800 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl @@ -0,0 +1,75 @@ +-module(glenvy@internal@parser). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([parse_env_file/1]). + +-spec skip_line_comment(binary()) -> {ok, binary()} | {error, nil}. +skip_line_comment(Line) -> + case begin + _pipe = Line, + gleam@string:starts_with(_pipe, <<"#"/utf8>>) + end of + false -> + {ok, Line}; + + true -> + {error, nil} + end. + +-spec strip_comments(binary()) -> {ok, binary()} | {error, nil}. +strip_comments(Line) -> + case begin + _pipe = Line, + gleam@string:split_once(_pipe, <<"#"/utf8>>) + end of + {ok, {Value, _}} -> + {ok, Value}; + + {error, nil} -> + {ok, Line} + end. + +-spec unquote(binary(), binary()) -> binary(). +unquote(Line, Quote_char) -> + _pipe = Line, + _pipe@1 = glenvy@internal@string:trim_chars_left(_pipe, Quote_char), + glenvy@internal@string:trim_chars_right(_pipe@1, Quote_char). + +-spec parse_line(binary()) -> {ok, {binary(), binary()}} | {error, nil}. +parse_line(Line) -> + gleam@result:'try'( + skip_line_comment(Line), + fun(Line@1) -> + gleam@result:'try'( + begin + _pipe = Line@1, + gleam@string:split_once(_pipe, <<"="/utf8>>) + end, + fun(_use0) -> + {Key, Value} = _use0, + gleam@result:'try'( + strip_comments(Value), + fun(Value@1) -> + Value@2 = begin + _pipe@1 = Value@1, + _pipe@2 = gleam@string:trim(_pipe@1), + _pipe@3 = unquote(_pipe@2, <<"'"/utf8>>), + unquote(_pipe@3, <<"\""/utf8>>) + end, + {ok, {Key, Value@2}} + end + ) + end + ) + end + ). + +-spec parse_env_file(binary()) -> gleam@map:map_(binary(), binary()). +parse_env_file(Contents) -> + Lines = glx@stringx:lines(Contents), + Env_vars = begin + _pipe = Lines, + _pipe@1 = gleam@list:filter_map(_pipe, fun parse_line/1), + gleam@map:from_list(_pipe@1) + end, + Env_vars. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl new file mode 100644 index 00000000000..eece3a111bc --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl @@ -0,0 +1,40 @@ +-module(glenvy@internal@string). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([trim_chars_left/2, trim_chars_right/2]). + +-spec trim_chars_left(binary(), binary()) -> binary(). +trim_chars_left(Value, Chars_to_trim) -> + case gleam@string:is_empty(Chars_to_trim) orelse not gleam@string:starts_with( + Value, + Chars_to_trim + ) of + true -> + Value; + + false -> + _pipe = Value, + gleam@string:slice( + _pipe, + gleam@string:length(Chars_to_trim), + gleam@string:length(Value) + ) + end. + +-spec trim_chars_right(binary(), binary()) -> binary(). +trim_chars_right(Value, Chars_to_trim) -> + case gleam@string:is_empty(Chars_to_trim) orelse not gleam@string:ends_with( + Value, + Chars_to_trim + ) of + true -> + Value; + + false -> + _pipe = Value, + gleam@string:slice( + _pipe, + 0, + gleam@string:length(Value) - gleam@string:length(Chars_to_trim) + ) + end. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs b/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs new file mode 100644 index 00000000000..0e641dbc1e0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs @@ -0,0 +1,32 @@ +import { Ok, Error } from "./gleam.mjs"; +import { readFileSync } from "node:fs"; + +const Nil = undefined; + +export function get_env(name) { + if (process.env[name]) { + return new Ok(process.env[name]); + } else { + return new Error(Nil); + } +} + +export function set_env(name, value) { + process.env[name] = value; + + return Nil; +} + +export function unset_env(name) { + delete process.env[name]; + + return Nil; +} + +export function read_file(path) { + try { + return new Ok(readFileSync(path, "utf-8")); + } catch (error) { + return new Error(error.message || ""); + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/README.md b/test-community-packages-javascript/build/packages/glerm/README.md new file mode 100644 index 00000000000..ffefb5af462 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/README.md @@ -0,0 +1,44 @@ +# glerm + +[![Package Version](https://img.shields.io/hexpm/v/glerm)](https://hex.pm/packages/glerm) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glerm/) + +A Gleam wrapper around `crossterm` to create terminal applications + +## Quick start + +### Caveats + +Currently, this only works on Linux. Gleam doesn't support any mechanism to +build the NIFs on your machine. To get around this for now, I am shipping +pre-compiled library files in the `priv/` directory. + +The `.dll` for windows does actually allow the program to run. Most of the +methods seem to work, but unfortunately the blocking `event::read()` call +just hangs. I expect this is some interaction between `erlang`, `crossterm`, +and Windows. I may try to look more into this, but right now I don't really +know what the issue is. Would love some help with this if possible! + +I tried to build this on my Intel Macbook, but got some errors from `rustler`. +I'm not sure if that's not considered a supported platform anymore by them, +but it's also currently not working. Any help with that would also be +appreciated. + +I don't have access to anything ARM, so unfortunately will not be able to +provide anything in that regard. + +### Getting started + +The docs should hopefully be helpful. Additionally, there is at least one +example usage in `examples/` that you can run with `gleam run` (if you are +using a version of Gleam that supports path dependencies). + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add glerm +``` + +and its documentation can be found at . diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache new file mode 100644 index 0000000000000000000000000000000000000000..92df63b06d41e6efd65b6315a7f45eecda1989b1 GIT binary patch literal 62841 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..698890486b4eefd538d84a817bea5b94838a49b2 GIT binary patch literal 114 zcmbQ#@07{_11wMmCzMXlNlnbv&&(^~LJ`QxEH2?e5h*Sy%FIg_Ll%oq&d<#)&C4vQ U)KAXO$uBKRP|)c6$?53<0DaOL6#xJL literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache new file mode 100644 index 0000000000000000000000000000000000000000..281d600331ef41cc683b222c82019938ad83533a GIT binary patch literal 27832 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 Xr2;?H=(%Don|&{23S|@5-_QOJqO9cK literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..53e1ad9d70b13428390bf75760603d9fea78299d GIT binary patch literal 123 zcmY%Gc1mS{0ahr36H2G&q$cL-XXce~qX?wsPE7MJFri4~U=W#*-Gp{UEr QEH0To^=sb0;|Fd400}J|+W-In literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache new file mode 100644 index 0000000000000000000000000000000000000000..e1d665bc07813583c29f571837c1676f1a4eae70 GIT binary patch literal 3072 zcmeH}&u<$=6vub$gmqSllBsE>AX%9jp*ohEbrSXBq;V2x5mMFGcBLR86p!tRy~^y4 zwL2TfMTi@Raw&fV{{zaA8wdC!IB@6I3o>tJepUr!DlrtxN&Zv9X6-L^~i2Fv$vGNg=T}GZ2nL5vYCP3y_sg~lNnh2G4rbR1{M<@x{gP^u7MarjrmNr zF+j5zS%!g-Vczx;X9WHR)<;4>lzjQEUG>6|dq@tyuadXOd} zj`XcQYSTtk?LBtLa5gx>uXgqa^yhmz-`Ct>zDMXf6M|& zhC=0^GZJMwedOGdEB|1+W?5vr$0T)lumj5=bY1F?cOIQmcgR_7+fH`Cu-$I!6j|iR zBP_Bgt&*=SLP&BIU#`@bM~+ZF+0)`UM%XXGgL|s#`@e@Y&JB;y}t_P_ykmd`z68(Rr>Zz{!BnJs6M2^HcNhg%UAzurW zs?3U|>DWk#Qj3TaPXIqrdX-IuXrpt62EfqYXp5|G464L^bhf2f2Wm0a5n@^p(yb1M zBGS~UVBcW}Dt9B;CDftkP{SFF?(O9=cwryUBfLo@V)7={U@g3#uVOYh-{<4NX$ ztQlww9ZL1C_9ZawMoEJi_pa;V`6sMYpK4U1Hiatyv~|(vlsFlgO`7{IH*x8y!B^;AV#g zES0oaveX=)9u#o#$C_GClo^c&zrVkG8%As;Q#HJB2QQcL@|_qLJo^Ej-N-&W dUU}sE!e87Mg5%jT>@B|VL$>mm@_;R&zW|Mmo`C=W literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..e926edf4bd2ba9772666976608cd9c70fb8c7d63 GIT binary patch literal 96 zcmY%Gc1mS{0cI$J8%n3=q$cL-r{&})mT;j6{9;O9{>a>7(@U7 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache new file mode 100644 index 0000000000000000000000000000000000000000..fec2276ac9ed8a761261ebb7794f915b24598595 GIT binary patch literal 8464 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 M*)452i|k|n0tn9F4*&oF literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..d76e6b61fe72a6e8f684b40640d58cd0bbc4a62a GIT binary patch literal 122 zcmY$r>zv8}11wMmFO*KtNlnbvPpQmH%*{;ZLJ`c#EG`j55lJn|Nz6;vPb|sL6~!iz SoRL@r()E&cT71TzYp(%&E*``H literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache new file mode 100644 index 0000000000000000000000000000000000000000..95b84a6370bf85d384448e840a67e10752456d39 GIT binary patch literal 2814 zcmbW3TW{Mo6vsu`o@}9>L!{}@VL@28U2G%Eb$!XOChn3H1&XFl24p}{*s@LAY9z{_ zs9XjN+k!pyt$ysM*h60T4fZtb1N3qG6y6~zxoK`qW*D|aiHGO%JAZQiOLNu2w+Fa9 zjsM*le`8JKiC5zj*~jBi)*5y_>iBb%BhO*oIY$J@*JE|cje;DkW=)(ws*RyEb}F?7 zN)I=9;BO1=BGz5!Jm3aGwJ*#RUbk>&fb;fwMhz3^j&Oc}C#=!@R5Cwt;=K>g%@lkK zRT22H@#;s6S8#5Cv8AS*=YY0Yy=mh6uWBWf8qb(~J8QzluV!=mH+hjyzumr>hKrvv zTid^6P-@tLNbBuGW)vLXZGk5@%v9}fl)=b0AZo+Fxw+bmnKF!88h#PZJ;FJT^VZL6 zhfGe1J!u~rQ|cbPkZ&#H+#=5HtZdOR^2C&izm`?cCM$SyfbU!In!H@ZlXI8FRCwx! ziGkRKCeCxn#Bhzaf;L^}h6Ob`$B_&|7!PWH!r#Pe{0~~V-L!{5fM18Ok%}8aKyeJf zgJPuK>9~e5B;WODYd0h%5s;8lvfrbkM>%mwBM!Ym_8c#w#0`nVh_pKc7j43+h&Utg zwi+aE$0n|T*Jf>-+`UWI4;;Vm(Gc$7^N_fHKj4CBMxYilt?{FzJaVWMKbn<;r52}- zpfV7@9s;VYTPpUb=LN-bxvXYy?q2#*viikKEG#a?rc@J@UL^U3Y?tUkpSA>TFO#BV zxHv;PLB!THgTqc)2JX9HjJgmHnWG)#Iry= zHKqcmP1`YtUuzDp-B{R!y7SsSSg?dtOP*QbyaqDNrQcJ3#61ByH7v+#?8@<}mMEQU z2@SioA|-=$HSE{xgCl$g7{9oCV%xhMFZ-v`w<~Ll{2AYeE z&;w{Yh=$10KyA6=x$EvxMs%E#<|iG(f|&A96F^*z{+`Q4w`6y^&>eQ7Lir~ zSMbL5JndR6<(l4o7={I5n)K055|-pk`q|=6*t71~lABE{w1y(kGHsxXaG5_TDOX_P z{Wg0>d173I#zg=wZ!=m1zzt(XgEPWqOYK+TgxuP6LpC5aoYSx$u(pa{gCXdFfX?j0 z6Uv06>I6lQ%*3^B$i8V@(6k;EB-mA`l5ZhHXE(4>CqIN7Cfiy(MYnhnUP-B}9%SES z^~tR|X5#fqb#BCDo!WfH{vQ(Ug#@-6&e z89%s%s})@Rzv8}1B_4xFO*KtNlnbvPpQmH%*{+@4&1o8X5AD)0Ik{zS^xk5 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache new file mode 100644 index 0000000000000000000000000000000000000000..bcc6f81a0dfa2081c8eb92964871ea0f0b07c088 GIT binary patch literal 789 zcmb7?&rZTX5XN_Qsii~$6HsndJ#FrDEL=Zv%tS!p$N=I#u`CQstgrd>K z{2WbvIXf-8G#b_kWrSE6 zIm4=oDx-x)6Ait6r&OG3QW@z)13-MY4&`EA;2|90Cd9H(f{!8_L^zPfhHk;<;`wFf zyQARVj%$6v{cs#GF|F~M3RXp}MS)ij3$|HHB<d*<< z+y7*q%fcvyDXi_ID8es7D$^VQ literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..7996afcc06d5ef47b53a066d1ed8fc8ff6d3e41f GIT binary patch literal 29 WcmY$r>zvAf4*c?#2l@L(90veAT?HEe literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache new file mode 100644 index 0000000000000000000000000000000000000000..4b38dc11252b6a5b8cd02c701e01e3383c6f92bc GIT binary patch literal 27622 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..e194cadac1c0380e6695db697ed205c3b05b0877 GIT binary patch literal 72 zcmaF#Dekh%ulbV>TpOje=pIB6sSjmGTT$EZ|np2{1>gDVm*}3Nd>o*cc literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache new file mode 100644 index 0000000000000000000000000000000000000000..724743b1b747f11d9798850084ff30365355adb8 GIT binary patch literal 2992 zcmbtW&rjS&6!whQn6-j7PXv@yK};%8gGC_=NTo9(t=(Rm!2aUV7@E&_hq{pODk`&3HE9R~Dj5h#f!AkN3XsoA3En zlg`?3tqCKa^e&QbdT-=Eg1%bskNMT!VaIN51%lVdMN9%7ZjFagm5401CSs!?gQZIp z`dse{$pNo7RGRvOeO-%6IQyViaya z@MekGTOxDiS%QN{bgsNYaWG)IW2n@I|(1c<8$gogK zqxy-&c^Z*AV&91x+#-K*2rNPYT<^f%w9>Aha#)E+A^q88<{E(&Ff>nY>l8Sf~qbbJlvFe9g*{enzi!gQ6f-%Qo zD{_7oR54cJA=?monW(ajeGCPG++aNs!RF18b;iRg+l|F8!lgHMSS*r8kjgFB*Vk3~ z4huvovs}xvyUo6ogRyLvQ8qTF9(4&fN4`=^O~*0F1ReqYVkk`dnR$Z;@c^8T;*wm$ccC55hvbuy!f9-)n1rDoYOS@x3ezDBiC_?;&Qjf>1V#*AD5~ z=bX6em^zxf5@rxp@;t~8^$|goGY>GcQIIHs;z7c8ZDr_ZmQbLKc18Iw_E|P?AVFYIi zUfFgsY?T-Aa9=;^9nm+`a%l&daV2bhUUtiy_qiX4>PmDsBMRNb-&9n|1#L!Sc>?B% zoSoXBt<|l- zDQKnqa7-x&UZ5-p8v{z9=t8jxpUOto9ukTzkalWWom!og)rU$}w!P#BnWnJUVDFWU z>#@AHXz7yFhPcVCKqMl^=TBCB9>AWBbN4kr2mX^9H^wdh1Da^a2d-TL@lpP&D zmK?vI8O~-ZP|HWu@(X-wVlr1K3@^h-7Yx^6q#sHyl=@+D1{V9_i3?A0az|r6NQzyAqMaBAQ9Tk!1@5=<`+AI>H;e{Unc(nzMMkP literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..4423143044877dc88fbf4e2fcfa1aa45a6e49927 GIT binary patch literal 54 scmY$r>zv8}1B_6HAe2teNlnbvPc6zx%uCl#EXmK^rz=1CkN%`J0NM!*Q2+n{ literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache new file mode 100644 index 0000000000000000000000000000000000000000..b1ab52ad3ff109aa0ca7422ecccc100f435855e5 GIT binary patch literal 3171 zcmbtW&u<%55Zr~c^Hs-kwNP2WFyFTS?$xDOs*nk~sJl2aovx z^lI(0jsvT|TC4XHEwdapn2+XOQZ=(dl0Xb@y`n&B(#)xvqL>N%C6FpXst754wif!f zyPXkEK+E{jMK6+8Q2`XqR|x@%=MG`OkOrK+x1vt}p#O~CXW^RVIBSZ|+;(K={VqFo zv!B};*)k5P4`E<+aNgbwBdK*;(KbV|i@<0JMvE}2quuEeq>GR~bEVT)L~CKgJmQ}R za73okKlOE+CG}uL2zb}FwroW?rd1ZUd^Z@O=wa&EK}fwVidUgl+p-;N!(kM!Wc!}m zWNt{?mT&XPfLi!IIk3YHCJY+3c5$U(7<6omF6>)P{ulq@Gect+p|o6H%r&ju!j|tf z*SOl;M`DiBv0S!xW1&*XPSEV+hV4#nSV1G3NAcpp<(1WWvDomMZ1V23@1Cp{3I(z6 zPF^z%g-jok&&fTm`2?0nU9em{d}L&;&Q@8_azYtdJNdmw5^cU>7E@n#LBkaW^PZssB1OZImmESBEL&;I(*-W zAm7JDm8gIr-Wx+P=w=OrkQIUtkSl_A#vwrl`58r-{#yM`ot?M*J==}4T&?f{@r#;ctC^^v!Mwj*T?l=nA=RCb%do z@sO#S5BcW-JjC>VQ9t&AHK9i#2j_;(DS}^GwQQl&*zbbNxv?*I421WK#OJ(ZWo0!xMII_AkIy7|JSJ1{S6^&N?yyDs*&&vmmaZ= z3gnHseia6aa0yv;9Dg%H2zkOi!--1bxaCR}3W>|~dKYXLuLr%c5n1|;%+l{MOaJZf zRM{J!Dr_@B`68a0_z2N(vpF?x=G2kb1qN>s%ZI)jw2DoQA`7!xV z@_5yD>)u{)OCeZLMThu|HKl4&1nxBqA8dGyPPsiP;HdA5KG|1e;B~ggycdN$@7*rk zb6!{HE~$_nhx9O9Ey2}cc=IMq6$ZC76g(bIIk`5WQ1Eg dEx=MC+7N6V%Q)z~iY$du!Hg+Rwzn^k{{Z{vFuMQ% literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..a5a851f1c263bb78396ce9ebd74ca3c7667c6267 GIT binary patch literal 46 kcmY$r>zv8}1B_4xCzMXlNlnbv&rK{?-X61bPE$%K0E>MIE&u=k literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache new file mode 100644 index 0000000000000000000000000000000000000000..ea7ffa3c47808ae67a2e15b6974cbf163c180ca5 GIT binary patch literal 30881 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 PlApUORpoUXPcJh7xDFae literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache new file mode 100644 index 0000000000000000000000000000000000000000..df361f2d9db1c6d104f839b32e4af8efe121dbf4 GIT binary patch literal 12240 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 UEmM0Af^=Q>Dt6zqR@t}zAJ|)+P5=M^ literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..01991ea93819cf78ea5922d9d397c28c0bf7596a GIT binary patch literal 196 zcmd=2#iz1d%nU|QGnJkDR2(>w}Bp=O${DP9q{Je+jWZ$%l-Z%gN D0-Q3b literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache new file mode 100644 index 0000000000000000000000000000000000000000..2f2cb4fe0a7c2a2ade829942c989b0f2be8e1794 GIT binary patch literal 2254 zcmbtVU27Xh6rDS(?OMWL2SpAp7Ot0;*dmUiH6f`;kX2|KK|(#UA)psUwwAC&+I3c& z7>7V!@=)|v$WKUqNT5HV52a5<5a=K1V^Qy}0q1U_Eui(c5Ma2|BFK zNX+%s6-wb*Lq(Jt*2e4Uc#qffav_M+SJHs8U=D!H*{2JMbRQTXZ%sPu?9DsU;NNgB z2$D2}(R0U_Kb-pV2IdA>wzNa0xwX0?acf`QAp;-k>Q^$dA8CL0FX8}(y}M{|kW2M< zS5h1tn~mL9CI|nRFY8~BG4z9@X3sqcgypw;La143sBJPqnV3Hzkhau}G=yM$f{?b6 zc6iQWoU2K-c%BH@SL^ZL0PBS1jDGCdD1_X)DsRYPtKDw8FI-Qv zZKBnV*YzSHwzlaFP4KQ!GySIV@E;Y}i3$?I+t_fh5r=C9tT|XKYAk4jDQg<5;4;kR z*kXXby3W*f5|hbiCg2p)QE7l~S7&8h?kik`@~7tskCoVkq8`al443{`BCVOnopoo# zDStUGWZsYrrjc~~^+XhGoS%O}&cP$M9J))xZr}$|;CrHS(2TsUJ2vshTD^;EJ<i1z7gp))9>Q90hwARUQBU literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..ad921d20ba6b51a57503d0e2a53829e220a0564a GIT binary patch literal 47 lcmd=2@D@_7$2$g6ThDMM(kcyvk$3! zXiKBUoQqP^`i)|9Lfne~o#&lq;`i9G0`4MYCEfF^4g+-nGu_&GP;f?_WA2 zCOQehRijUhD2$Je^U*qgBu2wDAGP^dEOx$FaEUQ(M$0BEwl$bHt5s04{h6(DZnKzo z?Fn!2~5%D|uY_qt0vX z#RY5~Tu6co)64wS4u2}PovE!}GV@LdCnPb9DXJuA-nNy9Cz?`Xb9u+I74W5b?_j24 z=G}8EE_LM2gy7DSm=(qx93xY~9$YM` z9ue^#;i+YdR!RYAJfABUO6L4kR&>AtH0wgLo>;6VTVTI|}Hc*xPn+a@d-Ogj~jioc4*o{aAn3Z`))R%0BplRWMz_J=@vd z!KBprNG#+zArwma-F^XPF1PM2HrIJEDNiwP;+{`;8Rg`dePHbnCkv^Mc#qgaJLX!sTIMcp~>u8E;DO?Mm!hN{zo@LrN zuJ?Wibl}?gU8cQ*>z8L3S5@u9Gx&)CI`pdA&*+M&+Anb3j;q>l;%dXOvL^Xaww|q$ z56Paf$(521fgom%Fc#%3PRgw)ygzB&fQwW}|KS(}gGU+T{FVXu z#E0tqBAXt$I}*yZ5J_+7&sgQlrtRFN=k(_Y!0Eyh>VoCEd+>k`-K65SEF z)AQD5CFc}ZOJ-aL?jYFFGWBE}N5mfbaq@A`o6^~Rq4n&(WBjW)yCbeQ?BUbnd^*La z3Fw>{=OSkhRbTVrR-E;524X!+m?z`hN+s`T*web0)}tOI!dA+-mGH(}^F zye~msVFcrQAqNuk^9=Zyv*+fHsD%A=#>cMn>=(=osVamdErjHP zDYE4bERJLJsJ_4X4ef?s{l+KRI3{ z2G{HIW|!Ebx#KR}?GO;LrwVBUdP7^FXbv zkcIPu1s)_}O+aWJQ)uaV5_X}PpKjI6ZQ~!sHo*YUKb_{&b^a6uNb`&QY@Hk17+y>9 zYjyrcvV#PTPc#UVBq1{woRK0eUS$9IE#yw0DxjT8ZxcRI~a*ZDlL)JSuq&Rf$hDs1Q0 z1v{62nS{_^R;?uAG{w(bSqDGI@H?cdE9NV>tz$e3O8UozsCLK!(2ZW8Aw}en^$xXF42sNZB}x&S%~Xbiq3|9Wuutipa%#c)}0L#Gp;)F z2`BaRmR>N|a)?`69zwTObDO4~tI`w#&*tT#RRcjTGMm&_YYu+HifgrUp5T<82L@j? z^;%VuoZmpY&(w>!4a-}bChjh;$91z*HTBgky^^a|@dftaKf&3^;qKhardamQRe|!s z4I<7g7fd^@TWjK@Po7}h$w(Zie#SXE0+C#8h@Hc8A+cI2`0AU17Ys&dOUCQF38l)0 z_Ty^q5pswrkf>pjrM)7(fCBGG1eg#3d5CI&Su9hDWKKNcRW7@^JQ2JAg z{HZ#hBgbD$@migKksMYa0UkmZd{p8?(^hx3n(Nf;m0LJ)b4#ycHh2(KXnnRxmx&K4RMppq_*^{x8f1|hVn9O1zP&_;{9GX5+gDuxdCo?L z0Lq?q0qOSy5k7A1#_!22YCjRbZ@<@;ft3N_qOdj>z4#))=deR@lLvlKnBs>pdl5ll zLf9(6fdH&PT=u$ zP2B<6&SylA^6Cv>LPFk2}i`7*N{{W^HN zAa^rYDj{@ja`g$xRdwHGM`Tp*h&+W%%N4>TL!J5WXtbA(`hsP>kSlL3G7qcoMwG|g zu8Tf`EXi9xAof;@cq{Fi6Nhm;Id*!C@C9HFs#IB1i6J52lSO&*pgUYLNeD&(Rizkai7_Rae%BS-tEmZ+P)X9 z3lkPXwu@EqJZZmVyzXTQ_XJ0GSgkvD?8P8*$Lq1{G0tYsT(N9QV)#MlldbxfH2y;D znVhwo^F@b+EXiQ!_kU8}`+;t}H?ei!-WN|6gu8!5%sy+}0PsW1euGW(+r2JRLJp~+ zpO?YnQ8$j1EYzK?is=T3@wk3=P2aL=h$gEdj)cRY_|lybsI@d_Av!ZfShmvqc_r>g zc_;6Ds2eI$WG5cuhIQUS>j*dW64H#Q=(uHbZ;iOV;$egJ6@Q5s)<6V!_P$&9arSDX zx>0iq)|IkyMkFu;2Ic)Wy?AREy};pkIf}iNBZw(OSng&dN5#=SDE=l$@{lTnTE$}L zilv0`Hwbh@?DncK8qL_PZ6_hiz?S}V{}XY}mfdKtT2UfqzNs92?aFb$p}?b^_#u>>sk!*Eh(S6Qx%vrZm-z2fB7c9MOIr^6AkP=la+tCZfwKWqtOnl=SHCH& z=TdRi&e>b!q|})=hkNhk>>bw>p`oOZm6f*EbY)Mg#dh=Llw2w6ga%*=wBb=w<9+udJnAOL-)Sw9RSE59+qND;i=v`X$O-UK zaWxnm+-ULTNu#AY?1hGMvz;PmcwaKG``#a#?4*^Q74<2vRP2%(x}%w|MCvF{O$?SS ztKxf!4iV%h6~Y~(ll|>Rk;hyyX{$gHcfxu2myeDdBR$FmnpCq@bg9NFLP}&U%J{t& zDUsb6)L2XB?FmWOO{(MpTv`4mmDH)=yW8@TYIK>iN)~asX_q6p5_JFa)J-HKQ;9`0 zSJ1wD=Hdj2jk+wDM-Qa0zC6qL&68(IZ}?GMjr?Jxi4WS^sgkn7 zCn7{Q5W4{O`@M1dQ#v}f-N5sK)c1Jz*yOj2V^hXQGS2%5ab9Xb%1y|D_yBe$=-*lZ z>v)83Ed>-AHJ=JHm#P}Pr92pFh5`qfEz=eYj)J39QTFMS?en1qI2IssST8mdZI zzC|7z-u`l~R5PoS6gbA|D}6<}9lEQzb$=5ps14wI0$0Qif0b11mwO1=siPf9zW9=!L5<82b&=9T0sAyNbD^e>bDKFQg53~<5cX2o!=Tz#@+w$hJM^I+=0NqKcFWT2y&G zLc0y269xK00mwZ+Ajp8Q zZ6Pd#RQ*l#ACMQ9tvC~N_o&(jtp3bL=(Ike?mRQ8s-n-7M1mX7krnU0lg58>MYNzU z0D`G}{yIFq%3rgM*YV$h@yC@LQp8Wq7U4n z__W&gq6JIU1!~E?D{`O)1 z?K=PdgZ!@+`OgpYzg^&eH_U&P;=ek~KbYVj4D)~6;s1G9V=Rs9Fy4XK(fZl2Hp)`C z4*T?~umIwvD6fx!-s9uZ1!Q(*638ueWkhL1B!tdDmC<^`qepo(75VJT3GtSbSBc@# z2_C&9`d`}=U#JMh3*@7G0$LA4w4MM~y3IxB&n8_p!K z6UQXfDh7jT%PI+)Q-c@mnwfYuhejVax(w84gN0kwd+$Ur1ucr4rTxIwE3f!(fAOdd a5dbf$f`x8%=+4q$LTt&ef^Zf)!u|&!=Jz!K literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..a58472ac5a3334d4ebecc990a11a97146d84232c GIT binary patch literal 200 zcmd=2~voLXGWk0O^}QlOuhT#{cTjUk+wSCX1noLN#CUs9BqoSj-Eh@u2)YF>UyYG>nW JlRa5%y8#W;Gll>F literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache new file mode 100644 index 0000000000000000000000000000000000000000..766ae18587236f92eb0a1c1c6979bb83bffd27d8 GIT binary patch literal 5222 zcmc&&Pi)&%827W|xXIRqPiaSoiek!&)@W+Gd5;rcKn8Np7>?#g!+DO$_wei;% zzwdp2f4|RufrQ8(Qwki~fRSQ+O?(u;8M_Gm*?3eY@jt_)Q7luVk}@4qOWA9-Lo0&N zT)S*K0;x?8h;S^c9Va2Ume;Q1<@coa8wtfRjJsJJ=9u&UmN$U@o@OI>^{!Rpi zN;Iq2qA1XP8NIL%g^~SP{pfxoHHy@^Y@?+DVFBDPN?Mu7K%#;`h#){Dr5zU~Eawn@ z5{L{zb<44u`m6EM4*Q-koHj0X}SuL+c)l$`=)dDT3%ci9kSW6U3)#7M0s-D4xifK{2 z1;4AHKHO(h%Fb0Uowk^JYQbEpS7;TDz;72XjV-dBcuA`(j#IPKsTAcmj+$06g*T@v zMwKDU=!#P*zvxAo9#h7mQ9|Yj{s4J)IwXRegb;}>TP8x#L|mSb*X_DpLtEW^tn5iX zFmdA$QIzwga)M)@mw^n=03y+KG6wmucX&|6HqP>t>4uR5mc+J97CGU_%4 zSuJ4>O`ZpJ#i$m_G^%1~5OmcFrVM-6enNS0E#p}b$V4f8BfNgzuYx;Jp&~N9pTnVC!CH%Ysy) zh;CLp zcyPj<5GM-qRk_hhjLrJj`-m^xKWo2m(&^(|vXF#@O)wOsm4zW#xbKR%y5WjBSlj^0 zZdlB~qJ^umX~(R%1@1AF;h3a?u-BQqI!!gcktV2pPLoBV@8-7V2dz_yp%x5{lshCE{ew zu#o8pX>gjv@jy_Jdx0%JW7j@k+YeIsNxZSMDvB$$?JzK9tPG%5eq;Ni?j9a#@c=npJyQL zqbt{_Ad@HFlWt259K=}TV!0p|afrOvW_iJHc}hF#Eie-^I}U_lOX z%P*y$w!Ewh#CE;>qRq>)=ae@epYRr#{av*8Ub~wObeDM&=3$VDYi{c zu2q3%ej3~aZv8_4Z0NDsQRoFstOsxnDdF>6n+!@zyN2k1tYQ3t%mM@JK{UPJGx-{-k(-QIGKi%2Vo`)vtgLAVD=?gO~UFyxR!)#2jON8 zJ_z&A18^q~cMot%DLWuP2lBXd;Y#APWto=mbyu5_(3^(d4D_DG7XvOKc@WjgKc396 zt=T?u2IQ>A;;rxy%a~@FJz~q_v3aXb6K9OFO?^rBH6*Km*7?+*L?9XOu?~px4EYa$ CU~~Qe literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..830d43596b10edc15b7bc2ceddbff2f713b2ccc0 GIT binary patch literal 103 zcmd=2Epm6!zHbICh(CUelyMYP8dc9=d9??WPr|0;Rh&ML{gY*;GNfB;MUg;>K&Q zY;V)#5(yzxAuja5sYvAn3RfhAgaqP-1cyo>l{*KHa6keHvAh}EX?HgXTXG?Z?8$ii z=FRus``+hEA1T*0IJE`mo*&*MpAWx3Z~|a%_|d?^ur;W)Rvl*5b6zM-HFBX9tVa_| zI6)ePqcV&vnkPvLtfIM$x9_v&cO=y+Y*=U5(@%rl}VB?Tgn|^wg~zb4CInmx-6P0Ss}8dB=__@9x(RzK*QO{ zuvov3RYD{=vdc$>3o_jD%{PfMTqkqo2EoCPa;5xO#=(b5vHU>6fu5?AkEU?&Me2U} zYd#q3yIrPzIQXeAUw+I7ziIjMuNn@n>e=!Y9S48n;13+MEROopiYH}!c877`kIIVa z5EY0aN$7?Idd|EqD~KJQTq2%_)o5jtT9jwlgkjJkqc2-NTWLCH>1*~nqsyVc zxs)7G9B=soTCoGV(sZk#?YXq(v4FZ>NPQMIeU~=f(02GvKBKtKiZ={B16Nd;eTVU# zW>$nVd}G@1y(;=htG*Sip)q{d?bsxKgl{6ElZ(gRJ=RJ*lSmjt{zDt&3+A$byk9^* zmW8n`IGaQCFOI{-JY3WcOd~~-wHY_eh&sgl=TW-`dLHzJsW}!jo%oT7<}pl)l<&#q2>!+_kyap1=41)h|3NH!HU# zja9=Kx=toJlR$^$pn`sABzE`P%d4-9N5*b$5>9iR1xUhjpLK-wnOQEy3+I5s63=_> zQ-Ue)3#J?qOgZva-(Jpl9dws1PyJW6oIfllaz@;*Xk$WTyXClHI}VmI4Z>!1o$~%; zyQ>DLc;10xmi#siLoF)^m>({AQhLK>Nip6%Y}8a9wQ)g*n)bTwWD=Sb5x6a?4XF*& z9*hnby0FJ`dq@9N&xkG)7u$Pn4jzul`#P8$*&3$=2j{U%3r=vz<$=5!xzOccoE-lb z_HFOJqA_Mz5Yewc_{m_#3O3zp4CKDF8_5!lw=YRTPDNBS9@Jixi56>;y!kMK?;*lB z*B@=X2Yls*wc%oNx3`pV%?fGNavZJ^R#6tXPc((?VkfFG>~l1Vyb&M~%F!gx5dRmX*IAAVzItxn!-^b#i4HPwQNG+VMV)v?`p;(L5Xfwdt5v!I( z3NG)uftb=Vi<_m_pbi$7L+f6x=`fT%)n*-yT0#V&hxmXi9+x{CO`Q?9LSja=Q-$+V+i2*Q(pq7~9&Wlo9{Oy|7n$jCx^Kbfg#K zjwD>^iW!%!vjl&DoG7GZP_IFXO!>?TJXew?Tm8p%p`M}+RepiA)$7ORFX9kGcqK4B z4%0hO(mIA)FtY<$esmH>>FOm^Cg`^n8ppnFYfB)J&@Z=r@bSaKc^-(KzXz|&h2t`uTZHqYaP=Bo z9fd*`3ZqaeLTMDNELekWTYy>wHJb=3k#ez!2K6+kdF74u41TtHe!A#+4lc#H^t|6> fnVXgqu;fD$)C%a84)w;x=B|PfNeLt??nC4s8k{p# literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..26c03cf3cb81f45c2b93bb6bf8021044c38675eb GIT binary patch literal 78 zcmd=2d8wObcoAllbB3s>Dhx{ zzz?BUFRe$9ehsg^2p)y)%UTxKf^&Ei9+`Q+-#?kT=?H8ExGZq_OS9wxF=(FgmF5)} z!zk8j5T=Gf_WHTQx28GH-pfU>@bO4Kfz|vC-nU->)-cj09O$CpD$?OusY@NkI*H6F z13Aqtc?vc{oiPB$(DCIew-}Q(s({WCI@gFobbBW+1AU!Ctdhvj^3*-1YrEqY*U%B- zYhv0XO6uDHi1+d{ZLK@p1N>NjhlY)fcorI6m{9*PI!{#0D!4AtLYUvGakQ7P1|sX7 z5b^E9u*lT+Bs7XyMW4_ssq;5dpWaCQ$6CpH=={Wn?;fh6|Ie19-pqVMjaP|`4)6Ek zNzo%ppL_#cq*|YV8k^B~V;uiHy93or;3fag1gelz73w>wRzp0wKwBfg1*-MYZId(B zFW?gBx0vGC*ucgdwmfXjZ3en1V}tewwAZYIetRd+)7;%o(->`!dhTIf>h`XR3q1pW E0Rs$`IsgCw literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..6beed5ed725df6a3a8e7149a83e1459488f7153b GIT binary patch literal 130 zcmWgo!@fp$Oz;7MJj$h~$?P=$9lGXN#bSrWWNS X=B4Ww6y+zU78mEVy3OV1H*Wv{xKbQz literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache new file mode 100644 index 0000000000000000000000000000000000000000..e087e75295da251e35223689a9dd0607ba37764f GIT binary patch literal 1223 zcmc(f&r9P#6vyXH8m1LW`zQ!mD2+m?$f9l)4_>qdS18M_u?vEiHZ_B$#s>1^;Q!;n zKg2)8i+_UPE&GyGlXkVZm-RB4nKyZv@8^AAwpwr?P&>n>z~)iyupkh}wN9Z`yD5n1 z!jb0n=E!7>H-Q5|ar-!;d(Su9co?gHX2BznkH$(l}wL(Wy z+z+HMtqlOiu(WBcafLCXKqFvj4@+$NGCpB}aLJjBmGK2vO)c135W& z2_$KrQn`((bTcZ&9F>S>AG&FaRE{lIQeB({>yDs zdGiDwpw6RM{j4bx`R|w_J^exHnJNB<^tsCCbj|6;tJ|dRvB78Ro^->4y8ly0WOe`K zj(EconesU_+jsnt)9<9nvAl=nWz@);%hL`;^$V(P<=0i?(DPg`F(#_(v{(76CjbBd literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..d03bd4e27eedf3cf7c1040715866556930eeee16 GIT binary patch literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache new file mode 100644 index 0000000000000000000000000000000000000000..7c790c0d491ccc8bd66f0fa11a008acd12df3a5d GIT binary patch literal 4956 zcmd5=O>7%Q6y90K-DG3O8PZfuXq2g|sA<%+#7RqJD%_;Bf+#>XZdJ7iIcs}tZ@SsF zcE?TK0~JvZs4ADLNEPA&LPDy9#E}+`Tq{)qE(pX4saLphK<3Ttk7LJ4OQFCa)_5kf z``-KB`@Z+QA9bP6PAYh41CJ?FV+YZ|hg}Hc)q%TRXka3W8fBB}Ye(~j%yPQp=ygeK zP%UC36Vuy}n}I=i@w zA1O}ORA3SBzLDMC4U2o-%h|8_;z5s-eb@tw&s8V;g$j!gdKa>HdSP)ab}>5}gT+s= zboNKS80*Vt$NOOMOP`Z{#20yl2Cl-N8bJfY5j5(WMu8%v#pHa7rbGZ;R_&s7;k8|5eEoAL{s>p z(#RVgFmgR79Bsv?K~7&`j$UB=JCiWg<{LqN?Oz(*~G2Vf>APPQ6(m|%B*rkC3D20Wu3uY ze~%P&i{#;oON;yx^$a8VI-_75BMjb8;o+SuGh9-tS)S!i&2ouhaU;M+3oaUK^hiWi z5n4hBVuW6ti^+I!81F`Sa3cJS=nSC*(=SmZCrXaJCP~vDcm3Mc$m=dWK9j2<$IKOJ z!7id8T|R9|m!sOaNS7`Fp%1T;$uh^V${|Y626=$|mIm(O!415GrUrkIJDJ@Gsx=l= zD|v-G!~;yYo8Kc@f41C&iKcLFO5f1c!U?uU=k0e z@Zc5zl-8Qz#i9{jGaHz|r`l$47&8>aOp>R+Q`GL30E?i7d2ziZFV1U=!n>`dJ+VV+ zC+2OtS=&vwxA+r9^3LG3&4E(bnwCdJ^oT(L(~gY4^XNg*mm6i z(~5CC+*f_vxyQV~rBTTL<1=2oMB;KO1Jo<=cj6hKl>%o9;m&(4Kp*vi_6cA@@cYrk zqTvSY?w>p^!FM{3@>IQ{fdzPQ6*H*y`Dn=UsGjrelcYBD8|0Kjb)eGSfVM@~o7@fz zOIB^e;>ErOLS$4;3a6It7}Vv&f8YS9guVvbE__>ASrIIvl9xHfLM+DL;%o_l;`KeA z%-0yBPV&%U(z0DL>&ZiJA5vR)y?+*G;?Y1Gz#A{97gSMRQ^#{u8WmaUN4(e;@uwh; z4iy9;y{PTukxk=$2*=fi$AYNvJTjFRXV!Ul#whhSKjb<-%4b7#*? z&XS_ebhygXty{@JqvWZ4Te@9uNwDC9laOL z=+!Fp)jsq$+Y%n87%+Kj>$2eWSslloj+?xL*;&`1jY(@&9?cE>5t@o$4NMD7-xKD% zFJ?Pw8C$oTBKH^}^FlDr>~tr2;#%g`N+sh;+p*BCog^*8Qx$$PS{E&Rs_+c&`8K)LDhP0;rnRQwEe{6lZ^0l2q)og+Mk^ zUsCO)Xg`&f-yno{%i0O9Fll@OifjS~#pbIs)G>9d+z13!;fe~T(=v6)dc`PIxRCNm z+^VhRVGo9JZ$O8En{Nk#o2Yvt^F8_vaGJj+Xs9&%54pBI0nTeP9)Zk&Z=ayxy&Vuc zOI_$G_^%U`f@>74cObC?2kP9>P5px6`ExpY34S3`PHw8@_#Qk2gWR4V7o)>Cnu@%6 dY4kMjL literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache new file mode 100644 index 0000000000000000000000000000000000000000..734764605f44fe1908f5139e0c3456768538a0a8 GIT binary patch literal 4184 zcmd^?O>g655XYaf<2ueZ4WlZHvg#^H)v7N7vZNrPT(XU{NUT<(u6NZH0wwXrEe>f? zJ$3}`1yt<;4oDDjVYPe73GE394jkaj1-=3t`2ryA&5YkllE$bn=E6#mGkN0J{{Nnt z|4eQ?5pT+v8{pcD`1v36*XLx+w&!zmEA#4{?Cf=n=6*>x!LI9lv(qww`)hT}W|>yU z)Hf3XO7EyiNH{gquDK^M(cl2;f*|588KnWHQ`0WQ1XS9X9%5E@YKOLA(T`b%?h)Lg zq#pvUdN-D7bxRQGwfTmC`xUhV;{1D{YYm`aO?af;5GW{$6|EprkWCD=g#-nEB^I?m z-Qa8KSbHo{V9p$Aof&sU=GtSKf-jR?`zlF6Q>keUg@SvjZS8)Fg5s4UZRrXHx!GfF zVHU*dgI@PR(sseDlQP}Ub`W>TSb}c(& zG+VC#FosG=y(@@}sR=p)D(k3}X)$xhwCuchnedx)vT`qW&YwsCh!wR!Z|MOR=tC;d zJAMB)ev`5@&MxomQ#x=ao87$t%)?l~td4@IcwpqJW^=lakB0K$qB3=L$yGbRCBSTI zTttN0l3bS^fB)+`n6@k0?23C234%HWr7tCew}=Z{uz9?wTI~Y&;R4i6Lc+<-K+nK#pVH*a_y1(~v7zEMxJ^kYnk@1e1p_ z{Z1Uf43$r1DQv7tZOO5Fb;{X#cxtQ_IA*EmoTJ>d`nRI>=Bx?X6Ivo-9P)tVJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache new file mode 100644 index 0000000000000000000000000000000000000000..46c9dc055260a8dd3af66ee241d2438c6ae38c14 GIT binary patch literal 1934 zcmchYQE$>v6vywmr70{Uc!Dfpae)yQ9dXWeE*f4KB$^DTu3)kk6IP(iZXKO%iOy)I zuY8I<_yP36Hy_k*;G-|Tndqm$(-sJ1-PB-w=*?-<_MHFk{O`Hff5N(i$u2HRxcD@F zPm(aP7vGRB$6rfQZ`aV&gXOvoPR({Ky}iqr|BP-~tZC@=bzZ#0aZOfkfDnHN`RZGs z;1e%ZKXM9Q3iawMfr4TvUtJGTFfUfBS&@S86#SqdWgB`!15mPDr~rs7(1qR>CAPJ6 zN2JAhtfhAbl{hukvecuU^nuyz7+P9y+m5C-uQ3L|7)Fj2gA0r))3gGvl&LgalPFxu z;F63>Zn%)a1sNBlUP*U~?%x<=DKEhm7o?506MREoM)DYuF|u8#Xm-cwzo&$~Tytfd zmvP=rkj!9G#^f0Z?(4=d0qIASl{5fGyZ8tYr+gkh<}vgDutk@EaI-kgF)@o50Ta35 zDyR-X%u)9>;IWov9x%3g$iMP}dU&X{n?7OX&7_346{19hPpdBDoQ!k9ssmZOM9UbJ zF&g}l2plm#ptI@H>5DlV4@bCM40DX;ahjmc(ps=Pt(N|b&^abC`3zxxtlPDY)4J7% z@?ugb%gR*`O31UqxuRUrInPE?tYn&_ULb*`f!egIc2H)3Tw(RD@I>gjeRlUIlW2GT zJ2h8E)%d2D3RQ0e488mN?vaGLk|l3r7qjHmsqu1yRN?z?g@)N~xL$TAf^sr>Yc@y4 z_~@5oo4P&Nzkk@Y^PNf}hfei+*Ow6_a&<3s66)2D9Ia;S&l&WmpYp$LnDK2mHu6Nb zU6t{!jZ_*arvMG;Ii`O`Fc|po!{n{|t6g>8aL)U)i9DOgU_!>kDLYH!bNMud5rKge zz6jwE9f$txiOyg$hsl}#NrB=lin8!vKXu!(Ov~H&DCX!{?4i}sQg>9t)-J#=bkpAw literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..e7f013d77b779ab53ac19ad95a796aa2567c499e GIT binary patch literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache new file mode 100644 index 0000000000000000000000000000000000000000..3c7e20ee8e09fbc83b25777f5a83a38a92dc43d7 GIT binary patch literal 7081 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache new file mode 100644 index 0000000000000000000000000000000000000000..df828811e1f6acdb6c0306f160245b2a929b56e7 GIT binary patch literal 49248 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 rLD-0D9YB7ELd04wR{~( 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 I=wcW9FKabJtpET3 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09 GIT binary patch literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache new file mode 100644 index 0000000000000000000000000000000000000000..eb1d9ed0279aeeb838591b0c87fbcab6dcc82006 GIT binary patch literal 5798 zcmc&&O>7)V6`pE)JoebmxHG#U4hgO#8!|Q%d+l*@7?wC22<+xUnpu>HB-&}u)YwgW zx`+OWJz=9ns~}k%(6ZXYYELUbEJ7R*N3=q)CxrO9fY{>-PK!8kLE;j=dezIf~*d1Y)!MJKXnZGk zwYHZ-gpQ^JuiEFW2m8H2yGCt^IxmjlUeK*8Y454N<5Tm&RGq#IKfP z#oPFOXNu(lv%{D%qm3DREUUA8Cc{`JqfcEoZfRqgj4`Q=F)cHuoGZq0a*jt%4Q@?7 z&N5BcPZ^IG(`WDLkJ#$$cPHf3Pku9h#k?bYZq7U0^tQsbZ~|^RO>T1Ea)1zTg$kW= zo;OU}_Ia>v28oyNSi!b(#l!P7-V;ISIZ^NU5w{#a5N4CREsW{S%~fxH*R(^ioabNn zMJu#<%k{VyIt~`X{jSs4_FTseeXOi0xM;ORBk(aL*4nW;!nPcY&1baAN3+w1HX5Pl zb=M*+KN`StCBjm|7J>VG4_x2}4A~gjaaigy05x?dl+Mf|SLE}e+h zG&%_W5U%yLdJ+|%mrNNWE9gr2@My6-gtS12@YR-Ra`COu0-A^>AmR0vQ!>kZbCI9B z$QyOODH?7YQ71n+(II{+2b@05uk4!bjxBurxAaAcC8Dsz8=f!&$rtX3o!)AR6BdHe z#2YQ}ga<6weIx6s_2SA&9I?5`v6Zk4ZIdG zqpR8o=Moaf3-FiuSLEkaCBpSO$w{7HyLISv~A#+ZScp@Ivu!_%p0_$MpiPG~2fPKq7660Nk+yOTPUJgi3d`QG%erj^Q7 zl=9X%8-l2loLD5F4~#F711BCtcap%FA`2ylXF3LIP=IB}6akhaQ{2f^N|*c3#WyFS z^^S&gz6U9tcJ)f1d<>~_6kLTi9+=J#Epr^N~eQvMy3~(ZM-xTroP02%}^v@3BIew3-WZkr@z2f z_5ZN`xkh6+5vLQ0ic*qc@0eXb5;my__;Wg-*IjdiG6Bh{lQW;6Q879naq8V+PQ5+I zsXrMuIi4X-&C==*ku8v&Bde1=44c9jIVi;~XGw9(X;a+tJt^+w#St5kSIR8y4Q%gk z1kuzMAk3Q{Wfxj zErEt7lLsXCZA$Lq?&xCTRPUWV3YM1VVjxgzSst=PDH}2H((8tS6pW~#@R8U$O%M;d zroa86+Dz+_Y~WM+E2`zzoK($eI)kgu>|=j&0Qa@4C@D02HNE!k%dpD3Zi}xF<6j?mOKLP z=YA3i;{_GV;_o!pR~$#=Cw@yUFyTGv1~+? zw-iy{0#SY$BQ=^RCx(e~VKh-L9GECLLXgoDUA7XsJoPE!l;SB4z@QCEdnAMW{Ezb2 z7_{<#T&+mB6D`%)bBSo81<=pLmejFoysvP7AGjaOM-&>3``IDfqhcNfE+s>~8<_p? zT6!hb6Ka@f>EMORz>NwNvSIlG6;oVq#-rj)40)p|OMF@1No5_lU+KFW7^-_^HKqzI z4+R!70#snK@RH44s)XZ`Y)zKE7s<%qXi$mDwAU`GYH}4-Se~y_J*rZIcM5+j^kVq) z0Wp6NiMcEzWDHlYD=|mRK1(q>i%8PlS?_;5E73DpT;$=x#t2kA1H|*qY@`LF5G|4Y96(fs+K?AemZ=A9mW>ZV`HKk3%2PwR?V-$3*9O#zZYcf# zADjy|@RW-3fqv+)&d$C#sp+#-efEexzogF}+4!39aUr2+kLlU9v9I1)xZ-)PSGerD Xww_&rukeZ&iiIzmxbM(eZjSvIo{p+3 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..8bfae6dc9ba127cf7714d1689d480cfcf6ebdc98 GIT binary patch literal 29 Wcmb15HB4nd2Wbbd7QGhmnF;_hmjz=0 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache new file mode 100644 index 0000000000000000000000000000000000000000..4f95ac68f6ba84f0c04893d7692c072161d8ec21 GIT binary patch literal 18139 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 EUoUbwbN~PV literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..7c99d5d905225ba7c564dd44324b01b038d7953b GIT binary patch literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache new file mode 100644 index 0000000000000000000000000000000000000000..9778e4e4367ebda16503f8b508d1629598257f12 GIT binary patch literal 2856 zcmcJR-*4Mg6vut-xK6B9-BqEeXedXmCXy0b;vj^oD%mP+bd_K=u7p@MH4eFL-8#1A zAGBRN@ys+N`oKT17bJM)iT?nJ7ZCgpd*Fd*Udp-mCh6LFlPWcl;v8T5`ked8_k4Xn zI8tvJbb6KEH0aGACx0jzl7N0onBGFE};bs(jK}!5!lf`iuE5yF0YId9Gl$eS_h@#Naf?ZKHMX?KbB($_h zOBO8|EhojP+htMvn!Ge4FBzYC{%~9;gwogs{w#c%=4}h{7~}N z?Se}6MOq-OM5I%c#`f6B*syY?)h}EbP2ruK!ZD*_Ags%keOC+4fa4NJQ?F&;KyKr^ z^kY1lWdZtfb$&~JCTDmxKfr%}B$`-0SL!!?O;Fs;sf#n$9~H#d-jQ4(fC)qW-a@<)X#I& z&wtnC6V5Mqjlb^`uw3}s^)ul=L!T1sg-VikF{;9$$9&;dpYZJoB!@xj9&mB3qhZO} zUIH;ovpB$hbhlC#V}o*k8}w)rVvoXCZonHiOYkl)fXIs&@7N@-J%=1GQw+}c z+^Dh@R1T_e1PAaQ)ZsBcUR)O$Uw!W!SmIvk+8b648u;Xm4{Pwz!xxPEY4MjLe*w$C zf3xpsquMZB<<6{AdRoE_Yf+`+i*$U7PS4Tlsn+K#$^4Y+Z&TgU?(dcF@Qvogav1tl SpTn_<^*CeYyRM(G>*RkRTfZIv literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..48ca73e0ee43502e40d1b8b70f34ddf19d858229 GIT binary patch literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache new file mode 100644 index 0000000000000000000000000000000000000000..a4ac54bf2faa670c4dfcd2bf5663a9eff8c0c3af GIT binary patch literal 37907 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 D?@Q*s literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..fb52d575e15e87bdb03fca9fb3c0bcfa695274fc GIT binary patch literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache new file mode 100644 index 0000000000000000000000000000000000000000..9da2217179c061bd64af462f20aeb7be93945c7a GIT binary patch literal 46246 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%0A~q@w1io@;8@DNN$`_S<-%0x&6vGevsYk{{pti7 z6(JHN_fI=rk8kMur^3kpsaRo-ER3}JHKZkLtqlyYh&vur&;i*~2WTd?&82|AWnel?L-d|=(Kjdgj#CCUY=wL?;nC^;3YX9iNiO^qD}JTU)c2VKzdAtp zc)FOc)ogcX@xTU7kMfAcMiPTcqsJF3^Vu-=5p`2aPdvsfe3l0ODx@b$Vd**K zm7d3x^yD7%kw={HbdMrYXOCR5?8JsKPy*h0EHlQATcKUbfNnp(i`a$XdByJ{-M7y< ziU6fe8u*RR=VK=mQZmQOD31;}Udsm!tpVi`E?NQXw=!%XXpfyCiRCR6Z1VFE=VLUl z*qX<5WYO7Cka?8g^a=~D=*{iKfBGHIDseUV-TLWZKd~Wmzsu%atXmMlMRN5Htl7Oi zw}VBlj^k;pPML=ud+lGnMuG~$m-l&0q&(58!(Y<@>(yC>KkLZg&(eU!Xl^g?uzoIV zlEr5QKnUHM^o3XoLB)I#L9|*dX9;*}fe~}uxYIw{1cR`D_K7!fHttK#W-SH>#3LTw z@N5C7#YZ_t_RQYftR zQ|LQkSc*`TgA${Ihri%Z=oj36_l3mx?V;oqMDv@`1$}GEp)^MEt|_ykMa=@+=ZUay2-f5 ziy)|f!%wKyi{S#i=D@dK`kyaR^bZ>v-5$TFsXnVE;+Lq$V+00257(r@y|cMbv8B)a z6o`9dt*DZ(yYI7M*sINK^V{N>rlsIVB$f1p6LCZHV9z}q*)XHQbsgX9+z+dXy_5-6 z@MZX>8!{1yUIkyu%{7EdeZKWut+Yyuwo@8|T4sp-l*THpv<%GQp1GfCqp_5G*2_HG zSj8rDREG?v#n+t~b7$7vsh@uxXKNxgNR5nFBc=P{-rcAi%tn37xxyQ$jV(Cp3upcl z!kGB*Z>HLWLA%XL2?8^)*9R7EXF#1sJ%+e8j=%KpzZBghfYdLAp&8uN`YyVJ=qIA= z2pOZA>+g}j{=)VbNzoz=jjS%-Z5l6Qft#GaL7DinBS~M5VU|hb4_0^zz6o3XkTOPyp@rZoMn3Uf6Q<7h0Q{*%3Zg-I>D z524R2le~)oPR(P58SK-&qXM)OOXWlqJxK>0k(dfu0Ua5`arDkt?lcWyfL=VfDQO;D zJa|uVZ?7Dz5@rWY+a?imuyRP=-AVWSivi)<=Tg{rDN9*Z;6fsGHv&QLqsra1Xztu< z_AZ)xH=6tV&HY<>iNe;vi_C^0Faq~B_U#}Kcp!{0EDUkrm|d+GYi7fCvmu*$=i$I&4vu_wbG)X9lYM$G#WP<{|{H33E=<$ literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..6587875a9ea9dec90101364c1e7d76d5ef2dffcf GIT binary patch literal 120 zcmdo0G9#4%23VmCPAHw8lbV>TpP5&}jUteilb?ttlwXvRTEvB-svt2FO(Z2Vxn%E! Lc~|2ZcNPEuC=VMA literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache new file mode 100644 index 0000000000000000000000000000000000000000..eb3b7c68476e2ba0e42159d0fb641fa4439c5c1b GIT binary patch literal 4740 zcmc&%O>7%Q6y7(x?q(f3+rdfGgqFB21+*%P5(^>u;yOwYRE1`}m4Yl#>eQRWjqSDU zb$?JLLscY>zzK1oLLA_VdH``kMd}4{=!qUGAp}xSoO&;BW@k59ckLQS3WpuP_0Eju z``&xsdvgL5`5!o=(wQPXHNEg~8dCQsfYQsUKPMoyp~I7{nq98X*UJ(#J$t?FN_wSM z-6$x8#xkY?iu!iB31FTkGVQFRP^n7tCD$AyG7t$L0EvX(3d@9kY?!w|PIX|(asiFc zh+%z7(5TBxR!v6ZeI;YPr=amstYqDap+Qx{I;^5`eJp2P8$;t~t!VwCq49S-XZ;mN z!%P^~Y66WPlZN#}5{>UBa;dWbshbLaDYV+m=B1@8~;P`BMkRXBt$&$jET*USIxoX>;*IBRO76Qp12Zco8NMZw!AT3l|lfa7w@E3UCmO|is z5Iy)-zyZBo{lFIBZXXo5LmZsSz-6e0Zc^2^8p2DfM2>O~J7)O!^x@;~cDcQdaklR; zTQj$Lm|>D(m>oCh@e)0;hQTr>k$$x(*NBwHm-A3WAHY6$gs!w?j#=L7{}`z9A#hHVI9mKZUcEvGI?-5uL* zRvTLY*@SjR%UA50?fSwsx+?cg7&;(f@EeB7bHlLUPxZni=Vu9LL0}ljLyiXs3zGn` zASC-z{9ODABZt)|34HMwor`%Pg1fags(|*CofPL{au_cBsa}OD`YDsAwC{iGP>pso(>7F^9u%DDACuL&QEa|M+P|EpW(F@1GT}Qia=#b1E;^s zLSG;WVHBz$Q+U0QAap82CxK4o_-Np$ZaOUpI3Rkp;X0@iU&_D9dZp#C4ivkr|3xLH zId4a!RAPFVm?sJ6G%$9+PDmD(HjpR}!lrd*oQB_fuZ(M3fhgnP-*YW1NcPK?(NXgWkQT zof@Y9_xFgDTaW7~`htLBm6#@3+2MtFPto~8y{}Tp;R8-bU(pxJ0ciFuTi2aeQ&jp=GaaQP+xz> z5bEns^9|nA)83x z6z02VFz~W*nI`A+=bLWTX$S~TQ_|V1xUA!JzGw))2m41=U5|+nO}$mu6HTw`&Z3M8 z=@caTt$A+z#yAD_OduIKnmj^h3_5c}+?r@?mc|z4^E-1Zt(Mc`cS0I7@IU=Rt7Ff- MQLeRZ+~P3&3(lYD?EnA( literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..0b52486cfc5f05044b9b56a9fe4cd784dca2c15b GIT binary patch literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache new file mode 100644 index 0000000000000000000000000000000000000000..d989e36ec8ef38c79c74bfdc93342613440fcf1e GIT binary patch literal 7258 zcmb_hPiz}m8J{<{sR#a-8 z=b7*Q`@Y}rd%y2_kt7q}RBxy0TZi=8?AkA9Nnwi;N)HR_G%5UUnw&i}4ZTygkCeRE zwk`2>*Y%Wq(`@hENvbqe)siH+asLS46QaGTCg{B~O&!uqHqu*BX{Jguhjg+m?IQ+S zQcVz5N%(*7d`YE0tZ6?WiGrq9>zgVxev(+KKTSa6R%);Q*%UO|W7Yb>7&LyCUaEhP zhQ?{8T0hA^<5$^Y{dpD|*K)=Br*hEvQ?6Ejg^fQ<%++5`K;!MHt@<~npz)8XTH#xS z6#h1~RoF|A!t@v^6yg7W$4McZ0e9p`;g31;#MHlYx@$YI*9kSDeMC}}WEF)FMWLA; z?Wvkj6m1+n37xOf`9r!`=I>V1S_$8c+Bz7jo4jirM}c)RmPc{e6j3RyX|D*OlZW&b zS({wS`CEyE;f!q=Ue~eQ>&!baSgY;09($~tU4yk-tnIP3%NljNV>C+41`Fr7?HbHL z3*9qZ-sxfcv0<@R*V;#1u$JvGowan++|&0TiNS7Uv+U|scK1Z@9GQj--x`eu$6JIqG*h9O=;V9|fwQW1Md0iTpe-x67(tn$u3sZ9l7`JoD*ZXM z_p;XDdzaf9K4;twC;tDvC6Ggq8<(^fVs9^iL%+`8`Xf6#V_&p8du_|O<^t$Vh!C?| ztRYfl!)0yDv*Cr?wjgl5=QpzKt1SkjF~c-EhUK9l=Mo=5cfgdB4xd@f5fp`Slm(*?wX#2#)lDTV3Jes=@D6@wN!XXL!xaxHXQE~M!O*v0ggRAG8o3$>P4788|_|y@34>M z`;Q>+`JNq~<$~sS9mjT-mt4q~y9TzGu(Nb9_b)hjd;CY^8v+&5v%iUW_BE1j4BbAQ zx8UnB$)~E;5PWI?pT3`zs~d3gSNMUV(?LF!vOO}`mU+qvAhrkua@$RxH={i-dIYeI zo-2tXW_<;*ir`*JBM^vUVHajZ^|@MHMoL zKnvV89v8#o@~mIdUJAc{41QH}xX=NozJ1ih6Z<*Ds%CcXyW%OuKNPd^n(!__;+=+MH>mu+BZRYViT1a7g4lHvq4#RsNoR7SYaKg1FufO|<&L&J z3`{D?DC$TQ!F#|Cd~*3$)gYgu{Cf(Jct0g)96-h06VK82z01PC0vMQSf*2@C&It@O zjg}56t1l8Ux}X*@h}H$s5!>$TyqiF^wP7cSG!))PtDAi;`hK3}CCMC3k_0OB^$#_2iDJw7lb=g-Lr9B8ANEO+RG1u*bs-E_I6jursEDFz?x zwwlei?Grj&?GHY@jq(t912{u8k~SN$vth=HljY7>JX0PJ1T& z{0#j3i*Z=>fQx0hwkT3)ymHOgj}Q~)8v8b6*cbr-g@FL%1sQKtE>I}J4l)#SfMFB| zYc!I_Zh!3I8M$XI2gW~q)C3ok_bcmN zDzr)>RZ_3qP|5JL8?Z-0xJXvdMm5_t72;7+mWTR;0;fXYi>&(3RZC#MNm3jTTN(pE zfH;MeM6b0qXfqEU{1-k!8FT8AjNCSHaszzace=90m3BM7oxy zWbce$^}y+_q(T4mL-6xR2+Sc_IsVPs8~kPs#1J&ZCwKXt_G97l=iu_cjD^=S;B={s z=0+O#RewMu$eaMubJ4ZWkPjp)NcjLE^%{!${^E zb35N`fnTuzi+(%xpD9X;c{s=e(fK$+o@eKhCr&Xs-77|?kt;kW z5W4AEzN3M-$&&TKYcE-$DC9*83ZigL3zu@P-MeE5q}v;88;reUn+YyME_NV-7zx%v zd_mP}KNPZ;qY47t!x>`glauXB#^qCN0Cz;KN?Vt}j5OZrlYovZ`~kXn`N$avGW{!arW-@-moLh5TV9 Pj|J8O*Ho0G-yr`36)Isa literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..8b36f47ca8f554f7005ebbf3285be4ae7326420d GIT binary patch literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache new file mode 100644 index 0000000000000000000000000000000000000000..62529545334bdbdf0797dc5ba7779d6eadbcbd7d GIT binary patch literal 2702 zcmd5;U2hvj6y4d6Y`kh@uB1Vt@Z{UvpVM;yALo`cw{o9l?B}h3`Q4jQtl3Q#tFK21*Rsu^Q{OXnunL|@%%!_A zP7~tI>ju1IgH?x&GrCsOAya@%9cFB0Jvx1$8~EG1rb9XJeLxKOCGY)AjNAfQsm>G8 z(Xpe8j!~@68`#O1rRubaopmc;buH|CZ18B7GSXs%Qkiw3L>+M=Rtl>CUD^exw423 zu;LwJ3^R2&BwI7z7~*u}QQTv^ABV{d2El03^@D&VoJNl+KZ$50NR!Z3=a_{eN=|DP zPTxaxvDxRf4acEZuhR0s?;hbg{HoPzl8_D>ptsd>&qc!<4mNVq!4#A2*{OG@?5;m} zU7`8{q4Eb4p$h!C_3DuF2mc^d?kS|O7PjBCO4crq9(BSYhnpj`y6L%+R;HxY1(Xn^ zS&_W4?K>e~l8HiETF4P7dV!)!fK*u?mdl3%Sob zQ7EZ{RFc%0%nudUs-(yIRvPpOgHnrf4+*q6!Jr}-CU(fyYK|b7W4Oj?BkCUcF?)?j zR`MPwkOv5I-W;BA9Od`b!Lx}h!kU!s8a?)dKEoj_%aBn&jId&3mmbNKbi$TM2|J;w z`DEx*Xe8-QI=o#}MOslsYB&xd2ZW%6kU4pWtbs|g!jO<{+q`8O`$Imypltt3Q|q|N zc;x#mN!EE=vz4HJ_4R4Yj!}Y!N&I7s{lSp^LzUf>1E{h@*TmntNGD%}9}!{lI|Tk3jIgMQc?8F0?b z&K6Eic+g4sMiRw*_5PMicU=1RLzmW{6tQ|GzN@G(8!0PpU@_enCNAB2D60+$fkoA@ zf3kN&*1}sat*Q1{I$ltWCcic$z(wzw0{9sM{P|Ss{v3Q4&hY(TFjY_}{Yoom>;_CN zq<)>r`iR2)=N=k@{X6-KsOKBD>J{Lj%ENW>Xt+S=Z|i%PbeJu|>}6Ok!17zLvj#ht zcki*JA8@ep_$V~)ezH`K<0w{pLng0&Sd{pj!skx56h#48YiOH2jQecqLqAB^8{}`- CaHa16 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..2395015401100f34736675fe98225d853098d534 GIT binary patch literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache new file mode 100644 index 0000000000000000000000000000000000000000..a00ce91d6e967cccbc3fb06b812213d5f34dd21a GIT binary patch literal 1882 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 W-%Mz(0#i!(lf#_&1p(}yApZfAnRP4x literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..6ec02d279a3395e477453db0c144ac488b739524 GIT binary patch literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache new file mode 100644 index 0000000000000000000000000000000000000000..282e43017750880bf511116eb8b996a120881481 GIT binary patch literal 6600 zcmds5-D@1z6`wn+)kve2rJJ=lp8@SCTby3tFNmTBF7eY3=a_oUWuuv#Tp< z*RwO*nNg&e1eel>VjM`Jc`#d+0?4pReGHFD2hbe@gx(jxeq#?~S44qXcU0nbc^^ zJ5*Bk=#ltu%k`v*9kW(hos{vkray~@u%YSO@blZc{yzNttEhjChElgFyn~Q_PLAOv z1;;CRR1FK1WIU?j(Fz_{#P0CpTXGEkQa>=f>i((a@ZH_yw658WX3eB)(uCvKjxTVz zr($(HUcp$2yw*+f{hLj%W?Sw+9gD)&V1GARt5;;aSpjdxl3yXM^iKqfnOLzzVz9t* ztuz^j#gB)JrRFd!exzun*A!TMJW?-xG6IX=jlNv^XcQK2t1p*+qQZiXl}r0$uy`*~ zEd4S8i+9FzrHA7v*4lOK2E@~ml$x~%>L=uw{sD?(q)HM(l7vU+^^6>oBz*|32#*$c zz?7Ae=fE2&4iAXY$)h_fx2bzzdg75j!kW}1n{irpYk94 zDO$kKs9`I@PHmBE4mCXLULppu=potWsN9}YRdV41SvxWsO_RFt-}d%4w?-u|5R-bu za9!$nw==hqfVn{86I12l3m*Ybq&X; z!hKRT!Nhc)Ng|~3rboAG)($-?kgMz#dNRiA%tX%F0GEpc)W-c2#=TXB)VUawN`qA;DMlgd z7k`gD8J_a;;%Cw45&yi>!#_nlRl(;w5~^p3_%CLfjB!!_68tq@c?zM0@n0tb8^bO; z&anl^F+ab^Va?kouHB%-*x9ME5E>@2MV%a+eEvpAJHNDMs)ow|>Qc)EX>ZViNSi!q zK(VQ9nKcV;v9tr!c28hGKAH6EB75^($3mbKe=nS$8`gkyW_98;sxrO8n(~|@h_J^sRQ%59o8&j;&o`hm5rb{Ft@4Zzx? zc1LrZK{dzw#eDa4hm7q2ejG9n(zMB8hkpgItHgz_QP7o`0WLXf5NKdf;0B|rZ%HS) zJjscY&RvsX&MFXA*!{eRy1HxI`9&>HuI9-SA^9t8|2n%1F-k9L?0S`5me}P=dXrVq zP%zqSN)9SZP*acyjwCI9J5fp8-?6vcs$oIjWwrMGZy-GVt0|9CStqOw*D-;s+Hx4( z1GS}?VTo8BGet>W{3@9^o8sx^WA11FVWX6ZqHUY0fT8%fdRO4;6TsC^6`@ZQSGTEm z;8^Z76tfCQpoT@DG1jW0iyrP%Zy&lRyHIjyxUh}40s_s|vb`rn;p@9|_S}kqp(sW@ zV92)gXBpjI1cTU%?Tn*)zw3_8vieAkFf>1!KaWK7dXILO=5(MV>y;ap&jx%lc}nsv zx_X@h@m1ES7!U(qBzS%}ydCYGHFhXCaBT$~2%0*KEh)~WAR+%Ke->*&Lh^9H`#dGT z3G`OFiGUn}%oO>&!(0;Rpvq(3D7k>HVFOiPNH)US{K zA6&}`!uvcgr#@ZTl2W{|M!j*8wjKTb!e57#fIs#qwxRUQMcI0!bcPEl>*|B%Sdo@R zPPSk3$#$U8fP8#_&%)GD#^+EgpnNFcd=hE}Y)^_=6qwAHv8ka67doY|6W>E^qw5_# zM7p1Z$H46H6vAncp5s&oBQ3={3r6$7Xwtu9-a>KSf^wxDnfIXNyD~JPN6&Hf!%hK0 zZJQ>odcT0~Vw$4AP?y-dtnC0L**h=|htQ*@Lt)OdttV_c>vnC^fL5v2m+4hQUc+eVQWg2(s9D8q_jgEW(;}a@rqfW=K1S4lKLs7Rt)=MxcWYSDx zIt#1`=1)GDb{BR0%|4=-N`WYqa3Thzm<_ajr+l7kbD_aIvwr!ljg8sO>G{=xAMNqYAKDi1+-{#^9(z2$ zyT8*Waxi?3>y_m<%5*%fwUnctnu4T2mmo7-4uOv6$-yJccaqg4 zMlbR6;o|DEGXA2z`ZqcG4$`hYL~`7&-73NTsDbbRpH51uZtY}Qfj>xEzNu4Uxv8^O+YBY6Lbm1ayATGs~weoV8 z-lc3Swc#`f`UCV3CpmvFsaprfFN*ck?V;DzM!v zwrSKCJu@-kZ`)1zcg=4mCTg}-J)1mtF{!;dt^a}zWw(>dUmwT8pAS^a zpB%t}Ig!hLmSWitGc5Zjd|n-A*|+i0Cswj|HI_|IvFtQHA0Nhbd_I4OWe*-@*=5eM z=keLfvFuCue0Bn|C)tqeF{Y0thxGrjVU1-H3C0o$ZS<13n&`0piw3%gXrlieW z!r|#p84cwGuXH#; zt&0=D$jPoorqj4MB))Mh47se|l7@T@hCH}W-7aR#r*1YqW4(FE7sesODPwMUZk-!2 z9eLZlGNI*M!MU2bVc=xT>f{JgFhk}y99|JmU+HgPse!=Ar=aa(H{&WXrBAXEiJp?8 zEW_BdjKOu;p>wIEHaxARB)FDt9(d=#9nWmo#=5E0{L$Xjysx{OQ$oSRiN0uJ7z|?! zD>JOpv!MtHdF+-$b&dw0(q%a z!kCl{{p}wQGb@MbzvNq7CIV9B=r;#nEF3DK(nL4 zDB<8a{r6I{|AuDoW@w2qt$wFbGn%GffD)xnH%+_7m14%=7Q_oBT0euAzatFk^ zKEVo+lHe7755otvs{SJVY-umDqIPg!^nNj?h*F;AIIx!VjtJ*1@D;39SWjLhW0@3Q zczqi&uWE94BO|Vpv3PT*F~DMh8Zhl#pwIrKw^k+DApDgAv1^yBW%%!8Nh^bJy@k4_m zw@Kb>G>OrOiGtwWVx)F1`%>{c&=PbM1Rk&tkCrtTIX7U69^AvEsTN?tQ-9y+2H~-#%uWCpOLX zt3E$?W7AZ@AV`opf`wp~{yZN%rc^OJ_Unf2BV@##JCtl;0OA+D?LZoeTKY-yH^~Vs z%8@!NKf)qPyQF{A)35skbWLdRU>MM~0Zfur^8Hh(KuW@+pg#$Cpfsr<;J+;&BBuFs zNSJKP81?xEh`Q4Bb}9?JY=WN2_ucjFy6H552841FK$LE_f-{||yB;bT2ZwbMn{Z&A z4mT_z#hf)74SNRx?$G$P@iW4VzVgCO4sHmAs>mk&YjNURmLJq`gJa$ULR$~E{IhdB zs01>Cg_re8OG{fRwX~R?z9CW@W0Kog2m+bPK>Q%n_mS+_J3?#n;h+=Ws>zJ0zr#xT zxyvdoQ6M)|akZ3x9!`0=IM0`!hZ9dwEeE&!>M`foF08fYp*~EckwZvrX1DM(ZRN3c z7rA9ebu239B-560sav)=CDeB)kxb(TcLV{sp2ikc@`($SsP<1gwLaH7YZW@JklBI?Z4Zenk~<`(5(&}F7Lf5>RpKEYD_>aP z7lE1P4Z1=_Ag*{|65@B0`q;TR{HgsPj(-8sw z=`b=K84#HsQu6&HQy?WHQ?88qgF;jGX8`#4`6(ir7_4&=*WdMXqC+B}Ab>^KZ5Z$_ zq-YjkCI}SR0un=~7Jj;8p?qxtbYA+a?5+j*osfY;Nz5+rIROsx@SH08bAr`HX-Xa` z79-47S;)6=YdHW(N4C!h+Ai17(#c~Wg=nK)ja@l5$fD{8T@qu}5 z+kz?(uZie_s=R`#wE|?@wtEAQ3Ds3LY@^vU9kd)#q9KD7%kE17bj4kG9e zZWy;M-xbw1pe73L0Wj-6^7vfN$j$Sc`Eay4Q>6A~JkN{H(oQB9Hql*B1fr0rPW75c zN>RBaa_}w>(~?kgP`Vvyxkd7!nX&6*8uNCQv#lj&P2!^v*7_cMa1VFy!5tOwoEZRO zDTOIS{PlFSS*b8>Ao@-ZcP=dk)K%Gw%L>;Ps}EX6L1=`__U>B;PcBA=rD?Ro)~h~^ zj#U|y6c&Gk35G<*#Q4)(W2?KsL(l|hDfzy1>1Ktlc}Sf&LZW$WfbQj}V@mg{`X8k3 zzku#b``cF=)4R%h9=p$ZPuFBb&|f>BsgCskI-|??+O3n-s_NNERP}4yNr~>^I2fG_`|Ol*Zo64wh=7n6lZ@kv&t{h)|8Tan)GAD#LgG2%>6`wkV?VwNe-Y zx+j0#2TE6IZF==jAcHv~qr~2qYQlhNTI=ZUfCJ}2>0H{IK+X}JqA|VVW$Vkff!x@AD z(RaLv8N$gq?d6D@qk?NROv8gbsvvX*@QQ@%)zE05dQ7Aj4RgIo6(G_LJPuk9WM%9= zI%2_LIn~j;Ti|^Y)4*GtuDv9A%Zx%Ahgr5TOo(!gxX&7xJ#{UEvpp_;{hu?WhYQLG0VTkNJV z%p$lg*Zwlq-$!Zj9Z$B)pK$9{%P~(U?oNrGCC)6!OKiz|aH2Q1W@3xCvGUnb=v{lSBEhGZksN+J~; zQ2)O~$MNn)`w+!RW=?DxwEkgSuyL?H{ra@V(r57kkSu7HweczKNI^R?rS<~oouJ{; b(1okBVgj+XrwtcyZi3J}D{zV_CfWZ04`O&F literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..f4e887486561f8be3945fd8b61344d52d6d64401 GIT binary patch literal 47 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 A*Z=?k literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache new file mode 100644 index 0000000000000000000000000000000000000000..803b10a07332be0a84317d77acfedc7e16097fe4 GIT binary patch literal 21827 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 bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache new file mode 100644 index 0000000000000000000000000000000000000000..8621e14afe1d360db5a53e513ea69d7e2ca45e60 GIT binary patch literal 10568 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 W@@*iRn844H!uq4K?}B#x0QoPNKzVuq literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a GIT binary patch literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache new file mode 100644 index 0000000000000000000000000000000000000000..6854436ee19d2eb620c05cf18f373ecb1659021c GIT binary patch literal 7764 zcmd5>U5Fdk6`ngi-|4C!LD5+jaIYT zktK~hGxF981t$fu@AgzBPvag*=qtQbOa0P#5|dXdnDgXrZ8xov=kW|A(4+qNTXQR z)Jm*wN<Rr)eN^t|dnYvfgXzqUL1=t7xSshO8~+(p zBFAJB`Pbmh$fp4k84Hp~9KPmLB=SS}<_AC<@Vy--k-K5iC>eS+YiUJkqM}u8OOjGM zWnbz#@lz6#Btj&K24kt$WFPeO!IjY9EDgrt&+sYTvM0DI-JS&R2_!SNsaK1l4^)AZ zdUW{-7{*L7{7F*=*HEWOUe!wS{P6V2=|)X6mqFaDl+>!rMnMBZq1d?&v8TOa_mE&S z;nq_HAzXpX(F=VW9_JsJTVSSEGc^nLpxU}ojfO&O za*`eYzFMi3H4E-?xg1w*h`r>_&5F6x%G{wtQ>KnYD)lHZVpMqvBn|fX=fGdR9#q^0+ z*!+{oq10J`)W=NRs)r znP1H`3PzTD6oDWpXb=KKb3*sWZ6=PTwig54EtsI=ac~DP^pHY_;&f<3hzHuu2XVYE zg1Y1cbt_`IxSB9z6L%r7kL)?W2lr)a72_(=vIWBiU`iIfxb*k7&7Di#@cQp8mof%Y zF3i$}I9=EVL~ReuwvB+?q3@=i0f!z+(`Vos>bX^~i-TIO?D=d@gX;uTLby&qC4m-J zcN+XPFX(MsQViy8PvR(kyM23IMef*JY5e{1MoqO>JsHS>^6PDu-nttpb)g(#%EA=iycwHf{>DR73_x@#+%epdpY2K zId=A1O@mx;QfSm2W3j4XgGXFd%X+~(8z#1L2&M>;RT3*#ET7qSaio2vTa{$LMh7O=tSBwOE-Kc8LpR0ytyTd(CZceHhrrVFg zxNBiBC76P;Db7kzdx!ob|J??`sxWEUfl*pVT{iphQ=0xLyn{v+h4f4!% zd&&fJXEBB((j{B|tpB(D08_A$?3KC{07E*!`S1Tjq_r|@MWK~AtpqyqB>@^qgXch{ z4(IbQhD3M9&{-sGWDt2Mo_JYs3qbkfK>KdHhU>S1nAOd)%dxq?w1uq7%22c*^j+4j zVPMt~!gbSv=uLBO2UOA_cbv@WRS~^>Nr<{FL@0l1c3W`@CIkacE9%j?@8plhogln8 z3I8YufZ&6>Gq{1MU<&kJa-5n&?VrCjGL!`R37pgMfKHD-;3WjTYu3$ZyvL+lCV`36 zJr1?>9w6=PQ;wYNwmYHOfG^gwJR6CPG&3ox+qDbAt+yM(1G8d5ThXg-PDFD3+~I}8 zt%TTvT;re_rxvj40Jo+MYjA|;U62X-qM{-5n1y0Vu{e_<8;sgGq~BMMp)hZ)^wXi=4V@uA5%8J+5|0h%f)gb3d%~@_7p{c9nV@f$=-XHry_cZx zmFQ2f`B8#?RHDDZ=KTb{U!q@N^I?KMjMIl$>V27@UzX@U;opd#B;Z?$1W7D;x`qX* zV?(1Rh4FS1#eY*K0rKsvkM|9?)uTNIc@gt59hvWbxKP9ynLf{UJgplU-6MXa6tz}avl%F1HO-cdhuv92R93RFPo^2i=Li%YxQcQBnj5(t;_Wl?p7aD@o)Ktl*n=PYv5{;aj zI=%urh{0jffuF-!QzOF*o?~@sLN6CI(@_riDAqyQd|eOY-w?~(Z7v8TbrX+Qbgx<= z^V}K!>o6thhRf9?Qf#?Op~IuM&7!(HbvkuJSpEi*+J5h|z0x&LlE=X4qR13%6&Q~= z>ug#6EE1#M6(dh2TOcFIr;hTfuT|$E@#J-#Q~P-s33f%JQBFl%1r{AP(v6CEP6upu zi&65H<5jjnoRU^*Y5&(9+Q06)7WzdGRsvY`gf$2*-s3d^cdfVJ#R#uRu7mN$`kNb& z-3_=emf*dT`zl}_K>8|-$(_`xRJKrJxahb;IK52&Hk*1tn)ycE?K$n0BLE=xkNwFLy&oAzj=@1+| z?56t^x^Iw9&C;pe&dVw4AEW-b@ATyfUZ$Z#Q=;Hc_!zv2q5fIu4xfcnv56CE*@C(v Hu#5Z;9viuX literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..2ae412bccfd7739434a236925520c9652e93ff84 GIT binary patch literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<nW832Uh9(Di# literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version new file mode 100644 index 00000000000..7dd8dc5809e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version @@ -0,0 +1 @@ +0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache new file mode 100644 index 0000000000000000000000000000000000000000..eba4407d83485e5a7ee4f182cdc6fdb2fb69ed59 GIT binary patch literal 3252 zcmbVOO>7fa5ZRZ|0kM z-+VL2%hD+sW@~WdQvP4^XMT242B_tyCvW5*Ps;suo6?SJg@Paq+m%;DIMUPKASviR z)NkRhUu*g!lFH8#&6pu*TpW)YKm8A4bY#W%)_ocT<#U^%<++0JoDdJ=5aTWn0TSXkOK#I^S?;@C@I0)??*_ z2(+NLhy=e?@e!r`Nqoe236YBT$bMoxKr4S+)Qnpq8naT>n32%0qj7nnYJ4(*22q|ElM0dM&w3ZaF4kdEl=R~y4J0dw zpzH=RAbFsmA0Px&!fTa{ybYx$6|cw*dFx~9H@twpe3)t?%)nnFkRh+ixr<@@ooAx_ zKOaCO09qmjca;cmDDzsT-!k2G>U$k2u)Fo9=U%6NSPw!UNm&oQx*1BGRjis{MAZ}s z5d=^!>BwP(Hi4f6=1MSEfH@h>=^E?$Ik{|bFZ0;xro)*V$7Y)ZkzN z4le9M6>}e2L0lp|uH6gj9m{w(Z8(i;08mPhH%>KC0xEwi_x+ArXLCd#gXeyfsKX`w z4zEL;y2e?$fKV1SSS-Ne!ic<{!^9D%casuJy$Xtt>bv!R*EJoh$x<<$g;rOX=iiYM zoaQmV3NgPzidByWrC9t!&P?POw+MM@ZfW{`#@`y;CvQ#NRJgmLvI>3mwB@!`(>>f$ zvAC*f+bRR0wmWWnlrte*)%~0(GC>rV#@57^kx^xleNjARh z<9xp1`PbgeX4Q(@jZdlQ38$s$JoTwz%SX?i-&Jo|;f89eSSza1mKCy4 zmYY@A>d{FnP*J@Ct3`c^@ROJ^ofdk)R2r0J#ZWA_ndLG+o~zc(>!#84t<8|%42Dk+ zVmCVh3Qgo0ua;fvqa%S7Pm@*h?8<-*#{}R+#7CS#yI(=LeE0Oj_)^DE4{&kGj_^Oc z1W3ilnZGmrHojfGZP|iEgIE{t?&yaz!~HO%+9jAS;DWSMwRe7JRK^BD(Hzw}rASV9 zUgFGN)m0{LS78M|vk9o%1kBajZ40*{vO)-|J~>*M5E)zd;+_5Y*>}vaxq**{XC&4L z#c$HTr?=koY!BZ(PT5YRyhHIL@N%x|dE3&?vU))|LzzNMJLY(dV>=%~D$dCoUw2Ih z2dY?)=2YGB*xFimWwyBPVo;5#ECW8~Uwm9W(T^caoX5zcS-ujFhmk=2Q|h18DY0@u zgtvQeat|zPu)Gg0HsJEB;FQ4G2VD)i8R$HOPxrv>8ho~A)D!{I8^v5+eMoDNF61uw z9Xfy7v;*2-8eS;5WFpT>gY76<#^O?kj`D3U-Es=k9ON}3pkMKfGNYv L2oQ}gM|;VC-XAjg literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..35823f819643250ce036eb3ade6a8b4cfeac4a68 GIT binary patch literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0uZ`~i9>azQphS>T;ri@)yrP21^3W{`nJO2#oDr|?QU$aZ4hBa z=+TRxz@y;Bi{HYlXZ;#p>%26{ZlMc;9x@qT!u$W`KQlXBXj)X6Q_Z5a&4C~Wj7zKwSJrJUa52{G_8u~6s`qk1uL6+abe&+-@xrtt98#(!m z?amjI__Ey@N>1!tqf^L%bp6*+F96UNQ0gHlf}#)rLXdr+cTftU3n&4Fc@){#$!?Hs zS&v46%M`s=Pf#jAq9eTtz%Sb5SX?YYyS{MD{aFRV=?(@Xfp_-cIlS-t-Pt7a6ZID> z>UF&xtLHcZ+1^suX@%jbu=%hah#6YC%0Q(#RXG+@t&9XxFB#@z{#$-A4rg6shJe4Y zgB?OZj=A#)*pd%=iwQ0t(H6(dk})Jgfe;x@=F3<34$h!AN*S6frdXyKLa^uOm2P_A ztyCW0mI<9L`-*kTT5u2i$t0Wz)Ao1@PF5uA+NcSg^kFyd!@>Q1e;NfdHy!~4#b#h^ ziArRW_1tkh)5$As-*R4^2noT_NT1 One&v_%-u7lUW7mHN#Q#H literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..401fd74cd1e9eb44559765e4eac26450d3f34537 GIT binary patch literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE new file mode 100644 index 00000000000..a84f0ec1d35 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE @@ -0,0 +1,190 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2023 Gleam Community Contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md new file mode 100644 index 00000000000..90ab0d56c57 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md @@ -0,0 +1,72 @@ +# gleam-community/ansi + +Format text with ANSI escape sequences. + +[![Package Version](https://img.shields.io/hexpm/v/gleam_community_ansi)](https://hex.pm/packages/gleam_community_ansi) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_ansi/) + +✨ This project is written in _pure Gleam_ so you can use it anywhere Gleam runs: +Erlang, Elixir, Node, Deno, even [some browsers](https://bit.ly/devtools-console-ansi-support)! + +--- + +## Quickstart + +```gleam +import gleam/io +import gleam_community/ansi + +pub fn main() { + let greeting = "Hello, " <> ansi.pink("world") <> "!" + + greeting + |> ansi.bg_white + |> io.println +} + +``` + +## Installation + +`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_ansi) +with the prefix `gleam_community_`. You can add them to your Gleam projects directly: + +```sh +gleam add gleam_community_ansi +``` + +The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_ansi). + +## ANSI-what? + +ANSI escape sequences date back to the 70s as a standard way to format text on +various video text terminals. Since then they have been adopted by many software +terminal emulators and platforms, including some Web browsers, and are a simple +way to format text without platform-specific APIs. + +The point of this package is to abstract the specific codes away and give you an +easy-to-understand API for formatting and colouring terminal text. Still, here is +a quick couple of examples of what's happening under the hood. + +You can copy these examples straight into your terminal to see them in action! + +- Colour text yellow: + + ```shell + $ echo "\e[33mhello" + ``` + +- Colour the background pink: + + ```shell + $ echo "\e[45mhello" + ``` + +- Render text italic: + + ```shell + $ echo "\e[3mhello\e[23m" + ``` + +As you can see, the escape sequences are a bit obscure. Sure, you could hard code +them, or you could use this package! diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml new file mode 100644 index 00000000000..5da1f7ec075 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml @@ -0,0 +1,13 @@ +name = "gleam_community_ansi" +version = "1.2.0" +licences = ["Apache-2.0"] +description = "ANSI colours, formatting, and control codes" +repository = { type = "github", user = "gleam-community", repo = "ansi" } +gleam = ">= 0.32.0" + +[dependencies] +gleam_stdlib = "~> 0.32" +gleam_community_colour = "~> 1.2" + +[dev-dependencies] +gleeunit = "~> 0.11" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam new file mode 100644 index 00000000000..a542ddac7ec --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam @@ -0,0 +1,2317 @@ +//// +//// - **Text style** +//// - [`bold`](#bold) +//// - [`italic`](#italic) +//// - [`underline`](#underline) +//// - [`strikethrough`](#strikethrough) +//// - [`inverse`](#inverse) +//// - [`dim`](#dim) +//// - [`hidden`](#hidden) +//// - [`reset`](#reset) +//// - **Text colour** +//// - [`black`](#black) +//// - [`red`](#red) +//// - [`green`](#green) +//// - [`yellow`](#yellow) +//// - [`blue`](#blue) +//// - [`magenta`](#magenta) +//// - [`cyan`](#cyan) +//// - [`white`](#white) +//// - [`pink`](#pink) +//// - [`grey`](#grey) +//// - [`gray`](#gray) +//// - [`bright_black`](#bright_black) +//// - [`bright_red`](#bright_red) +//// - [`bright_green`](#bright_green) +//// - [`bright_yellow`](#bright_yellow) +//// - [`bright_blue`](#bright_blue) +//// - [`bright_magenta`](#bright_magenta) +//// - [`bright_cyan`](#bright_cyan) +//// - [`bright_white`](#bright_white) +//// - [`hex`](#hex) +//// - [`colour`](#colour) +//// - [`color`](#color) +//// - **Background colour** +//// - [`bg_black`](#bg_black) +//// - [`bg_red`](#bg_red) +//// - [`bg_green`](#bg_green) +//// - [`bg_yellow`](#bg_yellow) +//// - [`bg_blue`](#bg_blue) +//// - [`bg_magenta`](#bg_magenta) +//// - [`bg_cyan`](#bg_cyan) +//// - [`bg_white`](#bg_white) +//// - [`bg_pink`](#bg_pink) +//// - [`bg_bright_black`](#bg_bright_black) +//// - [`bg_bright_red`](#bg_bright_red) +//// - [`bg_bright_green`](#bg_bright_green) +//// - [`bg_bright_yellow`](#bg_bright_yellow) +//// - [`bg_bright_blue`](#bg_bright_blue) +//// - [`bg_bright_magenta`](#bg_bright_magenta) +//// - [`bg_bright_cyan`](#bg_bright_cyan) +//// - [`bg_bright_white`](#bg_bright_white) +//// - [`bg_hex`](#bg_hex) +//// - [`bg_colour`](#bg_colour) +//// - [`bg_color`](#bg_color) +//// +//// --- +//// +//// This package was heavily inspired by the `colours` module in the Deno standard +//// library. The original source code can be found +//// here. +//// +////
+//// The license of that package is produced below: +//// +//// +//// > MIT License +//// +//// > Copyright 2018-2022 the Deno authors. +//// +//// > Permission is hereby granted, free of charge, to any person obtaining a copy +//// of this software and associated documentation files (the "Software"), to deal +//// in the Software without restriction, including without limitation the rights +//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//// copies of the Software, and to permit persons to whom the Software is +//// furnished to do so, subject to the following conditions: +//// +//// > The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +////
+//// + +// Just in case we decide in the future to no longer include the above reference +// and license, this package was initially a port of the Deno `colours` module: +// +// https://deno.land/std@0.167.0/fmt/colours.ts +// + +// This seems like a really handy reference if/when we want to expand this beyond +// formatting escape sequences: +// +// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 +// + +// IMPORTS -------------------------------------------------------------------- + +import gleam/int +import gleam/list +import gleam/string +import gleam_community/colour.{type Colour} as gc_colour + +// CONSTS --------------------------------------------------------------------- + +const asci_escape_character = "" + +// TYPES ---------------------------------------------------------------------- + +type Code { + Code(open: String, close: String, regexp: String) +} + +// UTILITY -------------------------------------------------------------------- + +/// Builds colour code +fn code(open: List(Int), close: Int) -> Code { + let close_str = int.to_string(close) + let open_strs = list.map(open, int.to_string) + + Code( + open: asci_escape_character <> "[" <> string.join(open_strs, ";") <> "m", + close: asci_escape_character <> "[" <> close_str <> "m", + regexp: asci_escape_character <> "[" <> close_str <> "m", + ) +} + +/// Applies colour and background based on colour code and its associated text +fn run(text: String, code: Code) -> String { + code.open <> string.replace(text, code.regexp, code.open) <> code.close +} + +// STYLES --------------------------------------------------------------------- + +/// Reset the text modified +pub fn reset(text: String) -> String { + run(text, code([0], 0)) +} + +/// Style the given text bold. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bold("lucy") +/// // => "\x1B[1mlucy\x1B[22m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code +/// for the "default" bold/dim style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +/// +/// +pub fn bold(text: String) -> String { + run(text, code([1], 22)) +} + +/// Style the given text's colour to be dimmer. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("lucy") +/// // => "\x1B[2mlucy\x1B[22m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code +/// for the "default" bold/dim style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +/// +/// +pub fn dim(text: String) -> String { + run(text, code([2], 22)) +} + +/// Style the given text italic. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.italic("lucy") +/// // => "\x1B[3mlucy\x1B[23m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[23m"` added to the string. This is the escape code +/// for the "default" italic style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.underline("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be underlined but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +/// +/// +pub fn italic(text: String) -> String { + run(text, code([3], 23)) +} + +/// Style the given text's colour to be dimmer. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.underline("lucy") +/// // => "\x1B[4mlucy\x1B[24m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[24m"` added to the string. This is the escape code +/// for the "default" underline style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +/// +/// +pub fn underline(text: String) -> String { + run(text, code([4], 24)) +} + +/// Inverse the given text's colour, and background colour. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.inverse("lucy") +/// // => "\x1B[7mlucy\x1B[27m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[27m"` added to the string. This is the escape code +/// for the "default" inverse style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +/// +/// +pub fn inverse(text: String) -> String { + run(text, code([7], 27)) +} + +/// Style the given text to be hidden. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.hidden("lucy") +/// // => "\x1B[8mlucy\x1B[28m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[28m"` added to the string. This is the escape code +/// for the "default" hidden style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +/// +/// +pub fn hidden(text: String) -> String { + run(text, code([8], 28)) +} + +/// Style the given text to be striked through. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.strikethrough("lucy") +/// // => "\x1B[9mlucy\x1B[29m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[29m"` added to the string. This is the escape code +/// for the "default" strikethrough style of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// style, it will use both the outter style and the inner style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be dim but the text "fun?" will be +/// both underlined, *and* bold! +///
+/// +/// +/// +pub fn strikethrough(text: String) -> String { + run(text, code([9], 29)) +} + +// FOREGROUND ----------------------------------------------------------------- + +/// Colour the given text black. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.black("lucy") +/// // => "\x1B[30mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn black(text: String) -> String { + run(text, code([30], 39)) +} + +/// Colour the given text red. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.red("lucy") +/// // => "\x1B[31mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn red(text: String) -> String { + run(text, code([31], 39)) +} + +/// Colour the given text green. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.green("lucy") +/// // => "\x1B[32mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn green(text: String) -> String { + run(text, code([32], 39)) +} + +/// Colour the given text yellow. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("lucy") +/// // => "\x1B[33mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn yellow(text: String) -> String { + run(text, code([33], 39)) +} + +/// Colour the given text blue. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.blue("lucy") +/// // => "\x1B[34mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn blue(text: String) -> String { + run(text, code([34], 39)) +} + +/// Colour the given text magenta. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.magenta("lucy") +/// // => "\x1B[35mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn magenta(text: String) -> String { + run(text, code([35], 39)) +} + +/// Colour the given text cyan. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.cyan("lucy") +/// // => "\x1B[36mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn cyan(text: String) -> String { + run(text, code([36], 39)) +} + +/// Colour the given text white. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.white("lucy") +/// // => "\x1B[37mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn white(text: String) -> String { + run(text, code([37], 39)) +} + +/// Colour the given text gray. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.gray("lucy") +/// // => "\x1B[90mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn grey(text: String) -> String { + bright_black(text) +} + +/// This is an alias for [`grey`](#grey) for those who prefer the American English +/// spelling. +/// +pub fn gray(text: String) -> String { + bright_black(text) +} + +/// Colour the given text bright black. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bright_black("lucy") +/// // => "\x1B[90mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_black(text: String) -> String { + run(text, code([90], 39)) +} + +/// Colour the given text bright red. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bright_red("lucy") +/// // => "\x1B[91mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_red(text: String) -> String { + run(text, code([91], 39)) +} + +/// Colour the given text bright green. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_green("lucy") +/// // => "\x1B[92mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_green(text: String) -> String { + run(text, code([92], 39)) +} + +/// Colour the given text bright yellow. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_yellow("lucy") +/// // => "\x1B[93mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_yellow(text: String) -> String { + run(text, code([93], 39)) +} + +/// Colour the given text bright blue. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_blue("lucy") +/// // => "\x1B[94mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_blue(text: String) -> String { + run(text, code([94], 39)) +} + +/// Colour the given text bright gremagentaen. This should increase the luminosity +/// of the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_magenta("lucy") +/// // => "\x1B[95mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_magenta(text: String) -> String { + run(text, code([95], 39)) +} + +/// Colour the given text bright cyan. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_cyan("lucy") +/// // => "\x1B[96mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_cyan(text: String) -> String { + run(text, code([96], 39)) +} + +/// Colour the given text bright white. This should increase the luminosity of +/// the base colour, but some terminals will interpret this as bold instead. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// ansi.bright_white("lucy") +/// // => "\x1B[97mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bright_white(text: String) -> String { + run(text, code([97], 39)) +} + +/// Colour the given text pink. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.pink("lucy") +/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn pink(text: String) -> String { + hex(text, 0xffaff3) +} + +/// Colour the given text the given colour represented by a hex `Int`. +/// +/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). +/// +/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the +/// colour will be set to black and white respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.hex("lucy", 0xffaff3) +/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn hex(text: String, colour: Int) -> String { + let colour = int.clamp(colour, max: 0xffffff, min: 0x0) + run( + text, + code( + [ + 38, + 2, + int.bitwise_shift_right(colour, 16) + |> int.bitwise_and(0xff), + int.bitwise_shift_right(colour, 8) + |> int.bitwise_and(0xff), + int.bitwise_and(colour, 0xff), + ], + 39, + ), + ) +} + +/// Colour the given text the given colour represented by a `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// import gleam_community/colour.{Colour} +/// +/// fn example() { +/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) +/// ansi.colour("lucy", pink) +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn colour(text: String, colour: Colour) -> String { + let hex_colour = gc_colour.to_rgb_hex(colour) + hex(text, hex_colour) +} + +/// This is an alias for [`colour`](#colour) for those who prefer the American English +/// spelling. +/// +pub fn color(text: String, color: Colour) -> String { + colour(text, color) +} + +// BACKGROUND ----------------------------------------------------------------- + +/// Colour the given text's background black. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_black("lucy") +/// // => "\x1B[40mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_black(text: String) -> String { + run(text, code([40], 49)) +} + +/// Colour the given text's background red. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_red("lucy") +/// // => "\x1B[41mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_red(text: String) -> String { + run(text, code([41], 49)) +} + +/// Colour the given text's background green. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_green("lucy") +/// // => "\x1B[42mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_green(text: String) -> String { + run(text, code([42], 49)) +} + +/// Colour the given text's background yellow. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_yellow("lucy") +/// // => "\x1B[43mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_yellow(text: String) -> String { + run(text, code([43], 49)) +} + +/// Colour the given text's background blue. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_blue("lucy") +/// // => "\x1B[44mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_blue(text: String) -> String { + run(text, code([44], 49)) +} + +/// Colour the given text's background magenta. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_magenta("lucy") +/// // => "\x1B[45mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_magenta(text: String) -> String { + run(text, code([45], 49)) +} + +/// Colour the given text's background cyan. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_cyan("lucy") +/// // => "\x1B[46mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_cyan(text: String) -> String { + run(text, code([46], 49)) +} + +/// Colour the given text's background white. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_white("lucy") +/// // => "\x1B[47mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_white(text: String) -> String { + run(text, code([47], 49)) +} + +/// Colour the given text's background bright black. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_black("lucy") +/// // => "\x1B[100mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_black(text: String) -> String { + run(text, code([100], 49)) +} + +/// Colour the given text's background bright red. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_red("lucy") +/// // => "\x1B[101mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_red(text: String) -> String { + run(text, code([101], 49)) +} + +/// Colour the given text's background bright green. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_green("lucy") +/// // => "\x1B[102mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_green(text: String) -> String { + run(text, code([102], 49)) +} + +/// Colour the given text's background bright yellow. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_yellow("lucy") +/// // => "\x1B[103mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_yellow(text: String) -> String { + run(text, code([103], 49)) +} + +/// Colour the given text's background bright blue. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_blue("lucy") +/// // => "\x1B[104mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_blue(text: String) -> String { + run(text, code([104], 49)) +} + +/// Colour the given text's background bright magenta. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_magenta("lucy") +/// // => "\x1B[105mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_magenta(text: String) -> String { + run(text, code([105], 49)) +} + +/// Colour the given text's background bright cyan. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_cyan("lucy") +/// // => "\x1B[106mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_cyan(text: String) -> String { + run(text, code([106], 49)) +} + +/// Colour the given text's background bright white. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_bright_white("lucy") +/// // => "\x1B[107mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_bright_white(text: String) -> String { + run(text, code([107], 49)) +} + +/// Colour the given text's background pink. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.bg_pink("lucy") +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_pink(text: String) -> String { + bg_hex(text, 0xffaff3) +} + +/// Colour the given text's background the given colour represented by a hex `Int`. +/// +/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). +/// +/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the +/// colour will be set to black and white respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.hex("lucy", 0xffaff3) +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_hex(text: String, colour: Int) -> String { + run( + text, + code( + [ + 48, + 2, + int.bitwise_shift_right(colour, 16) + |> int.bitwise_and(0xff), + int.bitwise_shift_right(colour, 8) + |> int.bitwise_and(0xff), + int.bitwise_and(colour, 0xff), + ], + 49, + ), + ) +} + +/// Colour the given text's background with the given colour represented by a `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// import gleam_community/ansi +/// import gleam_community/colour.{Colour} +/// +/// fn example() { +/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) +/// ansi.bg_colour("lucy", pink) +/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" +/// } +/// ``` +/// +/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code +/// for the "default" colour of the terminal. This means text you write after +/// this will revert back to default. +/// +/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default +/// colour, it will use the colour of the outter style. +/// +/// ```gleam +/// import gleam_community/ansi +/// +/// fn example() { +/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") +/// } +/// ``` +/// +/// In this example, the text "Gleam" will be pink but the text "fun?" will be +/// yellow, *not* the default colour! +///
+/// +/// +/// +pub fn bg_colour(text: String, colour: Colour) -> String { + let hex_colour = gc_colour.to_rgb_hex(colour) + bg_hex(text, hex_colour) +} + +/// This is an alias for [`bg_colour`](#bg_colour) for those who prefer the American English +/// spelling. +/// +pub fn bg_color(text: String, colour: Colour) -> String { + bg_colour(text, colour) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl new file mode 100644 index 00000000000..8b7a4c9e72f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl @@ -0,0 +1,263 @@ +-module(gleam_community@ansi). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([reset/1, bold/1, dim/1, italic/1, underline/1, inverse/1, hidden/1, strikethrough/1, black/1, red/1, green/1, yellow/1, blue/1, magenta/1, cyan/1, white/1, bright_black/1, grey/1, gray/1, bright_red/1, bright_green/1, bright_yellow/1, bright_blue/1, bright_magenta/1, bright_cyan/1, bright_white/1, hex/2, pink/1, colour/2, color/2, bg_black/1, bg_red/1, bg_green/1, bg_yellow/1, bg_blue/1, bg_magenta/1, bg_cyan/1, bg_white/1, bg_bright_black/1, bg_bright_red/1, bg_bright_green/1, bg_bright_yellow/1, bg_bright_blue/1, bg_bright_magenta/1, bg_bright_cyan/1, bg_bright_white/1, bg_hex/2, bg_pink/1, bg_colour/2, bg_color/2]). +-export_type([code/0]). + +-type code() :: {code, binary(), binary(), binary()}. + +-spec code(list(integer()), integer()) -> code(). +code(Open, Close) -> + Close_str = gleam@int:to_string(Close), + Open_strs = gleam@list:map(Open, fun gleam@int:to_string/1), + {code, + <<<<<<""/utf8, "["/utf8>>/binary, + (gleam@string:join(Open_strs, <<";"/utf8>>))/binary>>/binary, + "m"/utf8>>, + <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>, + <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>}. + +-spec run(binary(), code()) -> binary(). +run(Text, Code) -> + <<<<(erlang:element(2, Code))/binary, + (gleam@string:replace( + Text, + erlang:element(4, Code), + erlang:element(2, Code) + ))/binary>>/binary, + (erlang:element(3, Code))/binary>>. + +-spec reset(binary()) -> binary(). +reset(Text) -> + run(Text, code([0], 0)). + +-spec bold(binary()) -> binary(). +bold(Text) -> + run(Text, code([1], 22)). + +-spec dim(binary()) -> binary(). +dim(Text) -> + run(Text, code([2], 22)). + +-spec italic(binary()) -> binary(). +italic(Text) -> + run(Text, code([3], 23)). + +-spec underline(binary()) -> binary(). +underline(Text) -> + run(Text, code([4], 24)). + +-spec inverse(binary()) -> binary(). +inverse(Text) -> + run(Text, code([7], 27)). + +-spec hidden(binary()) -> binary(). +hidden(Text) -> + run(Text, code([8], 28)). + +-spec strikethrough(binary()) -> binary(). +strikethrough(Text) -> + run(Text, code([9], 29)). + +-spec black(binary()) -> binary(). +black(Text) -> + run(Text, code([30], 39)). + +-spec red(binary()) -> binary(). +red(Text) -> + run(Text, code([31], 39)). + +-spec green(binary()) -> binary(). +green(Text) -> + run(Text, code([32], 39)). + +-spec yellow(binary()) -> binary(). +yellow(Text) -> + run(Text, code([33], 39)). + +-spec blue(binary()) -> binary(). +blue(Text) -> + run(Text, code([34], 39)). + +-spec magenta(binary()) -> binary(). +magenta(Text) -> + run(Text, code([35], 39)). + +-spec cyan(binary()) -> binary(). +cyan(Text) -> + run(Text, code([36], 39)). + +-spec white(binary()) -> binary(). +white(Text) -> + run(Text, code([37], 39)). + +-spec bright_black(binary()) -> binary(). +bright_black(Text) -> + run(Text, code([90], 39)). + +-spec grey(binary()) -> binary(). +grey(Text) -> + bright_black(Text). + +-spec gray(binary()) -> binary(). +gray(Text) -> + bright_black(Text). + +-spec bright_red(binary()) -> binary(). +bright_red(Text) -> + run(Text, code([91], 39)). + +-spec bright_green(binary()) -> binary(). +bright_green(Text) -> + run(Text, code([92], 39)). + +-spec bright_yellow(binary()) -> binary(). +bright_yellow(Text) -> + run(Text, code([93], 39)). + +-spec bright_blue(binary()) -> binary(). +bright_blue(Text) -> + run(Text, code([94], 39)). + +-spec bright_magenta(binary()) -> binary(). +bright_magenta(Text) -> + run(Text, code([95], 39)). + +-spec bright_cyan(binary()) -> binary(). +bright_cyan(Text) -> + run(Text, code([96], 39)). + +-spec bright_white(binary()) -> binary(). +bright_white(Text) -> + run(Text, code([97], 39)). + +-spec hex(binary(), integer()) -> binary(). +hex(Text, Colour) -> + Colour@1 = gleam@int:clamp(Colour, 16#0, 16#ffffff), + run( + Text, + code( + [38, + 2, + begin + _pipe = erlang:'bsr'(Colour@1, 16), + erlang:'band'(_pipe, 16#ff) + end, + begin + _pipe@1 = erlang:'bsr'(Colour@1, 8), + erlang:'band'(_pipe@1, 16#ff) + end, + erlang:'band'(Colour@1, 16#ff)], + 39 + ) + ). + +-spec pink(binary()) -> binary(). +pink(Text) -> + hex(Text, 16#ffaff3). + +-spec colour(binary(), gleam_community@colour:colour()) -> binary(). +colour(Text, Colour) -> + Hex_colour = gleam_community@colour:to_rgb_hex(Colour), + hex(Text, Hex_colour). + +-spec color(binary(), gleam_community@colour:colour()) -> binary(). +color(Text, Color) -> + colour(Text, Color). + +-spec bg_black(binary()) -> binary(). +bg_black(Text) -> + run(Text, code([40], 49)). + +-spec bg_red(binary()) -> binary(). +bg_red(Text) -> + run(Text, code([41], 49)). + +-spec bg_green(binary()) -> binary(). +bg_green(Text) -> + run(Text, code([42], 49)). + +-spec bg_yellow(binary()) -> binary(). +bg_yellow(Text) -> + run(Text, code([43], 49)). + +-spec bg_blue(binary()) -> binary(). +bg_blue(Text) -> + run(Text, code([44], 49)). + +-spec bg_magenta(binary()) -> binary(). +bg_magenta(Text) -> + run(Text, code([45], 49)). + +-spec bg_cyan(binary()) -> binary(). +bg_cyan(Text) -> + run(Text, code([46], 49)). + +-spec bg_white(binary()) -> binary(). +bg_white(Text) -> + run(Text, code([47], 49)). + +-spec bg_bright_black(binary()) -> binary(). +bg_bright_black(Text) -> + run(Text, code([100], 49)). + +-spec bg_bright_red(binary()) -> binary(). +bg_bright_red(Text) -> + run(Text, code([101], 49)). + +-spec bg_bright_green(binary()) -> binary(). +bg_bright_green(Text) -> + run(Text, code([102], 49)). + +-spec bg_bright_yellow(binary()) -> binary(). +bg_bright_yellow(Text) -> + run(Text, code([103], 49)). + +-spec bg_bright_blue(binary()) -> binary(). +bg_bright_blue(Text) -> + run(Text, code([104], 49)). + +-spec bg_bright_magenta(binary()) -> binary(). +bg_bright_magenta(Text) -> + run(Text, code([105], 49)). + +-spec bg_bright_cyan(binary()) -> binary(). +bg_bright_cyan(Text) -> + run(Text, code([106], 49)). + +-spec bg_bright_white(binary()) -> binary(). +bg_bright_white(Text) -> + run(Text, code([107], 49)). + +-spec bg_hex(binary(), integer()) -> binary(). +bg_hex(Text, Colour) -> + run( + Text, + code( + [48, + 2, + begin + _pipe = erlang:'bsr'(Colour, 16), + erlang:'band'(_pipe, 16#ff) + end, + begin + _pipe@1 = erlang:'bsr'(Colour, 8), + erlang:'band'(_pipe@1, 16#ff) + end, + erlang:'band'(Colour, 16#ff)], + 49 + ) + ). + +-spec bg_pink(binary()) -> binary(). +bg_pink(Text) -> + bg_hex(Text, 16#ffaff3). + +-spec bg_colour(binary(), gleam_community@colour:colour()) -> binary(). +bg_colour(Text, Colour) -> + Hex_colour = gleam_community@colour:to_rgb_hex(Colour), + bg_hex(Text, Hex_colour). + +-spec bg_color(binary(), gleam_community@colour:colour()) -> binary(). +bg_color(Text, Colour) -> + bg_colour(Text, Colour). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src new file mode 100644 index 00000000000..dfcfdc39497 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src @@ -0,0 +1,9 @@ +{application, gleam_community_ansi, [ + {vsn, "1.2.0"}, + {applications, [gleam_community_colour, + gleam_stdlib, + gleeunit]}, + {description, "ANSI colours, formatting, and control codes"}, + {modules, [gleam_community@ansi]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE new file mode 100644 index 00000000000..a84f0ec1d35 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE @@ -0,0 +1,190 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2023 Gleam Community Contributors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md new file mode 100644 index 00000000000..0eccdd7dd50 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md @@ -0,0 +1,36 @@ +# gleam-community/colour + +A package for a standard Colour type, conversions, and other utilities. + +[![Package Version](https://img.shields.io/hexpm/v/gleam_community_colour)](https://hex.pm/packages/gleam_community_colour) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_colour/) + +✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! + +--- + +## Quickstart + +```gleam +import gleam_community/colour +import gleam_community/colour/accessibility + +pub fn main() { + let foreground = colour.from_hsl(h: 0.858, s: 1.0, l: 0.843) + + let background_options = [colour.light_grey, colour.dark_grey] + + let background = accessibility.maximum_contrast(foreground, background_options) +} +``` + +## Installation + +`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_colour) +with the prefix `gleam_community_`. You can add them to your Gleam projects directly: + +```sh +gleam add gleam_community_colour +``` + +The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_colour). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml new file mode 100644 index 00000000000..07a81bf3b42 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml @@ -0,0 +1,11 @@ +name = "gleam_community_colour" +version = "1.2.0" +licences = ["Apache-2.0"] +description = "Colour types, conversions, and other utilities" +repository = { type = "github", user = "gleam-community", repo = "colour" } + +[dependencies] +gleam_stdlib = "~> 0.32" + +[dev-dependencies] +gleeunit = "~> 0.11" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl new file mode 100644 index 00000000000..06116dfe288 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl @@ -0,0 +1 @@ +-record(hsla, {h :: float(), s :: float(), l :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl new file mode 100644 index 00000000000..fff139e06ac --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl @@ -0,0 +1 @@ +-record(rgba, {r :: float(), g :: float(), b :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam new file mode 100644 index 00000000000..1f5872faffa --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam @@ -0,0 +1,1126 @@ +//// +//// - **Types** +//// - [`Colour`](#Colour) +//// - [`Color`](#Color) +//// - **Constructors** +//// - [`from_rgb255`](#from_rgb255) +//// - [`from_rgb`](#from_rgb) +//// - [`from_rgba`](#from_rgba) +//// - [`from_hsl`](#from_hsl) +//// - [`from_hsla`](#from_hsla) +//// - [`from_rgb_hex`](#from_rgb_hex) +//// - [`from_rgba_hex`](#from_rgba_hex) +//// - [`from_rgb_hex_string`](#from_rgb_hex_string) +//// - [`from_rgba_hex_string`](#from_rgba_hex_string) +//// - **Conversions** +//// - [`to_rgba`](#to_rgba) +//// - [`to_hsla`](#hsla) +//// - [`to_css_rgba_string`](#to_css_rgba_string) +//// - [`to_rgba_hex_string`](#to_rgba_hex_string) +//// - [`to_rgb_hex_string`](#to_rgb_hex_string) +//// - [`to_rgba_hex`](#to_rgba_hex) +//// - [`to_rgb_hex`](#to_rgb_hex) +//// - **Colours** +//// - [`light_red`](#light_red) +//// - [`red`](#red) +//// - [`dark_red`](#dark_red) +//// - [`light_orange`](#light_orange) +//// - [`orange`](#orange) +//// - [`dark_orange`](#dark_orange) +//// - [`light_yellow`](#light_yellow) +//// - [`yellow`](#yellow) +//// - [`dark_yellow`](#dark_yellow) +//// - [`light_green`](#light_green) +//// - [`green`](#green) +//// - [`dark_green`](#dark_green) +//// - [`light_blue`](#light_blue) +//// - [`blue`](#blue) +//// - [`dark_blue`](#dark_blue) +//// - [`light_purple`](#light_purple) +//// - [`purple`](#purple) +//// - [`dark_purple`](#dark_purple) +//// - [`light_brown`](#light_brown) +//// - [`brown`](#brown) +//// - [`dark_brown`](#dark_brown) +//// - [`black`](#black) +//// - [`white`](#white) +//// - [`light_grey`](#light_grey) +//// - [`grey`](#grey) +//// - [`dark_grey`](#dark_grey) +//// - [`light_gray`](#light_gray) +//// - [`gray`](#gray) +//// - [`dark_gray`](#dark_gray) +//// - [`light_charcoal`](#light_charcoal) +//// - [`charcoal`](#charcoal) +//// - [`dark_charcoal`](#dark_charcoal) +//// - [`pink`](#pink) +//// +//// --- +//// +//// This package was heavily inspired by the `elm-color` module. +//// The original source code can be found +//// here. +//// +////
+//// The license of that package is produced below: +//// +//// +//// > MIT License +//// +//// > Copyright 2018 Aaron VonderHaar +//// +//// > Redistribution and use in source and binary forms, with or without modification, +//// are permitted provided that the following conditions are met: +//// +//// 1. Redistributions of source code must retain the above copyright notice, +//// this list of conditions and the following disclaimer. +//// +//// 2. Redistributions in binary form must reproduce the above copyright notice, +//// this list of conditions and the following disclaimer in the documentation +//// and/or other materials provided with the distribution. +//// +//// 3. Neither the name of the copyright holder nor the names of its contributors +//// may be used to endorse or promote products derived from this software without +//// specific prior written permission. +//// +//// > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +//// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +//// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +//// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +//// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +//// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +//// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//// +//// > The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +////
+//// + +// Just in case we decide in the future to no longer include the above reference +// and license, this package was initially a port of the `elm-color` module: +// +// https://github.com/avh4/elm-color/ +// + +// IMPORTS -------------------------------------------------------------------- + +import gleam/int +import gleam/float +import gleam/result +import gleam/string +import gleam/list + +// TYPES ---------------------------------------------------------------------- + +/// A representation of a colour that can be converted to RGBA or HSLA format. +/// +/// +///
+/// +pub opaque type Colour { + Rgba(r: Float, g: Float, b: Float, a: Float) + Hsla(h: Float, s: Float, l: Float, a: Float) +} + +/// Type alias for `Colour` +/// +/// +///
+/// +pub type Color = + Colour + +// UTILITY -------------------------------------------------------------------- + +fn valid_colour_value(c: Float) -> Result(Float, Nil) { + case c >. 1.0 || c <. 0.0 { + True -> Error(Nil) + False -> Ok(c) + } +} + +fn hue_to_rgb(hue: Float, m1: Float, m2: Float) -> Float { + let h = case hue { + _ if hue <. 0.0 -> hue +. 1.0 + _ if hue >. 1.0 -> hue -. 1.0 + _ -> hue + } + + let h_t_6 = h *. 6.0 + let h_t_2 = h *. 2.0 + let h_t_3 = h *. 3.0 + + case h { + _ if h_t_6 <. 1.0 -> m1 +. { m2 -. m1 } *. h *. 6.0 + _ if h_t_2 <. 1.0 -> m2 + _ if h_t_3 <. 2.0 -> m1 +. { m2 -. m1 } *. { 2.0 /. 3.0 -. h } *. 6.0 + _ -> m1 + } +} + +fn hex_string_to_int(hex_string: String) -> Result(Int, Nil) { + let hex = case hex_string { + "#" <> hex_number -> hex_number + "0x" <> hex_number -> hex_number + _ -> hex_string + } + + hex + |> string.lowercase() + |> string.to_graphemes() + |> list.reverse() + |> list.index_fold( + Ok(0), + fn(total, char, index) { + case total { + Error(Nil) -> Error(Nil) + Ok(v) -> { + use num <- result.then(case char { + "a" -> Ok(10) + "b" -> Ok(11) + "c" -> Ok(12) + "d" -> Ok(13) + "e" -> Ok(14) + "f" -> Ok(15) + _ -> int.parse(char) + }) + use base <- result.then(int.power(16, int.to_float(index))) + Ok(v + float.round(int.to_float(num) *. base)) + } + } + }, + ) +} + +fn hsla_to_rgba( + h: Float, + s: Float, + l: Float, + a: Float, +) -> #(Float, Float, Float, Float) { + let m2 = case l <=. 0.5 { + True -> l *. { s +. 1.0 } + False -> l +. s -. l *. s + } + + let m1 = l *. 2.0 -. m2 + + let r = hue_to_rgb(h +. 1.0 /. 3.0, m1, m2) + let g = hue_to_rgb(h, m1, m2) + let b = hue_to_rgb(h -. 1.0 /. 3.0, m1, m2) + + #(r, g, b, a) +} + +fn rgba_to_hsla( + r: Float, + g: Float, + b: Float, + a: Float, +) -> #(Float, Float, Float, Float) { + let min_colour = float.min(r, float.min(g, b)) + + let max_colour = float.max(r, float.max(g, b)) + + let h1 = case True { + _ if max_colour == r -> float.divide(g -. b, max_colour -. min_colour) + _ if max_colour == g -> + float.divide(b -. r, max_colour -. min_colour) + |> result.then(fn(d) { Ok(2.0 +. d) }) + _ -> + float.divide(r -. g, max_colour -. min_colour) + |> result.then(fn(d) { Ok(4.0 +. d) }) + } + + let h2 = case h1 { + Ok(v) -> Ok(v *. { 1.0 /. 6.0 }) + _ -> h1 + } + + let h3 = case h2 { + Ok(v) if v <. 0.0 -> v +. 1.0 + Ok(v) -> v + _ -> 0.0 + } + + let l = { min_colour +. max_colour } /. 2.0 + + let s = case True { + _ if min_colour == max_colour -> 0.0 + _ if l <. 0.5 -> + { max_colour -. min_colour } /. { max_colour +. min_colour } + _ -> { max_colour -. min_colour } /. { 2.0 -. max_colour -. min_colour } + } + + #(h3, s, l, a) +} + +// CONSTRUCTORS --------------------------------------------------------------- + +/// Returns a `Result(Colour)` created from the given 8 bit RGB values. +/// +/// Returns `Error(Nil)` if the supplied RGB values are greater than 255 or less than 0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// } +/// ``` +///
+/// +/// +/// +pub fn from_rgb255(r red: Int, g green: Int, b blue: Int) -> Result(Colour, Nil) { + use r <- result.then( + red + |> int.to_float() + |> float.divide(255.0) + |> result.then(valid_colour_value), + ) + + use g <- result.then( + green + |> int.to_float() + |> float.divide(255.0) + |> result.then(valid_colour_value), + ) + + use b <- result.then( + blue + |> int.to_float() + |> float.divide(255.0) + |> result.then(valid_colour_value), + ) + + Ok(Rgba(r: r, g: g, b: b, a: 1.0)) +} + +/// Returns `Result(Colour)` created from the given RGB values. +/// +/// If the supplied RGB values are greater than 1.0 or less than 0.0 returns `Error(Nil)` +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb(1.0, 0.0, 0.0) +/// } +/// ``` +///
+/// +/// +/// +pub fn from_rgb( + r red: Float, + g green: Float, + b blue: Float, +) -> Result(Colour, Nil) { + use r <- result.then(valid_colour_value(red)) + use g <- result.then(valid_colour_value(green)) + use b <- result.then(valid_colour_value(blue)) + + Ok(Rgba(r: r, g: g, b: b, a: 1.0)) +} + +/// Returns `Result(Colour)` created from the given RGBA values. +/// +/// Returns `Error(Nil)` if the supplied RGBA values are greater than 1.0 or less than 0.0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_rbga(1.0, 0.0, 0.0, 0.5) +/// } +/// ``` +///
+/// +/// +/// +pub fn from_rgba( + r red: Float, + g green: Float, + b blue: Float, + a alpha: Float, +) -> Result(Colour, Nil) { + use r <- result.then(valid_colour_value(red)) + use g <- result.then(valid_colour_value(green)) + use b <- result.then(valid_colour_value(blue)) + use a <- result.then(valid_colour_value(alpha)) + + Ok(Rgba(r: r, g: g, b: b, a: a)) +} + +/// Returns `Result(Colour)` created from the given HSLA values. +/// +/// Returns `Error(Nil)`f the supplied HSLA values are greater than 1.0 or less than 0.0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_hsla(0.0, 1.0, 0.5, 0.5) +/// } +/// ``` +///
+/// +/// +/// +pub fn from_hsla( + h hue: Float, + s saturation: Float, + l lightness: Float, + a alpha: Float, +) -> Result(Colour, Nil) { + use h <- result.then(valid_colour_value(hue)) + use s <- result.then(valid_colour_value(saturation)) + use l <- result.then(valid_colour_value(lightness)) + use a <- result.then(valid_colour_value(alpha)) + + Ok(Hsla(h: h, s: s, l: l, a: a)) +} + +/// Returns `Result(Colour)` created from the given HSL values. +/// +/// Returns `Error(Nil)` if the supplied HSL values are greater than 1.0 or less than 0.0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_hsla(0.0, 1.0, 0.5) +/// } +/// ``` +///
+/// +/// +/// +pub fn from_hsl( + h hue: Float, + s saturation: Float, + l lightness: Float, +) -> Result(Colour, Nil) { + from_hsla(hue, saturation, lightness, 1.0) +} + +/// Returns a `Result(Colour)` created from the given hex `Int`. +/// +/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffff or less than 0x0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb_hex(0xff0000) +/// } +/// ``` +///
+/// +/// +/// +pub fn from_rgb_hex(hex: Int) -> Result(Colour, Nil) { + case hex > 0xffffff || hex < 0 { + True -> Error(Nil) + False -> { + let r = + int.bitwise_shift_right(hex, 16) + |> int.bitwise_and(0xff) + let g = + int.bitwise_shift_right(hex, 8) + |> int.bitwise_and(0xff) + let b = int.bitwise_and(hex, 0xff) + from_rgb255(r, g, b) + } + } +} + +/// Returns a `Result(Colour)` created from the given RGB hex `String`. +/// +/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffff" or less than `"#0"` +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb_hex_string("#ff0000") +/// } +/// ``` +///
+/// +/// +/// +pub fn from_rgb_hex_string(hex_string: String) -> Result(Colour, Nil) { + use hex_int <- result.then(hex_string_to_int(hex_string)) + + from_rgb_hex(hex_int) +} + +/// Returns a `Result(Colour)` created from the given RGBA hex `String`. +/// +/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffffff" or less than `"#0"` +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_rgba_hex_string("#ff00007f") +/// } +/// ``` +///
+/// +/// +/// +pub fn from_rgba_hex_string(hex_string: String) -> Result(Colour, Nil) { + use hex_int <- result.then(hex_string_to_int(hex_string)) + + from_rgba_hex(hex_int) +} + +/// Returns a `Result(Colour)` created from the given hex `Int`. +/// +/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffffff or less than 0x0. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red_half_opacity) = from_rgba_hex(0xff00007f) +/// } +/// ``` +///
+/// +/// +/// +pub fn from_rgba_hex(hex: Int) -> Result(Colour, Nil) { + case hex > 0xffffffff || hex < 0 { + True -> Error(Nil) + False -> { + // This won't fail because we are always dividing by 255.0 + let assert Ok(r) = + int.bitwise_shift_right(hex, 24) + |> int.bitwise_and(0xff) + |> int.to_float() + |> float.divide(255.0) + // This won't fail because we are always dividing by 255.0 + let assert Ok(g) = + int.bitwise_shift_right(hex, 16) + |> int.bitwise_and(0xff) + |> int.to_float() + |> float.divide(255.0) + // This won't fail because we are always dividing by 255.0 + let assert Ok(b) = + int.bitwise_shift_right(hex, 8) + |> int.bitwise_and(0xff) + |> int.to_float() + |> float.divide(255.0) + // This won't fail because we are always dividing by 255.0 + let assert Ok(a) = + int.bitwise_and(hex, 0xff) + |> int.to_float() + |> float.divide(255.0) + from_rgba(r, g, b, a) + } + } +} + +// CONVERSIONS ---------------------------------------------------------------- + +/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s +/// R, G, B, and A values respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// let #(r, g, b, a) = to_rgba(red) +/// } +/// ``` +///
+/// +/// +/// +pub fn to_rgba(colour: Colour) -> #(Float, Float, Float, Float) { + case colour { + Rgba(r, g, b, a) -> #(r, g, b, a) + Hsla(h, s, l, a) -> hsla_to_rgba(h, s, l, a) + } +} + +/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s +/// H, S, L, and A values respectively. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// let #(h, s, l, a) = to_hsla(red) +/// } +/// ``` +///
+/// +/// +/// +pub fn to_hsla(colour: Colour) -> #(Float, Float, Float, Float) { + case colour { + Hsla(h, s, l, a) -> #(h, s, l, a) + Rgba(r, g, b, a) -> rgba_to_hsla(r, g, b, a) + } +} + +/// Returns an rgba formatted CSS `String` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgb255(255, 0, 0) +/// let css_red = to_css_rgba_string(red) +/// } +/// ``` +///
+/// +/// +/// +pub fn to_css_rgba_string(colour: Colour) -> String { + let #(r, g, b, a) = to_rgba(colour) + + let percent = fn(x: Float) -> Float { + // This won't fail because we are always dividing by 100.0 + let assert Ok(p) = + x + |> float.multiply(10_000.0) + |> float.round() + |> int.to_float() + |> float.divide(100.0) + + p + } + + let round_to = fn(x: Float) -> Float { + // This won't fail because we are always dividing by 1000.0 + let assert Ok(r) = + x + |> float.multiply(1000.0) + |> float.round() + |> int.to_float() + |> float.divide(1000.0) + + r + } + + string.join( + [ + "rgba(", + float.to_string(percent(r)) <> "%,", + float.to_string(percent(g)) <> "%,", + float.to_string(percent(b)) <> "%,", + float.to_string(round_to(a)), + ")", + ], + "", + ) +} + +/// Returns an rgba hex formatted `String` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) +/// let red_hex = to_rgba_hex_string(red) +/// } +/// ``` +///
+/// +/// +/// +pub fn to_rgba_hex_string(colour: Colour) -> String { + to_rgba_hex(colour) + |> int.to_base16() +} + +/// Returns an rgb hex formatted `String` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(255, 0, 0) +/// let red_hex = to_rgb_hex_string(red) +/// } +/// ``` +///
+/// +/// +/// +pub fn to_rgb_hex_string(colour: Colour) -> String { + to_rgb_hex(colour) + |> int.to_base16() +} + +/// Returns an hex `Int` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) +/// let red_hex_int = to_rgba_hex(red) +/// } +/// ``` +///
+/// +/// +/// +pub fn to_rgba_hex(colour: Colour) -> Int { + let #(r, g, b, a) = to_rgba(colour) + + let red = + r *. 255.0 + |> float.round() + |> int.bitwise_shift_left(24) + + let green = + g *. 255.0 + |> float.round() + |> int.bitwise_shift_left(16) + + let blue = + b *. 255.0 + |> float.round() + |> int.bitwise_shift_left(8) + + let alpha = + a *. 255.0 + |> float.round() + + red + green + blue + alpha +} + +/// Returns a rgb hex `Int` created from the given `Colour`. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// assert Ok(red) = from_rgba(255, 0, 0) +/// let red_hex_int = to_rgb_hex(red) +/// } +/// ``` +///
+/// +/// +/// +pub fn to_rgb_hex(colour: Colour) -> Int { + let #(r, g, b, _) = to_rgba(colour) + + let red = + r *. 255.0 + |> float.round() + |> int.bitwise_shift_left(16) + + let green = + g *. 255.0 + |> float.round() + |> int.bitwise_shift_left(8) + + let blue = + b *. 255.0 + |> float.round() + + red + green + blue +} + +// COLOURS -------------------------------------------------------------------- + +/// A `Colour` reprsenting the colour RGBA(239, 41, 41, 1.0) +pub const light_red = Rgba( + r: 0.9372549019607843, + g: 0.1607843137254902, + b: 0.1607843137254902, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(204, 0, 0, 1.0) +pub const red = Rgba(r: 0.8, g: 0.0, b: 0.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(164, 0, 0, 1.0) +pub const dark_red = Rgba(r: 0.6431372549019608, g: 0.0, b: 0.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(252, 175, 62, 1.0) +pub const light_orange = Rgba( + r: 0.9882352941176471, + g: 0.6862745098039216, + b: 0.24313725490196078, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(245, 121, 0, 1.0) +pub const orange = Rgba( + r: 0.9607843137254902, + g: 0.4745098039215686, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(206, 92, 0, 1.0) +pub const dark_orange = Rgba( + r: 0.807843137254902, + g: 0.3607843137254902, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(255, 233, 79, 1.0) +pub const light_yellow = Rgba( + r: 1.0, + g: 0.9137254901960784, + b: 0.30980392156862746, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(237, 212, 0, 1.0) +pub const yellow = Rgba( + r: 0.9294117647058824, + g: 0.8313725490196079, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(196, 160, 0, 1.0) +pub const dark_yellow = Rgba( + r: 0.7686274509803922, + g: 0.6274509803921569, + b: 0.0, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(138, 226, 52, 1.0) +pub const light_green = Rgba( + r: 0.5411764705882353, + g: 0.8862745098039215, + b: 0.20392156862745098, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(115, 210, 22, 1.0) +pub const green = Rgba( + r: 0.45098039215686275, + g: 0.8235294117647058, + b: 0.08627450980392157, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(78, 154, 6, 1.0) +pub const dark_green = Rgba( + r: 0.3058823529411765, + g: 0.6039215686274509, + b: 0.023529411764705882, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(114, 159, 207, 1.0) +pub const light_blue = Rgba( + r: 0.4470588235294118, + g: 0.6235294117647059, + b: 0.8117647058823529, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(52, 101, 164, 1.0) +pub const blue = Rgba( + r: 0.20392156862745098, + g: 0.396078431372549, + b: 0.6431372549019608, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(32, 74, 135, 1.0) +pub const dark_blue = Rgba( + r: 0.12549019607843137, + g: 0.2901960784313726, + b: 0.5294117647058824, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(173, 127, 168, 1.0) +pub const light_purple = Rgba( + r: 0.6784313725490196, + g: 0.4980392156862745, + b: 0.6588235294117647, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(117, 80, 123, 1.0) +pub const purple = Rgba( + r: 0.4588235294117647, + g: 0.3137254901960784, + b: 0.4823529411764706, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(92, 53, 102, 1.0) +pub const dark_purple = Rgba( + r: 0.3607843137254902, + g: 0.20784313725490197, + b: 0.4, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(233, 185, 110, 1.0) +pub const light_brown = Rgba( + r: 0.9137254901960784, + g: 0.7254901960784313, + b: 0.43137254901960786, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(193, 125, 17, 1.0) +pub const brown = Rgba( + r: 0.7568627450980392, + g: 0.49019607843137253, + b: 0.06666666666666667, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(143, 89, 2, 1.0) +pub const dark_brown = Rgba( + r: 0.5607843137254902, + g: 0.34901960784313724, + b: 0.00784313725490196, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(0, 0, 0, 1.0) +pub const black = Rgba(r: 0.0, g: 0.0, b: 0.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(255, 255, 255, 1.0) +pub const white = Rgba(r: 1.0, g: 1.0, b: 1.0, a: 1.0) + +/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) +pub const light_grey = Rgba( + r: 0.9333333333333333, + g: 0.9333333333333333, + b: 0.9254901960784314, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) +pub const grey = Rgba( + r: 0.8274509803921568, + g: 0.8431372549019608, + b: 0.8117647058823529, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) +pub const dark_grey = Rgba( + r: 0.7294117647058823, + g: 0.7411764705882353, + b: 0.7137254901960784, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) +pub const light_gray = Rgba( + r: 0.9333333333333333, + g: 0.9333333333333333, + b: 0.9254901960784314, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) +pub const gray = Rgba( + r: 0.8274509803921568, + g: 0.8431372549019608, + b: 0.8117647058823529, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) +pub const dark_gray = Rgba( + r: 0.7294117647058823, + g: 0.7411764705882353, + b: 0.7137254901960784, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(136, 138, 133, 1.0) +pub const light_charcoal = Rgba( + r: 0.5333333333333333, + g: 0.5411764705882353, + b: 0.5215686274509804, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(85, 87, 83, 1.0) +pub const charcoal = Rgba( + r: 0.3333333333333333, + g: 0.3411764705882353, + b: 0.3254901960784314, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(46, 52, 54, 1.0) +pub const dark_charcoal = Rgba( + r: 0.1803921568627451, + g: 0.20392156862745098, + b: 0.21176470588235294, + a: 1.0, +) + +/// A `Colour` reprsenting the colour RGBA(255, 175, 243, 1.0) +pub const pink = Rgba( + r: 1.0, + g: 0.6862745098039216, + b: 0.9529411764705882, + a: 1.0, +) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam new file mode 100644 index 00000000000..54f75e4d469 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam @@ -0,0 +1,173 @@ +//// +//// - **Accessibility** +//// - [`luminance`](#luminance) +//// - [`contrast_ratio`](#contrast_ratio) +//// - [`maximum_contrast`](#maximum_contrast) +//// +//// --- +//// +//// This package was heavily inspired by the `elm-color-extra` module. +//// The original source code can be found +//// here. +//// +////
+//// The license of that package is produced below: +//// +//// +//// > MIT License +//// +//// > Copyright (c) 2016 Andreas Köberle +//// +//// > Permission is hereby granted, free of charge, to any person obtaining a copy +//// of this software and associated documentation files (the "Software"), to deal +//// in the Software without restriction, including without limitation the rights +//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//// copies of the Software, and to permit persons to whom the Software is +//// furnished to do so, subject to the following conditions: +//// +//// > The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +//// +//// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +//// SOFTWARE. +//// +////
+//// + +// Just in case we decide in the future to no longer include the above reference +// and license, this package was initially a port of the `elm-color-extra` module: +// +// https://github.com/noahzgordon/elm-color-extra +// + +// IMPORTS -------------------------------------------------------------------- + +import gleam/float +import gleam/list +import gleam_community/colour.{type Colour} + +// UTILITIES ------------------------------------------------------------------ + +fn intensity(colour_value: Float) -> Float { + // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef + case True { + _ if colour_value <=. 0.03928 -> colour_value /. 12.92 + _ -> { + // Is this guaranteed to be `OK`? + let assert Ok(i) = float.power({ colour_value +. 0.055 } /. 1.055, 2.4) + i + } + } +} + +// ACCESSIBILITY -------------------------------------------------------------- + +/// Returns the relative brightness of the given `Colour` as a `Float` between +/// 0.0, and 1.0 with 0.0 being the darkest possible colour and 1.0 being the lightest. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// luminance(colour.white) // 1.0 +/// } +/// ``` +///
+/// +/// +/// +pub fn luminance(colour: Colour) -> Float { + // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef + let #(r, g, b, _) = colour.to_rgba(colour) + + let r_intensity = intensity(r) + let g_intensity = intensity(g) + let b_intensity = intensity(b) + + 0.2126 *. r_intensity +. 0.7152 *. g_intensity +. 0.0722 *. b_intensity +} + +/// Returns the contrast between two `Colour` values as a `Float` between 1.0, +/// and 21.0 with 1.0 being no contrast and, 21.0 being the highest possible contrast. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// contrast_ratio(between: colour.white, and: colour.black) // 21.0 +/// } +/// ``` +///
+/// +/// +/// +pub fn contrast_ratio(between colour_a: Colour, and colour_b: Colour) -> Float { + // Calculation taken from https://www.w3.org/TR/WCAG20/#contrast-ratiodef + let luminance_a = luminance(colour_a) +. 0.05 + let luminance_b = luminance(colour_b) +. 0.05 + + case luminance_a >. luminance_b { + True -> luminance_a /. luminance_b + False -> luminance_b /. luminance_a + } +} + +/// Returns the `Colour` with the highest contrast between the base `Colour`, +/// and and the other provided `Colour` values. +/// +///
+/// Example: +/// +/// ```gleam +/// fn example() { +/// maximum_contrast( +/// colour.yellow, +/// [colour.white, colour.dark_blue, colour.green], +/// ) +/// } +/// ``` +///
+/// +/// +/// +pub fn maximum_contrast( + base: Colour, + colours: List(Colour), +) -> Result(Colour, Nil) { + colours + |> list.sort(fn(colour_a, colour_b) { + let contrast_a = contrast_ratio(base, colour_a) + let contrast_b = contrast_ratio(base, colour_b) + + float.compare(contrast_b, contrast_a) + }) + |> list.first() +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl new file mode 100644 index 00000000000..21e4c819749 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl @@ -0,0 +1,511 @@ +-module(gleam_community@colour). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_rgb255/3, from_rgb/3, from_rgba/4, from_hsla/4, from_hsl/3, from_rgb_hex/1, from_rgb_hex_string/1, from_rgba_hex/1, from_rgba_hex_string/1, to_rgba/1, to_hsla/1, to_css_rgba_string/1, to_rgba_hex/1, to_rgba_hex_string/1, to_rgb_hex/1, to_rgb_hex_string/1]). +-export_type([colour/0]). + +-opaque colour() :: {rgba, float(), float(), float(), float()} | + {hsla, float(), float(), float(), float()}. + +-spec valid_colour_value(float()) -> {ok, float()} | {error, nil}. +valid_colour_value(C) -> + case (C > 1.0) orelse (C < +0.0) of + true -> + {error, nil}; + + false -> + {ok, C} + end. + +-spec hue_to_rgb(float(), float(), float()) -> float(). +hue_to_rgb(Hue, M1, M2) -> + H = case Hue of + _ when Hue < +0.0 -> + Hue + 1.0; + + _ when Hue > 1.0 -> + Hue - 1.0; + + _ -> + Hue + end, + H_t_6 = H * 6.0, + H_t_2 = H * 2.0, + H_t_3 = H * 3.0, + case H of + _ when H_t_6 < 1.0 -> + M1 + (((M2 - M1) * H) * 6.0); + + _ when H_t_2 < 1.0 -> + M2; + + _ when H_t_3 < 2.0 -> + M1 + (((M2 - M1) * ((2.0 / 3.0) - H)) * 6.0); + + _ -> + M1 + end. + +-spec hex_string_to_int(binary()) -> {ok, integer()} | {error, nil}. +hex_string_to_int(Hex_string) -> + Hex = case Hex_string of + <<"#"/utf8, Hex_number/binary>> -> + Hex_number; + + <<"0x"/utf8, Hex_number@1/binary>> -> + Hex_number@1; + + _ -> + Hex_string + end, + _pipe = Hex, + _pipe@1 = gleam@string:lowercase(_pipe), + _pipe@2 = gleam@string:to_graphemes(_pipe@1), + _pipe@3 = gleam@list:reverse(_pipe@2), + gleam@list:index_fold( + _pipe@3, + {ok, 0}, + fun(Total, Char, Index) -> case Total of + {error, nil} -> + {error, nil}; + + {ok, V} -> + gleam@result:then(case Char of + <<"a"/utf8>> -> + {ok, 10}; + + <<"b"/utf8>> -> + {ok, 11}; + + <<"c"/utf8>> -> + {ok, 12}; + + <<"d"/utf8>> -> + {ok, 13}; + + <<"e"/utf8>> -> + {ok, 14}; + + <<"f"/utf8>> -> + {ok, 15}; + + _ -> + gleam@int:parse(Char) + end, fun(Num) -> + gleam@result:then( + gleam@int:power(16, gleam@int:to_float(Index)), + fun(Base) -> + {ok, + V + gleam@float:round( + gleam@int:to_float(Num) * Base + )} + end + ) + end) + end end + ). + +-spec hsla_to_rgba(float(), float(), float(), float()) -> {float(), + float(), + float(), + float()}. +hsla_to_rgba(H, S, L, A) -> + M2 = case L =< 0.5 of + true -> + L * (S + 1.0); + + false -> + (L + S) - (L * S) + end, + M1 = (L * 2.0) - M2, + R = hue_to_rgb(H + (1.0 / 3.0), M1, M2), + G = hue_to_rgb(H, M1, M2), + B = hue_to_rgb(H - (1.0 / 3.0), M1, M2), + {R, G, B, A}. + +-spec rgba_to_hsla(float(), float(), float(), float()) -> {float(), + float(), + float(), + float()}. +rgba_to_hsla(R, G, B, A) -> + Min_colour = gleam@float:min(R, gleam@float:min(G, B)), + Max_colour = gleam@float:max(R, gleam@float:max(G, B)), + H1 = case true of + _ when Max_colour =:= R -> + gleam@float:divide(G - B, Max_colour - Min_colour); + + _ when Max_colour =:= G -> + _pipe = gleam@float:divide(B - R, Max_colour - Min_colour), + gleam@result:then(_pipe, fun(D) -> {ok, 2.0 + D} end); + + _ -> + _pipe@1 = gleam@float:divide(R - G, Max_colour - Min_colour), + gleam@result:then(_pipe@1, fun(D@1) -> {ok, 4.0 + D@1} end) + end, + H2 = case H1 of + {ok, V} -> + {ok, V * (1.0 / 6.0)}; + + _ -> + H1 + end, + H3 = case H2 of + {ok, V@1} when V@1 < +0.0 -> + V@1 + 1.0; + + {ok, V@2} -> + V@2; + + _ -> + +0.0 + end, + L = (Min_colour + Max_colour) / 2.0, + S = case true of + _ when Min_colour =:= Max_colour -> + +0.0; + + _ when L < 0.5 -> + case (Max_colour + Min_colour) of + 0.0 -> 0.0; + Gleam@denominator -> (Max_colour - Min_colour) / Gleam@denominator + end; + + _ -> + case ((2.0 - Max_colour) - Min_colour) of + 0.0 -> 0.0; + Gleam@denominator@1 -> (Max_colour - Min_colour) / Gleam@denominator@1 + end + end, + {H3, S, L, A}. + +-spec from_rgb255(integer(), integer(), integer()) -> {ok, colour()} | + {error, nil}. +from_rgb255(Red, Green, Blue) -> + gleam@result:then( + begin + _pipe = Red, + _pipe@1 = gleam@int:to_float(_pipe), + _pipe@2 = gleam@float:divide(_pipe@1, 255.0), + gleam@result:then(_pipe@2, fun valid_colour_value/1) + end, + fun(R) -> + gleam@result:then( + begin + _pipe@3 = Green, + _pipe@4 = gleam@int:to_float(_pipe@3), + _pipe@5 = gleam@float:divide(_pipe@4, 255.0), + gleam@result:then(_pipe@5, fun valid_colour_value/1) + end, + fun(G) -> + gleam@result:then( + begin + _pipe@6 = Blue, + _pipe@7 = gleam@int:to_float(_pipe@6), + _pipe@8 = gleam@float:divide(_pipe@7, 255.0), + gleam@result:then(_pipe@8, fun valid_colour_value/1) + end, + fun(B) -> {ok, {rgba, R, G, B, 1.0}} end + ) + end + ) + end + ). + +-spec from_rgb(float(), float(), float()) -> {ok, colour()} | {error, nil}. +from_rgb(Red, Green, Blue) -> + gleam@result:then( + valid_colour_value(Red), + fun(R) -> + gleam@result:then( + valid_colour_value(Green), + fun(G) -> + gleam@result:then( + valid_colour_value(Blue), + fun(B) -> {ok, {rgba, R, G, B, 1.0}} end + ) + end + ) + end + ). + +-spec from_rgba(float(), float(), float(), float()) -> {ok, colour()} | + {error, nil}. +from_rgba(Red, Green, Blue, Alpha) -> + gleam@result:then( + valid_colour_value(Red), + fun(R) -> + gleam@result:then( + valid_colour_value(Green), + fun(G) -> + gleam@result:then( + valid_colour_value(Blue), + fun(B) -> + gleam@result:then( + valid_colour_value(Alpha), + fun(A) -> {ok, {rgba, R, G, B, A}} end + ) + end + ) + end + ) + end + ). + +-spec from_hsla(float(), float(), float(), float()) -> {ok, colour()} | + {error, nil}. +from_hsla(Hue, Saturation, Lightness, Alpha) -> + gleam@result:then( + valid_colour_value(Hue), + fun(H) -> + gleam@result:then( + valid_colour_value(Saturation), + fun(S) -> + gleam@result:then( + valid_colour_value(Lightness), + fun(L) -> + gleam@result:then( + valid_colour_value(Alpha), + fun(A) -> {ok, {hsla, H, S, L, A}} end + ) + end + ) + end + ) + end + ). + +-spec from_hsl(float(), float(), float()) -> {ok, colour()} | {error, nil}. +from_hsl(Hue, Saturation, Lightness) -> + from_hsla(Hue, Saturation, Lightness, 1.0). + +-spec from_rgb_hex(integer()) -> {ok, colour()} | {error, nil}. +from_rgb_hex(Hex) -> + case (Hex > 16#ffffff) orelse (Hex < 0) of + true -> + {error, nil}; + + false -> + R = begin + _pipe = erlang:'bsr'(Hex, 16), + erlang:'band'(_pipe, 16#ff) + end, + G = begin + _pipe@1 = erlang:'bsr'(Hex, 8), + erlang:'band'(_pipe@1, 16#ff) + end, + B = erlang:'band'(Hex, 16#ff), + from_rgb255(R, G, B) + end. + +-spec from_rgb_hex_string(binary()) -> {ok, colour()} | {error, nil}. +from_rgb_hex_string(Hex_string) -> + gleam@result:then( + hex_string_to_int(Hex_string), + fun(Hex_int) -> from_rgb_hex(Hex_int) end + ). + +-spec from_rgba_hex(integer()) -> {ok, colour()} | {error, nil}. +from_rgba_hex(Hex) -> + case (Hex > 16#ffffffff) orelse (Hex < 0) of + true -> + {error, nil}; + + false -> + _assert_subject = begin + _pipe = erlang:'bsr'(Hex, 24), + _pipe@1 = erlang:'band'(_pipe, 16#ff), + _pipe@2 = gleam@int:to_float(_pipe@1), + gleam@float:divide(_pipe@2, 255.0) + end, + {ok, R} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 588}) + end, + _assert_subject@1 = begin + _pipe@3 = erlang:'bsr'(Hex, 16), + _pipe@4 = erlang:'band'(_pipe@3, 16#ff), + _pipe@5 = gleam@int:to_float(_pipe@4), + gleam@float:divide(_pipe@5, 255.0) + end, + {ok, G} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 594}) + end, + _assert_subject@2 = begin + _pipe@6 = erlang:'bsr'(Hex, 8), + _pipe@7 = erlang:'band'(_pipe@6, 16#ff), + _pipe@8 = gleam@int:to_float(_pipe@7), + gleam@float:divide(_pipe@8, 255.0) + end, + {ok, B} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 600}) + end, + _assert_subject@3 = begin + _pipe@9 = erlang:'band'(Hex, 16#ff), + _pipe@10 = gleam@int:to_float(_pipe@9), + gleam@float:divide(_pipe@10, 255.0) + end, + {ok, A} = case _assert_subject@3 of + {ok, _} -> _assert_subject@3; + _assert_fail@3 -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"gleam_community/colour"/utf8>>, + function => <<"from_rgba_hex"/utf8>>, + line => 606}) + end, + from_rgba(R, G, B, A) + end. + +-spec from_rgba_hex_string(binary()) -> {ok, colour()} | {error, nil}. +from_rgba_hex_string(Hex_string) -> + gleam@result:then( + hex_string_to_int(Hex_string), + fun(Hex_int) -> from_rgba_hex(Hex_int) end + ). + +-spec to_rgba(colour()) -> {float(), float(), float(), float()}. +to_rgba(Colour) -> + case Colour of + {rgba, R, G, B, A} -> + {R, G, B, A}; + + {hsla, H, S, L, A@1} -> + hsla_to_rgba(H, S, L, A@1) + end. + +-spec to_hsla(colour()) -> {float(), float(), float(), float()}. +to_hsla(Colour) -> + case Colour of + {hsla, H, S, L, A} -> + {H, S, L, A}; + + {rgba, R, G, B, A@1} -> + rgba_to_hsla(R, G, B, A@1) + end. + +-spec to_css_rgba_string(colour()) -> binary(). +to_css_rgba_string(Colour) -> + {R, G, B, A} = to_rgba(Colour), + Percent = fun(X) -> + _assert_subject = begin + _pipe = X, + _pipe@1 = gleam@float:multiply(_pipe, 10000.0), + _pipe@2 = gleam@float:round(_pipe@1), + _pipe@3 = gleam@int:to_float(_pipe@2), + gleam@float:divide(_pipe@3, 100.0) + end, + {ok, P} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam_community/colour"/utf8>>, + function => <<"to_css_rgba_string"/utf8>>, + line => 704}) + end, + P + end, + Round_to = fun(X@1) -> + _assert_subject@1 = begin + _pipe@4 = X@1, + _pipe@5 = gleam@float:multiply(_pipe@4, 1000.0), + _pipe@6 = gleam@float:round(_pipe@5), + _pipe@7 = gleam@int:to_float(_pipe@6), + gleam@float:divide(_pipe@7, 1000.0) + end, + {ok, R@1} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"gleam_community/colour"/utf8>>, + function => <<"to_css_rgba_string"/utf8>>, + line => 716}) + end, + R@1 + end, + gleam@string:join( + [<<"rgba("/utf8>>, + <<(gleam@float:to_string(Percent(R)))/binary, "%,"/utf8>>, + <<(gleam@float:to_string(Percent(G)))/binary, "%,"/utf8>>, + <<(gleam@float:to_string(Percent(B)))/binary, "%,"/utf8>>, + gleam@float:to_string(Round_to(A)), + <<")"/utf8>>], + <<""/utf8>> + ). + +-spec to_rgba_hex(colour()) -> integer(). +to_rgba_hex(Colour) -> + {R, G, B, A} = to_rgba(Colour), + Red = begin + _pipe = R * 255.0, + _pipe@1 = gleam@float:round(_pipe), + erlang:'bsl'(_pipe@1, 24) + end, + Green = begin + _pipe@2 = G * 255.0, + _pipe@3 = gleam@float:round(_pipe@2), + erlang:'bsl'(_pipe@3, 16) + end, + Blue = begin + _pipe@4 = B * 255.0, + _pipe@5 = gleam@float:round(_pipe@4), + erlang:'bsl'(_pipe@5, 8) + end, + Alpha = begin + _pipe@6 = A * 255.0, + gleam@float:round(_pipe@6) + end, + ((Red + Green) + Blue) + Alpha. + +-spec to_rgba_hex_string(colour()) -> binary(). +to_rgba_hex_string(Colour) -> + _pipe = to_rgba_hex(Colour), + gleam@int:to_base16(_pipe). + +-spec to_rgb_hex(colour()) -> integer(). +to_rgb_hex(Colour) -> + {R, G, B, _} = to_rgba(Colour), + Red = begin + _pipe = R * 255.0, + _pipe@1 = gleam@float:round(_pipe), + erlang:'bsl'(_pipe@1, 16) + end, + Green = begin + _pipe@2 = G * 255.0, + _pipe@3 = gleam@float:round(_pipe@2), + erlang:'bsl'(_pipe@3, 8) + end, + Blue = begin + _pipe@4 = B * 255.0, + gleam@float:round(_pipe@4) + end, + (Red + Green) + Blue. + +-spec to_rgb_hex_string(colour()) -> binary(). +to_rgb_hex_string(Colour) -> + _pipe = to_rgb_hex(Colour), + gleam@int:to_base16(_pipe). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl new file mode 100644 index 00000000000..64d37bf2eb3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl @@ -0,0 +1,73 @@ +-module(gleam_community@colour@accessibility). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([luminance/1, contrast_ratio/2, maximum_contrast/2]). + +-spec intensity(float()) -> float(). +intensity(Colour_value) -> + case true of + _ when Colour_value =< 0.03928 -> + Colour_value / 12.92; + + _ -> + _assert_subject = gleam@float:power( + (Colour_value + 0.055) / 1.055, + 2.4 + ), + {ok, I} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam_community/colour/accessibility"/utf8>>, + function => <<"intensity"/utf8>>, + line => 62}) + end, + I + end. + +-spec luminance(gleam_community@colour:colour()) -> float(). +luminance(Colour) -> + {R, G, B, _} = gleam_community@colour:to_rgba(Colour), + R_intensity = intensity(R), + G_intensity = intensity(G), + B_intensity = intensity(B), + ((0.2126 * R_intensity) + (0.7152 * G_intensity)) + (0.0722 * B_intensity). + +-spec contrast_ratio( + gleam_community@colour:colour(), + gleam_community@colour:colour() +) -> float(). +contrast_ratio(Colour_a, Colour_b) -> + Luminance_a = luminance(Colour_a) + 0.05, + Luminance_b = luminance(Colour_b) + 0.05, + case Luminance_a > Luminance_b of + true -> + case Luminance_b of + 0.0 -> 0.0; + Gleam@denominator -> Luminance_a / Gleam@denominator + end; + + false -> + case Luminance_a of + 0.0 -> 0.0; + Gleam@denominator@1 -> Luminance_b / Gleam@denominator@1 + end + end. + +-spec maximum_contrast( + gleam_community@colour:colour(), + list(gleam_community@colour:colour()) +) -> {ok, gleam_community@colour:colour()} | {error, nil}. +maximum_contrast(Base, Colours) -> + _pipe = Colours, + _pipe@1 = gleam@list:sort( + _pipe, + fun(Colour_a, Colour_b) -> + Contrast_a = contrast_ratio(Base, Colour_a), + Contrast_b = contrast_ratio(Base, Colour_b), + gleam@float:compare(Contrast_b, Contrast_a) + end + ), + gleam@list:first(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src new file mode 100644 index 00000000000..a32765072fc --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src @@ -0,0 +1,9 @@ +{application, gleam_community_colour, [ + {vsn, "1.2.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Colour types, conversions, and other utilities"}, + {modules, [gleam_community@colour, + gleam_community@colour@accessibility]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE new file mode 100644 index 00000000000..59e1345ab47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md new file mode 100644 index 00000000000..ffee4cd751f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md @@ -0,0 +1,37 @@ +# Gleam Erlang 🐙 + +A library for making use of Erlang specific code! + +## Features + +- Typed Erlang processes and message sending. +- Erlang binary format (de)serialisation. +- Functions for working with Erlang's charlists. +- Reading, writing, and deletion of files. +- Basic distributed Erlang support and working with nodes. +- Reading and writing of environment variables. +- Functions for working with atoms. + +## Usage + +Add this library to your Gleam project + +```shell +gleam add gleam_erlang +``` + +And then use it in your code + +```gleam +import gleam/io +import gleam/erlang/file + +pub fn main() { + assert Ok(contents) = file.read("pokedex.txt") + io.println(contents) +} +``` + +Documentation can be found at . + +This library requires OTP 23.0 or higher. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml new file mode 100644 index 00000000000..8d626035c25 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml @@ -0,0 +1,18 @@ +name = "gleam_erlang" + +version = "0.23.1" +licences = ["Apache-2.0"] +description = "A Gleam library for working with Erlang" + +repository = { type = "github", user = "gleam-lang", repo = "erlang" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] +gleam = ">= 0.32.0" + +[dependencies] +gleam_stdlib = "~> 0.32" + +[dev-dependencies] +gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl new file mode 100644 index 00000000000..b38d11e0f65 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl @@ -0,0 +1,15 @@ +-record(file_info, { + size :: integer(), + file_type :: gleam@erlang@file:file_type(), + access :: gleam@erlang@file:access(), + atime :: integer(), + mtime :: integer(), + ctime :: integer(), + mode :: integer(), + links :: integer(), + major_device :: integer(), + minor_device :: integer(), + inode :: integer(), + user_id :: integer(), + group_id :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl new file mode 100644 index 00000000000..4cd04529eb4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl @@ -0,0 +1 @@ +-record(abnormal, {reason :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl new file mode 100644 index 00000000000..5dd504715a5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl @@ -0,0 +1 @@ +-record(callee_down, {reason :: gleam@dynamic:dynamic_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl new file mode 100644 index 00000000000..b82b49fc597 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl @@ -0,0 +1 @@ +-record(cancelled, {time_remaining :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl new file mode 100644 index 00000000000..c476308c591 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl @@ -0,0 +1,4 @@ +-record(exit_message, { + pid :: gleam@erlang@process:pid_(), + reason :: gleam@erlang@process:exit_reason() +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl new file mode 100644 index 00000000000..df0b6b7793b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl @@ -0,0 +1,4 @@ +-record(process_down, { + pid :: gleam@erlang@process:pid_(), + reason :: gleam@dynamic:dynamic_() +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl new file mode 100644 index 00000000000..ce552e209e6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl @@ -0,0 +1 @@ +-record(process_monitor, {tag :: gleam@erlang:reference_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl new file mode 100644 index 00000000000..abc46b2ecd4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl @@ -0,0 +1,4 @@ +-record(subject, { + owner :: gleam@erlang@process:pid_(), + tag :: gleam@erlang:reference_() +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl new file mode 100644 index 00000000000..52c9896ede4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl @@ -0,0 +1,4 @@ +-record(application_failed_to_start, { + name :: gleam@erlang@atom:atom_(), + reason :: gleam@dynamic:dynamic_() +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl new file mode 100644 index 00000000000..fde3c61706e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl @@ -0,0 +1 @@ +-record(unknown_application, {name :: gleam@erlang@atom:atom_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam new file mode 100644 index 00000000000..783cd537232 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam @@ -0,0 +1,158 @@ +import gleam/dynamic.{type Dynamic} +import gleam/list +import gleam/erlang/atom.{type Atom} +import gleam/erlang/charlist.{type Charlist} + +@external(erlang, "io_lib", "format") +fn erl_format(a: String, b: List(a)) -> Charlist + +/// Return a string representation of any term +pub fn format(term: any) -> String { + charlist.to_string(erl_format("~p", [term])) +} + +@external(erlang, "erlang", "term_to_binary") +pub fn term_to_binary(a: a) -> BitArray + +type Safe { + Safe +} + +@external(erlang, "erlang", "binary_to_term") +fn erl_binary_to_term(a: BitArray, b: List(Safe)) -> Dynamic + +pub fn binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { + case rescue(fn() { erl_binary_to_term(binary, [Safe]) }) { + Ok(term) -> Ok(term) + Error(_) -> Error(Nil) + } +} + +pub fn unsafe_binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { + case rescue(fn() { erl_binary_to_term(binary, []) }) { + Ok(term) -> Ok(term) + Error(_) -> Error(Nil) + } +} + +/// Error value returned by `get_line` function +/// +pub type GetLineError { + Eof + NoData +} + +/// Reads a line from standard input with the given prompt. +/// +/// # Example +/// +/// > get_line("Language: ") +/// // -> Language: <- gleam +/// Ok("gleam\n") +/// +@external(erlang, "gleam_erlang_ffi", "get_line") +pub fn get_line(prompt prompt: String) -> Result(String, GetLineError) + +pub type TimeUnit { + Second + Millisecond + Microsecond + Nanosecond +} + +/// Returns the current OS system time. +/// +/// +@external(erlang, "os", "system_time") +pub fn system_time(a: TimeUnit) -> Int + +/// Returns the current OS system time as a tuple of Ints +/// +/// http://erlang.org/doc/man/os.html#timestamp-0 +@external(erlang, "os", "timestamp") +pub fn erlang_timestamp() -> #(Int, Int, Int) + +/// Gleam doesn't offer any way to raise exceptions, but they may still occur +/// due to bugs when working with unsafe code, such as when calling Erlang +/// function. +/// +/// This function will catch any error thrown and convert it into a result +/// rather than crashing the process. +/// +@external(erlang, "gleam_erlang_ffi", "rescue") +pub fn rescue(a: fn() -> a) -> Result(a, Crash) + +pub type Crash { + Exited(Dynamic) + Thrown(Dynamic) + Errored(Dynamic) +} + +@external(erlang, "init", "get_plain_arguments") +fn get_start_arguments() -> List(Charlist) + +/// Get the arguments given to the program when it was started. +/// +/// This is sometimes called `argv` in other languages. +pub fn start_arguments() -> List(String) { + get_start_arguments() + |> list.map(charlist.to_string) +} + +/// Starts an OTP application's process tree in the background, as well as +/// the trees of any applications that the given application depends upon. An +/// OTP application typically maps onto a Gleam or Hex package. +/// +/// Returns a list of the applications that were started. Calling this function +/// for application that have already been started is a no-op so you do not need +/// to check the application state beforehand. +/// +/// In Gleam we prefer to not use these implicit background process trees, but +/// you will likely still need to start the trees of OTP applications written in +/// other BEAM languages such as Erlang or Elixir, including those included by +/// default with Erlang/OTP. +/// +/// For more information see the OTP documentation. +/// - +/// - +/// +@external(erlang, "gleam_erlang_ffi", "ensure_all_started") +pub fn ensure_all_started( + application application: Atom, +) -> Result(List(Atom), EnsureAllStartedError) + +pub type EnsureAllStartedError { + UnknownApplication(name: Atom) + ApplicationFailedToStart(name: Atom, reason: Dynamic) +} + +/// A unique reference value. +/// +/// It holds no particular meaning or value, but unique values are often useful +/// in programs are used heavily within both Gleam and Erlang's OTP frameworks. +/// +/// More can be read about references in the [Erlang documentation][1]. +/// +/// [1]: https://www.erlang.org/doc/efficiency_guide/advanced.html#unique_references +/// +pub type Reference + +/// Create a new unique reference. +/// +@external(erlang, "erlang", "make_ref") +pub fn make_reference() -> Reference + +/// Returns the path of a package's `priv` directory, where extra non-Gleam +/// or Erlang files are typically kept. +/// +/// Returns an error if no package was found with the given name. +/// +/// # Example +/// +/// ```gleam +/// > erlang.priv_directory("my_app") +/// // -> Ok("/some/location/my_app/priv") +/// ``` +/// +@external(erlang, "gleam_erlang_ffi", "priv_directory") +pub fn priv_directory(name: String) -> Result(String, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam new file mode 100644 index 00000000000..a27289c112c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam @@ -0,0 +1,79 @@ +import gleam/dynamic.{type DecodeErrors, type Dynamic} + +/// Atom is a special string-like data-type that is most commonly used for +/// interfacing with code written in other BEAM languages such as Erlang and +/// Elixir. It is preferable to define your own custom types to use instead of +/// atoms where possible. +/// +/// Atoms are not used much in typical Gleam code! +/// +/// ## Creating atoms +/// +/// We can create atoms with the the [`create_from_string`](#create_from_string) +/// function, though we must be careful when doing so as atoms are never +/// garbage collected. If we create too many atoms (for example, if we convert +/// user input into atoms) we may hit the max limit of atoms and cause the +/// virtual machine to crash. +/// +pub type Atom + +/// An error returned when no atom is found in the virtual machine's atom table +/// for a given string when calling the [`from_string`](#from_string) function. +pub type FromStringError { + AtomNotLoaded +} + +/// Finds an existing Atom for the given String. +/// +/// If no atom is found in the virtual machine's atom table for the String then +/// an error is returned. +/// +/// ## Examples +/// +/// > from_string("ok") +/// Ok(create_from_string("ok")) +/// +/// > from_string("some_new_atom") +/// Error(AtomNotLoaded) +/// +@external(erlang, "gleam_erlang_ffi", "atom_from_string") +pub fn from_string(a: String) -> Result(Atom, FromStringError) + +/// Creates an atom from a string, inserting a new value into the virtual +/// machine's atom table if an atom does not already exist for the given +/// string. +/// +/// We must be careful when using this function as there is a limit to the +/// number of atom that can fit in the virtual machine's atom table. Never +/// convert user input into atoms as filling the atom table will cause the +/// virtual machine to crash! +/// +@external(erlang, "erlang", "binary_to_atom") +pub fn create_from_string(a: String) -> Atom + +/// Returns a `String` corresponding to the text representation of the given +/// `Atom`. +/// +/// ## Examples +/// +/// > let ok_atom = create_from_string("ok") +/// > to_string(ok_atom) +/// "ok" +/// +@external(erlang, "erlang", "atom_to_binary") +pub fn to_string(a: Atom) -> String + +/// Checks to see whether a `Dynamic` value is an atom, and return the atom if +/// it is. +/// +/// ## Examples +/// +/// > import gleam/dynamic +/// > from_dynamic(dynamic.from(create_from_string("hello"))) +/// Ok(create_from_string("hello")) +/// +/// > from_dynamic(dynamic.from(123)) +/// Error([DecodeError(expected: "Atom", found: "Int", path: [])]) +/// +@external(erlang, "gleam_erlang_ffi", "atom_from_dynamic") +pub fn from_dynamic(from from: Dynamic) -> Result(Atom, DecodeErrors) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam new file mode 100644 index 00000000000..e5b6d65f6b2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam @@ -0,0 +1,25 @@ +//// A charlist is a list of integers where all the integers are valid code +//// points. +//// +//// In practice, you will not come across them often, except perhaps when +//// interfacing with Erlang, in particular when using older libraries that do +//// not accept binaries as arguments. + +/// A list of characters represented as ints. Commonly used by older Erlang +/// modules. +pub type Charlist + +/// Transform a charlist to a string +@external(erlang, "unicode", "characters_to_binary") +pub fn to_string(a: Charlist) -> String + +// Calls `unicode:characters_to_binary(Data, unicode, unicode)` +// Note: `unicode is an alias for utf8` +// See + +/// Transform a string to a charlist +@external(erlang, "unicode", "characters_to_list") +pub fn from_string(a: String) -> Charlist +// Calls `unicode:characters_to_list(Data, unicode)` +// Note: `unicode is an alias for utf8` +// See diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam new file mode 100644 index 00000000000..48e11a7ad80 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam @@ -0,0 +1,737 @@ +//// Working with files on the filesystem. +//// +//// The functions included in this module are for high-level concepts such as +//// reading and writing. + +import gleam/bit_array +import gleam/result + +/// Reason represents all of the reasons that Erlang surfaces of why a file +/// system operation could fail. Most of these reasons are POSIX errors, which +/// come from the operating system and start with `E`. Others have been added to +/// represent other issues that may arise. +pub type Reason { + /// Permission denied. + Eacces + /// Resource temporarily unavailable. + Eagain + /// Bad file number + Ebadf + /// Bad message. + Ebadmsg + /// File busy. + Ebusy + /// Resource deadlock avoided. + Edeadlk + /// On most architectures, same as `Edeadlk`. On some architectures, it + /// means "File locking deadlock error." + Edeadlock + /// Disk quota exceeded. + Edquot + /// File already exists. + Eexist + /// Bad address in system call argument. + Efault + /// File too large. + Efbig + /// Inappropriate file type or format. Usually caused by trying to set the + /// "sticky bit" on a regular file (not a directory). + Eftype + /// Interrupted system call. + Eintr + /// Invalid argument. + Einval + /// I/O error. + Eio + /// Illegal operation on a directory. + Eisdir + /// Too many levels of symbolic links. + Eloop + /// Too many open files. + Emfile + /// Too many links. + Emlink + /// Multihop attempted. + Emultihop + /// Filename too long + Enametoolong + /// File table overflow + Enfile + /// No buffer space available. + Enobufs + /// No such device. + Enodev + /// No locks available. + Enolck + /// Link has been severed. + Enolink + /// No such file or directory. + Enoent + /// Not enough memory. + Enomem + /// No space left on device. + Enospc + /// No STREAM resources. + Enosr + /// Not a STREAM. + Enostr + /// Function not implemented. + Enosys + /// Block device required. + Enotblk + /// Not a directory. + Enotdir + /// Operation not supported. + Enotsup + /// No such device or address. + Enxio + /// Operation not supported on socket. + Eopnotsupp + /// Value too large to be stored in data type. + Eoverflow + /// Not owner. + Eperm + /// Broken pipe. + Epipe + /// Result too large. + Erange + /// Read-only file system. + Erofs + /// Invalid seek. + Espipe + /// No such process. + Esrch + /// Stale remote file handle. + Estale + /// Text file busy. + Etxtbsy + /// Cross-domain link. + Exdev + /// File was requested to be read as UTF-8, but is not UTF-8 encoded. + NotUtf8 +} + +/// The type of file found by `file_info` or `link_info`. +/// +pub type FileType { + Device + Directory + Other + Regular + Symlink +} + +/// The read/write permissions a user can have for a file. +/// +pub type Access { + NoAccess + Read + ReadWrite + Write +} + +/// Meta information for a file. +/// +/// Timestamps are in seconds before or after the Unix time epoch, +/// `1970-01-01 00:00:00 UTC`. +/// +pub type FileInfo { + FileInfo( + /// File size in bytes. + /// + size: Int, + /// `Regular`, `Directory`, `Symlink`, `Device`, or `Other`. + /// + file_type: FileType, + /// `ReadWrite`, `Read`, `Write`, or `NoAccess`. + /// + access: Access, + /// Timestamp of most recent access. + /// + atime: Int, + /// Timestamp of most recent modification. + /// + mtime: Int, + /// Timestamp of most recent change (or file creation, depending on + /// operating system). + /// + ctime: Int, + /// File permissions encoded as a sum of bit values, including but not + /// limited to: + /// + /// Owner read, write, execute. + /// + /// `0o400`, `0o200`, `0o100` + /// + /// Group read, write, execute. + /// + /// `0o40`, `0o20`, `0o10` + /// + /// Other read, write, execute. + /// + /// `0o4`, `0o2`, `0o1` + /// + /// Set user ID, group ID on execution. + /// + /// `0x800`, `0x400` + /// + mode: Int, + /// Total links to a file (always `1` for file systems without links). + /// + links: Int, + /// The file system where a file is located (`0` for drive `A:` on Windows, + /// `1` for `B:`, etc.). + /// + major_device: Int, + /// Character device (or `0` on non-Unix systems). + /// + minor_device: Int, + /// The `inode` number for a file (always `0` on non-Unix file systems). + /// + inode: Int, + /// The owner of a file (always `0` on non-Unix file systems). + /// + user_id: Int, + /// The group id of a file (always `0` on non-Unix file systems). + /// + group_id: Int, + ) +} + +/// Results in `FileInfo` about the given `path` on success, otherwise a +/// `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// To get `FileInfo` about a symlink itself, use `link_info`. +/// +/// ## Examples +/// +/// ```gleam +/// > file_info("gleam.toml") +/// Ok(FileInfo( +/// size: 430, +/// file_type: Regular, +/// access: ReadWrite, +/// atime: 1680580321, +/// mtime: 1680580272, +/// ctime: 1680580272, +/// mode: 33188, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 469028, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > file_info("/root") +/// Ok(FileInfo( +/// size: 16, +/// file_type: Directory, +/// access: Read, +/// atime: 1677789967, +/// mtime: 1664561240, +/// ctime: 1664561240, +/// mode: 16877, +/// links: 11, +/// major_device: 54, +/// minor_device: 0, +/// inode: 34, +/// user_id: 0, +/// group_id: 0, +/// )) +/// +/// > file_info("./build/dev/erlang/rad/priv") +/// Ok(FileInfo( +/// size: 140, +/// file_type: Directory, +/// access: ReadWrite, +/// atime: 1680580321, +/// mtime: 1680580272, +/// ctime: 1680580272, +/// mode: 33188, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 469028, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > file_info("/does_not_exist") +/// Error(Enoent) +/// +/// > file_info("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn file_info(a: String) -> Result(FileInfo, Reason) { + do_file_info(a) +} + +@external(erlang, "gleam_erlang_ffi", "file_info") +fn do_file_info(a: String) -> Result(FileInfo, Reason) + +/// Results in `FileInfo` about the given `path` on success, otherwise a +/// `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link itself. +/// To get `FileInfo` about a symlink's target, use `file_info`. +/// +/// ## Examples +/// +/// ```gleam +/// > link_info("gleam.toml") +/// Ok(FileInfo( +/// size: 430, +/// file_type: Regular, +/// access: ReadWrite, +/// atime: 1680580321, +/// mtime: 1680580272, +/// ctime: 1680580272, +/// mode: 33188, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 469028, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > link_info("/root") +/// Ok(FileInfo( +/// size: 16, +/// file_type: Directory, +/// access: Read, +/// atime: 1677789967, +/// mtime: 1664561240, +/// ctime: 1664561240, +/// mode: 16877, +/// links: 11, +/// major_device: 54, +/// minor_device: 0, +/// inode: 34, +/// user_id: 0, +/// group_id: 0, +/// )) +/// +/// > link_info("./build/dev/erlang/rad/priv") +/// Ok(FileInfo( +/// size: 41, +/// file_type: Symlink, +/// access: ReadWrite, +/// atime: 1680581150, +/// mtime: 1680581150, +/// ctime: 1680581150, +/// mode: 41471, +/// links: 1, +/// major_device: 64, +/// minor_device: 0, +/// inode: 471587, +/// user_id: 1000, +/// group_id: 1000, +/// )) +/// +/// > link_info("/does_not_exist") +/// Error(Enoent) +/// +/// > link_info("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn link_info(a: String) -> Result(FileInfo, Reason) { + do_link_info(a) +} + +@external(erlang, "gleam_erlang_ffi", "link_info") +fn do_link_info(a: String) -> Result(FileInfo, Reason) + +/// Results in a `Bool` on success that indicates whether the given `path` has +/// a `Directory` `FileType`, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// +/// ## Examples +/// +/// ```gleam +/// > is_directory("/tmp") +/// Ok(True) +/// +/// > is_directory("resume.pdf") +/// Ok(False) +/// +/// > is_directory("/does_not_exist") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn is_directory(path: String) -> Result(Bool, Reason) { + use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) + file_type == Directory +} + +/// Results in a `Bool` on success that indicates whether the given `path` has +/// a `Regular` `FileType`, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// +/// ## Examples +/// +/// ```gleam +/// > is_regular("resume.pdf") +/// Ok(True) +/// +/// > is_regular("/tmp") +/// Ok(False) +/// +/// > is_regular("/does_not_exist.txt") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn is_regular(path: String) -> Result(Bool, Reason) { + use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) + file_type == Regular +} + +/// Results in a `Bool` on success that indicates whether the given `path` +/// exists, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link's target. +/// To find whether a symlink itself exists, use `link_exists`. +/// +/// ## Examples +/// +/// ```gleam +/// > file_exists("resume.pdf") +/// Ok(True) +/// +/// > file_exists("/tmp") +/// Ok(True) +/// +/// > file_exists("/does_not_exist") +/// Ok(False) +/// +/// > file_exists("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn file_exists(path: String) -> Result(Bool, Reason) { + let result = + path + |> do_file_info + |> result.replace(True) + case result { + Error(Enoent) -> Ok(False) + _ -> result + } +} + +/// Results in a `Bool` on success that indicates whether the given `path` +/// exists, otherwise a `Reason` for failure. +/// +/// When `path` refers to a symlink, the result pertains to the link itself. +/// To find whether a symlink's target exists, use `file_exists`. +/// +/// ## Examples +/// +/// ```gleam +/// > link_exists("resume.pdf") +/// Ok(True) +/// +/// > link_exists("/tmp") +/// Ok(True) +/// +/// > link_exists("/does_not_exist") +/// Ok(False) +/// +/// > link_exists("/root/.local/maybe_exists") +/// Error(Eacces) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn link_exists(path: String) -> Result(Bool, Reason) { + let result = + path + |> do_link_info + |> result.replace(True) + case result { + Error(Enoent) -> Ok(False) + _ -> result + } +} + +/// Tries to create a directory. Missing parent directories are not created. +/// +/// Returns a Result of nil if the directory is created or Reason if the +/// operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > make_directory("/tmp/foo") +/// Ok(Nil) +/// +/// > make_directory("relative_directory") +/// Ok(Nil) +/// +/// > make_directory("/tmp/missing_intermediate_directory/foo") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +@external(erlang, "gleam_erlang_ffi", "make_directory") +pub fn make_directory(a: String) -> Result(Nil, Reason) + +/// Lists all files in a directory, except files with +/// [raw filenames](https://www.erlang.org/doc/apps/stdlib/unicode_usage.html#notes-about-raw-filenames). +/// +/// Returns a Result containing the list of filenames in the directory, or Reason +/// if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > list_directory("/tmp") +/// Ok(["FB01293B-8597-4359-80D5-130140A0C0DE","AlTest2.out"]) +/// +/// > list_directory("resume.docx") +/// Error(Enotdir) +/// ``` +/// +@deprecated("Use the simplifile package instead") +@external(erlang, "gleam_erlang_ffi", "list_directory") +pub fn list_directory(a: String) -> Result(List(String), Reason) + +/// Deletes a directory. +/// +/// The directory must be empty before it can be deleted. Returns a nil Success +/// or Reason if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > delete_directory("foo") +/// Ok(Nil) +/// +/// > delete_directory("does_not_exist/") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +@external(erlang, "gleam_erlang_ffi", "delete_directory") +pub fn delete_directory(a: String) -> Result(Nil, Reason) + +/// Deletes a file or directory recursively. +/// +/// Returns a nil Success or Reason if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > recursive_delete("foo") +/// Ok(Nil) +/// +/// > recursive_delete("/bar") +/// Ok(Nil) +/// +/// > recursive_delete("does_not_exist/") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +@external(erlang, "gleam_erlang_ffi", "recursive_delete") +pub fn recursive_delete(a: String) -> Result(Nil, Reason) + +/// Read the contents of the given file as a String +/// +/// Assumes the file is UTF-8 encoded. Returns a Result containing the file's +/// contents as a String if the operation was successful, or Reason if the file +/// operation failed. If the file is not UTF-8 encoded, the `NotUTF8` variant +/// will be returned. +/// +/// ## Examples +/// +/// ```gleam +/// > read("example.txt") +/// Ok("Hello, World!") +/// +/// > read(from: "example.txt") +/// Ok("Hello, World!") +/// +/// > read("does_not_exist.txt") +/// Error(Enoent) +/// +/// > read("cat.gif") +/// Error(NotUTF8) +/// ``` +/// +@deprecated("Use the simplifile package instead?") +pub fn read(from path: String) -> Result(String, Reason) { + path + |> do_read_bits() + |> result.then(fn(content) { + case bit_array.to_string(content) { + Ok(string) -> Ok(string) + Error(Nil) -> Error(NotUtf8) + } + }) +} + +/// Read the contents of the given file as a BitString +/// +/// Returns a Result containing the file's contents as a BitString if the +/// operation was successful, or Reason if the operation failed. +/// +/// ## Examples +/// +/// ```gleam +/// > read_bits("example.txt") +/// Ok(<<"Hello, World!">>) +/// +/// > read_bits(from: "cat.gif") +/// Ok(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) +/// +/// > read_bits("does_not_exist.txt") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn read_bits(from path: String) -> Result(BitArray, Reason) { + do_read_bits(path) +} + +@external(erlang, "gleam_erlang_ffi", "read_file") +fn do_read_bits(a: path) -> Result(BitArray, Reason) + +/// Write the given String contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > write("Hello, World!", "file.txt") +/// Ok(Nil) +/// +/// > write(to: "file.txt", contents: "Hello, World!") +/// Ok(Nil) +/// +/// > write("Hello, World!", "does_not_exist/file.txt") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn write(contents contents: String, to path: String) -> Result(Nil, Reason) { + contents + |> bit_array.from_string + |> do_write_bits(path) +} + +/// Write the given BitString contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") +/// Ok(Nil) +/// +/// > write_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) +/// Ok(Nil) +/// +/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn write_bits( + contents contents: BitArray, + to path: String, +) -> Result(Nil, Reason) { + do_write_bits(contents, path) +} + +@external(erlang, "gleam_erlang_ffi", "write_file") +fn do_write_bits(a: BitArray, b: String) -> Result(Nil, Reason) + +/// Append the given String contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > append("Hello, World!", "file.txt") +/// Ok(Nil) +/// +/// > append(to: "file.txt", contents: "Hello, World!") +/// Ok(Nil) +/// +/// > append("Hello, World!", "does_not_exist/file.txt") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +pub fn append(contents contents: String, to path: String) -> Result(Nil, Reason) { + contents + |> bit_array.from_string + |> do_append_bits(path) +} + +/// Append the given BitString contents to a file of the given name. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") +/// Ok(Nil) +/// +/// > append_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) +/// Ok(Nil) +/// +/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") +/// Error(Enoent) +/// ``` +/// +pub fn append_bits( + contents contents: BitArray, + to path: String, +) -> Result(Nil, Reason) { + do_append_bits(contents, path) +} + +@external(erlang, "gleam_erlang_ffi", "append_file") +fn do_append_bits( + contents contents: BitArray, + path path: String, +) -> Result(Nil, Reason) + +/// Delete the given file. +/// +/// Returns a Result with Nil if the operation was successful or a Reason +/// otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > delete("file.txt") +/// Ok(Nil) +/// +/// > delete("does_not_exist.txt") +/// Error(Enoent) +/// ``` +/// +@deprecated("Use the simplifile package instead") +@external(erlang, "gleam_erlang_ffi", "delete_file") +pub fn delete(a: String) -> Result(Nil, Reason) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam new file mode 100644 index 00000000000..339415c9a1a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam @@ -0,0 +1,62 @@ +import gleam/erlang/atom.{type Atom} + +pub type Node + +type DoNotLeak + +/// Return the current node. +/// +@external(erlang, "erlang", "node") +pub fn self() -> Node + +/// Return a list of all visible nodes in the cluster, not including the current +/// node. +/// +/// The current node can be included by calling `self()` and prepending the +/// result. +/// +/// ```gleam +/// let all_nodes = [node.self(), ..node.visible()] +/// ``` +/// +@external(erlang, "erlang", "nodes") +pub fn visible() -> List(Node) + +pub type ConnectError { + /// Was unable to connect to the node. + FailedToConnect + /// The local node is not alive, so it is not possible to connect to the other + /// node. + LocalNodeIsNotAlive +} + +// TODO: test unknown node +// TODO: test successfully connecting +/// Establish a connection to a node, so the nodes can send messages to each +/// other and any other connected nodes. +/// +/// Returns `Error(FailedToConnect)` if the node is not reachable. +/// +/// Returns `Error(LocalNodeIsNotAlive)` if the local node is not alive, meaning +/// it is not running in distributed mode. +/// +@external(erlang, "gleam_erlang_ffi", "connect_node") +pub fn connect(node: Atom) -> Result(Node, ConnectError) + +// TODO: test +/// Send a message to a named process on a given node. +/// +/// These messages are untyped, like regular Erlang messages. +/// +pub fn send(node: Node, name: Atom, message: message) -> Nil { + raw_send(#(name, node), message) + Nil +} + +@external(erlang, "erlang", "send") +fn raw_send(receiver: #(Atom, Node), message: message) -> DoNotLeak + +/// Convert a node to the atom of its name. +/// +@external(erlang, "gleam_erlang_ffi", "identity") +pub fn to_atom(node: Node) -> Atom diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam new file mode 100644 index 00000000000..e13597404bf --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam @@ -0,0 +1,95 @@ +//// Access to the shell's environment variables + +import gleam/map.{type Map} + +/// Returns the list of all available environment variables as a list of key, +/// tuples. +/// +/// ## Examples +/// +/// > get_all_env() +/// map.from_list([ +/// #("SHELL", "/bin/bash"), +/// #("PWD", "/home/j3rn"), +/// ... +/// ]) +/// +@external(erlang, "gleam_erlang_ffi", "get_all_env") +pub fn get_all_env() -> Map(String, String) + +/// Returns the value associated with the given environment variable name. +/// +/// ## Examples +/// +/// > get_env("SHELL") +/// "/bin/bash" +/// +/// > get_env(name: "PWD") +/// "/home/j3rn" +/// +@external(erlang, "gleam_erlang_ffi", "get_env") +pub fn get_env(name name: String) -> Result(String, Nil) + +/// Associates the given value with the given environment variable name. +/// +/// ## Examples +/// +/// > set_env("MYVAR", "MYVALUE") +/// Nil +/// > get_env("MYVAR") +/// "MYVALUE" +/// +/// > set_env(value: "MYVALUE", name: "MYVAR") +/// Nil +/// +@external(erlang, "gleam_erlang_ffi", "set_env") +pub fn set_env(name name: String, value value: String) -> Nil + +/// Removes the environment variable with the given name. +/// +/// Returns Nil regardless of whether the variable ever existed. +/// +/// ## Examples +/// +/// > get_env("MYVAR") +/// Ok("MYVALUE") +/// > unset_env("MYVAR") +/// Nil +/// > get_env("MYVAR") +/// Error(Nil) +/// +/// > unset_env(name: "MYVAR") +/// Nil +/// +@external(erlang, "gleam_erlang_ffi", "unset_env") +pub fn unset_env(name name: String) -> Nil + +/// Represents operating system kernels +pub type OsFamily { + // The family which includes modern versions of the Windows operating system. + WindowsNt + // The family of operating systems based on the open source Linux kernel. + Linux + // The family of Apple operating systems such as macOS and iOS. + Darwin + // The family of operating systems based on the FreeBSD kernel. + FreeBsd + // An operating system kernel other than Linux, Darwin, FreeBSD, or NT. + Other(String) +} + +/// Returns the kernel of the host operating system. +/// +/// Unknown kernels are reported as `Other(String)`; e.g. `Other("sunos")`. +/// +/// ## Examples +/// +/// > family() +/// Linux +/// > family() +/// Darwin +/// > family() +/// Other("sunos") +/// +@external(erlang, "gleam_erlang_ffi", "os_family") +pub fn family() -> OsFamily diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam new file mode 100644 index 00000000000..f66030612a5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam @@ -0,0 +1,744 @@ +import gleam/string +import gleam/dynamic.{type Dynamic} +import gleam/erlang.{type Reference} +import gleam/erlang/atom.{type Atom} + +/// A `Pid` (or Process identifier) is a reference to an Erlang process. Each +/// process has a `Pid` and it is one of the lowest level building blocks of +/// inter-process communication in the Erlang and Gleam OTP frameworks. +/// +pub type Pid + +/// Get the `Pid` for the current process. +@external(erlang, "erlang", "self") +pub fn self() -> Pid + +/// Create a new Erlang process that runs concurrently to the creator. In other +/// languages this might be called a fibre, a green thread, or a coroutine. +/// +/// If `linked` is `True` then the created process is linked to the creator +/// process. When a process terminates an exit signal is sent to all other +/// processes that are linked to it, causing the process to either terminate or +/// have to handle the signal. +/// +/// More can be read about processes and links in the [Erlang documentation][1]. +/// +/// [1]: https://www.erlang.org/doc/reference_manual/processes.html +/// +pub fn start(running implementation: fn() -> anything, linked link: Bool) -> Pid { + case link { + True -> spawn_link(implementation) + False -> spawn(implementation) + } +} + +@external(erlang, "erlang", "spawn") +fn spawn(a: fn() -> anything) -> Pid + +@external(erlang, "erlang", "spawn_link") +fn spawn_link(a: fn() -> anything) -> Pid + +/// A `Subject` is a value that processes can use to send and receive messages +/// to and from each other in a well typed way. +/// +/// Each subject is "owned" by the process that created it. Any process can use +/// the `send` function to sent a message of the correct type to the process +/// that owns the subject, and the owner can use the `receive` function or the +/// `Selector` type to receive these messages. +/// +/// The `Subject` type is similar to the "channel" types found in other +/// languages and the "topic" concept found in some pub-sub systems. +/// +/// # Examples +/// +/// ```gleam +/// let subject = new_subject() +/// +/// // Send a message with the subject +/// send(subject, "Hello, Joe!") +/// +/// // Receive the message +/// receive(subject, within: 10) +/// ``` +/// +pub opaque type Subject(message) { + Subject(owner: Pid, tag: Reference) +} + +/// Create a new `Subject` owned by the current process. +/// +pub fn new_subject() -> Subject(message) { + Subject(owner: self(), tag: erlang.make_reference()) +} + +/// Get the owner process for a `Subject`. This is the process that created the +/// `Subject` and will receive messages sent with it. +/// +pub fn subject_owner(subject: Subject(message)) -> Pid { + subject.owner +} + +type DoNotLeak + +@external(erlang, "erlang", "send") +fn raw_send(a: Pid, b: message) -> DoNotLeak + +/// Send a message to a process using a `Subject`. The message must be of the +/// type that the `Subject` accepts. +/// +/// This function does not wait for the `Subject` owner process to call the +/// `receive` function, instead it returns once the message has been placed in +/// the process' mailbox. +/// +/// # Ordering +/// +/// If process P1 sends two messages to process P2 it is guaranteed that process +/// P1 will receive the messages in the order they were sent. +/// +/// If you wish to receive the messages in a different order you can send them +/// on two different subjects and the receiver function can call the `receive` +/// function for each subject in the desired order, or you can write some Erlang +/// code to perform a selective receive. +/// +/// # Examples +/// +/// ```gleam +/// let subject = new_subject() +/// send(subject, "Hello, Joe!") +/// ``` +/// +pub fn send(subject: Subject(message), message: message) -> Nil { + raw_send(subject.owner, #(subject.tag, message)) + Nil +} + +/// Receive a message that has been sent to current process using the `Subject`. +/// +/// If there is not an existing message for the `Subject` in the process' +/// mailbox or one does not arrive `within` the permitted timeout then the +/// `Error(Nil)` is returned. +/// +/// Only the process that is owner of the `Subject` can receive a message using +/// it. If a process that does not own the `Subject` attempts to receive with it +/// then it will not receive a message. +/// +/// To wait for messages from multiple `Subject`s at the same time see the +/// `Selector` type. +/// +pub fn receive( + from subject: Subject(message), + within milliseconds: Int, +) -> Result(message, Nil) { + new_selector() + |> selecting(subject, fn(x) { x }) + |> select(within: milliseconds) +} + +/// A type that enables a process to wait for messages from multiple `Subject`s +/// at the same time, returning whichever message arrives first. +/// +/// Used with the `new_selector`, `selecting`, and `select` functions. +/// +/// # Examples +/// +/// ```gleam +/// > let int_subject = new_subject() +/// > let float_subject = new_subject() +/// > send(int_subject, 1) +/// > +/// > let selector = +/// > new_selector() +/// > |> selecting(int_subject, int.to_string) +/// > |> selecting(float_subject, float.to_string) +/// > +/// > select(selector, 10) +/// Ok("1") +/// ``` +/// +pub type Selector(payload) + +/// Create a new `Selector` which can be used to receive messages on multiple +/// `Subject`s at once. +/// +@external(erlang, "gleam_erlang_ffi", "new_selector") +pub fn new_selector() -> Selector(payload) + +/// Receive a message that has been sent to current process using any of the +/// `Subject`s that have been added to the `Selector` with the `selecting` +/// function. +/// +/// If there is not an existing message for the `Selector` in the process' +/// mailbox or one does not arrive `within` the permitted timeout then the +/// `Error(Nil)` is returned. +/// +/// Only the process that is owner of the `Subject`s can receive a message using +/// them. If a process that does not own the a `Subject` attempts to receive +/// with it then it will not receive a message. +/// +/// To wait forever for the next message rather than for a limited amount of +/// time see the `select_forever` function. +/// +@external(erlang, "gleam_erlang_ffi", "select") +pub fn select( + from from: Selector(payload), + within within: Int, +) -> Result(payload, Nil) + +/// Similar to the `select` function but will wait forever for a message to +/// arrive rather than timing out after a specified amount of time. +/// +@external(erlang, "gleam_erlang_ffi", "select") +pub fn select_forever(from from: Selector(payload)) -> payload + +/// Add a transformation function to a selector. When a message is received +/// using this selector the transformation function is applied to the message. +/// +/// This function can be used to change the type of messages received and may +/// be useful when combined with the `merge_selector` function. +/// +@external(erlang, "gleam_erlang_ffi", "map_selector") +pub fn map_selector(a: Selector(a), b: fn(a) -> b) -> Selector(b) + +/// Merge one selector into another, producing a selector that contains the +/// message handlers of both. +/// +/// If a subject is handled by both selectors the handler function of the +/// second selector is used. +/// +@external(erlang, "gleam_erlang_ffi", "merge_selector") +pub fn merge_selector(a: Selector(a), b: Selector(a)) -> Selector(a) + +pub type ExitMessage { + ExitMessage(pid: Pid, reason: ExitReason) +} + +pub type ExitReason { + Normal + Killed + Abnormal(reason: String) +} + +/// Add a handler for trapped exit messages. In order for these messages to be +/// sent to the process when a linked process exits the process must call the +/// `trap_exit` beforehand. +/// +pub fn selecting_trapped_exits( + selector: Selector(a), + handler: fn(ExitMessage) -> a, +) -> Selector(a) { + let tag = atom.create_from_string("EXIT") + let handler = fn(message: #(Atom, Pid, Dynamic)) -> a { + let reason = message.2 + let normal = dynamic.from(Normal) + let killed = dynamic.from(Killed) + let reason = case dynamic.string(reason) { + _ if reason == normal -> Normal + _ if reason == killed -> Killed + Ok(reason) -> Abnormal(reason) + Error(_) -> Abnormal(string.inspect(reason)) + } + handler(ExitMessage(message.1, reason)) + } + insert_selector_handler(selector, #(tag, 3), handler) +} + +// TODO: implement in Gleam +/// Discard all messages in the current process' mailbox. +/// +/// Warning: This function may cause other processes to crash if they sent a +/// message to the current process and are waiting for a response, so use with +/// caution. +/// +@external(erlang, "gleam_erlang_ffi", "flush_messages") +pub fn flush_messages() -> Nil + +/// Add a new `Subject` to the `Selector` to that it's messages can be received. +/// +/// The `mapping` function provided with the `Subject` can be used to convert +/// the type of messages received using this `Subject`. This is useful for when +/// you wish to add multiple `Subject`s to a `Seletor` when they have differing +/// message types. If you do not wish to transform the incoming messages in any +/// way then the `identity` function can be given. +/// +pub fn selecting( + selector: Selector(payload), + for subject: Subject(message), + mapping transform: fn(message) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(Reference, message)) { transform(message.1) } + insert_selector_handler(selector, #(subject.tag, 2), handler) +} + +/// Add a handler to a selector for 2 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record2( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic)) { transform(message.1) } + insert_selector_handler(selector, #(tag, 2), handler) +} + +/// Add a handler to a selector for 3 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record3( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic)) { + transform(message.1, message.2) + } + insert_selector_handler(selector, #(tag, 3), handler) +} + +/// Add a handler to a selector for 4 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record4( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic)) { + transform(message.1, message.2, message.3) + } + insert_selector_handler(selector, #(tag, 4), handler) +} + +/// Add a handler to a selector for 5 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record5( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic)) { + transform(message.1, message.2, message.3, message.4) + } + insert_selector_handler(selector, #(tag, 5), handler) +} + +/// Add a handler to a selector for 6 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record6( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> payload, +) -> Selector(payload) { + let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic)) { + transform(message.1, message.2, message.3, message.4, message.5) + } + insert_selector_handler(selector, #(tag, 6), handler) +} + +/// Add a handler to a selector for 7 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record7( + selector: Selector(payload), + tag: tag, + mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> + payload, +) -> Selector(payload) { + let handler = fn( + message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), + ) { + transform(message.1, message.2, message.3, message.4, message.5, message.6) + } + insert_selector_handler(selector, #(tag, 7), handler) +} + +/// Add a handler to a selector for 8 element tuple messages with a given tag +/// element in the first position. +/// +/// Typically you want to use the `selecting` function with a `Subject` instead, +/// but this function may be useful if you need to receive messages sent from +/// other BEAM languages that do not use the `Subject` type. +/// +pub fn selecting_record8( + selector: Selector(payload), + tag: tag, + mapping transform: fn( + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + ) -> + payload, +) -> Selector(payload) { + let handler = fn( + message: #( + tag, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + Dynamic, + ), + ) { + transform( + message.1, + message.2, + message.3, + message.4, + message.5, + message.6, + message.7, + ) + } + insert_selector_handler(selector, #(tag, 8), handler) +} + +type AnythingSelectorTag { + Anything +} + +/// Add a catch-all handler to a selector that will be used when no other +/// handler in a selector is suitable for a given message. +/// +/// This may be useful for when you want to ensure that any message in the inbox +/// is handled, or when you need to handle messages from other BEAM languages +/// which do not use subjects or record format messages. +/// +pub fn selecting_anything( + selector: Selector(payload), + mapping handler: fn(Dynamic) -> payload, +) -> Selector(payload) { + insert_selector_handler(selector, Anything, handler) +} + +@external(erlang, "gleam_erlang_ffi", "insert_selector_handler") +fn insert_selector_handler( + a: Selector(payload), + for for: tag, + mapping mapping: fn(message) -> payload, +) -> Selector(payload) + +/// Suspends the process calling this function for the specified number of +/// milliseconds. +/// +@external(erlang, "gleam_erlang_ffi", "sleep") +pub fn sleep(a: Int) -> Nil + +/// Suspends the process forever! This may be useful for suspending the main +/// process in a Gleam program when it has no more work to do but we want other +/// processes to continue to work. +/// +@external(erlang, "gleam_erlang_ffi", "sleep_forever") +pub fn sleep_forever() -> Nil + +/// Check to see whether the process for a given `Pid` is alive. +/// +/// See the [Erlang documentation][1] for more information. +/// +/// [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1 +/// +@external(erlang, "erlang", "is_process_alive") +pub fn is_alive(a: Pid) -> Bool + +type ProcessMonitorFlag { + Process +} + +@external(erlang, "erlang", "monitor") +fn erlang_monitor_process(a: ProcessMonitorFlag, b: Pid) -> Reference + +pub opaque type ProcessMonitor { + ProcessMonitor(tag: Reference) +} + +/// A message received when a monitored process exits. +/// +pub type ProcessDown { + ProcessDown(pid: Pid, reason: Dynamic) +} + +/// Start monitoring a process so that when the monitored process exits a +/// message is sent to the monitoring process. +/// +/// The message is only sent once, when the target process exits. If the +/// process was not alive when this function is called the message will never +/// be received. +/// +/// The down message can be received with a `Selector` and the +/// `selecting_process_down` function. +/// +/// The process can be demonitored with the `demonitor_process` function. +/// +pub fn monitor_process(pid: Pid) -> ProcessMonitor { + Process + |> erlang_monitor_process(pid) + |> ProcessMonitor +} + +/// Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can +/// be received using the `Selector` and the `select` function. +/// +pub fn selecting_process_down( + selector: Selector(payload), + monitor: ProcessMonitor, + mapping: fn(ProcessDown) -> payload, +) -> Selector(payload) { + insert_selector_handler(selector, monitor.tag, mapping) +} + +/// Remove the monitor for a process so that when the monitor process exits a +/// `ProcessDown` message is not sent to the monitoring process. +/// +/// If the message has already been sent it is removed from the monitoring +/// process' mailbox. +/// +@external(erlang, "gleam_erlang_ffi", "demonitor") +pub fn demonitor_process(monitor monitor: ProcessMonitor) -> Nil + +/// An error returned when making a call to a process. +/// +pub type CallError(msg) { + /// The process being called exited before it sent a response. + /// + CalleeDown(reason: Dynamic) + + /// The process being called did not response within the permitted amount of + /// time. + /// + CallTimeout +} + +// This function is based off of Erlang's gen:do_call/4. +/// Send a message to a process and wait for a reply. +/// +/// If the receiving process exits or does not reply within the allowed amount +/// of time then an error is returned. +/// +pub fn try_call( + subject: Subject(request), + make_request: fn(Subject(response)) -> request, + within timeout: Int, +) -> Result(response, CallError(response)) { + let reply_subject = new_subject() + + // Monitor the callee process so we can tell if it goes down (meaning we + // won't get a reply) + let monitor = monitor_process(subject_owner(subject)) + + // Send the request to the process over the channel + send(subject, make_request(reply_subject)) + + // Await a reply or handle failure modes (timeout, process down, etc) + let result = + new_selector() + |> selecting(reply_subject, Ok) + |> selecting_process_down( + monitor, + fn(down: ProcessDown) { Error(CalleeDown(reason: down.reason)) }, + ) + |> select(timeout) + + // Demonitor the process and close the channels as we're done + demonitor_process(monitor) + + // Prepare an appropriate error (if present) for the caller + case result { + Error(Nil) -> Error(CallTimeout) + Ok(res) -> res + } +} + +/// Send a message to a process and wait for a reply. +/// +/// If the receiving process exits or does not reply within the allowed amount +/// of time the calling process crashes. If you wish an error to be returned +/// instead see the `try_call` function. +/// +pub fn call( + subject: Subject(request), + make_request: fn(Subject(response)) -> request, + within timeout: Int, +) -> response { + let assert Ok(resp) = try_call(subject, make_request, timeout) + resp +} + +/// Creates a link between the calling process and another process. +/// +/// When a process crashes any linked processes will also crash. This is useful +/// to ensure that groups of processes that depend on each other all either +/// succeed or fail together. +/// +/// Returns `True` if the link was created successfully, returns `False` if the +/// process was not alive and as such could not be linked. +/// +@external(erlang, "gleam_erlang_ffi", "link") +pub fn link(pid pid: Pid) -> Bool + +@external(erlang, "erlang", "unlink") +fn erlang_unlink(pid pid: Pid) -> Bool + +/// Removes any existing link between the caller process and the target process. +/// +pub fn unlink(pid: Pid) -> Nil { + erlang_unlink(pid) + Nil +} + +pub type Timer + +@external(erlang, "erlang", "send_after") +fn erlang_send_after(a: Int, b: Pid, c: msg) -> Timer + +/// Send a message over a channel after a specified number of milliseconds. +/// +pub fn send_after(subject: Subject(msg), delay: Int, message: msg) -> Timer { + erlang_send_after(delay, subject.owner, #(subject.tag, message)) +} + +@external(erlang, "erlang", "cancel_timer") +fn erlang_cancel_timer(a: Timer) -> Dynamic + +/// Values returned when a timer is cancelled. +/// +pub type Cancelled { + /// The timer could not be found. It likely has already triggered. + /// + TimerNotFound + + /// The timer was found and cancelled before it triggered. + /// + /// The amount of remaining time before the timer was due to be triggered is + /// returned in milliseconds. + /// + Cancelled(time_remaining: Int) +} + +/// Cancel a given timer, causing it not to trigger if it has not done already. +/// +pub fn cancel_timer(timer: Timer) -> Cancelled { + case dynamic.int(erlang_cancel_timer(timer)) { + Ok(i) -> Cancelled(i) + Error(_) -> TimerNotFound + } +} + +type KillFlag { + Kill +} + +@external(erlang, "erlang", "exit") +fn erlang_kill(to to: Pid, because because: KillFlag) -> Bool + +// Go, my pretties. Kill! Kill! +// - Bart Simpson +// +/// Send an untrappable `kill` exit signal to the target process. +/// +/// See the documentation for the Erlang [`erlang:exit`][1] function for more +/// information. +/// +/// [1]: https://erlang.org/doc/man/erlang.html#exit-1 +/// +pub fn kill(pid: Pid) -> Nil { + erlang_kill(pid, Kill) + Nil +} + +@external(erlang, "erlang", "exit") +fn erlang_send_exit(to to: Pid, because because: whatever) -> Bool + +// TODO: test +/// Sends an exit signal to a process, indicating that the process is to shut +/// down. +/// +/// See the [Erlang documentation][erl] for more information. +/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 +/// +pub fn send_exit(to pid: Pid) -> Nil { + erlang_send_exit(pid, Normal) + Nil +} + +/// Sends an exit signal to a process, indicating that the process is to shut +/// down due to an abnormal reason such as a failure. +/// +/// See the [Erlang documentation][erl] for more information. +/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 +/// +pub fn send_abnormal_exit(pid: Pid, reason: String) -> Nil { + erlang_send_exit(pid, Abnormal(reason)) + Nil +} + +/// Set whether the current process is to trap exit signals or not. +/// +/// When not trapping exits if a linked process crashes the exit signal +/// propagates to the process which will also crash. +/// This is the normal behaviour before this function is called. +/// +/// When trapping exits (after this function is called) if a linked process +/// crashes an exit message is sent to the process instead. These messages can +/// be handled with the `selecting_trapped_exits` function. +/// +@external(erlang, "gleam_erlang_ffi", "trap_exits") +pub fn trap_exits(a: Bool) -> Nil + +/// Register a process under a given name, allowing it to be looked up using +/// the `named` function. +/// +/// This function will return an error under the following conditions: +/// - The process for the pid no longer exists. +/// - The name has already been registered. +/// - The process already has a name. +/// - The name is the atom `undefined`, which is reserved by Erlang. +/// +@external(erlang, "gleam_erlang_ffi", "register_process") +pub fn register(pid: Pid, name: Atom) -> Result(Nil, Nil) + +/// Un-register a process name, after which the process can no longer be looked +/// up by that name, and both the name and the process can be re-used in other +/// registrations. +/// +/// It is possible to un-register process that are not from your application, +/// including those from Erlang/OTP itself. This is not recommended and will +/// likely result in undesirable behaviour and crashes. +/// +@external(erlang, "gleam_erlang_ffi", "unregister_process") +pub fn unregister(name: Atom) -> Result(Nil, Nil) + +/// Look up a process by name, returning the pid if it exists. +/// +@external(erlang, "gleam_erlang_ffi", "process_named") +pub fn named(name: Atom) -> Result(Pid, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl new file mode 100644 index 00000000000..14a55381864 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl @@ -0,0 +1,90 @@ +-module(gleam@erlang). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0, priv_directory/1]). +-export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]). + +-type safe() :: safe. + +-type get_line_error() :: eof | no_data. + +-type time_unit() :: second | millisecond | microsecond | nanosecond. + +-type crash() :: {exited, gleam@dynamic:dynamic_()} | + {thrown, gleam@dynamic:dynamic_()} | + {errored, gleam@dynamic:dynamic_()}. + +-type ensure_all_started_error() :: {unknown_application, + gleam@erlang@atom:atom_()} | + {application_failed_to_start, + gleam@erlang@atom:atom_(), + gleam@dynamic:dynamic_()}. + +-type reference_() :: any(). + +-spec format(any()) -> binary(). +format(Term) -> + unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])). + +-spec term_to_binary(any()) -> bitstring(). +term_to_binary(A) -> + erlang:term_to_binary(A). + +-spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. +get_line(Prompt) -> + gleam_erlang_ffi:get_line(Prompt). + +-spec system_time(time_unit()) -> integer(). +system_time(A) -> + os:system_time(A). + +-spec erlang_timestamp() -> {integer(), integer(), integer()}. +erlang_timestamp() -> + os:timestamp(). + +-spec rescue(fun(() -> FHH)) -> {ok, FHH} | {error, crash()}. +rescue(A) -> + gleam_erlang_ffi:rescue(A). + +-spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | + {error, nil}. +binary_to_term(Binary) -> + case gleam_erlang_ffi:rescue( + fun() -> erlang:binary_to_term(Binary, [safe]) end + ) of + {ok, Term} -> + {ok, Term}; + + {error, _} -> + {error, nil} + end. + +-spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | + {error, nil}. +unsafe_binary_to_term(Binary) -> + case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of + {ok, Term} -> + {ok, Term}; + + {error, _} -> + {error, nil} + end. + +-spec start_arguments() -> list(binary()). +start_arguments() -> + _pipe = init:get_plain_arguments(), + gleam@list:map(_pipe, fun unicode:characters_to_binary/1). + +-spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok, + list(gleam@erlang@atom:atom_())} | + {error, ensure_all_started_error()}. +ensure_all_started(Application) -> + gleam_erlang_ffi:ensure_all_started(Application). + +-spec make_reference() -> reference_(). +make_reference() -> + erlang:make_ref(). + +-spec priv_directory(binary()) -> {ok, binary()} | {error, nil}. +priv_directory(Name) -> + gleam_erlang_ffi:priv_directory(Name). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl new file mode 100644 index 00000000000..e9ad5300ce5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl @@ -0,0 +1,26 @@ +-module(gleam@erlang@atom). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]). +-export_type([atom_/0, from_string_error/0]). + +-type atom_() :: any(). + +-type from_string_error() :: atom_not_loaded. + +-spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}. +from_string(A) -> + gleam_erlang_ffi:atom_from_string(A). + +-spec create_from_string(binary()) -> atom_(). +create_from_string(A) -> + erlang:binary_to_atom(A). + +-spec to_string(atom_()) -> binary(). +to_string(A) -> + erlang:atom_to_binary(A). + +-spec from_dynamic(gleam@dynamic:dynamic_()) -> {ok, atom_()} | + {error, list(gleam@dynamic:decode_error())}. +from_dynamic(From) -> + gleam_erlang_ffi:atom_from_dynamic(From). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl new file mode 100644 index 00000000000..9f9c0fa1c55 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl @@ -0,0 +1,15 @@ +-module(gleam@erlang@charlist). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([to_string/1, from_string/1]). +-export_type([charlist/0]). + +-type charlist() :: any(). + +-spec to_string(charlist()) -> binary(). +to_string(A) -> + unicode:characters_to_binary(A). + +-spec from_string(binary()) -> charlist(). +from_string(A) -> + unicode:characters_to_list(A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl new file mode 100644 index 00000000000..1fe6628add7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl @@ -0,0 +1,190 @@ +-module(gleam@erlang@file). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([file_info/1, link_info/1, is_directory/1, is_regular/1, file_exists/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]). +-export_type([reason/0, file_type/0, access/0, file_info/0]). + +-type reason() :: eacces | + eagain | + ebadf | + ebadmsg | + ebusy | + edeadlk | + edeadlock | + edquot | + eexist | + efault | + efbig | + eftype | + eintr | + einval | + eio | + eisdir | + eloop | + emfile | + emlink | + emultihop | + enametoolong | + enfile | + enobufs | + enodev | + enolck | + enolink | + enoent | + enomem | + enospc | + enosr | + enostr | + enosys | + enotblk | + enotdir | + enotsup | + enxio | + eopnotsupp | + eoverflow | + eperm | + epipe | + erange | + erofs | + espipe | + esrch | + estale | + etxtbsy | + exdev | + not_utf8. + +-type file_type() :: device | directory | other | regular | symlink. + +-type access() :: no_access | read | read_write | write. + +-type file_info() :: {file_info, + integer(), + file_type(), + access(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer()}. + +-spec file_info(binary()) -> {ok, file_info()} | {error, reason()}. +file_info(A) -> + gleam_erlang_ffi:file_info(A). + +-spec link_info(binary()) -> {ok, file_info()} | {error, reason()}. +link_info(A) -> + gleam_erlang_ffi:link_info(A). + +-spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}. +is_directory(Path) -> + gleam@result:map( + gleam_erlang_ffi:file_info(Path), + fun(_use0) -> + {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, + File_type =:= directory + end + ). + +-spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}. +is_regular(Path) -> + gleam@result:map( + gleam_erlang_ffi:file_info(Path), + fun(_use0) -> + {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, + File_type =:= regular + end + ). + +-spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}. +file_exists(Path) -> + Result = begin + _pipe = Path, + _pipe@1 = gleam_erlang_ffi:file_info(_pipe), + gleam@result:replace(_pipe@1, true) + end, + case Result of + {error, enoent} -> + {ok, false}; + + _ -> + Result + end. + +-spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}. +link_exists(Path) -> + Result = begin + _pipe = Path, + _pipe@1 = gleam_erlang_ffi:link_info(_pipe), + gleam@result:replace(_pipe@1, true) + end, + case Result of + {error, enoent} -> + {ok, false}; + + _ -> + Result + end. + +-spec make_directory(binary()) -> {ok, nil} | {error, reason()}. +make_directory(A) -> + gleam_erlang_ffi:make_directory(A). + +-spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}. +list_directory(A) -> + gleam_erlang_ffi:list_directory(A). + +-spec delete_directory(binary()) -> {ok, nil} | {error, reason()}. +delete_directory(A) -> + gleam_erlang_ffi:delete_directory(A). + +-spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}. +recursive_delete(A) -> + gleam_erlang_ffi:recursive_delete(A). + +-spec read(binary()) -> {ok, binary()} | {error, reason()}. +read(Path) -> + _pipe = Path, + _pipe@1 = gleam_erlang_ffi:read_file(_pipe), + gleam@result:then( + _pipe@1, + fun(Content) -> case gleam@bit_array:to_string(Content) of + {ok, String} -> + {ok, String}; + + {error, nil} -> + {error, not_utf8} + end end + ). + +-spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}. +read_bits(Path) -> + gleam_erlang_ffi:read_file(Path). + +-spec write(binary(), binary()) -> {ok, nil} | {error, reason()}. +write(Contents, Path) -> + _pipe = Contents, + _pipe@1 = gleam_stdlib:identity(_pipe), + gleam_erlang_ffi:write_file(_pipe@1, Path). + +-spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. +write_bits(Contents, Path) -> + gleam_erlang_ffi:write_file(Contents, Path). + +-spec append(binary(), binary()) -> {ok, nil} | {error, reason()}. +append(Contents, Path) -> + _pipe = Contents, + _pipe@1 = gleam_stdlib:identity(_pipe), + gleam_erlang_ffi:append_file(_pipe@1, Path). + +-spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. +append_bits(Contents, Path) -> + gleam_erlang_ffi:append_file(Contents, Path). + +-spec delete(binary()) -> {ok, nil} | {error, reason()}. +delete(A) -> + gleam_erlang_ffi:delete_file(A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl new file mode 100644 index 00000000000..f57d029ba1a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl @@ -0,0 +1,33 @@ +-module(gleam@erlang@node). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([self/0, visible/0, connect/1, send/3, to_atom/1]). +-export_type([node_/0, do_not_leak/0, connect_error/0]). + +-type node_() :: any(). + +-type do_not_leak() :: any(). + +-type connect_error() :: failed_to_connect | local_node_is_not_alive. + +-spec self() -> node_(). +self() -> + erlang:node(). + +-spec visible() -> list(node_()). +visible() -> + erlang:nodes(). + +-spec connect(gleam@erlang@atom:atom_()) -> {ok, node_()} | + {error, connect_error()}. +connect(Node) -> + gleam_erlang_ffi:connect_node(Node). + +-spec send(node_(), gleam@erlang@atom:atom_(), any()) -> nil. +send(Node, Name, Message) -> + erlang:send({Name, Node}, Message), + nil. + +-spec to_atom(node_()) -> gleam@erlang@atom:atom_(). +to_atom(Node) -> + gleam_erlang_ffi:identity(Node). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl new file mode 100644 index 00000000000..6604255b55f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl @@ -0,0 +1,27 @@ +-module(gleam@erlang@os). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]). +-export_type([os_family/0]). + +-type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}. + +-spec get_all_env() -> gleam@map:map_(binary(), binary()). +get_all_env() -> + gleam_erlang_ffi:get_all_env(). + +-spec get_env(binary()) -> {ok, binary()} | {error, nil}. +get_env(Name) -> + gleam_erlang_ffi:get_env(Name). + +-spec set_env(binary(), binary()) -> nil. +set_env(Name, Value) -> + gleam_erlang_ffi:set_env(Name, Value). + +-spec unset_env(binary()) -> nil. +unset_env(Name) -> + gleam_erlang_ffi:unset_env(Name). + +-spec family() -> os_family(). +family() -> + gleam_erlang_ffi:os_family(). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl new file mode 100644 index 00000000000..fc8e0ffe15f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl @@ -0,0 +1,374 @@ +-module(gleam@erlang@process). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([self/0, start/2, new_subject/0, subject_owner/1, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, selecting_process_down/3, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1, register/2, unregister/1, named/1]). +-export_type([pid_/0, subject/1, do_not_leak/0, selector/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, timer/0, cancelled/0, kill_flag/0]). + +-type pid_() :: any(). + +-opaque subject(FJD) :: {subject, pid_(), gleam@erlang:reference_()} | + {gleam_phantom, FJD}. + +-type do_not_leak() :: any(). + +-type selector(FJE) :: any() | {gleam_phantom, FJE}. + +-type exit_message() :: {exit_message, pid_(), exit_reason()}. + +-type exit_reason() :: normal | killed | {abnormal, binary()}. + +-type anything_selector_tag() :: anything. + +-type process_monitor_flag() :: process. + +-opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}. + +-type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic_()}. + +-type call_error(FJF) :: {callee_down, gleam@dynamic:dynamic_()} | + call_timeout | + {gleam_phantom, FJF}. + +-type timer() :: any(). + +-type cancelled() :: timer_not_found | {cancelled, integer()}. + +-type kill_flag() :: kill. + +-spec self() -> pid_(). +self() -> + erlang:self(). + +-spec start(fun(() -> any()), boolean()) -> pid_(). +start(Implementation, Link) -> + case Link of + true -> + erlang:spawn_link(Implementation); + + false -> + erlang:spawn(Implementation) + end. + +-spec new_subject() -> subject(any()). +new_subject() -> + {subject, erlang:self(), erlang:make_ref()}. + +-spec subject_owner(subject(any())) -> pid_(). +subject_owner(Subject) -> + erlang:element(2, Subject). + +-spec send(subject(FJO), FJO) -> nil. +send(Subject, Message) -> + erlang:send( + erlang:element(2, Subject), + {erlang:element(3, Subject), Message} + ), + nil. + +-spec new_selector() -> selector(any()). +new_selector() -> + gleam_erlang_ffi:new_selector(). + +-spec select(selector(FJW), integer()) -> {ok, FJW} | {error, nil}. +select(From, Within) -> + gleam_erlang_ffi:select(From, Within). + +-spec select_forever(selector(FKA)) -> FKA. +select_forever(From) -> + gleam_erlang_ffi:select(From). + +-spec map_selector(selector(FKC), fun((FKC) -> FKE)) -> selector(FKE). +map_selector(A, B) -> + gleam_erlang_ffi:map_selector(A, B). + +-spec merge_selector(selector(FKG), selector(FKG)) -> selector(FKG). +merge_selector(A, B) -> + gleam_erlang_ffi:merge_selector(A, B). + +-spec flush_messages() -> nil. +flush_messages() -> + gleam_erlang_ffi:flush_messages(). + +-spec selecting_trapped_exits(selector(FKK), fun((exit_message()) -> FKK)) -> selector(FKK). +selecting_trapped_exits(Selector, Handler) -> + Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>), + Handler@1 = fun(Message) -> + Reason = erlang:element(3, Message), + Normal = gleam@dynamic:from(normal), + Killed = gleam@dynamic:from(killed), + Reason@2 = case gleam@dynamic:string(Reason) of + _ when Reason =:= Normal -> + normal; + + _ when Reason =:= Killed -> + killed; + + {ok, Reason@1} -> + {abnormal, Reason@1}; + + {error, _} -> + {abnormal, gleam@string:inspect(Reason)} + end, + Handler({exit_message, erlang:element(2, Message), Reason@2}) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1). + +-spec selecting(selector(FKN), subject(FKP), fun((FKP) -> FKN)) -> selector(FKN). +selecting(Selector, Subject, Transform) -> + Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, + gleam_erlang_ffi:insert_selector_handler( + Selector, + {erlang:element(3, Subject), 2}, + Handler + ). + +-spec 'receive'(subject(FJQ), integer()) -> {ok, FJQ} | {error, nil}. +'receive'(Subject, Milliseconds) -> + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end), + gleam_erlang_ffi:select(_pipe@1, Milliseconds). + +-spec selecting_record2( + selector(FKS), + any(), + fun((gleam@dynamic:dynamic_()) -> FKS) +) -> selector(FKS). +selecting_record2(Selector, Tag, Transform) -> + Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler). + +-spec selecting_record3( + selector(FKW), + any(), + fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FKW) +) -> selector(FKW). +selecting_record3(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform(erlang:element(2, Message), erlang:element(3, Message)) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler). + +-spec selecting_record4( + selector(FLA), + any(), + fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLA) +) -> selector(FLA). +selecting_record4(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler). + +-spec selecting_record5( + selector(FLE), + any(), + fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLE) +) -> selector(FLE). +selecting_record5(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler). + +-spec selecting_record6( + selector(FLI), + any(), + fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLI) +) -> selector(FLI). +selecting_record6(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message), + erlang:element(6, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler). + +-spec selecting_record7( + selector(FLM), + any(), + fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLM) +) -> selector(FLM). +selecting_record7(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message), + erlang:element(6, Message), + erlang:element(7, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler). + +-spec selecting_record8( + selector(FLQ), + any(), + fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLQ) +) -> selector(FLQ). +selecting_record8(Selector, Tag, Transform) -> + Handler = fun(Message) -> + Transform( + erlang:element(2, Message), + erlang:element(3, Message), + erlang:element(4, Message), + erlang:element(5, Message), + erlang:element(6, Message), + erlang:element(7, Message), + erlang:element(8, Message) + ) + end, + gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler). + +-spec selecting_anything(selector(FLU), fun((gleam@dynamic:dynamic_()) -> FLU)) -> selector(FLU). +selecting_anything(Selector, Handler) -> + gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler). + +-spec sleep(integer()) -> nil. +sleep(A) -> + gleam_erlang_ffi:sleep(A). + +-spec sleep_forever() -> nil. +sleep_forever() -> + gleam_erlang_ffi:sleep_forever(). + +-spec is_alive(pid_()) -> boolean(). +is_alive(A) -> + erlang:is_process_alive(A). + +-spec monitor_process(pid_()) -> process_monitor(). +monitor_process(Pid) -> + _pipe = process, + _pipe@1 = erlang:monitor(_pipe, Pid), + {process_monitor, _pipe@1}. + +-spec selecting_process_down( + selector(FMC), + process_monitor(), + fun((process_down()) -> FMC) +) -> selector(FMC). +selecting_process_down(Selector, Monitor, Mapping) -> + gleam_erlang_ffi:insert_selector_handler( + Selector, + erlang:element(2, Monitor), + Mapping + ). + +-spec demonitor_process(process_monitor()) -> nil. +demonitor_process(Monitor) -> + gleam_erlang_ffi:demonitor(Monitor). + +-spec try_call(subject(FMF), fun((subject(FMH)) -> FMF), integer()) -> {ok, FMH} | + {error, call_error(FMH)}. +try_call(Subject, Make_request, Timeout) -> + Reply_subject = new_subject(), + Monitor = monitor_process(subject_owner(Subject)), + send(Subject, Make_request(Reply_subject)), + Result = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = selecting( + _pipe, + Reply_subject, + fun(Field@0) -> {ok, Field@0} end + ), + _pipe@2 = selecting_process_down( + _pipe@1, + Monitor, + fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end + ), + gleam_erlang_ffi:select(_pipe@2, Timeout) + end, + gleam_erlang_ffi:demonitor(Monitor), + case Result of + {error, nil} -> + {error, call_timeout}; + + {ok, Res} -> + Res + end. + +-spec call(subject(FMM), fun((subject(FMO)) -> FMM), integer()) -> FMO. +call(Subject, Make_request, Timeout) -> + _assert_subject = try_call(Subject, Make_request, Timeout), + {ok, Resp} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/erlang/process"/utf8>>, + function => <<"call"/utf8>>, + line => 593}) + end, + Resp. + +-spec link(pid_()) -> boolean(). +link(Pid) -> + gleam_erlang_ffi:link(Pid). + +-spec unlink(pid_()) -> nil. +unlink(Pid) -> + erlang:unlink(Pid), + nil. + +-spec send_after(subject(FMR), integer(), FMR) -> timer(). +send_after(Subject, Delay, Message) -> + erlang:send_after( + Delay, + erlang:element(2, Subject), + {erlang:element(3, Subject), Message} + ). + +-spec cancel_timer(timer()) -> cancelled(). +cancel_timer(Timer) -> + case gleam@dynamic:int(erlang:cancel_timer(Timer)) of + {ok, I} -> + {cancelled, I}; + + {error, _} -> + timer_not_found + end. + +-spec kill(pid_()) -> nil. +kill(Pid) -> + erlang:exit(Pid, kill), + nil. + +-spec send_exit(pid_()) -> nil. +send_exit(Pid) -> + erlang:exit(Pid, normal), + nil. + +-spec send_abnormal_exit(pid_(), binary()) -> nil. +send_abnormal_exit(Pid, Reason) -> + erlang:exit(Pid, {abnormal, Reason}), + nil. + +-spec trap_exits(boolean()) -> nil. +trap_exits(A) -> + gleam_erlang_ffi:trap_exits(A). + +-spec register(pid_(), gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. +register(Pid, Name) -> + gleam_erlang_ffi:register_process(Pid, Name). + +-spec unregister(gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. +unregister(Name) -> + gleam_erlang_ffi:unregister_process(Name). + +-spec named(gleam@erlang@atom:atom_()) -> {ok, pid_()} | {error, nil}. +named(Name) -> + gleam_erlang_ffi:process_named(Name). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src new file mode 100644 index 00000000000..bb1b8e635ed --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src @@ -0,0 +1,14 @@ +{application, gleam_erlang, [ + {vsn, "0.23.1"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "A Gleam library for working with Erlang"}, + {modules, [gleam@erlang, + gleam@erlang@atom, + gleam@erlang@charlist, + gleam@erlang@file, + gleam@erlang@node, + gleam@erlang@os, + gleam@erlang@process]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl new file mode 100644 index 00000000000..872126fec75 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl @@ -0,0 +1,263 @@ +-module(gleam_erlang_ffi). +-export([ + atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, + ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, + append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, + set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, + list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, + insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, + merge_selector/2, flush_messages/0, file_info/1, link_info/1, + priv_directory/1, connect_node/1, register_process/2, unregister_process/1, + process_named/1, identity/1 +]). + +-define(is_posix_error(Error), + Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse + Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse + Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse + Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse + Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse + Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse + Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse + Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse + Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse + Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse + Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse + Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse + Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse + Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse + Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse + Error =:= etxtbsy orelse Error =:= exdev +). + +-spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. +atom_from_string(S) -> + try {ok, binary_to_existing_atom(S)} + catch error:badarg -> {error, atom_not_loaded} + end. + +atom_from_dynamic(Data) when is_atom(Data) -> + {ok, Data}; +atom_from_dynamic(Data) -> + {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. + +-spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. +get_line(Prompt) -> + case io:get_line(Prompt) of + eof -> {error, eof}; + {error, _} -> {error, no_data}; + Data when is_binary(Data) -> {ok, Data}; + Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} + end. + +rescue(F) -> + try {ok, F()} + catch + throw:X -> {error, {thrown, X}}; + error:X -> {error, {errored, X}}; + exit:X -> {error, {exited, X}} + end. + +ensure_all_started(Application) -> + case application:ensure_all_started(Application) of + {ok, _} = Ok -> Ok; + + {error, {ProblemApp, {"no such file or directory", _}}} -> + {error, {unknown_application, ProblemApp}} + end. + +sleep(Microseconds) -> + timer:sleep(Microseconds), + nil. + +sleep_forever() -> + timer:sleep(infinity), + nil. + +file_info_result(Result) -> + case Result of + {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> + {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; + {ok, _} -> + Result; + {error, Reason} when ?is_posix_error(Reason) -> + Result + end. + +file_info(Filename) -> + file_info_result(file:read_file_info(Filename, [{time, posix}])). + +link_info(Filename) -> + file_info_result(file:read_link_info(Filename, [{time, posix}])). + +posix_result(Result) -> + case Result of + ok -> {ok, nil}; + {ok, Value} -> {ok, Value}; + {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} + end. + +read_file(Filename) -> + posix_result(file:read_file(Filename)). + +write_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents)). + +append_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents, [append])). + +delete_file(Filename) -> + posix_result(file:delete(Filename)). + +make_directory(Dir) -> + posix_result(file:make_dir(Dir)). + +list_directory(Dir) -> + case file:list_dir(Dir) of + {ok, Filenames} -> + {ok, [list_to_binary(Filename) || Filename <- Filenames]}; + {error, Reason} when ?is_posix_error(Reason) -> + {error, Reason} + end. + +delete_directory(Dir) -> + posix_result(file:del_dir(Dir)). + +recursive_delete(Dir) -> + posix_result(file:del_dir_r(Dir)). + +get_all_env() -> + BinVars = lists:map(fun(VarString) -> + [VarName, VarVal] = string:split(VarString, "="), + {list_to_binary(VarName), list_to_binary(VarVal)} + end, os:getenv()), + maps:from_list(BinVars). + +get_env(Name) -> + case os:getenv(binary_to_list(Name)) of + false -> {error, nil}; + Value -> {ok, list_to_binary(Value)} + end. + +set_env(Name, Value) -> + os:putenv(binary_to_list(Name), binary_to_list(Value)), + nil. + +unset_env(Name) -> + os:unsetenv(binary_to_list(Name)), + nil. + +os_family() -> + case os:type() of + {win32, nt} -> + windows_nt; + {unix, linux} -> + linux; + {unix, darwin} -> + darwin; + {unix, freebsd} -> + free_bsd; + {_, Other} -> + {other, atom_to_binary(Other, utf8)} + end. + +new_selector() -> + {selector, #{}}. + +map_selector({selector, Handlers}, Fn) -> + MappedHandlers = maps:map(fun(_Tag, Handler) -> + fun(Message) -> Fn(Handler(Message)) end + end, Handlers), + {selector, MappedHandlers}. + +merge_selector({selector, HandlersA}, {selector, HandlersB}) -> + {selector, maps:merge(HandlersA, HandlersB)}. + +insert_selector_handler({selector, Handlers}, Tag, Fn) -> + {selector, Handlers#{Tag => Fn}}. + +select(Selector) -> + {ok, Message} = select(Selector, infinity), + Message. + +select({selector, Handlers}, Timeout) -> + AnythingHandler = maps:get(anything, Handlers, undefined), + receive + % Monitored process down messages. + % This is special cased so we can selectively receive based on the + % reference as well as the record tag. + {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> + Fn = maps:get(Ref, Handlers), + {ok, Fn({process_down, Pid, Reason})}; + + Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> + Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), + {ok, Fn(Msg)}; + + Msg when AnythingHandler =/= undefined -> + {ok, AnythingHandler(Msg)} + after Timeout -> + {error, nil} + end. + +demonitor({_, Reference}) -> + erlang:demonitor(Reference, [flush]). + +link(Pid) -> + try + erlang:link(Pid) + catch + error:_ -> false + end. + +trap_exits(ShouldTrap) -> + erlang:process_flag(trap_exit, ShouldTrap), + nil. + +flush_messages() -> + receive _Message -> flush_messages() + after 0 -> nil + end. + +priv_directory(Name) -> + try erlang:binary_to_existing_atom(Name) of + Atom -> + case code:priv_dir(Atom) of + {error, _} -> {error, nil}; + Path -> {ok, unicode:characters_to_binary(Path)} + end + catch + error:badarg -> {error, nil} + end. + +connect_node(Node) -> + case net_kernel:connect_node(Node) of + true -> {ok, Node}; + false -> {error, failed_to_connect}; + ignored -> {error, local_node_is_not_alive} + end. + +register_process(Pid, Name) -> + try + true = erlang:register(Name, Pid), + {ok, nil} + catch + error:badarg -> {error, nil} + end. + +unregister_process(Name) -> + try + true = erlang:unregister(Name), + {ok, nil} + catch + error:badarg -> {error, nil} + end. + +process_named(Name) -> + case erlang:whereis(Name) of + Pid when is_pid(Pid) -> {ok, Pid}; + _ -> {error, nil} + end. + +identity(X) -> + X. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE new file mode 100644 index 00000000000..619ec77e6e1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2019, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md new file mode 100644 index 00000000000..3c313a1c8c9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md @@ -0,0 +1,91 @@ +# Gleam OTP + +GitHub release +Discord chat +![CI](https://github.com/gleam-lang/otp/workflows/test/badge.svg?branch=main) + +A Gleam library for building fault tolerant multi-core programs using the +actor model. It is compatible with Erlang's OTP framework. + +This library is experimental and will likely have many breaking changes in the +future! + +Gleam’s actor system is built with a few primary goals: + +- Full type safety of actors and messages. +- Be compatible with Erlang’s OTP actor framework. +- Provide fault tolerance and self-healing through supervisors. +- Have equivalent performance to Erlang’s OTP. + +This library documents its abstractions and functionality, but you may also wish +to read the documentation or other material on Erlang’s OTP framework to get a +fuller understanding of OTP, the problems it solves, and and the motivations for +its design. + +## Usage + +Add this library to your Gleam project. + +```shell +gleam add gleam_otp +``` + +## Actor hierarchy + +This library provides several different types of actor that can be used in +Gleam programs. + +### Process + +The process is the lowest level building block of OTP, all other actors are +built on top of processes either directly or indirectly. Typically this +abstraction would be not be used very often in Gleam applications, favour +other actor types that provide more functionality. + +Gleam's process module is defined in the `gleam_erlang` library. + +[[Documentation]](https://hexdocs.pm/gleam_erlang/gleam/erlang/process.html) + +### Actor + +The `actor` is the most commonly used process type in Gleam and serves as a good +building block for other abstractions. Like Erlang's `gen_server` it handles +OTP's system messages automatically to enable OTP's debugging and tracing +functionality. + +[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/actor.html) + +### Task + +A task is a kind of process that performs a single task and then shuts down. +Commonly tasks are used to convert sequential code into concurrent code by +performing computation in another process. + +[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/task.html) + +### Supervisor + +Supervisors is a process that starts and then supervises a group of processes, +restarting them if they crash. Supervisors can start other supervisors, +resulting in a hierarchical process structure called a supervision tree, +providing fault tolerance to a Gleam application. + +[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/supervisor.html) + +## Limitations and known issues + +This library is experimental there are some limitations that not yet been resolved. + +- There is no support for named processes. They are untyped global mutable + variables which may be uninitialized, more research is needed to find a + suitable type safe alternative. +- There are relatively few actor abstractions provided by this library. More + will be added in the future. +- Actors do not yet support all OTP system messages. Unsupported messages are + dropped. +- Supervisors do not yet support different shutdown periods per child. In + practice this means that children that are supervisors do not get an + unlimited amount of time to shut down, as is expected in Erlang or Elixir. +- This library has not seen much testing compared to the Erlang OTP + libraries, both in terms of unit tests and real world testing in + applications. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml new file mode 100644 index 00000000000..26e451baecf --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml @@ -0,0 +1,19 @@ +name = "gleam_otp" +version = "0.8.0" +licences = ["Apache-2.0"] +description = "Fault tolerant multicore Gleam programs with OTP" + +gleam = ">= 0.32.0" + +repository = { type = "github", user = "gleam-lang", repo = "otp" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[dependencies] +gleam_stdlib = "~> 0.32" +gleam_erlang = "~> 0.22" + +[dev-dependencies] +gleeunit = "~> 1.0" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl new file mode 100644 index 00000000000..85677d1b257 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl @@ -0,0 +1,4 @@ +-record(continue, { + state :: any(), + selector :: gleam@option:option(gleam@erlang@process:selector(any())) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl new file mode 100644 index 00000000000..75faa95149f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl @@ -0,0 +1 @@ +-record(ready, {state :: any(), selector :: gleam@erlang@process:selector(any())}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl new file mode 100644 index 00000000000..52874392c18 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl @@ -0,0 +1,5 @@ +-record(spec, { + init :: fun(() -> gleam@otp@actor:init_result(any(), any())), + init_timeout :: integer(), + loop :: fun((any(), any()) -> gleam@otp@actor:next(any(), any())) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl new file mode 100644 index 00000000000..3ed0b0122d4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl @@ -0,0 +1,5 @@ +-record(intensity_tracker, { + limit :: integer(), + period :: integer(), + events :: list(integer()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl new file mode 100644 index 00000000000..7afd07f0319 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl @@ -0,0 +1,5 @@ +-record(child_spec, { + start :: fun((any()) -> {ok, gleam@erlang@process:subject(any())} | + {error, gleam@otp@actor:start_error()}), + returning :: fun((any(), gleam@erlang@process:subject(any())) -> any()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl new file mode 100644 index 00000000000..b10bd9fa3f7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl @@ -0,0 +1,6 @@ +-record(spec, { + argument :: any(), + max_frequency :: integer(), + frequency_period :: integer(), + init :: fun((gleam@otp@supervisor:children(any())) -> gleam@otp@supervisor:children(any())) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl new file mode 100644 index 00000000000..99ab4cb7299 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl @@ -0,0 +1,7 @@ +-record(status_info, { + module :: gleam@erlang@atom:atom_(), + parent :: gleam@erlang@process:pid_(), + mode :: gleam@otp@system:mode(), + debug_state :: gleam@otp@system:debug_state(), + state :: gleam@dynamic:dynamic_() +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl new file mode 100644 index 00000000000..7c83874c276 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl @@ -0,0 +1 @@ +-record(exit, {reason :: gleam@dynamic:dynamic_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl new file mode 100644 index 00000000000..959bea8e9b9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl @@ -0,0 +1,6 @@ +-record(task, { + owner :: gleam@erlang@process:pid_(), + pid :: gleam@erlang@process:pid_(), + monitor :: gleam@erlang@process:process_monitor(), + selector :: gleam@erlang@process:selector(gleam@otp@task:message(any())) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam new file mode 100644 index 00000000000..9f6a6c41b06 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam @@ -0,0 +1,504 @@ +//// This module provides the _Actor_ abstraction, one of the most common +//// building blocks of Gleam OTP programs. +//// +//// An Actor is a process like any other BEAM process and can be be used to hold +//// state, execute code, and communicate with other processes by sending and +//// receiving messages. The advantage of using the actor abstraction over a bare +//// process is that it provides a single interface for commonly needed +//// functionality, including support for the [tracing and debugging +//// features in OTP](erlang-sys). +//// +//// Gleam's Actor is similar to Erlang's `gen_server` and Elixir's `GenServer` +//// but differs in that it offers a fully typed interface. This different API is +//// why Gleam uses the name Actor rather than some variation of generic-server. +//// +//// [erlang-sys]: https://www.erlang.org/doc/man/sys.html +//// +//// ## Example +//// +//// An Actor can be used to create a client-server interaction between an Actor +//// (the server) and other processes (the clients). In this example we have an +//// Actor that works as a stack, allowing clients to push and pop elements. +//// +//// ```gleam +//// pub fn main() { +//// // Start the actor with initial state of an empty list, and the +//// // `handle_message` callback function (defined below). +//// // We assert that it starts successfully. +//// // +//// // In real-world Gleam OTP programs we would likely write a wrapper functions +//// // called `start`, `push` `pop`, `shutdown` to start and interact with the +//// // Actor. We are not doing that here for the sake of showing how the Actor +//// // API works. +//// let assert Ok(actor) = actor.start([], handle_message) +//// +//// // We can send a message to the actor to push elements onto the stack. +//// process.send(actor, Push("Joe")) +//// process.send(actor, Push("Mike")) +//// process.send(actor, Push("Robert")) +//// +//// // The `Push` message expects no response, these messages are sent purely for +//// // the side effect of mutating the state held by the actor. +//// // +//// // We can also send the `Pop` message to take a value off of the actor's +//// // stack. This message expects a response, so we use `process.call` to send a +//// // message and wait until a reply is received. +//// // +//// // In this instance we are giving the actor 10 milliseconds to reply, if the +//// // `call` function doesn't get a reply within this time it will panic and +//// // crash the client process. +//// let assert Ok("Robert") = process.call(actor, Pop, 10) +//// let assert Ok("Mike") = process.call(actor, Pop, 10) +//// let assert Ok("Joe") = process.call(actor, Pop, 10) +//// +//// // The stack is now empty, so if we pop again the actor replies with an error. +//// let assert Error(Nil) = process.call(actor, Pop, 10) +//// +//// // Lastly, we can send a message to the actor asking it to shut down. +//// process.send(actor, Shutdown) +//// } +//// ``` +//// +//// Here is the code that is used to implement this actor: +//// +//// ```gleam +//// // First step of implementing the stack Actor is to define the message type that +//// // it can receive. +//// // +//// // The type of the elements in the stack is no fixed so a type parameter is used +//// // for it instead of a concrete type such as `String` or `Int`. +//// pub type Message(element) { +//// // The `Shutdown` message is used to tell the actor to stop. +//// // It is the simplest message type, it contains no data. +//// Shutdown +//// +//// // The `Push` message is used to add a new element to the stack. +//// // It contains the item to add, the type of which is the `element` +//// // parameterised type. +//// Push(push: element) +//// +//// // The `Pop` message is used to remove an element from the stack. +//// // It contains a `Subject`, which is used to send the response back to the +//// // message sender. In this case the reply is of type `Result(element, Nil)`. +//// Pop(reply_with: Subject(Result(element, Nil))) +//// } +//// +//// // The last part is to implement the `handle_message` callback function. +//// // +//// // This function is called by the Actor each for each message it receives. +//// // Actor is single threaded only does one thing at a time, so it handles +//// // messages sequentially and one at a time, in the order they are received. +//// // +//// // The function takes the message and the current state, and returns a data +//// // structure that indicates what to do next, along with the new state. +//// fn handle_message( +//// message: Message(e), +//// stack: List(e), +//// ) -> actor.Next(Message(e), List(e)) { +//// case message { +//// // For the `Shutdown` message we return the `actor.Stop` value, which causes +//// // the actor to discard any remaining messages and stop. +//// Shutdown -> actor.Stop(process.Normal) +//// +//// // For the `Push` message we add the new element to the stack and return +//// // `actor.continue` with this new stack, causing the actor to process any +//// // queued messages or wait for more. +//// Push(value) -> { +//// let new_state = [value, ..stack] +//// actor.continue(new_state) +//// } +//// +//// // For the `Pop` message we attempt to remove an element from the stack, +//// // sending it or an error back to the caller, before continuing. +//// Pop(client) -> +//// case stack { +//// [] -> { +//// // When the stack is empty we can't pop an element, so we send an +//// // error back. +//// process.send(client, Error(Nil)) +//// actor.continue([]) +//// } +//// +//// [first, ..rest] -> { +//// // Otherwise we send the first element back and use the remaining +//// // elements as the new state. +//// process.send(client, Ok(first)) +//// actor.continue(rest) +//// } +//// } +//// } +//// } +//// ``` + +import gleam/erlang/process.{ + type ExitReason, type Pid, type Selector, type Subject, Abnormal, +} +import gleam/erlang/charlist.{type Charlist} +import gleam/otp/system.{ + type DebugState, type Mode, type StatusInfo, type SystemMessage, GetState, + GetStatus, Resume, Running, StatusInfo, Suspend, Suspended, +} +import gleam/string +import gleam/dynamic.{type Dynamic} +import gleam/erlang/atom +import gleam/option.{type Option, None, Some} + +type Message(message) { + /// A regular message excepted by the process + Message(message) + + /// An OTP system message, for debugging or maintenance + System(SystemMessage) + + /// An unexpected message + Unexpected(Dynamic) +} + +/// The type used to indicate what to do after handling a message. +/// +pub type Next(message, state) { + /// Continue handling messages. + /// + Continue(state: state, selector: Option(Selector(message))) + + /// Stop handling messages and shut down. + /// + Stop(ExitReason) +} + +pub fn continue(state: state) -> Next(message, state) { + Continue(state, None) +} + +pub fn with_selector( + value: Next(message, state), + selector: Selector(message), +) -> Next(message, state) { + case value { + Continue(state, _) -> Continue(state, Some(selector)) + _ -> value + } +} + +/// The type used to indicate whether an actor has started successfully or not. +/// +pub type InitResult(state, message) { + /// The actor has successfully initialised. The actor can start handling + /// messages and actor's channel sender can be returned to the parent + /// process. + /// + Ready(state: state, selector: Selector(message)) + + /// The actor has failed to initialise. The actor shuts down and an error is + /// returned to the parent process. + /// + Failed(String) +} + +type Self(state, msg) { + Self( + mode: Mode, + parent: Pid, + state: state, + subject: Subject(msg), + selector: Selector(Message(msg)), + debug_state: DebugState, + message_handler: fn(msg, state) -> Next(msg, state), + ) +} + +/// This data structure holds all the values required by the `start_spec` +/// function in order to create an actor. +/// +/// If you do not need to configure the initialisation behaviour of your actor +/// consider using the `start` function. +/// +pub type Spec(state, msg) { + Spec( + /// The initialisation functionality for the actor. This function is called + /// just after the actor starts but before the channel sender is returned + /// to the parent. + /// + /// This function is used to ensure that any required data or state is + /// correct. If this function returns an error it means that the actor has + /// failed to start and an error is returned to the parent. + /// + init: fn() -> InitResult(state, msg), + /// How many milliseconds the `init` function has to return before it is + /// considered to have taken too long and failed. + /// + init_timeout: Int, + /// This function is called to handle each message that the actor receives. + /// + loop: fn(msg, state) -> Next(msg, state), + ) +} + +// TODO: Check needed functionality here to be OTP compatible +fn exit_process(reason: ExitReason) -> ExitReason { + // TODO + reason +} + +fn receive_message(self: Self(state, msg)) -> Message(msg) { + let selector = case self.mode { + // When suspended we only respond to system messages + Suspended -> + process.new_selector() + |> selecting_system_messages + + // When running we respond to all messages + Running -> + // We add the handler for unexpected messages first so that the user + // supplied selector can override it if desired + process.new_selector() + |> process.selecting_anything(Unexpected) + |> process.merge_selector(self.selector) + |> selecting_system_messages + } + + process.select_forever(selector) +} + +fn selecting_system_messages( + selector: Selector(Message(msg)), +) -> Selector(Message(msg)) { + selector + |> process.selecting_record3( + atom.create_from_string("system"), + convert_system_message, + ) +} + +@external(erlang, "gleam_otp_external", "convert_system_message") +fn convert_system_message(a: Dynamic, b: Dynamic) -> Message(msg) + +fn process_status_info(self: Self(state, msg)) -> StatusInfo { + StatusInfo( + module: atom.create_from_string("gleam@otp@actor"), + parent: self.parent, + mode: self.mode, + debug_state: self.debug_state, + state: dynamic.from(self.state), + ) +} + +fn loop(self: Self(state, msg)) -> ExitReason { + case receive_message(self) { + System(system) -> + case system { + GetState(callback) -> { + callback(dynamic.from(self.state)) + loop(self) + } + Resume(callback) -> { + callback() + loop(Self(..self, mode: Running)) + } + Suspend(callback) -> { + callback() + loop(Self(..self, mode: Suspended)) + } + GetStatus(callback) -> { + callback(process_status_info(self)) + loop(self) + } + } + + Unexpected(message) -> { + log_warning( + charlist.from_string("Actor discarding unexpected message: ~s"), + [charlist.from_string(string.inspect(message))], + ) + loop(self) + } + + Message(msg) -> + case self.message_handler(msg, self.state) { + Stop(reason) -> exit_process(reason) + Continue(state: state, selector: new_selector) -> { + let selector = + new_selector + |> option.map(init_selector(self.subject, _)) + |> option.unwrap(self.selector) + loop(Self(..self, state: state, selector: selector)) + } + } + } +} + +// TODO: replace this when we have Gleam bindings to the logger +@external(erlang, "logger", "warning") +fn log_warning(a: Charlist, b: List(Charlist)) -> Nil + +fn initialise_actor( + spec: Spec(state, msg), + ack: Subject(Result(Subject(msg), ExitReason)), +) { + let subject = process.new_subject() + case spec.init() { + Ready(state, selector) -> { + let selector = init_selector(subject, selector) + // Signal to parent that the process has initialised successfully + process.send(ack, Ok(subject)) + // Start message receive loop + let self = + Self( + state: state, + parent: process.subject_owner(ack), + subject: subject, + selector: selector, + message_handler: spec.loop, + debug_state: system.debug_state([]), + mode: Running, + ) + loop(self) + } + + Failed(reason) -> { + process.send(ack, Error(Abnormal(reason))) + exit_process(Abnormal(reason)) + } + } +} + +fn init_selector(subject, selector) { + process.new_selector() + |> process.selecting(subject, Message) + |> process.merge_selector(process.map_selector(selector, Message)) +} + +pub type StartError { + InitTimeout + InitFailed(ExitReason) + InitCrashed(Dynamic) +} + +/// The result of starting a Gleam actor. +/// +/// This type is compatible with Gleam supervisors. If you wish to convert it +/// to a type compatible with Erlang supervisors see the `ErlangStartResult` +/// type and `erlang_start_result` function. +/// +pub type StartResult(msg) = + Result(Subject(msg), StartError) + +/// An Erlang supervisor compatible process start result. +/// +/// If you wish to convert this into a `StartResult` compatible with Gleam +/// supervisors see the `from_erlang_start_result` and `wrap_erlang_starter` +/// functions. +/// +pub type ErlangStartResult = + Result(Pid, Dynamic) + +/// Convert a Gleam actor start result into an Erlang supervisor compatible +/// process start result. +/// +pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { + case res { + Ok(x) -> Ok(process.subject_owner(x)) + Error(x) -> Error(dynamic.from(x)) + } +} + +type StartInitMessage(msg) { + Ack(Result(Subject(msg), ExitReason)) + Mon(process.ProcessDown) +} + +// TODO: test init_timeout. Currently if we test it eunit prints an error from +// the process death. How do we avoid this? +// +/// Start an actor from a given specification. If the actor's `init` function +/// returns an error or does not return within `init_timeout` then an error is +/// returned. +/// +/// If you do not need to specify the initialisation behaviour of your actor +/// consider using the `start` function. +/// +pub fn start_spec(spec: Spec(state, msg)) -> Result(Subject(msg), StartError) { + let ack_subject = process.new_subject() + + let child = + process.start( + linked: True, + running: fn() { initialise_actor(spec, ack_subject) }, + ) + + let monitor = process.monitor_process(child) + let selector = + process.new_selector() + |> process.selecting(ack_subject, Ack) + |> process.selecting_process_down(monitor, Mon) + + let result = case process.select(selector, spec.init_timeout) { + // Child started OK + Ok(Ack(Ok(channel))) -> Ok(channel) + + // Child initialiser returned an error + Ok(Ack(Error(reason))) -> Error(InitFailed(reason)) + + // Child went down while initialising + Ok(Mon(down)) -> Error(InitCrashed(down.reason)) + + // Child did not finish initialising in time + Error(Nil) -> { + process.kill(child) + Error(InitTimeout) + } + } + + // Remove the monitor used for the starting of the actor as to avoid an extra + // message arriving at the parent if the child dies later. + process.demonitor_process(monitor) + + result +} + +/// Start an actor with a given initial state and message handling loop +/// function. +/// +/// This function returns a `Result` but it will always be `Ok` so it is safe +/// to use with `assert` if you are not starting this actor as part of a +/// supervision tree. +/// +/// If you wish to configure the initialisation behaviour of a new actor see +/// the `Spec` record and the `start_spec` function. +/// +pub fn start( + state: state, + loop: fn(msg, state) -> Next(msg, state), +) -> Result(Subject(msg), StartError) { + start_spec(Spec( + init: fn() { Ready(state, process.new_selector()) }, + loop: loop, + init_timeout: 5000, + )) +} + +/// Send a message over a given channel. +/// +/// This is a re-export of `process.send`, for the sake of convenience. +/// +pub fn send(subject: Subject(msg), msg: msg) -> Nil { + process.send(subject, msg) +} + +// TODO: test +/// Send a synchronous message and wait for a response from the receiving +/// process. +/// +/// If a reply is not received within the given timeout then the sender process +/// crashes. If you wish receive a `Result` rather than crashing see the +/// `process.try_call` function. +/// +/// This is a re-export of `process.call`, for the sake of convenience. +/// +pub fn call( + selector: Subject(message), + make_message: fn(Subject(reply)) -> message, + timeout: Int, +) -> reply { + process.call(selector, make_message, timeout) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam new file mode 100644 index 00000000000..2044be09787 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam @@ -0,0 +1,46 @@ +//// The intensity tracker is used to monitor how frequently an event happens, +//// erroring if it happens too many times within a period of time. + +import gleam/list + +// TODO: test +pub opaque type IntensityTracker { + IntensityTracker(limit: Int, period: Int, events: List(Int)) +} + +pub type TooIntense { + TooIntense +} + +pub fn new(limit limit: Int, period period: Int) -> IntensityTracker { + IntensityTracker(limit: limit, period: period, events: []) +} + +@external(erlang, "erlang", "monotonic_time") +fn monotonic_time(a: Int) -> Int + +fn now_seconds() -> Int { + monotonic_time(1) +} + +pub fn trim_window(events: List(Int), now: Int, period: Int) -> List(Int) { + case events { + [] -> [] + [event, ..events] -> + case now >= event + period { + True -> [event, ..trim_window(events, now, period)] + False -> [] + } + } +} + +pub fn add_event( + tracker: IntensityTracker, +) -> Result(IntensityTracker, TooIntense) { + let now = now_seconds() + let events = trim_window([now, ..tracker.events], now, tracker.period) + case list.length(events) >= tracker.limit { + True -> Error(TooIntense) + False -> Ok(IntensityTracker(..tracker, events: events)) + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam new file mode 100644 index 00000000000..4e1b4d81285 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam @@ -0,0 +1,9 @@ +/// Ports are how code running on the Erlang virtual machine interacts with +/// the outside world. Bytes of data can be sent to and read from ports, +/// providing a form of message passing to an external program or resource. +/// +/// For more information on ports see the [Erlang ports documentation][1]. +/// +/// [1]: https://erlang.org/doc/reference_manual/ports.html +/// +pub type Port diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam new file mode 100644 index 00000000000..b99ad8efb82 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam @@ -0,0 +1,410 @@ +// TODO: specify amount of time permitted for shut-down +import gleam/result +import gleam/string +import gleam/option.{type Option, None, Some} +import gleam/erlang/process.{type Pid, type Subject} +import gleam/otp/actor.{type StartError} +import gleam/otp/intensity_tracker.{type IntensityTracker} +import gleam/erlang/node.{type Node} + +/// This data structure holds all the values required by the `start_spec` +/// function in order to create an supervisor. +/// +/// If you do not need to configure the behaviour of your supervisor consider +/// using the `start` function. +/// +pub type Spec(argument, return) { + Spec( + argument: argument, + max_frequency: Int, + frequency_period: Int, + init: fn(Children(argument)) -> Children(return), + ) +} + +/// This type represents the starting children of a supervisor within the +/// `init` function. +/// +pub opaque type Children(argument) { + Ready(Starter(argument)) + Failed(ChildStartError) +} + +/// This type contains all the information required to start a new child and +/// add it to the `Children`. +/// +/// This is typically created with the `worker` function. +/// +pub opaque type ChildSpec(msg, argument, returning) { + ChildSpec( + // TODO: merge this into one field + start: fn(argument) -> Result(Subject(msg), StartError), + returning: fn(argument, Subject(msg)) -> returning, + ) +} + +type ChildStartError { + ChildStartError(previous_pid: Option(Pid), error: StartError) +} + +pub opaque type Message { + Exit(process.ExitMessage) + RetryRestart(Pid) +} + +type Instruction { + StartAll + StartFrom(Pid) +} + +type State(a) { + State( + restarts: IntensityTracker, + starter: Starter(a), + retry_restarts: Subject(Pid), + ) +} + +type Starter(argument) { + Starter( + argument: argument, + exec: Option( + fn(Instruction) -> + Result(#(Starter(argument), Instruction), ChildStartError), + ), + ) +} + +type Child(argument) { + Child(pid: Pid, argument: argument) +} + +fn start_child( + child_spec: ChildSpec(msg, argument_in, argument_out), + argument: argument_in, +) -> Result(Child(argument_out), ChildStartError) { + use subject <- result.then( + child_spec.start(argument) + |> result.map_error(ChildStartError(None, _)), + ) + + Ok(Child( + pid: process.subject_owner(subject), + // Merge the new child's pid into the argument to produce the new argument + // used to start any remaining children. + argument: child_spec.returning(argument, subject), + )) +} + +// TODO: more sophsiticated stopping of processes. i.e. give supervisors +// more time to shut down. +fn shutdown_child(pid: Pid, _spec: ChildSpec(msg, arg_1, arg_2)) -> Nil { + process.send_exit(pid) +} + +fn perform_instruction_for_child( + argument: argument_in, + instruction: Instruction, + child_spec: ChildSpec(msg, argument_in, argument_out), + child: Child(argument_out), +) -> Result(#(Child(argument_out), Instruction), ChildStartError) { + let current = child.pid + case instruction { + // This child is older than the StartFrom target, we don't need to + // restart it + StartFrom(target) if target != current -> Ok(#(child, instruction)) + + // This pid either is the cause of the problem, or we have the StartAll + // instruction. Either way it and its younger siblings need to be restarted. + _ -> { + shutdown_child(current, child_spec) + use child <- result.then(start_child(child_spec, argument)) + Ok(#(child, StartAll)) + } + } +} + +fn add_child_to_starter( + starter: Starter(argument_in), + child_spec: ChildSpec(msg, argument_in, argument_out), + child: Child(argument_out), +) -> Starter(argument_out) { + let starter = fn(instruction) { + // Restart the older children. We use `try` to return early if the older + // children failed to start + use #(starter, instruction) <- result.then(case starter.exec { + Some(start) -> start(instruction) + None -> Ok(#(starter, instruction)) + }) + + // Perform the instruction, restarting the child as required + use #(child, instruction) <- result.then(perform_instruction_for_child( + starter.argument, + instruction, + child_spec, + child, + )) + + // Create a new starter for the next time the supervisor needs to restart + let starter = add_child_to_starter(starter, child_spec, child) + + Ok(#(starter, instruction)) + } + + Starter(exec: Some(starter), argument: child.argument) +} + +fn start_and_add_child( + state: Starter(argument_0), + child_spec: ChildSpec(msg, argument_0, argument_1), +) -> Children(argument_1) { + case start_child(child_spec, state.argument) { + Ok(child) -> Ready(add_child_to_starter(state, child_spec, child)) + Error(reason) -> Failed(reason) + } +} + +/// Add a child to the collection of children of the supervisor +/// +/// This function starts the child from the child spec. +/// +pub fn add( + children: Children(argument), + child_spec: ChildSpec(msg, argument, new_argument), +) -> Children(new_argument) { + case children { + // If one of the previous children has failed then we cannot continue + Failed(fail) -> Failed(fail) + + // If everything is OK so far then we can add the child + Ready(state) -> start_and_add_child(state, child_spec) + } +} + +// TODO: test +// TODO: unlimitd shut down duration +/// Prepare a new supervisor type child. +/// +/// If you wish to prepare a new non-supervisor type child see the `worker` +/// function. +/// +/// If you wish to change the type of the argument for later children see the +/// `returning` function. +/// +/// Note: Gleam supervisors do not yet support different shutdown periods per +/// child so this function is currently identical in behaviour to `worker`. It is +/// recommended to use this function for supervisor children nevertheless so the +/// correct shut down behaviour is used in later releases of this library. +/// +pub fn supervisor( + start: fn(argument) -> Result(Subject(msg), StartError), +) -> ChildSpec(msg, argument, argument) { + ChildSpec(start: start, returning: fn(argument, _channel) { argument }) +} + +/// Prepare a new worker type child. +/// +/// If you wish to prepare a new supervisor type child see the `supervisor` +/// function. +/// +/// If you wish to change the type of the argument for later children see the +/// `returning` function. +/// +pub fn worker( + start: fn(argument) -> Result(Subject(msg), StartError), +) -> ChildSpec(msg, argument, argument) { + ChildSpec(start: start, returning: fn(argument, _channel) { argument }) +} + +// TODO: test +/// As each child is added to a supervisors children a new argument is prepared +/// with which to start the next child. By default argument is the same as the +/// previous argument, but this function can be used to change it to something +/// else by passing a function that takes the previous argument and the sender +/// of the previous child. +/// +pub fn returning( + child: ChildSpec(msg, argument_a, argument_b), + updater: fn(argument_a, Subject(msg)) -> argument_c, +) -> ChildSpec(msg, argument_a, argument_c) { + ChildSpec(start: child.start, returning: updater) +} + +fn init( + spec: Spec(argument, return), +) -> actor.InitResult(State(return), Message) { + // Create a subject so that we can asynchronously retry restarting when we + // fail to bring an exited child + let retry = process.new_subject() + + // Trap exits so that we get a message when a child crashes + process.trap_exits(True) + + // Combine selectors + let selector = + process.new_selector() + |> process.selecting(retry, RetryRestart) + |> process.selecting_trapped_exits(Exit) + + // Start any children + let result = + Starter(argument: spec.argument, exec: None) + |> Ready + |> spec.init + + // Pass back up the result + case result { + Ready(starter) -> { + let restarts = + intensity_tracker.new( + limit: spec.max_frequency, + period: spec.frequency_period, + ) + let state = + State(starter: starter, restarts: restarts, retry_restarts: retry) + actor.Ready(state, selector) + } + + Failed(error) -> + actor.Failed(case error.error { + actor.InitTimeout -> "Child initialisation timed out" + actor.InitCrashed(reason) -> + string.append( + "Child crashed during initialisation: ", + string.inspect(reason), + ) + actor.InitFailed(reason) -> + string.append( + "Child failed to start during initialisation: ", + string.inspect(reason), + ) + }) + } +} + +type HandleExitError { + RestartFailed(pid: Pid, restarts: IntensityTracker) + TooManyRestarts +} + +fn handle_exit(pid: Pid, state: State(a)) -> actor.Next(Message, State(a)) { + let outcome = { + // If we are handling an exit then we must have some children + let assert Some(start) = state.starter.exec + + // Check to see if there has been too many restarts in this period + use restarts <- result.then( + state.restarts + |> intensity_tracker.add_event + |> result.map_error(fn(_) { TooManyRestarts }), + ) + + // Restart the exited child and any following children + use #(starter, _) <- result.then( + start(StartFrom(pid)) + |> result.map_error(fn(e: ChildStartError) { + RestartFailed(option.unwrap(e.previous_pid, pid), restarts) + }), + ) + + Ok(State(..state, starter: starter, restarts: restarts)) + } + + case outcome { + Ok(state) -> actor.continue(state) + Error(RestartFailed(failed_child, restarts)) -> { + // Asynchronously enqueue the restarting of this child again as we were + // unable to restart them this time. We do this asynchronously as we want + // to have a chance to handle any system messages that have come in. + process.send(state.retry_restarts, failed_child) + let state = State(..state, restarts: restarts) + actor.continue(state) + } + Error(TooManyRestarts) -> + actor.Stop(process.Abnormal( + "Child processes restarted too many times within allowed period", + )) + } +} + +fn loop( + message: Message, + state: State(argument), +) -> actor.Next(Message, State(argument)) { + case message { + Exit(exit_message) -> handle_exit(exit_message.pid, state) + RetryRestart(pid) -> handle_exit(pid, state) + } +} + +/// Start a supervisor from a given specification. +/// +pub fn start_spec(spec: Spec(a, b)) -> Result(Subject(Message), StartError) { + actor.start_spec(actor.Spec( + init: fn() { init(spec) }, + loop: loop, + init_timeout: 60_000, + )) +} + +/// Start a supervisor from a given `init` function. +/// +/// The init argument passed to children will be `Nil` and the maximum restart +/// intensity will be 1 restart per 5 seconds (the same as the default for +/// [Erlang supervisors][erl-sup]). If you wish to specify these values, see +/// the `start_spec` function and the `Spec` type. +/// +/// [erl-sup]: https://www.erlang.org/doc/design_principles/sup_princ.html#maximum-restart-intensity +/// +pub fn start( + init: fn(Children(Nil)) -> Children(a), +) -> Result(Subject(Message), StartError) { + start_spec(Spec( + init: init, + argument: Nil, + max_frequency: 1, + frequency_period: 5, + )) +} + +/// A type used to describe the situation in which an Erlang based application +/// is starting. +/// +/// For more information see the [Erlang distributed application +/// documentation][1] and the Learn Your Some Erlang chapter on [distributed +/// applications][2]. +/// +/// [1]: https://erlang.org/doc/design_principles/distributed_applications.html +/// [2]: https://learnyousomeerlang.com/distributed-otp-applications +/// +pub type ApplicationStartMode { + Normal + Takeover(Node) + Failover(Node) +} + +pub type ApplicationStop + +@external(erlang, "gleam_otp_external", "application_stopped") +pub fn application_stopped() -> ApplicationStop + +/// The result of starting a Gleam actor. +/// +/// This type is compatible with Gleam supervisors. If you wish to convert it +/// to a type compatible with Erlang supervisors see the `ErlangStartResult` +/// type and `erlang_start_result` function. +/// +pub type StartResult(msg) = + actor.StartResult(msg) + +/// An Erlang supervisor compatible process start result. +/// +pub type ErlangStartResult = + actor.ErlangStartResult + +/// Convert a Gleam actor start result into an Erlang supervisor compatible +/// process start result. +/// +pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { + actor.to_erlang_start_result(res) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam new file mode 100644 index 00000000000..c05646baa26 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam @@ -0,0 +1,89 @@ +import gleam/dynamic.{type Dynamic} +import gleam/erlang/atom.{type Atom} +import gleam/erlang/process.{type Pid} + +pub type Mode { + Running + Suspended +} + +pub type DebugOption { + NoDebug +} + +pub type DebugState + +@external(erlang, "sys", "debug_options") +pub fn debug_state(a: List(DebugOption)) -> DebugState + +pub type StatusInfo { + StatusInfo( + module: Atom, + parent: Pid, + mode: Mode, + debug_state: DebugState, + state: Dynamic, + ) +} + +// TODO: document +// TODO: implement remaining messages +pub type SystemMessage { + // {replace_state, StateFn} + // {change_code, Mod, Vsn, Extra} + // {terminate, Reason} + // {debug, {log, Flag}} + // {debug, {trace, Flag}} + // {debug, {log_to_file, FileName}} + // {debug, {statistics, Flag}} + // {debug, no_debug} + // {debug, {install, {Func, FuncState}}} + // {debug, {install, {FuncId, Func, FuncState}}} + // {debug, {remove, FuncOrId}} + Resume(fn() -> Nil) + Suspend(fn() -> Nil) + GetState(fn(Dynamic) -> Nil) + GetStatus(fn(StatusInfo) -> Nil) +} + +type DoNotLeak + +/// Get the state of a given OTP compatible process. This function is only +/// intended for debugging. +/// +/// For more information see the [Erlang documentation][1]. +/// +/// [1]: https://erlang.org/doc/man/sys.html#get_state-1 +/// +@external(erlang, "sys", "get_state") +pub fn get_state(from from: Pid) -> Dynamic + +@external(erlang, "sys", "suspend") +fn erl_suspend(a: Pid) -> DoNotLeak + +/// Request an OTP compatible process to suspend, causing it to only handle +/// system messages. +/// +/// For more information see the [Erlang documentation][1]. +/// +/// [1]: https://erlang.org/doc/man/sys.html#suspend-1 +/// +pub fn suspend(pid: Pid) -> Nil { + erl_suspend(pid) + Nil +} + +@external(erlang, "sys", "resume") +fn erl_resume(from from: Pid) -> DoNotLeak + +/// Request a suspended OTP compatible process to result, causing it to handle +/// all messages rather than only system messages. +/// +/// For more information see the [Erlang documentation][1]. +/// +/// [1]: https://erlang.org/doc/man/sys.html#resume-1 +/// +pub fn resume(pid: Pid) -> Nil { + erl_resume(pid) + Nil +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam new file mode 100644 index 00000000000..b2b2c5c968e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam @@ -0,0 +1,151 @@ +//// A task is a kind of process that performs a single task and then shuts +//// down. Commonly tasks are used to convert sequential code into concurrent +//// code by performing computation in another process. +//// +//// let task = task.async(fn() { do_some_work() }) +//// let value = do_some_other_work() +//// value + task.await(task, 100) +//// +//// Tasks spawned with async can be awaited on by their caller process (and +//// only their caller) as shown in the example above. They are implemented by +//// spawning a process that sends a message to the caller once the given +//// computation is performed. +//// +//// There are two important things to consider when using `async`: +//// +//// 1. If you are using async tasks, you must await a reply as they are always +//// sent. +//// +//// 2. async tasks link the caller and the spawned process. This means that, +//// if the caller crashes, the task will crash too and vice-versa. This is +//// on purpose: if the process meant to receive the result no longer +//// exists, there is no purpose in completing the computation. +//// +//// This module is inspired by Elixir's [Task module][1]. +//// +//// [1]: https://hexdocs.pm/elixir/master/Task.html +//// + +// TODO: await_many +import gleam/erlang/process.{type Pid, type ProcessMonitor, type Selector} +import gleam/dynamic.{type Dynamic} + +pub opaque type Task(value) { + Task( + owner: Pid, + pid: Pid, + monitor: ProcessMonitor, + selector: Selector(Message(value)), + ) +} + +// TODO: test +/// Spawn a task process that calls a given function in order to perform some +/// work. The result of this function is send back to the parent and can be +/// received using the `await` function. +/// +/// See the top level module documentation for more information on async/await. +/// +pub fn async(work: fn() -> value) -> Task(value) { + let owner = process.self() + let subject = process.new_subject() + let pid = + process.start(linked: True, running: fn() { process.send(subject, work()) }) + let monitor = process.monitor_process(pid) + let selector = + process.new_selector() + |> process.selecting_process_down(monitor, FromMonitor) + |> process.selecting(subject, FromSubject) + Task(owner: owner, pid: pid, monitor: monitor, selector: selector) +} + +pub type AwaitError { + Timeout + Exit(reason: Dynamic) +} + +// We can only wait on a task if we are the owner of it so crash if we are +// waiting on a task we don't own. +fn assert_owner(task: Task(a)) -> Nil { + let self = process.self() + case task.owner == self { + True -> Nil + False -> + process.send_abnormal_exit( + self, + "awaited on a task that does not belong to this process", + ) + } +} + +type Message(value) { + FromMonitor(process.ProcessDown) + FromSubject(value) +} + +// TODO: test +/// Wait for the value computed by a task. +/// +/// If the a value is not received before the timeout has elapsed or if the +/// task process crashes then an error is returned. +/// +pub fn try_await(task: Task(value), timeout: Int) -> Result(value, AwaitError) { + assert_owner(task) + case process.select(task.selector, timeout) { + // The task process has sent back a value + Ok(FromSubject(x)) -> { + process.demonitor_process(task.monitor) + Ok(x) + } + + // The task process crashed without sending a value + Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) -> + Error(Exit(reason)) + + // The task process is alive but has not sent a value yet + Error(Nil) -> Error(Timeout) + } +} + +// TODO: test +/// Wait for the value computed by a task. +/// +/// If the a value is not received before the timeout has elapsed or if the +/// task process crashes then this function crashes. +/// +pub fn await(task: Task(value), timeout: Int) -> value { + let assert Ok(value) = try_await(task, timeout) + value +} + +/// Wait endlessly for the value computed by a task. +/// +/// Be Careful! This function does not return until there is a value to +/// receive. If a value is not received then the process will be stuck waiting +/// forever. +/// +pub fn try_await_forever(task: Task(value)) -> Result(value, AwaitError) { + assert_owner(task) + case process.select_forever(task.selector) { + // The task process has sent back a value + FromSubject(x) -> { + process.demonitor_process(task.monitor) + Ok(x) + } + + // The task process crashed without sending a value + FromMonitor(process.ProcessDown(reason: reason, ..)) -> Error(Exit(reason)) + } +} + +/// Wait endlessly for the value computed by a task. +/// +/// Be Careful! Like `try_await_forever`, this function does not return until there is a value to +/// receive. +/// +/// If the task process crashes then this function crashes. +/// +pub fn await_forever(task: Task(value)) -> value { + let assert Ok(value) = try_await_forever(task) + value +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl new file mode 100644 index 00000000000..0606147ca13 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl @@ -0,0 +1,273 @@ +-module(gleam@otp@actor). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([continue/1, with_selector/2, to_erlang_start_result/1, start_spec/1, start/2, send/2, call/3]). +-export_type([message/1, next/2, init_result/2, self/2, spec/2, start_error/0, start_init_message/1]). + +-type message(GAS) :: {message, GAS} | + {system, gleam@otp@system:system_message()} | + {unexpected, gleam@dynamic:dynamic_()}. + +-type next(GAT, GAU) :: {continue, + GAU, + gleam@option:option(gleam@erlang@process:selector(GAT))} | + {stop, gleam@erlang@process:exit_reason()}. + +-type init_result(GAV, GAW) :: {ready, GAV, gleam@erlang@process:selector(GAW)} | + {failed, binary()}. + +-type self(GAX, GAY) :: {self, + gleam@otp@system:mode(), + gleam@erlang@process:pid_(), + GAX, + gleam@erlang@process:subject(GAY), + gleam@erlang@process:selector(message(GAY)), + gleam@otp@system:debug_state(), + fun((GAY, GAX) -> next(GAY, GAX))}. + +-type spec(GAZ, GBA) :: {spec, + fun(() -> init_result(GAZ, GBA)), + integer(), + fun((GBA, GAZ) -> next(GBA, GAZ))}. + +-type start_error() :: init_timeout | + {init_failed, gleam@erlang@process:exit_reason()} | + {init_crashed, gleam@dynamic:dynamic_()}. + +-type start_init_message(GBB) :: {ack, + {ok, gleam@erlang@process:subject(GBB)} | + {error, gleam@erlang@process:exit_reason()}} | + {mon, gleam@erlang@process:process_down()}. + +-spec continue(GBI) -> next(any(), GBI). +continue(State) -> + {continue, State, none}. + +-spec with_selector(next(GBM, GBN), gleam@erlang@process:selector(GBM)) -> next(GBM, GBN). +with_selector(Value, Selector) -> + case Value of + {continue, State, _} -> + {continue, State, {some, Selector}}; + + _ -> + Value + end. + +-spec exit_process(gleam@erlang@process:exit_reason()) -> gleam@erlang@process:exit_reason(). +exit_process(Reason) -> + Reason. + +-spec selecting_system_messages(gleam@erlang@process:selector(message(GBY))) -> gleam@erlang@process:selector(message(GBY)). +selecting_system_messages(Selector) -> + _pipe = Selector, + gleam@erlang@process:selecting_record3( + _pipe, + erlang:binary_to_atom(<<"system"/utf8>>), + fun gleam_otp_external:convert_system_message/2 + ). + +-spec receive_message(self(any(), GBU)) -> message(GBU). +receive_message(Self) -> + Selector = case erlang:element(2, Self) of + suspended -> + _pipe = gleam_erlang_ffi:new_selector(), + selecting_system_messages(_pipe); + + running -> + _pipe@1 = gleam_erlang_ffi:new_selector(), + _pipe@2 = gleam@erlang@process:selecting_anything( + _pipe@1, + fun(Field@0) -> {unexpected, Field@0} end + ), + _pipe@3 = gleam_erlang_ffi:merge_selector( + _pipe@2, + erlang:element(6, Self) + ), + selecting_system_messages(_pipe@3) + end, + gleam_erlang_ffi:select(Selector). + +-spec process_status_info(self(any(), any())) -> gleam@otp@system:status_info(). +process_status_info(Self) -> + {status_info, + erlang:binary_to_atom(<<"gleam@otp@actor"/utf8>>), + erlang:element(3, Self), + erlang:element(2, Self), + erlang:element(7, Self), + gleam@dynamic:from(erlang:element(4, Self))}. + +-spec init_selector( + gleam@erlang@process:subject(GGN), + gleam@erlang@process:selector(GGN) +) -> gleam@erlang@process:selector(message(GGN)). +init_selector(Subject, Selector) -> + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Subject, + fun(Field@0) -> {message, Field@0} end + ), + gleam_erlang_ffi:merge_selector( + _pipe@1, + gleam_erlang_ffi:map_selector( + Selector, + fun(Field@0) -> {message, Field@0} end + ) + ). + +-spec loop(self(any(), any())) -> gleam@erlang@process:exit_reason(). +loop(Self) -> + case receive_message(Self) of + {system, System} -> + case System of + {get_state, Callback} -> + Callback(gleam@dynamic:from(erlang:element(4, Self))), + loop(Self); + + {resume, Callback@1} -> + Callback@1(), + loop(erlang:setelement(2, Self, running)); + + {suspend, Callback@2} -> + Callback@2(), + loop(erlang:setelement(2, Self, suspended)); + + {get_status, Callback@3} -> + Callback@3(process_status_info(Self)), + loop(Self) + end; + + {unexpected, Message} -> + logger:warning( + unicode:characters_to_list( + <<"Actor discarding unexpected message: ~s"/utf8>> + ), + [unicode:characters_to_list(gleam@string:inspect(Message))] + ), + loop(Self); + + {message, Msg} -> + case (erlang:element(8, Self))(Msg, erlang:element(4, Self)) of + {stop, Reason} -> + exit_process(Reason); + + {continue, State, New_selector} -> + Selector = begin + _pipe = New_selector, + _pipe@1 = gleam@option:map( + _pipe, + fun(_capture) -> + init_selector(erlang:element(5, Self), _capture) + end + ), + gleam@option:unwrap(_pipe@1, erlang:element(6, Self)) + end, + loop( + erlang:setelement( + 6, + erlang:setelement(4, Self, State), + Selector + ) + ) + end + end. + +-spec initialise_actor( + spec(any(), GCP), + gleam@erlang@process:subject({ok, gleam@erlang@process:subject(GCP)} | + {error, gleam@erlang@process:exit_reason()}) +) -> gleam@erlang@process:exit_reason(). +initialise_actor(Spec, Ack) -> + Subject = gleam@erlang@process:new_subject(), + case (erlang:element(2, Spec))() of + {ready, State, Selector} -> + Selector@1 = init_selector(Subject, Selector), + gleam@erlang@process:send(Ack, {ok, Subject}), + Self = {self, + running, + gleam@erlang@process:subject_owner(Ack), + State, + Subject, + Selector@1, + sys:debug_options([]), + erlang:element(4, Spec)}, + loop(Self); + + {failed, Reason} -> + gleam@erlang@process:send(Ack, {error, {abnormal, Reason}}), + exit_process({abnormal, Reason}) + end. + +-spec to_erlang_start_result( + {ok, gleam@erlang@process:subject(any())} | {error, start_error()} +) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. +to_erlang_start_result(Res) -> + case Res of + {ok, X} -> + {ok, gleam@erlang@process:subject_owner(X)}; + + {error, X@1} -> + {error, gleam@dynamic:from(X@1)} + end. + +-spec start_spec(spec(any(), GDD)) -> {ok, gleam@erlang@process:subject(GDD)} | + {error, start_error()}. +start_spec(Spec) -> + Ack_subject = gleam@erlang@process:new_subject(), + Child = gleam@erlang@process:start( + fun() -> initialise_actor(Spec, Ack_subject) end, + true + ), + Monitor = gleam@erlang@process:monitor_process(Child), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Ack_subject, + fun(Field@0) -> {ack, Field@0} end + ), + gleam@erlang@process:selecting_process_down( + _pipe@1, + Monitor, + fun(Field@0) -> {mon, Field@0} end + ) + end, + Result = case gleam_erlang_ffi:select(Selector, erlang:element(3, Spec)) of + {ok, {ack, {ok, Channel}}} -> + {ok, Channel}; + + {ok, {ack, {error, Reason}}} -> + {error, {init_failed, Reason}}; + + {ok, {mon, Down}} -> + {error, {init_crashed, erlang:element(3, Down)}}; + + {error, nil} -> + gleam@erlang@process:kill(Child), + {error, init_timeout} + end, + gleam_erlang_ffi:demonitor(Monitor), + Result. + +-spec start(GDJ, fun((GDK, GDJ) -> next(GDK, GDJ))) -> {ok, + gleam@erlang@process:subject(GDK)} | + {error, start_error()}. +start(State, Loop) -> + start_spec( + {spec, + fun() -> {ready, State, gleam_erlang_ffi:new_selector()} end, + 5000, + Loop} + ). + +-spec send(gleam@erlang@process:subject(GDQ), GDQ) -> nil. +send(Subject, Msg) -> + gleam@erlang@process:send(Subject, Msg). + +-spec call( + gleam@erlang@process:subject(GDS), + fun((gleam@erlang@process:subject(GDU)) -> GDS), + integer() +) -> GDU. +call(Selector, Make_message, Timeout) -> + gleam@erlang@process:call(Selector, Make_message, Timeout). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl new file mode 100644 index 00000000000..8792f143c9a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl @@ -0,0 +1,53 @@ +-module(gleam@otp@intensity_tracker). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/2, trim_window/3, add_event/1]). +-export_type([intensity_tracker/0, too_intense/0]). + +-opaque intensity_tracker() :: {intensity_tracker, + integer(), + integer(), + list(integer())}. + +-type too_intense() :: too_intense. + +-spec new(integer(), integer()) -> intensity_tracker(). +new(Limit, Period) -> + {intensity_tracker, Limit, Period, []}. + +-spec now_seconds() -> integer(). +now_seconds() -> + erlang:monotonic_time(1). + +-spec trim_window(list(integer()), integer(), integer()) -> list(integer()). +trim_window(Events, Now, Period) -> + case Events of + [] -> + []; + + [Event | Events@1] -> + case Now >= (Event + Period) of + true -> + [Event | trim_window(Events@1, Now, Period)]; + + false -> + [] + end + end. + +-spec add_event(intensity_tracker()) -> {ok, intensity_tracker()} | + {error, too_intense()}. +add_event(Tracker) -> + Now = now_seconds(), + Events = trim_window( + [Now | erlang:element(4, Tracker)], + Now, + erlang:element(3, Tracker) + ), + case gleam@list:length(Events) >= erlang:element(2, Tracker) of + true -> + {error, too_intense}; + + false -> + {ok, erlang:setelement(4, Tracker, Events)} + end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl new file mode 100644 index 00000000000..b2057392ae4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl @@ -0,0 +1,8 @@ +-module(gleam@otp@port). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export_type([port_/0]). + +-type port_() :: any(). + + diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl new file mode 100644 index 00000000000..39118f1a5ae --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl @@ -0,0 +1,322 @@ +-module(gleam@otp@supervisor). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([add/2, supervisor/1, worker/1, returning/2, start_spec/1, start/1, application_stopped/0, to_erlang_start_result/1]). +-export_type([spec/2, children/1, child_spec/3, child_start_error/0, message/0, instruction/0, state/1, starter/1, child/1, handle_exit_error/0, application_start_mode/0, application_stop/0]). + +-type spec(GLS, GLT) :: {spec, + GLS, + integer(), + integer(), + fun((children(GLS)) -> children(GLT))}. + +-opaque children(GLU) :: {ready, starter(GLU)} | {failed, child_start_error()}. + +-opaque child_spec(GLV, GLW, GLX) :: {child_spec, + fun((GLW) -> {ok, gleam@erlang@process:subject(GLV)} | + {error, gleam@otp@actor:start_error()}), + fun((GLW, gleam@erlang@process:subject(GLV)) -> GLX)}. + +-type child_start_error() :: {child_start_error, + gleam@option:option(gleam@erlang@process:pid_()), + gleam@otp@actor:start_error()}. + +-opaque message() :: {exit, gleam@erlang@process:exit_message()} | + {retry_restart, gleam@erlang@process:pid_()}. + +-type instruction() :: start_all | {start_from, gleam@erlang@process:pid_()}. + +-type state(GLY) :: {state, + gleam@otp@intensity_tracker:intensity_tracker(), + starter(GLY), + gleam@erlang@process:subject(gleam@erlang@process:pid_())}. + +-type starter(GLZ) :: {starter, + GLZ, + gleam@option:option(fun((instruction()) -> {ok, + {starter(GLZ), instruction()}} | + {error, child_start_error()}))}. + +-type child(GMA) :: {child, gleam@erlang@process:pid_(), GMA}. + +-type handle_exit_error() :: {restart_failed, + gleam@erlang@process:pid_(), + gleam@otp@intensity_tracker:intensity_tracker()} | + too_many_restarts. + +-type application_start_mode() :: normal | + {takeover, gleam@erlang@node:node_()} | + {failover, gleam@erlang@node:node_()}. + +-type application_stop() :: any(). + +-spec start_child(child_spec(any(), GME, GMF), GME) -> {ok, child(GMF)} | + {error, child_start_error()}. +start_child(Child_spec, Argument) -> + gleam@result:then( + begin + _pipe = (erlang:element(2, Child_spec))(Argument), + gleam@result:map_error( + _pipe, + fun(_capture) -> {child_start_error, none, _capture} end + ) + end, + fun(Subject) -> + {ok, + {child, + gleam@erlang@process:subject_owner(Subject), + (erlang:element(3, Child_spec))(Argument, Subject)}} + end + ). + +-spec shutdown_child( + gleam@erlang@process:pid_(), + child_spec(any(), any(), any()) +) -> nil. +shutdown_child(Pid, _) -> + gleam@erlang@process:send_exit(Pid). + +-spec perform_instruction_for_child( + GMS, + instruction(), + child_spec(any(), GMS, GMU), + child(GMU) +) -> {ok, {child(GMU), instruction()}} | {error, child_start_error()}. +perform_instruction_for_child(Argument, Instruction, Child_spec, Child) -> + Current = erlang:element(2, Child), + case Instruction of + {start_from, Target} when Target =/= Current -> + {ok, {Child, Instruction}}; + + _ -> + shutdown_child(Current, Child_spec), + gleam@result:then( + start_child(Child_spec, Argument), + fun(Child@1) -> {ok, {Child@1, start_all}} end + ) + end. + +-spec add_child_to_starter( + starter(GNC), + child_spec(any(), GNC, GNF), + child(GNF) +) -> starter(GNF). +add_child_to_starter(Starter, Child_spec, Child) -> + Starter@3 = fun(Instruction) -> + gleam@result:then(case erlang:element(3, Starter) of + {some, Start} -> + Start(Instruction); + + none -> + {ok, {Starter, Instruction}} + end, fun(_use0) -> + {Starter@1, Instruction@1} = _use0, + gleam@result:then( + perform_instruction_for_child( + erlang:element(2, Starter@1), + Instruction@1, + Child_spec, + Child + ), + fun(_use0@1) -> + {Child@1, Instruction@2} = _use0@1, + Starter@2 = add_child_to_starter( + Starter@1, + Child_spec, + Child@1 + ), + {ok, {Starter@2, Instruction@2}} + end + ) + end) + end, + {starter, erlang:element(3, Child), {some, Starter@3}}. + +-spec start_and_add_child(starter(GNL), child_spec(any(), GNL, GNO)) -> children(GNO). +start_and_add_child(State, Child_spec) -> + case start_child(Child_spec, erlang:element(2, State)) of + {ok, Child} -> + {ready, add_child_to_starter(State, Child_spec, Child)}; + + {error, Reason} -> + {failed, Reason} + end. + +-spec add(children(GNT), child_spec(any(), GNT, GNW)) -> children(GNW). +add(Children, Child_spec) -> + case Children of + {failed, Fail} -> + {failed, Fail}; + + {ready, State} -> + start_and_add_child(State, Child_spec) + end. + +-spec supervisor( + fun((GOB) -> {ok, gleam@erlang@process:subject(GOC)} | + {error, gleam@otp@actor:start_error()}) +) -> child_spec(GOC, GOB, GOB). +supervisor(Start) -> + {child_spec, Start, fun(Argument, _) -> Argument end}. + +-spec worker( + fun((GOJ) -> {ok, gleam@erlang@process:subject(GOK)} | + {error, gleam@otp@actor:start_error()}) +) -> child_spec(GOK, GOJ, GOJ). +worker(Start) -> + {child_spec, Start, fun(Argument, _) -> Argument end}. + +-spec returning( + child_spec(GOR, GOS, any()), + fun((GOS, gleam@erlang@process:subject(GOR)) -> GOY) +) -> child_spec(GOR, GOS, GOY). +returning(Child, Updater) -> + {child_spec, erlang:element(2, Child), Updater}. + +-spec init(spec(any(), GPD)) -> gleam@otp@actor:init_result(state(GPD), message()). +init(Spec) -> + Retry = gleam@erlang@process:new_subject(), + gleam_erlang_ffi:trap_exits(true), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Retry, + fun(Field@0) -> {retry_restart, Field@0} end + ), + gleam@erlang@process:selecting_trapped_exits( + _pipe@1, + fun(Field@0) -> {exit, Field@0} end + ) + end, + Result = begin + _pipe@2 = {starter, erlang:element(2, Spec), none}, + _pipe@3 = {ready, _pipe@2}, + (erlang:element(5, Spec))(_pipe@3) + end, + case Result of + {ready, Starter} -> + Restarts = gleam@otp@intensity_tracker:new( + erlang:element(3, Spec), + erlang:element(4, Spec) + ), + State = {state, Restarts, Starter, Retry}, + {ready, State, Selector}; + + {failed, Error} -> + {failed, case erlang:element(3, Error) of + init_timeout -> + <<"Child initialisation timed out"/utf8>>; + + {init_crashed, Reason} -> + gleam@string:append( + <<"Child crashed during initialisation: "/utf8>>, + gleam@string:inspect(Reason) + ); + + {init_failed, Reason@1} -> + gleam@string:append( + <<"Child failed to start during initialisation: "/utf8>>, + gleam@string:inspect(Reason@1) + ) + end} + end. + +-spec handle_exit(gleam@erlang@process:pid_(), state(GPJ)) -> gleam@otp@actor:next(message(), state(GPJ)). +handle_exit(Pid, State) -> + Outcome = begin + _assert_subject = erlang:element(3, erlang:element(3, State)), + {some, Start} = case _assert_subject of + {some, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/otp/supervisor"/utf8>>, + function => <<"handle_exit"/utf8>>, + line => 293}) + end, + gleam@result:then( + begin + _pipe = erlang:element(2, State), + _pipe@1 = gleam@otp@intensity_tracker:add_event(_pipe), + gleam@result:map_error(_pipe@1, fun(_) -> too_many_restarts end) + end, + fun(Restarts) -> + gleam@result:then( + begin + _pipe@2 = Start({start_from, Pid}), + gleam@result:map_error( + _pipe@2, + fun(E) -> + {restart_failed, + gleam@option:unwrap( + erlang:element(2, E), + Pid + ), + Restarts} + end + ) + end, + fun(_use0) -> + {Starter, _} = _use0, + {ok, + erlang:setelement( + 2, + erlang:setelement(3, State, Starter), + Restarts + )} + end + ) + end + ) + end, + case Outcome of + {ok, State@1} -> + gleam@otp@actor:continue(State@1); + + {error, {restart_failed, Failed_child, Restarts@1}} -> + gleam@erlang@process:send(erlang:element(4, State), Failed_child), + State@2 = erlang:setelement(2, State, Restarts@1), + gleam@otp@actor:continue(State@2); + + {error, too_many_restarts} -> + {stop, + {abnormal, + <<"Child processes restarted too many times within allowed period"/utf8>>}} + end. + +-spec loop(message(), state(GPO)) -> gleam@otp@actor:next(message(), state(GPO)). +loop(Message, State) -> + case Message of + {exit, Exit_message} -> + handle_exit(erlang:element(2, Exit_message), State); + + {retry_restart, Pid} -> + handle_exit(Pid, State) + end. + +-spec start_spec(spec(any(), any())) -> {ok, + gleam@erlang@process:subject(message())} | + {error, gleam@otp@actor:start_error()}. +start_spec(Spec) -> + gleam@otp@actor:start_spec( + {spec, fun() -> init(Spec) end, 60000, fun loop/2} + ). + +-spec start(fun((children(nil)) -> children(any()))) -> {ok, + gleam@erlang@process:subject(message())} | + {error, gleam@otp@actor:start_error()}. +start(Init) -> + start_spec({spec, nil, 1, 5, Init}). + +-spec application_stopped() -> application_stop(). +application_stopped() -> + gleam_otp_external:application_stopped(). + +-spec to_erlang_start_result( + {ok, gleam@erlang@process:subject(any())} | + {error, gleam@otp@actor:start_error()} +) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. +to_erlang_start_result(Res) -> + gleam@otp@actor:to_erlang_start_result(Res). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl new file mode 100644 index 00000000000..622e5ea10bf --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl @@ -0,0 +1,43 @@ +-module(gleam@otp@system). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([debug_state/1, get_state/1, suspend/1, resume/1]). +-export_type([mode/0, debug_option/0, debug_state/0, status_info/0, system_message/0, do_not_leak/0]). + +-type mode() :: running | suspended. + +-type debug_option() :: no_debug. + +-type debug_state() :: any(). + +-type status_info() :: {status_info, + gleam@erlang@atom:atom_(), + gleam@erlang@process:pid_(), + mode(), + debug_state(), + gleam@dynamic:dynamic_()}. + +-type system_message() :: {resume, fun(() -> nil)} | + {suspend, fun(() -> nil)} | + {get_state, fun((gleam@dynamic:dynamic_()) -> nil)} | + {get_status, fun((status_info()) -> nil)}. + +-type do_not_leak() :: any(). + +-spec debug_state(list(debug_option())) -> debug_state(). +debug_state(A) -> + sys:debug_options(A). + +-spec get_state(gleam@erlang@process:pid_()) -> gleam@dynamic:dynamic_(). +get_state(From) -> + sys:get_state(From). + +-spec suspend(gleam@erlang@process:pid_()) -> nil. +suspend(Pid) -> + sys:suspend(Pid), + nil. + +-spec resume(gleam@erlang@process:pid_()) -> nil. +resume(Pid) -> + sys:resume(Pid), + nil. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl new file mode 100644 index 00000000000..e00428491f4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl @@ -0,0 +1,111 @@ +-module(gleam@otp@task). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([async/1, try_await/2, await/2, try_await_forever/1, await_forever/1]). +-export_type([task/1, await_error/0, message/1]). + +-opaque task(FWJ) :: {task, + gleam@erlang@process:pid_(), + gleam@erlang@process:pid_(), + gleam@erlang@process:process_monitor(), + gleam@erlang@process:selector(message(FWJ))}. + +-type await_error() :: timeout | {exit, gleam@dynamic:dynamic_()}. + +-type message(FWK) :: {from_monitor, gleam@erlang@process:process_down()} | + {from_subject, FWK}. + +-spec async(fun(() -> FWL)) -> task(FWL). +async(Work) -> + Owner = erlang:self(), + Subject = gleam@erlang@process:new_subject(), + Pid = gleam@erlang@process:start( + fun() -> gleam@erlang@process:send(Subject, Work()) end, + true + ), + Monitor = gleam@erlang@process:monitor_process(Pid), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting_process_down( + _pipe, + Monitor, + fun(Field@0) -> {from_monitor, Field@0} end + ), + gleam@erlang@process:selecting( + _pipe@1, + Subject, + fun(Field@0) -> {from_subject, Field@0} end + ) + end, + {task, Owner, Pid, Monitor, Selector}. + +-spec assert_owner(task(any())) -> nil. +assert_owner(Task) -> + Self = erlang:self(), + case erlang:element(2, Task) =:= Self of + true -> + nil; + + false -> + gleam@erlang@process:send_abnormal_exit( + Self, + <<"awaited on a task that does not belong to this process"/utf8>> + ) + end. + +-spec try_await(task(FWP), integer()) -> {ok, FWP} | {error, await_error()}. +try_await(Task, Timeout) -> + assert_owner(Task), + case gleam_erlang_ffi:select(erlang:element(5, Task), Timeout) of + {ok, {from_subject, X}} -> + gleam_erlang_ffi:demonitor(erlang:element(4, Task)), + {ok, X}; + + {ok, {from_monitor, {process_down, _, Reason}}} -> + {error, {exit, Reason}}; + + {error, nil} -> + {error, timeout} + end. + +-spec await(task(FWT), integer()) -> FWT. +await(Task, Timeout) -> + _assert_subject = try_await(Task, Timeout), + {ok, Value} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/otp/task"/utf8>>, + function => <<"await"/utf8>>, + line => 117}) + end, + Value. + +-spec try_await_forever(task(FWV)) -> {ok, FWV} | {error, await_error()}. +try_await_forever(Task) -> + assert_owner(Task), + case gleam_erlang_ffi:select(erlang:element(5, Task)) of + {from_subject, X} -> + gleam_erlang_ffi:demonitor(erlang:element(4, Task)), + {ok, X}; + + {from_monitor, {process_down, _, Reason}} -> + {error, {exit, Reason}} + end. + +-spec await_forever(task(FWZ)) -> FWZ. +await_forever(Task) -> + _assert_subject = try_await_forever(Task), + {ok, Value} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => let_assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"gleam/otp/task"/utf8>>, + function => <<"await_forever"/utf8>>, + line => 149}) + end, + Value. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src new file mode 100644 index 00000000000..5c52295ceb9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src @@ -0,0 +1,15 @@ +{application, gleam_otp, [ + {vsn, "0.8.0"}, + {applications, [gleam_erlang, + gleam_stdlib, + gleeunit]}, + {description, "Fault tolerant multicore Gleam programs with OTP"}, + {modules, [gleam@otp@actor, + gleam@otp@intensity_tracker, + gleam@otp@port, + gleam@otp@supervisor, + gleam@otp@system, + gleam@otp@task, + gleam_otp]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl new file mode 100644 index 00000000000..9381ad2ac22 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl @@ -0,0 +1,28 @@ +-module(gleam_otp). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([main/0]). + +-spec spawn_task(integer()) -> gleam@otp@task:task(nil). +spawn_task(I) -> + gleam@otp@task:async(fun() -> case (I rem 500) =:= 0 of + true -> + gleam@io:println( + <<"Hello from "/utf8, (gleam@int:to_string(I))/binary>> + ); + + false -> + nil + end end). + +-spec main() -> integer(). +main() -> + gleam@io:debug( + gleam_otp_test_external:get_message_queue_length(erlang:self()) + ), + _pipe = gleam@list:range(0, 1000000), + _pipe@1 = gleam@list:map(_pipe, fun spawn_task/1), + gleam@list:each(_pipe@1, fun gleam@otp@task:await_forever/1), + gleam@io:debug( + gleam_otp_test_external:get_message_queue_length(erlang:self()) + ). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam new file mode 100644 index 00000000000..69cdd5bb1e6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam @@ -0,0 +1,27 @@ +import gleam/io +import gleam/int +import gleam/list +import gleam/otp/task +import gleam/erlang/process.{type Pid} + +@external(erlang, "gleam_otp_test_external", "get_message_queue_length") +fn get_message_queue_length(pid pid: Pid) -> Int + +fn spawn_task(i) { + task.async(fn() { + case i % 500 == 0 { + True -> io.println("Hello from " <> int.to_string(i)) + False -> Nil + } + }) +} + +pub fn main() { + io.debug(get_message_queue_length(process.self())) + + list.range(0, 1_000_000) + |> list.map(spawn_task) + |> list.each(task.await_forever) + + io.debug(get_message_queue_length(process.self())) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl new file mode 100644 index 00000000000..8910a67d7e2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl @@ -0,0 +1,43 @@ +-module(gleam_otp_external). + +-export([application_stopped/0, convert_system_message/2]). + +% TODO: support other system messages +% {replace_state, StateFn} +% {change_code, Mod, Vsn, Extra} +% {terminate, Reason} +% {debug, {log, Flag}} +% {debug, {trace, Flag}} +% {debug, {log_to_file, FileName}} +% {debug, {statistics, Flag}} +% {debug, no_debug} +% {debug, {install, {Func, FuncState}}} +% {debug, {install, {FuncId, Func, FuncState}}} +% {debug, {remove, FuncOrId}} +% GetStatus(Subject(StatusInfo)) +convert_system_message({From, Ref}, Request) when is_pid(From) -> + Reply = fun(Msg) -> + erlang:send(From, {Ref, Msg}), + nil + end, + System = fun(Callback) -> + {system, {Request, Callback}} + end, + case Request of + get_status -> System(fun(Status) -> Reply(process_status(Status)) end); + get_state -> System(Reply); + suspend -> System(fun() -> Reply(ok) end); + resume -> System(fun() -> Reply(ok) end); + Other -> {unexpeceted, Other} + end. + +process_status({status_info, Module, Parent, Mode, DebugState, State}) -> + Data = [ + get(), Mode, Parent, DebugState, + [{header, "Status for Gleam process " ++ pid_to_list(self())}, + {data, [{'Status', Mode}, {'Parent', Parent}, {'State', State}]}] + ], + {status, self(), {module, Module}, Data}. + +application_stopped() -> + ok. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE new file mode 100644 index 00000000000..c1dabd08e3d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2018, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md new file mode 100644 index 00000000000..05c68ca9075 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md @@ -0,0 +1,39 @@ +# stdlib + +GitHub release +Discord chat +![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) + +Gleam's standard library! +Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). + +## Installation + +Add `gleam_stdlib` to your Gleam project. + +```sh +gleam add gleam_stdlib +``` + +## Usage + +Import the modules you want to use and write some code! + +```gleam +import gleam/string + +pub fn greet(name: String) -> String { + string.concat(["Hello ", name, "!"]) +} +``` + +## Targets + +Gleam's standard library supports both targets: Erlang and JavaScript. + +### Compatibility + +This library is compatible with all versions of Erlang/OTP, NodeJS, and +major browsers that are currently supported by their maintainers. If you +have a compatibility issue with any platform open an issue and we'll see +what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml new file mode 100644 index 00000000000..a978a7ff425 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml @@ -0,0 +1,16 @@ +name = "gleam_stdlib" +version = "0.33.1" +gleam = ">= 0.32.0" +licences = ["Apache-2.0"] +description = "A standard library for the Gleam programming language" + +repository = { type = "github", user = "gleam-lang", repo = "stdlib" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[javascript.deno] +allow_read = [ + "./", +] diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl new file mode 100644 index 00000000000..b1135f2dea0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl @@ -0,0 +1,5 @@ +-record(decode_error, { + expected :: binary(), + found :: binary(), + path :: list(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl new file mode 100644 index 00000000000..b0d08dc71a3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl @@ -0,0 +1 @@ +-record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl new file mode 100644 index 00000000000..1f61922beda --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl @@ -0,0 +1 @@ +-record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl new file mode 100644 index 00000000000..88ac25ed0a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl @@ -0,0 +1 @@ +-record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl new file mode 100644 index 00000000000..ad5511eb103 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl @@ -0,0 +1 @@ +-record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl new file mode 100644 index 00000000000..42166198699 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl @@ -0,0 +1,4 @@ +-record(match, { + content :: binary(), + submatches :: list(gleam@option:option(binary())) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl new file mode 100644 index 00000000000..0074603b961 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl @@ -0,0 +1 @@ +-record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl new file mode 100644 index 00000000000..6e1e2261268 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl @@ -0,0 +1 @@ +-record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl new file mode 100644 index 00000000000..50150f476b1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl @@ -0,0 +1,9 @@ +-record(uri, { + scheme :: gleam@option:option(binary()), + userinfo :: gleam@option:option(binary()), + host :: gleam@option:option(binary()), + port :: gleam@option:option(integer()), + path :: binary(), + 'query' :: gleam@option:option(binary()), + fragment :: gleam@option:option(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs new file mode 100644 index 00000000000..a8309e0cdbd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs @@ -0,0 +1,957 @@ +/** + * This file uses jsdoc to annotate types. + * These types can be checked using the typescript compiler with "checkjs" option. + */ + +import { isEqual } from "./gleam.mjs"; + +const referenceMap = new WeakMap(); +const tempDataView = new DataView(new ArrayBuffer(8)); +let referenceUID = 0; +/** + * hash the object by reference using a weak map and incrementing uid + * @param {any} o + * @returns {number} + */ +function hashByReference(o) { + const known = referenceMap.get(o); + if (known !== undefined) { + return known; + } + const hash = referenceUID++; + if (referenceUID === 0x7fffffff) { + referenceUID = 0; + } + referenceMap.set(o, hash); + return hash; +} +/** + * merge two hashes in an order sensitive way + * @param {number} a + * @param {number} b + * @returns {number} + */ +function hashMerge(a, b) { + return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; +} +/** + * standard string hash popularised by java + * @param {string} s + * @returns {number} + */ +function hashString(s) { + let hash = 0; + const len = s.length; + for (let i = 0; i < len; i++) { + hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; + } + return hash; +} +/** + * hash a number by converting to two integers and do some jumbling + * @param {number} n + * @returns {number} + */ +function hashNumber(n) { + tempDataView.setFloat64(0, n); + const i = tempDataView.getInt32(0); + const j = tempDataView.getInt32(4); + return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; +} +/** + * hash a BigInt by converting it to a string and hashing that + * @param {BigInt} n + * @returns {number} + */ +function hashBigInt(n) { + return hashString(n.toString()); +} +/** + * hash any js object + * @param {any} o + * @returns {number} + */ +function hashObject(o) { + const proto = Object.getPrototypeOf(o); + if (proto !== null && typeof proto.hashCode === "function") { + try { + const code = o.hashCode(o); + if (typeof code === "number") { + return code; + } + } catch {} + } + if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { + return hashByReference(o); + } + if (o instanceof Date) { + return hashNumber(o.getTime()); + } + let h = 0; + if (o instanceof ArrayBuffer) { + o = new Uint8Array(o); + } + if (Array.isArray(o) || o instanceof Uint8Array) { + for (let i = 0; i < o.length; i++) { + h = (Math.imul(31, h) + getHash(o[i])) | 0; + } + } else if (o instanceof Set) { + o.forEach((v) => { + h = (h + getHash(v)) | 0; + }); + } else if (o instanceof Map) { + o.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + } else { + const keys = Object.keys(o); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + const v = o[k]; + h = (h + hashMerge(getHash(v), hashString(k))) | 0; + } + } + return h; +} +/** + * hash any js value + * @param {any} u + * @returns {number} + */ +export function getHash(u) { + if (u === null) return 0x42108422; + if (u === undefined) return 0x42108423; + if (u === true) return 0x42108421; + if (u === false) return 0x42108420; + switch (typeof u) { + case "number": + return hashNumber(u); + case "string": + return hashString(u); + case "bigint": + return hashBigInt(u); + case "object": + return hashObject(u); + case "symbol": + return hashByReference(u); + case "function": + return hashByReference(u); + default: + return 0; // should be unreachable + } +} +/** + * @template K,V + * @typedef {ArrayNode | IndexNode | CollisionNode} Node + */ +/** + * @template K,V + * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry + */ +/** + * @template K,V + * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry | Node)[] }} ArrayNode + */ +/** + * @template K,V + * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry | Node)[] }} IndexNode + */ +/** + * @template K,V + * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry[] }} CollisionNode + */ +/** + * @typedef {{ val: boolean }} Flag + */ +const SHIFT = 5; // number of bits you need to shift by to get the next bucket +const BUCKET_SIZE = Math.pow(2, SHIFT); +const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket +const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node +const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node +const ENTRY = 0; +const ARRAY_NODE = 1; +const INDEX_NODE = 2; +const COLLISION_NODE = 3; +/** @type {IndexNode} */ +const EMPTY = { + type: INDEX_NODE, + bitmap: 0, + array: [], +}; +/** + * Mask the hash to get only the bucket corresponding to shift + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function mask(hash, shift) { + return (hash >>> shift) & MASK; +} +/** + * Set only the Nth bit where N is the masked hash + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function bitpos(hash, shift) { + return 1 << mask(hash, shift); +} +/** + * Count the number of 1 bits in a number + * @param {number} x + * @returns {number} + */ +function bitcount(x) { + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x += x >> 8; + x += x >> 16; + return x & 0x7f; +} +/** + * Calculate the array index of an item in a bitmap index node + * @param {number} bitmap + * @param {number} bit + * @returns {number} + */ +function index(bitmap, bit) { + return bitcount(bitmap & (bit - 1)); +} +/** + * Efficiently copy an array and set one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function cloneAndSet(arr, at, val) { + const len = arr.length; + const out = new Array(len); + for (let i = 0; i < len; ++i) { + out[i] = arr[i]; + } + out[at] = val; + return out; +} +/** + * Efficiently copy an array and insert one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function spliceIn(arr, at, val) { + const len = arr.length; + const out = new Array(len + 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + out[g++] = val; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Efficiently copy an array and remove one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @returns {T[]} + */ +function spliceOut(arr, at) { + const len = arr.length; + const out = new Array(len - 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + ++i; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Create a new node containing two entries + * @template K,V + * @param {number} shift + * @param {K} key1 + * @param {V} val1 + * @param {number} key2hash + * @param {K} key2 + * @param {V} val2 + * @returns {Node} + */ +function createNode(shift, key1, val1, key2hash, key2, val2) { + const key1hash = getHash(key1); + if (key1hash === key2hash) { + return { + type: COLLISION_NODE, + hash: key1hash, + array: [ + { type: ENTRY, k: key1, v: val1 }, + { type: ENTRY, k: key2, v: val2 }, + ], + }; + } + const addedLeaf = { val: false }; + return assoc( + assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), + shift, + key2hash, + key2, + val2, + addedLeaf + ); +} +/** + * @template T,K,V + * @callback AssocFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @param {V} val + * @param {Flag} addedLeaf + * @returns {Node} + */ +/** + * Associate a node with a new entry, creating a new node + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assoc(root, shift, hash, key, val, addedLeaf) { + switch (root.type) { + case ARRAY_NODE: + return assocArray(root, shift, hash, key, val, addedLeaf); + case INDEX_NODE: + return assocIndex(root, shift, hash, key, val, addedLeaf); + case COLLISION_NODE: + return assocCollision(root, shift, hash, key, val, addedLeaf); + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocArray(root, shift, hash, key, val, addedLeaf) { + const idx = mask(hash, shift); + const node = root.array[idx]; + // if the corresponding index is empty set the index to a newly created node + if (node === undefined) { + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size + 1, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + if (node.type === ENTRY) { + // if keys are equal replace the entry + if (isEqual(key, node.k)) { + if (val === node.v) { + return root; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // otherwise upgrade the entry to a node and insert + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, node.k, node.v, hash, key, val) + ), + }; + } + // otherwise call assoc on the child node + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + // if the child node hasn't changed just return the old root + if (n === node) { + return root; + } + // otherwise set the index to the new node + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocIndex(root, shift, hash, key, val, addedLeaf) { + const bit = bitpos(hash, shift); + const idx = index(root.bitmap, bit); + // if there is already a item at this hash index.. + if ((root.bitmap & bit) !== 0) { + // if there is a node at the index (not an entry), call assoc on the child node + const node = root.array[idx]; + if (node.type !== ENTRY) { + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + if (n === node) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise there is an entry at the index + // if the keys are equal replace the entry with the updated value + const nodeKey = node.k; + if (isEqual(key, nodeKey)) { + if (val === node.v) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // if the keys are not equal, replace the entry with a new child node + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) + ), + }; + } else { + // else there is currently no item at the hash index + const n = root.array.length; + // if the number of nodes is at the maximum, expand this node into an array node + if (n >= MAX_INDEX_NODE) { + // create a 32 length array for the new array node (one for each bit in the hash) + const nodes = new Array(32); + // create and insert a node for the new entry + const jdx = mask(hash, shift); + nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); + let j = 0; + let bitmap = root.bitmap; + // place each item in the index node into the correct spot in the array node + // loop through all 32 bits / array positions + for (let i = 0; i < 32; i++) { + if ((bitmap & 1) !== 0) { + const node = root.array[j++]; + nodes[i] = node; + } + // shift the bitmap to process the next bit + bitmap = bitmap >>> 1; + } + return { + type: ARRAY_NODE, + size: n + 1, + array: nodes, + }; + } else { + // else there is still space in this index node + // simply insert a new entry at the hash index + const newArray = spliceIn(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }); + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap | bit, + array: newArray, + }; + } + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocCollision(root, shift, hash, key, val, addedLeaf) { + // if there is a hash collision + if (hash === root.hash) { + const idx = collisionIndexOf(root, key); + // if this key already exists replace the entry with the new value + if (idx !== -1) { + const entry = root.array[idx]; + if (entry.v === val) { + return root; + } + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + // otherwise insert the entry at the end of the array + const size = root.array.length; + addedLeaf.val = true; + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), + }; + } + // if there is no hash collision, upgrade to an index node + return assoc( + { + type: INDEX_NODE, + bitmap: bitpos(root.hash, shift), + array: [root], + }, + shift, + hash, + key, + val, + addedLeaf + ); +} +/** + * Find the index of a key in the collision node's array + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {number} + */ +function collisionIndexOf(root, key) { + const size = root.array.length; + for (let i = 0; i < size; i++) { + if (isEqual(key, root.array[i].k)) { + return i; + } + } + return -1; +} +/** + * @template T,K,V + * @callback FindFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Entry} + */ +/** + * Return the found entry or undefined if not present in the root + * @template K,V + * @type {FindFunction,K,V>} + */ +function find(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return findArray(root, shift, hash, key); + case INDEX_NODE: + return findIndex(root, shift, hash, key); + case COLLISION_NODE: + return findCollision(root, key); + } +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return undefined; + } + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return undefined; + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Entry} + */ +function findCollision(root, key) { + const idx = collisionIndexOf(root, key); + if (idx < 0) { + return undefined; + } + return root.array[idx]; +} +/** + * @template T,K,V + * @callback WithoutFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Node} + */ +/** + * Remove an entry from the root, returning the updated root. + * Returns undefined if the node should be removed from the parent. + * @template K,V + * @type {WithoutFunction,K,V>} + * */ +function without(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return withoutArray(root, shift, hash, key); + case INDEX_NODE: + return withoutIndex(root, shift, hash, key); + case COLLISION_NODE: + return withoutCollision(root, key); + } +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return root; // already empty + } + let n = undefined; + // if node is an entry and the keys are not equal there is nothing to remove + // if node is not an entry do a recursive call + if (node.type === ENTRY) { + if (!isEqual(node.k, key)) { + return root; // no changes + } + } else { + n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + } + // if the recursive call returned undefined the node should be removed + if (n === undefined) { + // if the number of child nodes is at the minimum, pack into an index node + if (root.size <= MIN_ARRAY_NODE) { + const arr = root.array; + const out = new Array(root.size - 1); + let i = 0; + let j = 0; + let bitmap = 0; + while (i < idx) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + ++i; // skip copying the removed node + while (i < arr.length) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + return { + type: INDEX_NODE, + bitmap: bitmap, + array: out, + }; + } + return { + type: ARRAY_NODE, + size: root.size - 1, + array: cloneAndSet(root.array, idx, n), + }; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return root; // already empty + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + // if the item is not an entry + if (node.type !== ENTRY) { + const n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + // if not undefined, the child node still has items, so update it + if (n !== undefined) { + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise the child node should be removed + // if it was the only child node, remove this node from the parent + if (root.bitmap === bit) { + return undefined; + } + // otherwise just remove the child node + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + // otherwise the item is an entry, remove it if the key matches + if (isEqual(key, node.k)) { + if (root.bitmap === bit) { + return undefined; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + return root; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Node} + */ +function withoutCollision(root, key) { + const idx = collisionIndexOf(root, key); + // if the key not found, no changes + if (idx < 0) { + return root; + } + // otherwise the entry was found, remove it + // if it was the only entry in this node, remove the whole node + if (root.array.length === 1) { + return undefined; + } + // otherwise just remove the entry + return { + type: COLLISION_NODE, + hash: root.hash, + array: spliceOut(root.array, idx), + }; +} +/** + * @template K,V + * @param {undefined | Node} root + * @param {(value:V,key:K)=>void} fn + * @returns {void} + */ +function forEach(root, fn) { + if (root === undefined) { + return; + } + const items = root.array; + const size = items.length; + for (let i = 0; i < size; i++) { + const item = items[i]; + if (item === undefined) { + continue; + } + if (item.type === ENTRY) { + fn(item.v, item.k); + continue; + } + forEach(item, fn); + } +} +/** + * Extra wrapper to keep track of Dict size and clean up the API + * @template K,V + */ +export default class Dict { + /** + * @template V + * @param {Record} o + * @returns {Dict} + */ + static fromObject(o) { + const keys = Object.keys(o); + /** @type Dict */ + let m = Dict.new(); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + m = m.set(k, o[k]); + } + return m; + } + /** + * @template K,V + * @param {Map} o + * @returns {Dict} + */ + static fromMap(o) { + /** @type Dict */ + let m = Dict.new(); + o.forEach((v, k) => { + m = m.set(k, v); + }); + return m; + } + static new() { + return new Dict(undefined, 0); + } + /** + * @param {undefined | Node} root + * @param {number} size + */ + constructor(root, size) { + this.root = root; + this.size = size; + } + /** + * @template NotFound + * @param {K} key + * @param {NotFound} notFound + * @returns {NotFound | V} + */ + get(key, notFound) { + if (this.root === undefined) { + return notFound; + } + const found = find(this.root, 0, getHash(key), key); + if (found === undefined) { + return notFound; + } + return found.v; + } + /** + * @param {K} key + * @param {V} val + * @returns {Dict} + */ + set(key, val) { + const addedLeaf = { val: false }; + const root = this.root === undefined ? EMPTY : this.root; + const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); + if (newRoot === this.root) { + return this; + } + return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); + } + /** + * @param {K} key + * @returns {Dict} + */ + delete(key) { + if (this.root === undefined) { + return this; + } + const newRoot = without(this.root, 0, getHash(key), key); + if (newRoot === this.root) { + return this; + } + if (newRoot === undefined) { + return Dict.new(); + } + return new Dict(newRoot, this.size - 1); + } + /** + * @param {K} key + * @returns {boolean} + */ + has(key) { + if (this.root === undefined) { + return false; + } + return find(this.root, 0, getHash(key), key) !== undefined; + } + /** + * @returns {[K,V][]} + */ + entries() { + if (this.root === undefined) { + return []; + } + /** @type [K,V][] */ + const result = []; + this.forEach((v, k) => result.push([k, v])); + return result; + } + /** + * + * @param {(val:V,key:K)=>void} fn + */ + forEach(fn) { + forEach(this.root, fn); + } + hashCode() { + let h = 0; + this.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + return h; + } + /** + * @param {unknown} o + * @returns {boolean} + */ + equals(o) { + if (!(o instanceof Dict) || this.size !== o.size) { + return false; + } + let equal = true; + this.forEach((v, k) => { + equal = equal && isEqual(o.get(k, !v), v); + }); + return equal; + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam new file mode 100644 index 00000000000..eab2f0b3fec --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam @@ -0,0 +1,21 @@ +import gleam/bit_array + +@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") +pub fn encode64(input: BitArray, padding: Bool) -> String { + bit_array.base64_encode(input, padding) +} + +@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") +pub fn decode64(encoded: String) -> Result(BitArray, Nil) { + bit_array.base64_decode(encoded) +} + +@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") +pub fn url_encode64(input: BitArray, padding: Bool) -> String { + bit_array.base64_url_encode(input, padding) +} + +@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") +pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { + bit_array.base64_url_decode(encoded) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam new file mode 100644 index 00000000000..79860e964ef --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam @@ -0,0 +1,157 @@ +//// BitArrays are a sequence of binary data of any length. + +import gleam/string + +/// Converts a UTF-8 `String` type into a `BitArray`. +/// +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") +pub fn from_string(x: String) -> BitArray + +/// Returns an integer which is the number of bytes in the bit array. +/// +@external(erlang, "erlang", "byte_size") +@external(javascript, "../gleam_stdlib.mjs", "length") +pub fn byte_size(x: BitArray) -> Int + +/// Creates a new bit array by joining two bit arrays. +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: from_string("butter"), suffix: from_string("fly")) +/// from_string("butterfly") +/// ``` +/// +pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { + concat([first, second]) +} + +/// Extracts a sub-section of a bit array. +/// +/// The slice will start at given position and continue up to specified +/// length. +/// A negative length can be used to extract bytes at the end of a bit array. +/// +/// This function runs in constant time. +/// +@external(erlang, "gleam_stdlib", "bit_array_slice") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") +pub fn slice( + from string: BitArray, + at position: Int, + take length: Int, +) -> Result(BitArray, Nil) + +/// Tests to see whether a bit array is valid UTF-8. +/// +pub fn is_utf8(bits: BitArray) -> Bool { + do_is_utf8(bits) +} + +@target(erlang) +fn do_is_utf8(bits: BitArray) -> Bool { + case bits { + <<>> -> True + <<_:utf8, rest:bytes>> -> do_is_utf8(rest) + _ -> False + } +} + +@target(javascript) +fn do_is_utf8(bits: BitArray) -> Bool { + case to_string(bits) { + Ok(_) -> True + _ -> False + } +} + +/// Converts a bit array to a string. +/// +/// Returns an error if the bit array is invalid UTF-8 data. +/// +pub fn to_string(bits: BitArray) -> Result(String, Nil) { + do_to_string(bits) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "identity") +fn unsafe_to_string(a: BitArray) -> String + +@target(erlang) +fn do_to_string(bits: BitArray) -> Result(String, Nil) { + case is_utf8(bits) { + True -> Ok(unsafe_to_string(bits)) + False -> Error(Nil) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") +fn do_to_string(a: BitArray) -> Result(String, Nil) + +/// Creates a new bit array by joining multiple binaries. +/// +/// ## Examples +/// +/// ```gleam +/// > concat([from_string("butter"), from_string("fly")]) +/// from_string("butterfly") +/// ``` +/// +@external(erlang, "gleam_stdlib", "bit_array_concat") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") +pub fn concat(bit_arrays: List(BitArray)) -> BitArray + +/// Encodes a BitArray into a base 64 encoded string. +/// +pub fn base64_encode(input: BitArray, padding: Bool) -> String { + let encoded = encode64(input) + case padding { + True -> encoded + False -> string.replace(encoded, "=", "") + } +} + +@external(erlang, "base64", "encode") +@external(javascript, "../gleam_stdlib.mjs", "encode64") +fn encode64(a: BitArray) -> String + +/// Decodes a base 64 encoded string into a `BitArray`. +/// +pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { + let padded = case byte_size(from_string(encoded)) % 4 { + 0 -> encoded + n -> string.append(encoded, string.repeat("=", 4 - n)) + } + decode64(padded) +} + +@external(erlang, "gleam_stdlib", "base_decode64") +@external(javascript, "../gleam_stdlib.mjs", "decode64") +fn decode64(a: String) -> Result(BitArray, Nil) + +/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. +/// +pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { + base64_encode(input, padding) + |> string.replace("+", "-") + |> string.replace("/", "_") +} + +/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. +/// +pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { + encoded + |> string.replace("-", "+") + |> string.replace("_", "/") + |> base64_decode() +} + +@external(erlang, "binary", "encode_hex") +@external(javascript, "../gleam_stdlib.mjs", "base16_encode") +pub fn base16_encode(input: BitArray) -> String + +@external(erlang, "gleam_stdlib", "base16_decode") +@external(javascript, "../gleam_stdlib.mjs", "base16_decode") +pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam new file mode 100644 index 00000000000..ce6fe52ec1b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam @@ -0,0 +1,80 @@ +//// This module has been deprecated in favour of `gleam/bytes_builder`. + +import gleam/bytes_builder +import gleam/string_builder.{type StringBuilder} + +pub type BitBuilder = + bytes_builder.BytesBuilder + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn new() -> BitBuilder { + bytes_builder.new() +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { + bytes_builder.prepend(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { + bytes_builder.append(to, suffix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { + bytes_builder.prepend_builder(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append_builder( + to first: BitBuilder, + suffix second: BitBuilder, +) -> BitBuilder { + bytes_builder.append_builder(first, second) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { + bytes_builder.prepend_string(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { + bytes_builder.append_string(to, suffix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn concat(builders: List(BitBuilder)) -> BitBuilder { + bytes_builder.concat(builders) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { + bytes_builder.concat_bit_arrays(bits) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_string(string: String) -> BitBuilder { + bytes_builder.from_string(string) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { + bytes_builder.from_string_builder(builder) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_bit_string(bits: BitArray) -> BitBuilder { + bytes_builder.from_bit_array(bits) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn to_bit_string(builder: BitBuilder) -> BitArray { + bytes_builder.to_bit_array(builder) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn byte_size(builder: BitBuilder) -> Int { + bytes_builder.byte_size(builder) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam new file mode 100644 index 00000000000..b703da0930d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam @@ -0,0 +1,43 @@ +//// This module has been deprecated. Please use the `gleam/bit_array` module +//// instead. + +import gleam/bit_array + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn from_string(x: String) -> BitArray { + bit_array.from_string(x) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn byte_size(x: BitArray) -> Int { + bit_array.byte_size(x) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { + bit_array.append(first, second) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn slice( + from string: BitArray, + at position: Int, + take length: Int, +) -> Result(BitArray, Nil) { + bit_array.slice(string, position, length) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn is_utf8(bits: BitArray) -> Bool { + bit_array.is_utf8(bits) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn to_string(bits: BitArray) -> Result(String, Nil) { + bit_array.to_string(bits) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn concat(bit_strings: List(BitArray)) -> BitArray { + bit_array.concat(bit_strings) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam new file mode 100644 index 00000000000..91bd6b76129 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam @@ -0,0 +1,428 @@ +//// A type with two possible values, `True` and `False`. Used to indicate whether +//// things are... true or false! +//// +//// Often is it clearer and offers more type safety to define a custom type +//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` +//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom +//// type that can be either `Student` or `Teacher`. + +import gleam/order.{type Order} + +/// Returns the and of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `&&` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > and(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > and(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > False |> and(True) +/// False +/// ``` +/// +pub fn and(a: Bool, b: Bool) -> Bool { + a && b +} + +/// Returns the or of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `||` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > or(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > False |> or(True) +/// True +/// ``` +/// +pub fn or(a: Bool, b: Bool) -> Bool { + a || b +} + +/// Returns the opposite bool value. +/// +/// This is the same as the `!` or `not` operators in some other languages. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(True) +/// False +/// ``` +/// +/// ```gleam +/// > negate(False) +/// True +/// ``` +/// +pub fn negate(bool: Bool) -> Bool { + case bool { + True -> False + False -> True + } +} + +/// Returns the nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, True) +/// False +/// ``` +/// +pub fn nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> False + } +} + +/// Returns the nand of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nand(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, True) +/// False +/// ``` +/// +pub fn nand(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive or of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_or(False, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, True) +/// False +/// ``` +/// +pub fn exclusive_or(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> False + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, True) +/// True +/// ``` +/// +pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> True + } +} + +/// Compares two bools and returns the first value's `Order` to the second. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/order +/// > compare(True, False) +/// order.Gt +/// ``` +/// +pub fn compare(a: Bool, with b: Bool) -> Order { + case a, b { + True, True -> order.Eq + True, False -> order.Gt + False, False -> order.Eq + False, True -> order.Lt + } +} + +/// Returns `True` if either argument's value is `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > max(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, False) +/// False +/// ``` +/// +pub fn max(a: Bool, b: Bool) -> Bool { + case a { + True -> True + False -> b + } +} + +/// Returns `False` if either bool value is `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > min(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > min(False, True) +/// False +/// +/// > min(False, False) +/// False +/// ``` +/// +pub fn min(a: Bool, b: Bool) -> Bool { + case a { + False -> False + True -> b + } +} + +/// Returns a numeric representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(True) +/// 1 +/// +/// > to_int(False) +/// 0 +/// ``` +/// +pub fn to_int(bool: Bool) -> Int { + case bool { + False -> 0 + True -> 1 + } +} + +/// Returns a string representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(True) +/// "True" +/// ``` +/// +/// ```gleam +/// > to_string(False) +/// "False" +/// ``` +/// +pub fn to_string(bool: Bool) -> String { + case bool { + False -> "False" + True -> "True" + } +} + +/// Run a callback function if the given bool is `False`, otherwise return a +/// default value. +/// +/// With a `use` expression this function can simulate the early-return pattern +/// found in some other programming languages. +/// +/// In a procedural language: +/// +/// ```js +/// if (predicate) return value; +/// // ... +/// ``` +/// +/// In Gleam with a `use` expression: +/// +/// ```gleam +/// use <- guard(when: predicate, return: value) +/// // ... +/// ``` +/// +/// Like everything in Gleam `use` is an expression, so it short circuits the +/// current block, not the entire function. As a result you can assign the value +/// to a variable: +/// +/// ```gleam +/// let x = { +/// use <- guard(when: predicate, return: value) +/// // ... +/// } +/// ``` +/// +/// Note that unlike in procedural languages the `return` value is evaluated +/// even when the predicate is `False`, so it is advisable not to perform +/// expensive computation there. +/// +/// +/// ## Examples +/// +/// ```gleam +/// > let name = "" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Welcome!" +/// ``` +/// +/// ```gleam +/// > let name = "Kamaka" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Hello, Kamaka" +/// ``` +/// +pub fn guard( + when requirement: Bool, + return consequence: t, + otherwise alternative: fn() -> t, +) -> t { + case requirement { + True -> consequence + False -> alternative() + } +} + +/// Runs a callback function if the given bool is `True`, otherwise runs an +/// alternative callback function. +/// +/// Useful when further computation should be delayed regardless of the given +/// bool's value. +/// +/// See [`guard`](#guard) for more info. +/// +/// ## Examples +/// +/// ```gleam +/// > let name = "Kamaka" +/// > let inquiry = fn() { "How may we address you?" } +/// > use <- lazy_guard(when: name == "", return: inquiry) +/// > "Hello, " <> name +/// "Hello, Kamaka" +/// ``` +/// +/// ```gleam +/// > import gleam/int +/// > let name = "" +/// > let greeting = fn() { "Hello, " <> name } +/// > use <- lazy_guard(when: name == "", otherwise: greeting) +/// > let number = int.random(1, 99) +/// > let name = "User " <> int.to_string(number) +/// > "Welcome, " <> name +/// "Welcome, User 54" +/// ``` +/// +pub fn lazy_guard( + when requirement: Bool, + return consequence: fn() -> a, + otherwise alternative: fn() -> a, +) -> a { + case requirement { + True -> consequence() + False -> alternative() + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam new file mode 100644 index 00000000000..20c145d93aa --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam @@ -0,0 +1,197 @@ +//// BytesBuilder is a type used for efficiently concatenating bytes together +//// without copying. +//// +//// If we append one bit array to another the bit arrays must be copied to a +//// new location in memory so that they can sit together. This behaviour +//// enables efficient reading of the string but copying can be expensive, +//// especially if we want to join many bit arrays together. +//// +//// BytesBuilder is different in that it can be joined together in constant +//// time using minimal memory, and then can be efficiently converted to a +//// bit array using the `to_bit_array` function. +//// +//// Byte builders are always byte aligned, so that a number of bits that is not +//// divisible by 8 will be padded with 0s. +//// +//// On Erlang this type is compatible with Erlang's iolists. + +// TODO: pad bit arrays to byte boundaries when adding to a builder. +import gleam/string_builder.{type StringBuilder} +import gleam/list +import gleam/bit_array + +pub opaque type BytesBuilder { + Bytes(BitArray) + Text(StringBuilder) + Many(List(BytesBuilder)) +} + +/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many +/// builders together. +/// +pub fn new() -> BytesBuilder { + concat([]) +} + +/// Prepends a bit array to the start of a builder. +/// +/// Runs in constant time. +/// +pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { + append_builder(from_bit_array(first), second) +} + +/// Appends a bit array to the end of a builder. +/// +/// Runs in constant time. +/// +pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { + append_builder(first, from_bit_array(second)) +} + +/// Prepends a builder onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder( + to second: BytesBuilder, + prefix first: BytesBuilder, +) -> BytesBuilder { + append_builder(first, second) +} + +/// Appends a builder onto the end of another. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "iodata_append") +pub fn append_builder( + to first: BytesBuilder, + suffix second: BytesBuilder, +) -> BytesBuilder { + case second { + Many(builders) -> Many([first, ..builders]) + _ -> Many([first, second]) + } +} + +/// Prepends a string onto the start of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn prepend_string( + to second: BytesBuilder, + prefix first: String, +) -> BytesBuilder { + append_builder(from_string(first), second) +} + +/// Appends a string onto the end of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn append_string( + to first: BytesBuilder, + suffix second: String, +) -> BytesBuilder { + append_builder(first, from_string(second)) +} + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "identity") +pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { + Many(builders) +} + +/// Joins a list of bit arrays into a single builder. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "identity") +pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { + bits + |> list.map(fn(b) { from_bit_array(b) }) + |> concat() +} + +/// Creates a new builder from a string. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_string(string: String) -> BytesBuilder { + Text(string_builder.from_string(string)) +} + +/// Creates a new builder from a string builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { + Text(builder) +} + +/// Creates a new builder from a bit array. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_bit_array(bits: BitArray) -> BytesBuilder { + Bytes(bits) +} + +/// Turns an builder into a bit array. +/// +/// Runs in linear time. +/// +/// When running on Erlang this function is implemented natively by the +/// virtual machine and is highly optimised. +/// +@external(erlang, "erlang", "list_to_bitstring") +pub fn to_bit_array(builder: BytesBuilder) -> BitArray { + [[builder]] + |> to_list([]) + |> list.reverse + |> bit_array.concat +} + +fn to_list( + stack: List(List(BytesBuilder)), + acc: List(BitArray), +) -> List(BitArray) { + case stack { + [] -> acc + + [[], ..remaining_stack] -> to_list(remaining_stack, acc) + + [[Bytes(bits), ..rest], ..remaining_stack] -> + to_list([rest, ..remaining_stack], [bits, ..acc]) + + [[Text(builder), ..rest], ..remaining_stack] -> { + let bits = bit_array.from_string(string_builder.to_string(builder)) + to_list([rest, ..remaining_stack], [bits, ..acc]) + } + + [[Many(builders), ..rest], ..remaining_stack] -> + to_list([builders, rest, ..remaining_stack], acc) + } +} + +/// Returns the size of the builder's content in bytes. +/// +/// Runs in linear time. +/// +@external(erlang, "erlang", "iolist_size") +pub fn byte_size(builder: BytesBuilder) -> Int { + [[builder]] + |> to_list([]) + |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam new file mode 100644 index 00000000000..280bf9d1d98 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam @@ -0,0 +1,544 @@ +import gleam/option.{type Option} + +/// A dictionary of keys and values. +/// +/// Any type can be used for the keys and values of a dict, but all the keys +/// must be of the same type and all the values must be of the same type. +/// +/// Each key can only be present in a dict once. +/// +/// Dicts are not ordered in any way, and any unintentional ordering is not to +/// be relied upon in your code as it may change in future versions of Erlang +/// or Gleam. +/// +/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more +/// information. +/// +pub type Dict(key, value) + +/// Determines the number of key-value pairs in the dict. +/// This function runs in constant time and does not need to iterate the dict. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> size() +/// 0 +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", "value") |> size() +/// 1 +/// ``` +/// +pub fn size(dict: Dict(k, v)) -> Int { + do_size(dict) +} + +@external(erlang, "maps", "size") +@external(javascript, "../gleam_stdlib.mjs", "map_size") +fn do_size(a: Dict(k, v)) -> Int + +/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for +/// each key-value pair in the dict. +/// +/// The tuples in the list have no specific order. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> to_list() +/// [] +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", 0) |> to_list() +/// [#("key", 0)] +/// ``` +/// +pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { + do_to_list(dict) +} + +@external(erlang, "maps", "to_list") +@external(javascript, "../gleam_stdlib.mjs", "map_to_list") +fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) + +/// Converts a list of 2-element tuples `#(key, value)` to a dict. +/// +/// If two tuples have the same key the last one in the list will be the one +/// that is present in the dict. +/// +pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { + do_from_list(list) +} + +@target(erlang) +@external(erlang, "maps", "from_list") +fn do_from_list(a: List(#(key, value))) -> Dict(key, value) + +@target(javascript) +fn fold_list_of_pair( + over list: List(#(k, v)), + from initial: Dict(k, v), +) -> Dict(k, v) { + case list { + [] -> initial + [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) + } +} + +@target(javascript) +fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { + fold_list_of_pair(list, new()) +} + +/// Determines whether or not a value present in the dict for a given key. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("a") +/// True +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("b") +/// False +/// ``` +/// +pub fn has_key(dict: Dict(k, v), key: k) -> Bool { + do_has_key(key, dict) +} + +@target(erlang) +@external(erlang, "maps", "is_key") +fn do_has_key(a: key, b: Dict(key, v)) -> Bool + +@target(javascript) +fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { + get(dict, key) != Error(Nil) +} + +/// Creates a fresh dict that contains no values. +/// +pub fn new() -> Dict(key, value) { + do_new() +} + +@external(erlang, "maps", "new") +@external(javascript, "../gleam_stdlib.mjs", "new_map") +fn do_new() -> Dict(key, value) + +/// Fetches a value from a dict for a given key. +/// +/// The dict may not have a value for the key, so the value is wrapped in a +/// `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("b") +/// Error(Nil) +/// ``` +/// +pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { + do_get(from, get) +} + +@external(erlang, "gleam_stdlib", "map_get") +@external(javascript, "../gleam_stdlib.mjs", "map_get") +fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) + +/// Inserts a value into the dict with the given key. +/// +/// If the dict already has a value for the given key then the value is +/// replaced with the new value. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> to_list +/// [#("a", 0)] +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list +/// [#("a", 5)] +/// ``` +/// +pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { + do_insert(key, value, dict) +} + +@external(erlang, "maps", "put") +@external(javascript, "../gleam_stdlib.mjs", "map_insert") +fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) + +/// Updates all values in a given dict by calling a given function on each key +/// and value. +/// +/// ## Examples +/// +/// ```gleam +/// > [#(3, 3), #(2, 4)] +/// > |> from_list +/// > |> map_values(fn(key, value) { key * value }) +/// [#(3, 9), #(2, 8)] +/// ``` +/// +pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { + do_map_values(fun, dict) +} + +@target(erlang) +@external(erlang, "maps", "map") +fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) + +@target(javascript) +fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { + let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } + dict + |> fold(from: new(), with: f) +} + +/// Gets a list of all keys in a given dict. +/// +/// Dicts are not ordered so the keys are not returned in any specific order. Do +/// not write code that relies on the order keys are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > keys([#("a", 0), #("b", 1)]) +/// ["a", "b"] +/// ``` +/// +pub fn keys(dict: Dict(keys, v)) -> List(keys) { + do_keys(dict) +} + +@target(erlang) +@external(erlang, "maps", "keys") +fn do_keys(a: Dict(keys, v)) -> List(keys) + +@target(javascript) +fn reverse_and_concat(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) + } +} + +@target(javascript) +fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) + } +} + +@target(javascript) +fn do_keys(dict: Dict(k, v)) -> List(k) { + let list_of_pairs = to_list(dict) + do_keys_acc(list_of_pairs, []) +} + +/// Gets a list of all values in a given dict. +/// +/// Dicts are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order values are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > values(from_list([#("a", 0), #("b", 1)])) +/// [0, 1] +/// ``` +/// +pub fn values(dict: Dict(k, values)) -> List(values) { + do_values(dict) +} + +@target(erlang) +@external(erlang, "maps", "values") +fn do_values(a: Dict(k, values)) -> List(values) + +@target(javascript) +fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) + } +} + +@target(javascript) +fn do_values(dict: Dict(k, v)) -> List(v) { + let list_of_pairs = to_list(dict) + do_values_acc(list_of_pairs, []) +} + +/// Creates a new dict from a given dict, minus any entries that a given function +/// returns `False` for. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { value != 0 }) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { True }) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn filter( + in dict: Dict(k, v), + keeping predicate: fn(k, v) -> Bool, +) -> Dict(k, v) { + do_filter(predicate, dict) +} + +@target(erlang) +@external(erlang, "maps", "filter") +fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) + +@target(javascript) +fn do_filter( + f: fn(key, value) -> Bool, + dict: Dict(key, value), +) -> Dict(key, value) { + let insert = fn(dict, k, v) { + case f(k, v) { + True -> insert(dict, k, v) + _ -> dict + } + } + dict + |> fold(from: new(), with: insert) +} + +/// Creates a new dict from a given dict, only including any entries for which the +/// keys are in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["b"]) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["a", "b", "c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { + do_take(desired_keys, dict) +} + +@target(erlang) +@external(erlang, "maps", "with") +fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) + +@target(javascript) +fn insert_taken( + dict: Dict(k, v), + desired_keys: List(k), + acc: Dict(k, v), +) -> Dict(k, v) { + let insert = fn(taken, key) { + case get(dict, key) { + Ok(value) -> insert(taken, key, value) + _ -> taken + } + } + case desired_keys { + [] -> acc + [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) + } +} + +@target(javascript) +fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { + insert_taken(dict, desired_keys, new()) +} + +/// Creates a new dict from a pair of given dicts by combining their entries. +/// +/// If there are entries with the same keys in both dicts the entry from the +/// second dict takes precedence. +/// +/// ## Examples +/// +/// ```gleam +/// > let a = from_list([#("a", 0), #("b", 1)]) +/// > let b = from_list([#("b", 2), #("c", 3)]) +/// > merge(a, b) +/// from_list([#("a", 0), #("b", 2), #("c", 3)]) +/// ``` +/// +pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { + do_merge(dict, new_entries) +} + +@target(erlang) +@external(erlang, "maps", "merge") +fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) + +@target(javascript) +fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { + insert(dict, pair.0, pair.1) +} + +@target(javascript) +fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { + case new_entries { + [] -> dict + [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) + } +} + +@target(javascript) +fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { + new_entries + |> to_list + |> fold_inserts(dict) +} + +/// Creates a new dict from a given dict with all the same entries except for the +/// one with a given key, if it exists. +/// +/// ## Examples +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "a") +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "c") +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { + do_delete(key, dict) +} + +@external(erlang, "maps", "remove") +@external(javascript, "../gleam_stdlib.mjs", "map_remove") +fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) + +/// Creates a new dict from a given dict with all the same entries except any with +/// keys found in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a"]) +/// from_list([#("b", 2)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], ["c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) +/// from_list([]) +/// ``` +/// +pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { + case disallowed_keys { + [] -> dict + [x, ..xs] -> drop(delete(dict, x), xs) + } +} + +/// Creates a new dict with one entry updated using a given function. +/// +/// If there was not an entry in the dict for the given key then the function +/// gets `None` as its argument, otherwise it gets `Some(value)`. +/// +/// ## Example +/// +/// ```gleam +/// > let increment = fn(x) { +/// > case x { +/// > Some(i) -> i + 1 +/// > None -> 0 +/// > } +/// > } +/// > let dict = from_list([#("a", 0)]) +/// > +/// > update(dict, "a", increment) +/// from_list([#("a", 1)]) +/// ``` +/// +/// ```gleam +/// > update(dict, "b", increment) +/// from_list([#("a", 0), #("b", 0)]) +/// ``` +/// +pub fn update( + in dict: Dict(k, v), + update key: k, + with fun: fn(Option(v)) -> v, +) -> Dict(k, v) { + dict + |> get(key) + |> option.from_result + |> fun + |> insert(dict, key, _) +} + +fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { + case list { + [] -> initial + [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) + } +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Dicts are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order entries are used by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) +/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) +/// 13 +/// ``` +/// +/// ```gleam +/// > import gleam/string.{append} +/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) +/// "abc" +/// ``` +/// +pub fn fold( + over dict: Dict(k, v), + from initial: acc, + with fun: fn(acc, k, v) -> acc, +) -> acc { + dict + |> to_list + |> do_fold(initial, fun) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam new file mode 100644 index 00000000000..c71c6f342ad --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam @@ -0,0 +1,1508 @@ +import gleam/int +import gleam/list +import gleam/dict.{type Dict} +import gleam/option.{type Option} +import gleam/result +import gleam/string_builder +@target(erlang) +import gleam/bit_array + +/// `Dynamic` data is data that we don't know the type of yet. +/// We likely get data like this from interop with Erlang, or from +/// IO with the outside world. +/// +pub type Dynamic + +/// Error returned when unexpected data is encountered +/// +pub type DecodeError { + DecodeError(expected: String, found: String, path: List(String)) +} + +pub type DecodeErrors = + List(DecodeError) + +pub type Decoder(t) = + fn(Dynamic) -> Result(t, DecodeErrors) + +/// Converts any Gleam data into `Dynamic` data. +/// +pub fn from(a) -> Dynamic { + do_from(a) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_from(a: anything) -> Dynamic + +/// Unsafely casts a Dynamic value into any other type. +/// +/// This is an escape hatch for the type system that may be useful when wrapping +/// native Erlang APIs. It is to be used as a last measure only! +/// +/// If you can avoid using this function, do! +/// +pub fn unsafe_coerce(a: Dynamic) -> anything { + do_unsafe_coerce(a) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_unsafe_coerce(a: Dynamic) -> a + +/// Decodes a `Dynamic` value from a `Dynamic` value. +/// +/// This function doesn't seem very useful at first, but it can be convenient +/// when you need to give a decoder function but you don't actually care what +/// the to-decode value is. +/// +pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { + Ok(value) +} + +/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit +/// array if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bit_array(from("Hello")) == bit_array.from_string("Hello") +/// True +/// ``` +/// +/// ```gleam +/// > bit_array(from(123)) +/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) +/// ``` +/// +pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { + decode_bit_array(data) +} + +@deprecated("Please use `bit_array` instead") +pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { + bit_array(data) +} + +@external(erlang, "gleam_stdlib", "decode_bit_array") +@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") +fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a string, and returns that string if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > string(from("Hello")) +/// Ok("Hello") +/// ``` +/// +/// ```gleam +/// > string(from(123)) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { + decode_string(data) +} + +fn map_errors( + result: Result(t, DecodeErrors), + f: fn(DecodeError) -> DecodeError, +) -> Result(t, DecodeErrors) { + result.map_error(result, list.map(_, f)) +} + +@target(erlang) +fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { + bit_array(data) + |> map_errors(put_expected(_, "String")) + |> result.try(fn(raw) { + case bit_array.to_string(raw) { + Ok(string) -> Ok(string) + Error(Nil) -> + Error([DecodeError(expected: "String", found: "BitArray", path: [])]) + } + }) +} + +@target(erlang) +fn put_expected(error: DecodeError, expected: String) -> DecodeError { + DecodeError(..error, expected: expected) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "decode_string") +fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) + +/// Return a string indicating the type of the dynamic value. +/// +/// ```gleam +/// > classify(from("Hello")) +/// "String" +/// ``` +/// +pub fn classify(data: Dynamic) -> String { + do_classify(data) +} + +@external(erlang, "gleam_stdlib", "classify_dynamic") +@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") +fn do_classify(a: Dynamic) -> String + +/// Checks to see whether a `Dynamic` value is an int, and returns that int if it +/// is. +/// +/// ## Examples +/// +/// ```gleam +/// > int(from(123)) +/// Ok(123) +/// ``` +/// +/// ```gleam +/// > int(from("Hello")) +/// Error([DecodeError(expected: "Int", found: "String", path: [])]) +/// ``` +/// +pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { + decode_int(data) +} + +@external(erlang, "gleam_stdlib", "decode_int") +@external(javascript, "../gleam_stdlib.mjs", "decode_int") +fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a float, and returns that float if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > float(from(2.0)) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > float(from(123)) +/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) +/// ``` +/// +pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { + decode_float(data) +} + +@external(erlang, "gleam_stdlib", "decode_float") +@external(javascript, "../gleam_stdlib.mjs", "decode_float") +fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bool(from(True)) +/// Ok(True) +/// ``` +/// +/// ```gleam +/// > bool(from(123)) +/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) +/// ``` +/// +pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { + decode_bool(data) +} + +@external(erlang, "gleam_stdlib", "decode_bool") +@external(javascript, "../gleam_stdlib.mjs", "decode_bool") +fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a list, and returns that list if it +/// is. The types of the elements are not checked. +/// +/// If you wish to decode all the elements in the list use the `list` function +/// instead. +/// +/// ## Examples +/// +/// ```gleam +/// > shallow_list(from(["a", "b", "c"])) +/// Ok([from("a"), from("b"), from("c")]) +/// ``` +/// +/// ```gleam +/// > shallow_list(1) +/// Error([DecodeError(expected: "List", found: "Int", path: [])]) +/// ``` +/// +pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { + decode_list(value) +} + +@external(erlang, "gleam_stdlib", "decode_list") +@external(javascript, "../gleam_stdlib.mjs", "decode_list") +fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_result") +@external(javascript, "../gleam_stdlib.mjs", "decode_result") +fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a result of a particular type, and +/// returns that result if it is. +/// +/// The `ok` and `error` arguments are decoders for decoding the `Ok` and +/// `Error` values of the result. +/// +/// ## Examples +/// +/// ```gleam +/// > from(Ok(1)) +/// > |> result(ok: int, error: string) +/// Ok(Ok(1)) +/// ``` +/// +/// ```gleam +/// > from(Error("boom")) +/// > |> result(ok: int, error: string) +/// Ok(Error("boom")) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> result(ok: int, error: string) +/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) +/// ``` +/// +pub fn result( + ok decode_ok: Decoder(a), + error decode_error: Decoder(e), +) -> Decoder(Result(a, e)) { + fn(value) { + use inner_result <- result.try(decode_result(value)) + + case inner_result { + Ok(raw) -> { + use value <- result.try( + decode_ok(raw) + |> map_errors(push_path(_, "ok")), + ) + Ok(Ok(value)) + } + Error(raw) -> { + use value <- result.try( + decode_error(raw) + |> map_errors(push_path(_, "error")), + ) + Ok(Error(value)) + } + } + } +} + +/// Checks to see whether a `Dynamic` value is a list of a particular type, and +/// returns that list if it is. +/// +/// The second argument is a decoder function used to decode the elements of +/// the list. The list is only decoded if all elements in the list can be +/// successfully decoded using this function. +/// +/// If you do not wish to decode all the elements in the list use the `shallow_list` +/// function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > from(["a", "b", "c"]) +/// > |> list(of: string) +/// Ok(["a", "b", "c"]) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> list(of: string) +/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) +/// ``` +/// +/// ```gleam +/// > from("ok") +/// > |> list(of: string) +/// Error([DecodeError(expected: "List", found: "String", path: [])]) +/// ``` +/// +pub fn list( + of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), +) -> Decoder(List(inner)) { + fn(dynamic) { + use list <- result.try(shallow_list(dynamic)) + list + |> list.try_map(decoder_type) + |> map_errors(push_path(_, "*")) + } +} + +/// Checks to see if a `Dynamic` value is a nullable version of a particular +/// type, and returns a corresponding `Option` if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("null")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("nil")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("undefined")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> optional(string) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { + fn(value) { decode_optional(value, decode) } +} + +@external(erlang, "gleam_stdlib", "decode_option") +@external(javascript, "../gleam_stdlib.mjs", "decode_option") +fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) + +/// Checks to see if a `Dynamic` value is a map with a specific field, and returns +/// the value of that field if it is. +/// +/// This will not succeed on a record. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> dict.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok("World") +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { + fn(value) { + let missing_field_error = + DecodeError(expected: "field", found: "nothing", path: []) + + use maybe_inner <- result.try(decode_field(value, name)) + maybe_inner + |> option.to_result([missing_field_error]) + |> result.try(inner_type) + |> map_errors(push_path(_, name)) + } +} + +/// Checks to see if a `Dynamic` value is a map with a specific field. +/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, +/// returns the decoded field wrapped in `Some(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> dict.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(Some("World")) +/// ``` +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn optional_field( + named name: a, + of inner_type: Decoder(t), +) -> Decoder(Option(t)) { + fn(value) { + use maybe_inner <- result.try(decode_field(value, name)) + case maybe_inner { + option.None -> Ok(option.None) + option.Some(dynamic_inner) -> + dynamic_inner + |> decode_optional(inner_type) + |> map_errors(push_path(_, name)) + } + } +} + +@external(erlang, "gleam_stdlib", "decode_field") +@external(javascript, "../gleam_stdlib.mjs", "decode_field") +fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) + +/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain +/// index, and returns the value of that index if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(0, int) +/// Ok(from(1)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(2, int) +/// Error([ +/// DecodeError( +/// expected: "Tuple of at least 3 elements", +/// found: "Tuple of 2 elements", +/// path: [], +/// ), +/// ]) +/// ``` +/// +pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { + fn(data: Dynamic) { + use tuple <- result.try(decode_tuple(data)) + let size = tuple_size(tuple) + use data <- result.try(case index >= 0 { + True -> + case index < size { + True -> tuple_get(tuple, index) + False -> at_least_decode_tuple_error(index + 1, data) + } + False -> + case int.absolute_value(index) <= size { + True -> tuple_get(tuple, size + index) + False -> at_least_decode_tuple_error(int.absolute_value(index), data) + } + }) + inner_type(data) + |> map_errors(push_path(_, index)) + } +} + +fn at_least_decode_tuple_error( + size: Int, + data: Dynamic, +) -> Result(a, DecodeErrors) { + let s = case size { + 1 -> "" + _ -> "s" + } + let error = + ["Tuple of at least ", int.to_string(size), " element", s] + |> string_builder.from_strings + |> string_builder.to_string + |> DecodeError(found: classify(data), path: []) + Error([error]) +} + +// A tuple of unknown size +type UnknownTuple + +@external(erlang, "gleam_stdlib", "decode_tuple") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") +fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple2") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") +fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple3") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") +fn decode_tuple3( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple4") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") +fn decode_tuple4( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple5") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") +fn decode_tuple5( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple6") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") +fn decode_tuple6( + a: Dynamic, +) -> Result( + #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), + DecodeErrors, +) + +@external(erlang, "gleam_stdlib", "tuple_get") +@external(javascript, "../gleam_stdlib.mjs", "tuple_get") +fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) + +@external(erlang, "gleam_stdlib", "size_of_tuple") +@external(javascript, "../gleam_stdlib.mjs", "length") +fn tuple_size(a: UnknownTuple) -> Int + +fn tuple_errors( + result: Result(a, List(DecodeError)), + name: String, +) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> list.map(errors, push_path(_, name)) + } +} + +fn push_path(error: DecodeError, name: t) -> DecodeError { + let name = from(name) + let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) + let name = case decoder(name) { + Ok(name) -> name + Error(_) -> + ["<", classify(name), ">"] + |> string_builder.from_strings + |> string_builder.to_string + } + DecodeError(..error, path: [name, ..error.path]) +} + +/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0)) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from([1, 2]) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0)]) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple2(int, float) +/// Error([ +/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple2(int, float) +/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple2( + first decode1: Decoder(a), + second decode2: Decoder(b), +) -> Decoder(#(a, b)) { + fn(value) { + use #(a, b) <- result.try(decode_tuple2(value)) + case decode1(a), decode2(b) { + Ok(a), Ok(b) -> Ok(#(a, b)) + a, b -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3")]) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple3( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), +) -> Decoder(#(a, b, c)) { + fn(value) { + use #(a, b, c) <- result.try(decode_tuple3(value)) + case decode1(a), decode2(b), decode3(c) { + Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) + a, b, c -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4)) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4)) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4]) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4)]) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple4( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), +) -> Decoder(#(a, b, c, d)) { + fn(value) { + use #(a, b, c, d) <- result.try(decode_tuple4(value)) + case decode1(a), decode2(b), decode3(c), decode4(d) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) + a, b, c, d -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5)) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5)) +/// > |> tuple5(int, float, string, int, int) +/// Ok(#(1, 2.0, "3", 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5]) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) +/// > |> tuple5(int, float, string, int, bool) +/// Ok(#(1, 2.0, "3", 4, True)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple5(int, float, string, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple5(int, float, string, int, int) +/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple5( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), +) -> Decoder(#(a, b, c, d, e)) { + fn(value) { + use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) + case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) + a, b, c, d, e -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5, 6)) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5, 6)) +/// > |> tuple6(int, float, string, int, int, int) +/// Ok(#(1, 2.0, "3", 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5, 6]) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) +/// > |> tuple6(int, float, string, int, bool, bool) +/// Ok(#(1, 2.0, "3", 4, True, False)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple6(int, float, string, int, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple6(int, float, string, int, int, int) +/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple6( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), + sixth decode6: Decoder(f), +) -> Decoder(#(a, b, c, d, e, f)) { + fn(value) { + use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) + case + decode1(a), + decode2(b), + decode3(c), + decode4(d), + decode5(e), + decode6(f) + { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) + a, b, c, d, e, f -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> list.append(tuple_errors(f, "5")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a dict. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() |> from |> map(string, int) +/// Ok(dict.new()) +/// ``` +/// +/// ```gleam +/// > from(1) |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "Int", path: [])) +/// ``` +/// +/// ```gleam +/// > from("") |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "String", path: [])) +/// ``` +/// +pub fn dict( + of key_type: Decoder(k), + to value_type: Decoder(v), +) -> Decoder(Dict(k, v)) { + fn(value) { + use map <- result.try(decode_map(value)) + use pairs <- result.try( + map + |> dict.to_list + |> list.try_map(fn(pair) { + let #(k, v) = pair + use k <- result.try( + key_type(k) + |> map_errors(push_path(_, "keys")), + ) + use v <- result.try( + value_type(v) + |> map_errors(push_path(_, "values")), + ) + Ok(#(k, v)) + }), + ) + Ok(dict.from_list(pairs)) + } +} + +@deprecated("Use `dict` instead") +pub fn map( + of key_type: Decoder(k), + to value_type: Decoder(v), +) -> Decoder(Dict(k, v)) { + dict(key_type, value_type) +} + +@external(erlang, "gleam_stdlib", "decode_map") +@external(javascript, "../gleam_stdlib.mjs", "decode_map") +fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) + +/// Joins multiple decoders into one. When run they will each be tried in turn +/// until one succeeds, or they all fail. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/result +/// > let bool_or_string = any(of: [ +/// > string, +/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } +/// > ]) +/// > bool_or_string(from("ok")) +/// Ok("ok") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(True)) +/// Ok("a bool") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(1)) +/// Error(DecodeError(expected: "another type", found: "Int", path: [])) +/// ``` +/// +pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { + fn(data) { + case decoders { + [] -> + Error([ + DecodeError(found: classify(data), expected: "another type", path: []), + ]) + + [decoder, ..decoders] -> + case decoder(data) { + Ok(decoded) -> Ok(decoded) + Error(_) -> any(decoders)(data) + } + } + } +} + +/// Decode 1 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode1(MyRecord, element(0, int)) +/// Ok(MyRecord(1)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode1(MyRecord, element(0, int)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// ]) +/// ``` +/// +pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { + fn(value) { + case t1(value) { + Ok(a) -> Ok(constructor(a)) + a -> Error(all_errors(a)) + } + } +} + +/// Decode 2 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Ok(MyRecord(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode2( + constructor: fn(t1, t2) -> t, + t1: Decoder(t1), + t2: Decoder(t2), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value) { + Ok(a), Ok(b) -> Ok(constructor(a, b)) + a, b -> Error(list.concat([all_errors(a), all_errors(b)])) + } + } +} + +/// Decode 3 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Ok(MyRecord(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode3( + constructor: fn(t1, t2, t3) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value), t3(value) { + Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) + a, b, c -> + Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) + } + } +} + +/// Decode 4 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode4( + constructor: fn(t1, t2, t3, t4) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) + a, b, c, d -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + ])) + } + } +} + +/// Decode 5 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode5( + constructor: fn(t1, t2, t3, t4, t5) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) + a, b, c, d, e -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + ])) + } + } +} + +/// Decode 6 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode6( + constructor: fn(t1, t2, t3, t4, t5, t6) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> + Ok(constructor(a, b, c, d, e, f)) + a, b, c, d, e, f -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + ])) + } + } +} + +/// Decode 7 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode7( + constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> + Ok(constructor(a, b, c, d, e, f, g)) + a, b, c, d, e, f, g -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + ])) + } + } +} + +/// Decode 8 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode8( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> + Ok(constructor(a, b, c, d, e, f, g, h)) + a, b, c, d, e, f, g, h -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + ])) + } + } +} + +/// Decode 9 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "", "")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode9( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), + t9: Decoder(t9), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> + Ok(constructor(a, b, c, d, e, f, g, h, i)) + a, b, c, d, e, f, g, h, i -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + all_errors(i), + ])) + } + } +} + +fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> errors + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam new file mode 100644 index 00000000000..5d62419fd0d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam @@ -0,0 +1,546 @@ +//// Functions for working with floats. +//// +//// ## Division by zero +//// +//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE +//// 754 standard for floating point arithmetic and does not have an `Infinity` +//// value. In Erlang division by zero results in a crash, however Gleam does +//// not have partial functions and operators in core so instead division by zero +//// returns zero, a behaviour taken from Pony, Coq, and Lean. +//// +//// This may seem unexpected at first, but it is no less mathematically valid +//// than crashing or returning a special value. Division by zero is undefined +//// in mathematics. + +import gleam/order.{type Order} + +/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was +/// not possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2.3") +/// Ok(2.3) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Float, Nil) { + do_parse(string) +} + +@external(erlang, "gleam_stdlib", "parse_float") +@external(javascript, "../gleam_stdlib.mjs", "parse_float") +fn do_parse(a: String) -> Result(Float, Nil) + +/// Returns the string representation of the provided `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2.3) +/// "2.3" +/// ``` +/// +pub fn to_string(x: Float) -> String { + do_to_string(x) +} + +@external(erlang, "gleam_stdlib", "float_to_string") +@external(javascript, "../gleam_stdlib.mjs", "float_to_string") +fn do_to_string(a: Float) -> String + +/// Restricts a `Float` between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(1.2, min: 1.4, max: 1.6) +/// 1.4 +/// ``` +/// +pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two `Float`s, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2.0, 2.3) +/// Lt +/// ``` +/// +/// To handle +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) +/// you may use [`loosely_compare`](#loosely_compare) instead. +/// +pub fn compare(a: Float, with b: Float) -> Order { + case a == b { + True -> order.Eq + False -> + case a <. b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two `Float`s within a tolerance, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) +/// Eq +/// ``` +/// +/// If you want to check only for equality you may use +/// [`loosely_equals`](#loosely_equals) instead. +/// +pub fn loosely_compare( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Order { + let difference = absolute_value(a -. b) + case difference <=. tolerance { + True -> order.Eq + False -> compare(a, b) + } +} + +/// Checks for equality of two `Float`s within a tolerance, +/// returning an `Bool`. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) +/// True +/// ``` +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) +/// False +/// ``` +/// +pub fn loosely_equals( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Bool { + let difference = absolute_value(a -. b) + difference <=. tolerance +} + +/// Compares two `Float`s, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2.0, 2.3) +/// 2.0 +/// ``` +/// +pub fn min(a: Float, b: Float) -> Float { + case a <. b { + True -> a + False -> b + } +} + +/// Compares two `Float`s, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2.0, 2.3) +/// 2.3 +/// ``` +/// +pub fn max(a: Float, b: Float) -> Float { + case a >. b { + True -> a + False -> b + } +} + +/// Rounds the value to the next highest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > ceiling(2.3) +/// 3.0 +/// ``` +/// +pub fn ceiling(x: Float) -> Float { + do_ceiling(x) +} + +@external(erlang, "math", "ceil") +@external(javascript, "../gleam_stdlib.mjs", "ceiling") +fn do_ceiling(a: Float) -> Float + +/// Rounds the value to the next lowest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor(2.3) +/// 2.0 +/// ``` +/// +pub fn floor(x: Float) -> Float { + do_floor(x) +} + +@external(erlang, "math", "floor") +@external(javascript, "../gleam_stdlib.mjs", "floor") +fn do_floor(a: Float) -> Float + +/// Rounds the value to the nearest whole number as an `Int`. +/// +/// ## Examples +/// +/// ```gleam +/// > round(2.3) +/// 2 +/// ``` +/// +/// ```gleam +/// > round(2.5) +/// 3 +/// ``` +/// +pub fn round(x: Float) -> Int { + do_round(x) +} + +@target(erlang) +@external(erlang, "erlang", "round") +fn do_round(a: Float) -> Int + +@target(javascript) +fn do_round(x: Float) -> Int { + case x >=. 0.0 { + True -> js_round(x) + _ -> 0 - js_round(negate(x)) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "round") +fn js_round(a: Float) -> Int + +/// Returns the value as an `Int`, truncating all decimal digits. +/// +/// ## Examples +/// +/// ```gleam +/// > truncate(2.4343434847383438) +/// 2 +/// ``` +/// +pub fn truncate(x: Float) -> Int { + do_truncate(x) +} + +@external(erlang, "erlang", "trunc") +@external(javascript, "../gleam_stdlib.mjs", "truncate") +fn do_truncate(a: Float) -> Int + +/// Returns the absolute value of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12.5) +/// 12.5 +/// ``` +/// +/// ```gleam +/// > absolute_value(10.2) +/// 10.2 +/// ``` +/// +pub fn absolute_value(x: Float) -> Float { + case x >=. 0.0 { + True -> x + _ -> 0.0 -. x + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2.0, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2.0, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8.0, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4.0 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1.0, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { + let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 + // In the following check: + // 1. If the base is negative and the exponent is fractional then + // return an error as it will otherwise be an imaginary number + // 2. If the base is 0 and the exponent is negative then the expression + // is equivalent to the exponent divided by 0 and an error should be + // returned + case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { + True -> Error(Nil) + False -> Ok(do_power(base, exponent)) + } +} + +@external(erlang, "math", "pow") +@external(javascript, "../gleam_stdlib.mjs", "power") +fn do_power(a: Float, b: Float) -> Float + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4.0) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16.0) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Float) -> Result(Float, Nil) { + power(x, 0.5) +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1.0) +/// -1.0 +/// ``` +/// +pub fn negate(x: Float) -> Float { + -1.0 *. x +} + +/// Sums a list of `Float`s. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1.0, 2.2, 3.3]) +/// 6.5 +/// ``` +/// +pub fn sum(numbers: List(Float)) -> Float { + numbers + |> do_sum(0.0) +} + +fn do_sum(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x +. initial) + } +} + +/// Multiplies a list of `Float`s and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2.5, 3.2, 4.2]) +/// 33.6 +/// ``` +/// +pub fn product(numbers: List(Float)) -> Float { + case numbers { + [] -> 1.0 + _ -> do_product(numbers, 1.0) + } +} + +fn do_product(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x *. initial) + } +} + +/// Generates a random float between the given minimum and maximum values. +/// +/// +/// ## Examples +/// +/// ```gleam +/// > random(1.0, 5.0) +/// 2.646355926896028 +/// ``` +/// +pub fn random(min: Float, max: Float) -> Float { + do_random_uniform() *. { max -. min } +. min +} + +/// Returns a random float uniformly distributed in the value range +/// 0.0 =< X < 1.0 and updates the state in the process dictionary. +/// See: +/// +@external(erlang, "rand", "uniform") +@external(javascript, "../gleam_stdlib.mjs", "random_uniform") +fn do_random_uniform() -> Float + +/// Returns division of the inputs as a `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0.0, 1.0) +/// Ok(1.0) +/// ``` +/// +/// ```gleam +/// > divide(1.0, 0.0) +/// Error(Nil) +/// ``` +/// +pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { + case b { + 0.0 -> Error(Nil) + b -> Ok(a /. b) + } +} + +/// Adds two floats together. +/// +/// It's the function equivalent of the `+.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1.0, 2.0) +/// 3.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 0.0, add) +/// 6.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> add(2.0) +/// 5.0 +/// ``` +/// +pub fn add(a: Float, b: Float) -> Float { + a +. b +} + +/// Multiplies two floats together. +/// +/// It's the function equivalent of the `*.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2.0, 4.0) +/// 8.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) +/// 24.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> multiply(2.0) +/// 6.0 +/// ``` +/// +pub fn multiply(a: Float, b: Float) -> Float { + a *. b +} + +/// Subtracts one float from another. +/// +/// It's the function equivalent of the `-.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3.0, 1.0) +/// 2.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) +/// 4.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(_, 2.0) +/// 1.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(2.0, _) +/// -1.0 +/// ``` +/// +pub fn subtract(a: Float, b: Float) -> Float { + a -. b +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam new file mode 100644 index 00000000000..daa997de92a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam @@ -0,0 +1,162 @@ +/// Takes two functions and chains them together to form one function that +/// takes the input from the first and returns the output of the second. +/// +pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { + fn(a) { fun2(fun1(a)) } +} + +/// Takes a function with `2` arguments (an arity of `2`), and returns the +/// curried equivalent. +/// +/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. +/// +/// ## Examples +/// +/// *Currying* creates a new function that is identical to the given function +/// except that arguments must now be supplied one by one over several function +/// calls. It thus is the process of taking a function with `n` arguments +/// and producing a sequence of `n` single-argument functions. Given: +/// +/// ```gleam +/// > fn my_fun(i: Int, s: String) -> String { ... } +/// ``` +/// +/// …calling `curry2(my_fun)` would return the curried equivalent, like so: +/// +/// ```gleam +/// > curry2(my_fun) +/// fn(Int) -> fn(String) -> String +/// ``` +/// +/// Currying is useful when you want to partially apply a function with +/// some arguments and then pass it somewhere else, for example: +/// +/// ```gleam +/// > import gleam/list +/// > let multiply = curry2(fn(x, y) { x * y }) +/// > let doubles = list.map([1, 2, 3], multiply(2)) +/// [2, 4, 6] +/// ``` +/// +pub fn curry2(fun: fn(a, b) -> value) { + fn(a) { fn(b) { fun(a, b) } } +} + +/// Takes a function with `3` arguments (an arity of `3`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry3(fun: fn(a, b, c) -> value) { + fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } +} + +/// Takes a function with `4` arguments (an arity of `4`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry4(fun: fn(a, b, c, d) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } +} + +/// Takes a function with `5` arguments (an arity of `5`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e) -> f` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry5(fun: fn(a, b, c, d, e) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } +} + +/// Takes a function with `6` arguments (an arity of `6`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e, f) -> g` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { + fn(a) { + fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } + } +} + +/// Takes a function that takes two arguments and returns a new function that +/// takes the same two arguments, but in reverse order. +/// +pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { + fn(b, a) { fun(a, b) } +} + +/// Takes a single argument and always returns its input value. +/// +pub fn identity(x: a) -> a { + x +} + +/// Takes a single argument and returns a new function that +/// ignores its argument and always returns the input value. +/// +pub fn constant(value: a) -> fn(b) -> a { + fn(_) { value } +} + +/// Takes an argument and a single function, +/// calls that function with that argument +/// and returns that argument instead of the function return value. +/// Useful for running synchronous side effects in a pipeline. +/// +pub fn tap(arg: a, effect: fn(a) -> b) -> a { + effect(arg) + arg +} + +/// Takes a function with arity one and an argument, +/// calls that function with the argument and returns the function return value. +/// +/// Useful for concisely calling functions returned as a part of a pipeline. +/// +/// ## Example +/// +/// ```gleam +/// > let doubler = fn() { +/// > fn(x: Int) { x * 2 } +/// > } +/// > +/// > doubler() +/// > |> apply1(2) +/// 4 +/// ``` +/// +pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { + fun(arg1) +} + +/// Takes a function with arity two and two arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { + fun(arg1, arg2) +} + +/// Takes a function with arity three and three arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { + fun(arg1, arg2, arg3) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam new file mode 100644 index 00000000000..d93c16afaf6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam @@ -0,0 +1,874 @@ +//// Functions for working with integers. +//// +//// ## Division by zero +//// +//// In Erlang division by zero results in a crash, however Gleam does not have +//// partial functions and operators in core so instead division by zero returns +//// zero, a behaviour taken from Pony, Coq, and Lean. +//// +//// This may seem unexpected at first, but it is no less mathematically valid +//// than crashing or returning a special value. Division by zero is undefined +//// in mathematics. + +import gleam/float +import gleam/order.{type Order} + +/// Returns the absolute value of the input. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12) +/// 12 +/// ``` +/// +/// ```gleam +/// > absolute_value(10) +/// 10 +/// ``` +/// +pub fn absolute_value(x: Int) -> Int { + case x >= 0 { + True -> x + False -> x * -1 + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { + base + |> to_float() + |> float.power(exponent) +} + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Int) -> Result(Float, Nil) { + x + |> to_float() + |> float.square_root() +} + +/// Parses a given string as an int if possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2") +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Int, Nil) { + do_parse(string) +} + +@external(erlang, "gleam_stdlib", "parse_int") +@external(javascript, "../gleam_stdlib.mjs", "parse_int") +fn do_parse(a: String) -> Result(Int, Nil) + +/// Parses a given string as an int in a given base if possible. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > base_parse("10", 2) +/// Ok(2) +/// +/// > base_parse("30", 16) +/// Ok(48) +/// +/// > base_parse("1C", 36) +/// Ok(48) +/// +/// > base_parse("48", 1) +/// Error(Nil) +/// +/// > base_parse("48", 37) +/// Error(Nil) +/// ``` +/// +pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { + case base >= 2 && base <= 36 { + True -> do_base_parse(string, base) + False -> Error(Nil) + } +} + +@external(erlang, "gleam_stdlib", "int_from_base_string") +@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") +fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) + +/// Prints a given int to a string. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2) +/// "2" +/// ``` +/// +pub fn to_string(x: Int) { + do_to_string(x) +} + +@external(erlang, "erlang", "integer_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "to_string") +fn do_to_string(a: Int) -> String + +/// Error value when trying to operate with a base out of the allowed range. +/// +pub type InvalidBase { + InvalidBase +} + +/// Prints a given int to a string using the base number provided. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. +/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base_string(2, 2) +/// Ok("10") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 16) +/// Ok("30") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 36) +/// Ok("1C") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 37) +/// Error(InvalidBase) +/// ``` +/// +pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { + case base >= 2 && base <= 36 { + True -> Ok(do_to_base_string(x, base)) + False -> Error(InvalidBase) + } +} + +@external(erlang, "erlang", "integer_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") +fn do_to_base_string(a: Int, b: Int) -> String + +/// Prints a given int to a string using base-2. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base2(2) +/// "10" +/// ``` +/// +pub fn to_base2(x: Int) -> String { + do_to_base_string(x, 2) +} + +/// Prints a given int to a string using base-8. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base8(15) +/// "17" +/// ``` +/// +pub fn to_base8(x: Int) -> String { + do_to_base_string(x, 8) +} + +/// Prints a given int to a string using base-16. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base16(48) +/// "30" +/// ``` +/// +pub fn to_base16(x: Int) -> String { + do_to_base_string(x, 16) +} + +/// Prints a given int to a string using base-36. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base36(48) +/// "1C" +/// ``` +/// +pub fn to_base36(x: Int) -> String { + do_to_base_string(x, 36) +} + +/// Takes an int and returns its value as a float. +/// +/// ## Examples +/// +/// ```gleam +/// > to_float(5) +/// 5.0 +/// ``` +/// +/// ```gleam +/// > to_float(0) +/// 0.0 +/// ``` +/// +/// ```gleam +/// > to_float(-3) +/// -3.0 +/// ``` +/// +pub fn to_float(x: Int) -> Float { + do_to_float(x) +} + +@external(erlang, "erlang", "float") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_to_float(a: Int) -> Float + +/// Restricts an int between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(40, min: 50, max: 60) +/// 50 +/// ``` +/// +pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two ints, returning an order. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2, 3) +/// Lt +/// ``` +/// +/// ```gleam +/// > compare(4, 3) +/// Gt +/// ``` +/// +/// ```gleam +/// > compare(3, 3) +/// Eq +/// ``` +/// +pub fn compare(a: Int, with b: Int) -> Order { + case a == b { + True -> order.Eq + False -> + case a < b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two ints, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2, 3) +/// 2 +/// ``` +/// +pub fn min(a: Int, b: Int) -> Int { + case a < b { + True -> a + False -> b + } +} + +/// Compares two ints, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2, 3) +/// 3 +/// ``` +/// +pub fn max(a: Int, b: Int) -> Int { + case a > b { + True -> a + False -> b + } +} + +/// Returns whether the value provided is even. +/// +/// ## Examples +/// +/// ```gleam +/// > is_even(2) +/// True +/// ``` +/// +/// ```gleam +/// > is_even(3) +/// False +/// ``` +/// +pub fn is_even(x: Int) -> Bool { + x % 2 == 0 +} + +/// Returns whether the value provided is odd. +/// +/// ## Examples +/// +/// ```gleam +/// > is_odd(3) +/// True +/// ``` +/// +/// ```gleam +/// > is_odd(2) +/// False +/// ``` +/// +pub fn is_odd(x: Int) -> Bool { + x % 2 != 0 +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1) +/// -1 +/// ``` +/// +pub fn negate(x: Int) -> Int { + -1 * x +} + +/// Sums a list of ints. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1, 2, 3]) +/// 6 +/// ``` +/// +pub fn sum(numbers: List(Int)) -> Int { + numbers + |> do_sum(0) +} + +fn do_sum(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x + initial) + } +} + +/// Multiplies a list of ints and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2, 3, 4]) +/// 24 +/// ``` +/// +pub fn product(numbers: List(Int)) -> Int { + case numbers { + [] -> 1 + _ -> do_product(numbers, 1) + } +} + +fn do_product(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x * initial) + } +} + +/// Splits an integer into its digit representation in the specified base +/// +/// ## Examples +/// +/// ```gleam +/// > digits(234, 10) +/// Ok([2,3,4]) +/// ``` +/// +/// ```gleam +/// > digits(234, 1) +/// Error(InvalidBase) +/// ``` +/// +pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> Ok(do_digits(x, base, [])) + } +} + +fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { + case absolute_value(x) < base { + True -> [x, ..acc] + False -> do_digits(x / base, base, [x % base, ..acc]) + } +} + +/// Joins a list of digits into a single value. +/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. +/// +/// ## Examples +/// +/// ```gleam +/// > undigits([2,3,4], 10) +/// Ok(234) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 2) +/// Error(InvalidBase) +/// ``` +/// +pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> do_undigits(numbers, base, 0) + } +} + +fn do_undigits( + numbers: List(Int), + base: Int, + acc: Int, +) -> Result(Int, InvalidBase) { + case numbers { + [] -> Ok(acc) + [digit, ..] if digit >= base -> Error(InvalidBase) + [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) + } +} + +/// Generates a random int between the given minimum and maximum values. +/// +/// ## Examples +/// +/// ```gleam +/// > random(1, 5) +/// 2 +/// ``` +/// +pub fn random(min: Int, max: Int) -> Int { + float.random(to_float(min), to_float(max)) + |> float.floor() + |> float.round() +} + +/// Performs a truncated integer division. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0, 1) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > divide(-99, 2) +/// Ok(-49) +/// ``` +/// +pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend / divisor) + } +} + +/// Computes the remainder of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > remainder(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > remainder(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: 3) +/// Ok(-1) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: -3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend % divisor) + } +} + +/// Computes the modulo of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > modulo(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > modulo(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: 3) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: -3) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + _ -> { + let remainder = dividend % divisor + case remainder * divisor < 0 { + True -> Ok(remainder + divisor) + False -> Ok(remainder) + } + } + } +} + +/// Performs a *floored* integer division, which means that the result will +/// always be rounded towards negative infinity. +/// +/// If you want to perform truncated integer division (rounding towards zero), +/// use `int.divide()` or the `/` operator instead. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor_divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > floor_divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > floor_divide(6, -4) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > floor_divide(-99, 2) +/// Ok(-50) +/// ``` +/// +pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> + case dividend * divisor < 0 && dividend % divisor != 0 { + True -> Ok(dividend / divisor - 1) + False -> Ok(dividend / divisor) + } + } +} + +/// Adds two integers together. +/// +/// It's the function equivalent of the `+` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1, 2) +/// 3 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 0, add) +/// 6 +/// ``` +/// +/// ```gleam +/// > 3 |> add(2) +/// 5 +/// ``` +/// +pub fn add(a: Int, b: Int) -> Int { + a + b +} + +/// Multiplies two integers together. +/// +/// It's the function equivalent of the `*` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2, 4) +/// 8 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2, 3, 4], 1, multiply) +/// 24 +/// ``` +/// +/// ```gleam +/// > 3 |> multiply(2) +/// 6 +/// ``` +/// +pub fn multiply(a: Int, b: Int) -> Int { + a * b +} + +/// Subtracts one int from another. +/// +/// It's the function equivalent of the `-` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3, 1) +/// 2.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 10, subtract) +/// 4 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2) +/// 1 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2, _) +/// -1 +/// ``` +/// +pub fn subtract(a: Int, b: Int) -> Int { + a - b +} + +/// Calculates the bitwise AND of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "band") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") +pub fn bitwise_and(x: Int, y: Int) -> Int + +/// Calculates the bitwise NOT of its argument. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bnot") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") +pub fn bitwise_not(x: Int) -> Int + +/// Calculates the bitwise OR of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bor") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") +pub fn bitwise_or(x: Int, y: Int) -> Int + +/// Calculates the bitwise XOR of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bxor") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") +pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int + +/// Calculates the result of an arithmetic left bitshift. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bsl") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") +pub fn bitwise_shift_left(x: Int, y: Int) -> Int + +/// Calculates the result of an arithmetic right bitshift. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bsr") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") +pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam new file mode 100644 index 00000000000..0c0a3eeffe0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam @@ -0,0 +1,117 @@ +import gleam/string + +/// Writes a string to standard output. +/// +/// If you want your output to be printed on its own line see `println`. +/// +/// ## Example +/// +/// ```gleam +/// > io.print("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn print(string: String) -> Nil { + do_print(string) +} + +@external(erlang, "gleam_stdlib", "print") +@external(javascript, "../gleam_stdlib.mjs", "print") +fn do_print(string string: String) -> Nil + +/// Writes a string to standard error. +/// +/// If you want your output to be printed on its own line see `println_error`. +/// +/// ## Example +/// +/// ``` +/// > io.print_error("Hi pop") +/// // -> Hi pop +/// Nil +/// ``` +/// +pub fn print_error(string: String) -> Nil { + do_print_error(string) +} + +@external(erlang, "gleam_stdlib", "print_error") +@external(javascript, "../gleam_stdlib.mjs", "print_error") +fn do_print_error(string string: String) -> Nil + +/// Writes a string to standard output, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println(string: String) -> Nil { + do_println(string) +} + +@external(erlang, "gleam_stdlib", "println") +@external(javascript, "../gleam_stdlib.mjs", "console_log") +fn do_println(string string: String) -> Nil + +/// Writes a string to standard error, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println_error("Hi pop") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println_error(string: String) -> Nil { + do_println_error(string) +} + +@external(erlang, "gleam_stdlib", "println_error") +@external(javascript, "../gleam_stdlib.mjs", "console_error") +fn do_println_error(string string: String) -> Nil + +/// Prints a value to standard error (stderr) yielding Gleam syntax. +/// +/// The value is returned after being printed so it can be used in pipelines. +/// +/// ## Example +/// +/// ```gleam +/// > debug("Hi mum") +/// // -> <<"Hi mum">> +/// "Hi mum" +/// ``` +/// +/// ```gleam +/// > debug(Ok(1)) +/// // -> {ok, 1} +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > import list +/// > [1, 2] +/// > |> list.map(fn(x) { x + 1 }) +/// > |> debug +/// > |> list.map(fn(x) { x * 2 }) +/// // -> [2, 3] +/// [4, 6] +/// ``` +/// +pub fn debug(term: anything) -> anything { + term + |> string.inspect + |> do_debug_println + + term +} + +@external(erlang, "gleam_stdlib", "println_error") +@external(javascript, "../gleam_stdlib.mjs", "print_debug") +fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam new file mode 100644 index 00000000000..c57e7fd9473 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam @@ -0,0 +1,1530 @@ +import gleam/result +import gleam/int +import gleam/list +import gleam/dict.{type Dict} +import gleam/option.{type Option, None, Some} +import gleam/order + +// Internal private representation of an Iterator +type Action(element) { + // Dedicated to Electric Six + // https://youtu.be/_30t2dzEgiw?t=162 + Stop + Continue(element, fn() -> Action(element)) +} + +/// An iterator is a lazily evaluated sequence of element. +/// +/// Iterators are useful when working with collections that are too large to +/// fit in memory (or those that are infinite in size) as they only require the +/// elements currently being processed to be in memory. +/// +/// As a lazy data structure no work is done when an iterator is filters, +/// mapped, etc, instead a new iterator is returned with these transformations +/// applied to the stream. Once the stream has all the required transformations +/// applied it can be evaluated using functions such as `fold` and `to_list`. +/// +pub opaque type Iterator(element) { + Iterator(continuation: fn() -> Action(element)) +} + +// Public API for iteration +pub type Step(element, accumulator) { + Next(element: element, accumulator: accumulator) + Done +} + +// Shortcut for an empty iterator. +fn stop() -> Action(element) { + Stop +} + +// Creating Iterators +fn do_unfold( + initial: acc, + f: fn(acc) -> Step(element, acc), +) -> fn() -> Action(element) { + fn() { + case f(initial) { + Next(x, acc) -> Continue(x, do_unfold(acc, f)) + Done -> Stop + } + } +} + +/// Creates an iterator from a given function and accumulator. +/// +/// The function is called on the accumulator and returns either `Done`, +/// indicating the iterator has no more elements, or `Next` which contains a +/// new element and accumulator. The element is yielded by the iterator and the +/// new accumulator is used with the function to compute the next element in +/// the sequence. +/// +/// ## Examples +/// +/// ```gleam +/// > unfold(from: 5, with: fn(n) { +/// > case n { +/// > 0 -> Done +/// > n -> Next(element: n, accumulator: n - 1) +/// > } +/// > }) +/// > |> to_list +/// [5, 4, 3, 2, 1] +/// ``` +/// +pub fn unfold( + from initial: acc, + with f: fn(acc) -> Step(element, acc), +) -> Iterator(element) { + initial + |> do_unfold(f) + |> Iterator +} + +// TODO: test +/// Creates an iterator that yields values created by calling a given function +/// repeatedly. +/// +pub fn repeatedly(f: fn() -> element) -> Iterator(element) { + unfold(Nil, fn(_) { Next(f(), Nil) }) +} + +/// Creates an iterator that returns the same value infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat(10) +/// > |> take(4) +/// > |> to_list +/// [10, 10, 10, 10] +/// ``` +/// +pub fn repeat(x: element) -> Iterator(element) { + repeatedly(fn() { x }) +} + +/// Creates an iterator that yields each element from the given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn from_list(list: List(element)) -> Iterator(element) { + let yield = fn(acc) { + case acc { + [] -> Done + [head, ..tail] -> Next(head, tail) + } + } + unfold(list, yield) +} + +// Consuming Iterators +fn do_transform( + continuation: fn() -> Action(a), + state: acc, + f: fn(acc, a) -> Step(b, acc), +) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> + case f(state, el) { + Done -> Stop + Next(yield, next_state) -> + Continue(yield, do_transform(next, next_state, f)) + } + } + } +} + +/// Creates an iterator from an existing iterator +/// and a stateful function that may short-circuit. +/// +/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, +/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. +/// +/// ## Examples +/// +/// Approximate implementation of `index` in terms of `transform`: +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) +/// > |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +pub fn transform( + over iterator: Iterator(a), + from initial: acc, + with f: fn(acc, a) -> Step(b, acc), +) -> Iterator(b) { + do_transform(iterator.continuation, initial, f) + |> Iterator +} + +fn do_fold( + continuation: fn() -> Action(e), + f: fn(acc, e) -> acc, + accumulator: acc, +) -> acc { + case continuation() { + Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) + Stop -> accumulator + } +} + +/// Reduces an iterator of elements into a single value by calling a given +/// function on each element in turn. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// If you do not care about the end value and only wish to evaluate the +/// iterator for side effects consider using the `run` function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) +/// 10 +/// ``` +/// +pub fn fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> acc, +) -> acc { + iterator.continuation + |> do_fold(f, initial) +} + +// TODO: test +/// Evaluates all elements emitted by the given iterator. This function is useful for when +/// you wish to trigger any side effects that would occur when evaluating +/// the iterator. +/// +pub fn run(iterator: Iterator(e)) -> Nil { + fold(iterator, Nil, fn(_, _) { Nil }) +} + +/// Evaluates an iterator and returns all the elements as a list. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn to_list(iterator: Iterator(element)) -> List(element) { + iterator + |> fold([], fn(acc, e) { [e, ..acc] }) + |> list.reverse +} + +/// Eagerly accesses the first value of an iterator, returning a `Next` +/// that contains the first value and the rest of the iterator. +/// +/// If called on an empty iterator, `Done` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Next(first, rest) = [1, 2, 3, 4] +/// > |> from_list +/// > |> step +/// > first +/// 1 +/// ``` +/// +/// ```gleam +/// > rest |> to_list +/// [2, 3, 4] +/// ``` +/// +/// ```gleam +/// > empty() |> step +/// Done +/// ``` +/// +pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { + case iterator.continuation() { + Stop -> Done + Continue(e, a) -> Next(e, Iterator(a)) + } +} + +fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { + fn() { + case desired > 0 { + False -> Stop + True -> + case continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, do_take(next, desired - 1)) + } + } + } +} + +/// Creates an iterator that only yields the first `desired` elements. +/// +/// If the iterator does not have enough elements all of them are yielded. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2, 3] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + iterator.continuation + |> do_take(desired) + |> Iterator +} + +fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case desired > 0 { + True -> do_drop(next, desired - 1) + False -> Continue(e, next) + } + } +} + +/// Evaluates and discards the first N elements in an iterator, returning a new +/// iterator. +/// +/// If the iterator does not have enough elements an empty iterator is +/// returned. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [4, 5] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [] +/// ``` +/// +pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + fn() { do_drop(iterator.continuation, desired) } + |> Iterator +} + +fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) + } + } +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { + iterator.continuation + |> do_map(f) + |> Iterator +} + +fn do_map2( + continuation1: fn() -> Action(a), + continuation2: fn() -> Action(b), + with fun: fn(a, b) -> c, +) -> fn() -> Action(c) { + fn() { + case continuation1() { + Stop -> Stop + Continue(a, next_a) -> + case continuation2() { + Stop -> Stop + Continue(b, next_b) -> + Continue(fun(a, b), do_map2(next_a, next_b, fun)) + } + } + } +} + +/// Combines two interators into a single one using the given function. +/// +/// If an iterator is longer than the other the extra elements are dropped. +/// +/// This function does not evaluate the elements of the two iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// let first = from_list([1, 2, 3]) +/// let second = from_list([4, 5, 6]) +/// map2(first, second, fn(x, y) { x + y }) |> to_list +/// // -> [5, 7, 9] +/// ``` +/// +/// ```gleam +/// let first = from_list([1, 2]) +/// let second = from_list(["a", "b", "c"]) +/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list +/// // -> [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2( + iterator1: Iterator(a), + iterator2: Iterator(b), + with fun: fn(a, b) -> c, +) -> Iterator(c) { + do_map2(iterator1.continuation, iterator2.continuation, fun) + |> Iterator +} + +fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { + case first() { + Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) + Stop -> second() + } +} + +/// Appends two iterators, producing a new iterator. +/// +/// This function does not evaluate the elements of the iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> append([3, 4] |> from_list) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { + fn() { do_append(first.continuation, second.continuation) } + |> Iterator +} + +fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { + case flattened() { + Stop -> Stop + Continue(it, next_iterator) -> + do_append(it.continuation, fn() { do_flatten(next_iterator) }) + } +} + +/// Flattens an iterator of iterators, creating a new iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([[1, 2], [3, 4]]) +/// > |> map(from_list) +/// > |> flatten +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { + fn() { do_flatten(iterator.continuation) } + |> Iterator +} + +/// Joins a list of iterators into a single iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [[1, 2], [3, 4]] +/// > |> map(from_list) +/// > |> concat +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { + flatten(from_list(iterators)) +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator and then flattening the +/// results. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) +/// > |> to_list +/// [1, 2, 2, 3] +/// ``` +/// +pub fn flat_map( + over iterator: Iterator(a), + with f: fn(a) -> Iterator(b), +) -> Iterator(b) { + iterator + |> map(f) + |> flatten +} + +fn do_filter( + continuation: fn() -> Action(e), + predicate: fn(e) -> Bool, +) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, iterator) -> + case predicate(e) { + True -> Continue(e, fn() { do_filter(iterator, predicate) }) + False -> do_filter(iterator, predicate) + } + } +} + +/// Creates an iterator from an existing iterator and a predicate function. +/// +/// The new iterator will contain elements from the first iterator for which +/// the given function returns `True`. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> filter(int.is_even) +/// > |> to_list +/// [2, 4] +/// ``` +/// +pub fn filter( + iterator: Iterator(a), + keeping predicate: fn(a) -> Bool, +) -> Iterator(a) { + fn() { do_filter(iterator.continuation, predicate) } + |> Iterator +} + +/// Creates an iterator that repeats a given iterator infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> cycle +/// > |> take(6) +/// > |> to_list +/// [1, 2, 1, 2, 1, 2] +/// ``` +/// +pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { + repeat(iterator) + |> flatten +} + +/// Creates an iterator of ints, starting at a given start int and stepping by +/// one to a given end int. +/// +/// ## Examples +/// +/// ```gleam +/// > range(from: 1, to: 5) |> to_list +/// [1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(from: 1, to: -2) |> to_list +/// [1, 0, -1, -2] +/// ``` +/// +/// ```gleam +/// > range(from: 0, to: 0) |> to_list +/// [0] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { + case int.compare(start, stop) { + order.Eq -> once(fn() { start }) + order.Gt -> + unfold( + from: start, + with: fn(current) { + case current < stop { + False -> Next(current, current - 1) + True -> Done + } + }, + ) + + order.Lt -> + unfold( + from: start, + with: fn(current) { + case current > stop { + False -> Next(current, current + 1) + True -> Done + } + }, + ) + } +} + +fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { + case continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + case f(e) { + True -> Ok(e) + False -> do_find(next, f) + } + } +} + +/// Finds the first element in a given iterator for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if the function does not return `True` for any of the +/// elements. +/// +/// ## Examples +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find(empty(), fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: Iterator(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + haystack.continuation + |> do_find(is_desired) +} + +fn do_index( + continuation: fn() -> Action(element), + next: Int, +) -> fn() -> Action(#(Int, element)) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> + Continue(#(next, e), do_index(continuation, next + 1)) + } + } +} + +/// Wraps values yielded from an iterator with indices, starting from 0. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) |> index |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +/// +pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { + iterator.continuation + |> do_index(0) + |> Iterator +} + +/// Creates an iterator that inifinitely applies a function to a value. +/// +/// ## Examples +/// +/// ```gleam +/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list +/// [1, 3, 9, 27, 81] +/// ``` +/// +pub fn iterate( + from initial: element, + with f: fn(element) -> element, +) -> Iterator(element) { + unfold(initial, fn(element) { Next(element, f(element)) }) +} + +fn do_take_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> fn() -> Action(element) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Stop + True -> Continue(e, do_take_while(next, predicate)) + } + } + } +} + +/// Creates an iterator that yields elements while the predicate returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 2, 4]) +/// > |> take_while(satisfying: fn(x) { x < 3 }) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + iterator.continuation + |> do_take_while(predicate) + |> Iterator +} + +fn do_drop_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Continue(e, next) + True -> do_drop_while(next, predicate) + } + } +} + +/// Creates an iterator that drops elements while the predicate returns `True`, +/// and then yields the remaining elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 2, 5]) +/// > |> drop_while(satisfying: fn(x) { x < 4 }) +/// > |> to_list +/// [4, 2, 5] +/// ``` +/// +pub fn drop_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + fn() { do_drop_while(iterator.continuation, predicate) } + |> Iterator +} + +fn do_scan( + continuation: fn() -> Action(element), + f: fn(acc, element) -> acc, + accumulator: acc, +) -> fn() -> Action(acc) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> { + let accumulated = f(accumulator, el) + Continue(accumulated, do_scan(next, f, accumulated)) + } + } + } +} + +/// Creates an iterator from an existing iterator and a stateful function. +/// +/// Specifically, this behaves like `fold`, but yields intermediate results. +/// +/// ## Examples +/// +/// ```gleam +/// // Generate a sequence of partial sums +/// > from_list([1, 2, 3, 4, 5]) +/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) +/// > |> to_list +/// [1, 3, 6, 10, 15] +/// ``` +/// +pub fn scan( + over iterator: Iterator(element), + from initial: acc, + with f: fn(acc, element) -> acc, +) -> Iterator(acc) { + iterator.continuation + |> do_scan(f, initial) + |> Iterator +} + +fn do_zip( + left: fn() -> Action(a), + right: fn() -> Action(b), +) -> fn() -> Action(#(a, b)) { + fn() { + case left() { + Stop -> Stop + Continue(el_left, next_left) -> + case right() { + Stop -> Stop + Continue(el_right, next_right) -> + Continue(#(el_left, el_right), do_zip(next_left, next_right)) + } + } + } +} + +/// Zips two iterators together, emitting values from both +/// until the shorter one runs out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> zip(range(20, 30)) +/// > |> to_list +/// [#("a", 20), #("b", 21), #("c", 22)] +/// ``` +/// +pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { + do_zip(left.continuation, right.continuation) + |> Iterator +} + +// Result of collecting a single chunk by key +type Chunk(element, key) { + AnotherBy(List(element), key, element, fn() -> Action(element)) + LastBy(List(element)) +} + +fn next_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + current_chunk: List(element), +) -> Chunk(element, key) { + case continuation() { + Stop -> LastBy(list.reverse(current_chunk)) + Continue(e, next) -> { + let key = f(e) + case key == previous_key { + True -> next_chunk(next, f, key, [e, ..current_chunk]) + False -> AnotherBy(list.reverse(current_chunk), key, e, next) + } + } + } +} + +fn do_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + previous_element: element, +) -> Action(List(element)) { + case next_chunk(continuation, f, previous_key, [previous_element]) { + LastBy(chunk) -> Continue(chunk, stop) + AnotherBy(chunk, key, el, next) -> + Continue(chunk, fn() { do_chunk(next, f, key, el) }) + } +} + +/// Creates an iterator that emits chunks of elements +/// for which `f` returns the same value. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) +/// > |> chunk(by: fn(n) { n % 2 }) +/// > |> to_list +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk( + over iterator: Iterator(element), + by f: fn(element) -> key, +) -> Iterator(List(element)) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> do_chunk(next, f, f(e), e) + } + } + |> Iterator +} + +// Result of collecting a single sized chunk +type SizedChunk(element) { + Another(List(element), fn() -> Action(element)) + Last(List(element)) + NoMore +} + +fn next_sized_chunk( + continuation: fn() -> Action(element), + left: Int, + current_chunk: List(element), +) -> SizedChunk(element) { + case continuation() { + Stop -> + case current_chunk { + [] -> NoMore + remaining -> Last(list.reverse(remaining)) + } + Continue(e, next) -> { + let chunk = [e, ..current_chunk] + case left > 1 { + False -> Another(list.reverse(chunk), next) + True -> next_sized_chunk(next, left - 1, chunk) + } + } + } +} + +fn do_sized_chunk( + continuation: fn() -> Action(element), + count: Int, +) -> fn() -> Action(List(element)) { + fn() { + case next_sized_chunk(continuation, count, []) { + NoMore -> Stop + Last(chunk) -> Continue(chunk, stop) + Another(chunk, next_element) -> + Continue(chunk, do_sized_chunk(next_element, count)) + } + } +} + +/// Creates an iterator that emits chunks of given size. +/// +/// If the last chunk does not have `count` elements, it is yielded +/// as a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) +/// > |> sized_chunk(into: 2) +/// > |> to_list +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) +/// > |> sized_chunk(into: 3) +/// > |> to_list +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk( + over iterator: Iterator(element), + into count: Int, +) -> Iterator(List(element)) { + iterator.continuation + |> do_sized_chunk(count) + |> Iterator +} + +fn do_intersperse( + continuation: fn() -> Action(element), + separator: element, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> { + let next_interspersed = fn() { do_intersperse(next, separator) } + Continue(separator, fn() { Continue(e, next_interspersed) }) + } + } +} + +/// Creates an iterator that yields the given `elem` element +/// between elements emitted by the underlying iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() +/// > |> intersperse(with: 0) +/// > |> to_list +/// [] +/// +/// > from_list([1]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1] +/// +/// > from_list([1, 2, 3, 4, 5]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1, 0, 2, 0, 3, 0, 4, 0, 5] +/// ``` +/// +pub fn intersperse( + over iterator: Iterator(element), + with elem: element, +) -> Iterator(element) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) + } + } + |> Iterator +} + +fn do_any( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> False + Continue(e, next) -> + case predicate(e) { + True -> True + False -> do_any(next, predicate) + } + } +} + +/// Returns `True` if any element emitted by the iterator satisfies the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a satisfying element. +/// +/// An empty iterator results in `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn any( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_any(predicate) +} + +fn do_all( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> True + Continue(e, next) -> + case predicate(e) { + True -> do_all(next, predicate) + False -> False + } + } +} + +/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a non-satisfying element. +/// +/// An empty iterator results in `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn all( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_all(predicate) +} + +fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { + fn(maybe_group) { + case maybe_group { + Some(group) -> [el, ..group] + None -> [el] + } + } +} + +fn group_updater( + f: fn(element) -> key, +) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { + fn(groups, elem) { + groups + |> dict.update(f(elem), update_group_with(elem)) + } +} + +/// Returns a `Dict(k, List(element))` of elements from the given iterator +/// grouped with the given key function. +/// +/// The order within each group is preserved from the iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) +/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) +/// ``` +/// +pub fn group( + in iterator: Iterator(element), + by key: fn(element) -> key, +) -> Dict(key, List(element)) { + iterator + |> fold(dict.new(), group_updater(key)) + |> dict.map_values(fn(_, group) { list.reverse(group) }) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first yielded element +/// and combines it with each subsequent element in turn using the given function. +/// The function is called as `f(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce( + over iterator: Iterator(e), + with f: fn(e, e) -> e, +) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + do_fold(next, f, e) + |> Ok + } +} + +/// Returns the last element in the given iterator. +/// +/// Returns `Error(Nil)` if the iterator is empty. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> last +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > range(1, 10) |> last +/// Ok(9) +/// ``` +/// +pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { + iterator + |> reduce(fn(_, elem) { elem }) +} + +/// Creates an iterator that yields no elements. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> to_list +/// [] +/// ``` +/// +pub fn empty() -> Iterator(element) { + Iterator(stop) +} + +/// Creates an iterator that yields exactly one element provided by calling the given function. +/// +/// ## Examples +/// +/// ```gleam +/// > once(fn() { 1 }) |> to_list +/// [1] +/// ``` +/// +pub fn once(f: fn() -> element) -> Iterator(element) { + fn() { Continue(f(), stop) } + |> Iterator +} + +/// Creates an iterator that yields the given element exactly once. +/// +/// ## Examples +/// +/// ```gleam +/// > single(1) |> to_list +/// [1] +/// ``` +/// +pub fn single(elem: element) -> Iterator(element) { + once(fn() { elem }) +} + +fn do_interleave( + current: fn() -> Action(element), + next: fn() -> Action(element), +) -> Action(element) { + case current() { + Stop -> next() + Continue(e, next_other) -> + Continue(e, fn() { do_interleave(next, next_other) }) + } +} + +/// Creates an iterator that alternates between the two given iterators +/// until both have run out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list +/// [1, 11, 2, 12, 3, 13, 4, 14] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list +/// [1, 100, 2, 3, 4] +/// ``` +/// +pub fn interleave( + left: Iterator(element), + with right: Iterator(element), +) -> Iterator(element) { + fn() { do_interleave(left.continuation, right.continuation) } + |> Iterator +} + +fn do_fold_until( + continuation: fn() -> Action(e), + f: fn(acc, e) -> list.ContinueOrStop(acc), + accumulator: acc, +) -> acc { + case continuation() { + Stop -> accumulator + Continue(elem, next) -> + case f(accumulator, elem) { + list.Continue(accumulator) -> do_fold_until(next, f, accumulator) + list.Stop(accumulator) -> accumulator + } + } +} + +/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given +/// function on each element in turn, but uses `list.ContinueOrStop` to determine +/// whether or not to keep iterating. +/// +/// If called on an iterator of infinite length then this function will only ever +/// return if the function returns `list.Stop`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > let f = fn(acc, e) { +/// > case e { +/// > _ if e < 4 -> list.Continue(e + acc) +/// > _ -> list.Stop(acc) +/// > } +/// > } +/// > +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold_until(from: acc, with: f) +/// 6 +/// ``` +/// +pub fn fold_until( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> list.ContinueOrStop(acc), +) -> acc { + iterator.continuation + |> do_fold_until(f, initial) +} + +fn do_try_fold( + over continuation: fn() -> Action(a), + with f: fn(acc, a) -> Result(acc, err), + from accumulator: acc, +) -> Result(acc, err) { + case continuation() { + Stop -> Ok(accumulator) + Continue(elem, next) -> { + use accumulator <- result.try(f(accumulator, elem)) + do_try_fold(next, f, accumulator) + } + } +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> iterator.from_list() +/// > |> try_fold(0, fn(acc, i) { +/// > case i < 3 { +/// > True -> Ok(acc + i) +/// > False -> Error(Nil) +/// > } +/// > }) +/// Error(Nil) +/// ``` +/// +pub fn try_fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> Result(acc, err), +) -> Result(acc, err) { + iterator.continuation + |> do_try_fold(f, initial) +} + +/// Returns the first element yielded by the given iterator, if it exists, +/// or `Error(Nil)` otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) |> first +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > empty() |> first +/// Error(Nil) +/// ``` +pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, _) -> Ok(e) + } +} + +/// Returns nth element yielded by the given iterator, where `0` means the first element. +/// +/// If there are not enough elements in the iterator, `Error(Nil)` is returned. +/// +/// For any `index` less than `0` this function behaves as if it was set to `0`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(2) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(4) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > empty() |> at(0) +/// Error(Nil) +/// ``` +/// +pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { + iterator + |> drop(index) + |> first +} + +fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { + case continuation() { + Stop -> length + Continue(_, next) -> do_length(next, length + 1) + } +} + +/// Counts the number of elements in the given iterator. +/// +/// This function has to traverse the entire iterator to count its elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> length +/// 0 +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> length +/// 4 +/// ``` +/// +pub fn length(over iterator: Iterator(e)) -> Int { + iterator.continuation + |> do_length(0) +} + +/// Traverse an iterator, calling a function on each element. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> each(io.println) +/// Nil +/// ``` +/// +/// ```gleam +/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) +/// // -> Tom +/// // -> Malory +/// // -> Louis +/// Nil +/// ``` +/// +pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { + iterator + |> map(f) + |> run +} + +/// Add a new element to the start of an iterator. +/// +/// This function is for use with `use` expressions, to replicate the behaviour +/// of the `yield` keyword found in other languages. +/// +/// ## Examples +/// +/// ```gleam +/// > use <- iterator.yield(1) +/// > use <- iterator.yield(2) +/// > use <- iterator.yield(3) +/// > iterator.empty() +/// iterator.from_list([1, 2, 3]) +/// ``` +/// +pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { + Iterator(fn() { Continue(element, next().continuation) }) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam new file mode 100644 index 00000000000..a5cffa9b951 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam @@ -0,0 +1,2154 @@ +//// Lists are an ordered sequence of elements and are one of the most common +//// data types in Gleam. +//// +//// New elements can be added and removed from the front of a list in +//// constant time, while adding and removing from the end requires traversing +//// the copying the whole list, so keep this in mind when designing your +//// programs. +//// +//// There is a dedicated syntax for prefixing to a list: +//// +//// ```gleam +//// let new_list = [1, 2, ..existing_list] +//// ``` +//// +//// And a matching syntax for getting the first elements of a list: +//// +//// ```gleam +//// case list { +//// [first_element, ..rest] -> first_element +//// _ -> "this pattern matches when the list is empty" +//// } +//// ``` +//// + +import gleam/int +import gleam/float +import gleam/order.{type Order} +import gleam/pair +import gleam/dict.{type Dict} + +/// An error value returned by the `strict_zip` function. +/// +pub type LengthMismatch { + LengthMismatch +} + +/// Counts the number of elements in a given list. +/// +/// This function has to traverse the list to determine the number of elements, +/// so it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > length([]) +/// 0 +/// ``` +/// +/// ```gleam +/// > length([1]) +/// 1 +/// ``` +/// +/// ```gleam +/// > length([1, 2]) +/// 2 +/// ``` +/// +pub fn length(of list: List(a)) -> Int { + do_length(list) +} + +@target(erlang) +@external(erlang, "erlang", "length") +fn do_length(a: List(a)) -> Int + +@target(javascript) +fn do_length(list: List(a)) -> Int { + do_length_acc(list, 0) +} + +@target(javascript) +fn do_length_acc(list: List(a), count: Int) -> Int { + case list { + [_, ..list] -> do_length_acc(list, count + 1) + _ -> count + } +} + +/// Creates a new list from a given list containing the same elements but in the +/// opposite order. +/// +/// This function has to traverse the list to create the new reversed list, so +/// it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse([]) +/// [] +/// ``` +/// +/// ```gleam +/// > reverse([1]) +/// [1] +/// ``` +/// +/// ```gleam +/// > reverse([1, 2]) +/// [2, 1] +/// ``` +/// +pub fn reverse(xs: List(a)) -> List(a) { + do_reverse(xs) +} + +@target(erlang) +@external(erlang, "lists", "reverse") +fn do_reverse(a: List(a)) -> List(a) + +@target(javascript) +fn do_reverse(list) { + do_reverse_acc(list, []) +} + +@target(javascript) +fn do_reverse_acc(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) + } +} + +/// Determines whether or not the list is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty([]) +/// True +/// ``` +/// +/// ```gleam +/// > is_empty([1]) +/// False +/// ``` +/// +/// ```gleam +/// > is_empty([1, 1]) +/// False +/// ``` +/// +pub fn is_empty(list: List(a)) -> Bool { + list == [] +} + +/// Determines whether or not a given element exists within a given list. +/// +/// This function traverses the list to find the element, so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [0] |> contains(any: 0) +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 0] |> contains(any: 0) +/// True +/// ``` +/// +pub fn contains(list: List(a), any elem: a) -> Bool { + case list { + [] -> False + [first, ..] if first == elem -> True + [_, ..rest] -> contains(rest, elem) + } +} + +/// Gets the first element from the start of the list, if there is one. +/// +/// ## Examples +/// +/// ```gleam +/// > first([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first([0]) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > first([1, 2]) +/// Ok(1) +/// ``` +/// +pub fn first(list: List(a)) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [x, ..] -> Ok(x) + } +} + +/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is +/// returned. +/// +/// This function runs in constant time and does not make a copy of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > rest([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > rest([0]) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > rest([1, 2]) +/// Ok([2]) +/// ``` +/// +pub fn rest(list: List(a)) -> Result(List(a), Nil) { + case list { + [] -> Error(Nil) + [_, ..xs] -> Ok(xs) + } +} + +fn update_group( + f: fn(element) -> key, +) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { + fn(groups, elem) { + case dict.get(groups, f(elem)) { + Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) + Error(_) -> dict.insert(groups, f(elem), [elem]) + } + } +} + +/// Takes a list and groups the values by a key +/// which is built from a key function. +/// +/// Does not preserve the initial value order. +/// +/// ## Examples +/// +/// ```gleam +/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] +/// |> group(by: fn(i) { +/// case i { +/// Ok(_) -> "Successful" +/// Error(_) -> "Failed" +/// } +/// }) +/// |> dict.to_list +/// +/// [ +/// #("Failed", [Error("Wrong")]), +/// #("Successful", [Ok(73), Ok(200), Ok(3)]) +/// ] +/// +/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) +/// |> dict.to_list +/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] +/// ``` +/// +pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { + fold(list, dict.new(), update_group(key)) +} + +fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + True -> [x, ..acc] + False -> acc + } + do_filter(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) +/// [4, 6] +/// ``` +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) +/// [] +/// ``` +/// +pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { + do_filter(list, predicate, []) +} + +fn do_filter_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + Ok(x) -> [x, ..acc] + Error(_) -> acc + } + do_filter_map(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `Ok(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], Error) +/// [] +/// ``` +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) +/// [3, 5, 7, 2] +/// ``` +/// +pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { + do_filter_map(list, fun, []) +} + +fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one. +/// +/// ## Examples +/// +/// ```gleam +/// > map([2, 4, 6], fn(x) { x * 2 }) +/// [4, 8, 12] +/// ``` +/// +pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { + do_map(list, fun, []) +} + +/// Combines two lists into a single list using the given function. +/// +/// If a list is longer than the other the extra elements are dropped. +/// +/// ## Examples +/// +/// ```gleam +/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) +/// [5, 7, 9] +/// ``` +/// +/// ```gleam +/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) +/// [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { + do_map2(list1, list2, fun, []) +} + +fn do_map2( + list1: List(a), + list2: List(b), + fun: fn(a, b) -> c, + acc: List(c), +) -> List(c) { + case list1, list2 { + [], _ | _, [] -> reverse(acc) + [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) + } +} + +/// Similar to `map` but also lets you pass around an accumulated value. +/// +/// ## Examples +/// +/// ```gleam +/// > map_fold( +/// over: [1, 2, 3], +/// from: 100, +/// with: fn(memo, i) { #(memo + i, i * 2) } +/// ) +/// #(106, [2, 4, 6]) +/// ``` +/// +pub fn map_fold( + over list: List(a), + from acc: acc, + with fun: fn(acc, a) -> #(acc, b), +) -> #(acc, List(b)) { + fold( + over: list, + from: #(acc, []), + with: fn(acc, item) { + let #(current_acc, items) = acc + let #(next_acc, next_item) = fun(current_acc, item) + #(next_acc, [next_item, ..items]) + }, + ) + |> pair.map_second(reverse) +} + +fn do_index_map( + list: List(a), + fun: fn(Int, a) -> b, + index: Int, + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let acc = [fun(index, x), ..acc] + do_index_map(xs, fun, index + 1, acc) + } + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one and their index. +/// +/// The index starts at 0, so the first element is 0, the second is 1, and so +/// on. +/// +/// ## Examples +/// +/// ```gleam +/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) +/// [#(0, "a"), #(1, "b")] +/// ``` +/// +pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { + do_index_map(list, fun, 0, []) +} + +fn do_try_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> Result(List(b), e) { + case list { + [] -> Ok(reverse(acc)) + [x, ..xs] -> + case fun(x) { + Ok(y) -> do_try_map(xs, fun, [y, ..acc]) + Error(error) -> Error(error) + } + } +} + +/// Takes a function that returns a `Result` and applies it to each element in a +/// given list in turn. +/// +/// If the function returns `Ok(new_value)` for all elements in the list then a +/// list of the new values is returned. +/// +/// If the function returns `Error(reason)` for any of the elements then it is +/// returned immediately. None of the elements in the list are processed after +/// one returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) +/// Ok([3, 4, 5]) +/// ``` +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(_) { Error(0) }) +/// Error(0) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [2, 3]], first) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [], [2]], first) +/// Error(Nil) +/// ``` +/// +pub fn try_map( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(List(b), e) { + do_try_map(list, fun, []) +} + +/// Returns a list that is the given list with up to the given number of +/// elements removed from the front of the list. +/// +/// If the element has less than the number of elements an empty list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 2) +/// [3, 4] +/// ``` +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 9) +/// [] +/// ``` +/// +pub fn drop(from list: List(a), up_to n: Int) -> List(a) { + case n <= 0 { + True -> list + False -> + case list { + [] -> [] + [_, ..xs] -> drop(xs, n - 1) + } + } +} + +fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { + case n <= 0 { + True -> reverse(acc) + False -> + case list { + [] -> reverse(acc) + [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) + } + } +} + +/// Returns a list containing the first given number of elements from the given +/// list. +/// +/// If the element has less than the number of elements then the full list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > take([1, 2, 3, 4], 2) +/// [1, 2] +/// ``` +/// +/// ```gleam +/// > take([1, 2, 3, 4], 9) +/// [1, 2, 3, 4] +/// ``` +/// +pub fn take(from list: List(a), up_to n: Int) -> List(a) { + do_take(list, n, []) +} + +/// Returns a new empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// [] +/// ``` +/// +pub fn new() -> List(a) { + [] +} + +/// Joins one list onto the end of another. +/// +/// This function runs in linear time, and it traverses and copies the first +/// list. +/// +/// ## Examples +/// +/// ```gleam +/// > append([1, 2], [3]) +/// [1, 2, 3] +/// ``` +/// +pub fn append(first: List(a), second: List(a)) -> List(a) { + do_append(first, second) +} + +@target(erlang) +@external(erlang, "lists", "append") +fn do_append(a: List(a), b: List(a)) -> List(a) + +@target(javascript) +fn do_append(first: List(a), second: List(a)) -> List(a) { + do_append_acc(reverse(first), second) +} + +@target(javascript) +fn do_append_acc(first: List(a), second: List(a)) -> List(a) { + case first { + [] -> second + [item, ..rest] -> do_append_acc(rest, [item, ..second]) + } +} + +/// Prefixes an item to a list. This can also be done using the dedicated +/// syntax instead +/// +/// ```gleam +/// let new_list = [1, ..existing_list] +/// ``` +/// +pub fn prepend(to list: List(a), this item: a) -> List(a) { + [item, ..list] +} + +// Reverses a list and prepends it to another list +fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { + case prefix { + [] -> suffix + [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) + } +} + +fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { + case lists { + [] -> reverse(acc) + [list, ..further_lists] -> + do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) + } +} + +/// Joins a list of lists into a single list. +/// +/// This function traverses all elements twice. +/// +/// ## Examples +/// +/// ```gleam +/// > concat([[1], [2, 3], []]) +/// [1, 2, 3] +/// ``` +/// +pub fn concat(lists: List(List(a))) -> List(a) { + do_concat(lists, []) +} + +/// This is the same as `concat`: it joins a list of lists into a single +/// list. +/// +/// This function traverses all elements twice. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten([[1], [2, 3], []]) +/// [1, 2, 3] +/// ``` +/// +pub fn flatten(lists: List(List(a))) -> List(a) { + do_concat(lists, []) +} + +/// Maps the list with the given function into a list of lists, and then flattens it. +/// +/// ## Examples +/// +/// ```gleam +/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) +/// [2, 3, 4, 5, 6, 7] +/// ``` +/// +pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { + map(list, fun) + |> concat +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from left to right. +/// +/// `fold([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 1), 2), 3)`. +/// +/// This function runs in linear time. +/// +pub fn fold( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fold(rest, fun(initial, x), fun) + } +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from right to left. +/// +/// `fold_right([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 3), 2), 1)`. +/// +/// This function runs in linear time. +/// +/// Unlike `fold` this function is not tail recursive. Where possible use +/// `fold` instead as it will use less memory. +/// +pub fn fold_right( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fun(fold_right(rest, initial, fun), x) + } +} + +fn do_index_fold( + over: List(a), + acc: acc, + with: fn(acc, a, Int) -> acc, + index: Int, +) -> acc { + case over { + [] -> acc + [first, ..rest] -> + do_index_fold(rest, with(acc, first, index), with, index + 1) + } +} + +/// Like fold but the folding function also receives the index of the current element. +/// +/// ## Examples +/// +/// ```gleam +/// ["a", "b", "c"] +/// |> index_fold([], fn(acc, item, index) { ... }) +/// ``` +/// +pub fn index_fold( + over over: List(a), + from initial: acc, + with fun: fn(acc, a, Int) -> acc, +) -> acc { + do_index_fold(over, initial, fun, 0) +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> try_fold(0, fn(acc, i) { +/// case i < 3 { +/// True -> Ok(acc + i) +/// False -> Error(Nil) +/// } +/// }) +/// ``` +/// +pub fn try_fold( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> Result(acc, e), +) -> Result(acc, e) { + case collection { + [] -> Ok(accumulator) + [first, ..rest] -> + case fun(accumulator, first) { + Ok(result) -> try_fold(rest, result, fun) + Error(_) as error -> error + } + } +} + +pub type ContinueOrStop(a) { + Continue(a) + Stop(a) +} + +/// A variant of fold that allows to stop folding earlier. +/// +/// The folding function should return `ContinueOrStop(accumulator)`. +/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. +/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> fold_until(0, fn(acc, i) { +/// case i < 3 { +/// True -> Continue(acc + i) +/// False -> Stop(acc) +/// } +/// }) +/// ``` +/// +pub fn fold_until( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> ContinueOrStop(acc), +) -> acc { + case collection { + [] -> accumulator + [first, ..rest] -> + case fun(accumulator, first) { + Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) + Stop(b) -> b + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case is_desired(x) { + True -> Ok(x) + _ -> find(in: rest, one_that: is_desired) + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find_map([[], [2], [3]], first) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > find_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn find_map( + in haystack: List(a), + with fun: fn(a) -> Result(b, c), +) -> Result(b, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case fun(x) { + Ok(x) -> Ok(x) + _ -> find_map(in: rest, with: fun) + } + } +} + +/// Returns `True` if the given function returns `True` for all the elements in +/// the given list. If the function returns `False` for any of the elements it +/// immediately returns `False` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > all([], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 3], fn(x) { x > 3 }) +/// False +/// ``` +/// +pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> True + [first, ..rest] -> + case predicate(first) { + True -> all(rest, predicate) + False -> False + } + } +} + +/// Returns `True` if the given function returns `True` for any the elements in +/// the given list. If the function returns `True` for any of the elements it +/// immediately returns `True` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > any([], fn(x) { x > 3 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > any([4, 3], fn(x) { x > 4 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([3, 4], fn(x) { x > 3 }) +/// True +/// ``` +/// +pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> False + [first, ..rest] -> + case predicate(first) { + True -> True + False -> any(rest, predicate) + } + } +} + +fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { + case xs, ys { + [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) + _, _ -> reverse(acc) + } +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, the remaining elements from +/// the longer list are not used. +/// +/// ## Examples +/// +/// ```gleam +/// > zip([], []) +/// [] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1], [3, 4]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3, 4]) +/// [#(1, 3), #(2, 4)] +/// ``` +/// +pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { + do_zip(list, other, []) +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, an `Error` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > strict_zip([], []) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1], [3, 4]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3, 4]) +/// Ok([#(1, 3), #(2, 4)]) +/// ``` +/// +pub fn strict_zip( + list: List(a), + with other: List(b), +) -> Result(List(#(a, b)), LengthMismatch) { + case length(of: list) == length(of: other) { + True -> Ok(zip(list, other)) + False -> Error(LengthMismatch) + } +} + +fn do_unzip(input, xs, ys) { + case input { + [] -> #(reverse(xs), reverse(ys)) + [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) + } +} + +/// Takes a single list of 2-element tuples and returns two lists. +/// +/// ## Examples +/// +/// ```gleam +/// > unzip([#(1, 2), #(3, 4)]) +/// #([1, 3], [2, 4]) +/// ``` +/// +/// ```gleam +/// > unzip([]) +/// #([], []) +/// ``` +/// +pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { + do_unzip(input, [], []) +} + +fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) + } +} + +/// Inserts a given value between each existing element in a given list. +/// +/// This function runs in linear time and copies the list. +/// +/// ## Examples +/// +/// ```gleam +/// > intersperse([1, 1, 1], 2) +/// [1, 2, 1, 2, 1] +/// ``` +/// +/// ```gleam +/// > intersperse([], 2) +/// [] +/// ``` +/// +pub fn intersperse(list: List(a), with elem: a) -> List(a) { + case list { + [] | [_] -> list + [x, ..rest] -> do_intersperse(rest, elem, [x]) + } +} + +/// Returns the element in the Nth position in the list, with 0 being the first +/// position. +/// +/// `Error(Nil)` is returned if the list is not long enough for the given index +/// or if the index is less than 0. +/// +/// ## Examples +/// +/// ```gleam +/// > at([1, 2, 3], 1) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > at([1, 2, 3], 5) +/// Error(Nil) +/// ``` +/// +pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { + case index >= 0 { + True -> + list + |> drop(index) + |> first + False -> Error(Nil) + } +} + +/// Removes any duplicate elements from a given list. +/// +/// This function returns in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) +/// [1, 4, 7, 3] +/// ``` +/// +pub fn unique(list: List(a)) -> List(a) { + case list { + [] -> [] + [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] + } +} + +/// Merge lists `a` and `b` in ascending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_up( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(ax, bx) { + order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + } + _, _, _, _ -> acc + } +} + +/// Merge lists `a` and `b` in descending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_down( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(bx, ax) { + order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + } + _, _, _, _ -> acc + } +} + +/// Merge sort that alternates merging in ascending and descending order +/// because the merge process also reverses the list. +/// +/// Some copying is avoided by merging only a subset of the lists +/// instead of creating and merging new smaller lists. +/// +fn merge_sort( + l: List(a), + ln: Int, + compare: fn(a, a) -> Order, + down: Bool, +) -> List(a) { + let n = ln / 2 + let a = l + let b = drop(l, n) + case ln < 3 { + True -> + case down { + True -> merge_down(n, ln - n, a, b, [], compare) + False -> merge_up(n, ln - n, a, b, [], compare) + } + False -> + case down { + True -> + merge_down( + n, + ln - n, + merge_sort(a, n, compare, False), + merge_sort(b, ln - n, compare, False), + [], + compare, + ) + False -> + merge_up( + n, + ln - n, + merge_sort(a, n, compare, True), + merge_sort(b, ln - n, compare, True), + [], + compare, + ) + } + } +} + +/// Sorts from smallest to largest based upon the ordering specified by a given +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) +/// [1, 2, 3, 4, 4, 5, 6] +/// ``` +/// +pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { + merge_sort(list, length(list), compare, True) +} + +/// Creates a list of ints ranging from a given start and finish. +/// +/// ## Examples +/// +/// ```gleam +/// > range(0, 0) +/// [0] +/// ``` +/// +/// ```gleam +/// > range(0, 5) +/// [0, 1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(1, -5) +/// [1, 0, -1, -2, -3, -4, -5] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> List(Int) { + tail_recursive_range(start, stop, []) +} + +fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { + case int.compare(start, stop) { + order.Eq -> [stop, ..acc] + order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) + order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) + } +} + +fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { + case times <= 0 { + True -> acc + False -> do_repeat(a, times - 1, [a, ..acc]) + } +} + +/// Builds a list of a given value a given number of times. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("a", times: 0) +/// [] +/// ``` +/// +/// ```gleam +/// > repeat("a", times: 5) +/// ["a", "a", "a", "a", "a"] +/// ``` +/// +pub fn repeat(item a: a, times times: Int) -> List(a) { + do_repeat(a, times, []) +} + +fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { + case n <= 0 { + True -> #(reverse(taken), list) + False -> + case list { + [] -> #(reverse(taken), []) + [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) + } + } +} + +/// Splits a list in two before the given index. +/// +/// If the list is not long enough to have the given index the before list will +/// be the input list, and the after list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split([6, 7, 8, 9], 0) +/// #([], [6, 7, 8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 2) +/// #([6, 7], [8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 4) +/// #([6, 7, 8, 9], []) +/// ``` +/// +pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { + do_split(list, index, []) +} + +fn do_split_while( + list: List(a), + f: fn(a) -> Bool, + acc: List(a), +) -> #(List(a), List(a)) { + case list { + [] -> #(reverse(acc), []) + [x, ..xs] -> + case f(x) { + False -> #(reverse(acc), list) + _ -> do_split_while(xs, f, [x, ..acc]) + } + } +} + +/// Splits a list in two before the first element that a given function returns +/// `False` for. +/// +/// If the function returns `True` for all elements the first list will be the +/// input list, and the second list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) +/// #([1, 2, 3], [4, 5]) +/// ``` +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) +/// #([1, 2, 3, 4, 5], []) +/// ``` +/// +pub fn split_while( + list list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_split_while(list, predicate, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element and returns the second element. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// This function may be useful for interacting with Erlang code where lists of +/// tuples are common. +/// +/// ## Examples +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "b") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_find( + in keyword_list: List(#(k, v)), + find desired_key: k, +) -> Result(v, Nil) { + find_map( + keyword_list, + fn(keyword) { + let #(key, value) = keyword + case key == desired_key { + True -> Ok(value) + False -> Error(Nil) + } + }, + ) +} + +/// Given a list of 2-element tuples, finds all tuples that have a given +/// key as the first element and returns the second element. +/// +/// This function may be useful for interacting with Erlang code where lists of +/// tuples are common. +/// +/// ## Examples +/// +/// ```gleam +/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") +/// [0, 2] +/// ``` +/// +/// ```gleam +/// > key_filter([#("a", 0), #("b", 1)], "c") +/// [] +/// ``` +/// +pub fn key_filter( + in keyword_list: List(#(k, v)), + find desired_key: k, +) -> List(v) { + filter_map( + keyword_list, + fn(keyword) { + let #(key, value) = keyword + case key == desired_key { + True -> Ok(value) + False -> Error(Nil) + } + }, + ) +} + +fn do_pop(haystack, predicate, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case predicate(x) { + True -> Ok(#(x, append(reverse(checked), rest))) + False -> do_pop(rest, predicate, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the predicate function returns `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 2 }) +/// Ok(#(3, [1, 2])) +/// ``` +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn pop( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(#(a, List(a)), Nil) { + do_pop(haystack, is_desired, []) +} + +fn do_pop_map(haystack, mapper, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case mapper(x) { + Ok(y) -> Ok(#(y, append(reverse(checked), rest))) + Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_map([[], [2], [3]], first) +/// Ok(#(2, [[], [3]])) +/// ``` +/// +/// ```gleam +/// > pop_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn pop_map( + in haystack: List(a), + one_that is_desired: fn(a) -> Result(b, c), +) -> Result(#(b, List(a)), Nil) { + do_pop_map(haystack, is_desired, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element. This function will return the second element +/// of the found tuple and list with tuple removed. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "a") +/// Ok(#(0, [#("b", 1)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "b") +/// Ok(#(1, [#("a", 0)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_pop( + haystack: List(#(k, v)), + key: k, +) -> Result(#(v, List(#(k, v))), Nil) { + pop_map( + haystack, + fn(entry) { + let #(k, v) = entry + case k { + k if k == key -> Ok(v) + _ -> Error(Nil) + } + }, + ) +} + +/// Given a list of 2-element tuples, inserts a key and value into the list. +/// +/// If there was already a tuple with the key then it is replaced, otherwise it +/// is added to the end of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 4, 100) +/// [#(5, 0), #(4, 100)] +/// ``` +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 1, 100) +/// [#(5, 0), #(4, 1), #(1, 100)] +/// ``` +/// +pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { + case list { + [] -> [#(key, value)] + [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] + [first, ..rest] -> [first, ..key_set(rest, key, value)] + } +} + +/// Calls a function for each element in a list, discarding the return value. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ```gleam +/// > list.each([1, 2, 3], io.println) +/// Nil +/// ``` +/// +pub fn each(list: List(a), f: fn(a) -> b) -> Nil { + case list { + [] -> Nil + [x, ..xs] -> { + f(x) + each(xs, f) + } + } +} + +/// Calls a `Result` returning function for each element in a list, discarding +/// the return value. If the function returns `Error` then the iteration is +/// stopped and the error is returned. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > try_each( +/// > over: [1, 2, 3], +/// > with: function_that_might_fail, +/// > ) +/// Ok(Nil) +/// ``` +/// +pub fn try_each( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(Nil, e) { + case list { + [] -> Ok(Nil) + [x, ..xs] -> + case fun(x) { + Ok(_) -> try_each(over: xs, with: fun) + Error(e) -> Error(e) + } + } +} + +fn do_partition(list, categorise, trues, falses) { + case list { + [] -> #(reverse(trues), reverse(falses)) + [x, ..xs] -> + case categorise(x) { + True -> do_partition(xs, categorise, [x, ..trues], falses) + False -> do_partition(xs, categorise, trues, [x, ..falses]) + } + } +} + +/// Partitions a list into a tuple/pair of lists +/// by a given categorisation function. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) +/// #([1, 3, 5], [2, 4]) +/// ``` +/// +pub fn partition( + list: List(a), + with categorise: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_partition(list, categorise, [], []) +} + +/// Returns all the permutations of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > permutations([1, 2]) +/// [[1, 2], [2, 1]] +/// ``` +/// +pub fn permutations(l: List(a)) -> List(List(a)) { + case l { + [] -> [[]] + _ -> + l + |> index_map(fn(i_idx, i) { + l + |> index_fold( + [], + fn(acc, j, j_idx) { + case i_idx == j_idx { + True -> acc + False -> [j, ..acc] + } + }, + ) + |> reverse + |> permutations + |> map(fn(permutation) { [i, ..permutation] }) + }) + |> concat + } +} + +fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { + let window = take(l, n) + + case length(window) == n { + True -> do_window([window, ..acc], drop(l, 1), n) + False -> acc + } +} + +/// Returns a list of sliding windows. +/// +/// ## Examples +/// +/// ```gleam +/// > window([1,2,3,4,5], 3) +/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] +/// ``` +/// +/// ```gleam +/// > window([1, 2], 4) +/// [] +/// ``` +/// +pub fn window(l: List(a), by n: Int) -> List(List(a)) { + do_window([], l, n) + |> reverse +} + +/// Returns a list of tuples containing two contiguous elements. +/// +/// ## Examples +/// +/// ```gleam +/// > window_by_2([1,2,3,4]) +/// [#(1, 2), #(2, 3), #(3, 4)] +/// ``` +/// +/// ```gleam +/// > window_by_2([1]) +/// [] +/// ``` +/// +pub fn window_by_2(l: List(a)) -> List(#(a, a)) { + zip(l, drop(l, 1)) +} + +/// Drops the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) +/// [3, 4] +/// ``` +/// +pub fn drop_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + case list { + [] -> [] + [x, ..xs] -> + case predicate(x) { + True -> drop_while(xs, predicate) + False -> [x, ..xs] + } + } +} + +fn do_take_while( + list: List(a), + predicate: fn(a) -> Bool, + acc: List(a), +) -> List(a) { + case list { + [] -> reverse(acc) + [first, ..rest] -> + case predicate(first) { + True -> do_take_while(rest, predicate, [first, ..acc]) + False -> reverse(acc) + } + } +} + +/// Takes the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) +/// [1, 2] +/// ``` +/// +pub fn take_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + do_take_while(list, predicate, []) +} + +fn do_chunk( + list: List(a), + f: fn(a) -> key, + previous_key: key, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [first, ..rest] -> { + let key = f(first) + case key == previous_key { + False -> { + let new_acc = [reverse(current_chunk), ..acc] + do_chunk(rest, f, key, [first], new_acc) + } + _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) + } + } + _empty -> reverse([reverse(current_chunk), ..acc]) + } +} + +/// Returns a list of chunks in which +/// the return value of calling `f` on each element is the same. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { + case list { + [] -> [] + [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) + } +} + +fn do_sized_chunk( + list: List(a), + count: Int, + left: Int, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [] -> + case current_chunk { + [] -> reverse(acc) + remaining -> reverse([reverse(remaining), ..acc]) + } + [first, ..rest] -> { + let chunk = [first, ..current_chunk] + case left > 1 { + False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) + True -> do_sized_chunk(rest, count, left - 1, chunk, acc) + } + } + } +} + +/// Returns a list of chunks containing `count` elements each. +/// +/// If the last chunk does not have `count` elements, it is instead +/// a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { + do_sized_chunk(list, count, count, [], []) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first element in the list +/// and combines it with each subsequent element in turn using the given +/// function. The function is called as `fun(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an +/// empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [first, ..rest] -> Ok(fold(rest, first, fun)) + } +} + +fn do_scan( + list: List(a), + accumulator: acc, + accumulated: List(acc), + fun: fn(acc, a) -> acc, +) -> List(acc) { + case list { + [] -> reverse(accumulated) + [x, ..xs] -> { + let next = fun(accumulator, x) + do_scan(xs, next, [next, ..accumulated], fun) + } + } +} + +/// Similar to `fold`, but yields the state of the accumulator at each stage. +/// +/// ## Examples +/// +/// ```gleam +/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) +/// [101, 103, 106] +/// ``` +/// +pub fn scan( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> List(acc) { + do_scan(list, initial, [], fun) +} + +/// Returns the last element in the given list. +/// +/// Returns `Error(Nil)` if the list is empty. +/// +/// This function runs in linear time. +/// For a collection oriented around performant access at either end, +/// see `gleam/queue.Queue`. +/// +/// ## Examples +/// +/// ```gleam +/// > last([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last([1, 2, 3, 4, 5]) +/// Ok(5) +/// ``` +/// +pub fn last(list: List(a)) -> Result(a, Nil) { + list + |> reduce(fn(_, elem) { elem }) +} + +/// Return unique combinations of elements in the list. +/// +/// ## Examples +/// +/// ```gleam +/// > combinations([1, 2, 3], 2) +/// [[1, 2], [1, 3], [2, 3]] +/// ``` +/// +/// ```gleam +/// > combinations([1, 2, 3, 4], 3) +/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] +/// ``` +/// +pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { + case n { + 0 -> [[]] + _ -> + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = + map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) + |> reverse + fold( + first_combinations, + combinations(xs, n), + fn(acc, c) { [c, ..acc] }, + ) + } + } + } +} + +fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = map(xs, with: fn(other) { #(x, other) }) + [first_combinations, ..do_combination_pairs(xs)] + } + } +} + +/// Return unique pair combinations of elements in the list +/// +/// ## Examples +/// +/// ```gleam +/// > combination_pairs([1, 2, 3]) +/// [#(1, 2), #(1, 3), #(2, 3)] +/// ``` +/// +pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { + do_combination_pairs(items) + |> concat +} + +/// Make a list alternating the elements from the given lists +/// +/// ## Examples +/// +/// ```gleam +/// > list.interleave([[1, 2], [101, 102], [201, 202]]) +/// [1, 101, 201, 2, 102, 202] +/// ``` +/// +pub fn interleave(list: List(List(a))) -> List(a) { + transpose(list) + |> concat +} + +/// Transpose rows and columns of the list of lists. +/// +/// Notice: This function is not tail recursive, +/// and thus may exceed stack size if called, +/// with large lists (on target JavaScript). +/// +/// ## Examples +/// +/// ```gleam +/// > transpose([[1, 2, 3], [101, 102, 103]]) +/// [[1, 101], [2, 102], [3, 103]] +/// ``` +/// +pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { + let take_first = fn(list) { + case list { + [] -> [] + [f] -> [f] + [f, ..] -> [f] + } + } + + case list_of_list { + [] -> [] + [[], ..xss] -> transpose(xss) + rows -> { + let firsts = + rows + |> map(take_first) + |> concat + let rest = transpose(map(rows, drop(_, 1))) + [firsts, ..rest] + } + } +} + +fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + [elem_pair, ..enumerable] -> + do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) + } +} + +fn do_shuffle_by_pair_indexes( + list_of_pairs: List(#(Float, a)), +) -> List(#(Float, a)) { + sort( + list_of_pairs, + fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { + float.compare(a_pair.0, b_pair.0) + }, + ) +} + +/// Takes a list, randomly sorts all items and returns the shuffled list. +/// +/// This function uses Erlang's `:rand` module or Javascript's +/// `Math.random()` to calculate the index shuffling. +/// +/// ## Example +/// +/// ```gleam +/// > range(1, 10) +/// > |> shuffle() +/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] +/// ``` +/// +pub fn shuffle(list: List(a)) -> List(a) { + list + |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) + |> do_shuffle_by_pair_indexes() + |> do_shuffle_pair_unwrap([]) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam new file mode 100644 index 00000000000..1f8b228eb90 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam @@ -0,0 +1,127 @@ +import gleam/option.{type Option} +import gleam/dict + +@deprecated("Please use the `gleam/dict` module instead") +pub type Map(key, value) = + dict.Dict(key, value) + +@deprecated("Please use the `gleam/dict` module instead") +pub fn size(map) -> Int { + dict.size(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn to_list(map) -> List(#(key, value)) { + dict.to_list(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn from_list(list: List(#(k, v))) { + dict.from_list(list) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn has_key(map, key: k) -> Bool { + dict.has_key(map, key) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn new() { + dict.new() +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn get(from, get: key) -> Result(value, Nil) { + dict.get(from, get) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn insert(into map, for key: k, insert value: v) { + dict.insert(map, key, value) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn map_values(in map, with fun: fn(k, v) -> w) { + dict.map_values(map, fun) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn keys(map) -> List(keys) { + dict.keys(map) +} + +@target(javascript) +fn reverse_and_concat(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) + } +} + +@target(javascript) +fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) + } +} + +@target(javascript) +fn do_keys(map) -> List(k) { + let list_of_pairs = + map + |> to_list + do_keys_acc(list_of_pairs, []) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn values(map) -> List(values) { + dict.values(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { + dict.filter(map, predicate) +} + +@target(javascript) +fn do_filter(f: fn(key, value) -> Bool, map) { + let insert = fn(map, k, v) { + case f(k, v) { + True -> insert(map, k, v) + _ -> map + } + } + map + |> fold(from: new(), with: insert) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn take(from map, keeping desired_keys: List(k)) { + dict.take(map, desired_keys) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn merge(into map, from new_entries) { + dict.merge(map, new_entries) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn delete(from map, delete key: k) { + dict.delete(map, key) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn drop(from map, drop disallowed_keys: List(k)) { + dict.drop(map, disallowed_keys) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { + dict.update(map, key, fun) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { + dict.fold(map, initial, fun) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam new file mode 100644 index 00000000000..6015c0fff8f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam @@ -0,0 +1,346 @@ +/// `Option` represents a value that may be present or not. `Some` means the value is +/// present, `None` means the value is not. +/// +/// This is Gleam's alternative to having a value that could be Null, as is +/// possible in some other languages. +/// +pub type Option(a) { + Some(a) + None +} + +fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { + case list { + [] -> Some(acc) + [x, ..rest] -> { + let accumulate = fn(acc, item) { + case acc, item { + Some(values), Some(value) -> Some([value, ..values]) + _, _ -> None + } + } + accumulate(do_all(rest, acc), x) + } + } +} + +/// Combines a list of `Option`s into a single `Option`. +/// If all elements in the list are `Some` then returns a `Some` holding the list of values. +/// If any element is `None` then returns`None`. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Some(1), Some(2)]) +/// Some([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Some(1), None]) +/// None +/// ``` +/// +pub fn all(list: List(Option(a))) -> Option(List(a)) { + do_all(list, []) +} + +/// Checks whether the `Option` is a `Some` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_some(Some(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_some(None) +/// False +/// ``` +/// +pub fn is_some(option: Option(a)) -> Bool { + option != None +} + +/// Checks whether the `Option` is a `None` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_none(Some(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_none(None) +/// True +/// ``` +/// +pub fn is_none(option: Option(a)) -> Bool { + option == None +} + +/// Converts an `Option` type to a `Result` type. +/// +/// ## Examples +/// +/// ```gleam +/// > to_result(Some(1), "some_error") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > to_result(None, "some_error") +/// Error("some_error") +/// ``` +/// +pub fn to_result(option: Option(a), e) -> Result(a, e) { + case option { + Some(a) -> Ok(a) + _ -> Error(e) + } +} + +/// Converts a `Result` type to an `Option` type. +/// +/// ## Examples +/// +/// ```gleam +/// > from_result(Ok(1)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > from_result(Error("some_error")) +/// None +/// ``` +/// +pub fn from_result(result: Result(a, e)) -> Option(a) { + case result { + Ok(a) -> Some(a) + _ -> None + } +} + +/// Extracts the value from an `Option`, returning a default value if there is none. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Some(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(None, 0) +/// 0 +/// ``` +/// +pub fn unwrap(option: Option(a), or default: a) -> a { + case option { + Some(x) -> x + None -> default + } +} + +/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Some(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(None, fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { + case option { + Some(x) -> x + None -> default() + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it. +/// +/// If the `Option` is a `None` rather than `Some`, the function is not called and the +/// `Option` stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Some(1), with: fn(x) { x + 1 }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > map(over: None, with: fn(x) { x + 1 }) +/// None +/// ``` +/// +pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { + case option { + Some(x) -> Some(fun(x)) + None -> None + } +} + +/// Merges a nested `Option` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Some(Some(1))) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > flatten(Some(None)) +/// None +/// ``` +/// +/// ```gleam +/// > flatten(None) +/// None +/// ``` +/// +pub fn flatten(option: Option(Option(a))) -> Option(a) { + case option { + Some(x) -> x + None -> None + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it, where the given function also returns an `Option`. The two options are +/// then merged together into one `Option`. +/// +/// If the `Option` is a `None` rather than `Some` the function is not called and the +/// option stays the same. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that return `Option`. +/// +/// ## Examples +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(x + 1) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(#("a", x)) }) +/// Some(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(_) { None }) +/// None +/// ``` +/// +/// ```gleam +/// > then(None, fn(x) { Some(x + 1) }) +/// None +/// ``` +/// +pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { + case option { + Some(x) -> fun(x) + None -> None + } +} + +/// Returns the first value if it is `Some`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Some(1), Some(2)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(Some(1), None) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(None, Some(2)) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > or(None, None) +/// None +/// ``` +/// +pub fn or(first: Option(a), second: Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second + } +} + +/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { Some(2) }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { None }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { Some(2) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { None }) +/// None +/// ``` +/// +pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second() + } +} + +fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + [x, ..xs] -> { + let accumulate = fn(acc, item) { + case item { + Some(value) -> [value, ..acc] + None -> acc + } + } + accumulate(do_values(xs, acc), x) + } + } +} + +/// Given a list of `Option`s, +/// returns only the values inside `Some`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Some(1), None, Some(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(options: List(Option(a))) -> List(a) { + do_values(options, []) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam new file mode 100644 index 00000000000..12ce01136ca --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam @@ -0,0 +1,133 @@ +/// Represents the result of a single comparison to determine the precise +/// ordering of two values. +/// +pub type Order { + /// Less-than + Lt + + /// Equal + Eq + + /// Greater than + Gt +} + +/// Inverts an order, so less-than becomes greater-than and greater-than +/// becomes less-than. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(Lt) +/// Gt +/// ``` +/// +/// ```gleam +/// > negate(Eq) +/// Eq +/// ``` +/// +/// ```gleam +/// > negate(Lt) +/// Gt +/// ``` +/// +pub fn negate(order: Order) -> Order { + case order { + Lt -> Gt + Eq -> Eq + Gt -> Lt + } +} + +/// Produces a numeric representation of the order. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(Lt) +/// -1 +/// ``` +/// +/// ```gleam +/// > to_int(Eq) +/// 0 +/// ``` +/// +/// ```gleam +/// > to_int(Gt) +/// 1 +/// ``` +/// +pub fn to_int(order: Order) -> Int { + case order { + Lt -> -1 + Eq -> 0 + Gt -> 1 + } +} + +/// Compares two `Order` values to one another, producing a new `Order`. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(Eq, with: Lt) +/// Gt +/// ``` +/// +pub fn compare(a: Order, with b: Order) -> Order { + case a, b { + x, y if x == y -> Eq + Lt, _ | Eq, Gt -> Lt + _, _ -> Gt + } +} + +/// Returns the largest of two orders given that `Gt > Eq > Lt`. +/// +/// ## Examples +/// +/// ```gleam +/// > max(Eq, Lt) +/// Eq +/// ``` +/// +pub fn max(a: Order, b: Order) -> Order { + case a, b { + Gt, _ -> Gt + Eq, Lt -> Eq + _, _ -> b + } +} + +/// Returns the smallest of two orders given that `Gt > Eq > Lt`. +/// +/// ## Examples +/// +/// ```gleam +/// > min(Eq, Lt) +/// Lt +/// ``` +/// +pub fn min(a: Order, b: Order) -> Order { + case a, b { + Lt, _ -> Lt + Eq, Gt -> Eq + _, _ -> b + } +} + +/// Inverts an ordering function, so less-than becomes greater-than and greater-than +/// becomes less-than. +/// +/// ## Examples +/// +/// ```gleam +/// > list.sort([1, 5, 4], by: reverse(int.compare)) +/// [5, 4, 1] +/// ``` +/// +pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { + fn(a, b) { orderer(b, a) } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam new file mode 100644 index 00000000000..894e6a8d9f1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam @@ -0,0 +1,85 @@ +/// Returns the first element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > first(#(1, 2)) +/// 1 +/// ``` +/// +pub fn first(pair: #(a, b)) -> a { + let #(a, _) = pair + a +} + +/// Returns the second element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > second(#(1, 2)) +/// 2 +/// ``` +/// +pub fn second(pair: #(a, b)) -> b { + let #(_, a) = pair + a +} + +/// Returns a new pair with the elements swapped. +/// +/// ## Examples +/// +/// ```gleam +/// > swap(#(1, 2)) +/// #(2, 1) +/// ``` +/// +pub fn swap(pair: #(a, b)) -> #(b, a) { + let #(a, b) = pair + #(b, a) +} + +/// Returns a new pair with the first element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_first(fn(n) { n * 2 }) +/// #(2, 2) +/// ``` +/// +pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { + let #(a, b) = pair + #(fun(a), b) +} + +/// Returns a new pair with the second element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_second(fn(n) { n * 2 }) +/// #(1, 4) +/// ``` +/// +pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { + let #(a, b) = pair + #(a, fun(b)) +} + +/// Returns a new pair with the given elements. This can also be done using the dedicated +/// syntax instead: `new(1, 2) == #(1, 2)`. +/// +/// ## Examples +/// +/// ```gleam +/// > new(1, 2) +/// #(1, 2) +/// ``` +/// +pub fn new(first: a, second: b) -> #(a, b) { + #(first, second) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam new file mode 100644 index 00000000000..5bf60c8a529 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam @@ -0,0 +1,292 @@ +import gleam/list + +/// A queue is an ordered collection of elements. It is similar to a list, but +/// unlike a list elements can be added to or removed from either the front or +/// the back in a performant fashion. +/// +/// The internal representation may be different for two queues with the same +/// elements in the same order if the queues were constructed in different +/// ways. This is the price paid for a queue's fast access at both the front +/// and the back. +/// +/// Because of unpredictable internal representation the equality operator `==` +/// may return surprising results, and the `is_equal` and `is_logically_equal` +/// functions are the recommended way to test queues for equality. +/// +pub opaque type Queue(element) { + Queue(in: List(element), out: List(element)) +} + +/// Creates a fresh queue that contains no values. +/// +pub fn new() -> Queue(a) { + Queue(in: [], out: []) +} + +/// Converts a list of elements into a queue of the same elements in the same +/// order. The first element in the list becomes the front element in the queue. +/// +/// This function runs in constant time. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2, 3] |> from_list |> length +/// 3 +/// ``` +/// +pub fn from_list(list: List(a)) -> Queue(a) { + Queue(in: [], out: list) +} + +/// Converts a queue of elements into a list of the same elements in the same +/// order. The front element in the queue becomes the first element in the list. +/// +/// This function runs in linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() |> push_back(1) |> push_back(2) |> to_list +/// [1, 2] +/// ``` +/// +pub fn to_list(queue: Queue(a)) -> List(a) { + queue.out + |> list.append(list.reverse(queue.in)) +} + +/// Determines whether or not the queue is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> is_empty +/// False +/// ``` +/// +pub fn is_empty(queue: Queue(a)) -> Bool { + queue.in == [] && queue.out == [] +} + +/// Counts the number of elements in a given queue. +/// +/// This function has to traverse the queue to determine the number of elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length(from_list([])) +/// 0 +/// ``` +/// +/// ```gleam +/// > length(from_list([1])) +/// 1 +/// ``` +/// +/// ```gleam +/// > length(from_list([1, 2])) +/// 2 +/// ``` +/// +pub fn length(queue: Queue(a)) -> Int { + list.length(queue.in) + list.length(queue.out) +} + +/// Pushes an element onto the back of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2] |> from_list |> push_back(3) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: [item, ..queue.in], out: queue.out) +} + +/// Pushes an element onto the front of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [0, 0] |> from_list |> push_front(1) |> to_list +/// [1, 0, 0] +/// ``` +/// +pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: queue.in, out: [item, ..queue.out]) +} + +/// Gets the last element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() +/// > |> push_back(0) +/// > |> push_back(1) +/// > |> pop_back() +/// Ok(#(1, push_front(new(), 0))) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> push_front(0) +/// > |> pop_back() +/// Ok(#(0, new())) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) + Queue(in: [first, ..rest], out: out) -> { + let queue = Queue(in: rest, out: out) + Ok(#(first, queue)) + } + } +} + +/// Gets the first element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_front(1) +/// > |> queue.push_front(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.push_back(queue.new(), 1))) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_back(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.new())) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) + Queue(in: in, out: [first, ..rest]) -> { + let queue = Queue(in: in, out: rest) + Ok(#(first, queue)) + } + } +} + +/// Creates a new queue from a given queue containing the same elements, but in +/// the opposite order. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> reverse |> to_list +/// [] +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> reverse |> to_list +/// [1] +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> reverse |> to_list +/// [2, 1] +/// ``` +/// +pub fn reverse(queue: Queue(a)) -> Queue(a) { + Queue(in: queue.out, out: queue.in) +} + +fn check_equal( + xs: List(t), + x_tail: List(t), + ys: List(t), + y_tail: List(t), + eq: fn(t, t) -> Bool, +) -> Bool { + case xs, x_tail, ys, y_tail { + [], [], [], [] -> True + [x, ..xs], _, [y, ..ys], _ -> + case eq(x, y) { + False -> False + True -> check_equal(xs, x_tail, ys, y_tail, eq) + } + [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) + _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) + _, _, _, _ -> False + } +} + +/// Checks whether two queues have equal elements in the same order, where the +/// equality of elements is determined by a given equality checking function. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time multiplied by the time taken by the +/// element equality checking function. +/// +pub fn is_logically_equal( + a: Queue(t), + to b: Queue(t), + checking element_is_equal: fn(t, t) -> Bool, +) -> Bool { + check_equal(a.out, a.in, b.out, b.in, element_is_equal) +} + +/// Checks whether two queues have the same elements in the same order. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time. +/// +pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { + check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam new file mode 100644 index 00000000000..9ffda789f6a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam @@ -0,0 +1,214 @@ +//// This module contains regular expression matching functions for strings. +//// The matching algorithms of the library are based on the PCRE library, but not +//// all of the PCRE library is interfaced and some parts of the library go beyond +//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. + +import gleam/option.{type Option} + +pub type Regex + +/// The details about a particular match: +/// +pub type Match { + Match( + /// The full string of the match. + content: String, + /// A `Regex` can have subpatterns, sup-parts that are in parentheses. + submatches: List(Option(String)), + ) +} + +/// When a regular expression fails to compile: +/// +pub type CompileError { + CompileError( + /// The problem encountered that caused the compilation to fail + error: String, + /// The byte index into the string to where the problem was found + /// This value may not be correct in JavaScript environments. + byte_index: Int, + ) +} + +pub type Options { + Options(case_insensitive: Bool, multi_line: Bool) +} + +/// Creates a `Regex` with some additional options. +/// +/// ## Examples +/// +/// ```gleam +/// > let options = Options(case_insensitive: False, multi_line: True) +/// > let assert Ok(re) = compile("^[0-9]", with: options) +/// > check(re, "abc\n123") +/// True +/// ``` +/// +/// ```gleam +/// > let options = Options(case_insensitive: True, multi_line: False) +/// > let assert Ok(re) = compile("[A-Z]", with: options) +/// > check(re, "abc123") +/// True +/// ``` +/// +pub fn compile( + pattern: String, + with options: Options, +) -> Result(Regex, CompileError) { + do_compile(pattern, options) +} + +@external(erlang, "gleam_stdlib", "compile_regex") +@external(javascript, "../gleam_stdlib.mjs", "compile_regex") +fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) + +/// Creates a new `Regex`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[0-9]") +/// > check(re, "abc123") +/// True +/// ``` +/// +/// ```gleam +/// > check(re, "abcxyz") +/// False +/// ``` +/// +/// ```gleam +/// > from_string("[0-9") +/// Error( +/// CompileError( +/// error: "missing terminating ] for character class", +/// byte_index: 4 +/// ) +/// ) +/// ``` +/// +pub fn from_string(pattern: String) -> Result(Regex, CompileError) { + compile(pattern, Options(case_insensitive: False, multi_line: False)) +} + +/// Returns a boolean indicating whether there was a match or not. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("^f.o.?") +/// > check(with: re, content: "foo") +/// True +/// ``` +/// +/// ```gleam +/// > check(with: re, content: "boo") +/// False +/// ``` +/// +pub fn check(with regex: Regex, content content: String) -> Bool { + do_check(regex, content) +} + +@external(erlang, "gleam_stdlib", "regex_check") +@external(javascript, "../gleam_stdlib.mjs", "regex_check") +fn do_check(a: Regex, b: String) -> Bool + +/// Splits a string. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string(" *, *") +/// > split(with: re, content: "foo,32, 4, 9 ,0") +/// ["foo", "32", "4", "9", "0"] +/// ``` +/// +pub fn split(with regex: Regex, content string: String) -> List(String) { + do_split(regex, string) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "regex_split") +fn do_split(a: Regex, b: String) -> List(String) + +@target(javascript) +fn do_split(regex, string) -> List(String) { + js_split(string, regex) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split") +fn js_split(a: String, b: Regex) -> List(String) + +/// Collects all matches of the regular expression. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") +/// > scan(with: re, content: "I am on a boat in a lake.") +/// [ +/// Match( +/// content: "on a boat", +/// submatches: [Some("boat")] +/// ), +/// Match( +/// content: "in a lake", +/// submatches: [Some("lake")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") +/// > scan(with: re, content: "-36") +/// [ +/// Match( +/// content: "-36", +/// submatches: [Some("-"), Some("36")] +/// ) +/// ] +/// +/// > scan(with: re, content: "36") +/// [ +/// Match( +/// content: "36", +/// submatches: [None, Some("36")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") +/// > scan(with: re, content: "var age = 32") +/// [ +/// Match( +/// content: "var age = 32", +/// submatches: [Some("age"), None, Some("32")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") +/// > scan(with: re, content: "let age = 32") +/// [ +/// Match( +/// content: "let age = 32", +/// submatches: [Some("age"), Some("32")] +/// ) +/// ] +/// +/// > scan(with: re, content: "const age = 32") +/// [] +/// ``` +/// +pub fn scan(with regex: Regex, content string: String) -> List(Match) { + do_scan(regex, string) +} + +@external(erlang, "gleam_stdlib", "regex_scan") +@external(javascript, "../gleam_stdlib.mjs", "regex_scan") +fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam new file mode 100644 index 00000000000..fb6dddb3110 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam @@ -0,0 +1,482 @@ +//// Result represents the result of something that may succeed or not. +//// `Ok` means it was successful, `Error` means it was not successful. + +import gleam/list + +/// Checks whether the result is an `Ok` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_ok(Ok(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_ok(Error(Nil)) +/// False +/// ``` +/// +pub fn is_ok(result: Result(a, e)) -> Bool { + case result { + Error(_) -> False + Ok(_) -> True + } +} + +/// Checks whether the result is an `Error` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_error(Ok(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_error(Error(Nil)) +/// True +/// ``` +/// +pub fn is_error(result: Result(a, e)) -> Bool { + case result { + Ok(_) -> False + Error(_) -> True + } +} + +/// Updates a value held within the `Ok` of a result by calling a given function +/// on it. +/// +/// If the result is an `Error` rather than `Ok` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > map(over: Error(1), with: fn(x) { x + 1 }) +/// Error(1) +/// ``` +/// +pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { + case result { + Ok(x) -> Ok(fun(x)) + Error(e) -> Error(e) + } +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it. +/// +/// If the result is `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map_error(over: Error(1), with: fn(x) { x + 1 }) +/// Error(2) +/// ``` +/// +/// ```gleam +/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(1) +/// ``` +/// +pub fn map_error( + over result: Result(a, e), + with fun: fn(e) -> f, +) -> Result(a, f) { + case result { + Ok(x) -> Ok(x) + Error(error) -> Error(fun(error)) + } +} + +/// Merges a nested `Result` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Ok(Ok(1))) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > flatten(Ok(Error(""))) +/// Error("") +/// ``` +/// +/// ```gleam +/// > flatten(Error(Nil)) +/// Error(Nil) +/// ``` +/// +pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { + case result { + Ok(x) -> x + Error(error) -> Error(error) + } +} + +/// "Updates" an `Ok` result by passing its value to a function that yields a result, +/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) +/// +/// If the input is an `Error` rather than an `Ok`, the function is not called and +/// the original `Error` is returned. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that may fail. +/// +/// ## Examples +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(x + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) +/// Ok(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(_) { Error("Oh no") }) +/// Error("Oh no") +/// ``` +/// +/// ```gleam +/// > try(Error(Nil), fn(x) { Ok(x + 1) }) +/// Error(Nil) +/// ``` +/// +pub fn try( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + case result { + Ok(x) -> fun(x) + Error(e) -> Error(e) + } +} + +/// An alias for `try`. See the documentation for that function for more information. +/// +pub fn then( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + try(result, fun) +} + +/// Extracts the `Ok` value from a result, returning a default value if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Ok(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(Error(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap(result: Result(a, e), or default: a) -> a { + case result { + Ok(v) -> v + Error(_) -> default + } +} + +/// Extracts the `Ok` value from a result, evaluating the default function if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Ok(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(Error(""), fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { + case result { + Ok(v) -> v + Error(_) -> default() + } +} + +/// Extracts the `Error` value from a result, returning a default value if the result +/// is an `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_error(Error(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_error(Ok(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap_error(result: Result(a, e), or default: e) -> e { + case result { + Ok(_) -> default + Error(e) -> e + } +} + +/// Extracts the inner value from a result. Both the value and error must be of +/// the same type. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_both(Error(1)) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_both(Ok(2)) +/// 2 +/// ``` +/// +pub fn unwrap_both(result: Result(a, a)) -> a { + case result { + Ok(a) -> a + Error(a) -> a + } +} + +/// Transforms any error into `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > nil_error(Error(1)) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > nil_error(Ok(1)) +/// Ok(1) +/// ``` +/// +pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { + map_error(result, fn(_) { Nil }) +} + +/// Returns the first value if it is `Ok`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Ok(1), Ok(2)) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Ok(1), Error("Error 2")) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Ok(2)) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Error("Error 2")) +/// Error("Error 2") +/// ``` +/// +pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second + } +} + +/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Ok(2) }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Error("Error 2") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) +/// Error("Error 2") +/// ``` +/// +pub fn lazy_or( + first: Result(a, e), + second: fn() -> Result(a, e), +) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second() + } +} + +/// Combines a list of results into a single result. +/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. +/// If any element is `Error` then returns the first error. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Ok(1), Ok(2)]) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Ok(1), Error("e")]) +/// Error("e") +/// ``` +/// +pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { + list.try_map(results, fn(x) { x }) +} + +/// Given a list of results, returns a pair where the first element is a list +/// of all the values inside `Ok` and the second element is a list with all the +/// values inside `Error`. The values in both lists appear in reverse order with +/// respect to their position in the original list of results. +/// +/// ## Examples +/// +/// ```gleam +/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) +/// #([2, 1], ["b", "a"]) +/// ``` +/// +pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { + do_partition(results, [], []) +} + +fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { + case results { + [] -> #(oks, errors) + [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) + [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) + } +} + +/// Replace the value within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace(Ok(1), Nil) +/// Ok(Nil) +/// ``` +/// +/// ```gleam +/// > replace(Error(1), Nil) +/// Error(1) +/// ``` +/// +pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { + case result { + Ok(_) -> Ok(value) + Error(error) -> Error(error) + } +} + +/// Replace the error within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace_error(Error(1), Nil) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > replace_error(Ok(1), Nil) +/// Ok(1) +/// ``` +/// +pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { + case result { + Ok(x) -> Ok(x) + Error(_) -> Error(error) + } +} + +/// Given a list of results, returns only the values inside `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Ok(1), Error("a"), Ok(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(results: List(Result(a, e))) -> List(a) { + list.filter_map(results, fn(r) { r }) +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it, where the given function also returns a result. The two results are +/// then merged together into one result. +/// +/// If the result is an `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// This function is useful for chaining together computations that may fail +/// and trying to recover from possible errors. +/// +/// ## Examples +/// +/// ```gleam +/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) +/// Error("failed to recover") +/// ``` +/// +pub fn try_recover( + result: Result(a, e), + with fun: fn(e) -> Result(a, f), +) -> Result(a, f) { + case result { + Ok(value) -> Ok(value) + Error(error) -> fun(error) + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam new file mode 100644 index 00000000000..df8d500e804 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam @@ -0,0 +1,264 @@ +import gleam/list +import gleam/dict.{type Dict} +import gleam/result + +// A list is used as the map value as an empty list has the smallest +// representation in Erlang's binary format +@target(erlang) +type Token = + List(Nil) + +@target(erlang) +const token = [] + +@target(javascript) +type Token = + Nil + +@target(javascript) +const token = Nil + +/// A set is a collection of unique members of the same type. +/// +/// It is implemented using the `gleam/map` module, so inserts and lookups have +/// logarithmic time complexity. +/// +pub opaque type Set(member) { + Set(map: Dict(member, Token)) +} + +/// Creates a new empty set. +/// +pub fn new() -> Set(member) { + Set(dict.new()) +} + +/// Gets the number of members in a set. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn size(set: Set(member)) -> Int { + dict.size(set.map) +} + +/// Inserts an member into the set. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn insert(into set: Set(member), this member: member) -> Set(member) { + Set(map: dict.insert(set.map, member, token)) +} + +/// Checks whether a set contains a given member. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(2) +/// True +/// ``` +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn contains(in set: Set(member), this member: member) -> Bool { + set.map + |> dict.get(member) + |> result.is_ok +} + +/// Removes a member from a set. If the set does not contain the member then +/// the set is returned unchanged. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> delete(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn delete(from set: Set(member), this member: member) -> Set(member) { + Set(map: dict.delete(set.map, member)) +} + +/// Converts the set into a list of the contained members. +/// +/// The list has no specific ordering, any unintentional ordering may change in +/// future versions of Gleam or Erlang. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert(2) |> to_list +/// [2] +/// ``` +/// +pub fn to_list(set: Set(member)) -> List(member) { + dict.keys(set.map) +} + +/// Creates a new set of the members in a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort +/// [1, 3, 3, 4] +/// ``` +/// +pub fn from_list(members: List(member)) -> Set(member) { + let map = + list.fold( + over: members, + from: dict.new(), + with: fn(m, k) { dict.insert(m, k, token) }, + ) + Set(map) +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Sets are not ordered so the values are not returned in any specific order. +/// Do not write code that relies on the order entries are used by this +/// function as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > from_list([1, 3, 9]) +/// > |> fold(0, fn(member, accumulator) { accumulator + member }) +/// 13 +/// ``` +/// +pub fn fold( + over set: Set(member), + from initial: acc, + with reducer: fn(acc, member) -> acc, +) -> acc { + dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) +} + +/// Creates a new set from an existing set, minus any members that a given +/// function returns `False` for. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > from_list([1, 4, 6, 3, 675, 44, 67]) +/// > |> filter(for: int.is_even) +/// > |> to_list +/// [4, 6, 44] +/// ``` +/// +pub fn filter( + in set: Set(member), + keeping predicate: fn(member) -> Bool, +) -> Set(member) { + Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) +} + +pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { + list.fold(over: disallowed, from: set, with: delete) +} + +/// Creates a new map from a given map, only including any members which are in +/// a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) +/// > |> take([1, 3, 5]) +/// > |> to_list +/// [1, 3] +/// ``` +/// +pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { + Set(dict.take(from: set.map, keeping: desired)) +} + +fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { + case dict.size(first.map) > dict.size(second.map) { + True -> #(first, second) + False -> #(second, first) + } +} + +/// Creates a new set that contains all members of both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { + let #(larger, smaller) = order(first, second) + fold(over: smaller, from: larger, with: insert) +} + +/// Creates a new set that contains members that are present in both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [2] +/// ``` +/// +pub fn intersection( + of first: Set(member), + and second: Set(member), +) -> Set(member) { + let #(larger, smaller) = order(first, second) + take(from: larger, keeping: to_list(smaller)) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam new file mode 100644 index 00000000000..7254fd9fd1c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam @@ -0,0 +1,913 @@ +//// Strings in Gleam are UTF-8 binaries. They can be written in your code as +//// text surrounded by `"double quotes"`. + +import gleam/iterator.{type Iterator} +import gleam/list +import gleam/option.{type Option, None, Some} +import gleam/order +import gleam/string_builder.{type StringBuilder} + +/// Determines if a `String` is empty. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty("") +/// True +/// ``` +/// +/// ```gleam +/// > is_empty("the world") +/// False +/// ``` +/// +pub fn is_empty(str: String) -> Bool { + str == "" +} + +/// Gets the number of grapheme clusters in a given `String`. +/// +/// This function has to iterate across the whole string to count the number of +/// graphemes, so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length("Gleam") +/// 5 +/// ``` +/// +/// ```gleam +/// > length("ß↑e̊") +/// 3 +/// ``` +/// +/// ```gleam +/// > length("") +/// 0 +/// ``` +/// +pub fn length(string: String) -> Int { + do_length(string) +} + +@external(erlang, "string", "length") +@external(javascript, "../gleam_stdlib.mjs", "string_length") +fn do_length(a: String) -> Int + +/// Reverses a `String`. +/// +/// This function has to iterate across the whole `String` so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse("stressed") +/// "desserts" +/// ``` +/// +pub fn reverse(string: String) -> String { + do_reverse(string) +} + +@target(erlang) +fn do_reverse(string: String) -> String { + string + |> string_builder.from_string + |> string_builder.reverse + |> string_builder.to_string +} + +@target(javascript) +fn do_reverse(string: String) -> String { + string + |> to_graphemes + |> list.reverse + |> concat +} + +/// Creates a new `String` by replacing all occurrences of a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > replace("www.example.com", each: ".", with: "-") +/// "www-example-com" +/// ``` +/// +/// ```gleam +/// > replace("a,b,c,d,e", each: ",", with: "/") +/// "a/b/c/d/e" +/// ``` +/// +pub fn replace( + in string: String, + each pattern: String, + with substitute: String, +) -> String { + string + |> string_builder.from_string + |> string_builder.replace(each: pattern, with: substitute) + |> string_builder.to_string +} + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// lowercase. +/// +/// Useful for case-insensitive comparisons. +/// +/// ## Examples +/// +/// ```gleam +/// > lowercase("X-FILES") +/// "x-files" +/// ``` +/// +pub fn lowercase(string: String) -> String { + do_lowercase(string) +} + +@external(erlang, "string", "lowercase") +@external(javascript, "../gleam_stdlib.mjs", "lowercase") +fn do_lowercase(a: String) -> String + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// uppercase. +/// +/// Useful for case-insensitive comparisons and VIRTUAL YELLING. +/// +/// ## Examples +/// +/// ```gleam +/// > uppercase("skinner") +/// "SKINNER" +/// ``` +/// +pub fn uppercase(string: String) -> String { + do_uppercase(string) +} + +@external(erlang, "string", "uppercase") +@external(javascript, "../gleam_stdlib.mjs", "uppercase") +fn do_uppercase(a: String) -> String + +/// Compares two `String`s to see which is "larger" by comparing their graphemes. +/// +/// This does not compare the size or length of the given `String`s. +/// +/// ## Examples +/// +/// ```gleam +/// > compare("Anthony", "Anthony") +/// order.Eq +/// ``` +/// +/// ```gleam +/// > compare("A", "B") +/// order.Lt +/// ``` +/// +pub fn compare(a: String, b: String) -> order.Order { + case a == b { + True -> order.Eq + _ -> + case less_than(a, b) { + True -> order.Lt + _ -> order.Gt + } + } +} + +@external(erlang, "gleam_stdlib", "less_than") +@external(javascript, "../gleam_stdlib.mjs", "less_than") +fn less_than(a: String, b: String) -> Bool + +/// Takes a substring given a start grapheme index and a length. Negative indexes +/// are taken starting from the *end* of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 2) +/// "le" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 10) +/// "leam" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 10, length: 3) +/// "" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -2, length: 2) +/// "am" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -12, length: 2) +/// "" +/// ``` +/// +pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { + case len < 0 { + True -> "" + False -> + case idx < 0 { + True -> { + let translated_idx = length(string) + idx + case translated_idx < 0 { + True -> "" + False -> do_slice(string, translated_idx, len) + } + } + False -> do_slice(string, idx, len) + } + } +} + +@target(erlang) +@external(erlang, "string", "slice") +fn do_slice(a: String, b: Int, c: Int) -> String + +@target(javascript) +fn do_slice(string: String, idx: Int, len: Int) -> String { + string + |> to_graphemes + |> list.drop(idx) + |> list.take(len) + |> concat +} + +/// Drops contents of the first `String` that occur before the second `String`. +/// If the `from` string does not contain the `before` string, `from` is returned unchanged. +/// +/// ## Examples +/// +/// ```gleam +/// > crop(from: "The Lone Gunmen", before: "Lone") +/// "Lone Gunmen" +/// ``` +/// +@external(erlang, "gleam_stdlib", "crop_string") +@external(javascript, "../gleam_stdlib.mjs", "crop_string") +pub fn crop(from string: String, before substring: String) -> String + +/// Drops *n* graphemes from the left side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_left(from: "The Lone Gunmen", up_to: 2) +/// "e Lone Gunmen" +/// ``` +/// +pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, num_graphemes, length(string) - num_graphemes) + } +} + +/// Drops *n* graphemes from the right side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) +/// "Cigarette Smoking M" +/// ``` +/// +pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, 0, length(string) - num_graphemes) + } +} + +/// Checks if the first `String` contains the second. +/// +/// ## Examples +/// +/// ```gleam +/// > contains(does: "theory", contain: "ory") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "the") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "THE") +/// False +/// ``` +/// +@external(erlang, "gleam_stdlib", "contains_string") +@external(javascript, "../gleam_stdlib.mjs", "contains_string") +pub fn contains(does haystack: String, contain needle: String) -> Bool + +/// Checks whether the first `String` starts with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > starts_with("theory", "ory") +/// False +/// ``` +/// +pub fn starts_with(string: String, prefix: String) -> Bool { + do_starts_with(string, prefix) +} + +@external(erlang, "gleam_stdlib", "string_starts_with") +@external(javascript, "../gleam_stdlib.mjs", "starts_with") +fn do_starts_with(a: String, b: String) -> Bool + +/// Checks whether the first `String` ends with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > ends_with("theory", "ory") +/// True +/// ``` +/// +pub fn ends_with(string: String, suffix: String) -> Bool { + do_ends_with(string, suffix) +} + +@external(erlang, "gleam_stdlib", "string_ends_with") +@external(javascript, "../gleam_stdlib.mjs", "ends_with") +fn do_ends_with(a: String, b: String) -> Bool + +/// Creates a list of `String`s by splitting a given string on a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > split("home/gleam/desktop/", on: "/") +/// ["home", "gleam", "desktop", ""] +/// ``` +/// +pub fn split(x: String, on substring: String) -> List(String) { + case substring { + "" -> to_graphemes(x) + _ -> + x + |> string_builder.from_string + |> string_builder.split(on: substring) + |> list.map(with: string_builder.to_string) + } +} + +/// Splits a `String` a single time on the given substring. +/// +/// Returns an `Error` if substring not present. +/// +/// ## Examples +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "/") +/// Ok(#("home", "gleam/desktop/")) +/// ``` +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "?") +/// Error(Nil) +/// ``` +/// +pub fn split_once( + x: String, + on substring: String, +) -> Result(#(String, String), Nil) { + do_split_once(x, substring) +} + +@target(erlang) +@external(erlang, "string", "split") +fn erl_split(a: String, b: String) -> List(String) + +@target(erlang) +fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { + case erl_split(x, substring) { + [first, rest] -> Ok(#(first, rest)) + _ -> Error(Nil) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split_once") +fn do_split_once( + x x: String, + substring substring: String, +) -> Result(#(String, String), Nil) + +/// Creates a new `String` by joining two `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: "butter", suffix: "fly") +/// "butterfly" +/// ``` +/// +pub fn append(to first: String, suffix second: String) -> String { + first + |> string_builder.from_string + |> string_builder.append(second) + |> string_builder.to_string +} + +/// Creates a new `String` by joining many `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > concat(["never", "the", "less"]) +/// "nevertheless" +/// ``` +/// +pub fn concat(strings: List(String)) -> String { + strings + |> string_builder.from_strings + |> string_builder.to_string +} + +/// Creates a new `String` by repeating a `String` a given number of times. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("ha", times: 3) +/// "hahaha" +/// ``` +/// +pub fn repeat(string: String, times times: Int) -> String { + iterator.repeat(string) + |> iterator.take(times) + |> iterator.to_list + |> concat +} + +/// Joins many `String`s together with a given separator. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > join(["home","evan","Desktop"], with: "/") +/// "home/evan/Desktop" +/// ``` +/// +pub fn join(strings: List(String), with separator: String) -> String { + do_join(strings, separator) +} + +@target(erlang) +fn do_join(strings: List(String), separator: String) -> String { + strings + |> list.intersperse(with: separator) + |> concat +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "join") +fn do_join(strings strings: List(String), string string: String) -> String + +/// Pads a `String` on the left until it has at least given number of graphemes. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_left("121", to: 5, with: ".") +/// "..121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 3, with: ".") +/// "121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 2, with: ".") +/// "121" +/// ``` +/// +pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + padding(to_pad_length, pad_string) + |> iterator.append(iterator.single(string)) + |> iterator.to_list + |> concat +} + +/// Pads a `String` on the right until it has a given length. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_right("123", to: 5, with: ".") +/// "123.." +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 3, with: ".") +/// "123" +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 2, with: ".") +/// "123" +/// ``` +/// +pub fn pad_right( + string: String, + to desired_length: Int, + with pad_string: String, +) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + iterator.single(string) + |> iterator.append(padding(to_pad_length, pad_string)) + |> iterator.to_list + |> concat +} + +fn padding(size: Int, pad_string: String) -> Iterator(String) { + let pad_length = length(pad_string) + let num_pads = size / pad_length + let extra = size % pad_length + iterator.repeat(pad_string) + |> iterator.take(num_pads) + |> iterator.append(iterator.single(slice(pad_string, 0, extra))) +} + +/// Removes whitespace on both sides of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim(" hats \n") +/// "hats" +/// ``` +/// +pub fn trim(string: String) -> String { + do_trim(string) +} + +@target(erlang) +fn do_trim(string: String) -> String { + erl_trim(string, Both) +} + +@target(erlang) +type Direction { + Leading + Trailing + Both +} + +@target(erlang) +@external(erlang, "string", "trim") +fn erl_trim(a: String, b: Direction) -> String + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim") +fn do_trim(string string: String) -> String + +/// Removes whitespace on the left of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_left(" hats \n") +/// "hats \n" +/// ``` +/// +pub fn trim_left(string: String) -> String { + do_trim_left(string) +} + +@target(erlang) +fn do_trim_left(string: String) -> String { + erl_trim(string, Leading) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim_left") +fn do_trim_left(string string: String) -> String + +/// Removes whitespace on the right of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_right(" hats \n") +/// " hats" +/// ``` +/// +pub fn trim_right(string: String) -> String { + do_trim_right(string) +} + +@target(erlang) +fn do_trim_right(string: String) -> String { + erl_trim(string, Trailing) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim_right") +fn do_trim_right(string string: String) -> String + +/// Splits a non-empty `String` into its first element (head) and rest (tail). +/// This lets you pattern match on `String`s exactly as you would with lists. +/// +/// Note on JavaScript using the function to iterate over a string will likely +/// be slower than using `to_graphemes` due to string slicing being more +/// expensive on JavaScript than Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_grapheme("gleam") +/// Ok(#("g", "leam")) +/// ``` +/// +/// ```gleam +/// > pop_grapheme("") +/// Error(Nil) +/// ``` +/// +pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { + do_pop_grapheme(string) +} + +@external(erlang, "gleam_stdlib", "string_pop_grapheme") +@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") +fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) + +/// Converts a `String` to a list of +/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). +/// +/// ```gleam +/// > to_graphemes("abc") +/// ["a", "b", "c"] +/// ``` +/// +@external(javascript, "../gleam_stdlib.mjs", "graphemes") +pub fn to_graphemes(string: String) -> List(String) { + do_to_graphemes(string, []) + |> list.reverse +} + +fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { + case pop_grapheme(string) { + Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) + _ -> acc + } +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "codepoint") +fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint + +/// Converts a `String` to a `List` of `UtfCodepoint`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > "a" |> to_utf_codepoints +/// [UtfCodepoint(97)] +/// ``` +/// +/// ```gleam +/// // Semantically the same as: +/// // ["🏳", "️", "‍", "🌈"] or: +/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] +/// > "🏳️‍🌈" |> to_utf_codepoints +/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] +/// ``` +/// +pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints(string) +} + +@target(erlang) +fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints_impl(<>, []) + |> list.reverse +} + +@target(erlang) +fn do_to_utf_codepoints_impl( + bit_array: BitArray, + acc: List(UtfCodepoint), +) -> List(UtfCodepoint) { + case bit_array { + <> -> + do_to_utf_codepoints_impl(rest, [first, ..acc]) + _ -> acc + } +} + +@target(javascript) +fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + string + |> string_to_codepoint_integer_list + |> list.map(unsafe_int_to_utf_codepoint) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") +fn string_to_codepoint_integer_list(a: String) -> List(Int) + +/// Converts a `List` of `UtfCodepoint`s to a `String`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > { +/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( +/// > utf_codepoint(97), +/// > utf_codepoint(98), +/// > utf_codepoint(99), +/// > ) +/// > [a, b, c] +/// > } +/// > |> from_utf_codepoints +/// "abc" +/// ``` +/// +@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") +@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") +pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String + +/// Converts an integer to a `UtfCodepoint`. +/// +/// Returns an `Error` if the integer does not represent a valid UTF codepoint. +/// +pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { + case value { + i if i > 1_114_111 -> Error(Nil) + 65_534 | 65_535 -> Error(Nil) + i if i >= 55_296 && i <= 57_343 -> Error(Nil) + i -> Ok(unsafe_int_to_utf_codepoint(i)) + } +} + +/// Converts an UtfCodepoint to its ordinal code point value. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") +/// > utf_codepoint_to_int(utf_codepoint) +/// 128156 +/// ``` +/// +pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { + do_utf_codepoint_to_int(cp) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") +fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int + +/// Converts a `String` into `Option(String)` where an empty `String` becomes +/// `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_option("") +/// None +/// ``` +/// +/// ```gleam +/// > to_option("hats") +/// Some("hats") +/// ``` +/// +pub fn to_option(s: String) -> Option(String) { + case s { + "" -> None + _ -> Some(s) + } +} + +/// Returns the first grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > first("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first("icecream") +/// Ok("i") +/// ``` +/// +pub fn first(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, _)) -> Ok(first) + Error(e) -> Error(e) + } +} + +/// Returns the last grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > last("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last("icecream") +/// Ok("m") +/// ``` +/// +pub fn last(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, "")) -> Ok(first) + Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) + Error(e) -> Error(e) + } +} + +/// Creates a new `String` with the first grapheme in the input `String` +/// converted to uppercase and the remaining graphemes to lowercase. +/// +/// ## Examples +/// +/// ```gleam +/// > capitalise("mamouna") +/// "Mamouna" +/// ``` +/// +pub fn capitalise(s: String) -> String { + case pop_grapheme(s) { + Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) + _ -> "" + } +} + +/// Returns a `String` representation of a term in Gleam syntax. +/// +pub fn inspect(term: anything) -> String { + do_inspect(term) + |> string_builder.to_string +} + +@external(erlang, "gleam_stdlib", "inspect") +@external(javascript, "../gleam_stdlib.mjs", "inspect") +fn do_inspect(term term: anything) -> StringBuilder + +/// Returns the number of bytes in a `String`. +/// +/// This function runs in constant time on Erlang and in linear time on +/// JavaScript. +/// +/// ## Examples +/// +/// ```gleam +/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") +/// 58 +/// ``` +/// +@external(erlang, "erlang", "byte_size") +@external(javascript, "../gleam_stdlib.mjs", "byte_size") +pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam new file mode 100644 index 00000000000..5792ca8699d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam @@ -0,0 +1,298 @@ +import gleam/list + +/// `StringBuilder` is a type used for efficiently building strings. +/// +/// When we append one string to another the strings must be copied to a +/// new location in memory so that they can sit together. This behaviour +/// enables efficient reading of the string but copying can be expensive, +/// especially if we want to join many strings together. +/// +/// `StringBuilder` is different in that it can be joined together in constant time +/// using minimal memory, and then can be efficiently converted to a string +/// using the `to_string` function. +/// +/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this +/// type is compatible with normal strings. +/// +pub type StringBuilder + +/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many +/// builders together. +/// +pub fn new() -> StringBuilder { + do_from_strings([]) +} + +/// Prepends a `String` onto the start of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn prepend( + to builder: StringBuilder, + prefix prefix: String, +) -> StringBuilder { + append_builder(from_string(prefix), builder) +} + +/// Appends a `String` onto the end of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { + append_builder(builder, from_string(second)) +} + +/// Prepends some `StringBuilder` onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder( + to builder: StringBuilder, + prefix prefix: StringBuilder, +) -> StringBuilder { + do_append(prefix, builder) +} + +/// Appends some `StringBuilder` onto the end of another. +/// +/// Runs in constant time. +/// +pub fn append_builder( + to builder: StringBuilder, + suffix suffix: StringBuilder, +) -> StringBuilder { + do_append(builder, suffix) +} + +@external(erlang, "gleam_stdlib", "iodata_append") +@external(javascript, "../gleam_stdlib.mjs", "add") +fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder + +/// Converts a list of strings into a builder. +/// +/// Runs in constant time. +/// +pub fn from_strings(strings: List(String)) -> StringBuilder { + do_from_strings(strings) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "concat") +fn do_from_strings(a: List(String)) -> StringBuilder + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +pub fn concat(builders: List(StringBuilder)) -> StringBuilder { + do_concat(builders) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "concat") +fn do_concat(a: List(StringBuilder)) -> StringBuilder + +/// Converts a string into a builder. +/// +/// Runs in constant time. +/// +pub fn from_string(string: String) -> StringBuilder { + do_from_string(string) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_from_string(a: String) -> StringBuilder + +/// Turns an `StringBuilder` into a `String` +/// +/// This function is implemented natively by the virtual machine and is highly +/// optimised. +/// +pub fn to_string(builder: StringBuilder) -> String { + do_to_string(builder) +} + +@external(erlang, "unicode", "characters_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_to_string(a: StringBuilder) -> String + +/// Returns the size of the `StringBuilder` in bytes. +/// +pub fn byte_size(builder: StringBuilder) -> Int { + do_byte_size(builder) +} + +@external(erlang, "erlang", "iolist_size") +@external(javascript, "../gleam_stdlib.mjs", "length") +fn do_byte_size(a: StringBuilder) -> Int + +/// Joins the given builders into a new builder separated with the given string +/// +pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { + builders + |> list.intersperse(from_string(sep)) + |> concat +} + +/// Converts a builder to a new builder where the contents have been +/// lowercased. +/// +pub fn lowercase(builder: StringBuilder) -> StringBuilder { + do_lowercase(builder) +} + +@external(erlang, "string", "lowercase") +@external(javascript, "../gleam_stdlib.mjs", "lowercase") +fn do_lowercase(a: StringBuilder) -> StringBuilder + +/// Converts a builder to a new builder where the contents have been +/// uppercased. +/// +pub fn uppercase(builder: StringBuilder) -> StringBuilder { + do_uppercase(builder) +} + +@external(erlang, "string", "uppercase") +@external(javascript, "../gleam_stdlib.mjs", "uppercase") +fn do_uppercase(a: StringBuilder) -> StringBuilder + +/// Converts a builder to a new builder with the contents reversed. +/// +pub fn reverse(builder: StringBuilder) -> StringBuilder { + do_reverse(builder) +} + +@target(erlang) +@external(erlang, "string", "reverse") +fn do_reverse(a: StringBuilder) -> StringBuilder + +@target(javascript) +fn do_reverse(builder: StringBuilder) -> StringBuilder { + builder + |> to_string + |> do_to_graphemes + |> list.reverse + |> from_strings +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "graphemes") +fn do_to_graphemes(string string: String) -> List(String) + +/// Splits a builder on a given pattern into a list of builders. +/// +pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { + do_split(iodata, pattern) +} + +@target(erlang) +type Direction { + All +} + +@target(erlang) +@external(erlang, "string", "split") +fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) + +@target(erlang) +fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { + erl_split(iodata, pattern, All) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split") +fn do_split( + builder builder: StringBuilder, + pattern pattern: String, +) -> List(StringBuilder) + +/// Replaces all instances of a pattern with a given string substitute. +/// +pub fn replace( + in builder: StringBuilder, + each pattern: String, + with substitute: String, +) -> StringBuilder { + do_replace(builder, pattern, substitute) +} + +@target(erlang) +fn do_replace( + iodata: StringBuilder, + pattern: String, + substitute: String, +) -> StringBuilder { + erl_replace(iodata, pattern, substitute, All) +} + +@target(erlang) +@external(erlang, "string", "replace") +fn erl_replace( + a: StringBuilder, + b: String, + c: String, + d: Direction, +) -> StringBuilder + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "string_replace") +fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder + +/// Compares two builders to determine if they have the same textual content. +/// +/// Comparing two iodata using the `==` operator may return `False` even if they +/// have the same content as they may have been build in different ways, so +/// using this function is often preferred. +/// +/// ## Examples +/// +/// ```gleam +/// > from_strings(["a", "b"]) == from_string("ab") +/// False +/// ``` +/// +/// ```gleam +/// > is_equal(from_strings(["a", "b"]), from_string("ab")) +/// True +/// ``` +/// +pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { + do_is_equal(a, b) +} + +@external(erlang, "string", "equal") +@external(javascript, "../gleam_stdlib.mjs", "equal") +fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool + +/// Inspects a builder to determine if it is equivalent to an empty string. +/// +/// ## Examples +/// +/// ```gleam +/// > from_string("ok") |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > from_string("") |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > from_strings([]) |> is_empty +/// True +/// ``` +/// +pub fn is_empty(builder: StringBuilder) -> Bool { + do_is_empty(builder) +} + +@target(erlang) +@external(erlang, "string", "is_empty") +fn do_is_empty(a: StringBuilder) -> Bool + +@target(javascript) +fn do_is_empty(builder: StringBuilder) -> Bool { + from_string("") == builder +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam new file mode 100644 index 00000000000..11f6ea68cd2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam @@ -0,0 +1,462 @@ +//// Utilities for working with URIs +//// +//// This module provides functions for working with URIs (for example, parsing +//// URIs or encoding query strings). The functions in this module are implemented +//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). +//// +//// Query encoding (Form encoding) is defined in the +//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). + +import gleam/int +import gleam/list +import gleam/option.{type Option, None, Some} +import gleam/string +import gleam/string_builder.{type StringBuilder} +@target(javascript) +import gleam/pair +@target(javascript) +import gleam/regex +@target(javascript) +import gleam/result + +/// Type representing holding the parsed components of an URI. +/// All components of a URI are optional, except the path. +/// +pub type Uri { + Uri( + scheme: Option(String), + userinfo: Option(String), + host: Option(String), + port: Option(Int), + path: String, + query: Option(String), + fragment: Option(String), + ) +} + +/// Parses a compliant URI string into the `Uri` Type. +/// If the string is not a valid URI string then an error is returned. +/// +/// The opposite operation is `uri.to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("https://example.com:1234/a/b?query=true#fragment") +/// Ok( +/// Uri( +/// scheme: Some("https"), +/// userinfo: None, +/// host: Some("example.com"), +/// port: Some(1234), +/// path: "/a/b", +/// query: Some("query=true"), +/// fragment: Some("fragment") +/// ) +/// ) +/// ``` +/// +pub fn parse(uri_string: String) -> Result(Uri, Nil) { + do_parse(uri_string) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "uri_parse") +fn do_parse(a: String) -> Result(Uri, Nil) + +@target(javascript) +fn do_parse(uri_string: String) -> Result(Uri, Nil) { + // From https://tools.ietf.org/html/rfc3986#appendix-B + let pattern = + // 12 3 4 5 6 7 8 + "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" + let matches = + pattern + |> regex_submatches(uri_string) + |> pad_list(8) + + let #(scheme, authority, path, query, fragment) = case matches { + [ + _scheme_with_colon, + scheme, + authority_with_slashes, + _authority, + path, + query_with_question_mark, + _query, + fragment, + ] -> #( + scheme, + authority_with_slashes, + path, + query_with_question_mark, + fragment, + ) + _ -> #(None, None, None, None, None) + } + + let scheme = noneify_empty_string(scheme) + let path = option.unwrap(path, "") + let query = noneify_query(query) + let #(userinfo, host, port) = split_authority(authority) + let fragment = + fragment + |> option.to_result(Nil) + |> result.try(string.pop_grapheme) + |> result.map(pair.second) + |> option.from_result + let scheme = + scheme + |> noneify_empty_string + |> option.map(string.lowercase) + Ok(Uri( + scheme: scheme, + userinfo: userinfo, + host: host, + port: port, + path: path, + query: query, + fragment: fragment, + )) +} + +@target(javascript) +fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { + pattern + |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) + |> result.nil_error + |> result.map(regex.scan(_, string)) + |> result.try(list.first) + |> result.map(fn(m: regex.Match) { m.submatches }) + |> result.unwrap([]) +} + +@target(javascript) +fn noneify_query(x: Option(String)) -> Option(String) { + case x { + None -> None + Some(x) -> + case string.pop_grapheme(x) { + Ok(#("?", query)) -> Some(query) + _ -> None + } + } +} + +@target(javascript) +fn noneify_empty_string(x: Option(String)) -> Option(String) { + case x { + Some("") | None -> None + Some(_) -> x + } +} + +// Split an authority into its userinfo, host and port parts. +@target(javascript) +fn split_authority( + authority: Option(String), +) -> #(Option(String), Option(String), Option(Int)) { + case option.unwrap(authority, "") { + "" -> #(None, None, None) + "//" -> #(None, Some(""), None) + authority -> { + let matches = + "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" + |> regex_submatches(authority) + |> pad_list(6) + case matches { + [_, _, userinfo, host, _, port] -> { + let userinfo = noneify_empty_string(userinfo) + let host = noneify_empty_string(host) + let port = + port + |> option.unwrap("") + |> int.parse + |> option.from_result + #(userinfo, host, port) + } + _ -> #(None, None, None) + } + } + } +} + +@target(javascript) +fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { + list + |> list.append(list.repeat(None, extra_required(list, size))) +} + +@target(javascript) +fn extra_required(list: List(a), remaining: Int) -> Int { + case list { + _ if remaining == 0 -> 0 + [] -> remaining + [_, ..xs] -> extra_required(xs, remaining - 1) + } +} + +/// Parses an urlencoded query string into a list of key value pairs. +/// Returns an error for invalid encoding. +/// +/// The opposite operation is `uri.query_to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse_query("a=1&b=2") +/// Ok([#("a", "1"), #("b", "2")]) +/// ``` +/// +pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { + do_parse_query(query) +} + +@external(erlang, "gleam_stdlib", "parse_query") +@external(javascript, "../gleam_stdlib.mjs", "parse_query") +fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) + +/// Encodes a list of key value pairs as a URI query string. +/// +/// The opposite operation is `uri.parse_query`. +/// +/// ## Examples +/// +/// ```gleam +/// > query_to_string([#("a", "1"), #("b", "2")]) +/// "a=1&b=2" +/// ``` +/// +pub fn query_to_string(query: List(#(String, String))) -> String { + query + |> list.map(query_pair) + |> list.intersperse(string_builder.from_string("&")) + |> string_builder.concat + |> string_builder.to_string +} + +fn query_pair(pair: #(String, String)) -> StringBuilder { + string_builder.from_strings([ + percent_encode(pair.0), + "=", + percent_encode(pair.1), + ]) +} + +/// Encodes a string into a percent encoded representation. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_encode("100% great") +/// "100%25%20great" +/// ``` +/// +pub fn percent_encode(value: String) -> String { + do_percent_encode(value) +} + +@external(erlang, "gleam_stdlib", "percent_encode") +@external(javascript, "../gleam_stdlib.mjs", "percent_encode") +fn do_percent_encode(a: String) -> String + +/// Decodes a percent encoded string. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_decode("100%25+great") +/// Ok("100% great") +/// ``` +/// +pub fn percent_decode(value: String) -> Result(String, Nil) { + do_percent_decode(value) +} + +@external(erlang, "gleam_stdlib", "percent_decode") +@external(javascript, "../gleam_stdlib.mjs", "percent_decode") +fn do_percent_decode(a: String) -> Result(String, Nil) + +fn do_remove_dot_segments( + input: List(String), + accumulator: List(String), +) -> List(String) { + case input { + [] -> list.reverse(accumulator) + [segment, ..rest] -> { + let accumulator = case segment, accumulator { + "", accumulator -> accumulator + ".", accumulator -> accumulator + "..", [] -> [] + "..", [_, ..accumulator] -> accumulator + segment, accumulator -> [segment, ..accumulator] + } + do_remove_dot_segments(rest, accumulator) + } + } +} + +fn remove_dot_segments(input: List(String)) -> List(String) { + do_remove_dot_segments(input, []) +} + +/// Splits the path section of a URI into it's constituent segments. +/// +/// Removes empty segments and resolves dot-segments as specified in +/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. +/// +/// ## Examples +/// +/// ```gleam +/// > path_segments("/users/1") +/// ["users" ,"1"] +/// ``` +/// +pub fn path_segments(path: String) -> List(String) { + remove_dot_segments(string.split(path, "/")) +} + +/// Encodes a `Uri` value as a URI string. +/// +/// The opposite operation is `uri.parse`. +/// +/// ## Examples +/// +/// ```gleam +/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) +/// > to_string(uri) +/// "http://example.com" +/// ``` +/// +pub fn to_string(uri: Uri) -> String { + let parts = case uri.fragment { + Some(fragment) -> ["#", fragment] + _ -> [] + } + let parts = case uri.query { + Some(query) -> ["?", query, ..parts] + _ -> parts + } + let parts = [uri.path, ..parts] + let parts = case uri.host, string.starts_with(uri.path, "/") { + Some(host), False if host != "" -> ["/", ..parts] + _, _ -> parts + } + let parts = case uri.host, uri.port { + Some(_), Some(port) -> [":", int.to_string(port), ..parts] + _, _ -> parts + } + let parts = case uri.scheme, uri.userinfo, uri.host { + Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] + Some(s), None, Some(h) -> [s, "://", h, ..parts] + Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] + None, None, Some(h) -> ["//", h, ..parts] + _, _, _ -> parts + } + string.concat(parts) +} + +/// Fetches the origin of a URI. +/// +/// Returns the origin of a uri as defined in +/// [RFC 6454](https://tools.ietf.org/html/rfc6454) +/// +/// The supported URI schemes are `http` and `https`. +/// URLs without a scheme will return `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") +/// > origin(uri) +/// Ok("http://example.com") +/// ``` +/// +pub fn origin(uri: Uri) -> Result(String, Nil) { + let Uri(scheme: scheme, host: host, port: port, ..) = uri + case scheme { + Some("https") if port == Some(443) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some("http") if port == Some(80) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some(s) if s == "http" || s == "https" -> { + let origin = Uri(scheme, None, host, port, "", None, None) + Ok(to_string(origin)) + } + _ -> Error(Nil) + } +} + +fn drop_last(elements: List(a)) -> List(a) { + list.take(from: elements, up_to: list.length(elements) - 1) +} + +fn join_segments(segments: List(String)) -> String { + string.join(["", ..segments], "/") +} + +/// Resolves a URI with respect to the given base URI. +/// +/// The base URI must be an absolute URI or this function will return an error. +/// The algorithm for merging uris is described in +/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). +/// +pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { + case base { + Uri(scheme: Some(_), host: Some(_), ..) -> + case relative { + Uri(host: Some(_), ..) -> { + let path = + string.split(relative.path, "/") + |> remove_dot_segments() + |> join_segments() + let resolved = + Uri( + option.or(relative.scheme, base.scheme), + None, + relative.host, + option.or(relative.port, base.port), + path, + relative.query, + relative.fragment, + ) + Ok(resolved) + } + _ -> { + let #(new_path, new_query) = case relative.path { + "" -> #(base.path, option.or(relative.query, base.query)) + _ -> { + let path_segments = case string.starts_with(relative.path, "/") { + True -> string.split(relative.path, "/") + False -> + string.split(base.path, "/") + |> drop_last() + |> list.append(string.split(relative.path, "/")) + } + let path = + path_segments + |> remove_dot_segments() + |> join_segments() + #(path, relative.query) + } + } + let resolved = + Uri( + base.scheme, + None, + base.host, + base.port, + new_path, + new_query, + relative.fragment, + ) + Ok(resolved) + } + } + _ -> Error(Nil) + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl new file mode 100644 index 00000000000..65bc3f63e4d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl @@ -0,0 +1,20 @@ +-module(gleam@base). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). + +-spec encode64(bitstring(), boolean()) -> binary(). +encode64(Input, Padding) -> + gleam@bit_array:base64_encode(Input, Padding). + +-spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. +decode64(Encoded) -> + gleam@bit_array:base64_decode(Encoded). + +-spec url_encode64(bitstring(), boolean()) -> binary(). +url_encode64(Input, Padding) -> + gleam@bit_array:base64_url_encode(Input, Padding). + +-spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. +url_decode64(Encoded) -> + gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl new file mode 100644 index 00000000000..ba18dfaabdd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl @@ -0,0 +1,102 @@ +-module(gleam@bit_array). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). + +-spec from_string(binary()) -> bitstring(). +from_string(X) -> + gleam_stdlib:identity(X). + +-spec byte_size(bitstring()) -> integer(). +byte_size(X) -> + erlang:byte_size(X). + +-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | + {error, nil}. +slice(String, Position, Length) -> + gleam_stdlib:bit_array_slice(String, Position, Length). + +-spec do_is_utf8(bitstring()) -> boolean(). +do_is_utf8(Bits) -> + case Bits of + <<>> -> + true; + + <<_/utf8, Rest/binary>> -> + do_is_utf8(Rest); + + _ -> + false + end. + +-spec is_utf8(bitstring()) -> boolean(). +is_utf8(Bits) -> + do_is_utf8(Bits). + +-spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. +do_to_string(Bits) -> + case is_utf8(Bits) of + true -> + {ok, gleam_stdlib:identity(Bits)}; + + false -> + {error, nil} + end. + +-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. +to_string(Bits) -> + do_to_string(Bits). + +-spec concat(list(bitstring())) -> bitstring(). +concat(Bit_arrays) -> + gleam_stdlib:bit_array_concat(Bit_arrays). + +-spec append(bitstring(), bitstring()) -> bitstring(). +append(First, Second) -> + gleam_stdlib:bit_array_concat([First, Second]). + +-spec base64_encode(bitstring(), boolean()) -> binary(). +base64_encode(Input, Padding) -> + Encoded = base64:encode(Input), + case Padding of + true -> + Encoded; + + false -> + gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) + end. + +-spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base64_decode(Encoded) -> + Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of + 0 -> + Encoded; + + N -> + gleam@string:append( + Encoded, + gleam@string:repeat(<<"="/utf8>>, 4 - N) + ) + end, + gleam_stdlib:base_decode64(Padded). + +-spec base64_url_encode(bitstring(), boolean()) -> binary(). +base64_url_encode(Input, Padding) -> + _pipe = base64_encode(Input, Padding), + _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), + gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). + +-spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base64_url_decode(Encoded) -> + _pipe = Encoded, + _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), + _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), + base64_decode(_pipe@2). + +-spec base16_encode(bitstring()) -> binary(). +base16_encode(Input) -> + binary:encode_hex(Input). + +-spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base16_decode(Input) -> + gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl new file mode 100644 index 00000000000..284c6d46cc3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl @@ -0,0 +1,66 @@ +-module(gleam@bit_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). + +-spec new() -> gleam@bytes_builder:bytes_builder(). +new() -> + gleam@bytes_builder:new(). + +-spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). +prepend(To, Prefix) -> + gleam@bytes_builder:prepend(To, Prefix). + +-spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). +append(To, Suffix) -> + gleam@bytes_builder:append(To, Suffix). + +-spec prepend_builder( + gleam@bytes_builder:bytes_builder(), + gleam@bytes_builder:bytes_builder() +) -> gleam@bytes_builder:bytes_builder(). +prepend_builder(To, Prefix) -> + gleam@bytes_builder:prepend_builder(To, Prefix). + +-spec append_builder( + gleam@bytes_builder:bytes_builder(), + gleam@bytes_builder:bytes_builder() +) -> gleam@bytes_builder:bytes_builder(). +append_builder(First, Second) -> + gleam_stdlib:iodata_append(First, Second). + +-spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). +prepend_string(To, Prefix) -> + gleam@bytes_builder:prepend_string(To, Prefix). + +-spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). +append_string(To, Suffix) -> + gleam@bytes_builder:append_string(To, Suffix). + +-spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). +concat_bit_strings(Bits) -> + gleam_stdlib:identity(Bits). + +-spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). +from_string(String) -> + gleam_stdlib:wrap_list(String). + +-spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). +from_string_builder(Builder) -> + gleam_stdlib:wrap_list(Builder). + +-spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). +from_bit_string(Bits) -> + gleam_stdlib:wrap_list(Bits). + +-spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). +to_bit_string(Builder) -> + erlang:list_to_bitstring(Builder). + +-spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl new file mode 100644 index 00000000000..7dabaa3bbc1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl @@ -0,0 +1,33 @@ +-module(gleam@bit_string). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). + +-spec from_string(binary()) -> bitstring(). +from_string(X) -> + gleam_stdlib:identity(X). + +-spec byte_size(bitstring()) -> integer(). +byte_size(X) -> + erlang:byte_size(X). + +-spec append(bitstring(), bitstring()) -> bitstring(). +append(First, Second) -> + gleam@bit_array:append(First, Second). + +-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | + {error, nil}. +slice(String, Position, Length) -> + gleam_stdlib:bit_array_slice(String, Position, Length). + +-spec is_utf8(bitstring()) -> boolean(). +is_utf8(Bits) -> + gleam@bit_array:is_utf8(Bits). + +-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. +to_string(Bits) -> + gleam@bit_array:to_string(Bits). + +-spec concat(list(bitstring())) -> bitstring(). +concat(Bit_strings) -> + gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl new file mode 100644 index 00000000000..5f95f4d8314 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl @@ -0,0 +1,162 @@ +-module(gleam@bool). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). + +-spec 'and'(boolean(), boolean()) -> boolean(). +'and'(A, B) -> + A andalso B. + +-spec 'or'(boolean(), boolean()) -> boolean(). +'or'(A, B) -> + A orelse B. + +-spec negate(boolean()) -> boolean(). +negate(Bool) -> + case Bool of + true -> + false; + + false -> + true + end. + +-spec nor(boolean(), boolean()) -> boolean(). +nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + false + end. + +-spec nand(boolean(), boolean()) -> boolean(). +nand(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_or(boolean(), boolean()) -> boolean(). +exclusive_or(A, B) -> + case {A, B} of + {false, false} -> + false; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_nor(boolean(), boolean()) -> boolean(). +exclusive_nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + true + end. + +-spec compare(boolean(), boolean()) -> gleam@order:order(). +compare(A, B) -> + case {A, B} of + {true, true} -> + eq; + + {true, false} -> + gt; + + {false, false} -> + eq; + + {false, true} -> + lt + end. + +-spec max(boolean(), boolean()) -> boolean(). +max(A, B) -> + case A of + true -> + true; + + false -> + B + end. + +-spec min(boolean(), boolean()) -> boolean(). +min(A, B) -> + case A of + false -> + false; + + true -> + B + end. + +-spec to_int(boolean()) -> integer(). +to_int(Bool) -> + case Bool of + false -> + 0; + + true -> + 1 + end. + +-spec to_string(boolean()) -> binary(). +to_string(Bool) -> + case Bool of + false -> + <<"False"/utf8>>; + + true -> + <<"True"/utf8>> + end. + +-spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. +guard(Requirement, Consequence, Alternative) -> + case Requirement of + true -> + Consequence; + + false -> + Alternative() + end. + +-spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. +lazy_guard(Requirement, Consequence, Alternative) -> + case Requirement of + true -> + Consequence(); + + false -> + Alternative() + end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl new file mode 100644 index 00000000000..2f6dd93a9f3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl @@ -0,0 +1,87 @@ +-module(gleam@bytes_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). +-export_type([bytes_builder/0]). + +-opaque bytes_builder() :: {bytes, bitstring()} | + {text, gleam@string_builder:string_builder()} | + {many, list(bytes_builder())}. + +-spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). +append_builder(First, Second) -> + gleam_stdlib:iodata_append(First, Second). + +-spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). +prepend_builder(Second, First) -> + gleam_stdlib:iodata_append(First, Second). + +-spec concat(list(bytes_builder())) -> bytes_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec new() -> bytes_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec from_string(binary()) -> bytes_builder(). +from_string(String) -> + gleam_stdlib:wrap_list(String). + +-spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). +prepend_string(Second, First) -> + gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). + +-spec append_string(bytes_builder(), binary()) -> bytes_builder(). +append_string(First, Second) -> + gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). + +-spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). +from_string_builder(Builder) -> + gleam_stdlib:wrap_list(Builder). + +-spec from_bit_array(bitstring()) -> bytes_builder(). +from_bit_array(Bits) -> + gleam_stdlib:wrap_list(Bits). + +-spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). +prepend(Second, First) -> + gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). + +-spec append(bytes_builder(), bitstring()) -> bytes_builder(). +append(First, Second) -> + gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). + +-spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). +concat_bit_arrays(Bits) -> + gleam_stdlib:identity(Bits). + +-spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). +to_list(Stack, Acc) -> + case Stack of + [] -> + Acc; + + [[] | Remaining_stack] -> + to_list(Remaining_stack, Acc); + + [[{bytes, Bits} | Rest] | Remaining_stack@1] -> + to_list([Rest | Remaining_stack@1], [Bits | Acc]); + + [[{text, Builder} | Rest@1] | Remaining_stack@2] -> + Bits@1 = gleam_stdlib:identity( + gleam@string_builder:to_string(Builder) + ), + to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); + + [[{many, Builders} | Rest@2] | Remaining_stack@3] -> + to_list([Builders, Rest@2 | Remaining_stack@3], Acc) + end. + +-spec to_bit_array(bytes_builder()) -> bitstring(). +to_bit_array(Builder) -> + erlang:list_to_bitstring(Builder). + +-spec byte_size(bytes_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl new file mode 100644 index 00000000000..99c231e18cc --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl @@ -0,0 +1,97 @@ +-module(gleam@dict). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). +-export_type([dict/2]). + +-type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. + +-spec size(dict(any(), any())) -> integer(). +size(Dict) -> + maps:size(Dict). + +-spec to_list(dict(NZ, OA)) -> list({NZ, OA}). +to_list(Dict) -> + maps:to_list(Dict). + +-spec from_list(list({OJ, OK})) -> dict(OJ, OK). +from_list(List) -> + maps:from_list(List). + +-spec has_key(dict(OT, any()), OT) -> boolean(). +has_key(Dict, Key) -> + maps:is_key(Key, Dict). + +-spec new() -> dict(any(), any()). +new() -> + maps:new(). + +-spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. +get(From, Get) -> + gleam_stdlib:map_get(From, Get). + +-spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). +insert(Dict, Key, Value) -> + maps:put(Key, Value, Dict). + +-spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). +map_values(Dict, Fun) -> + maps:map(Fun, Dict). + +-spec keys(dict(QV, any())) -> list(QV). +keys(Dict) -> + maps:keys(Dict). + +-spec values(dict(any(), RG)) -> list(RG). +values(Dict) -> + maps:values(Dict). + +-spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). +filter(Dict, Predicate) -> + maps:filter(Predicate, Dict). + +-spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). +take(Dict, Desired_keys) -> + maps:with(Desired_keys, Dict). + +-spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). +merge(Dict, New_entries) -> + maps:merge(Dict, New_entries). + +-spec delete(dict(TF, TG), TF) -> dict(TF, TG). +delete(Dict, Key) -> + maps:remove(Key, Dict). + +-spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). +drop(Dict, Disallowed_keys) -> + case Disallowed_keys of + [] -> + Dict; + + [X | Xs] -> + drop(delete(Dict, X), Xs) + end. + +-spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). +update(Dict, Key, Fun) -> + _pipe = Dict, + _pipe@1 = get(_pipe, Key), + _pipe@2 = gleam@option:from_result(_pipe@1), + _pipe@3 = Fun(_pipe@2), + insert(Dict, Key, _pipe@3). + +-spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. +do_fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [{K, V} | Rest] -> + do_fold(Rest, Fun(Initial, K, V), Fun) + end. + +-spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. +fold(Dict, Initial, Fun) -> + _pipe = Dict, + _pipe@1 = to_list(_pipe), + do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl new file mode 100644 index 00000000000..2c6016f4222 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl @@ -0,0 +1,808 @@ +-module(gleam@dynamic). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). +-export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). + +-type dynamic_() :: any(). + +-type decode_error() :: {decode_error, binary(), binary(), list(binary())}. + +-type unknown_tuple() :: any(). + +-spec from(any()) -> dynamic_(). +from(A) -> + gleam_stdlib:identity(A). + +-spec unsafe_coerce(dynamic_()) -> any(). +unsafe_coerce(A) -> + gleam_stdlib:identity(A). + +-spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. +dynamic(Value) -> + {ok, Value}. + +-spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. +bit_array(Data) -> + gleam_stdlib:decode_bit_array(Data). + +-spec bit_string(dynamic_()) -> {ok, bitstring()} | + {error, list(decode_error())}. +bit_string(Data) -> + bit_array(Data). + +-spec put_expected(decode_error(), binary()) -> decode_error(). +put_expected(Error, Expected) -> + erlang:setelement(2, Error, Expected). + +-spec classify(dynamic_()) -> binary(). +classify(Data) -> + gleam_stdlib:classify_dynamic(Data). + +-spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. +int(Data) -> + gleam_stdlib:decode_int(Data). + +-spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. +float(Data) -> + gleam_stdlib:decode_float(Data). + +-spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. +bool(Data) -> + gleam_stdlib:decode_bool(Data). + +-spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | + {error, list(decode_error())}. +shallow_list(Value) -> + gleam_stdlib:decode_list(Value). + +-spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, + gleam@option:option(DGM)} | + {error, list(decode_error())}). +optional(Decode) -> + fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. + +-spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | + {error, list(decode_error())}. +at_least_decode_tuple_error(Size, Data) -> + S = case Size of + 1 -> + <<""/utf8>>; + + _ -> + <<"s"/utf8>> + end, + Error = begin + _pipe = [<<"Tuple of at least "/utf8>>, + gleam@int:to_string(Size), + <<" element"/utf8>>, + S], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + _pipe@2 = gleam@string_builder:to_string(_pipe@1), + {decode_error, _pipe@2, classify(Data), []} + end, + {error, [Error]}. + +-spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, + DKT} | + {error, list(decode_error())}). +any(Decoders) -> + fun(Data) -> case Decoders of + [] -> + {error, + [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; + + [Decoder | Decoders@1] -> + case Decoder(Data) of + {ok, Decoded} -> + {ok, Decoded}; + + {error, _} -> + (any(Decoders@1))(Data) + end + end end. + +-spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). +all_errors(Result) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + Errors + end. + +-spec decode1( + fun((DKX) -> DKY), + fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). +decode1(Constructor, T1) -> + fun(Value) -> case T1(Value) of + {ok, A} -> + {ok, Constructor(A)}; + + A@1 -> + {error, all_errors(A@1)} + end end. + +-spec push_path(decode_error(), any()) -> decode_error(). +push_path(Error, Name) -> + Name@1 = from(Name), + Decoder = any( + [fun string/1, + fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] + ), + Name@3 = case Decoder(Name@1) of + {ok, Name@2} -> + Name@2; + + {error, _} -> + _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1) + end, + erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). + +-spec result( + fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | + {error, list(decode_error())}). +result(Decode_ok, Decode_error) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_result(Value), + fun(Inner_result) -> case Inner_result of + {ok, Raw} -> + gleam@result:'try'( + begin + _pipe = Decode_ok(Raw), + map_errors( + _pipe, + fun(_capture) -> + push_path(_capture, <<"ok"/utf8>>) + end + ) + end, + fun(Value@1) -> {ok, {ok, Value@1}} end + ); + + {error, Raw@1} -> + gleam@result:'try'( + begin + _pipe@1 = Decode_error(Raw@1), + map_errors( + _pipe@1, + fun(_capture@1) -> + push_path(_capture@1, <<"error"/utf8>>) + end + ) + end, + fun(Value@2) -> {ok, {error, Value@2}} end + ) + end end + ) + end. + +-spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, + list(DGH)} | + {error, list(decode_error())}). +list(Decoder_type) -> + fun(Dynamic) -> + gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, + _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end + ) end) + end. + +-spec map_errors( + {ok, DEV} | {error, list(decode_error())}, + fun((decode_error()) -> decode_error()) +) -> {ok, DEV} | {error, list(decode_error())}. +map_errors(Result, F) -> + gleam@result:map_error( + Result, + fun(_capture) -> gleam@list:map(_capture, F) end + ). + +-spec decode_string(dynamic_()) -> {ok, binary()} | + {error, list(decode_error())}. +decode_string(Data) -> + _pipe = bit_array(Data), + _pipe@1 = map_errors( + _pipe, + fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end + ), + gleam@result:'try'( + _pipe@1, + fun(Raw) -> case gleam@bit_array:to_string(Raw) of + {ok, String} -> + {ok, String}; + + {error, nil} -> + {error, + [{decode_error, + <<"String"/utf8>>, + <<"BitArray"/utf8>>, + []}]} + end end + ). + +-spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. +string(Data) -> + decode_string(Data). + +-spec field( + any(), + fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). +field(Name, Inner_type) -> + fun(Value) -> + Missing_field_error = {decode_error, + <<"field"/utf8>>, + <<"nothing"/utf8>>, + []}, + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> _pipe = Maybe_inner, + _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), + _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), + map_errors( + _pipe@2, + fun(_capture) -> push_path(_capture, Name) end + ) end + ) + end. + +-spec optional_field( + any(), + fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | + {error, list(decode_error())}). +optional_field(Name, Inner_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> case Maybe_inner of + none -> + {ok, none}; + + {some, Dynamic_inner} -> + _pipe = Dynamic_inner, + _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, Name) end + ) + end end + ) + end. + +-spec element( + integer(), + fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). +element(Index, Inner_type) -> + fun(Data) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple(Data), + fun(Tuple) -> + Size = gleam_stdlib:size_of_tuple(Tuple), + gleam@result:'try'(case Index >= 0 of + true -> + case Index < Size of + true -> + gleam_stdlib:tuple_get(Tuple, Index); + + false -> + at_least_decode_tuple_error(Index + 1, Data) + end; + + false -> + case gleam@int:absolute_value(Index) =< Size of + true -> + gleam_stdlib:tuple_get(Tuple, Size + Index); + + false -> + at_least_decode_tuple_error( + gleam@int:absolute_value(Index), + Data + ) + end + end, fun(Data@1) -> _pipe = Inner_type(Data@1), + map_errors( + _pipe, + fun(_capture) -> push_path(_capture, Index) end + ) end) + end + ) + end. + +-spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). +tuple_errors(Result, Name) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + gleam@list:map( + Errors, + fun(_capture) -> push_path(_capture, Name) end + ) + end. + +-spec tuple2( + fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). +tuple2(Decode1, Decode2) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple2(Value), + fun(_use0) -> + {A, B} = _use0, + case {Decode1(A), Decode2(B)} of + {{ok, A@1}, {ok, B@1}} -> + {ok, {A@1, B@1}}; + + {A@2, B@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + {error, _pipe@1} + end + end + ) + end. + +-spec tuple3( + fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). +tuple3(Decode1, Decode2, Decode3) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple3(Value), + fun(_use0) -> + {A, B, C} = _use0, + case {Decode1(A), Decode2(B), Decode3(C)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> + {ok, {A@1, B@1, C@1}}; + + {A@2, B@2, C@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + {error, _pipe@2} + end + end + ) + end. + +-spec tuple4( + fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | + {error, list(decode_error())}). +tuple4(Decode1, Decode2, Decode3, Decode4) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple4(Value), + fun(_use0) -> + {A, B, C, D} = _use0, + case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> + {ok, {A@1, B@1, C@1, D@1}}; + + {A@2, B@2, C@2, D@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + {error, _pipe@3} + end + end + ) + end. + +-spec tuple5( + fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | + {error, list(decode_error())}). +tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple5(Value), + fun(_use0) -> + {A, B, C, D, E} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1}}; + + {A@2, B@2, C@2, D@2, E@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + {error, _pipe@4} + end + end + ) + end. + +-spec tuple6( + fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | + {error, list(decode_error())}). +tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple6(Value), + fun(_use0) -> + {A, B, C, D, E, F} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E), + Decode6(F)} of + {{ok, A@1}, + {ok, B@1}, + {ok, C@1}, + {ok, D@1}, + {ok, E@1}, + {ok, F@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; + + {A@2, B@2, C@2, D@2, E@2, F@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + _pipe@5 = gleam@list:append( + _pipe@4, + tuple_errors(F@2, <<"5"/utf8>>) + ), + {error, _pipe@5} + end + end + ) + end. + +-spec dict( + fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | + {error, list(decode_error())}). +dict(Key_type, Value_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_map(Value), + fun(Map) -> + gleam@result:'try'( + begin + _pipe = Map, + _pipe@1 = gleam@dict:to_list(_pipe), + gleam@list:try_map( + _pipe@1, + fun(Pair) -> + {K, V} = Pair, + gleam@result:'try'( + begin + _pipe@2 = Key_type(K), + map_errors( + _pipe@2, + fun(_capture) -> + push_path( + _capture, + <<"keys"/utf8>> + ) + end + ) + end, + fun(K@1) -> + gleam@result:'try'( + begin + _pipe@3 = Value_type(V), + map_errors( + _pipe@3, + fun(_capture@1) -> + push_path( + _capture@1, + <<"values"/utf8>> + ) + end + ) + end, + fun(V@1) -> {ok, {K@1, V@1}} end + ) + end + ) + end + ) + end, + fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end + ) + end + ) + end. + +-spec map( + fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | + {error, list(decode_error())}). +map(Key_type, Value_type) -> + dict(Key_type, Value_type). + +-spec decode2( + fun((DLB, DLC) -> DLD), + fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). +decode2(Constructor, T1, T2) -> + fun(Value) -> case {T1(Value), T2(Value)} of + {{ok, A}, {ok, B}} -> + {ok, Constructor(A, B)}; + + {A@1, B@1} -> + {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} + end end. + +-spec decode3( + fun((DLH, DLI, DLJ) -> DLK), + fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). +decode3(Constructor, T1, T2, T3) -> + fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of + {{ok, A}, {ok, B}, {ok, C}} -> + {ok, Constructor(A, B, C)}; + + {A@1, B@1, C@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), all_errors(B@1), all_errors(C@1)] + )} + end end. + +-spec decode4( + fun((DLP, DLQ, DLR, DLS) -> DLT), + fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). +decode4(Constructor, T1, T2, T3, T4) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> + {ok, Constructor(A, B, C, D)}; + + {A@1, B@1, C@1, D@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1)] + )} + end end. + +-spec decode5( + fun((DLZ, DMA, DMB, DMC, DMD) -> DME), + fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). +decode5(Constructor, T1, T2, T3, T4, T5) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> + {ok, Constructor(A, B, C, D, E)}; + + {A@1, B@1, C@1, D@1, E@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1)] + )} + end end. + +-spec decode6( + fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), + fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). +decode6(Constructor, T1, T2, T3, T4, T5, T6) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> + {ok, Constructor(A, B, C, D, E, F)}; + + {A@1, B@1, C@1, D@1, E@1, F@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1)] + )} + end end. + +-spec decode7( + fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), + fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). +decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> + {ok, Constructor(A, B, C, D, E, F, G)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1)] + )} + end end. + +-spec decode8( + fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), + fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). +decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}} -> + {ok, Constructor(A, B, C, D, E, F, G, H)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1)] + )} + end end. + +-spec decode9( + fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), + fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). +decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> + fun(X) -> + case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}, + {ok, I}} -> + {ok, Constructor(A, B, C, D, E, F, G, H, I)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1), + all_errors(I@1)] + )} + end + end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl new file mode 100644 index 00000000000..33b3d4a3e3f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl @@ -0,0 +1,181 @@ +-module(gleam@float). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). + +-spec parse(binary()) -> {ok, float()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_float(String). + +-spec to_string(float()) -> binary(). +to_string(X) -> + gleam_stdlib:float_to_string(X). + +-spec compare(float(), float()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(float(), float()) -> float(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(float(), float()) -> float(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(float(), float(), float()) -> float(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec ceiling(float()) -> float(). +ceiling(X) -> + math:ceil(X). + +-spec floor(float()) -> float(). +floor(X) -> + math:floor(X). + +-spec round(float()) -> integer(). +round(X) -> + erlang:round(X). + +-spec truncate(float()) -> integer(). +truncate(X) -> + erlang:trunc(X). + +-spec absolute_value(float()) -> float(). +absolute_value(X) -> + case X >= +0.0 of + true -> + X; + + _ -> + +0.0 - X + end. + +-spec loosely_compare(float(), float(), float()) -> gleam@order:order(). +loosely_compare(A, B, Tolerance) -> + Difference = absolute_value(A - B), + case Difference =< Tolerance of + true -> + eq; + + false -> + compare(A, B) + end. + +-spec loosely_equals(float(), float(), float()) -> boolean(). +loosely_equals(A, B, Tolerance) -> + Difference = absolute_value(A - B), + Difference =< Tolerance. + +-spec power(float(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + Fractional = (ceiling(Exponent) - Exponent) > +0.0, + case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent + < +0.0)) of + true -> + {error, nil}; + + false -> + {ok, math:pow(Base, Exponent)} + end. + +-spec square_root(float()) -> {ok, float()} | {error, nil}. +square_root(X) -> + power(X, 0.5). + +-spec negate(float()) -> float(). +negate(X) -> + -1.0 * X. + +-spec do_sum(list(float()), float()) -> float(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(float())) -> float(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, +0.0). + +-spec do_product(list(float()), float()) -> float(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(float())) -> float(). +product(Numbers) -> + case Numbers of + [] -> + 1.0; + + _ -> + do_product(Numbers, 1.0) + end. + +-spec random(float(), float()) -> float(). +random(Min, Max) -> + (rand:uniform() * (Max - Min)) + Min. + +-spec divide(float(), float()) -> {ok, float()} | {error, nil}. +divide(A, B) -> + case B of + +0.0 -> + {error, nil}; + + B@1 -> + {ok, case B@1 of + +0.0 -> +0.0; + -0.0 -> -0.0; + Gleam@denominator -> A / Gleam@denominator + end} + end. + +-spec add(float(), float()) -> float(). +add(A, B) -> + A + B. + +-spec multiply(float(), float()) -> float(). +multiply(A, B) -> + A * B. + +-spec subtract(float(), float()) -> float(). +subtract(A, B) -> + A - B. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl new file mode 100644 index 00000000000..c58c0fe151b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl @@ -0,0 +1,67 @@ +-module(gleam@function). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). + +-spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). +compose(Fun1, Fun2) -> + fun(A) -> Fun2(Fun1(A)) end. + +-spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). +curry2(Fun) -> + fun(A) -> fun(B) -> Fun(A, B) end end. + +-spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). +curry3(Fun) -> + fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. + +-spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). +curry4(Fun) -> + fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. + +-spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). +curry5(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end + end + end. + +-spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). +curry6(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> + fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end + end + end + end. + +-spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). +flip(Fun) -> + fun(B, A) -> Fun(A, B) end. + +-spec identity(AS) -> AS. +identity(X) -> + X. + +-spec constant(AT) -> fun((any()) -> AT). +constant(Value) -> + fun(_) -> Value end. + +-spec tap(AV, fun((AV) -> any())) -> AV. +tap(Arg, Effect) -> + Effect(Arg), + Arg. + +-spec apply1(fun((AX) -> AY), AX) -> AY. +apply1(Fun, Arg1) -> + Fun(Arg1). + +-spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. +apply2(Fun, Arg1, Arg2) -> + Fun(Arg1, Arg2). + +-spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. +apply3(Fun, Arg1, Arg2, Arg3) -> + Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl new file mode 100644 index 00000000000..2a5dd2c8a1d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl @@ -0,0 +1,332 @@ +-module(gleam@int). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). +-export_type([invalid_base/0]). + +-type invalid_base() :: invalid_base. + +-spec absolute_value(integer()) -> integer(). +absolute_value(X) -> + case X >= 0 of + true -> + X; + + false -> + X * -1 + end. + +-spec parse(binary()) -> {ok, integer()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_int(String). + +-spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. +base_parse(String, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + gleam_stdlib:int_from_base_string(String, Base); + + false -> + {error, nil} + end. + +-spec to_string(integer()) -> binary(). +to_string(X) -> + erlang:integer_to_binary(X). + +-spec to_base_string(integer(), integer()) -> {ok, binary()} | + {error, invalid_base()}. +to_base_string(X, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + {ok, erlang:integer_to_binary(X, Base)}; + + false -> + {error, invalid_base} + end. + +-spec to_base2(integer()) -> binary(). +to_base2(X) -> + erlang:integer_to_binary(X, 2). + +-spec to_base8(integer()) -> binary(). +to_base8(X) -> + erlang:integer_to_binary(X, 8). + +-spec to_base16(integer()) -> binary(). +to_base16(X) -> + erlang:integer_to_binary(X, 16). + +-spec to_base36(integer()) -> binary(). +to_base36(X) -> + erlang:integer_to_binary(X, 36). + +-spec to_float(integer()) -> float(). +to_float(X) -> + erlang:float(X). + +-spec power(integer(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + _pipe = Base, + _pipe@1 = to_float(_pipe), + gleam@float:power(_pipe@1, Exponent). + +-spec square_root(integer()) -> {ok, float()} | {error, nil}. +square_root(X) -> + _pipe = X, + _pipe@1 = to_float(_pipe), + gleam@float:square_root(_pipe@1). + +-spec compare(integer(), integer()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(integer(), integer()) -> integer(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(integer(), integer()) -> integer(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(integer(), integer(), integer()) -> integer(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec is_even(integer()) -> boolean(). +is_even(X) -> + (X rem 2) =:= 0. + +-spec is_odd(integer()) -> boolean(). +is_odd(X) -> + (X rem 2) /= 0. + +-spec negate(integer()) -> integer(). +negate(X) -> + -1 * X. + +-spec do_sum(list(integer()), integer()) -> integer(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(integer())) -> integer(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, 0). + +-spec do_product(list(integer()), integer()) -> integer(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(integer())) -> integer(). +product(Numbers) -> + case Numbers of + [] -> + 1; + + _ -> + do_product(Numbers, 1) + end. + +-spec do_digits(integer(), integer(), list(integer())) -> list(integer()). +do_digits(X, Base, Acc) -> + case absolute_value(X) < Base of + true -> + [X | Acc]; + + false -> + do_digits(case Base of + 0 -> 0; + Gleam@denominator -> X div Gleam@denominator + end, Base, [case Base of + 0 -> 0; + Gleam@denominator@1 -> X rem Gleam@denominator@1 + end | Acc]) + end. + +-spec digits(integer(), integer()) -> {ok, list(integer())} | + {error, invalid_base()}. +digits(X, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + {ok, do_digits(X, Base, [])} + end. + +-spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | + {error, invalid_base()}. +do_undigits(Numbers, Base, Acc) -> + case Numbers of + [] -> + {ok, Acc}; + + [Digit | _] when Digit >= Base -> + {error, invalid_base}; + + [Digit@1 | Rest] -> + do_undigits(Rest, Base, (Acc * Base) + Digit@1) + end. + +-spec undigits(list(integer()), integer()) -> {ok, integer()} | + {error, invalid_base()}. +undigits(Numbers, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + do_undigits(Numbers, Base, 0) + end. + +-spec random(integer(), integer()) -> integer(). +random(Min, Max) -> + _pipe = gleam@float:random(to_float(Min), to_float(Max)), + _pipe@1 = gleam@float:floor(_pipe), + gleam@float:round(_pipe@1). + +-spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend div Gleam@denominator + end} + end. + +-spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. +remainder(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end} + end. + +-spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. +modulo(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + _ -> + Remainder = case Divisor of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end, + case (Remainder * Divisor) < 0 of + true -> + {ok, Remainder + Divisor}; + + false -> + {ok, Remainder} + end + end. + +-spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +floor_divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end) /= 0) of + true -> + {ok, (case Divisor@1 of + 0 -> 0; + Gleam@denominator@1 -> Dividend div Gleam@denominator@1 + end) - 1}; + + false -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator@2 -> Dividend div Gleam@denominator@2 + end} + end + end. + +-spec add(integer(), integer()) -> integer(). +add(A, B) -> + A + B. + +-spec multiply(integer(), integer()) -> integer(). +multiply(A, B) -> + A * B. + +-spec subtract(integer(), integer()) -> integer(). +subtract(A, B) -> + A - B. + +-spec bitwise_and(integer(), integer()) -> integer(). +bitwise_and(X, Y) -> + erlang:'band'(X, Y). + +-spec bitwise_not(integer()) -> integer(). +bitwise_not(X) -> + erlang:'bnot'(X). + +-spec bitwise_or(integer(), integer()) -> integer(). +bitwise_or(X, Y) -> + erlang:'bor'(X, Y). + +-spec bitwise_exclusive_or(integer(), integer()) -> integer(). +bitwise_exclusive_or(X, Y) -> + erlang:'bxor'(X, Y). + +-spec bitwise_shift_left(integer(), integer()) -> integer(). +bitwise_shift_left(X, Y) -> + erlang:'bsl'(X, Y). + +-spec bitwise_shift_right(integer(), integer()) -> integer(). +bitwise_shift_right(X, Y) -> + erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl new file mode 100644 index 00000000000..82865bbafa6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl @@ -0,0 +1,27 @@ +-module(gleam@io). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([print/1, print_error/1, println/1, println_error/1, debug/1]). + +-spec print(binary()) -> nil. +print(String) -> + gleam_stdlib:print(String). + +-spec print_error(binary()) -> nil. +print_error(String) -> + gleam_stdlib:print_error(String). + +-spec println(binary()) -> nil. +println(String) -> + gleam_stdlib:println(String). + +-spec println_error(binary()) -> nil. +println_error(String) -> + gleam_stdlib:println_error(String). + +-spec debug(ENH) -> ENH. +debug(Term) -> + _pipe = Term, + _pipe@1 = gleam@string:inspect(_pipe), + gleam_stdlib:println_error(_pipe@1), + Term. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl new file mode 100644 index 00000000000..a667ae1ac4b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl @@ -0,0 +1,744 @@ +-module(gleam@iterator). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). +-export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). + +-type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. + +-opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. + +-type step(BSE, BSF) :: {next, BSE, BSF} | done. + +-type chunk(BSG, BSH) :: {another_by, + list(BSG), + BSH, + BSG, + fun(() -> action(BSG))} | + {last_by, list(BSG)}. + +-type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | + {last, list(BSI)} | + no_more. + +-spec stop() -> action(any()). +stop() -> + stop. + +-spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). +do_unfold(Initial, F) -> + fun() -> case F(Initial) of + {next, X, Acc} -> + {continue, X, do_unfold(Acc, F)}; + + done -> + stop + end end. + +-spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). +unfold(Initial, F) -> + _pipe = Initial, + _pipe@1 = do_unfold(_pipe, F), + {iterator, _pipe@1}. + +-spec repeatedly(fun(() -> BSV)) -> iterator(BSV). +repeatedly(F) -> + unfold(nil, fun(_) -> {next, F(), nil} end). + +-spec repeat(BSX) -> iterator(BSX). +repeat(X) -> + repeatedly(fun() -> X end). + +-spec from_list(list(BSZ)) -> iterator(BSZ). +from_list(List) -> + Yield = fun(Acc) -> case Acc of + [] -> + done; + + [Head | Tail] -> + {next, Head, Tail} + end end, + unfold(List, Yield). + +-spec do_transform( + fun(() -> action(BTC)), + BTE, + fun((BTE, BTC) -> step(BTF, BTE)) +) -> fun(() -> action(BTF)). +do_transform(Continuation, State, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + case F(State, El) of + done -> + stop; + + {next, Yield, Next_state} -> + {continue, Yield, do_transform(Next, Next_state, F)} + end + end end. + +-spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). +transform(Iterator, Initial, F) -> + _pipe = do_transform(erlang:element(2, Iterator), Initial, F), + {iterator, _pipe}. + +-spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. +do_fold(Continuation, F, Accumulator) -> + case Continuation() of + {continue, Elem, Next} -> + do_fold(Next, F, F(Accumulator, Elem)); + + stop -> + Accumulator + end. + +-spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. +fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold(_pipe, F, Initial). + +-spec run(iterator(any())) -> nil. +run(Iterator) -> + fold(Iterator, nil, fun(_, _) -> nil end). + +-spec to_list(iterator(BTY)) -> list(BTY). +to_list(Iterator) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), + gleam@list:reverse(_pipe@1). + +-spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). +step(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + done; + + {continue, E, A} -> + {next, E, {iterator, A}} + end. + +-spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). +do_take(Continuation, Desired) -> + fun() -> case Desired > 0 of + false -> + stop; + + true -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, do_take(Next, Desired - 1)} + end + end end. + +-spec take(iterator(BUJ), integer()) -> iterator(BUJ). +take(Iterator, Desired) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take(_pipe, Desired), + {iterator, _pipe@1}. + +-spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). +do_drop(Continuation, Desired) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Desired > 0 of + true -> + do_drop(Next, Desired - 1); + + false -> + {continue, E, Next} + end + end. + +-spec drop(iterator(BUP), integer()) -> iterator(BUP). +drop(Iterator, Desired) -> + _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, + {iterator, _pipe}. + +-spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). +do_map(Continuation, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, F(E), do_map(Continuation@1, F)} + end end. + +-spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). +map(Iterator, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_map(_pipe, F), + {iterator, _pipe@1}. + +-spec do_map2( + fun(() -> action(BVA)), + fun(() -> action(BVC)), + fun((BVA, BVC) -> BVE) +) -> fun(() -> action(BVE)). +do_map2(Continuation1, Continuation2, Fun) -> + fun() -> case Continuation1() of + stop -> + stop; + + {continue, A, Next_a} -> + case Continuation2() of + stop -> + stop; + + {continue, B, Next_b} -> + {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} + end + end end. + +-spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). +map2(Iterator1, Iterator2, Fun) -> + _pipe = do_map2( + erlang:element(2, Iterator1), + erlang:element(2, Iterator2), + Fun + ), + {iterator, _pipe}. + +-spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). +do_append(First, Second) -> + case First() of + {continue, E, First@1} -> + {continue, E, fun() -> do_append(First@1, Second) end}; + + stop -> + Second() + end. + +-spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). +append(First, Second) -> + _pipe = fun() -> + do_append(erlang:element(2, First), erlang:element(2, Second)) + end, + {iterator, _pipe}. + +-spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). +do_flatten(Flattened) -> + case Flattened() of + stop -> + stop; + + {continue, It, Next_iterator} -> + do_append( + erlang:element(2, It), + fun() -> do_flatten(Next_iterator) end + ) + end. + +-spec flatten(iterator(iterator(BVY))) -> iterator(BVY). +flatten(Iterator) -> + _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, + {iterator, _pipe}. + +-spec concat(list(iterator(BWC))) -> iterator(BWC). +concat(Iterators) -> + flatten(from_list(Iterators)). + +-spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). +flat_map(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + flatten(_pipe@1). + +-spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). +do_filter(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Iterator} -> + case Predicate(E) of + true -> + {continue, E, fun() -> do_filter(Iterator, Predicate) end}; + + false -> + do_filter(Iterator, Predicate) + end + end. + +-spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). +filter(Iterator, Predicate) -> + _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec cycle(iterator(BWR)) -> iterator(BWR). +cycle(Iterator) -> + _pipe = repeat(Iterator), + flatten(_pipe). + +-spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | + {error, nil}. +do_find(Continuation, F) -> + case Continuation() of + stop -> + {error, nil}; + + {continue, E, Next} -> + case F(E) of + true -> + {ok, E}; + + false -> + do_find(Next, F) + end + end. + +-spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. +find(Haystack, Is_desired) -> + _pipe = erlang:element(2, Haystack), + do_find(_pipe, Is_desired). + +-spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), + BXD})). +do_index(Continuation, Next) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, {Next, E}, do_index(Continuation@1, Next + 1)} + end end. + +-spec index(iterator(BXG)) -> iterator({integer(), BXG}). +index(Iterator) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_index(_pipe, 0), + {iterator, _pipe@1}. + +-spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). +iterate(Initial, F) -> + unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). + +-spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). +do_take_while(Continuation, Predicate) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + stop; + + true -> + {continue, E, do_take_while(Next, Predicate)} + end + end end. + +-spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). +take_while(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take_while(_pipe, Predicate), + {iterator, _pipe@1}. + +-spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). +do_drop_while(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + {continue, E, Next}; + + true -> + do_drop_while(Next, Predicate) + end + end. + +-spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). +drop_while(Iterator, Predicate) -> + _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). +do_scan(Continuation, F, Accumulator) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + Accumulated = F(Accumulator, El), + {continue, Accumulated, do_scan(Next, F, Accumulated)} + end end. + +-spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). +scan(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_scan(_pipe, F, Initial), + {iterator, _pipe@1}. + +-spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, + BYH})). +do_zip(Left, Right) -> + fun() -> case Left() of + stop -> + stop; + + {continue, El_left, Next_left} -> + case Right() of + stop -> + stop; + + {continue, El_right, Next_right} -> + {continue, + {El_left, El_right}, + do_zip(Next_left, Next_right)} + end + end end. + +-spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). +zip(Left, Right) -> + _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), + {iterator, _pipe}. + +-spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). +next_chunk(Continuation, F, Previous_key, Current_chunk) -> + case Continuation() of + stop -> + {last_by, gleam@list:reverse(Current_chunk)}; + + {continue, E, Next} -> + Key = F(E), + case Key =:= Previous_key of + true -> + next_chunk(Next, F, Key, [E | Current_chunk]); + + false -> + {another_by, + gleam@list:reverse(Current_chunk), + Key, + E, + Next} + end + end. + +-spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). +do_chunk(Continuation, F, Previous_key, Previous_element) -> + case next_chunk(Continuation, F, Previous_key, [Previous_element]) of + {last_by, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another_by, Chunk@1, Key, El, Next} -> + {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} + end. + +-spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). +chunk(Iterator, F) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + do_chunk(Next, F, F(E), E) + end end, + {iterator, _pipe}. + +-spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). +next_sized_chunk(Continuation, Left, Current_chunk) -> + case Continuation() of + stop -> + case Current_chunk of + [] -> + no_more; + + Remaining -> + {last, gleam@list:reverse(Remaining)} + end; + + {continue, E, Next} -> + Chunk = [E | Current_chunk], + case Left > 1 of + false -> + {another, gleam@list:reverse(Chunk), Next}; + + true -> + next_sized_chunk(Next, Left - 1, Chunk) + end + end. + +-spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). +do_sized_chunk(Continuation, Count) -> + fun() -> case next_sized_chunk(Continuation, Count, []) of + no_more -> + stop; + + {last, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another, Chunk@1, Next_element} -> + {continue, Chunk@1, do_sized_chunk(Next_element, Count)} + end end. + +-spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). +sized_chunk(Iterator, Count) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_sized_chunk(_pipe, Count), + {iterator, _pipe@1}. + +-spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). +do_intersperse(Continuation, Separator) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + Next_interspersed = fun() -> do_intersperse(Next, Separator) end, + {continue, Separator, fun() -> {continue, E, Next_interspersed} end} + end. + +-spec intersperse(iterator(BZU), BZU) -> iterator(BZU). +intersperse(Iterator, Elem) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, fun() -> do_intersperse(Next, Elem) end} + end end, + {iterator, _pipe}. + +-spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). +do_any(Continuation, Predicate) -> + case Continuation() of + stop -> + false; + + {continue, E, Next} -> + case Predicate(E) of + true -> + true; + + false -> + do_any(Next, Predicate) + end + end. + +-spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). +any(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_any(_pipe, Predicate). + +-spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). +do_all(Continuation, Predicate) -> + case Continuation() of + stop -> + true; + + {continue, E, Next} -> + case Predicate(E) of + true -> + do_all(Next, Predicate); + + false -> + false + end + end. + +-spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). +all(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_all(_pipe, Predicate). + +-spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). +update_group_with(El) -> + fun(Maybe_group) -> case Maybe_group of + {some, Group} -> + [El | Group]; + + none -> + [El] + end end. + +-spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). +group_updater(F) -> + fun(Groups, Elem) -> _pipe = Groups, + gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. + +-spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). +group(Iterator, Key) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), + gleam@dict:map_values( + _pipe@1, + fun(_, Group) -> gleam@list:reverse(Group) end + ). + +-spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. +reduce(Iterator, F) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, Next} -> + _pipe = do_fold(Next, F, E), + {ok, _pipe} + end. + +-spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. +last(Iterator) -> + _pipe = Iterator, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec empty() -> iterator(any()). +empty() -> + {iterator, fun stop/0}. + +-spec once(fun(() -> CBH)) -> iterator(CBH). +once(F) -> + _pipe = fun() -> {continue, F(), fun stop/0} end, + {iterator, _pipe}. + +-spec range(integer(), integer()) -> iterator(integer()). +range(Start, Stop) -> + case gleam@int:compare(Start, Stop) of + eq -> + once(fun() -> Start end); + + gt -> + unfold(Start, fun(Current) -> case Current < Stop of + false -> + {next, Current, Current - 1}; + + true -> + done + end end); + + lt -> + unfold(Start, fun(Current@1) -> case Current@1 > Stop of + false -> + {next, Current@1, Current@1 + 1}; + + true -> + done + end end) + end. + +-spec single(CBJ) -> iterator(CBJ). +single(Elem) -> + once(fun() -> Elem end). + +-spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). +do_interleave(Current, Next) -> + case Current() of + stop -> + Next(); + + {continue, E, Next_other} -> + {continue, E, fun() -> do_interleave(Next, Next_other) end} + end. + +-spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). +interleave(Left, Right) -> + _pipe = fun() -> + do_interleave(erlang:element(2, Left), erlang:element(2, Right)) + end, + {iterator, _pipe}. + +-spec do_fold_until( + fun(() -> action(CBT)), + fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), + CBV +) -> CBV. +do_fold_until(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + Accumulator; + + {continue, Elem, Next} -> + case F(Accumulator, Elem) of + {continue, Accumulator@1} -> + do_fold_until(Next, F, Accumulator@1); + + {stop, Accumulator@2} -> + Accumulator@2 + end + end. + +-spec fold_until( + iterator(CBX), + CBZ, + fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) +) -> CBZ. +fold_until(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold_until(_pipe, F, Initial). + +-spec do_try_fold( + fun(() -> action(CCB)), + fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), + CCD +) -> {ok, CCD} | {error, CCE}. +do_try_fold(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + {ok, Accumulator}; + + {continue, Elem, Next} -> + gleam@result:'try'( + F(Accumulator, Elem), + fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end + ) + end. + +-spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, + CCL} | + {error, CCM}. +try_fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_try_fold(_pipe, F, Initial). + +-spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. +first(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, _} -> + {ok, E} + end. + +-spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. +at(Iterator, Index) -> + _pipe = Iterator, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1). + +-spec do_length(fun(() -> action(any())), integer()) -> integer(). +do_length(Continuation, Length) -> + case Continuation() of + stop -> + Length; + + {continue, _, Next} -> + do_length(Next, Length + 1) + end. + +-spec length(iterator(any())) -> integer(). +length(Iterator) -> + _pipe = erlang:element(2, Iterator), + do_length(_pipe, 0). + +-spec each(iterator(CDD), fun((CDD) -> any())) -> nil. +each(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + run(_pipe@1). + +-spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). +yield(Element, Next) -> + {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl new file mode 100644 index 00000000000..cb6c9e44af2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl @@ -0,0 +1,1136 @@ +-module(gleam@list). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). +-export_type([length_mismatch/0, continue_or_stop/1]). + +-type length_mismatch() :: length_mismatch. + +-type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. + +-spec length(list(any())) -> integer(). +length(List) -> + erlang:length(List). + +-spec reverse(list(XF)) -> list(XF). +reverse(Xs) -> + lists:reverse(Xs). + +-spec is_empty(list(any())) -> boolean(). +is_empty(List) -> + List =:= []. + +-spec contains(list(XN), XN) -> boolean(). +contains(List, Elem) -> + case List of + [] -> + false; + + [First | _] when First =:= Elem -> + true; + + [_ | Rest] -> + contains(Rest, Elem) + end. + +-spec first(list(XP)) -> {ok, XP} | {error, nil}. +first(List) -> + case List of + [] -> + {error, nil}; + + [X | _] -> + {ok, X} + end. + +-spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. +rest(List) -> + case List of + [] -> + {error, nil}; + + [_ | Xs] -> + {ok, Xs} + end. + +-spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). +update_group(F) -> + fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of + {ok, Existing} -> + gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); + + {error, _} -> + gleam@dict:insert(Groups, F(Elem), [Elem]) + end end. + +-spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). +do_filter(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + true -> + [X | Acc]; + + false -> + Acc + end, + do_filter(Xs, Fun, New_acc) + end. + +-spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). +filter(List, Predicate) -> + do_filter(List, Predicate, []). + +-spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). +do_filter_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + {ok, X@1} -> + [X@1 | Acc]; + + {error, _} -> + Acc + end, + do_filter_map(Xs, Fun, New_acc) + end. + +-spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). +filter_map(List, Fun) -> + do_filter_map(List, Fun, []). + +-spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). +do_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_map(Xs, Fun, [Fun(X) | Acc]) + end. + +-spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). +map(List, Fun) -> + do_map(List, Fun, []). + +-spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). +do_map2(List1, List2, Fun, Acc) -> + case {List1, List2} of + {[], _} -> + reverse(Acc); + + {_, []} -> + reverse(Acc); + + {[A | As_], [B | Bs]} -> + do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) + end. + +-spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). +map2(List1, List2, Fun) -> + do_map2(List1, List2, Fun, []). + +-spec do_index_map( + list(ABJ), + fun((integer(), ABJ) -> ABL), + integer(), + list(ABL) +) -> list(ABL). +do_index_map(List, Fun, Index, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + Acc@1 = [Fun(Index, X) | Acc], + do_index_map(Xs, Fun, Index + 1, Acc@1) + end. + +-spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). +index_map(List, Fun) -> + do_index_map(List, Fun, 0, []). + +-spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, + list(ABU)} | + {error, ABV}. +do_try_map(List, Fun, Acc) -> + case List of + [] -> + {ok, reverse(Acc)}; + + [X | Xs] -> + case Fun(X) of + {ok, Y} -> + do_try_map(Xs, Fun, [Y | Acc]); + + {error, Error} -> + {error, Error} + end + end. + +-spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, + list(ACE)} | + {error, ACF}. +try_map(List, Fun) -> + do_try_map(List, Fun, []). + +-spec drop(list(ACL), integer()) -> list(ACL). +drop(List, N) -> + case N =< 0 of + true -> + List; + + false -> + case List of + [] -> + []; + + [_ | Xs] -> + drop(Xs, N - 1) + end + end. + +-spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). +do_take(List, N, Acc) -> + case N =< 0 of + true -> + reverse(Acc); + + false -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_take(Xs, N - 1, [X | Acc]) + end + end. + +-spec take(list(ACS), integer()) -> list(ACS). +take(List, N) -> + do_take(List, N, []). + +-spec new() -> list(any()). +new() -> + []. + +-spec append(list(ACX), list(ACX)) -> list(ACX). +append(First, Second) -> + lists:append(First, Second). + +-spec prepend(list(ADF), ADF) -> list(ADF). +prepend(List, Item) -> + [Item | List]. + +-spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). +reverse_and_prepend(Prefix, Suffix) -> + case Prefix of + [] -> + Suffix; + + [First | Rest] -> + reverse_and_prepend(Rest, [First | Suffix]) + end. + +-spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). +do_concat(Lists, Acc) -> + case Lists of + [] -> + reverse(Acc); + + [List | Further_lists] -> + do_concat(Further_lists, reverse_and_prepend(List, Acc)) + end. + +-spec concat(list(list(ADR))) -> list(ADR). +concat(Lists) -> + do_concat(Lists, []). + +-spec flatten(list(list(ADV))) -> list(ADV). +flatten(Lists) -> + do_concat(Lists, []). + +-spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). +flat_map(List, Fun) -> + _pipe = map(List, Fun), + concat(_pipe). + +-spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. +fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + fold(Rest, Fun(Initial, X), Fun) + end. + +-spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). +group(List, Key) -> + fold(List, gleam@dict:new(), update_group(Key)). + +-spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, + list(ABH)}. +map_fold(List, Acc, Fun) -> + _pipe = fold( + List, + {Acc, []}, + fun(Acc@1, Item) -> + {Current_acc, Items} = Acc@1, + {Next_acc, Next_item} = Fun(Current_acc, Item), + {Next_acc, [Next_item | Items]} + end + ), + gleam@pair:map_second(_pipe, fun reverse/1). + +-spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. +fold_right(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + Fun(fold_right(Rest, Initial, Fun), X) + end. + +-spec do_index_fold( + list(AEK), + AEM, + fun((AEM, AEK, integer()) -> AEM), + integer() +) -> AEM. +do_index_fold(Over, Acc, With, Index) -> + case Over of + [] -> + Acc; + + [First | Rest] -> + do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) + end. + +-spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. +index_fold(Over, Initial, Fun) -> + do_index_fold(Over, Initial, Fun, 0). + +-spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, + AES} | + {error, AET}. +try_fold(Collection, Accumulator, Fun) -> + case Collection of + [] -> + {ok, Accumulator}; + + [First | Rest] -> + case Fun(Accumulator, First) of + {ok, Result} -> + try_fold(Rest, Result, Fun); + + {error, _} = Error -> + Error + end + end. + +-spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. +fold_until(Collection, Accumulator, Fun) -> + case Collection of + [] -> + Accumulator; + + [First | Rest] -> + case Fun(Accumulator, First) of + {continue, Next_accumulator} -> + fold_until(Rest, Next_accumulator, Fun); + + {stop, B} -> + B + end + end. + +-spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. +find(Haystack, Is_desired) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Is_desired(X) of + true -> + {ok, X}; + + _ -> + find(Rest, Is_desired) + end + end. + +-spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | + {error, nil}. +find_map(Haystack, Fun) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Fun(X) of + {ok, X@1} -> + {ok, X@1}; + + _ -> + find_map(Rest, Fun) + end + end. + +-spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). +all(List, Predicate) -> + case List of + [] -> + true; + + [First | Rest] -> + case Predicate(First) of + true -> + all(Rest, Predicate); + + false -> + false + end + end. + +-spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). +any(List, Predicate) -> + case List of + [] -> + false; + + [First | Rest] -> + case Predicate(First) of + true -> + true; + + false -> + any(Rest, Predicate) + end + end. + +-spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). +do_zip(Xs, Ys, Acc) -> + case {Xs, Ys} of + {[X | Xs@1], [Y | Ys@1]} -> + do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); + + {_, _} -> + reverse(Acc) + end. + +-spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). +zip(List, Other) -> + do_zip(List, Other, []). + +-spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | + {error, length_mismatch()}. +strict_zip(List, Other) -> + case length(List) =:= length(Other) of + true -> + {ok, zip(List, Other)}; + + false -> + {error, length_mismatch} + end. + +-spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. +do_unzip(Input, Xs, Ys) -> + case Input of + [] -> + {reverse(Xs), reverse(Ys)}; + + [{X, Y} | Rest] -> + do_unzip(Rest, [X | Xs], [Y | Ys]) + end. + +-spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. +unzip(Input) -> + do_unzip(Input, [], []). + +-spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). +do_intersperse(List, Separator, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Rest] -> + do_intersperse(Rest, Separator, [X, Separator | Acc]) + end. + +-spec intersperse(list(AGX), AGX) -> list(AGX). +intersperse(List, Elem) -> + case List of + [] -> + List; + + [_] -> + List; + + [X | Rest] -> + do_intersperse(Rest, Elem, [X]) + end. + +-spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. +at(List, Index) -> + case Index >= 0 of + true -> + _pipe = List, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1); + + false -> + {error, nil} + end. + +-spec unique(list(AHE)) -> list(AHE). +unique(List) -> + case List of + [] -> + []; + + [X | Rest] -> + [X | unique(filter(Rest, fun(Y) -> Y /= X end))] + end. + +-spec merge_up( + integer(), + integer(), + list(AHH), + list(AHH), + list(AHH), + fun((AHH, AHH) -> gleam@order:order()) +) -> list(AHH). +merge_up(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Ax@1, Bx@1) of + gt -> + merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); + + _ -> + merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) + end; + + {_, _, _, _} -> + Acc + end. + +-spec merge_down( + integer(), + integer(), + list(AHM), + list(AHM), + list(AHM), + fun((AHM, AHM) -> gleam@order:order()) +) -> list(AHM). +merge_down(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Bx@1, Ax@1) of + lt -> + merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); + + _ -> + merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) + end; + + {_, _, _, _} -> + Acc + end. + +-spec merge_sort( + list(AHR), + integer(), + fun((AHR, AHR) -> gleam@order:order()), + boolean() +) -> list(AHR). +merge_sort(L, Ln, Compare, Down) -> + N = Ln div 2, + A = L, + B = drop(L, N), + case Ln < 3 of + true -> + case Down of + true -> + merge_down(N, Ln - N, A, B, [], Compare); + + false -> + merge_up(N, Ln - N, A, B, [], Compare) + end; + + false -> + case Down of + true -> + merge_down( + N, + Ln - N, + merge_sort(A, N, Compare, false), + merge_sort(B, Ln - N, Compare, false), + [], + Compare + ); + + false -> + merge_up( + N, + Ln - N, + merge_sort(A, N, Compare, true), + merge_sort(B, Ln - N, Compare, true), + [], + Compare + ) + end + end. + +-spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). +sort(List, Compare) -> + merge_sort(List, length(List), Compare, true). + +-spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). +tail_recursive_range(Start, Stop, Acc) -> + case gleam@int:compare(Start, Stop) of + eq -> + [Stop | Acc]; + + gt -> + tail_recursive_range(Start, Stop + 1, [Stop | Acc]); + + lt -> + tail_recursive_range(Start, Stop - 1, [Stop | Acc]) + end. + +-spec range(integer(), integer()) -> list(integer()). +range(Start, Stop) -> + tail_recursive_range(Start, Stop, []). + +-spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). +do_repeat(A, Times, Acc) -> + case Times =< 0 of + true -> + Acc; + + false -> + do_repeat(A, Times - 1, [A | Acc]) + end. + +-spec repeat(AID, integer()) -> list(AID). +repeat(A, Times) -> + do_repeat(A, Times, []). + +-spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. +do_split(List, N, Taken) -> + case N =< 0 of + true -> + {reverse(Taken), List}; + + false -> + case List of + [] -> + {reverse(Taken), []}; + + [X | Xs] -> + do_split(Xs, N - 1, [X | Taken]) + end + end. + +-spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. +split(List, Index) -> + do_split(List, Index, []). + +-spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), + list(AIO)}. +do_split_while(List, F, Acc) -> + case List of + [] -> + {reverse(Acc), []}; + + [X | Xs] -> + case F(X) of + false -> + {reverse(Acc), List}; + + _ -> + do_split_while(Xs, F, [X | Acc]) + end + end. + +-spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. +split_while(List, Predicate) -> + do_split_while(List, Predicate, []). + +-spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. +key_find(Keyword_list, Desired_key) -> + find_map( + Keyword_list, + fun(Keyword) -> + {Key, Value} = Keyword, + case Key =:= Desired_key of + true -> + {ok, Value}; + + false -> + {error, nil} + end + end + ). + +-spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). +key_filter(Keyword_list, Desired_key) -> + filter_map( + Keyword_list, + fun(Keyword) -> + {Key, Value} = Keyword, + case Key =:= Desired_key of + true -> + {ok, Value}; + + false -> + {error, nil} + end + end + ). + +-spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, + {AZQ, list(AZQ)}} | + {error, nil}. +do_pop(Haystack, Predicate, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Predicate(X) of + true -> + {ok, {X, append(reverse(Checked), Rest)}}; + + false -> + do_pop(Rest, Predicate, [X | Checked]) + end + end. + +-spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | + {error, nil}. +pop(Haystack, Is_desired) -> + do_pop(Haystack, Is_desired, []). + +-spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, + {BAR, list(BAE)}} | + {error, nil}. +do_pop_map(Haystack, Mapper, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Mapper(X) of + {ok, Y} -> + {ok, {Y, append(reverse(Checked), Rest)}}; + + {error, _} -> + do_pop_map(Rest, Mapper, [X | Checked]) + end + end. + +-spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, + {AJV, list(AJT)}} | + {error, nil}. +pop_map(Haystack, Is_desired) -> + do_pop_map(Haystack, Is_desired, []). + +-spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | + {error, nil}. +key_pop(Haystack, Key) -> + pop_map( + Haystack, + fun(Entry) -> + {K, V} = Entry, + case K of + K@1 when K@1 =:= Key -> + {ok, V}; + + _ -> + {error, nil} + end + end + ). + +-spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). +key_set(List, Key, Value) -> + case List of + [] -> + [{Key, Value}]; + + [{K, _} | Rest] when K =:= Key -> + [{Key, Value} | Rest]; + + [First | Rest@1] -> + [First | key_set(Rest@1, Key, Value)] + end. + +-spec each(list(AKM), fun((AKM) -> any())) -> nil. +each(List, F) -> + case List of + [] -> + nil; + + [X | Xs] -> + F(X), + each(Xs, F) + end. + +-spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | + {error, AKS}. +try_each(List, Fun) -> + case List of + [] -> + {ok, nil}; + + [X | Xs] -> + case Fun(X) of + {ok, _} -> + try_each(Xs, Fun); + + {error, E} -> + {error, E} + end + end. + +-spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), + list(BBY)}. +do_partition(List, Categorise, Trues, Falses) -> + case List of + [] -> + {reverse(Trues), reverse(Falses)}; + + [X | Xs] -> + case Categorise(X) of + true -> + do_partition(Xs, Categorise, [X | Trues], Falses); + + false -> + do_partition(Xs, Categorise, Trues, [X | Falses]) + end + end. + +-spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. +partition(List, Categorise) -> + do_partition(List, Categorise, [], []). + +-spec permutations(list(ALG)) -> list(list(ALG)). +permutations(L) -> + case L of + [] -> + [[]]; + + _ -> + _pipe = L, + _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, + _pipe@2 = index_fold( + _pipe@1, + [], + fun(Acc, J, J_idx) -> case I_idx =:= J_idx of + true -> + Acc; + + false -> + [J | Acc] + end end + ), + _pipe@3 = reverse(_pipe@2), + _pipe@4 = permutations(_pipe@3), + map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), + concat(_pipe@5) + end. + +-spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). +do_window(Acc, L, N) -> + Window = take(L, N), + case length(Window) =:= N of + true -> + do_window([Window | Acc], drop(L, 1), N); + + false -> + Acc + end. + +-spec window(list(ALQ), integer()) -> list(list(ALQ)). +window(L, N) -> + _pipe = do_window([], L, N), + reverse(_pipe). + +-spec window_by_2(list(ALU)) -> list({ALU, ALU}). +window_by_2(L) -> + zip(L, drop(L, 1)). + +-spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). +drop_while(List, Predicate) -> + case List of + [] -> + []; + + [X | Xs] -> + case Predicate(X) of + true -> + drop_while(Xs, Predicate); + + false -> + [X | Xs] + end + end. + +-spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). +do_take_while(List, Predicate, Acc) -> + case List of + [] -> + reverse(Acc); + + [First | Rest] -> + case Predicate(First) of + true -> + do_take_while(Rest, Predicate, [First | Acc]); + + false -> + reverse(Acc) + end + end. + +-spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). +take_while(List, Predicate) -> + do_take_while(List, Predicate, []). + +-spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). +do_chunk(List, F, Previous_key, Current_chunk, Acc) -> + case List of + [First | Rest] -> + Key = F(First), + case Key =:= Previous_key of + false -> + New_acc = [reverse(Current_chunk) | Acc], + do_chunk(Rest, F, Key, [First], New_acc); + + _ -> + do_chunk(Rest, F, Key, [First | Current_chunk], Acc) + end; + + _ -> + reverse([reverse(Current_chunk) | Acc]) + end. + +-spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). +chunk(List, F) -> + case List of + [] -> + []; + + [First | Rest] -> + do_chunk(Rest, F, F(First), [First], []) + end. + +-spec do_sized_chunk( + list(AMU), + integer(), + integer(), + list(AMU), + list(list(AMU)) +) -> list(list(AMU)). +do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> + case List of + [] -> + case Current_chunk of + [] -> + reverse(Acc); + + Remaining -> + reverse([reverse(Remaining) | Acc]) + end; + + [First | Rest] -> + Chunk = [First | Current_chunk], + case Left > 1 of + false -> + do_sized_chunk( + Rest, + Count, + Count, + [], + [reverse(Chunk) | Acc] + ); + + true -> + do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) + end + end. + +-spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). +sized_chunk(List, Count) -> + do_sized_chunk(List, Count, Count, [], []). + +-spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. +reduce(List, Fun) -> + case List of + [] -> + {error, nil}; + + [First | Rest] -> + {ok, fold(Rest, First, Fun)} + end. + +-spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). +do_scan(List, Accumulator, Accumulated, Fun) -> + case List of + [] -> + reverse(Accumulated); + + [X | Xs] -> + Next = Fun(Accumulator, X), + do_scan(Xs, Next, [Next | Accumulated], Fun) + end. + +-spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). +scan(List, Initial, Fun) -> + do_scan(List, Initial, [], Fun). + +-spec last(list(ANS)) -> {ok, ANS} | {error, nil}. +last(List) -> + _pipe = List, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec combinations(list(ANW), integer()) -> list(list(ANW)). +combinations(Items, N) -> + case N of + 0 -> + [[]]; + + _ -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = begin + _pipe = map( + combinations(Xs, N - 1), + fun(Com) -> [X | Com] end + ), + reverse(_pipe) + end, + fold( + First_combinations, + combinations(Xs, N), + fun(Acc, C) -> [C | Acc] end + ) + end + end. + +-spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). +do_combination_pairs(Items) -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = map(Xs, fun(Other) -> {X, Other} end), + [First_combinations | do_combination_pairs(Xs)] + end. + +-spec combination_pairs(list(AOE)) -> list({AOE, AOE}). +combination_pairs(Items) -> + _pipe = do_combination_pairs(Items), + concat(_pipe). + +-spec transpose(list(list(AOL))) -> list(list(AOL)). +transpose(List_of_list) -> + Take_first = fun(List) -> case List of + [] -> + []; + + [F] -> + [F]; + + [F@1 | _] -> + [F@1] + end end, + case List_of_list of + [] -> + []; + + [[] | Xss] -> + transpose(Xss); + + Rows -> + Firsts = begin + _pipe = Rows, + _pipe@1 = map(_pipe, Take_first), + concat(_pipe@1) + end, + Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), + [Firsts | Rest] + end. + +-spec interleave(list(list(AOH))) -> list(AOH). +interleave(List) -> + _pipe = transpose(List), + concat(_pipe). + +-spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). +do_shuffle_pair_unwrap(List, Acc) -> + case List of + [] -> + Acc; + + [Elem_pair | Enumerable] -> + do_shuffle_pair_unwrap( + Enumerable, + [erlang:element(2, Elem_pair) | Acc] + ) + end. + +-spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). +do_shuffle_by_pair_indexes(List_of_pairs) -> + sort( + List_of_pairs, + fun(A_pair, B_pair) -> + gleam@float:compare( + erlang:element(1, A_pair), + erlang:element(1, B_pair) + ) + end + ). + +-spec shuffle(list(AOX)) -> list(AOX). +shuffle(List) -> + _pipe = List, + _pipe@1 = fold( + _pipe, + [], + fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end + ), + _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), + do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl new file mode 100644 index 00000000000..9f45b107384 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl @@ -0,0 +1,76 @@ +-module(gleam@map). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). + +-spec size(gleam@dict:dict(any(), any())) -> integer(). +size(Map) -> + gleam@dict:size(Map). + +-spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). +to_list(Map) -> + gleam@dict:to_list(Map). + +-spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). +from_list(List) -> + gleam@dict:from_list(List). + +-spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). +has_key(Map, Key) -> + gleam@dict:has_key(Map, Key). + +-spec new() -> gleam@dict:dict(any(), any()). +new() -> + gleam@dict:new(). + +-spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. +get(From, Get) -> + gleam@dict:get(From, Get). + +-spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). +insert(Map, Key, Value) -> + gleam@dict:insert(Map, Key, Value). + +-spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). +map_values(Map, Fun) -> + gleam@dict:map_values(Map, Fun). + +-spec keys(gleam@dict:dict(FED, any())) -> list(FED). +keys(Map) -> + gleam@dict:keys(Map). + +-spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). +values(Map) -> + gleam@dict:values(Map). + +-spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). +filter(Map, Predicate) -> + gleam@dict:filter(Map, Predicate). + +-spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). +take(Map, Desired_keys) -> + gleam@dict:take(Map, Desired_keys). + +-spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). +merge(Map, New_entries) -> + gleam@dict:merge(Map, New_entries). + +-spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). +delete(Map, Key) -> + gleam@dict:delete(Map, Key). + +-spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). +drop(Map, Disallowed_keys) -> + gleam@dict:drop(Map, Disallowed_keys). + +-spec update( + gleam@dict:dict(FFB, FFC), + FFB, + fun((gleam@option:option(FFC)) -> FFC) +) -> gleam@dict:dict(FFB, FFC). +update(Map, Key, Fun) -> + gleam@dict:update(Map, Key, Fun). + +-spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. +fold(Map, Initial, Fun) -> + gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl new file mode 100644 index 00000000000..812aa1fe854 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl @@ -0,0 +1,147 @@ +-module(gleam@option). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). +-export_type([option/1]). + +-type option(IY) :: {some, IY} | none. + +-spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). +do_all(List, Acc) -> + case List of + [] -> + {some, Acc}; + + [X | Rest] -> + Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of + {{some, Values}, {some, Value}} -> + {some, [Value | Values]}; + + {_, _} -> + none + end end, + Accumulate(do_all(Rest, Acc), X) + end. + +-spec all(list(option(JF))) -> option(list(JF)). +all(List) -> + do_all(List, []). + +-spec is_some(option(any())) -> boolean(). +is_some(Option) -> + Option /= none. + +-spec is_none(option(any())) -> boolean(). +is_none(Option) -> + Option =:= none. + +-spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. +to_result(Option, E) -> + case Option of + {some, A} -> + {ok, A}; + + _ -> + {error, E} + end. + +-spec from_result({ok, JU} | {error, any()}) -> option(JU). +from_result(Result) -> + case Result of + {ok, A} -> + {some, A}; + + _ -> + none + end. + +-spec unwrap(option(JZ), JZ) -> JZ. +unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default + end. + +-spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. +lazy_unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default() + end. + +-spec map(option(KD), fun((KD) -> KF)) -> option(KF). +map(Option, Fun) -> + case Option of + {some, X} -> + {some, Fun(X)}; + + none -> + none + end. + +-spec flatten(option(option(KH))) -> option(KH). +flatten(Option) -> + case Option of + {some, X} -> + X; + + none -> + none + end. + +-spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). +then(Option, Fun) -> + case Option of + {some, X} -> + Fun(X); + + none -> + none + end. + +-spec 'or'(option(KQ), option(KQ)) -> option(KQ). +'or'(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second + end. + +-spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). +lazy_or(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second() + end. + +-spec do_values(list(option(KY)), list(KY)) -> list(KY). +do_values(List, Acc) -> + case List of + [] -> + Acc; + + [X | Xs] -> + Accumulate = fun(Acc@1, Item) -> case Item of + {some, Value} -> + [Value | Acc@1]; + + none -> + Acc@1 + end end, + Accumulate(do_values(Xs, Acc), X) + end. + +-spec values(list(option(LD))) -> list(LD). +values(Options) -> + do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl new file mode 100644 index 00000000000..a9eed8f39c1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl @@ -0,0 +1,79 @@ +-module(gleam@order). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). +-export_type([order/0]). + +-type order() :: lt | eq | gt. + +-spec negate(order()) -> order(). +negate(Order) -> + case Order of + lt -> + gt; + + eq -> + eq; + + gt -> + lt + end. + +-spec to_int(order()) -> integer(). +to_int(Order) -> + case Order of + lt -> + -1; + + eq -> + 0; + + gt -> + 1 + end. + +-spec compare(order(), order()) -> order(). +compare(A, B) -> + case {A, B} of + {X, Y} when X =:= Y -> + eq; + + {lt, _} -> + lt; + + {eq, gt} -> + lt; + + {_, _} -> + gt + end. + +-spec max(order(), order()) -> order(). +max(A, B) -> + case {A, B} of + {gt, _} -> + gt; + + {eq, lt} -> + eq; + + {_, _} -> + B + end. + +-spec min(order(), order()) -> order(). +min(A, B) -> + case {A, B} of + {lt, _} -> + lt; + + {eq, gt} -> + eq; + + {_, _} -> + B + end. + +-spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). +reverse(Orderer) -> + fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl new file mode 100644 index 00000000000..2452a9817e1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl @@ -0,0 +1,33 @@ +-module(gleam@pair). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). + +-spec first({IJ, any()}) -> IJ. +first(Pair) -> + {A, _} = Pair, + A. + +-spec second({any(), IM}) -> IM. +second(Pair) -> + {_, A} = Pair, + A. + +-spec swap({IN, IO}) -> {IO, IN}. +swap(Pair) -> + {A, B} = Pair, + {B, A}. + +-spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. +map_first(Pair, Fun) -> + {A, B} = Pair, + {Fun(A), B}. + +-spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. +map_second(Pair, Fun) -> + {A, B} = Pair, + {A, Fun(B)}. + +-spec new(IV, IW) -> {IV, IW}. +new(First, Second) -> + {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl new file mode 100644 index 00000000000..faec6923a14 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl @@ -0,0 +1,121 @@ +-module(gleam@queue). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). +-export_type([queue/1]). + +-opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. + +-spec new() -> queue(any()). +new() -> + {queue, [], []}. + +-spec from_list(list(EYN)) -> queue(EYN). +from_list(List) -> + {queue, [], List}. + +-spec to_list(queue(EYQ)) -> list(EYQ). +to_list(Queue) -> + _pipe = erlang:element(3, Queue), + gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). + +-spec is_empty(queue(any())) -> boolean(). +is_empty(Queue) -> + (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). + +-spec length(queue(any())) -> integer(). +length(Queue) -> + gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( + erlang:element(3, Queue) + ). + +-spec push_back(queue(EYX), EYX) -> queue(EYX). +push_back(Queue, Item) -> + {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. + +-spec push_front(queue(EZA), EZA) -> queue(EZA). +push_front(Queue, Item) -> + {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. + +-spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. +pop_back(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, [], Out} -> + pop_back({queue, gleam@list:reverse(Out), []}); + + {queue, [First | Rest], Out@1} -> + Queue@1 = {queue, Rest, Out@1}, + {ok, {First, Queue@1}} + end. + +-spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. +pop_front(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, In, []} -> + pop_front({queue, [], gleam@list:reverse(In)}); + + {queue, In@1, [First | Rest]} -> + Queue@1 = {queue, In@1, Rest}, + {ok, {First, Queue@1}} + end. + +-spec reverse(queue(EZN)) -> queue(EZN). +reverse(Queue) -> + {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. + +-spec check_equal( + list(EZQ), + list(EZQ), + list(EZQ), + list(EZQ), + fun((EZQ, EZQ) -> boolean()) +) -> boolean(). +check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> + case {Xs, X_tail, Ys, Y_tail} of + {[], [], [], []} -> + true; + + {[X | Xs@1], _, [Y | Ys@1], _} -> + case Eq(X, Y) of + false -> + false; + + true -> + check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) + end; + + {[], [_ | _], _, _} -> + check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); + + {_, _, [], [_ | _]} -> + check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); + + {_, _, _, _} -> + false + end. + +-spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). +is_logically_equal(A, B, Element_is_equal) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + Element_is_equal + ). + +-spec is_equal(queue(EZY), queue(EZY)) -> boolean(). +is_equal(A, B) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + fun(A@1, B@1) -> A@1 =:= B@1 end + ). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl new file mode 100644 index 00000000000..2d1c5fc870e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl @@ -0,0 +1,33 @@ +-module(gleam@regex). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([compile/2, from_string/1, check/2, split/2, scan/2]). +-export_type([regex/0, match/0, compile_error/0, options/0]). + +-type regex() :: any(). + +-type match() :: {match, binary(), list(gleam@option:option(binary()))}. + +-type compile_error() :: {compile_error, binary(), integer()}. + +-type options() :: {options, boolean(), boolean()}. + +-spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. +compile(Pattern, Options) -> + gleam_stdlib:compile_regex(Pattern, Options). + +-spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. +from_string(Pattern) -> + compile(Pattern, {options, false, false}). + +-spec check(regex(), binary()) -> boolean(). +check(Regex, Content) -> + gleam_stdlib:regex_check(Regex, Content). + +-spec split(regex(), binary()) -> list(binary()). +split(Regex, String) -> + gleam_stdlib:regex_split(Regex, String). + +-spec scan(regex(), binary()) -> list(match()). +scan(Regex, String) -> + gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl new file mode 100644 index 00000000000..c80a7048303 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl @@ -0,0 +1,201 @@ +-module(gleam@result). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). + +-spec is_ok({ok, any()} | {error, any()}) -> boolean(). +is_ok(Result) -> + case Result of + {error, _} -> + false; + + {ok, _} -> + true + end. + +-spec is_error({ok, any()} | {error, any()}) -> boolean(). +is_error(Result) -> + case Result of + {ok, _} -> + false; + + {error, _} -> + true + end. + +-spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | + {error, BIK}. +map(Result, Fun) -> + case Result of + {ok, X} -> + {ok, Fun(X)}; + + {error, E} -> + {error, E} + end. + +-spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | + {error, BIU}. +map_error(Result, Fun) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, Error} -> + {error, Fun(Error)} + end. + +-spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | + {error, BIY}. +flatten(Result) -> + case Result of + {ok, X} -> + X; + + {error, Error} -> + {error, Error} + end. + +-spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, + BJJ} | + {error, BJG}. +'try'(Result, Fun) -> + case Result of + {ok, X} -> + Fun(X); + + {error, E} -> + {error, E} + end. + +-spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, + BJS} | + {error, BJP}. +then(Result, Fun) -> + 'try'(Result, Fun). + +-spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. +unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default + end. + +-spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. +lazy_unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default() + end. + +-spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. +unwrap_error(Result, Default) -> + case Result of + {ok, _} -> + Default; + + {error, E} -> + E + end. + +-spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. +unwrap_both(Result) -> + case Result of + {ok, A} -> + A; + + {error, A@1} -> + A@1 + end. + +-spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. +nil_error(Result) -> + map_error(Result, fun(_) -> nil end). + +-spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | + {error, BKT}. +'or'(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second + end. + +-spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, + BLA} | + {error, BLB}. +lazy_or(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second() + end. + +-spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. +all(Results) -> + gleam@list:try_map(Results, fun(X) -> X end). + +-spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), + list(BLY)}. +do_partition(Results, Oks, Errors) -> + case Results of + [] -> + {Oks, Errors}; + + [{ok, A} | Rest] -> + do_partition(Rest, [A | Oks], Errors); + + [{error, E} | Rest@1] -> + do_partition(Rest@1, Oks, [E | Errors]) + end. + +-spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. +partition(Results) -> + do_partition(Results, [], []). + +-spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. +replace(Result, Value) -> + case Result of + {ok, _} -> + {ok, Value}; + + {error, Error} -> + {error, Error} + end. + +-spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. +replace_error(Result, Error) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, _} -> + {error, Error} + end. + +-spec values(list({ok, BMT} | {error, any()})) -> list(BMT). +values(Results) -> + gleam@list:filter_map(Results, fun(R) -> R end). + +-spec try_recover( + {ok, BMZ} | {error, BNA}, + fun((BNA) -> {ok, BMZ} | {error, BND}) +) -> {ok, BMZ} | {error, BND}. +try_recover(Result, Fun) -> + case Result of + {ok, Value} -> + {ok, Value}; + + {error, Error} -> + Fun(Error) + end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl new file mode 100644 index 00000000000..3374ebc293f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl @@ -0,0 +1,85 @@ +-module(gleam@set). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). +-export_type([set/1]). + +-opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. + +-spec new() -> set(any()). +new() -> + {set, gleam@dict:new()}. + +-spec size(set(any())) -> integer(). +size(Set) -> + gleam@dict:size(erlang:element(2, Set)). + +-spec insert(set(EOQ), EOQ) -> set(EOQ). +insert(Set, Member) -> + {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. + +-spec contains(set(EOT), EOT) -> boolean(). +contains(Set, Member) -> + _pipe = erlang:element(2, Set), + _pipe@1 = gleam@dict:get(_pipe, Member), + gleam@result:is_ok(_pipe@1). + +-spec delete(set(EOV), EOV) -> set(EOV). +delete(Set, Member) -> + {set, gleam@dict:delete(erlang:element(2, Set), Member)}. + +-spec to_list(set(EOY)) -> list(EOY). +to_list(Set) -> + gleam@dict:keys(erlang:element(2, Set)). + +-spec from_list(list(EPB)) -> set(EPB). +from_list(Members) -> + Map = gleam@list:fold( + Members, + gleam@dict:new(), + fun(M, K) -> gleam@dict:insert(M, K, []) end + ), + {set, Map}. + +-spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. +fold(Set, Initial, Reducer) -> + gleam@dict:fold( + erlang:element(2, Set), + Initial, + fun(A, K, _) -> Reducer(A, K) end + ). + +-spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). +filter(Set, Predicate) -> + {set, + gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. + +-spec drop(set(EPK), list(EPK)) -> set(EPK). +drop(Set, Disallowed) -> + gleam@list:fold(Disallowed, Set, fun delete/2). + +-spec take(set(EPO), list(EPO)) -> set(EPO). +take(Set, Desired) -> + {set, gleam@dict:take(erlang:element(2, Set), Desired)}. + +-spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. +order(First, Second) -> + case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( + erlang:element(2, Second) + ) of + true -> + {First, Second}; + + false -> + {Second, First} + end. + +-spec union(set(EPX), set(EPX)) -> set(EPX). +union(First, Second) -> + {Larger, Smaller} = order(First, Second), + fold(Smaller, Larger, fun insert/2). + +-spec intersection(set(EQB), set(EQB)) -> set(EQB). +intersection(First, Second) -> + {Larger, Smaller} = order(First, Second), + take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl new file mode 100644 index 00000000000..6cba31d1895 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl @@ -0,0 +1,352 @@ +-module(gleam@string). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). +-export_type([direction/0]). + +-type direction() :: leading | trailing | both. + +-spec is_empty(binary()) -> boolean(). +is_empty(Str) -> + Str =:= <<""/utf8>>. + +-spec length(binary()) -> integer(). +length(String) -> + string:length(String). + +-spec do_reverse(binary()) -> binary(). +do_reverse(String) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:reverse(_pipe@1), + gleam@string_builder:to_string(_pipe@2). + +-spec reverse(binary()) -> binary(). +reverse(String) -> + do_reverse(String). + +-spec replace(binary(), binary(), binary()) -> binary(). +replace(String, Pattern, Substitute) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), + gleam@string_builder:to_string(_pipe@2). + +-spec lowercase(binary()) -> binary(). +lowercase(String) -> + string:lowercase(String). + +-spec uppercase(binary()) -> binary(). +uppercase(String) -> + string:uppercase(String). + +-spec compare(binary(), binary()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + _ -> + case gleam_stdlib:less_than(A, B) of + true -> + lt; + + _ -> + gt + end + end. + +-spec slice(binary(), integer(), integer()) -> binary(). +slice(String, Idx, Len) -> + case Len < 0 of + true -> + <<""/utf8>>; + + false -> + case Idx < 0 of + true -> + Translated_idx = length(String) + Idx, + case Translated_idx < 0 of + true -> + <<""/utf8>>; + + false -> + string:slice(String, Translated_idx, Len) + end; + + false -> + string:slice(String, Idx, Len) + end + end. + +-spec crop(binary(), binary()) -> binary(). +crop(String, Substring) -> + gleam_stdlib:crop_string(String, Substring). + +-spec drop_left(binary(), integer()) -> binary(). +drop_left(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, Num_graphemes, length(String) - Num_graphemes) + end. + +-spec drop_right(binary(), integer()) -> binary(). +drop_right(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, 0, length(String) - Num_graphemes) + end. + +-spec contains(binary(), binary()) -> boolean(). +contains(Haystack, Needle) -> + gleam_stdlib:contains_string(Haystack, Needle). + +-spec starts_with(binary(), binary()) -> boolean(). +starts_with(String, Prefix) -> + gleam_stdlib:string_starts_with(String, Prefix). + +-spec ends_with(binary(), binary()) -> boolean(). +ends_with(String, Suffix) -> + gleam_stdlib:string_ends_with(String, Suffix). + +-spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +do_split_once(X, Substring) -> + case string:split(X, Substring) of + [First, Rest] -> + {ok, {First, Rest}}; + + _ -> + {error, nil} + end. + +-spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +split_once(X, Substring) -> + do_split_once(X, Substring). + +-spec append(binary(), binary()) -> binary(). +append(First, Second) -> + _pipe = First, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:append(_pipe@1, Second), + gleam@string_builder:to_string(_pipe@2). + +-spec concat(list(binary())) -> binary(). +concat(Strings) -> + _pipe = Strings, + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1). + +-spec repeat(binary(), integer()) -> binary(). +repeat(String, Times) -> + _pipe = gleam@iterator:repeat(String), + _pipe@1 = gleam@iterator:take(_pipe, Times), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec do_join(list(binary()), binary()) -> binary(). +do_join(Strings, Separator) -> + _pipe = Strings, + _pipe@1 = gleam@list:intersperse(_pipe, Separator), + concat(_pipe@1). + +-spec join(list(binary()), binary()) -> binary(). +join(Strings, Separator) -> + do_join(Strings, Separator). + +-spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). +padding(Size, Pad_string) -> + Pad_length = length(Pad_string), + Num_pads = case Pad_length of + 0 -> 0; + Gleam@denominator -> Size div Gleam@denominator + end, + Extra = case Pad_length of + 0 -> 0; + Gleam@denominator@1 -> Size rem Gleam@denominator@1 + end, + _pipe = gleam@iterator:repeat(Pad_string), + _pipe@1 = gleam@iterator:take(_pipe, Num_pads), + gleam@iterator:append( + _pipe@1, + gleam@iterator:single(slice(Pad_string, 0, Extra)) + ). + +-spec pad_left(binary(), integer(), binary()) -> binary(). +pad_left(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = padding(To_pad_length, Pad_string), + _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec pad_right(binary(), integer(), binary()) -> binary(). +pad_right(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = gleam@iterator:single(String), + _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec do_trim(binary()) -> binary(). +do_trim(String) -> + string:trim(String, both). + +-spec trim(binary()) -> binary(). +trim(String) -> + do_trim(String). + +-spec do_trim_left(binary()) -> binary(). +do_trim_left(String) -> + string:trim(String, leading). + +-spec trim_left(binary()) -> binary(). +trim_left(String) -> + do_trim_left(String). + +-spec do_trim_right(binary()) -> binary(). +do_trim_right(String) -> + string:trim(String, trailing). + +-spec trim_right(binary()) -> binary(). +trim_right(String) -> + do_trim_right(String). + +-spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. +pop_grapheme(String) -> + gleam_stdlib:string_pop_grapheme(String). + +-spec do_to_graphemes(binary(), list(binary())) -> list(binary()). +do_to_graphemes(String, Acc) -> + case pop_grapheme(String) of + {ok, {Grapheme, Rest}} -> + do_to_graphemes(Rest, [Grapheme | Acc]); + + _ -> + Acc + end. + +-spec to_graphemes(binary()) -> list(binary()). +to_graphemes(String) -> + _pipe = do_to_graphemes(String, []), + gleam@list:reverse(_pipe). + +-spec split(binary(), binary()) -> list(binary()). +split(X, Substring) -> + case Substring of + <<""/utf8>> -> + to_graphemes(X); + + _ -> + _pipe = X, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), + gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) + end. + +-spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). +do_to_utf_codepoints_impl(Bit_array, Acc) -> + case Bit_array of + <> -> + do_to_utf_codepoints_impl(Rest, [First | Acc]); + + _ -> + Acc + end. + +-spec do_to_utf_codepoints(binary()) -> list(integer()). +do_to_utf_codepoints(String) -> + _pipe = do_to_utf_codepoints_impl(<>, []), + gleam@list:reverse(_pipe). + +-spec to_utf_codepoints(binary()) -> list(integer()). +to_utf_codepoints(String) -> + do_to_utf_codepoints(String). + +-spec from_utf_codepoints(list(integer())) -> binary(). +from_utf_codepoints(Utf_codepoints) -> + gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). + +-spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. +utf_codepoint(Value) -> + case Value of + I when I > 1114111 -> + {error, nil}; + + 65534 -> + {error, nil}; + + 65535 -> + {error, nil}; + + I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> + {error, nil}; + + I@2 -> + {ok, gleam_stdlib:identity(I@2)} + end. + +-spec utf_codepoint_to_int(integer()) -> integer(). +utf_codepoint_to_int(Cp) -> + gleam_stdlib:identity(Cp). + +-spec to_option(binary()) -> gleam@option:option(binary()). +to_option(S) -> + case S of + <<""/utf8>> -> + none; + + _ -> + {some, S} + end. + +-spec first(binary()) -> {ok, binary()} | {error, nil}. +first(S) -> + case pop_grapheme(S) of + {ok, {First, _}} -> + {ok, First}; + + {error, E} -> + {error, E} + end. + +-spec last(binary()) -> {ok, binary()} | {error, nil}. +last(S) -> + case pop_grapheme(S) of + {ok, {First, <<""/utf8>>}} -> + {ok, First}; + + {ok, {_, Rest}} -> + {ok, slice(Rest, -1, 1)}; + + {error, E} -> + {error, E} + end. + +-spec capitalise(binary()) -> binary(). +capitalise(S) -> + case pop_grapheme(S) of + {ok, {First, Rest}} -> + append(uppercase(First), lowercase(Rest)); + + _ -> + <<""/utf8>> + end. + +-spec inspect(any()) -> binary(). +inspect(Term) -> + _pipe = gleam_stdlib:inspect(Term), + gleam@string_builder:to_string(_pipe). + +-spec byte_size(binary()) -> integer(). +byte_size(String) -> + erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl new file mode 100644 index 00000000000..693e840f370 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl @@ -0,0 +1,91 @@ +-module(gleam@string_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). +-export_type([string_builder/0, direction/0]). + +-type string_builder() :: any(). + +-type direction() :: all. + +-spec prepend_builder(string_builder(), string_builder()) -> string_builder(). +prepend_builder(Builder, Prefix) -> + gleam_stdlib:iodata_append(Prefix, Builder). + +-spec append_builder(string_builder(), string_builder()) -> string_builder(). +append_builder(Builder, Suffix) -> + gleam_stdlib:iodata_append(Builder, Suffix). + +-spec new() -> string_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec from_strings(list(binary())) -> string_builder(). +from_strings(Strings) -> + gleam_stdlib:identity(Strings). + +-spec concat(list(string_builder())) -> string_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec from_string(binary()) -> string_builder(). +from_string(String) -> + gleam_stdlib:identity(String). + +-spec prepend(string_builder(), binary()) -> string_builder(). +prepend(Builder, Prefix) -> + append_builder(from_string(Prefix), Builder). + +-spec append(string_builder(), binary()) -> string_builder(). +append(Builder, Second) -> + append_builder(Builder, from_string(Second)). + +-spec to_string(string_builder()) -> binary(). +to_string(Builder) -> + unicode:characters_to_binary(Builder). + +-spec byte_size(string_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). + +-spec join(list(string_builder()), binary()) -> string_builder(). +join(Builders, Sep) -> + _pipe = Builders, + _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), + concat(_pipe@1). + +-spec lowercase(string_builder()) -> string_builder(). +lowercase(Builder) -> + string:lowercase(Builder). + +-spec uppercase(string_builder()) -> string_builder(). +uppercase(Builder) -> + string:uppercase(Builder). + +-spec reverse(string_builder()) -> string_builder(). +reverse(Builder) -> + string:reverse(Builder). + +-spec do_split(string_builder(), binary()) -> list(string_builder()). +do_split(Iodata, Pattern) -> + string:split(Iodata, Pattern, all). + +-spec split(string_builder(), binary()) -> list(string_builder()). +split(Iodata, Pattern) -> + do_split(Iodata, Pattern). + +-spec do_replace(string_builder(), binary(), binary()) -> string_builder(). +do_replace(Iodata, Pattern, Substitute) -> + string:replace(Iodata, Pattern, Substitute, all). + +-spec replace(string_builder(), binary(), binary()) -> string_builder(). +replace(Builder, Pattern, Substitute) -> + do_replace(Builder, Pattern, Substitute). + +-spec is_equal(string_builder(), string_builder()) -> boolean(). +is_equal(A, B) -> + string:equal(A, B). + +-spec is_empty(string_builder()) -> boolean(). +is_empty(Builder) -> + string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl new file mode 100644 index 00000000000..a36df375281 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl @@ -0,0 +1,252 @@ +-module(gleam@uri). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). +-export_type([uri/0]). + +-type uri() :: {uri, + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(integer()), + binary(), + gleam@option:option(binary()), + gleam@option:option(binary())}. + +-spec parse(binary()) -> {ok, uri()} | {error, nil}. +parse(Uri_string) -> + gleam_stdlib:uri_parse(Uri_string). + +-spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. +parse_query(Query) -> + gleam_stdlib:parse_query(Query). + +-spec percent_encode(binary()) -> binary(). +percent_encode(Value) -> + gleam_stdlib:percent_encode(Value). + +-spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). +query_pair(Pair) -> + gleam@string_builder:from_strings( + [percent_encode(erlang:element(1, Pair)), + <<"="/utf8>>, + percent_encode(erlang:element(2, Pair))] + ). + +-spec query_to_string(list({binary(), binary()})) -> binary(). +query_to_string(Query) -> + _pipe = Query, + _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), + _pipe@2 = gleam@list:intersperse( + _pipe@1, + gleam@string_builder:from_string(<<"&"/utf8>>) + ), + _pipe@3 = gleam@string_builder:concat(_pipe@2), + gleam@string_builder:to_string(_pipe@3). + +-spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. +percent_decode(Value) -> + gleam_stdlib:percent_decode(Value). + +-spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). +do_remove_dot_segments(Input, Accumulator) -> + case Input of + [] -> + gleam@list:reverse(Accumulator); + + [Segment | Rest] -> + Accumulator@5 = case {Segment, Accumulator} of + {<<""/utf8>>, Accumulator@1} -> + Accumulator@1; + + {<<"."/utf8>>, Accumulator@2} -> + Accumulator@2; + + {<<".."/utf8>>, []} -> + []; + + {<<".."/utf8>>, [_ | Accumulator@3]} -> + Accumulator@3; + + {Segment@1, Accumulator@4} -> + [Segment@1 | Accumulator@4] + end, + do_remove_dot_segments(Rest, Accumulator@5) + end. + +-spec remove_dot_segments(list(binary())) -> list(binary()). +remove_dot_segments(Input) -> + do_remove_dot_segments(Input, []). + +-spec path_segments(binary()) -> list(binary()). +path_segments(Path) -> + remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). + +-spec to_string(uri()) -> binary(). +to_string(Uri) -> + Parts = case erlang:element(8, Uri) of + {some, Fragment} -> + [<<"#"/utf8>>, Fragment]; + + _ -> + [] + end, + Parts@1 = case erlang:element(7, Uri) of + {some, Query} -> + [<<"?"/utf8>>, Query | Parts]; + + _ -> + Parts + end, + Parts@2 = [erlang:element(6, Uri) | Parts@1], + Parts@3 = case {erlang:element(4, Uri), + gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of + {{some, Host}, false} when Host =/= <<""/utf8>> -> + [<<"/"/utf8>> | Parts@2]; + + {_, _} -> + Parts@2 + end, + Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of + {{some, _}, {some, Port}} -> + [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; + + {_, _} -> + Parts@3 + end, + Parts@5 = case {erlang:element(2, Uri), + erlang:element(3, Uri), + erlang:element(4, Uri)} of + {{some, S}, {some, U}, {some, H}} -> + [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; + + {{some, S@1}, none, {some, H@1}} -> + [S@1, <<"://"/utf8>>, H@1 | Parts@4]; + + {{some, S@2}, {some, _}, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {{some, S@2}, none, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {none, none, {some, H@2}} -> + [<<"//"/utf8>>, H@2 | Parts@4]; + + {_, _, _} -> + Parts@4 + end, + gleam@string:concat(Parts@5). + +-spec origin(uri()) -> {ok, binary()} | {error, nil}. +origin(Uri) -> + {uri, Scheme, _, Host, Port, _, _, _} = Uri, + case Scheme of + {some, <<"https"/utf8>>} when Port =:= {some, 443} -> + Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin)}; + + {some, <<"http"/utf8>>} when Port =:= {some, 80} -> + Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin@1)}; + + {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> + Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, + {ok, to_string(Origin@2)}; + + _ -> + {error, nil} + end. + +-spec drop_last(list(ETW)) -> list(ETW). +drop_last(Elements) -> + gleam@list:take(Elements, gleam@list:length(Elements) - 1). + +-spec join_segments(list(binary())) -> binary(). +join_segments(Segments) -> + gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). + +-spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. +merge(Base, Relative) -> + case Base of + {uri, {some, _}, _, {some, _}, _, _, _, _} -> + case Relative of + {uri, _, _, {some, _}, _, _, _, _} -> + Path = begin + _pipe = gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ), + _pipe@1 = remove_dot_segments(_pipe), + join_segments(_pipe@1) + end, + Resolved = {uri, + gleam@option:'or'( + erlang:element(2, Relative), + erlang:element(2, Base) + ), + none, + erlang:element(4, Relative), + gleam@option:'or'( + erlang:element(5, Relative), + erlang:element(5, Base) + ), + Path, + erlang:element(7, Relative), + erlang:element(8, Relative)}, + {ok, Resolved}; + + _ -> + {New_path, New_query} = case erlang:element(6, Relative) of + <<""/utf8>> -> + {erlang:element(6, Base), + gleam@option:'or'( + erlang:element(7, Relative), + erlang:element(7, Base) + )}; + + _ -> + Path_segments = case gleam@string:starts_with( + erlang:element(6, Relative), + <<"/"/utf8>> + ) of + true -> + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ); + + false -> + _pipe@2 = gleam@string:split( + erlang:element(6, Base), + <<"/"/utf8>> + ), + _pipe@3 = drop_last(_pipe@2), + gleam@list:append( + _pipe@3, + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ) + ) + end, + Path@1 = begin + _pipe@4 = Path_segments, + _pipe@5 = remove_dot_segments(_pipe@4), + join_segments(_pipe@5) + end, + {Path@1, erlang:element(7, Relative)} + end, + Resolved@1 = {uri, + erlang:element(2, Base), + none, + erlang:element(4, Base), + erlang:element(5, Base), + New_path, + New_query, + erlang:element(8, Relative)}, + {ok, Resolved@1} + end; + + _ -> + {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src new file mode 100644 index 00000000000..76aa1ea673c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src @@ -0,0 +1,31 @@ +{application, gleam_stdlib, [ + {vsn, "0.33.1"}, + {applications, []}, + {description, "A standard library for the Gleam programming language"}, + {modules, [gleam@base, + gleam@bit_array, + gleam@bit_builder, + gleam@bit_string, + gleam@bool, + gleam@bytes_builder, + gleam@dict, + gleam@dynamic, + gleam@float, + gleam@function, + gleam@int, + gleam@io, + gleam@iterator, + gleam@list, + gleam@map, + gleam@option, + gleam@order, + gleam@pair, + gleam@queue, + gleam@regex, + gleam@result, + gleam@set, + gleam@string, + gleam@string_builder, + gleam@uri]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl new file mode 100644 index 00000000000..c6ea1257110 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl @@ -0,0 +1,529 @@ +-module(gleam_stdlib). + +-export([ + map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, + decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, + parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, + wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, + bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, + bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, + percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, + base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, + decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, + decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, + println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, + int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, + crop_string/2, base16_decode/1 +]). + +%% Taken from OTP's uri_string module +-define(DEC2HEX(X), + if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; + ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 + end). + +%% Taken from OTP's uri_string module +-define(HEX2DEC(X), + if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; + ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; + ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 + end). + +-define(is_lowercase_char(X), (X > 96 andalso X < 123)). +-define(is_underscore_char(X), (X == 95)). +-define(is_digit_char(X), (X > 47 andalso X < 58)). + +uppercase(X) -> X - 32. + +map_get(Map, Key) -> + case maps:find(Key, Map) of + error -> {error, nil}; + OkFound -> OkFound + end. + +iodata_append(Iodata, String) -> [Iodata, String]. + +identity(X) -> X. + +decode_error_msg(Expected, Data) when is_binary(Expected) -> + decode_error(Expected, classify_dynamic(Data)). +decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> + {error, [{decode_error, Expected, Got, []}]}. + +classify_dynamic(nil) -> <<"Nil">>; +classify_dynamic(X) when is_atom(X) -> <<"Atom">>; +classify_dynamic(X) when is_binary(X) -> <<"String">>; +classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; +classify_dynamic(X) when is_integer(X) -> <<"Int">>; +classify_dynamic(X) when is_float(X) -> <<"Float">>; +classify_dynamic(X) when is_list(X) -> <<"List">>; +classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; +classify_dynamic(X) when is_map(X) -> <<"Map">>; +classify_dynamic(X) when is_tuple(X) -> + iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); +classify_dynamic(X) when + is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse + is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse + is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse + is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse + is_function(X, 12) -> <<"Function">>; +classify_dynamic(_) -> <<"Some other type">>. + +decode_map(Data) when is_map(Data) -> {ok, Data}; +decode_map(Data) -> decode_error_msg(<<"Map">>, Data). + +decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; +decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). + +decode_int(Data) when is_integer(Data) -> {ok, Data}; +decode_int(Data) -> decode_error_msg(<<"Int">>, Data). + +decode_float(Data) when is_float(Data) -> {ok, Data}; +decode_float(Data) -> decode_error_msg(<<"Float">>, Data). + +decode_bool(Data) when is_boolean(Data) -> {ok, Data}; +decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). + +decode_list(Data) when is_list(Data) -> {ok, Data}; +decode_list(Data) -> decode_error_msg(<<"List">>, Data). + +decode_field(Data, Key) when is_map(Data) -> + case Data of + #{Key := Value} -> {ok, {some, Value}}; + _ -> + {ok, none} + end; +decode_field(Data, _) -> + decode_error_msg(<<"Map">>, Data). + +size_of_tuple(Data) -> tuple_size(Data). + +tuple_get(_tup, Index) when Index < 0 -> {error, nil}; +tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; +tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. + +decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; +decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). + +decode_tuple2({_,_} = A) -> {ok, A}; +decode_tuple2([A,B]) -> {ok, {A,B}}; +decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). + +decode_tuple3({_,_,_} = A) -> {ok, A}; +decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; +decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). + +decode_tuple4({_,_,_,_} = A) -> {ok, A}; +decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; +decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). + +decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; +decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; +decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). + +decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; +decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; +decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). + +decode_option(Term, F) -> + Decode = fun(Inner) -> + case F(Inner) of + {ok, Decoded} -> {ok, {some, Decoded}}; + Error -> Error + end + end, + case Term of + undefined -> {ok, none}; + error -> {ok, none}; + null -> {ok, none}; + none -> {ok, none}; + nil -> {ok, none}; + {some, Inner} -> Decode(Inner); + _ -> Decode(Term) + end. + +decode_result(Term) -> + case Term of + {ok, Inner} -> {ok, {ok, Inner}}; + ok -> {ok, {ok, nil}}; + {error, Inner} -> {ok, {error, Inner}}; + error -> {ok, {error, nil}}; + _ -> decode_error_msg(<<"Result">>, Term) + end. + +int_from_base_string(String, Base) -> + case catch binary_to_integer(String, Base) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_int(String) -> + case catch binary_to_integer(String) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_float(String) -> + case catch binary_to_float(String) of + Float when is_float(Float) -> {ok, Float}; + _ -> {error, nil} + end. + +less_than(Lhs, Rhs) -> + Lhs < Rhs. + +string_starts_with(_, <<>>) -> true; +string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; +string_starts_with(String, Prefix) -> + PrefixSize = byte_size(Prefix), + Prefix == binary_part(String, 0, PrefixSize). + +string_ends_with(_, <<>>) -> true; +string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; +string_ends_with(String, Suffix) -> + SuffixSize = byte_size(Suffix), + Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). + +string_pad(String, Length, Dir, PadString) -> + Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), + case unicode:characters_to_binary(Chars) of + Bin when is_binary(Bin) -> Bin; + Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) + end. + +string_pop_grapheme(String) -> + case string:next_grapheme(String) of + [ Next | Rest ] -> + {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; + _ -> {error, nil} + end. + +bit_array_concat(BitArrays) -> + list_to_bitstring(BitArrays). + +bit_array_slice(Bin, Pos, Len) -> + try {ok, binary:part(Bin, Pos, Len)} + catch error:badarg -> {error, nil} + end. + +bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> + {ok, <>}; +bit_array_int_to_u32(_) -> + {error, nil}. + +bit_array_int_from_u32(<>) -> + {ok, I}; +bit_array_int_from_u32(_) -> + {error, nil}. + +compile_regex(String, Options) -> + {options, Caseless, Multiline} = Options, + OptionsList = [ + unicode, + ucp, + Caseless andalso caseless, + Multiline andalso multiline + ], + FilteredOptions = [Option || Option <- OptionsList, Option /= false], + case re:compile(String, FilteredOptions) of + {ok, MP} -> {ok, MP}; + {error, {Str, Pos}} -> + {error, {compile_error, unicode:characters_to_binary(Str), Pos}} + end. + +regex_check(Regex, String) -> + re:run(String, Regex) /= nomatch. + +regex_split(Regex, String) -> + re:split(String, Regex). + +regex_submatches(_, {-1, 0}) -> none; +regex_submatches(String, {Start, Length}) -> + BinarySlice = binary:part(String, {Start, Length}), + case string:is_empty(binary_to_list(BinarySlice)) of + true -> none; + false -> {some, BinarySlice} + end. + +regex_matches(String, [{Start, Length} | Submatches]) -> + Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), + {match, binary:part(String, Start, Length), Submatches1}. + +regex_scan(Regex, String) -> + case re:run(String, Regex, [global]) of + {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); + nomatch -> [] + end. + +base_decode64(S) -> + try {ok, base64:decode(S)} + catch error:_ -> {error, nil} + end. + +wrap_list(X) when is_list(X) -> X; +wrap_list(X) -> [X]. + +parse_query(Query) -> + case uri_string:dissect_query(Query) of + {error, _, _} -> {error, nil}; + Pairs -> + Pairs1 = lists:map(fun + ({K, true}) -> {K, <<"">>}; + (Pair) -> Pair + end, Pairs), + {ok, Pairs1} + end. + +percent_encode(B) -> percent_encode(B, <<>>). +percent_encode(<<>>, Acc) -> + Acc; +percent_encode(<>, Acc) -> + case percent_ok(H) of + true -> + percent_encode(T, <>); + false -> + <> = <>, + percent_encode(T, <>) + end. + +percent_decode(Cs) -> percent_decode(Cs, <<>>). +percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> + case is_hex_digit(C0) andalso is_hex_digit(C1) of + true -> + B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), + percent_decode(Cs, <>); + false -> + {error, nil} + end; +percent_decode(<>, Acc) -> + percent_decode(Cs, <>); +percent_decode(<<>>, Acc) -> + check_utf8(Acc). + +percent_ok($!) -> true; +percent_ok($$) -> true; +percent_ok($') -> true; +percent_ok($() -> true; +percent_ok($)) -> true; +percent_ok($*) -> true; +percent_ok($+) -> true; +percent_ok($-) -> true; +percent_ok($.) -> true; +percent_ok($_) -> true; +percent_ok($~) -> true; +percent_ok(C) when $0 =< C, C =< $9 -> true; +percent_ok(C) when $A =< C, C =< $Z -> true; +percent_ok(C) when $a =< C, C =< $z -> true; +percent_ok(_) -> false. + +is_hex_digit(C) -> + ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). + +check_utf8(Cs) -> + case unicode:characters_to_list(Cs) of + {incomplete, _, _} -> {error, nil}; + {error, _, _} -> {error, nil}; + _ -> {ok, Cs} + end. + +uri_parse(String) -> + case uri_string:parse(String) of + {error, _, _} -> {error, nil}; + Uri -> + {ok, {uri, + maps_get_optional(Uri, scheme), + maps_get_optional(Uri, userinfo), + maps_get_optional(Uri, host), + maps_get_optional(Uri, port), + maps_get_or(Uri, path, <<>>), + maps_get_optional(Uri, query), + maps_get_optional(Uri, fragment) + }} + end. + +maps_get_optional(Map, Key) -> + try {some, maps:get(Key, Map)} + catch _:_ -> none + end. + +maps_get_or(Map, Key, Default) -> + try maps:get(Key, Map) + catch _:_ -> Default + end. + +print(String) -> + io:put_chars(String), + nil. + +println(String) -> + io:put_chars([String, $\n]), + nil. + +print_error(String) -> + io:put_chars(standard_error, String), + nil. + +println_error(String) -> + io:put_chars(standard_error, [String, $\n]), + nil. + +inspect(true) -> + "True"; +inspect(false) -> + "False"; +inspect(nil) -> + "Nil"; +inspect(Data) when is_map(Data) -> + Fields = [ + [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] + || {Key, Value} <- maps:to_list(Data) + ], + ["dict.from_list([", lists:join(", ", Fields), "])"]; +inspect(Atom) when is_atom(Atom) -> + Binary = erlang:atom_to_binary(Atom), + case inspect_maybe_gleam_atom(Binary, none, <<>>) of + {ok, Inspected} -> Inspected; + {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] + end; +inspect(Any) when is_integer(Any) -> + erlang:integer_to_list(Any); +inspect(Any) when is_float(Any) -> + io_lib_format:fwrite_g(Any); +inspect(Binary) when is_binary(Binary) -> + case inspect_maybe_utf8_string(Binary, <<>>) of + {ok, InspectedUtf8String} -> InspectedUtf8String; + {error, not_a_utf8_string} -> + Segments = [erlang:integer_to_list(X) || <> <= Binary], + ["<<", lists:join(", ", Segments), ">>"] + end; +inspect(Bits) when is_bitstring(Bits) -> + inspect_bit_array(Bits); +inspect(List) when is_list(List) -> + case inspect_list(List) of + {proper, Elements} -> ["[", Elements, "]"]; + {improper, Elements} -> ["//erl([", Elements, "])"] + end; +inspect(Any) when is_tuple(Any) % Record constructors + andalso is_atom(element(1, Any)) + andalso element(1, Any) =/= false + andalso element(1, Any) =/= true + andalso element(1, Any) =/= nil +-> + [Atom | ArgsList] = erlang:tuple_to_list(Any), + Args = lists:join(<<", ">>, + lists:map(fun inspect/1, ArgsList) + ), + [inspect(Atom), "(", Args, ")"]; +inspect(Tuple) when is_tuple(Tuple) -> + Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), + ["#(", lists:join(", ", Elements), ")"]; +inspect(Any) when is_function(Any) -> + {arity, Arity} = erlang:fun_info(Any, arity), + ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), + Args = lists:join(<<", ">>, + lists:map(fun(Arg) -> <> end, ArgsAsciiCodes) + ), + ["//fn(", Args, ") { ... }"]; +inspect(Any) -> + ["//erl(", io_lib:format("~p", [Any]), ")"]. + + +inspect_maybe_gleam_atom(<<>>, none, _) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, none, _) when ?is_digit_char(First) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, _PrevChar, _Acc) + when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, none, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> + inspect_maybe_gleam_atom(Rest, $_, Acc); +inspect_maybe_gleam_atom(<>, $_, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<>, _PrevChar, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> + {ok, Acc}; +inspect_maybe_gleam_atom(A, B, C) -> + erlang:display({A, B, C}), + throw({gleam_error, A, B, C}). + +inspect_list([]) -> + {proper, []}; +inspect_list([First]) -> + {proper, [inspect(First)]}; +inspect_list([First | Rest]) when is_list(Rest) -> + {Kind, Inspected} = inspect_list(Rest), + {Kind, [inspect(First), <<", ">> | Inspected]}; +inspect_list([First | ImproperTail]) -> + {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. + +inspect_bit_array(Bits) -> + Text = inspect_bit_array(Bits, <<"<<">>), + <>">>. + +inspect_bit_array(<<>>, Acc) -> + Acc; +inspect_bit_array(<>, Acc) -> + inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); +inspect_bit_array(Rest, Acc) -> + Size = bit_size(Rest), + <> = Rest, + X1 = erlang:integer_to_binary(X), + Size1 = erlang:integer_to_binary(Size), + Segment = <>, + inspect_bit_array(<<>>, append_segment(Acc, Segment)). + +append_segment(<<"<<">>, Segment) -> + <<"<<", Segment/binary>>; +append_segment(Acc, Segment) -> + <>. + + +inspect_maybe_utf8_string(Binary, Acc) -> + case Binary of + <<>> -> {ok, <<$", Acc/binary, $">>}; + <> -> + Escaped = case First of + $" -> <<$\\, $">>; + $\\ -> <<$\\, $\\>>; + $\r -> <<$\\, $r>>; + $\n -> <<$\\, $n>>; + $\t -> <<$\\, $t>>; + Other -> <> + end, + inspect_maybe_utf8_string(Rest, <>); + _ -> {error, not_a_utf8_string} + end. + +float_to_string(Float) when is_float(Float) -> + erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). + +utf_codepoint_list_to_string(List) -> + case unicode:characters_to_binary(List) of + {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); + Binary -> Binary + end. + +crop_string(String, Prefix) -> + case string:find(String, Prefix) of + nomatch -> String; + New -> New + end. + +contains_string(String, Substring) -> + is_bitstring(string:find(String, Substring)). + +base16_decode(String) -> + try + {ok, binary:decode_hex(String)} + catch + _:_ -> {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs new file mode 100644 index 00000000000..45c28cfc87b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs @@ -0,0 +1,878 @@ +import { + BitArray, + Error, + List, + Ok, + Result, + UtfCodepoint, + stringBits, + toBitArray, + NonEmpty, + CustomType, +} from "./gleam.mjs"; +import { + CompileError as RegexCompileError, + Match as RegexMatch, +} from "./gleam/regex.mjs"; +import { DecodeError } from "./gleam/dynamic.mjs"; +import { Some, None } from "./gleam/option.mjs"; +import Dict from "./dict.mjs"; + +const Nil = undefined; +const NOT_FOUND = {}; + +export function identity(x) { + return x; +} + +export function parse_int(value) { + if (/^[-+]?(\d+)$/.test(value)) { + return new Ok(parseInt(value)); + } else { + return new Error(Nil); + } +} + +export function parse_float(value) { + if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { + return new Ok(parseFloat(value)); + } else { + return new Error(Nil); + } +} + +export function to_string(term) { + return term.toString(); +} + +export function float_to_string(float) { + const string = float.toString(); + if (string.indexOf(".") >= 0) { + return string; + } else { + return string + ".0"; + } +} + +export function int_to_base_string(int, base) { + return int.toString(base).toUpperCase(); +} + +const int_base_patterns = { + 2: /[^0-1]/, + 3: /[^0-2]/, + 4: /[^0-3]/, + 5: /[^0-4]/, + 6: /[^0-5]/, + 7: /[^0-6]/, + 8: /[^0-7]/, + 9: /[^0-8]/, + 10: /[^0-9]/, + 11: /[^0-9a]/, + 12: /[^0-9a-b]/, + 13: /[^0-9a-c]/, + 14: /[^0-9a-d]/, + 15: /[^0-9a-e]/, + 16: /[^0-9a-f]/, + 17: /[^0-9a-g]/, + 18: /[^0-9a-h]/, + 19: /[^0-9a-i]/, + 20: /[^0-9a-j]/, + 21: /[^0-9a-k]/, + 22: /[^0-9a-l]/, + 23: /[^0-9a-m]/, + 24: /[^0-9a-n]/, + 25: /[^0-9a-o]/, + 26: /[^0-9a-p]/, + 27: /[^0-9a-q]/, + 28: /[^0-9a-r]/, + 29: /[^0-9a-s]/, + 30: /[^0-9a-t]/, + 31: /[^0-9a-u]/, + 32: /[^0-9a-v]/, + 33: /[^0-9a-w]/, + 34: /[^0-9a-x]/, + 35: /[^0-9a-y]/, + 36: /[^0-9a-z]/, +}; + +export function int_from_base_string(string, base) { + if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { + return new Error(Nil); + } + + const result = parseInt(string, base); + + if (isNaN(result)) { + return new Error(Nil); + } + + return new Ok(result); +} + +export function string_replace(string, target, substitute) { + if (typeof string.replaceAll !== "undefined") { + return string.replaceAll(target, substitute); + } + // Fallback for older Node.js versions: + // 1. + // 2. + // TODO: This fallback could be remove once Node.js 14 is EOL + // aka on or after 2024-04-30 + return string.replace( + // $& means the whole matched string + new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), + substitute + ); +} + +export function string_reverse(string) { + return [...string].reverse().join(""); +} + +export function string_length(string) { + if (string === "") { + return 0; + } + const iterator = graphemes_iterator(string); + if (iterator) { + let i = 0; + for (const _ of iterator) { + i++; + } + return i; + } else { + return string.match(/./gsu).length; + } +} + +export function graphemes(string) { + const iterator = graphemes_iterator(string); + if (iterator) { + return List.fromArray(Array.from(iterator).map((item) => item.segment)); + } else { + return List.fromArray(string.match(/./gsu)); + } +} + +function graphemes_iterator(string) { + if (Intl && Intl.Segmenter) { + return new Intl.Segmenter().segment(string)[Symbol.iterator](); + } +} + +export function pop_grapheme(string) { + let first; + const iterator = graphemes_iterator(string); + if (iterator) { + first = iterator.next().value?.segment; + } else { + first = string.match(/./su)?.[0]; + } + if (first) { + return new Ok([first, string.slice(first.length)]); + } else { + return new Error(Nil); + } +} + +export function lowercase(string) { + return string.toLowerCase(); +} + +export function uppercase(string) { + return string.toUpperCase(); +} + +export function less_than(a, b) { + return a < b; +} + +export function add(a, b) { + return a + b; +} + +export function equal(a, b) { + return a === b; +} + +export function split(xs, pattern) { + return List.fromArray(xs.split(pattern)); +} + +export function join(xs, separator) { + const iterator = xs[Symbol.iterator](); + let result = iterator.next().value || ""; + let current = iterator.next(); + while (!current.done) { + result = result + separator + current.value; + current = iterator.next(); + } + return result; +} + +export function concat(xs) { + let result = ""; + for (const x of xs) { + result = result + x; + } + return result; +} + +export function length(data) { + return data.length; +} + +export function crop_string(string, substring) { + return string.substring(string.indexOf(substring)); +} + +export function contains_string(haystack, needle) { + return haystack.indexOf(needle) >= 0; +} + +export function starts_with(haystack, needle) { + return haystack.startsWith(needle); +} + +export function ends_with(haystack, needle) { + return haystack.endsWith(needle); +} + +export function split_once(haystack, needle) { + const index = haystack.indexOf(needle); + if (index >= 0) { + const before = haystack.slice(0, index); + const after = haystack.slice(index + needle.length); + return new Ok([before, after]); + } else { + return new Error(Nil); + } +} + +export function trim(string) { + return string.trim(); +} + +export function trim_left(string) { + return string.trimLeft(); +} + +export function trim_right(string) { + return string.trimRight(); +} + +export function bit_array_from_string(string) { + return toBitArray([stringBits(string)]); +} + +export function bit_array_concat(bit_arrays) { + return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); +} + +export function console_log(term) { + console.log(term); +} + +export function console_error(term) { + console.error(term); +} + +export function crash(message) { + throw new globalThis.Error(message); +} + +export function bit_array_to_string(bit_array) { + try { + const decoder = new TextDecoder("utf-8", { fatal: true }); + return new Ok(decoder.decode(bit_array.buffer)); + } catch (_error) { + return new Error(Nil); + } +} + +export function print(string) { + if (typeof process === "object") { + process.stdout.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.log(string); // We're in a browser. Newlines are mandated + } +} + +export function print_error(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.error(string); // We're in a browser. Newlines are mandated + } +} + +export function print_debug(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` + } else { + console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) + } +} + +export function ceiling(float) { + return Math.ceil(float); +} + +export function floor(float) { + return Math.floor(float); +} + +export function round(float) { + return Math.round(float); +} + +export function truncate(float) { + return Math.trunc(float); +} + +export function power(base, exponent) { + // It is checked in Gleam that: + // - The base is non-negative and that the exponent is not fractional. + // - The base is non-zero and the exponent is non-negative (otherwise + // the result will essentially be division by zero). + // It can thus be assumed that valid input is passed to the Math.pow + // function and a NaN or Infinity value will not be produced. + return Math.pow(base, exponent); +} + +export function random_uniform() { + const random_uniform_result = Math.random(); + // With round-to-nearest-even behavior, the ranges claimed for the functions below + // (excluding the one for Math.random() itself) aren't exact. + // If extremely large bounds are chosen (2^53 or higher), + // it's possible in extremely rare cases to calculate the usually-excluded upper bound. + // Note that as numbers in JavaScript are IEEE 754 floating point numbers + // See: + // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: + if (random_uniform_result === 1.0) { + return random_uniform(); + } + return random_uniform_result; +} + +export function bit_array_slice(bits, position, length) { + const start = Math.min(position, position + length); + const end = Math.max(position, position + length); + if (start < 0 || end > bits.length) return new Error(Nil); + const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); + return new Ok(new BitArray(buffer)); +} + +export function codepoint(int) { + return new UtfCodepoint(int); +} + +export function string_to_codepoint_integer_list(string) { + return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); +} + +export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { + return utf_codepoint_integer_list + .toArray() + .map((x) => String.fromCodePoint(x.value)) + .join(""); +} + +export function utf_codepoint_to_int(utf_codepoint) { + return utf_codepoint.value; +} + +export function regex_check(regex, string) { + regex.lastIndex = 0; + return regex.test(string); +} + +export function compile_regex(pattern, options) { + try { + let flags = "gu"; + if (options.case_insensitive) flags += "i"; + if (options.multi_line) flags += "m"; + return new Ok(new RegExp(pattern, flags)); + } catch (error) { + const number = (error.columnNumber || 0) | 0; + return new Error(new RegexCompileError(error.message, number)); + } +} + +export function regex_scan(regex, string) { + const matches = Array.from(string.matchAll(regex)).map((match) => { + const content = match[0]; + const submatches = []; + for (let n = match.length - 1; n > 0; n--) { + if (match[n]) { + submatches[n - 1] = new Some(match[n]); + continue; + } + if (submatches.length > 0) { + submatches[n - 1] = new None(); + } + } + return new RegexMatch(content, List.fromArray(submatches)); + }); + return List.fromArray(matches); +} + +export function new_map() { + return Dict.new(); +} + +export function map_size(map) { + return map.size; +} + +export function map_to_list(map) { + return List.fromArray(map.entries()); +} + +export function map_remove(key, map) { + return map.delete(key); +} + +export function map_get(map, key) { + const value = map.get(key, NOT_FOUND); + if (value === NOT_FOUND) { + return new Error(Nil); + } + return new Ok(value); +} + +export function map_insert(key, value, map) { + return map.set(key, value); +} + +function unsafe_percent_decode(string) { + return decodeURIComponent((string || "").replace("+", " ")); +} + +export function percent_decode(string) { + try { + return new Ok(unsafe_percent_decode(string)); + } catch (_error) { + return new Error(Nil); + } +} + +export function percent_encode(string) { + return encodeURIComponent(string); +} + +export function parse_query(query) { + try { + const pairs = []; + for (const section of query.split("&")) { + const [key, value] = section.split("="); + if (!key) continue; + pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); + } + return new Ok(List.fromArray(pairs)); + } catch (_error) { + return new Error(Nil); + } +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function encode64(bit_array) { + const aBytes = bit_array.buffer; + let nMod3 = 2; + let sB64Enc = ""; + + for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { + nMod3 = nIdx % 3; + if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { + sB64Enc += "\r\n"; + } + nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); + if (nMod3 === 2 || aBytes.length - nIdx === 1) { + sB64Enc += String.fromCharCode( + uint6ToB64((nUint24 >>> 18) & 63), + uint6ToB64((nUint24 >>> 12) & 63), + uint6ToB64((nUint24 >>> 6) & 63), + uint6ToB64(nUint24 & 63) + ); + nUint24 = 0; + } + } + + return ( + sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + + (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") + ); +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function uint6ToB64(nUint6) { + return nUint6 < 26 + ? nUint6 + 65 + : nUint6 < 52 + ? nUint6 + 71 + : nUint6 < 62 + ? nUint6 - 4 + : nUint6 === 62 + ? 43 + : nUint6 === 63 + ? 47 + : 65; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function b64ToUint6(nChr) { + return nChr > 64 && nChr < 91 + ? nChr - 65 + : nChr > 96 && nChr < 123 + ? nChr - 71 + : nChr > 47 && nChr < 58 + ? nChr + 4 + : nChr === 43 + ? 62 + : nChr === 47 + ? 63 + : 0; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function decode64(sBase64) { + if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); + const sB64Enc = sBase64.replace(/=/g, ""); + const nInLen = sB64Enc.length; + const nOutLen = (nInLen * 3 + 1) >> 2; + const taBytes = new Uint8Array(nOutLen); + + for ( + let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; + nInIdx < nInLen; + nInIdx++ + ) { + nMod4 = nInIdx & 3; + nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); + if (nMod4 === 3 || nInLen - nInIdx === 1) { + for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { + taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; + } + nUint24 = 0; + } + } + + return new Ok(new BitArray(taBytes)); +} + +export function classify_dynamic(data) { + if (typeof data === "string") { + return "String"; + } else if (data instanceof Result) { + return "Result"; + } else if (data instanceof List) { + return "List"; + } else if (data instanceof BitArray) { + return "BitArray"; + } else if (data instanceof Dict) { + return "Map"; + } else if (Number.isInteger(data)) { + return "Int"; + } else if (Array.isArray(data)) { + return `Tuple of ${data.length} elements`; + } else if (typeof data === "number") { + return "Float"; + } else if (data === null) { + return "Null"; + } else if (data === undefined) { + return "Nil"; + } else { + const type = typeof data; + return type.charAt(0).toUpperCase() + type.slice(1); + } +} + +function decoder_error(expected, got) { + return decoder_error_no_classify(expected, classify_dynamic(got)); +} + +function decoder_error_no_classify(expected, got) { + return new Error( + List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) + ); +} + +export function decode_string(data) { + return typeof data === "string" + ? new Ok(data) + : decoder_error("String", data); +} + +export function decode_int(data) { + return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); +} + +export function decode_float(data) { + return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); +} + +export function decode_bool(data) { + return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); +} + +export function decode_bit_array(data) { + if (data instanceof BitArray) { + return new Ok(data); + } + if (data instanceof Uint8Array) { + return new Ok(new BitArray(data)); + } + return decoder_error("BitArray", data); +} + +export function decode_tuple(data) { + return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); +} + +export function decode_tuple2(data) { + return decode_tupleN(data, 2); +} + +export function decode_tuple3(data) { + return decode_tupleN(data, 3); +} + +export function decode_tuple4(data) { + return decode_tupleN(data, 4); +} + +export function decode_tuple5(data) { + return decode_tupleN(data, 5); +} + +export function decode_tuple6(data) { + return decode_tupleN(data, 6); +} + +function decode_tupleN(data, n) { + if (Array.isArray(data) && data.length == n) { + return new Ok(data); + } + + const list = decode_exact_length_list(data, n); + if (list) return new Ok(list); + + return decoder_error(`Tuple of ${n} elements`, data); +} + +function decode_exact_length_list(data, n) { + if (!(data instanceof List)) return; + + const elements = []; + let current = data; + + for (let i = 0; i < n; i++) { + if (!(current instanceof NonEmpty)) break; + elements.push(current.head); + current = current.tail; + } + + if (elements.length === n && !(current instanceof NonEmpty)) return elements; +} + +export function tuple_get(data, index) { + return index >= 0 && data.length > index + ? new Ok(data[index]) + : new Error(Nil); +} + +export function decode_list(data) { + if (Array.isArray(data)) { + return new Ok(List.fromArray(data)); + } + return data instanceof List ? new Ok(data) : decoder_error("List", data); +} + +export function decode_result(data) { + return data instanceof Result ? new Ok(data) : decoder_error("Result", data); +} + +export function decode_map(data) { + if (data instanceof Dict) { + return new Ok(Dict.fromMap(data)); + } + if (data == null) { + return decoder_error("Map", data); + } + if (typeof data !== "object") { + return decoder_error("Map", data); + } + const proto = Object.getPrototypeOf(data); + if (proto === Object.prototype || proto === null) { + return new Ok(Dict.fromObject(data)); + } + return decoder_error("Map", data); +} + +export function decode_option(data, decoder) { + if (data === null || data === undefined || data instanceof None) + return new Ok(new None()); + if (data instanceof Some) data = data[0]; + const result = decoder(data); + if (result.isOk()) { + return new Ok(new Some(result[0])); + } else { + return result; + } +} + +export function decode_field(value, name) { + const not_a_map_error = () => decoder_error("Map", value); + + if ( + value instanceof Dict || + value instanceof WeakMap || + value instanceof Map + ) { + const entry = map_get(value, name); + return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); + } else if (Object.getPrototypeOf(value) == Object.prototype) { + return try_get_field(value, name, () => new Ok(new None())); + } else { + return try_get_field(value, name, not_a_map_error); + } +} + +function try_get_field(value, field, or_else) { + try { + return field in value ? new Ok(new Some(value[field])) : or_else(); + } catch { + return or_else(); + } +} + +export function byte_size(string) { + return new TextEncoder().encode(string).length; +} + +// In Javascript bitwise operations convert numbers to a sequence of 32 bits +// while Erlang uses arbitrary precision. +// To get around this problem and get consistent results use BigInt and then +// downcast the value back to a Number value. + +export function bitwise_and(x, y) { + return Number(BigInt(x) & BigInt(y)); +} + +export function bitwise_not(x) { + return Number(~BigInt(x)); +} + +export function bitwise_or(x, y) { + return Number(BigInt(x) | BigInt(y)); +} + +export function bitwise_exclusive_or(x, y) { + return Number(BigInt(x) ^ BigInt(y)); +} + +export function bitwise_shift_left(x, y) { + return Number(BigInt(x) << BigInt(y)); +} + +export function bitwise_shift_right(x, y) { + return Number(BigInt(x) >> BigInt(y)); +} + +export function inspect(v) { + const t = typeof v; + if (v === true) return "True"; + if (v === false) return "False"; + if (v === null) return "//js(null)"; + if (v === undefined) return "Nil"; + if (t === "string") return JSON.stringify(v); + if (t === "bigint" || t === "number") return v.toString(); + if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; + if (v instanceof List) return inspectList(v); + if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); + if (v instanceof BitArray) return inspectBitArray(v); + if (v instanceof CustomType) return inspectCustomType(v); + if (v instanceof Dict) return inspectDict(v); + if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; + if (v instanceof RegExp) return `//js(${v})`; + if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; + if (v instanceof Function) { + const args = []; + for (const i of Array(v.length).keys()) + args.push(String.fromCharCode(i + 97)); + return `//fn(${args.join(", ")}) { ... }`; + } + return inspectObject(v); +} + +function inspectDict(map) { + let body = "dict.from_list(["; + let first = true; + map.forEach((value, key) => { + if (!first) body = body + ", "; + body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; + first = false; + }); + return body + "])"; +} + +function inspectObject(v) { + const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; + const props = []; + for (const k of Object.keys(v)) { + props.push(`${inspect(k)}: ${inspect(v[k])}`); + } + const body = props.length ? " " + props.join(", ") + " " : ""; + const head = name === "Object" ? "" : name + " "; + return `//js(${head}{${body}})`; +} + +function inspectCustomType(record) { + const props = Object.keys(record) + .map((label) => { + const value = inspect(record[label]); + return isNaN(parseInt(label)) ? `${label}: ${value}` : value; + }) + .join(", "); + return props + ? `${record.constructor.name}(${props})` + : record.constructor.name; +} + +export function inspectList(list) { + return `[${list.toArray().map(inspect).join(", ")}]`; +} + +export function inspectBitArray(bits) { + return `<<${Array.from(bits.buffer).join(", ")}>>`; +} + +export function inspectUtfCodepoint(codepoint) { + return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; +} + +export function base16_encode(bit_array) { + let result = ""; + for (const byte of bit_array.buffer) { + result += byte.toString(16).padStart(2, "0").toUpperCase(); + } + return result; +} + +export function base16_decode(string) { + const bytes = new Uint8Array(string.length / 2); + for (let i = 0; i < string.length; i += 2) { + const a = parseInt(string[i], 16); + const b = parseInt(string[i + 1], 16); + if (isNaN(a) || isNaN(b)) return new Error(Nil); + bytes[i / 2] = a * 16 + b; + } + return new Ok(new BitArray(bytes)); +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE new file mode 100644 index 00000000000..c7967c32d6f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2021, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md new file mode 100644 index 00000000000..3ca1c63e98d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md @@ -0,0 +1,52 @@ +# gleeunit + +Gleam bindings to the Erlang EUnit test framework. + +A custom test runner is included for when compiled to JavaScript running on +either NodeJS or Deno. + +Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). + +## Usage + +Add this package to your Gleam project. + +```sh +gleam add gleeunit --dev +``` + +And then call the `gleeunit.main` function from your test main function. + +```gleam +// In test/yourapp_test.gleam +import gleeunit + +pub fn main() { + gleeunit.main() +} +``` + +Now any public function with a name ending in `_test` in the `test` directory +will be found and run as a test. + +```gleam +pub fn the_universe_test() { + let assert 1 = 1 +} +``` + +Run the tests by entering `gleam test` in the command line. + +### Deno + +If using the Deno JavaScript runtime, you will need to add the following to your +`gleam.toml`. + +```toml +[javascript.deno] +allow_read = [ + "gleam.toml", + "test", + "build", +] +``` diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml new file mode 100644 index 00000000000..74b7e202e47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml @@ -0,0 +1,17 @@ +name = "gleeunit" +version = "0.11.0" +licences = ["Apache-2.0"] +description = "Gleam bindings to Erlang's EUnit test framework" + +[javascript.deno] +allow_read = [ + "gleam.toml", + "test", + "build", +] + +[dependencies] +gleam_stdlib = "~> 0.27" + +[dev-dependencies] +# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src new file mode 100644 index 00000000000..2f98842c95e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src @@ -0,0 +1,8 @@ +{application, gleeunit, [ + {vsn, "0.11.0"}, + {applications, [gleam_stdlib]}, + {description, "Gleam bindings to Erlang's EUnit test framework"}, + {modules, [gleeunit, + gleeunit@should]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl new file mode 100644 index 00000000000..32e1a833d01 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl @@ -0,0 +1,59 @@ +-module(gleeunit). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([main/0]). +-export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). + +-type atom_() :: any(). + +-type encoding() :: utf8. + +-type report_module_name() :: gleeunit_progress. + +-type gleeunit_progress_option() :: {colored, boolean()}. + +-type eunit_option() :: verbose | + no_tty | + {report, {report_module_name(), list(gleeunit_progress_option())}}. + +-spec gleam_to_erlang_module_name(binary()) -> binary(). +gleam_to_erlang_module_name(Path) -> + _pipe = Path, + _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), + _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), + gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). + +-spec do_main() -> nil. +do_main() -> + Options = [verbose, + no_tty, + {report, {gleeunit_progress, [{colored, true}]}}], + Result = begin + _pipe = gleeunit_ffi:find_files( + <<"**/*.{erl,gleam}"/utf8>>, + <<"test"/utf8>> + ), + _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), + _pipe@2 = gleam@list:map( + _pipe@1, + fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end + ), + _pipe@3 = eunit:test(_pipe@2, Options), + _pipe@4 = (gleam@dynamic:result( + fun gleam@dynamic:dynamic/1, + fun gleam@dynamic:dynamic/1 + ))(_pipe@3), + gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) + end, + Code = case Result of + {ok, _} -> + 0; + + {error, _} -> + 1 + end, + erlang:halt(Code). + +-spec main() -> nil. +main() -> + do_main(). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam new file mode 100644 index 00000000000..e5d4b460cad --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam @@ -0,0 +1,92 @@ +/// Find and run all test functions for the current project using Erlang's EUnit +/// test framework. +/// +/// Any Erlang or Gleam function in the `test` directory with a name editing in +/// `_test` is considered a test function and will be run. +/// +/// If running on JavaScript tests will be run with a custom test runner. +/// +pub fn main() -> Nil { + do_main() +} + +@target(javascript) +@external(javascript, "./gleeunit_ffi.mjs", "main") +fn do_main() -> Nil + +@target(erlang) +import gleam/list +@target(erlang) +import gleam/result +@target(erlang) +import gleam/string +@target(erlang) +import gleam/dynamic.{Dynamic} + +@target(erlang) +fn do_main() -> Nil { + let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] + + let result = + find_files(matching: "**/*.{erl,gleam}", in: "test") + |> list.map(gleam_to_erlang_module_name) + |> list.map(dangerously_convert_string_to_atom(_, Utf8)) + |> run_eunit(options) + |> dynamic.result(dynamic.dynamic, dynamic.dynamic) + |> result.unwrap(Error(dynamic.from(Nil))) + + let code = case result { + Ok(_) -> 0 + Error(_) -> 1 + } + halt(code) +} + +@target(erlang) +@external(erlang, "erlang", "halt") +fn halt(a: Int) -> Nil + +@target(erlang) +fn gleam_to_erlang_module_name(path: String) -> String { + path + |> string.replace(".gleam", "") + |> string.replace(".erl", "") + |> string.replace("/", "@") +} + +@target(erlang) +@external(erlang, "gleeunit_ffi", "find_files") +fn find_files(matching matching: String, in in: String) -> List(String) + +@target(erlang) +type Atom + +@target(erlang) +type Encoding { + Utf8 +} + +@target(erlang) +@external(erlang, "erlang", "binary_to_atom") +fn dangerously_convert_string_to_atom(a: String, b: Encoding) -> Atom + +@target(erlang) +type ReportModuleName { + GleeunitProgress +} + +@target(erlang) +type GleeunitProgressOption { + Colored(Bool) +} + +@target(erlang) +type EunitOption { + Verbose + NoTty + Report(#(ReportModuleName, List(GleeunitProgressOption))) +} + +@target(erlang) +@external(erlang, "eunit", "test") +fn run_eunit(a: List(Atom), b: List(EunitOption)) -> Dynamic diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam new file mode 100644 index 00000000000..c393c232724 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam @@ -0,0 +1,90 @@ +//// A module for testing your Gleam code. The functions found here are +//// compatible with the Erlang eunit test framework. +//// +//// More information on running eunit can be found in [the rebar3 +//// documentation](https://rebar3.org/docs/testing/eunit/). + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_equal") +pub fn equal(a: a, b: a) -> Nil + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_not_equal") +pub fn not_equal(a: a, b: a) -> Nil + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_be_ok") +pub fn be_ok(a: Result(a, b)) -> a + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_be_error") +pub fn be_error(a: Result(a, b)) -> b + +@target(javascript) +import gleam/string + +@target(javascript) +@external(javascript, "../gleam.mjs", "inspect") +fn stringify(a: anything) -> String + +@target(javascript) +@external(javascript, "../gleeunit_ffi.mjs", "crash") +fn crash(a: String) -> anything + +@target(javascript) +pub fn equal(a, b) { + case a == b { + True -> Nil + _ -> + crash(string.concat([ + "\n\t", + stringify(a), + "\n\tshould equal \n\t", + stringify(b), + ])) + } +} + +@target(javascript) +pub fn not_equal(a, b) { + case a != b { + True -> Nil + _ -> + crash(string.concat([ + "\n", + stringify(a), + "\nshould not equal \n", + stringify(b), + ])) + } +} + +@target(javascript) +pub fn be_ok(a) { + case a { + Ok(value) -> value + _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) + } +} + +@target(javascript) +pub fn be_error(a) { + case a { + Error(error) -> error + _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) + } +} + +pub fn be_true(actual: Bool) -> Nil { + actual + |> equal(True) +} + +pub fn be_false(actual: Bool) -> Nil { + actual + |> equal(False) +} + +pub fn fail() -> Nil { + be_true(False) +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl new file mode 100644 index 00000000000..acf032e1e7d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl @@ -0,0 +1,34 @@ +-module(gleeunit@should). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). + +-spec equal(EYG, EYG) -> nil. +equal(A, B) -> + gleeunit_ffi:should_equal(A, B). + +-spec not_equal(EYH, EYH) -> nil. +not_equal(A, B) -> + gleeunit_ffi:should_not_equal(A, B). + +-spec be_ok({ok, EYI} | {error, any()}) -> EYI. +be_ok(A) -> + gleeunit_ffi:should_be_ok(A). + +-spec be_error({ok, any()} | {error, EYN}) -> EYN. +be_error(A) -> + gleeunit_ffi:should_be_error(A). + +-spec be_true(boolean()) -> nil. +be_true(Actual) -> + _pipe = Actual, + gleeunit_ffi:should_equal(_pipe, true). + +-spec be_false(boolean()) -> nil. +be_false(Actual) -> + _pipe = Actual, + gleeunit_ffi:should_equal(_pipe, false). + +-spec fail() -> nil. +fail() -> + be_true(false). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl new file mode 100644 index 00000000000..31f9ef9e2c9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl @@ -0,0 +1,24 @@ +-module(gleeunit_ffi). + +-export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, + should_be_error/1]). + +-include_lib("eunit/include/eunit.hrl"). + +find_files(Pattern, In) -> + Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), + lists:map(fun list_to_binary/1, Results). + + +should_equal(Actual, Expected) -> + ?assertEqual(Expected, Actual), + nil. +should_not_equal(Actual, Expected) -> + ?assertNotEqual(Expected, Actual), + nil. +should_be_ok(A) -> + ?assertMatch({ok, _}, A), + element(2, A). +should_be_error(A) -> + ?assertMatch({error, _}, A), + element(2, A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs new file mode 100644 index 00000000000..339a843e5c5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs @@ -0,0 +1,101 @@ +async function* gleamFiles(directory) { + for (let entry of await read_dir(directory)) { + let path = join_path(directory, entry); + if (path.endsWith(".gleam")) { + yield path; + } else { + try { + yield* gleamFiles(path); + } catch (error) { + // Could not read directory, assume it's a file + } + } + } +} + +async function readRootPackageName() { + let toml = await read_file("gleam.toml", "utf-8"); + for (let line of toml.split("\n")) { + let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() + if (matches) return matches[1]; + } + throw new Error("Could not determine package name from gleam.toml"); +} + +export async function main() { + let passes = 0; + let failures = 0; + + let packageName = await readRootPackageName(); + let dist = `../${packageName}/`; + + for await (let path of await gleamFiles("test")) { + let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); + let module = await import(join_path(dist, js_path)); + for (let fnName of Object.keys(module)) { + if (!fnName.endsWith("_test")) continue; + try { + await module[fnName](); + write(`\u001b[32m.\u001b[0m`); + passes++; + } catch (error) { + let moduleName = "\n" + js_path.slice(0, -4); + let line = error.line ? `:${error.line}` : ""; + write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); + failures++; + } + } + } + + console.log(` +${passes + failures} tests, ${failures} failures`); + exit(failures ? 1 : 0); +} + +export function crash(message) { + throw new Error(message); +} + +function write(message) { + if (globalThis.Deno) { + Deno.stdout.writeSync(new TextEncoder().encode(message)); + } else { + process.stdout.write(message); + } +} + +function exit(code) { + if (globalThis.Deno) { + Deno.exit(code); + } else { + process.exit(code); + } +} + +async function read_dir(path) { + if (globalThis.Deno) { + let items = []; + for await (let item of Deno.readDir(path, { withFileTypes: true })) { + items.push(item.name); + } + return items; + } else { + let { readdir } = await import("fs/promises"); + return readdir(path); + } +} + +function join_path(a, b) { + if (a.endsWith("/")) return a + b; + return a + "/" + b; +} + +async function read_file(path) { + if (globalThis.Deno) { + return Deno.readTextFile(path); + } else { + let { readFile } = await import("fs/promises"); + let contents = await readFile(path); + return contents.toString(); + } +} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl new file mode 100644 index 00000000000..1f68eb95e58 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl @@ -0,0 +1,607 @@ +%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters + +%% @doc A listener/reporter for eunit that prints '.' for each +%% success, 'F' for each failure, and 'E' for each error. It can also +%% optionally summarize the failures at the end. +-compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). +-module(gleeunit_progress). +-behaviour(eunit_listener). +-define(NOTEST, true). +-include_lib("eunit/include/eunit.hrl"). + +-define(RED, "\e[0;31m"). +-define(GREEN, "\e[0;32m"). +-define(YELLOW, "\e[0;33m"). +-define(WHITE, "\e[0;37m"). +-define(CYAN, "\e[0;36m"). +-define(RESET, "\e[0m"). + +-record(node,{ + rank = 0 :: non_neg_integer(), + key :: term(), + value :: term(), + children = new() :: binomial_heap() + }). + +-export_type([binomial_heap/0, heap_node/0]). +-type binomial_heap() :: [ heap_node() ]. +-type heap_node() :: #node{}. + +%% eunit_listener callbacks +-export([ + init/1, + handle_begin/3, + handle_end/3, + handle_cancel/3, + terminate/2, + start/0, + start/1 + ]). + +%% -- binomial_heap.erl content start -- + +-record(state, { + status = dict:new() :: euf_dict(), + failures = [] :: [[pos_integer()]], + skips = [] :: [[pos_integer()]], + timings = new() :: binomial_heap(), + colored = true :: boolean(), + profile = false :: boolean() + }). + +-type euf_dict() :: dict:dict(). + +-spec new() -> binomial_heap(). +new() -> + []. + +% Inserts a new pair into the heap (or creates a new heap) +-spec insert(term(), term()) -> binomial_heap(). +insert(Key,Value) -> + insert(Key,Value,[]). + +-spec insert(term(), term(), binomial_heap()) -> binomial_heap(). +insert(Key,Value,Forest) -> + insTree(#node{key=Key,value=Value},Forest). + +% Merges two heaps +-spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). +merge(TS1,[]) when is_list(TS1) -> TS1; +merge([],TS2) when is_list(TS2) -> TS2; +merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> + if + R1 < R2 -> + [T1 | merge(TS1,F2)]; + R2 < R1 -> + [T2 | merge(F1, TS2)]; + true -> + insTree(link(T1,T2),merge(TS1,TS2)) + end. + +% Deletes the top entry from the heap and returns it +-spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. +delete(TS) -> + {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), + {{Key,Value},merge(lists:reverse(TS1),TS2)}. + +% Turns the heap into list in heap order +-spec to_list(binomial_heap()) -> [{term(), term()}]. +to_list([]) -> []; +to_list(List) when is_list(List) -> + to_list([],List). +to_list(Acc, []) -> + lists:reverse(Acc); +to_list(Acc,Forest) -> + {Next, Trees} = delete(Forest), + to_list([Next|Acc], Trees). + +% Take N elements from the top of the heap +-spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. +take(N,Trees) when is_integer(N), is_list(Trees) -> + take(N,Trees,[]). +take(0,_Trees,Acc) -> + lists:reverse(Acc); +take(_N,[],Acc)-> + lists:reverse(Acc); +take(N,Trees,Acc) -> + {Top,T2} = delete(Trees), + take(N-1,T2,[Top|Acc]). + +% Get an estimate of the size based on the binomial property +-spec size(binomial_heap()) -> non_neg_integer(). +size(Forest) -> + erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). + +%% Private API +-spec link(heap_node(), heap_node()) -> heap_node(). +link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> + case X1 < X2 of + true -> + T1#node{rank=R+1,children=[T2|C1]}; + _ -> + T2#node{rank=R+1,children=[T1|C2]} + end. + +insTree(Tree, []) -> + [Tree]; +insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> + case R1 < R2 of + true -> + [T1|TS]; + _ -> + insTree(link(T1,T2),Rest) + end. + +getMin([T]) -> + {T,[]}; +getMin([#node{key=K} = T|TS]) -> + {#node{key=K1} = T1,TS1} = getMin(TS), + case K < K1 of + true -> {T,TS}; + _ -> {T1,[T|TS1]} + end. + +%% -- binomial_heap.erl content end -- + +%% Startup +start() -> + start([]). + +start(Options) -> + eunit_listener:start(?MODULE, Options). + +%%------------------------------------------ +%% eunit_listener callbacks +%%------------------------------------------ +init(Options) -> + #state{colored=proplists:get_bool(colored, Options), + profile=proplists:get_bool(profile, Options)}. + +handle_begin(group, Data, St) -> + GID = proplists:get_value(id, Data), + Dict = St#state.status, + St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; +handle_begin(test, Data, St) -> + TID = proplists:get_value(id, Data), + Dict = St#state.status, + St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. + +handle_end(group, Data, St) -> + St#state{status=merge_on_end(Data, St#state.status)}; +handle_end(test, Data, St) -> + NewStatus = merge_on_end(Data, St#state.status), + St1 = print_progress(Data, St), + St2 = record_timing(Data, St1), + St2#state{status=NewStatus}. + +handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> + Status1 = merge_on_end(Data, Status), + ID = proplists:get_value(id, Data), + St#state{status=Status1, skips=[ID|Skips]}. + +terminate({ok, Data}, St) -> + print_failures(St), + print_pending(St), + print_profile(St), + print_timing(St), + print_results(Data, St); +terminate({error, Reason}, St) -> + io:nl(), io:nl(), + print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), + sync_end(error). + +sync_end(Result) -> + receive + {stop, Reference, ReplyTo} -> + ReplyTo ! {result, Reference, Result}, + ok + end. + +%%------------------------------------------ +%% Print and collect information during run +%%------------------------------------------ +print_progress(Data, St) -> + TID = proplists:get_value(id, Data), + case proplists:get_value(status, Data) of + ok -> + print_progress_success(St), + St; + {skipped, _Reason} -> + print_progress_skipped(St), + St#state{skips=[TID|St#state.skips]}; + {error, Exception} -> + print_progress_failed(Exception, St), + St#state{failures=[TID|St#state.failures]} + end. + +record_timing(Data, State=#state{timings=T, profile=true}) -> + TID = proplists:get_value(id, Data), + case lists:keyfind(time, 1, Data) of + {time, Int} -> + %% It's a min-heap, so we insert negative numbers instead + %% of the actuals and normalize when we report on them. + T1 = insert(-Int, TID, T), + State#state{timings=T1}; + false -> + State + end; +record_timing(_Data, State) -> + State. + +print_progress_success(St) -> + print_colored(".", ?GREEN, St). + +print_progress_skipped(St) -> + print_colored("*", ?YELLOW, St). + +print_progress_failed(_Exc, St) -> + print_colored("F", ?RED, St). + +merge_on_end(Data, Dict) -> + ID = proplists:get_value(id, Data), + dict:update(ID, + fun(Old) -> + orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) + end, Dict). + +merge_data(_K, undefined, X) -> X; +merge_data(_K, X, undefined) -> X; +merge_data(_K, _, X) -> X. + +%%------------------------------------------ +%% Print information at end of run +%%------------------------------------------ +print_failures(#state{failures=[]}) -> + ok; +print_failures(#state{failures=Fails}=State) -> + io:nl(), + io:fwrite("Failures:~n",[]), + lists:foldr(print_failure_fun(State), 1, Fails), + ok. + +print_failure_fun(#state{status=Status}=State) -> + fun(Key, Count) -> + TestData = dict:fetch(Key, Status), + TestId = format_test_identifier(TestData), + io:fwrite("~n ~p) ~ts~n", [Count, TestId]), + print_failure_reason(proplists:get_value(status, TestData), + proplists:get_value(output, TestData), + State), + io:nl(), + Count + 1 + end. + +print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> + X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), + print_colored(X, ?CYAN, State); +print_gleam_location(_, _) -> + ok. + +inspect(X) -> + gleam@string:inspect(X). + +print_gleam_failure_reason( + #{gleam_error := assert, message := Message, value := Value}, + State +) -> + print_colored(indent(5, "~s~n", [Message]), ?RED, State), + print_colored(indent(5, " value: ", []), ?RED, State), + print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); +print_gleam_failure_reason( + #{gleam_error := todo, message := Message}, + State +) -> + print_colored(indent(5, "todo expression run~n", []), ?RED, State), + print_colored(indent(5, " message: ", []), ?RED, State), + print_colored(indent(0, "~s~n", [Message]), ?RESET, State); +print_gleam_failure_reason(Error, State) -> + print_colored(indent(5, "~p~n", [Error]), ?RED, State). + +% New Gleeunit specific formatters +print_failure_reason( + {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State +) when is_list(Stack) -> + print_gleam_failure_reason(Error, State), + print_gleam_location(Error, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> + print_colored(indent(5, "No case clause matched~n", []), ?RED, State), + print_colored(indent(5, "Value: ", []), ?CYAN, State), + print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +% From the original Erlang version +print_failure_reason({skipped, Reason}, _Output, State) -> + print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), + ?RED, State); +print_failure_reason({error, {_Class, Term, _}}, Output, State) when + is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> + print_assertion_failure(Term, State), + print_failure_output(5, Output, State); +print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> + print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +print_failure_reason({error, Reason}, Output, State) -> + print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), + print_failure_output(5, Output, State). + +gleam_format_module_name(Module) -> + string:replace(atom_to_list(Module), "@", "/", all). + +print_stack(Stack, State) -> + print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), + print_stackframes(Stack, State). +print_stackframes([{eunit_test, _, _, _} | Stack], State) -> + print_stackframes(Stack, State); +print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> + print_stackframes(Stack, State); +print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> + GleamModule = gleam_format_module_name(Module), + print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), + print_stackframes(Stack, State); +print_stackframes([], _State) -> + ok. + + +print_failure_output(_, <<>>, _) -> ok; +print_failure_output(_, undefined, _) -> ok; +print_failure_output(Indent, Output, State) -> + print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). + +print_assertion_failure({Type, Props}, State) -> + FailureDesc = format_assertion_failure(Type, Props, 5), + print_colored(FailureDesc, ?RED, State), + io:nl(). + +print_pending(#state{skips=[]}) -> + ok; +print_pending(#state{status=Status, skips=Skips}=State) -> + io:nl(), + io:fwrite("Pending:~n", []), + lists:foreach(fun(ID) -> + Info = dict:fetch(ID, Status), + case proplists:get_value(reason, Info) of + undefined -> + ok; + Reason -> + print_pending_reason(Reason, Info, State) + end + end, lists:reverse(Skips)), + io:nl(). + +print_pending_reason(Reason0, Data, State) -> + Text = case proplists:get_value(type, Data) of + group -> + io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); + test -> + io_lib:format(" ~ts~n", [format_test_identifier(Data)]) + end, + Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), + print_colored(Text, ?YELLOW, State), + print_colored(Reason, ?CYAN, State). + +print_profile(#state{timings=T, status=Status, profile=true}=State) -> + TopN = take(10, T), + TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), + TLG = dict:fetch([], Status), + TotalTime = proplists:get_value(time, TLG), + if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> + TopNPct = (TopNTime / TotalTime) * 100, + io:nl(), io:nl(), + io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), + lists:foreach(print_timing_fun(State), TopN), + io:nl(); + true -> ok + end; +print_profile(#state{profile=false}) -> + ok. + +print_timing(#state{status=Status}) -> + TLG = dict:fetch([], Status), + Time = proplists:get_value(time, TLG), + io:nl(), + io:fwrite("Finished in ~ts~n", [format_time(Time)]), + ok. + +print_results(Data, State) -> + Pass = proplists:get_value(pass, Data, 0), + Fail = proplists:get_value(fail, Data, 0), + Skip = proplists:get_value(skip, Data, 0), + Cancel = proplists:get_value(cancel, Data, 0), + Total = Pass + Fail + Skip + Cancel, + {Color, Result} = if Fail > 0 -> {?RED, error}; + Skip > 0; Cancel > 0 -> {?YELLOW, error}; + Pass =:= 0 -> {?YELLOW, ok}; + true -> {?GREEN, ok} + end, + print_results(Color, Total, Fail, Skip, Cancel, State), + sync_end(Result). + +print_results(Color, 0, _, _, _, State) -> + print_colored(Color, "0 tests\n", State); +print_results(Color, Total, Fail, Skip, Cancel, State) -> + SkipText = format_optional_result(Skip, "skipped"), + CancelText = format_optional_result(Cancel, "cancelled"), + Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), + print_colored(Text, Color, State). + +print_timing_fun(#state{status=Status}=State) -> + fun({Time, Key}) -> + TestData = dict:fetch(Key, Status), + TestId = format_test_identifier(TestData), + io:nl(), + io:fwrite(" ~ts~n", [TestId]), + print_colored([" "|format_time(abs(Time))], ?CYAN, State) + end. + +%%------------------------------------------ +%% Print to the console with the given color +%% if enabled. +%%------------------------------------------ +print_colored(Text, Color, #state{colored=true}) -> + io:fwrite("~s~ts~s", [Color, Text, ?RESET]); +print_colored(Text, _Color, #state{colored=false}) -> + io:fwrite("~ts", [Text]). + +%%------------------------------------------ +%% Generic data formatters +%%------------------------------------------ +format_function_name(M, F) -> + M1 = gleam_format_module_name(M), + io_lib:format("~ts.~ts", [M1, F]). + +format_optional_result(0, _) -> + []; +format_optional_result(Count, Text) -> + io_lib:format(", ~p ~ts", [Count, Text]). + +format_test_identifier(Data) -> + {Mod, Fun, _} = proplists:get_value(source, Data), + Line = case proplists:get_value(line, Data) of + 0 -> ""; + L -> io_lib:format(":~p", [L]) + end, + Desc = case proplists:get_value(desc, Data) of + undefined -> ""; + DescText -> io_lib:format(": ~ts", [DescText]) + end, + io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). + +format_time(undefined) -> + "? seconds"; +format_time(Time) -> + io_lib:format("~.3f seconds", [Time / 1000]). + +format_pending_reason({module_not_found, M}) -> + M1 = gleam_format_module_name(M), + io_lib:format("Module '~ts' missing", [M1]); +format_pending_reason({no_such_function, {M,F,_}}) -> + M1 = gleam_format_module_name(M), + io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); +format_pending_reason({exit, Reason}) -> + io_lib:format("Related process exited with reason: ~p", [Reason]); +format_pending_reason(Reason) -> + io_lib:format("Unknown error: ~p", [Reason]). + +%% @doc Formats all the known eunit assertions, you're on your own if +%% you make an assertion yourself. +format_assertion_failure(Type, Props, I) when Type =:= assertion_failed + ; Type =:= assert -> + Keys = proplists:get_keys(Props), + HasEUnitProps = ([expression, value] -- Keys) =:= [], + HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], + if + HasEUnitProps -> + [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), + indent(I, " expected: true~n", []), + case proplists:get_value(value, Props) of + false -> + indent(I, " got: false", []); + {not_a_boolean, V} -> + indent(I, " got: ~p", [V]) + end]; + HasHamcrestProps -> + [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), + indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), + indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; + true -> + [indent(I, "Failure: unknown assert: ~p", [Props])] + end; + +format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed + ; Type =:= assertMatch -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + Value = proplists:get_value(value, Props), + [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), + indent(I, " expected: = ~ts~n", [Pattern]), + indent(I, " got: ~p", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed + ; Type =:= assertNotMatch -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + Value = proplists:get_value(value, Props), + [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), + indent(I, " expected not: = ~ts~n", [Pattern]), + indent(I, " got: ~p", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed + ; Type =:= assertEqual -> + Expected = inspect(proplists:get_value(expected, Props)), + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were not equal~n", []), + indent(I, "expected: ~ts~n", [Expected]), + indent(I, " got: ~ts", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed + ; Type =:= assertNotEqual -> + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were equal~n", []), + indent(I, "expected: not ~ts~n,", [Value]), + indent(I, " got: ~ts", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertException_failed + ; Type =:= assertException -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA + [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), + case proplists:is_defined(unexpected_success, Props) of + true -> + [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), + indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; + false -> + Ex = proplists:get_value(unexpected_exception, Props), + [indent(I, " expected: exception ~ts~n", [Pattern]), + indent(I, " got: exception ~p", [Ex])] + end]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed + ; Type =:= assertNotException -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT + Ex = proplists:get_value(unexpected_exception, Props), + [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), + indent(I, " expected not: exception ~ts~n", [Pattern]), + indent(I, " got: exception ~p", [Ex])]; + +format_assertion_failure(Type, Props, I) when Type =:= command_failed + ; Type =:= command -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_status, Props), + Status = proplists:get_value(status, Props), + [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: status ~p~n", [Expected]), + indent(I, " got: status ~p", [Status])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed + ; Type =:= assertCmd -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_status, Props), + Status = proplists:get_value(status, Props), + [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: status ~p~n", [Expected]), + indent(I, " got: status ~p", [Status])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed + ; Type =:= assertCmdOutput -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_output, Props), + Output = proplists:get_value(output, Props), + [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: ~p~n", [Expected]), + indent(I, " got: ~p", [Output])]; + +format_assertion_failure(Type, Props, I) -> + indent(I, "~p", [{Type, Props}]). + +indent(I, Fmt, Args) -> + io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). + +extract_exception_pattern(Str) -> + ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), + {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml new file mode 100644 index 00000000000..9e8e814435b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml @@ -0,0 +1,7 @@ +[packages] +gleam_community_ansi = "1.2.0" +gleam_otp = "0.8.0" +gleam_erlang = "0.23.1" +gleam_community_colour = "1.2.0" +gleam_stdlib = "0.33.1" +gleeunit = "0.11.0" diff --git a/test-community-packages-javascript/build/packages/glerm/gleam.toml b/test-community-packages-javascript/build/packages/glerm/gleam.toml new file mode 100644 index 00000000000..bcd667357ad --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/gleam.toml @@ -0,0 +1,17 @@ +name = "glerm" +version = "0.1.0" +description = "A terminal wrapper for Gleam" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +licences = ["Apache-2.0"] +repository = { type = "github", user = "rawhat", repo = "glerm" } + +[dependencies] +gleam_stdlib = "~> 0.28" +gleam_erlang = "~> 0.19" +gleam_otp = "~> 0.5" +gleam_community_ansi = "~> 1.1" + +[dev-dependencies] +gleeunit = "~> 0.7" diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl new file mode 100644 index 00000000000..b2b3067fe7d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl @@ -0,0 +1,4 @@ +-record(drag, { + button :: glerm:mouse_button(), + modifier :: gleam@option:option(glerm:modifier()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl new file mode 100644 index 00000000000..9342c911a37 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl @@ -0,0 +1 @@ +-record(focus, {event :: glerm:focus_event()}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl new file mode 100644 index 00000000000..293b9c94bc7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl @@ -0,0 +1,4 @@ +-record(key, { + key :: glerm:key_code(), + modifier :: gleam@option:option(glerm:modifier()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl new file mode 100644 index 00000000000..f7ab57fb003 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl @@ -0,0 +1,5 @@ +-record(listener_spec, { + init :: fun(() -> {any(), + gleam@option:option(gleam@erlang@process:selector(any()))}), + loop :: fun((glerm:listener_message(any()), any()) -> gleam@otp@actor:next(any())) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl new file mode 100644 index 00000000000..4d1e4b707da --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl @@ -0,0 +1 @@ +-record(mouse, {event :: glerm:mouse_event()}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl new file mode 100644 index 00000000000..858e2ae852d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl @@ -0,0 +1,4 @@ +-record(mouse_down, { + button :: glerm:mouse_button(), + modifier :: gleam@option:option(glerm:modifier()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl new file mode 100644 index 00000000000..62eefb79d0d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl @@ -0,0 +1,4 @@ +-record(mouse_up, { + button :: glerm:mouse_button(), + modifier :: gleam@option:option(glerm:modifier()) +}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl new file mode 100644 index 00000000000..b54f205f739 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl @@ -0,0 +1 @@ +-record(unknown, {tag :: binary(), message :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/glerm/manifest.toml b/test-community-packages-javascript/build/packages/glerm/manifest.toml new file mode 100644 index 00000000000..c6a2c505615 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/manifest.toml @@ -0,0 +1,18 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_community_ansi", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_colour"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8B5A9677BC5A2738712BBAF2BA289B1D8195FDF962BBC769569976AD5E9794E1" }, + { name = "gleam_community_colour", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "036C206886AFB9F153C552700A7A0B4D2864E3BC96A20C77E5F34A013C051BE3" }, + { name = "gleam_erlang", version = "0.23.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "C21CFB816C114784E669FFF4BBF433535EEA9960FA2F216209B8691E87156B96" }, + { name = "gleam_otp", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "18EF8242A5E54BA92F717C7222F03B3228AEE00D1F286D4C56C3E8C18AA2588E" }, + { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, + { name = "gleeunit", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "1397E5C4AC4108769EE979939AC39BF7870659C5AFB714630DEEEE16B8272AD5" }, +] + +[requirements] +gleam_community_ansi = { version = "~> 1.1" } +gleam_erlang = { version = "~> 0.19" } +gleam_otp = { version = "~> 0.5" } +gleam_stdlib = { version = "~> 0.28" } +gleeunit = { version = "~> 0.7" } diff --git a/test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so b/test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so new file mode 100755 index 0000000000000000000000000000000000000000..3a0e947838344eaf03b47dc7a9b0f7baa8fd0a94 GIT binary patch literal 4550752 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%0AR97K*PPR&ES6o#1ZAkNG| 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 *o3+j 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 z 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�@H&Q?GaSzN;F8X}9QZ|7pW9Gz&Cx@GUc=3d< z^FhJkMuQ=PV}kyKW`lFN$}cBeeYi2fK-HLFplVFeR5g=Tu`-Xe!7)L9ov^`~t&-N` z9>|`I4Nj>-Wo~GL69TotF~Pv#n4mT|CKk-YharO(RbAQK0&Q@%E6`(*4>xRZ_9#%K zr43F9)CR`{1GQ#?fm$;`-7Nobljjd@$l#C(1_r0DLPG{egCT=sf>pDixys*+JF91b z2?n#k1cO;%g61sfrHTz1922aX1!t?IRR-rNjLi884H=vX3Y4kAhZ{CHx0_XIgA)R^ z!7;&LWK1v^850bR%v@Dj$l!#)z~DThlD1>X^5KRJjs`;p#{~V6VT1FGS(P?8Cg_Wh z4bCensjPZgNOCVkp&^4qF{lu&B=f)oO0tNVDkWLU3AMqgU`8v+yf_%GBul^q28Yta zO0ocapd`zfF$~T!JjBXZ$l!!PZE#F5FgPX{7#tJS<0b~@MOB$>RkXobqd?I=e7IqQ z69NN+vr8pi$%Cm6H`(|l>p+$TU;HArlen@q=BV4MC!w_9E@WRQ)f9OQTlY?JAD3v83=coR_D zCfzFr0}W_`fd(`|y^{Wa#~Vf8F-9h^O{U{5uucCrINk!=GzkVrUx97sXcY?J9M z3fZPIRw3FpQKq3!^O*7VsW{%iiazDXSWB2;eJbz&Wr1OR%8#)YfDwHvjyEuR1J5^9 zvhkf8(Wm?vYY{WbHXU?V>%ZlA3v83=cnfTk>39=RY?CR=kZr2q9%)%-*EVEXz)Y1a zi@^r6EMrE?GP@2KEz2S>fh;S)n6k{PilV$ z+zqX*w~@|Ac>iUz!uHCpY2e+W{6peJjWt%i((?H z5QxH~h!}hkXmv~Y7Wur#9N9x2Nh5n_TRab){hn_}&cHvb-z)9obXtcvS?@*?ebidB zHbfex!FW<0$i62t-h3OLa#Gn?GWMpUQ-8zK`Ceh;1nV688dxERhuc|+-7uJZ61GR! z9TT(hTxbOt8M#m1htCJG{;mQ{9vC%pumBH&D+HnDL@WF+sIii3jM+63YrtTn$bQjI zh+J4hxb;&Kseje*Tyh!mjC9Gj;hB7IjhSFbOED%VDWc?w~MsVP5osBusC^QXkH8=~z`j zd#-3lmNz2_t2@s2yuE9!P{O*4T`zTO64<}37e5EzCmWzj_=-{E0RF}baDv}sc)#Hjr^qPcvTif zXFQ3F{hf3#btja2(@<%3qx(^s2})^FaqVzYzhV=tsyJIE<>`SorboFK9TeD*LG%WX zy_|<`=W%ncb($nDM%#**xzcTvwqgooz|7f=yeARf21CpjPrGJotb}(w1|kIRv$9f) z-VTF3_IdFU$=I?}xS-VGsP1=Fs()ThPhEk|hp^LdUwW7o!fL-9!NjHnUUH`jZsAq9 zx5l4$bFd?jlJUnq18?SC1+b9<;|!jO&!Bw>YZ?Nzo6-dN&?PSsnxJ-5nwVbfUX7_1 zwNZ7+eKD@up z&UKDkGw~VZn6U&5qw=79+gtM{rl^CAfjt0t%gC(jHPayfln|Gv-ym9=X3d>iUr zp->)T_k6de_XFw=f!cj&fh{Rtd6lY+wT^q9YF7y4T|FeiYNM1Je}mId z=HOXs#iw)5eokFk@D-dw>yiwp%0QP4QA?6nRiH~uuxd$msL_W9NZyaE0=R=bCgz2!C8T?kR(m8N|ISBX=n&du&Uw~Dyb5>ua!F~ zFpy+oEfgayLu=-uHO*inhNvXG3qgbHMr$R3ervh|y*!+>eY9f|=(lD9jMFtLDP--B z>qIDvDGHPwC))^*UDUG`x}1~Fcl_sXa=3~5=voLSaI2OwQ{`5z;Dp+(n(-7E?N%*h zM!QwZ!T8&5XtJEAgKc+$@8cDN58SGi%&4PlVge>j{xblcahk})>5fw$U($uU+`5T} zAkR`xG2P8h+c*U}jG2**ywwQzQmJ|P0=pIhwOunoZP!AWVb=z!QpK)a=i9XqrtF%D zX}gARC{V_;XyFXEj&x|KDojim+qI<-2p@9!3hbJ-&tTRQPz=!17&a43VY}8PDZ9371AsrFip@qnV%H|2SQC_D%TTNdO0j*C zvTM7R1-q8dveS002uxttO2KHmR>5Iq*ItA?GoC{(wre#Y$2?}VT`L3=*bxiv1io0! z1a`y(wcz|`;kg`b*J>MC{b%9Vpx(9$P4w@2(+uBxmK zSElV+2o$@P$c7jzxb631doT;zgAA;E5##mP9^`>xF)qONppe5#jQnsw33&HzSWLc0 zvq@E#;OfK=R*4>euh15Z&T;Ff?oI~3^}Nl=Sbe-hzZ9>{S8xTab?yg~@jMjG>8}5> zP#!atPNV2+_>5CR>3Cj%1NS*tB_6*)v|rVY(nTeC{Jy6KMPWcS$yZlHAiEy;{ZA9* z$thoWH9?-7DB5F{WveEnab57bMfq`#h|w;s!l0_y;Qhhg5nMGn{SqfGrtyc?KKL7s z!|qaOUOqq+qNi*H#gaF`lM8(Dj0_B)3HlnJk0YH`(x!e=|7=srg|Vjhw<^qOD|n?! zAF_fbC`C&v#;BxdT~#Ygu&NcsDyg=Da>B}3pzDH)811;F=yljzy$H7^Uo6tX>#Xe9%>av$ zj+sOqSnx7tMp?BJM`I$l(rg>$=Y<)m7G2 zV`6cYbu}@uuBj(uKK!6^%gCROO&B_EV#*H3i!mYoFa+X$;-#|wimD|kt71>4sIL&F z)K>_D`Vs{c09$8Agp{Cd_#e+ z&}w zZM~TW$YWYq!>;3<#`a646!0Us?cT-F*aY2d^_e0Q3euP6xcra;dxB3LqT?`nP(tDf z9)uaLFL?HRPw=@0I0Ybkf=@}t;0f+wV6{1&@&xMwS@_x$Y+~9ItT7g{_5_D8xlLUXiu<-1)ks#s6D|Zs6D|NO9J;5esc!D*|KAFH1Y=VX-cmkG69u~fM zg4aPHMPS4eyp5$(1_`hy*!+gKoTJzi{5et-a0=}SE@no1Z_1d_J_k~l+R6A1SrhcP z8@%<>SC#iB4T7jFLuu^2SqQtNFI8II=)Fmxl;*vZgvy?;Gzs)8zR##w6efFuBe;*Q zuZ9T7-j5PCRAct5VA&Hq21>Mm8TJJ4!?G%723oX&mzcUjS~LV|Eoy>Vi-s_zMQ>pX zp)RrCebZA%7(LQ9y~Y()O=nD>nDISKD&rQiC)gZR$;c<>2aN>~oS3`79_mX#Z4XT_ zP?IL8)uf5(#qRBZmD88lL-qvE$LT>|49d~Aq0t`(dCM1FpOjsnn13ZrFA@+{+Ad}2Nha;#)V zpO~{>H%`oGfLuJSgA=O4WW%ZjCnx57WDQQtIu)x7|NQu(F^(8?|HRzK7)Js5#B6@9 zkU=>y|NXbeS?kD&*?db*K;;Q$wNcECXHT#>2W3yAJ;7z1LhF)BW|DOYud3h}hp=1> z`b)ZcU6Q>D8IyHMaB?$s34>DFe@K^5Vhx5VpWDNpVE%l05i{%w=1=FBDuxog@u^^r zJ;4`((O2LJ-fRrGbVhrE^KlvrJi$fGBug@MAl3ylc(5ev0EN)u31+Qa%BArc*wo7Z zf+T|>G_`Wo5Sm(9>H2E4a-t<#Q^Bp_v+x!}Bf5Tr>qgfmf&RFDn}o`Q;-8|{7w7lI z@U&qguoo3EL<K9k7S0C~oP~>-sd|X1j1#gaxEIE{k{SIF zQ~sM^_$I zQ_LyY6P!8~I*b{dRrmjQ>>AFh|B7Af%2MJMvM1Q=kXS3WYrBo*5!kf>hCci^+O?*} zqzLTV^M(Nm>{=JY00nj}Gby{aYeyM)HqR=)!}*3$EQ4a#jx&m7Q0!WVr0m+Rb%R~Y zS&QPdT`K?+*tKFX+OCyxSlP8o$g`4jv0WPqIcC2NM%%S~Fk(meBUk!jjdGA(3)BoE z#jf#<@q_Fdr}FLEAI3Pc8Wd0PC}SK2{14bQ(R}O)Htm{#z9;x3h_Q^@&Ys|h;0dk- zBVxP-p5W|vd@;TRPjEhml^FTS$RhCK2{xaItnvi6g7eYSz!R)X;@tzY&!l#*=yVt&zK>&M{1)-SNd zruD0`#isT1{8H2Z3F`;TRb~D1xry5P6@v+^UpX^X){ovpLT&wWn9F&TD!~NS zFTXr&{Yt?H)-Pi{n5wDs81`2BVrhsc_&I=uNGG1)Q!xulm|;)wNTjad64(=b8JO%1 zz9)Eqp=Wt^vM2Zg#20WpJi%YH6_vF06a7$P8Nw*!urxNWmCV2s%+@t~Bf|d`>ng+i zuUOaAKaJgxj66KSLye9zrai&Klb0(z!KVI7M_L!2U{iewmZZJ}V^6TDfCOX(WNHcl z+2?6$3Tb9A-0%dCGTJKx<$Hn$V@&cPdhrCCI|SJ^vM1QwAqbd!@@4R#lP`nGCtt>7 z)!~11tRW}aA+RTSvH^-tU{CPf1}J)!J;4V_g+0Olic}J}!HgDj&j(xCY3#%(;~5A~ zF#9knIsCuXhe6SM&~|w!TY=yQ@VJ<#}pQFwy&bvOcOffxGVJP-dtU&Uik?a%P*8~C-55|A|m zKRMClvM5~(vMvHM?A<7>1X-tmX}CU0V?b6tyls%OAxam5EdE{M4zoNO50YfZ%=Ks< zNRrjM-=ix)oQ&+#d!gUw;LjS6b-4w|MVsB@PsE%!0nh<{jyYBzZToZyo}gI@=mpF9 zt-D1x^spq{b6AwhK)~@MyGY=^fj<|QB4r=Ebg&vX)duxMQf4~iq33db@EHu*E0D&0 z9eUlEYx>5$k3c&PIwki@h-UuET(PawKeHb$wi4VdK!WWy6*xCjMohqR8J z=lL=BAz~w370mGS`wO5;GB!cXY(RJ7;E)GK3}`XRE(F5|1r&pseg!g?0I^@l zOyC#4iI5z>=JUy1D39?+HELRg$@=fr#m2izHPHHS?Mh{rVRxoHtoEuIoEfq2Tn1mdA>hImp}pwLoPayu^h?R1Z)pvKxT z_M25F!Ba5@SzSE^H>q6QDxPiresL`Q4&Q4wgF0 z(FA3wvph{umO9JT1ocwqajW1Od8u=a85LmkfaNoz2doH8Fkq!%f&r@l6ATzd+e0#K z)o+S4B$Oaa{TH-g2YzCUud1bfB+?#lrsbs$n@kzIF!Ok+F9eeZhL?I1q~2)AoR|7? zEOir;rM?4|X)svoZ$VlnsF(W7Sn7LJsd}liT(+tCtd}~Ar;uBs#Z$_R7EcA3Ks*^A z8{)|W6No3Z76!6F$)Pp+#!H>2pvGD<#!H>2Vj;2yQ}8C0i)C1~)JG~bwA4*dFLkox z>+lO}b?|34$QsG-cx~;7+HM+^Aa}@TQQ8W^uX$N+`BMCxS}As3V36Rub=WqHxzF=A zM5}n8)w?8x+y&2i)a5xO;~zj$Lvoa8a-Bu{(oHHVH^XbU*17bqV zt^Fdj_q=q0OGGupv(A=*0b2m#bCuY?sQX+1F8DRA*#EXIDpva;NuF!8lv2esdb}S zvy;Hz+$@S-GYr36Y9>7_759X4QDHe(xYj*1F$opYB2+lbZWra+zgFpaV&uGr*I6lX zJZj8A8f3^!Y+Hpj3MTh__%e?`Ofi_QM`R}2Aza20b5p&8!dgU<% z#dgZJ;?Xne*a65hw9`=eJ!5YHEajCdag@6^FSTd%?j+Fnx!r?~T&t4u5fe!>qi3QS z^Nh-J?@wiAM)Dl01P0=-)$jaU(X)mah@8jJv%@hE+|2@J<~yErvlvX!%`z~$o0S}) zyP5qs7~M^&0DnT=)L?QqO+4tP308Geqj3a+ZfY=L__@eQ%y7&@7ud89Br((a z+w?6n9CP!vHoXm!m_q!l?izJ5ZbZoob0UhvL%b;f8aLpII2dmfaR*&uj zHH)yh+}9SV4tv9+nV@Ffx&D{FhW>kcyGMtA1n9j~%Uyy%haEmc_9IPk;=6R0N6&zo zO|p6Zl=7HcwbSSZP_vz=jO;)5z)mhc7ZJF4=BE_nacdEZS;4XnGxb^-xy$Why;6{JI4qwNzc5Oe{ zZRKUfusc&(n)qO5;t@2rsG%i~i6sX9flaDr9=HdaNyT^@;r7T^d8NQ5De>qdNnqjx z4;C1gx2hPv7nQsjS9PiDc}=ejgU4=k>Umkvs%A=gTrX_1|1JLA}4KQLIw3q;Qm)7pI{h2-jPW z>03x^o@SITMu5WutQ@D4pAi&S@~{+!Ayy1WM;RqI38DRp(5ws&n&H(hRe6CKzT% zV-bA{jJ|lXN)L0eCiKNiNGYyB1VqPA#<=T?K^gax&?J2^C;}h@490yE#$8_m z%DA6{ao1O9+)c1*+%?L!DA4gHsC(gtjP8GsIjtd1lOVR|kt16~s7*^SQ(PQDZv^)O zsQpit75NZ>mK-&gqe6!N7Hr*Cg4z$o{x1|0Vot%%?M9F!`(s`jb;9;dn7`3Ibr8?! zhhH)SwZ976wZ;9h*T(KwnAFQ%x)SuCW)?wq>5U*4Zb7Iyy=tV=B9O#{m{771^EX

K2Pap% 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%0DQP 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

V^2@WvIytR@`*-Q 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

  • ?L5{kBOjG;n50ignAfaWH9(`%%`8{wdVlvY&=D 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%0Dpu~D_sc~ydv#KeNM%Yh^!E- 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

    &8j|AO zo}czma;s7V|DaMq+(1I0aMRyR5#*{QYU8ZNB zf?aQ&P46m|0SszVGDV51vFtzebV5CfDWE6RlI>yxbyHHPNJ%>-`&c4lDWCxeA(sFL zV*z}c4;ny0F}Z4U)~@PI=$W37H08)2vnSaVi_ez|OtnNwsRchPYDLZ1`+lp#5GdC9^dUvbGu~fR?yiyXd$q;q2k&s z#e&p|_C*|qoOrdf1Q|UeWNsAW9UAFYhj$tR_L)i9PU>!UoG_DmQ`MK<0DtcrkP@L`kkDFe-3+&3(sD=Xg}nfK{4}*$s!O+I6*nNPtSPSLYp^;UiM!whemo7?1BTGO7YEEjD>#n+TotxXE zbRbR#PC=S`2UolCCetpdbs+kWdIV?|2++DLO!IZALx1cxAkU7@-%Nk%Pv|WUOdh)0 zJQLy_5_RV$%bq}0rS2UE=LldFjsP5)jwGyo_xDlad~U)kCY4O%n}YZb80eilYCX@v zYb)QF?2-lWw$cIEqWyFvNk{h6u{1rqulZTxO(_~2rNMXv3*ew&(-UcKl?pbVTm<8R VZ@w{j!88rCUh;6IMM{(|@_!|WeGLEr literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a GIT binary patch literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache new file mode 100644 index 0000000000000000000000000000000000000000..8a0b42a87ebe04e602200039906fd11ffcdc4611 GIT binary patch literal 7759 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 K=;oBj`1fDVAGuZl literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..2ae412bccfd7739434a236925520c9652e93ff84 GIT binary patch literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<nW832Uh9(Di# literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version new file mode 100644 index 00000000000..7dd8dc5809e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version @@ -0,0 +1 @@ +0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache new file mode 100644 index 0000000000000000000000000000000000000000..b7d93046a52ede28e212fe16157739a5771ad13c GIT binary patch literal 3254 zcmbVO!Ef7S6!&K*aUHeGo=T@}YNPhWJqfylqJx?BDU4@O0|l~b&@ZwH^(lY zolTiQy&;IWAaUS;&^U18unPyK{SinA!LGY;;<8EX6y9e$ZQP_KL#pDJ)bD-2_rBlz zy?3r8U6kQi6;7{CzaW21ADff`s?#%*_okmr%DoMT(za^{f*=gqvYRw!4;1*+77*HwWvTsROOMux>ydF zkw=j~Ck-j8cfmYKJ~sPC7sjJrh~4fjzDcR%Oh zdX&$LKsCKVr0F*48lMt0o|B^Sj2nuyW=u+G%%v*EYzmDpQ=0JwH=d{R#xrhMY0X$q zqwykLG5+Dk51FUNPZ=T=R^;QvXvp}}8xz-!a}#JRDiz~`LZn>FvRy*-Nm0@-k~EMk z){F=OD6&2wN&>%afq-%nlsx_>U$vciWTVx>-w6TG^oRJsIzA+CP2E?*aD&P9)JwM8 zP%ZaVLuGAOwH!wcs2`}!wp-_A^wp-v)L@gU^)_SF4b&~>-KOJoD-cjJt& zF0CMgv#~QnzTETJoj0>twd{7{w^WRT6}MVD(N)_GW3Tfw*VTs2FtW!w>ODKyR4vuT zI4W(}0YA!iv+BATy=nVu9l_ZR$|%B5V#ahD7y(nMQJxh?akkz3pQQMUm09guQPrp}^; zjg%b`e~|oA;YsGNOeyM7>~encp9y*_=-+aB=qcm@K0#SUfSfS|=DKjY3a`s(p3vY# z9!@Nb(YLt|Z9j;(#e;Ivy<``0mvPiv!+wA?$VWU=Jdo7HpK{0B) zy-sN&0<7sO@4?%!jGx&A)ZIjKX0vJYrd}oloyeK;gvcBAF!~(F&tA(4>YE4<-;uZ$ z6uwLUmfrq|vYO}9IOTIYtQ)7mfWrkUiTd{A?cx%of+4TTxs{-KVd#|qmgbPtTH=f_ zRN{b>nb$J&SG^lSXXu2n^T;R8h@vG9xh2=++@|H=bPoGuJwcBJ{cOKa_(k`1^s*as z{Q!MU^UKxrqxhIA!cp|jhUb)MsELAD_&W6CQo?M>Laj70=t1aSrPx zI}JMsq3yZh7)PQubFvn0FILM8JkgARn=OyeeAAWr)E}d0`}6<@zR$nH(mln^i14Kf zMekU+F^$#|~v)Tk@TbiL>A?Wr693t&F*tRv?A@4_C&o5;b4d`JD=V zF&q$tDhD$+BnSiR%Af}KNACf9RHy>?LxMsPW|1e^Ud?tb)-eO2#6fzkUAAmye$4c6 z(wKag6iA=1zwSZ*%^-R$l(Pja^`Zugc~~5!Q3oI#p=jfD9>3ZOC=B<Z4CSP)5qWzyGCn7p(W?12VzyxJ{ z@pJK_Se_N(?HVk;3Rg6^as+N_a5DodkKooJu&O{0fn5aq2(-KK*`efy9p;NOpx9T+ zNNM7^6m~46HAv@kH&~m_U$PvZMyvJErVuZvKq`H07-Sd_Efh+O?6;i&(#J8VbnVXk R5@Q}4HK>7fN39Eo$-gpIGF1Qo literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..35823f819643250ce036eb3ade6a8b4cfeac4a68 GIT binary patch literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0K#3 za`YmCS3y637r%v9KZAY)^&02dw(w6{K+*J331W*P?q~bOe z8&urCx#y3gVB#=H_o-SD5(V&&UlB<(5s9X1P5%vOjbmw+z;_NrRx)eD?(}+n5Z7Lc z_u>@;O-7NQ!aVu|=JGs@8^c(3D-44KMYA&HrR0Wnr+<7N6SY*0iON%|aV%xEa)B`u zm|@-&J{M-gaMJOgMP0xk1v*>++E-gKP^) Lk#k#b`f2. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md new file mode 100644 index 00000000000..05c68ca9075 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md @@ -0,0 +1,39 @@ +# stdlib + +GitHub release +Discord chat +![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) + +Gleam's standard library! +Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). + +## Installation + +Add `gleam_stdlib` to your Gleam project. + +```sh +gleam add gleam_stdlib +``` + +## Usage + +Import the modules you want to use and write some code! + +```gleam +import gleam/string + +pub fn greet(name: String) -> String { + string.concat(["Hello ", name, "!"]) +} +``` + +## Targets + +Gleam's standard library supports both targets: Erlang and JavaScript. + +### Compatibility + +This library is compatible with all versions of Erlang/OTP, NodeJS, and +major browsers that are currently supported by their maintainers. If you +have a compatibility issue with any platform open an issue and we'll see +what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml new file mode 100644 index 00000000000..a978a7ff425 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml @@ -0,0 +1,16 @@ +name = "gleam_stdlib" +version = "0.33.1" +gleam = ">= 0.32.0" +licences = ["Apache-2.0"] +description = "A standard library for the Gleam programming language" + +repository = { type = "github", user = "gleam-lang", repo = "stdlib" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[javascript.deno] +allow_read = [ + "./", +] diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl new file mode 100644 index 00000000000..b1135f2dea0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl @@ -0,0 +1,5 @@ +-record(decode_error, { + expected :: binary(), + found :: binary(), + path :: list(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl new file mode 100644 index 00000000000..b0d08dc71a3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl @@ -0,0 +1 @@ +-record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl new file mode 100644 index 00000000000..1f61922beda --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl @@ -0,0 +1 @@ +-record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl new file mode 100644 index 00000000000..88ac25ed0a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl @@ -0,0 +1 @@ +-record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl new file mode 100644 index 00000000000..ad5511eb103 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl @@ -0,0 +1 @@ +-record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl new file mode 100644 index 00000000000..42166198699 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl @@ -0,0 +1,4 @@ +-record(match, { + content :: binary(), + submatches :: list(gleam@option:option(binary())) +}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl new file mode 100644 index 00000000000..0074603b961 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl @@ -0,0 +1 @@ +-record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl new file mode 100644 index 00000000000..6e1e2261268 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl @@ -0,0 +1 @@ +-record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl new file mode 100644 index 00000000000..50150f476b1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl @@ -0,0 +1,9 @@ +-record(uri, { + scheme :: gleam@option:option(binary()), + userinfo :: gleam@option:option(binary()), + host :: gleam@option:option(binary()), + port :: gleam@option:option(integer()), + path :: binary(), + 'query' :: gleam@option:option(binary()), + fragment :: gleam@option:option(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs new file mode 100644 index 00000000000..a8309e0cdbd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs @@ -0,0 +1,957 @@ +/** + * This file uses jsdoc to annotate types. + * These types can be checked using the typescript compiler with "checkjs" option. + */ + +import { isEqual } from "./gleam.mjs"; + +const referenceMap = new WeakMap(); +const tempDataView = new DataView(new ArrayBuffer(8)); +let referenceUID = 0; +/** + * hash the object by reference using a weak map and incrementing uid + * @param {any} o + * @returns {number} + */ +function hashByReference(o) { + const known = referenceMap.get(o); + if (known !== undefined) { + return known; + } + const hash = referenceUID++; + if (referenceUID === 0x7fffffff) { + referenceUID = 0; + } + referenceMap.set(o, hash); + return hash; +} +/** + * merge two hashes in an order sensitive way + * @param {number} a + * @param {number} b + * @returns {number} + */ +function hashMerge(a, b) { + return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; +} +/** + * standard string hash popularised by java + * @param {string} s + * @returns {number} + */ +function hashString(s) { + let hash = 0; + const len = s.length; + for (let i = 0; i < len; i++) { + hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; + } + return hash; +} +/** + * hash a number by converting to two integers and do some jumbling + * @param {number} n + * @returns {number} + */ +function hashNumber(n) { + tempDataView.setFloat64(0, n); + const i = tempDataView.getInt32(0); + const j = tempDataView.getInt32(4); + return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; +} +/** + * hash a BigInt by converting it to a string and hashing that + * @param {BigInt} n + * @returns {number} + */ +function hashBigInt(n) { + return hashString(n.toString()); +} +/** + * hash any js object + * @param {any} o + * @returns {number} + */ +function hashObject(o) { + const proto = Object.getPrototypeOf(o); + if (proto !== null && typeof proto.hashCode === "function") { + try { + const code = o.hashCode(o); + if (typeof code === "number") { + return code; + } + } catch {} + } + if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { + return hashByReference(o); + } + if (o instanceof Date) { + return hashNumber(o.getTime()); + } + let h = 0; + if (o instanceof ArrayBuffer) { + o = new Uint8Array(o); + } + if (Array.isArray(o) || o instanceof Uint8Array) { + for (let i = 0; i < o.length; i++) { + h = (Math.imul(31, h) + getHash(o[i])) | 0; + } + } else if (o instanceof Set) { + o.forEach((v) => { + h = (h + getHash(v)) | 0; + }); + } else if (o instanceof Map) { + o.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + } else { + const keys = Object.keys(o); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + const v = o[k]; + h = (h + hashMerge(getHash(v), hashString(k))) | 0; + } + } + return h; +} +/** + * hash any js value + * @param {any} u + * @returns {number} + */ +export function getHash(u) { + if (u === null) return 0x42108422; + if (u === undefined) return 0x42108423; + if (u === true) return 0x42108421; + if (u === false) return 0x42108420; + switch (typeof u) { + case "number": + return hashNumber(u); + case "string": + return hashString(u); + case "bigint": + return hashBigInt(u); + case "object": + return hashObject(u); + case "symbol": + return hashByReference(u); + case "function": + return hashByReference(u); + default: + return 0; // should be unreachable + } +} +/** + * @template K,V + * @typedef {ArrayNode | IndexNode | CollisionNode} Node + */ +/** + * @template K,V + * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry + */ +/** + * @template K,V + * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry | Node)[] }} ArrayNode + */ +/** + * @template K,V + * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry | Node)[] }} IndexNode + */ +/** + * @template K,V + * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry[] }} CollisionNode + */ +/** + * @typedef {{ val: boolean }} Flag + */ +const SHIFT = 5; // number of bits you need to shift by to get the next bucket +const BUCKET_SIZE = Math.pow(2, SHIFT); +const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket +const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node +const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node +const ENTRY = 0; +const ARRAY_NODE = 1; +const INDEX_NODE = 2; +const COLLISION_NODE = 3; +/** @type {IndexNode} */ +const EMPTY = { + type: INDEX_NODE, + bitmap: 0, + array: [], +}; +/** + * Mask the hash to get only the bucket corresponding to shift + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function mask(hash, shift) { + return (hash >>> shift) & MASK; +} +/** + * Set only the Nth bit where N is the masked hash + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function bitpos(hash, shift) { + return 1 << mask(hash, shift); +} +/** + * Count the number of 1 bits in a number + * @param {number} x + * @returns {number} + */ +function bitcount(x) { + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x += x >> 8; + x += x >> 16; + return x & 0x7f; +} +/** + * Calculate the array index of an item in a bitmap index node + * @param {number} bitmap + * @param {number} bit + * @returns {number} + */ +function index(bitmap, bit) { + return bitcount(bitmap & (bit - 1)); +} +/** + * Efficiently copy an array and set one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function cloneAndSet(arr, at, val) { + const len = arr.length; + const out = new Array(len); + for (let i = 0; i < len; ++i) { + out[i] = arr[i]; + } + out[at] = val; + return out; +} +/** + * Efficiently copy an array and insert one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function spliceIn(arr, at, val) { + const len = arr.length; + const out = new Array(len + 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + out[g++] = val; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Efficiently copy an array and remove one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @returns {T[]} + */ +function spliceOut(arr, at) { + const len = arr.length; + const out = new Array(len - 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + ++i; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Create a new node containing two entries + * @template K,V + * @param {number} shift + * @param {K} key1 + * @param {V} val1 + * @param {number} key2hash + * @param {K} key2 + * @param {V} val2 + * @returns {Node} + */ +function createNode(shift, key1, val1, key2hash, key2, val2) { + const key1hash = getHash(key1); + if (key1hash === key2hash) { + return { + type: COLLISION_NODE, + hash: key1hash, + array: [ + { type: ENTRY, k: key1, v: val1 }, + { type: ENTRY, k: key2, v: val2 }, + ], + }; + } + const addedLeaf = { val: false }; + return assoc( + assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), + shift, + key2hash, + key2, + val2, + addedLeaf + ); +} +/** + * @template T,K,V + * @callback AssocFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @param {V} val + * @param {Flag} addedLeaf + * @returns {Node} + */ +/** + * Associate a node with a new entry, creating a new node + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assoc(root, shift, hash, key, val, addedLeaf) { + switch (root.type) { + case ARRAY_NODE: + return assocArray(root, shift, hash, key, val, addedLeaf); + case INDEX_NODE: + return assocIndex(root, shift, hash, key, val, addedLeaf); + case COLLISION_NODE: + return assocCollision(root, shift, hash, key, val, addedLeaf); + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocArray(root, shift, hash, key, val, addedLeaf) { + const idx = mask(hash, shift); + const node = root.array[idx]; + // if the corresponding index is empty set the index to a newly created node + if (node === undefined) { + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size + 1, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + if (node.type === ENTRY) { + // if keys are equal replace the entry + if (isEqual(key, node.k)) { + if (val === node.v) { + return root; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // otherwise upgrade the entry to a node and insert + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, node.k, node.v, hash, key, val) + ), + }; + } + // otherwise call assoc on the child node + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + // if the child node hasn't changed just return the old root + if (n === node) { + return root; + } + // otherwise set the index to the new node + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocIndex(root, shift, hash, key, val, addedLeaf) { + const bit = bitpos(hash, shift); + const idx = index(root.bitmap, bit); + // if there is already a item at this hash index.. + if ((root.bitmap & bit) !== 0) { + // if there is a node at the index (not an entry), call assoc on the child node + const node = root.array[idx]; + if (node.type !== ENTRY) { + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + if (n === node) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise there is an entry at the index + // if the keys are equal replace the entry with the updated value + const nodeKey = node.k; + if (isEqual(key, nodeKey)) { + if (val === node.v) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // if the keys are not equal, replace the entry with a new child node + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) + ), + }; + } else { + // else there is currently no item at the hash index + const n = root.array.length; + // if the number of nodes is at the maximum, expand this node into an array node + if (n >= MAX_INDEX_NODE) { + // create a 32 length array for the new array node (one for each bit in the hash) + const nodes = new Array(32); + // create and insert a node for the new entry + const jdx = mask(hash, shift); + nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); + let j = 0; + let bitmap = root.bitmap; + // place each item in the index node into the correct spot in the array node + // loop through all 32 bits / array positions + for (let i = 0; i < 32; i++) { + if ((bitmap & 1) !== 0) { + const node = root.array[j++]; + nodes[i] = node; + } + // shift the bitmap to process the next bit + bitmap = bitmap >>> 1; + } + return { + type: ARRAY_NODE, + size: n + 1, + array: nodes, + }; + } else { + // else there is still space in this index node + // simply insert a new entry at the hash index + const newArray = spliceIn(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }); + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap | bit, + array: newArray, + }; + } + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocCollision(root, shift, hash, key, val, addedLeaf) { + // if there is a hash collision + if (hash === root.hash) { + const idx = collisionIndexOf(root, key); + // if this key already exists replace the entry with the new value + if (idx !== -1) { + const entry = root.array[idx]; + if (entry.v === val) { + return root; + } + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + // otherwise insert the entry at the end of the array + const size = root.array.length; + addedLeaf.val = true; + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), + }; + } + // if there is no hash collision, upgrade to an index node + return assoc( + { + type: INDEX_NODE, + bitmap: bitpos(root.hash, shift), + array: [root], + }, + shift, + hash, + key, + val, + addedLeaf + ); +} +/** + * Find the index of a key in the collision node's array + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {number} + */ +function collisionIndexOf(root, key) { + const size = root.array.length; + for (let i = 0; i < size; i++) { + if (isEqual(key, root.array[i].k)) { + return i; + } + } + return -1; +} +/** + * @template T,K,V + * @callback FindFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Entry} + */ +/** + * Return the found entry or undefined if not present in the root + * @template K,V + * @type {FindFunction,K,V>} + */ +function find(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return findArray(root, shift, hash, key); + case INDEX_NODE: + return findIndex(root, shift, hash, key); + case COLLISION_NODE: + return findCollision(root, key); + } +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return undefined; + } + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return undefined; + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Entry} + */ +function findCollision(root, key) { + const idx = collisionIndexOf(root, key); + if (idx < 0) { + return undefined; + } + return root.array[idx]; +} +/** + * @template T,K,V + * @callback WithoutFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Node} + */ +/** + * Remove an entry from the root, returning the updated root. + * Returns undefined if the node should be removed from the parent. + * @template K,V + * @type {WithoutFunction,K,V>} + * */ +function without(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return withoutArray(root, shift, hash, key); + case INDEX_NODE: + return withoutIndex(root, shift, hash, key); + case COLLISION_NODE: + return withoutCollision(root, key); + } +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return root; // already empty + } + let n = undefined; + // if node is an entry and the keys are not equal there is nothing to remove + // if node is not an entry do a recursive call + if (node.type === ENTRY) { + if (!isEqual(node.k, key)) { + return root; // no changes + } + } else { + n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + } + // if the recursive call returned undefined the node should be removed + if (n === undefined) { + // if the number of child nodes is at the minimum, pack into an index node + if (root.size <= MIN_ARRAY_NODE) { + const arr = root.array; + const out = new Array(root.size - 1); + let i = 0; + let j = 0; + let bitmap = 0; + while (i < idx) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + ++i; // skip copying the removed node + while (i < arr.length) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + return { + type: INDEX_NODE, + bitmap: bitmap, + array: out, + }; + } + return { + type: ARRAY_NODE, + size: root.size - 1, + array: cloneAndSet(root.array, idx, n), + }; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return root; // already empty + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + // if the item is not an entry + if (node.type !== ENTRY) { + const n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + // if not undefined, the child node still has items, so update it + if (n !== undefined) { + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise the child node should be removed + // if it was the only child node, remove this node from the parent + if (root.bitmap === bit) { + return undefined; + } + // otherwise just remove the child node + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + // otherwise the item is an entry, remove it if the key matches + if (isEqual(key, node.k)) { + if (root.bitmap === bit) { + return undefined; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + return root; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Node} + */ +function withoutCollision(root, key) { + const idx = collisionIndexOf(root, key); + // if the key not found, no changes + if (idx < 0) { + return root; + } + // otherwise the entry was found, remove it + // if it was the only entry in this node, remove the whole node + if (root.array.length === 1) { + return undefined; + } + // otherwise just remove the entry + return { + type: COLLISION_NODE, + hash: root.hash, + array: spliceOut(root.array, idx), + }; +} +/** + * @template K,V + * @param {undefined | Node} root + * @param {(value:V,key:K)=>void} fn + * @returns {void} + */ +function forEach(root, fn) { + if (root === undefined) { + return; + } + const items = root.array; + const size = items.length; + for (let i = 0; i < size; i++) { + const item = items[i]; + if (item === undefined) { + continue; + } + if (item.type === ENTRY) { + fn(item.v, item.k); + continue; + } + forEach(item, fn); + } +} +/** + * Extra wrapper to keep track of Dict size and clean up the API + * @template K,V + */ +export default class Dict { + /** + * @template V + * @param {Record} o + * @returns {Dict} + */ + static fromObject(o) { + const keys = Object.keys(o); + /** @type Dict */ + let m = Dict.new(); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + m = m.set(k, o[k]); + } + return m; + } + /** + * @template K,V + * @param {Map} o + * @returns {Dict} + */ + static fromMap(o) { + /** @type Dict */ + let m = Dict.new(); + o.forEach((v, k) => { + m = m.set(k, v); + }); + return m; + } + static new() { + return new Dict(undefined, 0); + } + /** + * @param {undefined | Node} root + * @param {number} size + */ + constructor(root, size) { + this.root = root; + this.size = size; + } + /** + * @template NotFound + * @param {K} key + * @param {NotFound} notFound + * @returns {NotFound | V} + */ + get(key, notFound) { + if (this.root === undefined) { + return notFound; + } + const found = find(this.root, 0, getHash(key), key); + if (found === undefined) { + return notFound; + } + return found.v; + } + /** + * @param {K} key + * @param {V} val + * @returns {Dict} + */ + set(key, val) { + const addedLeaf = { val: false }; + const root = this.root === undefined ? EMPTY : this.root; + const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); + if (newRoot === this.root) { + return this; + } + return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); + } + /** + * @param {K} key + * @returns {Dict} + */ + delete(key) { + if (this.root === undefined) { + return this; + } + const newRoot = without(this.root, 0, getHash(key), key); + if (newRoot === this.root) { + return this; + } + if (newRoot === undefined) { + return Dict.new(); + } + return new Dict(newRoot, this.size - 1); + } + /** + * @param {K} key + * @returns {boolean} + */ + has(key) { + if (this.root === undefined) { + return false; + } + return find(this.root, 0, getHash(key), key) !== undefined; + } + /** + * @returns {[K,V][]} + */ + entries() { + if (this.root === undefined) { + return []; + } + /** @type [K,V][] */ + const result = []; + this.forEach((v, k) => result.push([k, v])); + return result; + } + /** + * + * @param {(val:V,key:K)=>void} fn + */ + forEach(fn) { + forEach(this.root, fn); + } + hashCode() { + let h = 0; + this.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + return h; + } + /** + * @param {unknown} o + * @returns {boolean} + */ + equals(o) { + if (!(o instanceof Dict) || this.size !== o.size) { + return false; + } + let equal = true; + this.forEach((v, k) => { + equal = equal && isEqual(o.get(k, !v), v); + }); + return equal; + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam new file mode 100644 index 00000000000..eab2f0b3fec --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam @@ -0,0 +1,21 @@ +import gleam/bit_array + +@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") +pub fn encode64(input: BitArray, padding: Bool) -> String { + bit_array.base64_encode(input, padding) +} + +@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") +pub fn decode64(encoded: String) -> Result(BitArray, Nil) { + bit_array.base64_decode(encoded) +} + +@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") +pub fn url_encode64(input: BitArray, padding: Bool) -> String { + bit_array.base64_url_encode(input, padding) +} + +@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") +pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { + bit_array.base64_url_decode(encoded) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam new file mode 100644 index 00000000000..79860e964ef --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam @@ -0,0 +1,157 @@ +//// BitArrays are a sequence of binary data of any length. + +import gleam/string + +/// Converts a UTF-8 `String` type into a `BitArray`. +/// +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") +pub fn from_string(x: String) -> BitArray + +/// Returns an integer which is the number of bytes in the bit array. +/// +@external(erlang, "erlang", "byte_size") +@external(javascript, "../gleam_stdlib.mjs", "length") +pub fn byte_size(x: BitArray) -> Int + +/// Creates a new bit array by joining two bit arrays. +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: from_string("butter"), suffix: from_string("fly")) +/// from_string("butterfly") +/// ``` +/// +pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { + concat([first, second]) +} + +/// Extracts a sub-section of a bit array. +/// +/// The slice will start at given position and continue up to specified +/// length. +/// A negative length can be used to extract bytes at the end of a bit array. +/// +/// This function runs in constant time. +/// +@external(erlang, "gleam_stdlib", "bit_array_slice") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") +pub fn slice( + from string: BitArray, + at position: Int, + take length: Int, +) -> Result(BitArray, Nil) + +/// Tests to see whether a bit array is valid UTF-8. +/// +pub fn is_utf8(bits: BitArray) -> Bool { + do_is_utf8(bits) +} + +@target(erlang) +fn do_is_utf8(bits: BitArray) -> Bool { + case bits { + <<>> -> True + <<_:utf8, rest:bytes>> -> do_is_utf8(rest) + _ -> False + } +} + +@target(javascript) +fn do_is_utf8(bits: BitArray) -> Bool { + case to_string(bits) { + Ok(_) -> True + _ -> False + } +} + +/// Converts a bit array to a string. +/// +/// Returns an error if the bit array is invalid UTF-8 data. +/// +pub fn to_string(bits: BitArray) -> Result(String, Nil) { + do_to_string(bits) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "identity") +fn unsafe_to_string(a: BitArray) -> String + +@target(erlang) +fn do_to_string(bits: BitArray) -> Result(String, Nil) { + case is_utf8(bits) { + True -> Ok(unsafe_to_string(bits)) + False -> Error(Nil) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") +fn do_to_string(a: BitArray) -> Result(String, Nil) + +/// Creates a new bit array by joining multiple binaries. +/// +/// ## Examples +/// +/// ```gleam +/// > concat([from_string("butter"), from_string("fly")]) +/// from_string("butterfly") +/// ``` +/// +@external(erlang, "gleam_stdlib", "bit_array_concat") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") +pub fn concat(bit_arrays: List(BitArray)) -> BitArray + +/// Encodes a BitArray into a base 64 encoded string. +/// +pub fn base64_encode(input: BitArray, padding: Bool) -> String { + let encoded = encode64(input) + case padding { + True -> encoded + False -> string.replace(encoded, "=", "") + } +} + +@external(erlang, "base64", "encode") +@external(javascript, "../gleam_stdlib.mjs", "encode64") +fn encode64(a: BitArray) -> String + +/// Decodes a base 64 encoded string into a `BitArray`. +/// +pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { + let padded = case byte_size(from_string(encoded)) % 4 { + 0 -> encoded + n -> string.append(encoded, string.repeat("=", 4 - n)) + } + decode64(padded) +} + +@external(erlang, "gleam_stdlib", "base_decode64") +@external(javascript, "../gleam_stdlib.mjs", "decode64") +fn decode64(a: String) -> Result(BitArray, Nil) + +/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. +/// +pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { + base64_encode(input, padding) + |> string.replace("+", "-") + |> string.replace("/", "_") +} + +/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. +/// +pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { + encoded + |> string.replace("-", "+") + |> string.replace("_", "/") + |> base64_decode() +} + +@external(erlang, "binary", "encode_hex") +@external(javascript, "../gleam_stdlib.mjs", "base16_encode") +pub fn base16_encode(input: BitArray) -> String + +@external(erlang, "gleam_stdlib", "base16_decode") +@external(javascript, "../gleam_stdlib.mjs", "base16_decode") +pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam new file mode 100644 index 00000000000..ce6fe52ec1b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam @@ -0,0 +1,80 @@ +//// This module has been deprecated in favour of `gleam/bytes_builder`. + +import gleam/bytes_builder +import gleam/string_builder.{type StringBuilder} + +pub type BitBuilder = + bytes_builder.BytesBuilder + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn new() -> BitBuilder { + bytes_builder.new() +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { + bytes_builder.prepend(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { + bytes_builder.append(to, suffix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { + bytes_builder.prepend_builder(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append_builder( + to first: BitBuilder, + suffix second: BitBuilder, +) -> BitBuilder { + bytes_builder.append_builder(first, second) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { + bytes_builder.prepend_string(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { + bytes_builder.append_string(to, suffix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn concat(builders: List(BitBuilder)) -> BitBuilder { + bytes_builder.concat(builders) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { + bytes_builder.concat_bit_arrays(bits) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_string(string: String) -> BitBuilder { + bytes_builder.from_string(string) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { + bytes_builder.from_string_builder(builder) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_bit_string(bits: BitArray) -> BitBuilder { + bytes_builder.from_bit_array(bits) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn to_bit_string(builder: BitBuilder) -> BitArray { + bytes_builder.to_bit_array(builder) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn byte_size(builder: BitBuilder) -> Int { + bytes_builder.byte_size(builder) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam new file mode 100644 index 00000000000..b703da0930d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam @@ -0,0 +1,43 @@ +//// This module has been deprecated. Please use the `gleam/bit_array` module +//// instead. + +import gleam/bit_array + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn from_string(x: String) -> BitArray { + bit_array.from_string(x) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn byte_size(x: BitArray) -> Int { + bit_array.byte_size(x) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { + bit_array.append(first, second) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn slice( + from string: BitArray, + at position: Int, + take length: Int, +) -> Result(BitArray, Nil) { + bit_array.slice(string, position, length) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn is_utf8(bits: BitArray) -> Bool { + bit_array.is_utf8(bits) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn to_string(bits: BitArray) -> Result(String, Nil) { + bit_array.to_string(bits) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn concat(bit_strings: List(BitArray)) -> BitArray { + bit_array.concat(bit_strings) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam new file mode 100644 index 00000000000..91bd6b76129 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam @@ -0,0 +1,428 @@ +//// A type with two possible values, `True` and `False`. Used to indicate whether +//// things are... true or false! +//// +//// Often is it clearer and offers more type safety to define a custom type +//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` +//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom +//// type that can be either `Student` or `Teacher`. + +import gleam/order.{type Order} + +/// Returns the and of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `&&` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > and(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > and(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > False |> and(True) +/// False +/// ``` +/// +pub fn and(a: Bool, b: Bool) -> Bool { + a && b +} + +/// Returns the or of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `||` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > or(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > False |> or(True) +/// True +/// ``` +/// +pub fn or(a: Bool, b: Bool) -> Bool { + a || b +} + +/// Returns the opposite bool value. +/// +/// This is the same as the `!` or `not` operators in some other languages. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(True) +/// False +/// ``` +/// +/// ```gleam +/// > negate(False) +/// True +/// ``` +/// +pub fn negate(bool: Bool) -> Bool { + case bool { + True -> False + False -> True + } +} + +/// Returns the nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, True) +/// False +/// ``` +/// +pub fn nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> False + } +} + +/// Returns the nand of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nand(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, True) +/// False +/// ``` +/// +pub fn nand(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive or of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_or(False, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, True) +/// False +/// ``` +/// +pub fn exclusive_or(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> False + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, True) +/// True +/// ``` +/// +pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> True + } +} + +/// Compares two bools and returns the first value's `Order` to the second. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/order +/// > compare(True, False) +/// order.Gt +/// ``` +/// +pub fn compare(a: Bool, with b: Bool) -> Order { + case a, b { + True, True -> order.Eq + True, False -> order.Gt + False, False -> order.Eq + False, True -> order.Lt + } +} + +/// Returns `True` if either argument's value is `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > max(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, False) +/// False +/// ``` +/// +pub fn max(a: Bool, b: Bool) -> Bool { + case a { + True -> True + False -> b + } +} + +/// Returns `False` if either bool value is `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > min(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > min(False, True) +/// False +/// +/// > min(False, False) +/// False +/// ``` +/// +pub fn min(a: Bool, b: Bool) -> Bool { + case a { + False -> False + True -> b + } +} + +/// Returns a numeric representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(True) +/// 1 +/// +/// > to_int(False) +/// 0 +/// ``` +/// +pub fn to_int(bool: Bool) -> Int { + case bool { + False -> 0 + True -> 1 + } +} + +/// Returns a string representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(True) +/// "True" +/// ``` +/// +/// ```gleam +/// > to_string(False) +/// "False" +/// ``` +/// +pub fn to_string(bool: Bool) -> String { + case bool { + False -> "False" + True -> "True" + } +} + +/// Run a callback function if the given bool is `False`, otherwise return a +/// default value. +/// +/// With a `use` expression this function can simulate the early-return pattern +/// found in some other programming languages. +/// +/// In a procedural language: +/// +/// ```js +/// if (predicate) return value; +/// // ... +/// ``` +/// +/// In Gleam with a `use` expression: +/// +/// ```gleam +/// use <- guard(when: predicate, return: value) +/// // ... +/// ``` +/// +/// Like everything in Gleam `use` is an expression, so it short circuits the +/// current block, not the entire function. As a result you can assign the value +/// to a variable: +/// +/// ```gleam +/// let x = { +/// use <- guard(when: predicate, return: value) +/// // ... +/// } +/// ``` +/// +/// Note that unlike in procedural languages the `return` value is evaluated +/// even when the predicate is `False`, so it is advisable not to perform +/// expensive computation there. +/// +/// +/// ## Examples +/// +/// ```gleam +/// > let name = "" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Welcome!" +/// ``` +/// +/// ```gleam +/// > let name = "Kamaka" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Hello, Kamaka" +/// ``` +/// +pub fn guard( + when requirement: Bool, + return consequence: t, + otherwise alternative: fn() -> t, +) -> t { + case requirement { + True -> consequence + False -> alternative() + } +} + +/// Runs a callback function if the given bool is `True`, otherwise runs an +/// alternative callback function. +/// +/// Useful when further computation should be delayed regardless of the given +/// bool's value. +/// +/// See [`guard`](#guard) for more info. +/// +/// ## Examples +/// +/// ```gleam +/// > let name = "Kamaka" +/// > let inquiry = fn() { "How may we address you?" } +/// > use <- lazy_guard(when: name == "", return: inquiry) +/// > "Hello, " <> name +/// "Hello, Kamaka" +/// ``` +/// +/// ```gleam +/// > import gleam/int +/// > let name = "" +/// > let greeting = fn() { "Hello, " <> name } +/// > use <- lazy_guard(when: name == "", otherwise: greeting) +/// > let number = int.random(1, 99) +/// > let name = "User " <> int.to_string(number) +/// > "Welcome, " <> name +/// "Welcome, User 54" +/// ``` +/// +pub fn lazy_guard( + when requirement: Bool, + return consequence: fn() -> a, + otherwise alternative: fn() -> a, +) -> a { + case requirement { + True -> consequence() + False -> alternative() + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam new file mode 100644 index 00000000000..20c145d93aa --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam @@ -0,0 +1,197 @@ +//// BytesBuilder is a type used for efficiently concatenating bytes together +//// without copying. +//// +//// If we append one bit array to another the bit arrays must be copied to a +//// new location in memory so that they can sit together. This behaviour +//// enables efficient reading of the string but copying can be expensive, +//// especially if we want to join many bit arrays together. +//// +//// BytesBuilder is different in that it can be joined together in constant +//// time using minimal memory, and then can be efficiently converted to a +//// bit array using the `to_bit_array` function. +//// +//// Byte builders are always byte aligned, so that a number of bits that is not +//// divisible by 8 will be padded with 0s. +//// +//// On Erlang this type is compatible with Erlang's iolists. + +// TODO: pad bit arrays to byte boundaries when adding to a builder. +import gleam/string_builder.{type StringBuilder} +import gleam/list +import gleam/bit_array + +pub opaque type BytesBuilder { + Bytes(BitArray) + Text(StringBuilder) + Many(List(BytesBuilder)) +} + +/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many +/// builders together. +/// +pub fn new() -> BytesBuilder { + concat([]) +} + +/// Prepends a bit array to the start of a builder. +/// +/// Runs in constant time. +/// +pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { + append_builder(from_bit_array(first), second) +} + +/// Appends a bit array to the end of a builder. +/// +/// Runs in constant time. +/// +pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { + append_builder(first, from_bit_array(second)) +} + +/// Prepends a builder onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder( + to second: BytesBuilder, + prefix first: BytesBuilder, +) -> BytesBuilder { + append_builder(first, second) +} + +/// Appends a builder onto the end of another. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "iodata_append") +pub fn append_builder( + to first: BytesBuilder, + suffix second: BytesBuilder, +) -> BytesBuilder { + case second { + Many(builders) -> Many([first, ..builders]) + _ -> Many([first, second]) + } +} + +/// Prepends a string onto the start of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn prepend_string( + to second: BytesBuilder, + prefix first: String, +) -> BytesBuilder { + append_builder(from_string(first), second) +} + +/// Appends a string onto the end of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn append_string( + to first: BytesBuilder, + suffix second: String, +) -> BytesBuilder { + append_builder(first, from_string(second)) +} + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "identity") +pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { + Many(builders) +} + +/// Joins a list of bit arrays into a single builder. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "identity") +pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { + bits + |> list.map(fn(b) { from_bit_array(b) }) + |> concat() +} + +/// Creates a new builder from a string. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_string(string: String) -> BytesBuilder { + Text(string_builder.from_string(string)) +} + +/// Creates a new builder from a string builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { + Text(builder) +} + +/// Creates a new builder from a bit array. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_bit_array(bits: BitArray) -> BytesBuilder { + Bytes(bits) +} + +/// Turns an builder into a bit array. +/// +/// Runs in linear time. +/// +/// When running on Erlang this function is implemented natively by the +/// virtual machine and is highly optimised. +/// +@external(erlang, "erlang", "list_to_bitstring") +pub fn to_bit_array(builder: BytesBuilder) -> BitArray { + [[builder]] + |> to_list([]) + |> list.reverse + |> bit_array.concat +} + +fn to_list( + stack: List(List(BytesBuilder)), + acc: List(BitArray), +) -> List(BitArray) { + case stack { + [] -> acc + + [[], ..remaining_stack] -> to_list(remaining_stack, acc) + + [[Bytes(bits), ..rest], ..remaining_stack] -> + to_list([rest, ..remaining_stack], [bits, ..acc]) + + [[Text(builder), ..rest], ..remaining_stack] -> { + let bits = bit_array.from_string(string_builder.to_string(builder)) + to_list([rest, ..remaining_stack], [bits, ..acc]) + } + + [[Many(builders), ..rest], ..remaining_stack] -> + to_list([builders, rest, ..remaining_stack], acc) + } +} + +/// Returns the size of the builder's content in bytes. +/// +/// Runs in linear time. +/// +@external(erlang, "erlang", "iolist_size") +pub fn byte_size(builder: BytesBuilder) -> Int { + [[builder]] + |> to_list([]) + |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam new file mode 100644 index 00000000000..280bf9d1d98 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam @@ -0,0 +1,544 @@ +import gleam/option.{type Option} + +/// A dictionary of keys and values. +/// +/// Any type can be used for the keys and values of a dict, but all the keys +/// must be of the same type and all the values must be of the same type. +/// +/// Each key can only be present in a dict once. +/// +/// Dicts are not ordered in any way, and any unintentional ordering is not to +/// be relied upon in your code as it may change in future versions of Erlang +/// or Gleam. +/// +/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more +/// information. +/// +pub type Dict(key, value) + +/// Determines the number of key-value pairs in the dict. +/// This function runs in constant time and does not need to iterate the dict. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> size() +/// 0 +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", "value") |> size() +/// 1 +/// ``` +/// +pub fn size(dict: Dict(k, v)) -> Int { + do_size(dict) +} + +@external(erlang, "maps", "size") +@external(javascript, "../gleam_stdlib.mjs", "map_size") +fn do_size(a: Dict(k, v)) -> Int + +/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for +/// each key-value pair in the dict. +/// +/// The tuples in the list have no specific order. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> to_list() +/// [] +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", 0) |> to_list() +/// [#("key", 0)] +/// ``` +/// +pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { + do_to_list(dict) +} + +@external(erlang, "maps", "to_list") +@external(javascript, "../gleam_stdlib.mjs", "map_to_list") +fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) + +/// Converts a list of 2-element tuples `#(key, value)` to a dict. +/// +/// If two tuples have the same key the last one in the list will be the one +/// that is present in the dict. +/// +pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { + do_from_list(list) +} + +@target(erlang) +@external(erlang, "maps", "from_list") +fn do_from_list(a: List(#(key, value))) -> Dict(key, value) + +@target(javascript) +fn fold_list_of_pair( + over list: List(#(k, v)), + from initial: Dict(k, v), +) -> Dict(k, v) { + case list { + [] -> initial + [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) + } +} + +@target(javascript) +fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { + fold_list_of_pair(list, new()) +} + +/// Determines whether or not a value present in the dict for a given key. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("a") +/// True +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("b") +/// False +/// ``` +/// +pub fn has_key(dict: Dict(k, v), key: k) -> Bool { + do_has_key(key, dict) +} + +@target(erlang) +@external(erlang, "maps", "is_key") +fn do_has_key(a: key, b: Dict(key, v)) -> Bool + +@target(javascript) +fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { + get(dict, key) != Error(Nil) +} + +/// Creates a fresh dict that contains no values. +/// +pub fn new() -> Dict(key, value) { + do_new() +} + +@external(erlang, "maps", "new") +@external(javascript, "../gleam_stdlib.mjs", "new_map") +fn do_new() -> Dict(key, value) + +/// Fetches a value from a dict for a given key. +/// +/// The dict may not have a value for the key, so the value is wrapped in a +/// `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("b") +/// Error(Nil) +/// ``` +/// +pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { + do_get(from, get) +} + +@external(erlang, "gleam_stdlib", "map_get") +@external(javascript, "../gleam_stdlib.mjs", "map_get") +fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) + +/// Inserts a value into the dict with the given key. +/// +/// If the dict already has a value for the given key then the value is +/// replaced with the new value. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> to_list +/// [#("a", 0)] +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list +/// [#("a", 5)] +/// ``` +/// +pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { + do_insert(key, value, dict) +} + +@external(erlang, "maps", "put") +@external(javascript, "../gleam_stdlib.mjs", "map_insert") +fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) + +/// Updates all values in a given dict by calling a given function on each key +/// and value. +/// +/// ## Examples +/// +/// ```gleam +/// > [#(3, 3), #(2, 4)] +/// > |> from_list +/// > |> map_values(fn(key, value) { key * value }) +/// [#(3, 9), #(2, 8)] +/// ``` +/// +pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { + do_map_values(fun, dict) +} + +@target(erlang) +@external(erlang, "maps", "map") +fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) + +@target(javascript) +fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { + let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } + dict + |> fold(from: new(), with: f) +} + +/// Gets a list of all keys in a given dict. +/// +/// Dicts are not ordered so the keys are not returned in any specific order. Do +/// not write code that relies on the order keys are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > keys([#("a", 0), #("b", 1)]) +/// ["a", "b"] +/// ``` +/// +pub fn keys(dict: Dict(keys, v)) -> List(keys) { + do_keys(dict) +} + +@target(erlang) +@external(erlang, "maps", "keys") +fn do_keys(a: Dict(keys, v)) -> List(keys) + +@target(javascript) +fn reverse_and_concat(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) + } +} + +@target(javascript) +fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) + } +} + +@target(javascript) +fn do_keys(dict: Dict(k, v)) -> List(k) { + let list_of_pairs = to_list(dict) + do_keys_acc(list_of_pairs, []) +} + +/// Gets a list of all values in a given dict. +/// +/// Dicts are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order values are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > values(from_list([#("a", 0), #("b", 1)])) +/// [0, 1] +/// ``` +/// +pub fn values(dict: Dict(k, values)) -> List(values) { + do_values(dict) +} + +@target(erlang) +@external(erlang, "maps", "values") +fn do_values(a: Dict(k, values)) -> List(values) + +@target(javascript) +fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) + } +} + +@target(javascript) +fn do_values(dict: Dict(k, v)) -> List(v) { + let list_of_pairs = to_list(dict) + do_values_acc(list_of_pairs, []) +} + +/// Creates a new dict from a given dict, minus any entries that a given function +/// returns `False` for. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { value != 0 }) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { True }) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn filter( + in dict: Dict(k, v), + keeping predicate: fn(k, v) -> Bool, +) -> Dict(k, v) { + do_filter(predicate, dict) +} + +@target(erlang) +@external(erlang, "maps", "filter") +fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) + +@target(javascript) +fn do_filter( + f: fn(key, value) -> Bool, + dict: Dict(key, value), +) -> Dict(key, value) { + let insert = fn(dict, k, v) { + case f(k, v) { + True -> insert(dict, k, v) + _ -> dict + } + } + dict + |> fold(from: new(), with: insert) +} + +/// Creates a new dict from a given dict, only including any entries for which the +/// keys are in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["b"]) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["a", "b", "c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { + do_take(desired_keys, dict) +} + +@target(erlang) +@external(erlang, "maps", "with") +fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) + +@target(javascript) +fn insert_taken( + dict: Dict(k, v), + desired_keys: List(k), + acc: Dict(k, v), +) -> Dict(k, v) { + let insert = fn(taken, key) { + case get(dict, key) { + Ok(value) -> insert(taken, key, value) + _ -> taken + } + } + case desired_keys { + [] -> acc + [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) + } +} + +@target(javascript) +fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { + insert_taken(dict, desired_keys, new()) +} + +/// Creates a new dict from a pair of given dicts by combining their entries. +/// +/// If there are entries with the same keys in both dicts the entry from the +/// second dict takes precedence. +/// +/// ## Examples +/// +/// ```gleam +/// > let a = from_list([#("a", 0), #("b", 1)]) +/// > let b = from_list([#("b", 2), #("c", 3)]) +/// > merge(a, b) +/// from_list([#("a", 0), #("b", 2), #("c", 3)]) +/// ``` +/// +pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { + do_merge(dict, new_entries) +} + +@target(erlang) +@external(erlang, "maps", "merge") +fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) + +@target(javascript) +fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { + insert(dict, pair.0, pair.1) +} + +@target(javascript) +fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { + case new_entries { + [] -> dict + [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) + } +} + +@target(javascript) +fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { + new_entries + |> to_list + |> fold_inserts(dict) +} + +/// Creates a new dict from a given dict with all the same entries except for the +/// one with a given key, if it exists. +/// +/// ## Examples +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "a") +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "c") +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { + do_delete(key, dict) +} + +@external(erlang, "maps", "remove") +@external(javascript, "../gleam_stdlib.mjs", "map_remove") +fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) + +/// Creates a new dict from a given dict with all the same entries except any with +/// keys found in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a"]) +/// from_list([#("b", 2)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], ["c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) +/// from_list([]) +/// ``` +/// +pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { + case disallowed_keys { + [] -> dict + [x, ..xs] -> drop(delete(dict, x), xs) + } +} + +/// Creates a new dict with one entry updated using a given function. +/// +/// If there was not an entry in the dict for the given key then the function +/// gets `None` as its argument, otherwise it gets `Some(value)`. +/// +/// ## Example +/// +/// ```gleam +/// > let increment = fn(x) { +/// > case x { +/// > Some(i) -> i + 1 +/// > None -> 0 +/// > } +/// > } +/// > let dict = from_list([#("a", 0)]) +/// > +/// > update(dict, "a", increment) +/// from_list([#("a", 1)]) +/// ``` +/// +/// ```gleam +/// > update(dict, "b", increment) +/// from_list([#("a", 0), #("b", 0)]) +/// ``` +/// +pub fn update( + in dict: Dict(k, v), + update key: k, + with fun: fn(Option(v)) -> v, +) -> Dict(k, v) { + dict + |> get(key) + |> option.from_result + |> fun + |> insert(dict, key, _) +} + +fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { + case list { + [] -> initial + [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) + } +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Dicts are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order entries are used by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) +/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) +/// 13 +/// ``` +/// +/// ```gleam +/// > import gleam/string.{append} +/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) +/// "abc" +/// ``` +/// +pub fn fold( + over dict: Dict(k, v), + from initial: acc, + with fun: fn(acc, k, v) -> acc, +) -> acc { + dict + |> to_list + |> do_fold(initial, fun) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam new file mode 100644 index 00000000000..c71c6f342ad --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam @@ -0,0 +1,1508 @@ +import gleam/int +import gleam/list +import gleam/dict.{type Dict} +import gleam/option.{type Option} +import gleam/result +import gleam/string_builder +@target(erlang) +import gleam/bit_array + +/// `Dynamic` data is data that we don't know the type of yet. +/// We likely get data like this from interop with Erlang, or from +/// IO with the outside world. +/// +pub type Dynamic + +/// Error returned when unexpected data is encountered +/// +pub type DecodeError { + DecodeError(expected: String, found: String, path: List(String)) +} + +pub type DecodeErrors = + List(DecodeError) + +pub type Decoder(t) = + fn(Dynamic) -> Result(t, DecodeErrors) + +/// Converts any Gleam data into `Dynamic` data. +/// +pub fn from(a) -> Dynamic { + do_from(a) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_from(a: anything) -> Dynamic + +/// Unsafely casts a Dynamic value into any other type. +/// +/// This is an escape hatch for the type system that may be useful when wrapping +/// native Erlang APIs. It is to be used as a last measure only! +/// +/// If you can avoid using this function, do! +/// +pub fn unsafe_coerce(a: Dynamic) -> anything { + do_unsafe_coerce(a) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_unsafe_coerce(a: Dynamic) -> a + +/// Decodes a `Dynamic` value from a `Dynamic` value. +/// +/// This function doesn't seem very useful at first, but it can be convenient +/// when you need to give a decoder function but you don't actually care what +/// the to-decode value is. +/// +pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { + Ok(value) +} + +/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit +/// array if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bit_array(from("Hello")) == bit_array.from_string("Hello") +/// True +/// ``` +/// +/// ```gleam +/// > bit_array(from(123)) +/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) +/// ``` +/// +pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { + decode_bit_array(data) +} + +@deprecated("Please use `bit_array` instead") +pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { + bit_array(data) +} + +@external(erlang, "gleam_stdlib", "decode_bit_array") +@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") +fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a string, and returns that string if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > string(from("Hello")) +/// Ok("Hello") +/// ``` +/// +/// ```gleam +/// > string(from(123)) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { + decode_string(data) +} + +fn map_errors( + result: Result(t, DecodeErrors), + f: fn(DecodeError) -> DecodeError, +) -> Result(t, DecodeErrors) { + result.map_error(result, list.map(_, f)) +} + +@target(erlang) +fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { + bit_array(data) + |> map_errors(put_expected(_, "String")) + |> result.try(fn(raw) { + case bit_array.to_string(raw) { + Ok(string) -> Ok(string) + Error(Nil) -> + Error([DecodeError(expected: "String", found: "BitArray", path: [])]) + } + }) +} + +@target(erlang) +fn put_expected(error: DecodeError, expected: String) -> DecodeError { + DecodeError(..error, expected: expected) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "decode_string") +fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) + +/// Return a string indicating the type of the dynamic value. +/// +/// ```gleam +/// > classify(from("Hello")) +/// "String" +/// ``` +/// +pub fn classify(data: Dynamic) -> String { + do_classify(data) +} + +@external(erlang, "gleam_stdlib", "classify_dynamic") +@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") +fn do_classify(a: Dynamic) -> String + +/// Checks to see whether a `Dynamic` value is an int, and returns that int if it +/// is. +/// +/// ## Examples +/// +/// ```gleam +/// > int(from(123)) +/// Ok(123) +/// ``` +/// +/// ```gleam +/// > int(from("Hello")) +/// Error([DecodeError(expected: "Int", found: "String", path: [])]) +/// ``` +/// +pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { + decode_int(data) +} + +@external(erlang, "gleam_stdlib", "decode_int") +@external(javascript, "../gleam_stdlib.mjs", "decode_int") +fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a float, and returns that float if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > float(from(2.0)) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > float(from(123)) +/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) +/// ``` +/// +pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { + decode_float(data) +} + +@external(erlang, "gleam_stdlib", "decode_float") +@external(javascript, "../gleam_stdlib.mjs", "decode_float") +fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bool(from(True)) +/// Ok(True) +/// ``` +/// +/// ```gleam +/// > bool(from(123)) +/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) +/// ``` +/// +pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { + decode_bool(data) +} + +@external(erlang, "gleam_stdlib", "decode_bool") +@external(javascript, "../gleam_stdlib.mjs", "decode_bool") +fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a list, and returns that list if it +/// is. The types of the elements are not checked. +/// +/// If you wish to decode all the elements in the list use the `list` function +/// instead. +/// +/// ## Examples +/// +/// ```gleam +/// > shallow_list(from(["a", "b", "c"])) +/// Ok([from("a"), from("b"), from("c")]) +/// ``` +/// +/// ```gleam +/// > shallow_list(1) +/// Error([DecodeError(expected: "List", found: "Int", path: [])]) +/// ``` +/// +pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { + decode_list(value) +} + +@external(erlang, "gleam_stdlib", "decode_list") +@external(javascript, "../gleam_stdlib.mjs", "decode_list") +fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_result") +@external(javascript, "../gleam_stdlib.mjs", "decode_result") +fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a result of a particular type, and +/// returns that result if it is. +/// +/// The `ok` and `error` arguments are decoders for decoding the `Ok` and +/// `Error` values of the result. +/// +/// ## Examples +/// +/// ```gleam +/// > from(Ok(1)) +/// > |> result(ok: int, error: string) +/// Ok(Ok(1)) +/// ``` +/// +/// ```gleam +/// > from(Error("boom")) +/// > |> result(ok: int, error: string) +/// Ok(Error("boom")) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> result(ok: int, error: string) +/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) +/// ``` +/// +pub fn result( + ok decode_ok: Decoder(a), + error decode_error: Decoder(e), +) -> Decoder(Result(a, e)) { + fn(value) { + use inner_result <- result.try(decode_result(value)) + + case inner_result { + Ok(raw) -> { + use value <- result.try( + decode_ok(raw) + |> map_errors(push_path(_, "ok")), + ) + Ok(Ok(value)) + } + Error(raw) -> { + use value <- result.try( + decode_error(raw) + |> map_errors(push_path(_, "error")), + ) + Ok(Error(value)) + } + } + } +} + +/// Checks to see whether a `Dynamic` value is a list of a particular type, and +/// returns that list if it is. +/// +/// The second argument is a decoder function used to decode the elements of +/// the list. The list is only decoded if all elements in the list can be +/// successfully decoded using this function. +/// +/// If you do not wish to decode all the elements in the list use the `shallow_list` +/// function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > from(["a", "b", "c"]) +/// > |> list(of: string) +/// Ok(["a", "b", "c"]) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> list(of: string) +/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) +/// ``` +/// +/// ```gleam +/// > from("ok") +/// > |> list(of: string) +/// Error([DecodeError(expected: "List", found: "String", path: [])]) +/// ``` +/// +pub fn list( + of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), +) -> Decoder(List(inner)) { + fn(dynamic) { + use list <- result.try(shallow_list(dynamic)) + list + |> list.try_map(decoder_type) + |> map_errors(push_path(_, "*")) + } +} + +/// Checks to see if a `Dynamic` value is a nullable version of a particular +/// type, and returns a corresponding `Option` if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("null")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("nil")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("undefined")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> optional(string) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { + fn(value) { decode_optional(value, decode) } +} + +@external(erlang, "gleam_stdlib", "decode_option") +@external(javascript, "../gleam_stdlib.mjs", "decode_option") +fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) + +/// Checks to see if a `Dynamic` value is a map with a specific field, and returns +/// the value of that field if it is. +/// +/// This will not succeed on a record. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> dict.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok("World") +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { + fn(value) { + let missing_field_error = + DecodeError(expected: "field", found: "nothing", path: []) + + use maybe_inner <- result.try(decode_field(value, name)) + maybe_inner + |> option.to_result([missing_field_error]) + |> result.try(inner_type) + |> map_errors(push_path(_, name)) + } +} + +/// Checks to see if a `Dynamic` value is a map with a specific field. +/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, +/// returns the decoded field wrapped in `Some(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> dict.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(Some("World")) +/// ``` +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn optional_field( + named name: a, + of inner_type: Decoder(t), +) -> Decoder(Option(t)) { + fn(value) { + use maybe_inner <- result.try(decode_field(value, name)) + case maybe_inner { + option.None -> Ok(option.None) + option.Some(dynamic_inner) -> + dynamic_inner + |> decode_optional(inner_type) + |> map_errors(push_path(_, name)) + } + } +} + +@external(erlang, "gleam_stdlib", "decode_field") +@external(javascript, "../gleam_stdlib.mjs", "decode_field") +fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) + +/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain +/// index, and returns the value of that index if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(0, int) +/// Ok(from(1)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(2, int) +/// Error([ +/// DecodeError( +/// expected: "Tuple of at least 3 elements", +/// found: "Tuple of 2 elements", +/// path: [], +/// ), +/// ]) +/// ``` +/// +pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { + fn(data: Dynamic) { + use tuple <- result.try(decode_tuple(data)) + let size = tuple_size(tuple) + use data <- result.try(case index >= 0 { + True -> + case index < size { + True -> tuple_get(tuple, index) + False -> at_least_decode_tuple_error(index + 1, data) + } + False -> + case int.absolute_value(index) <= size { + True -> tuple_get(tuple, size + index) + False -> at_least_decode_tuple_error(int.absolute_value(index), data) + } + }) + inner_type(data) + |> map_errors(push_path(_, index)) + } +} + +fn at_least_decode_tuple_error( + size: Int, + data: Dynamic, +) -> Result(a, DecodeErrors) { + let s = case size { + 1 -> "" + _ -> "s" + } + let error = + ["Tuple of at least ", int.to_string(size), " element", s] + |> string_builder.from_strings + |> string_builder.to_string + |> DecodeError(found: classify(data), path: []) + Error([error]) +} + +// A tuple of unknown size +type UnknownTuple + +@external(erlang, "gleam_stdlib", "decode_tuple") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") +fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple2") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") +fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple3") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") +fn decode_tuple3( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple4") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") +fn decode_tuple4( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple5") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") +fn decode_tuple5( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple6") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") +fn decode_tuple6( + a: Dynamic, +) -> Result( + #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), + DecodeErrors, +) + +@external(erlang, "gleam_stdlib", "tuple_get") +@external(javascript, "../gleam_stdlib.mjs", "tuple_get") +fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) + +@external(erlang, "gleam_stdlib", "size_of_tuple") +@external(javascript, "../gleam_stdlib.mjs", "length") +fn tuple_size(a: UnknownTuple) -> Int + +fn tuple_errors( + result: Result(a, List(DecodeError)), + name: String, +) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> list.map(errors, push_path(_, name)) + } +} + +fn push_path(error: DecodeError, name: t) -> DecodeError { + let name = from(name) + let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) + let name = case decoder(name) { + Ok(name) -> name + Error(_) -> + ["<", classify(name), ">"] + |> string_builder.from_strings + |> string_builder.to_string + } + DecodeError(..error, path: [name, ..error.path]) +} + +/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0)) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from([1, 2]) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0)]) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple2(int, float) +/// Error([ +/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple2(int, float) +/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple2( + first decode1: Decoder(a), + second decode2: Decoder(b), +) -> Decoder(#(a, b)) { + fn(value) { + use #(a, b) <- result.try(decode_tuple2(value)) + case decode1(a), decode2(b) { + Ok(a), Ok(b) -> Ok(#(a, b)) + a, b -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3")]) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple3( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), +) -> Decoder(#(a, b, c)) { + fn(value) { + use #(a, b, c) <- result.try(decode_tuple3(value)) + case decode1(a), decode2(b), decode3(c) { + Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) + a, b, c -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4)) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4)) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4]) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4)]) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple4( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), +) -> Decoder(#(a, b, c, d)) { + fn(value) { + use #(a, b, c, d) <- result.try(decode_tuple4(value)) + case decode1(a), decode2(b), decode3(c), decode4(d) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) + a, b, c, d -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5)) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5)) +/// > |> tuple5(int, float, string, int, int) +/// Ok(#(1, 2.0, "3", 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5]) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) +/// > |> tuple5(int, float, string, int, bool) +/// Ok(#(1, 2.0, "3", 4, True)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple5(int, float, string, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple5(int, float, string, int, int) +/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple5( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), +) -> Decoder(#(a, b, c, d, e)) { + fn(value) { + use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) + case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) + a, b, c, d, e -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5, 6)) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5, 6)) +/// > |> tuple6(int, float, string, int, int, int) +/// Ok(#(1, 2.0, "3", 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5, 6]) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) +/// > |> tuple6(int, float, string, int, bool, bool) +/// Ok(#(1, 2.0, "3", 4, True, False)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple6(int, float, string, int, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple6(int, float, string, int, int, int) +/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple6( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), + sixth decode6: Decoder(f), +) -> Decoder(#(a, b, c, d, e, f)) { + fn(value) { + use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) + case + decode1(a), + decode2(b), + decode3(c), + decode4(d), + decode5(e), + decode6(f) + { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) + a, b, c, d, e, f -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> list.append(tuple_errors(f, "5")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a dict. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() |> from |> map(string, int) +/// Ok(dict.new()) +/// ``` +/// +/// ```gleam +/// > from(1) |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "Int", path: [])) +/// ``` +/// +/// ```gleam +/// > from("") |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "String", path: [])) +/// ``` +/// +pub fn dict( + of key_type: Decoder(k), + to value_type: Decoder(v), +) -> Decoder(Dict(k, v)) { + fn(value) { + use map <- result.try(decode_map(value)) + use pairs <- result.try( + map + |> dict.to_list + |> list.try_map(fn(pair) { + let #(k, v) = pair + use k <- result.try( + key_type(k) + |> map_errors(push_path(_, "keys")), + ) + use v <- result.try( + value_type(v) + |> map_errors(push_path(_, "values")), + ) + Ok(#(k, v)) + }), + ) + Ok(dict.from_list(pairs)) + } +} + +@deprecated("Use `dict` instead") +pub fn map( + of key_type: Decoder(k), + to value_type: Decoder(v), +) -> Decoder(Dict(k, v)) { + dict(key_type, value_type) +} + +@external(erlang, "gleam_stdlib", "decode_map") +@external(javascript, "../gleam_stdlib.mjs", "decode_map") +fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) + +/// Joins multiple decoders into one. When run they will each be tried in turn +/// until one succeeds, or they all fail. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/result +/// > let bool_or_string = any(of: [ +/// > string, +/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } +/// > ]) +/// > bool_or_string(from("ok")) +/// Ok("ok") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(True)) +/// Ok("a bool") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(1)) +/// Error(DecodeError(expected: "another type", found: "Int", path: [])) +/// ``` +/// +pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { + fn(data) { + case decoders { + [] -> + Error([ + DecodeError(found: classify(data), expected: "another type", path: []), + ]) + + [decoder, ..decoders] -> + case decoder(data) { + Ok(decoded) -> Ok(decoded) + Error(_) -> any(decoders)(data) + } + } + } +} + +/// Decode 1 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode1(MyRecord, element(0, int)) +/// Ok(MyRecord(1)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode1(MyRecord, element(0, int)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// ]) +/// ``` +/// +pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { + fn(value) { + case t1(value) { + Ok(a) -> Ok(constructor(a)) + a -> Error(all_errors(a)) + } + } +} + +/// Decode 2 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Ok(MyRecord(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode2( + constructor: fn(t1, t2) -> t, + t1: Decoder(t1), + t2: Decoder(t2), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value) { + Ok(a), Ok(b) -> Ok(constructor(a, b)) + a, b -> Error(list.concat([all_errors(a), all_errors(b)])) + } + } +} + +/// Decode 3 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Ok(MyRecord(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode3( + constructor: fn(t1, t2, t3) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value), t3(value) { + Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) + a, b, c -> + Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) + } + } +} + +/// Decode 4 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode4( + constructor: fn(t1, t2, t3, t4) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) + a, b, c, d -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + ])) + } + } +} + +/// Decode 5 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode5( + constructor: fn(t1, t2, t3, t4, t5) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) + a, b, c, d, e -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + ])) + } + } +} + +/// Decode 6 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode6( + constructor: fn(t1, t2, t3, t4, t5, t6) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> + Ok(constructor(a, b, c, d, e, f)) + a, b, c, d, e, f -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + ])) + } + } +} + +/// Decode 7 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode7( + constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> + Ok(constructor(a, b, c, d, e, f, g)) + a, b, c, d, e, f, g -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + ])) + } + } +} + +/// Decode 8 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode8( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> + Ok(constructor(a, b, c, d, e, f, g, h)) + a, b, c, d, e, f, g, h -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + ])) + } + } +} + +/// Decode 9 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "", "")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode9( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), + t9: Decoder(t9), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> + Ok(constructor(a, b, c, d, e, f, g, h, i)) + a, b, c, d, e, f, g, h, i -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + all_errors(i), + ])) + } + } +} + +fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> errors + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam new file mode 100644 index 00000000000..5d62419fd0d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam @@ -0,0 +1,546 @@ +//// Functions for working with floats. +//// +//// ## Division by zero +//// +//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE +//// 754 standard for floating point arithmetic and does not have an `Infinity` +//// value. In Erlang division by zero results in a crash, however Gleam does +//// not have partial functions and operators in core so instead division by zero +//// returns zero, a behaviour taken from Pony, Coq, and Lean. +//// +//// This may seem unexpected at first, but it is no less mathematically valid +//// than crashing or returning a special value. Division by zero is undefined +//// in mathematics. + +import gleam/order.{type Order} + +/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was +/// not possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2.3") +/// Ok(2.3) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Float, Nil) { + do_parse(string) +} + +@external(erlang, "gleam_stdlib", "parse_float") +@external(javascript, "../gleam_stdlib.mjs", "parse_float") +fn do_parse(a: String) -> Result(Float, Nil) + +/// Returns the string representation of the provided `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2.3) +/// "2.3" +/// ``` +/// +pub fn to_string(x: Float) -> String { + do_to_string(x) +} + +@external(erlang, "gleam_stdlib", "float_to_string") +@external(javascript, "../gleam_stdlib.mjs", "float_to_string") +fn do_to_string(a: Float) -> String + +/// Restricts a `Float` between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(1.2, min: 1.4, max: 1.6) +/// 1.4 +/// ``` +/// +pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two `Float`s, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2.0, 2.3) +/// Lt +/// ``` +/// +/// To handle +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) +/// you may use [`loosely_compare`](#loosely_compare) instead. +/// +pub fn compare(a: Float, with b: Float) -> Order { + case a == b { + True -> order.Eq + False -> + case a <. b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two `Float`s within a tolerance, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) +/// Eq +/// ``` +/// +/// If you want to check only for equality you may use +/// [`loosely_equals`](#loosely_equals) instead. +/// +pub fn loosely_compare( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Order { + let difference = absolute_value(a -. b) + case difference <=. tolerance { + True -> order.Eq + False -> compare(a, b) + } +} + +/// Checks for equality of two `Float`s within a tolerance, +/// returning an `Bool`. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) +/// True +/// ``` +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) +/// False +/// ``` +/// +pub fn loosely_equals( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Bool { + let difference = absolute_value(a -. b) + difference <=. tolerance +} + +/// Compares two `Float`s, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2.0, 2.3) +/// 2.0 +/// ``` +/// +pub fn min(a: Float, b: Float) -> Float { + case a <. b { + True -> a + False -> b + } +} + +/// Compares two `Float`s, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2.0, 2.3) +/// 2.3 +/// ``` +/// +pub fn max(a: Float, b: Float) -> Float { + case a >. b { + True -> a + False -> b + } +} + +/// Rounds the value to the next highest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > ceiling(2.3) +/// 3.0 +/// ``` +/// +pub fn ceiling(x: Float) -> Float { + do_ceiling(x) +} + +@external(erlang, "math", "ceil") +@external(javascript, "../gleam_stdlib.mjs", "ceiling") +fn do_ceiling(a: Float) -> Float + +/// Rounds the value to the next lowest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor(2.3) +/// 2.0 +/// ``` +/// +pub fn floor(x: Float) -> Float { + do_floor(x) +} + +@external(erlang, "math", "floor") +@external(javascript, "../gleam_stdlib.mjs", "floor") +fn do_floor(a: Float) -> Float + +/// Rounds the value to the nearest whole number as an `Int`. +/// +/// ## Examples +/// +/// ```gleam +/// > round(2.3) +/// 2 +/// ``` +/// +/// ```gleam +/// > round(2.5) +/// 3 +/// ``` +/// +pub fn round(x: Float) -> Int { + do_round(x) +} + +@target(erlang) +@external(erlang, "erlang", "round") +fn do_round(a: Float) -> Int + +@target(javascript) +fn do_round(x: Float) -> Int { + case x >=. 0.0 { + True -> js_round(x) + _ -> 0 - js_round(negate(x)) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "round") +fn js_round(a: Float) -> Int + +/// Returns the value as an `Int`, truncating all decimal digits. +/// +/// ## Examples +/// +/// ```gleam +/// > truncate(2.4343434847383438) +/// 2 +/// ``` +/// +pub fn truncate(x: Float) -> Int { + do_truncate(x) +} + +@external(erlang, "erlang", "trunc") +@external(javascript, "../gleam_stdlib.mjs", "truncate") +fn do_truncate(a: Float) -> Int + +/// Returns the absolute value of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12.5) +/// 12.5 +/// ``` +/// +/// ```gleam +/// > absolute_value(10.2) +/// 10.2 +/// ``` +/// +pub fn absolute_value(x: Float) -> Float { + case x >=. 0.0 { + True -> x + _ -> 0.0 -. x + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2.0, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2.0, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8.0, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4.0 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1.0, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { + let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 + // In the following check: + // 1. If the base is negative and the exponent is fractional then + // return an error as it will otherwise be an imaginary number + // 2. If the base is 0 and the exponent is negative then the expression + // is equivalent to the exponent divided by 0 and an error should be + // returned + case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { + True -> Error(Nil) + False -> Ok(do_power(base, exponent)) + } +} + +@external(erlang, "math", "pow") +@external(javascript, "../gleam_stdlib.mjs", "power") +fn do_power(a: Float, b: Float) -> Float + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4.0) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16.0) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Float) -> Result(Float, Nil) { + power(x, 0.5) +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1.0) +/// -1.0 +/// ``` +/// +pub fn negate(x: Float) -> Float { + -1.0 *. x +} + +/// Sums a list of `Float`s. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1.0, 2.2, 3.3]) +/// 6.5 +/// ``` +/// +pub fn sum(numbers: List(Float)) -> Float { + numbers + |> do_sum(0.0) +} + +fn do_sum(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x +. initial) + } +} + +/// Multiplies a list of `Float`s and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2.5, 3.2, 4.2]) +/// 33.6 +/// ``` +/// +pub fn product(numbers: List(Float)) -> Float { + case numbers { + [] -> 1.0 + _ -> do_product(numbers, 1.0) + } +} + +fn do_product(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x *. initial) + } +} + +/// Generates a random float between the given minimum and maximum values. +/// +/// +/// ## Examples +/// +/// ```gleam +/// > random(1.0, 5.0) +/// 2.646355926896028 +/// ``` +/// +pub fn random(min: Float, max: Float) -> Float { + do_random_uniform() *. { max -. min } +. min +} + +/// Returns a random float uniformly distributed in the value range +/// 0.0 =< X < 1.0 and updates the state in the process dictionary. +/// See: +/// +@external(erlang, "rand", "uniform") +@external(javascript, "../gleam_stdlib.mjs", "random_uniform") +fn do_random_uniform() -> Float + +/// Returns division of the inputs as a `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0.0, 1.0) +/// Ok(1.0) +/// ``` +/// +/// ```gleam +/// > divide(1.0, 0.0) +/// Error(Nil) +/// ``` +/// +pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { + case b { + 0.0 -> Error(Nil) + b -> Ok(a /. b) + } +} + +/// Adds two floats together. +/// +/// It's the function equivalent of the `+.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1.0, 2.0) +/// 3.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 0.0, add) +/// 6.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> add(2.0) +/// 5.0 +/// ``` +/// +pub fn add(a: Float, b: Float) -> Float { + a +. b +} + +/// Multiplies two floats together. +/// +/// It's the function equivalent of the `*.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2.0, 4.0) +/// 8.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) +/// 24.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> multiply(2.0) +/// 6.0 +/// ``` +/// +pub fn multiply(a: Float, b: Float) -> Float { + a *. b +} + +/// Subtracts one float from another. +/// +/// It's the function equivalent of the `-.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3.0, 1.0) +/// 2.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) +/// 4.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(_, 2.0) +/// 1.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(2.0, _) +/// -1.0 +/// ``` +/// +pub fn subtract(a: Float, b: Float) -> Float { + a -. b +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam new file mode 100644 index 00000000000..daa997de92a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam @@ -0,0 +1,162 @@ +/// Takes two functions and chains them together to form one function that +/// takes the input from the first and returns the output of the second. +/// +pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { + fn(a) { fun2(fun1(a)) } +} + +/// Takes a function with `2` arguments (an arity of `2`), and returns the +/// curried equivalent. +/// +/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. +/// +/// ## Examples +/// +/// *Currying* creates a new function that is identical to the given function +/// except that arguments must now be supplied one by one over several function +/// calls. It thus is the process of taking a function with `n` arguments +/// and producing a sequence of `n` single-argument functions. Given: +/// +/// ```gleam +/// > fn my_fun(i: Int, s: String) -> String { ... } +/// ``` +/// +/// …calling `curry2(my_fun)` would return the curried equivalent, like so: +/// +/// ```gleam +/// > curry2(my_fun) +/// fn(Int) -> fn(String) -> String +/// ``` +/// +/// Currying is useful when you want to partially apply a function with +/// some arguments and then pass it somewhere else, for example: +/// +/// ```gleam +/// > import gleam/list +/// > let multiply = curry2(fn(x, y) { x * y }) +/// > let doubles = list.map([1, 2, 3], multiply(2)) +/// [2, 4, 6] +/// ``` +/// +pub fn curry2(fun: fn(a, b) -> value) { + fn(a) { fn(b) { fun(a, b) } } +} + +/// Takes a function with `3` arguments (an arity of `3`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry3(fun: fn(a, b, c) -> value) { + fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } +} + +/// Takes a function with `4` arguments (an arity of `4`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry4(fun: fn(a, b, c, d) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } +} + +/// Takes a function with `5` arguments (an arity of `5`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e) -> f` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry5(fun: fn(a, b, c, d, e) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } +} + +/// Takes a function with `6` arguments (an arity of `6`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e, f) -> g` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { + fn(a) { + fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } + } +} + +/// Takes a function that takes two arguments and returns a new function that +/// takes the same two arguments, but in reverse order. +/// +pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { + fn(b, a) { fun(a, b) } +} + +/// Takes a single argument and always returns its input value. +/// +pub fn identity(x: a) -> a { + x +} + +/// Takes a single argument and returns a new function that +/// ignores its argument and always returns the input value. +/// +pub fn constant(value: a) -> fn(b) -> a { + fn(_) { value } +} + +/// Takes an argument and a single function, +/// calls that function with that argument +/// and returns that argument instead of the function return value. +/// Useful for running synchronous side effects in a pipeline. +/// +pub fn tap(arg: a, effect: fn(a) -> b) -> a { + effect(arg) + arg +} + +/// Takes a function with arity one and an argument, +/// calls that function with the argument and returns the function return value. +/// +/// Useful for concisely calling functions returned as a part of a pipeline. +/// +/// ## Example +/// +/// ```gleam +/// > let doubler = fn() { +/// > fn(x: Int) { x * 2 } +/// > } +/// > +/// > doubler() +/// > |> apply1(2) +/// 4 +/// ``` +/// +pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { + fun(arg1) +} + +/// Takes a function with arity two and two arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { + fun(arg1, arg2) +} + +/// Takes a function with arity three and three arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { + fun(arg1, arg2, arg3) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam new file mode 100644 index 00000000000..d93c16afaf6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam @@ -0,0 +1,874 @@ +//// Functions for working with integers. +//// +//// ## Division by zero +//// +//// In Erlang division by zero results in a crash, however Gleam does not have +//// partial functions and operators in core so instead division by zero returns +//// zero, a behaviour taken from Pony, Coq, and Lean. +//// +//// This may seem unexpected at first, but it is no less mathematically valid +//// than crashing or returning a special value. Division by zero is undefined +//// in mathematics. + +import gleam/float +import gleam/order.{type Order} + +/// Returns the absolute value of the input. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12) +/// 12 +/// ``` +/// +/// ```gleam +/// > absolute_value(10) +/// 10 +/// ``` +/// +pub fn absolute_value(x: Int) -> Int { + case x >= 0 { + True -> x + False -> x * -1 + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { + base + |> to_float() + |> float.power(exponent) +} + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Int) -> Result(Float, Nil) { + x + |> to_float() + |> float.square_root() +} + +/// Parses a given string as an int if possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2") +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Int, Nil) { + do_parse(string) +} + +@external(erlang, "gleam_stdlib", "parse_int") +@external(javascript, "../gleam_stdlib.mjs", "parse_int") +fn do_parse(a: String) -> Result(Int, Nil) + +/// Parses a given string as an int in a given base if possible. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > base_parse("10", 2) +/// Ok(2) +/// +/// > base_parse("30", 16) +/// Ok(48) +/// +/// > base_parse("1C", 36) +/// Ok(48) +/// +/// > base_parse("48", 1) +/// Error(Nil) +/// +/// > base_parse("48", 37) +/// Error(Nil) +/// ``` +/// +pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { + case base >= 2 && base <= 36 { + True -> do_base_parse(string, base) + False -> Error(Nil) + } +} + +@external(erlang, "gleam_stdlib", "int_from_base_string") +@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") +fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) + +/// Prints a given int to a string. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2) +/// "2" +/// ``` +/// +pub fn to_string(x: Int) { + do_to_string(x) +} + +@external(erlang, "erlang", "integer_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "to_string") +fn do_to_string(a: Int) -> String + +/// Error value when trying to operate with a base out of the allowed range. +/// +pub type InvalidBase { + InvalidBase +} + +/// Prints a given int to a string using the base number provided. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. +/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base_string(2, 2) +/// Ok("10") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 16) +/// Ok("30") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 36) +/// Ok("1C") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 37) +/// Error(InvalidBase) +/// ``` +/// +pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { + case base >= 2 && base <= 36 { + True -> Ok(do_to_base_string(x, base)) + False -> Error(InvalidBase) + } +} + +@external(erlang, "erlang", "integer_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") +fn do_to_base_string(a: Int, b: Int) -> String + +/// Prints a given int to a string using base-2. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base2(2) +/// "10" +/// ``` +/// +pub fn to_base2(x: Int) -> String { + do_to_base_string(x, 2) +} + +/// Prints a given int to a string using base-8. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base8(15) +/// "17" +/// ``` +/// +pub fn to_base8(x: Int) -> String { + do_to_base_string(x, 8) +} + +/// Prints a given int to a string using base-16. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base16(48) +/// "30" +/// ``` +/// +pub fn to_base16(x: Int) -> String { + do_to_base_string(x, 16) +} + +/// Prints a given int to a string using base-36. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base36(48) +/// "1C" +/// ``` +/// +pub fn to_base36(x: Int) -> String { + do_to_base_string(x, 36) +} + +/// Takes an int and returns its value as a float. +/// +/// ## Examples +/// +/// ```gleam +/// > to_float(5) +/// 5.0 +/// ``` +/// +/// ```gleam +/// > to_float(0) +/// 0.0 +/// ``` +/// +/// ```gleam +/// > to_float(-3) +/// -3.0 +/// ``` +/// +pub fn to_float(x: Int) -> Float { + do_to_float(x) +} + +@external(erlang, "erlang", "float") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_to_float(a: Int) -> Float + +/// Restricts an int between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(40, min: 50, max: 60) +/// 50 +/// ``` +/// +pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two ints, returning an order. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2, 3) +/// Lt +/// ``` +/// +/// ```gleam +/// > compare(4, 3) +/// Gt +/// ``` +/// +/// ```gleam +/// > compare(3, 3) +/// Eq +/// ``` +/// +pub fn compare(a: Int, with b: Int) -> Order { + case a == b { + True -> order.Eq + False -> + case a < b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two ints, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2, 3) +/// 2 +/// ``` +/// +pub fn min(a: Int, b: Int) -> Int { + case a < b { + True -> a + False -> b + } +} + +/// Compares two ints, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2, 3) +/// 3 +/// ``` +/// +pub fn max(a: Int, b: Int) -> Int { + case a > b { + True -> a + False -> b + } +} + +/// Returns whether the value provided is even. +/// +/// ## Examples +/// +/// ```gleam +/// > is_even(2) +/// True +/// ``` +/// +/// ```gleam +/// > is_even(3) +/// False +/// ``` +/// +pub fn is_even(x: Int) -> Bool { + x % 2 == 0 +} + +/// Returns whether the value provided is odd. +/// +/// ## Examples +/// +/// ```gleam +/// > is_odd(3) +/// True +/// ``` +/// +/// ```gleam +/// > is_odd(2) +/// False +/// ``` +/// +pub fn is_odd(x: Int) -> Bool { + x % 2 != 0 +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1) +/// -1 +/// ``` +/// +pub fn negate(x: Int) -> Int { + -1 * x +} + +/// Sums a list of ints. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1, 2, 3]) +/// 6 +/// ``` +/// +pub fn sum(numbers: List(Int)) -> Int { + numbers + |> do_sum(0) +} + +fn do_sum(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x + initial) + } +} + +/// Multiplies a list of ints and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2, 3, 4]) +/// 24 +/// ``` +/// +pub fn product(numbers: List(Int)) -> Int { + case numbers { + [] -> 1 + _ -> do_product(numbers, 1) + } +} + +fn do_product(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x * initial) + } +} + +/// Splits an integer into its digit representation in the specified base +/// +/// ## Examples +/// +/// ```gleam +/// > digits(234, 10) +/// Ok([2,3,4]) +/// ``` +/// +/// ```gleam +/// > digits(234, 1) +/// Error(InvalidBase) +/// ``` +/// +pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> Ok(do_digits(x, base, [])) + } +} + +fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { + case absolute_value(x) < base { + True -> [x, ..acc] + False -> do_digits(x / base, base, [x % base, ..acc]) + } +} + +/// Joins a list of digits into a single value. +/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. +/// +/// ## Examples +/// +/// ```gleam +/// > undigits([2,3,4], 10) +/// Ok(234) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 2) +/// Error(InvalidBase) +/// ``` +/// +pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> do_undigits(numbers, base, 0) + } +} + +fn do_undigits( + numbers: List(Int), + base: Int, + acc: Int, +) -> Result(Int, InvalidBase) { + case numbers { + [] -> Ok(acc) + [digit, ..] if digit >= base -> Error(InvalidBase) + [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) + } +} + +/// Generates a random int between the given minimum and maximum values. +/// +/// ## Examples +/// +/// ```gleam +/// > random(1, 5) +/// 2 +/// ``` +/// +pub fn random(min: Int, max: Int) -> Int { + float.random(to_float(min), to_float(max)) + |> float.floor() + |> float.round() +} + +/// Performs a truncated integer division. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0, 1) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > divide(-99, 2) +/// Ok(-49) +/// ``` +/// +pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend / divisor) + } +} + +/// Computes the remainder of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > remainder(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > remainder(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: 3) +/// Ok(-1) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: -3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend % divisor) + } +} + +/// Computes the modulo of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > modulo(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > modulo(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: 3) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: -3) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + _ -> { + let remainder = dividend % divisor + case remainder * divisor < 0 { + True -> Ok(remainder + divisor) + False -> Ok(remainder) + } + } + } +} + +/// Performs a *floored* integer division, which means that the result will +/// always be rounded towards negative infinity. +/// +/// If you want to perform truncated integer division (rounding towards zero), +/// use `int.divide()` or the `/` operator instead. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor_divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > floor_divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > floor_divide(6, -4) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > floor_divide(-99, 2) +/// Ok(-50) +/// ``` +/// +pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> + case dividend * divisor < 0 && dividend % divisor != 0 { + True -> Ok(dividend / divisor - 1) + False -> Ok(dividend / divisor) + } + } +} + +/// Adds two integers together. +/// +/// It's the function equivalent of the `+` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1, 2) +/// 3 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 0, add) +/// 6 +/// ``` +/// +/// ```gleam +/// > 3 |> add(2) +/// 5 +/// ``` +/// +pub fn add(a: Int, b: Int) -> Int { + a + b +} + +/// Multiplies two integers together. +/// +/// It's the function equivalent of the `*` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2, 4) +/// 8 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2, 3, 4], 1, multiply) +/// 24 +/// ``` +/// +/// ```gleam +/// > 3 |> multiply(2) +/// 6 +/// ``` +/// +pub fn multiply(a: Int, b: Int) -> Int { + a * b +} + +/// Subtracts one int from another. +/// +/// It's the function equivalent of the `-` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3, 1) +/// 2.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 10, subtract) +/// 4 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2) +/// 1 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2, _) +/// -1 +/// ``` +/// +pub fn subtract(a: Int, b: Int) -> Int { + a - b +} + +/// Calculates the bitwise AND of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "band") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") +pub fn bitwise_and(x: Int, y: Int) -> Int + +/// Calculates the bitwise NOT of its argument. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bnot") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") +pub fn bitwise_not(x: Int) -> Int + +/// Calculates the bitwise OR of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bor") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") +pub fn bitwise_or(x: Int, y: Int) -> Int + +/// Calculates the bitwise XOR of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bxor") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") +pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int + +/// Calculates the result of an arithmetic left bitshift. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bsl") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") +pub fn bitwise_shift_left(x: Int, y: Int) -> Int + +/// Calculates the result of an arithmetic right bitshift. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bsr") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") +pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam new file mode 100644 index 00000000000..0c0a3eeffe0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam @@ -0,0 +1,117 @@ +import gleam/string + +/// Writes a string to standard output. +/// +/// If you want your output to be printed on its own line see `println`. +/// +/// ## Example +/// +/// ```gleam +/// > io.print("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn print(string: String) -> Nil { + do_print(string) +} + +@external(erlang, "gleam_stdlib", "print") +@external(javascript, "../gleam_stdlib.mjs", "print") +fn do_print(string string: String) -> Nil + +/// Writes a string to standard error. +/// +/// If you want your output to be printed on its own line see `println_error`. +/// +/// ## Example +/// +/// ``` +/// > io.print_error("Hi pop") +/// // -> Hi pop +/// Nil +/// ``` +/// +pub fn print_error(string: String) -> Nil { + do_print_error(string) +} + +@external(erlang, "gleam_stdlib", "print_error") +@external(javascript, "../gleam_stdlib.mjs", "print_error") +fn do_print_error(string string: String) -> Nil + +/// Writes a string to standard output, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println(string: String) -> Nil { + do_println(string) +} + +@external(erlang, "gleam_stdlib", "println") +@external(javascript, "../gleam_stdlib.mjs", "console_log") +fn do_println(string string: String) -> Nil + +/// Writes a string to standard error, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println_error("Hi pop") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println_error(string: String) -> Nil { + do_println_error(string) +} + +@external(erlang, "gleam_stdlib", "println_error") +@external(javascript, "../gleam_stdlib.mjs", "console_error") +fn do_println_error(string string: String) -> Nil + +/// Prints a value to standard error (stderr) yielding Gleam syntax. +/// +/// The value is returned after being printed so it can be used in pipelines. +/// +/// ## Example +/// +/// ```gleam +/// > debug("Hi mum") +/// // -> <<"Hi mum">> +/// "Hi mum" +/// ``` +/// +/// ```gleam +/// > debug(Ok(1)) +/// // -> {ok, 1} +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > import list +/// > [1, 2] +/// > |> list.map(fn(x) { x + 1 }) +/// > |> debug +/// > |> list.map(fn(x) { x * 2 }) +/// // -> [2, 3] +/// [4, 6] +/// ``` +/// +pub fn debug(term: anything) -> anything { + term + |> string.inspect + |> do_debug_println + + term +} + +@external(erlang, "gleam_stdlib", "println_error") +@external(javascript, "../gleam_stdlib.mjs", "print_debug") +fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam new file mode 100644 index 00000000000..c57e7fd9473 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam @@ -0,0 +1,1530 @@ +import gleam/result +import gleam/int +import gleam/list +import gleam/dict.{type Dict} +import gleam/option.{type Option, None, Some} +import gleam/order + +// Internal private representation of an Iterator +type Action(element) { + // Dedicated to Electric Six + // https://youtu.be/_30t2dzEgiw?t=162 + Stop + Continue(element, fn() -> Action(element)) +} + +/// An iterator is a lazily evaluated sequence of element. +/// +/// Iterators are useful when working with collections that are too large to +/// fit in memory (or those that are infinite in size) as they only require the +/// elements currently being processed to be in memory. +/// +/// As a lazy data structure no work is done when an iterator is filters, +/// mapped, etc, instead a new iterator is returned with these transformations +/// applied to the stream. Once the stream has all the required transformations +/// applied it can be evaluated using functions such as `fold` and `to_list`. +/// +pub opaque type Iterator(element) { + Iterator(continuation: fn() -> Action(element)) +} + +// Public API for iteration +pub type Step(element, accumulator) { + Next(element: element, accumulator: accumulator) + Done +} + +// Shortcut for an empty iterator. +fn stop() -> Action(element) { + Stop +} + +// Creating Iterators +fn do_unfold( + initial: acc, + f: fn(acc) -> Step(element, acc), +) -> fn() -> Action(element) { + fn() { + case f(initial) { + Next(x, acc) -> Continue(x, do_unfold(acc, f)) + Done -> Stop + } + } +} + +/// Creates an iterator from a given function and accumulator. +/// +/// The function is called on the accumulator and returns either `Done`, +/// indicating the iterator has no more elements, or `Next` which contains a +/// new element and accumulator. The element is yielded by the iterator and the +/// new accumulator is used with the function to compute the next element in +/// the sequence. +/// +/// ## Examples +/// +/// ```gleam +/// > unfold(from: 5, with: fn(n) { +/// > case n { +/// > 0 -> Done +/// > n -> Next(element: n, accumulator: n - 1) +/// > } +/// > }) +/// > |> to_list +/// [5, 4, 3, 2, 1] +/// ``` +/// +pub fn unfold( + from initial: acc, + with f: fn(acc) -> Step(element, acc), +) -> Iterator(element) { + initial + |> do_unfold(f) + |> Iterator +} + +// TODO: test +/// Creates an iterator that yields values created by calling a given function +/// repeatedly. +/// +pub fn repeatedly(f: fn() -> element) -> Iterator(element) { + unfold(Nil, fn(_) { Next(f(), Nil) }) +} + +/// Creates an iterator that returns the same value infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat(10) +/// > |> take(4) +/// > |> to_list +/// [10, 10, 10, 10] +/// ``` +/// +pub fn repeat(x: element) -> Iterator(element) { + repeatedly(fn() { x }) +} + +/// Creates an iterator that yields each element from the given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn from_list(list: List(element)) -> Iterator(element) { + let yield = fn(acc) { + case acc { + [] -> Done + [head, ..tail] -> Next(head, tail) + } + } + unfold(list, yield) +} + +// Consuming Iterators +fn do_transform( + continuation: fn() -> Action(a), + state: acc, + f: fn(acc, a) -> Step(b, acc), +) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> + case f(state, el) { + Done -> Stop + Next(yield, next_state) -> + Continue(yield, do_transform(next, next_state, f)) + } + } + } +} + +/// Creates an iterator from an existing iterator +/// and a stateful function that may short-circuit. +/// +/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, +/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. +/// +/// ## Examples +/// +/// Approximate implementation of `index` in terms of `transform`: +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) +/// > |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +pub fn transform( + over iterator: Iterator(a), + from initial: acc, + with f: fn(acc, a) -> Step(b, acc), +) -> Iterator(b) { + do_transform(iterator.continuation, initial, f) + |> Iterator +} + +fn do_fold( + continuation: fn() -> Action(e), + f: fn(acc, e) -> acc, + accumulator: acc, +) -> acc { + case continuation() { + Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) + Stop -> accumulator + } +} + +/// Reduces an iterator of elements into a single value by calling a given +/// function on each element in turn. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// If you do not care about the end value and only wish to evaluate the +/// iterator for side effects consider using the `run` function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) +/// 10 +/// ``` +/// +pub fn fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> acc, +) -> acc { + iterator.continuation + |> do_fold(f, initial) +} + +// TODO: test +/// Evaluates all elements emitted by the given iterator. This function is useful for when +/// you wish to trigger any side effects that would occur when evaluating +/// the iterator. +/// +pub fn run(iterator: Iterator(e)) -> Nil { + fold(iterator, Nil, fn(_, _) { Nil }) +} + +/// Evaluates an iterator and returns all the elements as a list. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn to_list(iterator: Iterator(element)) -> List(element) { + iterator + |> fold([], fn(acc, e) { [e, ..acc] }) + |> list.reverse +} + +/// Eagerly accesses the first value of an iterator, returning a `Next` +/// that contains the first value and the rest of the iterator. +/// +/// If called on an empty iterator, `Done` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Next(first, rest) = [1, 2, 3, 4] +/// > |> from_list +/// > |> step +/// > first +/// 1 +/// ``` +/// +/// ```gleam +/// > rest |> to_list +/// [2, 3, 4] +/// ``` +/// +/// ```gleam +/// > empty() |> step +/// Done +/// ``` +/// +pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { + case iterator.continuation() { + Stop -> Done + Continue(e, a) -> Next(e, Iterator(a)) + } +} + +fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { + fn() { + case desired > 0 { + False -> Stop + True -> + case continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, do_take(next, desired - 1)) + } + } + } +} + +/// Creates an iterator that only yields the first `desired` elements. +/// +/// If the iterator does not have enough elements all of them are yielded. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2, 3] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + iterator.continuation + |> do_take(desired) + |> Iterator +} + +fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case desired > 0 { + True -> do_drop(next, desired - 1) + False -> Continue(e, next) + } + } +} + +/// Evaluates and discards the first N elements in an iterator, returning a new +/// iterator. +/// +/// If the iterator does not have enough elements an empty iterator is +/// returned. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [4, 5] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [] +/// ``` +/// +pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + fn() { do_drop(iterator.continuation, desired) } + |> Iterator +} + +fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) + } + } +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { + iterator.continuation + |> do_map(f) + |> Iterator +} + +fn do_map2( + continuation1: fn() -> Action(a), + continuation2: fn() -> Action(b), + with fun: fn(a, b) -> c, +) -> fn() -> Action(c) { + fn() { + case continuation1() { + Stop -> Stop + Continue(a, next_a) -> + case continuation2() { + Stop -> Stop + Continue(b, next_b) -> + Continue(fun(a, b), do_map2(next_a, next_b, fun)) + } + } + } +} + +/// Combines two interators into a single one using the given function. +/// +/// If an iterator is longer than the other the extra elements are dropped. +/// +/// This function does not evaluate the elements of the two iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// let first = from_list([1, 2, 3]) +/// let second = from_list([4, 5, 6]) +/// map2(first, second, fn(x, y) { x + y }) |> to_list +/// // -> [5, 7, 9] +/// ``` +/// +/// ```gleam +/// let first = from_list([1, 2]) +/// let second = from_list(["a", "b", "c"]) +/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list +/// // -> [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2( + iterator1: Iterator(a), + iterator2: Iterator(b), + with fun: fn(a, b) -> c, +) -> Iterator(c) { + do_map2(iterator1.continuation, iterator2.continuation, fun) + |> Iterator +} + +fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { + case first() { + Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) + Stop -> second() + } +} + +/// Appends two iterators, producing a new iterator. +/// +/// This function does not evaluate the elements of the iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> append([3, 4] |> from_list) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { + fn() { do_append(first.continuation, second.continuation) } + |> Iterator +} + +fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { + case flattened() { + Stop -> Stop + Continue(it, next_iterator) -> + do_append(it.continuation, fn() { do_flatten(next_iterator) }) + } +} + +/// Flattens an iterator of iterators, creating a new iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([[1, 2], [3, 4]]) +/// > |> map(from_list) +/// > |> flatten +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { + fn() { do_flatten(iterator.continuation) } + |> Iterator +} + +/// Joins a list of iterators into a single iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [[1, 2], [3, 4]] +/// > |> map(from_list) +/// > |> concat +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { + flatten(from_list(iterators)) +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator and then flattening the +/// results. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) +/// > |> to_list +/// [1, 2, 2, 3] +/// ``` +/// +pub fn flat_map( + over iterator: Iterator(a), + with f: fn(a) -> Iterator(b), +) -> Iterator(b) { + iterator + |> map(f) + |> flatten +} + +fn do_filter( + continuation: fn() -> Action(e), + predicate: fn(e) -> Bool, +) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, iterator) -> + case predicate(e) { + True -> Continue(e, fn() { do_filter(iterator, predicate) }) + False -> do_filter(iterator, predicate) + } + } +} + +/// Creates an iterator from an existing iterator and a predicate function. +/// +/// The new iterator will contain elements from the first iterator for which +/// the given function returns `True`. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> filter(int.is_even) +/// > |> to_list +/// [2, 4] +/// ``` +/// +pub fn filter( + iterator: Iterator(a), + keeping predicate: fn(a) -> Bool, +) -> Iterator(a) { + fn() { do_filter(iterator.continuation, predicate) } + |> Iterator +} + +/// Creates an iterator that repeats a given iterator infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> cycle +/// > |> take(6) +/// > |> to_list +/// [1, 2, 1, 2, 1, 2] +/// ``` +/// +pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { + repeat(iterator) + |> flatten +} + +/// Creates an iterator of ints, starting at a given start int and stepping by +/// one to a given end int. +/// +/// ## Examples +/// +/// ```gleam +/// > range(from: 1, to: 5) |> to_list +/// [1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(from: 1, to: -2) |> to_list +/// [1, 0, -1, -2] +/// ``` +/// +/// ```gleam +/// > range(from: 0, to: 0) |> to_list +/// [0] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { + case int.compare(start, stop) { + order.Eq -> once(fn() { start }) + order.Gt -> + unfold( + from: start, + with: fn(current) { + case current < stop { + False -> Next(current, current - 1) + True -> Done + } + }, + ) + + order.Lt -> + unfold( + from: start, + with: fn(current) { + case current > stop { + False -> Next(current, current + 1) + True -> Done + } + }, + ) + } +} + +fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { + case continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + case f(e) { + True -> Ok(e) + False -> do_find(next, f) + } + } +} + +/// Finds the first element in a given iterator for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if the function does not return `True` for any of the +/// elements. +/// +/// ## Examples +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find(empty(), fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: Iterator(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + haystack.continuation + |> do_find(is_desired) +} + +fn do_index( + continuation: fn() -> Action(element), + next: Int, +) -> fn() -> Action(#(Int, element)) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> + Continue(#(next, e), do_index(continuation, next + 1)) + } + } +} + +/// Wraps values yielded from an iterator with indices, starting from 0. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) |> index |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +/// +pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { + iterator.continuation + |> do_index(0) + |> Iterator +} + +/// Creates an iterator that inifinitely applies a function to a value. +/// +/// ## Examples +/// +/// ```gleam +/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list +/// [1, 3, 9, 27, 81] +/// ``` +/// +pub fn iterate( + from initial: element, + with f: fn(element) -> element, +) -> Iterator(element) { + unfold(initial, fn(element) { Next(element, f(element)) }) +} + +fn do_take_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> fn() -> Action(element) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Stop + True -> Continue(e, do_take_while(next, predicate)) + } + } + } +} + +/// Creates an iterator that yields elements while the predicate returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 2, 4]) +/// > |> take_while(satisfying: fn(x) { x < 3 }) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + iterator.continuation + |> do_take_while(predicate) + |> Iterator +} + +fn do_drop_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Continue(e, next) + True -> do_drop_while(next, predicate) + } + } +} + +/// Creates an iterator that drops elements while the predicate returns `True`, +/// and then yields the remaining elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 2, 5]) +/// > |> drop_while(satisfying: fn(x) { x < 4 }) +/// > |> to_list +/// [4, 2, 5] +/// ``` +/// +pub fn drop_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + fn() { do_drop_while(iterator.continuation, predicate) } + |> Iterator +} + +fn do_scan( + continuation: fn() -> Action(element), + f: fn(acc, element) -> acc, + accumulator: acc, +) -> fn() -> Action(acc) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> { + let accumulated = f(accumulator, el) + Continue(accumulated, do_scan(next, f, accumulated)) + } + } + } +} + +/// Creates an iterator from an existing iterator and a stateful function. +/// +/// Specifically, this behaves like `fold`, but yields intermediate results. +/// +/// ## Examples +/// +/// ```gleam +/// // Generate a sequence of partial sums +/// > from_list([1, 2, 3, 4, 5]) +/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) +/// > |> to_list +/// [1, 3, 6, 10, 15] +/// ``` +/// +pub fn scan( + over iterator: Iterator(element), + from initial: acc, + with f: fn(acc, element) -> acc, +) -> Iterator(acc) { + iterator.continuation + |> do_scan(f, initial) + |> Iterator +} + +fn do_zip( + left: fn() -> Action(a), + right: fn() -> Action(b), +) -> fn() -> Action(#(a, b)) { + fn() { + case left() { + Stop -> Stop + Continue(el_left, next_left) -> + case right() { + Stop -> Stop + Continue(el_right, next_right) -> + Continue(#(el_left, el_right), do_zip(next_left, next_right)) + } + } + } +} + +/// Zips two iterators together, emitting values from both +/// until the shorter one runs out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> zip(range(20, 30)) +/// > |> to_list +/// [#("a", 20), #("b", 21), #("c", 22)] +/// ``` +/// +pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { + do_zip(left.continuation, right.continuation) + |> Iterator +} + +// Result of collecting a single chunk by key +type Chunk(element, key) { + AnotherBy(List(element), key, element, fn() -> Action(element)) + LastBy(List(element)) +} + +fn next_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + current_chunk: List(element), +) -> Chunk(element, key) { + case continuation() { + Stop -> LastBy(list.reverse(current_chunk)) + Continue(e, next) -> { + let key = f(e) + case key == previous_key { + True -> next_chunk(next, f, key, [e, ..current_chunk]) + False -> AnotherBy(list.reverse(current_chunk), key, e, next) + } + } + } +} + +fn do_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + previous_element: element, +) -> Action(List(element)) { + case next_chunk(continuation, f, previous_key, [previous_element]) { + LastBy(chunk) -> Continue(chunk, stop) + AnotherBy(chunk, key, el, next) -> + Continue(chunk, fn() { do_chunk(next, f, key, el) }) + } +} + +/// Creates an iterator that emits chunks of elements +/// for which `f` returns the same value. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) +/// > |> chunk(by: fn(n) { n % 2 }) +/// > |> to_list +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk( + over iterator: Iterator(element), + by f: fn(element) -> key, +) -> Iterator(List(element)) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> do_chunk(next, f, f(e), e) + } + } + |> Iterator +} + +// Result of collecting a single sized chunk +type SizedChunk(element) { + Another(List(element), fn() -> Action(element)) + Last(List(element)) + NoMore +} + +fn next_sized_chunk( + continuation: fn() -> Action(element), + left: Int, + current_chunk: List(element), +) -> SizedChunk(element) { + case continuation() { + Stop -> + case current_chunk { + [] -> NoMore + remaining -> Last(list.reverse(remaining)) + } + Continue(e, next) -> { + let chunk = [e, ..current_chunk] + case left > 1 { + False -> Another(list.reverse(chunk), next) + True -> next_sized_chunk(next, left - 1, chunk) + } + } + } +} + +fn do_sized_chunk( + continuation: fn() -> Action(element), + count: Int, +) -> fn() -> Action(List(element)) { + fn() { + case next_sized_chunk(continuation, count, []) { + NoMore -> Stop + Last(chunk) -> Continue(chunk, stop) + Another(chunk, next_element) -> + Continue(chunk, do_sized_chunk(next_element, count)) + } + } +} + +/// Creates an iterator that emits chunks of given size. +/// +/// If the last chunk does not have `count` elements, it is yielded +/// as a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) +/// > |> sized_chunk(into: 2) +/// > |> to_list +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) +/// > |> sized_chunk(into: 3) +/// > |> to_list +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk( + over iterator: Iterator(element), + into count: Int, +) -> Iterator(List(element)) { + iterator.continuation + |> do_sized_chunk(count) + |> Iterator +} + +fn do_intersperse( + continuation: fn() -> Action(element), + separator: element, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> { + let next_interspersed = fn() { do_intersperse(next, separator) } + Continue(separator, fn() { Continue(e, next_interspersed) }) + } + } +} + +/// Creates an iterator that yields the given `elem` element +/// between elements emitted by the underlying iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() +/// > |> intersperse(with: 0) +/// > |> to_list +/// [] +/// +/// > from_list([1]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1] +/// +/// > from_list([1, 2, 3, 4, 5]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1, 0, 2, 0, 3, 0, 4, 0, 5] +/// ``` +/// +pub fn intersperse( + over iterator: Iterator(element), + with elem: element, +) -> Iterator(element) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) + } + } + |> Iterator +} + +fn do_any( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> False + Continue(e, next) -> + case predicate(e) { + True -> True + False -> do_any(next, predicate) + } + } +} + +/// Returns `True` if any element emitted by the iterator satisfies the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a satisfying element. +/// +/// An empty iterator results in `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn any( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_any(predicate) +} + +fn do_all( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> True + Continue(e, next) -> + case predicate(e) { + True -> do_all(next, predicate) + False -> False + } + } +} + +/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a non-satisfying element. +/// +/// An empty iterator results in `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn all( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_all(predicate) +} + +fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { + fn(maybe_group) { + case maybe_group { + Some(group) -> [el, ..group] + None -> [el] + } + } +} + +fn group_updater( + f: fn(element) -> key, +) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { + fn(groups, elem) { + groups + |> dict.update(f(elem), update_group_with(elem)) + } +} + +/// Returns a `Dict(k, List(element))` of elements from the given iterator +/// grouped with the given key function. +/// +/// The order within each group is preserved from the iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) +/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) +/// ``` +/// +pub fn group( + in iterator: Iterator(element), + by key: fn(element) -> key, +) -> Dict(key, List(element)) { + iterator + |> fold(dict.new(), group_updater(key)) + |> dict.map_values(fn(_, group) { list.reverse(group) }) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first yielded element +/// and combines it with each subsequent element in turn using the given function. +/// The function is called as `f(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce( + over iterator: Iterator(e), + with f: fn(e, e) -> e, +) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + do_fold(next, f, e) + |> Ok + } +} + +/// Returns the last element in the given iterator. +/// +/// Returns `Error(Nil)` if the iterator is empty. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> last +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > range(1, 10) |> last +/// Ok(9) +/// ``` +/// +pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { + iterator + |> reduce(fn(_, elem) { elem }) +} + +/// Creates an iterator that yields no elements. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> to_list +/// [] +/// ``` +/// +pub fn empty() -> Iterator(element) { + Iterator(stop) +} + +/// Creates an iterator that yields exactly one element provided by calling the given function. +/// +/// ## Examples +/// +/// ```gleam +/// > once(fn() { 1 }) |> to_list +/// [1] +/// ``` +/// +pub fn once(f: fn() -> element) -> Iterator(element) { + fn() { Continue(f(), stop) } + |> Iterator +} + +/// Creates an iterator that yields the given element exactly once. +/// +/// ## Examples +/// +/// ```gleam +/// > single(1) |> to_list +/// [1] +/// ``` +/// +pub fn single(elem: element) -> Iterator(element) { + once(fn() { elem }) +} + +fn do_interleave( + current: fn() -> Action(element), + next: fn() -> Action(element), +) -> Action(element) { + case current() { + Stop -> next() + Continue(e, next_other) -> + Continue(e, fn() { do_interleave(next, next_other) }) + } +} + +/// Creates an iterator that alternates between the two given iterators +/// until both have run out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list +/// [1, 11, 2, 12, 3, 13, 4, 14] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list +/// [1, 100, 2, 3, 4] +/// ``` +/// +pub fn interleave( + left: Iterator(element), + with right: Iterator(element), +) -> Iterator(element) { + fn() { do_interleave(left.continuation, right.continuation) } + |> Iterator +} + +fn do_fold_until( + continuation: fn() -> Action(e), + f: fn(acc, e) -> list.ContinueOrStop(acc), + accumulator: acc, +) -> acc { + case continuation() { + Stop -> accumulator + Continue(elem, next) -> + case f(accumulator, elem) { + list.Continue(accumulator) -> do_fold_until(next, f, accumulator) + list.Stop(accumulator) -> accumulator + } + } +} + +/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given +/// function on each element in turn, but uses `list.ContinueOrStop` to determine +/// whether or not to keep iterating. +/// +/// If called on an iterator of infinite length then this function will only ever +/// return if the function returns `list.Stop`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > let f = fn(acc, e) { +/// > case e { +/// > _ if e < 4 -> list.Continue(e + acc) +/// > _ -> list.Stop(acc) +/// > } +/// > } +/// > +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold_until(from: acc, with: f) +/// 6 +/// ``` +/// +pub fn fold_until( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> list.ContinueOrStop(acc), +) -> acc { + iterator.continuation + |> do_fold_until(f, initial) +} + +fn do_try_fold( + over continuation: fn() -> Action(a), + with f: fn(acc, a) -> Result(acc, err), + from accumulator: acc, +) -> Result(acc, err) { + case continuation() { + Stop -> Ok(accumulator) + Continue(elem, next) -> { + use accumulator <- result.try(f(accumulator, elem)) + do_try_fold(next, f, accumulator) + } + } +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> iterator.from_list() +/// > |> try_fold(0, fn(acc, i) { +/// > case i < 3 { +/// > True -> Ok(acc + i) +/// > False -> Error(Nil) +/// > } +/// > }) +/// Error(Nil) +/// ``` +/// +pub fn try_fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> Result(acc, err), +) -> Result(acc, err) { + iterator.continuation + |> do_try_fold(f, initial) +} + +/// Returns the first element yielded by the given iterator, if it exists, +/// or `Error(Nil)` otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) |> first +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > empty() |> first +/// Error(Nil) +/// ``` +pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, _) -> Ok(e) + } +} + +/// Returns nth element yielded by the given iterator, where `0` means the first element. +/// +/// If there are not enough elements in the iterator, `Error(Nil)` is returned. +/// +/// For any `index` less than `0` this function behaves as if it was set to `0`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(2) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(4) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > empty() |> at(0) +/// Error(Nil) +/// ``` +/// +pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { + iterator + |> drop(index) + |> first +} + +fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { + case continuation() { + Stop -> length + Continue(_, next) -> do_length(next, length + 1) + } +} + +/// Counts the number of elements in the given iterator. +/// +/// This function has to traverse the entire iterator to count its elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> length +/// 0 +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> length +/// 4 +/// ``` +/// +pub fn length(over iterator: Iterator(e)) -> Int { + iterator.continuation + |> do_length(0) +} + +/// Traverse an iterator, calling a function on each element. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> each(io.println) +/// Nil +/// ``` +/// +/// ```gleam +/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) +/// // -> Tom +/// // -> Malory +/// // -> Louis +/// Nil +/// ``` +/// +pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { + iterator + |> map(f) + |> run +} + +/// Add a new element to the start of an iterator. +/// +/// This function is for use with `use` expressions, to replicate the behaviour +/// of the `yield` keyword found in other languages. +/// +/// ## Examples +/// +/// ```gleam +/// > use <- iterator.yield(1) +/// > use <- iterator.yield(2) +/// > use <- iterator.yield(3) +/// > iterator.empty() +/// iterator.from_list([1, 2, 3]) +/// ``` +/// +pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { + Iterator(fn() { Continue(element, next().continuation) }) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam new file mode 100644 index 00000000000..a5cffa9b951 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam @@ -0,0 +1,2154 @@ +//// Lists are an ordered sequence of elements and are one of the most common +//// data types in Gleam. +//// +//// New elements can be added and removed from the front of a list in +//// constant time, while adding and removing from the end requires traversing +//// the copying the whole list, so keep this in mind when designing your +//// programs. +//// +//// There is a dedicated syntax for prefixing to a list: +//// +//// ```gleam +//// let new_list = [1, 2, ..existing_list] +//// ``` +//// +//// And a matching syntax for getting the first elements of a list: +//// +//// ```gleam +//// case list { +//// [first_element, ..rest] -> first_element +//// _ -> "this pattern matches when the list is empty" +//// } +//// ``` +//// + +import gleam/int +import gleam/float +import gleam/order.{type Order} +import gleam/pair +import gleam/dict.{type Dict} + +/// An error value returned by the `strict_zip` function. +/// +pub type LengthMismatch { + LengthMismatch +} + +/// Counts the number of elements in a given list. +/// +/// This function has to traverse the list to determine the number of elements, +/// so it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > length([]) +/// 0 +/// ``` +/// +/// ```gleam +/// > length([1]) +/// 1 +/// ``` +/// +/// ```gleam +/// > length([1, 2]) +/// 2 +/// ``` +/// +pub fn length(of list: List(a)) -> Int { + do_length(list) +} + +@target(erlang) +@external(erlang, "erlang", "length") +fn do_length(a: List(a)) -> Int + +@target(javascript) +fn do_length(list: List(a)) -> Int { + do_length_acc(list, 0) +} + +@target(javascript) +fn do_length_acc(list: List(a), count: Int) -> Int { + case list { + [_, ..list] -> do_length_acc(list, count + 1) + _ -> count + } +} + +/// Creates a new list from a given list containing the same elements but in the +/// opposite order. +/// +/// This function has to traverse the list to create the new reversed list, so +/// it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse([]) +/// [] +/// ``` +/// +/// ```gleam +/// > reverse([1]) +/// [1] +/// ``` +/// +/// ```gleam +/// > reverse([1, 2]) +/// [2, 1] +/// ``` +/// +pub fn reverse(xs: List(a)) -> List(a) { + do_reverse(xs) +} + +@target(erlang) +@external(erlang, "lists", "reverse") +fn do_reverse(a: List(a)) -> List(a) + +@target(javascript) +fn do_reverse(list) { + do_reverse_acc(list, []) +} + +@target(javascript) +fn do_reverse_acc(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) + } +} + +/// Determines whether or not the list is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty([]) +/// True +/// ``` +/// +/// ```gleam +/// > is_empty([1]) +/// False +/// ``` +/// +/// ```gleam +/// > is_empty([1, 1]) +/// False +/// ``` +/// +pub fn is_empty(list: List(a)) -> Bool { + list == [] +} + +/// Determines whether or not a given element exists within a given list. +/// +/// This function traverses the list to find the element, so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [0] |> contains(any: 0) +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 0] |> contains(any: 0) +/// True +/// ``` +/// +pub fn contains(list: List(a), any elem: a) -> Bool { + case list { + [] -> False + [first, ..] if first == elem -> True + [_, ..rest] -> contains(rest, elem) + } +} + +/// Gets the first element from the start of the list, if there is one. +/// +/// ## Examples +/// +/// ```gleam +/// > first([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first([0]) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > first([1, 2]) +/// Ok(1) +/// ``` +/// +pub fn first(list: List(a)) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [x, ..] -> Ok(x) + } +} + +/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is +/// returned. +/// +/// This function runs in constant time and does not make a copy of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > rest([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > rest([0]) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > rest([1, 2]) +/// Ok([2]) +/// ``` +/// +pub fn rest(list: List(a)) -> Result(List(a), Nil) { + case list { + [] -> Error(Nil) + [_, ..xs] -> Ok(xs) + } +} + +fn update_group( + f: fn(element) -> key, +) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { + fn(groups, elem) { + case dict.get(groups, f(elem)) { + Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) + Error(_) -> dict.insert(groups, f(elem), [elem]) + } + } +} + +/// Takes a list and groups the values by a key +/// which is built from a key function. +/// +/// Does not preserve the initial value order. +/// +/// ## Examples +/// +/// ```gleam +/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] +/// |> group(by: fn(i) { +/// case i { +/// Ok(_) -> "Successful" +/// Error(_) -> "Failed" +/// } +/// }) +/// |> dict.to_list +/// +/// [ +/// #("Failed", [Error("Wrong")]), +/// #("Successful", [Ok(73), Ok(200), Ok(3)]) +/// ] +/// +/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) +/// |> dict.to_list +/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] +/// ``` +/// +pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { + fold(list, dict.new(), update_group(key)) +} + +fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + True -> [x, ..acc] + False -> acc + } + do_filter(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) +/// [4, 6] +/// ``` +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) +/// [] +/// ``` +/// +pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { + do_filter(list, predicate, []) +} + +fn do_filter_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + Ok(x) -> [x, ..acc] + Error(_) -> acc + } + do_filter_map(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `Ok(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], Error) +/// [] +/// ``` +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) +/// [3, 5, 7, 2] +/// ``` +/// +pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { + do_filter_map(list, fun, []) +} + +fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one. +/// +/// ## Examples +/// +/// ```gleam +/// > map([2, 4, 6], fn(x) { x * 2 }) +/// [4, 8, 12] +/// ``` +/// +pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { + do_map(list, fun, []) +} + +/// Combines two lists into a single list using the given function. +/// +/// If a list is longer than the other the extra elements are dropped. +/// +/// ## Examples +/// +/// ```gleam +/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) +/// [5, 7, 9] +/// ``` +/// +/// ```gleam +/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) +/// [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { + do_map2(list1, list2, fun, []) +} + +fn do_map2( + list1: List(a), + list2: List(b), + fun: fn(a, b) -> c, + acc: List(c), +) -> List(c) { + case list1, list2 { + [], _ | _, [] -> reverse(acc) + [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) + } +} + +/// Similar to `map` but also lets you pass around an accumulated value. +/// +/// ## Examples +/// +/// ```gleam +/// > map_fold( +/// over: [1, 2, 3], +/// from: 100, +/// with: fn(memo, i) { #(memo + i, i * 2) } +/// ) +/// #(106, [2, 4, 6]) +/// ``` +/// +pub fn map_fold( + over list: List(a), + from acc: acc, + with fun: fn(acc, a) -> #(acc, b), +) -> #(acc, List(b)) { + fold( + over: list, + from: #(acc, []), + with: fn(acc, item) { + let #(current_acc, items) = acc + let #(next_acc, next_item) = fun(current_acc, item) + #(next_acc, [next_item, ..items]) + }, + ) + |> pair.map_second(reverse) +} + +fn do_index_map( + list: List(a), + fun: fn(Int, a) -> b, + index: Int, + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let acc = [fun(index, x), ..acc] + do_index_map(xs, fun, index + 1, acc) + } + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one and their index. +/// +/// The index starts at 0, so the first element is 0, the second is 1, and so +/// on. +/// +/// ## Examples +/// +/// ```gleam +/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) +/// [#(0, "a"), #(1, "b")] +/// ``` +/// +pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { + do_index_map(list, fun, 0, []) +} + +fn do_try_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> Result(List(b), e) { + case list { + [] -> Ok(reverse(acc)) + [x, ..xs] -> + case fun(x) { + Ok(y) -> do_try_map(xs, fun, [y, ..acc]) + Error(error) -> Error(error) + } + } +} + +/// Takes a function that returns a `Result` and applies it to each element in a +/// given list in turn. +/// +/// If the function returns `Ok(new_value)` for all elements in the list then a +/// list of the new values is returned. +/// +/// If the function returns `Error(reason)` for any of the elements then it is +/// returned immediately. None of the elements in the list are processed after +/// one returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) +/// Ok([3, 4, 5]) +/// ``` +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(_) { Error(0) }) +/// Error(0) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [2, 3]], first) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [], [2]], first) +/// Error(Nil) +/// ``` +/// +pub fn try_map( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(List(b), e) { + do_try_map(list, fun, []) +} + +/// Returns a list that is the given list with up to the given number of +/// elements removed from the front of the list. +/// +/// If the element has less than the number of elements an empty list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 2) +/// [3, 4] +/// ``` +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 9) +/// [] +/// ``` +/// +pub fn drop(from list: List(a), up_to n: Int) -> List(a) { + case n <= 0 { + True -> list + False -> + case list { + [] -> [] + [_, ..xs] -> drop(xs, n - 1) + } + } +} + +fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { + case n <= 0 { + True -> reverse(acc) + False -> + case list { + [] -> reverse(acc) + [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) + } + } +} + +/// Returns a list containing the first given number of elements from the given +/// list. +/// +/// If the element has less than the number of elements then the full list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > take([1, 2, 3, 4], 2) +/// [1, 2] +/// ``` +/// +/// ```gleam +/// > take([1, 2, 3, 4], 9) +/// [1, 2, 3, 4] +/// ``` +/// +pub fn take(from list: List(a), up_to n: Int) -> List(a) { + do_take(list, n, []) +} + +/// Returns a new empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// [] +/// ``` +/// +pub fn new() -> List(a) { + [] +} + +/// Joins one list onto the end of another. +/// +/// This function runs in linear time, and it traverses and copies the first +/// list. +/// +/// ## Examples +/// +/// ```gleam +/// > append([1, 2], [3]) +/// [1, 2, 3] +/// ``` +/// +pub fn append(first: List(a), second: List(a)) -> List(a) { + do_append(first, second) +} + +@target(erlang) +@external(erlang, "lists", "append") +fn do_append(a: List(a), b: List(a)) -> List(a) + +@target(javascript) +fn do_append(first: List(a), second: List(a)) -> List(a) { + do_append_acc(reverse(first), second) +} + +@target(javascript) +fn do_append_acc(first: List(a), second: List(a)) -> List(a) { + case first { + [] -> second + [item, ..rest] -> do_append_acc(rest, [item, ..second]) + } +} + +/// Prefixes an item to a list. This can also be done using the dedicated +/// syntax instead +/// +/// ```gleam +/// let new_list = [1, ..existing_list] +/// ``` +/// +pub fn prepend(to list: List(a), this item: a) -> List(a) { + [item, ..list] +} + +// Reverses a list and prepends it to another list +fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { + case prefix { + [] -> suffix + [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) + } +} + +fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { + case lists { + [] -> reverse(acc) + [list, ..further_lists] -> + do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) + } +} + +/// Joins a list of lists into a single list. +/// +/// This function traverses all elements twice. +/// +/// ## Examples +/// +/// ```gleam +/// > concat([[1], [2, 3], []]) +/// [1, 2, 3] +/// ``` +/// +pub fn concat(lists: List(List(a))) -> List(a) { + do_concat(lists, []) +} + +/// This is the same as `concat`: it joins a list of lists into a single +/// list. +/// +/// This function traverses all elements twice. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten([[1], [2, 3], []]) +/// [1, 2, 3] +/// ``` +/// +pub fn flatten(lists: List(List(a))) -> List(a) { + do_concat(lists, []) +} + +/// Maps the list with the given function into a list of lists, and then flattens it. +/// +/// ## Examples +/// +/// ```gleam +/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) +/// [2, 3, 4, 5, 6, 7] +/// ``` +/// +pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { + map(list, fun) + |> concat +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from left to right. +/// +/// `fold([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 1), 2), 3)`. +/// +/// This function runs in linear time. +/// +pub fn fold( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fold(rest, fun(initial, x), fun) + } +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from right to left. +/// +/// `fold_right([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 3), 2), 1)`. +/// +/// This function runs in linear time. +/// +/// Unlike `fold` this function is not tail recursive. Where possible use +/// `fold` instead as it will use less memory. +/// +pub fn fold_right( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fun(fold_right(rest, initial, fun), x) + } +} + +fn do_index_fold( + over: List(a), + acc: acc, + with: fn(acc, a, Int) -> acc, + index: Int, +) -> acc { + case over { + [] -> acc + [first, ..rest] -> + do_index_fold(rest, with(acc, first, index), with, index + 1) + } +} + +/// Like fold but the folding function also receives the index of the current element. +/// +/// ## Examples +/// +/// ```gleam +/// ["a", "b", "c"] +/// |> index_fold([], fn(acc, item, index) { ... }) +/// ``` +/// +pub fn index_fold( + over over: List(a), + from initial: acc, + with fun: fn(acc, a, Int) -> acc, +) -> acc { + do_index_fold(over, initial, fun, 0) +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> try_fold(0, fn(acc, i) { +/// case i < 3 { +/// True -> Ok(acc + i) +/// False -> Error(Nil) +/// } +/// }) +/// ``` +/// +pub fn try_fold( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> Result(acc, e), +) -> Result(acc, e) { + case collection { + [] -> Ok(accumulator) + [first, ..rest] -> + case fun(accumulator, first) { + Ok(result) -> try_fold(rest, result, fun) + Error(_) as error -> error + } + } +} + +pub type ContinueOrStop(a) { + Continue(a) + Stop(a) +} + +/// A variant of fold that allows to stop folding earlier. +/// +/// The folding function should return `ContinueOrStop(accumulator)`. +/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. +/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> fold_until(0, fn(acc, i) { +/// case i < 3 { +/// True -> Continue(acc + i) +/// False -> Stop(acc) +/// } +/// }) +/// ``` +/// +pub fn fold_until( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> ContinueOrStop(acc), +) -> acc { + case collection { + [] -> accumulator + [first, ..rest] -> + case fun(accumulator, first) { + Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) + Stop(b) -> b + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case is_desired(x) { + True -> Ok(x) + _ -> find(in: rest, one_that: is_desired) + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find_map([[], [2], [3]], first) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > find_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn find_map( + in haystack: List(a), + with fun: fn(a) -> Result(b, c), +) -> Result(b, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case fun(x) { + Ok(x) -> Ok(x) + _ -> find_map(in: rest, with: fun) + } + } +} + +/// Returns `True` if the given function returns `True` for all the elements in +/// the given list. If the function returns `False` for any of the elements it +/// immediately returns `False` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > all([], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 3], fn(x) { x > 3 }) +/// False +/// ``` +/// +pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> True + [first, ..rest] -> + case predicate(first) { + True -> all(rest, predicate) + False -> False + } + } +} + +/// Returns `True` if the given function returns `True` for any the elements in +/// the given list. If the function returns `True` for any of the elements it +/// immediately returns `True` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > any([], fn(x) { x > 3 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > any([4, 3], fn(x) { x > 4 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([3, 4], fn(x) { x > 3 }) +/// True +/// ``` +/// +pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> False + [first, ..rest] -> + case predicate(first) { + True -> True + False -> any(rest, predicate) + } + } +} + +fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { + case xs, ys { + [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) + _, _ -> reverse(acc) + } +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, the remaining elements from +/// the longer list are not used. +/// +/// ## Examples +/// +/// ```gleam +/// > zip([], []) +/// [] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1], [3, 4]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3, 4]) +/// [#(1, 3), #(2, 4)] +/// ``` +/// +pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { + do_zip(list, other, []) +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, an `Error` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > strict_zip([], []) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1], [3, 4]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3, 4]) +/// Ok([#(1, 3), #(2, 4)]) +/// ``` +/// +pub fn strict_zip( + list: List(a), + with other: List(b), +) -> Result(List(#(a, b)), LengthMismatch) { + case length(of: list) == length(of: other) { + True -> Ok(zip(list, other)) + False -> Error(LengthMismatch) + } +} + +fn do_unzip(input, xs, ys) { + case input { + [] -> #(reverse(xs), reverse(ys)) + [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) + } +} + +/// Takes a single list of 2-element tuples and returns two lists. +/// +/// ## Examples +/// +/// ```gleam +/// > unzip([#(1, 2), #(3, 4)]) +/// #([1, 3], [2, 4]) +/// ``` +/// +/// ```gleam +/// > unzip([]) +/// #([], []) +/// ``` +/// +pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { + do_unzip(input, [], []) +} + +fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) + } +} + +/// Inserts a given value between each existing element in a given list. +/// +/// This function runs in linear time and copies the list. +/// +/// ## Examples +/// +/// ```gleam +/// > intersperse([1, 1, 1], 2) +/// [1, 2, 1, 2, 1] +/// ``` +/// +/// ```gleam +/// > intersperse([], 2) +/// [] +/// ``` +/// +pub fn intersperse(list: List(a), with elem: a) -> List(a) { + case list { + [] | [_] -> list + [x, ..rest] -> do_intersperse(rest, elem, [x]) + } +} + +/// Returns the element in the Nth position in the list, with 0 being the first +/// position. +/// +/// `Error(Nil)` is returned if the list is not long enough for the given index +/// or if the index is less than 0. +/// +/// ## Examples +/// +/// ```gleam +/// > at([1, 2, 3], 1) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > at([1, 2, 3], 5) +/// Error(Nil) +/// ``` +/// +pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { + case index >= 0 { + True -> + list + |> drop(index) + |> first + False -> Error(Nil) + } +} + +/// Removes any duplicate elements from a given list. +/// +/// This function returns in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) +/// [1, 4, 7, 3] +/// ``` +/// +pub fn unique(list: List(a)) -> List(a) { + case list { + [] -> [] + [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] + } +} + +/// Merge lists `a` and `b` in ascending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_up( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(ax, bx) { + order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + } + _, _, _, _ -> acc + } +} + +/// Merge lists `a` and `b` in descending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_down( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(bx, ax) { + order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + } + _, _, _, _ -> acc + } +} + +/// Merge sort that alternates merging in ascending and descending order +/// because the merge process also reverses the list. +/// +/// Some copying is avoided by merging only a subset of the lists +/// instead of creating and merging new smaller lists. +/// +fn merge_sort( + l: List(a), + ln: Int, + compare: fn(a, a) -> Order, + down: Bool, +) -> List(a) { + let n = ln / 2 + let a = l + let b = drop(l, n) + case ln < 3 { + True -> + case down { + True -> merge_down(n, ln - n, a, b, [], compare) + False -> merge_up(n, ln - n, a, b, [], compare) + } + False -> + case down { + True -> + merge_down( + n, + ln - n, + merge_sort(a, n, compare, False), + merge_sort(b, ln - n, compare, False), + [], + compare, + ) + False -> + merge_up( + n, + ln - n, + merge_sort(a, n, compare, True), + merge_sort(b, ln - n, compare, True), + [], + compare, + ) + } + } +} + +/// Sorts from smallest to largest based upon the ordering specified by a given +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) +/// [1, 2, 3, 4, 4, 5, 6] +/// ``` +/// +pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { + merge_sort(list, length(list), compare, True) +} + +/// Creates a list of ints ranging from a given start and finish. +/// +/// ## Examples +/// +/// ```gleam +/// > range(0, 0) +/// [0] +/// ``` +/// +/// ```gleam +/// > range(0, 5) +/// [0, 1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(1, -5) +/// [1, 0, -1, -2, -3, -4, -5] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> List(Int) { + tail_recursive_range(start, stop, []) +} + +fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { + case int.compare(start, stop) { + order.Eq -> [stop, ..acc] + order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) + order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) + } +} + +fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { + case times <= 0 { + True -> acc + False -> do_repeat(a, times - 1, [a, ..acc]) + } +} + +/// Builds a list of a given value a given number of times. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("a", times: 0) +/// [] +/// ``` +/// +/// ```gleam +/// > repeat("a", times: 5) +/// ["a", "a", "a", "a", "a"] +/// ``` +/// +pub fn repeat(item a: a, times times: Int) -> List(a) { + do_repeat(a, times, []) +} + +fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { + case n <= 0 { + True -> #(reverse(taken), list) + False -> + case list { + [] -> #(reverse(taken), []) + [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) + } + } +} + +/// Splits a list in two before the given index. +/// +/// If the list is not long enough to have the given index the before list will +/// be the input list, and the after list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split([6, 7, 8, 9], 0) +/// #([], [6, 7, 8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 2) +/// #([6, 7], [8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 4) +/// #([6, 7, 8, 9], []) +/// ``` +/// +pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { + do_split(list, index, []) +} + +fn do_split_while( + list: List(a), + f: fn(a) -> Bool, + acc: List(a), +) -> #(List(a), List(a)) { + case list { + [] -> #(reverse(acc), []) + [x, ..xs] -> + case f(x) { + False -> #(reverse(acc), list) + _ -> do_split_while(xs, f, [x, ..acc]) + } + } +} + +/// Splits a list in two before the first element that a given function returns +/// `False` for. +/// +/// If the function returns `True` for all elements the first list will be the +/// input list, and the second list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) +/// #([1, 2, 3], [4, 5]) +/// ``` +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) +/// #([1, 2, 3, 4, 5], []) +/// ``` +/// +pub fn split_while( + list list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_split_while(list, predicate, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element and returns the second element. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// This function may be useful for interacting with Erlang code where lists of +/// tuples are common. +/// +/// ## Examples +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "b") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_find( + in keyword_list: List(#(k, v)), + find desired_key: k, +) -> Result(v, Nil) { + find_map( + keyword_list, + fn(keyword) { + let #(key, value) = keyword + case key == desired_key { + True -> Ok(value) + False -> Error(Nil) + } + }, + ) +} + +/// Given a list of 2-element tuples, finds all tuples that have a given +/// key as the first element and returns the second element. +/// +/// This function may be useful for interacting with Erlang code where lists of +/// tuples are common. +/// +/// ## Examples +/// +/// ```gleam +/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") +/// [0, 2] +/// ``` +/// +/// ```gleam +/// > key_filter([#("a", 0), #("b", 1)], "c") +/// [] +/// ``` +/// +pub fn key_filter( + in keyword_list: List(#(k, v)), + find desired_key: k, +) -> List(v) { + filter_map( + keyword_list, + fn(keyword) { + let #(key, value) = keyword + case key == desired_key { + True -> Ok(value) + False -> Error(Nil) + } + }, + ) +} + +fn do_pop(haystack, predicate, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case predicate(x) { + True -> Ok(#(x, append(reverse(checked), rest))) + False -> do_pop(rest, predicate, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the predicate function returns `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 2 }) +/// Ok(#(3, [1, 2])) +/// ``` +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn pop( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(#(a, List(a)), Nil) { + do_pop(haystack, is_desired, []) +} + +fn do_pop_map(haystack, mapper, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case mapper(x) { + Ok(y) -> Ok(#(y, append(reverse(checked), rest))) + Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_map([[], [2], [3]], first) +/// Ok(#(2, [[], [3]])) +/// ``` +/// +/// ```gleam +/// > pop_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn pop_map( + in haystack: List(a), + one_that is_desired: fn(a) -> Result(b, c), +) -> Result(#(b, List(a)), Nil) { + do_pop_map(haystack, is_desired, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element. This function will return the second element +/// of the found tuple and list with tuple removed. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "a") +/// Ok(#(0, [#("b", 1)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "b") +/// Ok(#(1, [#("a", 0)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_pop( + haystack: List(#(k, v)), + key: k, +) -> Result(#(v, List(#(k, v))), Nil) { + pop_map( + haystack, + fn(entry) { + let #(k, v) = entry + case k { + k if k == key -> Ok(v) + _ -> Error(Nil) + } + }, + ) +} + +/// Given a list of 2-element tuples, inserts a key and value into the list. +/// +/// If there was already a tuple with the key then it is replaced, otherwise it +/// is added to the end of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 4, 100) +/// [#(5, 0), #(4, 100)] +/// ``` +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 1, 100) +/// [#(5, 0), #(4, 1), #(1, 100)] +/// ``` +/// +pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { + case list { + [] -> [#(key, value)] + [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] + [first, ..rest] -> [first, ..key_set(rest, key, value)] + } +} + +/// Calls a function for each element in a list, discarding the return value. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ```gleam +/// > list.each([1, 2, 3], io.println) +/// Nil +/// ``` +/// +pub fn each(list: List(a), f: fn(a) -> b) -> Nil { + case list { + [] -> Nil + [x, ..xs] -> { + f(x) + each(xs, f) + } + } +} + +/// Calls a `Result` returning function for each element in a list, discarding +/// the return value. If the function returns `Error` then the iteration is +/// stopped and the error is returned. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > try_each( +/// > over: [1, 2, 3], +/// > with: function_that_might_fail, +/// > ) +/// Ok(Nil) +/// ``` +/// +pub fn try_each( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(Nil, e) { + case list { + [] -> Ok(Nil) + [x, ..xs] -> + case fun(x) { + Ok(_) -> try_each(over: xs, with: fun) + Error(e) -> Error(e) + } + } +} + +fn do_partition(list, categorise, trues, falses) { + case list { + [] -> #(reverse(trues), reverse(falses)) + [x, ..xs] -> + case categorise(x) { + True -> do_partition(xs, categorise, [x, ..trues], falses) + False -> do_partition(xs, categorise, trues, [x, ..falses]) + } + } +} + +/// Partitions a list into a tuple/pair of lists +/// by a given categorisation function. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) +/// #([1, 3, 5], [2, 4]) +/// ``` +/// +pub fn partition( + list: List(a), + with categorise: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_partition(list, categorise, [], []) +} + +/// Returns all the permutations of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > permutations([1, 2]) +/// [[1, 2], [2, 1]] +/// ``` +/// +pub fn permutations(l: List(a)) -> List(List(a)) { + case l { + [] -> [[]] + _ -> + l + |> index_map(fn(i_idx, i) { + l + |> index_fold( + [], + fn(acc, j, j_idx) { + case i_idx == j_idx { + True -> acc + False -> [j, ..acc] + } + }, + ) + |> reverse + |> permutations + |> map(fn(permutation) { [i, ..permutation] }) + }) + |> concat + } +} + +fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { + let window = take(l, n) + + case length(window) == n { + True -> do_window([window, ..acc], drop(l, 1), n) + False -> acc + } +} + +/// Returns a list of sliding windows. +/// +/// ## Examples +/// +/// ```gleam +/// > window([1,2,3,4,5], 3) +/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] +/// ``` +/// +/// ```gleam +/// > window([1, 2], 4) +/// [] +/// ``` +/// +pub fn window(l: List(a), by n: Int) -> List(List(a)) { + do_window([], l, n) + |> reverse +} + +/// Returns a list of tuples containing two contiguous elements. +/// +/// ## Examples +/// +/// ```gleam +/// > window_by_2([1,2,3,4]) +/// [#(1, 2), #(2, 3), #(3, 4)] +/// ``` +/// +/// ```gleam +/// > window_by_2([1]) +/// [] +/// ``` +/// +pub fn window_by_2(l: List(a)) -> List(#(a, a)) { + zip(l, drop(l, 1)) +} + +/// Drops the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) +/// [3, 4] +/// ``` +/// +pub fn drop_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + case list { + [] -> [] + [x, ..xs] -> + case predicate(x) { + True -> drop_while(xs, predicate) + False -> [x, ..xs] + } + } +} + +fn do_take_while( + list: List(a), + predicate: fn(a) -> Bool, + acc: List(a), +) -> List(a) { + case list { + [] -> reverse(acc) + [first, ..rest] -> + case predicate(first) { + True -> do_take_while(rest, predicate, [first, ..acc]) + False -> reverse(acc) + } + } +} + +/// Takes the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) +/// [1, 2] +/// ``` +/// +pub fn take_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + do_take_while(list, predicate, []) +} + +fn do_chunk( + list: List(a), + f: fn(a) -> key, + previous_key: key, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [first, ..rest] -> { + let key = f(first) + case key == previous_key { + False -> { + let new_acc = [reverse(current_chunk), ..acc] + do_chunk(rest, f, key, [first], new_acc) + } + _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) + } + } + _empty -> reverse([reverse(current_chunk), ..acc]) + } +} + +/// Returns a list of chunks in which +/// the return value of calling `f` on each element is the same. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { + case list { + [] -> [] + [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) + } +} + +fn do_sized_chunk( + list: List(a), + count: Int, + left: Int, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [] -> + case current_chunk { + [] -> reverse(acc) + remaining -> reverse([reverse(remaining), ..acc]) + } + [first, ..rest] -> { + let chunk = [first, ..current_chunk] + case left > 1 { + False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) + True -> do_sized_chunk(rest, count, left - 1, chunk, acc) + } + } + } +} + +/// Returns a list of chunks containing `count` elements each. +/// +/// If the last chunk does not have `count` elements, it is instead +/// a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { + do_sized_chunk(list, count, count, [], []) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first element in the list +/// and combines it with each subsequent element in turn using the given +/// function. The function is called as `fun(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an +/// empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [first, ..rest] -> Ok(fold(rest, first, fun)) + } +} + +fn do_scan( + list: List(a), + accumulator: acc, + accumulated: List(acc), + fun: fn(acc, a) -> acc, +) -> List(acc) { + case list { + [] -> reverse(accumulated) + [x, ..xs] -> { + let next = fun(accumulator, x) + do_scan(xs, next, [next, ..accumulated], fun) + } + } +} + +/// Similar to `fold`, but yields the state of the accumulator at each stage. +/// +/// ## Examples +/// +/// ```gleam +/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) +/// [101, 103, 106] +/// ``` +/// +pub fn scan( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> List(acc) { + do_scan(list, initial, [], fun) +} + +/// Returns the last element in the given list. +/// +/// Returns `Error(Nil)` if the list is empty. +/// +/// This function runs in linear time. +/// For a collection oriented around performant access at either end, +/// see `gleam/queue.Queue`. +/// +/// ## Examples +/// +/// ```gleam +/// > last([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last([1, 2, 3, 4, 5]) +/// Ok(5) +/// ``` +/// +pub fn last(list: List(a)) -> Result(a, Nil) { + list + |> reduce(fn(_, elem) { elem }) +} + +/// Return unique combinations of elements in the list. +/// +/// ## Examples +/// +/// ```gleam +/// > combinations([1, 2, 3], 2) +/// [[1, 2], [1, 3], [2, 3]] +/// ``` +/// +/// ```gleam +/// > combinations([1, 2, 3, 4], 3) +/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] +/// ``` +/// +pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { + case n { + 0 -> [[]] + _ -> + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = + map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) + |> reverse + fold( + first_combinations, + combinations(xs, n), + fn(acc, c) { [c, ..acc] }, + ) + } + } + } +} + +fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = map(xs, with: fn(other) { #(x, other) }) + [first_combinations, ..do_combination_pairs(xs)] + } + } +} + +/// Return unique pair combinations of elements in the list +/// +/// ## Examples +/// +/// ```gleam +/// > combination_pairs([1, 2, 3]) +/// [#(1, 2), #(1, 3), #(2, 3)] +/// ``` +/// +pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { + do_combination_pairs(items) + |> concat +} + +/// Make a list alternating the elements from the given lists +/// +/// ## Examples +/// +/// ```gleam +/// > list.interleave([[1, 2], [101, 102], [201, 202]]) +/// [1, 101, 201, 2, 102, 202] +/// ``` +/// +pub fn interleave(list: List(List(a))) -> List(a) { + transpose(list) + |> concat +} + +/// Transpose rows and columns of the list of lists. +/// +/// Notice: This function is not tail recursive, +/// and thus may exceed stack size if called, +/// with large lists (on target JavaScript). +/// +/// ## Examples +/// +/// ```gleam +/// > transpose([[1, 2, 3], [101, 102, 103]]) +/// [[1, 101], [2, 102], [3, 103]] +/// ``` +/// +pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { + let take_first = fn(list) { + case list { + [] -> [] + [f] -> [f] + [f, ..] -> [f] + } + } + + case list_of_list { + [] -> [] + [[], ..xss] -> transpose(xss) + rows -> { + let firsts = + rows + |> map(take_first) + |> concat + let rest = transpose(map(rows, drop(_, 1))) + [firsts, ..rest] + } + } +} + +fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + [elem_pair, ..enumerable] -> + do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) + } +} + +fn do_shuffle_by_pair_indexes( + list_of_pairs: List(#(Float, a)), +) -> List(#(Float, a)) { + sort( + list_of_pairs, + fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { + float.compare(a_pair.0, b_pair.0) + }, + ) +} + +/// Takes a list, randomly sorts all items and returns the shuffled list. +/// +/// This function uses Erlang's `:rand` module or Javascript's +/// `Math.random()` to calculate the index shuffling. +/// +/// ## Example +/// +/// ```gleam +/// > range(1, 10) +/// > |> shuffle() +/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] +/// ``` +/// +pub fn shuffle(list: List(a)) -> List(a) { + list + |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) + |> do_shuffle_by_pair_indexes() + |> do_shuffle_pair_unwrap([]) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam new file mode 100644 index 00000000000..1f8b228eb90 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam @@ -0,0 +1,127 @@ +import gleam/option.{type Option} +import gleam/dict + +@deprecated("Please use the `gleam/dict` module instead") +pub type Map(key, value) = + dict.Dict(key, value) + +@deprecated("Please use the `gleam/dict` module instead") +pub fn size(map) -> Int { + dict.size(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn to_list(map) -> List(#(key, value)) { + dict.to_list(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn from_list(list: List(#(k, v))) { + dict.from_list(list) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn has_key(map, key: k) -> Bool { + dict.has_key(map, key) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn new() { + dict.new() +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn get(from, get: key) -> Result(value, Nil) { + dict.get(from, get) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn insert(into map, for key: k, insert value: v) { + dict.insert(map, key, value) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn map_values(in map, with fun: fn(k, v) -> w) { + dict.map_values(map, fun) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn keys(map) -> List(keys) { + dict.keys(map) +} + +@target(javascript) +fn reverse_and_concat(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) + } +} + +@target(javascript) +fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) + } +} + +@target(javascript) +fn do_keys(map) -> List(k) { + let list_of_pairs = + map + |> to_list + do_keys_acc(list_of_pairs, []) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn values(map) -> List(values) { + dict.values(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { + dict.filter(map, predicate) +} + +@target(javascript) +fn do_filter(f: fn(key, value) -> Bool, map) { + let insert = fn(map, k, v) { + case f(k, v) { + True -> insert(map, k, v) + _ -> map + } + } + map + |> fold(from: new(), with: insert) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn take(from map, keeping desired_keys: List(k)) { + dict.take(map, desired_keys) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn merge(into map, from new_entries) { + dict.merge(map, new_entries) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn delete(from map, delete key: k) { + dict.delete(map, key) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn drop(from map, drop disallowed_keys: List(k)) { + dict.drop(map, disallowed_keys) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { + dict.update(map, key, fun) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { + dict.fold(map, initial, fun) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam new file mode 100644 index 00000000000..6015c0fff8f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam @@ -0,0 +1,346 @@ +/// `Option` represents a value that may be present or not. `Some` means the value is +/// present, `None` means the value is not. +/// +/// This is Gleam's alternative to having a value that could be Null, as is +/// possible in some other languages. +/// +pub type Option(a) { + Some(a) + None +} + +fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { + case list { + [] -> Some(acc) + [x, ..rest] -> { + let accumulate = fn(acc, item) { + case acc, item { + Some(values), Some(value) -> Some([value, ..values]) + _, _ -> None + } + } + accumulate(do_all(rest, acc), x) + } + } +} + +/// Combines a list of `Option`s into a single `Option`. +/// If all elements in the list are `Some` then returns a `Some` holding the list of values. +/// If any element is `None` then returns`None`. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Some(1), Some(2)]) +/// Some([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Some(1), None]) +/// None +/// ``` +/// +pub fn all(list: List(Option(a))) -> Option(List(a)) { + do_all(list, []) +} + +/// Checks whether the `Option` is a `Some` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_some(Some(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_some(None) +/// False +/// ``` +/// +pub fn is_some(option: Option(a)) -> Bool { + option != None +} + +/// Checks whether the `Option` is a `None` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_none(Some(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_none(None) +/// True +/// ``` +/// +pub fn is_none(option: Option(a)) -> Bool { + option == None +} + +/// Converts an `Option` type to a `Result` type. +/// +/// ## Examples +/// +/// ```gleam +/// > to_result(Some(1), "some_error") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > to_result(None, "some_error") +/// Error("some_error") +/// ``` +/// +pub fn to_result(option: Option(a), e) -> Result(a, e) { + case option { + Some(a) -> Ok(a) + _ -> Error(e) + } +} + +/// Converts a `Result` type to an `Option` type. +/// +/// ## Examples +/// +/// ```gleam +/// > from_result(Ok(1)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > from_result(Error("some_error")) +/// None +/// ``` +/// +pub fn from_result(result: Result(a, e)) -> Option(a) { + case result { + Ok(a) -> Some(a) + _ -> None + } +} + +/// Extracts the value from an `Option`, returning a default value if there is none. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Some(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(None, 0) +/// 0 +/// ``` +/// +pub fn unwrap(option: Option(a), or default: a) -> a { + case option { + Some(x) -> x + None -> default + } +} + +/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Some(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(None, fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { + case option { + Some(x) -> x + None -> default() + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it. +/// +/// If the `Option` is a `None` rather than `Some`, the function is not called and the +/// `Option` stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Some(1), with: fn(x) { x + 1 }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > map(over: None, with: fn(x) { x + 1 }) +/// None +/// ``` +/// +pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { + case option { + Some(x) -> Some(fun(x)) + None -> None + } +} + +/// Merges a nested `Option` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Some(Some(1))) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > flatten(Some(None)) +/// None +/// ``` +/// +/// ```gleam +/// > flatten(None) +/// None +/// ``` +/// +pub fn flatten(option: Option(Option(a))) -> Option(a) { + case option { + Some(x) -> x + None -> None + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it, where the given function also returns an `Option`. The two options are +/// then merged together into one `Option`. +/// +/// If the `Option` is a `None` rather than `Some` the function is not called and the +/// option stays the same. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that return `Option`. +/// +/// ## Examples +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(x + 1) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(#("a", x)) }) +/// Some(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(_) { None }) +/// None +/// ``` +/// +/// ```gleam +/// > then(None, fn(x) { Some(x + 1) }) +/// None +/// ``` +/// +pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { + case option { + Some(x) -> fun(x) + None -> None + } +} + +/// Returns the first value if it is `Some`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Some(1), Some(2)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(Some(1), None) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(None, Some(2)) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > or(None, None) +/// None +/// ``` +/// +pub fn or(first: Option(a), second: Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second + } +} + +/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { Some(2) }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { None }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { Some(2) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { None }) +/// None +/// ``` +/// +pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second() + } +} + +fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + [x, ..xs] -> { + let accumulate = fn(acc, item) { + case item { + Some(value) -> [value, ..acc] + None -> acc + } + } + accumulate(do_values(xs, acc), x) + } + } +} + +/// Given a list of `Option`s, +/// returns only the values inside `Some`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Some(1), None, Some(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(options: List(Option(a))) -> List(a) { + do_values(options, []) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam new file mode 100644 index 00000000000..12ce01136ca --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam @@ -0,0 +1,133 @@ +/// Represents the result of a single comparison to determine the precise +/// ordering of two values. +/// +pub type Order { + /// Less-than + Lt + + /// Equal + Eq + + /// Greater than + Gt +} + +/// Inverts an order, so less-than becomes greater-than and greater-than +/// becomes less-than. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(Lt) +/// Gt +/// ``` +/// +/// ```gleam +/// > negate(Eq) +/// Eq +/// ``` +/// +/// ```gleam +/// > negate(Lt) +/// Gt +/// ``` +/// +pub fn negate(order: Order) -> Order { + case order { + Lt -> Gt + Eq -> Eq + Gt -> Lt + } +} + +/// Produces a numeric representation of the order. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(Lt) +/// -1 +/// ``` +/// +/// ```gleam +/// > to_int(Eq) +/// 0 +/// ``` +/// +/// ```gleam +/// > to_int(Gt) +/// 1 +/// ``` +/// +pub fn to_int(order: Order) -> Int { + case order { + Lt -> -1 + Eq -> 0 + Gt -> 1 + } +} + +/// Compares two `Order` values to one another, producing a new `Order`. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(Eq, with: Lt) +/// Gt +/// ``` +/// +pub fn compare(a: Order, with b: Order) -> Order { + case a, b { + x, y if x == y -> Eq + Lt, _ | Eq, Gt -> Lt + _, _ -> Gt + } +} + +/// Returns the largest of two orders given that `Gt > Eq > Lt`. +/// +/// ## Examples +/// +/// ```gleam +/// > max(Eq, Lt) +/// Eq +/// ``` +/// +pub fn max(a: Order, b: Order) -> Order { + case a, b { + Gt, _ -> Gt + Eq, Lt -> Eq + _, _ -> b + } +} + +/// Returns the smallest of two orders given that `Gt > Eq > Lt`. +/// +/// ## Examples +/// +/// ```gleam +/// > min(Eq, Lt) +/// Lt +/// ``` +/// +pub fn min(a: Order, b: Order) -> Order { + case a, b { + Lt, _ -> Lt + Eq, Gt -> Eq + _, _ -> b + } +} + +/// Inverts an ordering function, so less-than becomes greater-than and greater-than +/// becomes less-than. +/// +/// ## Examples +/// +/// ```gleam +/// > list.sort([1, 5, 4], by: reverse(int.compare)) +/// [5, 4, 1] +/// ``` +/// +pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { + fn(a, b) { orderer(b, a) } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam new file mode 100644 index 00000000000..894e6a8d9f1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam @@ -0,0 +1,85 @@ +/// Returns the first element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > first(#(1, 2)) +/// 1 +/// ``` +/// +pub fn first(pair: #(a, b)) -> a { + let #(a, _) = pair + a +} + +/// Returns the second element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > second(#(1, 2)) +/// 2 +/// ``` +/// +pub fn second(pair: #(a, b)) -> b { + let #(_, a) = pair + a +} + +/// Returns a new pair with the elements swapped. +/// +/// ## Examples +/// +/// ```gleam +/// > swap(#(1, 2)) +/// #(2, 1) +/// ``` +/// +pub fn swap(pair: #(a, b)) -> #(b, a) { + let #(a, b) = pair + #(b, a) +} + +/// Returns a new pair with the first element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_first(fn(n) { n * 2 }) +/// #(2, 2) +/// ``` +/// +pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { + let #(a, b) = pair + #(fun(a), b) +} + +/// Returns a new pair with the second element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_second(fn(n) { n * 2 }) +/// #(1, 4) +/// ``` +/// +pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { + let #(a, b) = pair + #(a, fun(b)) +} + +/// Returns a new pair with the given elements. This can also be done using the dedicated +/// syntax instead: `new(1, 2) == #(1, 2)`. +/// +/// ## Examples +/// +/// ```gleam +/// > new(1, 2) +/// #(1, 2) +/// ``` +/// +pub fn new(first: a, second: b) -> #(a, b) { + #(first, second) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam new file mode 100644 index 00000000000..5bf60c8a529 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam @@ -0,0 +1,292 @@ +import gleam/list + +/// A queue is an ordered collection of elements. It is similar to a list, but +/// unlike a list elements can be added to or removed from either the front or +/// the back in a performant fashion. +/// +/// The internal representation may be different for two queues with the same +/// elements in the same order if the queues were constructed in different +/// ways. This is the price paid for a queue's fast access at both the front +/// and the back. +/// +/// Because of unpredictable internal representation the equality operator `==` +/// may return surprising results, and the `is_equal` and `is_logically_equal` +/// functions are the recommended way to test queues for equality. +/// +pub opaque type Queue(element) { + Queue(in: List(element), out: List(element)) +} + +/// Creates a fresh queue that contains no values. +/// +pub fn new() -> Queue(a) { + Queue(in: [], out: []) +} + +/// Converts a list of elements into a queue of the same elements in the same +/// order. The first element in the list becomes the front element in the queue. +/// +/// This function runs in constant time. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2, 3] |> from_list |> length +/// 3 +/// ``` +/// +pub fn from_list(list: List(a)) -> Queue(a) { + Queue(in: [], out: list) +} + +/// Converts a queue of elements into a list of the same elements in the same +/// order. The front element in the queue becomes the first element in the list. +/// +/// This function runs in linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() |> push_back(1) |> push_back(2) |> to_list +/// [1, 2] +/// ``` +/// +pub fn to_list(queue: Queue(a)) -> List(a) { + queue.out + |> list.append(list.reverse(queue.in)) +} + +/// Determines whether or not the queue is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> is_empty +/// False +/// ``` +/// +pub fn is_empty(queue: Queue(a)) -> Bool { + queue.in == [] && queue.out == [] +} + +/// Counts the number of elements in a given queue. +/// +/// This function has to traverse the queue to determine the number of elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length(from_list([])) +/// 0 +/// ``` +/// +/// ```gleam +/// > length(from_list([1])) +/// 1 +/// ``` +/// +/// ```gleam +/// > length(from_list([1, 2])) +/// 2 +/// ``` +/// +pub fn length(queue: Queue(a)) -> Int { + list.length(queue.in) + list.length(queue.out) +} + +/// Pushes an element onto the back of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2] |> from_list |> push_back(3) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: [item, ..queue.in], out: queue.out) +} + +/// Pushes an element onto the front of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [0, 0] |> from_list |> push_front(1) |> to_list +/// [1, 0, 0] +/// ``` +/// +pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: queue.in, out: [item, ..queue.out]) +} + +/// Gets the last element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() +/// > |> push_back(0) +/// > |> push_back(1) +/// > |> pop_back() +/// Ok(#(1, push_front(new(), 0))) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> push_front(0) +/// > |> pop_back() +/// Ok(#(0, new())) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) + Queue(in: [first, ..rest], out: out) -> { + let queue = Queue(in: rest, out: out) + Ok(#(first, queue)) + } + } +} + +/// Gets the first element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_front(1) +/// > |> queue.push_front(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.push_back(queue.new(), 1))) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_back(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.new())) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) + Queue(in: in, out: [first, ..rest]) -> { + let queue = Queue(in: in, out: rest) + Ok(#(first, queue)) + } + } +} + +/// Creates a new queue from a given queue containing the same elements, but in +/// the opposite order. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> reverse |> to_list +/// [] +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> reverse |> to_list +/// [1] +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> reverse |> to_list +/// [2, 1] +/// ``` +/// +pub fn reverse(queue: Queue(a)) -> Queue(a) { + Queue(in: queue.out, out: queue.in) +} + +fn check_equal( + xs: List(t), + x_tail: List(t), + ys: List(t), + y_tail: List(t), + eq: fn(t, t) -> Bool, +) -> Bool { + case xs, x_tail, ys, y_tail { + [], [], [], [] -> True + [x, ..xs], _, [y, ..ys], _ -> + case eq(x, y) { + False -> False + True -> check_equal(xs, x_tail, ys, y_tail, eq) + } + [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) + _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) + _, _, _, _ -> False + } +} + +/// Checks whether two queues have equal elements in the same order, where the +/// equality of elements is determined by a given equality checking function. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time multiplied by the time taken by the +/// element equality checking function. +/// +pub fn is_logically_equal( + a: Queue(t), + to b: Queue(t), + checking element_is_equal: fn(t, t) -> Bool, +) -> Bool { + check_equal(a.out, a.in, b.out, b.in, element_is_equal) +} + +/// Checks whether two queues have the same elements in the same order. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time. +/// +pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { + check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam new file mode 100644 index 00000000000..9ffda789f6a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam @@ -0,0 +1,214 @@ +//// This module contains regular expression matching functions for strings. +//// The matching algorithms of the library are based on the PCRE library, but not +//// all of the PCRE library is interfaced and some parts of the library go beyond +//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. + +import gleam/option.{type Option} + +pub type Regex + +/// The details about a particular match: +/// +pub type Match { + Match( + /// The full string of the match. + content: String, + /// A `Regex` can have subpatterns, sup-parts that are in parentheses. + submatches: List(Option(String)), + ) +} + +/// When a regular expression fails to compile: +/// +pub type CompileError { + CompileError( + /// The problem encountered that caused the compilation to fail + error: String, + /// The byte index into the string to where the problem was found + /// This value may not be correct in JavaScript environments. + byte_index: Int, + ) +} + +pub type Options { + Options(case_insensitive: Bool, multi_line: Bool) +} + +/// Creates a `Regex` with some additional options. +/// +/// ## Examples +/// +/// ```gleam +/// > let options = Options(case_insensitive: False, multi_line: True) +/// > let assert Ok(re) = compile("^[0-9]", with: options) +/// > check(re, "abc\n123") +/// True +/// ``` +/// +/// ```gleam +/// > let options = Options(case_insensitive: True, multi_line: False) +/// > let assert Ok(re) = compile("[A-Z]", with: options) +/// > check(re, "abc123") +/// True +/// ``` +/// +pub fn compile( + pattern: String, + with options: Options, +) -> Result(Regex, CompileError) { + do_compile(pattern, options) +} + +@external(erlang, "gleam_stdlib", "compile_regex") +@external(javascript, "../gleam_stdlib.mjs", "compile_regex") +fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) + +/// Creates a new `Regex`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[0-9]") +/// > check(re, "abc123") +/// True +/// ``` +/// +/// ```gleam +/// > check(re, "abcxyz") +/// False +/// ``` +/// +/// ```gleam +/// > from_string("[0-9") +/// Error( +/// CompileError( +/// error: "missing terminating ] for character class", +/// byte_index: 4 +/// ) +/// ) +/// ``` +/// +pub fn from_string(pattern: String) -> Result(Regex, CompileError) { + compile(pattern, Options(case_insensitive: False, multi_line: False)) +} + +/// Returns a boolean indicating whether there was a match or not. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("^f.o.?") +/// > check(with: re, content: "foo") +/// True +/// ``` +/// +/// ```gleam +/// > check(with: re, content: "boo") +/// False +/// ``` +/// +pub fn check(with regex: Regex, content content: String) -> Bool { + do_check(regex, content) +} + +@external(erlang, "gleam_stdlib", "regex_check") +@external(javascript, "../gleam_stdlib.mjs", "regex_check") +fn do_check(a: Regex, b: String) -> Bool + +/// Splits a string. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string(" *, *") +/// > split(with: re, content: "foo,32, 4, 9 ,0") +/// ["foo", "32", "4", "9", "0"] +/// ``` +/// +pub fn split(with regex: Regex, content string: String) -> List(String) { + do_split(regex, string) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "regex_split") +fn do_split(a: Regex, b: String) -> List(String) + +@target(javascript) +fn do_split(regex, string) -> List(String) { + js_split(string, regex) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split") +fn js_split(a: String, b: Regex) -> List(String) + +/// Collects all matches of the regular expression. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") +/// > scan(with: re, content: "I am on a boat in a lake.") +/// [ +/// Match( +/// content: "on a boat", +/// submatches: [Some("boat")] +/// ), +/// Match( +/// content: "in a lake", +/// submatches: [Some("lake")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") +/// > scan(with: re, content: "-36") +/// [ +/// Match( +/// content: "-36", +/// submatches: [Some("-"), Some("36")] +/// ) +/// ] +/// +/// > scan(with: re, content: "36") +/// [ +/// Match( +/// content: "36", +/// submatches: [None, Some("36")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") +/// > scan(with: re, content: "var age = 32") +/// [ +/// Match( +/// content: "var age = 32", +/// submatches: [Some("age"), None, Some("32")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") +/// > scan(with: re, content: "let age = 32") +/// [ +/// Match( +/// content: "let age = 32", +/// submatches: [Some("age"), Some("32")] +/// ) +/// ] +/// +/// > scan(with: re, content: "const age = 32") +/// [] +/// ``` +/// +pub fn scan(with regex: Regex, content string: String) -> List(Match) { + do_scan(regex, string) +} + +@external(erlang, "gleam_stdlib", "regex_scan") +@external(javascript, "../gleam_stdlib.mjs", "regex_scan") +fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam new file mode 100644 index 00000000000..fb6dddb3110 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam @@ -0,0 +1,482 @@ +//// Result represents the result of something that may succeed or not. +//// `Ok` means it was successful, `Error` means it was not successful. + +import gleam/list + +/// Checks whether the result is an `Ok` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_ok(Ok(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_ok(Error(Nil)) +/// False +/// ``` +/// +pub fn is_ok(result: Result(a, e)) -> Bool { + case result { + Error(_) -> False + Ok(_) -> True + } +} + +/// Checks whether the result is an `Error` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_error(Ok(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_error(Error(Nil)) +/// True +/// ``` +/// +pub fn is_error(result: Result(a, e)) -> Bool { + case result { + Ok(_) -> False + Error(_) -> True + } +} + +/// Updates a value held within the `Ok` of a result by calling a given function +/// on it. +/// +/// If the result is an `Error` rather than `Ok` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > map(over: Error(1), with: fn(x) { x + 1 }) +/// Error(1) +/// ``` +/// +pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { + case result { + Ok(x) -> Ok(fun(x)) + Error(e) -> Error(e) + } +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it. +/// +/// If the result is `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map_error(over: Error(1), with: fn(x) { x + 1 }) +/// Error(2) +/// ``` +/// +/// ```gleam +/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(1) +/// ``` +/// +pub fn map_error( + over result: Result(a, e), + with fun: fn(e) -> f, +) -> Result(a, f) { + case result { + Ok(x) -> Ok(x) + Error(error) -> Error(fun(error)) + } +} + +/// Merges a nested `Result` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Ok(Ok(1))) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > flatten(Ok(Error(""))) +/// Error("") +/// ``` +/// +/// ```gleam +/// > flatten(Error(Nil)) +/// Error(Nil) +/// ``` +/// +pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { + case result { + Ok(x) -> x + Error(error) -> Error(error) + } +} + +/// "Updates" an `Ok` result by passing its value to a function that yields a result, +/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) +/// +/// If the input is an `Error` rather than an `Ok`, the function is not called and +/// the original `Error` is returned. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that may fail. +/// +/// ## Examples +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(x + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) +/// Ok(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(_) { Error("Oh no") }) +/// Error("Oh no") +/// ``` +/// +/// ```gleam +/// > try(Error(Nil), fn(x) { Ok(x + 1) }) +/// Error(Nil) +/// ``` +/// +pub fn try( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + case result { + Ok(x) -> fun(x) + Error(e) -> Error(e) + } +} + +/// An alias for `try`. See the documentation for that function for more information. +/// +pub fn then( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + try(result, fun) +} + +/// Extracts the `Ok` value from a result, returning a default value if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Ok(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(Error(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap(result: Result(a, e), or default: a) -> a { + case result { + Ok(v) -> v + Error(_) -> default + } +} + +/// Extracts the `Ok` value from a result, evaluating the default function if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Ok(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(Error(""), fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { + case result { + Ok(v) -> v + Error(_) -> default() + } +} + +/// Extracts the `Error` value from a result, returning a default value if the result +/// is an `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_error(Error(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_error(Ok(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap_error(result: Result(a, e), or default: e) -> e { + case result { + Ok(_) -> default + Error(e) -> e + } +} + +/// Extracts the inner value from a result. Both the value and error must be of +/// the same type. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_both(Error(1)) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_both(Ok(2)) +/// 2 +/// ``` +/// +pub fn unwrap_both(result: Result(a, a)) -> a { + case result { + Ok(a) -> a + Error(a) -> a + } +} + +/// Transforms any error into `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > nil_error(Error(1)) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > nil_error(Ok(1)) +/// Ok(1) +/// ``` +/// +pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { + map_error(result, fn(_) { Nil }) +} + +/// Returns the first value if it is `Ok`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Ok(1), Ok(2)) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Ok(1), Error("Error 2")) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Ok(2)) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Error("Error 2")) +/// Error("Error 2") +/// ``` +/// +pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second + } +} + +/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Ok(2) }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Error("Error 2") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) +/// Error("Error 2") +/// ``` +/// +pub fn lazy_or( + first: Result(a, e), + second: fn() -> Result(a, e), +) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second() + } +} + +/// Combines a list of results into a single result. +/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. +/// If any element is `Error` then returns the first error. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Ok(1), Ok(2)]) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Ok(1), Error("e")]) +/// Error("e") +/// ``` +/// +pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { + list.try_map(results, fn(x) { x }) +} + +/// Given a list of results, returns a pair where the first element is a list +/// of all the values inside `Ok` and the second element is a list with all the +/// values inside `Error`. The values in both lists appear in reverse order with +/// respect to their position in the original list of results. +/// +/// ## Examples +/// +/// ```gleam +/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) +/// #([2, 1], ["b", "a"]) +/// ``` +/// +pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { + do_partition(results, [], []) +} + +fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { + case results { + [] -> #(oks, errors) + [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) + [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) + } +} + +/// Replace the value within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace(Ok(1), Nil) +/// Ok(Nil) +/// ``` +/// +/// ```gleam +/// > replace(Error(1), Nil) +/// Error(1) +/// ``` +/// +pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { + case result { + Ok(_) -> Ok(value) + Error(error) -> Error(error) + } +} + +/// Replace the error within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace_error(Error(1), Nil) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > replace_error(Ok(1), Nil) +/// Ok(1) +/// ``` +/// +pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { + case result { + Ok(x) -> Ok(x) + Error(_) -> Error(error) + } +} + +/// Given a list of results, returns only the values inside `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Ok(1), Error("a"), Ok(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(results: List(Result(a, e))) -> List(a) { + list.filter_map(results, fn(r) { r }) +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it, where the given function also returns a result. The two results are +/// then merged together into one result. +/// +/// If the result is an `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// This function is useful for chaining together computations that may fail +/// and trying to recover from possible errors. +/// +/// ## Examples +/// +/// ```gleam +/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) +/// Error("failed to recover") +/// ``` +/// +pub fn try_recover( + result: Result(a, e), + with fun: fn(e) -> Result(a, f), +) -> Result(a, f) { + case result { + Ok(value) -> Ok(value) + Error(error) -> fun(error) + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam new file mode 100644 index 00000000000..df8d500e804 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam @@ -0,0 +1,264 @@ +import gleam/list +import gleam/dict.{type Dict} +import gleam/result + +// A list is used as the map value as an empty list has the smallest +// representation in Erlang's binary format +@target(erlang) +type Token = + List(Nil) + +@target(erlang) +const token = [] + +@target(javascript) +type Token = + Nil + +@target(javascript) +const token = Nil + +/// A set is a collection of unique members of the same type. +/// +/// It is implemented using the `gleam/map` module, so inserts and lookups have +/// logarithmic time complexity. +/// +pub opaque type Set(member) { + Set(map: Dict(member, Token)) +} + +/// Creates a new empty set. +/// +pub fn new() -> Set(member) { + Set(dict.new()) +} + +/// Gets the number of members in a set. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn size(set: Set(member)) -> Int { + dict.size(set.map) +} + +/// Inserts an member into the set. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn insert(into set: Set(member), this member: member) -> Set(member) { + Set(map: dict.insert(set.map, member, token)) +} + +/// Checks whether a set contains a given member. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(2) +/// True +/// ``` +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn contains(in set: Set(member), this member: member) -> Bool { + set.map + |> dict.get(member) + |> result.is_ok +} + +/// Removes a member from a set. If the set does not contain the member then +/// the set is returned unchanged. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> delete(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn delete(from set: Set(member), this member: member) -> Set(member) { + Set(map: dict.delete(set.map, member)) +} + +/// Converts the set into a list of the contained members. +/// +/// The list has no specific ordering, any unintentional ordering may change in +/// future versions of Gleam or Erlang. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert(2) |> to_list +/// [2] +/// ``` +/// +pub fn to_list(set: Set(member)) -> List(member) { + dict.keys(set.map) +} + +/// Creates a new set of the members in a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort +/// [1, 3, 3, 4] +/// ``` +/// +pub fn from_list(members: List(member)) -> Set(member) { + let map = + list.fold( + over: members, + from: dict.new(), + with: fn(m, k) { dict.insert(m, k, token) }, + ) + Set(map) +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Sets are not ordered so the values are not returned in any specific order. +/// Do not write code that relies on the order entries are used by this +/// function as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > from_list([1, 3, 9]) +/// > |> fold(0, fn(member, accumulator) { accumulator + member }) +/// 13 +/// ``` +/// +pub fn fold( + over set: Set(member), + from initial: acc, + with reducer: fn(acc, member) -> acc, +) -> acc { + dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) +} + +/// Creates a new set from an existing set, minus any members that a given +/// function returns `False` for. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > from_list([1, 4, 6, 3, 675, 44, 67]) +/// > |> filter(for: int.is_even) +/// > |> to_list +/// [4, 6, 44] +/// ``` +/// +pub fn filter( + in set: Set(member), + keeping predicate: fn(member) -> Bool, +) -> Set(member) { + Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) +} + +pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { + list.fold(over: disallowed, from: set, with: delete) +} + +/// Creates a new map from a given map, only including any members which are in +/// a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) +/// > |> take([1, 3, 5]) +/// > |> to_list +/// [1, 3] +/// ``` +/// +pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { + Set(dict.take(from: set.map, keeping: desired)) +} + +fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { + case dict.size(first.map) > dict.size(second.map) { + True -> #(first, second) + False -> #(second, first) + } +} + +/// Creates a new set that contains all members of both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { + let #(larger, smaller) = order(first, second) + fold(over: smaller, from: larger, with: insert) +} + +/// Creates a new set that contains members that are present in both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [2] +/// ``` +/// +pub fn intersection( + of first: Set(member), + and second: Set(member), +) -> Set(member) { + let #(larger, smaller) = order(first, second) + take(from: larger, keeping: to_list(smaller)) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam new file mode 100644 index 00000000000..7254fd9fd1c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam @@ -0,0 +1,913 @@ +//// Strings in Gleam are UTF-8 binaries. They can be written in your code as +//// text surrounded by `"double quotes"`. + +import gleam/iterator.{type Iterator} +import gleam/list +import gleam/option.{type Option, None, Some} +import gleam/order +import gleam/string_builder.{type StringBuilder} + +/// Determines if a `String` is empty. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty("") +/// True +/// ``` +/// +/// ```gleam +/// > is_empty("the world") +/// False +/// ``` +/// +pub fn is_empty(str: String) -> Bool { + str == "" +} + +/// Gets the number of grapheme clusters in a given `String`. +/// +/// This function has to iterate across the whole string to count the number of +/// graphemes, so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length("Gleam") +/// 5 +/// ``` +/// +/// ```gleam +/// > length("ß↑e̊") +/// 3 +/// ``` +/// +/// ```gleam +/// > length("") +/// 0 +/// ``` +/// +pub fn length(string: String) -> Int { + do_length(string) +} + +@external(erlang, "string", "length") +@external(javascript, "../gleam_stdlib.mjs", "string_length") +fn do_length(a: String) -> Int + +/// Reverses a `String`. +/// +/// This function has to iterate across the whole `String` so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse("stressed") +/// "desserts" +/// ``` +/// +pub fn reverse(string: String) -> String { + do_reverse(string) +} + +@target(erlang) +fn do_reverse(string: String) -> String { + string + |> string_builder.from_string + |> string_builder.reverse + |> string_builder.to_string +} + +@target(javascript) +fn do_reverse(string: String) -> String { + string + |> to_graphemes + |> list.reverse + |> concat +} + +/// Creates a new `String` by replacing all occurrences of a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > replace("www.example.com", each: ".", with: "-") +/// "www-example-com" +/// ``` +/// +/// ```gleam +/// > replace("a,b,c,d,e", each: ",", with: "/") +/// "a/b/c/d/e" +/// ``` +/// +pub fn replace( + in string: String, + each pattern: String, + with substitute: String, +) -> String { + string + |> string_builder.from_string + |> string_builder.replace(each: pattern, with: substitute) + |> string_builder.to_string +} + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// lowercase. +/// +/// Useful for case-insensitive comparisons. +/// +/// ## Examples +/// +/// ```gleam +/// > lowercase("X-FILES") +/// "x-files" +/// ``` +/// +pub fn lowercase(string: String) -> String { + do_lowercase(string) +} + +@external(erlang, "string", "lowercase") +@external(javascript, "../gleam_stdlib.mjs", "lowercase") +fn do_lowercase(a: String) -> String + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// uppercase. +/// +/// Useful for case-insensitive comparisons and VIRTUAL YELLING. +/// +/// ## Examples +/// +/// ```gleam +/// > uppercase("skinner") +/// "SKINNER" +/// ``` +/// +pub fn uppercase(string: String) -> String { + do_uppercase(string) +} + +@external(erlang, "string", "uppercase") +@external(javascript, "../gleam_stdlib.mjs", "uppercase") +fn do_uppercase(a: String) -> String + +/// Compares two `String`s to see which is "larger" by comparing their graphemes. +/// +/// This does not compare the size or length of the given `String`s. +/// +/// ## Examples +/// +/// ```gleam +/// > compare("Anthony", "Anthony") +/// order.Eq +/// ``` +/// +/// ```gleam +/// > compare("A", "B") +/// order.Lt +/// ``` +/// +pub fn compare(a: String, b: String) -> order.Order { + case a == b { + True -> order.Eq + _ -> + case less_than(a, b) { + True -> order.Lt + _ -> order.Gt + } + } +} + +@external(erlang, "gleam_stdlib", "less_than") +@external(javascript, "../gleam_stdlib.mjs", "less_than") +fn less_than(a: String, b: String) -> Bool + +/// Takes a substring given a start grapheme index and a length. Negative indexes +/// are taken starting from the *end* of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 2) +/// "le" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 10) +/// "leam" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 10, length: 3) +/// "" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -2, length: 2) +/// "am" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -12, length: 2) +/// "" +/// ``` +/// +pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { + case len < 0 { + True -> "" + False -> + case idx < 0 { + True -> { + let translated_idx = length(string) + idx + case translated_idx < 0 { + True -> "" + False -> do_slice(string, translated_idx, len) + } + } + False -> do_slice(string, idx, len) + } + } +} + +@target(erlang) +@external(erlang, "string", "slice") +fn do_slice(a: String, b: Int, c: Int) -> String + +@target(javascript) +fn do_slice(string: String, idx: Int, len: Int) -> String { + string + |> to_graphemes + |> list.drop(idx) + |> list.take(len) + |> concat +} + +/// Drops contents of the first `String` that occur before the second `String`. +/// If the `from` string does not contain the `before` string, `from` is returned unchanged. +/// +/// ## Examples +/// +/// ```gleam +/// > crop(from: "The Lone Gunmen", before: "Lone") +/// "Lone Gunmen" +/// ``` +/// +@external(erlang, "gleam_stdlib", "crop_string") +@external(javascript, "../gleam_stdlib.mjs", "crop_string") +pub fn crop(from string: String, before substring: String) -> String + +/// Drops *n* graphemes from the left side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_left(from: "The Lone Gunmen", up_to: 2) +/// "e Lone Gunmen" +/// ``` +/// +pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, num_graphemes, length(string) - num_graphemes) + } +} + +/// Drops *n* graphemes from the right side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) +/// "Cigarette Smoking M" +/// ``` +/// +pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, 0, length(string) - num_graphemes) + } +} + +/// Checks if the first `String` contains the second. +/// +/// ## Examples +/// +/// ```gleam +/// > contains(does: "theory", contain: "ory") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "the") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "THE") +/// False +/// ``` +/// +@external(erlang, "gleam_stdlib", "contains_string") +@external(javascript, "../gleam_stdlib.mjs", "contains_string") +pub fn contains(does haystack: String, contain needle: String) -> Bool + +/// Checks whether the first `String` starts with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > starts_with("theory", "ory") +/// False +/// ``` +/// +pub fn starts_with(string: String, prefix: String) -> Bool { + do_starts_with(string, prefix) +} + +@external(erlang, "gleam_stdlib", "string_starts_with") +@external(javascript, "../gleam_stdlib.mjs", "starts_with") +fn do_starts_with(a: String, b: String) -> Bool + +/// Checks whether the first `String` ends with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > ends_with("theory", "ory") +/// True +/// ``` +/// +pub fn ends_with(string: String, suffix: String) -> Bool { + do_ends_with(string, suffix) +} + +@external(erlang, "gleam_stdlib", "string_ends_with") +@external(javascript, "../gleam_stdlib.mjs", "ends_with") +fn do_ends_with(a: String, b: String) -> Bool + +/// Creates a list of `String`s by splitting a given string on a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > split("home/gleam/desktop/", on: "/") +/// ["home", "gleam", "desktop", ""] +/// ``` +/// +pub fn split(x: String, on substring: String) -> List(String) { + case substring { + "" -> to_graphemes(x) + _ -> + x + |> string_builder.from_string + |> string_builder.split(on: substring) + |> list.map(with: string_builder.to_string) + } +} + +/// Splits a `String` a single time on the given substring. +/// +/// Returns an `Error` if substring not present. +/// +/// ## Examples +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "/") +/// Ok(#("home", "gleam/desktop/")) +/// ``` +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "?") +/// Error(Nil) +/// ``` +/// +pub fn split_once( + x: String, + on substring: String, +) -> Result(#(String, String), Nil) { + do_split_once(x, substring) +} + +@target(erlang) +@external(erlang, "string", "split") +fn erl_split(a: String, b: String) -> List(String) + +@target(erlang) +fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { + case erl_split(x, substring) { + [first, rest] -> Ok(#(first, rest)) + _ -> Error(Nil) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split_once") +fn do_split_once( + x x: String, + substring substring: String, +) -> Result(#(String, String), Nil) + +/// Creates a new `String` by joining two `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: "butter", suffix: "fly") +/// "butterfly" +/// ``` +/// +pub fn append(to first: String, suffix second: String) -> String { + first + |> string_builder.from_string + |> string_builder.append(second) + |> string_builder.to_string +} + +/// Creates a new `String` by joining many `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > concat(["never", "the", "less"]) +/// "nevertheless" +/// ``` +/// +pub fn concat(strings: List(String)) -> String { + strings + |> string_builder.from_strings + |> string_builder.to_string +} + +/// Creates a new `String` by repeating a `String` a given number of times. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("ha", times: 3) +/// "hahaha" +/// ``` +/// +pub fn repeat(string: String, times times: Int) -> String { + iterator.repeat(string) + |> iterator.take(times) + |> iterator.to_list + |> concat +} + +/// Joins many `String`s together with a given separator. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > join(["home","evan","Desktop"], with: "/") +/// "home/evan/Desktop" +/// ``` +/// +pub fn join(strings: List(String), with separator: String) -> String { + do_join(strings, separator) +} + +@target(erlang) +fn do_join(strings: List(String), separator: String) -> String { + strings + |> list.intersperse(with: separator) + |> concat +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "join") +fn do_join(strings strings: List(String), string string: String) -> String + +/// Pads a `String` on the left until it has at least given number of graphemes. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_left("121", to: 5, with: ".") +/// "..121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 3, with: ".") +/// "121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 2, with: ".") +/// "121" +/// ``` +/// +pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + padding(to_pad_length, pad_string) + |> iterator.append(iterator.single(string)) + |> iterator.to_list + |> concat +} + +/// Pads a `String` on the right until it has a given length. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_right("123", to: 5, with: ".") +/// "123.." +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 3, with: ".") +/// "123" +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 2, with: ".") +/// "123" +/// ``` +/// +pub fn pad_right( + string: String, + to desired_length: Int, + with pad_string: String, +) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + iterator.single(string) + |> iterator.append(padding(to_pad_length, pad_string)) + |> iterator.to_list + |> concat +} + +fn padding(size: Int, pad_string: String) -> Iterator(String) { + let pad_length = length(pad_string) + let num_pads = size / pad_length + let extra = size % pad_length + iterator.repeat(pad_string) + |> iterator.take(num_pads) + |> iterator.append(iterator.single(slice(pad_string, 0, extra))) +} + +/// Removes whitespace on both sides of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim(" hats \n") +/// "hats" +/// ``` +/// +pub fn trim(string: String) -> String { + do_trim(string) +} + +@target(erlang) +fn do_trim(string: String) -> String { + erl_trim(string, Both) +} + +@target(erlang) +type Direction { + Leading + Trailing + Both +} + +@target(erlang) +@external(erlang, "string", "trim") +fn erl_trim(a: String, b: Direction) -> String + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim") +fn do_trim(string string: String) -> String + +/// Removes whitespace on the left of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_left(" hats \n") +/// "hats \n" +/// ``` +/// +pub fn trim_left(string: String) -> String { + do_trim_left(string) +} + +@target(erlang) +fn do_trim_left(string: String) -> String { + erl_trim(string, Leading) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim_left") +fn do_trim_left(string string: String) -> String + +/// Removes whitespace on the right of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_right(" hats \n") +/// " hats" +/// ``` +/// +pub fn trim_right(string: String) -> String { + do_trim_right(string) +} + +@target(erlang) +fn do_trim_right(string: String) -> String { + erl_trim(string, Trailing) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim_right") +fn do_trim_right(string string: String) -> String + +/// Splits a non-empty `String` into its first element (head) and rest (tail). +/// This lets you pattern match on `String`s exactly as you would with lists. +/// +/// Note on JavaScript using the function to iterate over a string will likely +/// be slower than using `to_graphemes` due to string slicing being more +/// expensive on JavaScript than Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_grapheme("gleam") +/// Ok(#("g", "leam")) +/// ``` +/// +/// ```gleam +/// > pop_grapheme("") +/// Error(Nil) +/// ``` +/// +pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { + do_pop_grapheme(string) +} + +@external(erlang, "gleam_stdlib", "string_pop_grapheme") +@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") +fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) + +/// Converts a `String` to a list of +/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). +/// +/// ```gleam +/// > to_graphemes("abc") +/// ["a", "b", "c"] +/// ``` +/// +@external(javascript, "../gleam_stdlib.mjs", "graphemes") +pub fn to_graphemes(string: String) -> List(String) { + do_to_graphemes(string, []) + |> list.reverse +} + +fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { + case pop_grapheme(string) { + Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) + _ -> acc + } +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "codepoint") +fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint + +/// Converts a `String` to a `List` of `UtfCodepoint`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > "a" |> to_utf_codepoints +/// [UtfCodepoint(97)] +/// ``` +/// +/// ```gleam +/// // Semantically the same as: +/// // ["🏳", "️", "‍", "🌈"] or: +/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] +/// > "🏳️‍🌈" |> to_utf_codepoints +/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] +/// ``` +/// +pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints(string) +} + +@target(erlang) +fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints_impl(<>, []) + |> list.reverse +} + +@target(erlang) +fn do_to_utf_codepoints_impl( + bit_array: BitArray, + acc: List(UtfCodepoint), +) -> List(UtfCodepoint) { + case bit_array { + <> -> + do_to_utf_codepoints_impl(rest, [first, ..acc]) + _ -> acc + } +} + +@target(javascript) +fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + string + |> string_to_codepoint_integer_list + |> list.map(unsafe_int_to_utf_codepoint) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") +fn string_to_codepoint_integer_list(a: String) -> List(Int) + +/// Converts a `List` of `UtfCodepoint`s to a `String`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > { +/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( +/// > utf_codepoint(97), +/// > utf_codepoint(98), +/// > utf_codepoint(99), +/// > ) +/// > [a, b, c] +/// > } +/// > |> from_utf_codepoints +/// "abc" +/// ``` +/// +@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") +@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") +pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String + +/// Converts an integer to a `UtfCodepoint`. +/// +/// Returns an `Error` if the integer does not represent a valid UTF codepoint. +/// +pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { + case value { + i if i > 1_114_111 -> Error(Nil) + 65_534 | 65_535 -> Error(Nil) + i if i >= 55_296 && i <= 57_343 -> Error(Nil) + i -> Ok(unsafe_int_to_utf_codepoint(i)) + } +} + +/// Converts an UtfCodepoint to its ordinal code point value. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") +/// > utf_codepoint_to_int(utf_codepoint) +/// 128156 +/// ``` +/// +pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { + do_utf_codepoint_to_int(cp) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") +fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int + +/// Converts a `String` into `Option(String)` where an empty `String` becomes +/// `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_option("") +/// None +/// ``` +/// +/// ```gleam +/// > to_option("hats") +/// Some("hats") +/// ``` +/// +pub fn to_option(s: String) -> Option(String) { + case s { + "" -> None + _ -> Some(s) + } +} + +/// Returns the first grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > first("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first("icecream") +/// Ok("i") +/// ``` +/// +pub fn first(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, _)) -> Ok(first) + Error(e) -> Error(e) + } +} + +/// Returns the last grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > last("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last("icecream") +/// Ok("m") +/// ``` +/// +pub fn last(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, "")) -> Ok(first) + Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) + Error(e) -> Error(e) + } +} + +/// Creates a new `String` with the first grapheme in the input `String` +/// converted to uppercase and the remaining graphemes to lowercase. +/// +/// ## Examples +/// +/// ```gleam +/// > capitalise("mamouna") +/// "Mamouna" +/// ``` +/// +pub fn capitalise(s: String) -> String { + case pop_grapheme(s) { + Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) + _ -> "" + } +} + +/// Returns a `String` representation of a term in Gleam syntax. +/// +pub fn inspect(term: anything) -> String { + do_inspect(term) + |> string_builder.to_string +} + +@external(erlang, "gleam_stdlib", "inspect") +@external(javascript, "../gleam_stdlib.mjs", "inspect") +fn do_inspect(term term: anything) -> StringBuilder + +/// Returns the number of bytes in a `String`. +/// +/// This function runs in constant time on Erlang and in linear time on +/// JavaScript. +/// +/// ## Examples +/// +/// ```gleam +/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") +/// 58 +/// ``` +/// +@external(erlang, "erlang", "byte_size") +@external(javascript, "../gleam_stdlib.mjs", "byte_size") +pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam new file mode 100644 index 00000000000..5792ca8699d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam @@ -0,0 +1,298 @@ +import gleam/list + +/// `StringBuilder` is a type used for efficiently building strings. +/// +/// When we append one string to another the strings must be copied to a +/// new location in memory so that they can sit together. This behaviour +/// enables efficient reading of the string but copying can be expensive, +/// especially if we want to join many strings together. +/// +/// `StringBuilder` is different in that it can be joined together in constant time +/// using minimal memory, and then can be efficiently converted to a string +/// using the `to_string` function. +/// +/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this +/// type is compatible with normal strings. +/// +pub type StringBuilder + +/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many +/// builders together. +/// +pub fn new() -> StringBuilder { + do_from_strings([]) +} + +/// Prepends a `String` onto the start of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn prepend( + to builder: StringBuilder, + prefix prefix: String, +) -> StringBuilder { + append_builder(from_string(prefix), builder) +} + +/// Appends a `String` onto the end of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { + append_builder(builder, from_string(second)) +} + +/// Prepends some `StringBuilder` onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder( + to builder: StringBuilder, + prefix prefix: StringBuilder, +) -> StringBuilder { + do_append(prefix, builder) +} + +/// Appends some `StringBuilder` onto the end of another. +/// +/// Runs in constant time. +/// +pub fn append_builder( + to builder: StringBuilder, + suffix suffix: StringBuilder, +) -> StringBuilder { + do_append(builder, suffix) +} + +@external(erlang, "gleam_stdlib", "iodata_append") +@external(javascript, "../gleam_stdlib.mjs", "add") +fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder + +/// Converts a list of strings into a builder. +/// +/// Runs in constant time. +/// +pub fn from_strings(strings: List(String)) -> StringBuilder { + do_from_strings(strings) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "concat") +fn do_from_strings(a: List(String)) -> StringBuilder + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +pub fn concat(builders: List(StringBuilder)) -> StringBuilder { + do_concat(builders) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "concat") +fn do_concat(a: List(StringBuilder)) -> StringBuilder + +/// Converts a string into a builder. +/// +/// Runs in constant time. +/// +pub fn from_string(string: String) -> StringBuilder { + do_from_string(string) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_from_string(a: String) -> StringBuilder + +/// Turns an `StringBuilder` into a `String` +/// +/// This function is implemented natively by the virtual machine and is highly +/// optimised. +/// +pub fn to_string(builder: StringBuilder) -> String { + do_to_string(builder) +} + +@external(erlang, "unicode", "characters_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_to_string(a: StringBuilder) -> String + +/// Returns the size of the `StringBuilder` in bytes. +/// +pub fn byte_size(builder: StringBuilder) -> Int { + do_byte_size(builder) +} + +@external(erlang, "erlang", "iolist_size") +@external(javascript, "../gleam_stdlib.mjs", "length") +fn do_byte_size(a: StringBuilder) -> Int + +/// Joins the given builders into a new builder separated with the given string +/// +pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { + builders + |> list.intersperse(from_string(sep)) + |> concat +} + +/// Converts a builder to a new builder where the contents have been +/// lowercased. +/// +pub fn lowercase(builder: StringBuilder) -> StringBuilder { + do_lowercase(builder) +} + +@external(erlang, "string", "lowercase") +@external(javascript, "../gleam_stdlib.mjs", "lowercase") +fn do_lowercase(a: StringBuilder) -> StringBuilder + +/// Converts a builder to a new builder where the contents have been +/// uppercased. +/// +pub fn uppercase(builder: StringBuilder) -> StringBuilder { + do_uppercase(builder) +} + +@external(erlang, "string", "uppercase") +@external(javascript, "../gleam_stdlib.mjs", "uppercase") +fn do_uppercase(a: StringBuilder) -> StringBuilder + +/// Converts a builder to a new builder with the contents reversed. +/// +pub fn reverse(builder: StringBuilder) -> StringBuilder { + do_reverse(builder) +} + +@target(erlang) +@external(erlang, "string", "reverse") +fn do_reverse(a: StringBuilder) -> StringBuilder + +@target(javascript) +fn do_reverse(builder: StringBuilder) -> StringBuilder { + builder + |> to_string + |> do_to_graphemes + |> list.reverse + |> from_strings +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "graphemes") +fn do_to_graphemes(string string: String) -> List(String) + +/// Splits a builder on a given pattern into a list of builders. +/// +pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { + do_split(iodata, pattern) +} + +@target(erlang) +type Direction { + All +} + +@target(erlang) +@external(erlang, "string", "split") +fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) + +@target(erlang) +fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { + erl_split(iodata, pattern, All) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split") +fn do_split( + builder builder: StringBuilder, + pattern pattern: String, +) -> List(StringBuilder) + +/// Replaces all instances of a pattern with a given string substitute. +/// +pub fn replace( + in builder: StringBuilder, + each pattern: String, + with substitute: String, +) -> StringBuilder { + do_replace(builder, pattern, substitute) +} + +@target(erlang) +fn do_replace( + iodata: StringBuilder, + pattern: String, + substitute: String, +) -> StringBuilder { + erl_replace(iodata, pattern, substitute, All) +} + +@target(erlang) +@external(erlang, "string", "replace") +fn erl_replace( + a: StringBuilder, + b: String, + c: String, + d: Direction, +) -> StringBuilder + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "string_replace") +fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder + +/// Compares two builders to determine if they have the same textual content. +/// +/// Comparing two iodata using the `==` operator may return `False` even if they +/// have the same content as they may have been build in different ways, so +/// using this function is often preferred. +/// +/// ## Examples +/// +/// ```gleam +/// > from_strings(["a", "b"]) == from_string("ab") +/// False +/// ``` +/// +/// ```gleam +/// > is_equal(from_strings(["a", "b"]), from_string("ab")) +/// True +/// ``` +/// +pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { + do_is_equal(a, b) +} + +@external(erlang, "string", "equal") +@external(javascript, "../gleam_stdlib.mjs", "equal") +fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool + +/// Inspects a builder to determine if it is equivalent to an empty string. +/// +/// ## Examples +/// +/// ```gleam +/// > from_string("ok") |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > from_string("") |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > from_strings([]) |> is_empty +/// True +/// ``` +/// +pub fn is_empty(builder: StringBuilder) -> Bool { + do_is_empty(builder) +} + +@target(erlang) +@external(erlang, "string", "is_empty") +fn do_is_empty(a: StringBuilder) -> Bool + +@target(javascript) +fn do_is_empty(builder: StringBuilder) -> Bool { + from_string("") == builder +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam new file mode 100644 index 00000000000..11f6ea68cd2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam @@ -0,0 +1,462 @@ +//// Utilities for working with URIs +//// +//// This module provides functions for working with URIs (for example, parsing +//// URIs or encoding query strings). The functions in this module are implemented +//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). +//// +//// Query encoding (Form encoding) is defined in the +//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). + +import gleam/int +import gleam/list +import gleam/option.{type Option, None, Some} +import gleam/string +import gleam/string_builder.{type StringBuilder} +@target(javascript) +import gleam/pair +@target(javascript) +import gleam/regex +@target(javascript) +import gleam/result + +/// Type representing holding the parsed components of an URI. +/// All components of a URI are optional, except the path. +/// +pub type Uri { + Uri( + scheme: Option(String), + userinfo: Option(String), + host: Option(String), + port: Option(Int), + path: String, + query: Option(String), + fragment: Option(String), + ) +} + +/// Parses a compliant URI string into the `Uri` Type. +/// If the string is not a valid URI string then an error is returned. +/// +/// The opposite operation is `uri.to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("https://example.com:1234/a/b?query=true#fragment") +/// Ok( +/// Uri( +/// scheme: Some("https"), +/// userinfo: None, +/// host: Some("example.com"), +/// port: Some(1234), +/// path: "/a/b", +/// query: Some("query=true"), +/// fragment: Some("fragment") +/// ) +/// ) +/// ``` +/// +pub fn parse(uri_string: String) -> Result(Uri, Nil) { + do_parse(uri_string) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "uri_parse") +fn do_parse(a: String) -> Result(Uri, Nil) + +@target(javascript) +fn do_parse(uri_string: String) -> Result(Uri, Nil) { + // From https://tools.ietf.org/html/rfc3986#appendix-B + let pattern = + // 12 3 4 5 6 7 8 + "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" + let matches = + pattern + |> regex_submatches(uri_string) + |> pad_list(8) + + let #(scheme, authority, path, query, fragment) = case matches { + [ + _scheme_with_colon, + scheme, + authority_with_slashes, + _authority, + path, + query_with_question_mark, + _query, + fragment, + ] -> #( + scheme, + authority_with_slashes, + path, + query_with_question_mark, + fragment, + ) + _ -> #(None, None, None, None, None) + } + + let scheme = noneify_empty_string(scheme) + let path = option.unwrap(path, "") + let query = noneify_query(query) + let #(userinfo, host, port) = split_authority(authority) + let fragment = + fragment + |> option.to_result(Nil) + |> result.try(string.pop_grapheme) + |> result.map(pair.second) + |> option.from_result + let scheme = + scheme + |> noneify_empty_string + |> option.map(string.lowercase) + Ok(Uri( + scheme: scheme, + userinfo: userinfo, + host: host, + port: port, + path: path, + query: query, + fragment: fragment, + )) +} + +@target(javascript) +fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { + pattern + |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) + |> result.nil_error + |> result.map(regex.scan(_, string)) + |> result.try(list.first) + |> result.map(fn(m: regex.Match) { m.submatches }) + |> result.unwrap([]) +} + +@target(javascript) +fn noneify_query(x: Option(String)) -> Option(String) { + case x { + None -> None + Some(x) -> + case string.pop_grapheme(x) { + Ok(#("?", query)) -> Some(query) + _ -> None + } + } +} + +@target(javascript) +fn noneify_empty_string(x: Option(String)) -> Option(String) { + case x { + Some("") | None -> None + Some(_) -> x + } +} + +// Split an authority into its userinfo, host and port parts. +@target(javascript) +fn split_authority( + authority: Option(String), +) -> #(Option(String), Option(String), Option(Int)) { + case option.unwrap(authority, "") { + "" -> #(None, None, None) + "//" -> #(None, Some(""), None) + authority -> { + let matches = + "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" + |> regex_submatches(authority) + |> pad_list(6) + case matches { + [_, _, userinfo, host, _, port] -> { + let userinfo = noneify_empty_string(userinfo) + let host = noneify_empty_string(host) + let port = + port + |> option.unwrap("") + |> int.parse + |> option.from_result + #(userinfo, host, port) + } + _ -> #(None, None, None) + } + } + } +} + +@target(javascript) +fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { + list + |> list.append(list.repeat(None, extra_required(list, size))) +} + +@target(javascript) +fn extra_required(list: List(a), remaining: Int) -> Int { + case list { + _ if remaining == 0 -> 0 + [] -> remaining + [_, ..xs] -> extra_required(xs, remaining - 1) + } +} + +/// Parses an urlencoded query string into a list of key value pairs. +/// Returns an error for invalid encoding. +/// +/// The opposite operation is `uri.query_to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse_query("a=1&b=2") +/// Ok([#("a", "1"), #("b", "2")]) +/// ``` +/// +pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { + do_parse_query(query) +} + +@external(erlang, "gleam_stdlib", "parse_query") +@external(javascript, "../gleam_stdlib.mjs", "parse_query") +fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) + +/// Encodes a list of key value pairs as a URI query string. +/// +/// The opposite operation is `uri.parse_query`. +/// +/// ## Examples +/// +/// ```gleam +/// > query_to_string([#("a", "1"), #("b", "2")]) +/// "a=1&b=2" +/// ``` +/// +pub fn query_to_string(query: List(#(String, String))) -> String { + query + |> list.map(query_pair) + |> list.intersperse(string_builder.from_string("&")) + |> string_builder.concat + |> string_builder.to_string +} + +fn query_pair(pair: #(String, String)) -> StringBuilder { + string_builder.from_strings([ + percent_encode(pair.0), + "=", + percent_encode(pair.1), + ]) +} + +/// Encodes a string into a percent encoded representation. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_encode("100% great") +/// "100%25%20great" +/// ``` +/// +pub fn percent_encode(value: String) -> String { + do_percent_encode(value) +} + +@external(erlang, "gleam_stdlib", "percent_encode") +@external(javascript, "../gleam_stdlib.mjs", "percent_encode") +fn do_percent_encode(a: String) -> String + +/// Decodes a percent encoded string. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_decode("100%25+great") +/// Ok("100% great") +/// ``` +/// +pub fn percent_decode(value: String) -> Result(String, Nil) { + do_percent_decode(value) +} + +@external(erlang, "gleam_stdlib", "percent_decode") +@external(javascript, "../gleam_stdlib.mjs", "percent_decode") +fn do_percent_decode(a: String) -> Result(String, Nil) + +fn do_remove_dot_segments( + input: List(String), + accumulator: List(String), +) -> List(String) { + case input { + [] -> list.reverse(accumulator) + [segment, ..rest] -> { + let accumulator = case segment, accumulator { + "", accumulator -> accumulator + ".", accumulator -> accumulator + "..", [] -> [] + "..", [_, ..accumulator] -> accumulator + segment, accumulator -> [segment, ..accumulator] + } + do_remove_dot_segments(rest, accumulator) + } + } +} + +fn remove_dot_segments(input: List(String)) -> List(String) { + do_remove_dot_segments(input, []) +} + +/// Splits the path section of a URI into it's constituent segments. +/// +/// Removes empty segments and resolves dot-segments as specified in +/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. +/// +/// ## Examples +/// +/// ```gleam +/// > path_segments("/users/1") +/// ["users" ,"1"] +/// ``` +/// +pub fn path_segments(path: String) -> List(String) { + remove_dot_segments(string.split(path, "/")) +} + +/// Encodes a `Uri` value as a URI string. +/// +/// The opposite operation is `uri.parse`. +/// +/// ## Examples +/// +/// ```gleam +/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) +/// > to_string(uri) +/// "http://example.com" +/// ``` +/// +pub fn to_string(uri: Uri) -> String { + let parts = case uri.fragment { + Some(fragment) -> ["#", fragment] + _ -> [] + } + let parts = case uri.query { + Some(query) -> ["?", query, ..parts] + _ -> parts + } + let parts = [uri.path, ..parts] + let parts = case uri.host, string.starts_with(uri.path, "/") { + Some(host), False if host != "" -> ["/", ..parts] + _, _ -> parts + } + let parts = case uri.host, uri.port { + Some(_), Some(port) -> [":", int.to_string(port), ..parts] + _, _ -> parts + } + let parts = case uri.scheme, uri.userinfo, uri.host { + Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] + Some(s), None, Some(h) -> [s, "://", h, ..parts] + Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] + None, None, Some(h) -> ["//", h, ..parts] + _, _, _ -> parts + } + string.concat(parts) +} + +/// Fetches the origin of a URI. +/// +/// Returns the origin of a uri as defined in +/// [RFC 6454](https://tools.ietf.org/html/rfc6454) +/// +/// The supported URI schemes are `http` and `https`. +/// URLs without a scheme will return `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") +/// > origin(uri) +/// Ok("http://example.com") +/// ``` +/// +pub fn origin(uri: Uri) -> Result(String, Nil) { + let Uri(scheme: scheme, host: host, port: port, ..) = uri + case scheme { + Some("https") if port == Some(443) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some("http") if port == Some(80) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some(s) if s == "http" || s == "https" -> { + let origin = Uri(scheme, None, host, port, "", None, None) + Ok(to_string(origin)) + } + _ -> Error(Nil) + } +} + +fn drop_last(elements: List(a)) -> List(a) { + list.take(from: elements, up_to: list.length(elements) - 1) +} + +fn join_segments(segments: List(String)) -> String { + string.join(["", ..segments], "/") +} + +/// Resolves a URI with respect to the given base URI. +/// +/// The base URI must be an absolute URI or this function will return an error. +/// The algorithm for merging uris is described in +/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). +/// +pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { + case base { + Uri(scheme: Some(_), host: Some(_), ..) -> + case relative { + Uri(host: Some(_), ..) -> { + let path = + string.split(relative.path, "/") + |> remove_dot_segments() + |> join_segments() + let resolved = + Uri( + option.or(relative.scheme, base.scheme), + None, + relative.host, + option.or(relative.port, base.port), + path, + relative.query, + relative.fragment, + ) + Ok(resolved) + } + _ -> { + let #(new_path, new_query) = case relative.path { + "" -> #(base.path, option.or(relative.query, base.query)) + _ -> { + let path_segments = case string.starts_with(relative.path, "/") { + True -> string.split(relative.path, "/") + False -> + string.split(base.path, "/") + |> drop_last() + |> list.append(string.split(relative.path, "/")) + } + let path = + path_segments + |> remove_dot_segments() + |> join_segments() + #(path, relative.query) + } + } + let resolved = + Uri( + base.scheme, + None, + base.host, + base.port, + new_path, + new_query, + relative.fragment, + ) + Ok(resolved) + } + } + _ -> Error(Nil) + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl new file mode 100644 index 00000000000..65bc3f63e4d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl @@ -0,0 +1,20 @@ +-module(gleam@base). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). + +-spec encode64(bitstring(), boolean()) -> binary(). +encode64(Input, Padding) -> + gleam@bit_array:base64_encode(Input, Padding). + +-spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. +decode64(Encoded) -> + gleam@bit_array:base64_decode(Encoded). + +-spec url_encode64(bitstring(), boolean()) -> binary(). +url_encode64(Input, Padding) -> + gleam@bit_array:base64_url_encode(Input, Padding). + +-spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. +url_decode64(Encoded) -> + gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl new file mode 100644 index 00000000000..ba18dfaabdd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl @@ -0,0 +1,102 @@ +-module(gleam@bit_array). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). + +-spec from_string(binary()) -> bitstring(). +from_string(X) -> + gleam_stdlib:identity(X). + +-spec byte_size(bitstring()) -> integer(). +byte_size(X) -> + erlang:byte_size(X). + +-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | + {error, nil}. +slice(String, Position, Length) -> + gleam_stdlib:bit_array_slice(String, Position, Length). + +-spec do_is_utf8(bitstring()) -> boolean(). +do_is_utf8(Bits) -> + case Bits of + <<>> -> + true; + + <<_/utf8, Rest/binary>> -> + do_is_utf8(Rest); + + _ -> + false + end. + +-spec is_utf8(bitstring()) -> boolean(). +is_utf8(Bits) -> + do_is_utf8(Bits). + +-spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. +do_to_string(Bits) -> + case is_utf8(Bits) of + true -> + {ok, gleam_stdlib:identity(Bits)}; + + false -> + {error, nil} + end. + +-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. +to_string(Bits) -> + do_to_string(Bits). + +-spec concat(list(bitstring())) -> bitstring(). +concat(Bit_arrays) -> + gleam_stdlib:bit_array_concat(Bit_arrays). + +-spec append(bitstring(), bitstring()) -> bitstring(). +append(First, Second) -> + gleam_stdlib:bit_array_concat([First, Second]). + +-spec base64_encode(bitstring(), boolean()) -> binary(). +base64_encode(Input, Padding) -> + Encoded = base64:encode(Input), + case Padding of + true -> + Encoded; + + false -> + gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) + end. + +-spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base64_decode(Encoded) -> + Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of + 0 -> + Encoded; + + N -> + gleam@string:append( + Encoded, + gleam@string:repeat(<<"="/utf8>>, 4 - N) + ) + end, + gleam_stdlib:base_decode64(Padded). + +-spec base64_url_encode(bitstring(), boolean()) -> binary(). +base64_url_encode(Input, Padding) -> + _pipe = base64_encode(Input, Padding), + _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), + gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). + +-spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base64_url_decode(Encoded) -> + _pipe = Encoded, + _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), + _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), + base64_decode(_pipe@2). + +-spec base16_encode(bitstring()) -> binary(). +base16_encode(Input) -> + binary:encode_hex(Input). + +-spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base16_decode(Input) -> + gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl new file mode 100644 index 00000000000..284c6d46cc3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl @@ -0,0 +1,66 @@ +-module(gleam@bit_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). + +-spec new() -> gleam@bytes_builder:bytes_builder(). +new() -> + gleam@bytes_builder:new(). + +-spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). +prepend(To, Prefix) -> + gleam@bytes_builder:prepend(To, Prefix). + +-spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). +append(To, Suffix) -> + gleam@bytes_builder:append(To, Suffix). + +-spec prepend_builder( + gleam@bytes_builder:bytes_builder(), + gleam@bytes_builder:bytes_builder() +) -> gleam@bytes_builder:bytes_builder(). +prepend_builder(To, Prefix) -> + gleam@bytes_builder:prepend_builder(To, Prefix). + +-spec append_builder( + gleam@bytes_builder:bytes_builder(), + gleam@bytes_builder:bytes_builder() +) -> gleam@bytes_builder:bytes_builder(). +append_builder(First, Second) -> + gleam_stdlib:iodata_append(First, Second). + +-spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). +prepend_string(To, Prefix) -> + gleam@bytes_builder:prepend_string(To, Prefix). + +-spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). +append_string(To, Suffix) -> + gleam@bytes_builder:append_string(To, Suffix). + +-spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). +concat_bit_strings(Bits) -> + gleam_stdlib:identity(Bits). + +-spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). +from_string(String) -> + gleam_stdlib:wrap_list(String). + +-spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). +from_string_builder(Builder) -> + gleam_stdlib:wrap_list(Builder). + +-spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). +from_bit_string(Bits) -> + gleam_stdlib:wrap_list(Bits). + +-spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). +to_bit_string(Builder) -> + erlang:list_to_bitstring(Builder). + +-spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl new file mode 100644 index 00000000000..7dabaa3bbc1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl @@ -0,0 +1,33 @@ +-module(gleam@bit_string). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). + +-spec from_string(binary()) -> bitstring(). +from_string(X) -> + gleam_stdlib:identity(X). + +-spec byte_size(bitstring()) -> integer(). +byte_size(X) -> + erlang:byte_size(X). + +-spec append(bitstring(), bitstring()) -> bitstring(). +append(First, Second) -> + gleam@bit_array:append(First, Second). + +-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | + {error, nil}. +slice(String, Position, Length) -> + gleam_stdlib:bit_array_slice(String, Position, Length). + +-spec is_utf8(bitstring()) -> boolean(). +is_utf8(Bits) -> + gleam@bit_array:is_utf8(Bits). + +-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. +to_string(Bits) -> + gleam@bit_array:to_string(Bits). + +-spec concat(list(bitstring())) -> bitstring(). +concat(Bit_strings) -> + gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl new file mode 100644 index 00000000000..5f95f4d8314 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl @@ -0,0 +1,162 @@ +-module(gleam@bool). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). + +-spec 'and'(boolean(), boolean()) -> boolean(). +'and'(A, B) -> + A andalso B. + +-spec 'or'(boolean(), boolean()) -> boolean(). +'or'(A, B) -> + A orelse B. + +-spec negate(boolean()) -> boolean(). +negate(Bool) -> + case Bool of + true -> + false; + + false -> + true + end. + +-spec nor(boolean(), boolean()) -> boolean(). +nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + false + end. + +-spec nand(boolean(), boolean()) -> boolean(). +nand(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_or(boolean(), boolean()) -> boolean(). +exclusive_or(A, B) -> + case {A, B} of + {false, false} -> + false; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_nor(boolean(), boolean()) -> boolean(). +exclusive_nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + true + end. + +-spec compare(boolean(), boolean()) -> gleam@order:order(). +compare(A, B) -> + case {A, B} of + {true, true} -> + eq; + + {true, false} -> + gt; + + {false, false} -> + eq; + + {false, true} -> + lt + end. + +-spec max(boolean(), boolean()) -> boolean(). +max(A, B) -> + case A of + true -> + true; + + false -> + B + end. + +-spec min(boolean(), boolean()) -> boolean(). +min(A, B) -> + case A of + false -> + false; + + true -> + B + end. + +-spec to_int(boolean()) -> integer(). +to_int(Bool) -> + case Bool of + false -> + 0; + + true -> + 1 + end. + +-spec to_string(boolean()) -> binary(). +to_string(Bool) -> + case Bool of + false -> + <<"False"/utf8>>; + + true -> + <<"True"/utf8>> + end. + +-spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. +guard(Requirement, Consequence, Alternative) -> + case Requirement of + true -> + Consequence; + + false -> + Alternative() + end. + +-spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. +lazy_guard(Requirement, Consequence, Alternative) -> + case Requirement of + true -> + Consequence(); + + false -> + Alternative() + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl new file mode 100644 index 00000000000..2f6dd93a9f3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl @@ -0,0 +1,87 @@ +-module(gleam@bytes_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). +-export_type([bytes_builder/0]). + +-opaque bytes_builder() :: {bytes, bitstring()} | + {text, gleam@string_builder:string_builder()} | + {many, list(bytes_builder())}. + +-spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). +append_builder(First, Second) -> + gleam_stdlib:iodata_append(First, Second). + +-spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). +prepend_builder(Second, First) -> + gleam_stdlib:iodata_append(First, Second). + +-spec concat(list(bytes_builder())) -> bytes_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec new() -> bytes_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec from_string(binary()) -> bytes_builder(). +from_string(String) -> + gleam_stdlib:wrap_list(String). + +-spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). +prepend_string(Second, First) -> + gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). + +-spec append_string(bytes_builder(), binary()) -> bytes_builder(). +append_string(First, Second) -> + gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). + +-spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). +from_string_builder(Builder) -> + gleam_stdlib:wrap_list(Builder). + +-spec from_bit_array(bitstring()) -> bytes_builder(). +from_bit_array(Bits) -> + gleam_stdlib:wrap_list(Bits). + +-spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). +prepend(Second, First) -> + gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). + +-spec append(bytes_builder(), bitstring()) -> bytes_builder(). +append(First, Second) -> + gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). + +-spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). +concat_bit_arrays(Bits) -> + gleam_stdlib:identity(Bits). + +-spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). +to_list(Stack, Acc) -> + case Stack of + [] -> + Acc; + + [[] | Remaining_stack] -> + to_list(Remaining_stack, Acc); + + [[{bytes, Bits} | Rest] | Remaining_stack@1] -> + to_list([Rest | Remaining_stack@1], [Bits | Acc]); + + [[{text, Builder} | Rest@1] | Remaining_stack@2] -> + Bits@1 = gleam_stdlib:identity( + gleam@string_builder:to_string(Builder) + ), + to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); + + [[{many, Builders} | Rest@2] | Remaining_stack@3] -> + to_list([Builders, Rest@2 | Remaining_stack@3], Acc) + end. + +-spec to_bit_array(bytes_builder()) -> bitstring(). +to_bit_array(Builder) -> + erlang:list_to_bitstring(Builder). + +-spec byte_size(bytes_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl new file mode 100644 index 00000000000..99c231e18cc --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl @@ -0,0 +1,97 @@ +-module(gleam@dict). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). +-export_type([dict/2]). + +-type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. + +-spec size(dict(any(), any())) -> integer(). +size(Dict) -> + maps:size(Dict). + +-spec to_list(dict(NZ, OA)) -> list({NZ, OA}). +to_list(Dict) -> + maps:to_list(Dict). + +-spec from_list(list({OJ, OK})) -> dict(OJ, OK). +from_list(List) -> + maps:from_list(List). + +-spec has_key(dict(OT, any()), OT) -> boolean(). +has_key(Dict, Key) -> + maps:is_key(Key, Dict). + +-spec new() -> dict(any(), any()). +new() -> + maps:new(). + +-spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. +get(From, Get) -> + gleam_stdlib:map_get(From, Get). + +-spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). +insert(Dict, Key, Value) -> + maps:put(Key, Value, Dict). + +-spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). +map_values(Dict, Fun) -> + maps:map(Fun, Dict). + +-spec keys(dict(QV, any())) -> list(QV). +keys(Dict) -> + maps:keys(Dict). + +-spec values(dict(any(), RG)) -> list(RG). +values(Dict) -> + maps:values(Dict). + +-spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). +filter(Dict, Predicate) -> + maps:filter(Predicate, Dict). + +-spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). +take(Dict, Desired_keys) -> + maps:with(Desired_keys, Dict). + +-spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). +merge(Dict, New_entries) -> + maps:merge(Dict, New_entries). + +-spec delete(dict(TF, TG), TF) -> dict(TF, TG). +delete(Dict, Key) -> + maps:remove(Key, Dict). + +-spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). +drop(Dict, Disallowed_keys) -> + case Disallowed_keys of + [] -> + Dict; + + [X | Xs] -> + drop(delete(Dict, X), Xs) + end. + +-spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). +update(Dict, Key, Fun) -> + _pipe = Dict, + _pipe@1 = get(_pipe, Key), + _pipe@2 = gleam@option:from_result(_pipe@1), + _pipe@3 = Fun(_pipe@2), + insert(Dict, Key, _pipe@3). + +-spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. +do_fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [{K, V} | Rest] -> + do_fold(Rest, Fun(Initial, K, V), Fun) + end. + +-spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. +fold(Dict, Initial, Fun) -> + _pipe = Dict, + _pipe@1 = to_list(_pipe), + do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl new file mode 100644 index 00000000000..2c6016f4222 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl @@ -0,0 +1,808 @@ +-module(gleam@dynamic). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). +-export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). + +-type dynamic_() :: any(). + +-type decode_error() :: {decode_error, binary(), binary(), list(binary())}. + +-type unknown_tuple() :: any(). + +-spec from(any()) -> dynamic_(). +from(A) -> + gleam_stdlib:identity(A). + +-spec unsafe_coerce(dynamic_()) -> any(). +unsafe_coerce(A) -> + gleam_stdlib:identity(A). + +-spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. +dynamic(Value) -> + {ok, Value}. + +-spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. +bit_array(Data) -> + gleam_stdlib:decode_bit_array(Data). + +-spec bit_string(dynamic_()) -> {ok, bitstring()} | + {error, list(decode_error())}. +bit_string(Data) -> + bit_array(Data). + +-spec put_expected(decode_error(), binary()) -> decode_error(). +put_expected(Error, Expected) -> + erlang:setelement(2, Error, Expected). + +-spec classify(dynamic_()) -> binary(). +classify(Data) -> + gleam_stdlib:classify_dynamic(Data). + +-spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. +int(Data) -> + gleam_stdlib:decode_int(Data). + +-spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. +float(Data) -> + gleam_stdlib:decode_float(Data). + +-spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. +bool(Data) -> + gleam_stdlib:decode_bool(Data). + +-spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | + {error, list(decode_error())}. +shallow_list(Value) -> + gleam_stdlib:decode_list(Value). + +-spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, + gleam@option:option(DGM)} | + {error, list(decode_error())}). +optional(Decode) -> + fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. + +-spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | + {error, list(decode_error())}. +at_least_decode_tuple_error(Size, Data) -> + S = case Size of + 1 -> + <<""/utf8>>; + + _ -> + <<"s"/utf8>> + end, + Error = begin + _pipe = [<<"Tuple of at least "/utf8>>, + gleam@int:to_string(Size), + <<" element"/utf8>>, + S], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + _pipe@2 = gleam@string_builder:to_string(_pipe@1), + {decode_error, _pipe@2, classify(Data), []} + end, + {error, [Error]}. + +-spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, + DKT} | + {error, list(decode_error())}). +any(Decoders) -> + fun(Data) -> case Decoders of + [] -> + {error, + [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; + + [Decoder | Decoders@1] -> + case Decoder(Data) of + {ok, Decoded} -> + {ok, Decoded}; + + {error, _} -> + (any(Decoders@1))(Data) + end + end end. + +-spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). +all_errors(Result) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + Errors + end. + +-spec decode1( + fun((DKX) -> DKY), + fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). +decode1(Constructor, T1) -> + fun(Value) -> case T1(Value) of + {ok, A} -> + {ok, Constructor(A)}; + + A@1 -> + {error, all_errors(A@1)} + end end. + +-spec push_path(decode_error(), any()) -> decode_error(). +push_path(Error, Name) -> + Name@1 = from(Name), + Decoder = any( + [fun string/1, + fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] + ), + Name@3 = case Decoder(Name@1) of + {ok, Name@2} -> + Name@2; + + {error, _} -> + _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1) + end, + erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). + +-spec result( + fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | + {error, list(decode_error())}). +result(Decode_ok, Decode_error) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_result(Value), + fun(Inner_result) -> case Inner_result of + {ok, Raw} -> + gleam@result:'try'( + begin + _pipe = Decode_ok(Raw), + map_errors( + _pipe, + fun(_capture) -> + push_path(_capture, <<"ok"/utf8>>) + end + ) + end, + fun(Value@1) -> {ok, {ok, Value@1}} end + ); + + {error, Raw@1} -> + gleam@result:'try'( + begin + _pipe@1 = Decode_error(Raw@1), + map_errors( + _pipe@1, + fun(_capture@1) -> + push_path(_capture@1, <<"error"/utf8>>) + end + ) + end, + fun(Value@2) -> {ok, {error, Value@2}} end + ) + end end + ) + end. + +-spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, + list(DGH)} | + {error, list(decode_error())}). +list(Decoder_type) -> + fun(Dynamic) -> + gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, + _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end + ) end) + end. + +-spec map_errors( + {ok, DEV} | {error, list(decode_error())}, + fun((decode_error()) -> decode_error()) +) -> {ok, DEV} | {error, list(decode_error())}. +map_errors(Result, F) -> + gleam@result:map_error( + Result, + fun(_capture) -> gleam@list:map(_capture, F) end + ). + +-spec decode_string(dynamic_()) -> {ok, binary()} | + {error, list(decode_error())}. +decode_string(Data) -> + _pipe = bit_array(Data), + _pipe@1 = map_errors( + _pipe, + fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end + ), + gleam@result:'try'( + _pipe@1, + fun(Raw) -> case gleam@bit_array:to_string(Raw) of + {ok, String} -> + {ok, String}; + + {error, nil} -> + {error, + [{decode_error, + <<"String"/utf8>>, + <<"BitArray"/utf8>>, + []}]} + end end + ). + +-spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. +string(Data) -> + decode_string(Data). + +-spec field( + any(), + fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). +field(Name, Inner_type) -> + fun(Value) -> + Missing_field_error = {decode_error, + <<"field"/utf8>>, + <<"nothing"/utf8>>, + []}, + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> _pipe = Maybe_inner, + _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), + _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), + map_errors( + _pipe@2, + fun(_capture) -> push_path(_capture, Name) end + ) end + ) + end. + +-spec optional_field( + any(), + fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | + {error, list(decode_error())}). +optional_field(Name, Inner_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> case Maybe_inner of + none -> + {ok, none}; + + {some, Dynamic_inner} -> + _pipe = Dynamic_inner, + _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, Name) end + ) + end end + ) + end. + +-spec element( + integer(), + fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). +element(Index, Inner_type) -> + fun(Data) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple(Data), + fun(Tuple) -> + Size = gleam_stdlib:size_of_tuple(Tuple), + gleam@result:'try'(case Index >= 0 of + true -> + case Index < Size of + true -> + gleam_stdlib:tuple_get(Tuple, Index); + + false -> + at_least_decode_tuple_error(Index + 1, Data) + end; + + false -> + case gleam@int:absolute_value(Index) =< Size of + true -> + gleam_stdlib:tuple_get(Tuple, Size + Index); + + false -> + at_least_decode_tuple_error( + gleam@int:absolute_value(Index), + Data + ) + end + end, fun(Data@1) -> _pipe = Inner_type(Data@1), + map_errors( + _pipe, + fun(_capture) -> push_path(_capture, Index) end + ) end) + end + ) + end. + +-spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). +tuple_errors(Result, Name) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + gleam@list:map( + Errors, + fun(_capture) -> push_path(_capture, Name) end + ) + end. + +-spec tuple2( + fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). +tuple2(Decode1, Decode2) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple2(Value), + fun(_use0) -> + {A, B} = _use0, + case {Decode1(A), Decode2(B)} of + {{ok, A@1}, {ok, B@1}} -> + {ok, {A@1, B@1}}; + + {A@2, B@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + {error, _pipe@1} + end + end + ) + end. + +-spec tuple3( + fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). +tuple3(Decode1, Decode2, Decode3) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple3(Value), + fun(_use0) -> + {A, B, C} = _use0, + case {Decode1(A), Decode2(B), Decode3(C)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> + {ok, {A@1, B@1, C@1}}; + + {A@2, B@2, C@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + {error, _pipe@2} + end + end + ) + end. + +-spec tuple4( + fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | + {error, list(decode_error())}). +tuple4(Decode1, Decode2, Decode3, Decode4) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple4(Value), + fun(_use0) -> + {A, B, C, D} = _use0, + case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> + {ok, {A@1, B@1, C@1, D@1}}; + + {A@2, B@2, C@2, D@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + {error, _pipe@3} + end + end + ) + end. + +-spec tuple5( + fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | + {error, list(decode_error())}). +tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple5(Value), + fun(_use0) -> + {A, B, C, D, E} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1}}; + + {A@2, B@2, C@2, D@2, E@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + {error, _pipe@4} + end + end + ) + end. + +-spec tuple6( + fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | + {error, list(decode_error())}). +tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple6(Value), + fun(_use0) -> + {A, B, C, D, E, F} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E), + Decode6(F)} of + {{ok, A@1}, + {ok, B@1}, + {ok, C@1}, + {ok, D@1}, + {ok, E@1}, + {ok, F@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; + + {A@2, B@2, C@2, D@2, E@2, F@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + _pipe@5 = gleam@list:append( + _pipe@4, + tuple_errors(F@2, <<"5"/utf8>>) + ), + {error, _pipe@5} + end + end + ) + end. + +-spec dict( + fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | + {error, list(decode_error())}). +dict(Key_type, Value_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_map(Value), + fun(Map) -> + gleam@result:'try'( + begin + _pipe = Map, + _pipe@1 = gleam@dict:to_list(_pipe), + gleam@list:try_map( + _pipe@1, + fun(Pair) -> + {K, V} = Pair, + gleam@result:'try'( + begin + _pipe@2 = Key_type(K), + map_errors( + _pipe@2, + fun(_capture) -> + push_path( + _capture, + <<"keys"/utf8>> + ) + end + ) + end, + fun(K@1) -> + gleam@result:'try'( + begin + _pipe@3 = Value_type(V), + map_errors( + _pipe@3, + fun(_capture@1) -> + push_path( + _capture@1, + <<"values"/utf8>> + ) + end + ) + end, + fun(V@1) -> {ok, {K@1, V@1}} end + ) + end + ) + end + ) + end, + fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end + ) + end + ) + end. + +-spec map( + fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | + {error, list(decode_error())}). +map(Key_type, Value_type) -> + dict(Key_type, Value_type). + +-spec decode2( + fun((DLB, DLC) -> DLD), + fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). +decode2(Constructor, T1, T2) -> + fun(Value) -> case {T1(Value), T2(Value)} of + {{ok, A}, {ok, B}} -> + {ok, Constructor(A, B)}; + + {A@1, B@1} -> + {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} + end end. + +-spec decode3( + fun((DLH, DLI, DLJ) -> DLK), + fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). +decode3(Constructor, T1, T2, T3) -> + fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of + {{ok, A}, {ok, B}, {ok, C}} -> + {ok, Constructor(A, B, C)}; + + {A@1, B@1, C@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), all_errors(B@1), all_errors(C@1)] + )} + end end. + +-spec decode4( + fun((DLP, DLQ, DLR, DLS) -> DLT), + fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). +decode4(Constructor, T1, T2, T3, T4) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> + {ok, Constructor(A, B, C, D)}; + + {A@1, B@1, C@1, D@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1)] + )} + end end. + +-spec decode5( + fun((DLZ, DMA, DMB, DMC, DMD) -> DME), + fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). +decode5(Constructor, T1, T2, T3, T4, T5) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> + {ok, Constructor(A, B, C, D, E)}; + + {A@1, B@1, C@1, D@1, E@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1)] + )} + end end. + +-spec decode6( + fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), + fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). +decode6(Constructor, T1, T2, T3, T4, T5, T6) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> + {ok, Constructor(A, B, C, D, E, F)}; + + {A@1, B@1, C@1, D@1, E@1, F@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1)] + )} + end end. + +-spec decode7( + fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), + fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). +decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> + {ok, Constructor(A, B, C, D, E, F, G)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1)] + )} + end end. + +-spec decode8( + fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), + fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). +decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}} -> + {ok, Constructor(A, B, C, D, E, F, G, H)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1)] + )} + end end. + +-spec decode9( + fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), + fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). +decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> + fun(X) -> + case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}, + {ok, I}} -> + {ok, Constructor(A, B, C, D, E, F, G, H, I)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1), + all_errors(I@1)] + )} + end + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl new file mode 100644 index 00000000000..33b3d4a3e3f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl @@ -0,0 +1,181 @@ +-module(gleam@float). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). + +-spec parse(binary()) -> {ok, float()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_float(String). + +-spec to_string(float()) -> binary(). +to_string(X) -> + gleam_stdlib:float_to_string(X). + +-spec compare(float(), float()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(float(), float()) -> float(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(float(), float()) -> float(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(float(), float(), float()) -> float(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec ceiling(float()) -> float(). +ceiling(X) -> + math:ceil(X). + +-spec floor(float()) -> float(). +floor(X) -> + math:floor(X). + +-spec round(float()) -> integer(). +round(X) -> + erlang:round(X). + +-spec truncate(float()) -> integer(). +truncate(X) -> + erlang:trunc(X). + +-spec absolute_value(float()) -> float(). +absolute_value(X) -> + case X >= +0.0 of + true -> + X; + + _ -> + +0.0 - X + end. + +-spec loosely_compare(float(), float(), float()) -> gleam@order:order(). +loosely_compare(A, B, Tolerance) -> + Difference = absolute_value(A - B), + case Difference =< Tolerance of + true -> + eq; + + false -> + compare(A, B) + end. + +-spec loosely_equals(float(), float(), float()) -> boolean(). +loosely_equals(A, B, Tolerance) -> + Difference = absolute_value(A - B), + Difference =< Tolerance. + +-spec power(float(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + Fractional = (ceiling(Exponent) - Exponent) > +0.0, + case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent + < +0.0)) of + true -> + {error, nil}; + + false -> + {ok, math:pow(Base, Exponent)} + end. + +-spec square_root(float()) -> {ok, float()} | {error, nil}. +square_root(X) -> + power(X, 0.5). + +-spec negate(float()) -> float(). +negate(X) -> + -1.0 * X. + +-spec do_sum(list(float()), float()) -> float(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(float())) -> float(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, +0.0). + +-spec do_product(list(float()), float()) -> float(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(float())) -> float(). +product(Numbers) -> + case Numbers of + [] -> + 1.0; + + _ -> + do_product(Numbers, 1.0) + end. + +-spec random(float(), float()) -> float(). +random(Min, Max) -> + (rand:uniform() * (Max - Min)) + Min. + +-spec divide(float(), float()) -> {ok, float()} | {error, nil}. +divide(A, B) -> + case B of + +0.0 -> + {error, nil}; + + B@1 -> + {ok, case B@1 of + +0.0 -> +0.0; + -0.0 -> -0.0; + Gleam@denominator -> A / Gleam@denominator + end} + end. + +-spec add(float(), float()) -> float(). +add(A, B) -> + A + B. + +-spec multiply(float(), float()) -> float(). +multiply(A, B) -> + A * B. + +-spec subtract(float(), float()) -> float(). +subtract(A, B) -> + A - B. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl new file mode 100644 index 00000000000..c58c0fe151b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl @@ -0,0 +1,67 @@ +-module(gleam@function). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). + +-spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). +compose(Fun1, Fun2) -> + fun(A) -> Fun2(Fun1(A)) end. + +-spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). +curry2(Fun) -> + fun(A) -> fun(B) -> Fun(A, B) end end. + +-spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). +curry3(Fun) -> + fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. + +-spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). +curry4(Fun) -> + fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. + +-spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). +curry5(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end + end + end. + +-spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). +curry6(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> + fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end + end + end + end. + +-spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). +flip(Fun) -> + fun(B, A) -> Fun(A, B) end. + +-spec identity(AS) -> AS. +identity(X) -> + X. + +-spec constant(AT) -> fun((any()) -> AT). +constant(Value) -> + fun(_) -> Value end. + +-spec tap(AV, fun((AV) -> any())) -> AV. +tap(Arg, Effect) -> + Effect(Arg), + Arg. + +-spec apply1(fun((AX) -> AY), AX) -> AY. +apply1(Fun, Arg1) -> + Fun(Arg1). + +-spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. +apply2(Fun, Arg1, Arg2) -> + Fun(Arg1, Arg2). + +-spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. +apply3(Fun, Arg1, Arg2, Arg3) -> + Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl new file mode 100644 index 00000000000..2a5dd2c8a1d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl @@ -0,0 +1,332 @@ +-module(gleam@int). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). +-export_type([invalid_base/0]). + +-type invalid_base() :: invalid_base. + +-spec absolute_value(integer()) -> integer(). +absolute_value(X) -> + case X >= 0 of + true -> + X; + + false -> + X * -1 + end. + +-spec parse(binary()) -> {ok, integer()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_int(String). + +-spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. +base_parse(String, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + gleam_stdlib:int_from_base_string(String, Base); + + false -> + {error, nil} + end. + +-spec to_string(integer()) -> binary(). +to_string(X) -> + erlang:integer_to_binary(X). + +-spec to_base_string(integer(), integer()) -> {ok, binary()} | + {error, invalid_base()}. +to_base_string(X, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + {ok, erlang:integer_to_binary(X, Base)}; + + false -> + {error, invalid_base} + end. + +-spec to_base2(integer()) -> binary(). +to_base2(X) -> + erlang:integer_to_binary(X, 2). + +-spec to_base8(integer()) -> binary(). +to_base8(X) -> + erlang:integer_to_binary(X, 8). + +-spec to_base16(integer()) -> binary(). +to_base16(X) -> + erlang:integer_to_binary(X, 16). + +-spec to_base36(integer()) -> binary(). +to_base36(X) -> + erlang:integer_to_binary(X, 36). + +-spec to_float(integer()) -> float(). +to_float(X) -> + erlang:float(X). + +-spec power(integer(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + _pipe = Base, + _pipe@1 = to_float(_pipe), + gleam@float:power(_pipe@1, Exponent). + +-spec square_root(integer()) -> {ok, float()} | {error, nil}. +square_root(X) -> + _pipe = X, + _pipe@1 = to_float(_pipe), + gleam@float:square_root(_pipe@1). + +-spec compare(integer(), integer()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(integer(), integer()) -> integer(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(integer(), integer()) -> integer(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(integer(), integer(), integer()) -> integer(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec is_even(integer()) -> boolean(). +is_even(X) -> + (X rem 2) =:= 0. + +-spec is_odd(integer()) -> boolean(). +is_odd(X) -> + (X rem 2) /= 0. + +-spec negate(integer()) -> integer(). +negate(X) -> + -1 * X. + +-spec do_sum(list(integer()), integer()) -> integer(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(integer())) -> integer(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, 0). + +-spec do_product(list(integer()), integer()) -> integer(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(integer())) -> integer(). +product(Numbers) -> + case Numbers of + [] -> + 1; + + _ -> + do_product(Numbers, 1) + end. + +-spec do_digits(integer(), integer(), list(integer())) -> list(integer()). +do_digits(X, Base, Acc) -> + case absolute_value(X) < Base of + true -> + [X | Acc]; + + false -> + do_digits(case Base of + 0 -> 0; + Gleam@denominator -> X div Gleam@denominator + end, Base, [case Base of + 0 -> 0; + Gleam@denominator@1 -> X rem Gleam@denominator@1 + end | Acc]) + end. + +-spec digits(integer(), integer()) -> {ok, list(integer())} | + {error, invalid_base()}. +digits(X, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + {ok, do_digits(X, Base, [])} + end. + +-spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | + {error, invalid_base()}. +do_undigits(Numbers, Base, Acc) -> + case Numbers of + [] -> + {ok, Acc}; + + [Digit | _] when Digit >= Base -> + {error, invalid_base}; + + [Digit@1 | Rest] -> + do_undigits(Rest, Base, (Acc * Base) + Digit@1) + end. + +-spec undigits(list(integer()), integer()) -> {ok, integer()} | + {error, invalid_base()}. +undigits(Numbers, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + do_undigits(Numbers, Base, 0) + end. + +-spec random(integer(), integer()) -> integer(). +random(Min, Max) -> + _pipe = gleam@float:random(to_float(Min), to_float(Max)), + _pipe@1 = gleam@float:floor(_pipe), + gleam@float:round(_pipe@1). + +-spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend div Gleam@denominator + end} + end. + +-spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. +remainder(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end} + end. + +-spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. +modulo(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + _ -> + Remainder = case Divisor of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end, + case (Remainder * Divisor) < 0 of + true -> + {ok, Remainder + Divisor}; + + false -> + {ok, Remainder} + end + end. + +-spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +floor_divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end) /= 0) of + true -> + {ok, (case Divisor@1 of + 0 -> 0; + Gleam@denominator@1 -> Dividend div Gleam@denominator@1 + end) - 1}; + + false -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator@2 -> Dividend div Gleam@denominator@2 + end} + end + end. + +-spec add(integer(), integer()) -> integer(). +add(A, B) -> + A + B. + +-spec multiply(integer(), integer()) -> integer(). +multiply(A, B) -> + A * B. + +-spec subtract(integer(), integer()) -> integer(). +subtract(A, B) -> + A - B. + +-spec bitwise_and(integer(), integer()) -> integer(). +bitwise_and(X, Y) -> + erlang:'band'(X, Y). + +-spec bitwise_not(integer()) -> integer(). +bitwise_not(X) -> + erlang:'bnot'(X). + +-spec bitwise_or(integer(), integer()) -> integer(). +bitwise_or(X, Y) -> + erlang:'bor'(X, Y). + +-spec bitwise_exclusive_or(integer(), integer()) -> integer(). +bitwise_exclusive_or(X, Y) -> + erlang:'bxor'(X, Y). + +-spec bitwise_shift_left(integer(), integer()) -> integer(). +bitwise_shift_left(X, Y) -> + erlang:'bsl'(X, Y). + +-spec bitwise_shift_right(integer(), integer()) -> integer(). +bitwise_shift_right(X, Y) -> + erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl new file mode 100644 index 00000000000..82865bbafa6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl @@ -0,0 +1,27 @@ +-module(gleam@io). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([print/1, print_error/1, println/1, println_error/1, debug/1]). + +-spec print(binary()) -> nil. +print(String) -> + gleam_stdlib:print(String). + +-spec print_error(binary()) -> nil. +print_error(String) -> + gleam_stdlib:print_error(String). + +-spec println(binary()) -> nil. +println(String) -> + gleam_stdlib:println(String). + +-spec println_error(binary()) -> nil. +println_error(String) -> + gleam_stdlib:println_error(String). + +-spec debug(ENH) -> ENH. +debug(Term) -> + _pipe = Term, + _pipe@1 = gleam@string:inspect(_pipe), + gleam_stdlib:println_error(_pipe@1), + Term. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl new file mode 100644 index 00000000000..a667ae1ac4b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl @@ -0,0 +1,744 @@ +-module(gleam@iterator). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). +-export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). + +-type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. + +-opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. + +-type step(BSE, BSF) :: {next, BSE, BSF} | done. + +-type chunk(BSG, BSH) :: {another_by, + list(BSG), + BSH, + BSG, + fun(() -> action(BSG))} | + {last_by, list(BSG)}. + +-type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | + {last, list(BSI)} | + no_more. + +-spec stop() -> action(any()). +stop() -> + stop. + +-spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). +do_unfold(Initial, F) -> + fun() -> case F(Initial) of + {next, X, Acc} -> + {continue, X, do_unfold(Acc, F)}; + + done -> + stop + end end. + +-spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). +unfold(Initial, F) -> + _pipe = Initial, + _pipe@1 = do_unfold(_pipe, F), + {iterator, _pipe@1}. + +-spec repeatedly(fun(() -> BSV)) -> iterator(BSV). +repeatedly(F) -> + unfold(nil, fun(_) -> {next, F(), nil} end). + +-spec repeat(BSX) -> iterator(BSX). +repeat(X) -> + repeatedly(fun() -> X end). + +-spec from_list(list(BSZ)) -> iterator(BSZ). +from_list(List) -> + Yield = fun(Acc) -> case Acc of + [] -> + done; + + [Head | Tail] -> + {next, Head, Tail} + end end, + unfold(List, Yield). + +-spec do_transform( + fun(() -> action(BTC)), + BTE, + fun((BTE, BTC) -> step(BTF, BTE)) +) -> fun(() -> action(BTF)). +do_transform(Continuation, State, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + case F(State, El) of + done -> + stop; + + {next, Yield, Next_state} -> + {continue, Yield, do_transform(Next, Next_state, F)} + end + end end. + +-spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). +transform(Iterator, Initial, F) -> + _pipe = do_transform(erlang:element(2, Iterator), Initial, F), + {iterator, _pipe}. + +-spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. +do_fold(Continuation, F, Accumulator) -> + case Continuation() of + {continue, Elem, Next} -> + do_fold(Next, F, F(Accumulator, Elem)); + + stop -> + Accumulator + end. + +-spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. +fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold(_pipe, F, Initial). + +-spec run(iterator(any())) -> nil. +run(Iterator) -> + fold(Iterator, nil, fun(_, _) -> nil end). + +-spec to_list(iterator(BTY)) -> list(BTY). +to_list(Iterator) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), + gleam@list:reverse(_pipe@1). + +-spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). +step(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + done; + + {continue, E, A} -> + {next, E, {iterator, A}} + end. + +-spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). +do_take(Continuation, Desired) -> + fun() -> case Desired > 0 of + false -> + stop; + + true -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, do_take(Next, Desired - 1)} + end + end end. + +-spec take(iterator(BUJ), integer()) -> iterator(BUJ). +take(Iterator, Desired) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take(_pipe, Desired), + {iterator, _pipe@1}. + +-spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). +do_drop(Continuation, Desired) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Desired > 0 of + true -> + do_drop(Next, Desired - 1); + + false -> + {continue, E, Next} + end + end. + +-spec drop(iterator(BUP), integer()) -> iterator(BUP). +drop(Iterator, Desired) -> + _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, + {iterator, _pipe}. + +-spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). +do_map(Continuation, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, F(E), do_map(Continuation@1, F)} + end end. + +-spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). +map(Iterator, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_map(_pipe, F), + {iterator, _pipe@1}. + +-spec do_map2( + fun(() -> action(BVA)), + fun(() -> action(BVC)), + fun((BVA, BVC) -> BVE) +) -> fun(() -> action(BVE)). +do_map2(Continuation1, Continuation2, Fun) -> + fun() -> case Continuation1() of + stop -> + stop; + + {continue, A, Next_a} -> + case Continuation2() of + stop -> + stop; + + {continue, B, Next_b} -> + {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} + end + end end. + +-spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). +map2(Iterator1, Iterator2, Fun) -> + _pipe = do_map2( + erlang:element(2, Iterator1), + erlang:element(2, Iterator2), + Fun + ), + {iterator, _pipe}. + +-spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). +do_append(First, Second) -> + case First() of + {continue, E, First@1} -> + {continue, E, fun() -> do_append(First@1, Second) end}; + + stop -> + Second() + end. + +-spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). +append(First, Second) -> + _pipe = fun() -> + do_append(erlang:element(2, First), erlang:element(2, Second)) + end, + {iterator, _pipe}. + +-spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). +do_flatten(Flattened) -> + case Flattened() of + stop -> + stop; + + {continue, It, Next_iterator} -> + do_append( + erlang:element(2, It), + fun() -> do_flatten(Next_iterator) end + ) + end. + +-spec flatten(iterator(iterator(BVY))) -> iterator(BVY). +flatten(Iterator) -> + _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, + {iterator, _pipe}. + +-spec concat(list(iterator(BWC))) -> iterator(BWC). +concat(Iterators) -> + flatten(from_list(Iterators)). + +-spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). +flat_map(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + flatten(_pipe@1). + +-spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). +do_filter(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Iterator} -> + case Predicate(E) of + true -> + {continue, E, fun() -> do_filter(Iterator, Predicate) end}; + + false -> + do_filter(Iterator, Predicate) + end + end. + +-spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). +filter(Iterator, Predicate) -> + _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec cycle(iterator(BWR)) -> iterator(BWR). +cycle(Iterator) -> + _pipe = repeat(Iterator), + flatten(_pipe). + +-spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | + {error, nil}. +do_find(Continuation, F) -> + case Continuation() of + stop -> + {error, nil}; + + {continue, E, Next} -> + case F(E) of + true -> + {ok, E}; + + false -> + do_find(Next, F) + end + end. + +-spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. +find(Haystack, Is_desired) -> + _pipe = erlang:element(2, Haystack), + do_find(_pipe, Is_desired). + +-spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), + BXD})). +do_index(Continuation, Next) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, {Next, E}, do_index(Continuation@1, Next + 1)} + end end. + +-spec index(iterator(BXG)) -> iterator({integer(), BXG}). +index(Iterator) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_index(_pipe, 0), + {iterator, _pipe@1}. + +-spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). +iterate(Initial, F) -> + unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). + +-spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). +do_take_while(Continuation, Predicate) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + stop; + + true -> + {continue, E, do_take_while(Next, Predicate)} + end + end end. + +-spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). +take_while(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take_while(_pipe, Predicate), + {iterator, _pipe@1}. + +-spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). +do_drop_while(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + {continue, E, Next}; + + true -> + do_drop_while(Next, Predicate) + end + end. + +-spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). +drop_while(Iterator, Predicate) -> + _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). +do_scan(Continuation, F, Accumulator) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + Accumulated = F(Accumulator, El), + {continue, Accumulated, do_scan(Next, F, Accumulated)} + end end. + +-spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). +scan(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_scan(_pipe, F, Initial), + {iterator, _pipe@1}. + +-spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, + BYH})). +do_zip(Left, Right) -> + fun() -> case Left() of + stop -> + stop; + + {continue, El_left, Next_left} -> + case Right() of + stop -> + stop; + + {continue, El_right, Next_right} -> + {continue, + {El_left, El_right}, + do_zip(Next_left, Next_right)} + end + end end. + +-spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). +zip(Left, Right) -> + _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), + {iterator, _pipe}. + +-spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). +next_chunk(Continuation, F, Previous_key, Current_chunk) -> + case Continuation() of + stop -> + {last_by, gleam@list:reverse(Current_chunk)}; + + {continue, E, Next} -> + Key = F(E), + case Key =:= Previous_key of + true -> + next_chunk(Next, F, Key, [E | Current_chunk]); + + false -> + {another_by, + gleam@list:reverse(Current_chunk), + Key, + E, + Next} + end + end. + +-spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). +do_chunk(Continuation, F, Previous_key, Previous_element) -> + case next_chunk(Continuation, F, Previous_key, [Previous_element]) of + {last_by, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another_by, Chunk@1, Key, El, Next} -> + {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} + end. + +-spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). +chunk(Iterator, F) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + do_chunk(Next, F, F(E), E) + end end, + {iterator, _pipe}. + +-spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). +next_sized_chunk(Continuation, Left, Current_chunk) -> + case Continuation() of + stop -> + case Current_chunk of + [] -> + no_more; + + Remaining -> + {last, gleam@list:reverse(Remaining)} + end; + + {continue, E, Next} -> + Chunk = [E | Current_chunk], + case Left > 1 of + false -> + {another, gleam@list:reverse(Chunk), Next}; + + true -> + next_sized_chunk(Next, Left - 1, Chunk) + end + end. + +-spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). +do_sized_chunk(Continuation, Count) -> + fun() -> case next_sized_chunk(Continuation, Count, []) of + no_more -> + stop; + + {last, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another, Chunk@1, Next_element} -> + {continue, Chunk@1, do_sized_chunk(Next_element, Count)} + end end. + +-spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). +sized_chunk(Iterator, Count) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_sized_chunk(_pipe, Count), + {iterator, _pipe@1}. + +-spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). +do_intersperse(Continuation, Separator) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + Next_interspersed = fun() -> do_intersperse(Next, Separator) end, + {continue, Separator, fun() -> {continue, E, Next_interspersed} end} + end. + +-spec intersperse(iterator(BZU), BZU) -> iterator(BZU). +intersperse(Iterator, Elem) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, fun() -> do_intersperse(Next, Elem) end} + end end, + {iterator, _pipe}. + +-spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). +do_any(Continuation, Predicate) -> + case Continuation() of + stop -> + false; + + {continue, E, Next} -> + case Predicate(E) of + true -> + true; + + false -> + do_any(Next, Predicate) + end + end. + +-spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). +any(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_any(_pipe, Predicate). + +-spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). +do_all(Continuation, Predicate) -> + case Continuation() of + stop -> + true; + + {continue, E, Next} -> + case Predicate(E) of + true -> + do_all(Next, Predicate); + + false -> + false + end + end. + +-spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). +all(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_all(_pipe, Predicate). + +-spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). +update_group_with(El) -> + fun(Maybe_group) -> case Maybe_group of + {some, Group} -> + [El | Group]; + + none -> + [El] + end end. + +-spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). +group_updater(F) -> + fun(Groups, Elem) -> _pipe = Groups, + gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. + +-spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). +group(Iterator, Key) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), + gleam@dict:map_values( + _pipe@1, + fun(_, Group) -> gleam@list:reverse(Group) end + ). + +-spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. +reduce(Iterator, F) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, Next} -> + _pipe = do_fold(Next, F, E), + {ok, _pipe} + end. + +-spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. +last(Iterator) -> + _pipe = Iterator, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec empty() -> iterator(any()). +empty() -> + {iterator, fun stop/0}. + +-spec once(fun(() -> CBH)) -> iterator(CBH). +once(F) -> + _pipe = fun() -> {continue, F(), fun stop/0} end, + {iterator, _pipe}. + +-spec range(integer(), integer()) -> iterator(integer()). +range(Start, Stop) -> + case gleam@int:compare(Start, Stop) of + eq -> + once(fun() -> Start end); + + gt -> + unfold(Start, fun(Current) -> case Current < Stop of + false -> + {next, Current, Current - 1}; + + true -> + done + end end); + + lt -> + unfold(Start, fun(Current@1) -> case Current@1 > Stop of + false -> + {next, Current@1, Current@1 + 1}; + + true -> + done + end end) + end. + +-spec single(CBJ) -> iterator(CBJ). +single(Elem) -> + once(fun() -> Elem end). + +-spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). +do_interleave(Current, Next) -> + case Current() of + stop -> + Next(); + + {continue, E, Next_other} -> + {continue, E, fun() -> do_interleave(Next, Next_other) end} + end. + +-spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). +interleave(Left, Right) -> + _pipe = fun() -> + do_interleave(erlang:element(2, Left), erlang:element(2, Right)) + end, + {iterator, _pipe}. + +-spec do_fold_until( + fun(() -> action(CBT)), + fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), + CBV +) -> CBV. +do_fold_until(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + Accumulator; + + {continue, Elem, Next} -> + case F(Accumulator, Elem) of + {continue, Accumulator@1} -> + do_fold_until(Next, F, Accumulator@1); + + {stop, Accumulator@2} -> + Accumulator@2 + end + end. + +-spec fold_until( + iterator(CBX), + CBZ, + fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) +) -> CBZ. +fold_until(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold_until(_pipe, F, Initial). + +-spec do_try_fold( + fun(() -> action(CCB)), + fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), + CCD +) -> {ok, CCD} | {error, CCE}. +do_try_fold(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + {ok, Accumulator}; + + {continue, Elem, Next} -> + gleam@result:'try'( + F(Accumulator, Elem), + fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end + ) + end. + +-spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, + CCL} | + {error, CCM}. +try_fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_try_fold(_pipe, F, Initial). + +-spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. +first(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, _} -> + {ok, E} + end. + +-spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. +at(Iterator, Index) -> + _pipe = Iterator, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1). + +-spec do_length(fun(() -> action(any())), integer()) -> integer(). +do_length(Continuation, Length) -> + case Continuation() of + stop -> + Length; + + {continue, _, Next} -> + do_length(Next, Length + 1) + end. + +-spec length(iterator(any())) -> integer(). +length(Iterator) -> + _pipe = erlang:element(2, Iterator), + do_length(_pipe, 0). + +-spec each(iterator(CDD), fun((CDD) -> any())) -> nil. +each(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + run(_pipe@1). + +-spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). +yield(Element, Next) -> + {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl new file mode 100644 index 00000000000..cb6c9e44af2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl @@ -0,0 +1,1136 @@ +-module(gleam@list). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). +-export_type([length_mismatch/0, continue_or_stop/1]). + +-type length_mismatch() :: length_mismatch. + +-type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. + +-spec length(list(any())) -> integer(). +length(List) -> + erlang:length(List). + +-spec reverse(list(XF)) -> list(XF). +reverse(Xs) -> + lists:reverse(Xs). + +-spec is_empty(list(any())) -> boolean(). +is_empty(List) -> + List =:= []. + +-spec contains(list(XN), XN) -> boolean(). +contains(List, Elem) -> + case List of + [] -> + false; + + [First | _] when First =:= Elem -> + true; + + [_ | Rest] -> + contains(Rest, Elem) + end. + +-spec first(list(XP)) -> {ok, XP} | {error, nil}. +first(List) -> + case List of + [] -> + {error, nil}; + + [X | _] -> + {ok, X} + end. + +-spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. +rest(List) -> + case List of + [] -> + {error, nil}; + + [_ | Xs] -> + {ok, Xs} + end. + +-spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). +update_group(F) -> + fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of + {ok, Existing} -> + gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); + + {error, _} -> + gleam@dict:insert(Groups, F(Elem), [Elem]) + end end. + +-spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). +do_filter(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + true -> + [X | Acc]; + + false -> + Acc + end, + do_filter(Xs, Fun, New_acc) + end. + +-spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). +filter(List, Predicate) -> + do_filter(List, Predicate, []). + +-spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). +do_filter_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + {ok, X@1} -> + [X@1 | Acc]; + + {error, _} -> + Acc + end, + do_filter_map(Xs, Fun, New_acc) + end. + +-spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). +filter_map(List, Fun) -> + do_filter_map(List, Fun, []). + +-spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). +do_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_map(Xs, Fun, [Fun(X) | Acc]) + end. + +-spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). +map(List, Fun) -> + do_map(List, Fun, []). + +-spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). +do_map2(List1, List2, Fun, Acc) -> + case {List1, List2} of + {[], _} -> + reverse(Acc); + + {_, []} -> + reverse(Acc); + + {[A | As_], [B | Bs]} -> + do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) + end. + +-spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). +map2(List1, List2, Fun) -> + do_map2(List1, List2, Fun, []). + +-spec do_index_map( + list(ABJ), + fun((integer(), ABJ) -> ABL), + integer(), + list(ABL) +) -> list(ABL). +do_index_map(List, Fun, Index, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + Acc@1 = [Fun(Index, X) | Acc], + do_index_map(Xs, Fun, Index + 1, Acc@1) + end. + +-spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). +index_map(List, Fun) -> + do_index_map(List, Fun, 0, []). + +-spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, + list(ABU)} | + {error, ABV}. +do_try_map(List, Fun, Acc) -> + case List of + [] -> + {ok, reverse(Acc)}; + + [X | Xs] -> + case Fun(X) of + {ok, Y} -> + do_try_map(Xs, Fun, [Y | Acc]); + + {error, Error} -> + {error, Error} + end + end. + +-spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, + list(ACE)} | + {error, ACF}. +try_map(List, Fun) -> + do_try_map(List, Fun, []). + +-spec drop(list(ACL), integer()) -> list(ACL). +drop(List, N) -> + case N =< 0 of + true -> + List; + + false -> + case List of + [] -> + []; + + [_ | Xs] -> + drop(Xs, N - 1) + end + end. + +-spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). +do_take(List, N, Acc) -> + case N =< 0 of + true -> + reverse(Acc); + + false -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_take(Xs, N - 1, [X | Acc]) + end + end. + +-spec take(list(ACS), integer()) -> list(ACS). +take(List, N) -> + do_take(List, N, []). + +-spec new() -> list(any()). +new() -> + []. + +-spec append(list(ACX), list(ACX)) -> list(ACX). +append(First, Second) -> + lists:append(First, Second). + +-spec prepend(list(ADF), ADF) -> list(ADF). +prepend(List, Item) -> + [Item | List]. + +-spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). +reverse_and_prepend(Prefix, Suffix) -> + case Prefix of + [] -> + Suffix; + + [First | Rest] -> + reverse_and_prepend(Rest, [First | Suffix]) + end. + +-spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). +do_concat(Lists, Acc) -> + case Lists of + [] -> + reverse(Acc); + + [List | Further_lists] -> + do_concat(Further_lists, reverse_and_prepend(List, Acc)) + end. + +-spec concat(list(list(ADR))) -> list(ADR). +concat(Lists) -> + do_concat(Lists, []). + +-spec flatten(list(list(ADV))) -> list(ADV). +flatten(Lists) -> + do_concat(Lists, []). + +-spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). +flat_map(List, Fun) -> + _pipe = map(List, Fun), + concat(_pipe). + +-spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. +fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + fold(Rest, Fun(Initial, X), Fun) + end. + +-spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). +group(List, Key) -> + fold(List, gleam@dict:new(), update_group(Key)). + +-spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, + list(ABH)}. +map_fold(List, Acc, Fun) -> + _pipe = fold( + List, + {Acc, []}, + fun(Acc@1, Item) -> + {Current_acc, Items} = Acc@1, + {Next_acc, Next_item} = Fun(Current_acc, Item), + {Next_acc, [Next_item | Items]} + end + ), + gleam@pair:map_second(_pipe, fun reverse/1). + +-spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. +fold_right(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + Fun(fold_right(Rest, Initial, Fun), X) + end. + +-spec do_index_fold( + list(AEK), + AEM, + fun((AEM, AEK, integer()) -> AEM), + integer() +) -> AEM. +do_index_fold(Over, Acc, With, Index) -> + case Over of + [] -> + Acc; + + [First | Rest] -> + do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) + end. + +-spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. +index_fold(Over, Initial, Fun) -> + do_index_fold(Over, Initial, Fun, 0). + +-spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, + AES} | + {error, AET}. +try_fold(Collection, Accumulator, Fun) -> + case Collection of + [] -> + {ok, Accumulator}; + + [First | Rest] -> + case Fun(Accumulator, First) of + {ok, Result} -> + try_fold(Rest, Result, Fun); + + {error, _} = Error -> + Error + end + end. + +-spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. +fold_until(Collection, Accumulator, Fun) -> + case Collection of + [] -> + Accumulator; + + [First | Rest] -> + case Fun(Accumulator, First) of + {continue, Next_accumulator} -> + fold_until(Rest, Next_accumulator, Fun); + + {stop, B} -> + B + end + end. + +-spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. +find(Haystack, Is_desired) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Is_desired(X) of + true -> + {ok, X}; + + _ -> + find(Rest, Is_desired) + end + end. + +-spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | + {error, nil}. +find_map(Haystack, Fun) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Fun(X) of + {ok, X@1} -> + {ok, X@1}; + + _ -> + find_map(Rest, Fun) + end + end. + +-spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). +all(List, Predicate) -> + case List of + [] -> + true; + + [First | Rest] -> + case Predicate(First) of + true -> + all(Rest, Predicate); + + false -> + false + end + end. + +-spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). +any(List, Predicate) -> + case List of + [] -> + false; + + [First | Rest] -> + case Predicate(First) of + true -> + true; + + false -> + any(Rest, Predicate) + end + end. + +-spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). +do_zip(Xs, Ys, Acc) -> + case {Xs, Ys} of + {[X | Xs@1], [Y | Ys@1]} -> + do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); + + {_, _} -> + reverse(Acc) + end. + +-spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). +zip(List, Other) -> + do_zip(List, Other, []). + +-spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | + {error, length_mismatch()}. +strict_zip(List, Other) -> + case length(List) =:= length(Other) of + true -> + {ok, zip(List, Other)}; + + false -> + {error, length_mismatch} + end. + +-spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. +do_unzip(Input, Xs, Ys) -> + case Input of + [] -> + {reverse(Xs), reverse(Ys)}; + + [{X, Y} | Rest] -> + do_unzip(Rest, [X | Xs], [Y | Ys]) + end. + +-spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. +unzip(Input) -> + do_unzip(Input, [], []). + +-spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). +do_intersperse(List, Separator, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Rest] -> + do_intersperse(Rest, Separator, [X, Separator | Acc]) + end. + +-spec intersperse(list(AGX), AGX) -> list(AGX). +intersperse(List, Elem) -> + case List of + [] -> + List; + + [_] -> + List; + + [X | Rest] -> + do_intersperse(Rest, Elem, [X]) + end. + +-spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. +at(List, Index) -> + case Index >= 0 of + true -> + _pipe = List, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1); + + false -> + {error, nil} + end. + +-spec unique(list(AHE)) -> list(AHE). +unique(List) -> + case List of + [] -> + []; + + [X | Rest] -> + [X | unique(filter(Rest, fun(Y) -> Y /= X end))] + end. + +-spec merge_up( + integer(), + integer(), + list(AHH), + list(AHH), + list(AHH), + fun((AHH, AHH) -> gleam@order:order()) +) -> list(AHH). +merge_up(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Ax@1, Bx@1) of + gt -> + merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); + + _ -> + merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) + end; + + {_, _, _, _} -> + Acc + end. + +-spec merge_down( + integer(), + integer(), + list(AHM), + list(AHM), + list(AHM), + fun((AHM, AHM) -> gleam@order:order()) +) -> list(AHM). +merge_down(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Bx@1, Ax@1) of + lt -> + merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); + + _ -> + merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) + end; + + {_, _, _, _} -> + Acc + end. + +-spec merge_sort( + list(AHR), + integer(), + fun((AHR, AHR) -> gleam@order:order()), + boolean() +) -> list(AHR). +merge_sort(L, Ln, Compare, Down) -> + N = Ln div 2, + A = L, + B = drop(L, N), + case Ln < 3 of + true -> + case Down of + true -> + merge_down(N, Ln - N, A, B, [], Compare); + + false -> + merge_up(N, Ln - N, A, B, [], Compare) + end; + + false -> + case Down of + true -> + merge_down( + N, + Ln - N, + merge_sort(A, N, Compare, false), + merge_sort(B, Ln - N, Compare, false), + [], + Compare + ); + + false -> + merge_up( + N, + Ln - N, + merge_sort(A, N, Compare, true), + merge_sort(B, Ln - N, Compare, true), + [], + Compare + ) + end + end. + +-spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). +sort(List, Compare) -> + merge_sort(List, length(List), Compare, true). + +-spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). +tail_recursive_range(Start, Stop, Acc) -> + case gleam@int:compare(Start, Stop) of + eq -> + [Stop | Acc]; + + gt -> + tail_recursive_range(Start, Stop + 1, [Stop | Acc]); + + lt -> + tail_recursive_range(Start, Stop - 1, [Stop | Acc]) + end. + +-spec range(integer(), integer()) -> list(integer()). +range(Start, Stop) -> + tail_recursive_range(Start, Stop, []). + +-spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). +do_repeat(A, Times, Acc) -> + case Times =< 0 of + true -> + Acc; + + false -> + do_repeat(A, Times - 1, [A | Acc]) + end. + +-spec repeat(AID, integer()) -> list(AID). +repeat(A, Times) -> + do_repeat(A, Times, []). + +-spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. +do_split(List, N, Taken) -> + case N =< 0 of + true -> + {reverse(Taken), List}; + + false -> + case List of + [] -> + {reverse(Taken), []}; + + [X | Xs] -> + do_split(Xs, N - 1, [X | Taken]) + end + end. + +-spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. +split(List, Index) -> + do_split(List, Index, []). + +-spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), + list(AIO)}. +do_split_while(List, F, Acc) -> + case List of + [] -> + {reverse(Acc), []}; + + [X | Xs] -> + case F(X) of + false -> + {reverse(Acc), List}; + + _ -> + do_split_while(Xs, F, [X | Acc]) + end + end. + +-spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. +split_while(List, Predicate) -> + do_split_while(List, Predicate, []). + +-spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. +key_find(Keyword_list, Desired_key) -> + find_map( + Keyword_list, + fun(Keyword) -> + {Key, Value} = Keyword, + case Key =:= Desired_key of + true -> + {ok, Value}; + + false -> + {error, nil} + end + end + ). + +-spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). +key_filter(Keyword_list, Desired_key) -> + filter_map( + Keyword_list, + fun(Keyword) -> + {Key, Value} = Keyword, + case Key =:= Desired_key of + true -> + {ok, Value}; + + false -> + {error, nil} + end + end + ). + +-spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, + {AZQ, list(AZQ)}} | + {error, nil}. +do_pop(Haystack, Predicate, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Predicate(X) of + true -> + {ok, {X, append(reverse(Checked), Rest)}}; + + false -> + do_pop(Rest, Predicate, [X | Checked]) + end + end. + +-spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | + {error, nil}. +pop(Haystack, Is_desired) -> + do_pop(Haystack, Is_desired, []). + +-spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, + {BAR, list(BAE)}} | + {error, nil}. +do_pop_map(Haystack, Mapper, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Mapper(X) of + {ok, Y} -> + {ok, {Y, append(reverse(Checked), Rest)}}; + + {error, _} -> + do_pop_map(Rest, Mapper, [X | Checked]) + end + end. + +-spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, + {AJV, list(AJT)}} | + {error, nil}. +pop_map(Haystack, Is_desired) -> + do_pop_map(Haystack, Is_desired, []). + +-spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | + {error, nil}. +key_pop(Haystack, Key) -> + pop_map( + Haystack, + fun(Entry) -> + {K, V} = Entry, + case K of + K@1 when K@1 =:= Key -> + {ok, V}; + + _ -> + {error, nil} + end + end + ). + +-spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). +key_set(List, Key, Value) -> + case List of + [] -> + [{Key, Value}]; + + [{K, _} | Rest] when K =:= Key -> + [{Key, Value} | Rest]; + + [First | Rest@1] -> + [First | key_set(Rest@1, Key, Value)] + end. + +-spec each(list(AKM), fun((AKM) -> any())) -> nil. +each(List, F) -> + case List of + [] -> + nil; + + [X | Xs] -> + F(X), + each(Xs, F) + end. + +-spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | + {error, AKS}. +try_each(List, Fun) -> + case List of + [] -> + {ok, nil}; + + [X | Xs] -> + case Fun(X) of + {ok, _} -> + try_each(Xs, Fun); + + {error, E} -> + {error, E} + end + end. + +-spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), + list(BBY)}. +do_partition(List, Categorise, Trues, Falses) -> + case List of + [] -> + {reverse(Trues), reverse(Falses)}; + + [X | Xs] -> + case Categorise(X) of + true -> + do_partition(Xs, Categorise, [X | Trues], Falses); + + false -> + do_partition(Xs, Categorise, Trues, [X | Falses]) + end + end. + +-spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. +partition(List, Categorise) -> + do_partition(List, Categorise, [], []). + +-spec permutations(list(ALG)) -> list(list(ALG)). +permutations(L) -> + case L of + [] -> + [[]]; + + _ -> + _pipe = L, + _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, + _pipe@2 = index_fold( + _pipe@1, + [], + fun(Acc, J, J_idx) -> case I_idx =:= J_idx of + true -> + Acc; + + false -> + [J | Acc] + end end + ), + _pipe@3 = reverse(_pipe@2), + _pipe@4 = permutations(_pipe@3), + map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), + concat(_pipe@5) + end. + +-spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). +do_window(Acc, L, N) -> + Window = take(L, N), + case length(Window) =:= N of + true -> + do_window([Window | Acc], drop(L, 1), N); + + false -> + Acc + end. + +-spec window(list(ALQ), integer()) -> list(list(ALQ)). +window(L, N) -> + _pipe = do_window([], L, N), + reverse(_pipe). + +-spec window_by_2(list(ALU)) -> list({ALU, ALU}). +window_by_2(L) -> + zip(L, drop(L, 1)). + +-spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). +drop_while(List, Predicate) -> + case List of + [] -> + []; + + [X | Xs] -> + case Predicate(X) of + true -> + drop_while(Xs, Predicate); + + false -> + [X | Xs] + end + end. + +-spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). +do_take_while(List, Predicate, Acc) -> + case List of + [] -> + reverse(Acc); + + [First | Rest] -> + case Predicate(First) of + true -> + do_take_while(Rest, Predicate, [First | Acc]); + + false -> + reverse(Acc) + end + end. + +-spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). +take_while(List, Predicate) -> + do_take_while(List, Predicate, []). + +-spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). +do_chunk(List, F, Previous_key, Current_chunk, Acc) -> + case List of + [First | Rest] -> + Key = F(First), + case Key =:= Previous_key of + false -> + New_acc = [reverse(Current_chunk) | Acc], + do_chunk(Rest, F, Key, [First], New_acc); + + _ -> + do_chunk(Rest, F, Key, [First | Current_chunk], Acc) + end; + + _ -> + reverse([reverse(Current_chunk) | Acc]) + end. + +-spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). +chunk(List, F) -> + case List of + [] -> + []; + + [First | Rest] -> + do_chunk(Rest, F, F(First), [First], []) + end. + +-spec do_sized_chunk( + list(AMU), + integer(), + integer(), + list(AMU), + list(list(AMU)) +) -> list(list(AMU)). +do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> + case List of + [] -> + case Current_chunk of + [] -> + reverse(Acc); + + Remaining -> + reverse([reverse(Remaining) | Acc]) + end; + + [First | Rest] -> + Chunk = [First | Current_chunk], + case Left > 1 of + false -> + do_sized_chunk( + Rest, + Count, + Count, + [], + [reverse(Chunk) | Acc] + ); + + true -> + do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) + end + end. + +-spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). +sized_chunk(List, Count) -> + do_sized_chunk(List, Count, Count, [], []). + +-spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. +reduce(List, Fun) -> + case List of + [] -> + {error, nil}; + + [First | Rest] -> + {ok, fold(Rest, First, Fun)} + end. + +-spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). +do_scan(List, Accumulator, Accumulated, Fun) -> + case List of + [] -> + reverse(Accumulated); + + [X | Xs] -> + Next = Fun(Accumulator, X), + do_scan(Xs, Next, [Next | Accumulated], Fun) + end. + +-spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). +scan(List, Initial, Fun) -> + do_scan(List, Initial, [], Fun). + +-spec last(list(ANS)) -> {ok, ANS} | {error, nil}. +last(List) -> + _pipe = List, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec combinations(list(ANW), integer()) -> list(list(ANW)). +combinations(Items, N) -> + case N of + 0 -> + [[]]; + + _ -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = begin + _pipe = map( + combinations(Xs, N - 1), + fun(Com) -> [X | Com] end + ), + reverse(_pipe) + end, + fold( + First_combinations, + combinations(Xs, N), + fun(Acc, C) -> [C | Acc] end + ) + end + end. + +-spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). +do_combination_pairs(Items) -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = map(Xs, fun(Other) -> {X, Other} end), + [First_combinations | do_combination_pairs(Xs)] + end. + +-spec combination_pairs(list(AOE)) -> list({AOE, AOE}). +combination_pairs(Items) -> + _pipe = do_combination_pairs(Items), + concat(_pipe). + +-spec transpose(list(list(AOL))) -> list(list(AOL)). +transpose(List_of_list) -> + Take_first = fun(List) -> case List of + [] -> + []; + + [F] -> + [F]; + + [F@1 | _] -> + [F@1] + end end, + case List_of_list of + [] -> + []; + + [[] | Xss] -> + transpose(Xss); + + Rows -> + Firsts = begin + _pipe = Rows, + _pipe@1 = map(_pipe, Take_first), + concat(_pipe@1) + end, + Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), + [Firsts | Rest] + end. + +-spec interleave(list(list(AOH))) -> list(AOH). +interleave(List) -> + _pipe = transpose(List), + concat(_pipe). + +-spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). +do_shuffle_pair_unwrap(List, Acc) -> + case List of + [] -> + Acc; + + [Elem_pair | Enumerable] -> + do_shuffle_pair_unwrap( + Enumerable, + [erlang:element(2, Elem_pair) | Acc] + ) + end. + +-spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). +do_shuffle_by_pair_indexes(List_of_pairs) -> + sort( + List_of_pairs, + fun(A_pair, B_pair) -> + gleam@float:compare( + erlang:element(1, A_pair), + erlang:element(1, B_pair) + ) + end + ). + +-spec shuffle(list(AOX)) -> list(AOX). +shuffle(List) -> + _pipe = List, + _pipe@1 = fold( + _pipe, + [], + fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end + ), + _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), + do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl new file mode 100644 index 00000000000..9f45b107384 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl @@ -0,0 +1,76 @@ +-module(gleam@map). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). + +-spec size(gleam@dict:dict(any(), any())) -> integer(). +size(Map) -> + gleam@dict:size(Map). + +-spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). +to_list(Map) -> + gleam@dict:to_list(Map). + +-spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). +from_list(List) -> + gleam@dict:from_list(List). + +-spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). +has_key(Map, Key) -> + gleam@dict:has_key(Map, Key). + +-spec new() -> gleam@dict:dict(any(), any()). +new() -> + gleam@dict:new(). + +-spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. +get(From, Get) -> + gleam@dict:get(From, Get). + +-spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). +insert(Map, Key, Value) -> + gleam@dict:insert(Map, Key, Value). + +-spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). +map_values(Map, Fun) -> + gleam@dict:map_values(Map, Fun). + +-spec keys(gleam@dict:dict(FED, any())) -> list(FED). +keys(Map) -> + gleam@dict:keys(Map). + +-spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). +values(Map) -> + gleam@dict:values(Map). + +-spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). +filter(Map, Predicate) -> + gleam@dict:filter(Map, Predicate). + +-spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). +take(Map, Desired_keys) -> + gleam@dict:take(Map, Desired_keys). + +-spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). +merge(Map, New_entries) -> + gleam@dict:merge(Map, New_entries). + +-spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). +delete(Map, Key) -> + gleam@dict:delete(Map, Key). + +-spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). +drop(Map, Disallowed_keys) -> + gleam@dict:drop(Map, Disallowed_keys). + +-spec update( + gleam@dict:dict(FFB, FFC), + FFB, + fun((gleam@option:option(FFC)) -> FFC) +) -> gleam@dict:dict(FFB, FFC). +update(Map, Key, Fun) -> + gleam@dict:update(Map, Key, Fun). + +-spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. +fold(Map, Initial, Fun) -> + gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl new file mode 100644 index 00000000000..812aa1fe854 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl @@ -0,0 +1,147 @@ +-module(gleam@option). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). +-export_type([option/1]). + +-type option(IY) :: {some, IY} | none. + +-spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). +do_all(List, Acc) -> + case List of + [] -> + {some, Acc}; + + [X | Rest] -> + Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of + {{some, Values}, {some, Value}} -> + {some, [Value | Values]}; + + {_, _} -> + none + end end, + Accumulate(do_all(Rest, Acc), X) + end. + +-spec all(list(option(JF))) -> option(list(JF)). +all(List) -> + do_all(List, []). + +-spec is_some(option(any())) -> boolean(). +is_some(Option) -> + Option /= none. + +-spec is_none(option(any())) -> boolean(). +is_none(Option) -> + Option =:= none. + +-spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. +to_result(Option, E) -> + case Option of + {some, A} -> + {ok, A}; + + _ -> + {error, E} + end. + +-spec from_result({ok, JU} | {error, any()}) -> option(JU). +from_result(Result) -> + case Result of + {ok, A} -> + {some, A}; + + _ -> + none + end. + +-spec unwrap(option(JZ), JZ) -> JZ. +unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default + end. + +-spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. +lazy_unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default() + end. + +-spec map(option(KD), fun((KD) -> KF)) -> option(KF). +map(Option, Fun) -> + case Option of + {some, X} -> + {some, Fun(X)}; + + none -> + none + end. + +-spec flatten(option(option(KH))) -> option(KH). +flatten(Option) -> + case Option of + {some, X} -> + X; + + none -> + none + end. + +-spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). +then(Option, Fun) -> + case Option of + {some, X} -> + Fun(X); + + none -> + none + end. + +-spec 'or'(option(KQ), option(KQ)) -> option(KQ). +'or'(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second + end. + +-spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). +lazy_or(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second() + end. + +-spec do_values(list(option(KY)), list(KY)) -> list(KY). +do_values(List, Acc) -> + case List of + [] -> + Acc; + + [X | Xs] -> + Accumulate = fun(Acc@1, Item) -> case Item of + {some, Value} -> + [Value | Acc@1]; + + none -> + Acc@1 + end end, + Accumulate(do_values(Xs, Acc), X) + end. + +-spec values(list(option(LD))) -> list(LD). +values(Options) -> + do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl new file mode 100644 index 00000000000..a9eed8f39c1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl @@ -0,0 +1,79 @@ +-module(gleam@order). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). +-export_type([order/0]). + +-type order() :: lt | eq | gt. + +-spec negate(order()) -> order(). +negate(Order) -> + case Order of + lt -> + gt; + + eq -> + eq; + + gt -> + lt + end. + +-spec to_int(order()) -> integer(). +to_int(Order) -> + case Order of + lt -> + -1; + + eq -> + 0; + + gt -> + 1 + end. + +-spec compare(order(), order()) -> order(). +compare(A, B) -> + case {A, B} of + {X, Y} when X =:= Y -> + eq; + + {lt, _} -> + lt; + + {eq, gt} -> + lt; + + {_, _} -> + gt + end. + +-spec max(order(), order()) -> order(). +max(A, B) -> + case {A, B} of + {gt, _} -> + gt; + + {eq, lt} -> + eq; + + {_, _} -> + B + end. + +-spec min(order(), order()) -> order(). +min(A, B) -> + case {A, B} of + {lt, _} -> + lt; + + {eq, gt} -> + eq; + + {_, _} -> + B + end. + +-spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). +reverse(Orderer) -> + fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl new file mode 100644 index 00000000000..2452a9817e1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl @@ -0,0 +1,33 @@ +-module(gleam@pair). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). + +-spec first({IJ, any()}) -> IJ. +first(Pair) -> + {A, _} = Pair, + A. + +-spec second({any(), IM}) -> IM. +second(Pair) -> + {_, A} = Pair, + A. + +-spec swap({IN, IO}) -> {IO, IN}. +swap(Pair) -> + {A, B} = Pair, + {B, A}. + +-spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. +map_first(Pair, Fun) -> + {A, B} = Pair, + {Fun(A), B}. + +-spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. +map_second(Pair, Fun) -> + {A, B} = Pair, + {A, Fun(B)}. + +-spec new(IV, IW) -> {IV, IW}. +new(First, Second) -> + {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl new file mode 100644 index 00000000000..faec6923a14 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl @@ -0,0 +1,121 @@ +-module(gleam@queue). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). +-export_type([queue/1]). + +-opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. + +-spec new() -> queue(any()). +new() -> + {queue, [], []}. + +-spec from_list(list(EYN)) -> queue(EYN). +from_list(List) -> + {queue, [], List}. + +-spec to_list(queue(EYQ)) -> list(EYQ). +to_list(Queue) -> + _pipe = erlang:element(3, Queue), + gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). + +-spec is_empty(queue(any())) -> boolean(). +is_empty(Queue) -> + (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). + +-spec length(queue(any())) -> integer(). +length(Queue) -> + gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( + erlang:element(3, Queue) + ). + +-spec push_back(queue(EYX), EYX) -> queue(EYX). +push_back(Queue, Item) -> + {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. + +-spec push_front(queue(EZA), EZA) -> queue(EZA). +push_front(Queue, Item) -> + {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. + +-spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. +pop_back(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, [], Out} -> + pop_back({queue, gleam@list:reverse(Out), []}); + + {queue, [First | Rest], Out@1} -> + Queue@1 = {queue, Rest, Out@1}, + {ok, {First, Queue@1}} + end. + +-spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. +pop_front(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, In, []} -> + pop_front({queue, [], gleam@list:reverse(In)}); + + {queue, In@1, [First | Rest]} -> + Queue@1 = {queue, In@1, Rest}, + {ok, {First, Queue@1}} + end. + +-spec reverse(queue(EZN)) -> queue(EZN). +reverse(Queue) -> + {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. + +-spec check_equal( + list(EZQ), + list(EZQ), + list(EZQ), + list(EZQ), + fun((EZQ, EZQ) -> boolean()) +) -> boolean(). +check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> + case {Xs, X_tail, Ys, Y_tail} of + {[], [], [], []} -> + true; + + {[X | Xs@1], _, [Y | Ys@1], _} -> + case Eq(X, Y) of + false -> + false; + + true -> + check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) + end; + + {[], [_ | _], _, _} -> + check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); + + {_, _, [], [_ | _]} -> + check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); + + {_, _, _, _} -> + false + end. + +-spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). +is_logically_equal(A, B, Element_is_equal) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + Element_is_equal + ). + +-spec is_equal(queue(EZY), queue(EZY)) -> boolean(). +is_equal(A, B) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + fun(A@1, B@1) -> A@1 =:= B@1 end + ). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl new file mode 100644 index 00000000000..2d1c5fc870e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl @@ -0,0 +1,33 @@ +-module(gleam@regex). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([compile/2, from_string/1, check/2, split/2, scan/2]). +-export_type([regex/0, match/0, compile_error/0, options/0]). + +-type regex() :: any(). + +-type match() :: {match, binary(), list(gleam@option:option(binary()))}. + +-type compile_error() :: {compile_error, binary(), integer()}. + +-type options() :: {options, boolean(), boolean()}. + +-spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. +compile(Pattern, Options) -> + gleam_stdlib:compile_regex(Pattern, Options). + +-spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. +from_string(Pattern) -> + compile(Pattern, {options, false, false}). + +-spec check(regex(), binary()) -> boolean(). +check(Regex, Content) -> + gleam_stdlib:regex_check(Regex, Content). + +-spec split(regex(), binary()) -> list(binary()). +split(Regex, String) -> + gleam_stdlib:regex_split(Regex, String). + +-spec scan(regex(), binary()) -> list(match()). +scan(Regex, String) -> + gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl new file mode 100644 index 00000000000..c80a7048303 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl @@ -0,0 +1,201 @@ +-module(gleam@result). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). + +-spec is_ok({ok, any()} | {error, any()}) -> boolean(). +is_ok(Result) -> + case Result of + {error, _} -> + false; + + {ok, _} -> + true + end. + +-spec is_error({ok, any()} | {error, any()}) -> boolean(). +is_error(Result) -> + case Result of + {ok, _} -> + false; + + {error, _} -> + true + end. + +-spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | + {error, BIK}. +map(Result, Fun) -> + case Result of + {ok, X} -> + {ok, Fun(X)}; + + {error, E} -> + {error, E} + end. + +-spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | + {error, BIU}. +map_error(Result, Fun) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, Error} -> + {error, Fun(Error)} + end. + +-spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | + {error, BIY}. +flatten(Result) -> + case Result of + {ok, X} -> + X; + + {error, Error} -> + {error, Error} + end. + +-spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, + BJJ} | + {error, BJG}. +'try'(Result, Fun) -> + case Result of + {ok, X} -> + Fun(X); + + {error, E} -> + {error, E} + end. + +-spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, + BJS} | + {error, BJP}. +then(Result, Fun) -> + 'try'(Result, Fun). + +-spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. +unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default + end. + +-spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. +lazy_unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default() + end. + +-spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. +unwrap_error(Result, Default) -> + case Result of + {ok, _} -> + Default; + + {error, E} -> + E + end. + +-spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. +unwrap_both(Result) -> + case Result of + {ok, A} -> + A; + + {error, A@1} -> + A@1 + end. + +-spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. +nil_error(Result) -> + map_error(Result, fun(_) -> nil end). + +-spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | + {error, BKT}. +'or'(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second + end. + +-spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, + BLA} | + {error, BLB}. +lazy_or(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second() + end. + +-spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. +all(Results) -> + gleam@list:try_map(Results, fun(X) -> X end). + +-spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), + list(BLY)}. +do_partition(Results, Oks, Errors) -> + case Results of + [] -> + {Oks, Errors}; + + [{ok, A} | Rest] -> + do_partition(Rest, [A | Oks], Errors); + + [{error, E} | Rest@1] -> + do_partition(Rest@1, Oks, [E | Errors]) + end. + +-spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. +partition(Results) -> + do_partition(Results, [], []). + +-spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. +replace(Result, Value) -> + case Result of + {ok, _} -> + {ok, Value}; + + {error, Error} -> + {error, Error} + end. + +-spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. +replace_error(Result, Error) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, _} -> + {error, Error} + end. + +-spec values(list({ok, BMT} | {error, any()})) -> list(BMT). +values(Results) -> + gleam@list:filter_map(Results, fun(R) -> R end). + +-spec try_recover( + {ok, BMZ} | {error, BNA}, + fun((BNA) -> {ok, BMZ} | {error, BND}) +) -> {ok, BMZ} | {error, BND}. +try_recover(Result, Fun) -> + case Result of + {ok, Value} -> + {ok, Value}; + + {error, Error} -> + Fun(Error) + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl new file mode 100644 index 00000000000..3374ebc293f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl @@ -0,0 +1,85 @@ +-module(gleam@set). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). +-export_type([set/1]). + +-opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. + +-spec new() -> set(any()). +new() -> + {set, gleam@dict:new()}. + +-spec size(set(any())) -> integer(). +size(Set) -> + gleam@dict:size(erlang:element(2, Set)). + +-spec insert(set(EOQ), EOQ) -> set(EOQ). +insert(Set, Member) -> + {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. + +-spec contains(set(EOT), EOT) -> boolean(). +contains(Set, Member) -> + _pipe = erlang:element(2, Set), + _pipe@1 = gleam@dict:get(_pipe, Member), + gleam@result:is_ok(_pipe@1). + +-spec delete(set(EOV), EOV) -> set(EOV). +delete(Set, Member) -> + {set, gleam@dict:delete(erlang:element(2, Set), Member)}. + +-spec to_list(set(EOY)) -> list(EOY). +to_list(Set) -> + gleam@dict:keys(erlang:element(2, Set)). + +-spec from_list(list(EPB)) -> set(EPB). +from_list(Members) -> + Map = gleam@list:fold( + Members, + gleam@dict:new(), + fun(M, K) -> gleam@dict:insert(M, K, []) end + ), + {set, Map}. + +-spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. +fold(Set, Initial, Reducer) -> + gleam@dict:fold( + erlang:element(2, Set), + Initial, + fun(A, K, _) -> Reducer(A, K) end + ). + +-spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). +filter(Set, Predicate) -> + {set, + gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. + +-spec drop(set(EPK), list(EPK)) -> set(EPK). +drop(Set, Disallowed) -> + gleam@list:fold(Disallowed, Set, fun delete/2). + +-spec take(set(EPO), list(EPO)) -> set(EPO). +take(Set, Desired) -> + {set, gleam@dict:take(erlang:element(2, Set), Desired)}. + +-spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. +order(First, Second) -> + case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( + erlang:element(2, Second) + ) of + true -> + {First, Second}; + + false -> + {Second, First} + end. + +-spec union(set(EPX), set(EPX)) -> set(EPX). +union(First, Second) -> + {Larger, Smaller} = order(First, Second), + fold(Smaller, Larger, fun insert/2). + +-spec intersection(set(EQB), set(EQB)) -> set(EQB). +intersection(First, Second) -> + {Larger, Smaller} = order(First, Second), + take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl new file mode 100644 index 00000000000..6cba31d1895 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl @@ -0,0 +1,352 @@ +-module(gleam@string). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). +-export_type([direction/0]). + +-type direction() :: leading | trailing | both. + +-spec is_empty(binary()) -> boolean(). +is_empty(Str) -> + Str =:= <<""/utf8>>. + +-spec length(binary()) -> integer(). +length(String) -> + string:length(String). + +-spec do_reverse(binary()) -> binary(). +do_reverse(String) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:reverse(_pipe@1), + gleam@string_builder:to_string(_pipe@2). + +-spec reverse(binary()) -> binary(). +reverse(String) -> + do_reverse(String). + +-spec replace(binary(), binary(), binary()) -> binary(). +replace(String, Pattern, Substitute) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), + gleam@string_builder:to_string(_pipe@2). + +-spec lowercase(binary()) -> binary(). +lowercase(String) -> + string:lowercase(String). + +-spec uppercase(binary()) -> binary(). +uppercase(String) -> + string:uppercase(String). + +-spec compare(binary(), binary()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + _ -> + case gleam_stdlib:less_than(A, B) of + true -> + lt; + + _ -> + gt + end + end. + +-spec slice(binary(), integer(), integer()) -> binary(). +slice(String, Idx, Len) -> + case Len < 0 of + true -> + <<""/utf8>>; + + false -> + case Idx < 0 of + true -> + Translated_idx = length(String) + Idx, + case Translated_idx < 0 of + true -> + <<""/utf8>>; + + false -> + string:slice(String, Translated_idx, Len) + end; + + false -> + string:slice(String, Idx, Len) + end + end. + +-spec crop(binary(), binary()) -> binary(). +crop(String, Substring) -> + gleam_stdlib:crop_string(String, Substring). + +-spec drop_left(binary(), integer()) -> binary(). +drop_left(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, Num_graphemes, length(String) - Num_graphemes) + end. + +-spec drop_right(binary(), integer()) -> binary(). +drop_right(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, 0, length(String) - Num_graphemes) + end. + +-spec contains(binary(), binary()) -> boolean(). +contains(Haystack, Needle) -> + gleam_stdlib:contains_string(Haystack, Needle). + +-spec starts_with(binary(), binary()) -> boolean(). +starts_with(String, Prefix) -> + gleam_stdlib:string_starts_with(String, Prefix). + +-spec ends_with(binary(), binary()) -> boolean(). +ends_with(String, Suffix) -> + gleam_stdlib:string_ends_with(String, Suffix). + +-spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +do_split_once(X, Substring) -> + case string:split(X, Substring) of + [First, Rest] -> + {ok, {First, Rest}}; + + _ -> + {error, nil} + end. + +-spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +split_once(X, Substring) -> + do_split_once(X, Substring). + +-spec append(binary(), binary()) -> binary(). +append(First, Second) -> + _pipe = First, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:append(_pipe@1, Second), + gleam@string_builder:to_string(_pipe@2). + +-spec concat(list(binary())) -> binary(). +concat(Strings) -> + _pipe = Strings, + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1). + +-spec repeat(binary(), integer()) -> binary(). +repeat(String, Times) -> + _pipe = gleam@iterator:repeat(String), + _pipe@1 = gleam@iterator:take(_pipe, Times), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec do_join(list(binary()), binary()) -> binary(). +do_join(Strings, Separator) -> + _pipe = Strings, + _pipe@1 = gleam@list:intersperse(_pipe, Separator), + concat(_pipe@1). + +-spec join(list(binary()), binary()) -> binary(). +join(Strings, Separator) -> + do_join(Strings, Separator). + +-spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). +padding(Size, Pad_string) -> + Pad_length = length(Pad_string), + Num_pads = case Pad_length of + 0 -> 0; + Gleam@denominator -> Size div Gleam@denominator + end, + Extra = case Pad_length of + 0 -> 0; + Gleam@denominator@1 -> Size rem Gleam@denominator@1 + end, + _pipe = gleam@iterator:repeat(Pad_string), + _pipe@1 = gleam@iterator:take(_pipe, Num_pads), + gleam@iterator:append( + _pipe@1, + gleam@iterator:single(slice(Pad_string, 0, Extra)) + ). + +-spec pad_left(binary(), integer(), binary()) -> binary(). +pad_left(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = padding(To_pad_length, Pad_string), + _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec pad_right(binary(), integer(), binary()) -> binary(). +pad_right(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = gleam@iterator:single(String), + _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec do_trim(binary()) -> binary(). +do_trim(String) -> + string:trim(String, both). + +-spec trim(binary()) -> binary(). +trim(String) -> + do_trim(String). + +-spec do_trim_left(binary()) -> binary(). +do_trim_left(String) -> + string:trim(String, leading). + +-spec trim_left(binary()) -> binary(). +trim_left(String) -> + do_trim_left(String). + +-spec do_trim_right(binary()) -> binary(). +do_trim_right(String) -> + string:trim(String, trailing). + +-spec trim_right(binary()) -> binary(). +trim_right(String) -> + do_trim_right(String). + +-spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. +pop_grapheme(String) -> + gleam_stdlib:string_pop_grapheme(String). + +-spec do_to_graphemes(binary(), list(binary())) -> list(binary()). +do_to_graphemes(String, Acc) -> + case pop_grapheme(String) of + {ok, {Grapheme, Rest}} -> + do_to_graphemes(Rest, [Grapheme | Acc]); + + _ -> + Acc + end. + +-spec to_graphemes(binary()) -> list(binary()). +to_graphemes(String) -> + _pipe = do_to_graphemes(String, []), + gleam@list:reverse(_pipe). + +-spec split(binary(), binary()) -> list(binary()). +split(X, Substring) -> + case Substring of + <<""/utf8>> -> + to_graphemes(X); + + _ -> + _pipe = X, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), + gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) + end. + +-spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). +do_to_utf_codepoints_impl(Bit_array, Acc) -> + case Bit_array of + <> -> + do_to_utf_codepoints_impl(Rest, [First | Acc]); + + _ -> + Acc + end. + +-spec do_to_utf_codepoints(binary()) -> list(integer()). +do_to_utf_codepoints(String) -> + _pipe = do_to_utf_codepoints_impl(<>, []), + gleam@list:reverse(_pipe). + +-spec to_utf_codepoints(binary()) -> list(integer()). +to_utf_codepoints(String) -> + do_to_utf_codepoints(String). + +-spec from_utf_codepoints(list(integer())) -> binary(). +from_utf_codepoints(Utf_codepoints) -> + gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). + +-spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. +utf_codepoint(Value) -> + case Value of + I when I > 1114111 -> + {error, nil}; + + 65534 -> + {error, nil}; + + 65535 -> + {error, nil}; + + I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> + {error, nil}; + + I@2 -> + {ok, gleam_stdlib:identity(I@2)} + end. + +-spec utf_codepoint_to_int(integer()) -> integer(). +utf_codepoint_to_int(Cp) -> + gleam_stdlib:identity(Cp). + +-spec to_option(binary()) -> gleam@option:option(binary()). +to_option(S) -> + case S of + <<""/utf8>> -> + none; + + _ -> + {some, S} + end. + +-spec first(binary()) -> {ok, binary()} | {error, nil}. +first(S) -> + case pop_grapheme(S) of + {ok, {First, _}} -> + {ok, First}; + + {error, E} -> + {error, E} + end. + +-spec last(binary()) -> {ok, binary()} | {error, nil}. +last(S) -> + case pop_grapheme(S) of + {ok, {First, <<""/utf8>>}} -> + {ok, First}; + + {ok, {_, Rest}} -> + {ok, slice(Rest, -1, 1)}; + + {error, E} -> + {error, E} + end. + +-spec capitalise(binary()) -> binary(). +capitalise(S) -> + case pop_grapheme(S) of + {ok, {First, Rest}} -> + append(uppercase(First), lowercase(Rest)); + + _ -> + <<""/utf8>> + end. + +-spec inspect(any()) -> binary(). +inspect(Term) -> + _pipe = gleam_stdlib:inspect(Term), + gleam@string_builder:to_string(_pipe). + +-spec byte_size(binary()) -> integer(). +byte_size(String) -> + erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl new file mode 100644 index 00000000000..693e840f370 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl @@ -0,0 +1,91 @@ +-module(gleam@string_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). +-export_type([string_builder/0, direction/0]). + +-type string_builder() :: any(). + +-type direction() :: all. + +-spec prepend_builder(string_builder(), string_builder()) -> string_builder(). +prepend_builder(Builder, Prefix) -> + gleam_stdlib:iodata_append(Prefix, Builder). + +-spec append_builder(string_builder(), string_builder()) -> string_builder(). +append_builder(Builder, Suffix) -> + gleam_stdlib:iodata_append(Builder, Suffix). + +-spec new() -> string_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec from_strings(list(binary())) -> string_builder(). +from_strings(Strings) -> + gleam_stdlib:identity(Strings). + +-spec concat(list(string_builder())) -> string_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec from_string(binary()) -> string_builder(). +from_string(String) -> + gleam_stdlib:identity(String). + +-spec prepend(string_builder(), binary()) -> string_builder(). +prepend(Builder, Prefix) -> + append_builder(from_string(Prefix), Builder). + +-spec append(string_builder(), binary()) -> string_builder(). +append(Builder, Second) -> + append_builder(Builder, from_string(Second)). + +-spec to_string(string_builder()) -> binary(). +to_string(Builder) -> + unicode:characters_to_binary(Builder). + +-spec byte_size(string_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). + +-spec join(list(string_builder()), binary()) -> string_builder(). +join(Builders, Sep) -> + _pipe = Builders, + _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), + concat(_pipe@1). + +-spec lowercase(string_builder()) -> string_builder(). +lowercase(Builder) -> + string:lowercase(Builder). + +-spec uppercase(string_builder()) -> string_builder(). +uppercase(Builder) -> + string:uppercase(Builder). + +-spec reverse(string_builder()) -> string_builder(). +reverse(Builder) -> + string:reverse(Builder). + +-spec do_split(string_builder(), binary()) -> list(string_builder()). +do_split(Iodata, Pattern) -> + string:split(Iodata, Pattern, all). + +-spec split(string_builder(), binary()) -> list(string_builder()). +split(Iodata, Pattern) -> + do_split(Iodata, Pattern). + +-spec do_replace(string_builder(), binary(), binary()) -> string_builder(). +do_replace(Iodata, Pattern, Substitute) -> + string:replace(Iodata, Pattern, Substitute, all). + +-spec replace(string_builder(), binary(), binary()) -> string_builder(). +replace(Builder, Pattern, Substitute) -> + do_replace(Builder, Pattern, Substitute). + +-spec is_equal(string_builder(), string_builder()) -> boolean(). +is_equal(A, B) -> + string:equal(A, B). + +-spec is_empty(string_builder()) -> boolean(). +is_empty(Builder) -> + string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl new file mode 100644 index 00000000000..a36df375281 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl @@ -0,0 +1,252 @@ +-module(gleam@uri). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). +-export_type([uri/0]). + +-type uri() :: {uri, + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(integer()), + binary(), + gleam@option:option(binary()), + gleam@option:option(binary())}. + +-spec parse(binary()) -> {ok, uri()} | {error, nil}. +parse(Uri_string) -> + gleam_stdlib:uri_parse(Uri_string). + +-spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. +parse_query(Query) -> + gleam_stdlib:parse_query(Query). + +-spec percent_encode(binary()) -> binary(). +percent_encode(Value) -> + gleam_stdlib:percent_encode(Value). + +-spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). +query_pair(Pair) -> + gleam@string_builder:from_strings( + [percent_encode(erlang:element(1, Pair)), + <<"="/utf8>>, + percent_encode(erlang:element(2, Pair))] + ). + +-spec query_to_string(list({binary(), binary()})) -> binary(). +query_to_string(Query) -> + _pipe = Query, + _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), + _pipe@2 = gleam@list:intersperse( + _pipe@1, + gleam@string_builder:from_string(<<"&"/utf8>>) + ), + _pipe@3 = gleam@string_builder:concat(_pipe@2), + gleam@string_builder:to_string(_pipe@3). + +-spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. +percent_decode(Value) -> + gleam_stdlib:percent_decode(Value). + +-spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). +do_remove_dot_segments(Input, Accumulator) -> + case Input of + [] -> + gleam@list:reverse(Accumulator); + + [Segment | Rest] -> + Accumulator@5 = case {Segment, Accumulator} of + {<<""/utf8>>, Accumulator@1} -> + Accumulator@1; + + {<<"."/utf8>>, Accumulator@2} -> + Accumulator@2; + + {<<".."/utf8>>, []} -> + []; + + {<<".."/utf8>>, [_ | Accumulator@3]} -> + Accumulator@3; + + {Segment@1, Accumulator@4} -> + [Segment@1 | Accumulator@4] + end, + do_remove_dot_segments(Rest, Accumulator@5) + end. + +-spec remove_dot_segments(list(binary())) -> list(binary()). +remove_dot_segments(Input) -> + do_remove_dot_segments(Input, []). + +-spec path_segments(binary()) -> list(binary()). +path_segments(Path) -> + remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). + +-spec to_string(uri()) -> binary(). +to_string(Uri) -> + Parts = case erlang:element(8, Uri) of + {some, Fragment} -> + [<<"#"/utf8>>, Fragment]; + + _ -> + [] + end, + Parts@1 = case erlang:element(7, Uri) of + {some, Query} -> + [<<"?"/utf8>>, Query | Parts]; + + _ -> + Parts + end, + Parts@2 = [erlang:element(6, Uri) | Parts@1], + Parts@3 = case {erlang:element(4, Uri), + gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of + {{some, Host}, false} when Host =/= <<""/utf8>> -> + [<<"/"/utf8>> | Parts@2]; + + {_, _} -> + Parts@2 + end, + Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of + {{some, _}, {some, Port}} -> + [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; + + {_, _} -> + Parts@3 + end, + Parts@5 = case {erlang:element(2, Uri), + erlang:element(3, Uri), + erlang:element(4, Uri)} of + {{some, S}, {some, U}, {some, H}} -> + [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; + + {{some, S@1}, none, {some, H@1}} -> + [S@1, <<"://"/utf8>>, H@1 | Parts@4]; + + {{some, S@2}, {some, _}, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {{some, S@2}, none, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {none, none, {some, H@2}} -> + [<<"//"/utf8>>, H@2 | Parts@4]; + + {_, _, _} -> + Parts@4 + end, + gleam@string:concat(Parts@5). + +-spec origin(uri()) -> {ok, binary()} | {error, nil}. +origin(Uri) -> + {uri, Scheme, _, Host, Port, _, _, _} = Uri, + case Scheme of + {some, <<"https"/utf8>>} when Port =:= {some, 443} -> + Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin)}; + + {some, <<"http"/utf8>>} when Port =:= {some, 80} -> + Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin@1)}; + + {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> + Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, + {ok, to_string(Origin@2)}; + + _ -> + {error, nil} + end. + +-spec drop_last(list(ETW)) -> list(ETW). +drop_last(Elements) -> + gleam@list:take(Elements, gleam@list:length(Elements) - 1). + +-spec join_segments(list(binary())) -> binary(). +join_segments(Segments) -> + gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). + +-spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. +merge(Base, Relative) -> + case Base of + {uri, {some, _}, _, {some, _}, _, _, _, _} -> + case Relative of + {uri, _, _, {some, _}, _, _, _, _} -> + Path = begin + _pipe = gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ), + _pipe@1 = remove_dot_segments(_pipe), + join_segments(_pipe@1) + end, + Resolved = {uri, + gleam@option:'or'( + erlang:element(2, Relative), + erlang:element(2, Base) + ), + none, + erlang:element(4, Relative), + gleam@option:'or'( + erlang:element(5, Relative), + erlang:element(5, Base) + ), + Path, + erlang:element(7, Relative), + erlang:element(8, Relative)}, + {ok, Resolved}; + + _ -> + {New_path, New_query} = case erlang:element(6, Relative) of + <<""/utf8>> -> + {erlang:element(6, Base), + gleam@option:'or'( + erlang:element(7, Relative), + erlang:element(7, Base) + )}; + + _ -> + Path_segments = case gleam@string:starts_with( + erlang:element(6, Relative), + <<"/"/utf8>> + ) of + true -> + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ); + + false -> + _pipe@2 = gleam@string:split( + erlang:element(6, Base), + <<"/"/utf8>> + ), + _pipe@3 = drop_last(_pipe@2), + gleam@list:append( + _pipe@3, + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ) + ) + end, + Path@1 = begin + _pipe@4 = Path_segments, + _pipe@5 = remove_dot_segments(_pipe@4), + join_segments(_pipe@5) + end, + {Path@1, erlang:element(7, Relative)} + end, + Resolved@1 = {uri, + erlang:element(2, Base), + none, + erlang:element(4, Base), + erlang:element(5, Base), + New_path, + New_query, + erlang:element(8, Relative)}, + {ok, Resolved@1} + end; + + _ -> + {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src new file mode 100644 index 00000000000..76aa1ea673c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src @@ -0,0 +1,31 @@ +{application, gleam_stdlib, [ + {vsn, "0.33.1"}, + {applications, []}, + {description, "A standard library for the Gleam programming language"}, + {modules, [gleam@base, + gleam@bit_array, + gleam@bit_builder, + gleam@bit_string, + gleam@bool, + gleam@bytes_builder, + gleam@dict, + gleam@dynamic, + gleam@float, + gleam@function, + gleam@int, + gleam@io, + gleam@iterator, + gleam@list, + gleam@map, + gleam@option, + gleam@order, + gleam@pair, + gleam@queue, + gleam@regex, + gleam@result, + gleam@set, + gleam@string, + gleam@string_builder, + gleam@uri]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl new file mode 100644 index 00000000000..c6ea1257110 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl @@ -0,0 +1,529 @@ +-module(gleam_stdlib). + +-export([ + map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, + decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, + parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, + wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, + bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, + bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, + percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, + base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, + decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, + decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, + println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, + int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, + crop_string/2, base16_decode/1 +]). + +%% Taken from OTP's uri_string module +-define(DEC2HEX(X), + if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; + ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 + end). + +%% Taken from OTP's uri_string module +-define(HEX2DEC(X), + if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; + ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; + ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 + end). + +-define(is_lowercase_char(X), (X > 96 andalso X < 123)). +-define(is_underscore_char(X), (X == 95)). +-define(is_digit_char(X), (X > 47 andalso X < 58)). + +uppercase(X) -> X - 32. + +map_get(Map, Key) -> + case maps:find(Key, Map) of + error -> {error, nil}; + OkFound -> OkFound + end. + +iodata_append(Iodata, String) -> [Iodata, String]. + +identity(X) -> X. + +decode_error_msg(Expected, Data) when is_binary(Expected) -> + decode_error(Expected, classify_dynamic(Data)). +decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> + {error, [{decode_error, Expected, Got, []}]}. + +classify_dynamic(nil) -> <<"Nil">>; +classify_dynamic(X) when is_atom(X) -> <<"Atom">>; +classify_dynamic(X) when is_binary(X) -> <<"String">>; +classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; +classify_dynamic(X) when is_integer(X) -> <<"Int">>; +classify_dynamic(X) when is_float(X) -> <<"Float">>; +classify_dynamic(X) when is_list(X) -> <<"List">>; +classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; +classify_dynamic(X) when is_map(X) -> <<"Map">>; +classify_dynamic(X) when is_tuple(X) -> + iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); +classify_dynamic(X) when + is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse + is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse + is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse + is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse + is_function(X, 12) -> <<"Function">>; +classify_dynamic(_) -> <<"Some other type">>. + +decode_map(Data) when is_map(Data) -> {ok, Data}; +decode_map(Data) -> decode_error_msg(<<"Map">>, Data). + +decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; +decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). + +decode_int(Data) when is_integer(Data) -> {ok, Data}; +decode_int(Data) -> decode_error_msg(<<"Int">>, Data). + +decode_float(Data) when is_float(Data) -> {ok, Data}; +decode_float(Data) -> decode_error_msg(<<"Float">>, Data). + +decode_bool(Data) when is_boolean(Data) -> {ok, Data}; +decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). + +decode_list(Data) when is_list(Data) -> {ok, Data}; +decode_list(Data) -> decode_error_msg(<<"List">>, Data). + +decode_field(Data, Key) when is_map(Data) -> + case Data of + #{Key := Value} -> {ok, {some, Value}}; + _ -> + {ok, none} + end; +decode_field(Data, _) -> + decode_error_msg(<<"Map">>, Data). + +size_of_tuple(Data) -> tuple_size(Data). + +tuple_get(_tup, Index) when Index < 0 -> {error, nil}; +tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; +tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. + +decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; +decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). + +decode_tuple2({_,_} = A) -> {ok, A}; +decode_tuple2([A,B]) -> {ok, {A,B}}; +decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). + +decode_tuple3({_,_,_} = A) -> {ok, A}; +decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; +decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). + +decode_tuple4({_,_,_,_} = A) -> {ok, A}; +decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; +decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). + +decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; +decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; +decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). + +decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; +decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; +decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). + +decode_option(Term, F) -> + Decode = fun(Inner) -> + case F(Inner) of + {ok, Decoded} -> {ok, {some, Decoded}}; + Error -> Error + end + end, + case Term of + undefined -> {ok, none}; + error -> {ok, none}; + null -> {ok, none}; + none -> {ok, none}; + nil -> {ok, none}; + {some, Inner} -> Decode(Inner); + _ -> Decode(Term) + end. + +decode_result(Term) -> + case Term of + {ok, Inner} -> {ok, {ok, Inner}}; + ok -> {ok, {ok, nil}}; + {error, Inner} -> {ok, {error, Inner}}; + error -> {ok, {error, nil}}; + _ -> decode_error_msg(<<"Result">>, Term) + end. + +int_from_base_string(String, Base) -> + case catch binary_to_integer(String, Base) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_int(String) -> + case catch binary_to_integer(String) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_float(String) -> + case catch binary_to_float(String) of + Float when is_float(Float) -> {ok, Float}; + _ -> {error, nil} + end. + +less_than(Lhs, Rhs) -> + Lhs < Rhs. + +string_starts_with(_, <<>>) -> true; +string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; +string_starts_with(String, Prefix) -> + PrefixSize = byte_size(Prefix), + Prefix == binary_part(String, 0, PrefixSize). + +string_ends_with(_, <<>>) -> true; +string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; +string_ends_with(String, Suffix) -> + SuffixSize = byte_size(Suffix), + Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). + +string_pad(String, Length, Dir, PadString) -> + Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), + case unicode:characters_to_binary(Chars) of + Bin when is_binary(Bin) -> Bin; + Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) + end. + +string_pop_grapheme(String) -> + case string:next_grapheme(String) of + [ Next | Rest ] -> + {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; + _ -> {error, nil} + end. + +bit_array_concat(BitArrays) -> + list_to_bitstring(BitArrays). + +bit_array_slice(Bin, Pos, Len) -> + try {ok, binary:part(Bin, Pos, Len)} + catch error:badarg -> {error, nil} + end. + +bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> + {ok, <>}; +bit_array_int_to_u32(_) -> + {error, nil}. + +bit_array_int_from_u32(<>) -> + {ok, I}; +bit_array_int_from_u32(_) -> + {error, nil}. + +compile_regex(String, Options) -> + {options, Caseless, Multiline} = Options, + OptionsList = [ + unicode, + ucp, + Caseless andalso caseless, + Multiline andalso multiline + ], + FilteredOptions = [Option || Option <- OptionsList, Option /= false], + case re:compile(String, FilteredOptions) of + {ok, MP} -> {ok, MP}; + {error, {Str, Pos}} -> + {error, {compile_error, unicode:characters_to_binary(Str), Pos}} + end. + +regex_check(Regex, String) -> + re:run(String, Regex) /= nomatch. + +regex_split(Regex, String) -> + re:split(String, Regex). + +regex_submatches(_, {-1, 0}) -> none; +regex_submatches(String, {Start, Length}) -> + BinarySlice = binary:part(String, {Start, Length}), + case string:is_empty(binary_to_list(BinarySlice)) of + true -> none; + false -> {some, BinarySlice} + end. + +regex_matches(String, [{Start, Length} | Submatches]) -> + Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), + {match, binary:part(String, Start, Length), Submatches1}. + +regex_scan(Regex, String) -> + case re:run(String, Regex, [global]) of + {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); + nomatch -> [] + end. + +base_decode64(S) -> + try {ok, base64:decode(S)} + catch error:_ -> {error, nil} + end. + +wrap_list(X) when is_list(X) -> X; +wrap_list(X) -> [X]. + +parse_query(Query) -> + case uri_string:dissect_query(Query) of + {error, _, _} -> {error, nil}; + Pairs -> + Pairs1 = lists:map(fun + ({K, true}) -> {K, <<"">>}; + (Pair) -> Pair + end, Pairs), + {ok, Pairs1} + end. + +percent_encode(B) -> percent_encode(B, <<>>). +percent_encode(<<>>, Acc) -> + Acc; +percent_encode(<>, Acc) -> + case percent_ok(H) of + true -> + percent_encode(T, <>); + false -> + <> = <>, + percent_encode(T, <>) + end. + +percent_decode(Cs) -> percent_decode(Cs, <<>>). +percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> + case is_hex_digit(C0) andalso is_hex_digit(C1) of + true -> + B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), + percent_decode(Cs, <>); + false -> + {error, nil} + end; +percent_decode(<>, Acc) -> + percent_decode(Cs, <>); +percent_decode(<<>>, Acc) -> + check_utf8(Acc). + +percent_ok($!) -> true; +percent_ok($$) -> true; +percent_ok($') -> true; +percent_ok($() -> true; +percent_ok($)) -> true; +percent_ok($*) -> true; +percent_ok($+) -> true; +percent_ok($-) -> true; +percent_ok($.) -> true; +percent_ok($_) -> true; +percent_ok($~) -> true; +percent_ok(C) when $0 =< C, C =< $9 -> true; +percent_ok(C) when $A =< C, C =< $Z -> true; +percent_ok(C) when $a =< C, C =< $z -> true; +percent_ok(_) -> false. + +is_hex_digit(C) -> + ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). + +check_utf8(Cs) -> + case unicode:characters_to_list(Cs) of + {incomplete, _, _} -> {error, nil}; + {error, _, _} -> {error, nil}; + _ -> {ok, Cs} + end. + +uri_parse(String) -> + case uri_string:parse(String) of + {error, _, _} -> {error, nil}; + Uri -> + {ok, {uri, + maps_get_optional(Uri, scheme), + maps_get_optional(Uri, userinfo), + maps_get_optional(Uri, host), + maps_get_optional(Uri, port), + maps_get_or(Uri, path, <<>>), + maps_get_optional(Uri, query), + maps_get_optional(Uri, fragment) + }} + end. + +maps_get_optional(Map, Key) -> + try {some, maps:get(Key, Map)} + catch _:_ -> none + end. + +maps_get_or(Map, Key, Default) -> + try maps:get(Key, Map) + catch _:_ -> Default + end. + +print(String) -> + io:put_chars(String), + nil. + +println(String) -> + io:put_chars([String, $\n]), + nil. + +print_error(String) -> + io:put_chars(standard_error, String), + nil. + +println_error(String) -> + io:put_chars(standard_error, [String, $\n]), + nil. + +inspect(true) -> + "True"; +inspect(false) -> + "False"; +inspect(nil) -> + "Nil"; +inspect(Data) when is_map(Data) -> + Fields = [ + [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] + || {Key, Value} <- maps:to_list(Data) + ], + ["dict.from_list([", lists:join(", ", Fields), "])"]; +inspect(Atom) when is_atom(Atom) -> + Binary = erlang:atom_to_binary(Atom), + case inspect_maybe_gleam_atom(Binary, none, <<>>) of + {ok, Inspected} -> Inspected; + {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] + end; +inspect(Any) when is_integer(Any) -> + erlang:integer_to_list(Any); +inspect(Any) when is_float(Any) -> + io_lib_format:fwrite_g(Any); +inspect(Binary) when is_binary(Binary) -> + case inspect_maybe_utf8_string(Binary, <<>>) of + {ok, InspectedUtf8String} -> InspectedUtf8String; + {error, not_a_utf8_string} -> + Segments = [erlang:integer_to_list(X) || <> <= Binary], + ["<<", lists:join(", ", Segments), ">>"] + end; +inspect(Bits) when is_bitstring(Bits) -> + inspect_bit_array(Bits); +inspect(List) when is_list(List) -> + case inspect_list(List) of + {proper, Elements} -> ["[", Elements, "]"]; + {improper, Elements} -> ["//erl([", Elements, "])"] + end; +inspect(Any) when is_tuple(Any) % Record constructors + andalso is_atom(element(1, Any)) + andalso element(1, Any) =/= false + andalso element(1, Any) =/= true + andalso element(1, Any) =/= nil +-> + [Atom | ArgsList] = erlang:tuple_to_list(Any), + Args = lists:join(<<", ">>, + lists:map(fun inspect/1, ArgsList) + ), + [inspect(Atom), "(", Args, ")"]; +inspect(Tuple) when is_tuple(Tuple) -> + Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), + ["#(", lists:join(", ", Elements), ")"]; +inspect(Any) when is_function(Any) -> + {arity, Arity} = erlang:fun_info(Any, arity), + ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), + Args = lists:join(<<", ">>, + lists:map(fun(Arg) -> <> end, ArgsAsciiCodes) + ), + ["//fn(", Args, ") { ... }"]; +inspect(Any) -> + ["//erl(", io_lib:format("~p", [Any]), ")"]. + + +inspect_maybe_gleam_atom(<<>>, none, _) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, none, _) when ?is_digit_char(First) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, _PrevChar, _Acc) + when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, none, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> + inspect_maybe_gleam_atom(Rest, $_, Acc); +inspect_maybe_gleam_atom(<>, $_, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<>, _PrevChar, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> + {ok, Acc}; +inspect_maybe_gleam_atom(A, B, C) -> + erlang:display({A, B, C}), + throw({gleam_error, A, B, C}). + +inspect_list([]) -> + {proper, []}; +inspect_list([First]) -> + {proper, [inspect(First)]}; +inspect_list([First | Rest]) when is_list(Rest) -> + {Kind, Inspected} = inspect_list(Rest), + {Kind, [inspect(First), <<", ">> | Inspected]}; +inspect_list([First | ImproperTail]) -> + {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. + +inspect_bit_array(Bits) -> + Text = inspect_bit_array(Bits, <<"<<">>), + <>">>. + +inspect_bit_array(<<>>, Acc) -> + Acc; +inspect_bit_array(<>, Acc) -> + inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); +inspect_bit_array(Rest, Acc) -> + Size = bit_size(Rest), + <> = Rest, + X1 = erlang:integer_to_binary(X), + Size1 = erlang:integer_to_binary(Size), + Segment = <>, + inspect_bit_array(<<>>, append_segment(Acc, Segment)). + +append_segment(<<"<<">>, Segment) -> + <<"<<", Segment/binary>>; +append_segment(Acc, Segment) -> + <>. + + +inspect_maybe_utf8_string(Binary, Acc) -> + case Binary of + <<>> -> {ok, <<$", Acc/binary, $">>}; + <> -> + Escaped = case First of + $" -> <<$\\, $">>; + $\\ -> <<$\\, $\\>>; + $\r -> <<$\\, $r>>; + $\n -> <<$\\, $n>>; + $\t -> <<$\\, $t>>; + Other -> <> + end, + inspect_maybe_utf8_string(Rest, <>); + _ -> {error, not_a_utf8_string} + end. + +float_to_string(Float) when is_float(Float) -> + erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). + +utf_codepoint_list_to_string(List) -> + case unicode:characters_to_binary(List) of + {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); + Binary -> Binary + end. + +crop_string(String, Prefix) -> + case string:find(String, Prefix) of + nomatch -> String; + New -> New + end. + +contains_string(String, Substring) -> + is_bitstring(string:find(String, Substring)). + +base16_decode(String) -> + try + {ok, binary:decode_hex(String)} + catch + _:_ -> {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs new file mode 100644 index 00000000000..45c28cfc87b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs @@ -0,0 +1,878 @@ +import { + BitArray, + Error, + List, + Ok, + Result, + UtfCodepoint, + stringBits, + toBitArray, + NonEmpty, + CustomType, +} from "./gleam.mjs"; +import { + CompileError as RegexCompileError, + Match as RegexMatch, +} from "./gleam/regex.mjs"; +import { DecodeError } from "./gleam/dynamic.mjs"; +import { Some, None } from "./gleam/option.mjs"; +import Dict from "./dict.mjs"; + +const Nil = undefined; +const NOT_FOUND = {}; + +export function identity(x) { + return x; +} + +export function parse_int(value) { + if (/^[-+]?(\d+)$/.test(value)) { + return new Ok(parseInt(value)); + } else { + return new Error(Nil); + } +} + +export function parse_float(value) { + if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { + return new Ok(parseFloat(value)); + } else { + return new Error(Nil); + } +} + +export function to_string(term) { + return term.toString(); +} + +export function float_to_string(float) { + const string = float.toString(); + if (string.indexOf(".") >= 0) { + return string; + } else { + return string + ".0"; + } +} + +export function int_to_base_string(int, base) { + return int.toString(base).toUpperCase(); +} + +const int_base_patterns = { + 2: /[^0-1]/, + 3: /[^0-2]/, + 4: /[^0-3]/, + 5: /[^0-4]/, + 6: /[^0-5]/, + 7: /[^0-6]/, + 8: /[^0-7]/, + 9: /[^0-8]/, + 10: /[^0-9]/, + 11: /[^0-9a]/, + 12: /[^0-9a-b]/, + 13: /[^0-9a-c]/, + 14: /[^0-9a-d]/, + 15: /[^0-9a-e]/, + 16: /[^0-9a-f]/, + 17: /[^0-9a-g]/, + 18: /[^0-9a-h]/, + 19: /[^0-9a-i]/, + 20: /[^0-9a-j]/, + 21: /[^0-9a-k]/, + 22: /[^0-9a-l]/, + 23: /[^0-9a-m]/, + 24: /[^0-9a-n]/, + 25: /[^0-9a-o]/, + 26: /[^0-9a-p]/, + 27: /[^0-9a-q]/, + 28: /[^0-9a-r]/, + 29: /[^0-9a-s]/, + 30: /[^0-9a-t]/, + 31: /[^0-9a-u]/, + 32: /[^0-9a-v]/, + 33: /[^0-9a-w]/, + 34: /[^0-9a-x]/, + 35: /[^0-9a-y]/, + 36: /[^0-9a-z]/, +}; + +export function int_from_base_string(string, base) { + if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { + return new Error(Nil); + } + + const result = parseInt(string, base); + + if (isNaN(result)) { + return new Error(Nil); + } + + return new Ok(result); +} + +export function string_replace(string, target, substitute) { + if (typeof string.replaceAll !== "undefined") { + return string.replaceAll(target, substitute); + } + // Fallback for older Node.js versions: + // 1. + // 2. + // TODO: This fallback could be remove once Node.js 14 is EOL + // aka on or after 2024-04-30 + return string.replace( + // $& means the whole matched string + new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), + substitute + ); +} + +export function string_reverse(string) { + return [...string].reverse().join(""); +} + +export function string_length(string) { + if (string === "") { + return 0; + } + const iterator = graphemes_iterator(string); + if (iterator) { + let i = 0; + for (const _ of iterator) { + i++; + } + return i; + } else { + return string.match(/./gsu).length; + } +} + +export function graphemes(string) { + const iterator = graphemes_iterator(string); + if (iterator) { + return List.fromArray(Array.from(iterator).map((item) => item.segment)); + } else { + return List.fromArray(string.match(/./gsu)); + } +} + +function graphemes_iterator(string) { + if (Intl && Intl.Segmenter) { + return new Intl.Segmenter().segment(string)[Symbol.iterator](); + } +} + +export function pop_grapheme(string) { + let first; + const iterator = graphemes_iterator(string); + if (iterator) { + first = iterator.next().value?.segment; + } else { + first = string.match(/./su)?.[0]; + } + if (first) { + return new Ok([first, string.slice(first.length)]); + } else { + return new Error(Nil); + } +} + +export function lowercase(string) { + return string.toLowerCase(); +} + +export function uppercase(string) { + return string.toUpperCase(); +} + +export function less_than(a, b) { + return a < b; +} + +export function add(a, b) { + return a + b; +} + +export function equal(a, b) { + return a === b; +} + +export function split(xs, pattern) { + return List.fromArray(xs.split(pattern)); +} + +export function join(xs, separator) { + const iterator = xs[Symbol.iterator](); + let result = iterator.next().value || ""; + let current = iterator.next(); + while (!current.done) { + result = result + separator + current.value; + current = iterator.next(); + } + return result; +} + +export function concat(xs) { + let result = ""; + for (const x of xs) { + result = result + x; + } + return result; +} + +export function length(data) { + return data.length; +} + +export function crop_string(string, substring) { + return string.substring(string.indexOf(substring)); +} + +export function contains_string(haystack, needle) { + return haystack.indexOf(needle) >= 0; +} + +export function starts_with(haystack, needle) { + return haystack.startsWith(needle); +} + +export function ends_with(haystack, needle) { + return haystack.endsWith(needle); +} + +export function split_once(haystack, needle) { + const index = haystack.indexOf(needle); + if (index >= 0) { + const before = haystack.slice(0, index); + const after = haystack.slice(index + needle.length); + return new Ok([before, after]); + } else { + return new Error(Nil); + } +} + +export function trim(string) { + return string.trim(); +} + +export function trim_left(string) { + return string.trimLeft(); +} + +export function trim_right(string) { + return string.trimRight(); +} + +export function bit_array_from_string(string) { + return toBitArray([stringBits(string)]); +} + +export function bit_array_concat(bit_arrays) { + return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); +} + +export function console_log(term) { + console.log(term); +} + +export function console_error(term) { + console.error(term); +} + +export function crash(message) { + throw new globalThis.Error(message); +} + +export function bit_array_to_string(bit_array) { + try { + const decoder = new TextDecoder("utf-8", { fatal: true }); + return new Ok(decoder.decode(bit_array.buffer)); + } catch (_error) { + return new Error(Nil); + } +} + +export function print(string) { + if (typeof process === "object") { + process.stdout.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.log(string); // We're in a browser. Newlines are mandated + } +} + +export function print_error(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.error(string); // We're in a browser. Newlines are mandated + } +} + +export function print_debug(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` + } else { + console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) + } +} + +export function ceiling(float) { + return Math.ceil(float); +} + +export function floor(float) { + return Math.floor(float); +} + +export function round(float) { + return Math.round(float); +} + +export function truncate(float) { + return Math.trunc(float); +} + +export function power(base, exponent) { + // It is checked in Gleam that: + // - The base is non-negative and that the exponent is not fractional. + // - The base is non-zero and the exponent is non-negative (otherwise + // the result will essentially be division by zero). + // It can thus be assumed that valid input is passed to the Math.pow + // function and a NaN or Infinity value will not be produced. + return Math.pow(base, exponent); +} + +export function random_uniform() { + const random_uniform_result = Math.random(); + // With round-to-nearest-even behavior, the ranges claimed for the functions below + // (excluding the one for Math.random() itself) aren't exact. + // If extremely large bounds are chosen (2^53 or higher), + // it's possible in extremely rare cases to calculate the usually-excluded upper bound. + // Note that as numbers in JavaScript are IEEE 754 floating point numbers + // See: + // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: + if (random_uniform_result === 1.0) { + return random_uniform(); + } + return random_uniform_result; +} + +export function bit_array_slice(bits, position, length) { + const start = Math.min(position, position + length); + const end = Math.max(position, position + length); + if (start < 0 || end > bits.length) return new Error(Nil); + const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); + return new Ok(new BitArray(buffer)); +} + +export function codepoint(int) { + return new UtfCodepoint(int); +} + +export function string_to_codepoint_integer_list(string) { + return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); +} + +export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { + return utf_codepoint_integer_list + .toArray() + .map((x) => String.fromCodePoint(x.value)) + .join(""); +} + +export function utf_codepoint_to_int(utf_codepoint) { + return utf_codepoint.value; +} + +export function regex_check(regex, string) { + regex.lastIndex = 0; + return regex.test(string); +} + +export function compile_regex(pattern, options) { + try { + let flags = "gu"; + if (options.case_insensitive) flags += "i"; + if (options.multi_line) flags += "m"; + return new Ok(new RegExp(pattern, flags)); + } catch (error) { + const number = (error.columnNumber || 0) | 0; + return new Error(new RegexCompileError(error.message, number)); + } +} + +export function regex_scan(regex, string) { + const matches = Array.from(string.matchAll(regex)).map((match) => { + const content = match[0]; + const submatches = []; + for (let n = match.length - 1; n > 0; n--) { + if (match[n]) { + submatches[n - 1] = new Some(match[n]); + continue; + } + if (submatches.length > 0) { + submatches[n - 1] = new None(); + } + } + return new RegexMatch(content, List.fromArray(submatches)); + }); + return List.fromArray(matches); +} + +export function new_map() { + return Dict.new(); +} + +export function map_size(map) { + return map.size; +} + +export function map_to_list(map) { + return List.fromArray(map.entries()); +} + +export function map_remove(key, map) { + return map.delete(key); +} + +export function map_get(map, key) { + const value = map.get(key, NOT_FOUND); + if (value === NOT_FOUND) { + return new Error(Nil); + } + return new Ok(value); +} + +export function map_insert(key, value, map) { + return map.set(key, value); +} + +function unsafe_percent_decode(string) { + return decodeURIComponent((string || "").replace("+", " ")); +} + +export function percent_decode(string) { + try { + return new Ok(unsafe_percent_decode(string)); + } catch (_error) { + return new Error(Nil); + } +} + +export function percent_encode(string) { + return encodeURIComponent(string); +} + +export function parse_query(query) { + try { + const pairs = []; + for (const section of query.split("&")) { + const [key, value] = section.split("="); + if (!key) continue; + pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); + } + return new Ok(List.fromArray(pairs)); + } catch (_error) { + return new Error(Nil); + } +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function encode64(bit_array) { + const aBytes = bit_array.buffer; + let nMod3 = 2; + let sB64Enc = ""; + + for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { + nMod3 = nIdx % 3; + if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { + sB64Enc += "\r\n"; + } + nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); + if (nMod3 === 2 || aBytes.length - nIdx === 1) { + sB64Enc += String.fromCharCode( + uint6ToB64((nUint24 >>> 18) & 63), + uint6ToB64((nUint24 >>> 12) & 63), + uint6ToB64((nUint24 >>> 6) & 63), + uint6ToB64(nUint24 & 63) + ); + nUint24 = 0; + } + } + + return ( + sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + + (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") + ); +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function uint6ToB64(nUint6) { + return nUint6 < 26 + ? nUint6 + 65 + : nUint6 < 52 + ? nUint6 + 71 + : nUint6 < 62 + ? nUint6 - 4 + : nUint6 === 62 + ? 43 + : nUint6 === 63 + ? 47 + : 65; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function b64ToUint6(nChr) { + return nChr > 64 && nChr < 91 + ? nChr - 65 + : nChr > 96 && nChr < 123 + ? nChr - 71 + : nChr > 47 && nChr < 58 + ? nChr + 4 + : nChr === 43 + ? 62 + : nChr === 47 + ? 63 + : 0; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function decode64(sBase64) { + if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); + const sB64Enc = sBase64.replace(/=/g, ""); + const nInLen = sB64Enc.length; + const nOutLen = (nInLen * 3 + 1) >> 2; + const taBytes = new Uint8Array(nOutLen); + + for ( + let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; + nInIdx < nInLen; + nInIdx++ + ) { + nMod4 = nInIdx & 3; + nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); + if (nMod4 === 3 || nInLen - nInIdx === 1) { + for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { + taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; + } + nUint24 = 0; + } + } + + return new Ok(new BitArray(taBytes)); +} + +export function classify_dynamic(data) { + if (typeof data === "string") { + return "String"; + } else if (data instanceof Result) { + return "Result"; + } else if (data instanceof List) { + return "List"; + } else if (data instanceof BitArray) { + return "BitArray"; + } else if (data instanceof Dict) { + return "Map"; + } else if (Number.isInteger(data)) { + return "Int"; + } else if (Array.isArray(data)) { + return `Tuple of ${data.length} elements`; + } else if (typeof data === "number") { + return "Float"; + } else if (data === null) { + return "Null"; + } else if (data === undefined) { + return "Nil"; + } else { + const type = typeof data; + return type.charAt(0).toUpperCase() + type.slice(1); + } +} + +function decoder_error(expected, got) { + return decoder_error_no_classify(expected, classify_dynamic(got)); +} + +function decoder_error_no_classify(expected, got) { + return new Error( + List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) + ); +} + +export function decode_string(data) { + return typeof data === "string" + ? new Ok(data) + : decoder_error("String", data); +} + +export function decode_int(data) { + return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); +} + +export function decode_float(data) { + return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); +} + +export function decode_bool(data) { + return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); +} + +export function decode_bit_array(data) { + if (data instanceof BitArray) { + return new Ok(data); + } + if (data instanceof Uint8Array) { + return new Ok(new BitArray(data)); + } + return decoder_error("BitArray", data); +} + +export function decode_tuple(data) { + return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); +} + +export function decode_tuple2(data) { + return decode_tupleN(data, 2); +} + +export function decode_tuple3(data) { + return decode_tupleN(data, 3); +} + +export function decode_tuple4(data) { + return decode_tupleN(data, 4); +} + +export function decode_tuple5(data) { + return decode_tupleN(data, 5); +} + +export function decode_tuple6(data) { + return decode_tupleN(data, 6); +} + +function decode_tupleN(data, n) { + if (Array.isArray(data) && data.length == n) { + return new Ok(data); + } + + const list = decode_exact_length_list(data, n); + if (list) return new Ok(list); + + return decoder_error(`Tuple of ${n} elements`, data); +} + +function decode_exact_length_list(data, n) { + if (!(data instanceof List)) return; + + const elements = []; + let current = data; + + for (let i = 0; i < n; i++) { + if (!(current instanceof NonEmpty)) break; + elements.push(current.head); + current = current.tail; + } + + if (elements.length === n && !(current instanceof NonEmpty)) return elements; +} + +export function tuple_get(data, index) { + return index >= 0 && data.length > index + ? new Ok(data[index]) + : new Error(Nil); +} + +export function decode_list(data) { + if (Array.isArray(data)) { + return new Ok(List.fromArray(data)); + } + return data instanceof List ? new Ok(data) : decoder_error("List", data); +} + +export function decode_result(data) { + return data instanceof Result ? new Ok(data) : decoder_error("Result", data); +} + +export function decode_map(data) { + if (data instanceof Dict) { + return new Ok(Dict.fromMap(data)); + } + if (data == null) { + return decoder_error("Map", data); + } + if (typeof data !== "object") { + return decoder_error("Map", data); + } + const proto = Object.getPrototypeOf(data); + if (proto === Object.prototype || proto === null) { + return new Ok(Dict.fromObject(data)); + } + return decoder_error("Map", data); +} + +export function decode_option(data, decoder) { + if (data === null || data === undefined || data instanceof None) + return new Ok(new None()); + if (data instanceof Some) data = data[0]; + const result = decoder(data); + if (result.isOk()) { + return new Ok(new Some(result[0])); + } else { + return result; + } +} + +export function decode_field(value, name) { + const not_a_map_error = () => decoder_error("Map", value); + + if ( + value instanceof Dict || + value instanceof WeakMap || + value instanceof Map + ) { + const entry = map_get(value, name); + return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); + } else if (Object.getPrototypeOf(value) == Object.prototype) { + return try_get_field(value, name, () => new Ok(new None())); + } else { + return try_get_field(value, name, not_a_map_error); + } +} + +function try_get_field(value, field, or_else) { + try { + return field in value ? new Ok(new Some(value[field])) : or_else(); + } catch { + return or_else(); + } +} + +export function byte_size(string) { + return new TextEncoder().encode(string).length; +} + +// In Javascript bitwise operations convert numbers to a sequence of 32 bits +// while Erlang uses arbitrary precision. +// To get around this problem and get consistent results use BigInt and then +// downcast the value back to a Number value. + +export function bitwise_and(x, y) { + return Number(BigInt(x) & BigInt(y)); +} + +export function bitwise_not(x) { + return Number(~BigInt(x)); +} + +export function bitwise_or(x, y) { + return Number(BigInt(x) | BigInt(y)); +} + +export function bitwise_exclusive_or(x, y) { + return Number(BigInt(x) ^ BigInt(y)); +} + +export function bitwise_shift_left(x, y) { + return Number(BigInt(x) << BigInt(y)); +} + +export function bitwise_shift_right(x, y) { + return Number(BigInt(x) >> BigInt(y)); +} + +export function inspect(v) { + const t = typeof v; + if (v === true) return "True"; + if (v === false) return "False"; + if (v === null) return "//js(null)"; + if (v === undefined) return "Nil"; + if (t === "string") return JSON.stringify(v); + if (t === "bigint" || t === "number") return v.toString(); + if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; + if (v instanceof List) return inspectList(v); + if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); + if (v instanceof BitArray) return inspectBitArray(v); + if (v instanceof CustomType) return inspectCustomType(v); + if (v instanceof Dict) return inspectDict(v); + if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; + if (v instanceof RegExp) return `//js(${v})`; + if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; + if (v instanceof Function) { + const args = []; + for (const i of Array(v.length).keys()) + args.push(String.fromCharCode(i + 97)); + return `//fn(${args.join(", ")}) { ... }`; + } + return inspectObject(v); +} + +function inspectDict(map) { + let body = "dict.from_list(["; + let first = true; + map.forEach((value, key) => { + if (!first) body = body + ", "; + body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; + first = false; + }); + return body + "])"; +} + +function inspectObject(v) { + const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; + const props = []; + for (const k of Object.keys(v)) { + props.push(`${inspect(k)}: ${inspect(v[k])}`); + } + const body = props.length ? " " + props.join(", ") + " " : ""; + const head = name === "Object" ? "" : name + " "; + return `//js(${head}{${body}})`; +} + +function inspectCustomType(record) { + const props = Object.keys(record) + .map((label) => { + const value = inspect(record[label]); + return isNaN(parseInt(label)) ? `${label}: ${value}` : value; + }) + .join(", "); + return props + ? `${record.constructor.name}(${props})` + : record.constructor.name; +} + +export function inspectList(list) { + return `[${list.toArray().map(inspect).join(", ")}]`; +} + +export function inspectBitArray(bits) { + return `<<${Array.from(bits.buffer).join(", ")}>>`; +} + +export function inspectUtfCodepoint(codepoint) { + return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; +} + +export function base16_encode(bit_array) { + let result = ""; + for (const byte of bit_array.buffer) { + result += byte.toString(16).padStart(2, "0").toUpperCase(); + } + return result; +} + +export function base16_decode(string) { + const bytes = new Uint8Array(string.length / 2); + for (let i = 0; i < string.length; i += 2) { + const a = parseInt(string[i], 16); + const b = parseInt(string[i + 1], 16); + if (isNaN(a) || isNaN(b)) return new Error(Nil); + bytes[i / 2] = a * 16 + b; + } + return new Ok(new BitArray(bytes)); +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml new file mode 100644 index 00000000000..08c866301c6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml @@ -0,0 +1,2 @@ +[packages] +gleam_stdlib = "0.33.1" diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml new file mode 100644 index 00000000000..74b7e202e47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml @@ -0,0 +1,17 @@ +name = "gleeunit" +version = "0.11.0" +licences = ["Apache-2.0"] +description = "Gleam bindings to Erlang's EUnit test framework" + +[javascript.deno] +allow_read = [ + "gleam.toml", + "test", + "build", +] + +[dependencies] +gleam_stdlib = "~> 0.27" + +[dev-dependencies] +# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml new file mode 100644 index 00000000000..913de938d95 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml @@ -0,0 +1,9 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, +] + +[requirements] +gleam_stdlib = { version = "~> 0.27" } diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src new file mode 100644 index 00000000000..2f98842c95e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src @@ -0,0 +1,8 @@ +{application, gleeunit, [ + {vsn, "0.11.0"}, + {applications, [gleam_stdlib]}, + {description, "Gleam bindings to Erlang's EUnit test framework"}, + {modules, [gleeunit, + gleeunit@should]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl new file mode 100644 index 00000000000..32e1a833d01 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl @@ -0,0 +1,59 @@ +-module(gleeunit). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([main/0]). +-export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). + +-type atom_() :: any(). + +-type encoding() :: utf8. + +-type report_module_name() :: gleeunit_progress. + +-type gleeunit_progress_option() :: {colored, boolean()}. + +-type eunit_option() :: verbose | + no_tty | + {report, {report_module_name(), list(gleeunit_progress_option())}}. + +-spec gleam_to_erlang_module_name(binary()) -> binary(). +gleam_to_erlang_module_name(Path) -> + _pipe = Path, + _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), + _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), + gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). + +-spec do_main() -> nil. +do_main() -> + Options = [verbose, + no_tty, + {report, {gleeunit_progress, [{colored, true}]}}], + Result = begin + _pipe = gleeunit_ffi:find_files( + <<"**/*.{erl,gleam}"/utf8>>, + <<"test"/utf8>> + ), + _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), + _pipe@2 = gleam@list:map( + _pipe@1, + fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end + ), + _pipe@3 = eunit:test(_pipe@2, Options), + _pipe@4 = (gleam@dynamic:result( + fun gleam@dynamic:dynamic/1, + fun gleam@dynamic:dynamic/1 + ))(_pipe@3), + gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) + end, + Code = case Result of + {ok, _} -> + 0; + + {error, _} -> + 1 + end, + erlang:halt(Code). + +-spec main() -> nil. +main() -> + do_main(). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam new file mode 100644 index 00000000000..e5d4b460cad --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam @@ -0,0 +1,92 @@ +/// Find and run all test functions for the current project using Erlang's EUnit +/// test framework. +/// +/// Any Erlang or Gleam function in the `test` directory with a name editing in +/// `_test` is considered a test function and will be run. +/// +/// If running on JavaScript tests will be run with a custom test runner. +/// +pub fn main() -> Nil { + do_main() +} + +@target(javascript) +@external(javascript, "./gleeunit_ffi.mjs", "main") +fn do_main() -> Nil + +@target(erlang) +import gleam/list +@target(erlang) +import gleam/result +@target(erlang) +import gleam/string +@target(erlang) +import gleam/dynamic.{Dynamic} + +@target(erlang) +fn do_main() -> Nil { + let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] + + let result = + find_files(matching: "**/*.{erl,gleam}", in: "test") + |> list.map(gleam_to_erlang_module_name) + |> list.map(dangerously_convert_string_to_atom(_, Utf8)) + |> run_eunit(options) + |> dynamic.result(dynamic.dynamic, dynamic.dynamic) + |> result.unwrap(Error(dynamic.from(Nil))) + + let code = case result { + Ok(_) -> 0 + Error(_) -> 1 + } + halt(code) +} + +@target(erlang) +@external(erlang, "erlang", "halt") +fn halt(a: Int) -> Nil + +@target(erlang) +fn gleam_to_erlang_module_name(path: String) -> String { + path + |> string.replace(".gleam", "") + |> string.replace(".erl", "") + |> string.replace("/", "@") +} + +@target(erlang) +@external(erlang, "gleeunit_ffi", "find_files") +fn find_files(matching matching: String, in in: String) -> List(String) + +@target(erlang) +type Atom + +@target(erlang) +type Encoding { + Utf8 +} + +@target(erlang) +@external(erlang, "erlang", "binary_to_atom") +fn dangerously_convert_string_to_atom(a: String, b: Encoding) -> Atom + +@target(erlang) +type ReportModuleName { + GleeunitProgress +} + +@target(erlang) +type GleeunitProgressOption { + Colored(Bool) +} + +@target(erlang) +type EunitOption { + Verbose + NoTty + Report(#(ReportModuleName, List(GleeunitProgressOption))) +} + +@target(erlang) +@external(erlang, "eunit", "test") +fn run_eunit(a: List(Atom), b: List(EunitOption)) -> Dynamic diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam new file mode 100644 index 00000000000..c393c232724 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam @@ -0,0 +1,90 @@ +//// A module for testing your Gleam code. The functions found here are +//// compatible with the Erlang eunit test framework. +//// +//// More information on running eunit can be found in [the rebar3 +//// documentation](https://rebar3.org/docs/testing/eunit/). + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_equal") +pub fn equal(a: a, b: a) -> Nil + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_not_equal") +pub fn not_equal(a: a, b: a) -> Nil + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_be_ok") +pub fn be_ok(a: Result(a, b)) -> a + +@target(erlang) +@external(erlang, "gleeunit_ffi", "should_be_error") +pub fn be_error(a: Result(a, b)) -> b + +@target(javascript) +import gleam/string + +@target(javascript) +@external(javascript, "../gleam.mjs", "inspect") +fn stringify(a: anything) -> String + +@target(javascript) +@external(javascript, "../gleeunit_ffi.mjs", "crash") +fn crash(a: String) -> anything + +@target(javascript) +pub fn equal(a, b) { + case a == b { + True -> Nil + _ -> + crash(string.concat([ + "\n\t", + stringify(a), + "\n\tshould equal \n\t", + stringify(b), + ])) + } +} + +@target(javascript) +pub fn not_equal(a, b) { + case a != b { + True -> Nil + _ -> + crash(string.concat([ + "\n", + stringify(a), + "\nshould not equal \n", + stringify(b), + ])) + } +} + +@target(javascript) +pub fn be_ok(a) { + case a { + Ok(value) -> value + _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) + } +} + +@target(javascript) +pub fn be_error(a) { + case a { + Error(error) -> error + _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) + } +} + +pub fn be_true(actual: Bool) -> Nil { + actual + |> equal(True) +} + +pub fn be_false(actual: Bool) -> Nil { + actual + |> equal(False) +} + +pub fn fail() -> Nil { + be_true(False) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl new file mode 100644 index 00000000000..acf032e1e7d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl @@ -0,0 +1,34 @@ +-module(gleeunit@should). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). + +-spec equal(EYG, EYG) -> nil. +equal(A, B) -> + gleeunit_ffi:should_equal(A, B). + +-spec not_equal(EYH, EYH) -> nil. +not_equal(A, B) -> + gleeunit_ffi:should_not_equal(A, B). + +-spec be_ok({ok, EYI} | {error, any()}) -> EYI. +be_ok(A) -> + gleeunit_ffi:should_be_ok(A). + +-spec be_error({ok, any()} | {error, EYN}) -> EYN. +be_error(A) -> + gleeunit_ffi:should_be_error(A). + +-spec be_true(boolean()) -> nil. +be_true(Actual) -> + _pipe = Actual, + gleeunit_ffi:should_equal(_pipe, true). + +-spec be_false(boolean()) -> nil. +be_false(Actual) -> + _pipe = Actual, + gleeunit_ffi:should_equal(_pipe, false). + +-spec fail() -> nil. +fail() -> + be_true(false). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl new file mode 100644 index 00000000000..31f9ef9e2c9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl @@ -0,0 +1,24 @@ +-module(gleeunit_ffi). + +-export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, + should_be_error/1]). + +-include_lib("eunit/include/eunit.hrl"). + +find_files(Pattern, In) -> + Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), + lists:map(fun list_to_binary/1, Results). + + +should_equal(Actual, Expected) -> + ?assertEqual(Expected, Actual), + nil. +should_not_equal(Actual, Expected) -> + ?assertNotEqual(Expected, Actual), + nil. +should_be_ok(A) -> + ?assertMatch({ok, _}, A), + element(2, A). +should_be_error(A) -> + ?assertMatch({error, _}, A), + element(2, A). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs new file mode 100644 index 00000000000..339a843e5c5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs @@ -0,0 +1,101 @@ +async function* gleamFiles(directory) { + for (let entry of await read_dir(directory)) { + let path = join_path(directory, entry); + if (path.endsWith(".gleam")) { + yield path; + } else { + try { + yield* gleamFiles(path); + } catch (error) { + // Could not read directory, assume it's a file + } + } + } +} + +async function readRootPackageName() { + let toml = await read_file("gleam.toml", "utf-8"); + for (let line of toml.split("\n")) { + let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() + if (matches) return matches[1]; + } + throw new Error("Could not determine package name from gleam.toml"); +} + +export async function main() { + let passes = 0; + let failures = 0; + + let packageName = await readRootPackageName(); + let dist = `../${packageName}/`; + + for await (let path of await gleamFiles("test")) { + let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); + let module = await import(join_path(dist, js_path)); + for (let fnName of Object.keys(module)) { + if (!fnName.endsWith("_test")) continue; + try { + await module[fnName](); + write(`\u001b[32m.\u001b[0m`); + passes++; + } catch (error) { + let moduleName = "\n" + js_path.slice(0, -4); + let line = error.line ? `:${error.line}` : ""; + write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); + failures++; + } + } + } + + console.log(` +${passes + failures} tests, ${failures} failures`); + exit(failures ? 1 : 0); +} + +export function crash(message) { + throw new Error(message); +} + +function write(message) { + if (globalThis.Deno) { + Deno.stdout.writeSync(new TextEncoder().encode(message)); + } else { + process.stdout.write(message); + } +} + +function exit(code) { + if (globalThis.Deno) { + Deno.exit(code); + } else { + process.exit(code); + } +} + +async function read_dir(path) { + if (globalThis.Deno) { + let items = []; + for await (let item of Deno.readDir(path, { withFileTypes: true })) { + items.push(item.name); + } + return items; + } else { + let { readdir } = await import("fs/promises"); + return readdir(path); + } +} + +function join_path(a, b) { + if (a.endsWith("/")) return a + b; + return a + "/" + b; +} + +async function read_file(path) { + if (globalThis.Deno) { + return Deno.readTextFile(path); + } else { + let { readFile } = await import("fs/promises"); + let contents = await readFile(path); + return contents.toString(); + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl new file mode 100644 index 00000000000..1f68eb95e58 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl @@ -0,0 +1,607 @@ +%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters + +%% @doc A listener/reporter for eunit that prints '.' for each +%% success, 'F' for each failure, and 'E' for each error. It can also +%% optionally summarize the failures at the end. +-compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). +-module(gleeunit_progress). +-behaviour(eunit_listener). +-define(NOTEST, true). +-include_lib("eunit/include/eunit.hrl"). + +-define(RED, "\e[0;31m"). +-define(GREEN, "\e[0;32m"). +-define(YELLOW, "\e[0;33m"). +-define(WHITE, "\e[0;37m"). +-define(CYAN, "\e[0;36m"). +-define(RESET, "\e[0m"). + +-record(node,{ + rank = 0 :: non_neg_integer(), + key :: term(), + value :: term(), + children = new() :: binomial_heap() + }). + +-export_type([binomial_heap/0, heap_node/0]). +-type binomial_heap() :: [ heap_node() ]. +-type heap_node() :: #node{}. + +%% eunit_listener callbacks +-export([ + init/1, + handle_begin/3, + handle_end/3, + handle_cancel/3, + terminate/2, + start/0, + start/1 + ]). + +%% -- binomial_heap.erl content start -- + +-record(state, { + status = dict:new() :: euf_dict(), + failures = [] :: [[pos_integer()]], + skips = [] :: [[pos_integer()]], + timings = new() :: binomial_heap(), + colored = true :: boolean(), + profile = false :: boolean() + }). + +-type euf_dict() :: dict:dict(). + +-spec new() -> binomial_heap(). +new() -> + []. + +% Inserts a new pair into the heap (or creates a new heap) +-spec insert(term(), term()) -> binomial_heap(). +insert(Key,Value) -> + insert(Key,Value,[]). + +-spec insert(term(), term(), binomial_heap()) -> binomial_heap(). +insert(Key,Value,Forest) -> + insTree(#node{key=Key,value=Value},Forest). + +% Merges two heaps +-spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). +merge(TS1,[]) when is_list(TS1) -> TS1; +merge([],TS2) when is_list(TS2) -> TS2; +merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> + if + R1 < R2 -> + [T1 | merge(TS1,F2)]; + R2 < R1 -> + [T2 | merge(F1, TS2)]; + true -> + insTree(link(T1,T2),merge(TS1,TS2)) + end. + +% Deletes the top entry from the heap and returns it +-spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. +delete(TS) -> + {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), + {{Key,Value},merge(lists:reverse(TS1),TS2)}. + +% Turns the heap into list in heap order +-spec to_list(binomial_heap()) -> [{term(), term()}]. +to_list([]) -> []; +to_list(List) when is_list(List) -> + to_list([],List). +to_list(Acc, []) -> + lists:reverse(Acc); +to_list(Acc,Forest) -> + {Next, Trees} = delete(Forest), + to_list([Next|Acc], Trees). + +% Take N elements from the top of the heap +-spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. +take(N,Trees) when is_integer(N), is_list(Trees) -> + take(N,Trees,[]). +take(0,_Trees,Acc) -> + lists:reverse(Acc); +take(_N,[],Acc)-> + lists:reverse(Acc); +take(N,Trees,Acc) -> + {Top,T2} = delete(Trees), + take(N-1,T2,[Top|Acc]). + +% Get an estimate of the size based on the binomial property +-spec size(binomial_heap()) -> non_neg_integer(). +size(Forest) -> + erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). + +%% Private API +-spec link(heap_node(), heap_node()) -> heap_node(). +link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> + case X1 < X2 of + true -> + T1#node{rank=R+1,children=[T2|C1]}; + _ -> + T2#node{rank=R+1,children=[T1|C2]} + end. + +insTree(Tree, []) -> + [Tree]; +insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> + case R1 < R2 of + true -> + [T1|TS]; + _ -> + insTree(link(T1,T2),Rest) + end. + +getMin([T]) -> + {T,[]}; +getMin([#node{key=K} = T|TS]) -> + {#node{key=K1} = T1,TS1} = getMin(TS), + case K < K1 of + true -> {T,TS}; + _ -> {T1,[T|TS1]} + end. + +%% -- binomial_heap.erl content end -- + +%% Startup +start() -> + start([]). + +start(Options) -> + eunit_listener:start(?MODULE, Options). + +%%------------------------------------------ +%% eunit_listener callbacks +%%------------------------------------------ +init(Options) -> + #state{colored=proplists:get_bool(colored, Options), + profile=proplists:get_bool(profile, Options)}. + +handle_begin(group, Data, St) -> + GID = proplists:get_value(id, Data), + Dict = St#state.status, + St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; +handle_begin(test, Data, St) -> + TID = proplists:get_value(id, Data), + Dict = St#state.status, + St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. + +handle_end(group, Data, St) -> + St#state{status=merge_on_end(Data, St#state.status)}; +handle_end(test, Data, St) -> + NewStatus = merge_on_end(Data, St#state.status), + St1 = print_progress(Data, St), + St2 = record_timing(Data, St1), + St2#state{status=NewStatus}. + +handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> + Status1 = merge_on_end(Data, Status), + ID = proplists:get_value(id, Data), + St#state{status=Status1, skips=[ID|Skips]}. + +terminate({ok, Data}, St) -> + print_failures(St), + print_pending(St), + print_profile(St), + print_timing(St), + print_results(Data, St); +terminate({error, Reason}, St) -> + io:nl(), io:nl(), + print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), + sync_end(error). + +sync_end(Result) -> + receive + {stop, Reference, ReplyTo} -> + ReplyTo ! {result, Reference, Result}, + ok + end. + +%%------------------------------------------ +%% Print and collect information during run +%%------------------------------------------ +print_progress(Data, St) -> + TID = proplists:get_value(id, Data), + case proplists:get_value(status, Data) of + ok -> + print_progress_success(St), + St; + {skipped, _Reason} -> + print_progress_skipped(St), + St#state{skips=[TID|St#state.skips]}; + {error, Exception} -> + print_progress_failed(Exception, St), + St#state{failures=[TID|St#state.failures]} + end. + +record_timing(Data, State=#state{timings=T, profile=true}) -> + TID = proplists:get_value(id, Data), + case lists:keyfind(time, 1, Data) of + {time, Int} -> + %% It's a min-heap, so we insert negative numbers instead + %% of the actuals and normalize when we report on them. + T1 = insert(-Int, TID, T), + State#state{timings=T1}; + false -> + State + end; +record_timing(_Data, State) -> + State. + +print_progress_success(St) -> + print_colored(".", ?GREEN, St). + +print_progress_skipped(St) -> + print_colored("*", ?YELLOW, St). + +print_progress_failed(_Exc, St) -> + print_colored("F", ?RED, St). + +merge_on_end(Data, Dict) -> + ID = proplists:get_value(id, Data), + dict:update(ID, + fun(Old) -> + orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) + end, Dict). + +merge_data(_K, undefined, X) -> X; +merge_data(_K, X, undefined) -> X; +merge_data(_K, _, X) -> X. + +%%------------------------------------------ +%% Print information at end of run +%%------------------------------------------ +print_failures(#state{failures=[]}) -> + ok; +print_failures(#state{failures=Fails}=State) -> + io:nl(), + io:fwrite("Failures:~n",[]), + lists:foldr(print_failure_fun(State), 1, Fails), + ok. + +print_failure_fun(#state{status=Status}=State) -> + fun(Key, Count) -> + TestData = dict:fetch(Key, Status), + TestId = format_test_identifier(TestData), + io:fwrite("~n ~p) ~ts~n", [Count, TestId]), + print_failure_reason(proplists:get_value(status, TestData), + proplists:get_value(output, TestData), + State), + io:nl(), + Count + 1 + end. + +print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> + X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), + print_colored(X, ?CYAN, State); +print_gleam_location(_, _) -> + ok. + +inspect(X) -> + gleam@string:inspect(X). + +print_gleam_failure_reason( + #{gleam_error := assert, message := Message, value := Value}, + State +) -> + print_colored(indent(5, "~s~n", [Message]), ?RED, State), + print_colored(indent(5, " value: ", []), ?RED, State), + print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); +print_gleam_failure_reason( + #{gleam_error := todo, message := Message}, + State +) -> + print_colored(indent(5, "todo expression run~n", []), ?RED, State), + print_colored(indent(5, " message: ", []), ?RED, State), + print_colored(indent(0, "~s~n", [Message]), ?RESET, State); +print_gleam_failure_reason(Error, State) -> + print_colored(indent(5, "~p~n", [Error]), ?RED, State). + +% New Gleeunit specific formatters +print_failure_reason( + {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State +) when is_list(Stack) -> + print_gleam_failure_reason(Error, State), + print_gleam_location(Error, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> + print_colored(indent(5, "No case clause matched~n", []), ?RED, State), + print_colored(indent(5, "Value: ", []), ?CYAN, State), + print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +% From the original Erlang version +print_failure_reason({skipped, Reason}, _Output, State) -> + print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), + ?RED, State); +print_failure_reason({error, {_Class, Term, _}}, Output, State) when + is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> + print_assertion_failure(Term, State), + print_failure_output(5, Output, State); +print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> + print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +print_failure_reason({error, Reason}, Output, State) -> + print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), + print_failure_output(5, Output, State). + +gleam_format_module_name(Module) -> + string:replace(atom_to_list(Module), "@", "/", all). + +print_stack(Stack, State) -> + print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), + print_stackframes(Stack, State). +print_stackframes([{eunit_test, _, _, _} | Stack], State) -> + print_stackframes(Stack, State); +print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> + print_stackframes(Stack, State); +print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> + GleamModule = gleam_format_module_name(Module), + print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), + print_stackframes(Stack, State); +print_stackframes([], _State) -> + ok. + + +print_failure_output(_, <<>>, _) -> ok; +print_failure_output(_, undefined, _) -> ok; +print_failure_output(Indent, Output, State) -> + print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). + +print_assertion_failure({Type, Props}, State) -> + FailureDesc = format_assertion_failure(Type, Props, 5), + print_colored(FailureDesc, ?RED, State), + io:nl(). + +print_pending(#state{skips=[]}) -> + ok; +print_pending(#state{status=Status, skips=Skips}=State) -> + io:nl(), + io:fwrite("Pending:~n", []), + lists:foreach(fun(ID) -> + Info = dict:fetch(ID, Status), + case proplists:get_value(reason, Info) of + undefined -> + ok; + Reason -> + print_pending_reason(Reason, Info, State) + end + end, lists:reverse(Skips)), + io:nl(). + +print_pending_reason(Reason0, Data, State) -> + Text = case proplists:get_value(type, Data) of + group -> + io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); + test -> + io_lib:format(" ~ts~n", [format_test_identifier(Data)]) + end, + Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), + print_colored(Text, ?YELLOW, State), + print_colored(Reason, ?CYAN, State). + +print_profile(#state{timings=T, status=Status, profile=true}=State) -> + TopN = take(10, T), + TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), + TLG = dict:fetch([], Status), + TotalTime = proplists:get_value(time, TLG), + if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> + TopNPct = (TopNTime / TotalTime) * 100, + io:nl(), io:nl(), + io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), + lists:foreach(print_timing_fun(State), TopN), + io:nl(); + true -> ok + end; +print_profile(#state{profile=false}) -> + ok. + +print_timing(#state{status=Status}) -> + TLG = dict:fetch([], Status), + Time = proplists:get_value(time, TLG), + io:nl(), + io:fwrite("Finished in ~ts~n", [format_time(Time)]), + ok. + +print_results(Data, State) -> + Pass = proplists:get_value(pass, Data, 0), + Fail = proplists:get_value(fail, Data, 0), + Skip = proplists:get_value(skip, Data, 0), + Cancel = proplists:get_value(cancel, Data, 0), + Total = Pass + Fail + Skip + Cancel, + {Color, Result} = if Fail > 0 -> {?RED, error}; + Skip > 0; Cancel > 0 -> {?YELLOW, error}; + Pass =:= 0 -> {?YELLOW, ok}; + true -> {?GREEN, ok} + end, + print_results(Color, Total, Fail, Skip, Cancel, State), + sync_end(Result). + +print_results(Color, 0, _, _, _, State) -> + print_colored(Color, "0 tests\n", State); +print_results(Color, Total, Fail, Skip, Cancel, State) -> + SkipText = format_optional_result(Skip, "skipped"), + CancelText = format_optional_result(Cancel, "cancelled"), + Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), + print_colored(Text, Color, State). + +print_timing_fun(#state{status=Status}=State) -> + fun({Time, Key}) -> + TestData = dict:fetch(Key, Status), + TestId = format_test_identifier(TestData), + io:nl(), + io:fwrite(" ~ts~n", [TestId]), + print_colored([" "|format_time(abs(Time))], ?CYAN, State) + end. + +%%------------------------------------------ +%% Print to the console with the given color +%% if enabled. +%%------------------------------------------ +print_colored(Text, Color, #state{colored=true}) -> + io:fwrite("~s~ts~s", [Color, Text, ?RESET]); +print_colored(Text, _Color, #state{colored=false}) -> + io:fwrite("~ts", [Text]). + +%%------------------------------------------ +%% Generic data formatters +%%------------------------------------------ +format_function_name(M, F) -> + M1 = gleam_format_module_name(M), + io_lib:format("~ts.~ts", [M1, F]). + +format_optional_result(0, _) -> + []; +format_optional_result(Count, Text) -> + io_lib:format(", ~p ~ts", [Count, Text]). + +format_test_identifier(Data) -> + {Mod, Fun, _} = proplists:get_value(source, Data), + Line = case proplists:get_value(line, Data) of + 0 -> ""; + L -> io_lib:format(":~p", [L]) + end, + Desc = case proplists:get_value(desc, Data) of + undefined -> ""; + DescText -> io_lib:format(": ~ts", [DescText]) + end, + io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). + +format_time(undefined) -> + "? seconds"; +format_time(Time) -> + io_lib:format("~.3f seconds", [Time / 1000]). + +format_pending_reason({module_not_found, M}) -> + M1 = gleam_format_module_name(M), + io_lib:format("Module '~ts' missing", [M1]); +format_pending_reason({no_such_function, {M,F,_}}) -> + M1 = gleam_format_module_name(M), + io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); +format_pending_reason({exit, Reason}) -> + io_lib:format("Related process exited with reason: ~p", [Reason]); +format_pending_reason(Reason) -> + io_lib:format("Unknown error: ~p", [Reason]). + +%% @doc Formats all the known eunit assertions, you're on your own if +%% you make an assertion yourself. +format_assertion_failure(Type, Props, I) when Type =:= assertion_failed + ; Type =:= assert -> + Keys = proplists:get_keys(Props), + HasEUnitProps = ([expression, value] -- Keys) =:= [], + HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], + if + HasEUnitProps -> + [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), + indent(I, " expected: true~n", []), + case proplists:get_value(value, Props) of + false -> + indent(I, " got: false", []); + {not_a_boolean, V} -> + indent(I, " got: ~p", [V]) + end]; + HasHamcrestProps -> + [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), + indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), + indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; + true -> + [indent(I, "Failure: unknown assert: ~p", [Props])] + end; + +format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed + ; Type =:= assertMatch -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + Value = proplists:get_value(value, Props), + [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), + indent(I, " expected: = ~ts~n", [Pattern]), + indent(I, " got: ~p", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed + ; Type =:= assertNotMatch -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + Value = proplists:get_value(value, Props), + [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), + indent(I, " expected not: = ~ts~n", [Pattern]), + indent(I, " got: ~p", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed + ; Type =:= assertEqual -> + Expected = inspect(proplists:get_value(expected, Props)), + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were not equal~n", []), + indent(I, "expected: ~ts~n", [Expected]), + indent(I, " got: ~ts", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed + ; Type =:= assertNotEqual -> + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were equal~n", []), + indent(I, "expected: not ~ts~n,", [Value]), + indent(I, " got: ~ts", [Value])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertException_failed + ; Type =:= assertException -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA + [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), + case proplists:is_defined(unexpected_success, Props) of + true -> + [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), + indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; + false -> + Ex = proplists:get_value(unexpected_exception, Props), + [indent(I, " expected: exception ~ts~n", [Pattern]), + indent(I, " got: exception ~p", [Ex])] + end]; + +format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed + ; Type =:= assertNotException -> + Expr = proplists:get_value(expression, Props), + Pattern = proplists:get_value(pattern, Props), + {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT + Ex = proplists:get_value(unexpected_exception, Props), + [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), + indent(I, " expected not: exception ~ts~n", [Pattern]), + indent(I, " got: exception ~p", [Ex])]; + +format_assertion_failure(Type, Props, I) when Type =:= command_failed + ; Type =:= command -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_status, Props), + Status = proplists:get_value(status, Props), + [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: status ~p~n", [Expected]), + indent(I, " got: status ~p", [Status])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed + ; Type =:= assertCmd -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_status, Props), + Status = proplists:get_value(status, Props), + [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: status ~p~n", [Expected]), + indent(I, " got: status ~p", [Status])]; + +format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed + ; Type =:= assertCmdOutput -> + Cmd = proplists:get_value(command, Props), + Expected = proplists:get_value(expected_output, Props), + Output = proplists:get_value(output, Props), + [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), + indent(I, " expected: ~p~n", [Expected]), + indent(I, " got: ~p", [Output])]; + +format_assertion_failure(Type, Props, I) -> + indent(I, "~p", [{Type, Props}]). + +indent(I, Fmt, Args) -> + io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). + +extract_exception_pattern(Str) -> + ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), + {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml new file mode 100644 index 00000000000..44f92f58c1d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml @@ -0,0 +1,3 @@ +[packages] +gleam_stdlib = "0.33.1" +gleeunit = "0.11.0" diff --git a/test-community-packages-javascript/build/packages/glx/gleam.toml b/test-community-packages-javascript/build/packages/glx/gleam.toml new file mode 100644 index 00000000000..bbbca2306be --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/gleam.toml @@ -0,0 +1,11 @@ +name = "glx" +version = "0.2.0" +description = "Extensions to the Gleam standard library." +licences = ["MIT"] +repository = { type = "github", user = "maxdeviant", repo = "glx" } + +[dependencies] +gleam_stdlib = "~> 0.29" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glx/manifest.toml b/test-community-packages-javascript/build/packages/glx/manifest.toml new file mode 100644 index 00000000000..b605eaf19d3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/manifest.toml @@ -0,0 +1,11 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, + { name = "gleeunit", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "1397E5C4AC4108769EE979939AC39BF7870659C5AFB714630DEEEE16B8272AD5" }, +] + +[requirements] +gleam_stdlib = { version = "~> 0.29" } +gleeunit = { version = "~> 0.10" } diff --git a/test-community-packages-javascript/build/packages/glx/src/glx.app.src b/test-community-packages-javascript/build/packages/glx/src/glx.app.src new file mode 100644 index 00000000000..c6fc08eca4b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/src/glx.app.src @@ -0,0 +1,8 @@ +{application, glx, [ + {vsn, "0.2.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Extensions to the Gleam standard library."}, + {modules, [glx@stringx]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam b/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam new file mode 100644 index 00000000000..ba8bfd24805 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam @@ -0,0 +1,31 @@ +//// Extensions to `gleam/string`. + +import gleam/bool.{negate} +import gleam/list +import gleam/regex +import gleam/string + +/// Returns the lines contained in the given string. +/// +/// Supports both `\n` and `\r\n` line endings. +/// +/// ## Examples +/// +/// ```gleam +/// > lines("one\ntwo\n\nthree\n") +/// ["one", "two", "three"] +/// ``` +/// +/// ```gleam +/// > lines("one\r\ntwo\r\n\r\nthree\r\n") +/// ["one", "two", "three"] +/// ``` +pub fn lines(value: String) -> List(String) { + let assert Ok(newline_regex) = regex.from_string("\r?\n") + + let is_not_empty = fn(line) { negate(string.is_empty(line)) } + + value + |> regex.split(with: newline_regex) + |> list.filter(is_not_empty) +} diff --git a/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl b/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl new file mode 100644 index 00000000000..442e47bcd68 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl @@ -0,0 +1,24 @@ +-module(glx@stringx). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([lines/1]). + +-spec lines(binary()) -> list(binary()). +lines(Value) -> + _assert_subject = gleam@regex:from_string(<<"\r?\n"/utf8>>), + {ok, Newline_regex} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"glx/stringx"/utf8>>, + function => <<"lines"/utf8>>, + line => 24}) + end, + Is_not_empty = fun(Line) -> + gleam@bool:negate(gleam@string:is_empty(Line)) + end, + _pipe = Value, + _pipe@1 = gleam@regex:split(Newline_regex, _pipe), + gleam@list:filter(_pipe@1, Is_not_empty). diff --git a/test-community-packages-javascript/build/packages/gsv/README.md b/test-community-packages-javascript/build/packages/gsv/README.md new file mode 100644 index 00000000000..f9e1f0e4d20 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/README.md @@ -0,0 +1,45 @@ +# gsv + +[![Package Version](https://img.shields.io/hexpm/v/csv)](https://hex.pm/packages/csv) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/csv/) + +This is a simple csv parser and writer for gleam. It will get more performant in the future, +but if you're looking for high performance now, I'd recommend doing ffi to an existing parser +in your target runtime. + +We are using the grammar from [rfc 4180](https://datatracker.ietf.org/doc/html/rfc4180#section-2) + +#### Example + +```gleam +import gsv.{Unix, Windows} + +pub fn main() { + let csv_str = "Hello, World\nGoodbye, Mars" + + // Parse a CSV string to a List(List(String)) + let assert Ok(records) = gsv.to_lists(csv_str) + + // Write a List(List(String)) to a CSV string + let csv_str = records + |> gsv.from_lists(separator: ",", line_ending: Windows) +} +``` + +## Quick start + +```sh +gleam run # Run the project +gleam test # Run the tests +gleam shell # Run an Erlang shell +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add csv +``` + +and its documentation can be found at . diff --git a/test-community-packages-javascript/build/packages/gsv/gleam.toml b/test-community-packages-javascript/build/packages/gsv/gleam.toml new file mode 100644 index 00000000000..5531f8f1ada --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/gleam.toml @@ -0,0 +1,20 @@ +name = "gsv" +version = "0.1.0" +description = "A simple csv parser and generator written in gleam " + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +# +licences = ["Apache-2.0"] +repository = { type = "github", user = "bcpeinhardt", repo = "gsv" } + +internal_modules = [ + "gsv/internal", + "gsv/internal/*", +] + +[dependencies] +gleam_stdlib = "~> 0.28" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl b/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl new file mode 100644 index 00000000000..6f89ba03f95 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl @@ -0,0 +1 @@ +-record(textdata, {inner :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src b/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src new file mode 100644 index 00000000000..357abfbd8a2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src @@ -0,0 +1,10 @@ +{application, gsv, [ + {vsn, "0.1.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "A simple csv parser and generator written in gleam "}, + {modules, [gsv, + gsv@internal@ast, + gsv@internal@token]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv.erl new file mode 100644 index 00000000000..a5751d0d9a4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/src/gsv.erl @@ -0,0 +1,58 @@ +-module(gsv). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_lists/1, from_lists/3]). +-export_type([line_ending/0]). + +-type line_ending() :: windows | unix. + +-spec to_lists(binary()) -> {ok, list(list(binary()))} | {error, nil}. +to_lists(Input) -> + _pipe = Input, + _pipe@1 = gsv@internal@token:scan(_pipe), + gsv@internal@ast:parse(_pipe@1). + +-spec le_to_string(line_ending()) -> binary(). +le_to_string(Le) -> + case Le of + windows -> + <<"\r\n"/utf8>>; + + unix -> + <<"\n"/utf8>> + end. + +-spec from_lists(list(list(binary())), binary(), line_ending()) -> binary(). +from_lists(Input, Separator, Line_ending) -> + _pipe = Input, + _pipe@1 = gleam@list:map( + _pipe, + fun(Row) -> + gleam@list:map( + Row, + fun(Entry) -> + Entry@1 = gleam@string:replace( + Entry, + <<"\""/utf8>>, + <<"\"\""/utf8>> + ), + case (gleam@string:contains(Entry@1, Separator) orelse gleam@string:contains( + Entry@1, + <<"\n"/utf8>> + )) + orelse gleam@string:contains(Entry@1, <<"\""/utf8>>) of + true -> + <<<<"\""/utf8, Entry@1/binary>>/binary, "\""/utf8>>; + + false -> + Entry@1 + end + end + ) + end + ), + _pipe@2 = gleam@list:map( + _pipe@1, + fun(Row@1) -> gleam@string:join(Row@1, Separator) end + ), + gleam@string:join(_pipe@2, le_to_string(Line_ending)). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam new file mode 100644 index 00000000000..3feff3f6228 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam @@ -0,0 +1,62 @@ +import gsv/internal/ast +import gsv/internal/token +import gleam/list +import gleam/string + +/// Parses a csv string to a list of lists of strings. +/// Automatically handles Windows and Unix line endings. +pub fn to_lists(input: String) -> Result(List(List(String)), Nil) { + input + |> token.scan + |> ast.parse +} + +/// Option for using "\n = LF = Unix" or "\r\n = CRLF = Windows" +/// line endings. Use with the `from_lists` function when +/// writing to a csv string. +pub type LineEnding { + Windows + Unix +} + +fn le_to_string(le: LineEnding) -> String { + case le { + Windows -> "\r\n" + Unix -> "\n" + } +} + +/// Takes a list of lists of strings and writes it to a csv string. +/// Will automatically escape strings that contain double quotes or +/// line endings with double quotes (in csv, double quotes get escaped by doing +/// a double doublequote) +/// The string `he"llo\n` becomes `"he""llo\n"` +pub fn from_lists( + input: List(List(String)), + separator separator: String, + line_ending line_ending: LineEnding, +) -> String { + input + |> list.map(fn(row) { + list.map( + row, + fn(entry) { + // Double quotes need to be escaped with an extra doublequote + let entry = string.replace(entry, "\"", "\"\"") + + // If the string contains a , \n \r\n or " it needs to be escaped by wrapping in double quotes + case + string.contains(entry, separator) || string.contains(entry, "\n") || string.contains( + entry, + "\"", + ) + { + True -> "\"" <> entry <> "\"" + False -> entry + } + }, + ) + }) + |> list.map(fn(row) { string.join(row, separator) }) + |> string.join(le_to_string(line_ending)) +} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam new file mode 100644 index 00000000000..f991b826f7d --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam @@ -0,0 +1,140 @@ +//// We are using the following grammar for CSV from rfc4180 +//// +//// file = [header CRLF] record *(CRLF record) [CRLF] +//// header = name *(COMMA name) +//// record = field *(COMMA field) +//// name = field +//// field = (escaped / non-escaped) +//// escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE +//// non-escaped = *TEXTDATA + +import gleam/list +import gleam/result +import gsv/internal/token.{CR, Comma, CsvToken, Doublequote, LF, Textdata} + +type ParseState { + Beginning + JustParsedField + JustParsedComma + JustParsedNewline + JustParsedCR + InsideEscapedString +} + +pub fn parse(input: List(CsvToken)) -> Result(List(List(String)), Nil) { + let inner_rev = { + use llf <- result.try(parse_p(input, Beginning, [])) + use lf <- list.try_map(llf) + Ok(list.reverse(lf)) + } + use ir <- result.try(inner_rev) + Ok(list.reverse(ir)) +} + +fn parse_p( + input: List(CsvToken), + parse_state: ParseState, + llf: List(List(String)), +) -> Result(List(List(String)), Nil) { + case input, parse_state, llf { + // Error Case: An empty list should produce an Error + [], Beginning, _ -> Error(Nil) + + // BASE CASE: We are done parsing tokens + [], _, llf -> Ok(llf) + + // File should begin with either Escaped or Nonescaped string + [Textdata(str), ..remaining_tokens], Beginning, [] -> + parse_p(remaining_tokens, JustParsedField, [[str]]) + + [Doublequote, ..remaining_tokens], Beginning, [] -> + parse_p(remaining_tokens, InsideEscapedString, [[""]]) + + _, Beginning, _ -> Error(Nil) + + // If we just parsed a field, we're expecting either a comma or a CRLF + [Comma, ..remaining_tokens], JustParsedField, llf -> + parse_p(remaining_tokens, JustParsedComma, llf) + + [LF, ..remaining_tokens], JustParsedField, llf -> + parse_p(remaining_tokens, JustParsedNewline, llf) + + [CR, ..remaining_tokens], JustParsedField, llf -> + parse_p(remaining_tokens, JustParsedCR, llf) + + _, JustParsedField, _ -> Error(Nil) + + // If we just parsed a CR, we're expecting an LF + [LF, ..remaining_tokens], JustParsedCR, llf -> + parse_p(remaining_tokens, JustParsedNewline, llf) + + _, JustParsedCR, _ -> Error(Nil) + + // If we just parsed a comma, we're expecting an Escaped or Non-Escaped string + [Textdata(str), ..remaining_tokens], JustParsedComma, [ + curr_line, + ..previously_parsed_lines + ] -> + parse_p( + remaining_tokens, + JustParsedField, + [[str, ..curr_line], ..previously_parsed_lines], + ) + + [Doublequote, ..remaining_tokens], JustParsedComma, [ + curr_line, + ..previously_parsed_lines + ] -> + parse_p( + remaining_tokens, + InsideEscapedString, + [["", ..curr_line], ..previously_parsed_lines], + ) + + _, JustParsedComma, _ -> Error(Nil) + + // If we just parsed a new line, we're expecting an escaped or non-escaped string + [Textdata(str), ..remaining_tokens], JustParsedNewline, llf -> + parse_p(remaining_tokens, JustParsedField, [[str], ..llf]) + + [Doublequote, ..remaining_tokens], JustParsedNewline, [ + curr_line, + ..previously_parsed_lines + ] -> + parse_p( + remaining_tokens, + InsideEscapedString, + [["", ..curr_line], ..previously_parsed_lines], + ) + + _, JustParsedNewline, _ -> Error(Nil) + + // If we're inside an escaped string, we can take anything until we get a double quote, + // but a double double quote "" escapes the double quote and we keep parsing + [Doublequote, Doublequote, ..remaining_tokens], InsideEscapedString, [ + [str, ..rest_curr_line], + ..previously_parsed_lines + ] -> + parse_p( + remaining_tokens, + InsideEscapedString, + [[str <> "\"", ..rest_curr_line], ..previously_parsed_lines], + ) + + [Doublequote, ..remaining_tokens], InsideEscapedString, llf -> + parse_p(remaining_tokens, JustParsedField, llf) + + [other_token, ..remaining_tokens], InsideEscapedString, [ + [str, ..rest_curr_line], + ..previously_parsed_lines + ] -> + parse_p( + remaining_tokens, + InsideEscapedString, + [ + [str <> token.to_lexeme(other_token), ..rest_curr_line], + ..previously_parsed_lines + ], + ) + } +} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam new file mode 100644 index 00000000000..ff70536f4f1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam @@ -0,0 +1,54 @@ +//// We are using the following grammar for CSV from rfc4180 +//// +//// file = [header CRLF] record *(CRLF record) [CRLF] +//// header = name *(COMMA name) +//// record = field *(COMMA field) +//// name = field +//// field = (escaped / non-escaped) +//// escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE +//// non-escaped = *TEXTDATA + +import gleam/string +import gleam/list + +pub type CsvToken { + Comma + LF + CR + Doublequote + Textdata(inner: String) +} + +pub fn to_lexeme(token: CsvToken) -> String { + case token { + Comma -> "," + LF -> "\n" + CR -> "\r" + Doublequote -> "\"" + Textdata(str) -> str + } +} + +pub fn scan(input: String) -> List(CsvToken) { + input + |> string.to_utf_codepoints + |> list.fold( + [], + fn(acc, x) { + case string.utf_codepoint_to_int(x) { + 0x2c -> [Comma, ..acc] + 0x22 -> [Doublequote, ..acc] + 0x0a -> [LF, ..acc] + 0x0D -> [CR, ..acc] + _ -> { + let cp = string.from_utf_codepoints([x]) + case acc { + [Textdata(str), ..rest] -> [Textdata(str <> cp), ..rest] + _ -> [Textdata(cp), ..acc] + } + } + } + }, + ) + |> list.reverse +} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl new file mode 100644 index 00000000000..ac107202ac0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl @@ -0,0 +1,125 @@ +-module(gsv@internal@ast). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([parse/1]). +-export_type([parse_state/0]). + +-type parse_state() :: beginning | + just_parsed_field | + just_parsed_comma | + just_parsed_newline | + just_parsed_cr | + inside_escaped_string. + +-spec parse_p( + list(gsv@internal@token:csv_token()), + parse_state(), + list(list(binary())) +) -> {ok, list(list(binary()))} | {error, nil}. +parse_p(Input, Parse_state, Llf) -> + case {Input, Parse_state, Llf} of + {[], beginning, _} -> + {error, nil}; + + {[], _, Llf@1} -> + {ok, Llf@1}; + + {[{textdata, Str} | Remaining_tokens], beginning, []} -> + parse_p(Remaining_tokens, just_parsed_field, [[Str]]); + + {[doublequote | Remaining_tokens@1], beginning, []} -> + parse_p(Remaining_tokens@1, inside_escaped_string, [[<<""/utf8>>]]); + + {_, beginning, _} -> + {error, nil}; + + {[comma | Remaining_tokens@2], just_parsed_field, Llf@2} -> + parse_p(Remaining_tokens@2, just_parsed_comma, Llf@2); + + {[lf | Remaining_tokens@3], just_parsed_field, Llf@3} -> + parse_p(Remaining_tokens@3, just_parsed_newline, Llf@3); + + {[cr | Remaining_tokens@4], just_parsed_field, Llf@4} -> + parse_p(Remaining_tokens@4, just_parsed_cr, Llf@4); + + {_, just_parsed_field, _} -> + {error, nil}; + + {[lf | Remaining_tokens@5], just_parsed_cr, Llf@5} -> + parse_p(Remaining_tokens@5, just_parsed_newline, Llf@5); + + {_, just_parsed_cr, _} -> + {error, nil}; + + {[{textdata, Str@1} | Remaining_tokens@6], + just_parsed_comma, + [Curr_line | Previously_parsed_lines]} -> + parse_p( + Remaining_tokens@6, + just_parsed_field, + [[Str@1 | Curr_line] | Previously_parsed_lines] + ); + + {[doublequote | Remaining_tokens@7], + just_parsed_comma, + [Curr_line@1 | Previously_parsed_lines@1]} -> + parse_p( + Remaining_tokens@7, + inside_escaped_string, + [[<<""/utf8>> | Curr_line@1] | Previously_parsed_lines@1] + ); + + {_, just_parsed_comma, _} -> + {error, nil}; + + {[{textdata, Str@2} | Remaining_tokens@8], just_parsed_newline, Llf@6} -> + parse_p(Remaining_tokens@8, just_parsed_field, [[Str@2] | Llf@6]); + + {[doublequote | Remaining_tokens@9], + just_parsed_newline, + [Curr_line@2 | Previously_parsed_lines@2]} -> + parse_p( + Remaining_tokens@9, + inside_escaped_string, + [[<<""/utf8>> | Curr_line@2] | Previously_parsed_lines@2] + ); + + {_, just_parsed_newline, _} -> + {error, nil}; + + {[doublequote, doublequote | Remaining_tokens@10], + inside_escaped_string, + [[Str@3 | Rest_curr_line] | Previously_parsed_lines@3]} -> + parse_p( + Remaining_tokens@10, + inside_escaped_string, + [[<> | Rest_curr_line] | + Previously_parsed_lines@3] + ); + + {[doublequote | Remaining_tokens@11], inside_escaped_string, Llf@7} -> + parse_p(Remaining_tokens@11, just_parsed_field, Llf@7); + + {[Other_token | Remaining_tokens@12], + inside_escaped_string, + [[Str@4 | Rest_curr_line@1] | Previously_parsed_lines@4]} -> + parse_p( + Remaining_tokens@12, + inside_escaped_string, + [[<> | + Rest_curr_line@1] | + Previously_parsed_lines@4] + ) + end. + +-spec parse(list(gsv@internal@token:csv_token())) -> {ok, list(list(binary()))} | + {error, nil}. +parse(Input) -> + Inner_rev = (gleam@result:'try'( + parse_p(Input, beginning, []), + fun(Llf) -> + gleam@list:try_map(Llf, fun(Lf) -> {ok, gleam@list:reverse(Lf)} end) + end + )), + gleam@result:'try'(Inner_rev, fun(Ir) -> {ok, gleam@list:reverse(Ir)} end). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl new file mode 100644 index 00000000000..63647f465f1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl @@ -0,0 +1,59 @@ +-module(gsv@internal@token). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_lexeme/1, scan/1]). +-export_type([csv_token/0]). + +-type csv_token() :: comma | lf | cr | doublequote | {textdata, binary()}. + +-spec to_lexeme(csv_token()) -> binary(). +to_lexeme(Token) -> + case Token of + comma -> + <<","/utf8>>; + + lf -> + <<"\n"/utf8>>; + + cr -> + <<"\r"/utf8>>; + + doublequote -> + <<"\""/utf8>>; + + {textdata, Str} -> + Str + end. + +-spec scan(binary()) -> list(csv_token()). +scan(Input) -> + _pipe = Input, + _pipe@1 = gleam@string:to_utf_codepoints(_pipe), + _pipe@2 = gleam@list:fold( + _pipe@1, + [], + fun(Acc, X) -> case gleam@string:utf_codepoint_to_int(X) of + 16#2c -> + [comma | Acc]; + + 16#22 -> + [doublequote | Acc]; + + 16#0a -> + [lf | Acc]; + + 16#0D -> + [cr | Acc]; + + _ -> + Cp = gleam@string:from_utf_codepoints([X]), + case Acc of + [{textdata, Str} | Rest] -> + [{textdata, <>} | Rest]; + + _ -> + [{textdata, Cp} | Acc] + end + end end + ), + gleam@list:reverse(_pipe@2). diff --git a/test-community-packages-javascript/build/packages/hug/README.md b/test-community-packages-javascript/build/packages/hug/README.md new file mode 100644 index 00000000000..a55808a6eb5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/hug/README.md @@ -0,0 +1,47 @@ +# hug + +A package for creating helpful, and pretty CLI messages. + +[![Package Version](https://img.shields.io/hexpm/v/hug)](https://hex.pm/packages/hug) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/hug/) + +✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! + +--- + +## Quick start + +```gleam +import gleam/io +import hug + +pub fn main() { + let source = "let six = 5 + 1.0" + + source + |> hug.error( + in: "example.gleam", + from: #(1, 10), + to: #(1, 17), + message: "invalid type", + hint: "can not add an `Int` to a `Float`" + ) + |> io.println() + ) +} +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add hug +``` + +and its documentation can be found at . + + +## Why `hug`? + +The name `hug` is inspired by Mark Rendle's talk [The Worst Programming Language Ever](https://youtu.be/vcFBwt1nu2U?t=2229) where he refers error messages in Rust as "a hug from the compiler". diff --git a/test-community-packages-javascript/build/packages/hug/gleam.toml b/test-community-packages-javascript/build/packages/hug/gleam.toml new file mode 100644 index 00000000000..3aedf38c6fa --- /dev/null +++ b/test-community-packages-javascript/build/packages/hug/gleam.toml @@ -0,0 +1,16 @@ +name = "hug" +version = "0.1.0" +licences = ["Apache-2.0"] +description = "Helpful and pretty CLI messages" +repository = { type = "github", user = "brettkolodny", repo = "gleam-hug" } + +[javascript.deno] +allow_read = ["./gleam.toml", "./test/"] + +[dependencies] +gleam_stdlib = "~> 0.26" +gleam_community_ansi = "~> 1.0" + +[dev-dependencies] +gleeunit = "~> 0.9" +gleam_erlang = "~> 0.17" diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.app.src b/test-community-packages-javascript/build/packages/hug/src/hug.app.src new file mode 100644 index 00000000000..dfed29a1cf7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/hug/src/hug.app.src @@ -0,0 +1,10 @@ +{application, hug, [ + {vsn, "0.1.0"}, + {applications, [gleam_community_ansi, + gleam_erlang, + gleam_stdlib, + gleeunit]}, + {description, "Helpful and pretty CLI messages"}, + {modules, [hug]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.erl b/test-community-packages-javascript/build/packages/hug/src/hug.erl new file mode 100644 index 00000000000..21d3a159505 --- /dev/null +++ b/test-community-packages-javascript/build/packages/hug/src/hug.erl @@ -0,0 +1,303 @@ +-module(hug). +-compile(no_auto_import). + +-export([error/6, warning/6, info/6]). +-export_type([location/0, output/0]). + +-type location() :: {location, integer(), integer()}. + +-type output() :: error | warning | info. + +-spec error( + binary(), + binary(), + {integer(), integer()}, + {integer(), integer()}, + binary(), + binary() +) -> binary(). +error(File_name, Source, Start, End, Msg, Hint) -> + output( + File_name, + Source, + {location, erlang:element(1, Start), erlang:element(2, Start)}, + {location, erlang:element(1, End), erlang:element(2, End)}, + Msg, + Hint, + error + ). + +-spec warning( + binary(), + binary(), + {integer(), integer()}, + {integer(), integer()}, + binary(), + binary() +) -> binary(). +warning(File_name, Source, Start, End, Msg, Hint) -> + output( + File_name, + Source, + {location, erlang:element(1, Start), erlang:element(2, Start)}, + {location, erlang:element(1, End), erlang:element(2, End)}, + Msg, + Hint, + warning + ). + +-spec info( + binary(), + binary(), + {integer(), integer()}, + {integer(), integer()}, + binary(), + binary() +) -> binary(). +info(File_name, Source, Start, End, Msg, Hint) -> + output( + File_name, + Source, + {location, erlang:element(1, Start), erlang:element(2, Start)}, + {location, erlang:element(1, End), erlang:element(2, End)}, + Msg, + Hint, + info + ). + +-spec output( + binary(), + binary(), + location(), + location(), + binary(), + binary(), + output() +) -> binary(). +output(File_name, Source, Start, End, Err, Hint, Output) -> + Header = construct_header(Err, Output), + Body = construct_body(File_name, Source, Start, End, Output), + gleam@string:join([Header, Body, <<""/utf8>>, Hint], <<"\n"/utf8>>). + +-spec get_relevant_lines(list(binary()), location(), location()) -> list(binary()). +get_relevant_lines(Source_lines, Start, End) -> + gleam@list:index_fold( + Source_lines, + [], + fun(Lines, Line, Index) -> + case ((Index + + 1) + >= erlang:element(2, Start)) + andalso ((Index + + 1) + =< erlang:element(2, End)) of + true -> + gleam@list:append(Lines, [Line]); + + false -> + Lines + end + end + ). + +-spec underline_source(list(binary()), location(), location(), output()) -> list(binary()). +underline_source(Source_lines, Start, End, Output) -> + Colour = case Output of + error -> + fun gleam_community@ansi:red/1; + + warning -> + fun gleam_community@ansi:yellow/1; + + info -> + fun gleam_community@ansi:blue/1 + end, + gleam@list:index_map( + Source_lines, + fun(Index, Line) -> + case gleam@string:trim(Line) of + <<""/utf8>> -> + <<""/utf8>>; + + _@1 -> + case Index =:= 0 of + true -> + White_space = gleam@string:repeat( + <<" "/utf8>>, + erlang:element(3, Start) + - 1 + ), + Underline_end = case erlang:element(2, End) + =:= erlang:element(2, Start) of + true -> + erlang:element(3, End) - erlang:element( + 3, + Start + ); + + false -> + gleam@string:length(Line) - gleam@string:length( + White_space + ) + end, + <>, + Underline_end + ) + ))/binary>>; + + false -> + Line_length = gleam@string:length(Line), + Line_length_post_trim = gleam@string:length( + gleam@string:trim_left(Line) + ), + Num_white_space = Line_length + - Line_length_post_trim, + White_space@1 = gleam@string:repeat( + <<" "/utf8>>, + Num_white_space + ), + <>, + Line_length_post_trim + ) + ))/binary>> + end + end + end + ). + +-spec construct_header(binary(), output()) -> binary(). +construct_header(Message, Output) -> + case Output of + error -> + <<(gleam_community@ansi:red(<<"error: "/utf8>>))/binary, + Message/binary>>; + + warning -> + <<(gleam_community@ansi:yellow(<<"warning: "/utf8>>))/binary, + Message/binary>>; + + info -> + <<(gleam_community@ansi:blue(<<"info: "/utf8>>))/binary, + Message/binary>> + end. + +-spec construct_body(binary(), binary(), location(), location(), output()) -> binary(). +construct_body(File_name, Source, Start, End, Output) -> + Left_padding = gleam@int:max( + gleam@string:length(gleam@int:to_string(erlang:element(2, Start))), + gleam@string:length(gleam@int:to_string(erlang:element(2, End))) + ) + - 1, + Body_start = <<<<<<<<<<<<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, + " ┌─ "/utf8>>/binary, + File_name/binary>>/binary, + ":"/utf8>>/binary, + (gleam@int:to_string(erlang:element(2, Start)))/binary>>/binary, + ":"/utf8>>/binary, + (gleam@int:to_string(erlang:element(3, Start)))/binary>>, + Relevant_lines = get_relevant_lines( + gleam@string:split(Source, <<"\n"/utf8>>), + Start, + End + ), + Underlines = underline_source(Relevant_lines, Start, End, Output), + Trim_left_amount = get_trim_left_amount(Relevant_lines), + Body = begin + _pipe = gleam@list:zip(Relevant_lines, Underlines), + _pipe@1 = gleam@list:index_map( + _pipe, + fun(Index, Input) -> + construct_output_line( + Input, + Index + + erlang:element(2, Start), + Trim_left_amount, + Left_padding + ) + end + ), + gleam@string:join(_pipe@1, <<"\n"/utf8>>) + end, + gleam@string:join( + [Body_start, + <<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, + " │"/utf8>>, + Body, + <<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, + " │"/utf8>>], + <<"\n"/utf8>> + ). + +-spec construct_output_line( + {binary(), binary()}, + integer(), + integer(), + integer() +) -> binary(). +construct_output_line(Input, Row, Trim_left_amount, Left_padding) -> + {Source_line, Underline} = Input, + Line_number_padding = (Left_padding + - gleam@string:length(gleam@int:to_string(Row))) + + 1, + Source_line@1 = <<<<<<(gleam_community@ansi:green(gleam@int:to_string(Row)))/binary, + (gleam@string:repeat(<<" "/utf8>>, Line_number_padding))/binary>>/binary, + " │ "/utf8>>/binary, + (trim_left(Source_line, Trim_left_amount))/binary>>, + case gleam@string:length(Underline) of + 0 -> + Source_line@1; + + _@1 -> + Underline_line = <<<<(gleam@string:repeat( + <<" "/utf8>>, + Left_padding + ))/binary, + " │ "/utf8>>/binary, + (trim_left(Underline, Trim_left_amount))/binary>>, + gleam@string:join([Source_line@1, Underline_line], <<"\n"/utf8>>) + end. + +-spec get_trim_left_amount(list(binary())) -> integer(). +get_trim_left_amount(Lines) -> + Get_left_white_space = fun(Line) -> + gleam@string:length(Line) + - begin + _pipe = Line, + _pipe@1 = gleam@string:trim_left(_pipe), + gleam@string:length(_pipe@1) + end + end, + First_line = begin + _pipe@2 = gleam@list:first(Lines), + gleam@result:unwrap(_pipe@2, <<""/utf8>>) + end, + gleam@list:fold( + Lines, + Get_left_white_space(First_line), + fun(Min_white_space, Line@1) -> + case gleam@string:trim(Line@1) of + <<""/utf8>> -> + Min_white_space; + + _@1 -> + White_space = gleam@string:length(Line@1) + - begin + _pipe@3 = Line@1, + _pipe@4 = gleam@string:trim_left(_pipe@3), + gleam@string:length(_pipe@4) + end, + gleam@int:min(Min_white_space, White_space) + end + end + ). + +-spec trim_left(binary(), integer()) -> binary(). +trim_left(Str, Num_white_space) -> + String_length = gleam@string:length(Str), + gleam@string:slice(Str, Num_white_space, String_length). diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.gleam b/test-community-packages-javascript/build/packages/hug/src/hug.gleam new file mode 100644 index 00000000000..5c81514446d --- /dev/null +++ b/test-community-packages-javascript/build/packages/hug/src/hug.gleam @@ -0,0 +1,405 @@ +//// +//// - **Outputs** +//// - [`error`](#error) +//// - [`warning`](#error) +//// - [`info`](#info) +//// +//// --- +//// +////

    +//// The license of that package is produced below: +//// +//// +//// > MIT License +//// +//// > Permission is hereby granted, free of charge, to any person obtaining a copy +//// of this software and associated documentation files (the "Software"), to deal +//// in the Software without restriction, including without limitation the rights +//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +//// copies of the Software, and to permit persons to whom the Software is +//// furnished to do so, subject to the following conditions: +//// +//// > The above copyright notice and this permission notice shall be included in all +//// copies or substantial portions of the Software. +////
    +//// + +// IMPORTS -------------------------------------------------------------------- + +import gleam/int +import gleam/list +import gleam/result +import gleam/string +import gleam_community/ansi + +// TYPES ---------------------------------------------------------------------- + +type Location { + Location(row: Int, col: Int) +} + +type Output { + Error + Warning + Info +} + +// OUTPUTS -------------------------------------------------------------------- + +/// Returns a `String` displaying the provided error and relevant code. +/// +/// +///
    +/// Example: +/// +/// ```gleam +/// fn example() { +/// let source = "let five = 4 + 1.0" +/// +/// source +/// |> hug.error( +/// in: "example.gleam", +/// from: #(1, 11), +/// to: #(1, 18), +/// message: "invalid type", +/// hint: "can not add an `Int` to a `Float`" +/// ) +/// |> io.println() +/// } +/// ``` +///
    +/// +/// +/// +pub fn error( + in file_name: String, + containing source: String, + from start: #(Int, Int), + to end: #(Int, Int), + message msg: String, + hint hint: String, +) -> String { + output( + file_name, + source, + Location(row: start.0, col: start.1), + Location(row: end.0, col: end.1), + msg, + hint, + Error, + ) +} + +/// Returns a `String` displaying the provided warning and relevant code. +/// +/// +///
    +/// Example: +/// +/// ```gleam +/// fn example() { +/// let source = "let five = 4 + 1.0" +/// +/// source +/// |> hug.warning( +/// in: "example.gleam", +/// from: #(1, 5), +/// to: #(1, 9), +/// message: "unused variable", +/// hint: "the variable `five` is declared but never used" +/// ) +/// |> io.println() +/// } +/// ``` +///
    +/// +/// +/// +pub fn warning( + in file_name: String, + containing source: String, + from start: #(Int, Int), + to end: #(Int, Int), + message msg: String, + hint hint: String, +) -> String { + output( + file_name, + source, + Location(row: start.0, col: start.1), + Location(row: end.0, col: end.1), + msg, + hint, + Warning, + ) +} + +/// Returns a `String` displaying the provided info and relevant code. +/// +/// +///
    +/// Example: +/// +/// ```gleam +/// fn example() { +/// let source = "try five = int.parse("4") |> result.then(fn(v) { v + 1})" +/// +/// source +/// |> hug.info( +/// in: "example.gleam", +/// from: #(1, 1), +/// to: #(1, 4), +/// message: "use of deprecated code", +/// hint: "`try` is marked as deprecated, check out `use`!" +/// ) +/// |> io.println() +/// } +/// ``` +///
    +/// +/// +/// +pub fn info( + in file_name: String, + containing source: String, + from start: #(Int, Int), + to end: #(Int, Int), + message msg: String, + hint hint: String, +) -> String { + output( + file_name, + source, + Location(row: start.0, col: start.1), + Location(row: end.0, col: end.1), + msg, + hint, + Info, + ) +} + +// ---------------------------------------------------------------------------- + +fn output( + file_name: String, + source: String, + start: Location, + end: Location, + err: String, + hint: String, + output: Output, +) { + let header = construct_header(err, output) + + let body = construct_body(file_name, source, start, end, output) + + string.join([header, body, "", hint], "\n") +} + +// +fn get_relevant_lines( + source_lines: List(String), + start: Location, + end: Location, +) -> List(String) { + use lines, line, index <- list.index_fold(source_lines, []) + + case index + 1 >= start.row && index + 1 <= end.row { + True -> list.append(lines, [line]) + False -> lines + } +} + +// +fn underline_source( + source_lines: List(String), + start: Location, + end: Location, + output: Output, +) -> List(String) { + let colour = case output { + Error -> ansi.red + Warning -> ansi.yellow + Info -> ansi.blue + } + + use index, line <- list.index_map(source_lines) + + case string.trim(line) { + "" -> "" + _ -> + case index == 0 { + True -> { + let white_space = string.repeat(" ", start.col - 1) + + let underline_end = case end.row == start.row { + True -> end.col - start.col + False -> string.length(line) - string.length(white_space) + } + + white_space <> colour(string.repeat("~", underline_end)) + } + + False -> { + let line_length = string.length(line) + let line_length_post_trim = string.length(string.trim_left(line)) + + let num_white_space = line_length - line_length_post_trim + + let white_space = string.repeat(" ", num_white_space) + + white_space <> colour(string.repeat("~", line_length_post_trim)) + } + } + } +} + +fn construct_header(message: String, output: Output) -> String { + case output { + Error -> ansi.red("error: ") <> message + Warning -> ansi.yellow("warning: ") <> message + Info -> ansi.blue("info: ") <> message + } +} + +// +fn construct_body( + file_name: String, + source: String, + start: Location, + end: Location, + output: Output, +) -> String { + let left_padding = + int.max( + string.length(int.to_string(start.row)), + string.length(int.to_string(end.row)), + ) - 1 + + let body_start = + string.repeat(" ", left_padding) <> " ┌─ " <> file_name <> ":" <> int.to_string( + start.row, + ) <> ":" <> int.to_string(start.col) + + let relevant_lines = + get_relevant_lines(string.split(source, on: "\n"), start, end) + + let underlines = underline_source(relevant_lines, start, end, output) + + let trim_left_amount = get_trim_left_amount(relevant_lines) + + let body = + list.zip(relevant_lines, underlines) + |> list.index_map(fn(index, input) { + construct_output_line( + input, + index + start.row, + trim_left_amount, + left_padding, + ) + }) + |> string.join("\n") + + string.join( + [ + body_start, + string.repeat(" ", left_padding) <> " │", + body, + string.repeat(" ", left_padding) <> " │", + ], + "\n", + ) +} + +// +fn construct_output_line( + input: #(String, String), + row: Int, + trim_left_amount: Int, + left_padding: Int, +) -> String { + let #(source_line, underline) = input + + let line_number_padding = left_padding - string.length(int.to_string(row)) + 1 + + let source_line = + ansi.green(int.to_string(row)) <> string.repeat(" ", line_number_padding) <> " │ " <> trim_left( + source_line, + by: trim_left_amount, + ) + + case string.length(underline) { + 0 -> source_line + _ -> { + let underline_line = + string.repeat(" ", left_padding) <> " │ " <> trim_left( + underline, + by: trim_left_amount, + ) + + string.join([source_line, underline_line], "\n") + } + } +} + +// +fn get_trim_left_amount(lines: List(String)) -> Int { + let get_left_white_space = fn(line) { + string.length(line) - { + line + |> string.trim_left() + |> string.length() + } + } + + let first_line = + list.first(lines) + |> result.unwrap("") + + use min_white_space, line <- list.fold( + lines, + get_left_white_space(first_line), + ) + + case string.trim(line) { + "" -> min_white_space + _ -> { + let white_space = + string.length(line) - { + line + |> string.trim_left() + |> string.length() + } + + int.min(min_white_space, white_space) + } + } +} + +// +fn trim_left(str: String, by num_white_space: Int) -> String { + let string_length = string.length(str) + + string.slice(from: str, at_index: num_white_space, length: string_length) +} diff --git a/test-community-packages-javascript/build/packages/mist/README.md b/test-community-packages-javascript/build/packages/mist/README.md new file mode 100644 index 00000000000..fedef427160 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/README.md @@ -0,0 +1,202 @@ +# mist + +A glistening Gleam web server. + +## Installation + +This package can be added to your Gleam project: + +```sh +gleam add mist +``` + +and its documentation can be found at . + +## Usage + +Right now there are a few options. Let's say you want a "simple" HTTP server +that you can customize to your heart's content. In that case, you want: + +```gleam +import gleam/bit_builder +import gleam/erlang/process +import gleam/http/response +import mist + +pub fn main() { + let assert Ok(_) = + mist.run_service( + 8080, + fn(_req) { + response.new(200) + |> response.set_body(bit_builder.from_string("hello, world!")) + }, + max_body_limit: 4_000_000 + ) + process.sleep_forever() +} +``` + +Maybe you also want to work with websockets. Maybe those should only be +upgradable at a certain endpoint. For that, you can use `mist.handler_func`. +The websocket methods help you build a handler with connect/disconnect handlers. +You can use these to track connected clients, for example. + +```gleam +import gleam/bit_builder +import gleam/erlang/process +import gleam/http.{Get, Post} +import gleam/http/request.{Request} +import gleam/http/response +import gleam/result +import mist +import mist/websocket + +pub fn main() { + let assert Ok(_) = + mist.serve( + 8080, + mist.handler_func(fn(req) { + case req.method, request.path_segments(req) { + Get, ["echo", "test"] -> websocket_echo() + Post, ["echo", "body"] -> echo_body(req) + Get, ["home"] -> + response.new(200) + |> mist.bit_builder_response( + bit_builder.from_string("sup home boy") + ) + _, _ -> + response.new(200) + |> mist.bit_builder_response( + bit_builder.from_string("Hello, world!") + ) + } + }), + ) + process.sleep_forever() +} + +fn websocket_echo() { + websocket.echo_handler + |> websocket.with_handler + // Here you can gain access to the `Subject` to send message to + // with: + // |> websocket.on_init(fn(subj) { ... }) + // |> websocket.on_close(fn(subj) { ... }) + |> mist.upgrade +} + +fn echo_body(req: Request(mist.Body)) { + req + |> mist.read_body + |> result.map(fn(req) { + response.new(200) + |> response.prepend_header( + "content-type", + request.get_header(req, "content-type") + |> result.unwrap("application/octet-stream"), + ) + |> mist.bit_builder_response(bit_builder.from_bit_string(req.body)) + }) + |> result.unwrap( + response.new(400) + |> mist.empty_response, + ) +} +``` + +You might also want to use SSL. You can do that with the following options. + +With `run_service_ssl`: + +```gleam +import gleam/bit_builder +import gleam/erlang/process +import gleam/http/response +import mist + +pub fn main() { + let assert Ok(_) = + mist.run_service_ssl( + port: 8080, + certfile: "/path/to/server.crt", + keyfile: "/path/to/server.key", + handler: fn(_req) { + response.new(200) + |> response.set_body(bit_builder.from_bit_string(<< + "hello, world!":utf8, + >>)) + }, + max_body_limit: 4_000_000 + ) + process.sleep_forever() +} +``` + +With `serve_ssl`: + +```gleam +pub fn main() { + let assert Ok(_) = + mist.serve_ssl( + port: 8080, + certfile: "...", + keyfile: "...", + mist.handler_func(fn(req) { + todo + } + ) + // ... +} +``` + +There is support for sending files as well. This uses the `file:sendfile` erlang +method under the hood. + +```gleam +import gleam/bit_builder +import gleam/erlang/process +import gleam/http/request.{Request} +import gleam/http/response +import gleam/string +import mist + +pub fn main() { + let asset_root = "..." + let assert Ok(_) = + mist.serve( + 8080, + mist.handler_func(fn(req: Request(Body)) { + let not_found = + response.new(404) + |> mist.empty_response + case request.path_segments(req) { + ["static", ..path] -> { + // verify, validate, etc + let file_path = + path + |> string.join("/") + |> string.append("/", _) + response.new(200) + |> mist.file_response(asset_root <> file_path) + |> result.unwrap(not_found) + } + _ -> not_found + } + }), + ) + process.sleep_forever() +} +``` + +You can return chunked responses using the `mist.{chunked_response}` method. +This takes an `Iterator(BitBuilder)` and handles sending the initial +response, and subsequent chunks in the proper format as they are emitted from +the iterator. The iterator must be finite. + +If you need something a little more complex or custom, you can always use the +helpers exported by the various `glisten`/`mist` modules. + +## Benchmarks + +These are currently located [here](https://github.com/rawhat/http-benchmarks) diff --git a/test-community-packages-javascript/build/packages/mist/gleam.toml b/test-community-packages-javascript/build/packages/mist/gleam.toml new file mode 100644 index 00000000000..91c326f0ca4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/gleam.toml @@ -0,0 +1,17 @@ +name = "mist" +version = "0.11.0" + +licences = ["Apache-2.0"] +description = "a misty Gleam web server" +repository = { type = "github", user = "rawhat", repo = "mist" } + +[dependencies] +gleam_stdlib = "~> 0.28" +gleam_erlang = "~> 0.18" +gleam_http = "~> 3.2" +gleam_otp = "~> 0.5" +glisten = "~> 0.7" + +[dev-dependencies] +gleeunit = "~> 0.10" +gleam_hackney = "~> 1.0" diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl new file mode 100644 index 00000000000..c49d5eace0b --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl @@ -0,0 +1,3 @@ +-record(response, { + response :: gleam@http@response:response(mist@internal@http:http_response_body()) +}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl new file mode 100644 index 00000000000..4dc61ad70a9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl @@ -0,0 +1,4 @@ +-record(state, { + idle_timer :: gleam@option:option(gleam@erlang@process:timer()), + upgraded_handler :: gleam@option:option(mist@internal@websocket:websocket_handler()) +}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl new file mode 100644 index 00000000000..95dd5e515b9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl @@ -0,0 +1 @@ +-record(buffer, {remaining :: integer(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl new file mode 100644 index 00000000000..ce21939a44f --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl @@ -0,0 +1,6 @@ +-record(file_body, { + file_descriptor :: mist@internal@file:file_descriptor(), + content_type :: binary(), + offset :: integer(), + length :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl new file mode 100644 index 00000000000..b58f506cc3a --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl @@ -0,0 +1 @@ +-record(read, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl new file mode 100644 index 00000000000..204cebd84f7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl @@ -0,0 +1 @@ +-record(unread, {rest :: bitstring(), socket :: glisten@socket:socket()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl new file mode 100644 index 00000000000..4d0a2f59f4a --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl @@ -0,0 +1 @@ +-record(binary_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl new file mode 100644 index 00000000000..f44c5b4e905 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl @@ -0,0 +1 @@ +-record(binary_message, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl new file mode 100644 index 00000000000..ec07ce26727 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl @@ -0,0 +1 @@ +-record(close_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl new file mode 100644 index 00000000000..eb73aeab1f8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl @@ -0,0 +1 @@ +-record(ping_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl new file mode 100644 index 00000000000..c55a2aa1fc9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl @@ -0,0 +1 @@ +-record(pong_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl new file mode 100644 index 00000000000..25def5fbb71 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl @@ -0,0 +1 @@ +-record(text_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl new file mode 100644 index 00000000000..c4cf5176528 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl @@ -0,0 +1 @@ +-record(text_message, {data :: binary()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl new file mode 100644 index 00000000000..00dd595dba4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl @@ -0,0 +1,7 @@ +-record(websocket_handler, { + on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + handler :: fun((mist@internal@websocket:message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, + nil} | + {error, nil}) +}). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.app.src b/test-community-packages-javascript/build/packages/mist/src/mist.app.src new file mode 100644 index 00000000000..9cd4bf452a0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist.app.src @@ -0,0 +1,20 @@ +{application, mist, [ + {vsn, "0.11.0"}, + {applications, [gleam_erlang, + gleam_hackney, + gleam_http, + gleam_otp, + gleam_stdlib, + gleeunit, + glisten]}, + {description, "a misty Gleam web server"}, + {modules, [mist, + mist@internal@encoder, + mist@internal@file, + mist@internal@handler, + mist@internal@http, + mist@internal@logger, + mist@internal@websocket, + mist@websocket]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.erl b/test-community-packages-javascript/build/packages/mist/src/mist.erl new file mode 100644 index 00000000000..c5e34db8e56 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist.erl @@ -0,0 +1,116 @@ +-module(mist). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([run_service/3, run_service_ssl/5, serve/2, serve_ssl/4, handler_func/1, read_body/1, upgrade/1, empty_response/1, bit_builder_response/2, file_response/3, chunked_response/2]). + +-spec run_service( + integer(), + fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), + integer() +) -> {ok, nil} | {error, glisten:start_error()}. +run_service(Port, Handler, Max_body_limit) -> + _pipe = Handler, + _pipe@1 = mist@internal@handler:with(_pipe, Max_body_limit), + _pipe@2 = glisten@acceptor:new_pool_with_data( + _pipe@1, + mist@internal@handler:new_state() + ), + glisten:serve(Port, _pipe@2). + +-spec run_service_ssl( + integer(), + binary(), + binary(), + fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), + integer() +) -> {ok, nil} | {error, glisten:start_error()}. +run_service_ssl(Port, Certfile, Keyfile, Handler, Max_body_limit) -> + _pipe = Handler, + _pipe@1 = mist@internal@handler:with(_pipe, Max_body_limit), + _pipe@2 = glisten@acceptor:new_pool_with_data( + _pipe@1, + mist@internal@handler:new_state() + ), + glisten:serve_ssl(Port, Certfile, Keyfile, _pipe@2). + +-spec serve( + integer(), + fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))) +) -> {ok, nil} | {error, glisten:start_error()}. +serve(Port, Handler) -> + _pipe = Handler, + _pipe@1 = glisten@acceptor:new_pool_with_data( + _pipe, + mist@internal@handler:new_state() + ), + glisten:serve(Port, _pipe@1). + +-spec serve_ssl( + integer(), + binary(), + binary(), + fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))) +) -> {ok, nil} | {error, glisten:start_error()}. +serve_ssl(Port, Certfile, Keyfile, Handler) -> + _pipe = Handler, + _pipe@1 = glisten@acceptor:new_pool_with_data( + _pipe, + mist@internal@handler:new_state() + ), + glisten:serve_ssl(Port, Certfile, Keyfile, _pipe@1). + +-spec handler_func( + fun((gleam@http@request:request(mist@internal@http:body())) -> mist@internal@handler:handler_response()) +) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))). +handler_func(Handler) -> + mist@internal@handler:with_func(Handler). + +-spec read_body(gleam@http@request:request(mist@internal@http:body())) -> {ok, + gleam@http@request:request(bitstring())} | + {error, mist@internal@http:decode_error()}. +read_body(Req) -> + mist@internal@http:read_body(Req). + +-spec upgrade(mist@internal@websocket:websocket_handler()) -> mist@internal@handler:handler_response(). +upgrade(Websocket_handler) -> + {upgrade, Websocket_handler}. + +-spec empty_response(gleam@http@response:response(any())) -> mist@internal@handler:handler_response(). +empty_response(Resp) -> + _pipe = Resp, + _pipe@1 = gleam@http@response:set_body( + _pipe, + {bit_builder_body, gleam@bit_builder:new()} + ), + {response, _pipe@1}. + +-spec bit_builder_response( + gleam@http@response:response(any()), + gleam@bit_builder:bit_builder() +) -> mist@internal@handler:handler_response(). +bit_builder_response(Resp, Data) -> + _pipe = Resp, + _pipe@1 = gleam@http@response:set_body(_pipe, {bit_builder_body, Data}), + {response, _pipe@1}. + +-spec file_response(gleam@http@response:response(any()), binary(), binary()) -> {ok, + mist@internal@handler:handler_response()} | + {error, mist@internal@file:file_error()}. +file_response(Resp, Path, Content_type) -> + File_path = gleam@bit_string:from_string(Path), + Size = filelib:file_size(File_path), + gleam@result:map(mist_ffi:file_open(File_path), fun(Fd) -> _pipe = Resp, + _pipe@1 = gleam@http@response:set_body( + _pipe, + {file_body, Fd, Content_type, 0, Size} + ), + {response, _pipe@1} end). + +-spec chunked_response( + gleam@http@response:response(any()), + gleam@iterator:iterator(gleam@bit_builder:bit_builder()) +) -> mist@internal@handler:handler_response(). +chunked_response(Resp, Iter) -> + _pipe = Resp, + _pipe@1 = gleam@http@response:set_body(_pipe, {chunked, Iter}), + {response, _pipe@1}. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.gleam b/test-community-packages-javascript/build/packages/mist/src/mist.gleam new file mode 100644 index 00000000000..62dd7e18ec8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist.gleam @@ -0,0 +1,165 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/bit_string +import gleam/http/request.{Request} +import gleam/http/response.{Response as HttpResponse} +import gleam/iterator.{Iterator} +import gleam/result +import glisten +import glisten/acceptor +import glisten/handler.{LoopFn} as glisten_handler +import mist/internal/handler.{ + HandlerResponse, Response as MistResponse, State, Upgrade, +} +import mist/internal/http.{BitBuilderBody, Body as HTTPBody, Chunked, FileBody} +import mist/internal/file.{FileError} +import mist/internal/websocket.{WebsocketHandler} + +/// This type reflects whether the body has been read from the socket yet. +pub type Body = + HTTPBody + +/// Mist supports `BitBuilder`, `FileBody`, and `Chunked` response types. The +/// helper methods provided can generate these from a `gleam/http/response` +/// Response. This type is re-exported for pulling specific handlers out into +/// separate functions. +pub type Response = + HandlerResponse + +/// Runs an HTTP Request->Response server at the given port, with your defined +/// handler. This will automatically read the full body contents up to the +/// specified `max_body_limit` in bytes. If you'd prefer to have finer-grain +/// control over this behavior, consider using `mist.serve`. +pub fn run_service( + port: Int, + handler: handler.Handler, + max_body_limit max_body_limit: Int, +) -> Result(Nil, glisten.StartError) { + handler + |> handler.with(max_body_limit) + |> acceptor.new_pool_with_data(handler.new_state()) + |> glisten.serve(port, _) +} + +/// Similar setup and behavior to `run_service`, but instead takes in the SSL +/// certificate/key and serves over HTTPS. +pub fn run_service_ssl( + port port: Int, + certfile certfile: String, + keyfile keyfile: String, + handler handler: handler.Handler, + max_body_limit max_body_limit: Int, +) -> Result(Nil, glisten.StartError) { + handler + |> handler.with(max_body_limit) + |> acceptor.new_pool_with_data(handler.new_state()) + |> glisten.serve_ssl( + port: port, + certfile: certfile, + keyfile: keyfile, + with_pool: _, + ) +} + +/// Slightly more flexible alternative to `run_service`. This allows hooking +/// into the `mist.handler_func` method. Note that the request body +/// will not be automatically read. You will need to call `mist.read_body`. +/// Ensure that this is only called _once_ per request. +pub fn serve( + port port: Int, + handler handler: LoopFn(State), +) -> Result(Nil, glisten.StartError) { + handler + |> acceptor.new_pool_with_data(handler.new_state()) + |> glisten.serve(port, _) +} + +/// Similar to the `run_service` method, `serve` also has a similar SSL method. +pub fn serve_ssl( + port port: Int, + certfile certfile: String, + keyfile keyfile: String, + handler handler: LoopFn(State), +) -> Result(Nil, glisten.StartError) { + handler + |> acceptor.new_pool_with_data(handler.new_state()) + |> glisten.serve_ssl( + port: port, + certfile: certfile, + keyfile: keyfile, + with_pool: _, + ) +} + +/// Handles converting the mist `Response` type into a gleam HTTP Response. Use +/// this when calling `mist.serve` to start your application. +pub fn handler_func( + handler: handler.HandlerFunc, +) -> glisten_handler.LoopFn(handler.State) { + handler.with_func(handler) +} + +/// When using `mist.serve`, the body is not automatically read. You can +/// inspect content headers to determine whether to read the body or not. +/// This function will pull the content from the sender. It gives back a +/// `Request(BitString)` containing the body. This return value should be +/// treated as replacing the initial request. Do not attempt to call this +/// method multiple times on the same request. +pub fn read_body( + req: Request(Body), +) -> Result(Request(BitString), http.DecodeError) { + http.read_body(req) +} + +/// A websocket handler is created using the `websocket.with_handler` +/// method. This function enables the mist HTTP layer to build the properly +/// formatted websocket upgrade response. +pub fn upgrade(websocket_handler: WebsocketHandler) -> Response { + Upgrade(websocket_handler) +} + +/// `mist.serve` expects the mist Response type, rather than the `gleam/http` +/// Response. When returning a response with no body, this will convert the +/// type. Note that any previously set response body will be removed before +/// sending. +pub fn empty_response(resp: HttpResponse(a)) -> Response { + resp + |> response.set_body(BitBuilderBody(bit_builder.new())) + |> MistResponse +} + +/// The mist runtime only supports sending BitBuilder types, or files (see +/// below). This method will erase any pre-existing response body. +pub fn bit_builder_response(resp: HttpResponse(a), data: BitBuilder) -> Response { + resp + |> response.set_body(BitBuilderBody(data)) + |> MistResponse +} + +/// This is a more generally optimized method for returning files to a client. +/// It's a light wrapper around Erlang's `file:sendfile/5` method. The error +/// can be matched on with `mist/file.{FileError}` if custom behavior is desired +/// for various cases. The size of the file will be added to the +/// `content-length` header field. +pub fn file_response( + resp: HttpResponse(a), + path: String, + content_type: String, +) -> Result(Response, FileError) { + let file_path = bit_string.from_string(path) + let size = file.size(file_path) + use fd <- result.map(file.open(file_path)) + resp + |> response.set_body(FileBody(fd, content_type, 0, size)) + |> MistResponse +} + +/// You can send chunks of responses from an iterator. The iterator must +/// complete. +pub fn chunked_response( + resp: HttpResponse(a), + iter: Iterator(BitBuilder), +) -> Response { + resp + |> response.set_body(Chunked(iter)) + |> MistResponse +} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam new file mode 100644 index 00000000000..95e529ee6fc --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam @@ -0,0 +1,104 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/http.{Header} +import gleam/http/response.{Response} +import gleam/int +import gleam/list + +/// Turns an HTTP response into a TCP message +pub fn to_bit_builder(resp: Response(BitBuilder)) -> BitBuilder { + resp.status + |> response_builder(resp.headers) + |> bit_builder.append_builder(resp.body) +} + +pub fn response_builder(status: Int, headers: List(Header)) -> BitBuilder { + let status_string = + status + |> int.to_string + |> bit_builder.from_string + |> bit_builder.append(<<" ":utf8>>) + |> bit_builder.append(status_to_bit_string(status)) + + bit_builder.new() + |> bit_builder.append(<<"HTTP/1.1 ":utf8>>) + |> bit_builder.append_builder(status_string) + |> bit_builder.append(<<"\r\n":utf8>>) + |> bit_builder.append_builder(encode_headers(headers)) + |> bit_builder.append(<<"\r\n":utf8>>) +} + +pub fn status_to_bit_string(status: Int) -> BitString { + // Obviously nowhere near exhaustive... + case status { + 100 -> <<"Continue":utf8>> + 101 -> <<"Switching Protocols":utf8>> + 103 -> <<"Early Hints":utf8>> + 200 -> <<"OK":utf8>> + 201 -> <<"Created":utf8>> + 202 -> <<"Accepted":utf8>> + 203 -> <<"Non-Authoritative Information":utf8>> + 204 -> <<"No Content":utf8>> + 205 -> <<"Reset Content":utf8>> + 206 -> <<"Partial Content":utf8>> + 300 -> <<"Multiple Choices":utf8>> + 301 -> <<"Moved Permanently":utf8>> + 302 -> <<"Found":utf8>> + 303 -> <<"See Other":utf8>> + 304 -> <<"Not Modified":utf8>> + 307 -> <<"Temporary Redirect":utf8>> + 308 -> <<"Permanent Redirect":utf8>> + 400 -> <<"Bad Request":utf8>> + 401 -> <<"Unauthorized":utf8>> + 402 -> <<"Payment Required":utf8>> + 403 -> <<"Forbidden":utf8>> + 404 -> <<"Not Found":utf8>> + 405 -> <<"Method Not Allowed":utf8>> + 406 -> <<"Not Acceptable":utf8>> + 407 -> <<"Proxy Authentication Required":utf8>> + 408 -> <<"Request Timeout":utf8>> + 409 -> <<"Conflict":utf8>> + 410 -> <<"Gone":utf8>> + 411 -> <<"Length Required":utf8>> + 412 -> <<"Precondition Failed":utf8>> + 413 -> <<"Payload Too Large":utf8>> + 414 -> <<"URI Too Long":utf8>> + 415 -> <<"Unsupported Media Type":utf8>> + 416 -> <<"Range Not Satisfiable":utf8>> + 417 -> <<"Expectation Failed":utf8>> + 418 -> <<"I'm a teapot":utf8>> + 422 -> <<"Unprocessable Entity":utf8>> + 425 -> <<"Too Early":utf8>> + 426 -> <<"Upgrade Required":utf8>> + 428 -> <<"Precondition Required":utf8>> + 429 -> <<"Too Many Requests":utf8>> + 431 -> <<"Request Header Fields Too Large":utf8>> + 451 -> <<"Unavailable For Legal Reasons":utf8>> + 500 -> <<"Internal Server Error":utf8>> + 501 -> <<"Not Implemented":utf8>> + 502 -> <<"Bad Gateway":utf8>> + 503 -> <<"Service Unavailable":utf8>> + 504 -> <<"Gateway Timeout":utf8>> + 505 -> <<"HTTP Version Not Supported":utf8>> + 506 -> <<"Variant Also Negotiates":utf8>> + 507 -> <<"Insufficient Storage":utf8>> + 508 -> <<"Loop Detected":utf8>> + 510 -> <<"Not Extended":utf8>> + 511 -> <<"Network Authentication Required":utf8>> + } +} + +pub fn encode_headers(headers: List(Header)) -> BitBuilder { + list.fold( + headers, + bit_builder.new(), + fn(builder, tup) { + let #(header, value) = tup + + builder + |> bit_builder.append_string(header) + |> bit_builder.append(<<": ":utf8>>) + |> bit_builder.append_string(value) + |> bit_builder.append(<<"\r\n":utf8>>) + }, + ) +} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam new file mode 100644 index 00000000000..9783db1b2d0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam @@ -0,0 +1,26 @@ +import gleam/erlang/atom.{Atom} +import glisten/socket.{Socket} + +pub external type FileDescriptor + +pub external fn size(path: BitString) -> Int = + "filelib" "file_size" + +pub external fn sendfile( + file_descriptor: FileDescriptor, + socket: Socket, + offset: Int, + bytes: Int, + options: List(a), +) -> Result(Int, Atom) = + "file" "sendfile" + +pub type FileError { + IsDir + NoAccess + NoEntry + UnknownFileError +} + +pub external fn open(file: BitString) -> Result(FileDescriptor, FileError) = + "mist_ffi" "file_open" diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam new file mode 100644 index 00000000000..1f5ea1bbc78 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam @@ -0,0 +1,350 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/bit_string +import gleam/dynamic +import gleam/erlang.{Errored, Exited, Thrown, rescue} +import gleam/erlang/process +import gleam/http/request.{Request} +import gleam/http/response +import gleam/int +import gleam/iterator.{Iterator} +import gleam/option.{None, Option, Some} +import gleam/otp/actor +import gleam/result +import glisten/handler.{Close, LoopFn, LoopState} +import glisten/socket.{Socket} +import glisten/socket/transport.{Transport} +import mist/internal/encoder +import mist/internal/file +import mist/internal/http.{ + BitBuilderBody, Body, Chunked, DecodeError, DiscardPacket, FileBody, + HttpResponseBody, +} +import mist/internal/logger +import mist/internal/websocket + +pub type Handler = + fn(request.Request(BitString)) -> response.Response(BitBuilder) + +pub type HandlerResponse { + Response(response: response.Response(HttpResponseBody)) + Upgrade(websocket.WebsocketHandler) +} + +pub type HandlerFunc = + fn(Request(Body)) -> HandlerResponse + +pub type HandlerError { + InvalidRequest(DecodeError) + NotFound +} + +const stop_normal = actor.Stop(process.Normal) + +pub type State { + State( + idle_timer: Option(process.Timer), + upgraded_handler: Option(websocket.WebsocketHandler), + ) +} + +pub fn new_state() -> State { + State(None, None) +} + +/// This is a more flexible handler. It will allow you to upgrade a connection +/// to a websocket connection, or deal with a regular HTTP req->resp workflow. +pub fn with_func(handler: HandlerFunc) -> LoopFn(State) { + handler.func(fn(msg, socket_state: LoopState(State)) { + let LoopState(socket, transport: transport, data: state, ..) = socket_state + case state.upgraded_handler { + Some(ws_handler) -> + handle_websocket_message(socket_state, ws_handler, msg) + None -> + { + let _ = case state.idle_timer { + Some(t) -> process.cancel_timer(t) + _ -> process.TimerNotFound + } + msg + |> http.parse_request(socket, transport) + |> result.map_error(fn(err) { + case err { + DiscardPacket -> Nil + _ -> { + logger.error(err) + let _ = transport.close(socket) + Nil + } + } + }) + |> result.replace_error(stop_normal) + |> result.then(fn(req) { + rescue(fn() { handler(req) }) + |> result.map(fn(resp) { #(req, resp) }) + |> result.map_error(log_and_error( + _, + socket_state.socket, + socket_state.transport, + )) + }) + |> result.map(fn(req_resp) { + let #(req, response) = req_resp + case response { + Response( + response: response.Response(body: BitBuilderBody(body), ..) as resp, + ) -> handle_bit_builder_body(resp, body, socket_state) + Response( + response: response.Response(body: Chunked(body), ..) as resp, + ) -> handle_chunked_body(resp, body, socket_state) + Response( + response: response.Response(body: FileBody(..), ..) as resp, + ) -> handle_file_body(resp, socket_state) + Upgrade(with_handler) -> + handle_upgrade(req, with_handler, socket_state) + } + }) + } + |> result.unwrap_both + } + }) +} + +fn handle_websocket_message( + state: LoopState(State), + handler: websocket.WebsocketHandler, + msg: BitString, +) -> actor.Next(LoopState(State)) { + case websocket.frame_from_message(state.socket, state.transport, msg) { + Ok(websocket.PingFrame(_, _)) -> { + let assert Ok(_) = + state.transport.send( + state.socket, + websocket.frame_to_bit_builder(websocket.PongFrame(0, <<>>)), + ) + actor.Continue(state) + } + Ok(websocket.CloseFrame(..) as frame) -> { + let assert Ok(_) = + state.transport.send( + state.socket, + websocket.frame_to_bit_builder(frame), + ) + let _ = case handler.on_close { + Some(func) -> func(state.sender) + _ -> Nil + } + actor.Stop(process.Normal) + } + Ok(websocket.PongFrame(..)) -> stop_normal + Ok(frame) -> + case frame { + websocket.TextFrame(_length, payload) -> { + let assert Ok(msg) = bit_string.to_string(payload) + websocket.TextMessage(msg) + } + // NOTE: this doesn't need to be exhaustive since we already + // cover the cases above + _frame -> websocket.BinaryMessage(frame.payload) + } + |> fn(ws_msg) { rescue(fn() { handler.handler(ws_msg, state.sender) }) } + |> result.replace(actor.Continue(state)) + |> result.map_error(fn(err) { + logger.error(err) + let _ = case handler.on_close { + Some(func) -> func(state.sender) + _ -> Nil + } + err + }) + |> result.replace_error(stop_normal) + |> result.unwrap_both + Error(_) -> { + let _ = case handler.on_close { + Some(func) -> func(state.sender) + _ -> Nil + } + // TODO: not normal + stop_normal + } + } +} + +fn log_and_error( + error: erlang.Crash, + socket: Socket, + transport: Transport, +) -> actor.Next(LoopState(State)) { + case error { + Exited(msg) | Thrown(msg) | Errored(msg) -> { + logger.error(error) + response.new(500) + |> response.set_body(bit_builder.from_bit_string(<< + "Internal Server Error":utf8, + >>)) + |> response.prepend_header("content-length", "21") + |> http.add_default_headers + |> encoder.to_bit_builder + |> transport.send(socket, _) + let _ = transport.close(socket) + actor.Stop(process.Abnormal(dynamic.unsafe_coerce(msg))) + } + } +} + +fn handle_bit_builder_body( + resp: response.Response(HttpResponseBody), + body: BitBuilder, + state: LoopState(State), +) -> actor.Next(LoopState(State)) { + resp + |> response.set_body(body) + |> http.add_default_headers + |> encoder.to_bit_builder + |> state.transport.send(state.socket, _) + |> result.map(fn(_sent) { + // If the handler explicitly says to close the connection, we should + // probably listen to them + case response.get_header(resp, "connection") { + Ok("close") -> { + let _ = state.transport.close(state.socket) + stop_normal + } + _ -> { + // TODO: this should be a configuration + let timer = process.send_after(state.sender, 10_000, Close) + actor.Continue( + LoopState(..state, data: State(..state.data, idle_timer: Some(timer))), + ) + } + } + }) + |> result.replace_error(stop_normal) + |> result.unwrap_both +} + +external fn integer_to_list(int: Int, base: Int) -> String = + "erlang" "integer_to_list" + +fn int_to_hex(int: Int) -> String { + integer_to_list(int, 16) +} + +fn handle_chunked_body( + resp: response.Response(HttpResponseBody), + body: Iterator(BitBuilder), + state: LoopState(State), +) -> actor.Next(LoopState(State)) { + let headers = [#("transfer-encoding", "chunked"), ..resp.headers] + let initial_payload = encoder.response_builder(resp.status, headers) + + state.transport.send(state.socket, initial_payload) + |> result.then(fn(_ok) { + body + |> iterator.append(iterator.from_list([bit_builder.new()])) + |> iterator.try_fold( + Nil, + fn(_prev, chunk) { + let size = bit_builder.byte_size(chunk) + let encoded = + size + |> int_to_hex + |> bit_builder.from_string + |> bit_builder.append_string("\r\n") + |> bit_builder.append_builder(chunk) + |> bit_builder.append_string("\r\n") + + state.transport.send(state.socket, encoded) + }, + ) + }) + |> result.replace(actor.Continue(state)) + |> result.unwrap(stop_normal) +} + +fn handle_file_body( + resp: response.Response(HttpResponseBody), + state: LoopState(State), +) -> actor.Next(LoopState(State)) { + let assert FileBody(file_descriptor, content_type, offset, length) = resp.body + resp + |> response.prepend_header("content-length", int.to_string(length - offset)) + |> response.prepend_header("content-type", content_type) + |> response.set_body(bit_builder.new()) + |> fn(r: response.Response(BitBuilder)) { + encoder.response_builder(resp.status, r.headers) + } + |> state.transport.send(state.socket, _) + |> result.map(fn(_) { + file.sendfile(file_descriptor, state.socket, offset, length, []) + }) + |> result.replace(actor.Continue(state)) + // TODO: not normal + |> result.replace_error(stop_normal) + |> result.unwrap_both +} + +fn handle_upgrade( + req: Request(Body), + handler: websocket.WebsocketHandler, + state: LoopState(State), +) -> actor.Next(LoopState(State)) { + req + |> http.upgrade(state.socket, state.transport, _) + |> result.map(fn(_nil) { + let _ = case handler.on_init { + Some(func) -> func(state.sender) + _ -> Nil + } + }) + |> result.replace(actor.Continue( + LoopState( + ..state, + data: State(..state.data, upgraded_handler: Some(handler)), + ), + )) + // TODO: not normal + |> result.replace_error(stop_normal) + |> result.unwrap_both +} + +/// Creates a standard HTTP handler service to pass to `mist.serve` +pub fn with(handler: Handler, max_body_limit: Int) -> LoopFn(State) { + let bad_request = + response.new(400) + |> response.set_body(bit_builder.new()) + with_func(fn(req) { + case + request.get_header(req, "content-length"), + request.get_header(req, "transfer-encoding") + { + Ok("0"), _ | Error(Nil), Error(Nil) -> + req + |> request.set_body(<<>>) + |> handler + _, Ok("chunked") -> + req + |> http.read_body + |> result.map(handler) + |> result.unwrap(bad_request) + Ok(size), _ -> + size + |> int.parse + |> result.map(fn(size) { + case size > max_body_limit { + True -> + response.new(413) + |> response.set_body(bit_builder.new()) + |> response.prepend_header("connection", "close") + False -> + req + |> http.read_body + |> result.map(handler) + |> result.unwrap(bad_request) + } + }) + |> result.unwrap(bad_request) + } + |> response.map(BitBuilderBody) + |> Response + }) +} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam new file mode 100644 index 00000000000..c845487a3a8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam @@ -0,0 +1,393 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/bit_string +import gleam/dynamic.{Dynamic} +import gleam/erlang/atom.{Atom} +import gleam/erlang/charlist.{Charlist} +import gleam/http/request.{Request} +import gleam/http/response.{Response} +import gleam/http +import gleam/int +import gleam/iterator.{Iterator} +import gleam/list +import gleam/map.{Map} +import gleam/option.{Option} +import gleam/pair +import gleam/result +import gleam/string +import gleam/uri +import glisten/socket.{Socket} +import glisten/socket/transport.{Transport} +import mist/internal/encoder +import mist/internal/file +import mist/internal/websocket + +pub type PacketType { + Http + HttphBin + HttpBin +} + +pub type HttpUri { + AbsPath(BitString) +} + +pub type HttpPacket { + HttpRequest(Dynamic, HttpUri, #(Int, Int)) + HttpHeader(Int, Atom, BitString, BitString) +} + +pub type DecodedPacket { + BinaryData(HttpPacket, BitString) + EndOfHeaders(BitString) + MoreData(Option(Int)) +} + +pub type DecodeError { + MalformedRequest + InvalidMethod + InvalidPath + UnknownHeader + UnknownMethod + // TODO: better name? + InvalidBody + DiscardPacket +} + +external fn decode_packet( + packet_type: PacketType, + packet: BitString, + options: List(a), +) -> Result(DecodedPacket, DecodeError) = + "mist_ffi" "decode_packet" + +pub fn from_header(value: BitString) -> String { + let assert Ok(value) = bit_string.to_string(value) + + string.lowercase(value) +} + +pub type Buffer { + Buffer(remaining: Int, data: BitString) +} + +pub fn parse_headers( + bs: BitString, + socket: Socket, + transport: Transport, + headers: Map(String, String), +) -> Result(#(Map(String, String), BitString), DecodeError) { + case decode_packet(HttphBin, bs, []) { + Ok(BinaryData(HttpHeader(_, _field, field, value), rest)) -> { + let field = from_header(field) + let assert Ok(value) = bit_string.to_string(value) + headers + |> map.insert(field, value) + |> parse_headers(rest, socket, transport, _) + } + Ok(EndOfHeaders(rest)) -> Ok(#(headers, rest)) + Ok(MoreData(size)) -> { + let amount_to_read = option.unwrap(size, 0) + use next <- result.then(read_data( + socket, + transport, + Buffer(amount_to_read, bs), + UnknownHeader, + )) + parse_headers(next, socket, transport, headers) + } + _other -> Error(UnknownHeader) + } +} + +pub fn read_data( + socket: Socket, + transport: Transport, + buffer: Buffer, + error: DecodeError, +) -> Result(BitString, DecodeError) { + // TODO: don't hard-code these, probably + let to_read = int.min(buffer.remaining, 1_000_000) + let timeout = 15_000 + use data <- result.then( + socket + |> transport.receive_timeout(to_read, timeout) + |> result.replace_error(error), + ) + let next_buffer = + Buffer( + remaining: buffer.remaining - to_read, + data: <>, + ) + + case next_buffer.remaining > 0 { + True -> read_data(socket, transport, next_buffer, error) + False -> Ok(next_buffer.data) + } +} + +external fn binary_match( + source: BitString, + pattern: BitString, +) -> Result(#(Int, Int), Nil) = + "mist_ffi" "binary_match" + +external fn string_to_int(string: Charlist, base: Int) -> Result(Int, Nil) = + "mist_ffi" "string_to_int" + +const crnl = <<13:int, 10:int>> + +fn read_chunk( + socket: Socket, + transport: Transport, + buffer: Buffer, + body: BitBuilder, +) -> Result(BitBuilder, DecodeError) { + case buffer.data, binary_match(buffer.data, crnl) { + _, Ok(#(offset, _)) -> { + let assert << + chunk:binary-size(offset), + _return:int, + _newline:int, + rest:binary, + >> = buffer.data + use chunk_size <- result.then( + chunk + |> bit_string.to_string + |> result.map(charlist.from_string) + |> result.replace_error(InvalidBody), + ) + use size <- result.then( + string_to_int(chunk_size, 16) + |> result.replace_error(InvalidBody), + ) + case size { + 0 -> Ok(body) + size -> + case rest { + <> -> + read_chunk( + socket, + transport, + Buffer(0, rest), + bit_builder.append(body, next_chunk), + ) + _ -> { + use next <- result.then(read_data( + socket, + transport, + Buffer(0, buffer.data), + InvalidBody, + )) + read_chunk(socket, transport, Buffer(0, next), body) + } + } + } + } + <<>>, _ -> { + use next <- result.then(read_data( + socket, + transport, + Buffer(0, buffer.data), + InvalidBody, + )) + read_chunk(socket, transport, Buffer(0, next), body) + } + _, Error(Nil) -> Error(InvalidBody) + } +} + +/// Turns the TCP message into an HTTP request +pub fn parse_request( + bs: BitString, + socket: Socket, + transport: Transport, +) -> Result(request.Request(Body), DecodeError) { + case decode_packet(HttpBin, bs, []) { + Ok(BinaryData(HttpRequest(http_method, AbsPath(path), _version), rest)) -> { + use method <- result.then( + http_method + |> atom.from_dynamic + |> result.map(atom.to_string) + |> result.or(dynamic.string(http_method)) + |> result.nil_error + |> result.then(http.parse_method) + |> result.replace_error(UnknownMethod), + ) + use #(headers, rest) <- result.then(parse_headers( + rest, + socket, + transport, + map.new(), + )) + use path <- result.then( + path + |> bit_string.to_string + |> result.replace_error(InvalidPath), + ) + let #(path, query) = case string.split(path, "?") { + [path] -> #(path, []) + [path, query_string] -> { + let query = + query_string + |> uri.parse_query + |> result.unwrap([]) + #(path, query) + } + } + let req = + request.new() + |> request.set_scheme(case transport { + transport.Ssl(..) -> http.Https + transport.Tcp(..) -> http.Http + }) + |> request.set_body(Unread(rest, socket)) + |> request.set_method(method) + |> request.set_path(path) + |> request.set_query(query) + Ok(request.Request(..req, headers: map.to_list(headers))) + } + _ -> Error(DiscardPacket) + } +} + +pub opaque type Body { + Unread(rest: BitString, socket: Socket) + Read(data: BitString) +} + +pub fn read_body(req: Request(Body)) -> Result(Request(BitString), DecodeError) { + let transport = case req.scheme { + http.Https -> transport.ssl() + http.Http -> transport.tcp() + } + case request.get_header(req, "transfer-encoding"), req.body { + Ok("chunked"), Unread(rest, socket) -> { + use chunk <- result.then(read_chunk( + socket, + transport, + Buffer(remaining: 0, data: rest), + bit_builder.new(), + )) + Ok(request.set_body(req, bit_builder.to_bit_string(chunk))) + } + _, Unread(rest, socket) -> { + let _continue = case is_continue(req) { + True -> { + let assert Ok(Nil) = + response.new(100) + |> response.set_body(bit_builder.new()) + |> encoder.to_bit_builder + |> transport.send(socket, _) + Nil + } + False -> Nil + } + let body_size = + req.headers + |> list.find(fn(tup) { pair.first(tup) == "content-length" }) + |> result.map(pair.second) + |> result.then(int.parse) + |> result.unwrap(0) + let remaining = body_size - bit_string.byte_size(rest) + case body_size, remaining { + 0, 0 -> Ok(<<>>) + 0, _n -> Ok(rest) + // is this pipelining? check for GET? + _n, 0 -> Ok(rest) + _size, _rem -> + read_data(socket, transport, Buffer(remaining, rest), InvalidBody) + } + |> result.map(request.set_body(req, _)) + |> result.replace_error(InvalidBody) + } + _, Read(_data) -> Error(InvalidBody) + } +} + +pub type HttpResponseBody { + BitBuilderBody(BitBuilder) + Chunked(Iterator(BitBuilder)) + FileBody( + file_descriptor: file.FileDescriptor, + content_type: String, + offset: Int, + length: Int, + ) +} + +pub fn upgrade_socket( + req: Request(Body), +) -> Result(Response(BitBuilder), Request(Body)) { + use _upgrade <- result.then( + request.get_header(req, "upgrade") + |> result.replace_error(req), + ) + use key <- result.then( + request.get_header(req, "sec-websocket-key") + |> result.replace_error(req), + ) + use _version <- result.then( + request.get_header(req, "sec-websocket-version") + |> result.replace_error(req), + ) + + let accept_key = websocket.parse_key(key) + + response.new(101) + |> response.set_body(bit_builder.new()) + |> response.prepend_header("Upgrade", "websocket") + |> response.prepend_header("Connection", "Upgrade") + |> response.prepend_header("Sec-WebSocket-Accept", accept_key) + |> Ok +} + +// TODO: improve this error type +pub fn upgrade( + socket: Socket, + transport: Transport, + req: Request(Body), +) -> Result(Nil, Nil) { + use resp <- result.then( + upgrade_socket(req) + |> result.nil_error, + ) + + use _sent <- result.then( + resp + |> add_default_headers + |> encoder.to_bit_builder + |> transport.send(socket, _) + |> result.nil_error, + ) + + Ok(Nil) +} + +pub fn add_default_headers(resp: Response(BitBuilder)) -> Response(BitBuilder) { + let body_size = bit_builder.byte_size(resp.body) + + let headers = + map.from_list([ + #("content-length", int.to_string(body_size)), + #("connection", "keep-alive"), + ]) + |> list.fold( + resp.headers, + _, + fn(defaults, tup) { + let #(key, value) = tup + map.insert(defaults, key, value) + }, + ) + |> map.to_list + + Response(..resp, headers: headers) +} + +fn is_continue(req: Request(Body)) -> Bool { + req.headers + |> list.find(fn(tup) { + pair.first(tup) == "expect" && pair.second(tup) == "100-continue" + }) + |> result.is_ok +} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam new file mode 100644 index 00000000000..14a31a6ce54 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam @@ -0,0 +1,8 @@ +import gleam/erlang/charlist.{Charlist} + +external fn log_error(format: Charlist, data: any) -> Nil = + "logger" "error" + +pub fn error(data: any) -> Nil { + log_error(charlist.from_string("~tp"), [data]) +} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam new file mode 100644 index 00000000000..50318f2c6fe --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam @@ -0,0 +1,167 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/bit_string +import gleam/erlang/process.{Subject} +import gleam/list +import gleam/option.{Option} +import gleam/string +import glisten/handler.{HandlerMessage} +import glisten/socket.{Socket} +import glisten/socket/transport.{Transport} + +pub type Message { + BinaryMessage(data: BitString) + TextMessage(data: String) +} + +pub type Handler = + fn(Message, Subject(HandlerMessage)) -> Result(Nil, Nil) + +// TODO: there are other message types, AND ALSO will need to buffer across +// multiple frames, potentially +pub type Frame { + // TODO: should this include data? + CloseFrame(payload_length: Int, payload: BitString) + TextFrame(payload_length: Int, payload: BitString) + BinaryFrame(payload_length: Int, payload: BitString) + // We don't care about basicaly everything else for now + PingFrame(payload_length: Int, payload: BitString) + PongFrame(payload_length: Int, payload: BitString) +} + +external fn crypto_exor(a: BitString, b: BitString) -> BitString = + "crypto" "exor" + +fn unmask_data( + data: BitString, + masks: List(BitString), + index: Int, + resp: BitString, +) -> BitString { + case data { + <<>> -> resp + <> -> { + let assert Ok(mask_value) = list.at(masks, index % 4) + let unmasked = crypto_exor(mask_value, masked) + unmask_data( + rest, + masks, + index + 1, + <>, + ) + } + } +} + +pub fn frame_from_message( + socket: Socket, + transport: Transport, + message: BitString, +) -> Result(Frame, Nil) { + let assert <<_fin:1, rest:bit_string>> = message + let assert <<_reserved:3, rest:bit_string>> = rest + let assert <> = rest + case opcode { + 1 | 2 -> { + // mask + let assert <<1:1, rest:bit_string>> = rest + let assert <> = rest + let #(payload_length, rest) = case payload_length { + 126 -> { + let assert <> = rest + #(length, rest) + } + 127 -> { + let assert <> = rest + #(length, rest) + } + _ -> #(payload_length, rest) + } + let assert << + mask1:bit_string-size(8), + mask2:bit_string-size(8), + mask3:bit_string-size(8), + mask4:bit_string-size(8), + rest:bit_string, + >> = rest + let data = case payload_length - bit_string.byte_size(rest) { + 0 -> unmask_data(rest, [mask1, mask2, mask3, mask4], 0, <<>>) + need -> { + let assert Ok(needed) = transport.receive(socket, need) + rest + |> bit_string.append(needed) + |> unmask_data([mask1, mask2, mask3, mask4], 0, <<>>) + } + } + case opcode { + 1 -> TextFrame(payload_length, data) + 2 -> BinaryFrame(payload_length, data) + } + |> Ok + } + 8 -> Ok(CloseFrame(payload_length: 0, payload: <<>>)) + } +} + +pub fn frame_to_bit_builder(frame: Frame) -> BitBuilder { + case frame { + TextFrame(payload_length, payload) -> make_frame(1, payload_length, payload) + CloseFrame(payload_length, payload) -> + make_frame(8, payload_length, payload) + BinaryFrame(payload_length, payload) -> + make_frame(2, payload_length, payload) + PongFrame(payload_length, payload) -> + make_frame(10, payload_length, payload) + PingFrame(..) -> bit_builder.from_bit_string(<<>>) + } +} + +fn make_frame(opcode: Int, length: Int, payload: BitString) -> BitBuilder { + let length_section = case length { + length if length > 65_535 -> <<127:7, length:int-size(64)>> + length if length >= 126 -> <<126:7, length:int-size(16)>> + _length -> <> + } + + <<1:1, 0:3, opcode:4, 0:1, length_section:bit_string, payload:bit_string>> + |> bit_builder.from_bit_string +} + +pub fn to_text_frame(data: BitString) -> BitBuilder { + let size = bit_string.byte_size(data) + frame_to_bit_builder(TextFrame(size, data)) +} + +pub fn to_binary_frame(data: BitString) -> BitBuilder { + let size = bit_string.byte_size(data) + frame_to_bit_builder(BinaryFrame(size, data)) +} + +const websocket_key = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + +pub type ShaHash { + Sha +} + +pub external fn crypto_hash(hash: ShaHash, data: String) -> String = + "crypto" "hash" + +pub external fn base64_encode(data: String) -> String = + "base64" "encode" + +pub fn parse_key(key: String) -> String { + key + |> string.append(websocket_key) + |> crypto_hash(Sha, _) + |> base64_encode +} + +pub type EventHandler = + fn(Subject(HandlerMessage)) -> Nil + +pub type WebsocketHandler { + WebsocketHandler( + on_close: Option(EventHandler), + on_init: Option(EventHandler), + handler: Handler, + ) +} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam new file mode 100644 index 00000000000..4205bfe793d --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam @@ -0,0 +1,51 @@ +import gleam/bit_string +import gleam/erlang/process.{Subject} +import gleam/option.{None, Some} +import glisten/handler.{HandlerMessage, SendMessage} +import mist/internal/websocket.{ + BinaryMessage, EventHandler, Handler, Message, TextMessage, WebsocketHandler, + to_binary_frame, to_text_frame, +} + +/// Helper to encapsulate the logic to send a provided message over the +/// WebSocket +pub fn send(sender: Subject(HandlerMessage), message: Message) -> Nil { + case message { + TextMessage(data) -> + data + |> bit_string.from_string + |> to_text_frame + BinaryMessage(data) -> to_binary_frame(data) + } + |> SendMessage + |> process.send(sender, _) + + Nil +} + +pub fn echo_handler( + message: Message, + sender: Subject(HandlerMessage), +) -> Result(Nil, Nil) { + let _ = send(sender, message) + + Ok(Nil) +} + +pub fn with_handler(func: Handler) -> WebsocketHandler { + WebsocketHandler(on_close: None, on_init: None, handler: func) +} + +pub fn on_init( + handler: WebsocketHandler, + func: EventHandler, +) -> WebsocketHandler { + WebsocketHandler(..handler, on_init: Some(func)) +} + +pub fn on_close( + handler: WebsocketHandler, + func: EventHandler, +) -> WebsocketHandler { + WebsocketHandler(..handler, on_close: Some(func)) +} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl new file mode 100644 index 00000000000..78d65345b19 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl @@ -0,0 +1,209 @@ +-module(mist@internal@encoder). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([status_to_bit_string/1, encode_headers/1, response_builder/2, to_bit_builder/1]). + +-spec status_to_bit_string(integer()) -> bitstring(). +status_to_bit_string(Status) -> + case Status of + 100 -> + <<"Continue"/utf8>>; + + 101 -> + <<"Switching Protocols"/utf8>>; + + 103 -> + <<"Early Hints"/utf8>>; + + 200 -> + <<"OK"/utf8>>; + + 201 -> + <<"Created"/utf8>>; + + 202 -> + <<"Accepted"/utf8>>; + + 203 -> + <<"Non-Authoritative Information"/utf8>>; + + 204 -> + <<"No Content"/utf8>>; + + 205 -> + <<"Reset Content"/utf8>>; + + 206 -> + <<"Partial Content"/utf8>>; + + 300 -> + <<"Multiple Choices"/utf8>>; + + 301 -> + <<"Moved Permanently"/utf8>>; + + 302 -> + <<"Found"/utf8>>; + + 303 -> + <<"See Other"/utf8>>; + + 304 -> + <<"Not Modified"/utf8>>; + + 307 -> + <<"Temporary Redirect"/utf8>>; + + 308 -> + <<"Permanent Redirect"/utf8>>; + + 400 -> + <<"Bad Request"/utf8>>; + + 401 -> + <<"Unauthorized"/utf8>>; + + 402 -> + <<"Payment Required"/utf8>>; + + 403 -> + <<"Forbidden"/utf8>>; + + 404 -> + <<"Not Found"/utf8>>; + + 405 -> + <<"Method Not Allowed"/utf8>>; + + 406 -> + <<"Not Acceptable"/utf8>>; + + 407 -> + <<"Proxy Authentication Required"/utf8>>; + + 408 -> + <<"Request Timeout"/utf8>>; + + 409 -> + <<"Conflict"/utf8>>; + + 410 -> + <<"Gone"/utf8>>; + + 411 -> + <<"Length Required"/utf8>>; + + 412 -> + <<"Precondition Failed"/utf8>>; + + 413 -> + <<"Payload Too Large"/utf8>>; + + 414 -> + <<"URI Too Long"/utf8>>; + + 415 -> + <<"Unsupported Media Type"/utf8>>; + + 416 -> + <<"Range Not Satisfiable"/utf8>>; + + 417 -> + <<"Expectation Failed"/utf8>>; + + 418 -> + <<"I'm a teapot"/utf8>>; + + 422 -> + <<"Unprocessable Entity"/utf8>>; + + 425 -> + <<"Too Early"/utf8>>; + + 426 -> + <<"Upgrade Required"/utf8>>; + + 428 -> + <<"Precondition Required"/utf8>>; + + 429 -> + <<"Too Many Requests"/utf8>>; + + 431 -> + <<"Request Header Fields Too Large"/utf8>>; + + 451 -> + <<"Unavailable For Legal Reasons"/utf8>>; + + 500 -> + <<"Internal Server Error"/utf8>>; + + 501 -> + <<"Not Implemented"/utf8>>; + + 502 -> + <<"Bad Gateway"/utf8>>; + + 503 -> + <<"Service Unavailable"/utf8>>; + + 504 -> + <<"Gateway Timeout"/utf8>>; + + 505 -> + <<"HTTP Version Not Supported"/utf8>>; + + 506 -> + <<"Variant Also Negotiates"/utf8>>; + + 507 -> + <<"Insufficient Storage"/utf8>>; + + 508 -> + <<"Loop Detected"/utf8>>; + + 510 -> + <<"Not Extended"/utf8>>; + + 511 -> + <<"Network Authentication Required"/utf8>> + end. + +-spec encode_headers(list({binary(), binary()})) -> gleam@bit_builder:bit_builder(). +encode_headers(Headers) -> + gleam@list:fold( + Headers, + gleam@bit_builder:new(), + fun(Builder, Tup) -> + {Header, Value} = Tup, + _pipe = Builder, + _pipe@1 = gleam@bit_builder:append_string(_pipe, Header), + _pipe@2 = gleam@bit_builder:append(_pipe@1, <<": "/utf8>>), + _pipe@3 = gleam@bit_builder:append_string(_pipe@2, Value), + gleam@bit_builder:append(_pipe@3, <<"\r\n"/utf8>>) + end + ). + +-spec response_builder(integer(), list({binary(), binary()})) -> gleam@bit_builder:bit_builder(). +response_builder(Status, Headers) -> + Status_string = begin + _pipe = Status, + _pipe@1 = gleam@int:to_string(_pipe), + _pipe@2 = gleam@bit_builder:from_string(_pipe@1), + _pipe@3 = gleam@bit_builder:append(_pipe@2, <<" "/utf8>>), + gleam@bit_builder:append(_pipe@3, status_to_bit_string(Status)) + end, + _pipe@4 = gleam@bit_builder:new(), + _pipe@5 = gleam@bit_builder:append(_pipe@4, <<"HTTP/1.1 "/utf8>>), + _pipe@6 = gleam@bit_builder:append_builder(_pipe@5, Status_string), + _pipe@7 = gleam@bit_builder:append(_pipe@6, <<"\r\n"/utf8>>), + _pipe@8 = gleam@bit_builder:append_builder(_pipe@7, encode_headers(Headers)), + gleam@bit_builder:append(_pipe@8, <<"\r\n"/utf8>>). + +-spec to_bit_builder( + gleam@http@response:response(gleam@bit_builder:bit_builder()) +) -> gleam@bit_builder:bit_builder(). +to_bit_builder(Resp) -> + _pipe = erlang:element(2, Resp), + _pipe@1 = response_builder(_pipe, erlang:element(3, Resp)), + gleam@bit_builder:append_builder(_pipe@1, erlang:element(4, Resp)). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl new file mode 100644 index 00000000000..51bd02b0819 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl @@ -0,0 +1,27 @@ +-module(mist@internal@file). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([size/1, sendfile/5, open/1]). +-export_type([file_error/0, file_descriptor/0]). + +-type file_error() :: is_dir | no_access | no_entry | unknown_file_error. + +-type file_descriptor() :: any(). + +-spec size(bitstring()) -> integer(). +size(Field@0) -> + filelib:file_size(Field@0). + +-spec sendfile( + file_descriptor(), + glisten@socket:socket(), + integer(), + integer(), + list(any()) +) -> {ok, integer()} | {error, gleam@erlang@atom:atom_()}. +sendfile(Field@0, Field@1, Field@2, Field@3, Field@4) -> + file:sendfile(Field@0, Field@1, Field@2, Field@3, Field@4). + +-spec open(bitstring()) -> {ok, file_descriptor()} | {error, file_error()}. +open(Field@0) -> + mist_ffi:file_open(Field@0). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl new file mode 100644 index 00000000000..7b0afe0b615 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl @@ -0,0 +1,577 @@ +-module(mist@internal@handler). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new_state/0, with_func/1, with/2]). +-export_type([handler_response/0, handler_error/0, state/0]). + +-type handler_response() :: {response, + gleam@http@response:response(mist@internal@http:http_response_body())} | + {upgrade, mist@internal@websocket:websocket_handler()}. + +-type handler_error() :: {invalid_request, mist@internal@http:decode_error()} | + not_found. + +-type state() :: {state, + gleam@option:option(gleam@erlang@process:timer()), + gleam@option:option(mist@internal@websocket:websocket_handler())}. + +-spec new_state() -> state(). +new_state() -> + {state, none, none}. + +-spec handle_websocket_message( + glisten@handler:loop_state(state()), + mist@internal@websocket:websocket_handler(), + bitstring() +) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). +handle_websocket_message(State, Handler, Msg) -> + case mist@internal@websocket:frame_from_message( + erlang:element(2, State), + erlang:element(4, State), + Msg + ) of + {ok, {ping_frame, _, _}} -> + _assert_subject = (erlang:element(11, erlang:element(4, State)))( + erlang:element(2, State), + mist@internal@websocket:frame_to_bit_builder( + {pong_frame, 0, <<>>} + ) + ), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/handler"/utf8>>, + function => <<"handle_websocket_message"/utf8>>, + line => 119}) + end, + {continue, State}; + + {ok, {close_frame, _, _} = Frame} -> + _assert_subject@1 = (erlang:element(11, erlang:element(4, State)))( + erlang:element(2, State), + mist@internal@websocket:frame_to_bit_builder(Frame) + ), + {ok, _} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"mist/internal/handler"/utf8>>, + function => <<"handle_websocket_message"/utf8>>, + line => 127}) + end, + _ = case erlang:element(2, Handler) of + {some, Func} -> + Func(erlang:element(3, State)); + + _ -> + nil + end, + {stop, normal}; + + {ok, {pong_frame, _, _}} -> + {stop, normal}; + + {ok, Frame@1} -> + _pipe = case Frame@1 of + {text_frame, _, Payload} -> + _assert_subject@2 = gleam@bit_string:to_string(Payload), + {ok, Msg@1} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"mist/internal/handler"/utf8>>, + function => <<"handle_websocket_message"/utf8>>, + line => 142}) + end, + {text_message, Msg@1}; + + _ -> + {binary_message, erlang:element(3, Frame@1)} + end, + _pipe@1 = (fun(Ws_msg) -> + gleam_erlang_ffi:rescue( + fun() -> + (erlang:element(4, Handler))( + Ws_msg, + erlang:element(3, State) + ) + end + ) + end)(_pipe), + _pipe@2 = gleam@result:replace(_pipe@1, {continue, State}), + _pipe@3 = gleam@result:map_error( + _pipe@2, + fun(Err) -> + mist@internal@logger:error(Err), + _ = case erlang:element(2, Handler) of + {some, Func@1} -> + Func@1(erlang:element(3, State)); + + _ -> + nil + end, + Err + end + ), + _pipe@4 = gleam@result:replace_error(_pipe@3, {stop, normal}), + gleam@result:unwrap_both(_pipe@4); + + {error, _} -> + _ = case erlang:element(2, Handler) of + {some, Func@2} -> + Func@2(erlang:element(3, State)); + + _ -> + nil + end, + {stop, normal} + end. + +-spec log_and_error( + gleam@erlang:crash(), + glisten@socket:socket(), + glisten@socket@transport:transport() +) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). +log_and_error(Error, Socket, Transport) -> + case Error of + {exited, Msg} -> + mist@internal@logger:error(Error), + _pipe = gleam@http@response:new(500), + _pipe@1 = gleam@http@response:set_body( + _pipe, + gleam@bit_builder:from_bit_string( + <<"Internal Server Error"/utf8>> + ) + ), + _pipe@2 = gleam@http@response:prepend_header( + _pipe@1, + <<"content-length"/utf8>>, + <<"21"/utf8>> + ), + _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), + _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), + (erlang:element(11, Transport))(Socket, _pipe@4), + _ = (erlang:element(4, Transport))(Socket), + {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}}; + + {thrown, Msg} -> + mist@internal@logger:error(Error), + _pipe = gleam@http@response:new(500), + _pipe@1 = gleam@http@response:set_body( + _pipe, + gleam@bit_builder:from_bit_string( + <<"Internal Server Error"/utf8>> + ) + ), + _pipe@2 = gleam@http@response:prepend_header( + _pipe@1, + <<"content-length"/utf8>>, + <<"21"/utf8>> + ), + _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), + _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), + (erlang:element(11, Transport))(Socket, _pipe@4), + _ = (erlang:element(4, Transport))(Socket), + {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}}; + + {errored, Msg} -> + mist@internal@logger:error(Error), + _pipe = gleam@http@response:new(500), + _pipe@1 = gleam@http@response:set_body( + _pipe, + gleam@bit_builder:from_bit_string( + <<"Internal Server Error"/utf8>> + ) + ), + _pipe@2 = gleam@http@response:prepend_header( + _pipe@1, + <<"content-length"/utf8>>, + <<"21"/utf8>> + ), + _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), + _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), + (erlang:element(11, Transport))(Socket, _pipe@4), + _ = (erlang:element(4, Transport))(Socket), + {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}} + end. + +-spec handle_bit_builder_body( + gleam@http@response:response(mist@internal@http:http_response_body()), + gleam@bit_builder:bit_builder(), + glisten@handler:loop_state(state()) +) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). +handle_bit_builder_body(Resp, Body, State) -> + _pipe = Resp, + _pipe@1 = gleam@http@response:set_body(_pipe, Body), + _pipe@2 = mist@internal@http:add_default_headers(_pipe@1), + _pipe@3 = mist@internal@encoder:to_bit_builder(_pipe@2), + _pipe@4 = (erlang:element(11, erlang:element(4, State)))( + erlang:element(2, State), + _pipe@3 + ), + _pipe@5 = gleam@result:map( + _pipe@4, + fun(_) -> + case gleam@http@response:get_header(Resp, <<"connection"/utf8>>) of + {ok, <<"close"/utf8>>} -> + _ = (erlang:element(4, erlang:element(4, State)))( + erlang:element(2, State) + ), + {stop, normal}; + + _ -> + Timer = gleam@erlang@process:send_after( + erlang:element(3, State), + 10000, + close + ), + {continue, + erlang:setelement( + 5, + State, + erlang:setelement( + 2, + erlang:element(5, State), + {some, Timer} + ) + )} + end + end + ), + _pipe@6 = gleam@result:replace_error(_pipe@5, {stop, normal}), + gleam@result:unwrap_both(_pipe@6). + +-spec handle_file_body( + gleam@http@response:response(mist@internal@http:http_response_body()), + glisten@handler:loop_state(state()) +) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). +handle_file_body(Resp, State) -> + _assert_subject = erlang:element(4, Resp), + {file_body, File_descriptor, Content_type, Offset, Length} = case _assert_subject of + {file_body, _, _, _, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/handler"/utf8>>, + function => <<"handle_file_body"/utf8>>, + line => 268}) + end, + _pipe = Resp, + _pipe@1 = gleam@http@response:prepend_header( + _pipe, + <<"content-length"/utf8>>, + gleam@int:to_string(Length - Offset) + ), + _pipe@2 = gleam@http@response:prepend_header( + _pipe@1, + <<"content-type"/utf8>>, + Content_type + ), + _pipe@3 = gleam@http@response:set_body(_pipe@2, gleam@bit_builder:new()), + _pipe@4 = (fun(R) -> + mist@internal@encoder:response_builder( + erlang:element(2, Resp), + erlang:element(3, R) + ) + end)(_pipe@3), + _pipe@5 = (erlang:element(11, erlang:element(4, State)))( + erlang:element(2, State), + _pipe@4 + ), + _pipe@6 = gleam@result:map( + _pipe@5, + fun(_) -> + file:sendfile( + File_descriptor, + erlang:element(2, State), + Offset, + Length, + [] + ) + end + ), + _pipe@7 = gleam@result:replace(_pipe@6, {continue, State}), + _pipe@8 = gleam@result:replace_error(_pipe@7, {stop, normal}), + gleam@result:unwrap_both(_pipe@8). + +-spec handle_upgrade( + gleam@http@request:request(mist@internal@http:body()), + mist@internal@websocket:websocket_handler(), + glisten@handler:loop_state(state()) +) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). +handle_upgrade(Req, Handler, State) -> + _pipe = Req, + _pipe@1 = mist@internal@http:upgrade( + erlang:element(2, State), + erlang:element(4, State), + _pipe + ), + _pipe@2 = gleam@result:map( + _pipe@1, + fun(_) -> _ = case erlang:element(3, Handler) of + {some, Func} -> + Func(erlang:element(3, State)); + + _ -> + nil + end end + ), + _pipe@3 = gleam@result:replace( + _pipe@2, + {continue, + erlang:setelement( + 5, + State, + erlang:setelement(3, erlang:element(5, State), {some, Handler}) + )} + ), + _pipe@4 = gleam@result:replace_error(_pipe@3, {stop, normal}), + gleam@result:unwrap_both(_pipe@4). + +-spec int_to_hex(integer()) -> binary(). +int_to_hex(Int) -> + erlang:integer_to_list(Int, 16). + +-spec handle_chunked_body( + gleam@http@response:response(mist@internal@http:http_response_body()), + gleam@iterator:iterator(gleam@bit_builder:bit_builder()), + glisten@handler:loop_state(state()) +) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). +handle_chunked_body(Resp, Body, State) -> + Headers = [{<<"transfer-encoding"/utf8>>, <<"chunked"/utf8>>} | + erlang:element(3, Resp)], + Initial_payload = mist@internal@encoder:response_builder( + erlang:element(2, Resp), + Headers + ), + _pipe = (erlang:element(11, erlang:element(4, State)))( + erlang:element(2, State), + Initial_payload + ), + _pipe@8 = gleam@result:then(_pipe, fun(_) -> _pipe@1 = Body, + _pipe@2 = gleam@iterator:append( + _pipe@1, + gleam@iterator:from_list([gleam@bit_builder:new()]) + ), + gleam@iterator:try_fold( + _pipe@2, + nil, + fun(_, Chunk) -> + Size = gleam@bit_builder:byte_size(Chunk), + Encoded = begin + _pipe@3 = Size, + _pipe@4 = int_to_hex(_pipe@3), + _pipe@5 = gleam@bit_builder:from_string(_pipe@4), + _pipe@6 = gleam@bit_builder:append_string( + _pipe@5, + <<"\r\n"/utf8>> + ), + _pipe@7 = gleam@bit_builder:append_builder( + _pipe@6, + Chunk + ), + gleam@bit_builder:append_string( + _pipe@7, + <<"\r\n"/utf8>> + ) + end, + (erlang:element(11, erlang:element(4, State)))( + erlang:element(2, State), + Encoded + ) + end + ) end), + _pipe@9 = gleam@result:replace(_pipe@8, {continue, State}), + gleam@result:unwrap(_pipe@9, {stop, normal}). + +-spec with_func( + fun((gleam@http@request:request(mist@internal@http:body())) -> handler_response()) +) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(state())) -> gleam@otp@actor:next(glisten@handler:loop_state(state()))). +with_func(Handler) -> + glisten@handler:func( + fun(Msg, Socket_state) -> + {loop_state, Socket, _, Transport, State} = Socket_state, + case erlang:element(3, State) of + {some, Ws_handler} -> + handle_websocket_message(Socket_state, Ws_handler, Msg); + + none -> + _pipe@7 = begin + _ = case erlang:element(2, State) of + {some, T} -> + gleam@erlang@process:cancel_timer(T); + + _ -> + timer_not_found + end, + _pipe = Msg, + _pipe@1 = mist@internal@http:parse_request( + _pipe, + Socket, + Transport + ), + _pipe@2 = gleam@result:map_error( + _pipe@1, + fun(Err) -> case Err of + discard_packet -> + nil; + + _ -> + mist@internal@logger:error(Err), + _ = (erlang:element(4, Transport))( + Socket + ), + nil + end end + ), + _pipe@3 = gleam@result:replace_error( + _pipe@2, + {stop, normal} + ), + _pipe@6 = gleam@result:then( + _pipe@3, + fun(Req) -> + _pipe@4 = gleam_erlang_ffi:rescue( + fun() -> Handler(Req) end + ), + _pipe@5 = gleam@result:map( + _pipe@4, + fun(Resp) -> {Req, Resp} end + ), + gleam@result:map_error( + _pipe@5, + fun(_capture) -> + log_and_error( + _capture, + erlang:element(2, Socket_state), + erlang:element(4, Socket_state) + ) + end + ) + end + ), + gleam@result:map( + _pipe@6, + fun(Req_resp) -> + {Req@1, Response} = Req_resp, + case Response of + {response, + {response, + _, + _, + {bit_builder_body, Body}} = Resp@1} -> + handle_bit_builder_body( + Resp@1, + Body, + Socket_state + ); + + {response, + {response, _, _, {chunked, Body@1}} = Resp@2} -> + handle_chunked_body( + Resp@2, + Body@1, + Socket_state + ); + + {response, + {response, + _, + _, + {file_body, _, _, _, _}} = Resp@3} -> + handle_file_body(Resp@3, Socket_state); + + {upgrade, With_handler} -> + handle_upgrade( + Req@1, + With_handler, + Socket_state + ) + end + end + ) + end, + gleam@result:unwrap_both(_pipe@7) + end + end + ). + +-spec with( + fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), + integer() +) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(state())) -> gleam@otp@actor:next(glisten@handler:loop_state(state()))). +with(Handler, Max_body_limit) -> + Bad_request = begin + _pipe = gleam@http@response:new(400), + gleam@http@response:set_body(_pipe, gleam@bit_builder:new()) + end, + with_func( + fun(Req) -> + _pipe@14 = case {gleam@http@request:get_header( + Req, + <<"content-length"/utf8>> + ), + gleam@http@request:get_header(Req, <<"transfer-encoding"/utf8>>)} of + {{ok, <<"0"/utf8>>}, _} -> + _pipe@1 = Req, + _pipe@2 = gleam@http@request:set_body(_pipe@1, <<>>), + Handler(_pipe@2); + + {{error, nil}, {error, nil}} -> + _pipe@1 = Req, + _pipe@2 = gleam@http@request:set_body(_pipe@1, <<>>), + Handler(_pipe@2); + + {_, {ok, <<"chunked"/utf8>>}} -> + _pipe@3 = Req, + _pipe@4 = mist@internal@http:read_body(_pipe@3), + _pipe@5 = gleam@result:map(_pipe@4, Handler), + gleam@result:unwrap(_pipe@5, Bad_request); + + {{ok, Size}, _} -> + _pipe@6 = Size, + _pipe@7 = gleam@int:parse(_pipe@6), + _pipe@13 = gleam@result:map( + _pipe@7, + fun(Size@1) -> case Size@1 > Max_body_limit of + true -> + _pipe@8 = gleam@http@response:new(413), + _pipe@9 = gleam@http@response:set_body( + _pipe@8, + gleam@bit_builder:new() + ), + gleam@http@response:prepend_header( + _pipe@9, + <<"connection"/utf8>>, + <<"close"/utf8>> + ); + + false -> + _pipe@10 = Req, + _pipe@11 = mist@internal@http:read_body( + _pipe@10 + ), + _pipe@12 = gleam@result:map( + _pipe@11, + Handler + ), + gleam@result:unwrap(_pipe@12, Bad_request) + end end + ), + gleam@result:unwrap(_pipe@13, Bad_request) + end, + _pipe@15 = gleam@http@response:map( + _pipe@14, + fun(Field@0) -> {bit_builder_body, Field@0} end + ), + {response, _pipe@15} + end + ). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl new file mode 100644 index 00000000000..aad9e7db5c8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl @@ -0,0 +1,591 @@ +-module(mist@internal@http). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([from_header/1, upgrade_socket/1, add_default_headers/1, upgrade/3, parse_headers/4, parse_request/3, read_data/4, read_body/1]). +-export_type([packet_type/0, http_uri/0, http_packet/0, decoded_packet/0, decode_error/0, buffer/0, body/0, http_response_body/0]). + +-type packet_type() :: http | httph_bin | http_bin. + +-type http_uri() :: {abs_path, bitstring()}. + +-type http_packet() :: {http_request, + gleam@dynamic:dynamic(), + http_uri(), + {integer(), integer()}} | + {http_header, + integer(), + gleam@erlang@atom:atom_(), + bitstring(), + bitstring()}. + +-type decoded_packet() :: {binary_data, http_packet(), bitstring()} | + {end_of_headers, bitstring()} | + {more_data, gleam@option:option(integer())}. + +-type decode_error() :: malformed_request | + invalid_method | + invalid_path | + unknown_header | + unknown_method | + invalid_body | + discard_packet. + +-type buffer() :: {buffer, integer(), bitstring()}. + +-opaque body() :: {unread, bitstring(), glisten@socket:socket()} | + {read, bitstring()}. + +-type http_response_body() :: {bit_builder_body, + gleam@bit_builder:bit_builder()} | + {chunked, gleam@iterator:iterator(gleam@bit_builder:bit_builder())} | + {file_body, + mist@internal@file:file_descriptor(), + binary(), + integer(), + integer()}. + +-spec from_header(bitstring()) -> binary(). +from_header(Value) -> + _assert_subject = gleam@bit_string:to_string(Value), + {ok, Value@1} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/http"/utf8>>, + function => <<"from_header"/utf8>>, + line => 64}) + end, + gleam@string:lowercase(Value@1). + +-spec upgrade_socket(gleam@http@request:request(body())) -> {ok, + gleam@http@response:response(gleam@bit_builder:bit_builder())} | + {error, gleam@http@request:request(body())}. +upgrade_socket(Req) -> + gleam@result:then( + begin + _pipe = gleam@http@request:get_header(Req, <<"upgrade"/utf8>>), + gleam@result:replace_error(_pipe, Req) + end, + fun(_) -> + gleam@result:then( + begin + _pipe@1 = gleam@http@request:get_header( + Req, + <<"sec-websocket-key"/utf8>> + ), + gleam@result:replace_error(_pipe@1, Req) + end, + fun(Key) -> + gleam@result:then( + begin + _pipe@2 = gleam@http@request:get_header( + Req, + <<"sec-websocket-version"/utf8>> + ), + gleam@result:replace_error(_pipe@2, Req) + end, + fun(_) -> + Accept_key = mist@internal@websocket:parse_key(Key), + _pipe@3 = gleam@http@response:new(101), + _pipe@4 = gleam@http@response:set_body( + _pipe@3, + gleam@bit_builder:new() + ), + _pipe@5 = gleam@http@response:prepend_header( + _pipe@4, + <<"Upgrade"/utf8>>, + <<"websocket"/utf8>> + ), + _pipe@6 = gleam@http@response:prepend_header( + _pipe@5, + <<"Connection"/utf8>>, + <<"Upgrade"/utf8>> + ), + _pipe@7 = gleam@http@response:prepend_header( + _pipe@6, + <<"Sec-WebSocket-Accept"/utf8>>, + Accept_key + ), + {ok, _pipe@7} + end + ) + end + ) + end + ). + +-spec add_default_headers( + gleam@http@response:response(gleam@bit_builder:bit_builder()) +) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). +add_default_headers(Resp) -> + Body_size = gleam@bit_builder:byte_size(erlang:element(4, Resp)), + Headers = begin + _pipe = gleam@map:from_list( + [{<<"content-length"/utf8>>, gleam@int:to_string(Body_size)}, + {<<"connection"/utf8>>, <<"keep-alive"/utf8>>}] + ), + _pipe@1 = gleam@list:fold( + erlang:element(3, Resp), + _pipe, + fun(Defaults, Tup) -> + {Key, Value} = Tup, + gleam@map:insert(Defaults, Key, Value) + end + ), + gleam@map:to_list(_pipe@1) + end, + erlang:setelement(3, Resp, Headers). + +-spec upgrade( + glisten@socket:socket(), + glisten@socket@transport:transport(), + gleam@http@request:request(body()) +) -> {ok, nil} | {error, nil}. +upgrade(Socket, Transport, Req) -> + gleam@result:then( + begin + _pipe = upgrade_socket(Req), + gleam@result:nil_error(_pipe) + end, + fun(Resp) -> + gleam@result:then( + begin + _pipe@1 = Resp, + _pipe@2 = add_default_headers(_pipe@1), + _pipe@3 = mist@internal@encoder:to_bit_builder(_pipe@2), + _pipe@4 = (erlang:element(11, Transport))(Socket, _pipe@3), + gleam@result:nil_error(_pipe@4) + end, + fun(_) -> {ok, nil} end + ) + end + ). + +-spec is_continue(gleam@http@request:request(body())) -> boolean(). +is_continue(Req) -> + _pipe = erlang:element(3, Req), + _pipe@1 = gleam@list:find( + _pipe, + fun(Tup) -> + (gleam@pair:first(Tup) =:= <<"expect"/utf8>>) andalso (gleam@pair:second( + Tup + ) + =:= <<"100-continue"/utf8>>) + end + ), + gleam@result:is_ok(_pipe@1). + +-spec parse_headers( + bitstring(), + glisten@socket:socket(), + glisten@socket@transport:transport(), + gleam@map:map_(binary(), binary()) +) -> {ok, {gleam@map:map_(binary(), binary()), bitstring()}} | + {error, decode_error()}. +parse_headers(Bs, Socket, Transport, Headers) -> + case mist_ffi:decode_packet(httph_bin, Bs, []) of + {ok, {binary_data, {http_header, _, _, Field, Value}, Rest}} -> + Field@1 = from_header(Field), + _assert_subject = gleam@bit_string:to_string(Value), + {ok, Value@1} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/http"/utf8>>, + function => <<"parse_headers"/utf8>>, + line => 82}) + end, + _pipe = Headers, + _pipe@1 = gleam@map:insert(_pipe, Field@1, Value@1), + parse_headers(Rest, Socket, Transport, _pipe@1); + + {ok, {end_of_headers, Rest@1}} -> + {ok, {Headers, Rest@1}}; + + {ok, {more_data, Size}} -> + Amount_to_read = gleam@option:unwrap(Size, 0), + gleam@result:then( + read_data( + Socket, + Transport, + {buffer, Amount_to_read, Bs}, + unknown_header + ), + fun(Next) -> parse_headers(Next, Socket, Transport, Headers) end + ); + + _ -> + {error, unknown_header} + end. + +-spec parse_request( + bitstring(), + glisten@socket:socket(), + glisten@socket@transport:transport() +) -> {ok, gleam@http@request:request(body())} | {error, decode_error()}. +parse_request(Bs, Socket, Transport) -> + case mist_ffi:decode_packet(http_bin, Bs, []) of + {ok, + {binary_data, + {http_request, Http_method, {abs_path, Path}, _}, + Rest}} -> + gleam@result:then( + begin + _pipe = Http_method, + _pipe@1 = gleam_erlang_ffi:atom_from_dynamic(_pipe), + _pipe@2 = gleam@result:map( + _pipe@1, + fun gleam@erlang@atom:to_string/1 + ), + _pipe@3 = gleam@result:'or'( + _pipe@2, + gleam@dynamic:string(Http_method) + ), + _pipe@4 = gleam@result:nil_error(_pipe@3), + _pipe@5 = gleam@result:then( + _pipe@4, + fun gleam@http:parse_method/1 + ), + gleam@result:replace_error(_pipe@5, unknown_method) + end, + fun(Method) -> + gleam@result:then( + parse_headers(Rest, Socket, Transport, gleam@map:new()), + fun(_use0) -> + {Headers, Rest@1} = _use0, + gleam@result:then( + begin + _pipe@6 = Path, + _pipe@7 = gleam@bit_string:to_string( + _pipe@6 + ), + gleam@result:replace_error( + _pipe@7, + invalid_path + ) + end, + fun(Path@1) -> + {Path@4, Query@1} = case gleam@string:split( + Path@1, + <<"?"/utf8>> + ) of + [Path@2] -> + {Path@2, []}; + + [Path@3, Query_string] -> + Query = begin + _pipe@8 = Query_string, + _pipe@9 = gleam@uri:parse_query( + _pipe@8 + ), + gleam@result:unwrap(_pipe@9, []) + end, + {Path@3, Query} + end, + Req = begin + _pipe@10 = gleam@http@request:new(), + _pipe@11 = gleam@http@request:set_scheme( + _pipe@10, + case Transport of + {ssl, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _} -> + https; + + {tcp, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _, + _} -> + http + end + ), + _pipe@12 = gleam@http@request:set_body( + _pipe@11, + {unread, Rest@1, Socket} + ), + _pipe@13 = gleam@http@request:set_method( + _pipe@12, + Method + ), + _pipe@14 = gleam@http@request:set_path( + _pipe@13, + Path@4 + ), + gleam@http@request:set_query( + _pipe@14, + Query@1 + ) + end, + {ok, + erlang:setelement( + 3, + Req, + gleam@map:to_list(Headers) + )} + end + ) + end + ) + end + ); + + _ -> + {error, discard_packet} + end. + +-spec read_data( + glisten@socket:socket(), + glisten@socket@transport:transport(), + buffer(), + decode_error() +) -> {ok, bitstring()} | {error, decode_error()}. +read_data(Socket, Transport, Buffer, Error) -> + To_read = gleam@int:min(erlang:element(2, Buffer), 1000000), + Timeout = 15000, + gleam@result:then( + begin + _pipe = Socket, + _pipe@1 = (erlang:element(10, Transport))(_pipe, To_read, Timeout), + gleam@result:replace_error(_pipe@1, Error) + end, + fun(Data) -> + Next_buffer = {buffer, + erlang:element(2, Buffer) - To_read, + <<(erlang:element(3, Buffer))/bitstring, Data/bitstring>>}, + case erlang:element(2, Next_buffer) > 0 of + true -> + read_data(Socket, Transport, Next_buffer, Error); + + false -> + {ok, erlang:element(3, Next_buffer)} + end + end + ). + +-spec read_chunk( + glisten@socket:socket(), + glisten@socket@transport:transport(), + buffer(), + gleam@bit_builder:bit_builder() +) -> {ok, gleam@bit_builder:bit_builder()} | {error, decode_error()}. +read_chunk(Socket, Transport, Buffer, Body) -> + case {erlang:element(3, Buffer), + mist_ffi:binary_match( + erlang:element(3, Buffer), + <<13/integer, 10/integer>> + )} of + {_, {ok, {Offset, _}}} -> + _assert_subject = erlang:element(3, Buffer), + <> = case _assert_subject of + <<_:Offset/binary, _/integer, _/integer, _/binary>> -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/http"/utf8>>, + function => <<"read_chunk"/utf8>>, + line => 147}) + end, + gleam@result:then( + begin + _pipe = Chunk, + _pipe@1 = gleam@bit_string:to_string(_pipe), + _pipe@2 = gleam@result:map( + _pipe@1, + fun gleam@erlang@charlist:from_string/1 + ), + gleam@result:replace_error(_pipe@2, invalid_body) + end, + fun(Chunk_size) -> + gleam@result:then( + begin + _pipe@3 = mist_ffi:string_to_int(Chunk_size, 16), + gleam@result:replace_error(_pipe@3, invalid_body) + end, + fun(Size) -> case Size of + 0 -> + {ok, Body}; + + Size@1 -> + case Rest of + <> -> + read_chunk( + Socket, + Transport, + {buffer, 0, Rest@1}, + gleam@bit_builder:append( + Body, + Next_chunk + ) + ); + + _ -> + gleam@result:then( + read_data( + Socket, + Transport, + {buffer, + 0, + erlang:element( + 3, + Buffer + )}, + invalid_body + ), + fun(Next) -> + read_chunk( + Socket, + Transport, + {buffer, 0, Next}, + Body + ) + end + ) + end + end end + ) + end + ); + + {<<>>, _} -> + gleam@result:then( + read_data( + Socket, + Transport, + {buffer, 0, erlang:element(3, Buffer)}, + invalid_body + ), + fun(Next@1) -> + read_chunk(Socket, Transport, {buffer, 0, Next@1}, Body) + end + ); + + {_, {error, nil}} -> + {error, invalid_body} + end. + +-spec read_body(gleam@http@request:request(body())) -> {ok, + gleam@http@request:request(bitstring())} | + {error, decode_error()}. +read_body(Req) -> + Transport = case erlang:element(5, Req) of + https -> + glisten@socket@transport:ssl(); + + http -> + glisten@socket@transport:tcp() + end, + case {gleam@http@request:get_header(Req, <<"transfer-encoding"/utf8>>), + erlang:element(4, Req)} of + {{ok, <<"chunked"/utf8>>}, {unread, Rest, Socket}} -> + gleam@result:then( + read_chunk( + Socket, + Transport, + {buffer, 0, Rest}, + gleam@bit_builder:new() + ), + fun(Chunk) -> + {ok, + gleam@http@request:set_body( + Req, + gleam@bit_builder:to_bit_string(Chunk) + )} + end + ); + + {_, {unread, Rest@1, Socket@1}} -> + _ = case is_continue(Req) of + true -> + _assert_subject = begin + _pipe = gleam@http@response:new(100), + _pipe@1 = gleam@http@response:set_body( + _pipe, + gleam@bit_builder:new() + ), + _pipe@2 = mist@internal@encoder:to_bit_builder(_pipe@1), + (erlang:element(11, Transport))(Socket@1, _pipe@2) + end, + {ok, nil} = case _assert_subject of + {ok, nil} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/http"/utf8>>, + function => <<"read_body"/utf8>>, + line => 276}) + end, + nil; + + false -> + nil + end, + Body_size = begin + _pipe@3 = erlang:element(3, Req), + _pipe@4 = gleam@list:find( + _pipe@3, + fun(Tup) -> + gleam@pair:first(Tup) =:= <<"content-length"/utf8>> + end + ), + _pipe@5 = gleam@result:map(_pipe@4, fun gleam@pair:second/1), + _pipe@6 = gleam@result:then(_pipe@5, fun gleam@int:parse/1), + gleam@result:unwrap(_pipe@6, 0) + end, + Remaining = Body_size - gleam@bit_string:byte_size(Rest@1), + _pipe@7 = case {Body_size, Remaining} of + {0, 0} -> + {ok, <<>>}; + + {0, _} -> + {ok, Rest@1}; + + {_, 0} -> + {ok, Rest@1}; + + {_, _} -> + read_data( + Socket@1, + Transport, + {buffer, Remaining, Rest@1}, + invalid_body + ) + end, + _pipe@8 = gleam@result:map( + _pipe@7, + fun(_capture) -> gleam@http@request:set_body(Req, _capture) end + ), + gleam@result:replace_error(_pipe@8, invalid_body); + + {_, {read, _}} -> + {error, invalid_body} + end. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl new file mode 100644 index 00000000000..214e0870e63 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl @@ -0,0 +1,8 @@ +-module(mist@internal@logger). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([error/1]). + +-spec error(any()) -> nil. +error(Data) -> + logger:error(unicode:characters_to_list(<<"~tp"/utf8>>), [Data]). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl new file mode 100644 index 00000000000..c361892ff13 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl @@ -0,0 +1,359 @@ +-module(mist@internal@websocket). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([frame_to_bit_builder/1, to_text_frame/1, to_binary_frame/1, crypto_hash/2, base64_encode/1, parse_key/1, frame_from_message/3]). +-export_type([message/0, frame/0, sha_hash/0, websocket_handler/0]). + +-type message() :: {binary_message, bitstring()} | {text_message, binary()}. + +-type frame() :: {close_frame, integer(), bitstring()} | + {text_frame, integer(), bitstring()} | + {binary_frame, integer(), bitstring()} | + {ping_frame, integer(), bitstring()} | + {pong_frame, integer(), bitstring()}. + +-type sha_hash() :: sha. + +-type websocket_handler() :: {websocket_handler, + gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + fun((message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, + nil} | + {error, nil})}. + +-spec make_frame(integer(), integer(), bitstring()) -> gleam@bit_builder:bit_builder(). +make_frame(Opcode, Length, Payload) -> + Length_section = case Length of + Length@1 when Length@1 > 65535 -> + <<127:7, Length@1:64/integer>>; + + Length@2 when Length@2 >= 126 -> + <<126:7, Length@2:16/integer>>; + + _ -> + <> + end, + _pipe = <<1:1, + 0:3, + Opcode:4, + 0:1, + Length_section/bitstring, + Payload/bitstring>>, + gleam@bit_builder:from_bit_string(_pipe). + +-spec frame_to_bit_builder(frame()) -> gleam@bit_builder:bit_builder(). +frame_to_bit_builder(Frame) -> + case Frame of + {text_frame, Payload_length, Payload} -> + make_frame(1, Payload_length, Payload); + + {close_frame, Payload_length@1, Payload@1} -> + make_frame(8, Payload_length@1, Payload@1); + + {binary_frame, Payload_length@2, Payload@2} -> + make_frame(2, Payload_length@2, Payload@2); + + {pong_frame, Payload_length@3, Payload@3} -> + make_frame(10, Payload_length@3, Payload@3); + + {ping_frame, _, _} -> + gleam@bit_builder:from_bit_string(<<>>) + end. + +-spec to_text_frame(bitstring()) -> gleam@bit_builder:bit_builder(). +to_text_frame(Data) -> + Size = gleam@bit_string:byte_size(Data), + frame_to_bit_builder({text_frame, Size, Data}). + +-spec to_binary_frame(bitstring()) -> gleam@bit_builder:bit_builder(). +to_binary_frame(Data) -> + Size = gleam@bit_string:byte_size(Data), + frame_to_bit_builder({binary_frame, Size, Data}). + +-spec crypto_hash(sha_hash(), binary()) -> binary(). +crypto_hash(Field@0, Field@1) -> + crypto:hash(Field@0, Field@1). + +-spec base64_encode(binary()) -> binary(). +base64_encode(Field@0) -> + base64:encode(Field@0). + +-spec parse_key(binary()) -> binary(). +parse_key(Key) -> + _pipe = Key, + _pipe@1 = gleam@string:append( + _pipe, + <<"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"/utf8>> + ), + _pipe@2 = crypto:hash(sha, _pipe@1), + base64:encode(_pipe@2). + +-spec unmask_data(bitstring(), list(bitstring()), integer(), bitstring()) -> bitstring(). +unmask_data(Data, Masks, Index, Resp) -> + case Data of + <<>> -> + Resp; + + <> -> + _assert_subject = gleam@list:at(Masks, Index rem 4), + {ok, Mask_value} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"unmask_data"/utf8>>, + line => 43}) + end, + Unmasked = crypto:exor(Mask_value, Masked), + unmask_data( + Rest, + Masks, + Index + 1, + <> + ) + end. + +-spec frame_from_message( + glisten@socket:socket(), + glisten@socket@transport:transport(), + bitstring() +) -> {ok, frame()} | {error, nil}. +frame_from_message(Socket, Transport, Message) -> + <<_:1, Rest/bitstring>> = case Message of + <<_:1, _/bitstring>> -> Message; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 60}) + end, + <<_:3, Rest@1/bitstring>> = case Rest of + <<_:3, _/bitstring>> -> Rest; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 61}) + end, + <> = case Rest@1 of + <<_:4/integer, _/bitstring>> -> Rest@1; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 62}) + end, + case Opcode of + 1 -> + <<1:1, Rest@3/bitstring>> = case Rest@2 of + <<1:1, _/bitstring>> -> Rest@2; + _assert_fail@3 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 66}) + end, + <> = case Rest@3 of + <<_:7/integer, _/bitstring>> -> Rest@3; + _assert_fail@4 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@4, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 67}) + end, + {Payload_length@1, Rest@7} = case Payload_length of + 126 -> + <> = case Rest@4 of + <<_:16/integer, _/bitstring>> -> Rest@4; + _assert_fail@5 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@5, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 70}) + end, + {Length, Rest@5}; + + 127 -> + <> = case Rest@4 of + <<_:64/integer, _/bitstring>> -> Rest@4; + _assert_fail@6 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@6, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 74}) + end, + {Length@1, Rest@6}; + + _ -> + {Payload_length, Rest@4} + end, + <> = case Rest@7 of + <<_:8/bitstring, + _:8/bitstring, + _:8/bitstring, + _:8/bitstring, + _/bitstring>> -> Rest@7; + _assert_fail@7 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@7, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 79}) + end, + Data = case Payload_length@1 - gleam@bit_string:byte_size(Rest@8) of + 0 -> + unmask_data(Rest@8, [Mask1, Mask2, Mask3, Mask4], 0, <<>>); + + Need -> + _assert_subject = (erlang:element(9, Transport))( + Socket, + Need + ), + {ok, Needed} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail@8 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@8, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 89}) + end, + _pipe = Rest@8, + _pipe@1 = gleam@bit_string:append(_pipe, Needed), + unmask_data(_pipe@1, [Mask1, Mask2, Mask3, Mask4], 0, <<>>) + end, + _pipe@2 = case Opcode of + 1 -> + {text_frame, Payload_length@1, Data}; + + 2 -> + {binary_frame, Payload_length@1, Data} + end, + {ok, _pipe@2}; + + 2 -> + <<1:1, Rest@3/bitstring>> = case Rest@2 of + <<1:1, _/bitstring>> -> Rest@2; + _assert_fail@3 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 66}) + end, + <> = case Rest@3 of + <<_:7/integer, _/bitstring>> -> Rest@3; + _assert_fail@4 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@4, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 67}) + end, + {Payload_length@1, Rest@7} = case Payload_length of + 126 -> + <> = case Rest@4 of + <<_:16/integer, _/bitstring>> -> Rest@4; + _assert_fail@5 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@5, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 70}) + end, + {Length, Rest@5}; + + 127 -> + <> = case Rest@4 of + <<_:64/integer, _/bitstring>> -> Rest@4; + _assert_fail@6 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@6, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 74}) + end, + {Length@1, Rest@6}; + + _ -> + {Payload_length, Rest@4} + end, + <> = case Rest@7 of + <<_:8/bitstring, + _:8/bitstring, + _:8/bitstring, + _:8/bitstring, + _/bitstring>> -> Rest@7; + _assert_fail@7 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@7, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 79}) + end, + Data = case Payload_length@1 - gleam@bit_string:byte_size(Rest@8) of + 0 -> + unmask_data(Rest@8, [Mask1, Mask2, Mask3, Mask4], 0, <<>>); + + Need -> + _assert_subject = (erlang:element(9, Transport))( + Socket, + Need + ), + {ok, Needed} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail@8 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@8, + module => <<"mist/internal/websocket"/utf8>>, + function => <<"frame_from_message"/utf8>>, + line => 89}) + end, + _pipe = Rest@8, + _pipe@1 = gleam@bit_string:append(_pipe, Needed), + unmask_data(_pipe@1, [Mask1, Mask2, Mask3, Mask4], 0, <<>>) + end, + _pipe@2 = case Opcode of + 1 -> + {text_frame, Payload_length@1, Data}; + + 2 -> + {binary_frame, Payload_length@1, Data} + end, + {ok, _pipe@2}; + + 8 -> + {ok, {close_frame, 0, <<>>}} + end. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl b/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl new file mode 100644 index 00000000000..8e5110f7274 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl @@ -0,0 +1,52 @@ +-module(mist@websocket). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([send/2, echo_handler/2, with_handler/1, on_init/2, on_close/2]). + +-spec send( + gleam@erlang@process:subject(glisten@handler:handler_message()), + mist@internal@websocket:message() +) -> nil. +send(Sender, Message) -> + _pipe@2 = case Message of + {text_message, Data} -> + _pipe = Data, + _pipe@1 = gleam@bit_string:from_string(_pipe), + mist@internal@websocket:to_text_frame(_pipe@1); + + {binary_message, Data@1} -> + mist@internal@websocket:to_binary_frame(Data@1) + end, + _pipe@3 = {send_message, _pipe@2}, + gleam@erlang@process:send(Sender, _pipe@3), + nil. + +-spec echo_handler( + mist@internal@websocket:message(), + gleam@erlang@process:subject(glisten@handler:handler_message()) +) -> {ok, nil} | {error, nil}. +echo_handler(Message, Sender) -> + _ = send(Sender, Message), + {ok, nil}. + +-spec with_handler( + fun((mist@internal@websocket:message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, + nil} | + {error, nil}) +) -> mist@internal@websocket:websocket_handler(). +with_handler(Func) -> + {websocket_handler, none, none, Func}. + +-spec on_init( + mist@internal@websocket:websocket_handler(), + fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) +) -> mist@internal@websocket:websocket_handler(). +on_init(Handler, Func) -> + erlang:setelement(3, Handler, {some, Func}). + +-spec on_close( + mist@internal@websocket:websocket_handler(), + fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) +) -> mist@internal@websocket:websocket_handler(). +on_close(Handler, Func) -> + erlang:setelement(2, Handler, {some, Func}). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl b/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl new file mode 100644 index 00000000000..f83e08f5c27 --- /dev/null +++ b/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl @@ -0,0 +1,47 @@ +-module(mist_ffi). + +-export([binary_match/2, decode_packet/3, file_open/1, string_to_int/2]). + +decode_packet(Type, Packet, Opts) -> + case erlang:decode_packet(Type, Packet, Opts) of + {ok, http_eoh, Rest} -> + {ok, {end_of_headers, Rest}}; + {ok, Binary, Rest} -> + {ok, {binary_data, Binary, Rest}}; + {more, Length} when Length =:= undefined -> + {ok, {more_data, none}}; + {more, Length} -> + {ok, {more_data, {some, Length}}}; + {error, Reason} -> + {error, Reason} + end. + +binary_match(Source, Pattern) -> + case binary:match(Source, Pattern) of + {Before, After} -> + {ok, {Before, After}}; + nomatch -> + {error, nil} + end. + +string_to_int(String, Base) -> + try + {ok, erlang:list_to_integer(String, Base)} + catch + badarg -> + {error, nil} + end. + +file_open(Path) -> + case file:open(Path, [raw]) of + {ok, fd} -> + {ok, fd}; + {error, enoent} -> + {error, no_entry}; + {error, eacces} -> + {error, no_access}; + {error, eisdir} -> + {error, is_dir}; + _ -> + {error, unknown_file_error} + end. diff --git a/test-community-packages-javascript/build/packages/nakai/LICENSE b/test-community-packages-javascript/build/packages/nakai/LICENSE new file mode 100644 index 00000000000..2f3b8c6484c --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2022 McKayla Washburn +Copyright (c) 2022 Nakai Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/nakai/README.md b/test-community-packages-javascript/build/packages/nakai/README.md new file mode 100644 index 00000000000..49bcf2f50cb --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/README.md @@ -0,0 +1,46 @@ +![Nakai](https://cdn.mckayla.cloud/-/2d8051c1ce2f4fbd91eaf07df5661e25/Nakai-Banner.svg) + +[![Documentation](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/nakai/) + +## Getting started + +```sh +gleam add nakai +``` + +```gleam +import nakai +import nakai/html.{Node} +import nakai/html/attrs.{Attr} + +const header_style = " + color: #331f26; + font-family: 'Neuton', serif; + font-size: 128px; + font-weight: 400; +" + +pub fn header(attrs: List(Attr(a)), text: String) -> Node(a) { + let attrs = [attrs.style(header_style), ..attrs] + html.h1_text(attrs, text) +} + +pub fn app() -> String { + html.div( + [], + [ + html.Head([html.title("Hello!")]), + header([], "Hello, from Nakai!") + ], + ) + |> nakai.to_string() +} +``` + +## Development + +While Nakai itself is pure Gleam, the benchmarks require having [Elixir] installed, +and some of its dependencies require [Rebar3] to compile. + +[elixir]: https://elixir-lang.org/ +[rebar3]: https://rebar3.org/ diff --git a/test-community-packages-javascript/build/packages/nakai/gleam.toml b/test-community-packages-javascript/build/packages/nakai/gleam.toml new file mode 100644 index 00000000000..6a59fb50e38 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/gleam.toml @@ -0,0 +1,20 @@ +name = "nakai" +version = "0.8.0" +licences = ["MIT"] +description = "HTML generation for Gleam, on the server or anywhere else" +repository = { type = "github", user = "nakaixo", repo = "nakai" } +links = [ + { title = "Website", href = "https://nakaixo.github.io" }, + { title = "Sponsor", href = "https://github.com/sponsors/aslilac" }, +] + +internal_modules = ["nakai/internal/*", "nakai/experimental/*"] + +[dependencies] +gleam_stdlib = "~> 0.29" + +[dev-dependencies] +gleam_erlang = "~> 0.19" +gleam_json = "~> 0.5" +gleeunit = "~> 0.10" +glychee = "~> 0.2" diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl new file mode 100644 index 00000000000..a1e6394f178 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl @@ -0,0 +1 @@ +-record(attr, {name :: binary(), value :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl new file mode 100644 index 00000000000..ff64a0a76cc --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl @@ -0,0 +1 @@ +-record(event, {name :: binary(), action :: any()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl new file mode 100644 index 00000000000..1536616600a --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl @@ -0,0 +1,4 @@ +-record(body, { + attrs :: list(nakai@html@attrs:attr(any())), + children :: list(nakai@html:node_(any())) +}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl new file mode 100644 index 00000000000..7ca4cf0259f --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl @@ -0,0 +1 @@ +-record(comment, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl new file mode 100644 index 00000000000..d1e743c6e74 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl @@ -0,0 +1 @@ +-record(doctype, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl new file mode 100644 index 00000000000..498ade5cb56 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl @@ -0,0 +1,5 @@ +-record(element, { + tag :: binary(), + attrs :: list(nakai@html@attrs:attr(any())), + children :: list(nakai@html:node_(any())) +}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl new file mode 100644 index 00000000000..1753ea5e619 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl @@ -0,0 +1 @@ +-record(fragment, {children :: list(nakai@html:node_(any()))}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl new file mode 100644 index 00000000000..db9f893f8ce --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl @@ -0,0 +1 @@ +-record(head, {children :: list(nakai@html:node_(any()))}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl new file mode 100644 index 00000000000..474196a71bb --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl @@ -0,0 +1,4 @@ +-record(html, { + attrs :: list(nakai@html@attrs:attr(any())), + children :: list(nakai@html:node_(any())) +}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl new file mode 100644 index 00000000000..bd76321701c --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl @@ -0,0 +1,4 @@ +-record(leaf_element, { + tag :: binary(), + attrs :: list(nakai@html@attrs:attr(any())) +}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl new file mode 100644 index 00000000000..e95a602c375 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl @@ -0,0 +1 @@ +-record(script, {script :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl new file mode 100644 index 00000000000..174e44494d9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl @@ -0,0 +1 @@ +-record(text, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl new file mode 100644 index 00000000000..05a9922f2a5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl @@ -0,0 +1 @@ +-record(unsafe_text, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl new file mode 100644 index 00000000000..67f0288ec89 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl @@ -0,0 +1,8 @@ +-record(document, { + doctype :: gleam@option:option(binary()), + html_attrs :: gleam@string_builder:string_builder(), + body_attrs :: gleam@string_builder:string_builder(), + head :: gleam@string_builder:string_builder(), + body :: gleam@string_builder:string_builder(), + scripts :: list(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src b/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src new file mode 100644 index 00000000000..3c3ace613f4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src @@ -0,0 +1,18 @@ +{application, nakai, [ + {vsn, "0.8.0"}, + {applications, [gleam_erlang, + gleam_json, + gleam_stdlib, + gleeunit, + glychee]}, + {description, "HTML generation for Gleam, on the server or anywhere else"}, + {modules, [nakai, + nakai@experimental@head, + nakai@experimental@on, + nakai@experimental@web_components, + nakai@html, + nakai@html@attrs, + nakai@internal@document, + nakai@internal@render]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai.erl new file mode 100644 index 00000000000..ce38b1f6f17 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai.erl @@ -0,0 +1,22 @@ +-module(nakai). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_string_builder/1, to_string/1, to_inline_string_builder/1, to_inline_string/1]). + +-spec to_string_builder(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). +to_string_builder(Tree) -> + nakai@internal@render:render_document(Tree). + +-spec to_string(nakai@html:node_(any())) -> binary(). +to_string(Tree) -> + _pipe = nakai@internal@render:render_document(Tree), + gleam@string_builder:to_string(_pipe). + +-spec to_inline_string_builder(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). +to_inline_string_builder(Tree) -> + nakai@internal@render:render_inline(Tree). + +-spec to_inline_string(nakai@html:node_(any())) -> binary(). +to_inline_string(Tree) -> + _pipe = nakai@internal@render:render_inline(Tree), + gleam@string_builder:to_string(_pipe). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam new file mode 100644 index 00000000000..18c83efcade --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam @@ -0,0 +1,60 @@ +//// Nakai has several "builders" that can be used. +//// - A `document` builder (the recommend one) that renders a full HTML document, +//// does a little magic to dedepulicate `` elements, and some other things +//// that generally fit the theme of "rendering a full, valid, HTML document" +//// - An `inline` builder that should mostly be used for snippets, and partial bits of +//// HTML that will be inlined into a full document; hence the name. It renders things +//// much more literally. If you tell it to give you a `` element inside a +//// `

    `, it will, as an example. +//// - A future experimental DOM renderer (meant for use in the browser) that isn't +//// actually done yet. + +import gleam/string_builder.{StringBuilder} +import nakai/html.{Node} +import nakai/internal/render + +/// Renders a full HTML document from the given tree, into a `StringBuilder`. +/// ## Examples +/// ```gleam +/// html.div_text([], "hello, lucy!") +/// |> nakai.to_string_builder() +/// ``` +pub fn to_string_builder(tree: Node(a)) -> StringBuilder { + render.render_document(tree) +} + +/// Renders a full HTML document from the given tree, into a `String`. +/// ## Examples +/// ```gleam +/// html.div_text([], "hello, lucy!") +/// |> nakai.to_string() +/// ``` +pub fn to_string(tree: Node(a)) -> String { + render.render_document(tree) + |> string_builder.to_string() +} + +/// Renders only the provided HTML, exactly as provided (disables `` +/// deduplication, etc.), into a `StringBuilder`. Useful for generating snippets +/// instead of whole pages. +/// ## Examples +/// ```gleam +/// html.div_text([], "hello, lucy!") +/// |> nakai.to_inline_string_builder() +/// ``` +pub fn to_inline_string_builder(tree: Node(a)) -> StringBuilder { + render.render_inline(tree) +} + +/// Renders only the provided HTML, exactly as provided (disables `` +/// deduplication, etc.), into a `String`. Useful for generating snippets instead +/// of whole pages. +/// ## Examples +/// ```gleam +/// html.div_text([], "hello, lucy!") +/// |> nakai.to_inline_string() +/// ``` +pub fn to_inline_string(tree: Node(a)) -> String { + render.render_inline(tree) + |> string_builder.to_string() +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam new file mode 100644 index 00000000000..466c0c259aa --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam @@ -0,0 +1,22 @@ +import nakai/html +import nakai/html/attrs + +pub fn title(title: String) { + html.Head([html.title(title)]) +} + +pub fn link(rel rel: String, href href: String) { + html.Head([html.link([attrs.rel(rel), attrs.href(href)])]) +} + +pub fn meta(name name: String, content content: String) { + html.Head([html.meta([attrs.name(name), attrs.content(content)])]) +} + +pub fn http_equiv(header: String, content content: String) { + html.Head([html.meta([attrs.http_equiv(header), attrs.content(content)])]) +} + +pub fn charset(charset: String) { + html.Head([html.meta([attrs.charset(charset)])]) +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam new file mode 100644 index 00000000000..07f43f0a398 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam @@ -0,0 +1,5 @@ +import nakai/html/attrs.{Attr} + +pub fn click(script: String) -> Attr(a) { + Attr(name: "onclick", value: script) +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam new file mode 100644 index 00000000000..9041dd78bdc --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam @@ -0,0 +1,10 @@ +import nakai/html.{Element, LeafElement, Node} +import nakai/html/attrs.{Attr} + +pub fn slot(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "slot", attrs: attrs) +} + +pub fn template(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "template", attrs: attrs, children: children) +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam new file mode 100644 index 00000000000..d1b07418fe7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam @@ -0,0 +1,1164 @@ + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * THIS FILE IS GENERATED. DO NOT EDIT IT. * +// * You're probably looking for ./codegen/html_prelude.gleam, or ./codegen/html.json. * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + + + +import nakai/html/attrs.{Attr} + +pub type Node(a) { + /// Can be used anywhere in the document, and will set the doctype of the document + /// being rendered. Usually not necessary, as documents have a default of ``. + /// ## Example + /// ```gleam + /// html.Doctype("html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"") + /// ``` + Doctype(content: String) + /// Used for setting attributes on the root `` element of the document. Children + /// will be rendered in-place, equivalent to using `html.Fragment(children)`. + /// ## Example + /// ```gleam + /// html.Html([attrs.lang("en-US")], [ + /// ... + /// ]) + /// ``` + Html(attrs: List(Attr(a)), children: List(Node(a))) + /// Used for placing content in the `` of the document. Useful for elements like + /// ``, ``, `<link>`, etc. + /// ## Example + /// ```gleam + /// html.Fragment([ + /// html.Head([ + /// html.title("List of puppies") + /// ]), + /// html.div([], [ + /// ... + /// ]) + /// ]) + /// ``` + Head(children: List(Node(a))) + /// Used for setting attributes on the `<body>` element of the document. Children + /// will be rendered in-place, equivalent to using `html.Fragment(children)`. + /// ## Example + /// ```gleam + /// html.Body([attrs.class("dark-mode")], [ + /// ... + /// ]) + /// ``` + Body(attrs: List(Attr(a)), children: List(Node(a))) + /// An "transparent" container that will render it's children, but does not add anything + /// itself to the document. If you've ever used `React.Fragment` or `<>` and `</>` in + /// JSX/React, this is that. + /// ## Example + /// ```gleam + /// html.ul([], [ + /// // some puppies are hard-coded + /// html.li_text([], "August"), + /// // some are loaded from a server + /// html.Fragment(puppies_fetched_from_api |> list.map(html.li_text([], _))) + /// ]) + /// // <ul> + /// // <li>August</li> + /// // <li>Dot</li> + /// // <li>Mody</li> + /// // <li>Spot</li> + /// // <li>Toby</li> + /// // </ul> + /// ``` + Fragment(children: List(Node(a))) + /// An HTML element. You shouldn't need to reach for this very often, but it can be a + /// handy escape hatch if there isn't a shorthand function for the element type you need. + /// ## Example + /// ```gleam + /// // bad example, pls use `html.div` + /// html.Element("div", [], [html.Text("hello, lucy!")]) + /// ``` + Element(tag: String, attrs: List(Attr(a)), children: List(Node(a))) + /// An HTML element, but that does not have any children, and should be self closing. + /// Similarly to `Element`, you shouldn't really need this, except as an escape hatch + /// if there isn't a shorthand function for the element type you need. + /// ## Example + /// ```gleam + /// // bad example, pls use `html.link` + /// html.LeafElement("link", [attrs.rel("stylesheet"), attrs.href(...)]) + /// ``` + LeafElement(tag: String, attrs: List(Attr(a))) + /// An HTML comment, which will be included in the document. + /// ## Example + /// ```gleam + /// html.Comment("You've uncovered my secrets!") + /// // <!-- You've uncovered my secrets! --> + /// ``` + Comment(content: String) + /// Some plain text to include in the document. The provided text will be escaped, to + /// make it safe to include in the document. + /// ## Example + /// ```gleam + /// html.Text("hello, lucy!") + /// // hello, lucy! + /// ``` + /// ```gleam + /// // Time to trust some unvalidated user input! :^) + /// html.div_text([], "<script>alert('pwned');</script>") + /// // <div><script>alert('pwned');</script></div> + /// ``` + Text(content: String) + /// The dangerous cousin of `Text`. This will render the provided text as-is, without + /// any santization. Good for things like including some HTML you just generated from + /// a Markdown file. Bad for things like `$_GET['search']`. + /// ## Example + /// ```gleam + /// html.Text("hello, lucy!") + /// // hello, lucy! + /// ``` + /// ```gleam + /// // Time to trust some unvalidated user input! :^) + /// html.div([], [html.UnsafeText("<script>alert('pwned');</script>")]) + /// // <div><script>alert('pwned');</script></div> + /// // Oh no, we just got got! D: + /// ``` + UnsafeText(content: String) + /// Add some JavaScript to your page! Scripts will always be inserted at the end of the + /// page, regardless of where in the document the `Script` node is, so that your content + /// loads first. + /// ## Example + /// ```gleam + /// html.Script("alert('hello, lucy!')") + /// ``` + Script(script: String) + /// Renders absolutely nothing. For when you may or may not have something to render, + /// and need a way to say "I've got nothing." + /// ## Example + /// ```gleam + /// html.div([], [ + /// case my_cool_feature { + /// Enabled -> super_cool_stuff() + /// Disabled -> html.Nothing + /// } + /// ]) + Nothing +} + +/// The HTML [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title) element +pub fn title(text: String) -> Node(a) { + Element("title", [], [Text(text)]) +} + +/// The [HTML `<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) +pub fn a(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "a", attrs: attrs, children: children) +} + +/// Shorthand for `html.a(attrs, children: [html.Text(text)])` +pub fn a_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "a", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<abbr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr) +pub fn abbr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "abbr", attrs: attrs, children: children) +} + +/// Shorthand for `html.abbr(attrs, children: [html.Text(text)])` +pub fn abbr_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "abbr", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<address>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address) +pub fn address(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "address", attrs: attrs, children: children) +} + +/// Shorthand for `html.address(attrs, children: [html.Text(text)])` +pub fn address_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "address", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<area />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area) +pub fn area(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "area", attrs: attrs) +} + +/// The [HTML `<article>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article) +pub fn article(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "article", attrs: attrs, children: children) +} + +/// Shorthand for `html.article(attrs, children: [html.Text(text)])` +pub fn article_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "article", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<aside>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside) +pub fn aside(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "aside", attrs: attrs, children: children) +} + +/// Shorthand for `html.aside(attrs, children: [html.Text(text)])` +pub fn aside_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "aside", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<audio>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio) +pub fn audio(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "audio", attrs: attrs, children: children) +} + +/// Shorthand for `html.audio(attrs, children: [html.Text(text)])` +pub fn audio_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "audio", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<b>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b) +pub fn b(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "b", attrs: attrs, children: children) +} + +/// Shorthand for `html.b(attrs, children: [html.Text(text)])` +pub fn b_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "b", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<base />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) +pub fn base(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "base", attrs: attrs) +} + +/// The [HTML `<bdi>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi) +pub fn bdi(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "bdi", attrs: attrs, children: children) +} + +/// Shorthand for `html.bdi(attrs, children: [html.Text(text)])` +pub fn bdi_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "bdi", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<bdo>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo) +pub fn bdo(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "bdo", attrs: attrs, children: children) +} + +/// Shorthand for `html.bdo(attrs, children: [html.Text(text)])` +pub fn bdo_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "bdo", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<blockquote>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote) +pub fn blockquote(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "blockquote", attrs: attrs, children: children) +} + +/// Shorthand for `html.blockquote(attrs, children: [html.Text(text)])` +pub fn blockquote_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "blockquote", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<br />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br) +pub fn br(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "br", attrs: attrs) +} + +/// The [HTML `<button>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) +pub fn button(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "button", attrs: attrs, children: children) +} + +/// Shorthand for `html.button(attrs, children: [html.Text(text)])` +pub fn button_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "button", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<canvas>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) +pub fn canvas(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "canvas", attrs: attrs, children: children) +} + +/// Shorthand for `html.canvas(attrs, children: [html.Text(text)])` +pub fn canvas_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "canvas", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<caption>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption) +pub fn caption(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "caption", attrs: attrs, children: children) +} + +/// Shorthand for `html.caption(attrs, children: [html.Text(text)])` +pub fn caption_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "caption", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<cite>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite) +pub fn cite(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "cite", attrs: attrs, children: children) +} + +/// Shorthand for `html.cite(attrs, children: [html.Text(text)])` +pub fn cite_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "cite", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<code>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code) +pub fn code(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "code", attrs: attrs, children: children) +} + +/// Shorthand for `html.code(attrs, children: [html.Text(text)])` +pub fn code_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "code", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<col>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col) +pub fn col(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "col", attrs: attrs, children: children) +} + +/// Shorthand for `html.col(attrs, children: [html.Text(text)])` +pub fn col_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "col", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<colgroup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup) +pub fn colgroup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "colgroup", attrs: attrs, children: children) +} + +/// Shorthand for `html.colgroup(attrs, children: [html.Text(text)])` +pub fn colgroup_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "colgroup", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<data>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data) +pub fn data(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "data", attrs: attrs, children: children) +} + +/// Shorthand for `html.data(attrs, children: [html.Text(text)])` +pub fn data_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "data", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<datalist>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) +pub fn datalist(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "datalist", attrs: attrs, children: children) +} + +/// Shorthand for `html.datalist(attrs, children: [html.Text(text)])` +pub fn datalist_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "datalist", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<dd>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd) +pub fn dd(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "dd", attrs: attrs, children: children) +} + +/// Shorthand for `html.dd(attrs, children: [html.Text(text)])` +pub fn dd_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "dd", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<del>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del) +pub fn del(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "del", attrs: attrs, children: children) +} + +/// Shorthand for `html.del(attrs, children: [html.Text(text)])` +pub fn del_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "del", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<details>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details) +pub fn details(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "details", attrs: attrs, children: children) +} + +/// Shorthand for `html.details(attrs, children: [html.Text(text)])` +pub fn details_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "details", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<dfn>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dfn) +pub fn dfn(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "dfn", attrs: attrs, children: children) +} + +/// Shorthand for `html.dfn(attrs, children: [html.Text(text)])` +pub fn dfn_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "dfn", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<dialog>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) +pub fn dialog(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "dialog", attrs: attrs, children: children) +} + +/// Shorthand for `html.dialog(attrs, children: [html.Text(text)])` +pub fn dialog_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "dialog", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<div>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) +pub fn div(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "div", attrs: attrs, children: children) +} + +/// Shorthand for `html.div(attrs, children: [html.Text(text)])` +pub fn div_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "div", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<dl>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl) +pub fn dl(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "dl", attrs: attrs, children: children) +} + +/// Shorthand for `html.dl(attrs, children: [html.Text(text)])` +pub fn dl_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "dl", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<dt>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt) +pub fn dt(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "dt", attrs: attrs, children: children) +} + +/// Shorthand for `html.dt(attrs, children: [html.Text(text)])` +pub fn dt_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "dt", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<em>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em) +pub fn em(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "em", attrs: attrs, children: children) +} + +/// Shorthand for `html.em(attrs, children: [html.Text(text)])` +pub fn em_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "em", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<embed>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed) +pub fn embed(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "embed", attrs: attrs, children: children) +} + +/// Shorthand for `html.embed(attrs, children: [html.Text(text)])` +pub fn embed_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "embed", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<fieldset>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset) +pub fn fieldset(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "fieldset", attrs: attrs, children: children) +} + +/// Shorthand for `html.fieldset(attrs, children: [html.Text(text)])` +pub fn fieldset_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "fieldset", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<figcaption>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption) +pub fn figcaption(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "figcaption", attrs: attrs, children: children) +} + +/// Shorthand for `html.figcaption(attrs, children: [html.Text(text)])` +pub fn figcaption_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "figcaption", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<figure>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure) +pub fn figure(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "figure", attrs: attrs, children: children) +} + +/// Shorthand for `html.figure(attrs, children: [html.Text(text)])` +pub fn figure_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "figure", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<footer>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer) +pub fn footer(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "footer", attrs: attrs, children: children) +} + +/// Shorthand for `html.footer(attrs, children: [html.Text(text)])` +pub fn footer_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "footer", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<form>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) +pub fn form(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "form", attrs: attrs, children: children) +} + +/// Shorthand for `html.form(attrs, children: [html.Text(text)])` +pub fn form_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "form", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<h1>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1) +pub fn h1(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "h1", attrs: attrs, children: children) +} + +/// Shorthand for `html.h1(attrs, children: [html.Text(text)])` +pub fn h1_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "h1", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<h2>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2) +pub fn h2(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "h2", attrs: attrs, children: children) +} + +/// Shorthand for `html.h2(attrs, children: [html.Text(text)])` +pub fn h2_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "h2", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<h3>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3) +pub fn h3(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "h3", attrs: attrs, children: children) +} + +/// Shorthand for `html.h3(attrs, children: [html.Text(text)])` +pub fn h3_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "h3", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<h4>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4) +pub fn h4(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "h4", attrs: attrs, children: children) +} + +/// Shorthand for `html.h4(attrs, children: [html.Text(text)])` +pub fn h4_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "h4", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<h5>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5) +pub fn h5(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "h5", attrs: attrs, children: children) +} + +/// Shorthand for `html.h5(attrs, children: [html.Text(text)])` +pub fn h5_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "h5", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<h6>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6) +pub fn h6(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "h6", attrs: attrs, children: children) +} + +/// Shorthand for `html.h6(attrs, children: [html.Text(text)])` +pub fn h6_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "h6", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<header>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header) +pub fn header(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "header", attrs: attrs, children: children) +} + +/// Shorthand for `html.header(attrs, children: [html.Text(text)])` +pub fn header_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "header", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<hr />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr) +pub fn hr(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "hr", attrs: attrs) +} + +/// The [HTML `<i>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i) +pub fn i(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "i", attrs: attrs, children: children) +} + +/// Shorthand for `html.i(attrs, children: [html.Text(text)])` +pub fn i_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "i", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<iframe>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) +pub fn iframe(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "iframe", attrs: attrs, children: children) +} + +/// Shorthand for `html.iframe(attrs, children: [html.Text(text)])` +pub fn iframe_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "iframe", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<img />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) +pub fn img(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "img", attrs: attrs) +} + +/// The [HTML `<input />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) +pub fn input(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "input", attrs: attrs) +} + +/// The [HTML `<ins>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins) +pub fn ins(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "ins", attrs: attrs, children: children) +} + +/// Shorthand for `html.ins(attrs, children: [html.Text(text)])` +pub fn ins_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "ins", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<kbd>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd) +pub fn kbd(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "kbd", attrs: attrs, children: children) +} + +/// Shorthand for `html.kbd(attrs, children: [html.Text(text)])` +pub fn kbd_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "kbd", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<label>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) +pub fn label(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "label", attrs: attrs, children: children) +} + +/// Shorthand for `html.label(attrs, children: [html.Text(text)])` +pub fn label_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "label", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<legend>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend) +pub fn legend(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "legend", attrs: attrs, children: children) +} + +/// Shorthand for `html.legend(attrs, children: [html.Text(text)])` +pub fn legend_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "legend", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<li>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li) +pub fn li(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "li", attrs: attrs, children: children) +} + +/// Shorthand for `html.li(attrs, children: [html.Text(text)])` +pub fn li_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "li", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<link />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) +pub fn link(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "link", attrs: attrs) +} + +/// The [HTML `<main>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main) +pub fn main(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "main", attrs: attrs, children: children) +} + +/// Shorthand for `html.main(attrs, children: [html.Text(text)])` +pub fn main_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "main", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<map>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map) +pub fn map(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "map", attrs: attrs, children: children) +} + +/// Shorthand for `html.map(attrs, children: [html.Text(text)])` +pub fn map_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "map", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<mark>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark) +pub fn mark(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "mark", attrs: attrs, children: children) +} + +/// Shorthand for `html.mark(attrs, children: [html.Text(text)])` +pub fn mark_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "mark", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<math>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/math) +pub fn math(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "math", attrs: attrs, children: children) +} + +/// Shorthand for `html.math(attrs, children: [html.Text(text)])` +pub fn math_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "math", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<menu>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu) +pub fn menu(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "menu", attrs: attrs, children: children) +} + +/// Shorthand for `html.menu(attrs, children: [html.Text(text)])` +pub fn menu_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "menu", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<menuitem>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menuitem) +pub fn menuitem(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "menuitem", attrs: attrs, children: children) +} + +/// Shorthand for `html.menuitem(attrs, children: [html.Text(text)])` +pub fn menuitem_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "menuitem", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<meta />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) +pub fn meta(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "meta", attrs: attrs) +} + +/// The [HTML `<meter>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter) +pub fn meter(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "meter", attrs: attrs, children: children) +} + +/// Shorthand for `html.meter(attrs, children: [html.Text(text)])` +pub fn meter_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "meter", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<nav>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav) +pub fn nav(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "nav", attrs: attrs, children: children) +} + +/// Shorthand for `html.nav(attrs, children: [html.Text(text)])` +pub fn nav_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "nav", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<noscript>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript) +pub fn noscript(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "noscript", attrs: attrs, children: children) +} + +/// Shorthand for `html.noscript(attrs, children: [html.Text(text)])` +pub fn noscript_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "noscript", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<object>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object) +pub fn object(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "object", attrs: attrs, children: children) +} + +/// Shorthand for `html.object(attrs, children: [html.Text(text)])` +pub fn object_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "object", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<ol>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol) +pub fn ol(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "ol", attrs: attrs, children: children) +} + +/// Shorthand for `html.ol(attrs, children: [html.Text(text)])` +pub fn ol_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "ol", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<optgroup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup) +pub fn optgroup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "optgroup", attrs: attrs, children: children) +} + +/// Shorthand for `html.optgroup(attrs, children: [html.Text(text)])` +pub fn optgroup_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "optgroup", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<option>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) +pub fn option(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "option", attrs: attrs, children: children) +} + +/// Shorthand for `html.option(attrs, children: [html.Text(text)])` +pub fn option_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "option", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<output>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output) +pub fn output(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "output", attrs: attrs, children: children) +} + +/// Shorthand for `html.output(attrs, children: [html.Text(text)])` +pub fn output_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "output", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<p>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p) +pub fn p(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "p", attrs: attrs, children: children) +} + +/// Shorthand for `html.p(attrs, children: [html.Text(text)])` +pub fn p_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "p", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<param>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param) +pub fn param(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "param", attrs: attrs, children: children) +} + +/// Shorthand for `html.param(attrs, children: [html.Text(text)])` +pub fn param_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "param", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<picture>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) +pub fn picture(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "picture", attrs: attrs, children: children) +} + +/// Shorthand for `html.picture(attrs, children: [html.Text(text)])` +pub fn picture_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "picture", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<pre>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre) +pub fn pre(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "pre", attrs: attrs, children: children) +} + +/// Shorthand for `html.pre(attrs, children: [html.Text(text)])` +pub fn pre_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "pre", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<progress>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) +pub fn progress(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "progress", attrs: attrs, children: children) +} + +/// Shorthand for `html.progress(attrs, children: [html.Text(text)])` +pub fn progress_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "progress", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<q>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q) +pub fn q(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "q", attrs: attrs, children: children) +} + +/// Shorthand for `html.q(attrs, children: [html.Text(text)])` +pub fn q_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "q", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<rp>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp) +pub fn rp(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "rp", attrs: attrs, children: children) +} + +/// Shorthand for `html.rp(attrs, children: [html.Text(text)])` +pub fn rp_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "rp", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<rt>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rt) +pub fn rt(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "rt", attrs: attrs, children: children) +} + +/// Shorthand for `html.rt(attrs, children: [html.Text(text)])` +pub fn rt_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "rt", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<ruby>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby) +pub fn ruby(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "ruby", attrs: attrs, children: children) +} + +/// Shorthand for `html.ruby(attrs, children: [html.Text(text)])` +pub fn ruby_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "ruby", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<s>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s) +pub fn s(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "s", attrs: attrs, children: children) +} + +/// Shorthand for `html.s(attrs, children: [html.Text(text)])` +pub fn s_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "s", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<samp>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/samp) +pub fn samp(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "samp", attrs: attrs, children: children) +} + +/// Shorthand for `html.samp(attrs, children: [html.Text(text)])` +pub fn samp_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "samp", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<section>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section) +pub fn section(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "section", attrs: attrs, children: children) +} + +/// Shorthand for `html.section(attrs, children: [html.Text(text)])` +pub fn section_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "section", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<select>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) +pub fn select(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "select", attrs: attrs, children: children) +} + +/// Shorthand for `html.select(attrs, children: [html.Text(text)])` +pub fn select_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "select", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<small>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small) +pub fn small(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "small", attrs: attrs, children: children) +} + +/// Shorthand for `html.small(attrs, children: [html.Text(text)])` +pub fn small_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "small", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<source />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source) +pub fn source(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "source", attrs: attrs) +} + +/// The [HTML `<span>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span) +pub fn span(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "span", attrs: attrs, children: children) +} + +/// Shorthand for `html.span(attrs, children: [html.Text(text)])` +pub fn span_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "span", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<strong>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong) +pub fn strong(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "strong", attrs: attrs, children: children) +} + +/// Shorthand for `html.strong(attrs, children: [html.Text(text)])` +pub fn strong_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "strong", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<sub>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub) +pub fn sub(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "sub", attrs: attrs, children: children) +} + +/// Shorthand for `html.sub(attrs, children: [html.Text(text)])` +pub fn sub_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "sub", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<summary>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary) +pub fn summary(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "summary", attrs: attrs, children: children) +} + +/// Shorthand for `html.summary(attrs, children: [html.Text(text)])` +pub fn summary_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "summary", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<sup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup) +pub fn sup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "sup", attrs: attrs, children: children) +} + +/// Shorthand for `html.sup(attrs, children: [html.Text(text)])` +pub fn sup_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "sup", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<svg>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/svg) +pub fn svg(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "svg", attrs: attrs, children: children) +} + +/// Shorthand for `html.svg(attrs, children: [html.Text(text)])` +pub fn svg_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "svg", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<table>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table) +pub fn table(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "table", attrs: attrs, children: children) +} + +/// Shorthand for `html.table(attrs, children: [html.Text(text)])` +pub fn table_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "table", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<tbody>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody) +pub fn tbody(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "tbody", attrs: attrs, children: children) +} + +/// Shorthand for `html.tbody(attrs, children: [html.Text(text)])` +pub fn tbody_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "tbody", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<td>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) +pub fn td(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "td", attrs: attrs, children: children) +} + +/// Shorthand for `html.td(attrs, children: [html.Text(text)])` +pub fn td_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "td", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<textarea>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) +pub fn textarea(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "textarea", attrs: attrs, children: children) +} + +/// Shorthand for `html.textarea(attrs, children: [html.Text(text)])` +pub fn textarea_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "textarea", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<tfoot>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot) +pub fn tfoot(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "tfoot", attrs: attrs, children: children) +} + +/// Shorthand for `html.tfoot(attrs, children: [html.Text(text)])` +pub fn tfoot_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "tfoot", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<th>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th) +pub fn th(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "th", attrs: attrs, children: children) +} + +/// Shorthand for `html.th(attrs, children: [html.Text(text)])` +pub fn th_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "th", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<thead>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead) +pub fn thead(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "thead", attrs: attrs, children: children) +} + +/// Shorthand for `html.thead(attrs, children: [html.Text(text)])` +pub fn thead_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "thead", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<time>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time) +pub fn time(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "time", attrs: attrs, children: children) +} + +/// Shorthand for `html.time(attrs, children: [html.Text(text)])` +pub fn time_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "time", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<tr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr) +pub fn tr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "tr", attrs: attrs, children: children) +} + +/// Shorthand for `html.tr(attrs, children: [html.Text(text)])` +pub fn tr_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "tr", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<track />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track) +pub fn track(attrs: List(Attr(a))) -> Node(a) { + LeafElement(tag: "track", attrs: attrs) +} + +/// The [HTML `<u>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u) +pub fn u(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "u", attrs: attrs, children: children) +} + +/// Shorthand for `html.u(attrs, children: [html.Text(text)])` +pub fn u_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "u", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<ul>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul) +pub fn ul(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "ul", attrs: attrs, children: children) +} + +/// Shorthand for `html.ul(attrs, children: [html.Text(text)])` +pub fn ul_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "ul", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<var>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var) +pub fn var(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "var", attrs: attrs, children: children) +} + +/// Shorthand for `html.var(attrs, children: [html.Text(text)])` +pub fn var_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "var", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<video>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) +pub fn video(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "video", attrs: attrs, children: children) +} + +/// Shorthand for `html.video(attrs, children: [html.Text(text)])` +pub fn video_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "video", attrs: attrs, children: [Text(text)]) +} + +/// The [HTML `<wbr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr) +pub fn wbr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { + Element(tag: "wbr", attrs: attrs, children: children) +} + +/// Shorthand for `html.wbr(attrs, children: [html.Text(text)])` +pub fn wbr_text(attrs: List(Attr(a)), text: String) -> Node(a) { + Element(tag: "wbr", attrs: attrs, children: [Text(text)]) +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam new file mode 100644 index 00000000000..a8fda0fb25a --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam @@ -0,0 +1,203 @@ + + + + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +// * THIS FILE IS GENERATED. DO NOT EDIT IT. * +// * You're probably looking for ./codegen/attrs_prelude.gleam, or ./codegen/attrs.json. * +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + + + + +pub type Attr(a) { + Attr(name: String, value: String) + Event(name: String, action: a) +} + +pub fn data(name: String, value: String) -> Attr(a) { + Attr(name: "data-" <> name, value: value) +} + +pub fn accept(value: String) -> Attr(a) { + Attr(name: "accept", value: value) +} + +pub fn accept_charset(value: String) -> Attr(a) { + Attr(name: "accept-charset", value: value) +} + +pub fn action(value: String) -> Attr(a) { + Attr(name: "action", value: value) +} + +pub fn alt(value: String) -> Attr(a) { + Attr(name: "alt", value: value) +} + +pub fn async() -> Attr(a) { + Attr(name: "async", value: "true") +} + +pub fn autocapitalize(value: String) -> Attr(a) { + Attr(name: "autocapitalize", value: value) +} + +pub fn autocomplete(value: String) -> Attr(a) { + Attr(name: "autocomplete", value: value) +} + +pub fn autofocus() -> Attr(a) { + Attr(name: "autofocus", value: "true") +} + +pub fn autoplay() -> Attr(a) { + Attr(name: "autoplay", value: "true") +} + +pub fn capture(value: String) -> Attr(a) { + Attr(name: "capture", value: value) +} + +pub fn charset(value: String) -> Attr(a) { + Attr(name: "charset", value: value) +} + +pub fn checked() -> Attr(a) { + Attr(name: "checked", value: "true") +} + +pub fn cite(value: String) -> Attr(a) { + Attr(name: "cite", value: value) +} + +pub fn class(value: String) -> Attr(a) { + Attr(name: "class", value: value) +} + +pub fn content(value: String) -> Attr(a) { + Attr(name: "content", value: value) +} + +pub fn contenteditable() -> Attr(a) { + Attr(name: "contenteditable", value: "true") +} + +pub fn crossorigin() -> Attr(a) { + Attr(name: "crossorigin", value: "true") +} + +pub fn defer() -> Attr(a) { + Attr(name: "defer", value: "true") +} + +pub fn disabled() -> Attr(a) { + Attr(name: "disabled", value: "true") +} + +pub fn draggable() -> Attr(a) { + Attr(name: "draggable", value: "true") +} + +pub fn for(value: String) -> Attr(a) { + Attr(name: "for", value: value) +} + +pub fn formaction(value: String) -> Attr(a) { + Attr(name: "formaction", value: value) +} + +pub fn height(value: String) -> Attr(a) { + Attr(name: "height", value: value) +} + +pub fn href(value: String) -> Attr(a) { + Attr(name: "href", value: value) +} + +pub fn http_equiv(value: String) -> Attr(a) { + Attr(name: "http-equiv", value: value) +} + +pub fn id(value: String) -> Attr(a) { + Attr(name: "id", value: value) +} + +pub fn integrity(value: String) -> Attr(a) { + Attr(name: "integrity", value: value) +} + +pub fn lang(value: String) -> Attr(a) { + Attr(name: "lang", value: value) +} + +pub fn loop() -> Attr(a) { + Attr(name: "loop", value: "true") +} + +pub fn method(value: String) -> Attr(a) { + Attr(name: "method", value: value) +} + +pub fn name(value: String) -> Attr(a) { + Attr(name: "name", value: value) +} + +pub fn placeholder(value: String) -> Attr(a) { + Attr(name: "placeholder", value: value) +} + +pub fn preload() -> Attr(a) { + Attr(name: "preload", value: "true") +} + +pub fn property(value: String) -> Attr(a) { + Attr(name: "property", value: value) +} + +pub fn readonly() -> Attr(a) { + Attr(name: "readonly", value: "true") +} + +pub fn rel(value: String) -> Attr(a) { + Attr(name: "rel", value: value) +} + +pub fn selected() -> Attr(a) { + Attr(name: "selected", value: "true") +} + +pub fn src(value: String) -> Attr(a) { + Attr(name: "src", value: value) +} + +pub fn style(value: String) -> Attr(a) { + Attr(name: "style", value: value) +} + +pub fn tabindex(value: String) -> Attr(a) { + Attr(name: "tabindex", value: value) +} + +pub fn target(value: String) -> Attr(a) { + Attr(name: "target", value: value) +} + +pub fn title(value: String) -> Attr(a) { + Attr(name: "title", value: value) +} + +pub fn type_(value: String) -> Attr(a) { + Attr(name: "type", value: value) +} + +pub fn value(value: String) -> Attr(a) { + Attr(name: "value", value: value) +} + +pub fn width(value: String) -> Attr(a) { + Attr(name: "width", value: value) +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam new file mode 100644 index 00000000000..8fe56a47f23 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam @@ -0,0 +1,97 @@ +import gleam/option.{Option} +import gleam/list +import gleam/string_builder.{StringBuilder} + +pub const encoding = " +<meta charset=\"utf-8\" /> +<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /> +" + +pub type Document { + Document( + doctype: Option(String), + html_attrs: StringBuilder, + body_attrs: StringBuilder, + head: StringBuilder, + body: StringBuilder, + scripts: List(String), + ) +} + +pub fn new() { + Document( + doctype: option.None, + html_attrs: string_builder.new(), + body_attrs: string_builder.new(), + head: string_builder.new(), + body: string_builder.new(), + scripts: [], + ) +} + +pub fn merge(self: Document, new: Document) -> Document { + Document( + // Overwrite the doctype with a newer one, unless the newer one is `None` + doctype: option.or(new.doctype, self.doctype), + html_attrs: string_builder.append_builder(self.html_attrs, new.html_attrs), + body_attrs: string_builder.append_builder(self.body_attrs, new.body_attrs), + head: string_builder.append_builder(self.head, new.head), + body: string_builder.append_builder(self.body, new.body), + scripts: list.append(self.scripts, new.scripts), + ) +} + +pub fn concat(docs: List(Document)) -> Document { + docs + |> list.fold(new(), merge) +} + +pub fn from_doctype(doctype: String) -> Document { + Document(..new(), doctype: option.Some(doctype)) +} + +pub fn append_html_attrs(self: Document, html_attrs: StringBuilder) -> Document { + Document( + ..self, + html_attrs: string_builder.append_builder(self.html_attrs, html_attrs), + ) +} + +pub fn append_body_attrs(self: Document, body_attrs: StringBuilder) -> Document { + Document( + ..self, + body_attrs: string_builder.append_builder(self.body_attrs, body_attrs), + ) +} + +pub fn from_head(head: StringBuilder) -> Document { + Document(..new(), head: head) +} + +pub fn append_head(self: Document, head: StringBuilder) -> Document { + Document(..self, head: string_builder.append_builder(self.head, head)) +} + +pub fn from_body(body: StringBuilder) -> Document { + Document(..new(), body: body) +} + +pub fn append_body(self: Document, body: StringBuilder) -> Document { + Document(..self, body: string_builder.append_builder(self.body, body)) +} + +pub fn replace_body(self: Document, body: StringBuilder) -> Document { + Document(..self, body: body) +} + +pub fn from_script(script: String) -> Document { + Document(..new(), scripts: [script]) +} + +pub fn into_head(state: Document) -> Document { + Document( + ..state, + head: string_builder.append_builder(state.head, state.body), + body: string_builder.new(), + ) +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam new file mode 100644 index 00000000000..780a9715f79 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam @@ -0,0 +1,211 @@ +import gleam/list +import gleam/option +import gleam/string_builder.{StringBuilder} +import gleam/string +import nakai/html.{Node} +import nakai/html/attrs.{Attr, Event} +import nakai/internal/document.{Document} + +type Builder(a, output) { + Builder(map: fn(Node(a)) -> output, fold: fn(List(output)) -> output) +} + +const document_builder = Builder( + map: render_document_node, + fold: document.concat, +) + +const inline_builder = Builder( + map: render_inline_node, + fold: string_builder.concat, +) + +fn render_doctype(doctype: String) -> StringBuilder { + string_builder.from_strings(["<!DOCTYPE ", doctype, ">\n"]) +} + +fn render_children( + children: List(Node(a)), + builder: Builder(a, output), +) -> output { + children + |> list.map(builder.map) + |> builder.fold() +} + +fn render_attrs(attrs: List(Attr(a))) -> StringBuilder { + attrs + |> list.map(render_attr) + |> list.fold(string_builder.new(), string_builder.append_builder) +} + +fn render_attr(attr: Attr(a)) -> StringBuilder { + case attr { + Attr(name, value) -> { + let sanitized_value = + value + |> string.replace("\"", """) + |> string.replace(">", ">") + string_builder.from_strings([" ", name, "=\"", sanitized_value, "\""]) + } + Event(_name, _action) -> { + string_builder.new() + } + } +} + +fn render_document_node(tree: Node(a)) -> Document { + case tree { + html.Doctype(doctype) -> document.from_doctype(doctype) + + html.Html(attrs, children) -> + render_children(children, document_builder) + |> document.append_html_attrs(render_attrs(attrs)) + + html.Head(children) -> + render_children(children, document_builder) + |> document.into_head() + + html.Body(attrs, children) -> + render_children(children, document_builder) + |> document.append_body_attrs(render_attrs(attrs)) + + html.Fragment(children) -> render_children(children, document_builder) + + html.Element(tag, attrs, children) -> { + let child_document = render_children(children, document_builder) + string_builder.concat([ + string_builder.from_strings(["<", tag]), + render_attrs(attrs), + string_builder.from_string(">"), + child_document.body, + string_builder.from_strings(["</", tag, ">"]), + ]) + |> document.replace_body(child_document, _) + } + + html.LeafElement(tag, attrs) -> + string_builder.concat([ + string_builder.from_strings(["<", tag]), + render_attrs(attrs), + string_builder.from_string(" />"), + ]) + |> document.from_body() + + html.Comment(content) -> { + let content = + content + |> string.replace("-->", "") + string_builder.from_strings(["<!-- ", content, " -->"]) + |> document.from_body() + } + + html.Text(content) -> + string_builder.from_string(content) + |> string_builder.replace("&", "&") + |> string_builder.replace("<", "<") + |> string_builder.replace(">", ">") + |> document.from_body() + + html.UnsafeText(content) -> + string_builder.from_string(content) + |> document.from_body() + + html.Script(script) -> document.from_script(script) + + html.Nothing -> document.new() + } +} + +fn render_inline_node(tree: Node(a)) -> StringBuilder { + case tree { + html.Doctype(doctype) -> render_doctype(doctype) + + html.Html(attrs, children) -> + render_inline_node(html.Element("html", attrs, children)) + + html.Head(children) -> + render_inline_node(html.Element("head", [], children)) + + html.Body(attrs, children) -> + render_inline_node(html.Element("body", attrs, children)) + + html.Fragment(children) -> render_children(children, inline_builder) + + html.Element(tag, attrs, children) -> { + let child_document = render_children(children, inline_builder) + string_builder.concat([ + string_builder.from_strings(["<", tag]), + render_attrs(attrs), + string_builder.from_string(">"), + child_document, + string_builder.from_strings(["</", tag, ">"]), + ]) + } + + html.LeafElement(tag, attrs) -> + string_builder.concat([ + string_builder.from_strings(["<", tag]), + render_attrs(attrs), + string_builder.from_string(" />"), + ]) + + html.Comment(content) -> { + let content = + content + |> string.replace("-->", "") + string_builder.from_strings(["<!-- ", content, " -->"]) + } + + html.Text(content) -> + string_builder.from_string(content) + |> string_builder.replace("&", "&") + |> string_builder.replace("<", "<") + |> string_builder.replace(">", ">") + + html.UnsafeText(content) -> string_builder.from_string(content) + + html.Script(script) -> + render_inline_node(html.Element("script", [], [html.Text(script)])) + + html.Nothing -> string_builder.new() + } +} + +fn render_script(script: String) -> StringBuilder { + string_builder.concat([ + string_builder.from_string("<script>"), + string_builder.from_string(script), + string_builder.from_string("</script>\n"), + ]) +} + +fn render_scripts(scripts: List(String)) -> StringBuilder { + scripts + |> list.map(render_script) + |> string_builder.concat() +} + +pub fn render_document(tree: Node(a)) -> StringBuilder { + let result = render_document_node(tree) + string_builder.concat([ + render_doctype( + result.doctype + |> option.unwrap("html"), + ), + string_builder.from_string("<html"), + result.html_attrs, + string_builder.from_string(">\n<head>" <> document.encoding), + result.head, + string_builder.from_string("</head>\n<body"), + result.body_attrs, + string_builder.from_string(">"), + result.body, + render_scripts(result.scripts), + string_builder.from_string("</body>\n</html>\n"), + ]) +} + +pub fn render_inline(tree: Node(a)) -> StringBuilder { + render_inline_node(tree) +} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl new file mode 100644 index 00000000000..ee2b3a30198 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl @@ -0,0 +1,34 @@ +-module(nakai@experimental@head). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([title/1, link/2, meta/2, http_equiv/2, charset/1]). + +-spec title(binary()) -> nakai@html:node_(any()). +title(Title) -> + {head, [nakai@html:title(Title)]}. + +-spec link(binary(), binary()) -> nakai@html:node_(any()). +link(Rel, Href) -> + {head, + [nakai@html:link( + [nakai@html@attrs:rel(Rel), nakai@html@attrs:href(Href)] + )]}. + +-spec meta(binary(), binary()) -> nakai@html:node_(any()). +meta(Name, Content) -> + {head, + [nakai@html:meta( + [nakai@html@attrs:name(Name), nakai@html@attrs:content(Content)] + )]}. + +-spec http_equiv(binary(), binary()) -> nakai@html:node_(any()). +http_equiv(Header, Content) -> + {head, + [nakai@html:meta( + [nakai@html@attrs:http_equiv(Header), + nakai@html@attrs:content(Content)] + )]}. + +-spec charset(binary()) -> nakai@html:node_(any()). +charset(Charset) -> + {head, [nakai@html:meta([nakai@html@attrs:charset(Charset)])]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl new file mode 100644 index 00000000000..447491b17a6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl @@ -0,0 +1,8 @@ +-module(nakai@experimental@on). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([click/1]). + +-spec click(binary()) -> nakai@html@attrs:attr(any()). +click(Script) -> + {attr, <<"onclick"/utf8>>, Script}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl new file mode 100644 index 00000000000..d1a7ff36142 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl @@ -0,0 +1,12 @@ +-module(nakai@experimental@web_components). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([slot/1, template/2]). + +-spec slot(list(nakai@html@attrs:attr(ICF))) -> nakai@html:node_(ICF). +slot(Attrs) -> + {leaf_element, <<"slot"/utf8>>, Attrs}. + +-spec template(list(nakai@html@attrs:attr(ICJ)), list(nakai@html:node_(ICJ))) -> nakai@html:node_(ICJ). +template(Attrs, Children) -> + {element, <<"template"/utf8>>, Attrs, Children}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl new file mode 100644 index 00000000000..52c46d513f4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl @@ -0,0 +1,830 @@ +-module(nakai@html). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([title/1, a/2, a_text/2, abbr/2, abbr_text/2, address/2, address_text/2, area/1, article/2, article_text/2, aside/2, aside_text/2, audio/2, audio_text/2, b/2, b_text/2, base/1, bdi/2, bdi_text/2, bdo/2, bdo_text/2, blockquote/2, blockquote_text/2, br/1, button/2, button_text/2, canvas/2, canvas_text/2, caption/2, caption_text/2, cite/2, cite_text/2, code/2, code_text/2, col/2, col_text/2, colgroup/2, colgroup_text/2, data/2, data_text/2, datalist/2, datalist_text/2, dd/2, dd_text/2, del/2, del_text/2, details/2, details_text/2, dfn/2, dfn_text/2, dialog/2, dialog_text/2, 'div'/2, div_text/2, dl/2, dl_text/2, dt/2, dt_text/2, em/2, em_text/2, embed/2, embed_text/2, fieldset/2, fieldset_text/2, figcaption/2, figcaption_text/2, figure/2, figure_text/2, footer/2, footer_text/2, form/2, form_text/2, h1/2, h1_text/2, h2/2, h2_text/2, h3/2, h3_text/2, h4/2, h4_text/2, h5/2, h5_text/2, h6/2, h6_text/2, header/2, header_text/2, hr/1, i/2, i_text/2, iframe/2, iframe_text/2, img/1, input/1, ins/2, ins_text/2, kbd/2, kbd_text/2, label/2, label_text/2, legend/2, legend_text/2, li/2, li_text/2, link/1, main/2, main_text/2, map/2, map_text/2, mark/2, mark_text/2, math/2, math_text/2, menu/2, menu_text/2, menuitem/2, menuitem_text/2, meta/1, meter/2, meter_text/2, nav/2, nav_text/2, noscript/2, noscript_text/2, object/2, object_text/2, ol/2, ol_text/2, optgroup/2, optgroup_text/2, option/2, option_text/2, output/2, output_text/2, p/2, p_text/2, param/2, param_text/2, picture/2, picture_text/2, pre/2, pre_text/2, progress/2, progress_text/2, q/2, q_text/2, rp/2, rp_text/2, rt/2, rt_text/2, ruby/2, ruby_text/2, s/2, s_text/2, samp/2, samp_text/2, section/2, section_text/2, select/2, select_text/2, small/2, small_text/2, source/1, span/2, span_text/2, strong/2, strong_text/2, sub/2, sub_text/2, summary/2, summary_text/2, sup/2, sup_text/2, svg/2, svg_text/2, table/2, table_text/2, tbody/2, tbody_text/2, td/2, td_text/2, textarea/2, textarea_text/2, tfoot/2, tfoot_text/2, th/2, th_text/2, thead/2, thead_text/2, time/2, time_text/2, tr/2, tr_text/2, track/1, u/2, u_text/2, ul/2, ul_text/2, var/2, var_text/2, video/2, video_text/2, wbr/2, wbr_text/2]). +-export_type([node_/1]). + +-type node_(FSS) :: {doctype, binary()} | + {html, list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | + {head, list(node_(FSS))} | + {body, list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | + {fragment, list(node_(FSS))} | + {element, binary(), list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | + {leaf_element, binary(), list(nakai@html@attrs:attr(FSS))} | + {comment, binary()} | + {text, binary()} | + {unsafe_text, binary()} | + {script, binary()} | + nothing. + +-spec title(binary()) -> node_(any()). +title(Text) -> + {element, <<"title"/utf8>>, [], [{text, Text}]}. + +-spec a(list(nakai@html@attrs:attr(FSV)), list(node_(FSV))) -> node_(FSV). +a(Attrs, Children) -> + {element, <<"a"/utf8>>, Attrs, Children}. + +-spec a_text(list(nakai@html@attrs:attr(FTB)), binary()) -> node_(FTB). +a_text(Attrs, Text) -> + {element, <<"a"/utf8>>, Attrs, [{text, Text}]}. + +-spec abbr(list(nakai@html@attrs:attr(FTF)), list(node_(FTF))) -> node_(FTF). +abbr(Attrs, Children) -> + {element, <<"abbr"/utf8>>, Attrs, Children}. + +-spec abbr_text(list(nakai@html@attrs:attr(FTL)), binary()) -> node_(FTL). +abbr_text(Attrs, Text) -> + {element, <<"abbr"/utf8>>, Attrs, [{text, Text}]}. + +-spec address(list(nakai@html@attrs:attr(FTP)), list(node_(FTP))) -> node_(FTP). +address(Attrs, Children) -> + {element, <<"address"/utf8>>, Attrs, Children}. + +-spec address_text(list(nakai@html@attrs:attr(FTV)), binary()) -> node_(FTV). +address_text(Attrs, Text) -> + {element, <<"address"/utf8>>, Attrs, [{text, Text}]}. + +-spec area(list(nakai@html@attrs:attr(FTZ))) -> node_(FTZ). +area(Attrs) -> + {leaf_element, <<"area"/utf8>>, Attrs}. + +-spec article(list(nakai@html@attrs:attr(FUD)), list(node_(FUD))) -> node_(FUD). +article(Attrs, Children) -> + {element, <<"article"/utf8>>, Attrs, Children}. + +-spec article_text(list(nakai@html@attrs:attr(FUJ)), binary()) -> node_(FUJ). +article_text(Attrs, Text) -> + {element, <<"article"/utf8>>, Attrs, [{text, Text}]}. + +-spec aside(list(nakai@html@attrs:attr(FUN)), list(node_(FUN))) -> node_(FUN). +aside(Attrs, Children) -> + {element, <<"aside"/utf8>>, Attrs, Children}. + +-spec aside_text(list(nakai@html@attrs:attr(FUT)), binary()) -> node_(FUT). +aside_text(Attrs, Text) -> + {element, <<"aside"/utf8>>, Attrs, [{text, Text}]}. + +-spec audio(list(nakai@html@attrs:attr(FUX)), list(node_(FUX))) -> node_(FUX). +audio(Attrs, Children) -> + {element, <<"audio"/utf8>>, Attrs, Children}. + +-spec audio_text(list(nakai@html@attrs:attr(FVD)), binary()) -> node_(FVD). +audio_text(Attrs, Text) -> + {element, <<"audio"/utf8>>, Attrs, [{text, Text}]}. + +-spec b(list(nakai@html@attrs:attr(FVH)), list(node_(FVH))) -> node_(FVH). +b(Attrs, Children) -> + {element, <<"b"/utf8>>, Attrs, Children}. + +-spec b_text(list(nakai@html@attrs:attr(FVN)), binary()) -> node_(FVN). +b_text(Attrs, Text) -> + {element, <<"b"/utf8>>, Attrs, [{text, Text}]}. + +-spec base(list(nakai@html@attrs:attr(FVR))) -> node_(FVR). +base(Attrs) -> + {leaf_element, <<"base"/utf8>>, Attrs}. + +-spec bdi(list(nakai@html@attrs:attr(FVV)), list(node_(FVV))) -> node_(FVV). +bdi(Attrs, Children) -> + {element, <<"bdi"/utf8>>, Attrs, Children}. + +-spec bdi_text(list(nakai@html@attrs:attr(FWB)), binary()) -> node_(FWB). +bdi_text(Attrs, Text) -> + {element, <<"bdi"/utf8>>, Attrs, [{text, Text}]}. + +-spec bdo(list(nakai@html@attrs:attr(FWF)), list(node_(FWF))) -> node_(FWF). +bdo(Attrs, Children) -> + {element, <<"bdo"/utf8>>, Attrs, Children}. + +-spec bdo_text(list(nakai@html@attrs:attr(FWL)), binary()) -> node_(FWL). +bdo_text(Attrs, Text) -> + {element, <<"bdo"/utf8>>, Attrs, [{text, Text}]}. + +-spec blockquote(list(nakai@html@attrs:attr(FWP)), list(node_(FWP))) -> node_(FWP). +blockquote(Attrs, Children) -> + {element, <<"blockquote"/utf8>>, Attrs, Children}. + +-spec blockquote_text(list(nakai@html@attrs:attr(FWV)), binary()) -> node_(FWV). +blockquote_text(Attrs, Text) -> + {element, <<"blockquote"/utf8>>, Attrs, [{text, Text}]}. + +-spec br(list(nakai@html@attrs:attr(FWZ))) -> node_(FWZ). +br(Attrs) -> + {leaf_element, <<"br"/utf8>>, Attrs}. + +-spec button(list(nakai@html@attrs:attr(FXD)), list(node_(FXD))) -> node_(FXD). +button(Attrs, Children) -> + {element, <<"button"/utf8>>, Attrs, Children}. + +-spec button_text(list(nakai@html@attrs:attr(FXJ)), binary()) -> node_(FXJ). +button_text(Attrs, Text) -> + {element, <<"button"/utf8>>, Attrs, [{text, Text}]}. + +-spec canvas(list(nakai@html@attrs:attr(FXN)), list(node_(FXN))) -> node_(FXN). +canvas(Attrs, Children) -> + {element, <<"canvas"/utf8>>, Attrs, Children}. + +-spec canvas_text(list(nakai@html@attrs:attr(FXT)), binary()) -> node_(FXT). +canvas_text(Attrs, Text) -> + {element, <<"canvas"/utf8>>, Attrs, [{text, Text}]}. + +-spec caption(list(nakai@html@attrs:attr(FXX)), list(node_(FXX))) -> node_(FXX). +caption(Attrs, Children) -> + {element, <<"caption"/utf8>>, Attrs, Children}. + +-spec caption_text(list(nakai@html@attrs:attr(FYD)), binary()) -> node_(FYD). +caption_text(Attrs, Text) -> + {element, <<"caption"/utf8>>, Attrs, [{text, Text}]}. + +-spec cite(list(nakai@html@attrs:attr(FYH)), list(node_(FYH))) -> node_(FYH). +cite(Attrs, Children) -> + {element, <<"cite"/utf8>>, Attrs, Children}. + +-spec cite_text(list(nakai@html@attrs:attr(FYN)), binary()) -> node_(FYN). +cite_text(Attrs, Text) -> + {element, <<"cite"/utf8>>, Attrs, [{text, Text}]}. + +-spec code(list(nakai@html@attrs:attr(FYR)), list(node_(FYR))) -> node_(FYR). +code(Attrs, Children) -> + {element, <<"code"/utf8>>, Attrs, Children}. + +-spec code_text(list(nakai@html@attrs:attr(FYX)), binary()) -> node_(FYX). +code_text(Attrs, Text) -> + {element, <<"code"/utf8>>, Attrs, [{text, Text}]}. + +-spec col(list(nakai@html@attrs:attr(FZB)), list(node_(FZB))) -> node_(FZB). +col(Attrs, Children) -> + {element, <<"col"/utf8>>, Attrs, Children}. + +-spec col_text(list(nakai@html@attrs:attr(FZH)), binary()) -> node_(FZH). +col_text(Attrs, Text) -> + {element, <<"col"/utf8>>, Attrs, [{text, Text}]}. + +-spec colgroup(list(nakai@html@attrs:attr(FZL)), list(node_(FZL))) -> node_(FZL). +colgroup(Attrs, Children) -> + {element, <<"colgroup"/utf8>>, Attrs, Children}. + +-spec colgroup_text(list(nakai@html@attrs:attr(FZR)), binary()) -> node_(FZR). +colgroup_text(Attrs, Text) -> + {element, <<"colgroup"/utf8>>, Attrs, [{text, Text}]}. + +-spec data(list(nakai@html@attrs:attr(FZV)), list(node_(FZV))) -> node_(FZV). +data(Attrs, Children) -> + {element, <<"data"/utf8>>, Attrs, Children}. + +-spec data_text(list(nakai@html@attrs:attr(GAB)), binary()) -> node_(GAB). +data_text(Attrs, Text) -> + {element, <<"data"/utf8>>, Attrs, [{text, Text}]}. + +-spec datalist(list(nakai@html@attrs:attr(GAF)), list(node_(GAF))) -> node_(GAF). +datalist(Attrs, Children) -> + {element, <<"datalist"/utf8>>, Attrs, Children}. + +-spec datalist_text(list(nakai@html@attrs:attr(GAL)), binary()) -> node_(GAL). +datalist_text(Attrs, Text) -> + {element, <<"datalist"/utf8>>, Attrs, [{text, Text}]}. + +-spec dd(list(nakai@html@attrs:attr(GAP)), list(node_(GAP))) -> node_(GAP). +dd(Attrs, Children) -> + {element, <<"dd"/utf8>>, Attrs, Children}. + +-spec dd_text(list(nakai@html@attrs:attr(GAV)), binary()) -> node_(GAV). +dd_text(Attrs, Text) -> + {element, <<"dd"/utf8>>, Attrs, [{text, Text}]}. + +-spec del(list(nakai@html@attrs:attr(GAZ)), list(node_(GAZ))) -> node_(GAZ). +del(Attrs, Children) -> + {element, <<"del"/utf8>>, Attrs, Children}. + +-spec del_text(list(nakai@html@attrs:attr(GBF)), binary()) -> node_(GBF). +del_text(Attrs, Text) -> + {element, <<"del"/utf8>>, Attrs, [{text, Text}]}. + +-spec details(list(nakai@html@attrs:attr(GBJ)), list(node_(GBJ))) -> node_(GBJ). +details(Attrs, Children) -> + {element, <<"details"/utf8>>, Attrs, Children}. + +-spec details_text(list(nakai@html@attrs:attr(GBP)), binary()) -> node_(GBP). +details_text(Attrs, Text) -> + {element, <<"details"/utf8>>, Attrs, [{text, Text}]}. + +-spec dfn(list(nakai@html@attrs:attr(GBT)), list(node_(GBT))) -> node_(GBT). +dfn(Attrs, Children) -> + {element, <<"dfn"/utf8>>, Attrs, Children}. + +-spec dfn_text(list(nakai@html@attrs:attr(GBZ)), binary()) -> node_(GBZ). +dfn_text(Attrs, Text) -> + {element, <<"dfn"/utf8>>, Attrs, [{text, Text}]}. + +-spec dialog(list(nakai@html@attrs:attr(GCD)), list(node_(GCD))) -> node_(GCD). +dialog(Attrs, Children) -> + {element, <<"dialog"/utf8>>, Attrs, Children}. + +-spec dialog_text(list(nakai@html@attrs:attr(GCJ)), binary()) -> node_(GCJ). +dialog_text(Attrs, Text) -> + {element, <<"dialog"/utf8>>, Attrs, [{text, Text}]}. + +-spec 'div'(list(nakai@html@attrs:attr(GCN)), list(node_(GCN))) -> node_(GCN). +'div'(Attrs, Children) -> + {element, <<"div"/utf8>>, Attrs, Children}. + +-spec div_text(list(nakai@html@attrs:attr(GCT)), binary()) -> node_(GCT). +div_text(Attrs, Text) -> + {element, <<"div"/utf8>>, Attrs, [{text, Text}]}. + +-spec dl(list(nakai@html@attrs:attr(GCX)), list(node_(GCX))) -> node_(GCX). +dl(Attrs, Children) -> + {element, <<"dl"/utf8>>, Attrs, Children}. + +-spec dl_text(list(nakai@html@attrs:attr(GDD)), binary()) -> node_(GDD). +dl_text(Attrs, Text) -> + {element, <<"dl"/utf8>>, Attrs, [{text, Text}]}. + +-spec dt(list(nakai@html@attrs:attr(GDH)), list(node_(GDH))) -> node_(GDH). +dt(Attrs, Children) -> + {element, <<"dt"/utf8>>, Attrs, Children}. + +-spec dt_text(list(nakai@html@attrs:attr(GDN)), binary()) -> node_(GDN). +dt_text(Attrs, Text) -> + {element, <<"dt"/utf8>>, Attrs, [{text, Text}]}. + +-spec em(list(nakai@html@attrs:attr(GDR)), list(node_(GDR))) -> node_(GDR). +em(Attrs, Children) -> + {element, <<"em"/utf8>>, Attrs, Children}. + +-spec em_text(list(nakai@html@attrs:attr(GDX)), binary()) -> node_(GDX). +em_text(Attrs, Text) -> + {element, <<"em"/utf8>>, Attrs, [{text, Text}]}. + +-spec embed(list(nakai@html@attrs:attr(GEB)), list(node_(GEB))) -> node_(GEB). +embed(Attrs, Children) -> + {element, <<"embed"/utf8>>, Attrs, Children}. + +-spec embed_text(list(nakai@html@attrs:attr(GEH)), binary()) -> node_(GEH). +embed_text(Attrs, Text) -> + {element, <<"embed"/utf8>>, Attrs, [{text, Text}]}. + +-spec fieldset(list(nakai@html@attrs:attr(GEL)), list(node_(GEL))) -> node_(GEL). +fieldset(Attrs, Children) -> + {element, <<"fieldset"/utf8>>, Attrs, Children}. + +-spec fieldset_text(list(nakai@html@attrs:attr(GER)), binary()) -> node_(GER). +fieldset_text(Attrs, Text) -> + {element, <<"fieldset"/utf8>>, Attrs, [{text, Text}]}. + +-spec figcaption(list(nakai@html@attrs:attr(GEV)), list(node_(GEV))) -> node_(GEV). +figcaption(Attrs, Children) -> + {element, <<"figcaption"/utf8>>, Attrs, Children}. + +-spec figcaption_text(list(nakai@html@attrs:attr(GFB)), binary()) -> node_(GFB). +figcaption_text(Attrs, Text) -> + {element, <<"figcaption"/utf8>>, Attrs, [{text, Text}]}. + +-spec figure(list(nakai@html@attrs:attr(GFF)), list(node_(GFF))) -> node_(GFF). +figure(Attrs, Children) -> + {element, <<"figure"/utf8>>, Attrs, Children}. + +-spec figure_text(list(nakai@html@attrs:attr(GFL)), binary()) -> node_(GFL). +figure_text(Attrs, Text) -> + {element, <<"figure"/utf8>>, Attrs, [{text, Text}]}. + +-spec footer(list(nakai@html@attrs:attr(GFP)), list(node_(GFP))) -> node_(GFP). +footer(Attrs, Children) -> + {element, <<"footer"/utf8>>, Attrs, Children}. + +-spec footer_text(list(nakai@html@attrs:attr(GFV)), binary()) -> node_(GFV). +footer_text(Attrs, Text) -> + {element, <<"footer"/utf8>>, Attrs, [{text, Text}]}. + +-spec form(list(nakai@html@attrs:attr(GFZ)), list(node_(GFZ))) -> node_(GFZ). +form(Attrs, Children) -> + {element, <<"form"/utf8>>, Attrs, Children}. + +-spec form_text(list(nakai@html@attrs:attr(GGF)), binary()) -> node_(GGF). +form_text(Attrs, Text) -> + {element, <<"form"/utf8>>, Attrs, [{text, Text}]}. + +-spec h1(list(nakai@html@attrs:attr(GGJ)), list(node_(GGJ))) -> node_(GGJ). +h1(Attrs, Children) -> + {element, <<"h1"/utf8>>, Attrs, Children}. + +-spec h1_text(list(nakai@html@attrs:attr(GGP)), binary()) -> node_(GGP). +h1_text(Attrs, Text) -> + {element, <<"h1"/utf8>>, Attrs, [{text, Text}]}. + +-spec h2(list(nakai@html@attrs:attr(GGT)), list(node_(GGT))) -> node_(GGT). +h2(Attrs, Children) -> + {element, <<"h2"/utf8>>, Attrs, Children}. + +-spec h2_text(list(nakai@html@attrs:attr(GGZ)), binary()) -> node_(GGZ). +h2_text(Attrs, Text) -> + {element, <<"h2"/utf8>>, Attrs, [{text, Text}]}. + +-spec h3(list(nakai@html@attrs:attr(GHD)), list(node_(GHD))) -> node_(GHD). +h3(Attrs, Children) -> + {element, <<"h3"/utf8>>, Attrs, Children}. + +-spec h3_text(list(nakai@html@attrs:attr(GHJ)), binary()) -> node_(GHJ). +h3_text(Attrs, Text) -> + {element, <<"h3"/utf8>>, Attrs, [{text, Text}]}. + +-spec h4(list(nakai@html@attrs:attr(GHN)), list(node_(GHN))) -> node_(GHN). +h4(Attrs, Children) -> + {element, <<"h4"/utf8>>, Attrs, Children}. + +-spec h4_text(list(nakai@html@attrs:attr(GHT)), binary()) -> node_(GHT). +h4_text(Attrs, Text) -> + {element, <<"h4"/utf8>>, Attrs, [{text, Text}]}. + +-spec h5(list(nakai@html@attrs:attr(GHX)), list(node_(GHX))) -> node_(GHX). +h5(Attrs, Children) -> + {element, <<"h5"/utf8>>, Attrs, Children}. + +-spec h5_text(list(nakai@html@attrs:attr(GID)), binary()) -> node_(GID). +h5_text(Attrs, Text) -> + {element, <<"h5"/utf8>>, Attrs, [{text, Text}]}. + +-spec h6(list(nakai@html@attrs:attr(GIH)), list(node_(GIH))) -> node_(GIH). +h6(Attrs, Children) -> + {element, <<"h6"/utf8>>, Attrs, Children}. + +-spec h6_text(list(nakai@html@attrs:attr(GIN)), binary()) -> node_(GIN). +h6_text(Attrs, Text) -> + {element, <<"h6"/utf8>>, Attrs, [{text, Text}]}. + +-spec header(list(nakai@html@attrs:attr(GIR)), list(node_(GIR))) -> node_(GIR). +header(Attrs, Children) -> + {element, <<"header"/utf8>>, Attrs, Children}. + +-spec header_text(list(nakai@html@attrs:attr(GIX)), binary()) -> node_(GIX). +header_text(Attrs, Text) -> + {element, <<"header"/utf8>>, Attrs, [{text, Text}]}. + +-spec hr(list(nakai@html@attrs:attr(GJB))) -> node_(GJB). +hr(Attrs) -> + {leaf_element, <<"hr"/utf8>>, Attrs}. + +-spec i(list(nakai@html@attrs:attr(GJF)), list(node_(GJF))) -> node_(GJF). +i(Attrs, Children) -> + {element, <<"i"/utf8>>, Attrs, Children}. + +-spec i_text(list(nakai@html@attrs:attr(GJL)), binary()) -> node_(GJL). +i_text(Attrs, Text) -> + {element, <<"i"/utf8>>, Attrs, [{text, Text}]}. + +-spec iframe(list(nakai@html@attrs:attr(GJP)), list(node_(GJP))) -> node_(GJP). +iframe(Attrs, Children) -> + {element, <<"iframe"/utf8>>, Attrs, Children}. + +-spec iframe_text(list(nakai@html@attrs:attr(GJV)), binary()) -> node_(GJV). +iframe_text(Attrs, Text) -> + {element, <<"iframe"/utf8>>, Attrs, [{text, Text}]}. + +-spec img(list(nakai@html@attrs:attr(GJZ))) -> node_(GJZ). +img(Attrs) -> + {leaf_element, <<"img"/utf8>>, Attrs}. + +-spec input(list(nakai@html@attrs:attr(GKD))) -> node_(GKD). +input(Attrs) -> + {leaf_element, <<"input"/utf8>>, Attrs}. + +-spec ins(list(nakai@html@attrs:attr(GKH)), list(node_(GKH))) -> node_(GKH). +ins(Attrs, Children) -> + {element, <<"ins"/utf8>>, Attrs, Children}. + +-spec ins_text(list(nakai@html@attrs:attr(GKN)), binary()) -> node_(GKN). +ins_text(Attrs, Text) -> + {element, <<"ins"/utf8>>, Attrs, [{text, Text}]}. + +-spec kbd(list(nakai@html@attrs:attr(GKR)), list(node_(GKR))) -> node_(GKR). +kbd(Attrs, Children) -> + {element, <<"kbd"/utf8>>, Attrs, Children}. + +-spec kbd_text(list(nakai@html@attrs:attr(GKX)), binary()) -> node_(GKX). +kbd_text(Attrs, Text) -> + {element, <<"kbd"/utf8>>, Attrs, [{text, Text}]}. + +-spec label(list(nakai@html@attrs:attr(GLB)), list(node_(GLB))) -> node_(GLB). +label(Attrs, Children) -> + {element, <<"label"/utf8>>, Attrs, Children}. + +-spec label_text(list(nakai@html@attrs:attr(GLH)), binary()) -> node_(GLH). +label_text(Attrs, Text) -> + {element, <<"label"/utf8>>, Attrs, [{text, Text}]}. + +-spec legend(list(nakai@html@attrs:attr(GLL)), list(node_(GLL))) -> node_(GLL). +legend(Attrs, Children) -> + {element, <<"legend"/utf8>>, Attrs, Children}. + +-spec legend_text(list(nakai@html@attrs:attr(GLR)), binary()) -> node_(GLR). +legend_text(Attrs, Text) -> + {element, <<"legend"/utf8>>, Attrs, [{text, Text}]}. + +-spec li(list(nakai@html@attrs:attr(GLV)), list(node_(GLV))) -> node_(GLV). +li(Attrs, Children) -> + {element, <<"li"/utf8>>, Attrs, Children}. + +-spec li_text(list(nakai@html@attrs:attr(GMB)), binary()) -> node_(GMB). +li_text(Attrs, Text) -> + {element, <<"li"/utf8>>, Attrs, [{text, Text}]}. + +-spec link(list(nakai@html@attrs:attr(GMF))) -> node_(GMF). +link(Attrs) -> + {leaf_element, <<"link"/utf8>>, Attrs}. + +-spec main(list(nakai@html@attrs:attr(GMJ)), list(node_(GMJ))) -> node_(GMJ). +main(Attrs, Children) -> + {element, <<"main"/utf8>>, Attrs, Children}. + +-spec main_text(list(nakai@html@attrs:attr(GMP)), binary()) -> node_(GMP). +main_text(Attrs, Text) -> + {element, <<"main"/utf8>>, Attrs, [{text, Text}]}. + +-spec map(list(nakai@html@attrs:attr(GMT)), list(node_(GMT))) -> node_(GMT). +map(Attrs, Children) -> + {element, <<"map"/utf8>>, Attrs, Children}. + +-spec map_text(list(nakai@html@attrs:attr(GMZ)), binary()) -> node_(GMZ). +map_text(Attrs, Text) -> + {element, <<"map"/utf8>>, Attrs, [{text, Text}]}. + +-spec mark(list(nakai@html@attrs:attr(GND)), list(node_(GND))) -> node_(GND). +mark(Attrs, Children) -> + {element, <<"mark"/utf8>>, Attrs, Children}. + +-spec mark_text(list(nakai@html@attrs:attr(GNJ)), binary()) -> node_(GNJ). +mark_text(Attrs, Text) -> + {element, <<"mark"/utf8>>, Attrs, [{text, Text}]}. + +-spec math(list(nakai@html@attrs:attr(GNN)), list(node_(GNN))) -> node_(GNN). +math(Attrs, Children) -> + {element, <<"math"/utf8>>, Attrs, Children}. + +-spec math_text(list(nakai@html@attrs:attr(GNT)), binary()) -> node_(GNT). +math_text(Attrs, Text) -> + {element, <<"math"/utf8>>, Attrs, [{text, Text}]}. + +-spec menu(list(nakai@html@attrs:attr(GNX)), list(node_(GNX))) -> node_(GNX). +menu(Attrs, Children) -> + {element, <<"menu"/utf8>>, Attrs, Children}. + +-spec menu_text(list(nakai@html@attrs:attr(GOD)), binary()) -> node_(GOD). +menu_text(Attrs, Text) -> + {element, <<"menu"/utf8>>, Attrs, [{text, Text}]}. + +-spec menuitem(list(nakai@html@attrs:attr(GOH)), list(node_(GOH))) -> node_(GOH). +menuitem(Attrs, Children) -> + {element, <<"menuitem"/utf8>>, Attrs, Children}. + +-spec menuitem_text(list(nakai@html@attrs:attr(GON)), binary()) -> node_(GON). +menuitem_text(Attrs, Text) -> + {element, <<"menuitem"/utf8>>, Attrs, [{text, Text}]}. + +-spec meta(list(nakai@html@attrs:attr(GOR))) -> node_(GOR). +meta(Attrs) -> + {leaf_element, <<"meta"/utf8>>, Attrs}. + +-spec meter(list(nakai@html@attrs:attr(GOV)), list(node_(GOV))) -> node_(GOV). +meter(Attrs, Children) -> + {element, <<"meter"/utf8>>, Attrs, Children}. + +-spec meter_text(list(nakai@html@attrs:attr(GPB)), binary()) -> node_(GPB). +meter_text(Attrs, Text) -> + {element, <<"meter"/utf8>>, Attrs, [{text, Text}]}. + +-spec nav(list(nakai@html@attrs:attr(GPF)), list(node_(GPF))) -> node_(GPF). +nav(Attrs, Children) -> + {element, <<"nav"/utf8>>, Attrs, Children}. + +-spec nav_text(list(nakai@html@attrs:attr(GPL)), binary()) -> node_(GPL). +nav_text(Attrs, Text) -> + {element, <<"nav"/utf8>>, Attrs, [{text, Text}]}. + +-spec noscript(list(nakai@html@attrs:attr(GPP)), list(node_(GPP))) -> node_(GPP). +noscript(Attrs, Children) -> + {element, <<"noscript"/utf8>>, Attrs, Children}. + +-spec noscript_text(list(nakai@html@attrs:attr(GPV)), binary()) -> node_(GPV). +noscript_text(Attrs, Text) -> + {element, <<"noscript"/utf8>>, Attrs, [{text, Text}]}. + +-spec object(list(nakai@html@attrs:attr(GPZ)), list(node_(GPZ))) -> node_(GPZ). +object(Attrs, Children) -> + {element, <<"object"/utf8>>, Attrs, Children}. + +-spec object_text(list(nakai@html@attrs:attr(GQF)), binary()) -> node_(GQF). +object_text(Attrs, Text) -> + {element, <<"object"/utf8>>, Attrs, [{text, Text}]}. + +-spec ol(list(nakai@html@attrs:attr(GQJ)), list(node_(GQJ))) -> node_(GQJ). +ol(Attrs, Children) -> + {element, <<"ol"/utf8>>, Attrs, Children}. + +-spec ol_text(list(nakai@html@attrs:attr(GQP)), binary()) -> node_(GQP). +ol_text(Attrs, Text) -> + {element, <<"ol"/utf8>>, Attrs, [{text, Text}]}. + +-spec optgroup(list(nakai@html@attrs:attr(GQT)), list(node_(GQT))) -> node_(GQT). +optgroup(Attrs, Children) -> + {element, <<"optgroup"/utf8>>, Attrs, Children}. + +-spec optgroup_text(list(nakai@html@attrs:attr(GQZ)), binary()) -> node_(GQZ). +optgroup_text(Attrs, Text) -> + {element, <<"optgroup"/utf8>>, Attrs, [{text, Text}]}. + +-spec option(list(nakai@html@attrs:attr(GRD)), list(node_(GRD))) -> node_(GRD). +option(Attrs, Children) -> + {element, <<"option"/utf8>>, Attrs, Children}. + +-spec option_text(list(nakai@html@attrs:attr(GRJ)), binary()) -> node_(GRJ). +option_text(Attrs, Text) -> + {element, <<"option"/utf8>>, Attrs, [{text, Text}]}. + +-spec output(list(nakai@html@attrs:attr(GRN)), list(node_(GRN))) -> node_(GRN). +output(Attrs, Children) -> + {element, <<"output"/utf8>>, Attrs, Children}. + +-spec output_text(list(nakai@html@attrs:attr(GRT)), binary()) -> node_(GRT). +output_text(Attrs, Text) -> + {element, <<"output"/utf8>>, Attrs, [{text, Text}]}. + +-spec p(list(nakai@html@attrs:attr(GRX)), list(node_(GRX))) -> node_(GRX). +p(Attrs, Children) -> + {element, <<"p"/utf8>>, Attrs, Children}. + +-spec p_text(list(nakai@html@attrs:attr(GSD)), binary()) -> node_(GSD). +p_text(Attrs, Text) -> + {element, <<"p"/utf8>>, Attrs, [{text, Text}]}. + +-spec param(list(nakai@html@attrs:attr(GSH)), list(node_(GSH))) -> node_(GSH). +param(Attrs, Children) -> + {element, <<"param"/utf8>>, Attrs, Children}. + +-spec param_text(list(nakai@html@attrs:attr(GSN)), binary()) -> node_(GSN). +param_text(Attrs, Text) -> + {element, <<"param"/utf8>>, Attrs, [{text, Text}]}. + +-spec picture(list(nakai@html@attrs:attr(GSR)), list(node_(GSR))) -> node_(GSR). +picture(Attrs, Children) -> + {element, <<"picture"/utf8>>, Attrs, Children}. + +-spec picture_text(list(nakai@html@attrs:attr(GSX)), binary()) -> node_(GSX). +picture_text(Attrs, Text) -> + {element, <<"picture"/utf8>>, Attrs, [{text, Text}]}. + +-spec pre(list(nakai@html@attrs:attr(GTB)), list(node_(GTB))) -> node_(GTB). +pre(Attrs, Children) -> + {element, <<"pre"/utf8>>, Attrs, Children}. + +-spec pre_text(list(nakai@html@attrs:attr(GTH)), binary()) -> node_(GTH). +pre_text(Attrs, Text) -> + {element, <<"pre"/utf8>>, Attrs, [{text, Text}]}. + +-spec progress(list(nakai@html@attrs:attr(GTL)), list(node_(GTL))) -> node_(GTL). +progress(Attrs, Children) -> + {element, <<"progress"/utf8>>, Attrs, Children}. + +-spec progress_text(list(nakai@html@attrs:attr(GTR)), binary()) -> node_(GTR). +progress_text(Attrs, Text) -> + {element, <<"progress"/utf8>>, Attrs, [{text, Text}]}. + +-spec q(list(nakai@html@attrs:attr(GTV)), list(node_(GTV))) -> node_(GTV). +q(Attrs, Children) -> + {element, <<"q"/utf8>>, Attrs, Children}. + +-spec q_text(list(nakai@html@attrs:attr(GUB)), binary()) -> node_(GUB). +q_text(Attrs, Text) -> + {element, <<"q"/utf8>>, Attrs, [{text, Text}]}. + +-spec rp(list(nakai@html@attrs:attr(GUF)), list(node_(GUF))) -> node_(GUF). +rp(Attrs, Children) -> + {element, <<"rp"/utf8>>, Attrs, Children}. + +-spec rp_text(list(nakai@html@attrs:attr(GUL)), binary()) -> node_(GUL). +rp_text(Attrs, Text) -> + {element, <<"rp"/utf8>>, Attrs, [{text, Text}]}. + +-spec rt(list(nakai@html@attrs:attr(GUP)), list(node_(GUP))) -> node_(GUP). +rt(Attrs, Children) -> + {element, <<"rt"/utf8>>, Attrs, Children}. + +-spec rt_text(list(nakai@html@attrs:attr(GUV)), binary()) -> node_(GUV). +rt_text(Attrs, Text) -> + {element, <<"rt"/utf8>>, Attrs, [{text, Text}]}. + +-spec ruby(list(nakai@html@attrs:attr(GUZ)), list(node_(GUZ))) -> node_(GUZ). +ruby(Attrs, Children) -> + {element, <<"ruby"/utf8>>, Attrs, Children}. + +-spec ruby_text(list(nakai@html@attrs:attr(GVF)), binary()) -> node_(GVF). +ruby_text(Attrs, Text) -> + {element, <<"ruby"/utf8>>, Attrs, [{text, Text}]}. + +-spec s(list(nakai@html@attrs:attr(GVJ)), list(node_(GVJ))) -> node_(GVJ). +s(Attrs, Children) -> + {element, <<"s"/utf8>>, Attrs, Children}. + +-spec s_text(list(nakai@html@attrs:attr(GVP)), binary()) -> node_(GVP). +s_text(Attrs, Text) -> + {element, <<"s"/utf8>>, Attrs, [{text, Text}]}. + +-spec samp(list(nakai@html@attrs:attr(GVT)), list(node_(GVT))) -> node_(GVT). +samp(Attrs, Children) -> + {element, <<"samp"/utf8>>, Attrs, Children}. + +-spec samp_text(list(nakai@html@attrs:attr(GVZ)), binary()) -> node_(GVZ). +samp_text(Attrs, Text) -> + {element, <<"samp"/utf8>>, Attrs, [{text, Text}]}. + +-spec section(list(nakai@html@attrs:attr(GWD)), list(node_(GWD))) -> node_(GWD). +section(Attrs, Children) -> + {element, <<"section"/utf8>>, Attrs, Children}. + +-spec section_text(list(nakai@html@attrs:attr(GWJ)), binary()) -> node_(GWJ). +section_text(Attrs, Text) -> + {element, <<"section"/utf8>>, Attrs, [{text, Text}]}. + +-spec select(list(nakai@html@attrs:attr(GWN)), list(node_(GWN))) -> node_(GWN). +select(Attrs, Children) -> + {element, <<"select"/utf8>>, Attrs, Children}. + +-spec select_text(list(nakai@html@attrs:attr(GWT)), binary()) -> node_(GWT). +select_text(Attrs, Text) -> + {element, <<"select"/utf8>>, Attrs, [{text, Text}]}. + +-spec small(list(nakai@html@attrs:attr(GWX)), list(node_(GWX))) -> node_(GWX). +small(Attrs, Children) -> + {element, <<"small"/utf8>>, Attrs, Children}. + +-spec small_text(list(nakai@html@attrs:attr(GXD)), binary()) -> node_(GXD). +small_text(Attrs, Text) -> + {element, <<"small"/utf8>>, Attrs, [{text, Text}]}. + +-spec source(list(nakai@html@attrs:attr(GXH))) -> node_(GXH). +source(Attrs) -> + {leaf_element, <<"source"/utf8>>, Attrs}. + +-spec span(list(nakai@html@attrs:attr(GXL)), list(node_(GXL))) -> node_(GXL). +span(Attrs, Children) -> + {element, <<"span"/utf8>>, Attrs, Children}. + +-spec span_text(list(nakai@html@attrs:attr(GXR)), binary()) -> node_(GXR). +span_text(Attrs, Text) -> + {element, <<"span"/utf8>>, Attrs, [{text, Text}]}. + +-spec strong(list(nakai@html@attrs:attr(GXV)), list(node_(GXV))) -> node_(GXV). +strong(Attrs, Children) -> + {element, <<"strong"/utf8>>, Attrs, Children}. + +-spec strong_text(list(nakai@html@attrs:attr(GYB)), binary()) -> node_(GYB). +strong_text(Attrs, Text) -> + {element, <<"strong"/utf8>>, Attrs, [{text, Text}]}. + +-spec sub(list(nakai@html@attrs:attr(GYF)), list(node_(GYF))) -> node_(GYF). +sub(Attrs, Children) -> + {element, <<"sub"/utf8>>, Attrs, Children}. + +-spec sub_text(list(nakai@html@attrs:attr(GYL)), binary()) -> node_(GYL). +sub_text(Attrs, Text) -> + {element, <<"sub"/utf8>>, Attrs, [{text, Text}]}. + +-spec summary(list(nakai@html@attrs:attr(GYP)), list(node_(GYP))) -> node_(GYP). +summary(Attrs, Children) -> + {element, <<"summary"/utf8>>, Attrs, Children}. + +-spec summary_text(list(nakai@html@attrs:attr(GYV)), binary()) -> node_(GYV). +summary_text(Attrs, Text) -> + {element, <<"summary"/utf8>>, Attrs, [{text, Text}]}. + +-spec sup(list(nakai@html@attrs:attr(GYZ)), list(node_(GYZ))) -> node_(GYZ). +sup(Attrs, Children) -> + {element, <<"sup"/utf8>>, Attrs, Children}. + +-spec sup_text(list(nakai@html@attrs:attr(GZF)), binary()) -> node_(GZF). +sup_text(Attrs, Text) -> + {element, <<"sup"/utf8>>, Attrs, [{text, Text}]}. + +-spec svg(list(nakai@html@attrs:attr(GZJ)), list(node_(GZJ))) -> node_(GZJ). +svg(Attrs, Children) -> + {element, <<"svg"/utf8>>, Attrs, Children}. + +-spec svg_text(list(nakai@html@attrs:attr(GZP)), binary()) -> node_(GZP). +svg_text(Attrs, Text) -> + {element, <<"svg"/utf8>>, Attrs, [{text, Text}]}. + +-spec table(list(nakai@html@attrs:attr(GZT)), list(node_(GZT))) -> node_(GZT). +table(Attrs, Children) -> + {element, <<"table"/utf8>>, Attrs, Children}. + +-spec table_text(list(nakai@html@attrs:attr(GZZ)), binary()) -> node_(GZZ). +table_text(Attrs, Text) -> + {element, <<"table"/utf8>>, Attrs, [{text, Text}]}. + +-spec tbody(list(nakai@html@attrs:attr(HAD)), list(node_(HAD))) -> node_(HAD). +tbody(Attrs, Children) -> + {element, <<"tbody"/utf8>>, Attrs, Children}. + +-spec tbody_text(list(nakai@html@attrs:attr(HAJ)), binary()) -> node_(HAJ). +tbody_text(Attrs, Text) -> + {element, <<"tbody"/utf8>>, Attrs, [{text, Text}]}. + +-spec td(list(nakai@html@attrs:attr(HAN)), list(node_(HAN))) -> node_(HAN). +td(Attrs, Children) -> + {element, <<"td"/utf8>>, Attrs, Children}. + +-spec td_text(list(nakai@html@attrs:attr(HAT)), binary()) -> node_(HAT). +td_text(Attrs, Text) -> + {element, <<"td"/utf8>>, Attrs, [{text, Text}]}. + +-spec textarea(list(nakai@html@attrs:attr(HAX)), list(node_(HAX))) -> node_(HAX). +textarea(Attrs, Children) -> + {element, <<"textarea"/utf8>>, Attrs, Children}. + +-spec textarea_text(list(nakai@html@attrs:attr(HBD)), binary()) -> node_(HBD). +textarea_text(Attrs, Text) -> + {element, <<"textarea"/utf8>>, Attrs, [{text, Text}]}. + +-spec tfoot(list(nakai@html@attrs:attr(HBH)), list(node_(HBH))) -> node_(HBH). +tfoot(Attrs, Children) -> + {element, <<"tfoot"/utf8>>, Attrs, Children}. + +-spec tfoot_text(list(nakai@html@attrs:attr(HBN)), binary()) -> node_(HBN). +tfoot_text(Attrs, Text) -> + {element, <<"tfoot"/utf8>>, Attrs, [{text, Text}]}. + +-spec th(list(nakai@html@attrs:attr(HBR)), list(node_(HBR))) -> node_(HBR). +th(Attrs, Children) -> + {element, <<"th"/utf8>>, Attrs, Children}. + +-spec th_text(list(nakai@html@attrs:attr(HBX)), binary()) -> node_(HBX). +th_text(Attrs, Text) -> + {element, <<"th"/utf8>>, Attrs, [{text, Text}]}. + +-spec thead(list(nakai@html@attrs:attr(HCB)), list(node_(HCB))) -> node_(HCB). +thead(Attrs, Children) -> + {element, <<"thead"/utf8>>, Attrs, Children}. + +-spec thead_text(list(nakai@html@attrs:attr(HCH)), binary()) -> node_(HCH). +thead_text(Attrs, Text) -> + {element, <<"thead"/utf8>>, Attrs, [{text, Text}]}. + +-spec time(list(nakai@html@attrs:attr(HCL)), list(node_(HCL))) -> node_(HCL). +time(Attrs, Children) -> + {element, <<"time"/utf8>>, Attrs, Children}. + +-spec time_text(list(nakai@html@attrs:attr(HCR)), binary()) -> node_(HCR). +time_text(Attrs, Text) -> + {element, <<"time"/utf8>>, Attrs, [{text, Text}]}. + +-spec tr(list(nakai@html@attrs:attr(HCV)), list(node_(HCV))) -> node_(HCV). +tr(Attrs, Children) -> + {element, <<"tr"/utf8>>, Attrs, Children}. + +-spec tr_text(list(nakai@html@attrs:attr(HDB)), binary()) -> node_(HDB). +tr_text(Attrs, Text) -> + {element, <<"tr"/utf8>>, Attrs, [{text, Text}]}. + +-spec track(list(nakai@html@attrs:attr(HDF))) -> node_(HDF). +track(Attrs) -> + {leaf_element, <<"track"/utf8>>, Attrs}. + +-spec u(list(nakai@html@attrs:attr(HDJ)), list(node_(HDJ))) -> node_(HDJ). +u(Attrs, Children) -> + {element, <<"u"/utf8>>, Attrs, Children}. + +-spec u_text(list(nakai@html@attrs:attr(HDP)), binary()) -> node_(HDP). +u_text(Attrs, Text) -> + {element, <<"u"/utf8>>, Attrs, [{text, Text}]}. + +-spec ul(list(nakai@html@attrs:attr(HDT)), list(node_(HDT))) -> node_(HDT). +ul(Attrs, Children) -> + {element, <<"ul"/utf8>>, Attrs, Children}. + +-spec ul_text(list(nakai@html@attrs:attr(HDZ)), binary()) -> node_(HDZ). +ul_text(Attrs, Text) -> + {element, <<"ul"/utf8>>, Attrs, [{text, Text}]}. + +-spec var(list(nakai@html@attrs:attr(HED)), list(node_(HED))) -> node_(HED). +var(Attrs, Children) -> + {element, <<"var"/utf8>>, Attrs, Children}. + +-spec var_text(list(nakai@html@attrs:attr(HEJ)), binary()) -> node_(HEJ). +var_text(Attrs, Text) -> + {element, <<"var"/utf8>>, Attrs, [{text, Text}]}. + +-spec video(list(nakai@html@attrs:attr(HEN)), list(node_(HEN))) -> node_(HEN). +video(Attrs, Children) -> + {element, <<"video"/utf8>>, Attrs, Children}. + +-spec video_text(list(nakai@html@attrs:attr(HET)), binary()) -> node_(HET). +video_text(Attrs, Text) -> + {element, <<"video"/utf8>>, Attrs, [{text, Text}]}. + +-spec wbr(list(nakai@html@attrs:attr(HEX)), list(node_(HEX))) -> node_(HEX). +wbr(Attrs, Children) -> + {element, <<"wbr"/utf8>>, Attrs, Children}. + +-spec wbr_text(list(nakai@html@attrs:attr(HFD)), binary()) -> node_(HFD). +wbr_text(Attrs, Text) -> + {element, <<"wbr"/utf8>>, Attrs, [{text, Text}]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl new file mode 100644 index 00000000000..a75887648d0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl @@ -0,0 +1,191 @@ +-module(nakai@html@attrs). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([data/2, accept/1, accept_charset/1, action/1, alt/1, async/0, autocapitalize/1, autocomplete/1, autofocus/0, autoplay/0, capture/1, charset/1, checked/0, cite/1, class/1, content/1, contenteditable/0, crossorigin/0, defer/0, disabled/0, draggable/0, for/1, formaction/1, height/1, href/1, http_equiv/1, id/1, integrity/1, lang/1, loop/0, method/1, name/1, placeholder/1, preload/0, property/1, readonly/0, rel/1, selected/0, src/1, style/1, tabindex/1, target/1, title/1, type_/1, value/1, width/1]). +-export_type([attr/1]). + +-type attr(FNI) :: {attr, binary(), binary()} | {event, binary(), FNI}. + +-spec data(binary(), binary()) -> attr(any()). +data(Name, Value) -> + {attr, <<"data-"/utf8, Name/binary>>, Value}. + +-spec accept(binary()) -> attr(any()). +accept(Value) -> + {attr, <<"accept"/utf8>>, Value}. + +-spec accept_charset(binary()) -> attr(any()). +accept_charset(Value) -> + {attr, <<"accept-charset"/utf8>>, Value}. + +-spec action(binary()) -> attr(any()). +action(Value) -> + {attr, <<"action"/utf8>>, Value}. + +-spec alt(binary()) -> attr(any()). +alt(Value) -> + {attr, <<"alt"/utf8>>, Value}. + +-spec async() -> attr(any()). +async() -> + {attr, <<"async"/utf8>>, <<"true"/utf8>>}. + +-spec autocapitalize(binary()) -> attr(any()). +autocapitalize(Value) -> + {attr, <<"autocapitalize"/utf8>>, Value}. + +-spec autocomplete(binary()) -> attr(any()). +autocomplete(Value) -> + {attr, <<"autocomplete"/utf8>>, Value}. + +-spec autofocus() -> attr(any()). +autofocus() -> + {attr, <<"autofocus"/utf8>>, <<"true"/utf8>>}. + +-spec autoplay() -> attr(any()). +autoplay() -> + {attr, <<"autoplay"/utf8>>, <<"true"/utf8>>}. + +-spec capture(binary()) -> attr(any()). +capture(Value) -> + {attr, <<"capture"/utf8>>, Value}. + +-spec charset(binary()) -> attr(any()). +charset(Value) -> + {attr, <<"charset"/utf8>>, Value}. + +-spec checked() -> attr(any()). +checked() -> + {attr, <<"checked"/utf8>>, <<"true"/utf8>>}. + +-spec cite(binary()) -> attr(any()). +cite(Value) -> + {attr, <<"cite"/utf8>>, Value}. + +-spec class(binary()) -> attr(any()). +class(Value) -> + {attr, <<"class"/utf8>>, Value}. + +-spec content(binary()) -> attr(any()). +content(Value) -> + {attr, <<"content"/utf8>>, Value}. + +-spec contenteditable() -> attr(any()). +contenteditable() -> + {attr, <<"contenteditable"/utf8>>, <<"true"/utf8>>}. + +-spec crossorigin() -> attr(any()). +crossorigin() -> + {attr, <<"crossorigin"/utf8>>, <<"true"/utf8>>}. + +-spec defer() -> attr(any()). +defer() -> + {attr, <<"defer"/utf8>>, <<"true"/utf8>>}. + +-spec disabled() -> attr(any()). +disabled() -> + {attr, <<"disabled"/utf8>>, <<"true"/utf8>>}. + +-spec draggable() -> attr(any()). +draggable() -> + {attr, <<"draggable"/utf8>>, <<"true"/utf8>>}. + +-spec for(binary()) -> attr(any()). +for(Value) -> + {attr, <<"for"/utf8>>, Value}. + +-spec formaction(binary()) -> attr(any()). +formaction(Value) -> + {attr, <<"formaction"/utf8>>, Value}. + +-spec height(binary()) -> attr(any()). +height(Value) -> + {attr, <<"height"/utf8>>, Value}. + +-spec href(binary()) -> attr(any()). +href(Value) -> + {attr, <<"href"/utf8>>, Value}. + +-spec http_equiv(binary()) -> attr(any()). +http_equiv(Value) -> + {attr, <<"http-equiv"/utf8>>, Value}. + +-spec id(binary()) -> attr(any()). +id(Value) -> + {attr, <<"id"/utf8>>, Value}. + +-spec integrity(binary()) -> attr(any()). +integrity(Value) -> + {attr, <<"integrity"/utf8>>, Value}. + +-spec lang(binary()) -> attr(any()). +lang(Value) -> + {attr, <<"lang"/utf8>>, Value}. + +-spec loop() -> attr(any()). +loop() -> + {attr, <<"loop"/utf8>>, <<"true"/utf8>>}. + +-spec method(binary()) -> attr(any()). +method(Value) -> + {attr, <<"method"/utf8>>, Value}. + +-spec name(binary()) -> attr(any()). +name(Value) -> + {attr, <<"name"/utf8>>, Value}. + +-spec placeholder(binary()) -> attr(any()). +placeholder(Value) -> + {attr, <<"placeholder"/utf8>>, Value}. + +-spec preload() -> attr(any()). +preload() -> + {attr, <<"preload"/utf8>>, <<"true"/utf8>>}. + +-spec property(binary()) -> attr(any()). +property(Value) -> + {attr, <<"property"/utf8>>, Value}. + +-spec readonly() -> attr(any()). +readonly() -> + {attr, <<"readonly"/utf8>>, <<"true"/utf8>>}. + +-spec rel(binary()) -> attr(any()). +rel(Value) -> + {attr, <<"rel"/utf8>>, Value}. + +-spec selected() -> attr(any()). +selected() -> + {attr, <<"selected"/utf8>>, <<"true"/utf8>>}. + +-spec src(binary()) -> attr(any()). +src(Value) -> + {attr, <<"src"/utf8>>, Value}. + +-spec style(binary()) -> attr(any()). +style(Value) -> + {attr, <<"style"/utf8>>, Value}. + +-spec tabindex(binary()) -> attr(any()). +tabindex(Value) -> + {attr, <<"tabindex"/utf8>>, Value}. + +-spec target(binary()) -> attr(any()). +target(Value) -> + {attr, <<"target"/utf8>>, Value}. + +-spec title(binary()) -> attr(any()). +title(Value) -> + {attr, <<"title"/utf8>>, Value}. + +-spec type_(binary()) -> attr(any()). +type_(Value) -> + {attr, <<"type"/utf8>>, Value}. + +-spec value(binary()) -> attr(any()). +value(Value) -> + {attr, <<"value"/utf8>>, Value}. + +-spec width(binary()) -> attr(any()). +width(Value) -> + {attr, <<"width"/utf8>>, Value}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl new file mode 100644 index 00000000000..2b544c8d6f6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl @@ -0,0 +1,117 @@ +-module(nakai@internal@document). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/0, merge/2, concat/1, from_doctype/1, append_html_attrs/2, append_body_attrs/2, from_head/1, append_head/2, from_body/1, append_body/2, replace_body/2, from_script/1, into_head/1]). +-export_type([document/0]). + +-type document() :: {document, + gleam@option:option(binary()), + gleam@string_builder:string_builder(), + gleam@string_builder:string_builder(), + gleam@string_builder:string_builder(), + gleam@string_builder:string_builder(), + list(binary())}. + +-spec new() -> document(). +new() -> + {document, + none, + gleam@string_builder:new(), + gleam@string_builder:new(), + gleam@string_builder:new(), + gleam@string_builder:new(), + []}. + +-spec merge(document(), document()) -> document(). +merge(Self, New) -> + {document, + gleam@option:'or'(erlang:element(2, New), erlang:element(2, Self)), + gleam@string_builder:append_builder( + erlang:element(3, Self), + erlang:element(3, New) + ), + gleam@string_builder:append_builder( + erlang:element(4, Self), + erlang:element(4, New) + ), + gleam@string_builder:append_builder( + erlang:element(5, Self), + erlang:element(5, New) + ), + gleam@string_builder:append_builder( + erlang:element(6, Self), + erlang:element(6, New) + ), + gleam@list:append(erlang:element(7, Self), erlang:element(7, New))}. + +-spec concat(list(document())) -> document(). +concat(Docs) -> + _pipe = Docs, + gleam@list:fold(_pipe, new(), fun merge/2). + +-spec from_doctype(binary()) -> document(). +from_doctype(Doctype) -> + erlang:setelement(2, new(), {some, Doctype}). + +-spec append_html_attrs(document(), gleam@string_builder:string_builder()) -> document(). +append_html_attrs(Self, Html_attrs) -> + erlang:setelement( + 3, + Self, + gleam@string_builder:append_builder(erlang:element(3, Self), Html_attrs) + ). + +-spec append_body_attrs(document(), gleam@string_builder:string_builder()) -> document(). +append_body_attrs(Self, Body_attrs) -> + erlang:setelement( + 4, + Self, + gleam@string_builder:append_builder(erlang:element(4, Self), Body_attrs) + ). + +-spec from_head(gleam@string_builder:string_builder()) -> document(). +from_head(Head) -> + erlang:setelement(5, new(), Head). + +-spec append_head(document(), gleam@string_builder:string_builder()) -> document(). +append_head(Self, Head) -> + erlang:setelement( + 5, + Self, + gleam@string_builder:append_builder(erlang:element(5, Self), Head) + ). + +-spec from_body(gleam@string_builder:string_builder()) -> document(). +from_body(Body) -> + erlang:setelement(6, new(), Body). + +-spec append_body(document(), gleam@string_builder:string_builder()) -> document(). +append_body(Self, Body) -> + erlang:setelement( + 6, + Self, + gleam@string_builder:append_builder(erlang:element(6, Self), Body) + ). + +-spec replace_body(document(), gleam@string_builder:string_builder()) -> document(). +replace_body(Self, Body) -> + erlang:setelement(6, Self, Body). + +-spec from_script(binary()) -> document(). +from_script(Script) -> + erlang:setelement(7, new(), [Script]). + +-spec into_head(document()) -> document(). +into_head(State) -> + erlang:setelement( + 6, + erlang:setelement( + 5, + State, + gleam@string_builder:append_builder( + erlang:element(5, State), + erlang:element(6, State) + ) + ), + gleam@string_builder:new() + ). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl new file mode 100644 index 00000000000..ad00173bdd4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl @@ -0,0 +1,297 @@ +-module(nakai@internal@render). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([render_document/1, render_inline/1]). +-export_type([builder/2]). + +-type builder(HVS, HVT) :: {builder, + fun((nakai@html:node_(HVS)) -> HVT), + fun((list(HVT)) -> HVT)}. + +-spec render_doctype(binary()) -> gleam@string_builder:string_builder(). +render_doctype(Doctype) -> + gleam@string_builder:from_strings( + [<<"<!DOCTYPE "/utf8>>, Doctype, <<">\n"/utf8>>] + ). + +-spec render_children(list(nakai@html:node_(HVU)), builder(HVU, HVX)) -> HVX. +render_children(Children, Builder) -> + _pipe = Children, + _pipe@1 = gleam@list:map(_pipe, erlang:element(2, Builder)), + (erlang:element(3, Builder))(_pipe@1). + +-spec render_attr(nakai@html@attrs:attr(any())) -> gleam@string_builder:string_builder(). +render_attr(Attr) -> + case Attr of + {attr, Name, Value} -> + Sanitized_value = begin + _pipe = Value, + _pipe@1 = gleam@string:replace( + _pipe, + <<"\""/utf8>>, + <<"""/utf8>> + ), + gleam@string:replace(_pipe@1, <<">"/utf8>>, <<">"/utf8>>) + end, + gleam@string_builder:from_strings( + [<<" "/utf8>>, + Name, + <<"=\""/utf8>>, + Sanitized_value, + <<"\""/utf8>>] + ); + + {event, _, _} -> + gleam@string_builder:new() + end. + +-spec render_attrs(list(nakai@html@attrs:attr(any()))) -> gleam@string_builder:string_builder(). +render_attrs(Attrs) -> + _pipe = Attrs, + _pipe@1 = gleam@list:map(_pipe, fun render_attr/1), + gleam@list:fold( + _pipe@1, + gleam@string_builder:new(), + fun gleam@string_builder:append_builder/2 + ). + +-spec render_document_node(nakai@html:node_(any())) -> nakai@internal@document:document(). +render_document_node(Tree) -> + case Tree of + {doctype, Doctype} -> + nakai@internal@document:from_doctype(Doctype); + + {html, Attrs, Children} -> + _pipe = render_children( + Children, + {builder, + fun render_document_node/1, + fun nakai@internal@document:concat/1} + ), + nakai@internal@document:append_html_attrs( + _pipe, + render_attrs(Attrs) + ); + + {head, Children@1} -> + _pipe@1 = render_children( + Children@1, + {builder, + fun render_document_node/1, + fun nakai@internal@document:concat/1} + ), + nakai@internal@document:into_head(_pipe@1); + + {body, Attrs@1, Children@2} -> + _pipe@2 = render_children( + Children@2, + {builder, + fun render_document_node/1, + fun nakai@internal@document:concat/1} + ), + nakai@internal@document:append_body_attrs( + _pipe@2, + render_attrs(Attrs@1) + ); + + {fragment, Children@3} -> + render_children( + Children@3, + {builder, + fun render_document_node/1, + fun nakai@internal@document:concat/1} + ); + + {element, Tag, Attrs@2, Children@4} -> + Child_document = render_children( + Children@4, + {builder, + fun render_document_node/1, + fun nakai@internal@document:concat/1} + ), + _pipe@3 = gleam@string_builder:concat( + [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag]), + render_attrs(Attrs@2), + gleam@string_builder:from_string(<<">"/utf8>>), + erlang:element(6, Child_document), + gleam@string_builder:from_strings( + [<<"</"/utf8>>, Tag, <<">"/utf8>>] + )] + ), + nakai@internal@document:replace_body(Child_document, _pipe@3); + + {leaf_element, Tag@1, Attrs@3} -> + _pipe@4 = gleam@string_builder:concat( + [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag@1]), + render_attrs(Attrs@3), + gleam@string_builder:from_string(<<" />"/utf8>>)] + ), + nakai@internal@document:from_body(_pipe@4); + + {comment, Content} -> + Content@1 = begin + _pipe@5 = Content, + gleam@string:replace(_pipe@5, <<"-->"/utf8>>, <<""/utf8>>) + end, + _pipe@6 = gleam@string_builder:from_strings( + [<<"<!-- "/utf8>>, Content@1, <<" -->"/utf8>>] + ), + nakai@internal@document:from_body(_pipe@6); + + {text, Content@2} -> + _pipe@7 = gleam@string_builder:from_string(Content@2), + _pipe@8 = gleam@string_builder:replace( + _pipe@7, + <<"&"/utf8>>, + <<"&"/utf8>> + ), + _pipe@9 = gleam@string_builder:replace( + _pipe@8, + <<"<"/utf8>>, + <<"<"/utf8>> + ), + _pipe@10 = gleam@string_builder:replace( + _pipe@9, + <<">"/utf8>>, + <<">"/utf8>> + ), + nakai@internal@document:from_body(_pipe@10); + + {unsafe_text, Content@3} -> + _pipe@11 = gleam@string_builder:from_string(Content@3), + nakai@internal@document:from_body(_pipe@11); + + {script, Script} -> + nakai@internal@document:from_script(Script); + + nothing -> + nakai@internal@document:new() + end. + +-spec render_script(binary()) -> gleam@string_builder:string_builder(). +render_script(Script) -> + gleam@string_builder:concat( + [gleam@string_builder:from_string(<<"<script>"/utf8>>), + gleam@string_builder:from_string(Script), + gleam@string_builder:from_string(<<"</script>\n"/utf8>>)] + ). + +-spec render_scripts(list(binary())) -> gleam@string_builder:string_builder(). +render_scripts(Scripts) -> + _pipe = Scripts, + _pipe@1 = gleam@list:map(_pipe, fun render_script/1), + gleam@string_builder:concat(_pipe@1). + +-spec render_document(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). +render_document(Tree) -> + Result = render_document_node(Tree), + gleam@string_builder:concat( + [render_doctype( + begin + _pipe = erlang:element(2, Result), + gleam@option:unwrap(_pipe, <<"html"/utf8>>) + end + ), + gleam@string_builder:from_string(<<"<html"/utf8>>), + erlang:element(3, Result), + gleam@string_builder:from_string( + <<">\n<head>"/utf8, + (<<" +<meta charset=\"utf-8\" /> +<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /> +"/utf8>>)/binary>> + ), + erlang:element(5, Result), + gleam@string_builder:from_string(<<"</head>\n<body"/utf8>>), + erlang:element(4, Result), + gleam@string_builder:from_string(<<">"/utf8>>), + erlang:element(6, Result), + render_scripts(erlang:element(7, Result)), + gleam@string_builder:from_string(<<"</body>\n</html>\n"/utf8>>)] + ). + +-spec render_inline_node(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). +render_inline_node(Tree) -> + case Tree of + {doctype, Doctype} -> + render_doctype(Doctype); + + {html, Attrs, Children} -> + render_inline_node({element, <<"html"/utf8>>, Attrs, Children}); + + {head, Children@1} -> + render_inline_node({element, <<"head"/utf8>>, [], Children@1}); + + {body, Attrs@1, Children@2} -> + render_inline_node({element, <<"body"/utf8>>, Attrs@1, Children@2}); + + {fragment, Children@3} -> + render_children( + Children@3, + {builder, + fun render_inline_node/1, + fun gleam@string_builder:concat/1} + ); + + {element, Tag, Attrs@2, Children@4} -> + Child_document = render_children( + Children@4, + {builder, + fun render_inline_node/1, + fun gleam@string_builder:concat/1} + ), + gleam@string_builder:concat( + [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag]), + render_attrs(Attrs@2), + gleam@string_builder:from_string(<<">"/utf8>>), + Child_document, + gleam@string_builder:from_strings( + [<<"</"/utf8>>, Tag, <<">"/utf8>>] + )] + ); + + {leaf_element, Tag@1, Attrs@3} -> + gleam@string_builder:concat( + [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag@1]), + render_attrs(Attrs@3), + gleam@string_builder:from_string(<<" />"/utf8>>)] + ); + + {comment, Content} -> + Content@1 = begin + _pipe = Content, + gleam@string:replace(_pipe, <<"-->"/utf8>>, <<""/utf8>>) + end, + gleam@string_builder:from_strings( + [<<"<!-- "/utf8>>, Content@1, <<" -->"/utf8>>] + ); + + {text, Content@2} -> + _pipe@1 = gleam@string_builder:from_string(Content@2), + _pipe@2 = gleam@string_builder:replace( + _pipe@1, + <<"&"/utf8>>, + <<"&"/utf8>> + ), + _pipe@3 = gleam@string_builder:replace( + _pipe@2, + <<"<"/utf8>>, + <<"<"/utf8>> + ), + gleam@string_builder:replace(_pipe@3, <<">"/utf8>>, <<">"/utf8>>); + + {unsafe_text, Content@3} -> + gleam@string_builder:from_string(Content@3); + + {script, Script} -> + render_inline_node( + {element, <<"script"/utf8>>, [], [{text, Script}]} + ); + + nothing -> + gleam@string_builder:new() + end. + +-spec render_inline(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). +render_inline(Tree) -> + render_inline_node(Tree). diff --git a/test-community-packages-javascript/build/packages/nibble/LICENSE b/test-community-packages-javascript/build/packages/nibble/LICENSE new file mode 100644 index 00000000000..b8320fd29e4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/LICENSE @@ -0,0 +1,18 @@ +Copyright 2022 Hayleigh Thompson + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in the +Software without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/nibble/README.md b/test-community-packages-javascript/build/packages/nibble/README.md new file mode 100644 index 00000000000..b6cba15088f --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/README.md @@ -0,0 +1,46 @@ +# nibble + +[![Package Version](https://img.shields.io/hexpm/v/nibble)](https://hex.pm/packages/nibble) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/nibble/) + +A string parsing library heavily inspired by [`elm/parser`](https://github.com/elm/parser). + +## Quick start + +```gleam +import gleam/function +import nibble.{ Parser } + +type Point { + Point(x: Int, y: Int) +} + +pub fn main () { + let parser = + nibble.succeed(function.curry2(Point)) + |> nibble.drop(nibble.grapheme("(")) + |> nibble.drop(nibble.spaces()) + |> nibble.keep(nibble.int()) + |> nibble.drop(nibble.spaces()) + |> nibble.drop(nibble.grapheme(",")) + |> nibble.drop(nibble.spaces()) + |> nibble.keep(nibble.int()) + |> nibble.drop(nibble.spaces()) + |> nibble.drop(nibble.grapheme(")")) + + assert Ok(point) = nibble.run("(1, 2)", parser) + + point.x //=> 1 + point.y //=> 2 +} +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add nibble +``` + +and its documentation can be found at <https://hexdocs.pm/nibble>. diff --git a/test-community-packages-javascript/build/packages/nibble/gleam.toml b/test-community-packages-javascript/build/packages/nibble/gleam.toml new file mode 100644 index 00000000000..2f6286a1f38 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/gleam.toml @@ -0,0 +1,15 @@ +name = "nibble" +version = "0.2.3" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +# +licences = ["MIT"] +description = "A string parsing library heavily inspired by elm/parser." +repository = { type = "github", user = "hayleigh-dot-dev", repo = "gleam-nibble" } + +[dependencies] +gleam_stdlib = "~> 0.28" + +[dev-dependencies] +gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl new file mode 100644 index 00000000000..4980405448d --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl @@ -0,0 +1,5 @@ +-record(config, { + one_of :: list(fun((nibble@pratt:config(any(), any())) -> nibble:parser(any(), any()))), + and_then_one_of :: list(nibble@pratt:operator(any(), any())), + spaces :: nibble:parser(nil, any()) +}). diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl new file mode 100644 index 00000000000..3e3e338638d --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl @@ -0,0 +1,6 @@ +-record(dead_end, { + row :: integer(), + col :: integer(), + problem :: nibble:error(), + context :: list(nibble:located(any())) +}). diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl new file mode 100644 index 00000000000..b987412c2cb --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl @@ -0,0 +1 @@ +-record(located, {row :: integer(), col :: integer(), context :: any()}). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src b/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src new file mode 100644 index 00000000000..f499dc88532 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src @@ -0,0 +1,10 @@ +{application, nibble, [ + {vsn, "0.2.3"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "A string parsing library heavily inspired by elm/parser."}, + {modules, [nibble, + nibble@pratt, + nibble@predicates]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble.erl new file mode 100644 index 00000000000..da1bce811f8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/src/nibble.erl @@ -0,0 +1,517 @@ +-module(nibble). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([succeed/1, lazy/1, backtrackable/1, commit/1, then/2, map/2, replace/2, keep/2, drop/2, fail/1, eof/0, take_if/2, any/0, grapheme/1, one_of/1, in/2, inspect/2, string/1, run/2, int/0, float/0, take_while/1, spaces/0, whitespace/0, take_if_and_while/2, take_until/1, loop/2, many/2]). +-export_type([parser/2, state/1, step/2, located/1, backtrackable/0, loop/2, error/0, dead_end/1, bag/1]). + +-opaque parser(EVD, EVE) :: {parser, fun((state(EVE)) -> step(EVD, EVE))}. + +-type state(EVF) :: {state, + gleam@map:map_(integer(), binary()), + integer(), + list(located(EVF)), + integer(), + integer()}. + +-type step(EVG, EVH) :: {cont, backtrackable(), EVG, state(EVH)} | + {fail, backtrackable(), bag(EVH)}. + +-type located(EVI) :: {located, integer(), integer(), EVI}. + +-type backtrackable() :: commit | backtrack. + +-type loop(EVJ, EVK) :: {continue, EVK} | {break, EVJ}. + +-type error() :: {bad_parser, binary()} | + {custom, binary()} | + end_of_input | + {expected, binary(), binary()} | + {unexpected, binary()}. + +-type dead_end(EVL) :: {dead_end, + integer(), + integer(), + error(), + list(located(EVL))}. + +-type bag(EVM) :: empty | + {cons, bag(EVM), dead_end(EVM)} | + {append, bag(EVM), bag(EVM)}. + +-spec runwrap(state(EVV), parser(EVX, EVV)) -> step(EVX, EVV). +runwrap(State, Parser) -> + {parser, Parse} = Parser, + Parse(State). + +-spec succeed(EWG) -> parser(EWG, any()). +succeed(A) -> + {parser, fun(State) -> {cont, backtrack, A, State} end}. + +-spec lazy(fun(() -> parser(EWO, EWP))) -> parser(EWO, EWP). +lazy(Parser) -> + {parser, fun(State) -> runwrap(State, Parser()) end}. + +-spec backtrackable(parser(EWU, EWV)) -> parser(EWU, EWV). +backtrackable(Parser) -> + {parser, fun(State) -> case runwrap(State, Parser) of + {cont, _, A, State@1} -> + {cont, backtrack, A, State@1}; + + {fail, _, Bag} -> + {fail, backtrack, Bag} + end end}. + +-spec commit(EXA) -> parser(EXA, any()). +commit(A) -> + {parser, fun(State) -> {cont, commit, A, State} end}. + +-spec should_commit(backtrackable(), backtrackable()) -> backtrackable(). +should_commit(To_x, To_y) -> + case {To_x, To_y} of + {commit, _} -> + commit; + + {_, commit} -> + commit; + + {_, _} -> + backtrack + end. + +-spec then(parser(EXE, EXF), fun((EXE) -> parser(EXI, EXF))) -> parser(EXI, EXF). +then(Parser, F) -> + {parser, fun(State) -> case runwrap(State, Parser) of + {cont, To_a, A, State@1} -> + case runwrap(State@1, F(A)) of + {cont, To_b, B, State@2} -> + {cont, should_commit(To_a, To_b), B, State@2}; + + {fail, To_b@1, Bag} -> + {fail, should_commit(To_a, To_b@1), Bag} + end; + + {fail, Can_backtrack, Bag@1} -> + {fail, Can_backtrack, Bag@1} + end end}. + +-spec map(parser(EXN, EXO), fun((EXN) -> EXR)) -> parser(EXR, EXO). +map(Parser, F) -> + then(Parser, fun(A) -> succeed(F(A)) end). + +-spec next(state(EWC)) -> {gleam@option:option(binary()), state(EWC)}. +next(State) -> + case gleam@map:get(erlang:element(2, State), erlang:element(3, State)) of + {ok, <<"\n"/utf8>>} -> + {{some, <<"\n"/utf8>>}, + erlang:setelement( + 5, + erlang:setelement( + 6, + erlang:setelement( + 3, + State, + erlang:element(3, State) + 1 + ), + 1 + ), + erlang:element(5, State) + 1 + )}; + + {ok, G} -> + {{some, G}, + erlang:setelement( + 6, + erlang:setelement(3, State, erlang:element(3, State) + 1), + erlang:element(6, State) + 1 + )}; + + {error, _} -> + {none, State} + end. + +-spec map2(parser(EXU, EXV), parser(EXY, EXV), fun((EXU, EXY) -> EYB)) -> parser(EYB, EXV). +map2(Parse_a, Parse_b, F) -> + then(Parse_a, fun(A) -> map(Parse_b, fun(B) -> F(A, B) end) end). + +-spec replace(parser(any(), EYF), EYI) -> parser(EYI, EYF). +replace(Parser, B) -> + map(Parser, fun(_) -> B end). + +-spec keep(parser(fun((EYL) -> EYM), EYN), parser(EYL, EYN)) -> parser(EYM, EYN). +keep(Parse_f, Parse_a) -> + map2(Parse_f, Parse_a, fun(F, A) -> F(A) end). + +-spec drop(parser(EYU, EYV), parser(any(), EYV)) -> parser(EYU, EYV). +drop(Parse_a, Parse_x) -> + map2(Parse_a, Parse_x, fun(A, _) -> A end). + +-spec bag_from_state(state(FCC), error()) -> bag(FCC). +bag_from_state(State, Problem) -> + {cons, + empty, + {dead_end, + erlang:element(5, State), + erlang:element(6, State), + Problem, + erlang:element(4, State)}}. + +-spec fail(binary()) -> parser(any(), any()). +fail(Message) -> + {parser, + fun(State) -> + {fail, backtrack, bag_from_state(State, {custom, Message})} + end}. + +-spec eof() -> parser(nil, any()). +eof() -> + {parser, fun(State) -> case next(State) of + {{some, Str}, _} -> + {fail, backtrack, bag_from_state(State, {unexpected, Str})}; + + {none, _} -> + {cont, backtrack, nil, State} + end end}. + +-spec take_if(fun((binary()) -> boolean()), binary()) -> parser(binary(), any()). +take_if(Predicate, Expecting) -> + {parser, + fun(State) -> + {Str, Next_state} = next(State), + Should_take = begin + _pipe = Str, + _pipe@1 = gleam@option:map(_pipe, Predicate), + gleam@option:unwrap(_pipe@1, false) + end, + Str@1 = gleam@option:unwrap(Str, <<""/utf8>>), + case Should_take of + true -> + {cont, commit, Str@1, Next_state}; + + false -> + {fail, + backtrack, + bag_from_state(State, {expected, Expecting, Str@1})} + end + end}. + +-spec any() -> parser(binary(), any()). +any() -> + take_if(gleam@function:constant(true), <<"a single grapheme"/utf8>>). + +-spec grapheme(binary()) -> parser(nil, any()). +grapheme(Str) -> + _pipe = take_if(fun(G) -> G =:= Str end, Str), + map(_pipe, gleam@function:constant(nil)). + +-spec add_bag_to_step(step(FCL, FCM), bag(FCM)) -> step(FCL, FCM). +add_bag_to_step(Step, Left) -> + case Step of + {cont, Can_backtrack, A, State} -> + {cont, Can_backtrack, A, State}; + + {fail, Can_backtrack@1, Right} -> + {fail, Can_backtrack@1, {append, Left, Right}} + end. + +-spec one_of(list(parser(FAB, FAC))) -> parser(FAB, FAC). +one_of(Parsers) -> + {parser, + fun(State) -> + Init = {fail, backtrack, empty}, + gleam@list:fold_until( + Parsers, + Init, + fun(Result, Next) -> case Result of + {cont, _, _, _} -> + {stop, Result}; + + {fail, commit, _} -> + {stop, Result}; + + {fail, _, Bag} -> + _pipe = runwrap(State, Next), + _pipe@1 = add_bag_to_step(_pipe, Bag), + {continue, _pipe@1} + end end + ) + end}. + +-spec push_context(state(FCY), FCY) -> state(FCY). +push_context(State, Context) -> + Located = {located, + erlang:element(5, State), + erlang:element(6, State), + Context}, + erlang:setelement(4, State, [Located | erlang:element(4, State)]). + +-spec pop_context(state(FDB)) -> state(FDB). +pop_context(State) -> + case erlang:element(4, State) of + [] -> + State; + + [_ | Context] -> + erlang:setelement(4, State, Context) + end. + +-spec in(parser(FCS, FCT), FCT) -> parser(FCS, FCT). +in(Parser, Context) -> + {parser, fun(State) -> case runwrap(push_context(State, Context), Parser) of + {cont, Can_backtrack, A, State@1} -> + {cont, Can_backtrack, A, pop_context(State@1)}; + + {fail, Can_backtrack@1, Bag} -> + {fail, Can_backtrack@1, Bag} + end end}. + +-spec inspect(parser(FDE, FDF), binary()) -> parser(FDE, FDF). +inspect(Parser, Message) -> + {parser, + fun(State) -> + gleam@io:print(Message), + gleam@io:println(<<": "/utf8>>), + _pipe = runwrap(State, Parser), + gleam@io:debug(_pipe) + end}. + +-spec string(binary()) -> parser(nil, any()). +string(Str) -> + Graphemes = gleam@string:to_graphemes(Str), + {parser, fun(State) -> case Graphemes of + [] -> + {fail, + backtrack, + bag_from_state( + State, + {bad_parser, <<"empty string"/utf8>>} + )}; + + [Head | Tail] -> + Parse_each = gleam@list:fold( + Tail, + grapheme(Head), + fun(Parse, Next) -> _pipe = Parse, + drop(_pipe, grapheme(Next)) end + ), + case runwrap(State, Parse_each) of + {cont, _, _, State@1} -> + {cont, commit, nil, State@1}; + + {fail, _, Bag} -> + {fail, backtrack, Bag} + end + end end}. + +-spec to_deadends(bag(FCF), list(dead_end(FCF))) -> list(dead_end(FCF)). +to_deadends(Bag, Acc) -> + case Bag of + empty -> + Acc; + + {cons, empty, Deadend} -> + [Deadend | Acc]; + + {cons, Bag@1, Deadend@1} -> + to_deadends(Bag@1, [Deadend@1 | Acc]); + + {append, Left, Right} -> + to_deadends(Left, to_deadends(Right, Acc)) + end. + +-spec run(binary(), parser(EVN, EVO)) -> {ok, EVN} | + {error, list(dead_end(EVO))}. +run(Src, Parser) -> + Graphemes = begin + _pipe = gleam@string:to_graphemes(Src), + _pipe@1 = gleam@list:index_map( + _pipe, + fun(I, Grapheme) -> {I, Grapheme} end + ), + gleam@map:from_list(_pipe@1) + end, + Init = {state, Graphemes, 0, [], 1, 1}, + case runwrap(Init, Parser) of + {cont, _, A, _} -> + {ok, A}; + + {fail, _, Bag} -> + {error, to_deadends(Bag, [])} + end. + +-spec int() -> parser(integer(), any()). +int() -> + _pipe = take_if_and_while( + fun nibble@predicates:is_digit/1, + <<"a digit"/utf8>> + ), + map( + _pipe, + fun(Digits) -> + _assert_subject = gleam@int:parse(Digits), + {ok, Int} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"nibble"/utf8>>, + function => <<"int"/utf8>>, + line => 254}) + end, + Int + end + ). + +-spec float() -> parser(float(), any()). +float() -> + Make_float_string = gleam@function:curry2( + fun(X, Y) -> gleam@string:concat([X, <<"."/utf8>>, Y]) end + ), + _pipe = succeed(Make_float_string), + _pipe@1 = keep( + _pipe, + take_if_and_while(fun nibble@predicates:is_digit/1, <<"a digit"/utf8>>) + ), + _pipe@2 = drop(_pipe@1, grapheme(<<"."/utf8>>)), + _pipe@3 = keep( + _pipe@2, + take_if_and_while(fun nibble@predicates:is_digit/1, <<"a digit"/utf8>>) + ), + map( + _pipe@3, + fun(Digits) -> + _assert_subject = gleam@float:parse(Digits), + {ok, Float} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"nibble"/utf8>>, + function => <<"float"/utf8>>, + line => 271}) + end, + Float + end + ). + +-spec take_while(fun((binary()) -> boolean())) -> parser(binary(), any()). +take_while(Predicate) -> + {parser, + fun(State) -> + {Str, Next_state} = next(State), + Should_take = begin + _pipe = Str, + _pipe@1 = gleam@option:map(_pipe, Predicate), + gleam@option:unwrap(_pipe@1, false) + end, + Str@1 = gleam@option:unwrap(Str, <<""/utf8>>), + case Should_take of + true -> + runwrap( + Next_state, + map( + take_while(Predicate), + fun(_capture) -> + gleam@string:append(Str@1, _capture) + end + ) + ); + + false -> + {cont, backtrack, <<""/utf8>>, State} + end + end}. + +-spec spaces() -> parser(nil, any()). +spaces() -> + _pipe = take_while(fun(G) -> G =:= <<" "/utf8>> end), + map(_pipe, gleam@function:constant(nil)). + +-spec whitespace() -> parser(nil, any()). +whitespace() -> + _pipe = take_while(fun nibble@predicates:is_whitespace/1), + map(_pipe, gleam@function:constant(nil)). + +-spec take_if_and_while(fun((binary()) -> boolean()), binary()) -> parser(binary(), any()). +take_if_and_while(Predicate, Expecting) -> + map2( + take_if(Predicate, Expecting), + take_while(Predicate), + fun gleam@string:append/2 + ). + +-spec take_until(fun((binary()) -> boolean())) -> parser(binary(), any()). +take_until(Predicate) -> + take_while(gleam@function:compose(Predicate, fun gleam@bool:negate/1)). + +-spec loop_help( + fun((FBC) -> parser(loop(FBD, FBC), FBG)), + backtrackable(), + FBC, + state(FBG) +) -> step(FBD, FBG). +loop_help(F, Commit, Loop_state, State) -> + case runwrap(State, F(Loop_state)) of + {cont, Can_backtrack, {continue, Next_loop_state}, Next_state} -> + loop_help( + F, + should_commit(Commit, Can_backtrack), + Next_loop_state, + Next_state + ); + + {cont, Can_backtrack@1, {break, Result}, Next_state@1} -> + {cont, should_commit(Commit, Can_backtrack@1), Result, Next_state@1}; + + {fail, Can_backtrack@2, Bag} -> + {fail, should_commit(Commit, Can_backtrack@2), Bag} + end. + +-spec loop(FBC, fun((FBC) -> parser(loop(FBD, FBC), FBG))) -> parser(FBD, FBG). +loop(Init, Step) -> + {parser, fun(State) -> loop_help(Step, backtrack, Init, State) end}. + +-spec more(FAS, parser(FAS, FAT), parser(any(), FAT)) -> parser(list(FAS), FAT). +more(X, Parser, Separator) -> + loop( + [X], + fun(Xs) -> + one_of( + [begin + _pipe = succeed( + fun(_capture) -> + gleam@list:prepend(Xs, _capture) + end + ), + _pipe@1 = drop(_pipe, Separator), + _pipe@2 = keep(_pipe@1, Parser), + map(_pipe@2, fun(Field@0) -> {continue, Field@0} end) + end, + begin + _pipe@3 = succeed(Xs), + _pipe@4 = drop(_pipe@3, eof()), + _pipe@5 = map(_pipe@4, fun gleam@list:reverse/1), + map(_pipe@5, fun(Field@0) -> {break, Field@0} end) + end, + begin + _pipe@6 = succeed(Xs), + _pipe@7 = map(_pipe@6, fun gleam@list:reverse/1), + map(_pipe@7, fun(Field@0) -> {break, Field@0} end) + end] + ) + end + ). + +-spec many(parser(FAI, FAJ), parser(any(), FAJ)) -> parser(list(FAI), FAJ). +many(Parser, Separator) -> + one_of( + [begin + _pipe = Parser, + then( + _pipe, + fun(_capture) -> more(_capture, Parser, Separator) end + ) + end, + succeed([])] + ). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam new file mode 100644 index 00000000000..3292d85d810 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam @@ -0,0 +1,519 @@ +//// + +// IMPORTS --------------------------------------------------------------------- + +import gleam/bool +import gleam/float +import gleam/function +import gleam/int +import gleam/io +import gleam/list +import gleam/map.{Map} +import gleam/option.{Option} +import gleam/string +import nibble/predicates + +// TYPES ----------------------------------------------------------------------- + +/// +pub opaque type Parser(a, ctx) { + Parser(fn(State(ctx)) -> Step(a, ctx)) +} + +type State(ctx) { + State( + // The Gleam stdlib doesn't seem to have an `Array` type, so we'll just + // use a `Map` instead. We only need something for indexed access, to it's + // not a huge deal. + // + // TODO: Louis says making an `Array` backed by tuples in Erlang will + // be way better for performance. In JavaScript we could just use normal + // arrays - someone should look into this. + src: Map(Int, String), + offset: Int, + context: List(Located(ctx)), + row: Int, + col: Int, + ) +} + +type Step(a, ctx) { + Cont(Backtrackable, a, State(ctx)) + Fail(Backtrackable, Bag(ctx)) +} + +/// +pub type Located(ctx) { + Located(row: Int, col: Int, context: ctx) +} + +type Backtrackable { + Commit + Backtrack +} + +// RUNNING PARSERS ------------------------------------------------------------- + +/// +pub fn run(src: String, parser: Parser(a, ctx)) -> Result(a, List(DeadEnd(ctx))) { + let graphemes = + string.to_graphemes(src) + |> list.index_map(fn(i, grapheme) { #(i, grapheme) }) + |> map.from_list + + let init = State(graphemes, 0, [], 1, 1) + + case runwrap(init, parser) { + Cont(_, a, _) -> Ok(a) + + Fail(_, bag) -> Error(to_deadends(bag, [])) + } +} + +fn runwrap(state: State(ctx), parser: Parser(a, ctx)) -> Step(a, ctx) { + let Parser(parse) = parser + parse(state) +} + +fn next(state: State(ctx)) -> #(Option(String), State(ctx)) { + case map.get(state.src, state.offset) { + Ok("\n") -> #( + option.Some("\n"), + State(..state, offset: state.offset + 1, col: 1, row: state.row + 1), + ) + + Ok(g) -> #( + option.Some(g), + State(..state, offset: state.offset + 1, col: state.col + 1), + ) + + Error(_) -> #(option.None, state) + } +} + +// CONSTRUCTORS ---------------------------------------------------------------- + +/// +pub fn succeed(a: a) -> Parser(a, ctx) { + Parser(fn(state) { Cont(Backtrack, a, state) }) +} + +/// +pub fn fail(message: String) -> Parser(a, ctx) { + Parser(fn(state) { Fail(Backtrack, bag_from_state(state, Custom(message))) }) +} + +/// +pub fn lazy(parser: fn() -> Parser(a, ctx)) -> Parser(a, ctx) { + Parser(fn(state) { runwrap(state, parser()) }) +} + +// BACKTRACKING ---------------------------------------------------------------- + +/// +pub fn backtrackable(parser: Parser(a, ctx)) -> Parser(a, ctx) { + Parser(fn(state) { + case runwrap(state, parser) { + Cont(_, a, state) -> Cont(Backtrack, a, state) + + Fail(_, bag) -> Fail(Backtrack, bag) + } + }) +} + +/// +pub fn commit(to a: a) -> Parser(a, ctx) { + Parser(fn(state) { Cont(Commit, a, state) }) +} + +fn should_commit(to_x: Backtrackable, or to_y: Backtrackable) -> Backtrackable { + case to_x, to_y { + Commit, _ -> Commit + + _, Commit -> Commit + + _, _ -> Backtrack + } +} + +// MANIPULATING PARSERS -------------------------------------------------------- + +/// +pub fn then( + parser: Parser(a, ctx), + f: fn(a) -> Parser(b, ctx), +) -> Parser(b, ctx) { + Parser(fn(state) { + case runwrap(state, parser) { + Cont(to_a, a, state) -> + case runwrap(state, f(a)) { + Cont(to_b, b, state) -> Cont(should_commit(to_a, or: to_b), b, state) + Fail(to_b, bag) -> Fail(should_commit(to_a, or: to_b), bag) + } + + Fail(can_backtrack, bag) -> Fail(can_backtrack, bag) + } + }) +} + +/// +pub fn map(parser: Parser(a, ctx), f: fn(a) -> b) -> Parser(b, ctx) { + then(parser, fn(a) { succeed(f(a)) }) +} + +fn map2( + parse_a: Parser(a, ctx), + parse_b: Parser(b, ctx), + f: fn(a, b) -> c, +) -> Parser(c, ctx) { + then(parse_a, fn(a) { map(parse_b, fn(b) { f(a, b) }) }) +} + +/// +pub fn replace(parser: Parser(a, ctx), with b: b) -> Parser(b, ctx) { + map(parser, fn(_) { b }) +} + +// PIPE-FRIENDLY HELPERS ------------------------------------------------------- + +/// +pub fn keep( + parse_f: Parser(fn(a) -> b, ctx), + parse_a: Parser(a, ctx), +) -> Parser(b, ctx) { + map2(parse_f, parse_a, fn(f, a) { f(a) }) +} + +/// +pub fn drop(parse_a: Parser(a, ctx), parse_x: Parser(x, ctx)) -> Parser(a, ctx) { + map2(parse_a, parse_x, fn(a, _) { a }) +} + +// SIMPLE PARSERS -------------------------------------------------------------- + +/// +pub fn any() -> Parser(String, ctx) { + take_if(function.constant(True), "a single grapheme") +} + +/// +pub fn eof() -> Parser(Nil, ctx) { + Parser(fn(state) { + case next(state) { + #(option.Some(str), _) -> + Fail(Backtrack, bag_from_state(state, Unexpected(str))) + + #(option.None, _) -> Cont(Backtrack, Nil, state) + } + }) +} + +// GRAPHEMES AND STRINGS ------------------------------------------------------- + +/// +pub fn grapheme(str: String) -> Parser(Nil, ctx) { + take_if(fn(g) { g == str }, str) + |> map(function.constant(Nil)) +} + +/// +pub fn string(str: String) -> Parser(Nil, ctx) { + let graphemes = string.to_graphemes(str) + + Parser(fn(state) { + case graphemes { + [] -> Fail(Backtrack, bag_from_state(state, BadParser("empty string"))) + + [head, ..tail] -> { + let parse_each = + list.fold( + tail, + grapheme(head), + fn(parse, next) { + parse + |> drop(grapheme(next)) + }, + ) + case runwrap(state, parse_each) { + Cont(_, _, state) -> Cont(Commit, Nil, state) + Fail(_, bag) -> Fail(Backtrack, bag) + } + } + } + }) +} + +// NUMBERS --------------------------------------------------------------------- + +/// +pub fn int() -> Parser(Int, ctx) { + take_if_and_while(predicates.is_digit, "a digit") + // We can make the following assertion because we know our parser will + // only consume digits, and is guaranteed to have at least one. + |> map(fn(digits) { + let assert Ok(int) = int.parse(digits) + int + }) +} + +/// +pub fn float() -> Parser(Float, ctx) { + let make_float_string = + function.curry2(fn(x, y) { string.concat([x, ".", y]) }) + + succeed(make_float_string) + |> keep(take_if_and_while(predicates.is_digit, "a digit")) + |> drop(grapheme(".")) + |> keep(take_if_and_while(predicates.is_digit, "a digit")) + // We can make the following assertion because we know our parser will + // only consume digits, and is guaranteed to have at least one. + |> map(fn(digits) { + let assert Ok(float) = float.parse(digits) + float + }) +} + +// WHITESPACE ------------------------------------------------------------------ + +/// +pub fn spaces() -> Parser(Nil, ctx) { + take_while(fn(g) { g == " " }) + |> map(function.constant(Nil)) +} + +/// +pub fn whitespace() -> Parser(Nil, ctx) { + take_while(predicates.is_whitespace) + |> map(function.constant(Nil)) +} + +// BRANCHING AND LOOPING ------------------------------------------------------- + +/// +pub fn one_of(parsers: List(Parser(a, ctx))) -> Parser(a, ctx) { + Parser(fn(state) { + let init = Fail(Backtrack, Empty) + + list.fold_until( + parsers, + init, + fn(result, next) { + case result { + Cont(_, _, _) -> list.Stop(result) + + Fail(Commit, _) -> list.Stop(result) + + Fail(_, bag) -> + runwrap(state, next) + |> add_bag_to_step(bag) + |> list.Continue + } + }, + ) + }) +} + +/// +pub fn many( + parser: Parser(a, ctx), + separator: Parser(x, ctx), +) -> Parser(List(a), ctx) { + one_of([ + parser + |> then(more(_, parser, separator)), + succeed([]), + ]) +} + +fn more( + x: a, + parser: Parser(a, ctx), + separator: Parser(x, ctx), +) -> Parser(List(a), ctx) { + loop( + [x], + fn(xs) { + one_of([ + succeed(list.prepend(xs, _)) + |> drop(separator) + |> keep(parser) + |> map(Continue), + succeed(xs) + |> drop(eof()) + |> map(list.reverse) + |> map(Break), + succeed(xs) + |> map(list.reverse) + |> map(Break), + ]) + }, + ) +} + +pub type Loop(a, state) { + Continue(state) + Break(a) +} + +pub fn loop( + init: state, + step: fn(state) -> Parser(Loop(a, state), ctx), +) -> Parser(a, ctx) { + Parser(fn(state) { loop_help(step, Backtrack, init, state) }) +} + +fn loop_help(f, commit, loop_state, state) { + case runwrap(state, f(loop_state)) { + Cont(can_backtrack, Continue(next_loop_state), next_state) -> + loop_help( + f, + should_commit(commit, can_backtrack), + next_loop_state, + next_state, + ) + + Cont(can_backtrack, Break(result), next_state) -> + Cont(should_commit(commit, can_backtrack), result, next_state) + + Fail(can_backtrack, bag) -> Fail(should_commit(commit, can_backtrack), bag) + } +} + +// PREDICATES ------------------------------------------------------------------ + +/// +pub fn take_if( + predicate: fn(String) -> Bool, + expecting: String, +) -> Parser(String, ctx) { + Parser(fn(state) { + let #(str, next_state) = next(state) + let should_take = + str + |> option.map(predicate) + |> option.unwrap(False) + let str = option.unwrap(str, "") + + case should_take { + True -> Cont(Commit, str, next_state) + + False -> + Fail(Backtrack, bag_from_state(state, Expected(expecting, got: str))) + } + }) +} + +/// +pub fn take_while(predicate: fn(String) -> Bool) -> Parser(String, ctx) { + Parser(fn(state) { + let #(str, next_state) = next(state) + let should_take = + str + |> option.map(predicate) + |> option.unwrap(False) + let str = option.unwrap(str, "") + + case should_take { + True -> + runwrap(next_state, map(take_while(predicate), string.append(str, _))) + + False -> Cont(Backtrack, "", state) + } + }) +} + +/// +pub fn take_if_and_while( + predicate: fn(String) -> Bool, + expecting: String, +) -> Parser(String, ctx) { + map2(take_if(predicate, expecting), take_while(predicate), string.append) +} + +/// +pub fn take_until(predicate: fn(String) -> Bool) -> Parser(String, ctx) { + take_while(function.compose(predicate, bool.negate)) +} + +// ERRORS ---------------------------------------------------------------------- + +pub type Error { + BadParser(String) + Custom(String) + EndOfInput + Expected(String, got: String) + Unexpected(String) +} + +/// +pub type DeadEnd(ctx) { + DeadEnd(row: Int, col: Int, problem: Error, context: List(Located(ctx))) +} + +type Bag(ctx) { + Empty + Cons(Bag(ctx), DeadEnd(ctx)) + Append(Bag(ctx), Bag(ctx)) +} + +fn bag_from_state(state: State(ctx), problem: Error) -> Bag(ctx) { + Cons(Empty, DeadEnd(state.row, state.col, problem, state.context)) +} + +fn to_deadends(bag: Bag(ctx), acc: List(DeadEnd(ctx))) -> List(DeadEnd(ctx)) { + case bag { + Empty -> acc + + Cons(Empty, deadend) -> [deadend, ..acc] + + Cons(bag, deadend) -> to_deadends(bag, [deadend, ..acc]) + + Append(left, right) -> to_deadends(left, to_deadends(right, acc)) + } +} + +fn add_bag_to_step(step: Step(a, ctx), left: Bag(ctx)) -> Step(a, ctx) { + case step { + Cont(can_backtrack, a, state) -> Cont(can_backtrack, a, state) + + Fail(can_backtrack, right) -> Fail(can_backtrack, Append(left, right)) + } +} + +// CONTEXT --------------------------------------------------------------------- + +/// +pub fn in(parser: Parser(a, ctx), context: ctx) -> Parser(a, ctx) { + Parser(fn(state) { + case runwrap(push_context(state, context), parser) { + Cont(can_backtrack, a, state) -> + Cont(can_backtrack, a, pop_context(state)) + + Fail(can_backtrack, bag) -> Fail(can_backtrack, bag) + } + }) +} + +fn push_context(state: State(ctx), context: ctx) -> State(ctx) { + let located = Located(state.row, state.col, context) + State(..state, context: [located, ..state.context]) +} + +fn pop_context(state: State(ctx)) -> State(ctx) { + case state.context { + [] -> state + + [_, ..context] -> State(..state, context: context) + } +} + +/// Run the given parser and then inspect it's state. +pub fn inspect(parser: Parser(a, ctx), message: String) -> Parser(a, ctx) { + Parser(fn(state) { + io.print(message) + io.println(": ") + + runwrap(state, parser) + |> io.debug + }) +} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam new file mode 100644 index 00000000000..968e75b128b --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam @@ -0,0 +1,113 @@ +// IMPORTS --------------------------------------------------------------------- + +import gleam/list +import gleam/function +import nibble.{ Parser } + +// TYPES ----------------------------------------------------------------------- + +pub opaque type Config(a, ctx) { + Config( + one_of: List(fn (Config(a, ctx)) -> Parser(a, ctx)), + and_then_one_of: List(Operator(a, ctx)), + spaces: Parser(Nil, ctx) + ) +} + +pub opaque type Operator(a, ctx) { + Operator( + fn(Config(a, ctx)) -> #(Int, fn (a) -> Parser(a, ctx)) + ) +} + +// + +pub fn expression( + one_of first: List(fn (Config(a, ctx)) -> Parser(a, ctx)), + and_then_one_of then: List(Operator(a, ctx)), + dropping spaces: Parser(Nil, ctx) +) -> Parser(a, ctx) { + let config = Config(first, then, spaces) + sub_expression(config, 0) +} + +pub fn sub_expression (config: Config(a, ctx), precedence: Int) -> Parser(a, ctx) { + let expr = nibble.lazy(fn () { + config.one_of + |> list.map(fn (p) { p(config) }) + |> nibble.one_of + }) + + let go = fn (expr) { + nibble.succeed(function.identity) + |> nibble.drop(config.spaces) + |> nibble.keep( + nibble.one_of([ + nibble.succeed(expr) + |> nibble.then(operation(_, config, precedence)) + |> nibble.map(nibble.Continue), + nibble.succeed(expr) + |> nibble.map(nibble.Break) + ]) + ) + } + + nibble.succeed(function.identity) + |> nibble.drop(config.spaces) + |> nibble.keep(expr) + |> nibble.then(nibble.loop(_, go)) +} + +fn operation (expr: a, config: Config(a, ctx), current_precedence: Int) -> Parser(a, ctx) { + config.and_then_one_of + |> list.filter_map(fn (operator) { + let Operator(op) = operator + case op(config) { + #(precedence, parser) if precedence > current_precedence -> + Ok(parser(expr)) + + _ -> + Error(Nil) + } + + }) + |> nibble.one_of() +} + +// + +pub fn prefix (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a) -> a) -> fn (Config(a, ctx)) -> Parser(a, ctx) { + fn (config) { + nibble.succeed(apply) + |> nibble.drop(operator) + |> nibble.keep(sub_expression(config, precedence)) + } +} + +pub fn infix_left (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { + make_infix(#(precedence, precedence), operator, apply) +} + +pub fn infix_right (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { + make_infix(#(precedence, precedence - 1), operator, apply) +} + +pub fn postfix (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a) -> a) -> Operator(a, ctx) { + Operator(fn (_) { + #(precedence, fn (lhs) { + nibble.succeed(apply(lhs)) + |> nibble.drop(operator) + }) + }) +} + +fn make_infix(precedence: #(Int, Int), operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { + let #(left_precedence, right_precedence) = precedence + Operator(fn (config) { + #(left_precedence, fn (lhs) { + nibble.succeed(apply(lhs, _)) + |> nibble.drop(operator) + |> nibble.keep(sub_expression(config, right_precedence)) + }) + }) +} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam new file mode 100644 index 00000000000..756ccbd3ba7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam @@ -0,0 +1,59 @@ +/// +pub fn is_digit (grapheme: String) -> Bool { + case grapheme { + "0" | "1" | "2" | "3" | "4" | + "5" | "6" | "7" | "8" | "9" -> + True + + _ -> + False + } +} + +/// +pub fn is_whitespace (grapheme: String) -> Bool { + case grapheme { + " " | "\t" | "\n" | "\r" -> + True + + _ -> + False + } +} + +/// +pub fn is_upper (grapheme: String) -> Bool { + case grapheme { + "A" | "B" | "C" | "D" | "E" | + "F" | "G" | "H" | "I" | "J" | + "K" | "L" | "M" | "N" | "O" | + "P" | "Q" | "R" | "S" | "T" | + "U" | "V" | "W" | "X" | "Y" | + "Z" -> + True + + _ -> + False + } +} + +/// +pub fn is_lower (grapheme: String) -> Bool { + case grapheme { + "a" | "b" | "c" | "d" | "e" | + "f" | "g" | "h" | "i" | "j" | + "k" | "l" | "m" | "n" | "o" | + "p" | "q" | "r" | "s" | "t" | + "u" | "v" | "w" | "x" | "y" | + "z" -> + True + + _ -> + False + } +} + +/// +pub fn is_alphanum (grapheme: String) -> Bool { + is_digit(grapheme) || is_upper(grapheme) || is_lower(grapheme) +} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl new file mode 100644 index 00000000000..36a1260fc3b --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl @@ -0,0 +1,120 @@ +-module(nibble@pratt). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([sub_expression/2, expression/3, prefix/3, postfix/3, infix_left/3, infix_right/3]). +-export_type([config/2, operator/2]). + +-opaque config(FVQ, FVR) :: {config, + list(fun((config(FVQ, FVR)) -> nibble:parser(FVQ, FVR))), + list(operator(FVQ, FVR)), + nibble:parser(nil, FVR)}. + +-opaque operator(FVS, FVT) :: {operator, + fun((config(FVS, FVT)) -> {integer(), + fun((FVS) -> nibble:parser(FVS, FVT))})}. + +-spec operation(FWO, config(FWO, FWP), integer()) -> nibble:parser(FWO, FWP). +operation(Expr, Config, Current_precedence) -> + _pipe = erlang:element(3, Config), + _pipe@1 = gleam@list:filter_map( + _pipe, + fun(Operator) -> + {operator, Op} = Operator, + case Op(Config) of + {Precedence, Parser} when Precedence > Current_precedence -> + {ok, Parser(Expr)}; + + _ -> + {error, nil} + end + end + ), + nibble:one_of(_pipe@1). + +-spec sub_expression(config(FWI, FWJ), integer()) -> nibble:parser(FWI, FWJ). +sub_expression(Config, Precedence) -> + Expr = nibble:lazy(fun() -> _pipe = erlang:element(2, Config), + _pipe@1 = gleam@list:map(_pipe, fun(P) -> P(Config) end), + nibble:one_of(_pipe@1) end), + Go = fun(Expr@1) -> _pipe@2 = nibble:succeed(fun gleam@function:identity/1), + _pipe@3 = nibble:drop(_pipe@2, erlang:element(4, Config)), + nibble:keep( + _pipe@3, + nibble:one_of( + [begin + _pipe@4 = nibble:succeed(Expr@1), + _pipe@5 = nibble:then( + _pipe@4, + fun(_capture) -> + operation(_capture, Config, Precedence) + end + ), + nibble:map( + _pipe@5, + fun(Field@0) -> {continue, Field@0} end + ) + end, + begin + _pipe@6 = nibble:succeed(Expr@1), + nibble:map( + _pipe@6, + fun(Field@0) -> {break, Field@0} end + ) + end] + ) + ) end, + _pipe@7 = nibble:succeed(fun gleam@function:identity/1), + _pipe@8 = nibble:drop(_pipe@7, erlang:element(4, Config)), + _pipe@9 = nibble:keep(_pipe@8, Expr), + nibble:then(_pipe@9, fun(_capture@1) -> nibble:loop(_capture@1, Go) end). + +-spec expression( + list(fun((config(FVU, FVV)) -> nibble:parser(FVU, FVV))), + list(operator(FVU, FVV)), + nibble:parser(nil, FVV) +) -> nibble:parser(FVU, FVV). +expression(First, Then, Spaces) -> + Config = {config, First, Then, Spaces}, + sub_expression(Config, 0). + +-spec prefix(integer(), nibble:parser(nil, FWU), fun((FWX) -> FWX)) -> fun((config(FWX, FWU)) -> nibble:parser(FWX, FWU)). +prefix(Precedence, Operator, Apply) -> + fun(Config) -> _pipe = nibble:succeed(Apply), + _pipe@1 = nibble:drop(_pipe, Operator), + nibble:keep(_pipe@1, sub_expression(Config, Precedence)) end. + +-spec postfix(integer(), nibble:parser(nil, FXO), fun((FXR) -> FXR)) -> operator(FXR, FXO). +postfix(Precedence, Operator, Apply) -> + {operator, + fun(_) -> {Precedence, fun(Lhs) -> _pipe = nibble:succeed(Apply(Lhs)), + nibble:drop(_pipe, Operator) end} end}. + +-spec make_infix( + {integer(), integer()}, + nibble:parser(nil, FXU), + fun((FXX, FXX) -> FXX) +) -> operator(FXX, FXU). +make_infix(Precedence, Operator, Apply) -> + {Left_precedence, Right_precedence} = Precedence, + {operator, + fun(Config) -> + {Left_precedence, + fun(Lhs) -> + _pipe = nibble:succeed( + fun(_capture) -> Apply(Lhs, _capture) end + ), + _pipe@1 = nibble:drop(_pipe, Operator), + nibble:keep( + _pipe@1, + sub_expression(Config, Right_precedence) + ) + end} + end}. + +-spec infix_left(integer(), nibble:parser(nil, FXC), fun((FXF, FXF) -> FXF)) -> operator(FXF, FXC). +infix_left(Precedence, Operator, Apply) -> + make_infix({Precedence, Precedence}, Operator, Apply). + +-spec infix_right(integer(), nibble:parser(nil, FXI), fun((FXL, FXL) -> FXL)) -> operator(FXL, FXI). +infix_right(Precedence, Operator, Apply) -> + make_infix({Precedence, Precedence - 1}, Operator, Apply). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl new file mode 100644 index 00000000000..153d6223e49 --- /dev/null +++ b/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl @@ -0,0 +1,234 @@ +-module(nibble@predicates). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([is_digit/1, is_whitespace/1, is_upper/1, is_lower/1, is_alphanum/1]). + +-spec is_digit(binary()) -> boolean(). +is_digit(Grapheme) -> + case Grapheme of + <<"0"/utf8>> -> + true; + + <<"1"/utf8>> -> + true; + + <<"2"/utf8>> -> + true; + + <<"3"/utf8>> -> + true; + + <<"4"/utf8>> -> + true; + + <<"5"/utf8>> -> + true; + + <<"6"/utf8>> -> + true; + + <<"7"/utf8>> -> + true; + + <<"8"/utf8>> -> + true; + + <<"9"/utf8>> -> + true; + + _ -> + false + end. + +-spec is_whitespace(binary()) -> boolean(). +is_whitespace(Grapheme) -> + case Grapheme of + <<" "/utf8>> -> + true; + + <<"\t"/utf8>> -> + true; + + <<"\n"/utf8>> -> + true; + + <<"\r"/utf8>> -> + true; + + _ -> + false + end. + +-spec is_upper(binary()) -> boolean(). +is_upper(Grapheme) -> + case Grapheme of + <<"A"/utf8>> -> + true; + + <<"B"/utf8>> -> + true; + + <<"C"/utf8>> -> + true; + + <<"D"/utf8>> -> + true; + + <<"E"/utf8>> -> + true; + + <<"F"/utf8>> -> + true; + + <<"G"/utf8>> -> + true; + + <<"H"/utf8>> -> + true; + + <<"I"/utf8>> -> + true; + + <<"J"/utf8>> -> + true; + + <<"K"/utf8>> -> + true; + + <<"L"/utf8>> -> + true; + + <<"M"/utf8>> -> + true; + + <<"N"/utf8>> -> + true; + + <<"O"/utf8>> -> + true; + + <<"P"/utf8>> -> + true; + + <<"Q"/utf8>> -> + true; + + <<"R"/utf8>> -> + true; + + <<"S"/utf8>> -> + true; + + <<"T"/utf8>> -> + true; + + <<"U"/utf8>> -> + true; + + <<"V"/utf8>> -> + true; + + <<"W"/utf8>> -> + true; + + <<"X"/utf8>> -> + true; + + <<"Y"/utf8>> -> + true; + + <<"Z"/utf8>> -> + true; + + _ -> + false + end. + +-spec is_lower(binary()) -> boolean(). +is_lower(Grapheme) -> + case Grapheme of + <<"a"/utf8>> -> + true; + + <<"b"/utf8>> -> + true; + + <<"c"/utf8>> -> + true; + + <<"d"/utf8>> -> + true; + + <<"e"/utf8>> -> + true; + + <<"f"/utf8>> -> + true; + + <<"g"/utf8>> -> + true; + + <<"h"/utf8>> -> + true; + + <<"i"/utf8>> -> + true; + + <<"j"/utf8>> -> + true; + + <<"k"/utf8>> -> + true; + + <<"l"/utf8>> -> + true; + + <<"m"/utf8>> -> + true; + + <<"n"/utf8>> -> + true; + + <<"o"/utf8>> -> + true; + + <<"p"/utf8>> -> + true; + + <<"q"/utf8>> -> + true; + + <<"r"/utf8>> -> + true; + + <<"s"/utf8>> -> + true; + + <<"t"/utf8>> -> + true; + + <<"u"/utf8>> -> + true; + + <<"v"/utf8>> -> + true; + + <<"w"/utf8>> -> + true; + + <<"x"/utf8>> -> + true; + + <<"y"/utf8>> -> + true; + + <<"z"/utf8>> -> + true; + + _ -> + false + end. + +-spec is_alphanum(binary()) -> boolean(). +is_alphanum(Grapheme) -> + (is_digit(Grapheme) orelse is_upper(Grapheme)) orelse is_lower(Grapheme). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/LICENSE b/test-community-packages-javascript/build/packages/non_empty_list/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/non_empty_list/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/test-community-packages-javascript/build/packages/non_empty_list/README.md b/test-community-packages-javascript/build/packages/non_empty_list/README.md new file mode 100644 index 00000000000..4502421a799 --- /dev/null +++ b/test-community-packages-javascript/build/packages/non_empty_list/README.md @@ -0,0 +1,40 @@ +# non_empty_list + +[![Package Version](https://img.shields.io/hexpm/v/non_empty_list)](https://hex.pm/packages/non_empty_list) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/non_empty_list/) +![CI](https://github.com/giacomocavalieri/non_empty_list/workflows/CI/badge.svg?branch=main) + +Non-empty lists in Gleam ✨ + +> ⚙️ This package supports both the Erlang and JavaScript target! + +## Installation + +To add this package to your Gleam project: + +```sh +gleam add non_empty_list +``` + +## Usage + +Import the `non_empty_list` module and write some code! + +```gleam +import non_empty_list +import gleam/int +import gleam/io + +pub fn main() { + non_empty_list.new(1, [2, 3, 4]) + |> non_empty_list.reduce(with: fn(n, m) { n + m }) + |> int.to_string + |> io.println +} +``` + +## Contributing + +This package exposes most of the same functions you'd find in the `gleam/list` module but it may be missing some useful functions. + +If you think there's a missing function that would fit here, or if you spot a bug don't be afraid to open PRs, issues or requests of any kind! Any contribution is welcome 💜 diff --git a/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml b/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml new file mode 100644 index 00000000000..4ac8d3b865f --- /dev/null +++ b/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml @@ -0,0 +1,13 @@ +name = "non_empty_list" +version = "1.0.0" +description = "Non-empty lists in Gleam" + +licences = ["Apache-2.0"] +repository = { type = "github", user = "giacomocavalieri", repo = "non_empty_list" } +links = [] + +[dependencies] +gleam_stdlib = "~> 0.29" + +[dev-dependencies] +glacier = "~> 0.8" diff --git a/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl b/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl new file mode 100644 index 00000000000..d88aaf5f88b --- /dev/null +++ b/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl @@ -0,0 +1 @@ +-record(non_empty_list, {first :: any(), rest :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src new file mode 100644 index 00000000000..ec63d53e799 --- /dev/null +++ b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src @@ -0,0 +1,8 @@ +{application, non_empty_list, [ + {vsn, "1.0.0"}, + {applications, [glacier, + gleam_stdlib]}, + {description, "Non-empty lists in Gleam"}, + {modules, [non_empty_list]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl new file mode 100644 index 00000000000..efb67411150 --- /dev/null +++ b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl @@ -0,0 +1,304 @@ +-module(non_empty_list). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([first/1, last/1, new/2, append_list/2, from_list/1, intersperse/2, map/2, prepend/2, reduce/2, rest/1, single/1, to_list/1, append/2, drop/2, reverse/1, map_fold/3, scan/3, shuffle/1, sort/2, take/2, unique/1, unzip/1, zip/2, strict_zip/2, flatten/1, flat_map/2, index_map/2]). +-export_type([non_empty_list/1, list_was_empty/0]). + +-type non_empty_list(GJS) :: {non_empty_list, GJS, list(GJS)}. + +-type list_was_empty() :: list_was_empty. + +-spec first(non_empty_list(GKE)) -> GKE. +first(List) -> + erlang:element(2, List). + +-spec last(non_empty_list(GLP)) -> GLP. +last(List) -> + _pipe = gleam@list:last(erlang:element(3, List)), + gleam@result:unwrap(_pipe, erlang:element(2, List)). + +-spec new(GMA, list(GMA)) -> non_empty_list(GMA). +new(First, Rest) -> + {non_empty_list, First, Rest}. + +-spec append_list(non_empty_list(GJX), list(GJX)) -> non_empty_list(GJX). +append_list(First, Second) -> + new( + erlang:element(2, First), + gleam@list:append(erlang:element(3, First), Second) + ). + +-spec from_list(list(GKY)) -> {ok, non_empty_list(GKY)} | + {error, list_was_empty()}. +from_list(List) -> + case List of + [] -> + {error, list_was_empty}; + + [First | Rest] -> + {ok, new(First, Rest)} + end. + +-spec intersperse(non_empty_list(GLM), GLM) -> non_empty_list(GLM). +intersperse(List, Elem) -> + new( + erlang:element(2, List), + [Elem | gleam@list:intersperse(erlang:element(3, List), Elem)] + ). + +-spec map(non_empty_list(GLR), fun((GLR) -> GLT)) -> non_empty_list(GLT). +map(List, Fun) -> + new( + Fun(erlang:element(2, List)), + gleam@list:map(erlang:element(3, List), Fun) + ). + +-spec prepend(non_empty_list(GMD), GMD) -> non_empty_list(GMD). +prepend(List, Item) -> + new(Item, [erlang:element(2, List) | erlang:element(3, List)]). + +-spec reduce(non_empty_list(GMG), fun((GMG, GMG) -> GMG)) -> GMG. +reduce(List, Fun) -> + gleam@list:fold(erlang:element(3, List), erlang:element(2, List), Fun). + +-spec rest(non_empty_list(GMI)) -> list(GMI). +rest(List) -> + erlang:element(3, List). + +-spec single(GMV) -> non_empty_list(GMV). +single(First) -> + new(First, []). + +-spec to_list(non_empty_list(GNK)) -> list(GNK). +to_list(Non_empty) -> + [erlang:element(2, Non_empty) | erlang:element(3, Non_empty)]. + +-spec append(non_empty_list(GJT), non_empty_list(GJT)) -> non_empty_list(GJT). +append(First, Second) -> + new( + erlang:element(2, First), + gleam@list:append(erlang:element(3, First), to_list(Second)) + ). + +-spec drop(non_empty_list(GKB), integer()) -> list(GKB). +drop(List, N) -> + _pipe = List, + _pipe@1 = to_list(_pipe), + gleam@list:drop(_pipe@1, N). + +-spec reverse(non_empty_list(GML)) -> non_empty_list(GML). +reverse(List) -> + _assert_subject = begin + _pipe = List, + _pipe@1 = to_list(_pipe), + _pipe@2 = gleam@list:reverse(_pipe@1), + from_list(_pipe@2) + end, + {ok, Reversed} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"non_empty_list"/utf8>>, + function => <<"reverse"/utf8>>, + line => 378}) + end, + Reversed. + +-spec map_fold(non_empty_list(GLV), GLX, fun((GLX, GLV) -> {GLX, GLY})) -> {GLX, + non_empty_list(GLY)}. +map_fold(List, Acc, Fun) -> + {Acc@1, First_elem} = Fun(Acc, erlang:element(2, List)), + _pipe = gleam@list:fold( + erlang:element(3, List), + {Acc@1, single(First_elem)}, + fun(Acc_non_empty, Item) -> + {Acc@2, Non_empty} = Acc_non_empty, + {Acc@3, New_item} = Fun(Acc@2, Item), + {Acc@3, prepend(Non_empty, New_item)} + end + ), + gleam@pair:map_second(_pipe, fun reverse/1). + +-spec scan(non_empty_list(GMO), GMQ, fun((GMQ, GMO) -> GMQ)) -> non_empty_list(GMQ). +scan(List, Initial, Fun) -> + _assert_subject = begin + _pipe = List, + _pipe@1 = to_list(_pipe), + _pipe@2 = gleam@list:scan(_pipe@1, Initial, Fun), + from_list(_pipe@2) + end, + {ok, Scanned} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"non_empty_list"/utf8>>, + function => <<"scan"/utf8>>, + line => 400}) + end, + Scanned. + +-spec shuffle(non_empty_list(GMS)) -> non_empty_list(GMS). +shuffle(List) -> + _assert_subject = begin + _pipe = List, + _pipe@1 = to_list(_pipe), + _pipe@2 = gleam@list:shuffle(_pipe@1), + from_list(_pipe@2) + end, + {ok, Shuffled} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"non_empty_list"/utf8>>, + function => <<"shuffle"/utf8>>, + line => 423}) + end, + Shuffled. + +-spec sort(non_empty_list(GMX), fun((GMX, GMX) -> gleam@order:order())) -> non_empty_list(GMX). +sort(List, Compare) -> + _assert_subject = begin + _pipe = List, + _pipe@1 = to_list(_pipe), + _pipe@2 = gleam@list:sort(_pipe@1, Compare), + from_list(_pipe@2) + end, + {ok, Sorted} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"non_empty_list"/utf8>>, + function => <<"sort"/utf8>>, + line => 459}) + end, + Sorted. + +-spec take(non_empty_list(GNH), integer()) -> list(GNH). +take(List, N) -> + _pipe = List, + _pipe@1 = to_list(_pipe), + gleam@list:take(_pipe@1, N). + +-spec unique(non_empty_list(GNN)) -> non_empty_list(GNN). +unique(List) -> + _assert_subject = begin + _pipe = List, + _pipe@1 = to_list(_pipe), + _pipe@2 = gleam@list:unique(_pipe@1), + from_list(_pipe@2) + end, + {ok, Unique} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"non_empty_list"/utf8>>, + function => <<"unique"/utf8>>, + line => 557}) + end, + Unique. + +-spec unzip(non_empty_list({GNQ, GNR})) -> {non_empty_list(GNQ), + non_empty_list(GNR)}. +unzip(List) -> + _pipe = gleam@list:unzip(erlang:element(3, List)), + _pipe@1 = gleam@pair:map_first( + _pipe, + fun(_capture) -> + new(erlang:element(1, erlang:element(2, List)), _capture) + end + ), + gleam@pair:map_second( + _pipe@1, + fun(_capture@1) -> + new(erlang:element(2, erlang:element(2, List)), _capture@1) + end + ). + +-spec zip(non_empty_list(GNV), non_empty_list(GNX)) -> non_empty_list({GNV, GNX}). +zip(List, Other) -> + new( + {erlang:element(2, List), erlang:element(2, Other)}, + gleam@list:zip(erlang:element(3, List), erlang:element(3, Other)) + ). + +-spec strict_zip(non_empty_list(GNA), non_empty_list(GNC)) -> {ok, + non_empty_list({GNA, GNC})} | + {error, gleam@list:length_mismatch()}. +strict_zip(List, Other) -> + case gleam@list:length(to_list(List)) =:= gleam@list:length(to_list(Other)) of + true -> + {ok, zip(List, Other)}; + + false -> + {error, length_mismatch} + end. + +-spec do_flatten(list(non_empty_list(GKP)), non_empty_list(GKP)) -> non_empty_list(GKP). +do_flatten(Lists, Accumulator) -> + case Lists of + [] -> + reverse(Accumulator); + + [List | Further_lists] -> + do_flatten(Further_lists, reverse_and_prepend(List, Accumulator)) + end. + +-spec flatten(non_empty_list(non_empty_list(GKL))) -> non_empty_list(GKL). +flatten(Lists) -> + do_flatten(erlang:element(3, Lists), reverse(erlang:element(2, Lists))). + +-spec flat_map(non_empty_list(GKG), fun((GKG) -> non_empty_list(GKI))) -> non_empty_list(GKI). +flat_map(List, Fun) -> + _pipe = List, + _pipe@1 = map(_pipe, Fun), + flatten(_pipe@1). + +-spec reverse_and_prepend(non_empty_list(GKU), non_empty_list(GKU)) -> non_empty_list(GKU). +reverse_and_prepend(Prefix, Suffix) -> + case erlang:element(3, Prefix) of + [] -> + new(erlang:element(2, Prefix), to_list(Suffix)); + + [First | Rest] -> + reverse_and_prepend( + new(First, Rest), + new(erlang:element(2, Prefix), to_list(Suffix)) + ) + end. + +-spec do_index_map( + list(GLH), + list(GLJ), + integer(), + fun((integer(), GLH) -> GLJ) +) -> list(GLJ). +do_index_map(List, Accumulator, Index, Fun) -> + case List of + [] -> + gleam@list:reverse(Accumulator); + + [First | Rest] -> + do_index_map( + Rest, + [Fun(Index, First) | Accumulator], + Index + 1, + Fun + ) + end. + +-spec index_map(non_empty_list(GLD), fun((integer(), GLD) -> GLF)) -> non_empty_list(GLF). +index_map(List, Fun) -> + new( + Fun(0, erlang:element(2, List)), + do_index_map(erlang:element(3, List), [], 1, Fun) + ). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam new file mode 100644 index 00000000000..9ceb47e143e --- /dev/null +++ b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam @@ -0,0 +1,607 @@ +import gleam/list +import gleam/result +import gleam/pair +import gleam/order.{Order} + +/// A list that is guaranteed to contain at least one item. +pub type NonEmptyList(a) { + NonEmptyList(first: a, rest: List(a)) +} + +/// An error that occurs when trying to convert an empty list into a +/// non empty list. +/// +pub type ListWasEmpty { + ListWasEmpty +} + +/// Joins a non-empty list onto the end of a non-empty list. +/// +/// This function runs in linear time, and it traverses and copies the first non-empty list. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> append(new(5, [6, 7])) +/// NonEmptyList(1, [2, 3, 4, 5, 6, 7]) +/// ``` +/// +/// ```gleam +/// > single("a") +/// > |> append(new("b", ["c"]) +/// NonEmptyList("a", ["b", "c"]) +/// ```` +/// +pub fn append( + first: NonEmptyList(a), + second: NonEmptyList(a), +) -> NonEmptyList(a) { + new(first.first, list.append(first.rest, to_list(second))) +} + +/// Joins a list onto the end of a non-empty list. +/// +/// This function runs in linear time, and it traverses and copies the first non-empty list. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> append_list([5, 6, 7]) +/// NonEmptyList(1, [2, 3, 4, 5, 6, 7]) +/// ``` +/// +/// ```gleam +/// > new("a", ["b", "c"]) +/// > |> append_list([]) +/// NonEmptyList("a", ["b", "c"]) +/// ``` +/// +pub fn append_list(first: NonEmptyList(a), second: List(a)) -> NonEmptyList(a) { + new(first.first, list.append(first.rest, second)) +} + +/// Returns a list that is the given non-empty list with up to the given +/// number of elements removed from the front of the list. +/// +/// ## Examples +/// ```gleam +/// > new("a", ["b", "c"]) +/// > |> drop(up_to: 2) +/// ["c"] +/// ``` +/// +/// ```gleam +/// > new("a", ["b", "c"]) +/// > |> drop(up_to: 3) +/// [] +/// ``` +/// +pub fn drop(from list: NonEmptyList(a), up_to n: Int) -> List(a) { + list + |> to_list + |> list.drop(up_to: n) +} + +/// Gets the first element from the start of the non-empty list. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> first +/// 1 +/// ``` +/// +pub fn first(list: NonEmptyList(a)) -> a { + list.first +} + +/// Maps the non-empty list with the given function and then flattens it. +/// +/// ## Examples +/// ```gleam +/// > new(1, [3, 5]) +/// > |> flat_map(fn(x) { new(x, [x + 1]) }) +/// NonEmptyList(1, [2, 3, 4, 5, 6]) +/// ``` +/// +pub fn flat_map( + over list: NonEmptyList(a), + with fun: fn(a) -> NonEmptyList(b), +) -> NonEmptyList(b) { + list + |> map(fun) + |> flatten +} + +/// Flattens a non-empty list of non-empty lists into a single non-empty list. +/// +/// This function traverses all elements twice. +/// +/// ### Examples +/// +/// ```gleam +/// > new(new(1, [2, 3]), [new(3, [4, 5])]) +/// > |> flatten +/// NonEmptyList(1, [2, 3, 4, 5]) +/// ``` +/// +pub fn flatten(lists: NonEmptyList(NonEmptyList(a))) -> NonEmptyList(a) { + do_flatten(lists.rest, reverse(lists.first)) +} + +fn do_flatten( + lists: List(NonEmptyList(a)), + accumulator: NonEmptyList(a), +) -> NonEmptyList(a) { + case lists { + [] -> reverse(accumulator) + [list, ..further_lists] -> + do_flatten(further_lists, reverse_and_prepend(list, accumulator)) + } +} + +fn reverse_and_prepend( + list prefix: NonEmptyList(a), + to suffix: NonEmptyList(a), +) -> NonEmptyList(a) { + case prefix.rest { + [] -> new(prefix.first, to_list(suffix)) + [first, ..rest] -> + reverse_and_prepend(new(first, rest), new(prefix.first, to_list(suffix))) + } +} + +/// Attempts to turn a list into a non-empty list, fails if the starting +/// list is empty. +/// +/// ## Examples +/// ```gleam +/// > from_list([1, 2, 3, 4]) +/// Ok(NonEmptyList(1, [2, 3, 4])) +/// ``` +/// +/// ```gleam +/// > from_list(["a"]) +/// Ok(NonEmptyList("a", [])) +/// ``` +/// +/// ```gleam +/// > from_list([]) +/// Error(ListWasEmpty) +/// ``` +/// +pub fn from_list(list: List(a)) -> Result(NonEmptyList(a), ListWasEmpty) { + case list { + [] -> Error(ListWasEmpty) + [first, ..rest] -> Ok(new(first, rest)) + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one and their index. +/// +/// The index starts at 0, so the first element is 0, the second is 1, and so on. +/// +/// ## Examples +/// ```gleam +/// > new("a", ["b", "c"]) +/// > |> index_map(fn(index, letter) { #(index, letter) }) +/// NonEmpty(#(0, "a"), [#(1, "b"), #(2, "c")]) +/// ``` +/// +pub fn index_map( + list: NonEmptyList(a), + with fun: fn(Int, a) -> b, +) -> NonEmptyList(b) { + new(fun(0, list.first), do_index_map(list.rest, [], 1, fun)) +} + +fn do_index_map( + list: List(a), + accumulator: List(b), + index: Int, + fun: fn(Int, a) -> b, +) -> List(b) { + case list { + [] -> list.reverse(accumulator) + [first, ..rest] -> + do_index_map(rest, [fun(index, first), ..accumulator], index + 1, fun) + } +} + +/// Inserts a given value between each existing element in a given list. +/// +/// This function runs in linear time and copies the list. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> intersperse(with: 0) +/// NonEmptyList(1, [0, 2, 0, 3, 0, 4]) +/// ``` +/// +/// ```gleam +/// > single("a") +/// > |> intersperse(with: "z") +/// NonEmptyList("a", ["z"]) +/// ``` +/// +pub fn intersperse(list: NonEmptyList(a), with elem: a) -> NonEmptyList(a) { + new(list.first, [elem, ..list.intersperse(list.rest, with: elem)]) +} + +/// Returns the last element in the given list. +/// +/// This function runs in linear time. +/// For a collection oriented around performant access at either end, +/// see `gleam/queue.Queue`. +/// +/// ## Examples +/// ```gleam +/// > single(1) +/// > |> last +/// 1 +/// ``` +/// +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> last +/// 4 +/// ``` +/// +pub fn last(list: NonEmptyList(a)) -> a { + list.last(list.rest) + |> result.unwrap(list.first) +} + +/// Returns a new non-empty list containing only the elements of the first +/// non-empty list after the function has been applied to each one. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3]) +/// > |> map(fn(x) { x + 1 }) +/// NonEmpty(2, [3, 4]) +/// ``` +/// +pub fn map(over list: NonEmptyList(a), with fun: fn(a) -> b) -> NonEmptyList(b) { + new(fun(list.first), list.map(list.rest, with: fun)) +} + +/// Similar to `map` but also lets you pass around an accumulated value. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3]) +/// > |> map_fold(from: 100, with: fn(memo, n) { #(memo + i, i * 2) }) +/// #(106, NonEmpty(2, [4, 6])) +/// ``` +/// +pub fn map_fold( + over list: NonEmptyList(a), + from acc: b, + with fun: fn(b, a) -> #(b, c), +) -> #(b, NonEmptyList(c)) { + let #(acc, first_elem) = fun(acc, list.first) + list.fold( + over: list.rest, + from: #(acc, single(first_elem)), + with: fn(acc_non_empty, item) { + let #(acc, non_empty) = acc_non_empty + let #(acc, new_item) = fun(acc, item) + #(acc, prepend(to: non_empty, this: new_item)) + }, + ) + |> pair.map_second(reverse) +} + +/// Creates a new non-empty list given its first element and a list +/// for the rest of the elements. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// NonEmptyList(1, [2, 3, 4]) +/// ``` +/// ```gleam +/// > new("a", []) +/// NonEmptyList("a", []) +/// ``` +/// +pub fn new(first: a, rest: List(a)) -> NonEmptyList(a) { + NonEmptyList(first, rest) +} + +/// Prefixes an item to a non-empty list. +/// +/// ## Examples +/// ```gleam +/// > new(2, [3, 4]) +/// > |> prepend(1) +/// NonEmptyList(1, [2, 3, 4]) +/// ``` +/// +pub fn prepend(to list: NonEmptyList(a), this item: a) -> NonEmptyList(a) { + new(item, [list.first, ..list.rest]) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first element in the non-empty list and combines it with each +/// subsequent element in turn using the given function. +/// The function is called as `fun(accumulator, current_element)`. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> reduce(fn(acc, x) { acc + x }) +/// 10 +/// ``` +/// +pub fn reduce(over list: NonEmptyList(a), with fun: fn(a, a) -> a) -> a { + list.fold(over: list.rest, from: list.first, with: fun) +} + +/// Returns the list minus the first element. Since the remaining list could +/// be empty this functions returns a normal list. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> rest +/// [2, 3, 4] +/// ``` +/// +/// ```gleam +/// > single(1) +/// > |> rest +/// [] +/// ``` +/// +pub fn rest(list: NonEmptyList(a)) -> List(a) { + list.rest +} + +/// Creates a new non-empty list from a given non-empty list containing the same elements +/// but in the opposite order. +/// +/// This function has to traverse the non-empty list to create the new reversed +/// non-empty list, so it runs in linear time. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> reverse +/// NonEmptyList(4, [3, 2, 1]) +/// ``` +/// +pub fn reverse(list: NonEmptyList(a)) -> NonEmptyList(a) { + let assert Ok(reversed) = + list + |> to_list + |> list.reverse + |> from_list + reversed +} + +/// Similar to fold, but yields the state of the accumulator at each stage. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> scan(from: 100, with: fn(acc, i) { acc + i }) +/// NonEmptyList(101 [103, 106, 110]) +/// ``` +/// +pub fn scan( + over list: NonEmptyList(a), + from initial: b, + with fun: fn(b, a) -> b, +) -> NonEmptyList(b) { + let assert Ok(scanned) = + list + |> to_list + |> list.scan(from: initial, with: fun) + |> from_list + scanned +} + +/// Takes a non-empty list, randomly sorts all items and returns the shuffled +/// non-empty list. +/// +/// This function uses Erlang's `:rand` module or Javascript's +/// `Math.random()` to calcuate the index shuffling. +/// +/// ## Examples +/// +/// ```gleam +/// > new("a", ["b", "c", "d"]) +/// > |> shuffle +/// NonEmptyList("c", ["a", "d", "b"]) +/// ``` +/// +pub fn shuffle(list: NonEmptyList(a)) -> NonEmptyList(a) { + let assert Ok(shuffled) = + list + |> to_list + |> list.shuffle + |> from_list + shuffled +} + +/// Creates a non-empty list with a single element. +/// +/// ## Examples +/// ```gleam +/// > single(1) +/// NonEmptyList(1, []) +/// ``` +/// +pub fn single(first: a) -> NonEmptyList(a) { + new(first, []) +} + +/// Sorts a given non-empty list from smallest to largest based upon the +/// ordering specified by a given function. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > new(4, [1, 3, 4, 2, 6, 5]) +/// > sort(by: int.compare) +/// NonEmptyList(1, [2, 3, 4, 4, 5, 6]) +/// ``` +/// +pub fn sort( + list: NonEmptyList(a), + by compare: fn(a, a) -> Order, +) -> NonEmptyList(a) { + let assert Ok(sorted) = + list + |> to_list + |> list.sort(by: compare) + |> from_list + sorted +} + +/// Takes two non-empty lists and returns a single non-empty list of 2-element tuples. +/// +/// If one of the non-empty lists is longer than the other, an `Error` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > strict_zip(single(1), new("a", ["b", "c"])) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip(new(1, [2, 3]), single("a")) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip(new(1, [2, 3]), new("a", ["b", "c"])) +/// Ok(NonEmptyList(#(1, "a"), [#(2, "b"), #(3, "c")])) +/// ``` +/// +pub fn strict_zip( + list: NonEmptyList(a), + with other: NonEmptyList(b), +) -> Result(NonEmptyList(#(a, b)), list.LengthMismatch) { + case list.length(to_list(list)) == list.length(to_list(other)) { + True -> Ok(zip(list, with: other)) + False -> Error(list.LengthMismatch) + } +} + +/// Returns a list containing the first given number of elements from the given +/// non-empty list. +/// +/// If the element has less than the number of elements then the full list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > take(2) +/// [1, 2] +/// ``` +/// +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > take(9) +/// [1, 2, 3, 4] +/// ``` +/// +pub fn take(from list: NonEmptyList(a), up_to n: Int) -> List(a) { + list + |> to_list + |> list.take(n) +} + +/// Turns a non-empty list back into a normal list with the same +/// elements. +/// +/// ## Examples +/// ```gleam +/// > new(1, [2, 3, 4]) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +/// ```gleam +/// > single("a") +/// > |> to_list +/// ["a"] +/// ``` +/// +pub fn to_list(non_empty: NonEmptyList(a)) -> List(a) { + [non_empty.first, ..non_empty.rest] +} + +/// Removes any duplicate elements from a given list. +/// +/// This function returns in loglinear time. +/// +/// ## Examples +/// ```gleam +/// > new(1, [1, 2, 3, 1, 4, 4, 3]) +/// > |> unique +/// NonEmptyList(1, [2, 3, 4]) +/// ``` +/// +pub fn unique(list: NonEmptyList(a)) -> NonEmptyList(a) { + let assert Ok(unique) = + list + |> to_list + |> list.unique + |> from_list + unique +} + +/// Takes a single non-empty list of 2-element tuples and returns two +/// non-empty lists. +/// +/// ## Examples +/// ```gleam +/// > new(#(1, "a"), [#(2, "b"), #(3, "c")]) +/// > |> unzip +/// #(NonEmptyList(1, [2, 3]), NonEmptyList("a", ["b", "c"])) +/// ``` +/// +pub fn unzip(list: NonEmptyList(#(a, b))) -> #(NonEmptyList(a), NonEmptyList(b)) { + list.unzip(list.rest) + |> pair.map_first(new(list.first.0, _)) + |> pair.map_second(new(list.first.1, _)) +} + +/// Takes two non-empty lists and returns a single non-empty list of 2-element tuples. +/// +/// If one of the non-empty lists is longer than the other, the remaining elements from +/// the longer non-empty list are not used. +/// +/// ## Examples +/// ```gleam +/// > zip(new(1, [2, 3]), single("a")) +/// NonEmptyList(#(1, "a"), []) +/// ``` +/// +/// ```gleam +/// > zip(single(1), new("a", ["b", "c"])) +/// NonEmptyList(#(1, "a"), []) +/// ``` +/// +/// ```gleam +/// > zip(new(1, [2, 3]), new("a", ["b", "c"])) +/// NonEmptyList(#(1, "a"), [#(2, "b"), #(3, "c")]) +/// ``` +/// +pub fn zip( + list: NonEmptyList(a), + with other: NonEmptyList(b), +) -> NonEmptyList(#(a, b)) { + new(#(list.first, other.first), list.zip(list.rest, other.rest)) +} diff --git a/test-community-packages-javascript/build/packages/packages.toml b/test-community-packages-javascript/build/packages/packages.toml new file mode 100644 index 00000000000..948d847a082 --- /dev/null +++ b/test-community-packages-javascript/build/packages/packages.toml @@ -0,0 +1,30 @@ +[packages] +gliew = "0.3.0" +gleam_community_colour = "1.1.0" +gleam_stdlib = "0.29.2" +simplifile = "0.1.4" +gleam_bitwise = "1.2.0" +nakai = "0.8.0" +gleam_erlang = "0.19.0" +gleeunit = "0.10.1" +gsv = "0.1.0" +gleam_community_ansi = "1.1.0" +trie_again = "1.1.1" +ream = "0.1.0" +gleam_cors = "0.2.0" +gleam_otp = "0.5.3" +glisten = "0.7.0" +nibble = "0.2.3" +gleam_crypto = "0.3.1" +globe = "0.1.0" +glove = "0.2.0" +mist = "0.11.0" +gloml = "0.1.2" +toml = "0.7.0" +gleam_http = "3.2.0" +hug = "0.1.0" +glenvy = "0.4.0" +glx = "0.2.0" +non_empty_list = "1.0.0" +glerm = "0.1.0" +gleamy_structures = "0.3.0" diff --git a/test-community-packages-javascript/build/packages/ream/LICENSE b/test-community-packages-javascript/build/packages/ream/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/test-community-packages-javascript/build/packages/ream/README.md b/test-community-packages-javascript/build/packages/ream/README.md new file mode 100644 index 00000000000..f31e5667fb3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/README.md @@ -0,0 +1,64 @@ +# ream + +[![Package Version](https://img.shields.io/hexpm/v/ream)](https://hex.pm/packages/ream) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/ream/) + +REAM is an event-sourcing system. + +The REAM server is a simple TCP server that's receiving events from aggregators which are +sending the event and a status update. The idea is: + +- The Aggregator receives a command. +- The aggregator validates the command and generates: + 1. One or more events are generated by the aggregator and published into REAM. + 2. A modification in the state is performed in the aggregator and stored in REAM. +- Subscribers, mainly projectors receive the event. +- These subscribers perform a change in the schema and publish changes into projections. + +Therefore we have three different but related storage: + +- Events. It's getting events in different streams. We can create as many streams as we need. +- Aggregations. It's storing the state for the aggregators based on the last processed event for a specific stream. +- Projections. Stored the projections based on the information provided by the projectors. + +The main idea is to provide an easy way for implementing aggregators and projectors to process the data we need in the way we need it. + +## Quick start + +```sh +gleam run # Run the project +gleam test # Run the tests +gleam shell # Run an Erlang shell +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add ream +``` + +and its documentation can be found at <https://hexdocs.pm/ream>. + +## Architecture and Design + +You can check the protocol [here](docs/protocol.md) and how the storage is going to take place [here](docs/storage.md). + +## License + +Apache License Version 2.0, see [LICENSE](LICENSE) + +Copyright 2023 Altenwald + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/test-community-packages-javascript/build/packages/ream/gleam.toml b/test-community-packages-javascript/build/packages/ream/gleam.toml new file mode 100644 index 00000000000..43c839f2fbc --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/gleam.toml @@ -0,0 +1,27 @@ +name = "ream" +version = "0.1.0" +description = "REAM is an event sourcing system" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. + +licences = ["Apache-2.0"] +repository = { type = "github", user = "altenwald", repo = "ream" } +# links = [{ title = "Website", href = "https://gleam.run" }] + +[dependencies] +gleam_stdlib = "~> 0.28" +gleam_otp = "~> 0.5" +hug = "~> 0.1" +gloml = "~> 0.1" +gleam_erlang = "~> 0.19" + +[dev-dependencies] +glacier = "~> 0.8" + +[documentation] +pages = [ + { title = "LICENSE", path = "license.html", source = "LICENSE" }, + { title = "Protocol", path = "protocol.html", source = "docs/protocol.md" }, + { title = "Storage", path = "storage.html", source = "docs/storage.md" } +] diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl new file mode 100644 index 00000000000..686a9b2f541 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl @@ -0,0 +1 @@ +-record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl new file mode 100644 index 00000000000..686a9b2f541 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl @@ -0,0 +1 @@ +-record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl new file mode 100644 index 00000000000..db5abbdf21d --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl @@ -0,0 +1 @@ +-record(ok, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl new file mode 100644 index 00000000000..686a9b2f541 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl @@ -0,0 +1 @@ +-record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl new file mode 100644 index 00000000000..eb7e3ac051a --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl @@ -0,0 +1 @@ +-record(delayed_write, {size :: integer(), delay :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl new file mode 100644 index 00000000000..2d13f93ccb9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl @@ -0,0 +1 @@ +-record(encoding, {encoding :: ream@storage@file:encoding_type()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl new file mode 100644 index 00000000000..963a65ce424 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl @@ -0,0 +1 @@ +-record(read_ahead, {size :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl new file mode 100644 index 00000000000..0be9823bd17 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl @@ -0,0 +1,5 @@ +-record(mem_table, { + entries :: gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry()), + size :: integer(), + max_size :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl new file mode 100644 index 00000000000..b342d1a4d84 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl @@ -0,0 +1,4 @@ +-record(mem_table_entry, { + key :: binary(), + value :: ream@storage@kv@value:value() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl new file mode 100644 index 00000000000..1631ca7075a --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl @@ -0,0 +1,6 @@ +-record(value, { + offset :: integer(), + deleted :: boolean(), + data :: gleam@option:option(bitstring()), + file_id :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl new file mode 100644 index 00000000000..b8fd91be66a --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl @@ -0,0 +1,7 @@ +-record(value_file, { + id :: integer(), + handler :: gleam@erlang@process:pid_(), + size :: integer(), + max_size :: integer(), + file_path :: binary() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl new file mode 100644 index 00000000000..9582b309c40 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl @@ -0,0 +1,7 @@ +-record(value_file_info, { + file_id :: integer(), + size :: integer(), + max_size :: integer(), + entries :: integer(), + deleted :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl new file mode 100644 index 00000000000..75884f81d1d --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl @@ -0,0 +1,11 @@ +-record(kv, { + base_path :: binary(), + name :: binary(), + memtable_ranges :: gleam@map:map_(integer(), ream@storage@kv:mem_table_range()), + active_value_file :: gleam@option:option(integer()), + values :: gleam@map:map_(integer(), ream@storage@kv@value:value_file()), + memtables_loaded :: integer(), + max_memtables_loaded :: integer(), + max_memtable_size :: integer(), + max_value_size :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl new file mode 100644 index 00000000000..3bd9ff18d40 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl @@ -0,0 +1,12 @@ +-record(kv_info, { + base_path :: binary(), + name :: binary(), + values :: integer(), + values_size_bytes :: integer(), + memtables_total :: integer(), + memtables_loaded :: integer(), + memtables_loaded_size_bytes :: integer(), + max_memtables_loaded :: integer(), + max_memtable_size :: integer(), + max_value_size :: integer() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl new file mode 100644 index 00000000000..71ec67b0599 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl @@ -0,0 +1,5 @@ +-record(mem_table_range, { + lower :: integer(), + upper :: integer(), + memtable :: gleam@option:option(ream@storage@kv@memtable:mem_table()) +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl new file mode 100644 index 00000000000..8eaa99ab752 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl @@ -0,0 +1 @@ +-record(event, {offset :: integer(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl new file mode 100644 index 00000000000..eab4d784cf5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl @@ -0,0 +1,6 @@ +-record(event_file, { + id :: integer(), + handler :: gleam@erlang@process:pid_(), + size :: integer(), + file_path :: binary() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl new file mode 100644 index 00000000000..eed9e04ebec --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl @@ -0,0 +1 @@ +-record(index, {offset :: integer(), size :: integer(), file_id :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl new file mode 100644 index 00000000000..7a25f9bdfcb --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl @@ -0,0 +1,5 @@ +-record(index_file, { + handler :: gleam@erlang@process:pid_(), + size :: integer(), + file_path :: binary() +}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl new file mode 100644 index 00000000000..ff7a5576983 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl @@ -0,0 +1,7 @@ +-record(stream, { + name :: binary(), + index :: ream@storage@stream@index:index_file(), + active_file :: gleam@option:option(ream@storage@stream@event:event_file()), + files :: gleam@map:map_(integer(), ream@storage@stream@event:event_file()), + base_path :: binary() +}). diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.app.src b/test-community-packages-javascript/build/packages/ream/src/ream.app.src new file mode 100644 index 00000000000..ad44dc9c44d --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream.app.src @@ -0,0 +1,24 @@ +{application, ream, [ + {vsn, "0.1.0"}, + {applications, [glacier, + gleam_erlang, + gleam_otp, + gleam_stdlib, + gloml, + hug]}, + {description, "REAM is an event sourcing system"}, + {modules, [ream, + ream@storage@file, + ream@storage@file@close, + ream@storage@file@read, + ream@storage@file@write, + ream@storage@kv, + ream@storage@kv@memtable, + ream@storage@kv@sstable, + ream@storage@kv@value, + ream@storage@stream, + ream@storage@stream@event, + ream@storage@stream@index, + ream@uuid]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.erl b/test-community-packages-javascript/build/packages/ream/src/ream.erl new file mode 100644 index 00000000000..a54ca2a1af2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream.erl @@ -0,0 +1 @@ +-module(ream). diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.gleam b/test-community-packages-javascript/build/packages/ream/src/ream.gleam new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream.gleam @@ -0,0 +1 @@ + diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam new file mode 100644 index 00000000000..64e87f2e0d3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam @@ -0,0 +1,103 @@ +import gleam/erlang/process.{Pid} +import gleam/erlang/file +import ream/storage/file/read +import ream/storage/file/close +import ream/storage/file/write + +pub type Endian { + Big + Little +} + +pub type EncodingType { + Unicode + Utf8 + Utf16(Endian) + Utf32(Endian) + Latin1 +} + +pub type Mode { + Read + Write + Append + Exclusive + Raw + Binary + DelayedWrite(size: Int, delay: Int) + ReadAhead(size: Int) + Compressed + CompressedOne + Encoding(encoding: EncodingType) + Ram + Sync + Directory +} + +pub type Location { + Bof(Int) + Cur(Int) + Eof(Int) +} + +pub fn open(filename: String, mode: List(Mode)) -> Result(Pid, file.Reason) { + do_open(filename, [Binary, ..mode]) +} + +pub external fn do_open( + filename: String, + mode: List(Mode), +) -> Result(Pid, file.Reason) = + "file" "open" + +pub external fn read(io_device: Pid, bytes: Int) -> read.Result = + "file" "read" + +pub fn close(io_device: Pid) -> Result(Bool, file.Reason) { + case do_close(io_device) { + close.Ok -> Ok(True) + close.Error(reason) -> Error(reason) + } +} + +external fn do_close(io_device: Pid) -> close.Result = + "file" "close" + +pub fn write(io_device: Pid, data: BitString) -> Result(Bool, file.Reason) { + case do_write(io_device, data) { + write.Ok -> Ok(True) + write.Error(reason) -> Error(reason) + } +} + +external fn do_write(io_device: Pid, data: BitString) -> write.Result = + "file" "write" + +pub external fn dirname(filename: String) -> String = + "filename" "dirname" + +pub external fn basename(filename: String) -> String = + "filename" "basename" + +pub external fn join(parts: List(String)) -> String = + "filename" "join" + +pub external fn position( + io_device: Pid, + location: Location, +) -> Result(Int, file.Reason) = + "file" "position" + +pub fn recursive_make_directory(path: String) -> Result(Bool, file.Reason) { + case file.is_directory(path) { + Error(file.Enoent) -> { + let prev_dir = dirname(path) + let assert Ok(True) = recursive_make_directory(prev_dir) + let assert Ok(_) = file.make_directory(path) + Ok(True) + } + Error(file.Eexist) -> Ok(True) + Ok(True) -> Ok(True) + _ -> Error(file.Einval) + } +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam new file mode 100644 index 00000000000..8d98d62ae47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam @@ -0,0 +1,6 @@ +import gleam/erlang/file + +pub type Result { + Ok + Error(reason: file.Reason) +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam new file mode 100644 index 00000000000..571e0b0cb92 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam @@ -0,0 +1,7 @@ +import gleam/erlang/file + +pub type Result { + Ok(data: BitString) + Eof + Error(reason: file.Reason) +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam new file mode 100644 index 00000000000..8d98d62ae47 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam @@ -0,0 +1,6 @@ +import gleam/erlang/file + +pub type Result { + Ok + Error(reason: file.Reason) +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam new file mode 100644 index 00000000000..81f59437b30 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam @@ -0,0 +1,430 @@ +import gleam/erlang/process.{Pid} +import gleam/list +import gleam/map.{Map} +import gleam/option.{None, Option, Some} +import gleam/result.{try} +import ream/storage/file as fs +import ream/storage/file/read +import ream/storage/kv/memtable.{CapacityExceeded, MemTable} +import ream/storage/kv/sstable +import ream/storage/kv/value.{Value, ValueFile} +import ream/uuid + +pub type MemTableRange { + MemTableRange(lower: Int, upper: Int, memtable: Option(MemTable)) +} + +pub type KV { + KV( + base_path: String, + name: String, + memtable_ranges: Map(Int, MemTableRange), + active_value_file: Option(Int), + values: Map(Int, ValueFile), + memtables_loaded: Int, + max_memtables_loaded: Int, + max_memtable_size: Int, + max_value_size: Int, + ) +} + +pub type KVInfo { + KVInfo( + base_path: String, + name: String, + values: Int, + values_size_bytes: Int, + memtables_total: Int, + memtables_loaded: Int, + memtables_loaded_size_bytes: Int, + max_memtables_loaded: Int, + max_memtable_size: Int, + max_value_size: Int, + ) +} + +const min_bound = 0 + +const max_bound = 340_282_366_920_938_463_463_374_607_431_768_211_455 + +pub fn open( + path: String, + name: String, + max_memtables_loaded: Int, + max_memtable_size: Int, + max_value_size: Int, +) -> KV { + let path = fs.join([path, "kv", name]) + + let key_index_file = fs.join([path, "key", "index"]) + let assert Ok(True) = fs.recursive_make_directory(fs.dirname(key_index_file)) + let assert Ok(kv) = fs.open(key_index_file, [fs.Read, fs.Write]) + let ranges = + read_memtable_ranges( + kv, + fs.join([path, "key"]), + max_memtable_size, + map.new(), + ) + let #(memtables_loaded, ranges) = case map.size(ranges) == 0 { + True -> { + let memtable = memtable.new(max_memtable_size) + let ranges = + [#(new_id(), MemTableRange(min_bound, max_bound, Some(memtable)))] + |> map.from_list() + #(1, ranges) + } + False -> #(0, ranges) + } + let assert Ok(_) = fs.close(kv) + + let value_index_file = fs.join([path, "value", "index"]) + let assert Ok(True) = + fs.recursive_make_directory(fs.dirname(value_index_file)) + let assert Ok(kv) = fs.open(value_index_file, [fs.Read, fs.Write]) + let #(active_value_file, values) = + read_values(kv, fs.join([path, "value"]), None, max_value_size, map.new()) + let assert Ok(_) = fs.close(kv) + + KV( + path, + name, + ranges, + active_value_file, + values, + memtables_loaded, + max_memtables_loaded, + max_memtable_size, + max_value_size, + ) +} + +fn new_id() -> Int { + uuid.to_int(uuid.new()) +} + +fn read_memtable_ranges( + kv: Pid, + path: String, + max_size: Int, + acc: Map(Int, MemTableRange), +) -> Map(Int, MemTableRange) { + case fs.read(kv, 48) { + read.Ok(<<lower:size(128), upper:size(128), id:size(128)>>) -> { + let range = MemTableRange(lower, upper, None) + read_memtable_ranges(kv, path, max_size, map.insert(acc, id, range)) + } + read.Eof -> acc + read.Error(_err) -> { + let assert Ok(_) = fs.close(kv) + // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed + panic + } + } +} + +fn read_values( + kv: Pid, + path: String, + last_file_id: Option(Int), + max_value_size: Int, + acc: Map(Int, ValueFile), +) -> #(Option(Int), Map(Int, ValueFile)) { + case fs.read(kv, 16) { + read.Ok(<<file_id:size(128)>>) -> { + let assert Ok(value_file) = value.open(path, file_id, max_value_size) + read_values( + kv, + path, + Some(file_id), + max_value_size, + map.insert(acc, file_id, value_file), + ) + } + read.Eof -> #(last_file_id, acc) + read.Error(_err) -> { + let assert Ok(_) = fs.close(kv) + // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed + panic + } + } +} + +fn sstable_path(path: String, id: Int) -> String { + let parts = uuid.parts(uuid.from_int(id)) + fs.join([path, "key", ..parts]) +} + +fn find_range(kv: KV, key_hash: Int, max_size: Int) -> #(Int, KV) { + let max_memtables_loaded = kv.max_memtables_loaded + let assert #(#(loaded, Some(range_id)), range_list) = + kv.memtable_ranges + |> map.to_list() + |> list.map_fold( + #(kv.memtables_loaded, None), + fn(acc, entry) { + let #(id, range) = entry + let #(loaded, range_id) = acc + case + key_hash >= range.lower && key_hash <= range.upper, + range.memtable + { + True, Some(_) -> #(#(loaded, Some(id)), #(id, range)) + True, None -> { + let assert Ok(memtable) = + sstable.load(sstable_path(kv.base_path, id), max_size) + #( + #(loaded + 1, Some(id)), + #(id, MemTableRange(..range, memtable: Some(memtable))), + ) + } + False, Some(memtable) if loaded >= max_memtables_loaded -> { + let assert Ok(_) = + sstable.flush(memtable, sstable_path(kv.base_path, id)) + #( + #(loaded - 1, range_id), + #(id, MemTableRange(..range, memtable: None)), + ) + } + False, _ -> #(acc, #(id, range)) + } + }, + ) + + #( + range_id, + KV( + ..kv, + memtable_ranges: map.from_list(range_list), + memtables_loaded: loaded, + ), + ) +} + +pub fn close(kv: KV) -> Result(Nil, Nil) { + let assert Ok(_) = flush(kv) + + map.values(kv.values) + |> list.each(fn(v) { value.close(v) }) + + Ok(Nil) +} + +pub fn flush(kv: KV) -> Result(Nil, Nil) { + let key_index_file = fs.join([kv.base_path, "key", "index"]) + let assert Ok(True) = fs.recursive_make_directory(fs.dirname(key_index_file)) + let assert Ok(kv_file) = fs.open(key_index_file, [fs.Write]) + let memtable_ranges = map.to_list(kv.memtable_ranges) + let assert Ok(_) = + write_memtable_ranges(kv_file, kv.base_path, memtable_ranges) + let assert Ok(_) = fs.close(kv_file) + + let value_index_file = fs.join([kv.base_path, "value", "index"]) + let assert Ok(True) = + fs.recursive_make_directory(fs.dirname(value_index_file)) + let assert Ok(kv_file) = fs.open(value_index_file, [fs.Write]) + let assert Ok(_) = write_values(kv_file, map.keys(kv.values)) + let assert Ok(_) = fs.close(kv_file) + + Ok(Nil) +} + +fn write_memtable_ranges( + kv_file: Pid, + base_path: String, + memtable_ranges: List(#(Int, MemTableRange)), +) -> Result(Nil, Nil) { + case memtable_ranges { + [#(id, MemTableRange(lower, upper, Some(memtable))), ..rest] -> { + let assert Ok(True) = sstable.flush(memtable, sstable_path(base_path, id)) + let assert Ok(_) = fs.write(kv_file, <<lower:128, upper:128, id:128>>) + write_memtable_ranges(kv_file, base_path, rest) + } + [#(id, MemTableRange(lower, upper, None)), ..rest] -> { + let assert Ok(_) = fs.write(kv_file, <<lower:128, upper:128, id:128>>) + write_memtable_ranges(kv_file, base_path, rest) + } + [] -> Ok(Nil) + } +} + +fn write_values(kv: Pid, values: List(Int)) -> Result(Nil, Nil) { + case values { + [id, ..rest] -> { + let assert Ok(_) = fs.write(kv, <<id:128>>) + write_values(kv, rest) + } + [] -> Ok(Nil) + } +} + +pub fn get(kv: KV, key: String) -> #(Result(BitString, Nil), KV) { + let key_hash = memtable.hash(key) + let #(range_id, kv) = find_range(kv, key_hash, kv.max_memtable_size) + let assert Ok(range) = map.get(kv.memtable_ranges, range_id) + let assert Some(memtable) = range.memtable + case memtable.get(memtable, key) { + Ok(value) -> { + let assert Ok(vfile) = map.get(kv.values, value.file_id) + case value.read(vfile, value.offset) { + Ok(Value(deleted: False, file_id: _, offset: _, data: Some(data))) -> #( + Ok(data), + kv, + ) + _ -> #(Error(Nil), kv) + } + } + Error(_err) -> #(Error(Nil), kv) + } +} + +pub fn set(kv: KV, key: String, value: BitString) -> KV { + let key_hash = memtable.hash(key) + let #(range_id, kv) = find_range(kv, key_hash, kv.max_memtable_size) + let assert Ok(range) = map.get(kv.memtable_ranges, range_id) + let assert Some(memtable) = range.memtable + let kv = case kv.active_value_file { + Some(_file_id) -> kv + None -> { + let assert Ok(vfile) = + value.create(fs.join([kv.base_path, "value"]), kv.max_value_size) + KV( + ..kv, + active_value_file: Some(vfile.id), + values: map.insert(kv.values, vfile.id, vfile), + ) + } + } + case memtable.get(memtable, key) { + Ok(old_value) -> { + // key is in the index, we have to replace it + case store_value(kv, key, range_id, range, memtable, value) { + Ok(kv) -> kv + Error(CapacityExceeded) -> { + let kv = split(kv, key_hash, range_id, range, memtable) + set(kv, key, value) + } + } + let assert Ok(kv) = delete_value(kv, old_value) + kv + } + Error(Nil) -> { + // key isn't in the index yet, insert it as a new key + case store_value(kv, key, range_id, range, memtable, value) { + Ok(kv) -> kv + Error(CapacityExceeded) -> { + let kv = split(kv, key_hash, range_id, range, memtable) + set(kv, key, value) + } + } + } + } +} + +fn split( + kv: KV, + key_hash: Int, + range_id: Int, + range: MemTableRange, + memtable: MemTable, +) -> KV { + let #(memtable_low, memtable_high, pivot) = memtable.split(memtable, key_hash) + let assert MemTableRange(lower, upper, _) = range + let #(memtable_range_low, memtable_range_high) = case + memtable_low.size >= memtable_high.size + { + False -> #( + MemTableRange(lower, pivot - 1, Some(memtable_low)), + MemTableRange(pivot, upper, None), + ) + True -> #( + MemTableRange(lower, pivot - 1, None), + MemTableRange(pivot, upper, Some(memtable_high)), + ) + } + let memtable_high_id = new_id() + let memtable_ranges = + kv.memtable_ranges + |> map.insert(range_id, memtable_range_low) + |> map.insert(memtable_high_id, memtable_range_high) + + let assert Ok(True) = + sstable.flush(memtable_high, sstable_path(kv.base_path, memtable_high_id)) + + let assert Ok(True) = + sstable.flush(memtable_low, sstable_path(kv.base_path, range_id)) + + KV(..kv, memtable_ranges: memtable_ranges) +} + +fn store_value( + kv: KV, + key: String, + range_id: Int, + range: MemTableRange, + memtable: MemTable, + value_data: BitString, +) -> Result(KV, memtable.Reason) { + let assert Some(file_id) = kv.active_value_file + let assert Ok(vfile) = map.get(kv.values, file_id) + case value.write(vfile, value_data) { + Ok(#(vfile, value)) -> { + use memtable <- try(memtable.set(memtable, key, value)) + let range = MemTableRange(..range, memtable: Some(memtable)) + Ok( + KV( + ..kv, + active_value_file: Some(vfile.id), + values: map.insert(kv.values, vfile.id, vfile), + memtable_ranges: map.insert(kv.memtable_ranges, range_id, range), + ), + ) + } + Error(value.CapacityExceeded) -> { + let assert Ok(vfile) = + value.create(fs.join([kv.base_path, "value"]), kv.max_value_size) + KV( + ..kv, + active_value_file: Some(vfile.id), + values: map.insert(kv.values, vfile.id, vfile), + ) + |> store_value(key, range_id, range, memtable, value_data) + } + } +} + +fn delete_value(kv: KV, value: Value) -> Result(KV, Nil) { + let file_id = value.file_id + let assert Ok(vfile) = map.get(kv.values, file_id) + let assert Ok(vfile) = value.delete(vfile, value) + let values = map.insert(kv.values, file_id, vfile) + Ok(KV(..kv, values: values)) +} + +pub fn info(kv: KV) -> KVInfo { + KVInfo( + base_path: kv.base_path, + name: kv.name, + values: map.size(kv.values), + values_size_bytes: map.fold( + kv.values, + 0, + fn(acc, _key, value_file) { acc + value_file.size }, + ), + memtables_total: map.size(kv.memtable_ranges), + memtables_loaded: kv.memtables_loaded, + memtables_loaded_size_bytes: map.fold( + kv.memtable_ranges, + 0, + fn(acc, _key, memtable_range) { + case memtable_range.memtable { + Some(memtable) -> acc + memtable.size + None -> acc + } + }, + ), + max_memtables_loaded: kv.max_memtables_loaded, + max_memtable_size: kv.max_memtable_size, + max_value_size: kv.max_value_size, + ) +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam new file mode 100644 index 00000000000..1b49010d665 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam @@ -0,0 +1,287 @@ +//// MemTable is an in-memory data structure that holds the latest written +//// records. It is a sorted list of records sorted by the key hash. When the +//// MemTable reaches its capacity, it is flushed to disk as a Table (Sorted +//// String Table or SSTable). See the sstable module for more details. + +import gleam/bit_string +import gleam/list +import gleam/map.{Map} +import gleam/option.{None} +import ream/storage/kv/value.{Value} + +/// MemTable holds a sorted list of the latest written records. Generally, we +/// could implement a sorted list algorithm like skip list, but for simplicity +/// we use a map instead. +/// +/// MemTables have a max capacity and when that is reached, we flush the MemTable +/// to disk as a Table (Sorted String Table or SSTable). See the sstable module +/// for more details. +/// +/// The MemTable structure is as follows: +/// - `entries`: a map of key hash to MemTableEntry. The key hash is the hash of +/// the key string. +/// - `size`: the total size of the MemTable in bytes. +/// - `max_size`: the maximum size of the MemTable in bytes. +pub type MemTable { + MemTable(entries: Map(Int, MemTableEntry), size: Int, max_size: Int) +} + +/// MemTableEntry is a single entry in the MemTable. +pub type MemTableEntry { + MemTableEntry(key: String, value: Value) +} + +/// Reason is the reason why a MemTable operation failed. +pub type Reason { + /// The MemTable is full and cannot accept more entries. + CapacityExceeded +} + +/// The key hash size is 32-bit integer +pub const key_hash_size_bytes = 4 + +/// The key string size data is 16-bit integer +pub const key_size_bytes = 2 + +/// The file ID size is 128-bit integer corresponding to the UUID +/// of the file in binary format. +pub const file_id_size_bytes = 16 + +/// The file offset size is 32-bit integer. +pub const file_offset_size_bytes = 4 + +/// The payload size for the memtable entry, it is the sum of the +/// key hash size, file ID size, file offset size and key size. +pub const payload_size_bytes = 26 + +pub fn new(max_size: Int) -> MemTable { + MemTable(entries: map.new(), size: 0, max_size: max_size) +} + +/// calculate_entries_size calculates the total size of the entries in the +/// MemTable. It is mainly used when we load the MemTable from disk. +pub fn from_entries(entries: Map(Int, MemTableEntry), max_size: Int) -> MemTable { + let size = calculate_entries_size(entries) + MemTable(entries: entries, size: size, max_size: max_size) +} + +/// entry_to_bitstring converts a MemTableEntry to a bitstring. It is mainly used +/// when we need to convert the MemTableEntry to its binary representation. +pub fn entry_to_bitstring(entry: MemTableEntry) -> BitString { + let key_hash = hash(entry.key) + let key_string = bit_string.from_string(entry.key) + let key_size = bit_string.byte_size(key_string) + let file_id = entry.value.file_id + let file_offset = entry.value.offset + << + key_hash:128, + key_size:16, + file_id:128, + file_offset:32, + key_string:bit_string, + >> +} + +/// bitstring_to_entry converts a bitstring to a MemTableEntry. It is mainly used +/// when we need to convert the binary representation of a MemTableEntry to a +/// MemTableEntry. +pub fn bitstring_to_entry(bitstring: BitString) -> #(Int, MemTableEntry) { + let << + key_hash:128, + _key_size:16, + file_id:128, + file_offset:32, + key_string:bit_string, + >> = bitstring + let assert Ok(key) = bit_string.to_string(key_string) + let value = + Value(data: None, deleted: False, file_id: file_id, offset: file_offset) + #(key_hash, MemTableEntry(key: key, value: value)) +} + +/// contains checks if the MemTable contains the given key. +pub fn contains(mem_table: MemTable, key: String) -> Bool { + map.has_key(mem_table.entries, hash(key)) +} + +/// generates a hash for the given key. +pub external fn hash(key: String) -> Int = + "erlang" "phash2" + +/// set sets the given key to the given value in the MemTable. If the MemTable +/// reaches its capacity, it returns an error. Otherwise, it returns the updated +/// MemTable. +pub fn set( + mem_table: MemTable, + key: String, + value: Value, +) -> Result(MemTable, Reason) { + let key_hash = hash(key) + case map.get(mem_table.entries, key_hash) { + Error(Nil) -> { + let entry = MemTableEntry(key, value) + let entry_size = calculate_size(entry) + let current_size = mem_table.size + entry_size + case current_size > mem_table.max_size { + True -> Error(CapacityExceeded) + False -> + Ok( + MemTable( + ..mem_table, + entries: map.insert(mem_table.entries, key_hash, entry), + size: current_size, + ), + ) + } + } + Ok(old_entry) -> { + let old_entry_size = calculate_size(old_entry) + let entry = MemTableEntry(..old_entry, value: value) + let current_entry_size = calculate_size(entry) + let mem_table_size = mem_table.size + current_entry_size - old_entry_size + case mem_table_size > mem_table.max_size { + True -> Error(CapacityExceeded) + False -> + Ok( + MemTable( + ..mem_table, + entries: map.insert(mem_table.entries, key_hash, entry), + size: mem_table_size, + ), + ) + } + } + } +} + +/// deletes the given key from the MemTable. If the key does not exist, it +/// returns the original MemTable. Otherwise, it returns the updated MemTable. +pub fn delete(mem_table: MemTable, key: String) -> MemTable { + let key_hash = hash(key) + case map.get(mem_table.entries, key_hash) { + Error(Nil) -> mem_table + Ok(entry) -> { + MemTable( + ..mem_table, + entries: map.delete(mem_table.entries, key_hash), + size: mem_table.size - calculate_size(entry), + ) + } + } +} + +/// gets the value of the given key from the MemTable. If the key does not +/// exist, it returns an error. +pub fn get(mem_table: MemTable, key: String) -> Result(Value, Nil) { + case map.get(mem_table.entries, hash(key)) { + Ok(MemTableEntry(key: stored_key, value: value)) if key == stored_key -> + Ok(value) + Ok(MemTableEntry(key: _stored_key, value: _)) -> { + // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed + // let errmsg = + // "collision hash function between " <> key <> " and " <> stored_key + panic + } + Error(Nil) -> Error(Nil) + } +} + +/// search for a pivot in the MemTable. The pivot is the middle key in the +/// MemTable. +pub fn search_pivot(mem_table: MemTable) -> Int { + let entries = mem_table.entries + let keys = map.keys(entries) + let entries_count = map.size(entries) + let #(_, [pivot, ..]) = list.split(keys, at: entries_count / 2) + pivot +} + +/// splits the MemTable into two MemTables. The first MemTable contains +/// MemTableEntries with keys less than the pivot. The second MemTable contains +/// MemTableEntries with keys greater than or equal to the pivot. The pivot is +/// the middle key in the MemTable. +pub fn split(mem_table: MemTable, pivot: Int) -> #(MemTable, MemTable, Int) { + let #(low_entries, high_entries) = + mem_table.entries + |> map.to_list() + |> list.partition(fn(entry) { entry.0 < pivot }) + + let low_entries = map.from_list(low_entries) + + let low = + MemTable( + ..mem_table, + entries: low_entries, + size: calculate_entries_size(low_entries), + ) + + let high_entries = map.from_list(high_entries) + + let high = + MemTable( + ..mem_table, + entries: high_entries, + size: calculate_entries_size(high_entries), + ) + + case low.size >= high.size, map.get(high.entries, pivot) { + True, _ -> #(low, high, pivot) + False, Error(Nil) -> #(low, high, pivot + 1) + False, Ok(entry) -> { + let high = + MemTable( + ..high, + entries: map.delete(high.entries, pivot), + size: high.size - calculate_size(entry), + ) + let low = + MemTable( + ..low, + entries: map.insert(low.entries, pivot, entry), + size: low.size + calculate_size(entry), + ) + #(low, high, pivot + 1) + } + } +} + +fn calculate_entries_size(entries: Map(Int, MemTableEntry)) -> Int { + map.fold(entries, 0, fn(acc, _key, entry) { acc + calculate_size(entry) }) +} + +fn calculate_size(entry: MemTableEntry) -> Int { + bit_string.byte_size(entry_to_bitstring(entry)) +} + +/// get_bounds returns the lower and higher bounds of the MemTable. If the +/// MemTable is empty, it returns `#(0, 0)`. +pub fn get_bounds(mem_table: MemTable) -> #(Int, Int) { + case map.to_list(mem_table.entries) { + [] -> #(0, 0) + [#(k, _), ..entries] -> { + list.fold( + entries, + #(k, k), + fn(acc: #(Int, Int), entry) { + #(get_lower(acc.0, entry.0), get_higher(acc.1, entry.0)) + }, + ) + } + } +} + +fn get_lower(lower_bound: Int, key: Int) -> Int { + case lower_bound { + 0 -> key + lower_bound if key < lower_bound -> key + lower_bound -> lower_bound + } +} + +fn get_higher(higher_bound: Int, key: Int) -> Int { + case higher_bound { + 0 -> key + higher_bound if key > higher_bound -> key + higher_bound -> higher_bound + } +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam new file mode 100644 index 00000000000..ec218baab55 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam @@ -0,0 +1,54 @@ +import gleam/erlang/file +import gleam/erlang/process.{Pid} +import gleam/map.{Map} +import ream/storage/file as fs +import ream/storage/file/read +import ream/storage/kv/memtable.{MemTable, MemTableEntry} + +const header_size = 38 + +pub fn flush(mem_table: MemTable, path: String) -> Result(Bool, file.Reason) { + let assert Ok(True) = fs.recursive_make_directory(fs.dirname(path)) + let assert Ok(file) = fs.open(path, [fs.Write]) + // TODO maybe suggest the inclusion of `map.each/2` for gleam/stdlib + map.filter( + mem_table.entries, + fn(_key, entry) { + let content = memtable.entry_to_bitstring(entry) + let assert Ok(_) = fs.write(file, content) + False + }, + ) + let assert Ok(_) = fs.close(file) + Ok(True) +} + +pub fn load(path: String, max_size: Int) -> Result(MemTable, file.Reason) { + let assert Ok(file) = fs.open(path, [fs.Read]) + let assert Ok(entries) = read_entries(file, map.new()) + let assert Ok(_) = fs.close(file) + Ok(memtable.from_entries(entries, max_size)) +} + +fn read_entries( + file: Pid, + entries: Map(Int, MemTableEntry), +) -> Result(Map(Int, MemTableEntry), file.Reason) { + case fs.read(file, header_size) { + read.Ok(<<key_hash:128, key_size:16, file_id:128, offset:32>>) -> { + let assert read.Ok(key_string) = fs.read(file, key_size) + let #(_key, entry) = + memtable.bitstring_to_entry(<< + key_hash:128, + key_size:16, + file_id:128, + offset:32, + key_string:bit_string, + >>) + let entries = map.insert(entries, key_hash, entry) + read_entries(file, entries) + } + read.Eof -> Ok(entries) + read.Error(reason) -> Error(reason) + } +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam new file mode 100644 index 00000000000..8711085f8f6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam @@ -0,0 +1,206 @@ +//// Store the information of the values for kv. +//// +//// The events stored in the file are in the following format: +//// - 4 bytes: the size of the event +//// - 1 byte: 0 if the event is not deleted, 1 if it is +//// - n bytes: the event +//// +//// The KV system is split into two parts: the key store and the value store. +//// The file is related to the value store. As we said it's a file with the +//// content marking the size of the value, if it's deleted and the value itself. +//// +//// The file is append only. When a value is written, it's appended to the end +//// of the file. When a value is deleted, it's not deleted from the file, it's +//// marked as deleted. When a value is updated, it's deleted and a new value is +//// appended to the end of the file. + +import gleam/bit_string +import gleam/erlang/file +import gleam/erlang/process.{Pid} +import gleam/option.{None, Option, Some} +import gleam/result.{try} +import ream/storage/file as fs +import ream/storage/file/read +import ream/uuid + +pub const value_size_bits = 32 + +pub type Reason { + CapacityExceeded +} + +/// The information for a value. The fields are: +/// - `offset`: the offset of the value in the file. +/// - `deleted`: if the value is deleted. +/// - `data`: the value. It can be `None` if we didn't read the value yet. +/// - `file_id`: the id of the file where the value is stored. +pub type Value { + Value(offset: Int, deleted: Bool, data: Option(BitString), file_id: Int) +} + +/// The information for the kv file. The fields are: +/// - `id`: the id of the file. It's intended to be a UUID but it's stored as an Int. +/// - `handler`: the file handler to read and write values. +/// - `size`: the size of the file. +/// - `max_size`: the maximum size of the file. +/// - `file_path`: the path of the file. +pub type ValueFile { + ValueFile(id: Int, handler: Pid, size: Int, max_size: Int, file_path: String) +} + +/// The information for the kv file. The fields are: +/// - `file_id`: the id of the file. It's intended to be a UUID but it's stored as an Int. +/// - `size`: the size of the file. +/// - `entries`: the number of entries in the file. +/// - `deleted`: the number of deleted entries in the file. +pub type ValueFileInfo { + ValueFileInfo( + file_id: Int, + size: Int, + max_size: Int, + entries: Int, + deleted: Int, + ) +} + +/// Create a new kv file. It creates a new file with a random UUID as the +/// path for finding the file. +/// +/// For example, if the UUID is `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, the +/// file will be created in the following path: +/// `base_path/f81d4fae/7dec/11d0/a765/00a0c91e6bf6`. +pub fn create( + base_path: String, + max_size: Int, +) -> Result(ValueFile, file.Reason) { + let file_id = uuid.to_int(uuid.new()) + let file_name = get_file_name(base_path, file_id) + let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) + use file_pid <- try(fs.open(file_name, [fs.Read, fs.Write])) + Ok(ValueFile(file_id, file_pid, 0, max_size, file_name)) +} + +fn get_file_name(base_path: String, file_id: Int) -> String { + fs.join([base_path, ..uuid.parts(uuid.from_int(file_id))]) +} + +/// Open a kv file. It opens the file with the given file id. +/// If the file doesn't exist, it is creating it. The main difference +/// with `create` is that `open` doesn't generate a new UUID. +/// It returns the kv file with the file handler and the file size. +pub fn open( + path: String, + file_id: Int, + max_size: Int, +) -> Result(ValueFile, file.Reason) { + let file_name = get_file_name(path, file_id) + let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) + let assert Ok(file_pid) = fs.open(file_name, [fs.Read, fs.Write]) + let assert Ok(file_info) = file.file_info(file_name) + Ok(ValueFile(file_id, file_pid, file_info.size, max_size, file_name)) +} + +/// Close a kv file. It closes the file handler. +pub fn close(vfile: ValueFile) -> Result(Nil, file.Reason) { + let assert Ok(_) = fs.close(vfile.handler) + Ok(Nil) +} + +/// Write a value to the kv file. It writes the value in the following +/// format: +/// - 4 bytes: the size of the value +/// - 1 byte: 0 if the value is not deleted, 1 if it is +/// - n bytes: the value +/// It returns the updated kv file with the new size. +pub fn write_value(vfile: ValueFile, value: Value) -> Result(ValueFile, Reason) { + // FIXME: https://github.com/gleam-lang/gleam/issues/2166 + let value_size_bits = value_size_bits + // end FIXME + let value_size_bytes = value_size_bits / 8 + let assert Some(data) = value.data + let data_size = bit_string.byte_size(data) + value_size_bytes + 1 + let deleted = case value.deleted { + True -> 1 + False -> 0 + } + let packed_data = << + data_size:size(value_size_bits), + deleted:8, + data:bit_string, + >> + let assert Ok(offset) = fs.position(vfile.handler, fs.Bof(value.offset)) + case offset + data_size > vfile.max_size { + True -> Error(CapacityExceeded) + False -> { + let assert Ok(_) = fs.write(vfile.handler, packed_data) + case offset + data_size > vfile.size { + True -> Ok(ValueFile(..vfile, size: offset + data_size)) + False -> Ok(vfile) + } + } + } +} + +pub fn write( + vfile: ValueFile, + value: BitString, +) -> Result(#(ValueFile, Value), Reason) { + let value = Value(vfile.size, False, Some(value), vfile.id) + use vfile <- try(write_value(vfile, value)) + Ok(#(vfile, Value(..value, data: None))) +} + +/// Delete a value from the kv file. It marks the value as deleted. +/// It returns the updated kv file with the new size. +pub fn delete(vfile: ValueFile, value: Value) -> Result(ValueFile, Reason) { + use value <- try(read(vfile, value.offset)) + write_value(vfile, Value(..value, deleted: True)) +} + +/// Read a value from the kv file. It reads the value and returns it as +/// a BitString with the following format: +/// - 4 bytes: the size of the value +/// - 1 byte: 0 if the value is not deleted, 1 if it is +/// - n bytes: the value +pub fn read(vfile: ValueFile, offset: Int) -> Result(Value, Reason) { + // FIXME: https://github.com/gleam-lang/gleam/issues/2166 + let value_size_bits = value_size_bits + // end FIXME + let value_size_bytes = value_size_bits / 8 + let assert Ok(_) = fs.position(vfile.handler, fs.Bof(offset)) + let assert read.Ok(<<size:size(value_size_bits), deleted:8>>) = + fs.read(vfile.handler, value_size_bytes + 1) + let content_size = size - value_size_bytes - 1 + let assert read.Ok(data) = fs.read(vfile.handler, content_size) + let deleted = case deleted { + 0 -> False + 1 -> True + } + Ok(Value(offset, deleted, Some(data), vfile.id)) +} + +pub fn get_file_info(vfile: ValueFile) -> ValueFileInfo { + let assert Ok(_) = fs.position(vfile.handler, fs.Bof(0)) + let assert Ok(#(entries, deleted)) = + get_entries_and_deleted(vfile.handler, #(0, 0)) + ValueFileInfo(vfile.id, vfile.size, vfile.max_size, entries, deleted) +} + +fn get_entries_and_deleted( + handler: Pid, + acc: #(Int, Int), +) -> Result(#(Int, Int), file.Reason) { + // FIXME: https://github.com/gleam-lang/gleam/issues/2166 + let value_size_bits = value_size_bits + // end FIXME + let value_size_bytes = value_size_bits / 8 + case fs.read(handler, value_size_bytes + 1) { + read.Ok(<<size:size(value_size_bits), deleted:8>>) -> { + let payload_size = size - value_size_bytes - 1 + let assert Ok(_) = fs.position(handler, fs.Cur(payload_size)) + get_entries_and_deleted(handler, #(acc.0 + 1, acc.1 + deleted)) + } + read.Eof -> Ok(acc) + read.Error(reason) -> Error(reason) + } +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam new file mode 100644 index 00000000000..7d40439966f --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam @@ -0,0 +1,139 @@ +import gleam/bit_string +import gleam/erlang/file +import gleam/iterator +import gleam/list +import gleam/map.{Map} +import gleam/option.{None, Option, Some} +import gleam/result.{try} +import ream/storage/file as fs +import ream/storage/stream/event.{Event, EventFile} +import ream/storage/stream/index.{Index, IndexFile} + +pub type Stream { + Stream( + name: String, + index: IndexFile, + active_file: Option(EventFile), + files: Map(Int, EventFile), + base_path: String, + ) +} + +pub fn get_base_path(path: String, name: String) -> String { + fs.join([path, "stream", name]) +} + +pub fn open(name: String, path path: String) -> Result(Stream, file.Reason) { + let base_path = fs.join([path, "stream", name]) + let assert Ok(index_file) = index.open(base_path) + use files <- try(do_open_files(index_file, base_path, map.new())) + let active_file = less_populated_file(map.values(files)) + Ok(Stream(name, index_file, active_file, files, base_path)) +} + +fn less_populated_file(files: List(EventFile)) -> Option(EventFile) { + files + |> list.fold( + with: fn(acc, file) { + let file_size = file.size + case acc { + Some(EventFile(_id, _handler, size, _file_id)) if file_size >= size -> + acc + _ -> Some(file) + } + }, + from: None, + ) +} + +pub fn close(stream: Stream) -> Result(Nil, file.Reason) { + let assert Ok(_) = index.close(stream.index) + + stream.files + |> map.values() + |> list.each(fn(file) { fs.close(file.handler) }) + + Ok(Nil) +} + +fn do_open_files( + index_file: IndexFile, + path: String, + acc: Map(Int, EventFile), +) -> Result(Map(Int, EventFile), file.Reason) { + case index.count(index_file) { + 0 -> Ok(acc) + num_of_events -> { + let _ = index.set_pos(index_file, 0) + + let files = + num_of_events - 1 + |> iterator.range(0, _) + |> iterator.fold( + from: acc, + with: fn(acc, _idx) { + let assert Ok(Index(_offset, _size, file_id)) = + index.get_next(index_file) + case map.has_key(acc, file_id) { + True -> acc + False -> { + let assert Ok(file) = event.open(path, file_id) + map.insert(acc, file_id, file) + } + } + }, + ) + + Ok(files) + } + } +} + +pub fn add_event( + stream: Stream, + event_content: BitString, +) -> Result(Stream, file.Reason) { + let event_size = bit_string.byte_size(event_content) + let #(stream, index) = case index.count(stream.index) { + 0 -> { + let assert Ok(stream_file) = event.create(stream.base_path) + let #(index, index_file) = + index.add(stream.index, event_size, stream_file.id) + let stream = + Stream( + ..stream, + index: index_file, + active_file: Some(stream_file), + files: map.insert(stream.files, stream_file.id, stream_file), + ) + #(stream, index) + } + _ -> { + let assert Some(active_file) = stream.active_file + let #(index, index_file) = + index.add(stream.index, event_size, active_file.id) + let stream = Stream(..stream, index: index_file) + #(stream, index) + } + } + + let assert Ok(file) = map.get(stream.files, index.file_id) + let event = Event(index.offset, event_content) + let stream_file = event.write(file, event) + + let files = map.insert(stream.files, stream_file.id, stream_file) + Ok(Stream(..stream, files: files)) +} + +pub fn get_event(stream: Stream, index: Int) -> Result(BitString, file.Reason) { + case index.count(stream.index) > index { + True -> { + let assert Ok(Index(offset, _size, file_id)) = + index.get(stream.index, index) + let assert Ok(file) = map.get(stream.files, file_id) + let assert Ok(Event(_offset, data)) = event.read(file, offset) + Ok(data) + } + False -> Error(file.Einval) + } +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam new file mode 100644 index 00000000000..14ab0e946dc --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam @@ -0,0 +1,95 @@ +//// Store the information of the event that is being streamed. It is used to +//// write and read events from the file. +//// +//// The events stored in the file are in the following format: +//// - 4 bytes: the size of the event +//// - n bytes: the event + +import gleam/erlang/file +import gleam/erlang/process.{Pid} +import gleam/bit_string +import gleam/result.{try} +import ream/storage/file as fs +import ream/storage/file/read +import ream/storage/stream/index +import ream/uuid + +pub type Event { + Event(offset: Int, data: BitString) +} + +/// The information for the stream file. The fields are: +/// - `id`: the id of the file. It's intended to be a UUID but it's stored as an Int. +/// - `handler`: the file handler to read and write events. +/// - `size`: the size of the file. +/// - `file_path`: the path of the file. +pub type EventFile { + EventFile(id: Int, handler: Pid, size: Int, file_path: String) +} + +/// Create a new stream file. It creates a new file with a random UUID as the +/// path for finding the file. +/// +/// For example, if the UUID is `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, the +/// file will be created in the following path: +/// `base_path/f81d4fae/7dec/11d0/a765/00a0c91e6bf6`. +pub fn create(base_path: String) -> Result(EventFile, file.Reason) { + let <<file_id:128>> = uuid.new() + let file_name = get_file_name(base_path, file_id) + let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) + use file_pid <- try(fs.open(file_name, [fs.Read, fs.Append])) + Ok(EventFile(file_id, file_pid, 0, file_name)) +} + +fn get_file_name(base_path: String, file_id: Int) -> String { + fs.join([base_path, ..uuid.parts(<<file_id:128>>)]) +} + +/// Open a stream file. It opens the file with the given file id. +/// If the file doesn't exist, it is creating it. The main difference +/// with `create` is that `open` doesn't generate a new UUID. +/// It returns the stream file with the file handler and the file size. +pub fn open(path: String, file_id: Int) -> Result(EventFile, file.Reason) { + let file_name = get_file_name(path, file_id) + let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) + let assert Ok(file_pid) = fs.open(file_name, [fs.Read, fs.Append]) + let assert Ok(file_info) = file.file_info(file_name) + Ok(EventFile(file_id, file_pid, file_info.size, file_name)) +} + +/// Close a stream file. It closes the file handler. +pub fn close(stream_file: EventFile) -> Result(Nil, file.Reason) { + let assert Ok(_) = fs.close(stream_file.handler) + Ok(Nil) +} + +/// Write an event to the stream file. It writes the event in the following +/// format: +/// - 4 bytes: the size of the event +/// - n bytes: the event +/// It returns the updated stream file with the new size. +pub fn write(stream_file: EventFile, event: Event) -> EventFile { + let event_size_bits = index.event_size_bits + let event_size_bytes = event_size_bits / 8 + let data_size = bit_string.byte_size(event.data) + event_size_bytes + let data = <<data_size:size(event_size_bits), event.data:bit_string>> + let assert Ok(_) = fs.position(stream_file.handler, fs.Bof(event.offset)) + let assert Ok(_) = fs.write(stream_file.handler, data) + let data_size = bit_string.byte_size(data) + EventFile(..stream_file, size: stream_file.size + data_size) +} + +/// Read an event from the stream file. It reads the event and returns it as +/// a BitString with the following format: +/// - 4 bytes: the size of the event +/// - n bytes: the event +pub fn read(stream_file: EventFile, offset: Int) -> Result(Event, file.Reason) { + let event_size_bits = index.event_size_bits + let event_size_bytes = event_size_bits / 8 + let assert Ok(_) = fs.position(stream_file.handler, fs.Bof(offset)) + let assert read.Ok(<<size:size(event_size_bits)>>) = + fs.read(stream_file.handler, event_size_bytes) + let content_size = size - event_size_bytes + let assert read.Ok(data) = fs.read(stream_file.handler, content_size) + Ok(Event(offset, data)) +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam new file mode 100644 index 00000000000..83f5104c935 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam @@ -0,0 +1,153 @@ +import gleam/erlang/file +import gleam/erlang/process.{Pid} +import gleam/int +import gleam/result.{try} +import ream/storage/file as fs +import ream/storage/file/read + +/// the size of the offset in bytes, it's 6 bytes or 48 bits +/// letting us store offsets of 2^48 bytes (256TB) of data +pub const offset_size_bits = 48 + +/// event size (in bits) is storing letting us store events +/// of 2^24 bits (16MB) of data +pub const event_size_bits = 24 + +/// the size of the file id in bytes, it's 16 bytes or 128 bits +/// representing a 128 bit integer (UUID) +pub const file_id_size_bits = 128 + +/// the size of the index entry in bytes, it's 25 bytes because +/// we're storing the offset (6 bytes), the event size (3 bytes) +/// and the file id (16 bytes). +pub const index_size_bytes = 25 + +pub type Index { + Index(offset: Int, size: Int, file_id: Int) +} + +pub type IndexFile { + IndexFile(handler: Pid, size: Int, file_path: String) +} + +pub fn open(path: String) -> Result(IndexFile, file.Reason) { + let assert Ok(True) = fs.recursive_make_directory(path) + let index = fs.join([path, "index"]) + use index_pid <- try(fs.open(index, [fs.Read, fs.Append])) + use index_info <- try(file.file_info(index)) + Ok(IndexFile(index_pid, index_info.size, index)) +} + +pub fn close(index_file: IndexFile) -> Result(Nil, file.Reason) { + let assert Ok(_) = fs.close(index_file.handler) + Ok(Nil) +} + +pub fn add( + index_file: IndexFile, + event_size: Int, + file_id: Int, +) -> #(Index, IndexFile) { + let event_size_bytes = event_size_bits / 8 + let #(index_content, index) = case index_file.size { + 0 -> { + let index = Index(0, event_size + event_size_bytes, file_id) + #(index_binary(index), index) + } + _ -> { + let assert Ok(_) = + fs.position(index_file.handler, fs.Eof(-index_size_bytes)) + // FIXME: https://github.com/gleam-lang/gleam/issues/2166 + let offset_size_bits = offset_size_bits + let event_size_bits = event_size_bits + let file_id_size_bits = file_id_size_bits + // end FIXME + let assert Ok(<< + offset:size(offset_size_bits), + prev_size:size(event_size_bits), + _file_id:size(file_id_size_bits), + >>) = last_entry_for_file(index_file.handler, file_id) + let offset = offset + prev_size + let index = Index(offset, event_size + event_size_bytes, file_id) + #(index_binary(index), index) + } + } + let assert Ok(_) = fs.write(index_file.handler, index_content) + let index_file = + IndexFile(..index_file, size: index_file.size + index_size_bytes) + #(index, index_file) +} + +fn index_binary(index: Index) -> BitString { + // FIXME: https://github.com/gleam-lang/gleam/issues/2166 + let offset_size_bits = offset_size_bits + let event_size_bits = event_size_bits + let file_id_size_bits = file_id_size_bits + // end FIXME + << + index.offset:size(offset_size_bits), + index.size:size(event_size_bits), + index.file_id:size(file_id_size_bits), + >> +} + +fn last_entry_for_file( + index_file: Pid, + file_id: Int, +) -> Result(BitString, file.Reason) { + // FIXME: https://github.com/gleam-lang/gleam/issues/2166 + let offset_size_bits = offset_size_bits + let event_size_bits = event_size_bits + let file_id_size_bits = file_id_size_bits + // end FIXME + let assert read.Ok(<< + offset:size(offset_size_bits), + size:size(event_size_bits), + new_file_id:size(file_id_size_bits), + >>) = fs.read(index_file, index_size_bytes) + case new_file_id == file_id { + True -> Ok(index_binary(Index(offset, size, file_id))) + False -> { + case fs.position(index_file, fs.Cur(-2 * index_size_bytes)) { + Ok(_) -> last_entry_for_file(index_file, file_id) + Error(file.Einval) -> Ok(index_binary(Index(0, 0, file_id))) + } + } + } +} + +pub fn count(index_file: IndexFile) -> Int { + let assert Ok(result) = int.divide(index_file.size, index_size_bytes) + result +} + +pub fn set_pos(index_file: IndexFile, index: Int) -> Result(Int, file.Reason) { + fs.position(index_file.handler, fs.Bof(index * index_size_bytes)) +} + +pub fn get_next(index_file: IndexFile) -> Result(Index, file.Reason) { + // FIXME: https://github.com/gleam-lang/gleam/issues/2166 + let offset_size_bits = offset_size_bits + let event_size_bits = event_size_bits + let file_id_size_bits = file_id_size_bits + // end FIXME + case fs.read(index_file.handler, index_size_bytes) { + read.Ok(<< + offset:size(offset_size_bits), + size:size(event_size_bits), + file_id:size(file_id_size_bits), + >>) -> Ok(Index(offset, size, file_id)) + read.Eof -> Error(file.Espipe) + _ -> Error(file.Einval) + } +} + +pub fn get(index_file: IndexFile, index: Int) -> Result(Index, file.Reason) { + case count(index_file) > index { + True -> { + let assert Ok(_) = set_pos(index_file, index) + get_next(index_file) + } + False -> Error(file.Einval) + } +} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam new file mode 100644 index 00000000000..03a489db8b2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam @@ -0,0 +1,48 @@ +//// This module implements the UUID v4 generation algorithm. + +import gleam/int +import gleam/string + +pub fn new() -> BitString { + let <<u0:size(48), _:size(4), u1:size(12), _:size(2), u2:size(62)>> = + crypto_strong_rand_bytes(16) + + <<u0:size(48), 4:size(4), u1:size(12), 2:size(2), u2:size(62)>> +} + +pub fn to_string(uuid: BitString) -> String { + parts(uuid) + |> string.join(with: "-") +} + +pub fn to_int(uuid: BitString) -> Int { + let <<uuid_int:128>> = uuid + uuid_int +} + +pub fn from_int(uuid: Int) -> BitString { + <<uuid:128>> +} + +pub fn from_string(uuid: String) -> BitString { + let assert Ok(uuid_int) = + uuid + |> string.replace(each: "-", with: "") + |> int.base_parse(16) + + from_int(uuid_int) +} + +pub fn parts(uuid: BitString) -> List(String) { + let <<p1:32, p2:16, p3:16, p4:16, p5:48>> = uuid + [to_hex(p1, 8), to_hex(p2, 4), to_hex(p3, 4), to_hex(p4, 4), to_hex(p5, 12)] +} + +fn to_hex(n: Int, size: Int) -> String { + int.to_base16(n) + |> string.lowercase() + |> string.pad_left(to: size, with: "0") +} + +external fn crypto_strong_rand_bytes(Int) -> BitString = + "crypto" "strong_rand_bytes" diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl new file mode 100644 index 00000000000..9120a478ea0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl @@ -0,0 +1,123 @@ +-module(ream@storage@file). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([do_open/2, open/2, read/2, close/1, write/2, dirname/1, basename/1, join/1, position/2, recursive_make_directory/1]). +-export_type([endian/0, encoding_type/0, mode/0, location/0]). + +-type endian() :: big | little. + +-type encoding_type() :: unicode | + utf8 | + {utf16, endian()} | + {utf32, endian()} | + latin1. + +-type mode() :: read | + write | + append | + exclusive | + raw | + binary | + {delayed_write, integer(), integer()} | + {read_ahead, integer()} | + compressed | + compressed_one | + {encoding, encoding_type()} | + ram | + sync | + directory. + +-type location() :: {bof, integer()} | {cur, integer()} | {eof, integer()}. + +-spec do_open(binary(), list(mode())) -> {ok, gleam@erlang@process:pid_()} | + {error, gleam@erlang@file:reason()}. +do_open(Field@0, Field@1) -> + file:open(Field@0, Field@1). + +-spec open(binary(), list(mode())) -> {ok, gleam@erlang@process:pid_()} | + {error, gleam@erlang@file:reason()}. +open(Filename, Mode) -> + file:open(Filename, [binary | Mode]). + +-spec read(gleam@erlang@process:pid_(), integer()) -> ream@storage@file@read:result(). +read(Field@0, Field@1) -> + file:read(Field@0, Field@1). + +-spec close(gleam@erlang@process:pid_()) -> {ok, boolean()} | + {error, gleam@erlang@file:reason()}. +close(Io_device) -> + case file:close(Io_device) of + ok -> + {ok, true}; + + {error, Reason} -> + {error, Reason} + end. + +-spec write(gleam@erlang@process:pid_(), bitstring()) -> {ok, boolean()} | + {error, gleam@erlang@file:reason()}. +write(Io_device, Data) -> + case file:write(Io_device, Data) of + ok -> + {ok, true}; + + {error, Reason} -> + {error, Reason} + end. + +-spec dirname(binary()) -> binary(). +dirname(Field@0) -> + filename:dirname(Field@0). + +-spec basename(binary()) -> binary(). +basename(Field@0) -> + filename:basename(Field@0). + +-spec join(list(binary())) -> binary(). +join(Field@0) -> + filename:join(Field@0). + +-spec position(gleam@erlang@process:pid_(), location()) -> {ok, integer()} | + {error, gleam@erlang@file:reason()}. +position(Field@0, Field@1) -> + file:position(Field@0, Field@1). + +-spec recursive_make_directory(binary()) -> {ok, boolean()} | + {error, gleam@erlang@file:reason()}. +recursive_make_directory(Path) -> + case gleam@erlang@file:is_directory(Path) of + {error, enoent} -> + Prev_dir = filename:dirname(Path), + _assert_subject = recursive_make_directory(Prev_dir), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/file"/utf8>>, + function => <<"recursive_make_directory"/utf8>>, + line => 95}) + end, + _assert_subject@1 = gleam_erlang_ffi:make_directory(Path), + {ok, _} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/file"/utf8>>, + function => <<"recursive_make_directory"/utf8>>, + line => 96}) + end, + {ok, true}; + + {error, eexist} -> + {ok, true}; + + {ok, true} -> + {ok, true}; + + _ -> + {error, einval} + end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl new file mode 100644 index 00000000000..3cd71df7c31 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl @@ -0,0 +1,8 @@ +-module(ream@storage@file@close). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([result/0]). + +-type result() :: ok | {error, gleam@erlang@file:reason()}. + + diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl new file mode 100644 index 00000000000..ab021bd22bd --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl @@ -0,0 +1,8 @@ +-module(ream@storage@file@read). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([result/0]). + +-type result() :: {ok, bitstring()} | eof | {error, gleam@erlang@file:reason()}. + + diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl new file mode 100644 index 00000000000..7bdc59d9767 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl @@ -0,0 +1,8 @@ +-module(ream@storage@file@write). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([result/0]). + +-type result() :: ok | {error, gleam@erlang@file:reason()}. + + diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl new file mode 100644 index 00000000000..00b8caa6701 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl @@ -0,0 +1,901 @@ +-module(ream@storage@kv). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([get/2, info/1, open/5, flush/1, close/1, set/3]). +-export_type([mem_table_range/0, kv/0, kv_info/0]). + +-type mem_table_range() :: {mem_table_range, + integer(), + integer(), + gleam@option:option(ream@storage@kv@memtable:mem_table())}. + +-type kv() :: {kv, + binary(), + binary(), + gleam@map:map_(integer(), mem_table_range()), + gleam@option:option(integer()), + gleam@map:map_(integer(), ream@storage@kv@value:value_file()), + integer(), + integer(), + integer(), + integer()}. + +-type kv_info() :: {kv_info, + binary(), + binary(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer(), + integer()}. + +-spec new_id() -> integer(). +new_id() -> + ream@uuid:to_int(ream@uuid:new()). + +-spec sstable_path(binary(), integer()) -> binary(). +sstable_path(Path, Id) -> + Parts = ream@uuid:parts(ream@uuid:from_int(Id)), + filename:join([Path, <<"key"/utf8>> | Parts]). + +-spec find_range(kv(), integer(), integer()) -> {integer(), kv()}. +find_range(Kv, Key_hash, Max_size) -> + Max_memtables_loaded = erlang:element(8, Kv), + _assert_subject@2 = begin + _pipe = erlang:element(4, Kv), + _pipe@1 = gleam@map:to_list(_pipe), + gleam@list:map_fold( + _pipe@1, + {erlang:element(7, Kv), none}, + fun(Acc, Entry) -> + {Id, Range} = Entry, + {Loaded, Range_id} = Acc, + case {(Key_hash >= erlang:element(2, Range)) andalso (Key_hash + =< erlang:element(3, Range)), + erlang:element(4, Range)} of + {true, {some, _}} -> + {{Loaded, {some, Id}}, {Id, Range}}; + + {true, none} -> + _assert_subject = ream@storage@kv@sstable:load( + sstable_path(erlang:element(2, Kv), Id), + Max_size + ), + {ok, Memtable} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"find_range"/utf8>>, + line => 174}) + end, + {{Loaded + 1, {some, Id}}, + {Id, erlang:setelement(4, Range, {some, Memtable})}}; + + {false, {some, Memtable@1}} when Loaded >= Max_memtables_loaded -> + _assert_subject@1 = ream@storage@kv@sstable:flush( + Memtable@1, + sstable_path(erlang:element(2, Kv), Id) + ), + {ok, _} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"find_range"/utf8>>, + line => 182}) + end, + {{Loaded - 1, Range_id}, + {Id, erlang:setelement(4, Range, none)}}; + + {false, _} -> + {Acc, {Id, Range}} + end + end + ) + end, + {{Loaded@1, {some, Range_id@1}}, Range_list} = case _assert_subject@2 of + {{_, {some, _}}, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"find_range"/utf8>>, + line => 160}) + end, + {Range_id@1, + erlang:setelement( + 7, + erlang:setelement(4, Kv, gleam@map:from_list(Range_list)), + Loaded@1 + )}. + +-spec get(kv(), binary()) -> {{ok, bitstring()} | {error, nil}, kv()}. +get(Kv, Key) -> + Key_hash = erlang:phash2(Key), + {Range_id, Kv@1} = find_range(Kv, Key_hash, erlang:element(9, Kv)), + _assert_subject = gleam@map:get(erlang:element(4, Kv@1), Range_id), + {ok, Range} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"get"/utf8>>, + line => 264}) + end, + _assert_subject@1 = erlang:element(4, Range), + {some, Memtable} = case _assert_subject@1 of + {some, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"get"/utf8>>, + line => 265}) + end, + case ream@storage@kv@memtable:get(Memtable, Key) of + {ok, Value} -> + _assert_subject@2 = gleam@map:get( + erlang:element(6, Kv@1), + erlang:element(5, Value) + ), + {ok, Vfile} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"get"/utf8>>, + line => 268}) + end, + case ream@storage@kv@value:read(Vfile, erlang:element(2, Value)) of + {ok, {value, _, false, {some, Data}, _}} -> + {{ok, Data}, Kv@1}; + + _ -> + {{error, nil}, Kv@1} + end; + + {error, _} -> + {{error, nil}, Kv@1} + end. + +-spec split( + kv(), + integer(), + integer(), + mem_table_range(), + ream@storage@kv@memtable:mem_table() +) -> kv(). +split(Kv, Key_hash, Range_id, Range, Memtable) -> + {Memtable_low, Memtable_high, Pivot} = ream@storage@kv@memtable:split( + Memtable, + Key_hash + ), + {mem_table_range, Lower, Upper, _} = case Range of + {mem_table_range, _, _, _} -> Range; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"split"/utf8>>, + line => 332}) + end, + {Memtable_range_low, Memtable_range_high} = case erlang:element( + 3, + Memtable_low + ) + >= erlang:element(3, Memtable_high) of + false -> + {{mem_table_range, Lower, Pivot - 1, {some, Memtable_low}}, + {mem_table_range, Pivot, Upper, none}}; + + true -> + {{mem_table_range, Lower, Pivot - 1, none}, + {mem_table_range, Pivot, Upper, {some, Memtable_high}}} + end, + Memtable_high_id = new_id(), + Memtable_ranges = begin + _pipe = erlang:element(4, Kv), + _pipe@1 = gleam@map:insert(_pipe, Range_id, Memtable_range_low), + gleam@map:insert(_pipe@1, Memtable_high_id, Memtable_range_high) + end, + _assert_subject = ream@storage@kv@sstable:flush( + Memtable_high, + sstable_path(erlang:element(2, Kv), Memtable_high_id) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"split"/utf8>>, + line => 351}) + end, + _assert_subject@1 = ream@storage@kv@sstable:flush( + Memtable_low, + sstable_path(erlang:element(2, Kv), Range_id) + ), + {ok, true} = case _assert_subject@1 of + {ok, true} -> _assert_subject@1; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"split"/utf8>>, + line => 354}) + end, + erlang:setelement(4, Kv, Memtable_ranges). + +-spec delete_value(kv(), ream@storage@kv@value:value()) -> {ok, kv()} | + {error, nil}. +delete_value(Kv, Value) -> + File_id = erlang:element(5, Value), + _assert_subject = gleam@map:get(erlang:element(6, Kv), File_id), + {ok, Vfile} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"delete_value"/utf8>>, + line => 398}) + end, + _assert_subject@1 = ream@storage@kv@value:delete(Vfile, Value), + {ok, Vfile@1} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"delete_value"/utf8>>, + line => 399}) + end, + Values = gleam@map:insert(erlang:element(6, Kv), File_id, Vfile@1), + {ok, erlang:setelement(6, Kv, Values)}. + +-spec info(kv()) -> kv_info(). +info(Kv) -> + {kv_info, + erlang:element(2, Kv), + erlang:element(3, Kv), + gleam@map:size(erlang:element(6, Kv)), + gleam@map:fold( + erlang:element(6, Kv), + 0, + fun(Acc, _, Value_file) -> Acc + erlang:element(4, Value_file) end + ), + gleam@map:size(erlang:element(4, Kv)), + erlang:element(7, Kv), + gleam@map:fold( + erlang:element(4, Kv), + 0, + fun(Acc@1, _, Memtable_range) -> + case erlang:element(4, Memtable_range) of + {some, Memtable} -> + Acc@1 + erlang:element(3, Memtable); + + none -> + Acc@1 + end + end + ), + erlang:element(8, Kv), + erlang:element(9, Kv), + erlang:element(10, Kv)}. + +-spec read_memtable_ranges( + gleam@erlang@process:pid_(), + binary(), + integer(), + gleam@map:map_(integer(), mem_table_range()) +) -> gleam@map:map_(integer(), mem_table_range()). +read_memtable_ranges(Kv, Path, Max_size, Acc) -> + case file:read(Kv, 48) of + {ok, <<Lower:128, Upper:128, Id:128>>} -> + Range = {mem_table_range, Lower, Upper, none}, + read_memtable_ranges( + Kv, + Path, + Max_size, + gleam@map:insert(Acc, Id, Range) + ); + + eof -> + Acc; + + {error, _} -> + _assert_subject = ream@storage@file:close(Kv), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"read_memtable_ranges"/utf8>>, + line => 119}) + end, + erlang:error(#{gleam_error => panic, + message => <<"panic expression evaluated"/utf8>>, + module => <<"ream/storage/kv"/utf8>>, + function => <<"read_memtable_ranges"/utf8>>, + line => 121}) + end. + +-spec read_values( + gleam@erlang@process:pid_(), + binary(), + gleam@option:option(integer()), + integer(), + gleam@map:map_(integer(), ream@storage@kv@value:value_file()) +) -> {gleam@option:option(integer()), + gleam@map:map_(integer(), ream@storage@kv@value:value_file())}. +read_values(Kv, Path, Last_file_id, Max_value_size, Acc) -> + case file:read(Kv, 16) of + {ok, <<File_id:128>>} -> + _assert_subject = ream@storage@kv@value:open( + Path, + File_id, + Max_value_size + ), + {ok, Value_file} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"read_values"/utf8>>, + line => 135}) + end, + read_values( + Kv, + Path, + {some, File_id}, + Max_value_size, + gleam@map:insert(Acc, File_id, Value_file) + ); + + eof -> + {Last_file_id, Acc}; + + {error, _} -> + _assert_subject@1 = ream@storage@file:close(Kv), + {ok, _} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"read_values"/utf8>>, + line => 146}) + end, + erlang:error(#{gleam_error => panic, + message => <<"panic expression evaluated"/utf8>>, + module => <<"ream/storage/kv"/utf8>>, + function => <<"read_values"/utf8>>, + line => 148}) + end. + +-spec open(binary(), binary(), integer(), integer(), integer()) -> kv(). +open(Path, Name, Max_memtables_loaded, Max_memtable_size, Max_value_size) -> + Path@1 = filename:join([Path, <<"kv"/utf8>>, Name]), + Key_index_file = filename:join([Path@1, <<"key"/utf8>>, <<"index"/utf8>>]), + _assert_subject = ream@storage@file:recursive_make_directory( + filename:dirname(Key_index_file) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"open"/utf8>>, + line => 60}) + end, + _assert_subject@1 = ream@storage@file:open(Key_index_file, [read, write]), + {ok, Kv} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"open"/utf8>>, + line => 61}) + end, + Ranges = read_memtable_ranges( + Kv, + filename:join([Path@1, <<"key"/utf8>>]), + Max_memtable_size, + gleam@map:new() + ), + {Memtables_loaded, Ranges@2} = case gleam@map:size(Ranges) =:= 0 of + true -> + Memtable = ream@storage@kv@memtable:new(Max_memtable_size), + Ranges@1 = begin + _pipe = [{new_id(), + {mem_table_range, + 0, + 340282366920938463463374607431768211455, + {some, Memtable}}}], + gleam@map:from_list(_pipe) + end, + {1, Ranges@1}; + + false -> + {0, Ranges} + end, + _assert_subject@2 = ream@storage@file:close(Kv), + {ok, _} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"open"/utf8>>, + line => 79}) + end, + Value_index_file = filename:join( + [Path@1, <<"value"/utf8>>, <<"index"/utf8>>] + ), + _assert_subject@3 = ream@storage@file:recursive_make_directory( + filename:dirname(Value_index_file) + ), + {ok, true} = case _assert_subject@3 of + {ok, true} -> _assert_subject@3; + _assert_fail@3 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"ream/storage/kv"/utf8>>, + function => <<"open"/utf8>>, + line => 82}) + end, + _assert_subject@4 = ream@storage@file:open(Value_index_file, [read, write]), + {ok, Kv@1} = case _assert_subject@4 of + {ok, _} -> _assert_subject@4; + _assert_fail@4 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@4, + module => <<"ream/storage/kv"/utf8>>, + function => <<"open"/utf8>>, + line => 84}) + end, + {Active_value_file, Values} = read_values( + Kv@1, + filename:join([Path@1, <<"value"/utf8>>]), + none, + Max_value_size, + gleam@map:new() + ), + _assert_subject@5 = ream@storage@file:close(Kv@1), + {ok, _} = case _assert_subject@5 of + {ok, _} -> _assert_subject@5; + _assert_fail@5 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@5, + module => <<"ream/storage/kv"/utf8>>, + function => <<"open"/utf8>>, + line => 87}) + end, + {kv, + Path@1, + Name, + Ranges@2, + Active_value_file, + Values, + Memtables_loaded, + Max_memtables_loaded, + Max_memtable_size, + Max_value_size}. + +-spec write_memtable_ranges( + gleam@erlang@process:pid_(), + binary(), + list({integer(), mem_table_range()}) +) -> {ok, nil} | {error, nil}. +write_memtable_ranges(Kv_file, Base_path, Memtable_ranges) -> + case Memtable_ranges of + [{Id, {mem_table_range, Lower, Upper, {some, Memtable}}} | Rest] -> + _assert_subject = ream@storage@kv@sstable:flush( + Memtable, + sstable_path(Base_path, Id) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"write_memtable_ranges"/utf8>>, + line => 239}) + end, + _assert_subject@1 = ream@storage@file:write( + Kv_file, + <<Lower:128, Upper:128, Id:128>> + ), + {ok, _} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"write_memtable_ranges"/utf8>>, + line => 240}) + end, + write_memtable_ranges(Kv_file, Base_path, Rest); + + [{Id@1, {mem_table_range, Lower@1, Upper@1, none}} | Rest@1] -> + _assert_subject@2 = ream@storage@file:write( + Kv_file, + <<Lower@1:128, Upper@1:128, Id@1:128>> + ), + {ok, _} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"write_memtable_ranges"/utf8>>, + line => 244}) + end, + write_memtable_ranges(Kv_file, Base_path, Rest@1); + + [] -> + {ok, nil} + end. + +-spec write_values(gleam@erlang@process:pid_(), list(integer())) -> {ok, nil} | + {error, nil}. +write_values(Kv, Values) -> + case Values of + [Id | Rest] -> + _assert_subject = ream@storage@file:write(Kv, <<Id:128>>), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"write_values"/utf8>>, + line => 254}) + end, + write_values(Kv, Rest); + + [] -> + {ok, nil} + end. + +-spec flush(kv()) -> {ok, nil} | {error, nil}. +flush(Kv) -> + Key_index_file = filename:join( + [erlang:element(2, Kv), <<"key"/utf8>>, <<"index"/utf8>>] + ), + _assert_subject = ream@storage@file:recursive_make_directory( + filename:dirname(Key_index_file) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 215}) + end, + _assert_subject@1 = ream@storage@file:open(Key_index_file, [write]), + {ok, Kv_file} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 216}) + end, + Memtable_ranges = gleam@map:to_list(erlang:element(4, Kv)), + _assert_subject@2 = write_memtable_ranges( + Kv_file, + erlang:element(2, Kv), + Memtable_ranges + ), + {ok, _} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 218}) + end, + _assert_subject@3 = ream@storage@file:close(Kv_file), + {ok, _} = case _assert_subject@3 of + {ok, _} -> _assert_subject@3; + _assert_fail@3 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 220}) + end, + Value_index_file = filename:join( + [erlang:element(2, Kv), <<"value"/utf8>>, <<"index"/utf8>>] + ), + _assert_subject@4 = ream@storage@file:recursive_make_directory( + filename:dirname(Value_index_file) + ), + {ok, true} = case _assert_subject@4 of + {ok, true} -> _assert_subject@4; + _assert_fail@4 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@4, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 223}) + end, + _assert_subject@5 = ream@storage@file:open(Value_index_file, [write]), + {ok, Kv_file@1} = case _assert_subject@5 of + {ok, _} -> _assert_subject@5; + _assert_fail@5 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@5, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 225}) + end, + _assert_subject@6 = write_values( + Kv_file@1, + gleam@map:keys(erlang:element(6, Kv)) + ), + {ok, _} = case _assert_subject@6 of + {ok, _} -> _assert_subject@6; + _assert_fail@6 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@6, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 226}) + end, + _assert_subject@7 = ream@storage@file:close(Kv_file@1), + {ok, _} = case _assert_subject@7 of + {ok, _} -> _assert_subject@7; + _assert_fail@7 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@7, + module => <<"ream/storage/kv"/utf8>>, + function => <<"flush"/utf8>>, + line => 227}) + end, + {ok, nil}. + +-spec close(kv()) -> {ok, nil} | {error, nil}. +close(Kv) -> + _assert_subject = flush(Kv), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"close"/utf8>>, + line => 205}) + end, + _pipe = gleam@map:values(erlang:element(6, Kv)), + gleam@list:each(_pipe, fun(V) -> ream@storage@kv@value:close(V) end), + {ok, nil}. + +-spec set(kv(), binary(), bitstring()) -> kv(). +set(Kv, Key, Value) -> + Key_hash = erlang:phash2(Key), + {Range_id, Kv@1} = find_range(Kv, Key_hash, erlang:element(9, Kv)), + _assert_subject = gleam@map:get(erlang:element(4, Kv@1), Range_id), + {ok, Range} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"set"/utf8>>, + line => 284}) + end, + _assert_subject@1 = erlang:element(4, Range), + {some, Memtable} = case _assert_subject@1 of + {some, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"set"/utf8>>, + line => 285}) + end, + Kv@2 = case erlang:element(5, Kv@1) of + {some, _} -> + Kv@1; + + none -> + _assert_subject@2 = ream@storage@kv@value:create( + filename:join([erlang:element(2, Kv@1), <<"value"/utf8>>]), + erlang:element(10, Kv@1) + ), + {ok, Vfile} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"set"/utf8>>, + line => 289}) + end, + erlang:setelement( + 6, + erlang:setelement(5, Kv@1, {some, erlang:element(2, Vfile)}), + gleam@map:insert( + erlang:element(6, Kv@1), + erlang:element(2, Vfile), + Vfile + ) + ) + end, + case ream@storage@kv@memtable:get(Memtable, Key) of + {ok, Old_value} -> + case store_value(Kv@2, Key, Range_id, Range, Memtable, Value) of + {ok, Kv@3} -> + Kv@3; + + {error, capacity_exceeded} -> + Kv@4 = split(Kv@2, Key_hash, Range_id, Range, Memtable), + set(Kv@4, Key, Value) + end, + _assert_subject@3 = delete_value(Kv@2, Old_value), + {ok, Kv@5} = case _assert_subject@3 of + {ok, _} -> _assert_subject@3; + _assert_fail@3 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"ream/storage/kv"/utf8>>, + function => <<"set"/utf8>>, + line => 308}) + end, + Kv@5; + + {error, nil} -> + case store_value(Kv@2, Key, Range_id, Range, Memtable, Value) of + {ok, Kv@6} -> + Kv@6; + + {error, capacity_exceeded} -> + Kv@7 = split(Kv@2, Key_hash, Range_id, Range, Memtable), + set(Kv@7, Key, Value) + end + end. + +-spec store_value( + kv(), + binary(), + integer(), + mem_table_range(), + ream@storage@kv@memtable:mem_table(), + bitstring() +) -> {ok, kv()} | {error, ream@storage@kv@memtable:reason()}. +store_value(Kv, Key, Range_id, Range, Memtable, Value_data) -> + _assert_subject = erlang:element(5, Kv), + {some, File_id} = case _assert_subject of + {some, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv"/utf8>>, + function => <<"store_value"/utf8>>, + line => 368}) + end, + _assert_subject@1 = gleam@map:get(erlang:element(6, Kv), File_id), + {ok, Vfile} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv"/utf8>>, + function => <<"store_value"/utf8>>, + line => 369}) + end, + case ream@storage@kv@value:write(Vfile, Value_data) of + {ok, {Vfile@1, Value}} -> + gleam@result:'try'( + ream@storage@kv@memtable:set(Memtable, Key, Value), + fun(Memtable@1) -> + Range@1 = erlang:setelement(4, Range, {some, Memtable@1}), + {ok, + erlang:setelement( + 4, + erlang:setelement( + 6, + erlang:setelement( + 5, + Kv, + {some, erlang:element(2, Vfile@1)} + ), + gleam@map:insert( + erlang:element(6, Kv), + erlang:element(2, Vfile@1), + Vfile@1 + ) + ), + gleam@map:insert( + erlang:element(4, Kv), + Range_id, + Range@1 + ) + )} + end + ); + + {error, capacity_exceeded} -> + _assert_subject@2 = ream@storage@kv@value:create( + filename:join([erlang:element(2, Kv), <<"value"/utf8>>]), + erlang:element(10, Kv) + ), + {ok, Vfile@2} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv"/utf8>>, + function => <<"store_value"/utf8>>, + line => 384}) + end, + _pipe = erlang:setelement( + 6, + erlang:setelement(5, Kv, {some, erlang:element(2, Vfile@2)}), + gleam@map:insert( + erlang:element(6, Kv), + erlang:element(2, Vfile@2), + Vfile@2 + ) + ), + store_value(_pipe, Key, Range_id, Range, Memtable, Value_data) + end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl new file mode 100644 index 00000000000..dd2140c0085 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl @@ -0,0 +1,277 @@ +-module(ream@storage@kv@memtable). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([new/1, bitstring_to_entry/1, search_pivot/1, get_bounds/1, hash/1, entry_to_bitstring/1, contains/2, get/2, set/3, delete/2, from_entries/2, split/2]). +-export_type([mem_table/0, mem_table_entry/0, reason/0]). + +-type mem_table() :: {mem_table, + gleam@map:map_(integer(), mem_table_entry()), + integer(), + integer()}. + +-type mem_table_entry() :: {mem_table_entry, + binary(), + ream@storage@kv@value:value()}. + +-type reason() :: capacity_exceeded. + +-spec new(integer()) -> mem_table(). +new(Max_size) -> + {mem_table, gleam@map:new(), 0, Max_size}. + +-spec bitstring_to_entry(bitstring()) -> {integer(), mem_table_entry()}. +bitstring_to_entry(Bitstring) -> + <<Key_hash:128, _:16, File_id:128, File_offset:32, Key_string/bitstring>> = Bitstring, + _assert_subject = gleam@bit_string:to_string(Key_string), + {ok, Key} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/memtable"/utf8>>, + function => <<"bitstring_to_entry"/utf8>>, + line => 96}) + end, + Value = {value, File_offset, false, none, File_id}, + {Key_hash, {mem_table_entry, Key, Value}}. + +-spec search_pivot(mem_table()) -> integer(). +search_pivot(Mem_table) -> + Entries = erlang:element(2, Mem_table), + Keys = gleam@map:keys(Entries), + Entries_count = gleam@map:size(Entries), + {_, [Pivot | _]} = gleam@list:split(Keys, Entries_count div 2), + Pivot. + +-spec get_lower(integer(), integer()) -> integer(). +get_lower(Lower_bound, Key) -> + case Lower_bound of + 0 -> + Key; + + Lower_bound@1 when Key < Lower_bound@1 -> + Key; + + Lower_bound@2 -> + Lower_bound@2 + end. + +-spec get_higher(integer(), integer()) -> integer(). +get_higher(Higher_bound, Key) -> + case Higher_bound of + 0 -> + Key; + + Higher_bound@1 when Key > Higher_bound@1 -> + Key; + + Higher_bound@2 -> + Higher_bound@2 + end. + +-spec get_bounds(mem_table()) -> {integer(), integer()}. +get_bounds(Mem_table) -> + case gleam@map:to_list(erlang:element(2, Mem_table)) of + [] -> + {0, 0}; + + [{K, _} | Entries] -> + gleam@list:fold( + Entries, + {K, K}, + fun(Acc, Entry) -> + {get_lower(erlang:element(1, Acc), erlang:element(1, Entry)), + get_higher( + erlang:element(2, Acc), + erlang:element(1, Entry) + )} + end + ) + end. + +-spec hash(binary()) -> integer(). +hash(Field@0) -> + erlang:phash2(Field@0). + +-spec entry_to_bitstring(mem_table_entry()) -> bitstring(). +entry_to_bitstring(Entry) -> + Key_hash = erlang:phash2(erlang:element(2, Entry)), + Key_string = gleam@bit_string:from_string(erlang:element(2, Entry)), + Key_size = gleam@bit_string:byte_size(Key_string), + File_id = erlang:element(5, erlang:element(3, Entry)), + File_offset = erlang:element(2, erlang:element(3, Entry)), + <<Key_hash:128, + Key_size:16, + File_id:128, + File_offset:32, + Key_string/bitstring>>. + +-spec contains(mem_table(), binary()) -> boolean(). +contains(Mem_table, Key) -> + gleam@map:has_key(erlang:element(2, Mem_table), erlang:phash2(Key)). + +-spec get(mem_table(), binary()) -> {ok, ream@storage@kv@value:value()} | + {error, nil}. +get(Mem_table, Key) -> + case gleam@map:get(erlang:element(2, Mem_table), erlang:phash2(Key)) of + {ok, {mem_table_entry, Stored_key, Value}} when Key =:= Stored_key -> + {ok, Value}; + + {ok, {mem_table_entry, _, _}} -> + erlang:error(#{gleam_error => panic, + message => <<"panic expression evaluated"/utf8>>, + module => <<"ream/storage/kv/memtable"/utf8>>, + function => <<"get"/utf8>>, + line => 183}); + + {error, nil} -> + {error, nil} + end. + +-spec calculate_size(mem_table_entry()) -> integer(). +calculate_size(Entry) -> + gleam@bit_string:byte_size(entry_to_bitstring(Entry)). + +-spec set(mem_table(), binary(), ream@storage@kv@value:value()) -> {ok, + mem_table()} | + {error, reason()}. +set(Mem_table, Key, Value) -> + Key_hash = erlang:phash2(Key), + case gleam@map:get(erlang:element(2, Mem_table), Key_hash) of + {error, nil} -> + Entry = {mem_table_entry, Key, Value}, + Entry_size = calculate_size(Entry), + Current_size = erlang:element(3, Mem_table) + Entry_size, + case Current_size > erlang:element(4, Mem_table) of + true -> + {error, capacity_exceeded}; + + false -> + {ok, + erlang:setelement( + 3, + erlang:setelement( + 2, + Mem_table, + gleam@map:insert( + erlang:element(2, Mem_table), + Key_hash, + Entry + ) + ), + Current_size + )} + end; + + {ok, Old_entry} -> + Old_entry_size = calculate_size(Old_entry), + Entry@1 = erlang:setelement(3, Old_entry, Value), + Current_entry_size = calculate_size(Entry@1), + Mem_table_size = (erlang:element(3, Mem_table) + Current_entry_size) + - Old_entry_size, + case Mem_table_size > erlang:element(4, Mem_table) of + true -> + {error, capacity_exceeded}; + + false -> + {ok, + erlang:setelement( + 3, + erlang:setelement( + 2, + Mem_table, + gleam@map:insert( + erlang:element(2, Mem_table), + Key_hash, + Entry@1 + ) + ), + Mem_table_size + )} + end + end. + +-spec delete(mem_table(), binary()) -> mem_table(). +delete(Mem_table, Key) -> + Key_hash = erlang:phash2(Key), + case gleam@map:get(erlang:element(2, Mem_table), Key_hash) of + {error, nil} -> + Mem_table; + + {ok, Entry} -> + erlang:setelement( + 3, + erlang:setelement( + 2, + Mem_table, + gleam@map:delete(erlang:element(2, Mem_table), Key_hash) + ), + erlang:element(3, Mem_table) - calculate_size(Entry) + ) + end. + +-spec calculate_entries_size(gleam@map:map_(integer(), mem_table_entry())) -> integer(). +calculate_entries_size(Entries) -> + gleam@map:fold( + Entries, + 0, + fun(Acc, _, Entry) -> Acc + calculate_size(Entry) end + ). + +-spec from_entries(gleam@map:map_(integer(), mem_table_entry()), integer()) -> mem_table(). +from_entries(Entries, Max_size) -> + Size = calculate_entries_size(Entries), + {mem_table, Entries, Size, Max_size}. + +-spec split(mem_table(), integer()) -> {mem_table(), mem_table(), integer()}. +split(Mem_table, Pivot) -> + {Low_entries, High_entries} = begin + _pipe = erlang:element(2, Mem_table), + _pipe@1 = gleam@map:to_list(_pipe), + gleam@list:partition( + _pipe@1, + fun(Entry) -> erlang:element(1, Entry) < Pivot end + ) + end, + Low_entries@1 = gleam@map:from_list(Low_entries), + Low = erlang:setelement( + 3, + erlang:setelement(2, Mem_table, Low_entries@1), + calculate_entries_size(Low_entries@1) + ), + High_entries@1 = gleam@map:from_list(High_entries), + High = erlang:setelement( + 3, + erlang:setelement(2, Mem_table, High_entries@1), + calculate_entries_size(High_entries@1) + ), + case {erlang:element(3, Low) >= erlang:element(3, High), + gleam@map:get(erlang:element(2, High), Pivot)} of + {true, _} -> + {Low, High, Pivot}; + + {false, {error, nil}} -> + {Low, High, Pivot + 1}; + + {false, {ok, Entry@1}} -> + High@1 = erlang:setelement( + 3, + erlang:setelement( + 2, + High, + gleam@map:delete(erlang:element(2, High), Pivot) + ), + erlang:element(3, High) - calculate_size(Entry@1) + ), + Low@1 = erlang:setelement( + 3, + erlang:setelement( + 2, + Low, + gleam@map:insert(erlang:element(2, Low), Pivot, Entry@1) + ), + erlang:element(3, Low) + calculate_size(Entry@1) + ), + {Low@1, High@1, Pivot + 1} + end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl new file mode 100644 index 00000000000..c8800712fc5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl @@ -0,0 +1,136 @@ +-module(ream@storage@kv@sstable). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([flush/2, load/2]). + +-spec flush(ream@storage@kv@memtable:mem_table(), binary()) -> {ok, boolean()} | + {error, gleam@erlang@file:reason()}. +flush(Mem_table, Path) -> + _assert_subject = ream@storage@file:recursive_make_directory( + filename:dirname(Path) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"flush"/utf8>>, + line => 11}) + end, + _assert_subject@1 = ream@storage@file:open(Path, [write]), + {ok, File} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"flush"/utf8>>, + line => 12}) + end, + gleam@map:filter( + erlang:element(2, Mem_table), + fun(_, Entry) -> + Content = ream@storage@kv@memtable:entry_to_bitstring(Entry), + _assert_subject@2 = ream@storage@file:write(File, Content), + {ok, _} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"flush"/utf8>>, + line => 18}) + end, + false + end + ), + _assert_subject@3 = ream@storage@file:close(File), + {ok, _} = case _assert_subject@3 of + {ok, _} -> _assert_subject@3; + _assert_fail@3 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@3, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"flush"/utf8>>, + line => 22}) + end, + {ok, true}. + +-spec read_entries( + gleam@erlang@process:pid_(), + gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry()) +) -> {ok, gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry())} | + {error, gleam@erlang@file:reason()}. +read_entries(File, Entries) -> + case file:read(File, 38) of + {ok, <<Key_hash:128, Key_size:16, File_id:128, Offset:32>>} -> + _assert_subject = file:read(File, Key_size), + {ok, Key_string} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"read_entries"/utf8>>, + line => 39}) + end, + {_, Entry} = ream@storage@kv@memtable:bitstring_to_entry( + <<Key_hash:128, + Key_size:16, + File_id:128, + Offset:32, + Key_string/bitstring>> + ), + Entries@1 = gleam@map:insert(Entries, Key_hash, Entry), + read_entries(File, Entries@1); + + eof -> + {ok, Entries}; + + {error, Reason} -> + {error, Reason} + end. + +-spec load(binary(), integer()) -> {ok, ream@storage@kv@memtable:mem_table()} | + {error, gleam@erlang@file:reason()}. +load(Path, Max_size) -> + _assert_subject = ream@storage@file:open(Path, [read]), + {ok, File} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"load"/utf8>>, + line => 27}) + end, + _assert_subject@1 = read_entries(File, gleam@map:new()), + {ok, Entries} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"load"/utf8>>, + line => 28}) + end, + _assert_subject@2 = ream@storage@file:close(File), + {ok, _} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv/sstable"/utf8>>, + function => <<"load"/utf8>>, + line => 29}) + end, + {ok, ream@storage@kv@memtable:from_entries(Entries, Max_size)}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl new file mode 100644 index 00000000000..5d11a993bde --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl @@ -0,0 +1,326 @@ +-module(ream@storage@kv@value). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([create/2, open/3, close/1, write_value/2, write/2, read/2, delete/2, get_file_info/1]). +-export_type([reason/0, value/0, value_file/0, value_file_info/0]). + +-type reason() :: capacity_exceeded. + +-type value() :: {value, + integer(), + boolean(), + gleam@option:option(bitstring()), + integer()}. + +-type value_file() :: {value_file, + integer(), + gleam@erlang@process:pid_(), + integer(), + integer(), + binary()}. + +-type value_file_info() :: {value_file_info, + integer(), + integer(), + integer(), + integer(), + integer()}. + +-spec get_file_name(binary(), integer()) -> binary(). +get_file_name(Base_path, File_id) -> + filename:join([Base_path | ream@uuid:parts(ream@uuid:from_int(File_id))]). + +-spec create(binary(), integer()) -> {ok, value_file()} | + {error, gleam@erlang@file:reason()}. +create(Base_path, Max_size) -> + File_id = ream@uuid:to_int(ream@uuid:new()), + File_name = get_file_name(Base_path, File_id), + _assert_subject = ream@storage@file:recursive_make_directory( + filename:dirname(File_name) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"create"/utf8>>, + line => 78}) + end, + gleam@result:'try'( + ream@storage@file:open(File_name, [read, write]), + fun(File_pid) -> + {ok, {value_file, File_id, File_pid, 0, Max_size, File_name}} + end + ). + +-spec open(binary(), integer(), integer()) -> {ok, value_file()} | + {error, gleam@erlang@file:reason()}. +open(Path, File_id, Max_size) -> + File_name = get_file_name(Path, File_id), + _assert_subject = ream@storage@file:recursive_make_directory( + filename:dirname(File_name) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"open"/utf8>>, + line => 97}) + end, + _assert_subject@1 = ream@storage@file:open(File_name, [read, write]), + {ok, File_pid} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"open"/utf8>>, + line => 98}) + end, + _assert_subject@2 = gleam_erlang_ffi:file_info(File_name), + {ok, File_info} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"open"/utf8>>, + line => 99}) + end, + {ok, + {value_file, + File_id, + File_pid, + erlang:element(2, File_info), + Max_size, + File_name}}. + +-spec close(value_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. +close(Vfile) -> + _assert_subject = ream@storage@file:close(erlang:element(3, Vfile)), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"close"/utf8>>, + line => 105}) + end, + {ok, nil}. + +-spec write_value(value_file(), value()) -> {ok, value_file()} | + {error, reason()}. +write_value(Vfile, Value) -> + Value_size_bits = 32, + Value_size_bytes = Value_size_bits div 8, + _assert_subject = erlang:element(4, Value), + {some, Data} = case _assert_subject of + {some, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"write_value"/utf8>>, + line => 120}) + end, + Data_size = (gleam@bit_string:byte_size(Data) + Value_size_bytes) + 1, + Deleted = case erlang:element(3, Value) of + true -> + 1; + + false -> + 0 + end, + Packed_data = <<Data_size:(lists:max([(Value_size_bits), 0])), + Deleted:8, + Data/bitstring>>, + _assert_subject@1 = file:position( + erlang:element(3, Vfile), + {bof, erlang:element(2, Value)} + ), + {ok, Offset} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"write_value"/utf8>>, + line => 131}) + end, + case (Offset + Data_size) > erlang:element(5, Vfile) of + true -> + {error, capacity_exceeded}; + + false -> + _assert_subject@2 = ream@storage@file:write( + erlang:element(3, Vfile), + Packed_data + ), + {ok, _} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"write_value"/utf8>>, + line => 135}) + end, + case (Offset + Data_size) > erlang:element(4, Vfile) of + true -> + {ok, erlang:setelement(4, Vfile, Offset + Data_size)}; + + false -> + {ok, Vfile} + end + end. + +-spec write(value_file(), bitstring()) -> {ok, {value_file(), value()}} | + {error, reason()}. +write(Vfile, Value) -> + Value@1 = {value, + erlang:element(4, Vfile), + false, + {some, Value}, + erlang:element(2, Vfile)}, + gleam@result:'try'( + write_value(Vfile, Value@1), + fun(Vfile@1) -> {ok, {Vfile@1, erlang:setelement(4, Value@1, none)}} end + ). + +-spec read(value_file(), integer()) -> {ok, value()} | {error, reason()}. +read(Vfile, Offset) -> + Value_size_bits = 32, + Value_size_bytes = Value_size_bits div 8, + _assert_subject = file:position(erlang:element(3, Vfile), {bof, Offset}), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"read"/utf8>>, + line => 170}) + end, + _assert_subject@1 = file:read( + erlang:element(3, Vfile), + Value_size_bytes + 1 + ), + {ok, <<Size:Value_size_bits, Deleted:8>>} = case _assert_subject@1 of + {ok, <<_:Value_size_bits, _:8>>} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"read"/utf8>>, + line => 171}) + end, + Content_size = (Size - Value_size_bytes) - 1, + _assert_subject@2 = file:read(erlang:element(3, Vfile), Content_size), + {ok, Data} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"read"/utf8>>, + line => 174}) + end, + Deleted@1 = case Deleted of + 0 -> + false; + + 1 -> + true + end, + {ok, {value, Offset, Deleted@1, {some, Data}, erlang:element(2, Vfile)}}. + +-spec delete(value_file(), value()) -> {ok, value_file()} | {error, reason()}. +delete(Vfile, Value) -> + gleam@result:'try'( + read(Vfile, erlang:element(2, Value)), + fun(Value@1) -> + write_value(Vfile, erlang:setelement(3, Value@1, true)) + end + ). + +-spec get_entries_and_deleted( + gleam@erlang@process:pid_(), + {integer(), integer()} +) -> {ok, {integer(), integer()}} | {error, gleam@erlang@file:reason()}. +get_entries_and_deleted(Handler, Acc) -> + Value_size_bits = 32, + Value_size_bytes = Value_size_bits div 8, + case file:read(Handler, Value_size_bytes + 1) of + {ok, <<Size:Value_size_bits, Deleted:8>>} -> + Payload_size = (Size - Value_size_bytes) - 1, + _assert_subject = file:position(Handler, {cur, Payload_size}), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"get_entries_and_deleted"/utf8>>, + line => 200}) + end, + get_entries_and_deleted( + Handler, + {erlang:element(1, Acc) + 1, erlang:element(2, Acc) + Deleted} + ); + + eof -> + {ok, Acc}; + + {error, Reason} -> + {error, Reason} + end. + +-spec get_file_info(value_file()) -> value_file_info(). +get_file_info(Vfile) -> + _assert_subject = file:position(erlang:element(3, Vfile), {bof, 0}), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"get_file_info"/utf8>>, + line => 183}) + end, + _assert_subject@1 = get_entries_and_deleted( + erlang:element(3, Vfile), + {0, 0} + ), + {ok, {Entries, Deleted}} = case _assert_subject@1 of + {ok, {_, _}} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/kv/value"/utf8>>, + function => <<"get_file_info"/utf8>>, + line => 184}) + end, + {value_file_info, + erlang:element(2, Vfile), + erlang:element(4, Vfile), + erlang:element(5, Vfile), + Entries, + Deleted}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl new file mode 100644 index 00000000000..fd978abe885 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl @@ -0,0 +1,272 @@ +-module(ream@storage@stream). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([get_base_path/2, close/1, open/2, add_event/2, get_event/2]). +-export_type([stream/0]). + +-type stream() :: {stream, + binary(), + ream@storage@stream@index:index_file(), + gleam@option:option(ream@storage@stream@event:event_file()), + gleam@map:map_(integer(), ream@storage@stream@event:event_file()), + binary()}. + +-spec get_base_path(binary(), binary()) -> binary(). +get_base_path(Path, Name) -> + filename:join([Path, <<"stream"/utf8>>, Name]). + +-spec less_populated_file(list(ream@storage@stream@event:event_file())) -> gleam@option:option(ream@storage@stream@event:event_file()). +less_populated_file(Files) -> + _pipe = Files, + gleam@list:fold( + _pipe, + none, + fun(Acc, File) -> + File_size = erlang:element(4, File), + case Acc of + {some, {event_file, _, _, Size, _}} when File_size >= Size -> + Acc; + + _ -> + {some, File} + end + end + ). + +-spec close(stream()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. +close(Stream) -> + _assert_subject = ream@storage@stream@index:close(erlang:element(3, Stream)), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream"/utf8>>, + function => <<"close"/utf8>>, + line => 50}) + end, + _pipe = erlang:element(5, Stream), + _pipe@1 = gleam@map:values(_pipe), + gleam@list:each( + _pipe@1, + fun(File) -> ream@storage@file:close(erlang:element(3, File)) end + ), + {ok, nil}. + +-spec do_open_files( + ream@storage@stream@index:index_file(), + binary(), + gleam@map:map_(integer(), ream@storage@stream@event:event_file()) +) -> {ok, gleam@map:map_(integer(), ream@storage@stream@event:event_file())} | + {error, gleam@erlang@file:reason()}. +do_open_files(Index_file, Path, Acc) -> + case ream@storage@stream@index:count(Index_file) of + 0 -> + {ok, Acc}; + + Num_of_events -> + _ = ream@storage@stream@index:set_pos(Index_file, 0), + Files = begin + _pipe = Num_of_events - 1, + _pipe@1 = gleam@iterator:range(0, _pipe), + gleam@iterator:fold( + _pipe@1, + Acc, + fun(Acc@1, _) -> + _assert_subject = ream@storage@stream@index:get_next( + Index_file + ), + {ok, {index, _, _, File_id}} = case _assert_subject of + {ok, {index, _, _, _}} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream"/utf8>>, + function => <<"do_open_files"/utf8>>, + line => 75}) + end, + case gleam@map:has_key(Acc@1, File_id) of + true -> + Acc@1; + + false -> + _assert_subject@1 = ream@storage@stream@event:open( + Path, + File_id + ), + {ok, File} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/stream"/utf8>>, + function => <<"do_open_files"/utf8>>, + line => 80}) + end, + gleam@map:insert(Acc@1, File_id, File) + end + end + ) + end, + {ok, Files} + end. + +-spec open(binary(), binary()) -> {ok, stream()} | + {error, gleam@erlang@file:reason()}. +open(Name, Path) -> + Base_path = filename:join([Path, <<"stream"/utf8>>, Name]), + _assert_subject = ream@storage@stream@index:open(Base_path), + {ok, Index_file} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream"/utf8>>, + function => <<"open"/utf8>>, + line => 28}) + end, + gleam@result:'try'( + do_open_files(Index_file, Base_path, gleam@map:new()), + fun(Files) -> + Active_file = less_populated_file(gleam@map:values(Files)), + {ok, {stream, Name, Index_file, Active_file, Files, Base_path}} + end + ). + +-spec add_event(stream(), bitstring()) -> {ok, stream()} | + {error, gleam@erlang@file:reason()}. +add_event(Stream, Event_content) -> + Event_size = gleam@bit_string:byte_size(Event_content), + {Stream@3, Index@2} = case ream@storage@stream@index:count( + erlang:element(3, Stream) + ) of + 0 -> + _assert_subject = ream@storage@stream@event:create( + erlang:element(6, Stream) + ), + {ok, Stream_file} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream"/utf8>>, + function => <<"add_event"/utf8>>, + line => 99}) + end, + {Index, Index_file} = ream@storage@stream@index:add( + erlang:element(3, Stream), + Event_size, + erlang:element(2, Stream_file) + ), + Stream@1 = erlang:setelement( + 5, + erlang:setelement( + 4, + erlang:setelement(3, Stream, Index_file), + {some, Stream_file} + ), + gleam@map:insert( + erlang:element(5, Stream), + erlang:element(2, Stream_file), + Stream_file + ) + ), + {Stream@1, Index}; + + _ -> + _assert_subject@1 = erlang:element(4, Stream), + {some, Active_file} = case _assert_subject@1 of + {some, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/stream"/utf8>>, + function => <<"add_event"/utf8>>, + line => 112}) + end, + {Index@1, Index_file@1} = ream@storage@stream@index:add( + erlang:element(3, Stream), + Event_size, + erlang:element(2, Active_file) + ), + Stream@2 = erlang:setelement(3, Stream, Index_file@1), + {Stream@2, Index@1} + end, + _assert_subject@2 = gleam@map:get( + erlang:element(5, Stream@3), + erlang:element(4, Index@2) + ), + {ok, File} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/stream"/utf8>>, + function => <<"add_event"/utf8>>, + line => 120}) + end, + Event = {event, erlang:element(2, Index@2), Event_content}, + Stream_file@1 = ream@storage@stream@event:write(File, Event), + Files = gleam@map:insert( + erlang:element(5, Stream@3), + erlang:element(2, Stream_file@1), + Stream_file@1 + ), + {ok, erlang:setelement(5, Stream@3, Files)}. + +-spec get_event(stream(), integer()) -> {ok, bitstring()} | + {error, gleam@erlang@file:reason()}. +get_event(Stream, Index) -> + case ream@storage@stream@index:count(erlang:element(3, Stream)) > Index of + true -> + _assert_subject = ream@storage@stream@index:get( + erlang:element(3, Stream), + Index + ), + {ok, {index, Offset, _, File_id}} = case _assert_subject of + {ok, {index, _, _, _}} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream"/utf8>>, + function => <<"get_event"/utf8>>, + line => 131}) + end, + _assert_subject@1 = gleam@map:get( + erlang:element(5, Stream), + File_id + ), + {ok, File} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/stream"/utf8>>, + function => <<"get_event"/utf8>>, + line => 133}) + end, + _assert_subject@2 = ream@storage@stream@event:read(File, Offset), + {ok, {event, _, Data}} = case _assert_subject@2 of + {ok, {event, _, _}} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/stream"/utf8>>, + function => <<"get_event"/utf8>>, + line => 134}) + end, + {ok, Data}; + + false -> + {error, einval} + end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl new file mode 100644 index 00000000000..f52e4f21270 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl @@ -0,0 +1,186 @@ +-module(ream@storage@stream@event). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([create/1, open/2, close/1, write/2, read/2]). +-export_type([event/0, event_file/0]). + +-type event() :: {event, integer(), bitstring()}. + +-type event_file() :: {event_file, + integer(), + gleam@erlang@process:pid_(), + integer(), + binary()}. + +-spec get_file_name(binary(), integer()) -> binary(). +get_file_name(Base_path, File_id) -> + filename:join([Base_path | ream@uuid:parts(<<File_id:128>>)]). + +-spec create(binary()) -> {ok, event_file()} | + {error, gleam@erlang@file:reason()}. +create(Base_path) -> + <<File_id:128>> = ream@uuid:new(), + File_name = get_file_name(Base_path, File_id), + _assert_subject = ream@storage@file:recursive_make_directory( + filename:dirname(File_name) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"create"/utf8>>, + line => 39}) + end, + gleam@result:'try'( + ream@storage@file:open(File_name, [read, append]), + fun(File_pid) -> {ok, {event_file, File_id, File_pid, 0, File_name}} end + ). + +-spec open(binary(), integer()) -> {ok, event_file()} | + {error, gleam@erlang@file:reason()}. +open(Path, File_id) -> + File_name = get_file_name(Path, File_id), + _assert_subject = ream@storage@file:recursive_make_directory( + filename:dirname(File_name) + ), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"open"/utf8>>, + line => 54}) + end, + _assert_subject@1 = ream@storage@file:open(File_name, [read, append]), + {ok, File_pid} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"open"/utf8>>, + line => 55}) + end, + _assert_subject@2 = gleam_erlang_ffi:file_info(File_name), + {ok, File_info} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"open"/utf8>>, + line => 56}) + end, + {ok, + {event_file, File_id, File_pid, erlang:element(2, File_info), File_name}}. + +-spec close(event_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. +close(Stream_file) -> + _assert_subject = ream@storage@file:close(erlang:element(3, Stream_file)), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"close"/utf8>>, + line => 62}) + end, + {ok, nil}. + +-spec write(event_file(), event()) -> event_file(). +write(Stream_file, Event) -> + Event_size_bits = 24, + Event_size_bytes = Event_size_bits div 8, + Data_size = gleam@bit_string:byte_size(erlang:element(3, Event)) + Event_size_bytes, + Data = <<Data_size:(lists:max([(Event_size_bits), 0])), + (erlang:element(3, Event))/bitstring>>, + _assert_subject = file:position( + erlang:element(3, Stream_file), + {bof, erlang:element(2, Event)} + ), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"write"/utf8>>, + line => 76}) + end, + _assert_subject@1 = ream@storage@file:write( + erlang:element(3, Stream_file), + Data + ), + {ok, _} = case _assert_subject@1 of + {ok, _} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"write"/utf8>>, + line => 77}) + end, + Data_size@1 = gleam@bit_string:byte_size(Data), + erlang:setelement( + 4, + Stream_file, + erlang:element(4, Stream_file) + Data_size@1 + ). + +-spec read(event_file(), integer()) -> {ok, event()} | + {error, gleam@erlang@file:reason()}. +read(Stream_file, Offset) -> + Event_size_bits = 24, + Event_size_bytes = Event_size_bits div 8, + _assert_subject = file:position( + erlang:element(3, Stream_file), + {bof, Offset} + ), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"read"/utf8>>, + line => 89}) + end, + _assert_subject@1 = file:read( + erlang:element(3, Stream_file), + Event_size_bytes + ), + {ok, <<Size:Event_size_bits>>} = case _assert_subject@1 of + {ok, <<_:Event_size_bits>>} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"read"/utf8>>, + line => 90}) + end, + Content_size = Size - Event_size_bytes, + _assert_subject@2 = file:read(erlang:element(3, Stream_file), Content_size), + {ok, Data} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/stream/event"/utf8>>, + function => <<"read"/utf8>>, + line => 93}) + end, + {ok, {event, Offset, Data}}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl new file mode 100644 index 00000000000..1580dada363 --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl @@ -0,0 +1,234 @@ +-module(ream@storage@stream@index). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([open/1, close/1, count/1, set_pos/2, get_next/1, get/2, add/3]). +-export_type([index/0, index_file/0]). + +-type index() :: {index, integer(), integer(), integer()}. + +-type index_file() :: {index_file, + gleam@erlang@process:pid_(), + integer(), + binary()}. + +-spec open(binary()) -> {ok, index_file()} | {error, gleam@erlang@file:reason()}. +open(Path) -> + _assert_subject = ream@storage@file:recursive_make_directory(Path), + {ok, true} = case _assert_subject of + {ok, true} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"open"/utf8>>, + line => 34}) + end, + Index = filename:join([Path, <<"index"/utf8>>]), + gleam@result:'try'( + ream@storage@file:open(Index, [read, append]), + fun(Index_pid) -> + gleam@result:'try'( + gleam_erlang_ffi:file_info(Index), + fun(Index_info) -> + {ok, + {index_file, + Index_pid, + erlang:element(2, Index_info), + Index}} + end + ) + end + ). + +-spec close(index_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. +close(Index_file) -> + _assert_subject = ream@storage@file:close(erlang:element(2, Index_file)), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"close"/utf8>>, + line => 42}) + end, + {ok, nil}. + +-spec index_binary(index()) -> bitstring(). +index_binary(Index) -> + Offset_size_bits = 48, + Event_size_bits = 24, + File_id_size_bits = 128, + <<(erlang:element(2, Index)):(lists:max([(Offset_size_bits), 0])), + (erlang:element(3, Index)):(lists:max([(Event_size_bits), 0])), + (erlang:element(4, Index)):(lists:max([(File_id_size_bits), 0]))>>. + +-spec count(index_file()) -> integer(). +count(Index_file) -> + _assert_subject = gleam@int:divide(erlang:element(3, Index_file), 25), + {ok, Result} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"count"/utf8>>, + line => 120}) + end, + Result. + +-spec set_pos(index_file(), integer()) -> {ok, integer()} | + {error, gleam@erlang@file:reason()}. +set_pos(Index_file, Index) -> + file:position(erlang:element(2, Index_file), {bof, Index * 25}). + +-spec get_next(index_file()) -> {ok, index()} | + {error, gleam@erlang@file:reason()}. +get_next(Index_file) -> + Offset_size_bits = 48, + Event_size_bits = 24, + File_id_size_bits = 128, + case file:read(erlang:element(2, Index_file), 25) of + {ok, + <<Offset:Offset_size_bits, + Size:Event_size_bits, + File_id:File_id_size_bits>>} -> + {ok, {index, Offset, Size, File_id}}; + + eof -> + {error, espipe}; + + _ -> + {error, einval} + end. + +-spec get(index_file(), integer()) -> {ok, index()} | + {error, gleam@erlang@file:reason()}. +get(Index_file, Index) -> + case count(Index_file) > Index of + true -> + _assert_subject = set_pos(Index_file, Index), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"get"/utf8>>, + line => 148}) + end, + get_next(Index_file); + + false -> + {error, einval} + end. + +-spec last_entry_for_file(gleam@erlang@process:pid_(), integer()) -> {ok, + bitstring()} | + {error, gleam@erlang@file:reason()}. +last_entry_for_file(Index_file, File_id) -> + Offset_size_bits = 48, + Event_size_bits = 24, + File_id_size_bits = 128, + _assert_subject = file:read(Index_file, 25), + {ok, + <<Offset:Offset_size_bits, + Size:Event_size_bits, + New_file_id:File_id_size_bits>>} = case _assert_subject of + {ok, <<_:Offset_size_bits, _:Event_size_bits, _:File_id_size_bits>>} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"last_entry_for_file"/utf8>>, + line => 103}) + end, + case New_file_id =:= File_id of + true -> + {ok, index_binary({index, Offset, Size, File_id})}; + + false -> + case file:position(Index_file, {cur, -2 * 25}) of + {ok, _} -> + last_entry_for_file(Index_file, File_id); + + {error, einval} -> + {ok, index_binary({index, 0, 0, File_id})} + end + end. + +-spec add(index_file(), integer(), integer()) -> {index(), index_file()}. +add(Index_file, Event_size, File_id) -> + Event_size_bytes = 24 div 8, + {Index_content, Index@2} = case erlang:element(3, Index_file) of + 0 -> + Index = {index, 0, Event_size + Event_size_bytes, File_id}, + {index_binary(Index), Index}; + + _ -> + _assert_subject = file:position( + erlang:element(2, Index_file), + {eof, - 25} + ), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"add"/utf8>>, + line => 58}) + end, + Offset_size_bits = 48, + Event_size_bits = 24, + File_id_size_bits = 128, + _assert_subject@1 = last_entry_for_file( + erlang:element(2, Index_file), + File_id + ), + {ok, + <<Offset:Offset_size_bits, + Prev_size:Event_size_bits, + _:File_id_size_bits>>} = case _assert_subject@1 of + {ok, + <<_:Offset_size_bits, + _:Event_size_bits, + _:File_id_size_bits>>} -> _assert_subject@1; + _assert_fail@1 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@1, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"add"/utf8>>, + line => 65}) + end, + Offset@1 = Offset + Prev_size, + Index@1 = {index, Offset@1, Event_size + Event_size_bytes, File_id}, + {index_binary(Index@1), Index@1} + end, + _assert_subject@2 = ream@storage@file:write( + erlang:element(2, Index_file), + Index_content + ), + {ok, _} = case _assert_subject@2 of + {ok, _} -> _assert_subject@2; + _assert_fail@2 -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail@2, + module => <<"ream/storage/stream/index"/utf8>>, + function => <<"add"/utf8>>, + line => 75}) + end, + Index_file@1 = erlang:setelement( + 3, + Index_file, + erlang:element(3, Index_file) + 25 + ), + {Index@2, Index_file@1}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl b/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl new file mode 100644 index 00000000000..67ad2a2773d --- /dev/null +++ b/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl @@ -0,0 +1,53 @@ +-module(ream@uuid). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_int/1, from_int/1, from_string/1, parts/1, to_string/1, new/0]). + +-spec to_int(bitstring()) -> integer(). +to_int(Uuid) -> + <<Uuid_int:128>> = Uuid, + Uuid_int. + +-spec from_int(integer()) -> bitstring(). +from_int(Uuid) -> + <<Uuid:128>>. + +-spec from_string(binary()) -> bitstring(). +from_string(Uuid) -> + _assert_subject = begin + _pipe = Uuid, + _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<""/utf8>>), + gleam@int:base_parse(_pipe@1, 16) + end, + {ok, Uuid_int} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"ream/uuid"/utf8>>, + function => <<"from_string"/utf8>>, + line => 28}) + end, + from_int(Uuid_int). + +-spec to_hex(integer(), integer()) -> binary(). +to_hex(N, Size) -> + _pipe = gleam@int:to_base16(N), + _pipe@1 = gleam@string:lowercase(_pipe), + gleam@string:pad_left(_pipe@1, Size, <<"0"/utf8>>). + +-spec parts(bitstring()) -> list(binary()). +parts(Uuid) -> + <<P1:32, P2:16, P3:16, P4:16, P5:48>> = Uuid, + [to_hex(P1, 8), to_hex(P2, 4), to_hex(P3, 4), to_hex(P4, 4), to_hex(P5, 12)]. + +-spec to_string(bitstring()) -> binary(). +to_string(Uuid) -> + _pipe = parts(Uuid), + gleam@string:join(_pipe, <<"-"/utf8>>). + +-spec new() -> bitstring(). +new() -> + <<U0:48, _:4, U1:12, _:2, U2:62>> = crypto:strong_rand_bytes(16), + <<U0:48, 4:4, U1:12, 2:2, U2:62>>. diff --git a/test-community-packages-javascript/build/packages/simplifile/README.md b/test-community-packages-javascript/build/packages/simplifile/README.md new file mode 100644 index 00000000000..006d5b762a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/simplifile/README.md @@ -0,0 +1,35 @@ +# simplifile + +[![Package Version](https://img.shields.io/hexpm/v/simplifile)](https://hex.pm/packages/simplifile) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/simplifile/) + +Simplifile provides basic file operations (read, write, append, and delete) that work +for all targets (Erlang, Node, and Deno). It also provides functions for working with directories. + +## Example +```gleam +let filepath = "./test/hello.txt" +let assert Ok(_) = "Hello, World" |> write(to: filepath) +let assert Ok(_) = "Goodbye, Mars" |> append(to: filepath) +let assert Ok("Hello, WorldGoodbye, Mars") = read(from: filepath) +let assert Ok(_) = delete(filepath) +let assert Error(_) = read(from: filepath) +``` + +## Quick start + +```sh +gleam run # Run the project +gleam test # Run the tests +gleam shell # Run an Erlang shell +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add simplifile +``` + +and its documentation can be found at <https://hexdocs.pm/simplifile>. diff --git a/test-community-packages-javascript/build/packages/simplifile/gleam.toml b/test-community-packages-javascript/build/packages/simplifile/gleam.toml new file mode 100644 index 00000000000..be16a280dd5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/simplifile/gleam.toml @@ -0,0 +1,19 @@ +name = "simplifile" +version = "0.1.4" +description = "Basic file operations that work on all targets" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +# +licences = ["Apache-2.0"] +repository = { type = "github", user = "bcpeinhardt", repo = "simplifile" } +# links = [{ title = "Website", href = "https://gleam.run" }] + +[javascript.deno] +allow_all = true + +[dependencies] +gleam_stdlib = "~> 0.29" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/simplifile/src/file.mjs b/test-community-packages-javascript/build/packages/simplifile/src/file.mjs new file mode 100644 index 00000000000..a707f9e5f6d --- /dev/null +++ b/test-community-packages-javascript/build/packages/simplifile/src/file.mjs @@ -0,0 +1,84 @@ +import fs from "node:fs" +import path from "node:path" +import { BitString, Ok, Error as GError, toList} from "./gleam.mjs"; + +export function readFile(filepath) { + try { + const contents = fs.readFileSync(path.normalize(filepath)).toString() + return new Ok(contents) + } catch(e) { + return new GError(stringifyError(e)) + } +} + +export function readBits(filepath) { + try { + const contents = fs.readFileSync(path.normalize(filepath)) + return new Ok(new BitString(new Uint8Array(contents))) + } catch(e) { + return new GError(stringifyError(e)) + } +} + +export function writeFile(contents, filepath) { + try { + fs.writeFileSync(path.normalize(filepath), contents) + return new Ok(undefined) + } catch(e) { + return new GError(stringifyError(e)) + } +} + +export function writeBits(contents, filepath) { + try { + fs.writeFileSync(path.normalize(filepath), contents.buffer) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +export function deleteFile(filepath) { + try { + fs.unlinkSync(path.normalize(filepath)) + return new Ok(undefined) + } catch(e) { + return new GError(stringifyError(e)) + } +} + +export function appendFile(contents, filepath) { + try { + fs.appendFileSync(path.normalize(filepath), contents) + return new Ok(undefined) + } catch(e) { + return new GError(stringifyError(e)) + } +} + +export function appendBits(contents, filepath) { + try { + fs.appendFileSync(path.normalize(filepath), contents.buffer) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +function stringifyError(e) { + return e.code +} + +export function isDirectory(filepath) { + let fp = path.normalize(filepath) + return fs.existsSync(fp) && fs.lstatSync(fp).isDirectory(); +} + +export function listContents(filepath) { + try { + const stuff = toList(fs.readdirSync(path.normalize(filepath))) + return new Ok(stuff) + } catch(e) { + return new GError(stringifyError(e)) + } +} \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl new file mode 100644 index 00000000000..b902c92cf1b --- /dev/null +++ b/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl @@ -0,0 +1,218 @@ +-module(gleam_erlang_ffi). +-export([ + atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, + ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, + append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, + set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, + list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, + insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, + merge_selector/2, flush_messages/0, file_info/1, link_info/1 +]). + +-define(is_posix_error(Error), + Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse + Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse + Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse + Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse + Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse + Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse + Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse + Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse + Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse + Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse + Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse + Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse + Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse + Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse + Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse + Error =:= etxtbsy orelse Error =:= exdev +). + +-spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. +atom_from_string(S) -> + try {ok, binary_to_existing_atom(S)} + catch error:badarg -> {error, atom_not_loaded} + end. + +atom_from_dynamic(Data) when is_atom(Data) -> + {ok, Data}; +atom_from_dynamic(Data) -> + {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. + +-spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. +get_line(Prompt) -> + case io:get_line(Prompt) of + eof -> {error, eof}; + {error, _} -> {error, no_data}; + Data when is_binary(Data) -> {ok, Data}; + Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} + end. + +rescue(F) -> + try {ok, F()} + catch + throw:X -> {error, {thrown, X}}; + error:X -> {error, {errored, X}}; + exit:X -> {error, {exited, X}} + end. + +ensure_all_started(Application) -> + case application:ensure_all_started(Application) of + {ok, _} = Ok -> Ok; + + {error, {ProblemApp, {"no such file or directory", _}}} -> + {error, {unknown_application, ProblemApp}} + end. + +sleep(Microseconds) -> + timer:sleep(Microseconds), + nil. + +sleep_forever() -> + timer:sleep(infinity), + nil. + +file_info_result(Result) -> + case Result of + {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> + {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; + {ok, _} -> + Result; + {error, Reason} when ?is_posix_error(Reason) -> + Result + end. + +file_info(Filename) -> + file_info_result(file:read_file_info(Filename, [{time, posix}])). + +link_info(Filename) -> + file_info_result(file:read_link_info(Filename, [{time, posix}])). + +posix_result(Result) -> + case Result of + ok -> {ok, nil}; + {ok, Value} -> {ok, Value}; + {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} + end. + +read_file(Filename) -> + posix_result(file:read_file(Filename)). + +write_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents)). + +append_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents, [append])). + +delete_file(Filename) -> + posix_result(file:delete(Filename)). + +make_directory(Dir) -> + posix_result(file:make_dir(Dir)). + +list_directory(Dir) -> + case file:list_dir(Dir) of + {ok, Filenames} -> + {ok, [list_to_binary(Filename) || Filename <- Filenames]}; + {error, Reason} when ?is_posix_error(Reason) -> + {error, Reason} + end. + +delete_directory(Dir) -> + posix_result(file:del_dir(Dir)). + +recursive_delete(Dir) -> + posix_result(file:del_dir_r(Dir)). + +get_all_env() -> + BinVars = lists:map(fun(VarString) -> + [VarName, VarVal] = string:split(VarString, "="), + {list_to_binary(VarName), list_to_binary(VarVal)} + end, os:getenv()), + maps:from_list(BinVars). + +get_env(Name) -> + case os:getenv(binary_to_list(Name)) of + false -> {error, nil}; + Value -> {ok, list_to_binary(Value)} + end. + +set_env(Name, Value) -> + os:putenv(binary_to_list(Name), binary_to_list(Value)), + nil. + +unset_env(Name) -> + os:unsetenv(binary_to_list(Name)), + nil. + +os_family() -> + case os:type() of + {win32, nt} -> + windows_nt; + {unix, linux} -> + linux; + {unix, darwin} -> + darwin; + {unix, freebsd} -> + free_bsd; + {_, Other} -> + {other, atom_to_binary(Other, utf8)} + end. + +new_selector() -> + {selector, #{}}. + +map_selector({selector, Handlers}, Fn) -> + MappedHandlers = maps:map(fun(_Tag, Handler) -> + fun(Message) -> Fn(Handler(Message)) end + end, Handlers), + {selector, MappedHandlers}. + +merge_selector({selector, HandlersA}, {selector, HandlersB}) -> + {selector, maps:merge(HandlersA, HandlersB)}. + +insert_selector_handler({selector, Handlers}, Tag, Fn) -> + {selector, Handlers#{Tag => Fn}}. + +select(Selector) -> + {ok, Message} = select(Selector, infinity), + Message. + +select({selector, Handlers}, Timeout) -> + AnythingHandler = maps:get(anything, Handlers, undefined), + receive + % Monitored process down messages. + % This is special cased so we can selectively receive based on the + % reference as well as the record tag. + {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> + Fn = maps:get(Ref, Handlers), + {ok, Fn({process_down, Pid, Reason})}; + + Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> + Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), + {ok, Fn(Msg)}; + + Msg when AnythingHandler =/= undefined -> + {ok, AnythingHandler(Msg)} + after Timeout -> + {error, nil} + end. + +demonitor({_, Reference}) -> + erlang:demonitor(Reference, [flush]). + +link(Pid) -> + try + erlang:link(Pid) + catch + error:_ -> false + end. + +trap_exits(ShouldTrap) -> + erlang:process_flag(trap_exit, ShouldTrap), + nil. + +flush_messages() -> + receive _Message -> flush_messages() + after 0 -> nil + end. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src new file mode 100644 index 00000000000..5e1c9b5afca --- /dev/null +++ b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src @@ -0,0 +1,8 @@ +{application, simplifile, [ + {vsn, "0.1.4"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Basic file operations that work on all targets"}, + {modules, [simplifile]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl new file mode 100644 index 00000000000..e6cacc110b1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl @@ -0,0 +1,131 @@ +-module(simplifile). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([append_bits/2, append/2, write_bits/2, write/2, read_bits/1, read/1, delete/1, is_directory/1, list_contents/1]). +-export_type([file_error/0]). + +-type file_error() :: eacces | + eagain | + ebadf | + ebadmsg | + ebusy | + edeadlk | + edeadlock | + edquot | + eexist | + efault | + efbig | + eftype | + eintr | + einval | + eio | + eisdir | + eloop | + emfile | + emlink | + emultihop | + enametoolong | + enfile | + enobufs | + enodev | + enolck | + enolink | + enoent | + enomem | + enospc | + enosr | + enostr | + enosys | + enotblk | + enotdir | + enotsup | + enxio | + eopnotsupp | + eoverflow | + eperm | + epipe | + erange | + erofs | + espipe | + esrch | + estale | + etxtbsy | + exdev | + not_utf8 | + unknown. + +-spec cast_error({ok, EXS} | {error, file_error()}) -> {ok, EXS} | + {error, file_error()}. +cast_error(Input) -> + Input. + +-spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, file_error()}. +append_bits(Bits, Filepath) -> + _pipe = gleam_erlang_ffi:append_file(Bits, Filepath), + cast_error(_pipe). + +-spec do_append(binary(), binary()) -> {ok, nil} | {error, file_error()}. +do_append(Content, Filepath) -> + _pipe = Content, + _pipe@1 = gleam@bit_string:from_string(_pipe), + gleam_erlang_ffi:append_file(_pipe@1, Filepath). + +-spec append(binary(), binary()) -> {ok, nil} | {error, file_error()}. +append(Contents, Filepath) -> + _pipe = do_append(Contents, Filepath), + cast_error(_pipe). + +-spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, file_error()}. +write_bits(Bits, Filepath) -> + _pipe = gleam_erlang_ffi:write_file(Bits, Filepath), + cast_error(_pipe). + +-spec do_write(binary(), binary()) -> {ok, nil} | {error, file_error()}. +do_write(Content, Filepath) -> + _pipe = Content, + _pipe@1 = gleam@bit_string:from_string(_pipe), + gleam_erlang_ffi:write_file(_pipe@1, Filepath). + +-spec write(binary(), binary()) -> {ok, nil} | {error, file_error()}. +write(Contents, Filepath) -> + _pipe = do_write(Contents, Filepath), + cast_error(_pipe). + +-spec read_bits(binary()) -> {ok, bitstring()} | {error, file_error()}. +read_bits(Filepath) -> + _pipe = gleam_erlang_ffi:read_file(Filepath), + cast_error(_pipe). + +-spec do_read(binary()) -> {ok, binary()} | {error, file_error()}. +do_read(Filepath) -> + case gleam_erlang_ffi:read_file(Filepath) of + {ok, Bit_str} -> + case gleam@bit_string:to_string(Bit_str) of + {ok, Str} -> + {ok, Str}; + + _ -> + {error, not_utf8} + end; + + {error, E} -> + {error, E} + end. + +-spec read(binary()) -> {ok, binary()} | {error, file_error()}. +read(Filepath) -> + _pipe = do_read(Filepath), + cast_error(_pipe). + +-spec delete(binary()) -> {ok, nil} | {error, file_error()}. +delete(Filepath) -> + _pipe = gleam_erlang_ffi:delete_file(Filepath), + cast_error(_pipe). + +-spec is_directory(binary()) -> boolean(). +is_directory(Filepath) -> + filelib:is_dir(Filepath). + +-spec list_contents(binary()) -> {ok, list(binary())} | {error, file_error()}. +list_contents(Directory) -> + gleam_erlang_ffi:list_directory(Directory). diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam new file mode 100644 index 00000000000..0a94ea185a6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam @@ -0,0 +1,359 @@ +/// This type represents all of the reasons for why a file system operation could fail. +/// +/// Most of these reasons are POSIX errors, which come from the operating system +/// and start with E. Others have been added to represent other issues that may +/// arise specific to this library. +/// +pub type FileError { + /// Permission denied. + Eacces + /// Resource temporarily unavailable. + Eagain + /// Bad file number + Ebadf + /// Bad message. + Ebadmsg + /// File busy. + Ebusy + /// Resource deadlock avoided. + Edeadlk + /// On most architectures, same as `Edeadlk`. On some architectures, it + /// means "File locking deadlock error." + Edeadlock + /// Disk quota exceeded. + Edquot + /// File already exists. + Eexist + /// Bad address in system call argument. + Efault + /// File too large. + Efbig + /// Inappropriate file type or format. Usually caused by trying to set the + /// "sticky bit" on a regular file (not a directory). + Eftype + /// Interrupted system call. + Eintr + /// Invalid argument. + Einval + /// I/O error. + Eio + /// Illegal operation on a directory. + Eisdir + /// Too many levels of symbolic links. + Eloop + /// Too many open files. + Emfile + /// Too many links. + Emlink + /// Multihop attempted. + Emultihop + /// Filename too long + Enametoolong + /// File table overflow + Enfile + /// No buffer space available. + Enobufs + /// No such device. + Enodev + /// No locks available. + Enolck + /// Link has been severed. + Enolink + /// No such file or directory. + Enoent + /// Not enough memory. + Enomem + /// No space left on device. + Enospc + /// No STREAM resources. + Enosr + /// Not a STREAM. + Enostr + /// Function not implemented. + Enosys + /// Block device required. + Enotblk + /// Not a directory. + Enotdir + /// Operation not supported. + Enotsup + /// No such device or address. + Enxio + /// Operation not supported on socket. + Eopnotsupp + /// Value too large to be stored in data type. + Eoverflow + /// Not owner. + Eperm + /// Broken pipe. + Epipe + /// Result too large. + Erange + /// Read-only file system. + Erofs + /// Invalid seek. + Espipe + /// No such process. + Esrch + /// Stale remote file handle. + Estale + /// Text file busy. + Etxtbsy + /// Cross-domain link. + Exdev + /// File was requested to be read as UTF-8, but is not UTF-8 encoded. + NotUtf8 + /// Any error not accounted for by this type + Unknown +} + +/// Read a files contents as a string +/// ## Example +/// ```gleam +/// let assert Ok(records) = read(from: "./users.csv") +/// ``` +/// ### A note about utf8 +/// Currently on the erlang target, this function expects a utf8 string +/// and returns a `NotUtf8` error if it reads a non utf8 string. +/// On the javascript target, it will read any string. +/// This behavior will probably change soon. +/// +pub fn read(from filepath: String) -> Result(String, FileError) { + do_read(filepath) + |> cast_error +} + +/// Write a string to a file at the given path +/// ## Example +/// ```gleam +/// let assert Ok(Nil) = write("Hello, World!", to: "./hello_world.txt") +/// ``` +/// +pub fn write(contents: String, to filepath: String) -> Result(Nil, FileError) { + do_write(contents, to: filepath) + |> cast_error +} + +/// Delete a file at a given filepath +/// ## Example +/// ```gleam +/// let assert Ok(Nil) = delete(file_at: "./delete_me.txt") +/// ``` +/// +pub fn delete(file_at filepath: String) -> Result(Nil, FileError) { + do_delete(filepath) + |> cast_error +} + +/// Append a string to the contents of a file at the given path +/// ## Example +/// ```gleam +/// let assert Ok(Nil) = append("more text", to: "./needs_more_text.txt") +/// ``` +/// +pub fn append(contents: String, to filepath: String) -> Result(Nil, FileError) { + do_append(contents, to: filepath) + |> cast_error +} + +/// Read a files contents as a bitstring +/// ## Example +/// ```gleam +/// let assert Ok(records) = read_bits(from: "./users.csv") +/// ``` +/// +pub fn read_bits(from filepath: String) -> Result(BitString, FileError) { + do_read_bits(filepath) + |> cast_error +} + +/// Write a bitstring to a file at the given path +/// ## Example +/// ```gleam +/// let assert Ok(Nil) = write_bits(<<"Hello, World!":utf8>>, to: "./hello_world.txt") +/// ``` +/// +pub fn write_bits( + bits: BitString, + to filepath: String, +) -> Result(Nil, FileError) { + do_write_bits(bits, filepath) + |> cast_error +} + +/// Append a bitstring to the contents of a file at the given path +/// ## Example +/// ```gleam +/// let assert Ok(Nil) = append_bits(<<"more text":utf8>>, to: "./needs_more_text.txt") +/// ``` +/// +pub fn append_bits( + bits: BitString, + to filepath: String, +) -> Result(Nil, FileError) { + do_append_bits(bits, filepath) + |> cast_error +} + +/// Checks if the provided filepath is a directory +/// ## Example +/// ```gleam +/// let assert True = is_directory("./test") +/// ``` +pub fn is_directory(filepath: String) -> Bool { + do_is_directory(filepath) +} + +/// Lists the contents of a directory. +/// The list contains directory and file names, and is not recursive. +/// +/// ## Example +/// ```gleam +/// let assert Ok(files_and_folders) = list_contents(of: "./Folder1") +/// ``` +/// +pub fn list_contents(of directory: String) -> Result(List(String), FileError) { + do_list_contents(directory) +} + +if javascript { + import gleam/result + + external fn do_read(from: String) -> Result(String, String) = + "./file.mjs" "readFile" + + external fn do_write(String, to: String) -> Result(Nil, String) = + "./file.mjs" "writeFile" + + external fn do_delete(file_at: String) -> Result(Nil, String) = + "./file.mjs" "deleteFile" + + external fn do_append(String, to: String) -> Result(Nil, String) = + "./file.mjs" "appendFile" + + external fn do_read_bits(from: String) -> Result(BitString, String) = + "./file.mjs" "readBits" + + external fn do_write_bits(BitString, to: String) -> Result(Nil, String) = + "./file.mjs" "writeBits" + + external fn do_append_bits(BitString, to: String) -> Result(Nil, String) = + "./file.mjs" "appendBits" + + external fn do_is_directory(String) -> Bool = + "./file.mjs" "isDirectory" + + external fn do_list_contents(String) -> Result(List(String), FileError) = + "./file.mjs" "listContents" + + fn cast_error(input: Result(a, String)) -> Result(a, FileError) { + result.map_error( + input, + fn(e) { + case e { + "EACCES" -> Eacces + "EAGAIN" -> Eagain + "EBADF" -> Ebadf + "EBADMSG" -> Ebadmsg + "EBUSY" -> Ebusy + "EDEADLK" -> Edeadlk + "EDEADLOCK" -> Edeadlock + "EDQUOT" -> Edquot + "EEXIST" -> Eexist + "EFAULT" -> Efault + "EFBIG" -> Efbig + "EFTYPE" -> Eftype + "EINTR" -> Eintr + "EINVAL" -> Einval + "EIO" -> Eio + "EISDIR" -> Eisdir + "ELOOP" -> Eloop + "EMFILE" -> Emfile + "EMLINK" -> Emlink + "EMULTIHOP" -> Emultihop + "ENAMETOOLONG" -> Enametoolong + "ENFILE" -> Enfile + "ENOBUFS" -> Enobufs + "ENODEV" -> Enodev + "ENOLCK" -> Enolck + "ENOLINK" -> Enolink + "ENOENT" -> Enoent + "ENOMEM" -> Enomem + "ENOSPC" -> Enospc + "ENOSR" -> Enosr + "ENOSTR" -> Enostr + "ENOSYS" -> Enosys + "ENOBLK" -> Enotblk + "ENODIR" -> Enotdir + "ENOTSUP" -> Enotsup + "ENXIO" -> Enxio + "EOPNOTSUPP" -> Eopnotsupp + "EOVERFLOW" -> Eoverflow + "EPERM" -> Eperm + "EPIPE" -> Epipe + "ERANGE" -> Erange + "EROFS" -> Erofs + "ESPIPE" -> Espipe + "ESRCH" -> Esrch + "ESTALE" -> Estale + "ETXTBSY" -> Etxtbsy + "EXDEV" -> Exdev + "NOTUTF8" -> NotUtf8 + _ -> Unknown + } + }, + ) + } +} + +if erlang { + import gleam/bit_string + + external fn do_append_bits(BitString, to: String) -> Result(Nil, FileError) = + "gleam_erlang_ffi" "append_file" + + external fn do_write_bits(BitString, to: String) -> Result(Nil, FileError) = + "gleam_erlang_ffi" "write_file" + + external fn do_read_bits(from: String) -> Result(BitString, FileError) = + "gleam_erlang_ffi" "read_file" + + external fn do_delete(String) -> Result(Nil, FileError) = + "gleam_erlang_ffi" "delete_file" + + fn do_append(content: String, to filepath: String) -> Result(Nil, FileError) { + content + |> bit_string.from_string + |> do_append_bits(filepath) + } + + fn do_write(content: String, to filepath: String) -> Result(Nil, FileError) { + content + |> bit_string.from_string + |> do_write_bits(filepath) + } + + fn do_read(from filepath: String) -> Result(String, FileError) { + case do_read_bits(filepath) { + Ok(bit_str) -> { + case bit_string.to_string(bit_str) { + Ok(str) -> Ok(str) + _ -> Error(NotUtf8) + } + } + Error(e) -> Error(e) + } + } + + fn cast_error(input: Result(a, FileError)) -> Result(a, FileError) { + input + } + + external fn do_is_directory(String) -> Bool = + "filelib" "is_dir" + + external fn do_list_contents( + directory: String, + ) -> Result(List(String), FileError) = + "gleam_erlang_ffi" "list_directory" +} diff --git a/test-community-packages-javascript/build/packages/toml/LICENSE b/test-community-packages-javascript/build/packages/toml/LICENSE new file mode 100644 index 00000000000..e1ebf2e95c4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/test-community-packages-javascript/build/packages/toml/README.md b/test-community-packages-javascript/build/packages/toml/README.md new file mode 100644 index 00000000000..8fb93a965d3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/README.md @@ -0,0 +1,338 @@ +# TOML for Elixir + +[![Main](https://github.com/bitwalker/toml-elixir/workflows/elixir/badge.svg?branch=main)](https://github.com/bitwalker/toml-elixir/actions?query=workflow%3A%22elixir%22+branch%3Amain) +[![Hex.pm Version](https://img.shields.io/hexpm/v/toml.svg?style=flat)](https://hex.pm/packages/toml) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg?style=flat)](https://hexdocs.pm/toml) +[![Total Download](https://img.shields.io/hexpm/dt/toml.svg?style=flat)](https://hex.pm/packages/toml) +[![Last Updated](https://img.shields.io/github/last-commit/bitwalker/toml-elixir.svg?style=flat)](https://github.com/bitwalker/toml-elixir/commits/main) + +This is a TOML library for Elixir projects. + +It is compliant with version 1.0 of the [official TOML specification](https://github.com/toml-lang/toml). You can find a +brief overview of the feature set below, but you are encouraged to read the full spec at the link above (it is short and easy to read!). + +## Features + +- Decode from string, file, or stream +- Fully compliant with the latest version of the TOML spec +- Is tested against [toml-test](https://github.com/BurntSushi/toml-test), a test + suite for spec-compliant TOML encoders/decoders, used by implementations in + multiple languages. The test suite has been integrated into this project to be + run under Mix so that we get better error information and so it can run as + part of the test suite. +- Decoder produces a map with values using the appropriate Elixir data types for + representation +- Supports extension via value transformers (see `Toml.Transform` docs for details) +- Supports use as a configuration provider in Distillery 2.x+ (use TOML + files for configuration!) +- Decoder is written by hand to take advantage of various optimizations. +- Library passes Dialyzer checks + +## Comparison To Other Libraries + +I compared `toml` to four other libraries: + +- `toml_elixir` +- `tomlex` +- `jerry` +- `etoml` + +Of these four, none correctly implement the 0.5.0 specification. Either they are +targeting older versions of the spec (in `etoml`, it is built against pre-0.1), +are not fully implemented (i.e. don't support all features), or have bugs which +prevent them from properly parsing a 0.5.0 example file (the +`test/fixtures/example.toml` file in this repository). + +If you are looking for a TOML library, at present `toml` is the only one which +full implements the spec and correctly decodes `example.toml`. + +## Installation + +This library is available on Hex as `:toml`, and can be added to your deps like so: + +```elixir +def deps do + [ + {:toml, "~> 0.7"} + ] +end +``` + +NOTE: You can determine the latest version on Hex by running `mix hex.info toml`. + +## Type Conversions + +In case you are curious how TOML types are translated to Elixir types, the +following table provides the conversions. + +**NOTE:** The various possible representations of each type, such as +hex/octal/binary integers, quoted/literal strings, etc., are considered to be +the same base type (e.g. integer and string respectively in the examples given). + +| TOML | Elixir | +|-------|-------| +| String | String.t (binary) | +| Integer | integer | +| inf | :infinity | +| +inf | :infinity | +| -inf | :negative_infinity | +| nan | :nan | +| +nan | :nan | +| -nan | :negative_nan | +| Boolean | boolean | +| Offset Date-Time | DateTime.t | +| Local Date-Time | NaiveDateTime.t | +| Local Date | Date.t | +| Local Time | Time.t | +| Array | list | +| Table | map | +| Table Array | list(map) | + +## Implementation-specific Behaviors + +Certain features of TOML have implementation-specific behavior: + +- `-inf`, `inf`, and `+inf` are all valid infinity values in TOML. + In Erlang/Elixir, these don't have exact representations. Instead, by convention, + `:infinity` is used for positive infinity, as atoms are always larger than integers + when using comparison operators, so `:infinity > <any integer>` will always be true. + However, negative infinity cannot be represented, as numbers are always considered smaller + than every other type in term comparisons. Instead, we represent it with `:negative_infinity`, + so that the type information is not lost, but you must be careful to deal with it specifically + in comparisons/sorting/etc. +- `-nan`, `nan`, and `+nan` are all valid NaN (not a number) values in TOML. In Erlang/Elixir, + NaN is traditionally represented with `:nan`, but there is no representation for negative NaN, + and no API actually produces `:nan`, instead invalid numbers typically raise errors, in the typical + spirit of "let it crash" in the face of errors. For purposes of preserving type information though, + we use the `:nan` convention, and `:negative_nan` for -NaN. You will need to take care to deal with + these values manually if the values need to be preserved. +- The maximum precision of times in the various time types is microseconds (i.e. precision to six decimal places), + if you provide higher precision values (i.e. nanoseconds), the extra precision will be lost. +- Hex, octal, and binary numbers are converted to integers, so serializing those values after decoding + them from a TOML document will be in their decimal representation. + +## Example Usage + +The following is a brief overview of how to use this library. First, let's take +a look at an example TOML file, as borrowed from the [TOML +homepage](https://github.com/toml-lang/toml): + +``` toml +# This is a TOML document. + +title = "TOML Example" + +[owner] +name = "Tom Preston-Werner" +dob = 1979-05-27T07:32:00-08:00 # First class dates + +[database] +server = "192.168.1.1" +ports = [ 8001, 8001, 8002 ] +connection_max = 5000 +enabled = true + +[servers] + + # Indentation (tabs and/or spaces) is allowed but not required + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + +[clients] +data = [ ["gamma", "delta"], [1, 2] ] + +# Line breaks are OK when inside arrays +hosts = [ + "alpha", + "omega" +] +``` + +### Parsing + +```elixir +iex> input = """ +[database] +server = "192.168.1.1" +""" +...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode(input) +...> {:ok, %{database: %{server: "192.168.1.1"}}} = Toml.decode(input, keys: :atoms) +...> stream = File.stream!("example.toml") +...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode_stream(stream) +...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode_file("example.toml") +...> invalid = """ +[invalid] +a = 1 b = 2 +""" +...> {:error, {:invalid_toml, reason}} = Toml.decode(invalid); IO.puts(reason) +expected '\n', but got 'b' in nofile on line 2: + + a = 1 b = 2 + ^ + +:ok +``` + +### Transforms + +Support for extending value conversions is provided by the `Toml.Transform` +behavior. An example is shown below: + +Given the following TOML document: + +``` toml +[servers.alpha] +ip = "192.168.1.1" +ports = [8080, 8081] + +[servers.beta] +ip = "192.168.1.2" +ports = [8082, 8083] +``` + +And the following modules: + +``` elixir +defmodule Server do + defstruct [:name, :ip, :ports] +end + +defmodule IPStringToCharlist do + use Toml.Transform + + def transform(:ip, v) when is_binary(v) do + String.to_charlist(v) + end + def transform(_k, v), do: v +end + +defmodule CharlistToIP do + use Toml.Transform + + def transform(:ip, v) when is_list(v) do + case :inet.parse_ipv4_address(v) do + {:ok, address} -> + address + {:error, reason} -> + {:error, {:invalid_ip_address, reason}} + end + end + def transform(:ip, v), do: {:error, {:invalid_ip_address, v}} + def transform(_k, v), do: v +end + +defmodule ServerMapToList do + use Toml.Transform + + def transform(:servers, v) when is_map(v) do + for {name, server} <- v, do: struct(Server, Map.put(server, :name, name)) + end + def transform(_k, v), do: v +end +``` + +You can convert the TOML document to a more strongly-typed version using the +above transforms like so: + +```elixir +iex> transforms = [IPStringToCharlist, CharlistToIP, ServerMapToList] +...> {:ok, result} = Toml.decode("example.toml", keys: :atoms, transforms: transforms) +%{servers: [%Server{name: :alpha, ip: {192,168,1,1}}, ports: [8080, 8081] | _]} +``` + +The transforms given here are intended to show how they can be composed: they +are applied in the order provided, and the document is transformed using a +depth-first, bottom-up traversal. Put another way, you transform the leaves of +the tree before the branches; as shown in the example above, this means the +`:ip` key is converted to an address tuple before the `:servers` key is +transformed into a list of `Server` structs. + +## Using with Elixir Releases (1.9+) + +To use this library as a configuration provider in Elixir, use the following +example of how one might use it in their release configuration, and tailor it +to your needs: + +```elixir +config_providers: [ + {Toml.Provider, [ + path: {:system, "XDG_CONFIG_DIR", "myapp.toml"}, + transforms: [...] + ]} +] +``` + +See the "Using as a Config Provider" section for more info. + +## Using with Distillery + +Like the above, use the following example as a guideline for how you use this +in your own release configuration (i.e. in `rel/config.exs`): + +``` elixir +release :myapp do + # ...snip... + set config_providers: [ + {Toml.Provider, [path: "${XDG_CONFIG_DIR}/myapp.toml", transforms: [...]]} + ] +end +``` + +## Using as a Config Provider + +The usages described above will result in `Toml.Provider` being invoked during boot, at which point it +will evaluate the given path and read the TOML file it finds. If one is not +found, or is not accessible, the provider will raise an error, and the boot +sequence will terminate unsuccessfully. If it succeeds, it persists settings in +the file to the application environment (i.e. you access it via +`Application.get_env/2`). + +You can pass the same options in the arguments list for `Toml.Provider` as you +can to `Toml.decode/2`, but `:path` is required, and `:keys` only supports +`:atoms` and `:atoms!` values. + +The config provider expects a certain format to the TOML file, namely that keys +at the root of the document correspond to applications which need to be configured. +If it encounters keys at the root of the document which are not tables, they are ignored. + +``` toml +# This is an example of something that would be ignored +title = "My config file" + +# We're expecting something like this: +[myapp] +key = "value" + +# To use a bit of Phoenix config, you translate to TOML like so: +[myapp."MyApp.Endpoint"] +cache_static_manifest = "priv/static/cache_manifest.json" + +[myapp."MyApp.Endpoint".http] +port = "4000" + +[myapp."MyApp.Endpoint".force_ssl] +hsts = true + +# Or logger.. +[logger] +level = "info" + +[logger.console] +format = "[$level] $message \n" +``` + +## Roadmap + +- [x] Add benchmarking suite +- [x] Provide options for converting keys to atom, similar to Jason/Poison/etc. +- [ ] Optimize lexer to always send offsets to decoder, rather than only in some cases +- [ ] Try to find pathological TOML files to test + +## License + +This project is licensed Apache 2.0, see the `LICENSE` file in this repo for details. diff --git a/test-community-packages-javascript/build/packages/toml/lib/builder.ex b/test-community-packages-javascript/build/packages/toml/lib/builder.ex new file mode 100644 index 00000000000..8491af59817 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/builder.ex @@ -0,0 +1,413 @@ +defmodule Toml.Builder do + @moduledoc false + + @compile inline: [key: 3, keys: 2, comment: 2, open: 2, close: 1, to_result: 1] + + # Builds a Document, performing validation along the way + + alias Toml.Document + + @doc """ + Creates a new empty TOML document to build with. + """ + defdelegate new(opts), to: Document + + @doc """ + Starts a new table and sets the context for subsequent key/values + """ + def push_table(%Document{} = doc, keypath) do + with {:ok, doc} = push_key(%Document{doc | open_table: nil}, keypath, {:table_decl, %{}}) do + # We're explicitly opening a new table + doc |> open(keypath) |> to_result() + end + end + + @doc """ + Starts a new array of tables and sets the context for subsequent key/values + """ + def push_table_array(%Document{} = doc, keypath) do + with {:ok, doc} = push_key(%Document{doc | open_table: nil}, keypath, {:table_array, []}) do + # We're explicitly opening a new table + doc |> open(keypath) |> to_result() + end + end + + @doc """ + Push a comment on a stack containing lines of comments applying to some element. + Comments are collected and assigned to key paths when a key is set, table created, etc. + """ + def push_comment(%Document{comment_stack: cs} = doc, comment) do + %Document{doc | comment_stack: [comment | cs]} + end + + @doc """ + Push a value for a key into the TOML document. + + This operation is used when any key/value pair is set, and table or table array is defined. + + Based on the key the type of the value provided, the behavior of this function varies, as validation + as performed as part of setting the key, to ensure that redefining keys is prohibited, but that setting + child keys of existing tables is allowed. Table arrays considerably complicate this unfortunately. + """ + def push_key(%Document{keys: ks} = doc, [key], value) + when is_map(value) and map_size(value) == 0 + when is_tuple(value) and elem(value, 0) == :table_decl do + # New table + keypath = [key] + + case Map.get(ks, key) do + nil -> + doc + |> key(key, %{}) + |> comment(keypath) + |> open(keypath) + |> to_result() + + exists when is_map(exists) -> + cond do + map_size(exists) == 0 -> + # Redefinition + key_exists!(keypath) + + Enum.all?(exists, fn + {_, v} when is_map(v) -> true + _ -> false + end) -> + # All keys are sub-tables, we'll allow this + doc + |> comment(keypath) + |> open(keypath) + |> to_result() + + :else -> + {k, _} = Enum.find(exists, fn {_, v} -> not is_map(v) end) + key_exists!(keypath ++ [k]) + end + + _exists -> + key_exists!(keypath) + end + end + + def push_key(%Document{keys: ks} = doc, [key], value) when is_map(value) do + # Pushing an inline table + keypath = + case doc.open_table do + nil -> + [key] + + opened -> + opened ++ [key] + end + + case push_key_into_table(ks, keypath, value) do + {:ok, ks} -> + doc + |> keys(ks) + |> comment(keypath) + |> to_result() + + {:error, :key_exists} -> + key_exists!(keypath) + end + end + + def push_key(%Document{keys: ks} = doc, [key], {:table_array, _} = value) do + keypath = [key] + + case push_key_into_table(ks, [key], value) do + {:ok, ks} -> + doc + |> keys(ks) + |> comment(keypath) + |> close() + |> to_result() + + {:error, :key_exists} -> + key_exists!(keypath) + end + end + + def push_key(%Document{keys: ks, open_table: nil} = doc, [key], value) do + # Pushing a key/value pair at the root level of the document + keypath = [key] + + if Map.has_key?(ks, key) do + key_exists!(keypath) + end + + doc + |> key(key, value) + |> comment(keypath) + |> close() + |> to_result() + end + + def push_key(%Document{keys: ks, open_table: opened} = doc, [key], value) do + # Pushing a key/value pair when a table is open + keypath = opened ++ [key] + + case push_key_into_table(ks, keypath, value) do + {:ok, ks} -> + doc + |> keys(ks) + |> comment(keypath) + |> to_result() + + {:error, :key_exists} -> + key_exists!(keypath) + end + end + + def push_key(%Document{keys: ks} = doc, keypath, value) + when is_list(keypath) and is_map(value) + when is_list(keypath) and is_tuple(value) and elem(value, 0) == :table_decl do + # Pushing a multi-part key with a table value + keypath = + case doc.open_table do + nil -> + keypath + + opened -> + opened ++ keypath + end + + case push_key_into_table(ks, keypath, value) do + {:ok, ks} -> + doc + |> keys(ks) + |> comment(keypath) + |> to_result() + + {:error, :key_exists} -> + key_exists!(keypath) + end + end + + def push_key(%Document{keys: ks} = doc, keypath, value) when is_list(keypath) do + # Pushing a multi-part key with a plain value + keypath = + case doc.open_table do + nil -> + keypath + + opened -> + opened ++ keypath + end + + case push_key_into_table(ks, keypath, value) do + {:ok, ks} -> + doc + |> keys(ks) + |> comment(keypath) + |> to_result() + + {:error, :key_exists} -> + key_exists!(keypath) + end + end + + # Handles pushing a value into a map, arbitrarily deep, and respecting + # the desired behavior of table arrays. Can be used with any map. + # + # NOTE: This is similar to `put_in/3`, but does not raise if a key does + # exist, instead it creates a new table (map) at the level needed, and continues + # pushing the key into this new table + @doc false + def push_key_into_table({:table_array, array}, [key], {:table_array, _} = value) do + case array do + [] -> + {:ok, {:table_array, [Map.put(%{}, key, value)]}} + + [h | t] when is_map(h) -> + case Map.get(h, key) do + nil -> + {:ok, {:table_array, [Map.put(h, key, value) | t]}} + + {:table_array, items} -> + {:ok, {:table_array, [Map.put(h, key, {:table_array, [%{} | items]}) | t]}} + + _ -> + {:error, :key_exists} + end + end + end + + def push_key_into_table({:table_array, array}, keypath, {:table_decl, value}) do + case array do + [] -> + {:ok, {:table_array, [value]}} + + [h | t] when is_map(h) -> + case push_key_into_table(h, keypath, {:table_decl, value}) do + {:ok, h2} -> + {:ok, {:table_array, [h2 | t]}} + + {:error, _} = err -> + err + end + end + end + + def push_key_into_table({:table_array, array}, keypath, value) when is_map(value) do + case array do + [] -> + {:ok, {:table_array, [value]}} + + [h | t] when is_map(h) -> + case push_key_into_table(h, keypath, value) do + {:ok, h2} -> + {:ok, {:table_array, [h2 | t]}} + + {:error, _} = err -> + err + end + end + end + + def push_key_into_table({:table_array, array}, keypath, value) do + # Adding key/value to last table item + case array do + [] -> + case push_key_into_table(%{}, keypath, value) do + {:ok, item} -> + {:ok, {:table_array, [item]}} + + {:error, _} = err -> + err + end + + [h | t] when is_map(h) -> + case push_key_into_table(h, keypath, value) do + {:ok, h2} -> + {:ok, {:table_array, [h2 | t]}} + + {:error, _} = err -> + err + end + end + end + + def push_key_into_table(ts, [key], {:table_decl, value}) do + case Map.get(ts, key) do + nil -> + {:ok, Map.put(ts, key, value)} + + exists when is_map(exists) -> + # We're reopening a table, but we allow it as long as keys + # in that table don't override previously defined keys + {:ok, ts} + + _exists -> + {:error, :key_exists} + end + end + + def push_key_into_table(ts, [key], value) when is_map(ts) do + # Reached final table + case Map.get(ts, key) do + nil -> + {:ok, Map.put(ts, key, value)} + + {:table_array, items} + when is_list(items) and is_tuple(value) and elem(value, 0) == :table_array -> + # Appending to table array + {:ok, Map.put(ts, key, {:table_array, [%{} | items]})} + + {:table_array, items} when is_list(items) and is_map(value) -> + # Pushing into table array + {:ok, Map.put(ts, key, {:table_array, [value | items]})} + + exists when is_map(exists) and is_map(value) and map_size(value) > 0 -> + result = + Enum.reduce(value, exists, fn {k, v}, acc -> + case push_key_into_table(acc, [k], v) do + {:ok, acc2} -> + acc2 + + {:error, _} = err -> + throw(err) + end + end) + + {:ok, result} + + _exists -> + {:error, :key_exists} + end + catch + :throw, {:error, _} = err -> + err + end + + def push_key_into_table(ts, _keypath, _value) when not is_map(ts) do + # The table we're trying to push into is not itself a table, this is redefinition! + {:error, :key_exists} + end + + def push_key_into_table(ts, [table | keypath], value) when is_map(ts) do + result = + case Map.get(ts, table) do + nil -> + push_key_into_table(%{}, keypath, value) + + child -> + push_key_into_table(child, keypath, value) + end + + case result do + {:ok, child} -> + {:ok, Map.put(ts, table, child)} + + {:error, _} = err -> + err + end + end + + # Raised if the given keypath has already been defined + # and the value being set at that keypath is not an inline + # table (effectively extending the keypath and pushing multiple values), + # or table array (resulting in a new table being pushed into that array) + @spec key_exists!([binary]) :: no_return + defp key_exists!(keypath), + do: error!({:key_exists, Enum.join(keypath, ".")}) + + # Raised due to any other document builder error + @spec error!([binary]) :: no_return + defp error!(reason), + do: throw({:error, {:invalid_toml, reason}}) + + # Set a key at the document root + defp key(%Document{keys: keys} = doc, key, value), + do: %Document{doc | keys: Map.put(keys, key, value)} + + # Replace the set of keys in the document + defp keys(%Document{} = doc, keys), + do: %Document{doc | keys: keys} + + # Comment the given key, if comments are available on the stack + defp comment(%Document{comments: cs, comment_stack: stack} = doc, key) do + comment = + stack + |> Enum.reverse() + |> Enum.join("\n") + + if byte_size(comment) > 0 do + %Document{doc | comment_stack: [], comments: Map.put(cs, key, comment)} + else + %Document{doc | comment_stack: []} + end + end + + # Open a table at the given key + defp open(%Document{} = doc, key), + do: %Document{doc | open_table: key} + + # Close any open table + defp close(%Document{} = doc), + do: %Document{doc | open_table: nil} + + # Wrap the document in a ok tuple + defp to_result(%Document{} = doc), + do: {:ok, doc} +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/decoder.ex b/test-community-packages-javascript/build/packages/toml/lib/decoder.ex new file mode 100644 index 00000000000..ac0801adab1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/decoder.ex @@ -0,0 +1,1055 @@ +defmodule Toml.Decoder do + @moduledoc false + + alias Toml.Document + alias Toml.Builder + alias Toml.Lexer + + @compile :inline_list_funs + @compile inline: [ + pop_skip: 2, + peek_skip: 2, + iodata_to_str: 1, + iodata_to_integer: 1, + iodata_to_float: 1 + ] + + @doc """ + Decodes a raw binary into a map. + + `Toml.Error` is raised if decoding fails. + """ + @spec decode!(binary, Toml.opts()) :: map | no_return + def decode!(bin, opts) when is_binary(bin) and is_list(opts) do + # Raise if the filename is invalid + filename = + case Keyword.get(opts, :filename, "nofile") do + name when is_binary(name) -> + name + + n -> + raise ArgumentError, "invalid :filename option '#{inspect(n)}', must be a binary!" + end + + # Get our lexer outside the try so that we can stop it if things go south + # This can only fail if the lexer process itself crashes during init + {:ok, lexer} = Lexer.new(bin) + + try do + case do_decode(lexer, bin, Builder.new(opts)) do + {:ok, doc} -> + case Document.to_map(doc) do + {:ok, result} -> + result + + {:error, reason} -> + raise Toml.Error, reason + end + + {:error, reason, skip, lines} -> + raise Toml.Error, format_error(reason, bin, filename, skip, lines) + end + catch + :throw, {:error, {:invalid_toml, reason}} -> + raise Toml.Error, reason + + :throw, {:badarg, {option, value, valid}} -> + raise Toml.Error, {:badarg, option, value, valid} + after + Lexer.stop(lexer) + end + end + + @doc """ + Decodes a raw binary safely, returns `{:ok, map}` or `{:error, reason}` + """ + @spec decode(binary, Toml.opts()) :: {:ok, map} | Toml.error() + def decode(bin, opts) when is_binary(bin) and is_list(opts) do + {:ok, decode!(bin, opts)} + rescue + err in [Toml.Error] -> + {:error, {:invalid_toml, Exception.message(err)}} + + err in [ArgumentError] -> + {:error, err.message} + catch + :error, reason -> + {:error, Toml.Error.format_reason(reason)} + end + + @doc """ + Decodes a stream. + + Raises `Toml.Error` if decoding fails. + """ + @spec decode_stream!(Enumerable.t(), Toml.opts()) :: map | no_return + def decode_stream!(stream, opts) do + decode!(Enum.into(stream, <<>>), opts) + end + + @doc """ + Decodes a stream safely. + + Returns same type as `decode/2` + """ + @spec decode_stream(Enumerable.t(), Toml.opts()) :: {:ok, map} | Toml.error() + def decode_stream(stream, opts) do + decode(Enum.into(stream, <<>>), opts) + end + + @doc """ + Decodes a file. + + Raises `Toml.Error` if decoding fails. + """ + @spec decode_file!(String.t(), Toml.opts()) :: map | no_return + def decode_file!(path, opts) when is_binary(path) do + with {:ok, opts} <- set_filename_opt(opts, path), + bin = File.read!(path) do + decode!(bin, opts) + end + end + + @doc """ + Decodes a file safely. + + Returns same type as `decode/2` + """ + @spec decode_file(String.t(), Toml.opts()) :: {:ok, map} | Toml.error() + def decode_file(path, opts) when is_binary(path) do + with {:ok, opts} <- set_filename_opt(opts, path), + {:ok, bin} <- File.read(path) do + decode(bin, opts) + else + {:error, reason} -> + {:error, "unable to open file '#{Path.relative_to_cwd(path)}': #{inspect(reason)}"} + end + end + + defp set_filename_opt(opts, default) do + case Keyword.get(opts, :filename) do + nil -> + {:ok, Keyword.put(opts, :filename, default)} + + _name -> + {:ok, opts} + end + end + + ## Decoder Implementation + + @spec do_decode(Lexer.t(), binary, Document.t()) :: {:ok, Document.t()} | Lexer.lexer_err() + defp do_decode(lexer, original, %Document{} = doc) do + with {:ok, {type, skip, data, lines}} <- Lexer.pop(lexer) do + handle_token(lexer, original, doc, type, skip, data, lines) + end + end + + # Converts an error into a friendly, printable representation + defp format_error(reason, original, filename, skip, lines) do + msg = + "#{Toml.Error.format_reason(reason)} in #{Path.relative_to_cwd(filename)} on line #{lines}" + + {ctx, pos} = seek_line(original, skip - 1, lines) + + """ + #{msg}: + + #{ctx} + #{String.duplicate(" ", pos)}^ at column #{pos} + """ + end + + # Finds the line of context for display in a formatted error + defp seek_line(original, skip, lines) do + seek_line(original, original, 0, 0, skip, lines - 1) + end + + defp seek_line(original, rest, lastnl, from, len, 0) do + case seek_to_eol(rest, 0) do + 0 -> + {binary_part(original, lastnl, from - lastnl), from - lastnl} + + len_to_eol when len_to_eol > 0 -> + {binary_part(original, from, len_to_eol), len} + end + end + + defp seek_line(original, <<?\r, ?\n, rest::binary>>, lastnl, from, len, 1) when len <= 0 do + # Content occurred on the last line right before the newline + seek_line(original, rest, lastnl, from + 2, 0, 0) + end + + defp seek_line(original, <<?\r, ?\n, rest::binary>>, _, from, len, lines) do + seek_line(original, rest, from + 2, from + 2, len - 2, lines - 1) + end + + defp seek_line(original, <<?\n, rest::binary>>, lastnl, from, len, 1) when len <= 0 do + # Content occurred on the last line right before the newline + seek_line(original, rest, lastnl, from + 1, 0, 0) + end + + defp seek_line(original, <<?\n, rest::binary>>, _, from, len, lines) do + seek_line(original, rest, from + 1, from + 1, len - 1, lines - 1) + end + + defp seek_line(original, <<_::utf8, rest::binary>>, lastnl, from, len, lines) do + seek_line(original, rest, lastnl, from + 1, len - 1, lines) + end + + # Find the number of bytes to the end of the current line in the input + defp seek_to_eol(<<>>, len), do: len + defp seek_to_eol(<<?\r, ?\n, _::binary>>, len), do: len + defp seek_to_eol(<<?\n, _::binary>>, len), do: len + + defp seek_to_eol(<<_::utf8, rest::binary>>, len) do + seek_to_eol(rest, len + 1) + end + + # Handles invalid byte sequences (i.e. invalid unicode) + # Considers the invalid byte as EOL so context can still be shown + defp seek_to_eol(<<_, _rest::binary>>, len), do: len + + # Skip top-level whitespace and newlines + @spec handle_token( + Lexer.t(), + binary, + Document.t(), + Lexer.type(), + Lexer.skip(), + binary | non_neg_integer, + Lexer.lines() + ) :: {:ok, Document.t()} | Lexer.lexer_err() + defp handle_token(lexer, original, doc, :whitespace, _skip, _data, _lines), + do: do_decode(lexer, original, doc) + + defp handle_token(lexer, original, doc, :newline, _skip, _data, _lines), + do: do_decode(lexer, original, doc) + + # Push comments on the comment stack + defp handle_token(lexer, original, doc, :comment, skip, size, _lines) do + comment = binary_part(original, skip - size, size) + do_decode(lexer, original, Builder.push_comment(doc, comment)) + end + + # Handle valid top-level entities + # - array of tables + # - table + # - key/value + defp handle_token(lexer, original, doc, ?\[, skip, data, lines) do + case peek_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {?\[, _, _, _}} -> + # Push opening bracket, second was peeked, so no need + Lexer.push(lexer, {?\[, skip, data, lines}) + handle_table_array(lexer, original, doc) + + {:ok, {_, _, _, _}} -> + Lexer.push(lexer, {?\[, skip, data, lines}) + handle_table(lexer, original, doc) + end + end + + defp handle_token(lexer, original, doc, type, skip, data, lines) + when type in [:digits, :alpha, :string] do + Lexer.push(lexer, {type, skip, data, lines}) + + with {:ok, key, _skip, _lines} <- key(lexer) do + handle_key(lexer, original, doc, key) + end + end + + defp handle_token(lexer, original, doc, type, skip, _data, lines) when type in '-_' do + handle_token(lexer, original, doc, :string, skip, <<type::utf8>>, lines) + end + + # We're done + defp handle_token(_lexer, _original, doc, :eof, _skip, _data, _lines) do + {:ok, doc} + end + + # Anything else at top-level is invalid + defp handle_token(_lexer, _original, _doc, type, skip, data, lines) do + {:error, {:invalid_token, {type, data}}, skip, lines} + end + + defp handle_key(lexer, original, doc, key) do + with {:ok, {?=, _, _, _}} <- pop_skip(lexer, [:whitespace]), + {:ok, value} <- value(lexer), + {:ok, doc} <- Builder.push_key(doc, key, value) do + # Make sure key/value pairs are separated by a newline + case peek_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {:comment, _, _, _}} -> + # Implies newline + do_decode(lexer, original, doc) + + {:ok, {type, _, _, _}} when type in [:newline, :eof] -> + do_decode(lexer, original, doc) + + {:ok, {type, skip, data, lines}} -> + {:error, {:expected, :newline, {type, data}}, skip, lines} + end + else + {:error, _, _, _} = err -> + err + + {:ok, {type, skip, data, lines}} -> + {:error, {:expected, ?=, {type, data}}, skip, lines} + end + end + + defp handle_table(lexer, original, doc) do + # Guaranteed to have an open bracket + with {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), + {:ok, key, _line, _col} <- key(lexer), + {:ok, {?\], _, _, _}} <- pop_skip(lexer, [:whitespace]), + {:ok, doc} <- Builder.push_table(doc, key) do + # Make sure table opening is followed by newline + case peek_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {:comment, _, _, _}} -> + do_decode(lexer, original, doc) + + {:ok, {type, _, _, _}} when type in [:newline, :eof] -> + do_decode(lexer, original, doc) + + {:ok, {type, skip, data, lines}} -> + {:error, {:expected, :newline, {type, data}}, skip, lines} + end + else + {:error, _, _, _} = err -> + err + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + end + + defp handle_table_array(lexer, original, doc) do + # Guaranteed to have two open brackets + with {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), + {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), + {:ok, key, _, _} <- key(lexer), + {_, {:ok, {?\], _, _, _}}} <- {:close, pop_skip(lexer, [:whitespace])}, + {_, {:ok, {?\], _, _, _}}} <- {:close, pop_skip(lexer, [:whitespace])}, + {:ok, doc} <- Builder.push_table_array(doc, key) do + # Make sure table opening is followed by newline + case peek_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {:comment, _, _, _}} -> + do_decode(lexer, original, doc) + + {:ok, {type, _, _, _}} when type in [:newline, :eof] -> + do_decode(lexer, original, doc) + + {:ok, {type, skip, data, lines}} -> + {:error, {:expected, :newline, {type, data}}, skip, lines} + end + else + {:error, _, _, _} = err -> + err + + {_, {:error, _, _, _} = err} -> + err + + {:close, {:ok, {type, skip, data, lines}}} -> + {:error, {:unclosed_table_array_name, {type, data}}, skip, lines} + end + end + + defp maybe_integer(lexer) do + case pop_skip(lexer, [:whitespace]) do + {:ok, {type, _skip, _data, _lines}} when type in '-+' -> + # Can be integer, float + case Lexer.peek(lexer) do + {:error, _, _, _} = err -> + err + + # Handle infinity/nan with leading sign + {:ok, {:alpha, _, "inf", _}} -> + Lexer.advance(lexer) + + if type == ?\+ do + {:ok, :infinity} + else + {:ok, :negative_infinity} + end + + {:ok, {:alpha, _, "nan", _}} -> + Lexer.advance(lexer) + + if type == ?\+ do + {:ok, :nan} + else + {:ok, :negative_nan} + end + + # Must be a signed integer or float + {:ok, {:digits, _, d, _}} -> + Lexer.advance(lexer) + maybe_integer(lexer, [d, type]) + + # Invalid + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + + {:ok, {:digits, skip, <<leader::utf8, _::utf8, _::utf8, _::utf8>> = d, lines} = token} -> + # Could be a datetime + case Lexer.peek(lexer) do + {:ok, {?-, _, _, _}} -> + # This is a date or datetime + Lexer.push(lexer, token) + maybe_datetime(lexer) + + {:ok, {?., _, _, _}} -> + # Float + Lexer.advance(lexer) + float(lexer, ?., [?., d]) + + {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' -> + # Float + Lexer.advance(lexer) + float(lexer, ?e, [?e, ?0, ?., d]) + + {:ok, {?_, _, _, _}} -> + # Integer + maybe_integer(lexer, [d]) + + _ -> + # Just an integer + if leader == ?0 do + # Leading zeroes not allowed + {:error, {:invalid_integer, :leading_zero}, skip, lines} + else + {:ok, String.to_integer(d)} + end + end + + {:ok, {:digits, skip, <<leader::utf8, _::utf8>> = d, lines} = token} -> + # Could be a time + case Lexer.peek(lexer) do + {:ok, {?:, _, _, _}} -> + # This is a local time + Lexer.push(lexer, token) + time(lexer) + + _ -> + # It's just an integer + if leader == ?0 do + # Leading zeros not allowed + {:error, {:invalid_integer, :leading_zero}, skip, lines} + else + maybe_integer(lexer, [d]) + end + end + + {:ok, {:digits, _, d, _}} -> + # Just a integer or float + maybe_integer(lexer, [d]) + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + end + + defp maybe_integer(lexer, parts) do + case Lexer.pop(lexer) do + {:error, _, _, _} = err -> + err + + {:ok, {?., _, _, _}} -> + # Float + float(lexer, ?., [?. | parts]) + + {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' -> + # Float, need to add .0 before e, or String.to_float fails + float(lexer, ?e, [?e, ?0, ?. | parts]) + + {:ok, {?_, _, _, _}} -> + case Lexer.peek(lexer) do + {:ok, {:digits, _, d, _}} -> + # Allowed, just skip the underscore + Lexer.advance(lexer) + maybe_integer(lexer, [d | parts]) + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + + {:error, _, _, _} = err -> + err + end + + {:ok, {_, skip, _, lines} = token} -> + # Just an integer + Lexer.push(lexer, token) + + with {:ok, _} = result <- iodata_to_integer(parts) do + result + else + {:error, reason} -> + {:error, reason, skip, lines} + end + end + end + + defp float(lexer, signal, [last | _] = parts) do + case Lexer.pop(lexer) do + {:error, _, _, _} = err -> + err + + {:ok, {?., skip, _, lines}} -> + # Always an error at this point, as either duplicate or after E + {:error, {:invalid_float, {?., 0}}, skip, lines} + + {:ok, {sign, _, _, _}} when sign in '-+' and last == ?e -> + # +/- are allowed after e/E + float(lexer, signal, [sign | parts]) + + {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' and signal == ?. -> + # Valid if after a dot + float(lexer, ?e, [?e | parts]) + + {:ok, {?_, skip, _, lines}} when last not in '_e.' -> + # Valid only when surrounded by digits + with {:ok, {:digits, _, d, _}} <- Lexer.peek(lexer), + _ = Lexer.advance(lexer) do + float(lexer, signal, [d | parts]) + else + {:error, _, _, _} = err -> + err + + {:ok, {_, _, _, _}} -> + {:error, {:invalid_float, {?_, 0}}, skip, lines} + end + + {:ok, {:digits, _, d, _}} -> + float(lexer, signal, [d | parts]) + + {:ok, {type, skip, data, lines}} when last in 'e.' -> + # Incomplete float + {:error, {:invalid_float, {type, data}}, skip, lines} + + {:ok, {_type, skip, _data, lines} = token} when last not in '_e.' -> + # Done + Lexer.push(lexer, token) + + with {:ok, _} = result <- iodata_to_float(parts) do + result + else + {:error, reason} -> + {:error, reason, skip, lines} + end + end + end + + defp time(lexer) do + # At this point we know we have at least HH: + with {:ok, {:digits, skip, <<_::utf8, _::utf8>> = hh, lines}} <- Lexer.pop(lexer), + {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), + {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer), + {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), + {:ok, {:digits, _, <<_::utf8, _::utf8>> = ss, _}} <- Lexer.pop(lexer) do + # Check for fractional + parts = [ss, ?:, mm, ?:, hh] + + parts = + case Lexer.peek(lexer) do + {:ok, {?., _, _, _}} -> + Lexer.advance(lexer) + + case Lexer.pop(lexer) do + {:ok, {:digits, _, d, _}} -> + [d, ?. | parts] + + {:ok, {type, skip, data, lines}} -> + # Invalid + throw({:error, {:invalid_token, {type, data}}, skip, lines}) + + {:error, reason, skip, lines} -> + throw({:error, {:invalid_fractional_seconds, reason}, skip, lines}) + end + + {:ok, _} -> + parts + end + + case Time.from_iso8601(iodata_to_str(parts)) do + {:ok, _} = result -> + result + + {:error, :invalid_time} -> + {:error, :invalid_time, skip, lines} + + {:error, reason} -> + {:error, {:invalid_time, reason}, skip, lines} + end + else + {:error, _, _, _} = err -> + err + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + catch + :throw, {:error, _, _, _} = err -> + err + end + + defp maybe_datetime(lexer) do + # At this point we have at least YYYY- + with {:ok, {:digits, _, <<_::utf8, _::utf8, _::utf8, _::utf8>> = yy, _}} <- Lexer.pop(lexer), + {:ok, {?-, _, _, _}} <- Lexer.pop(lexer), + {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer), + {:ok, {?-, _, _, _}} <- Lexer.pop(lexer), + {:ok, {:digits, skip, <<_::utf8, _::utf8>> = dd, lines}} <- Lexer.pop(lexer) do + # At this point we have a full date, check for time + case Lexer.pop(lexer) do + {:ok, {:alpha, _, "T", _}} -> + # Expecting a time + with {:ok, time} <- time(lexer) do + datetime(lexer, [dd, ?-, mm, ?-, yy], time) + end + + {:ok, {:whitespace, _, _, _}} -> + case Lexer.peek(lexer) do + {:ok, {:digits, _, <<_::utf8, _::utf8>>, _}} -> + # Expecting a time + with {:ok, time} <- time(lexer) do + datetime(lexer, [dd, ?-, mm, ?-, yy], time) + end + + _ -> + # Just a date + case Date.from_iso8601(iodata_to_str([dd, ?-, mm, ?-, yy])) do + {:ok, _} = result -> + result + + {:error, :invalid_date} -> + {:error, :invalid_date, skip, lines} + + {:error, reason} -> + {:error, {:invalid_date, reason}, skip, lines} + end + end + + {:ok, {_type, skip, _data, lines} = token} -> + # Just a date + Lexer.push(lexer, token) + + case Date.from_iso8601(iodata_to_str([dd, ?-, mm, ?-, yy])) do + {:ok, _} = result -> + result + + {:error, :invalid_date} -> + {:error, :invalid_date, skip, lines} + + {:error, reason} -> + {:error, {:invalid_date, reason}, skip, lines} + end + end + else + {:error, _, _, _} = err -> + err + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + end + + defp datetime(lexer, parts, time) do + # Track the current lexer position for errors + {:ok, skip, lines} = Lexer.pos(lexer) + # Convert parts to string + datestr = iodata_to_str(parts) + # At this point we have at least YYYY-mm-dd and a fully decoded time + with {_, {:ok, date}} <- {:date, Date.from_iso8601(datestr)}, + {_, {:ok, naive}} <- {:datetime, NaiveDateTime.new(date, time)} do + # We just need to check for Z or UTC offset + case Lexer.pop(lexer) do + {:ok, {:alpha, _, "Z", _}} -> + DateTime.from_naive(naive, "Etc/UTC") + + {:ok, {sign, _, _, _}} when sign in '-+' -> + # We have an offset + with {:ok, {:digits, _, <<_::utf8, _::utf8>> = hh, _}} <- Lexer.pop(lexer), + {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), + {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer) do + # Shift naive to account for offset + hours = String.to_integer(hh) + mins = String.to_integer(mm) + offset = hours * 60 * 60 + mins * 60 + + naive = + case sign do + ?- -> + NaiveDateTime.add(naive, offset * -1, :second) + + ?+ -> + NaiveDateTime.add(naive, offset, :second) + end + + DateTime.from_naive(naive, "Etc/UTC") + else + {:error, _, _, _} = err -> + err + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_datetime_offset, {type, data}}, skip, lines} + end + + {:ok, {type, _, _, _} = token} when type in [:eof, :whitespace, :newline] -> + # Just a local date/time + Lexer.push(lexer, token) + {:ok, naive} + end + else + {:date, {:error, :invalid_date}} -> + {:error, {:invalid_date, datestr}, skip, lines} + + {:date, {:error, reason}} -> + {:error, {:invalid_date, reason, datestr}, skip, lines} + + {:datetime, {:error, :invalid_date}} -> + {:error, {:invalid_datetime, {datestr, time}}, skip, lines} + + {:datetime, {:error, reason}} -> + {:error, {:invalid_date, reason, {datestr, time}}, skip, lines} + + {:error, _, _, _} = err -> + err + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + end + + # Allowed values + # - Array + # - Inline table + # - Integer (in all forms) + # - Float + # - String + # - DateTime + defp value(lexer) do + case peek_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {:comment, _, _, _}} -> + Lexer.advance(lexer) + value(lexer) + + {:ok, {?\[, _skip, _, _lines}} -> + # Need to embellish some errors with line/col + with {:ok, _} = ok <- array(lexer) do + ok + else + {:error, _, _, _} = err -> + err + end + + {:ok, {?\{, _, _, _}} -> + inline_table(lexer) + + {:ok, {:hex, _, v, _}} -> + Lexer.advance(lexer) + {:ok, String.to_integer(v, 16)} + + {:ok, {:octal, _, v, _}} -> + Lexer.advance(lexer) + {:ok, String.to_integer(v, 8)} + + {:ok, {:binary, _, v, _}} -> + Lexer.advance(lexer) + {:ok, String.to_integer(v, 2)} + + {:ok, {true, _, _, _}} -> + Lexer.advance(lexer) + {:ok, true} + + {:ok, {false, _, _, _}} -> + Lexer.advance(lexer) + {:ok, false} + + {:ok, {:alpha, _, "inf", _}} -> + Lexer.advance(lexer) + {:ok, :infinity} + + {:ok, {:alpha, _, "nan", _}} -> + Lexer.advance(lexer) + {:ok, :nan} + + {:ok, {type, _, v, _}} when type in [:string, :multiline_string] -> + Lexer.advance(lexer) + {:ok, v} + + {:ok, {sign, _, _, _}} when sign in '-+' -> + maybe_integer(lexer) + + {:ok, {:digits, _, _, _}} -> + maybe_integer(lexer) + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + end + + defp array(lexer) do + with {:ok, {?\[, skip, _, lines}} <- pop_skip(lexer, [:whitespace]), + {:ok, elements} <- accumulate_array_elements(lexer), + {_, _, {:ok, {?\], _, _, _}}} <- + {:close, {skip, lines}, pop_skip(lexer, [:whitespace, :newline, :comment])} do + {:ok, elements} + else + {:error, _, _, _} = err -> + err + + {:close, {:error, _, _, _} = err} -> + err + + {:close, {_oline, _ocol} = opened, {:ok, {_, eskip, _, elines}}} -> + {:error, {:unclosed_array, opened}, eskip, elines} + + {:valid?, err} -> + err + end + end + + defp inline_table(lexer) do + with {:ok, {?\{, skip, _, lines}} <- pop_skip(lexer, [:whitespace]), + {:ok, elements} <- accumulate_table_elements(lexer), + {_, _, {:ok, {?\}, _, _, _}}} <- {:close, {skip, lines}, pop_skip(lexer, [:whitespace])} do + {:ok, elements} + else + {:error, _, _, _} = err -> + err + + {:close, {:error, _, _, _} = err} -> + err + + {:close, {_oskip, _olines} = opened, {:ok, {_, eskip, _, elines}}} -> + {:error, {:unclosed_inline_table, opened}, eskip, elines} + end + end + + defp accumulate_array_elements(lexer) do + accumulate_array_elements(lexer, []) + end + + defp accumulate_array_elements(lexer, acc) do + with {:ok, {type, _, _, _}} <- peek_skip(lexer, [:whitespace, :newline, :comment]), + {_, false} <- {:trailing_comma, type == ?\]}, + {:ok, value} <- value(lexer), + {:ok, {next, _, _, _}} <- peek_skip(lexer, [:whitespace]) do + if next == ?, do + Lexer.advance(lexer) + accumulate_array_elements(lexer, [value | acc]) + else + {:ok, Enum.reverse([value | acc])} + end + else + {:error, _, _, _} = err -> + err + + {:trailing_comma, true} -> + {:ok, Enum.reverse(acc)} + end + end + + defp accumulate_table_elements(lexer) do + accumulate_table_elements(lexer, %{}) + end + + defp accumulate_table_elements(lexer, acc) do + with {:ok, {type, _, _, _}} <- peek_skip(lexer, [:whitespace, :newline, :comment]), + {_, false} <- {:trailing_comma, type == ?\}}, + {:ok, key, skip, lines} <- key(lexer), + {_, _, false, _, _} <- {:key_exists, key, Map.has_key?(acc, key), skip, lines}, + {:ok, {?=, _, _, _}} <- pop_skip(lexer, [:whitespace, :comments]), + {:ok, value} <- value(lexer), + {_, {:ok, acc2}} <- {key, Builder.push_key_into_table(acc, key, value)}, + {:ok, {next, _, _, _}} <- peek_skip(lexer, [:whitespace, :comments]) do + if next == ?, do + Lexer.advance(lexer) + accumulate_table_elements(lexer, acc2) + else + {:ok, acc2} + end + else + {:error, _, _, _} = err -> + err + + {:key_exists, key, true, line, col} -> + {:error, {:key_exists, key}, line, col} + + {table, {:error, :key_exists}} -> + {:error, {:key_exists_in_table, table}, -1, -1} + + {:trailing_comma, true} -> + {:ok, acc} + + {:ok, {type, skip, data, lines} = token} -> + Lexer.push(lexer, token) + {:error, {:invalid_key_value, {type, data}}, skip, lines} + end + end + + defp key(lexer) do + result = + case pop_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {type, skip, s, lines}} when type in [:digits, :alpha, :string] -> + {key(lexer, s, []), skip, lines} + + {:ok, {type, skip, _, lines}} when type in '-_' -> + {key(lexer, <<type::utf8>>, []), skip, lines} + + {:ok, {type, skip, data, lines} = token} -> + Lexer.push(lexer, token) + {:error, {:invalid_token, {type, data}}, skip, lines} + end + + case result do + {:error, _, _, _} = err -> + err + + {{:ok, key}, skip, lines} -> + {:ok, key, skip, lines} + + {{:error, _, _, _} = err, _, _} -> + err + end + end + + defp key(lexer, word, acc) do + case Lexer.peek(lexer) do + {:error, _, _, _} = err -> + err + + {:ok, {:whitespace, _, _, _}} -> + # The only allowed continuation now is a . followed by key char + case peek_skip(lexer, [:whitespace]) do + {:ok, {?., _, _, _}} -> + Lexer.advance(lexer) + + case peek_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {type, _, _, _}} when type in [:digits, :alpha, :string] -> + key(lexer, "", [word | acc]) + + {:ok, {type, _, _, _}} when type in '-_' -> + key(lexer, "", [word | acc]) + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + + {:ok, _} -> + {:ok, Enum.reverse([word | acc])} + end + + {:ok, {type, _, s, _}} when type in [:digits, :alpha, :string] -> + Lexer.advance(lexer) + key(lexer, word <> s, acc) + + {:ok, {type, _, _, _}} when type in '-_' -> + Lexer.advance(lexer) + key(lexer, word <> iodata_to_str([type]), acc) + + {:ok, {?., _, _, _}} -> + Lexer.advance(lexer) + + case peek_skip(lexer, [:whitespace]) do + {:error, _, _, _} = err -> + err + + {:ok, {type, _, _, _}} when type in [:digits, :alpha, :string] -> + key(lexer, "", [word | acc]) + + {:ok, {type, _, _, _}} when type in '-_' -> + key(lexer, "", [word | acc]) + + {:ok, {type, skip, data, lines}} -> + {:error, {:invalid_token, {type, data}}, skip, lines} + end + + {:ok, _} -> + {:ok, Enum.reverse([word | acc])} + end + end + + defp iodata_to_integer(data) do + case iodata_to_str(data) do + <<?0, rest::binary>> when byte_size(rest) > 0 -> + {:error, {:invalid_integer, :leading_zero}} + + <<sign::utf8, ?0, rest::binary>> when (sign == ?- or sign == ?+) and byte_size(rest) > 0 -> + {:error, {:invalid_integer, :leading_zero}} + + s -> + {:ok, String.to_integer(s)} + end + end + + defp iodata_to_float(data) do + case iodata_to_str(data) do + <<?0, next::utf8, _::binary>> when next != ?. -> + {:error, {:invalid_float, :leading_zero}} + + <<sign::utf8, ?0, next::utf8, _::binary>> when (sign == ?- or sign == ?+) and next != ?. -> + {:error, {:invalid_float, :leading_zero}} + + s -> + {:ok, String.to_float(s)} + end + end + + defp iodata_to_str(parts) do + parts + |> Enum.reverse() + |> IO.chardata_to_string() + end + + defp pop_skip(lexer, skip) do + case Lexer.pop(lexer) do + {:error, _, _, _} = err -> + err + + {:ok, {type, _, _, _}} = result -> + if :lists.member(type, skip) do + pop_skip(lexer, skip) + else + result + end + end + end + + defp peek_skip(lexer, skip) do + case Lexer.peek(lexer) do + {:error, _, _, _} = err -> + err + + {:ok, {type, _, _, _}} = result -> + if :lists.member(type, skip) do + Lexer.advance(lexer) + peek_skip(lexer, skip) + else + result + end + end + end +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/document.ex b/test-community-packages-javascript/build/packages/toml/lib/document.ex new file mode 100644 index 00000000000..730abd17f86 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/document.ex @@ -0,0 +1,182 @@ +defmodule Toml.Document do + @moduledoc false + + # Represents a TOML document, and handles conversion to a plain map + # See `Toml.Builder` for the actual logic for constructing the document. + + defstruct [:keys, :comments, :open_table, :comment_stack, :keyfun, :transforms] + + # A key is either binary or atom depending on the decoder option value + @type key :: binary | atom | term + + # A value is the fully decoded value from the TOML + @type value :: + %{key => value} + | {:table_array, [%{key => value}]} + | number + | binary + | NaiveDateTime.t() + | DateTime.t() + | Date.t() + | Time.t() + | [value] + + # A keypath is a list of keys, they are all of the same key type + @type keypath :: list(binary) | list(atom) | list(term) + + @type t :: %__MODULE__{ + keys: %{key => value}, + comments: %{keypath => binary}, + open_table: keypath | nil, + comment_stack: [binary], + keyfun: nil | (binary -> term | no_return), + transforms: [Toml.Transform.t()] + } + + @doc """ + Create a new empty TOML document + """ + @spec new(Toml.opts()) :: t + def new(opts) when is_list(opts) do + keyfun = to_key_fun(Keyword.get(opts, :keys, :strings)) + transforms = Keyword.get(opts, :transforms, []) + + %__MODULE__{ + keys: %{}, + comments: %{}, + open_table: nil, + comment_stack: [], + keyfun: keyfun, + transforms: transforms + } + end + + @doc """ + Convert the given TOML document to a plain map. + + During conversion to a plain map, keys are converted according + to the key type defined when the document was created. + + In addition to converting keys, if transforms were defined, they are + applied to values depth-first, bottom-up. Transforms are first composed + into a single function, designed to be executed in the order they appear + in the list provided; if any transform returns an error, conversion is + stopped and an error is returned - otherwise, the value is passed from + transformer to transformer and the final result replaces the value in the + document. + """ + def to_map(%__MODULE__{keys: keys, keyfun: keyfun, transforms: ts}) do + transform = + case ts do + [] -> + nil + + ts when is_list(ts) -> + Toml.Transform.compose(ts) + end + + {:ok, to_map2(keys, keyfun, transform)} + catch + _, {:error, {:keys, {:non_existing_atom, _}}} = err -> + err + end + + # Called when a table is being converted + defp to_map2(m, nil, nil) when is_map(m) do + for {k, v} <- m, into: %{}, do: {k, to_map3(k, v, nil, nil)} + end + + defp to_map2(m, keyfun, nil) when is_map(m) and is_function(keyfun, 1) do + for {k, v} <- m, into: %{} do + k2 = keyfun.(k) + {k2, to_map3(k2, v, keyfun, nil)} + end + end + + defp to_map2(m, nil, transform) when is_map(m) and is_function(transform, 2) do + for {k, v} <- m, into: %{} do + v2 = to_map3(k, v, nil, transform) + {k, v2} + end + end + + defp to_map2(m, keyfun, transform) + when is_map(m) and is_function(keyfun, 1) and is_function(transform, 2) do + for {k, v} <- m, into: %{} do + k2 = keyfun.(k) + v2 = to_map3(k2, v, keyfun, transform) + {k2, v2} + end + end + + # Called when a table value is being converted + defp to_map3(_key, %_{} = s, _keyfun, nil), do: s + defp to_map3(key, %_{} = s, _keyfun, transform), do: transform.(key, s) + + defp to_map3(key, list, keyfun, nil) when is_list(list) do + for v <- list, do: to_map3(key, v, keyfun, nil) + end + + defp to_map3(key, list, _keyfun, transform) when is_list(list) do + transform.(key, list) + end + + defp to_map3(_key, {:table_array, list}, keyfun, nil) do + for v <- Enum.reverse(list) do + to_map2(v, keyfun, nil) + end + end + + defp to_map3(key, {:table_array, list}, keyfun, transform) do + for v <- Enum.reverse(list) do + to_map2(v, keyfun, transform) + end + |> (&transform.(key, &1)).() + end + + defp to_map3(_key, v, keyfun, nil) when is_map(v) do + to_map2(v, keyfun, nil) + end + + defp to_map3(key, v, keyfun, transform) when is_map(v) and is_function(transform) do + transform.(key, to_map2(v, keyfun, transform)) + end + + defp to_map3(_key, v, _keyfun, nil), do: v + defp to_map3(key, v, _keyfun, transform), do: transform.(key, v) + + # Convert the value of `:keys` to a key conversion function (if not already one) + @valid_keys_opts [:atoms, :atoms!, :strings, "(key :: String.t) -> term"] + defp to_key_fun(:atoms), do: &to_atom/1 + defp to_key_fun(:atoms!), do: &to_existing_atom/1 + defp to_key_fun(:strings), do: nil + defp to_key_fun(fun) when is_function(fun, 1), do: fun + defp to_key_fun(invalid), do: throw({:badarg, {:keys, invalid, @valid_keys_opts}}) + + # Convert the given key (as binary) to an atom + # Handle converting uppercase keys to module names rather than plain atoms + defp to_atom(<<c::utf8, _::binary>> = key) when c >= ?A and c <= ?Z do + Module.concat([key]) + end + + defp to_atom(key), do: String.to_atom(key) + + # Convert the given key (as binary) to an existing atom + # Handle converting uppercase keys to module names rather than plain atoms + # + # NOTE: This throws an error if the atom does not exist, and is intended to + # be handled in the decoder + defp to_existing_atom(<<c::utf8, _::binary>> = key) when c >= ?A and c <= ?Z do + Module.concat([String.to_existing_atom(key)]) + rescue + _ -> + throw({:error, {:keys, {:non_existing_atom, key}}}) + end + + defp to_existing_atom(key) do + String.to_existing_atom(key) + rescue + _ -> + throw({:error, {:keys, {:non_existing_atom, key}}}) + end +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/error.ex b/test-community-packages-javascript/build/packages/toml/lib/error.ex new file mode 100644 index 00000000000..c4690b7b333 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/error.ex @@ -0,0 +1,143 @@ +defmodule Toml.Error do + @moduledoc false + + defexception [:message, :reason] + + def exception(msg) when is_binary(msg) do + %__MODULE__{message: msg, reason: nil} + end + + def exception({:error, reason}) do + %__MODULE__{message: format_reason(reason), reason: reason} + end + + def exception(reason) when is_tuple(reason) do + %__MODULE__{message: format_reason(reason), reason: reason} + end + + def message(%__MODULE__{message: message}) do + message + end + + @doc """ + Convert internal error reasons into friendly, printable form + """ + def format_reason({:keys, {:non_existing_atom, key}}), + do: "unable to convert '#{key}' to an existing atom" + + def format_reason({:expected, token, other}), + do: "expected #{format_token(token)}, but got #{format_token(other)}" + + def format_reason({:invalid_token, token}), + do: "invalid token #{format_token(token)}" + + def format_reason({:invalid_integer, :leading_zero}), + do: "invalid integer syntax, leading zeros are not allowed" + + def format_reason({:invalid_float, :leading_zero}), + do: "invalid float syntax, leading zeros are not allowed" + + def format_reason({:invalid_float, token}), + do: "invalid float syntax, unexpected token #{format_token(token)}" + + def format_reason({:invalid_datetime, reason}), + do: "invalid datetime syntax, #{inspect(reason)}" + + def format_reason({:invalid_datetime_offset, reason}), + do: "invalid datetime offset syntax, #{inspect(reason)}" + + def format_reason({:invalid_date, reason}), + do: "invalid date syntax, #{inspect(reason)}" + + def format_reason({:invalid_time, reason}), + do: "invalid time syntax, #{inspect(reason)}" + + def format_reason({:invalid_key_value, token}), + do: "invalid key/value syntax, unexpected token #{format_token(token)}" + + def format_reason({:unclosed_table_array_name, token}), + do: "unclosed table array name at #{format_token(token)}" + + def format_reason({:unclosed_array, {oline, ocol}}), + do: "unclosed array started on line #{oline}, column #{ocol}" + + def format_reason({:unclosed_inline_table, {oline, ocol}}), + do: "unclosed inline table started on line #{oline}, column #{ocol}" + + def format_reason(:unclosed_quote), + do: "unclosed quoted string" + + def format_reason(:unexpected_newline), + do: "unexpected newline in single-quoted string" + + def format_reason(:unexpected_eof), + do: "unexpected end of file" + + def format_reason({:invalid_escape, char}), + do: "illegal escape sequence #{char}" + + def format_reason({:invalid_control_char, char}) do + if String.printable?(char) do + "illegal control character #{inspect(char, base: :hex)} ('#{char}')" + else + "illegal control character #{inspect(char, base: :hex)}" + end + end + + def format_reason({:invalid_char, char}) do + if String.printable?(char) do + "illegal character #{inspect(char, base: :hex)} ('#{char}')" + else + "illegal character #{inspect(char, base: :hex)}" + end + end + + def format_reason({:invalid_unicode, char}) do + if String.printable?(char) do + "illegal unicode escape, #{inspect(char, base: :hex)} ('#{char}')" + else + "illegal unicode escape, #{inspect(char, base: :hex)}" + end + end + + def format_reason({:key_exists, key}) do + "cannot redefine key in path '#{key}'" + end + + def format_reason({:badarg, option, value, valid}) when is_list(valid) do + valid = + valid + |> Enum.map(fn + a when is_atom(a) -> + "#{inspect(a)}" + + s when is_binary(s) -> + s + + v -> + "#{inspect(v)}" + end) + |> Enum.join(", ") + + "invalid value `#{inspect(value)}` for option #{inspect(option)}; must be one of [#{valid}]" + end + + def format_reason(reason), do: "#{inspect(reason)}" + + # Format a token in `{type, data}`, or `type` form into printable representation + defp format_token({true, _}), do: "'true'" + defp format_token({false, _}), do: "'false'" + defp format_token(:newline), do: "'\\n'" + + defp format_token({_, data}) when is_binary(data), + do: "'#{data}'" + + defp format_token({token, data}) when is_atom(token), + do: "'#{data}' (#{token})" + + defp format_token({token, _}), + do: "'#{<<token>>}'" + + defp format_token(token), + do: "'#{<<token>>}'" +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer.ex new file mode 100644 index 00000000000..58824f1d3e1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/lexer.ex @@ -0,0 +1,392 @@ +defmodule Toml.Lexer do + @moduledoc false + + import __MODULE__.Guards + + defstruct [:pid] + + @type t :: %__MODULE__{pid: pid} + + # The type of the token + @type type :: + :whitespace + | :newline + | :comment + | :digits + | :hex + | :octal + | :binary + | :alpha + | __MODULE__.String.type() + | boolean + | non_neg_integer + | :eof + # The number of bytes in the input to skip to reach the beginning of the token + @type skip :: non_neg_integer + # The data representation of a token (either size, a character, or string) + @type data :: non_neg_integer | binary + # The line number of the token + @type lines :: non_neg_integer + # The full shape of a token + @type token :: {type, skip, data, lines} + # The shape of errors the lexer produces + @type lexer_err :: {:error, term, skip, lines} + # The shape of the lexer stack + @type stack :: [token] | lexer_err + # The shape of replies which return tokens + @type token_reply :: + {:ok, token} + | lexer_err + + @doc """ + Creates a new Lexer with the given binary content. + + The lexer is a process, which manages the state of the lexer, + and provides the following benefits: + + - Only lexes content as the decoder walks the document, minimizing + the work performed, and resources (i.e. memory) used. + - Allows pushing an arbitrary tokens back on the stack, allowing the + decoder to "rewind" the lexer and try an alternative path. + - Lexing the next token happens concurrently with the decoder handling the last token + + Currently, the lexer will build up strings for most tokens and send them back to + the decoder, since these are running in separate processes, this means all string data + contained in the tokens is copied. For some tokens, like comments, the lexer will send + only the token type (e.g. `:comment`), and indexes into the original input, so that the + content can be extracted only when needed, and in the most efficient manner possible. In + the future, the lexer will do this will all tokens, allowing us to only make copies or store + references into the original input when absolutely needed. We do not do this currently, as + strings in TOML have escapes, which need to be unescaped during parsing. This could be deferred + and done in the decoder, but is not done so right now. + + Returns `{:ok, %#{__MODULE__}{}}`. + """ + @spec new(binary) :: {:ok, t} + def new(content) when is_binary(content) do + {:ok, pid} = :proc_lib.start_link(__MODULE__, :init, [self(), content]) + {:ok, %__MODULE__{pid: pid}} + end + + @doc """ + Pops the next token from the lexer. This advances the lexer to the next token. + """ + @spec pop(t) :: token_reply + def pop(%__MODULE__{pid: pid}) when is_pid(pid), + do: server_call(pid, :pop) + + @doc """ + Advances the lexer to the next token, without returning the current token on the stack, + effectively skipping the current token. + """ + @spec advance(t) :: :ok + def advance(%__MODULE__{pid: pid}) when is_pid(pid), + do: server_call(pid, :advance) + + @doc """ + Peeks at the next token the lexer will return from `pop/1`. + + Always returns the same result until the lexer advances. + """ + @spec peek(t) :: token_reply + def peek(%__MODULE__{pid: pid}) when is_pid(pid), + do: server_call(pid, :peek) + + @doc """ + Pushes a token back on the lexer's stack. + + You may push as many tokens back on the stack as desired. + """ + @spec push(t, token) :: :ok + def push(%__MODULE__{pid: pid}, {_type, _skip, _data, _lines} = token) when is_pid(pid), + do: server_call(pid, {:push, token}) + + @doc """ + Retrieves the position of the lexer in the current input + """ + @spec pos(t) :: {:ok, skip, lines} + def pos(%__MODULE__{pid: pid}) when is_pid(pid), + do: server_call(pid, :pos) + + @doc """ + Terminates the lexer process. + """ + @spec stop(t) :: :ok + def stop(%__MODULE__{pid: pid}) when is_pid(pid) do + if Process.alive?(pid) do + server_call(pid, :stop) + else + :ok + end + end + + @doc """ + Converts the lexer in to a `Stream`. Not currently used. + """ + @spec stream(t) :: Enumerable.t() + def stream(%__MODULE__{} = lexer) do + Stream.resource( + fn -> {lexer, false, false} end, + fn + {_lexer, true, _error?} = acc -> + {:halt, acc} + + {_lexer, _eof?, true} = acc -> + {:halt, acc} + + {lexer, false, false} -> + case pop(lexer) do + {:error, _, _, _} = err -> + {[err], {lexer, false, true}} + + {:ok, {:eof, _, _, _}} = ok -> + {[ok], {lexer, true, false}} + + {:ok, _} = ok -> + {[ok], {lexer, false, false}} + end + end, + fn {lexer, _, _} -> stop(lexer) end + ) + end + + ## Private + + def init(parent, {:stream, stream}) when is_pid(parent) do + init(parent, Enum.into(stream, <<>>)) + end + + def init(parent, data) when is_pid(parent) and is_binary(data) do + Process.flag(:trap_exit, true) + :proc_lib.init_ack(parent, {:ok, self()}) + lex(parent, :sys.debug_options([]), data, 0, 1, []) + end + + # If an error is on the stack keep it there unless we push a valid token back on + @spec lex(pid, term, binary, skip, lines, stack) :: no_return + defp lex(parent, debug, data, skip, lines, {:error, _, eskip, elines} = err) do + receive do + {:EXIT, ^parent, reason} -> + exit(reason) + + {from, :stop} -> + send(from, {self(), :ok}) + exit(:normal) + + {from, {:push, {_type, _tskip, _tsize, _tline} = token}} -> + send(from, {self(), :ok}) + lex(parent, debug, data, skip, lines, [token]) + + {from, op} when op in [:pop, :peek, :advance] -> + send(from, {self(), err}) + lex(parent, debug, data, skip, lines, err) + + {from, :pos} -> + send(from, {self(), {:ok, eskip, elines}}) + lex(parent, debug, data, skip, lines, err) + end + end + + defp lex(parent, debug, data, skip, lines, []) do + case do_lex(data, skip, lines) do + {:error, _, _, _} = err -> + lex(parent, debug, data, skip, lines, err) + + {:ok, data, {_type, skip, _size, lines} = token} -> + lex(parent, debug, data, skip, lines, [token]) + end + end + + defp lex(parent, debug, data, skip, lines, [{_, tskip, _, tlines} = token | stack] = ostack) do + receive do + {:EXIT, ^parent, reason} -> + exit(reason) + + {from, :stop} -> + send(from, {self(), :ok}) + exit(:normal) + + {from, :pop} -> + send(from, {self(), {:ok, token}}) + lex(parent, debug, data, skip, lines, stack) + + {from, :advance} -> + send(from, {self(), :ok}) + lex(parent, debug, data, skip, lines, stack) + + {from, :peek} -> + send(from, {self(), {:ok, token}}) + lex(parent, debug, data, skip, lines, ostack) + + {from, {:push, pushed}} -> + send(from, {self(), :ok}) + lex(parent, debug, data, skip, lines, [pushed | ostack]) + + {from, :pos} -> + send(from, {self(), {:ok, tskip, tlines}}) + lex(parent, debug, data, skip, lines, ostack) + end + end + + @spec do_lex(binary, skip, lines) :: {:ok, binary, token} | {:error, term, skip, lines} + defp do_lex(data, skip, lines) + + defp do_lex(<<>> = data, skip, lines), + do: {:ok, data, {:eof, skip, 0, lines}} + + defp do_lex(<<?\#, rest::binary>>, skip, lines), + do: lex_comment(rest, skip + 1, 0, lines) + + defp do_lex(<<?\r, ?\n, rest::binary>>, skip, lines), + do: {:ok, rest, {:newline, skip + 2, 0, lines + 1}} + + defp do_lex(<<?\n, rest::binary>>, skip, lines), + do: {:ok, rest, {:newline, skip + 1, 0, lines + 1}} + + defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), + do: lex_whitespace(rest, skip + 1, lines) + + defp do_lex(<<"true", rest::binary>>, skip, lines), + do: {:ok, rest, {true, skip + 4, 0, lines}} + + defp do_lex(<<"false", rest::binary>>, skip, lines), + do: {:ok, rest, {false, skip + 5, 0, lines}} + + defp do_lex(<<?=, rest::binary>>, skip, lines), + do: {:ok, rest, {?=, skip + 1, 0, lines}} + + defp do_lex(<<?., rest::binary>>, skip, lines), + do: {:ok, rest, {?., skip + 1, 0, lines}} + + defp do_lex(<<?\[, rest::binary>>, skip, lines), + do: {:ok, rest, {?\[, skip + 1, 0, lines}} + + defp do_lex(<<?\], rest::binary>>, skip, lines), + do: {:ok, rest, {?\], skip + 1, 0, lines}} + + defp do_lex(<<?\{, rest::binary>>, skip, lines), + do: {:ok, rest, {?\{, skip + 1, 0, lines}} + + defp do_lex(<<?\}, rest::binary>>, skip, lines), + do: {:ok, rest, {?\}, skip + 1, 0, lines}} + + defp do_lex(<<?+, rest::binary>>, skip, lines), + do: {:ok, rest, {?+, skip + 1, 0, lines}} + + defp do_lex(<<?-, rest::binary>>, skip, lines), + do: {:ok, rest, {?-, skip + 1, 0, lines}} + + defp do_lex(<<?:, rest::binary>>, skip, lines), + do: {:ok, rest, {?:, skip + 1, 0, lines}} + + defp do_lex(<<?,, rest::binary>>, skip, lines), + do: {:ok, rest, {?,, skip + 1, 0, lines}} + + defp do_lex(<<?_, rest::binary>>, skip, lines), + do: {:ok, rest, {?_, skip + 1, 0, lines}} + + defp do_lex(<<?0, ?x, c::utf8, rest::binary>>, skip, lines) when is_hex(c), + do: lex_hex(rest, skip + 3, [c], lines) + + defp do_lex(<<?0, ?o, c::utf8, rest::binary>>, skip, lines) when is_octal(c), + do: lex_octal(rest, skip + 3, [c], lines) + + defp do_lex(<<?0, ?b, c::utf8, rest::binary>>, skip, lines) when is_bin(c), + do: lex_binary(rest, skip + 3, [c], lines) + + defp do_lex(<<c::utf8, _::binary>> = data, skip, lines) when is_quote(c), + do: __MODULE__.String.lex(data, skip, lines) + + defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_digit(c), + do: lex_digits(rest, skip + 1, [c], lines) + + defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_alpha(c), + do: lex_alpha(rest, skip + 1, [c], lines) + + defp do_lex(<<c::utf8, _::binary>>, skip, lines), + do: {:error, {:invalid_char, <<c::utf8>>}, skip + 1, lines} + + defp lex_whitespace(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), + do: lex_whitespace(rest, skip + 1, lines) + + defp lex_whitespace(rest, skip, lines), + do: {:ok, rest, {:whitespace, skip, 0, lines}} + + defp lex_comment(<<?\r, ?\n, rest::binary>>, skip, size, lines), + do: {:ok, rest, {:comment, skip + 2, size, lines + 1}} + + defp lex_comment(<<?\n, rest::binary>>, skip, size, lines), + do: {:ok, rest, {:comment, skip + 1, size, lines + 1}} + + defp lex_comment(<<_::utf8, rest::binary>>, skip, size, lines), + do: lex_comment(rest, skip + 1, size + 1, lines) + + defp lex_comment(<<>> = rest, skip, size, lines), + do: {:ok, rest, {:comment, skip, size, lines}} + + defp lex_digits(<<c::utf8, rest::binary>>, skip, acc, lines) when is_digit(c), + do: lex_digits(rest, skip + 1, [c | acc], lines) + + defp lex_digits(rest, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:digits, skip, bin, lines}} + end + + defp lex_hex(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) + when is_hex(c) and is_hex(d), + do: lex_hex(rest, skip + 3, [d, c | acc], lines) + + defp lex_hex(<<c::utf8, rest::binary>>, skip, acc, lines) when is_hex(c), + do: lex_hex(rest, skip + 1, [c | acc], lines) + + defp lex_hex(rest, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:hex, skip, bin, lines}} + end + + defp lex_octal(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) + when is_octal(c) and is_octal(d), + do: lex_octal(rest, skip + 3, [d, c | acc], lines) + + defp lex_octal(<<c::utf8, rest::binary>>, skip, acc, lines) when is_octal(c), + do: lex_octal(rest, skip + 1, [c | acc], lines) + + defp lex_octal(rest, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:octal, skip, bin, lines}} + end + + defp lex_binary(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) + when is_bin(c) and is_bin(d), + do: lex_binary(rest, skip + 3, [d, c | acc], lines) + + defp lex_binary(<<c::utf8, rest::binary>>, skip, acc, lines) when is_bin(c), + do: lex_binary(rest, skip + 1, [c | acc], lines) + + defp lex_binary(rest, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:binary, skip, bin, lines}} + end + + defp lex_alpha(<<c::utf8, rest::binary>>, skip, acc, lines) when is_alpha(c), + do: lex_alpha(rest, skip + 1, [c | acc], lines) + + defp lex_alpha(rest, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:alpha, skip, bin, lines}} + end + + defp server_call(pid, msg) do + ref = Process.monitor(pid) + send(pid, {self(), msg}) + + receive do + {:DOWN, ^ref, _type, _pid, info} -> + {:error, info} + + {^pid, reply} -> + Process.demonitor(ref, [:flush]) + reply + end + end +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex new file mode 100644 index 00000000000..bd3df5f7c27 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex @@ -0,0 +1,21 @@ +defmodule Toml.Lexer.Guards do + @moduledoc false + + defguard is_lowercase(c) when c >= ?a and c <= ?z + + defguard is_uppercase(c) when c >= ?A and c <= ?Z + + defguard is_alpha(c) when is_lowercase(c) or is_uppercase(c) + + defguard is_digit(c) when c >= ?0 and c <= ?9 + + defguard is_hex(c) when is_digit(c) or (c >= ?a and c <= ?z) or (c >= ?A and c <= ?Z) + + defguard is_octal(c) when c >= ?0 and c <= ?8 + + defguard is_bin(c) when c == ?0 or c == ?1 + + defguard is_whitespace(c) when c == ?\s or c == ?\t + + defguard is_quote(c) when c == ?\" or c == ?\' +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex new file mode 100644 index 00000000000..dbe7635f699 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex @@ -0,0 +1,294 @@ +defmodule Toml.Lexer.String do + @moduledoc false + + # This module manages the complexity of lexing quoted and literal + # strings as defined by the TOML spec. + + import Toml.Lexer.Guards + + @type type :: + :string + | :multiline_string + + @type skip :: Toml.Lexer.skip() + @type lines :: Toml.Lexer.lines() + @type lexer_err :: Toml.Lexer.lexer_err() + @type result :: {:ok, binary, {type, skip, binary, lines}} | lexer_err + + @spec lex(binary, skip, lines) :: result + def lex(binary, skip, lines) + + def lex(<<>>, skip, lines), + do: {:error, :unexpected_eof, skip, lines} + + def lex(<<?\', ?\', ?\', rest::binary>>, skip, lines) do + {rest, skip, lines} = trim_newline(rest, skip + 3, lines) + lex_literal(:multi, rest, skip, [], lines) + end + + def lex(<<?\', ?\', rest::binary>>, skip, lines), + do: {:ok, rest, {:string, skip + 2, <<>>, lines}} + + def lex(<<?\', rest::binary>>, skip, lines), + do: lex_literal(:single, rest, skip + 1, [], lines) + + def lex(<<?\", ?\", ?\", rest::binary>>, skip, lines) do + {rest, skip, lines} = trim_newline(rest, skip + 3, lines) + lex_quoted(:multi, rest, skip, [], lines) + end + + def lex(<<?\", ?\", rest::binary>>, skip, lines), + do: {:ok, rest, {:string, skip + 2, <<>>, lines}} + + def lex(<<?\", rest::binary>>, skip, lines), + do: lex_quoted(:single, rest, skip + 1, [], lines) + + defp lex_literal(_type, <<>>, skip, _acc, lines), + do: {:error, :unclosed_quote, skip, lines} + + # Disallow newlines in single-line literals + defp lex_literal(:single, <<?\r, ?\n, _::binary>>, skip, _acc, lines), + do: {:error, :unexpected_newline, skip + 1, lines} + + defp lex_literal(:single, <<?\n, _::binary>>, skip, _acc, lines), + do: {:error, :unexpected_newline, skip + 1, lines} + + defp lex_literal(type, <<?\r, ?\n, rest::binary>>, skip, acc, lines), + do: lex_literal(type, rest, skip + 2, [?\n | acc], lines + 1) + + defp lex_literal(type, <<?\n, rest::binary>>, skip, acc, lines), + do: lex_literal(type, rest, skip + 1, [?\n | acc], lines + 1) + + # Closing quotes + defp lex_literal(:single, <<?\', rest::binary>>, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:string, skip + 1, bin, lines}} + end + + defp lex_literal(:multi, <<?\', ?\', ?\', rest::binary>>, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:multiline_string, skip + 3, bin, lines}} + end + + # Disallow any control chars in single quoted literals + defp lex_literal(:single, <<c::utf8, _::binary>>, skip, _acc, lines) + when (c >= 0 and c <= 31) or c == 127, + do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} + + # Disallow any control chars in single quoted literals, EXCEPT \t in multi-line literals + defp lex_literal(:multi, <<?\t, rest::binary>>, skip, acc, lines), + do: lex_literal(:multi, rest, skip + 1, [?\t | acc], lines) + + defp lex_literal(:multi, <<c::utf8, _::binary>>, skip, _acc, lines) + when (c >= 0 and c <= 31) or c == 127, + do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} + + # Eat next character in string + defp lex_literal(type, <<c::utf8, rest::binary>>, skip, acc, lines), + do: lex_literal(type, rest, skip + 1, [c | acc], lines) + + # Invalid byte sequence (i.e. invalid unicode) + defp lex_literal(_type, <<c, _::binary>>, skip, _acc, lines), + do: {:error, {:invalid_unicode, <<c>>}, skip + 1, lines} + + defp lex_quoted(_type, <<>>, skip, _acc, lines), + do: {:error, :unclosed_quote, skip, lines} + + # Disallow newlines in single-line strings + defp lex_quoted(:single, <<?\r, ?\n, _::binary>>, skip, _acc, lines), + do: {:error, :unexpected_newline, skip + 1, lines} + + defp lex_quoted(:single, <<?\n, _::binary>>, skip, _acc, lines), + do: {:error, :unexpected_newline, skip + 1, lines} + + defp lex_quoted(type, <<?\r, ?\n, rest::binary>>, skip, acc, lines), + do: lex_quoted(type, rest, skip + 2, [?\n | acc], lines + 1) + + defp lex_quoted(type, <<?\n, rest::binary>>, skip, acc, lines), + do: lex_quoted(type, rest, skip + 1, [?\n | acc], lines + 1) + + # Allow escaping newlines in multi-ine strings + defp lex_quoted(:multi, <<?\\, ?\r, ?\n, rest::binary>>, skip, acc, lines) do + {rest, skip, lines} = trim_whitespace(rest, skip + 3, lines + 1) + lex_quoted(:multi, rest, skip, acc, lines) + end + + defp lex_quoted(:multi, <<?\\, ?\n, rest::binary>>, skip, acc, lines) do + {rest, skip, lines} = trim_whitespace(rest, skip + 2, lines + 1) + lex_quoted(:multi, rest, skip, acc, lines) + end + + # Trim trailing whitespace at end of line + defp lex_quoted(:multi, <<?\\, ?\s, rest::binary>>, skip, acc, lines) do + lex_quoted(:multi, <<?\\, rest::binary>>, skip, acc, lines) + end + + # Allowed escapes + defp lex_quoted(type, <<?\\, ?\\, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 2, [?\\ | acc], lines) + end + + defp lex_quoted(type, <<?\\, ?b, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 2, [?\b | acc], lines) + end + + defp lex_quoted(type, <<?\\, ?d, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 2, [?\d | acc], lines) + end + + defp lex_quoted(type, <<?\\, ?f, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 2, [?\f | acc], lines) + end + + defp lex_quoted(type, <<?\\, ?n, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 2, [?\n | acc], lines) + end + + defp lex_quoted(type, <<?\\, ?r, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 2, [?\r | acc], lines) + end + + defp lex_quoted(type, <<?\\, ?t, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 2, [?\t | acc], lines) + end + + defp lex_quoted(type, <<?\\, ?\", rest::binary>>, skip, acc, lines), + do: lex_quoted(type, rest, skip + 2, [?\" | acc], lines) + + defp lex_quoted(type, <<?\\, ?u, rest::binary>>, skip, acc, lines) do + {char, rest, skip2} = unescape_unicode(?u, rest) + lex_quoted(type, rest, 2 + skip + skip2, [char | acc], lines) + catch + :throw, {:invalid_unicode, _} = reason -> + {:error, reason, skip + 1, lines} + end + + defp lex_quoted(type, <<?\\, ?U, rest::binary>>, skip, acc, lines) do + {char, rest, skip2} = unescape_unicode(?U, rest) + lex_quoted(type, rest, 2 + skip + skip2, [char | acc], lines) + catch + :throw, {:invalid_unicode, _} = reason -> + {:error, reason, skip + 1, lines} + end + + # Bad escape + defp lex_quoted(_type, <<?\\, char::utf8, _::binary>>, skip, _acc, lines) do + {:error, {:invalid_escape, <<?\\, char::utf8>>}, skip + 1, lines} + end + + # Closing quotes + defp lex_quoted(:multi, <<?\", ?\", ?\", rest::binary>>, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:multiline_string, skip + 3, bin, lines}} + end + + defp lex_quoted(:single, <<?\", rest::binary>>, skip, acc, lines) do + bin = acc |> Enum.reverse() |> IO.chardata_to_string() + {:ok, rest, {:string, skip + 1, bin, lines}} + end + + # Disallow any unescaped control chars in quoted strings + defp lex_quoted(_type, <<c::utf8, _::binary>>, skip, _acc, lines) + when (c >= 0 and c <= 31) or c == 127, + do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} + + # Eat next character in string + defp lex_quoted(type, <<c::utf8, rest::binary>>, skip, acc, lines) do + lex_quoted(type, rest, skip + 1, [c | acc], lines) + end + + defp lex_quoted(_type, <<c, _::binary>>, skip, _acc, lines), + do: {:error, {:invalid_unicode, <<c>>}, skip + 1, lines} + + defp trim_newline(<<?\r, ?\n, rest::binary>>, skip, lines), do: {rest, skip + 2, lines + 1} + defp trim_newline(<<?\n, rest::binary>>, skip, lines), do: {rest, skip + 1, lines + 1} + defp trim_newline(rest, skip, lines), do: {rest, skip, lines} + + # Trims whitespace (tab, space) up until next non-whitespace character, + # or until closing delimiter. Only allowed with mulit-line quoted strings. + defp trim_whitespace(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), + do: trim_whitespace(rest, skip + 1, lines) + + defp trim_whitespace(<<?\", ?\", ?\", _::binary>> = rest, skip, lines), + do: {rest, skip, lines} + + defp trim_whitespace(rest, skip, lines), + do: {rest, skip, lines} + + def unescape_unicode(?U, <<n::8-binary, bin::binary>>) do + char = + case :erlang.binary_to_integer(n, 16) do + u when u <= 0x007F -> + <<u>> + + u when 0x0080 <= u and u <= 0x07FF -> + u1 = div(u, 64) + 192 + u2 = mod(u, 64) + 128 + <<u1, u2>> + + u when (0x0080 <= u and u <= 0xD7FF) or (0xE000 <= u and u <= 0xFFFF) -> + u1 = div(u, 4096) + 224 + u2 = div(mod(u, 4096), 64) + 128 + u3 = mod(u, 64) + 128 + <<u1, u2, u3>> + + u -> + u1 = div(u, 262_144) + 240 + u2 = div(mod(u, 262_144), 4096) + 128 + u3 = div(mod(u, 4096), 64) + 128 + u4 = mod(u, 64) + 128 + <<u1, u2, u3, u4>> + end + + # Check that we have a valid utf8 encoding + case char do + <<_::utf8>> -> + {char, bin, 8} + + _ -> + bad_unicode!(char) + end + end + + def unescape_unicode(?u, <<n::4-binary, bin::binary>>) do + case :erlang.binary_to_integer(n, 16) do + high when 0xD800 <= high and high <= 0xDBFF -> + # surrogate pair + case bin do + <<?\\, ?u, n2::4-binary, bin2::binary>> -> + case :erlang.binary_to_integer(n2, 16) do + low when 0xDC00 <= low and low <= 0xDFFF -> + <<u::utf16>> = <<high::16, low::16>> + {<<u::utf8>>, bin2, 4 + 6} + + _ -> + bad_unicode!(n) + end + + _ -> + bad_unicode!(n) + end + + # second part of surrogate pair (without first part) + u when (0xDC00 <= u and u <= 0xDFFF) or u < 0 -> + bad_unicode!(n) + + u -> + {<<u::utf8>>, bin, 4} + end + catch + :error, :badarg -> + bad_unicode!(n) + end + + def unescape_unicode(_type, <<c, _::binary>>) do + bad_unicode!(<<c>>) + end + + @spec bad_unicode!(binary) :: no_return + defp bad_unicode!(byte), do: throw({:invalid_unicode, byte}) + + defp mod(x, y) when x > 0, do: rem(x, y) + defp mod(x, y) when x < 0, do: y + rem(x, y) + defp mod(0, _), do: 0 +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/provider.ex b/test-community-packages-javascript/build/packages/toml/lib/provider.ex new file mode 100644 index 00000000000..400d72a3478 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/provider.ex @@ -0,0 +1,227 @@ +defmodule Toml.Provider do + @moduledoc """ + This module provides an implementation of both the Distilery and Elixir + config provider behaviours, so that TOML files can be used for configuration + in releases. + + ## Distillery Usage + + Add the following to your `rel/config.exs` + + release :myapp do + # ...snip... + set config_providers: [ + {Toml.Provider, [path: "${XDG_CONFIG_DIR}/myapp.toml", transforms: [...]]} + ] + end + + ## Elixir Usage + + config_providers: [ + {Toml.Provider, [ + path: {:system, "XDG_CONFIG_DIR", "myapp.toml"}, + transforms: [...] + ]} + ] + + This will result in `Toml.Provider` being invoked during boot, at which point it + will evaluate the given path and read the TOML file it finds. If one is not + found, or is not accessible, the provider will raise an error, and the boot + sequence will terminate unsuccessfully. If it succeeds, it persists settings in + the file to the application environment (i.e. you access it via + `Application.get_env/2`). + + The config provider expects a certain format to the TOML file, namely that + keys at the root of the document are tables which correspond to applications + which need to be configured. If it encounters keys at the root of the document + which are not tables, they are ignored. + + ## Options + + The same options that `Toml.parse/2` accepts are able to be provided to `Toml.Provider`, + but there are two main differences: + + * `:path` (required) - sets the path to the TOML file to load config from + * `:keys` - defaults to `:atoms`, but can be set to `:atoms!` if desired, all other + key types are ignored, as it results in an invalid config structure + + """ + has_config_api? = Version.match?(Version.parse!(System.version()), ">= 1.9.0") + + if has_config_api? do + @behaviour Config.Provider + end + + @doc false + def init(opts) when is_list(opts) do + opts = + case Keyword.get(opts, :keys) do + a when a in [:atoms, :atoms!] -> + opts + + _ -> + Keyword.put(opts, :keys, :atoms) + end + + if is_distillery_env?() do + # When running under Distillery, init performs load + load([], opts) + opts + else + # With 1.9 releases, init just preps arguments for `load` + opts + end + end + + @doc false + def load(config, opts) when is_list(opts) do + path = Keyword.fetch!(opts, :path) + # path expansion should happen in load rather than init, otherwise + # in 1.9 releases using a {:system, env_var, path} tuple an error + # will be raised if the env var is not set in the build environment + with {:ok, path} <- expand_path(path) do + map = Toml.decode_file!(path, opts) + persist(config, to_keyword(map)) + else + {:error, reason} -> + exit(reason) + end + end + + @doc false + def get([app | keypath]) do + config = Application.get_all_env(app) + + case get_in(config, keypath) do + nil -> + nil + + val -> + {:ok, val} + end + end + + if has_config_api? do + defp persist(config, keyword) when is_list(keyword) do + config = Config.Reader.merge(config, keyword) + Application.put_all_env(config, persistent: true) + config + end + else + defp persist(config, keyword) when is_list(keyword) do + # For each app + for {app, app_config} <- keyword do + # Get base config + base = Application.get_all_env(app) + base = deep_merge(base, Keyword.get(config, app, [])) + # Merge this app's TOML config over the base config + merged = deep_merge(base, app_config) + # Persist key/value pairs for this app + for {k, v} <- merged do + Application.put_env(app, k, v, persistent: true) + end + + # Return merged config + {app, merged} + end + end + + defp deep_merge(a, b) when is_list(a) and is_list(b) do + if Keyword.keyword?(a) and Keyword.keyword?(b) do + Keyword.merge(a, b, &deep_merge/3) + else + b + end + end + + defp deep_merge(_k, a, b) when is_list(a) and is_list(b) do + if Keyword.keyword?(a) and Keyword.keyword?(b) do + Keyword.merge(a, b, &deep_merge/3) + else + b + end + end + + defp deep_merge(_k, a, b) when is_map(a) and is_map(b) do + Map.merge(a, b, &deep_merge/3) + end + + defp deep_merge(_k, _a, b), do: b + end + + # At the top level, convert the map to a keyword list of keyword lists + # Keys with no children (i.e. keys which are not tables) are dropped + defp to_keyword(map) when is_map(map) do + for {k, v} <- map, v2 = to_keyword2(v), is_list(v2), into: [] do + {k, v2} + end + end + + # For all other values, convert tables to keywords + defp to_keyword2(map) when is_map(map) do + Enum.map(map, fn {k, v} -> {k, to_keyword2(v)} end) + end + + # And leave all other values untouched + defp to_keyword2(term), do: term + + def expand_path(path) when is_binary(path) do + case expand_path(path, <<>>) do + {:ok, p} -> + {:ok, Path.expand(p)} + + {:error, _} = err -> + err + end + end + + if has_config_api? do + def expand_path(path) do + {:ok, Config.Provider.resolve_config_path!(path)} + end + end + + defp expand_path(<<>>, acc), + do: {:ok, acc} + + defp expand_path(<<?$, ?\{, rest::binary>>, acc) do + case expand_var(rest) do + {:ok, var, rest} -> + expand_path(rest, acc <> var) + + {:error, _} = err -> + err + end + end + + defp expand_path(<<c::utf8, rest::binary>>, acc) do + expand_path(rest, <<acc::binary, c::utf8>>) + end + + defp expand_var(bin), + do: expand_var(bin, <<>>) + + defp expand_var(<<>>, _acc), + do: {:error, :unclosed_var_expansion} + + defp expand_var(<<?\}, rest::binary>>, acc), + do: {:ok, System.get_env(acc) || "", rest} + + defp expand_var(<<c::utf8, rest::binary>>, acc) do + expand_var(rest, <<acc::binary, c::utf8>>) + end + + defp is_distillery_env? do + if Version.match?(Version.parse!(System.version()), ">= 1.9.0") do + Code.ensure_loaded?(Distillery.Releases.Config.Provider) + else + true + end + rescue + _ -> + case :erlang.phash2(1, 1) do + 0 -> true + _ -> false + end + end +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/toml.ex b/test-community-packages-javascript/build/packages/toml/lib/toml.ex new file mode 100644 index 00000000000..c040f5c2944 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/toml.ex @@ -0,0 +1,94 @@ +defmodule Toml do + @external_resource "README.md" + + @moduledoc File.read!(Path.join([__DIR__, "..", "README.md"])) + + @type key :: binary | atom | term + @type opt :: + {:keys, :atoms | :atoms! | :string | (key -> term)} + | {:filename, String.t()} + | {:transforms, [Toml.Transform.t()]} + @type opts :: [opt] + + @type reason :: {:invalid_toml, binary} | binary + @type error :: {:error, reason} + + @doc """ + Decode the given binary as TOML content + + ## Options + + You can pass the following options to configure the decoder behavior: + + * `:filename` - pass a filename to use in error messages + * `:keys` - controls how keys in the document are decoded. Possible values are: + * `:strings` (default) - decodes keys as strings + * `:atoms` - converts keys to atoms with `String.to_atom/1` + * `:atoms!` - converts keys to atoms with `String.to_existing_atom/1` + * `(key -> term)` - converts keys using the provided function + * `:transforms` - a list of custom transformations to apply to decoded TOML values, + see `c:Toml.Transform.transform/2` for details. + + ## Decoding keys to atoms + + The `:atoms` option uses the `String.to_atom/1` call that can create atoms at runtime. + Since the atoms are not garbage collected, this can pose a DoS attack vector when used + on user-controlled data. It is recommended that if you either avoid converting to atoms, + by using `keys: :strings`, or require known keys, by using the `keys: :atoms!` option, + which will cause decoding to fail if the key is not an atom already in the atom table. + + ## Transformations + + You should rarely need custom datatype transformations, but in some cases it can be quite + useful. In particular if you want to transform things like IP addresses from their string + form to the Erlang address tuples used in most `:inet` APIs, a custom transform can ensure + that all addresses are usable right away, and that validation of those addresses is done as + part of decoding the document. + + Keep in mind that transforms add additional work to decoding, which may result in reduced + performance, if you don't need the convenience, or the validation, deferring such conversions + until the values are used may be a better approach, rather than incurring the overhead during decoding. + """ + @spec decode(binary) :: {:ok, map} | error + @spec decode(binary, opts) :: {:ok, map} | error + defdelegate decode(bin, opts \\ []), to: __MODULE__.Decoder + + @doc """ + Same as `decode/1`, but returns the document directly, or raises `Toml.Error` if it fails. + """ + @spec decode!(binary) :: map | no_return + @spec decode!(binary, opts) :: map | no_return + defdelegate decode!(bin, opts \\ []), to: __MODULE__.Decoder + + @doc """ + Decode the file at the given path as TOML + + Takes same options as `decode/2` + """ + @spec decode_file(binary) :: {:ok, map} | error + @spec decode_file(binary, opts) :: {:ok, map} | error + defdelegate decode_file(path, opts \\ []), to: __MODULE__.Decoder + + @doc """ + Same as `decode_file/1`, but returns the document directly, or raises `Toml.Error` if it fails. + """ + @spec decode_file!(binary) :: map | no_return + @spec decode_file!(binary, opts) :: map | no_return + defdelegate decode_file!(path, opts \\ []), to: __MODULE__.Decoder + + @doc """ + Decode the given stream as TOML. + + Takes same options as `decode/2` + """ + @spec decode_stream(Enumerable.t()) :: {:ok, map} | error + @spec decode_stream(Enumerable.t(), opts) :: {:ok, map} | error + defdelegate decode_stream(stream, opts \\ []), to: __MODULE__.Decoder + + @doc """ + Same as `decode_stream/1`, but returns the document directly, or raises `Toml.Error` if it fails. + """ + @spec decode_stream!(Enumerable.t()) :: map | no_return + @spec decode_stream!(Enumerable.t(), opts) :: map | no_return + defdelegate decode_stream!(stream, opts \\ []), to: __MODULE__.Decoder +end diff --git a/test-community-packages-javascript/build/packages/toml/lib/transform.ex b/test-community-packages-javascript/build/packages/toml/lib/transform.ex new file mode 100644 index 00000000000..78cd21741b7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/lib/transform.ex @@ -0,0 +1,127 @@ +defmodule Toml.Transform do + @moduledoc """ + Defines the behavior for custom transformations of decoded TOML values. + + See the documentation for `c:transform/2` for more details. + """ + + @type t :: module + @type key :: binary | atom | term + @type keypath :: [binary] | [atom] | [term] + @type value :: + %{key => value} + | [value] + | number + | binary + | NaiveDateTime.t() + | DateTime.t() + | Date.t() + | Time.t() + + def __using__(_) do + quote do + @behaviour unquote(__MODULE__) + end + end + + @doc """ + This function is invoked for every key/value pair in the document, in a depth-first, + bottom-up, traversal of the document. + + The transformer must return one of two values: + + * `{:error, term}` - an error occurred in the transformer, and decoding should fail + * `term` - replace the value for the given key with the value returned from the + transformer in the final document + + ## Example + + An example transformation would be the conversion of tables of a certain shape to a known struct value. + + The struct: + + defmodule Server do + defstruct [:name, :ip, :ports] + end + + + TOML which contains a table of this shape: + + [servers.alpha] + ip = "192.168.1.1" + ports = [8080, 8081] + + [servers.beta] + ip = "192.168.1.2" + ports = [8082, 8083] + + + And finally, the transforer implementation: + + defmodule ServerTransform do + use Toml.Transform + + # Transform IP strings to Erlang address tuples + def transform(:ip, ip) when is_binary(ip) do + case :inet.parse_ipv4_address(String.to_charlist(ip)) do + {:ok, result} -> + result + {:error, reason} -> + {:error, {:invalid_ip, ip, reason}} + end + end + + # Non-binary values for IP addresses should return an error + def transform(:ip, ip), do: {:error, {:invalid_ip, ip, :expected_string}} + + # Transform the server objects to Server structs + def transform(:servers, servers) when is_map(servers) do + for {name, server} <- servers do + struct(Server, Map.put(server, :name, name)) + end + end + + # Non-map values for servers should return an error + def transform(:servers, s), do: {:error, {:invalid_server, s}} + + # Ignore all other values + def transform(_key, v), do: v + end + + Assuming we decode with the following options: + + Toml.decode!(content, keys: :atoms, transforms: [ServerTransform]) + + The result would be: + + %{ + servers: [ + %Server{name: :alpha, ip: {192,168,1,1}, ports: [8080, 8081]}, + %Server{name: :beta, ip: {192,168,1,2}, ports: [8082, 8083]} + ] + } + + """ + @callback transform(key, value) :: {:error, term} | term + + # Given a list of transform functions, compose them into a single transformation pass + @doc false + def compose(mods) when is_list(mods) do + Enum.reduce(mods, nil, &compose_transforms/2) + end + + # The first transform in the list does not require composition + defp compose_transforms(mod, nil), do: &mod.transform/2 + # All subsequent transforms are composed with the previous + defp compose_transforms(mod, acc) when is_atom(mod) and is_function(acc) do + fn k, v -> + case acc.(k, v) do + {:error, _} = err -> + throw(err) + + v2 -> + mod.transform(k, v2) + end + end + end +end diff --git a/test-community-packages-javascript/build/packages/toml/mix.exs b/test-community-packages-javascript/build/packages/toml/mix.exs new file mode 100644 index 00000000000..cc5511df9f2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/toml/mix.exs @@ -0,0 +1,125 @@ +defmodule Toml.MixProject do + use Mix.Project + + @version "0.7.0" + @source_url "https://github.com/bitwalker/toml-elixir" + + def project do + [ + app: :toml, + version: @version, + elixir: "~> 1.9", + start_permanent: Mix.env() == :prod, + consolidate_protocols: Mix.env() != :test, + description: "An implementation of TOML for Elixir projects", + package: package(), + deps: deps(), + aliases: aliases(Mix.env()), + preferred_cli_env: [ + bench: :bench, + "bench.decoder": :bench, + "bench.lexer": :bench, + docs: :docs, + "hex.publish": :docs, + coveralls: :test, + "coveralls.html": :test, + "coveralls.details": :test + ], + dialyzer: dialyzer(), + docs: docs(), + elixirc_paths: elixirc_paths(Mix.env()), + escript: escript(Mix.env()), + test_coverage: [tool: ExCoveralls] + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:ex_doc, ">= 0.0.0", only: [:docs]}, + {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, + {:benchee, "~> 1.0", only: [:bench]}, + {:benchee_html, "~> 1.0", only: [:bench]}, + {:jason, "~> 1.0", only: [:test, :bench]}, + {:excoveralls, "~> 0.9", only: [:test]} + # For benchmarking, though none of these libraries work at this point + # {:tomlex, "~> 0.0.5", only: [:bench]}, + # {:toml_elixir, "~> 2.0.1", only: [:bench]}, + # {:jerry, "~> 0.1.4", only: [:bench]}, + # {:etoml, "~> 0.1.0", only: [:bench]}, + ] + end + + defp package do + [ + files: ["lib", "mix.exs", "README.md", "LICENSE"], + maintainers: ["Paul Schoenfelder"], + licenses: ["Apache-2.0"], + links: %{"GitHub" => @source_url} + ] + end + + defp docs do + [ + main: "readme", + source_url: @source_url, + source_ref: @version, + extras: [ + LICENSE: [title: "License"], + "README.md": [title: "Overview"] + ], + formatters: ["html"] + ] + end + + defp escript(:test) do + [ + main_module: Toml.CLI, + name: :toml, + path: Path.join([__DIR__, "bin", "toml"]) + ] + end + + defp escript(_), do: nil + + defp aliases(_env) do + [ + "compile-check": [ + "compile --warnings-as-errors", + "format --check-formatted --dry-run", + "dialyzer --format dialyxir" + ], + clean: ["clean", &clean/1], + bench: ["bench.decoder", "bench.lexer"], + "bench.decoder": ["run bench/bench.decoder.exs"], + "bench.lexer": ["run bench/bench.lexer.exs"] + ] + end + + defp elixirc_paths(:test), do: ["lib", "test/support"] + defp elixirc_paths(:bench), do: ["lib", "bench/support"] + defp elixirc_paths(_), do: ["lib"] + + defp dialyzer do + [ + ignore_warnings: "dialyzer.ignore", + flags: [:error_handling, :underspecs], + plt_core_path: System.get_env("PLT_PATH") || System.get_env("MIX_HOME") + ] + end + + defp clean(_args) do + toml = Path.join([__DIR__, "bin", "toml"]) + + if File.exists?(toml) do + _ = File.rm(toml) + end + end +end diff --git a/test-community-packages-javascript/build/packages/trie_again/LICENSE b/test-community-packages-javascript/build/packages/trie_again/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/trie_again/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/test-community-packages-javascript/build/packages/trie_again/README.md b/test-community-packages-javascript/build/packages/trie_again/README.md new file mode 100644 index 00000000000..0dbd9478a04 --- /dev/null +++ b/test-community-packages-javascript/build/packages/trie_again/README.md @@ -0,0 +1,62 @@ +# trie_again + +[![Package Version](https://img.shields.io/hexpm/v/trie_again)](https://hex.pm/packages/trie_again) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/trie_again/) +![CI](https://github.com/giacomocavalieri/trie_again/workflows/CI/badge.svg?branch=main) + +Tries in Gleam 🌳 + +> ⚙️ This package supports the Erlang and Javascript targets! + +## Why tries? + +A [trie](https://en.wikipedia.org/wiki/Trie) is a data structure that uses lists as keys. By taking advantage of this property it is possible to efficiently perform some queries: for example imagine you want to find all the elements that are associated with a key with the same prefix; with a trie the complexity of the lookup is linear in the size of the prefix you're looking for. + +That is why tries can be used to implement autocompleting text dictionaries, spell checking or prefix matching algorithms. + +In this example a trie is used to store words (as lists of graphemes) as keys associated with a definition. With the `subtrie` function one can look for all the elements sharing a commong prefix in their key: + +```gleam +import trie +import string + +let dictionary = + trie.new() + |> trie.insert(at: string.to_graphemes("gleam"), value: "To produce a small, bright light") + |> trie.insert(at: string.to_graphemes("gleaming"), value: "Bright and shiny") + |> trie.insert(at: string.to_graphemes("beam"), value: "A line of light that shines from a bright object") + +dictionary +|> trie.subtrie(at: ["g", "l"]) +|> trie.to_list +// -> [ +// #(["g", "l", "e", "a", "m"], "To produce a small, bright light"), +// #(["g", "l", "e", "a", "m", "i", "n", "g"], "Bright and shiny"), +// ] +``` + +## Installation + +To add this package to your Gleam project: + +```sh +gleam add trie_again +``` + +## Usage + +Import the `trie` module and write some code! You can find many examples of how the different functions work in the [project documentation](https://hexdocs.pm/trie_again/). + +```gleam +import trie + +trie.new() +|> trie.insert(at: ["c", "a", "r"], value: 1) +|> trie.insert(at: ["c", "a", "t"], value: 10) +|> trie.get(at: ["c", "a", "t"]) +// -> Ok(10) +``` + +## Contributing + +If you think there's any way to improve this package, or if you spot a bug don't be afraid to open PRs, issues or requests of any kind! Any contribution is welcome 💜 diff --git a/test-community-packages-javascript/build/packages/trie_again/gleam.toml b/test-community-packages-javascript/build/packages/trie_again/gleam.toml new file mode 100644 index 00000000000..75fa79b7bcd --- /dev/null +++ b/test-community-packages-javascript/build/packages/trie_again/gleam.toml @@ -0,0 +1,12 @@ +name = "trie_again" +version = "1.1.1" +description = "Tries in Gleam" +licences = ["Apache-2.0"] +repository = { type = "github", user = "giacomocavalieri", repo = "trie_again" } +links = [] + +[dependencies] +gleam_stdlib = "~> 0.29" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl b/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl new file mode 100644 index 00000000000..b5da5c01430 --- /dev/null +++ b/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl @@ -0,0 +1,4 @@ +-record(trie, { + entry :: gleam@option:option(any()), + children_map :: gleam@map:map_(any(), trie:trie(any(), any())) +}). diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie.erl b/test-community-packages-javascript/build/packages/trie_again/src/trie.erl new file mode 100644 index 00000000000..47d83f03ca4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/trie_again/src/trie.erl @@ -0,0 +1,232 @@ +-module(trie). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([map/2, new/0, delete/2, fold/3, paths/1, size/1, is_empty/1, to_list/1, values/1, insert/3, from_list/1, singleton/2, get/2, has_path/2, subtrie/2, update/3]). +-export_type([trie/2]). + +-opaque trie(EWX, EWY) :: {trie, + gleam@option:option(EWY), + gleam@map:map_(EWX, trie(EWX, EWY))}. + +-spec do_delete(trie(EXG, EXH), list(EXG)) -> gleam@option:option(trie(EXG, EXH)). +do_delete(Trie, Path) -> + case {Path, Trie} of + {[], {trie, _, Children_map}} -> + case gleam@map:size(Children_map) of + 0 -> + none; + + _ -> + {some, {trie, none, Children_map}} + end; + + {[First | Rest], {trie, Entry, Children_map@1}} -> + New_children = case gleam@map:get(Children_map@1, First) of + {error, _} -> + Children_map@1; + + {ok, Child} -> + case do_delete(Child, Rest) of + none -> + gleam@map:delete(Children_map@1, First); + + {some, Trie@1} -> + gleam@map:insert(Children_map@1, First, Trie@1) + end + end, + case {Entry, gleam@map:size(New_children)} of + {none, 0} -> + none; + + {_, _} -> + {some, {trie, Entry, New_children}} + end + end. + +-spec map(trie(EYX, EYY), fun((EYY) -> EZB)) -> trie(EYX, EZB). +map(Trie, Fun) -> + {trie, + gleam@option:map(erlang:element(2, Trie), Fun), + gleam@map:map_values( + erlang:element(3, Trie), + fun(_, T) -> map(T, Fun) end + )}. + +-spec new() -> trie(any(), any()). +new() -> + {trie, none, gleam@map:new()}. + +-spec delete(trie(EWZ, EXA), list(EWZ)) -> trie(EWZ, EXA). +delete(Trie, Path) -> + _pipe = do_delete(Trie, Path), + gleam@option:unwrap(_pipe, new()). + +-spec fold(trie(EXO, EXP), EXS, fun((EXS, list(EXO), EXP) -> EXS)) -> EXS. +fold(Trie, Initial, Fun) -> + gleam@map:fold( + erlang:element(3, Trie), + begin + _pipe = erlang:element(2, Trie), + _pipe@1 = gleam@option:map( + _pipe, + fun(_capture) -> Fun(Initial, [], _capture) end + ), + gleam@option:unwrap(_pipe@1, Initial) + end, + fun(Acc, First, Trie@1) -> + fold( + Trie@1, + Acc, + fun(Acc@1, Rest, Value) -> Fun(Acc@1, [First | Rest], Value) end + ) + end + ). + +-spec paths(trie(EZI, any())) -> list(list(EZI)). +paths(Trie) -> + fold(Trie, [], fun(Rest, Path, _) -> [Path | Rest] end). + +-spec size(trie(any(), any())) -> integer(). +size(Trie) -> + fold(Trie, 0, fun(Acc, _, _) -> Acc + 1 end). + +-spec is_empty(trie(any(), any())) -> boolean(). +is_empty(Trie) -> + size(Trie) =:= 0. + +-spec to_list(trie(FAG, FAH)) -> list({list(FAG), FAH}). +to_list(Trie) -> + fold(Trie, [], fun(Rest, Path, Value) -> [{Path, Value} | Rest] end). + +-spec values(trie(any(), FBG)) -> list(FBG). +values(Trie) -> + fold(Trie, [], fun(Values, _, Value) -> [Value | Values] end). + +-spec insert(trie(EYM, EYN), list(EYM), EYN) -> trie(EYM, EYN). +insert(Trie, Path, Value) -> + case {Path, Trie} of + {[], {trie, _, Children_map}} -> + {trie, {some, Value}, Children_map}; + + {[First | Rest], {trie, Entry, Children_map@1}} -> + _pipe = gleam@map:get(Children_map@1, First), + _pipe@1 = gleam@result:unwrap(_pipe, new()), + _pipe@2 = insert(_pipe@1, Rest, Value), + _pipe@3 = gleam@map:insert(Children_map@1, First, _pipe@2), + {trie, Entry, _pipe@3} + end. + +-spec from_list(list({list(EXU), EXW})) -> trie(EXU, EXW). +from_list(List) -> + gleam@list:fold( + List, + new(), + fun(Trie, Pair) -> + insert(Trie, erlang:element(1, Pair), erlang:element(2, Pair)) + end + ). + +-spec singleton(list(EZO), EZQ) -> trie(EZO, EZQ). +singleton(Path, Value) -> + insert(new(), Path, Value). + +-spec get(trie(EYA, EYB), list(EYA)) -> {ok, EYB} | {error, nil}. +get(From, Path) -> + case {Path, From} of + {[], {trie, none, _}} -> + {error, nil}; + + {[], {trie, {some, Value}, _}} -> + {ok, Value}; + + {[First | Rest], {trie, _, Children_map}} -> + _pipe = Children_map, + _pipe@1 = gleam@map:get(_pipe, First), + gleam@result:then(_pipe@1, fun(_capture) -> get(_capture, Rest) end) + end. + +-spec has_path(trie(EYH, any()), list(EYH)) -> boolean(). +has_path(Trie, Path) -> + case get(Trie, Path) of + {ok, _} -> + true; + + {error, _} -> + false + end. + +-spec subtrie(trie(EZX, EZY), list(EZX)) -> {ok, trie(EZX, EZY)} | {error, nil}. +subtrie(Trie, Prefix) -> + case {Prefix, Trie} of + {[], _} -> + {ok, Trie}; + + {[First | Rest], {trie, _, Children_map}} -> + _pipe = Children_map, + _pipe@1 = gleam@map:get(_pipe, First), + _pipe@2 = gleam@result:'try'( + _pipe@1, + fun(_capture) -> subtrie(_capture, Rest) end + ), + gleam@result:map(_pipe@2, fun(Subtrie) -> _pipe@3 = gleam@map:new(), + _pipe@4 = gleam@map:insert(_pipe@3, First, Subtrie), + {trie, none, _pipe@4} end) + end. + +-spec do_update( + trie(FAV, FAW), + list(FAV), + fun((gleam@option:option(FAW)) -> gleam@option:option(FAW)) +) -> gleam@option:option(trie(FAV, FAW)). +do_update(Trie, Path, Fun) -> + case {Path, Trie} of + {[], {trie, Entry, Children_map}} -> + case {Fun(Entry), gleam@map:size(Children_map)} of + {none, 0} -> + none; + + {_ = New_entry, _} -> + {some, {trie, New_entry, Children_map}} + end; + + {[First | Rest], {trie, Entry@1, Children_map@1}} -> + New_children = case gleam@map:get(Children_map@1, First) of + {ok, Child} -> + case do_update(Child, Rest, Fun) of + none -> + gleam@map:delete(Children_map@1, First); + + {some, New_child} -> + gleam@map:insert(Children_map@1, First, New_child) + end; + + {error, _} -> + case Fun(none) of + none -> + Children_map@1; + + {some, Value} -> + gleam@map:insert( + Children_map@1, + First, + singleton(Rest, Value) + ) + end + end, + case {Entry@1, gleam@map:size(New_children)} of + {none, 0} -> + none; + + {_, _} -> + {some, {trie, Entry@1, New_children}} + end + end. + +-spec update( + trie(FAM, FAN), + list(FAM), + fun((gleam@option:option(FAN)) -> gleam@option:option(FAN)) +) -> trie(FAM, FAN). +update(Trie, Path, Fun) -> + _pipe = do_update(Trie, Path, Fun), + gleam@option:unwrap(_pipe, new()). diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam b/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam new file mode 100644 index 00000000000..406e483a2dd --- /dev/null +++ b/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam @@ -0,0 +1,466 @@ +import gleam/list +import gleam/map.{Map} +import gleam/option.{None, Option, Some} +import gleam/result + +/// A `Trie(k, v)` is a data structure that allows to store values of type `v` indexed by lists +/// of values of type `k`. +/// +pub opaque type Trie(k, v) { + /// The trie constructor, its implementation is based on the one described by Okasaki in + /// Purely Functional Data Structures. + /// + Trie(entry: Option(v), children_map: Map(k, Trie(k, v))) +} + +/// Deletes from a trie the value associated with a given path. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2], "a"), #([1], "b")] +/// > |> from_list +/// > |> delete(at: [1, 2]) +/// > |> to_list +/// [#([1], "b")] +/// ``` +/// +/// ```gleam +/// > new() +/// > |> delete(at: [1, 2]) +/// > |> to_list +/// [] +/// ``` +/// +pub fn delete(from trie: Trie(k, v), at path: List(k)) -> Trie(k, v) { + do_delete(from: trie, at: path) + |> option.unwrap(new()) +} + +/// Exactly same behaviour as delete but returns `None` if the tree is empty as a +/// result of the deletion. +/// +fn do_delete(from trie: Trie(k, v), at path: List(k)) -> Option(Trie(k, v)) { + case path, trie { + [], Trie(_, children_map) -> + case map.size(children_map) { + 0 -> None + _ -> Some(Trie(None, children_map)) + } + [first, ..rest], Trie(entry, children_map) -> { + let new_children = case map.get(children_map, first) { + Error(_) -> children_map + Ok(child) -> + case do_delete(from: child, at: rest) { + None -> map.delete(children_map, first) + Some(trie) -> map.insert(children_map, first, trie) + } + } + case entry, map.size(new_children) { + None, 0 -> None + _, _ -> Some(Trie(entry, new_children)) + } + } + } +} + +/// Combines all the trie's values into a single one by calling a given function on each one. +/// +/// The function takes as input the accumulator, the path of a value and the corresponding value. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2], 10), #([1], 1)] +/// > |> from_list +/// > |> fold(from: 0, with: fn(sum, _, value) { sum + value }) +/// 11 +/// ``` +/// +pub fn fold( + over trie: Trie(k, a), + from initial: b, + with fun: fn(b, List(k), a) -> b, +) -> b { + map.fold( + over: trie.children_map, + from: trie.entry + |> option.map(fun(initial, [], _)) + |> option.unwrap(initial), + with: fn(acc, first, trie) { + fold( + over: trie, + from: acc, + with: fn(acc, rest, value) { fun(acc, [first, ..rest], value) }, + ) + }, + ) +} + +/// Creates a new trie from a list of path-value pairs. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2], "a"), #([1], "b")] +/// > |> from_list +/// > |> to_list +/// [#([1, 2], "a"), #([1], "b")] +/// ``` +/// +pub fn from_list(list: List(#(List(k), v))) -> Trie(k, v) { + list.fold( + over: list, + from: new(), + with: fn(trie, pair) { insert(trie, pair.0, pair.1) }, + ) +} + +/// Fetches a value from a trie for a given path. +/// If a value is present at the given path it returns it wrapped in an `Ok`, +/// otherwise it returns `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> get(at: [1, 2]) +/// Result(Nil) +/// ``` +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> get(at: [1, 2]) +/// Ok("a") +/// ``` +/// +pub fn get(from: Trie(k, v), at path: List(k)) -> Result(v, Nil) { + case path, from { + [], Trie(None, _) -> Error(Nil) + [], Trie(Some(value), _) -> Ok(value) + [first, ..rest], Trie(_, children_map) -> + children_map + |> map.get(first) + |> result.then(get(_, rest)) + } +} + +/// Determines wether a trie contains a value associated with the given path. +/// +/// ## Examples +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> has_path([1, 2]) +/// True +/// ``` +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> has_path([1]) +/// False +/// ``` +/// +pub fn has_path(trie: Trie(k, v), path: List(k)) -> Bool { + case get(trie, path) { + Ok(_) -> True + Error(_) -> False + } +} + +/// Inserts a value in a trie at a given path. If there already is a value +/// at the given path it is replaced by the new one. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(at: [1, 2], value: "a") +/// > |> insert(at: [1], value: "b") +/// > |> to_list +/// [#([1, 2], "a"), #([1], "b")] +/// ``` +/// +/// ```gleam +/// > new() +/// > |> insert(at: [1, 2], value: "a") +/// > |> insert(at: [1, 2], value: "b") +/// > |> to_list +/// [#([1, 2], "b")] +/// ``` +/// +pub fn insert( + into trie: Trie(k, v), + at path: List(k), + value value: v, +) -> Trie(k, v) { + case path, trie { + [], Trie(_, children_map) -> Trie(Some(value), children_map) + [first, ..rest], Trie(entry, children_map) -> { + map.get(children_map, first) + |> result.unwrap(new()) + |> insert(rest, value) + |> map.insert(children_map, first, _) + |> Trie(entry, _) + } + } +} + +/// Determines wether or not the trie is empty. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> is_empty +/// False +/// ``` +/// +pub fn is_empty(trie: Trie(k, v)) -> Bool { + size(trie) == 0 +} + +/// Updates all the values in a given trie by calling a function on each value. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2], "a"), #([1], "b")] +/// > |> from_list +/// > |> map(fn(s) { s <> "!" }) +/// > |> to_list +/// [#([1, 2], "a!"), #([1], "b!")] +/// ``` +/// +pub fn map(over trie: Trie(k, v), with fun: fn(v) -> a) -> Trie(k, a) { + Trie( + option.map(trie.entry, fun), + map.map_values(trie.children_map, fn(_, t) { map(t, fun) }), + ) +} + +/// Creates a new empty trie. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> to_list +/// [] +/// ``` +/// +pub fn new() -> Trie(k, v) { + Trie(None, map.new()) +} + +/// Gets a list of all the valid paths in the trie. That is all the paths associated with a value. +/// +/// Tries are not ordered so the paths are not returned in any specific order. +/// Do not write code that relies on the order paths are returned by this function +/// as it may change in later versions of the library. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2], "a"), #([1], "b")] +/// > |> from_list +/// > |> paths +/// [[1, 2], [1]] +/// ``` +/// +/// ```gleam +/// > new() +/// > |> paths +/// [] +/// ``` +pub fn paths(trie: Trie(k, v)) -> List(List(k)) { + fold(over: trie, from: [], with: fn(rest, path, _) { [path, ..rest] }) +} + +/// Creates a new trie with a single value associated to the given path. +/// +/// ## Examples +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> to_list +/// [#([1, 2], "a")] +/// ``` +/// +pub fn singleton(path: List(k), value: v) -> Trie(k, v) { + insert(new(), at: path, value: value) +} + +/// Gets the number of elements in the trie. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2], "a"), #([1], "b")] +/// > |> from_list +/// > |> size +/// 2 +/// ``` +/// +pub fn size(trie: Trie(k, v)) -> Int { + fold(trie, from: 0, with: fn(acc, _, _) { acc + 1 }) +} + +/// Gets the subtrie whose elements all share a common given prefix. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2, 3], "a"), #([1, 2, 4, 5], "b"), #([3, 4], "c")] +/// > |> from_list +/// > |> subtrie(at: [1, 2]) +/// > |> to_list +/// [#([1, 2, 3], "a"), #([1, 2, 4, 5], "b")] +/// ``` +/// +pub fn subtrie(trie: Trie(k, v), at prefix: List(k)) -> Result(Trie(k, v), Nil) { + case prefix, trie { + [], _ -> Ok(trie) + [first, ..rest], Trie(_, children_map) -> + children_map + |> map.get(first) + |> result.try(subtrie(_, rest)) + |> result.map(fn(subtrie) { + map.new() + |> map.insert(first, subtrie) + |> Trie(None, _) + }) + } +} + +/// Turns a trie into a list of path-value pairs. +/// +/// ## Examples +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> to_list +/// [#([1, 2], "a")] +/// ``` +/// +/// ```gleam +/// > new() +/// > |> to_list +/// [] +/// ``` +/// +pub fn to_list(trie: Trie(k, v)) -> List(#(List(k), v)) { + fold( + over: trie, + from: [], + with: fn(rest, path, value) { [#(path, value), ..rest] }, + ) +} + +/// Updates the value associated with a path applying it the given function. +/// If there is no value associated with the given path the function is passed `None`. +/// +/// If the function returns `None` any value associated with the path is deleted from the trie. +/// If the function returns `Some(value)` then the new value is associated to the given path. +/// +/// ## Examples +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> update(at: [1, 2], with: fn(n) { n |> option.map(fn(_) { "b" }) }) +/// > |> to_list +/// [#([1, 2], "b")] +/// ``` +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> update(at: [1, 2], with: fn(_) { None }) +/// > |> to_list +/// [] +/// ``` +/// +/// ```gleam +/// > singleton([1, 2], "a") +/// > |> update(at: [1], with: fn(_) { Some("b") }) +/// > |> to_list +/// [#([1, 2], "a"), #([1], "b")] +/// ``` +/// +pub fn update( + trie: Trie(k, v), + at path: List(k), + with fun: fn(Option(v)) -> Option(v), +) -> Trie(k, v) { + do_update(trie, at: path, with: fun) + |> option.unwrap(new()) +} + +/// Exactly same behaviour as update but returns `None` if the tree is empty as a +/// result of the (possible) deletion. +/// +fn do_update( + trie: Trie(k, v), + at path: List(k), + with fun: fn(Option(v)) -> Option(v), +) -> Option(Trie(k, v)) { + case path, trie { + [], Trie(entry, children_map) -> { + case fun(entry), map.size(children_map) { + None, 0 -> None + _ as new_entry, _ -> Some(Trie(new_entry, children_map)) + } + } + [first, ..rest], Trie(entry, children_map) -> { + let new_children = case map.get(children_map, first) { + Ok(child) -> + case do_update(child, at: rest, with: fun) { + None -> map.delete(children_map, first) + Some(new_child) -> map.insert(children_map, first, new_child) + } + Error(_) -> { + case fun(None) { + None -> children_map + Some(value) -> + map.insert(children_map, first, singleton(rest, value)) + } + } + } + + case entry, map.size(new_children) { + None, 0 -> None + _, _ -> Some(Trie(entry, new_children)) + } + } + } +} + +/// Gets a list of all the values in a given trie. +/// +/// Tries are not ordered so the values are not returned in any specific order. +/// Do not write code that relies on the order values are returned by this function +/// as it may change in later versions of the library. +/// +/// ## Examples +/// +/// ```gleam +/// > [#([1, 2], "a"), #([1], "b")] +/// > |> from_list +/// > |> values +/// ["a", "b"] +/// ``` +/// +/// ```gleam +/// > new() +/// > |> values +/// [] +/// ``` +/// +pub fn values(trie: Trie(k, v)) -> List(v) { + fold(trie, from: [], with: fn(values, _, value) { [value, ..values] }) +} diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src b/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src new file mode 100644 index 00000000000..e48a5f7a864 --- /dev/null +++ b/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src @@ -0,0 +1,8 @@ +{application, trie_again, [ + {vsn, "1.1.1"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Tries in Gleam"}, + {modules, [trie]}, + {registered, []} +]}. From de2ba27f63e627b67aae6ccd5572e546d6165af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Tue, 9 Apr 2024 20:06:17 +0200 Subject: [PATCH 02/11] Make AST traversal more efficient * pruning on definition nodes * pruning on statement nodes * early exit list, block and tuple expressions --- compiler-core/Cargo.toml | 2 + compiler-core/src/ast.rs | 79 ++++++++++++++++++-------------- compiler-core/src/ast/tests.rs | 83 ++++++++++++++++++++++++++++++++++ compiler-core/src/ast/typed.rs | 33 +++++++++++--- 4 files changed, 156 insertions(+), 41 deletions(-) diff --git a/compiler-core/Cargo.toml b/compiler-core/Cargo.toml index 43d9e200083..d281c9f6373 100644 --- a/compiler-core/Cargo.toml +++ b/compiler-core/Cargo.toml @@ -42,6 +42,8 @@ pubgrub = "0.2" pathdiff = { version = "0.2.1", features = ["camino"] } # Memory arena using ids rather than references id-arena = "2.1" +# Assert certain code path executions +cov-mark = "2.0.0-pre.1" async-trait.workspace = true base16.workspace = true bytes.workspace = true diff --git a/compiler-core/src/ast.rs b/compiler-core/src/ast.rs index f21e1e60a0f..fd436fbc155 100644 --- a/compiler-core/src/ast.rs +++ b/compiler-core/src/ast.rs @@ -574,33 +574,37 @@ impl TypedDefinition { pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { match self { Definition::Function(function) => { - if let Some(found) = function.body.iter().find_map(|s| s.find_node(byte_index)) { - return Some(found); - }; - - if let Some(found_arg) = function - .arguments - .iter() - .find(|arg| arg.location.contains(byte_index)) - { - return Some(Located::Arg(found_arg)); - }; - - if let Some(found_statement) = function - .body - .iter() - .find(|statement| statement.location().contains(byte_index)) - { - return Some(Located::Statement(found_statement)); - }; - - // Note that the fn `.location` covers the function head, not - // the entire statement. - if function.location.contains(byte_index) { - Some(Located::ModuleStatement(self)) - } else if function.full_location().contains(byte_index) { + if function.full_location().contains(byte_index) { + if let Some(found) = function.body.iter().find_map(|s| s.find_node(byte_index)) + { + return Some(found); + }; + + if let Some(found_arg) = function + .arguments + .iter() + .find(|arg| arg.location.contains(byte_index)) + { + return Some(Located::Arg(found_arg)); + }; + + if let Some(found_statement) = function + .body + .iter() + .find(|statement| statement.location().contains(byte_index)) + { + return Some(Located::Statement(found_statement)); + }; + + // Note that the fn `.location` covers the function head, not + // the entire statement. + if function.location.contains(byte_index) { + return Some(Located::ModuleStatement(self)); + } + Some(Located::FunctionBody(function)) } else { + cov_mark::hit!(prune_function_definition); None } } @@ -1750,16 +1754,23 @@ impl TypedStatement { } pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { - match self { - Statement::Use(_) => None, - Statement::Expression(expression) => expression.find_node(byte_index), - Statement::Assignment(assignment) => assignment.find_node(byte_index).or_else(|| { - if assignment.location.contains(byte_index) { - Some(Located::Statement(self)) - } else { - None + if self.location().contains(byte_index) { + match self { + Statement::Use(_) => None, + Statement::Expression(expression) => expression.find_node(byte_index), + Statement::Assignment(assignment) => { + assignment.find_node(byte_index).or_else(|| { + if assignment.location.contains(byte_index) { + Some(Located::Statement(self)) + } else { + None + } + }) } - }), + } + } else { + cov_mark::hit!(prune_statement); + None } } diff --git a/compiler-core/src/ast/tests.rs b/compiler-core/src/ast/tests.rs index fb2763cb338..f24e8301d73 100644 --- a/compiler-core/src/ast/tests.rs +++ b/compiler-core/src/ast/tests.rs @@ -240,6 +240,15 @@ fn find_node_sequence() { assert!(block.find_node(7).is_none()); } +// The function exits early when attempting to find the AST node for a specific index, +// if the remaining elements have indices beyond the search index, returning none. +#[test] +fn find_node_sequence_early_exit() { + let block = compile_expression(r#"{ 1 2 3 }"#); + cov_mark::check!(early_exit_block); + assert!(block.find_node(1).is_none()); +} + #[test] fn find_node_list() { let statement = compile_expression(r#"[1, 2, 3]"#); @@ -273,6 +282,17 @@ fn find_node_list() { assert_eq!(list.find_node(9), None); } +// The function exits early when attempting to find the AST node for a specific index, +// if the remaining elements have indices beyond the search index, returning the list itself. +#[test] +fn find_node_list_early_exit() { + let statement = compile_expression(r#"[1, 2, 3]"#); + let list = get_bare_expression(&statement); + + cov_mark::check!(early_exit_tuple_list); + assert_eq!(list.find_node(2), Some(Located::Expression(list))); +} + #[test] fn find_node_tuple() { let statement = compile_expression(r#"#(1, 2, 3)"#); @@ -307,6 +327,17 @@ fn find_node_tuple() { assert_eq!(tuple.find_node(10), None); } +// The function exits early when attempting to find the AST node for a specific index, +// if the remaining elements have indices beyond the search index, returning the tuple itself. +#[test] +fn find_node_tuple_early_exit() { + let statement = compile_expression(r#"#(1, 2, 3)"#); + let tuple = get_bare_expression(&statement); + + cov_mark::check!(early_exit_tuple_list); + assert_eq!(tuple.find_node(3), Some(Located::Expression(tuple))); +} + #[test] fn find_node_binop() { let statement = compile_expression(r#"1 + 2"#); @@ -576,3 +607,55 @@ use x <- fn(f) { f(1) } assert!(use_.find_node(26).is_some()); // The int } + +// Check that the AST tree gets pruned at the definition level. +#[test] +fn find_node_with_pruning_definition() { + let module = compile_module( + r#" +pub fn main() { + 1 +} + +fn test1() { + 2 +} + +fn i_am_here(){ + 3 +} + "#, + ); + + let int3 = TypedExpr::Int { + location: SrcSpan { start: 68, end: 69 }, + typ: type_::int(), + value: "3".into(), + }; + + cov_mark::check!(prune_function_definition); //main() and test1() should be pruned + assert_eq!(module.find_node(68), Some(Located::Expression(&int3))); +} + +// Check that the AST tree gets pruned at the statement level. +#[test] +fn find_node_with_pruning_statement() { + let module = compile_module( + r#" +pub fn main() { + let s1 = 1 + let s2 = 2 + let s3 = 3 +} + "#, + ); + + let int3 = TypedExpr::Int { + location: SrcSpan { start: 60, end: 61 }, + typ: type_::int(), + value: "3".into(), + }; + + cov_mark::check!(prune_statement); //let s1 and let s2 should be pruned + assert_eq!(module.find_node(60), Some(Located::Expression(&int3))); +} diff --git a/compiler-core/src/ast/typed.rs b/compiler-core/src/ast/typed.rs index aa4b2a95238..05467cb0e5e 100644 --- a/compiler-core/src/ast/typed.rs +++ b/compiler-core/src/ast/typed.rs @@ -164,8 +164,6 @@ impl TypedExpr { } } - // This could be optimised in places to exit early if the first of a series - // of expressions is after the byte index. pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { match self { Self::Var { .. } @@ -186,7 +184,18 @@ impl TypedExpr { .or_else(|| finally.find_node(byte_index)), Self::Block { statements, .. } => { - statements.iter().find_map(|e| e.find_node(byte_index)) + for statement in statements { + if statement.location().start > byte_index { + cov_mark::hit!(early_exit_block); + break; + } + + if let Some(located) = statement.find_node(byte_index) { + return Some(located); + } + } + + None } Self::Tuple { @@ -195,10 +204,20 @@ impl TypedExpr { | Self::List { elements: expressions, .. - } => expressions - .iter() - .find_map(|e| e.find_node(byte_index)) - .or_else(|| self.self_if_contains_location(byte_index)), + } => { + for expression in expressions { + if expression.location().start > byte_index { + cov_mark::hit!(early_exit_tuple_list); + break; + } + + if let Some(located) = expression.find_node(byte_index) { + return Some(located); + } + } + + self.self_if_contains_location(byte_index) + } Self::NegateBool { value, .. } | Self::NegateInt { value, .. } => value .find_node(byte_index) From bd99302d5cf25de9ca8ebe836c11c5093ebee67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Tue, 9 Apr 2024 20:46:06 +0200 Subject: [PATCH 03/11] remove this folder? --- Cargo.lock | 7 + .../build/lsp/erlang/gleam_version | 1 - .../build/packages/gleam_bitwise/LICENSE | 191 -- .../build/packages/gleam_bitwise/README.md | 24 - .../build/packages/gleam_bitwise/gleam.toml | 16 - .../gleam_bitwise/src/gleam/bitwise.gleam | 91 - .../gleam_bitwise/src/gleam@bitwise.erl | 28 - .../gleam_bitwise/src/gleam_bitwise.app.src | 8 - .../gleam_bitwise/src/gleam_bitwise.mjs | 28 - .../packages/gleam_community_ansi/LICENCE | 190 -- .../packages/gleam_community_ansi/README.md | 72 - .../packages/gleam_community_ansi/gleam.toml | 13 - .../src/gleam_community/ansi.gleam | 2318 ----------------- .../src/gleam_community@ansi.erl | 263 -- .../src/gleam_community_ansi.app.src | 10 - .../packages/gleam_community_colour/LICENCE | 190 -- .../packages/gleam_community_colour/README.md | 36 - .../gleam_community_colour/gleam.toml | 12 - .../include/gleam_community@colour_Hsla.hrl | 1 - .../include/gleam_community@colour_Rgba.hrl | 1 - .../src/gleam_community/colour.gleam | 1127 -------- .../colour/accessibility.gleam | 173 -- .../src/gleam_community@colour.erl | 525 ---- .../gleam_community@colour@accessibility.erl | 75 - .../src/gleam_community_colour.app.src | 10 - .../build/packages/gleam_cors/LICENSE | 21 - .../build/packages/gleam_cors/README.md | 38 - .../build/packages/gleam_cors/gleam.toml | 13 - .../gleam_cors/src/gleam/http/cors.gleam | 227 -- .../gleam_cors/src/gleam@http@cors.erl | 243 -- .../gleam_cors/src/gleam_cors.app.src | 9 - .../build/packages/gleam_crypto/LICENSE | 191 -- .../build/packages/gleam_crypto/README.md | 13 - .../build/packages/gleam_crypto/gleam.toml | 17 - .../gleam_crypto/src/gleam/crypto.gleam | 135 - .../gleam_crypto/src/gleam@crypto.erl | 135 - .../gleam_crypto/src/gleam_crypto.app.src | 9 - .../build/packages/gleam_erlang/LICENSE | 191 -- .../build/packages/gleam_erlang/README.md | 34 - .../build/packages/gleam_erlang/gleam.toml | 17 - .../include/gleam@erlang@file_FileInfo.hrl | 15 - .../include/gleam@erlang@process_Abnormal.hrl | 1 - .../gleam@erlang@process_CalleeDown.hrl | 1 - .../gleam@erlang@process_Cancelled.hrl | 1 - .../gleam@erlang@process_ExitMessage.hrl | 4 - .../gleam@erlang@process_ProcessDown.hrl | 4 - .../gleam@erlang@process_ProcessMonitor.hrl | 1 - .../include/gleam@erlang@process_Subject.hrl | 4 - .../gleam@erlang_ApplicationFailedToStart.hrl | 4 - .../gleam@erlang_UnknownApplication.hrl | 1 - .../gleam_erlang/src/gleam/erlang.gleam | 143 - .../gleam_erlang/src/gleam/erlang/atom.gleam | 79 - .../src/gleam/erlang/charlist.gleam | 25 - .../gleam_erlang/src/gleam/erlang/file.gleam | 713 ----- .../gleam_erlang/src/gleam/erlang/os.gleam | 95 - .../src/gleam/erlang/process.gleam | 716 ----- .../gleam_erlang/src/gleam@erlang.erl | 86 - .../gleam_erlang/src/gleam@erlang@atom.erl | 26 - .../src/gleam@erlang@charlist.erl | 15 - .../gleam_erlang/src/gleam@erlang@file.erl | 190 -- .../gleam_erlang/src/gleam@erlang@os.erl | 27 - .../gleam_erlang/src/gleam@erlang@process.erl | 362 --- .../gleam_erlang/src/gleam_erlang.app.src | 13 - .../gleam_erlang/src/gleam_erlang_ffi.erl | 218 -- .../build/packages/gleam_http/LICENSE | 191 -- .../build/packages/gleam_http/README.md | 65 - .../build/packages/gleam_http/gleam.toml | 16 - .../include/gleam@http@cookie_Attributes.hrl | 8 - .../include/gleam@http@request_Request.hrl | 10 - .../include/gleam@http@response_Response.hrl | 5 - .../packages/gleam_http/src/gleam/http.gleam | 122 - .../gleam_http/src/gleam/http/cookie.gleam | 128 - .../gleam_http/src/gleam/http/request.gleam | 258 -- .../gleam_http/src/gleam/http/response.gleam | 141 - .../gleam_http/src/gleam/http/service.gleam | 82 - .../packages/gleam_http/src/gleam@http.erl | 124 - .../gleam_http/src/gleam@http@cookie.erl | 153 -- .../gleam_http/src/gleam@http@request.erl | 202 -- .../gleam_http/src/gleam@http@response.erl | 97 - .../gleam_http/src/gleam@http@service.erl | 82 - .../gleam_http/src/gleam_http.app.src | 12 - .../gleam_http/src/gleam_http_native.erl | 88 - .../gleam_http/src/gleam_http_native.mjs | 38 - .../build/packages/gleam_otp/LICENCE | 191 -- .../build/packages/gleam_otp/README.md | 91 - .../build/packages/gleam_otp/gleam.toml | 17 - .../include/gleam@otp@actor_Ready.hrl | 1 - .../include/gleam@otp@actor_Spec.hrl | 5 - ...otp@intensity_tracker_IntensityTracker.hrl | 5 - .../gleam@otp@supervisor_ChildSpec.hrl | 5 - .../include/gleam@otp@supervisor_Spec.hrl | 6 - .../include/gleam@otp@system_StatusInfo.hrl | 7 - .../gleam_otp/include/gleam@otp@task_Exit.hrl | 1 - .../gleam_otp/include/gleam@otp@task_Task.hrl | 6 - .../gleam_otp/src/gleam/otp/actor.gleam | 473 ---- .../src/gleam/otp/intensity_tracker.gleam | 46 - .../gleam_otp/src/gleam/otp/node.gleam | 1 - .../gleam_otp/src/gleam/otp/port.gleam | 9 - .../gleam_otp/src/gleam/otp/supervisor.gleam | 403 --- .../gleam_otp/src/gleam/otp/system.gleam | 89 - .../gleam_otp/src/gleam/otp/task.gleam | 151 -- .../gleam_otp/src/gleam@otp@actor.erl | 233 -- .../src/gleam@otp@intensity_tracker.erl | 53 - .../packages/gleam_otp/src/gleam@otp@node.erl | 8 - .../packages/gleam_otp/src/gleam@otp@port.erl | 8 - .../gleam_otp/src/gleam@otp@supervisor.erl | 322 --- .../gleam_otp/src/gleam@otp@system.erl | 43 - .../packages/gleam_otp/src/gleam@otp@task.erl | 111 - .../packages/gleam_otp/src/gleam_otp.app.src | 15 - .../gleam_otp/src/gleam_otp_external.erl | 43 - .../build/packages/gleam_stdlib/LICENCE | 191 -- .../build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 19 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../gleam_stdlib/src/gleam/base.gleam | 59 - .../gleam_stdlib/src/gleam/bit_builder.gleam | 276 -- .../gleam_stdlib/src/gleam/bit_string.gleam | 155 -- .../gleam_stdlib/src/gleam/bool.gleam | 388 --- .../gleam_stdlib/src/gleam/dynamic.gleam | 1613 ------------ .../gleam_stdlib/src/gleam/float.gleam | 589 ----- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 854 ------ .../packages/gleam_stdlib/src/gleam/io.gleam | 147 -- .../gleam_stdlib/src/gleam/iterator.gleam | 1442 ---------- .../gleam_stdlib/src/gleam/list.gleam | 2075 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 593 ----- .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 119 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 233 -- .../gleam_stdlib/src/gleam/result.gleam | 483 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 1046 -------- .../src/gleam/string_builder.gleam | 356 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 476 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 45 - .../gleam_stdlib/src/gleam@bit_builder.erl | 63 - .../gleam_stdlib/src/gleam@bit_string.erl | 56 - .../packages/gleam_stdlib/src/gleam@bool.erl | 152 -- .../gleam_stdlib/src/gleam@dynamic.erl | 794 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 193 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 323 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 707 ----- .../packages/gleam_stdlib/src/gleam@list.erl | 1082 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 97 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 75 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 393 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 255 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 28 - .../gleam_stdlib/src/gleam_stdlib.erl | 441 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 739 ------ .../gleam_stdlib/src/persistent-hash-map.mjs | 957 ------- .../packages/gleamy_structures/README.md | 27 - .../packages/gleamy_structures/gleam.toml | 15 - ...eamy_structures@heap@leftist_heap_Heap.hrl | 4 - ...eamy_structures@heap@pairing_heap_Heap.hrl | 4 - .../gleamy_structures@non_empty_list_End.hrl | 1 - .../gleamy_structures@non_empty_list_Next.hrl | 4 - ...tructures@tree@binary_search_tree_Tree.hrl | 4 - ...my_structures@tree@red_black_tree_Tree.hrl | 4 - ...structures@tree@red_black_tree_kv_Tree.hrl | 4 - .../src/gleamy_structures.app.src | 16 - .../gleamy_structures/heap/leftist_heap.gleam | 61 - .../gleamy_structures/heap/pairing_heap.gleam | 55 - .../src/gleamy_structures/map.gleam | 85 - .../gleamy_structures/non_empty_list.gleam | 63 - .../gleamy_structures/priority_queue.gleam | 54 - .../src/gleamy_structures/set.gleam | 91 - .../tree/binary_search_tree.gleam | 123 - .../tree/red_black_tree.gleam | 224 -- .../tree/red_black_tree_kv.gleam | 232 -- .../gleamy_structures@heap@leftist_heap.erl | 90 - .../gleamy_structures@heap@pairing_heap.erl | 75 - .../src/gleamy_structures@map.erl | 121 - .../src/gleamy_structures@non_empty_list.erl | 77 - .../src/gleamy_structures@priority_queue.erl | 74 - .../src/gleamy_structures@set.erl | 123 - ...amy_structures@tree@binary_search_tree.erl | 167 -- .../gleamy_structures@tree@red_black_tree.erl | 326 --- ...eamy_structures@tree@red_black_tree_kv.erl | 336 --- .../build/packages/gleeunit/LICENCE | 191 -- .../build/packages/gleeunit/README.md | 52 - .../build/packages/gleeunit/gleam.toml | 17 - .../packages/gleeunit/src/gleeunit.app.src | 8 - .../build/packages/gleeunit/src/gleeunit.erl | 59 - .../packages/gleeunit/src/gleeunit.gleam | 80 - .../gleeunit/src/gleeunit/should.gleam | 83 - .../packages/gleeunit/src/gleeunit@should.erl | 34 - .../packages/gleeunit/src/gleeunit_ffi.erl | 24 - .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 - .../gleeunit/src/gleeunit_progress.erl | 607 ----- .../build/packages/glenvy/LICENSE | 21 - .../build/packages/glenvy/README.md | 31 - .../build/packages/glenvy/gleam.toml | 13 - .../glenvy/include/glenvy@error_Io.hrl | 1 - .../build/packages/glenvy/src/glenvy.app.src | 16 - .../packages/glenvy/src/glenvy/dotenv.gleam | 42 - .../packages/glenvy/src/glenvy/env.gleam | 81 - .../packages/glenvy/src/glenvy/error.gleam | 5 - .../glenvy/src/glenvy/internal/file.gleam | 15 - .../glenvy/src/glenvy/internal/os.gleam | 26 - .../glenvy/src/glenvy/internal/parser.gleam | 69 - .../glenvy/src/glenvy/internal/string.gleam | 33 - .../packages/glenvy/src/glenvy@dotenv.erl | 40 - .../build/packages/glenvy/src/glenvy@env.erl | 69 - .../packages/glenvy/src/glenvy@error.erl | 8 - .../glenvy/src/glenvy@internal@file.erl | 9 - .../glenvy/src/glenvy@internal@os.erl | 16 - .../glenvy/src/glenvy@internal@parser.erl | 75 - .../glenvy/src/glenvy@internal@string.erl | 40 - .../build/packages/glenvy/src/glenvy_ffi.mjs | 32 - .../build/packages/glerm/README.md | 44 - .../gleam_community@ansi.cache | Bin 62841 -> 0 bytes .../gleam_community@ansi.cache_meta | Bin 114 -> 0 bytes .../gleam_community@colour.cache | Bin 27832 -> 0 bytes .../gleam_community@colour.cache_meta | Bin 123 -> 0 bytes ...gleam_community@colour@accessibility.cache | Bin 3072 -> 0 bytes ..._community@colour@accessibility.cache_meta | Bin 96 -> 0 bytes .../_gleam_artefacts/gleam@erlang.cache | Bin 8464 -> 0 bytes .../_gleam_artefacts/gleam@erlang.cache_meta | Bin 122 -> 0 bytes .../_gleam_artefacts/gleam@erlang@atom.cache | Bin 2814 -> 0 bytes .../gleam@erlang@atom.cache_meta | Bin 50 -> 0 bytes .../gleam@erlang@charlist.cache | Bin 789 -> 0 bytes .../gleam@erlang@charlist.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@erlang@file.cache | Bin 27622 -> 0 bytes .../gleam@erlang@file.cache_meta | Bin 72 -> 0 bytes .../_gleam_artefacts/gleam@erlang@node.cache | Bin 2992 -> 0 bytes .../gleam@erlang@node.cache_meta | Bin 54 -> 0 bytes .../_gleam_artefacts/gleam@erlang@os.cache | Bin 3171 -> 0 bytes .../gleam@erlang@os.cache_meta | Bin 46 -> 0 bytes .../gleam@erlang@process.cache | Bin 30881 -> 0 bytes .../gleam@erlang@process.cache_meta | Bin 115 -> 0 bytes .../_gleam_artefacts/gleam@otp@actor.cache | Bin 12240 -> 0 bytes .../gleam@otp@actor.cache_meta | Bin 196 -> 0 bytes .../gleam@otp@intensity_tracker.cache | Bin 2254 -> 0 bytes .../gleam@otp@intensity_tracker.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@otp@port.cache | Bin 273 -> 0 bytes .../gleam@otp@port.cache_meta | Bin 29 -> 0 bytes .../gleam@otp@supervisor.cache | Bin 14883 -> 0 bytes .../gleam@otp@supervisor.cache_meta | Bin 200 -> 0 bytes .../_gleam_artefacts/gleam@otp@system.cache | Bin 5222 -> 0 bytes .../gleam@otp@system.cache_meta | Bin 103 -> 0 bytes .../_gleam_artefacts/gleam@otp@task.cache | Bin 3940 -> 0 bytes .../gleam@otp@task.cache_meta | Bin 78 -> 0 bytes .../_gleam_artefacts/gleam_otp.cache | Bin 650 -> 0 bytes .../_gleam_artefacts/gleam_otp.cache_meta | Bin 130 -> 0 bytes .../_gleam_artefacts/gleam@base.cache | Bin 1223 -> 0 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 4956 -> 0 bytes .../gleam@bit_array.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 4184 -> 0 bytes .../gleam@bit_builder.cache_meta | Bin 84 -> 0 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 1934 -> 0 bytes .../gleam@bit_string.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 7081 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 48 -> 0 bytes .../gleam@bytes_builder.cache | Bin 6045 -> 0 bytes .../gleam@bytes_builder.cache_meta | Bin 98 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 12265 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 49248 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 173 -> 0 bytes .../_gleam_artefacts/gleam@float.cache | Bin 11372 -> 0 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 48 -> 0 bytes .../_gleam_artefacts/gleam@function.cache | Bin 5798 -> 0 bytes .../gleam@function.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@int.cache | Bin 18139 -> 0 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@io.cache | Bin 2856 -> 0 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 37907 -> 0 bytes .../gleam@iterator.cache_meta | Bin 141 -> 0 bytes .../_gleam_artefacts/gleam@list.cache | Bin 46246 -> 0 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 120 -> 0 bytes .../_gleam_artefacts/gleam@map.cache | Bin 4740 -> 0 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@option.cache | Bin 7258 -> 0 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@order.cache | Bin 2702 -> 0 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 1882 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 7021 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 6600 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@result.cache | Bin 10378 -> 0 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@set.cache | Bin 6383 -> 0 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 85 -> 0 bytes .../_gleam_artefacts/gleam@string.cache | Bin 21827 -> 0 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 136 -> 0 bytes .../gleam@string_builder.cache | Bin 10568 -> 0 bytes .../gleam@string_builder.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 7764 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 132 -> 0 bytes .../glerm/build/lsp/erlang/gleam_version | 1 - .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 3252 -> 0 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 108 -> 0 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 1132 -> 0 bytes .../gleeunit@should.cache_meta | Bin 29 -> 0 bytes .../packages/gleam_community_ansi/LICENCE | 190 -- .../packages/gleam_community_ansi/README.md | 72 - .../packages/gleam_community_ansi/gleam.toml | 13 - .../src/gleam_community/ansi.gleam | 2317 ---------------- .../src/gleam_community@ansi.erl | 263 -- .../src/gleam_community_ansi.app.src | 9 - .../packages/gleam_community_colour/LICENCE | 190 -- .../packages/gleam_community_colour/README.md | 36 - .../gleam_community_colour/gleam.toml | 11 - .../include/gleam_community@colour_Hsla.hrl | 1 - .../include/gleam_community@colour_Rgba.hrl | 1 - .../src/gleam_community/colour.gleam | 1126 -------- .../colour/accessibility.gleam | 173 -- .../src/gleam_community@colour.erl | 511 ---- .../gleam_community@colour@accessibility.erl | 73 - .../src/gleam_community_colour.app.src | 9 - .../glerm/build/packages/gleam_erlang/LICENSE | 191 -- .../build/packages/gleam_erlang/README.md | 37 - .../build/packages/gleam_erlang/gleam.toml | 18 - .../include/gleam@erlang@file_FileInfo.hrl | 15 - .../include/gleam@erlang@process_Abnormal.hrl | 1 - .../gleam@erlang@process_CalleeDown.hrl | 1 - .../gleam@erlang@process_Cancelled.hrl | 1 - .../gleam@erlang@process_ExitMessage.hrl | 4 - .../gleam@erlang@process_ProcessDown.hrl | 4 - .../gleam@erlang@process_ProcessMonitor.hrl | 1 - .../include/gleam@erlang@process_Subject.hrl | 4 - .../gleam@erlang_ApplicationFailedToStart.hrl | 4 - .../gleam@erlang_UnknownApplication.hrl | 1 - .../gleam_erlang/src/gleam/erlang.gleam | 158 -- .../gleam_erlang/src/gleam/erlang/atom.gleam | 79 - .../src/gleam/erlang/charlist.gleam | 25 - .../gleam_erlang/src/gleam/erlang/file.gleam | 737 ------ .../gleam_erlang/src/gleam/erlang/node.gleam | 62 - .../gleam_erlang/src/gleam/erlang/os.gleam | 95 - .../src/gleam/erlang/process.gleam | 744 ------ .../gleam_erlang/src/gleam@erlang.erl | 90 - .../gleam_erlang/src/gleam@erlang@atom.erl | 26 - .../src/gleam@erlang@charlist.erl | 15 - .../gleam_erlang/src/gleam@erlang@file.erl | 190 -- .../gleam_erlang/src/gleam@erlang@node.erl | 33 - .../gleam_erlang/src/gleam@erlang@os.erl | 27 - .../gleam_erlang/src/gleam@erlang@process.erl | 374 --- .../gleam_erlang/src/gleam_erlang.app.src | 14 - .../gleam_erlang/src/gleam_erlang_ffi.erl | 263 -- .../glerm/build/packages/gleam_otp/LICENCE | 191 -- .../glerm/build/packages/gleam_otp/README.md | 91 - .../glerm/build/packages/gleam_otp/gleam.toml | 19 - .../include/gleam@otp@actor_Continue.hrl | 4 - .../include/gleam@otp@actor_Ready.hrl | 1 - .../include/gleam@otp@actor_Spec.hrl | 5 - ...otp@intensity_tracker_IntensityTracker.hrl | 5 - .../gleam@otp@supervisor_ChildSpec.hrl | 5 - .../include/gleam@otp@supervisor_Spec.hrl | 6 - .../include/gleam@otp@system_StatusInfo.hrl | 7 - .../gleam_otp/include/gleam@otp@task_Exit.hrl | 1 - .../gleam_otp/include/gleam@otp@task_Task.hrl | 6 - .../gleam_otp/src/gleam/otp/actor.gleam | 504 ---- .../src/gleam/otp/intensity_tracker.gleam | 46 - .../gleam_otp/src/gleam/otp/port.gleam | 9 - .../gleam_otp/src/gleam/otp/supervisor.gleam | 410 --- .../gleam_otp/src/gleam/otp/system.gleam | 89 - .../gleam_otp/src/gleam/otp/task.gleam | 151 -- .../gleam_otp/src/gleam@otp@actor.erl | 273 -- .../src/gleam@otp@intensity_tracker.erl | 53 - .../packages/gleam_otp/src/gleam@otp@port.erl | 8 - .../gleam_otp/src/gleam@otp@supervisor.erl | 322 --- .../gleam_otp/src/gleam@otp@system.erl | 43 - .../packages/gleam_otp/src/gleam@otp@task.erl | 111 - .../packages/gleam_otp/src/gleam_otp.app.src | 15 - .../packages/gleam_otp/src/gleam_otp.erl | 28 - .../packages/gleam_otp/src/gleam_otp.gleam | 27 - .../gleam_otp/src/gleam_otp_external.erl | 43 - .../glerm/build/packages/gleam_stdlib/LICENCE | 191 -- .../build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 16 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../build/packages/gleam_stdlib/src/dict.mjs | 957 ------- .../gleam_stdlib/src/gleam/base.gleam | 21 - .../gleam_stdlib/src/gleam/bit_array.gleam | 157 -- .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 - .../gleam_stdlib/src/gleam/bit_string.gleam | 43 - .../gleam_stdlib/src/gleam/bool.gleam | 428 --- .../src/gleam/bytes_builder.gleam | 197 -- .../gleam_stdlib/src/gleam/dict.gleam | 544 ---- .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 ----------- .../gleam_stdlib/src/gleam/float.gleam | 546 ---- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 874 ------- .../packages/gleam_stdlib/src/gleam/io.gleam | 117 - .../gleam_stdlib/src/gleam/iterator.gleam | 1530 ----------- .../gleam_stdlib/src/gleam/list.gleam | 2154 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 127 - .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 133 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 214 -- .../gleam_stdlib/src/gleam/result.gleam | 482 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 913 ------- .../src/gleam/string_builder.gleam | 298 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 20 - .../gleam_stdlib/src/gleam@bit_array.erl | 102 - .../gleam_stdlib/src/gleam@bit_builder.erl | 66 - .../gleam_stdlib/src/gleam@bit_string.erl | 33 - .../packages/gleam_stdlib/src/gleam@bool.erl | 162 -- .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 - .../packages/gleam_stdlib/src/gleam@dict.erl | 97 - .../gleam_stdlib/src/gleam@dynamic.erl | 808 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 181 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 332 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 744 ------ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 76 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 79 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 352 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 252 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 31 - .../gleam_stdlib/src/gleam_stdlib.erl | 529 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 878 ------- .../glerm/build/packages/gleeunit/LICENCE | 191 -- .../glerm/build/packages/gleeunit/README.md | 52 - .../glerm/build/packages/gleeunit/gleam.toml | 17 - .../packages/gleeunit/src/gleeunit.app.src | 8 - .../build/packages/gleeunit/src/gleeunit.erl | 59 - .../packages/gleeunit/src/gleeunit.gleam | 92 - .../gleeunit/src/gleeunit/should.gleam | 90 - .../packages/gleeunit/src/gleeunit@should.erl | 34 - .../packages/gleeunit/src/gleeunit_ffi.erl | 24 - .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 - .../gleeunit/src/gleeunit_progress.erl | 607 ----- .../glerm/build/packages/packages.toml | 7 - .../build/packages/glerm/gleam.toml | 17 - .../packages/glerm/include/glerm_Drag.hrl | 4 - .../packages/glerm/include/glerm_Focus.hrl | 1 - .../packages/glerm/include/glerm_Key.hrl | 4 - .../glerm/include/glerm_ListenerSpec.hrl | 5 - .../packages/glerm/include/glerm_Mouse.hrl | 1 - .../glerm/include/glerm_MouseDown.hrl | 4 - .../packages/glerm/include/glerm_MouseUp.hrl | 4 - .../packages/glerm/include/glerm_Unknown.hrl | 1 - .../build/packages/glerm/manifest.toml | 18 - .../packages/glerm/priv/linux/libglerm.so | Bin 4550752 -> 0 bytes .../packages/glerm/priv/windows/libglerm.dll | Bin 352768 -> 0 bytes .../build/packages/glerm/src/glerm.app.src | 11 - .../build/packages/glerm/src/glerm.erl | 397 --- .../build/packages/glerm/src/glerm.gleam | 354 --- .../build/packages/glerm/src/glerm_ffi.erl | 67 - .../build/packages/gliew/README.md | 393 --- .../build/packages/gliew/gleam.toml | 16 - .../gliew@internal@event_LiveMount.hrl | 3 - .../gliew@internal@manager_GetWorker.hrl | 7 - .../gliew@internal@manager_ProcessTree.hrl | 5 - .../gliew@internal@worker_ConnectSocket.hrl | 3 - ...gliew@internal@worker_DisconnectSocket.hrl | 3 - .../gliew@internal@worker_LiveUpdate.hrl | 1 - .../packages/gliew/include/gliew_Response.hrl | 5 - .../packages/gliew/include/gliew_Server.hrl | 5 - .../packages/gliew/include/gliew_View.hrl | 5 - .../build/packages/gliew/src/gliew.app.src | 17 - .../build/packages/gliew/src/gliew.erl | 495 ---- .../build/packages/gliew/src/gliew.gleam | 477 ---- .../gliew/src/gliew/internal/event.gleam | 20 - .../gliew/src/gliew/internal/manager.gleam | 222 -- .../gliew/src/gliew/internal/util.gleam | 18 - .../gliew/src/gliew/internal/worker.gleam | 128 - .../gliew/src/gliew@internal@event.erl | 11 - .../gliew/src/gliew@internal@manager.erl | 216 -- .../gliew/src/gliew@internal@util.erl | 23 - .../gliew/src/gliew@internal@worker.erl | 129 - .../build/packages/glisten/README.md | 132 - .../build/packages/glisten/gleam.toml | 13 - .../glisten@acceptor_AcceptorState.hrl | 5 - .../glisten/include/glisten@acceptor_Pool.hrl | 9 - .../include/glisten@handler_Handler.hrl | 8 - .../include/glisten@handler_LoopState.hrl | 6 - .../glisten/include/glisten@handler_Ssl.hrl | 1 - .../glisten/include/glisten@handler_Tcp.hrl | 1 - .../include/glisten@socket@transport_Ssl.hrl | 34 - .../include/glisten@socket@transport_Tcp.hrl | 34 - .../packages/glisten/src/glisten.app.src | 18 - .../build/packages/glisten/src/glisten.erl | 102 - .../build/packages/glisten/src/glisten.gleam | 85 - .../glisten/src/glisten/acceptor.gleam | 204 -- .../glisten/src/glisten/handler.gleam | 160 -- .../packages/glisten/src/glisten/logger.gleam | 8 - .../packages/glisten/src/glisten/socket.gleam | 93 - .../glisten/src/glisten/socket/options.gleam | 83 - .../src/glisten/socket/transport.gleam | 122 - .../packages/glisten/src/glisten/ssl.gleam | 93 - .../packages/glisten/src/glisten/tcp.gleam | 94 - .../packages/glisten/src/glisten@acceptor.erl | 232 -- .../packages/glisten/src/glisten@handler.erl | 234 -- .../packages/glisten/src/glisten@logger.erl | 8 - .../packages/glisten/src/glisten@socket.erl | 90 - .../glisten/src/glisten@socket@options.erl | 79 - .../glisten/src/glisten@socket@transport.erl | 102 - .../packages/glisten/src/glisten@ssl.erl | 94 - .../packages/glisten/src/glisten@tcp.erl | 96 - .../build/packages/glisten/src/ssl_ffi.erl | 60 - .../build/packages/glisten/src/tcp_ffi.erl | 32 - .../build/packages/globe/LICENSE | 21 - .../build/packages/globe/README.md | 26 - .../build/packages/globe/gleam.toml | 12 - .../build/packages/globe/src/globe.app.src | 8 - .../build/packages/globe/src/globe.erl | 8 - .../build/packages/globe/src/globe.gleam | 5 - .../build/packages/gloml/README.md | 40 - .../build/packages/gloml/gleam.toml | 16 - .../packages/gloml/priv/package-lock.json | 18 - .../build/packages/gloml/priv/package.json | 5 - .../build/packages/gloml/src/TomlFFI.ex | 5 - .../build/packages/gloml/src/gloml.app.src | 9 - .../build/packages/gloml/src/gloml.erl | 44 - .../build/packages/gloml/src/gloml.gleam | 77 - .../build/packages/gloml/src/toml_ffi.mjs | 14 - .../build/packages/glove/LICENSE | 21 - .../build/packages/glove/README.md | 40 - .../build/packages/glove/gleam.toml | 11 - .../packages/glove/include/glove_Block.hrl | 1 - .../packages/glove/include/glove_Const.hrl | 1 - .../packages/glove/include/glove_DataDef.hrl | 6 - .../packages/glove/include/glove_Function.hrl | 7 - .../packages/glove/include/glove_Global.hrl | 1 - .../packages/glove/include/glove_Linkage.hrl | 5 - .../packages/glove/include/glove_Module.hrl | 5 - .../glove/include/glove_Temporary.hrl | 1 - .../packages/glove/include/glove_TypeDef.hrl | 5 - .../build/packages/glove/src/glove.app.src | 8 - .../build/packages/glove/src/glove.erl | 640 ----- .../build/packages/glove/src/glove.gleam | 563 ---- .../build/packages/glx/LICENSE | 21 - .../build/packages/glx/README.md | 12 - .../_gleam_artefacts/gleam@base.cache | Bin 1223 -> 0 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 4959 -> 0 bytes .../gleam@bit_array.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 4184 -> 0 bytes .../gleam@bit_builder.cache_meta | Bin 84 -> 0 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 1934 -> 0 bytes .../gleam@bit_string.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 7081 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 48 -> 0 bytes .../gleam@bytes_builder.cache | Bin 6045 -> 0 bytes .../gleam@bytes_builder.cache_meta | Bin 98 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 12276 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 49265 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 173 -> 0 bytes .../_gleam_artefacts/gleam@float.cache | Bin 11362 -> 0 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 48 -> 0 bytes .../_gleam_artefacts/gleam@function.cache | Bin 5793 -> 0 bytes .../gleam@function.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@int.cache | Bin 18155 -> 0 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@io.cache | Bin 2856 -> 0 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 37897 -> 0 bytes .../gleam@iterator.cache_meta | Bin 141 -> 0 bytes .../_gleam_artefacts/gleam@list.cache | Bin 46265 -> 0 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 120 -> 0 bytes .../_gleam_artefacts/gleam@map.cache | Bin 4750 -> 0 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@option.cache | Bin 7259 -> 0 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@order.cache | Bin 2704 -> 0 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 1879 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 7006 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 6599 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@result.cache | Bin 10381 -> 0 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@set.cache | Bin 6395 -> 0 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 85 -> 0 bytes .../_gleam_artefacts/gleam@string.cache | Bin 21839 -> 0 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 136 -> 0 bytes .../gleam@string_builder.cache | Bin 10571 -> 0 bytes .../gleam@string_builder.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 7769 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 132 -> 0 bytes .../glx/build/lsp/erlang/gleam_version | 1 - .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 3252 -> 0 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 108 -> 0 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 1132 -> 0 bytes .../gleeunit@should.cache_meta | Bin 29 -> 0 bytes .../glx/_gleam_artefacts/glx@stringx.cache | Bin 552 -> 0 bytes .../_gleam_artefacts/glx@stringx.cache_meta | Bin 104 -> 0 bytes .../glx/build/packages/gleam_stdlib/LICENCE | 191 -- .../glx/build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 16 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../build/packages/gleam_stdlib/src/dict.mjs | 957 ------- .../gleam_stdlib/src/gleam/base.gleam | 21 - .../gleam_stdlib/src/gleam/bit_array.gleam | 157 -- .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 - .../gleam_stdlib/src/gleam/bit_string.gleam | 43 - .../gleam_stdlib/src/gleam/bool.gleam | 428 --- .../src/gleam/bytes_builder.gleam | 197 -- .../gleam_stdlib/src/gleam/dict.gleam | 544 ---- .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 ----------- .../gleam_stdlib/src/gleam/float.gleam | 546 ---- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 874 ------- .../packages/gleam_stdlib/src/gleam/io.gleam | 117 - .../gleam_stdlib/src/gleam/iterator.gleam | 1530 ----------- .../gleam_stdlib/src/gleam/list.gleam | 2154 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 127 - .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 133 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 214 -- .../gleam_stdlib/src/gleam/result.gleam | 482 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 913 ------- .../src/gleam/string_builder.gleam | 298 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 20 - .../gleam_stdlib/src/gleam@bit_array.erl | 102 - .../gleam_stdlib/src/gleam@bit_builder.erl | 66 - .../gleam_stdlib/src/gleam@bit_string.erl | 33 - .../packages/gleam_stdlib/src/gleam@bool.erl | 162 -- .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 - .../packages/gleam_stdlib/src/gleam@dict.erl | 97 - .../gleam_stdlib/src/gleam@dynamic.erl | 808 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 181 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 332 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 744 ------ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 76 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 79 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 352 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 252 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 31 - .../gleam_stdlib/src/gleam_stdlib.erl | 529 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 878 ------- .../glx/build/packages/gleeunit/LICENCE | 191 -- .../glx/build/packages/gleeunit/README.md | 52 - .../_gleam_artefacts/gleam@base.cache | Bin 1223 -> 0 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 4962 -> 0 bytes .../gleam@bit_array.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 4184 -> 0 bytes .../gleam@bit_builder.cache_meta | Bin 84 -> 0 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 1934 -> 0 bytes .../gleam@bit_string.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 7078 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 48 -> 0 bytes .../gleam@bytes_builder.cache | Bin 6050 -> 0 bytes .../gleam@bytes_builder.cache_meta | Bin 98 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 12268 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 49216 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 173 -> 0 bytes .../_gleam_artefacts/gleam@float.cache | Bin 11377 -> 0 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 48 -> 0 bytes .../_gleam_artefacts/gleam@function.cache | Bin 5806 -> 0 bytes .../gleam@function.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@int.cache | Bin 18138 -> 0 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@io.cache | Bin 2856 -> 0 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 37904 -> 0 bytes .../gleam@iterator.cache_meta | Bin 141 -> 0 bytes .../_gleam_artefacts/gleam@list.cache | Bin 46259 -> 0 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 120 -> 0 bytes .../_gleam_artefacts/gleam@map.cache | Bin 4737 -> 0 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@option.cache | Bin 7261 -> 0 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@order.cache | Bin 2704 -> 0 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 1880 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 7006 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 6607 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@result.cache | Bin 10388 -> 0 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@set.cache | Bin 6402 -> 0 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 85 -> 0 bytes .../_gleam_artefacts/gleam@string.cache | Bin 21832 -> 0 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 136 -> 0 bytes .../gleam@string_builder.cache | Bin 10562 -> 0 bytes .../gleam@string_builder.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 7759 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 132 -> 0 bytes .../gleeunit/build/lsp/erlang/gleam_version | 1 - .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 3254 -> 0 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 108 -> 0 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 1134 -> 0 bytes .../gleeunit@should.cache_meta | Bin 29 -> 0 bytes .../build/packages/gleam_stdlib/LICENCE | 191 -- .../build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 16 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../build/packages/gleam_stdlib/src/dict.mjs | 957 ------- .../gleam_stdlib/src/gleam/base.gleam | 21 - .../gleam_stdlib/src/gleam/bit_array.gleam | 157 -- .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 - .../gleam_stdlib/src/gleam/bit_string.gleam | 43 - .../gleam_stdlib/src/gleam/bool.gleam | 428 --- .../src/gleam/bytes_builder.gleam | 197 -- .../gleam_stdlib/src/gleam/dict.gleam | 544 ---- .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 ----------- .../gleam_stdlib/src/gleam/float.gleam | 546 ---- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 874 ------- .../packages/gleam_stdlib/src/gleam/io.gleam | 117 - .../gleam_stdlib/src/gleam/iterator.gleam | 1530 ----------- .../gleam_stdlib/src/gleam/list.gleam | 2154 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 127 - .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 133 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 214 -- .../gleam_stdlib/src/gleam/result.gleam | 482 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 913 ------- .../src/gleam/string_builder.gleam | 298 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 20 - .../gleam_stdlib/src/gleam@bit_array.erl | 102 - .../gleam_stdlib/src/gleam@bit_builder.erl | 66 - .../gleam_stdlib/src/gleam@bit_string.erl | 33 - .../packages/gleam_stdlib/src/gleam@bool.erl | 162 -- .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 - .../packages/gleam_stdlib/src/gleam@dict.erl | 97 - .../gleam_stdlib/src/gleam@dynamic.erl | 808 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 181 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 332 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 744 ------ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 76 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 79 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 352 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 252 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 31 - .../gleam_stdlib/src/gleam_stdlib.erl | 529 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 878 ------- .../gleeunit/build/packages/packages.toml | 2 - .../glx/build/packages/gleeunit/gleam.toml | 17 - .../glx/build/packages/gleeunit/manifest.toml | 9 - .../packages/gleeunit/src/gleeunit.app.src | 8 - .../build/packages/gleeunit/src/gleeunit.erl | 59 - .../packages/gleeunit/src/gleeunit.gleam | 92 - .../gleeunit/src/gleeunit/should.gleam | 90 - .../packages/gleeunit/src/gleeunit@should.erl | 34 - .../packages/gleeunit/src/gleeunit_ffi.erl | 24 - .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 - .../gleeunit/src/gleeunit_progress.erl | 607 ----- .../packages/glx/build/packages/packages.toml | 3 - .../build/packages/glx/gleam.toml | 11 - .../build/packages/glx/manifest.toml | 11 - .../build/packages/glx/src/glx.app.src | 8 - .../build/packages/glx/src/glx/stringx.gleam | 31 - .../build/packages/glx/src/glx@stringx.erl | 24 - .../build/packages/gsv/README.md | 45 - .../build/packages/gsv/gleam.toml | 20 - .../include/gsv@internal@token_Textdata.hrl | 1 - .../build/packages/gsv/src/gsv.app.src | 10 - .../build/packages/gsv/src/gsv.erl | 58 - .../build/packages/gsv/src/gsv.gleam | 62 - .../packages/gsv/src/gsv/internal/ast.gleam | 140 - .../packages/gsv/src/gsv/internal/token.gleam | 54 - .../packages/gsv/src/gsv@internal@ast.erl | 125 - .../packages/gsv/src/gsv@internal@token.erl | 59 - .../build/packages/hug/README.md | 47 - .../build/packages/hug/gleam.toml | 16 - .../build/packages/hug/src/hug.app.src | 10 - .../build/packages/hug/src/hug.erl | 303 --- .../build/packages/hug/src/hug.gleam | 405 --- .../build/packages/mist/README.md | 202 -- .../build/packages/mist/gleam.toml | 17 - .../mist@internal@handler_Response.hrl | 3 - .../include/mist@internal@handler_State.hrl | 4 - .../include/mist@internal@http_Buffer.hrl | 1 - .../include/mist@internal@http_FileBody.hrl | 6 - .../mist/include/mist@internal@http_Read.hrl | 1 - .../include/mist@internal@http_Unread.hrl | 1 - .../mist@internal@websocket_BinaryFrame.hrl | 1 - .../mist@internal@websocket_BinaryMessage.hrl | 1 - .../mist@internal@websocket_CloseFrame.hrl | 1 - .../mist@internal@websocket_PingFrame.hrl | 1 - .../mist@internal@websocket_PongFrame.hrl | 1 - .../mist@internal@websocket_TextFrame.hrl | 1 - .../mist@internal@websocket_TextMessage.hrl | 1 - ...st@internal@websocket_WebsocketHandler.hrl | 7 - .../build/packages/mist/src/mist.app.src | 20 - .../build/packages/mist/src/mist.erl | 116 - .../build/packages/mist/src/mist.gleam | 165 -- .../mist/src/mist/internal/encoder.gleam | 104 - .../mist/src/mist/internal/file.gleam | 26 - .../mist/src/mist/internal/handler.gleam | 350 --- .../mist/src/mist/internal/http.gleam | 393 --- .../mist/src/mist/internal/logger.gleam | 8 - .../mist/src/mist/internal/websocket.gleam | 167 -- .../packages/mist/src/mist/websocket.gleam | 51 - .../mist/src/mist@internal@encoder.erl | 209 -- .../packages/mist/src/mist@internal@file.erl | 27 - .../mist/src/mist@internal@handler.erl | 577 ---- .../packages/mist/src/mist@internal@http.erl | 591 ----- .../mist/src/mist@internal@logger.erl | 8 - .../mist/src/mist@internal@websocket.erl | 359 --- .../packages/mist/src/mist@websocket.erl | 52 - .../build/packages/mist/src/mist_ffi.erl | 47 - .../build/packages/nakai/LICENSE | 22 - .../build/packages/nakai/README.md | 46 - .../build/packages/nakai/gleam.toml | 20 - .../nakai/include/nakai@html@attrs_Attr.hrl | 1 - .../nakai/include/nakai@html@attrs_Event.hrl | 1 - .../nakai/include/nakai@html_Body.hrl | 4 - .../nakai/include/nakai@html_Comment.hrl | 1 - .../nakai/include/nakai@html_Doctype.hrl | 1 - .../nakai/include/nakai@html_Element.hrl | 5 - .../nakai/include/nakai@html_Fragment.hrl | 1 - .../nakai/include/nakai@html_Head.hrl | 1 - .../nakai/include/nakai@html_Html.hrl | 4 - .../nakai/include/nakai@html_LeafElement.hrl | 4 - .../nakai/include/nakai@html_Script.hrl | 1 - .../nakai/include/nakai@html_Text.hrl | 1 - .../nakai/include/nakai@html_UnsafeText.hrl | 1 - .../nakai@internal@document_Document.hrl | 8 - .../build/packages/nakai/src/nakai.app.src | 18 - .../build/packages/nakai/src/nakai.erl | 22 - .../build/packages/nakai/src/nakai.gleam | 60 - .../nakai/src/nakai/experimental/head.gleam | 22 - .../nakai/src/nakai/experimental/on.gleam | 5 - .../nakai/experimental/web_components.gleam | 10 - .../build/packages/nakai/src/nakai/html.gleam | 1164 --------- .../packages/nakai/src/nakai/html/attrs.gleam | 203 -- .../nakai/src/nakai/internal/document.gleam | 97 - .../nakai/src/nakai/internal/render.gleam | 211 -- .../nakai/src/nakai@experimental@head.erl | 34 - .../nakai/src/nakai@experimental@on.erl | 8 - .../src/nakai@experimental@web_components.erl | 12 - .../build/packages/nakai/src/nakai@html.erl | 830 ------ .../packages/nakai/src/nakai@html@attrs.erl | 191 -- .../nakai/src/nakai@internal@document.erl | 117 - .../nakai/src/nakai@internal@render.erl | 297 --- .../build/packages/nibble/LICENSE | 18 - .../build/packages/nibble/README.md | 46 - .../build/packages/nibble/gleam.toml | 15 - .../nibble/include/nibble@pratt_Config.hrl | 5 - .../nibble/include/nibble_DeadEnd.hrl | 6 - .../nibble/include/nibble_Located.hrl | 1 - .../build/packages/nibble/src/nibble.app.src | 10 - .../build/packages/nibble/src/nibble.erl | 517 ---- .../build/packages/nibble/src/nibble.gleam | 519 ---- .../packages/nibble/src/nibble/pratt.gleam | 113 - .../nibble/src/nibble/predicates.gleam | 59 - .../packages/nibble/src/nibble@pratt.erl | 120 - .../packages/nibble/src/nibble@predicates.erl | 234 -- .../build/packages/non_empty_list/LICENSE | 201 -- .../build/packages/non_empty_list/README.md | 40 - .../build/packages/non_empty_list/gleam.toml | 13 - .../include/non_empty_list_NonEmptyList.hrl | 1 - .../non_empty_list/src/non_empty_list.app.src | 8 - .../non_empty_list/src/non_empty_list.erl | 304 --- .../non_empty_list/src/non_empty_list.gleam | 607 ----- .../build/packages/packages.toml | 30 - .../build/packages/ream/LICENSE | 201 -- .../build/packages/ream/README.md | 64 - .../build/packages/ream/gleam.toml | 27 - .../include/ream@storage@file@close_Error.hrl | 1 - .../include/ream@storage@file@read_Error.hrl | 1 - .../include/ream@storage@file@read_Ok.hrl | 1 - .../include/ream@storage@file@write_Error.hrl | 1 - .../ream@storage@file_DelayedWrite.hrl | 1 - .../include/ream@storage@file_Encoding.hrl | 1 - .../include/ream@storage@file_ReadAhead.hrl | 1 - .../ream@storage@kv@memtable_MemTable.hrl | 5 - ...ream@storage@kv@memtable_MemTableEntry.hrl | 4 - .../include/ream@storage@kv@value_Value.hrl | 6 - .../ream@storage@kv@value_ValueFile.hrl | 7 - .../ream@storage@kv@value_ValueFileInfo.hrl | 7 - .../ream/include/ream@storage@kv_KV.hrl | 11 - .../ream/include/ream@storage@kv_KVInfo.hrl | 12 - .../include/ream@storage@kv_MemTableRange.hrl | 5 - .../ream@storage@stream@event_Event.hrl | 1 - .../ream@storage@stream@event_EventFile.hrl | 6 - .../ream@storage@stream@index_Index.hrl | 1 - .../ream@storage@stream@index_IndexFile.hrl | 5 - .../include/ream@storage@stream_Stream.hrl | 7 - .../build/packages/ream/src/ream.app.src | 24 - .../build/packages/ream/src/ream.erl | 1 - .../build/packages/ream/src/ream.gleam | 1 - .../packages/ream/src/ream/storage/file.gleam | 103 - .../ream/src/ream/storage/file/close.gleam | 6 - .../ream/src/ream/storage/file/read.gleam | 7 - .../ream/src/ream/storage/file/write.gleam | 6 - .../packages/ream/src/ream/storage/kv.gleam | 430 --- .../ream/src/ream/storage/kv/memtable.gleam | 287 -- .../ream/src/ream/storage/kv/sstable.gleam | 54 - .../ream/src/ream/storage/kv/value.gleam | 206 -- .../ream/src/ream/storage/stream.gleam | 139 - .../ream/src/ream/storage/stream/event.gleam | 95 - .../ream/src/ream/storage/stream/index.gleam | 153 -- .../build/packages/ream/src/ream/uuid.gleam | 48 - .../packages/ream/src/ream@storage@file.erl | 123 - .../ream/src/ream@storage@file@close.erl | 8 - .../ream/src/ream@storage@file@read.erl | 8 - .../ream/src/ream@storage@file@write.erl | 8 - .../packages/ream/src/ream@storage@kv.erl | 901 ------- .../ream/src/ream@storage@kv@memtable.erl | 277 -- .../ream/src/ream@storage@kv@sstable.erl | 136 - .../ream/src/ream@storage@kv@value.erl | 326 --- .../packages/ream/src/ream@storage@stream.erl | 272 -- .../ream/src/ream@storage@stream@event.erl | 186 -- .../ream/src/ream@storage@stream@index.erl | 234 -- .../build/packages/ream/src/ream@uuid.erl | 53 - .../build/packages/simplifile/README.md | 35 - .../build/packages/simplifile/gleam.toml | 19 - .../build/packages/simplifile/src/file.mjs | 84 - .../simplifile/src/gleam_erlang_ffi.erl | 218 -- .../simplifile/src/simplifile.app.src | 8 - .../packages/simplifile/src/simplifile.erl | 131 - .../packages/simplifile/src/simplifile.gleam | 359 --- .../build/packages/toml/LICENSE | 176 -- .../build/packages/toml/README.md | 338 --- .../build/packages/toml/lib/builder.ex | 413 --- .../build/packages/toml/lib/decoder.ex | 1055 -------- .../build/packages/toml/lib/document.ex | 182 -- .../build/packages/toml/lib/error.ex | 143 - .../build/packages/toml/lib/lexer.ex | 392 --- .../build/packages/toml/lib/lexer/guards.ex | 21 - .../build/packages/toml/lib/lexer/string.ex | 294 --- .../build/packages/toml/lib/provider.ex | 227 -- .../build/packages/toml/lib/toml.ex | 94 - .../build/packages/toml/lib/transform.ex | 127 - .../build/packages/toml/mix.exs | 125 - .../build/packages/trie_again/LICENSE | 201 -- .../build/packages/trie_again/README.md | 62 - .../build/packages/trie_again/gleam.toml | 12 - .../packages/trie_again/include/trie_Trie.hrl | 4 - .../build/packages/trie_again/src/trie.erl | 232 -- .../build/packages/trie_again/src/trie.gleam | 466 ---- .../trie_again/src/trie_again.app.src | 8 - 1015 files changed, 7 insertions(+), 138937 deletions(-) delete mode 100644 test-community-packages-javascript/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glenvy/README.md delete mode 100644 test-community-packages-javascript/build/packages/glenvy/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/manifest.toml delete mode 100755 test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so delete mode 100644 test-community-packages-javascript/build/packages/glerm/priv/windows/libglerm.dll delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/README.md delete mode 100644 test-community-packages-javascript/build/packages/gliew/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.app.src delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/README.md delete mode 100644 test-community-packages-javascript/build/packages/glisten/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.app.src delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/globe/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/globe/README.md delete mode 100644 test-community-packages-javascript/build/packages/globe/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.app.src delete mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.erl delete mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.gleam delete mode 100644 test-community-packages-javascript/build/packages/gloml/README.md delete mode 100644 test-community-packages-javascript/build/packages/gloml/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gloml/priv/package-lock.json delete mode 100644 test-community-packages-javascript/build/packages/gloml/priv/package.json delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.app.src delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.erl delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.gleam delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glove/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glove/README.md delete mode 100644 test-community-packages-javascript/build/packages/glove/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.app.src delete mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.erl delete mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glx/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/manifest.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/src/glx.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl delete mode 100644 test-community-packages-javascript/build/packages/gsv/README.md delete mode 100644 test-community-packages-javascript/build/packages/gsv/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.app.src delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.erl delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.gleam delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl delete mode 100644 test-community-packages-javascript/build/packages/hug/README.md delete mode 100644 test-community-packages-javascript/build/packages/hug/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.app.src delete mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.erl delete mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/README.md delete mode 100644 test-community-packages-javascript/build/packages/mist/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.app.src delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/nakai/README.md delete mode 100644 test-community-packages-javascript/build/packages/nakai/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.app.src delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl delete mode 100644 test-community-packages-javascript/build/packages/nibble/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/nibble/README.md delete mode 100644 test-community-packages-javascript/build/packages/nibble/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl delete mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl delete mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.app.src delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.erl delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.gleam delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/README.md delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam delete mode 100644 test-community-packages-javascript/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/ream/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/ream/README.md delete mode 100644 test-community-packages-javascript/build/packages/ream/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.app.src delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl delete mode 100644 test-community-packages-javascript/build/packages/simplifile/README.md delete mode 100644 test-community-packages-javascript/build/packages/simplifile/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/file.mjs delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam delete mode 100644 test-community-packages-javascript/build/packages/toml/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/toml/README.md delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/builder.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/decoder.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/document.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/error.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/provider.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/toml.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/transform.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/mix.exs delete mode 100644 test-community-packages-javascript/build/packages/trie_again/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/trie_again/README.md delete mode 100644 test-community-packages-javascript/build/packages/trie_again/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl delete mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie.erl delete mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie.gleam delete mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src diff --git a/Cargo.lock b/Cargo.lock index 75ba9328c8c..de01f126ecc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,6 +435,12 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cov-mark" +version = "2.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d48d8f76bd9331f19fe2aaf3821a9f9fb32c3963e1e3d6ce82a8c09cef7444a" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -889,6 +895,7 @@ dependencies = [ "capnp", "capnpc", "codespan-reporting", + "cov-mark", "debug-ignore", "dirs-next", "ecow", diff --git a/test-community-packages-javascript/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE b/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/README.md b/test-community-packages-javascript/build/packages/gleam_bitwise/README.md deleted file mode 100644 index 6838e2232b1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# bitwise - -[![Package Version](https://img.shields.io/hexpm/v/gleam_bitwise)](https://hex.pm/packages/gleam_bitwise) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_bitwise/) - -🍓 Bitwise operations on integers. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gleam_bitwise -``` - -and its documentation can be found at <https://hexdocs.pm/gleam_bitwise/>. diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml b/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml deleted file mode 100644 index dd8cd839a87..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_bitwise" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "Bitwise operations on integers" - -repository = { type = "github", user = "gleam-lang", repo = "bitwise" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.21" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam deleted file mode 100644 index 662f9104da6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam +++ /dev/null @@ -1,91 +0,0 @@ -//// A set of functions for bitwise operations on integers. - -/// Calculates the bitwise AND of its arguments. -pub fn and(x: Int, y: Int) -> Int { - do_and(x, y) -} - -if erlang { - external fn do_and(Int, Int) -> Int = - "erlang" "band" -} - -if javascript { - external fn do_and(Int, Int) -> Int = - "../gleam_bitwise.mjs" "and" -} - -/// Calculates the bitwise NOT of its argument. -pub fn not(x: Int) -> Int { - do_not(x) -} - -if erlang { - external fn do_not(Int) -> Int = - "erlang" "bnot" -} - -if javascript { - external fn do_not(Int) -> Int = - "../gleam_bitwise.mjs" "not" -} - -/// Calculates the bitwise OR of its arguments. -pub fn or(x: Int, y: Int) -> Int { - do_or(x, y) -} - -if erlang { - external fn do_or(Int, Int) -> Int = - "erlang" "bor" -} - -if javascript { - external fn do_or(Int, Int) -> Int = - "../gleam_bitwise.mjs" "or" -} - -/// Calculates the bitwise XOR of its arguments. -pub fn exclusive_or(x: Int, y: Int) -> Int { - do_exclusive_or(x, y) -} - -if erlang { - external fn do_exclusive_or(Int, Int) -> Int = - "erlang" "bxor" -} - -if javascript { - external fn do_exclusive_or(Int, Int) -> Int = - "../gleam_bitwise.mjs" "exclusive_or" -} - -/// Calculates the result of an arithmetic left bitshift. -pub fn shift_left(x: Int, y: Int) -> Int { - do_shift_left(x, y) -} - -if erlang { - external fn do_shift_left(Int, Int) -> Int = - "erlang" "bsl" -} - -if javascript { - external fn do_shift_left(Int, Int) -> Int = - "../gleam_bitwise.mjs" "shift_left" -} - -/// Calculates the result of an arithmetic right bitshift. -pub fn shift_right(x: Int, y: Int) -> Int { - do_shift_right(x, y) -} - -if erlang { - external fn do_shift_right(Int, Int) -> Int = - "erlang" "bsr" -} - -if javascript { - external fn do_shift_right(Int, Int) -> Int = - "../gleam_bitwise.mjs" "shift_right" -} diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl deleted file mode 100644 index 57d63544e64..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(gleam@bitwise). --compile(no_auto_import). - --export(['and'/2, 'not'/1, 'or'/2, exclusive_or/2, shift_left/2, shift_right/2]). - --spec 'and'(integer(), integer()) -> integer(). -'and'(X, Y) -> - erlang:'band'(X, Y). - --spec 'not'(integer()) -> integer(). -'not'(X) -> - erlang:'bnot'(X). - --spec 'or'(integer(), integer()) -> integer(). -'or'(X, Y) -> - erlang:'bor'(X, Y). - --spec exclusive_or(integer(), integer()) -> integer(). -exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec shift_left(integer(), integer()) -> integer(). -shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec shift_right(integer(), integer()) -> integer(). -shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src deleted file mode 100644 index bd9497aca13..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleam_bitwise, [ - {vsn, "1.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Bitwise operations on integers"}, - {modules, [gleam@bitwise]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs deleted file mode 100644 index 4f928cbc42e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs +++ /dev/null @@ -1,28 +0,0 @@ -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function not(x) { - return Number(~BigInt(x)); -} - -export function or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE b/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md b/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md deleted file mode 100644 index 90ab0d56c57..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# gleam-community/ansi - -Format text with ANSI escape sequences. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_ansi)](https://hex.pm/packages/gleam_community_ansi) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_ansi/) - -✨ This project is written in _pure Gleam_ so you can use it anywhere Gleam runs: -Erlang, Elixir, Node, Deno, even [some browsers](https://bit.ly/devtools-console-ansi-support)! - ---- - -## Quickstart - -```gleam -import gleam/io -import gleam_community/ansi - -pub fn main() { - let greeting = "Hello, " <> ansi.pink("world") <> "!" - - greeting - |> ansi.bg_white - |> io.println -} - -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_ansi) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_ansi -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_ansi). - -## ANSI-what? - -ANSI escape sequences date back to the 70s as a standard way to format text on -various video text terminals. Since then they have been adopted by many software -terminal emulators and platforms, including some Web browsers, and are a simple -way to format text without platform-specific APIs. - -The point of this package is to abstract the specific codes away and give you an -easy-to-understand API for formatting and colouring terminal text. Still, here is -a quick couple of examples of what's happening under the hood. - -You can copy these examples straight into your terminal to see them in action! - -- Colour text yellow: - - ```shell - $ echo "\e[33mhello" - ``` - -- Colour the background pink: - - ```shell - $ echo "\e[45mhello" - ``` - -- Render text italic: - - ```shell - $ echo "\e[3mhello\e[23m" - ``` - -As you can see, the escape sequences are a bit obscure. Sure, you could hard code -them, or you could use this package! diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml b/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml deleted file mode 100644 index 026a2d2baa0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "gleam_community_ansi" -version = "1.1.0" -licences = ["Apache-2.0"] -description = "ANSI colours, formatting, and control codes" -repository = { type = "github", user = "gleam-community", repo = "ansi" } - -[dependencies] -gleam_bitwise = "~> 1.2" -gleam_stdlib = "~> 0.25" -gleam_community_colour = "~> 1.0" - -[dev-dependencies] -gleeunit = "~> 0.7" diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam deleted file mode 100644 index 045273abd09..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam +++ /dev/null @@ -1,2318 +0,0 @@ -//// -//// - **Text style** -//// - [`bold`](#bold) -//// - [`italic`](#italic) -//// - [`underline`](#underline) -//// - [`strikethrough`](#strikethrough) -//// - [`inverse`](#inverse) -//// - [`dim`](#dim) -//// - [`hidden`](#hidden) -//// - [`reset`](#reset) -//// - **Text colour** -//// - [`black`](#black) -//// - [`red`](#red) -//// - [`green`](#green) -//// - [`yellow`](#yellow) -//// - [`blue`](#blue) -//// - [`magenta`](#magenta) -//// - [`cyan`](#cyan) -//// - [`white`](#white) -//// - [`pink`](#pink) -//// - [`grey`](#grey) -//// - [`gray`](#gray) -//// - [`bright_black`](#bright_black) -//// - [`bright_red`](#bright_red) -//// - [`bright_green`](#bright_green) -//// - [`bright_yellow`](#bright_yellow) -//// - [`bright_blue`](#bright_blue) -//// - [`bright_magenta`](#bright_magenta) -//// - [`bright_cyan`](#bright_cyan) -//// - [`bright_white`](#bright_white) -//// - [`hex`](#hex) -//// - [`colour`](#colour) -//// - [`color`](#color) -//// - **Background colour** -//// - [`bg_black`](#bg_black) -//// - [`bg_red`](#bg_red) -//// - [`bg_green`](#bg_green) -//// - [`bg_yellow`](#bg_yellow) -//// - [`bg_blue`](#bg_blue) -//// - [`bg_magenta`](#bg_magenta) -//// - [`bg_cyan`](#bg_cyan) -//// - [`bg_white`](#bg_white) -//// - [`bg_pink`](#bg_pink) -//// - [`bg_bright_black`](#bg_bright_black) -//// - [`bg_bright_red`](#bg_bright_red) -//// - [`bg_bright_green`](#bg_bright_green) -//// - [`bg_bright_yellow`](#bg_bright_yellow) -//// - [`bg_bright_blue`](#bg_bright_blue) -//// - [`bg_bright_magenta`](#bg_bright_magenta) -//// - [`bg_bright_cyan`](#bg_bright_cyan) -//// - [`bg_bright_white`](#bg_bright_white) -//// - [`bg_hex`](#bg_hex) -//// - [`bg_colour`](#bg_colour) -//// - [`bg_color`](#bg_color) -//// -//// --- -//// -//// This package was heavily inspired by the `colours` module in the Deno standard -//// library. The original source code can be found -//// <a href="https://deno.land/std@0.167.0/fmt/colours.ts">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018-2022 the Deno authors. -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the Deno `colours` module: -// -// https://deno.land/std@0.167.0/fmt/colours.ts -// - -// This seems like a really handy reference if/when we want to expand this beyond -// formatting escape sequences: -// -// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/bitwise -import gleam/int -import gleam/list -import gleam/string -import gleam_community/colour.{Colour} as gc_colour - -// CONSTS --------------------------------------------------------------------- - -const asci_escape_character = "" - -// TYPES ---------------------------------------------------------------------- - -type Code { - Code(open: String, close: String, regexp: String) -} - -// UTILITY -------------------------------------------------------------------- - -/// Builds colour code -fn code(open: List(Int), close: Int) -> Code { - let close_str = int.to_string(close) - let open_strs = list.map(open, int.to_string) - - Code( - open: asci_escape_character <> "[" <> string.join(open_strs, ";") <> "m", - close: asci_escape_character <> "[" <> close_str <> "m", - regexp: asci_escape_character <> "[" <> close_str <> "m", - ) -} - -/// Applies colour and background based on colour code and its associated text -fn run(text: String, code: Code) -> String { - code.open <> string.replace(text, code.regexp, code.open) <> code.close -} - -// STYLES --------------------------------------------------------------------- - -/// Reset the text modified -pub fn reset(text: String) -> String { - run(text, code([0], 0)) -} - -/// Style the given text bold. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bold("lucy") -/// // => "\x1B[1mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bold(text: String) -> String { - run(text, code([1], 22)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("lucy") -/// // => "\x1B[2mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn dim(text: String) -> String { - run(text, code([2], 22)) -} - -/// Style the given text italic. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.italic("lucy") -/// // => "\x1B[3mlucy\x1B[23m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[23m"` added to the string. This is the escape code -/// for the "default" italic style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be underlined but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn italic(text: String) -> String { - run(text, code([3], 23)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("lucy") -/// // => "\x1B[4mlucy\x1B[24m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[24m"` added to the string. This is the escape code -/// for the "default" underline style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn underline(text: String) -> String { - run(text, code([4], 24)) -} - -/// Inverse the given text's colour, and background colour. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.inverse("lucy") -/// // => "\x1B[7mlucy\x1B[27m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[27m"` added to the string. This is the escape code -/// for the "default" inverse style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn inverse(text: String) -> String { - run(text, code([7], 27)) -} - -/// Style the given text to be hidden. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hidden("lucy") -/// // => "\x1B[8mlucy\x1B[28m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[28m"` added to the string. This is the escape code -/// for the "default" hidden style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hidden(text: String) -> String { - run(text, code([8], 28)) -} - -/// Style the given text to be striked through. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.strikethrough("lucy") -/// // => "\x1B[9mlucy\x1B[29m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[29m"` added to the string. This is the escape code -/// for the "default" strikethrough style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn strikethrough(text: String) -> String { - run(text, code([9], 29)) -} - -// FOREGROUND ----------------------------------------------------------------- - -/// Colour the given text black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.black("lucy") -/// // => "\x1B[30mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn black(text: String) -> String { - run(text, code([30], 39)) -} - -/// Colour the given text red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.red("lucy") -/// // => "\x1B[31mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn red(text: String) -> String { - run(text, code([31], 39)) -} - -/// Colour the given text green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.green("lucy") -/// // => "\x1B[32mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn green(text: String) -> String { - run(text, code([32], 39)) -} - -/// Colour the given text yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("lucy") -/// // => "\x1B[33mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn yellow(text: String) -> String { - run(text, code([33], 39)) -} - -/// Colour the given text blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.blue("lucy") -/// // => "\x1B[34mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn blue(text: String) -> String { - run(text, code([34], 39)) -} - -/// Colour the given text magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.magenta("lucy") -/// // => "\x1B[35mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn magenta(text: String) -> String { - run(text, code([35], 39)) -} - -/// Colour the given text cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.cyan("lucy") -/// // => "\x1B[36mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cyan(text: String) -> String { - run(text, code([36], 39)) -} - -/// Colour the given text white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.white("lucy") -/// // => "\x1B[37mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn white(text: String) -> String { - run(text, code([37], 39)) -} - -/// Colour the given text gray. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.gray("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn grey(text: String) -> String { - bright_black(text) -} - -/// This is an alias for [`grey`](#grey) for those who prefer the American English -/// spelling. -/// -pub fn gray(text: String) -> String { - bright_black(text) -} - -/// Colour the given text bright black. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_black("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_black(text: String) -> String { - run(text, code([90], 39)) -} - -/// Colour the given text bright red. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_red("lucy") -/// // => "\x1B[91mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_red(text: String) -> String { - run(text, code([91], 39)) -} - -/// Colour the given text bright green. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_green("lucy") -/// // => "\x1B[92mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_green(text: String) -> String { - run(text, code([92], 39)) -} - -/// Colour the given text bright yellow. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_yellow("lucy") -/// // => "\x1B[93mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_yellow(text: String) -> String { - run(text, code([93], 39)) -} - -/// Colour the given text bright blue. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_blue("lucy") -/// // => "\x1B[94mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_blue(text: String) -> String { - run(text, code([94], 39)) -} - -/// Colour the given text bright gremagentaen. This should increase the luminosity -/// of the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_magenta("lucy") -/// // => "\x1B[95mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_magenta(text: String) -> String { - run(text, code([95], 39)) -} - -/// Colour the given text bright cyan. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_cyan("lucy") -/// // => "\x1B[96mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_cyan(text: String) -> String { - run(text, code([96], 39)) -} - -/// Colour the given text bright white. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_white("lucy") -/// // => "\x1B[97mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_white(text: String) -> String { - run(text, code([97], 39)) -} - -/// Colour the given text pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.pink("lucy") -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn pink(text: String) -> String { - hex(text, 0xffaff3) -} - -/// Colour the given text the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hex(text: String, colour: Int) -> String { - let colour = int.clamp(colour, max: 0xffffff, min: 0x0) - run( - text, - code( - [ - 38, - 2, - bitwise.shift_right(colour, 16) - |> bitwise.and(0xff), - bitwise.shift_right(colour, 8) - |> bitwise.and(0xff), - bitwise.and(colour, 0xff), - ], - 39, - ), - ) -} - -/// Colour the given text the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - hex(text, hex_colour) -} - -/// This is an alias for [`colour`](#colour) for those who prefer the American English -/// spelling. -/// -pub fn color(text: String, color: Colour) -> String { - colour(text, color) -} - -// BACKGROUND ----------------------------------------------------------------- - -/// Colour the given text's background black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_black("lucy") -/// // => "\x1B[40mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_black(text: String) -> String { - run(text, code([40], 49)) -} - -/// Colour the given text's background red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_red("lucy") -/// // => "\x1B[41mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_red(text: String) -> String { - run(text, code([41], 49)) -} - -/// Colour the given text's background green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_green("lucy") -/// // => "\x1B[42mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_green(text: String) -> String { - run(text, code([42], 49)) -} - -/// Colour the given text's background yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_yellow("lucy") -/// // => "\x1B[43mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_yellow(text: String) -> String { - run(text, code([43], 49)) -} - -/// Colour the given text's background blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_blue("lucy") -/// // => "\x1B[44mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_blue(text: String) -> String { - run(text, code([44], 49)) -} - -/// Colour the given text's background magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_magenta("lucy") -/// // => "\x1B[45mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_magenta(text: String) -> String { - run(text, code([45], 49)) -} - -/// Colour the given text's background cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_cyan("lucy") -/// // => "\x1B[46mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_cyan(text: String) -> String { - run(text, code([46], 49)) -} - -/// Colour the given text's background white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_white("lucy") -/// // => "\x1B[47mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_white(text: String) -> String { - run(text, code([47], 49)) -} - -/// Colour the given text's background bright black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_black("lucy") -/// // => "\x1B[100mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_black(text: String) -> String { - run(text, code([100], 49)) -} - -/// Colour the given text's background bright red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_red("lucy") -/// // => "\x1B[101mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_red(text: String) -> String { - run(text, code([101], 49)) -} - -/// Colour the given text's background bright green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_green("lucy") -/// // => "\x1B[102mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_green(text: String) -> String { - run(text, code([102], 49)) -} - -/// Colour the given text's background bright yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_yellow("lucy") -/// // => "\x1B[103mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_yellow(text: String) -> String { - run(text, code([103], 49)) -} - -/// Colour the given text's background bright blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_blue("lucy") -/// // => "\x1B[104mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_blue(text: String) -> String { - run(text, code([104], 49)) -} - -/// Colour the given text's background bright magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_magenta("lucy") -/// // => "\x1B[105mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_magenta(text: String) -> String { - run(text, code([105], 49)) -} - -/// Colour the given text's background bright cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_cyan("lucy") -/// // => "\x1B[106mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_cyan(text: String) -> String { - run(text, code([106], 49)) -} - -/// Colour the given text's background bright white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_white("lucy") -/// // => "\x1B[107mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_white(text: String) -> String { - run(text, code([107], 49)) -} - -/// Colour the given text's background pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_pink("lucy") -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_pink(text: String) -> String { - bg_hex(text, 0xffaff3) -} - -/// Colour the given text's background the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_hex(text: String, colour: Int) -> String { - run( - text, - code( - [ - 48, - 2, - bitwise.shift_right(colour, 16) - |> bitwise.and(0xff), - bitwise.shift_right(colour, 8) - |> bitwise.and(0xff), - bitwise.and(colour, 0xff), - ], - 49, - ), - ) -} - -/// Colour the given text's background with the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.bg_colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - bg_hex(text, hex_colour) -} - -/// This is an alias for [`bg_colour`](#bg_colour) for those who prefer the American English -/// spelling. -/// -pub fn bg_color(text: String, colour: Colour) -> String { - bg_colour(text, colour) -} diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl deleted file mode 100644 index 0db99ed781b..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_community@ansi). --compile(no_auto_import). - --export([reset/1, bold/1, dim/1, italic/1, underline/1, inverse/1, hidden/1, strikethrough/1, black/1, red/1, green/1, yellow/1, blue/1, magenta/1, cyan/1, white/1, grey/1, gray/1, bright_black/1, bright_red/1, bright_green/1, bright_yellow/1, bright_blue/1, bright_magenta/1, bright_cyan/1, bright_white/1, pink/1, hex/2, colour/2, color/2, bg_black/1, bg_red/1, bg_green/1, bg_yellow/1, bg_blue/1, bg_magenta/1, bg_cyan/1, bg_white/1, bg_bright_black/1, bg_bright_red/1, bg_bright_green/1, bg_bright_yellow/1, bg_bright_blue/1, bg_bright_magenta/1, bg_bright_cyan/1, bg_bright_white/1, bg_pink/1, bg_hex/2, bg_colour/2, bg_color/2]). --export_type([code/0]). - --type code() :: {code, binary(), binary(), binary()}. - --spec code(list(integer()), integer()) -> code(). -code(Open, Close) -> - Close_str = gleam@int:to_string(Close), - Open_strs = gleam@list:map(Open, fun gleam@int:to_string/1), - {code, - <<<<<<""/utf8, "["/utf8>>/binary, - (gleam@string:join(Open_strs, <<";"/utf8>>))/binary>>/binary, - "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>}. - --spec run(binary(), code()) -> binary(). -run(Text, Code) -> - <<<<(erlang:element(2, Code))/binary, - (gleam@string:replace( - Text, - erlang:element(4, Code), - erlang:element(2, Code) - ))/binary>>/binary, - (erlang:element(3, Code))/binary>>. - --spec reset(binary()) -> binary(). -reset(Text) -> - run(Text, code([0], 0)). - --spec bold(binary()) -> binary(). -bold(Text) -> - run(Text, code([1], 22)). - --spec dim(binary()) -> binary(). -dim(Text) -> - run(Text, code([2], 22)). - --spec italic(binary()) -> binary(). -italic(Text) -> - run(Text, code([3], 23)). - --spec underline(binary()) -> binary(). -underline(Text) -> - run(Text, code([4], 24)). - --spec inverse(binary()) -> binary(). -inverse(Text) -> - run(Text, code([7], 27)). - --spec hidden(binary()) -> binary(). -hidden(Text) -> - run(Text, code([8], 28)). - --spec strikethrough(binary()) -> binary(). -strikethrough(Text) -> - run(Text, code([9], 29)). - --spec black(binary()) -> binary(). -black(Text) -> - run(Text, code([30], 39)). - --spec red(binary()) -> binary(). -red(Text) -> - run(Text, code([31], 39)). - --spec green(binary()) -> binary(). -green(Text) -> - run(Text, code([32], 39)). - --spec yellow(binary()) -> binary(). -yellow(Text) -> - run(Text, code([33], 39)). - --spec blue(binary()) -> binary(). -blue(Text) -> - run(Text, code([34], 39)). - --spec magenta(binary()) -> binary(). -magenta(Text) -> - run(Text, code([35], 39)). - --spec cyan(binary()) -> binary(). -cyan(Text) -> - run(Text, code([36], 39)). - --spec white(binary()) -> binary(). -white(Text) -> - run(Text, code([37], 39)). - --spec grey(binary()) -> binary(). -grey(Text) -> - bright_black(Text). - --spec gray(binary()) -> binary(). -gray(Text) -> - bright_black(Text). - --spec bright_black(binary()) -> binary(). -bright_black(Text) -> - run(Text, code([90], 39)). - --spec bright_red(binary()) -> binary(). -bright_red(Text) -> - run(Text, code([91], 39)). - --spec bright_green(binary()) -> binary(). -bright_green(Text) -> - run(Text, code([92], 39)). - --spec bright_yellow(binary()) -> binary(). -bright_yellow(Text) -> - run(Text, code([93], 39)). - --spec bright_blue(binary()) -> binary(). -bright_blue(Text) -> - run(Text, code([94], 39)). - --spec bright_magenta(binary()) -> binary(). -bright_magenta(Text) -> - run(Text, code([95], 39)). - --spec bright_cyan(binary()) -> binary(). -bright_cyan(Text) -> - run(Text, code([96], 39)). - --spec bright_white(binary()) -> binary(). -bright_white(Text) -> - run(Text, code([97], 39)). - --spec pink(binary()) -> binary(). -pink(Text) -> - hex(Text, 16#ffaff3). - --spec hex(binary(), integer()) -> binary(). -hex(Text, Colour) -> - Colour@1 = gleam@int:clamp(Colour, 16#0, 16#ffffff), - run( - Text, - code( - [38, - 2, - begin - _pipe = gleam@bitwise:shift_right(Colour@1, 16), - gleam@bitwise:'and'(_pipe, 16#ff) - end, - begin - _pipe@1 = gleam@bitwise:shift_right(Colour@1, 8), - gleam@bitwise:'and'(_pipe@1, 16#ff) - end, - gleam@bitwise:'and'(Colour@1, 16#ff)], - 39 - ) - ). - --spec colour(binary(), gleam_community@colour:colour()) -> binary(). -colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - hex(Text, Hex_colour). - --spec color(binary(), gleam_community@colour:colour()) -> binary(). -color(Text, Color) -> - colour(Text, Color). - --spec bg_black(binary()) -> binary(). -bg_black(Text) -> - run(Text, code([40], 49)). - --spec bg_red(binary()) -> binary(). -bg_red(Text) -> - run(Text, code([41], 49)). - --spec bg_green(binary()) -> binary(). -bg_green(Text) -> - run(Text, code([42], 49)). - --spec bg_yellow(binary()) -> binary(). -bg_yellow(Text) -> - run(Text, code([43], 49)). - --spec bg_blue(binary()) -> binary(). -bg_blue(Text) -> - run(Text, code([44], 49)). - --spec bg_magenta(binary()) -> binary(). -bg_magenta(Text) -> - run(Text, code([45], 49)). - --spec bg_cyan(binary()) -> binary(). -bg_cyan(Text) -> - run(Text, code([46], 49)). - --spec bg_white(binary()) -> binary(). -bg_white(Text) -> - run(Text, code([47], 49)). - --spec bg_bright_black(binary()) -> binary(). -bg_bright_black(Text) -> - run(Text, code([100], 49)). - --spec bg_bright_red(binary()) -> binary(). -bg_bright_red(Text) -> - run(Text, code([101], 49)). - --spec bg_bright_green(binary()) -> binary(). -bg_bright_green(Text) -> - run(Text, code([102], 49)). - --spec bg_bright_yellow(binary()) -> binary(). -bg_bright_yellow(Text) -> - run(Text, code([103], 49)). - --spec bg_bright_blue(binary()) -> binary(). -bg_bright_blue(Text) -> - run(Text, code([104], 49)). - --spec bg_bright_magenta(binary()) -> binary(). -bg_bright_magenta(Text) -> - run(Text, code([105], 49)). - --spec bg_bright_cyan(binary()) -> binary(). -bg_bright_cyan(Text) -> - run(Text, code([106], 49)). - --spec bg_bright_white(binary()) -> binary(). -bg_bright_white(Text) -> - run(Text, code([107], 49)). - --spec bg_pink(binary()) -> binary(). -bg_pink(Text) -> - bg_hex(Text, 16#ffaff3). - --spec bg_hex(binary(), integer()) -> binary(). -bg_hex(Text, Colour) -> - run( - Text, - code( - [48, - 2, - begin - _pipe = gleam@bitwise:shift_right(Colour, 16), - gleam@bitwise:'and'(_pipe, 16#ff) - end, - begin - _pipe@1 = gleam@bitwise:shift_right(Colour, 8), - gleam@bitwise:'and'(_pipe@1, 16#ff) - end, - gleam@bitwise:'and'(Colour, 16#ff)], - 49 - ) - ). - --spec bg_colour(binary(), gleam_community@colour:colour()) -> binary(). -bg_colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - bg_hex(Text, Hex_colour). - --spec bg_color(binary(), gleam_community@colour:colour()) -> binary(). -bg_color(Text, Colour) -> - bg_colour(Text, Colour). diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src deleted file mode 100644 index 75be12e5003..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, gleam_community_ansi, [ - {vsn, "1.1.0"}, - {applications, [gleam_bitwise, - gleam_community_colour, - gleam_stdlib, - gleeunit]}, - {description, "ANSI colours, formatting, and control codes"}, - {modules, [gleam_community@ansi]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE b/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/README.md b/test-community-packages-javascript/build/packages/gleam_community_colour/README.md deleted file mode 100644 index 0eccdd7dd50..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# gleam-community/colour - -A package for a standard Colour type, conversions, and other utilities. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_colour)](https://hex.pm/packages/gleam_community_colour) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_colour/) - -✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! - ---- - -## Quickstart - -```gleam -import gleam_community/colour -import gleam_community/colour/accessibility - -pub fn main() { - let foreground = colour.from_hsl(h: 0.858, s: 1.0, l: 0.843) - - let background_options = [colour.light_grey, colour.dark_grey] - - let background = accessibility.maximum_contrast(foreground, background_options) -} -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_colour) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_colour -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_colour). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml b/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml deleted file mode 100644 index 36aa4270553..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml +++ /dev/null @@ -1,12 +0,0 @@ -name = "gleam_community_colour" -version = "1.1.0" -licences = ["Apache-2.0"] -description = "Colour types, conversions, and other utilities" -repository = { type = "github", user = "gleam-community", repo = "colour" } - -[dependencies] -gleam_bitwise = "~> 1.2" -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl deleted file mode 100644 index 06116dfe288..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl +++ /dev/null @@ -1 +0,0 @@ --record(hsla, {h :: float(), s :: float(), l :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl deleted file mode 100644 index fff139e06ac..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl +++ /dev/null @@ -1 +0,0 @@ --record(rgba, {r :: float(), g :: float(), b :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam deleted file mode 100644 index 50244b5ab4f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam +++ /dev/null @@ -1,1127 +0,0 @@ -//// -//// - **Types** -//// - [`Colour`](#Colour) -//// - [`Color`](#Color) -//// - **Constructors** -//// - [`from_rgb255`](#from_rgb255) -//// - [`from_rgb`](#from_rgb) -//// - [`from_rgba`](#from_rgba) -//// - [`from_hsl`](#from_hsl) -//// - [`from_hsla`](#from_hsla) -//// - [`from_rgb_hex`](#from_rgb_hex) -//// - [`from_rgba_hex`](#from_rgba_hex) -//// - [`from_rgb_hex_string`](#from_rgb_hex_string) -//// - [`from_rgba_hex_string`](#from_rgba_hex_string) -//// - **Conversions** -//// - [`to_rgba`](#to_rgba) -//// - [`to_hsla`](#hsla) -//// - [`to_css_rgba_string`](#to_css_rgba_string) -//// - [`to_rgba_hex_string`](#to_rgba_hex_string) -//// - [`to_rgb_hex_string`](#to_rgb_hex_string) -//// - [`to_rgba_hex`](#to_rgba_hex) -//// - [`to_rgb_hex`](#to_rgb_hex) -//// - **Colours** -//// - [`light_red`](#light_red) -//// - [`red`](#red) -//// - [`dark_red`](#dark_red) -//// - [`light_orange`](#light_orange) -//// - [`orange`](#orange) -//// - [`dark_orange`](#dark_orange) -//// - [`light_yellow`](#light_yellow) -//// - [`yellow`](#yellow) -//// - [`dark_yellow`](#dark_yellow) -//// - [`light_green`](#light_green) -//// - [`green`](#green) -//// - [`dark_green`](#dark_green) -//// - [`light_blue`](#light_blue) -//// - [`blue`](#blue) -//// - [`dark_blue`](#dark_blue) -//// - [`light_purple`](#light_purple) -//// - [`purple`](#purple) -//// - [`dark_purple`](#dark_purple) -//// - [`light_brown`](#light_brown) -//// - [`brown`](#brown) -//// - [`dark_brown`](#dark_brown) -//// - [`black`](#black) -//// - [`white`](#white) -//// - [`light_grey`](#light_grey) -//// - [`grey`](#grey) -//// - [`dark_grey`](#dark_grey) -//// - [`light_gray`](#light_gray) -//// - [`gray`](#gray) -//// - [`dark_gray`](#dark_gray) -//// - [`light_charcoal`](#light_charcoal) -//// - [`charcoal`](#charcoal) -//// - [`dark_charcoal`](#dark_charcoal) -//// - [`pink`](#pink) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color` module. -//// The original source code can be found -//// <a href="https://github.com/avh4/elm-color/">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018 Aaron VonderHaar -//// -//// > Redistribution and use in source and binary forms, with or without modification, -//// are permitted provided that the following conditions are met: -//// -//// 1. Redistributions of source code must retain the above copyright notice, -//// this list of conditions and the following disclaimer. -//// -//// 2. Redistributions in binary form must reproduce the above copyright notice, -//// this list of conditions and the following disclaimer in the documentation -//// and/or other materials provided with the distribution. -//// -//// 3. Neither the name of the copyright holder nor the names of its contributors -//// may be used to endorse or promote products derived from this software without -//// specific prior written permission. -//// -//// > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -//// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -//// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -//// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -//// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -//// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color` module: -// -// https://github.com/avh4/elm-color/ -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/bitwise -import gleam/int -import gleam/float -import gleam/result -import gleam/string -import gleam/list - -// TYPES ---------------------------------------------------------------------- - -/// A representation of a colour that can be converted to RGBA or HSLA format. -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub opaque type Colour { - Rgba(r: Float, g: Float, b: Float, a: Float) - Hsla(h: Float, s: Float, l: Float, a: Float) -} - -/// Type alias for `Colour` -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub type Color = - Colour - -// UTILITY -------------------------------------------------------------------- - -fn valid_colour_value(c: Float) -> Result(Float, Nil) { - case c >. 1.0 || c <. 0.0 { - True -> Error(Nil) - False -> Ok(c) - } -} - -fn hue_to_rgb(hue: Float, m1: Float, m2: Float) -> Float { - let h = case hue { - _ if hue <. 0.0 -> hue +. 1.0 - _ if hue >. 1.0 -> hue -. 1.0 - _ -> hue - } - - let h_t_6 = h *. 6.0 - let h_t_2 = h *. 2.0 - let h_t_3 = h *. 3.0 - - case h { - _ if h_t_6 <. 1.0 -> m1 +. { m2 -. m1 } *. h *. 6.0 - _ if h_t_2 <. 1.0 -> m2 - _ if h_t_3 <. 2.0 -> m1 +. { m2 -. m1 } *. { 2.0 /. 3.0 -. h } *. 6.0 - _ -> m1 - } -} - -fn hex_string_to_int(hex_string: String) -> Result(Int, Nil) { - let hex = case hex_string { - "#" <> hex_number -> hex_number - "0x" <> hex_number -> hex_number - _ -> hex_string - } - - hex - |> string.lowercase() - |> string.to_graphemes() - |> list.reverse() - |> list.index_fold( - Ok(0), - fn(total, char, index) { - case total { - Error(Nil) -> Error(Nil) - Ok(v) -> { - use num <- result.then(case char { - "a" -> Ok(10) - "b" -> Ok(11) - "c" -> Ok(12) - "d" -> Ok(13) - "e" -> Ok(14) - "f" -> Ok(15) - _ -> int.parse(char) - }) - use base <- result.then(int.power(16, int.to_float(index))) - Ok(v + float.round(int.to_float(num) *. base)) - } - } - }, - ) -} - -fn hsla_to_rgba( - h: Float, - s: Float, - l: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let m2 = case l <=. 0.5 { - True -> l *. { s +. 1.0 } - False -> l +. s -. l *. s - } - - let m1 = l *. 2.0 -. m2 - - let r = hue_to_rgb(h +. 1.0 /. 3.0, m1, m2) - let g = hue_to_rgb(h, m1, m2) - let b = hue_to_rgb(h -. 1.0 /. 3.0, m1, m2) - - #(r, g, b, a) -} - -fn rgba_to_hsla( - r: Float, - g: Float, - b: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let min_colour = float.min(r, float.min(g, b)) - - let max_colour = float.max(r, float.max(g, b)) - - let h1 = case True { - _ if max_colour == r -> float.divide(g -. b, max_colour -. min_colour) - _ if max_colour == g -> - float.divide(b -. r, max_colour -. min_colour) - |> result.then(fn(d) { Ok(2.0 +. d) }) - _ -> - float.divide(r -. g, max_colour -. min_colour) - |> result.then(fn(d) { Ok(4.0 +. d) }) - } - - let h2 = case h1 { - Ok(v) -> Ok(v *. { 1.0 /. 6.0 }) - _ -> h1 - } - - let h3 = case h2 { - Ok(v) if v <. 0.0 -> v +. 1.0 - Ok(v) -> v - _ -> 0.0 - } - - let l = { min_colour +. max_colour } /. 2.0 - - let s = case True { - _ if min_colour == max_colour -> 0.0 - _ if l <. 0.5 -> - { max_colour -. min_colour } /. { max_colour +. min_colour } - _ -> { max_colour -. min_colour } /. { 2.0 -. max_colour -. min_colour } - } - - #(h3, s, l, a) -} - -// CONSTRUCTORS --------------------------------------------------------------- - -/// Returns a `Result(Colour)` created from the given 8 bit RGB values. -/// -/// Returns `Error(Nil)` if the supplied RGB values are greater than 255 or less than 0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb255(r red: Int, g green: Int, b blue: Int) -> Result(Colour, Nil) { - use r <- result.then( - red - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use g <- result.then( - green - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use b <- result.then( - blue - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGB values. -/// -/// If the supplied RGB values are greater than 1.0 or less than 0.0 returns `Error(Nil)` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb(1.0, 0.0, 0.0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb( - r red: Float, - g green: Float, - b blue: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGBA values. -/// -/// Returns `Error(Nil)` if the supplied RGBA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rbga(1.0, 0.0, 0.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba( - r red: Float, - g green: Float, - b blue: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Rgba(r: r, g: g, b: b, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSLA values. -/// -/// Returns `Error(Nil)`f the supplied HSLA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_hsla(0.0, 1.0, 0.5, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsla( - h hue: Float, - s saturation: Float, - l lightness: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use h <- result.then(valid_colour_value(hue)) - use s <- result.then(valid_colour_value(saturation)) - use l <- result.then(valid_colour_value(lightness)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Hsla(h: h, s: s, l: l, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSL values. -/// -/// Returns `Error(Nil)` if the supplied HSL values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_hsla(0.0, 1.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsl( - h hue: Float, - s saturation: Float, - l lightness: Float, -) -> Result(Colour, Nil) { - from_hsla(hue, saturation, lightness, 1.0) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex(0xff0000) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffff || hex < 0 { - True -> Error(Nil) - False -> { - let r = - bitwise.shift_right(hex, 16) - |> bitwise.and(0xff) - let g = - bitwise.shift_right(hex, 8) - |> bitwise.and(0xff) - let b = bitwise.and(hex, 0xff) - from_rgb255(r, g, b) - } - } -} - -/// Returns a `Result(Colour)` created from the given RGB hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex_string("#ff0000") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgb_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given RGBA hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex_string("#ff00007f") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgba_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex(0xff00007f) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffffff || hex < 0 { - True -> Error(Nil) - False -> { - // This won't fail because we are always dividing by 255.0 - let assert Ok(r) = - bitwise.shift_right(hex, 24) - |> bitwise.and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(g) = - bitwise.shift_right(hex, 16) - |> bitwise.and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(b) = - bitwise.shift_right(hex, 8) - |> bitwise.and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(a) = - bitwise.and(hex, 0xff) - |> int.to_float() - |> float.divide(255.0) - from_rgba(r, g, b, a) - } - } -} - -// CONVERSIONS ---------------------------------------------------------------- - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// R, G, B, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(r, g, b, a) = to_rgba(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Rgba(r, g, b, a) -> #(r, g, b, a) - Hsla(h, s, l, a) -> hsla_to_rgba(h, s, l, a) - } -} - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// H, S, L, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(h, s, l, a) = to_hsla(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_hsla(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Hsla(h, s, l, a) -> #(h, s, l, a) - Rgba(r, g, b, a) -> rgba_to_hsla(r, g, b, a) - } -} - -/// Returns an rgba formatted CSS `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let css_red = to_css_rgba_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_css_rgba_string(colour: Colour) -> String { - let #(r, g, b, a) = to_rgba(colour) - - let percent = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 100.0 - let assert Ok(p) = - x - |> float.multiply(10_000.0) - |> float.round() - |> int.to_float() - |> float.divide(100.0) - - p - } - - let round_to = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 1000.0 - let assert Ok(r) = - x - |> float.multiply(1000.0) - |> float.round() - |> int.to_float() - |> float.divide(1000.0) - - r - } - - string.join( - [ - "rgba(", - float.to_string(percent(r)) <> "%,", - float.to_string(percent(g)) <> "%,", - float.to_string(percent(b)) <> "%,", - float.to_string(round_to(a)), - ")", - ], - "", - ) -} - -/// Returns an rgba hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex = to_rgba_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex_string(colour: Colour) -> String { - to_rgba_hex(colour) - |> int.to_base16() -} - -/// Returns an rgb hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex = to_rgb_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex_string(colour: Colour) -> String { - to_rgb_hex(colour) - |> int.to_base16() -} - -/// Returns an hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex_int = to_rgba_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex(colour: Colour) -> Int { - let #(r, g, b, a) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> bitwise.shift_left(24) - - let green = - g *. 255.0 - |> float.round() - |> bitwise.shift_left(16) - - let blue = - b *. 255.0 - |> float.round() - |> bitwise.shift_left(8) - - let alpha = - a *. 255.0 - |> float.round() - - red + green + blue + alpha -} - -/// Returns a rgb hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex_int = to_rgb_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex(colour: Colour) -> Int { - let #(r, g, b, _) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> bitwise.shift_left(16) - - let green = - g *. 255.0 - |> float.round() - |> bitwise.shift_left(8) - - let blue = - b *. 255.0 - |> float.round() - - red + green + blue -} - -// COLOURS -------------------------------------------------------------------- - -/// A `Colour` reprsenting the colour RGBA(239, 41, 41, 1.0) -pub const light_red = Rgba( - r: 0.9372549019607843, - g: 0.1607843137254902, - b: 0.1607843137254902, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(204, 0, 0, 1.0) -pub const red = Rgba(r: 0.8, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(164, 0, 0, 1.0) -pub const dark_red = Rgba(r: 0.6431372549019608, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(252, 175, 62, 1.0) -pub const light_orange = Rgba( - r: 0.9882352941176471, - g: 0.6862745098039216, - b: 0.24313725490196078, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(245, 121, 0, 1.0) -pub const orange = Rgba( - r: 0.9607843137254902, - g: 0.4745098039215686, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(206, 92, 0, 1.0) -pub const dark_orange = Rgba( - r: 0.807843137254902, - g: 0.3607843137254902, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 233, 79, 1.0) -pub const light_yellow = Rgba( - r: 1.0, - g: 0.9137254901960784, - b: 0.30980392156862746, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(237, 212, 0, 1.0) -pub const yellow = Rgba( - r: 0.9294117647058824, - g: 0.8313725490196079, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(196, 160, 0, 1.0) -pub const dark_yellow = Rgba( - r: 0.7686274509803922, - g: 0.6274509803921569, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(138, 226, 52, 1.0) -pub const light_green = Rgba( - r: 0.5411764705882353, - g: 0.8862745098039215, - b: 0.20392156862745098, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(115, 210, 22, 1.0) -pub const green = Rgba( - r: 0.45098039215686275, - g: 0.8235294117647058, - b: 0.08627450980392157, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(78, 154, 6, 1.0) -pub const dark_green = Rgba( - r: 0.3058823529411765, - g: 0.6039215686274509, - b: 0.023529411764705882, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(114, 159, 207, 1.0) -pub const light_blue = Rgba( - r: 0.4470588235294118, - g: 0.6235294117647059, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(52, 101, 164, 1.0) -pub const blue = Rgba( - r: 0.20392156862745098, - g: 0.396078431372549, - b: 0.6431372549019608, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(32, 74, 135, 1.0) -pub const dark_blue = Rgba( - r: 0.12549019607843137, - g: 0.2901960784313726, - b: 0.5294117647058824, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(173, 127, 168, 1.0) -pub const light_purple = Rgba( - r: 0.6784313725490196, - g: 0.4980392156862745, - b: 0.6588235294117647, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(117, 80, 123, 1.0) -pub const purple = Rgba( - r: 0.4588235294117647, - g: 0.3137254901960784, - b: 0.4823529411764706, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(92, 53, 102, 1.0) -pub const dark_purple = Rgba( - r: 0.3607843137254902, - g: 0.20784313725490197, - b: 0.4, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(233, 185, 110, 1.0) -pub const light_brown = Rgba( - r: 0.9137254901960784, - g: 0.7254901960784313, - b: 0.43137254901960786, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(193, 125, 17, 1.0) -pub const brown = Rgba( - r: 0.7568627450980392, - g: 0.49019607843137253, - b: 0.06666666666666667, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(143, 89, 2, 1.0) -pub const dark_brown = Rgba( - r: 0.5607843137254902, - g: 0.34901960784313724, - b: 0.00784313725490196, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(0, 0, 0, 1.0) -pub const black = Rgba(r: 0.0, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(255, 255, 255, 1.0) -pub const white = Rgba(r: 1.0, g: 1.0, b: 1.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_grey = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const grey = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_grey = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_gray = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const gray = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_gray = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(136, 138, 133, 1.0) -pub const light_charcoal = Rgba( - r: 0.5333333333333333, - g: 0.5411764705882353, - b: 0.5215686274509804, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(85, 87, 83, 1.0) -pub const charcoal = Rgba( - r: 0.3333333333333333, - g: 0.3411764705882353, - b: 0.3254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(46, 52, 54, 1.0) -pub const dark_charcoal = Rgba( - r: 0.1803921568627451, - g: 0.20392156862745098, - b: 0.21176470588235294, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 175, 243, 1.0) -pub const pink = Rgba( - r: 1.0, - g: 0.6862745098039216, - b: 0.9529411764705882, - a: 1.0, -) diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam deleted file mode 100644 index 471685732f9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam +++ /dev/null @@ -1,173 +0,0 @@ -//// -//// - **Accessibility** -//// - [`luminance`](#luminance) -//// - [`contrast_ratio`](#contrast_ratio) -//// - [`maximum_contrast`](#maximum_contrast) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color-extra` module. -//// The original source code can be found -//// <a href="https://github.com/noahzgordon/elm-color-extra">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright (c) 2016 Andreas Köberle -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// -//// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -//// SOFTWARE. -//// -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color-extra` module: -// -// https://github.com/noahzgordon/elm-color-extra -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/float -import gleam/list -import gleam_community/colour.{Colour} - -// UTILITIES ------------------------------------------------------------------ - -fn intensity(colour_value: Float) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - case True { - _ if colour_value <=. 0.03928 -> colour_value /. 12.92 - _ -> { - // Is this guaranteed to be `OK`? - let assert Ok(i) = float.power({ colour_value +. 0.055 } /. 1.055, 2.4) - i - } - } -} - -// ACCESSIBILITY -------------------------------------------------------------- - -/// Returns the relative brightness of the given `Colour` as a `Float` between -/// 0.0, and 1.0 with 0.0 being the darkest possible colour and 1.0 being the lightest. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// luminance(colour.white) // 1.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn luminance(colour: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - let #(r, g, b, _) = colour.to_rgba(colour) - - let r_intensity = intensity(r) - let g_intensity = intensity(g) - let b_intensity = intensity(b) - - 0.2126 *. r_intensity +. 0.7152 *. g_intensity +. 0.0722 *. b_intensity -} - -/// Returns the contrast between two `Colour` values as a `Float` between 1.0, -/// and 21.0 with 1.0 being no contrast and, 21.0 being the highest possible contrast. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// contrast_ratio(between: colour.white, and: colour.black) // 21.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn contrast_ratio(between colour_a: Colour, and colour_b: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#contrast-ratiodef - let luminance_a = luminance(colour_a) +. 0.05 - let luminance_b = luminance(colour_b) +. 0.05 - - case luminance_a >. luminance_b { - True -> luminance_a /. luminance_b - False -> luminance_b /. luminance_a - } -} - -/// Returns the `Colour` with the highest contrast between the base `Colour`, -/// and and the other provided `Colour` values. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// maximum_contrast( -/// colour.yellow, -/// [colour.white, colour.dark_blue, colour.green], -/// ) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn maximum_contrast( - base: Colour, - colours: List(Colour), -) -> Result(Colour, Nil) { - colours - |> list.sort(fn(colour_a, colour_b) { - let contrast_a = contrast_ratio(base, colour_a) - let contrast_b = contrast_ratio(base, colour_b) - - float.compare(contrast_b, contrast_a) - }) - |> list.first() -} diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl deleted file mode 100644 index 6b3063f7aa0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl +++ /dev/null @@ -1,525 +0,0 @@ --module(gleam_community@colour). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_rgb255/3, from_rgb/3, from_rgba/4, from_hsla/4, from_hsl/3, from_rgb_hex/1, from_rgb_hex_string/1, from_rgba_hex/1, from_rgba_hex_string/1, to_rgba/1, to_hsla/1, to_css_rgba_string/1, to_rgba_hex/1, to_rgba_hex_string/1, to_rgb_hex/1, to_rgb_hex_string/1]). --export_type([colour/0]). - --opaque colour() :: {rgba, float(), float(), float(), float()} | - {hsla, float(), float(), float(), float()}. - --spec valid_colour_value(float()) -> {ok, float()} | {error, nil}. -valid_colour_value(C) -> - case (C > 1.0) orelse (C < 0.0) of - true -> - {error, nil}; - - false -> - {ok, C} - end. - --spec hue_to_rgb(float(), float(), float()) -> float(). -hue_to_rgb(Hue, M1, M2) -> - H = case Hue of - _ when Hue < 0.0 -> - Hue + 1.0; - - _ when Hue > 1.0 -> - Hue - 1.0; - - _ -> - Hue - end, - H_t_6 = H * 6.0, - H_t_2 = H * 2.0, - H_t_3 = H * 3.0, - case H of - _ when H_t_6 < 1.0 -> - M1 + (((M2 - M1) * H) * 6.0); - - _ when H_t_2 < 1.0 -> - M2; - - _ when H_t_3 < 2.0 -> - M1 + (((M2 - M1) * ((2.0 / 3.0) - H)) * 6.0); - - _ -> - M1 - end. - --spec hex_string_to_int(binary()) -> {ok, integer()} | {error, nil}. -hex_string_to_int(Hex_string) -> - Hex = case Hex_string of - <<"#"/utf8, Hex_number/binary>> -> - Hex_number; - - <<"0x"/utf8, Hex_number@1/binary>> -> - Hex_number@1; - - _ -> - Hex_string - end, - _pipe = Hex, - _pipe@1 = gleam@string:lowercase(_pipe), - _pipe@2 = gleam@string:to_graphemes(_pipe@1), - _pipe@3 = gleam@list:reverse(_pipe@2), - gleam@list:index_fold( - _pipe@3, - {ok, 0}, - fun(Total, Char, Index) -> case Total of - {error, nil} -> - {error, nil}; - - {ok, V} -> - gleam@result:then(case Char of - <<"a"/utf8>> -> - {ok, 10}; - - <<"b"/utf8>> -> - {ok, 11}; - - <<"c"/utf8>> -> - {ok, 12}; - - <<"d"/utf8>> -> - {ok, 13}; - - <<"e"/utf8>> -> - {ok, 14}; - - <<"f"/utf8>> -> - {ok, 15}; - - _ -> - gleam@int:parse(Char) - end, fun(Num) -> - gleam@result:then( - gleam@int:power(16, gleam@int:to_float(Index)), - fun(Base) -> - {ok, - V - + gleam@float:round( - gleam@int:to_float(Num) - * Base - )} - end - ) - end) - end end - ). - --spec hsla_to_rgba(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -hsla_to_rgba(H, S, L, A) -> - M2 = case L =< 0.5 of - true -> - L * (S + 1.0); - - false -> - (L + S) - (L * S) - end, - M1 = (L * 2.0) - M2, - R = hue_to_rgb(H + (1.0 / 3.0), M1, M2), - G = hue_to_rgb(H, M1, M2), - B = hue_to_rgb(H - (1.0 / 3.0), M1, M2), - {R, G, B, A}. - --spec rgba_to_hsla(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -rgba_to_hsla(R, G, B, A) -> - Min_colour = gleam@float:min(R, gleam@float:min(G, B)), - Max_colour = gleam@float:max(R, gleam@float:max(G, B)), - H1 = case true of - _ when Max_colour =:= R -> - gleam@float:divide(G - B, Max_colour - Min_colour); - - _ when Max_colour =:= G -> - _pipe = gleam@float:divide(B - R, Max_colour - Min_colour), - gleam@result:then(_pipe, fun(D) -> {ok, 2.0 + D} end); - - _ -> - _pipe@1 = gleam@float:divide(R - G, Max_colour - Min_colour), - gleam@result:then(_pipe@1, fun(D@1) -> {ok, 4.0 + D@1} end) - end, - H2 = case H1 of - {ok, V} -> - {ok, V * (1.0 / 6.0)}; - - _ -> - H1 - end, - H3 = case H2 of - {ok, V@1} when V@1 < 0.0 -> - V@1 + 1.0; - - {ok, V@2} -> - V@2; - - _ -> - 0.0 - end, - L = (Min_colour + Max_colour) / 2.0, - S = case true of - _ when Min_colour =:= Max_colour -> - 0.0; - - _ when L < 0.5 -> - case (Max_colour + Min_colour) of - 0.0 -> 0.0; - Gleam@denominator -> (Max_colour - Min_colour) / Gleam@denominator - end; - - _ -> - case ((2.0 - Max_colour) - Min_colour) of - 0.0 -> 0.0; - Gleam@denominator@1 -> (Max_colour - Min_colour) / Gleam@denominator@1 - end - end, - {H3, S, L, A}. - --spec from_rgb255(integer(), integer(), integer()) -> {ok, colour()} | - {error, nil}. -from_rgb255(Red, Green, Blue) -> - gleam@result:then( - begin - _pipe = Red, - _pipe@1 = gleam@int:to_float(_pipe), - _pipe@2 = gleam@float:divide(_pipe@1, 255.0), - gleam@result:then(_pipe@2, fun valid_colour_value/1) - end, - fun(R) -> - gleam@result:then( - begin - _pipe@3 = Green, - _pipe@4 = gleam@int:to_float(_pipe@3), - _pipe@5 = gleam@float:divide(_pipe@4, 255.0), - gleam@result:then(_pipe@5, fun valid_colour_value/1) - end, - fun(G) -> - gleam@result:then( - begin - _pipe@6 = Blue, - _pipe@7 = gleam@int:to_float(_pipe@6), - _pipe@8 = gleam@float:divide(_pipe@7, 255.0), - gleam@result:then(_pipe@8, fun valid_colour_value/1) - end, - fun(B) -> - {ok, {rgba, R, G, B, 1.0}} - end - ) - end - ) - end - ). - --spec from_rgb(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_rgb(Red, Green, Blue) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> - {ok, {rgba, R, G, B, 1.0}} - end - ) - end - ) - end - ). - --spec from_rgba(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_rgba(Red, Green, Blue, Alpha) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> - {ok, {rgba, R, G, B, A}} - end - ) - end - ) - end - ) - end - ). - --spec from_hsla(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_hsla(Hue, Saturation, Lightness, Alpha) -> - gleam@result:then( - valid_colour_value(Hue), - fun(H) -> - gleam@result:then( - valid_colour_value(Saturation), - fun(S) -> - gleam@result:then( - valid_colour_value(Lightness), - fun(L) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> - {ok, {hsla, H, S, L, A}} - end - ) - end - ) - end - ) - end - ). - --spec from_hsl(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_hsl(Hue, Saturation, Lightness) -> - from_hsla(Hue, Saturation, Lightness, 1.0). - --spec from_rgb_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgb_hex(Hex) -> - case (Hex > 16#ffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - R = begin - _pipe = gleam@bitwise:shift_right(Hex, 16), - gleam@bitwise:'and'(_pipe, 16#ff) - end, - G = begin - _pipe@1 = gleam@bitwise:shift_right(Hex, 8), - gleam@bitwise:'and'(_pipe@1, 16#ff) - end, - B = gleam@bitwise:'and'(Hex, 16#ff), - from_rgb255(R, G, B) - end. - --spec from_rgb_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgb_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> - from_rgb_hex(Hex_int) - end - ). - --spec from_rgba_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgba_hex(Hex) -> - case (Hex > 16#ffffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - _assert_subject = begin - _pipe = gleam@bitwise:shift_right(Hex, 24), - _pipe@1 = gleam@bitwise:'and'(_pipe, 16#ff), - _pipe@2 = gleam@int:to_float(_pipe@1), - gleam@float:divide(_pipe@2, 255.0) - end, - {ok, R} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 589}) - end, - _assert_subject@1 = begin - _pipe@3 = gleam@bitwise:shift_right(Hex, 16), - _pipe@4 = gleam@bitwise:'and'(_pipe@3, 16#ff), - _pipe@5 = gleam@int:to_float(_pipe@4), - gleam@float:divide(_pipe@5, 255.0) - end, - {ok, G} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 595}) - end, - _assert_subject@2 = begin - _pipe@6 = gleam@bitwise:shift_right(Hex, 8), - _pipe@7 = gleam@bitwise:'and'(_pipe@6, 16#ff), - _pipe@8 = gleam@int:to_float(_pipe@7), - gleam@float:divide(_pipe@8, 255.0) - end, - {ok, B} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 601}) - end, - _assert_subject@3 = begin - _pipe@9 = gleam@bitwise:'and'(Hex, 16#ff), - _pipe@10 = gleam@int:to_float(_pipe@9), - gleam@float:divide(_pipe@10, 255.0) - end, - {ok, A} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 607}) - end, - from_rgba(R, G, B, A) - end. - --spec from_rgba_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgba_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> - from_rgba_hex(Hex_int) - end - ). - --spec to_rgba(colour()) -> {float(), float(), float(), float()}. -to_rgba(Colour) -> - case Colour of - {rgba, R, G, B, A} -> - {R, G, B, A}; - - {hsla, H, S, L, A@1} -> - hsla_to_rgba(H, S, L, A@1) - end. - --spec to_hsla(colour()) -> {float(), float(), float(), float()}. -to_hsla(Colour) -> - case Colour of - {hsla, H, S, L, A} -> - {H, S, L, A}; - - {rgba, R, G, B, A@1} -> - rgba_to_hsla(R, G, B, A@1) - end. - --spec to_css_rgba_string(colour()) -> binary(). -to_css_rgba_string(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Percent = fun(X) -> - _assert_subject = begin - _pipe = X, - _pipe@1 = gleam@float:multiply(_pipe, 10000.0), - _pipe@2 = gleam@float:round(_pipe@1), - _pipe@3 = gleam@int:to_float(_pipe@2), - gleam@float:divide(_pipe@3, 100.0) - end, - {ok, P} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 705}) - end, - P - end, - Round_to = fun(X@1) -> - _assert_subject@1 = begin - _pipe@4 = X@1, - _pipe@5 = gleam@float:multiply(_pipe@4, 1000.0), - _pipe@6 = gleam@float:round(_pipe@5), - _pipe@7 = gleam@int:to_float(_pipe@6), - gleam@float:divide(_pipe@7, 1000.0) - end, - {ok, R@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 717}) - end, - R@1 - end, - gleam@string:join( - [<<"rgba("/utf8>>, - <<(gleam@float:to_string(Percent(R)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(G)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(B)))/binary, "%,"/utf8>>, - gleam@float:to_string(Round_to(A)), - <<")"/utf8>>], - <<""/utf8>> - ). - --spec to_rgba_hex(colour()) -> integer(). -to_rgba_hex(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - gleam@bitwise:shift_left(_pipe@1, 24) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - gleam@bitwise:shift_left(_pipe@3, 16) - end, - Blue = begin - _pipe@4 = B * 255.0, - _pipe@5 = gleam@float:round(_pipe@4), - gleam@bitwise:shift_left(_pipe@5, 8) - end, - Alpha = begin - _pipe@6 = A * 255.0, - gleam@float:round(_pipe@6) - end, - ((Red + Green) + Blue) + Alpha. - --spec to_rgba_hex_string(colour()) -> binary(). -to_rgba_hex_string(Colour) -> - _pipe = to_rgba_hex(Colour), - gleam@int:to_base16(_pipe). - --spec to_rgb_hex(colour()) -> integer(). -to_rgb_hex(Colour) -> - {R, G, B, _} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - gleam@bitwise:shift_left(_pipe@1, 16) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - gleam@bitwise:shift_left(_pipe@3, 8) - end, - Blue = begin - _pipe@4 = B * 255.0, - gleam@float:round(_pipe@4) - end, - (Red + Green) + Blue. - --spec to_rgb_hex_string(colour()) -> binary(). -to_rgb_hex_string(Colour) -> - _pipe = to_rgb_hex(Colour), - gleam@int:to_base16(_pipe). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl deleted file mode 100644 index cacebf288c5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(gleam_community@colour@accessibility). --compile([no_auto_import, nowarn_unused_vars]). - --export([luminance/1, contrast_ratio/2, maximum_contrast/2]). - --spec intensity(float()) -> float(). -intensity(Colour_value) -> - case true of - _ when Colour_value =< 0.03928 -> - Colour_value / 12.92; - - _ -> - _assert_subject = gleam@float:power( - (Colour_value - + 0.055) - / 1.055, - 2.4 - ), - {ok, I} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour/accessibility"/utf8>>, - function => <<"intensity"/utf8>>, - line => 62}) - end, - I - end. - --spec luminance(gleam_community@colour:colour()) -> float(). -luminance(Colour) -> - {R, G, B, _} = gleam_community@colour:to_rgba(Colour), - R_intensity = intensity(R), - G_intensity = intensity(G), - B_intensity = intensity(B), - ((0.2126 * R_intensity) + (0.7152 * G_intensity)) + (0.0722 * B_intensity). - --spec contrast_ratio( - gleam_community@colour:colour(), - gleam_community@colour:colour() -) -> float(). -contrast_ratio(Colour_a, Colour_b) -> - Luminance_a = luminance(Colour_a) + 0.05, - Luminance_b = luminance(Colour_b) + 0.05, - case Luminance_a > Luminance_b of - true -> - case Luminance_b of - 0.0 -> 0.0; - Gleam@denominator -> Luminance_a / Gleam@denominator - end; - - false -> - case Luminance_a of - 0.0 -> 0.0; - Gleam@denominator@1 -> Luminance_b / Gleam@denominator@1 - end - end. - --spec maximum_contrast( - gleam_community@colour:colour(), - list(gleam_community@colour:colour()) -) -> {ok, gleam_community@colour:colour()} | {error, nil}. -maximum_contrast(Base, Colours) -> - _pipe = Colours, - _pipe@1 = gleam@list:sort( - _pipe, - fun(Colour_a, Colour_b) -> - Contrast_a = contrast_ratio(Base, Colour_a), - Contrast_b = contrast_ratio(Base, Colour_b), - gleam@float:compare(Contrast_b, Contrast_a) - end - ), - gleam@list:first(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src deleted file mode 100644 index 4755b196289..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, gleam_community_colour, [ - {vsn, "1.1.0"}, - {applications, [gleam_bitwise, - gleam_stdlib, - gleeunit]}, - {description, "Colour types, conversions, and other utilities"}, - {modules, [gleam_community@colour, - gleam_community@colour@accessibility]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/LICENSE b/test-community-packages-javascript/build/packages/gleam_cors/LICENSE deleted file mode 100644 index 728cade93fb..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Filip Figiel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/README.md b/test-community-packages-javascript/build/packages/gleam_cors/README.md deleted file mode 100644 index d753b8da638..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# gleam_cors - -[![Package Version](https://img.shields.io/hexpm/v/gleam_cors)](https://hex.pm/packages/gleam_cors) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_cors/) - -Unofficial CORS middleware for the [`gleam_http`](https://hexdocs.pm/gleam_http/index.html) library. - -## Installation - -```sh -gleam add gleam_cors -``` - -## Usage - -Use the `middleware` function to set up CORS for your application. This middleware should be -placed early in your middleware stack (late in the pipeline). - -```diff -+import gleam/http/cors -+import gleam/http - import myproject/web/middleware - - pub fn stack() { - service - |> middleware.rescue - |> middleware.log -+ |> cors.middleware( -+ origins: ["http://localhost:8000"], -+ methods: [http.Get, http.Post, http.Delete], -+ headers: ["Authorization", "Content-Type"], -+ ) - } -``` - -## Changelog - -See [CHANGELOG.md](CHANGELOG.md) in the project repository diff --git a/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml b/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml deleted file mode 100644 index c6861872847..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "gleam_cors" -version = "0.2.0" - -licences = ["MIT"] -description = "A CORS middleware for Gleam" -repository = { type = "github", user = "megapctr", repo = "gleam_cors" } - -[dependencies] -gleam_stdlib = "~> 0.29" -gleam_http = "~> 3.2" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam deleted file mode 100644 index 42a869b6441..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam +++ /dev/null @@ -1,227 +0,0 @@ -import gleam/http.{Method, Options} -import gleam/http/request.{Request} -import gleam/http/response -import gleam/http/service.{Middleware} -import gleam/bit_builder.{BitBuilder} -import gleam/result.{try} -import gleam/list -import gleam/set.{Set} -import gleam/function -import gleam/string - -type Config { - Config( - allowed_origins: AllowedOrigins, - allowed_methods: AllowedMethods, - allowed_headers: AllowedHeaders, - ) -} - -type AllowedOrigins { - AllowAll - AllowSome(Set(String)) -} - -type AllowedMethods = - Set(Method) - -type AllowedHeaders = - Set(String) - -const allow_origin_header = "Access-Control-Allow-Origin" - -const allow_all_origins = "*" - -const request_method_header = "Access-Control-Request-Method" - -const request_headers_header = "Access-Control-Request-Headers" - -const allow_headers_header = "Access-Control-Allow-Headers" - -fn parse_config( - allowed_origins: List(String), - allowed_methods: List(Method), - allowed_headers: List(String), -) -> Result(Config, Nil) { - use allowed_origins <- try(parse_allowed_origins(allowed_origins)) - use allowed_methods <- try(parse_allowed_methods(allowed_methods)) - use allowed_headers <- try(parse_allowed_headers(allowed_headers)) - Config(allowed_origins, allowed_methods, allowed_headers) - |> Ok -} - -fn parse_allowed_origins(l: List(String)) -> Result(AllowedOrigins, Nil) { - case list.contains(l, allow_all_origins), l { - True, _ -> Ok(AllowAll) - _, origins -> { - let origins_set = - origins - |> list.map(string.lowercase) - |> set.from_list - // `handler` relies on "" not being in the set, "" is not a valid origin anyway - |> set.delete("") - case set.size(origins_set) { - 0 -> Error(Nil) - _ -> - AllowSome(origins_set) - |> Ok - } - } - } -} - -fn parse_allowed_methods(l: List(Method)) -> Result(AllowedMethods, Nil) { - let methods_set = set.from_list(l) - case set.size(methods_set) { - 0 -> Error(Nil) - _ -> Ok(methods_set) - } -} - -fn parse_allowed_headers(l: List(String)) -> Result(AllowedHeaders, Nil) { - let headers_set = - l - |> list.map(string.lowercase) - |> set.from_list - Ok(headers_set) -} - -type Response = - response.Response(BitBuilder) - -/// A middleware that adds CORS headers to responses based on the given configuration. -/// -/// ## Examples -/// -/// service -/// |> cors.middleware( -/// origins: ["https://staging.example.com", "http://localhost:8000"], -/// methods: [Get, Post, Delete], -/// headers: ["Authorization", "Content-Type"], -/// ) -pub fn middleware( - origins allowed_origins: List(String), - methods allowed_methods: List(Method), - headers allowed_headers: List(String), -) -> Middleware(a, BitBuilder, a, BitBuilder) { - case parse_config(allowed_origins, allowed_methods, allowed_headers) { - Ok(config) -> middleware_from_config(config) - Error(_) -> function.identity - } -} - -fn middleware_from_config( - config: Config, -) -> Middleware(a, BitBuilder, a, BitBuilder) { - fn(service) { - fn(request: Request(a)) -> Response { - case request.method { - Options -> handle_options_request(request, config) - _ -> handle_other_request(service, request, config.allowed_origins) - } - } - } -} - -/// For OPTIONS requests, we must check if request origin, request method and request headers are -/// allowed, and include CORS headers for allowed origin and allowed headers. -fn handle_options_request(request: Request(a), config: Config) -> Response { - let response = - response.new(200) - |> response.set_body(bit_builder.new()) - - let origin = get_origin(request) - - let ac_request_method = - request.get_header(request, request_method_header) - |> result.then(http.parse_method) - |> result.unwrap(http.Other("")) - - let ac_request_headers = - request.get_header(request, request_headers_header) - |> result.map(string.split(_, ", ")) - |> result.unwrap([]) - - let is_request_allowed = - is_origin_allowed(origin, config.allowed_origins) && is_method_allowed( - ac_request_method, - config.allowed_methods, - ) && are_headers_allowed(ac_request_headers, config.allowed_headers) - case is_request_allowed { - True -> - response - |> prepend_allow_origin_header(origin, config.allowed_origins) - |> prepend_allow_headers_header(ac_request_headers) - False -> response - } -} - -/// For other requests, if the request Origin header matches allowed origins, we must include the CORS header for allowed origin. -fn handle_other_request( - service, - request: Request(a), - allowed_origins: AllowedOrigins, -) -> Response { - let origin = get_origin(request) - let response = service(request) - case is_origin_allowed(origin, allowed_origins) { - True -> - response - |> prepend_allow_origin_header(origin, allowed_origins) - False -> response - } -} - -fn get_origin(request: Request(a)) -> String { - request.get_header(request, "origin") - |> result.unwrap("") -} - -fn is_origin_allowed(origin: String, allowed_origins: AllowedOrigins) -> Bool { - case allowed_origins { - AllowAll -> True - AllowSome(origins) -> set.contains(origins, string.lowercase(origin)) - } -} - -fn is_method_allowed(method: Method, allowed_methods: AllowedMethods) -> Bool { - set.contains(allowed_methods, method) -} - -fn are_headers_allowed( - request_headers: List(String), - allowed_headers: AllowedHeaders, -) -> Bool { - list.all( - request_headers, - fn(header) { set.contains(allowed_headers, string.lowercase(header)) }, - ) -} - -fn prepend_allow_origin_header( - response: Response, - origin: String, - allowed_origins: AllowedOrigins, -) -> Response { - case allowed_origins { - AllowAll -> - response - |> response.prepend_header(allow_origin_header, allow_all_origins) - AllowSome(_) -> - response - |> response.prepend_header(allow_origin_header, origin) - |> response.prepend_header("Vary", "Origin") - } -} - -fn prepend_allow_headers_header( - response: Response, - headers: List(String), -) -> Response { - case list.length(headers) { - 0 -> response - _ -> - string.join(headers, ", ") - |> response.prepend_header(response, allow_headers_header, _) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl deleted file mode 100644 index 0f9d5b47cd9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl +++ /dev/null @@ -1,243 +0,0 @@ --module(gleam@http@cors). --compile([no_auto_import, nowarn_unused_vars]). - --export([middleware/3]). --export_type([config/0, allowed_origins/0]). - --type config() :: {config, - allowed_origins(), - gleam@set:set(gleam@http:method()), - gleam@set:set(binary())}. - --type allowed_origins() :: allow_all | {allow_some, gleam@set:set(binary())}. - --spec parse_allowed_origins(list(binary())) -> {ok, allowed_origins()} | - {error, nil}. -parse_allowed_origins(L) -> - case {gleam@list:contains(L, <<"*"/utf8>>), L} of - {true, _} -> - {ok, allow_all}; - - {_, Origins} -> - Origins_set = begin - _pipe = Origins, - _pipe@1 = gleam@list:map(_pipe, fun gleam@string:lowercase/1), - _pipe@2 = gleam@set:from_list(_pipe@1), - gleam@set:delete(_pipe@2, <<""/utf8>>) - end, - case gleam@set:size(Origins_set) of - 0 -> - {error, nil}; - - _ -> - _pipe@3 = {allow_some, Origins_set}, - {ok, _pipe@3} - end - end. - --spec parse_allowed_methods(list(gleam@http:method())) -> {ok, - gleam@set:set(gleam@http:method())} | - {error, nil}. -parse_allowed_methods(L) -> - Methods_set = gleam@set:from_list(L), - case gleam@set:size(Methods_set) of - 0 -> - {error, nil}; - - _ -> - {ok, Methods_set} - end. - --spec parse_allowed_headers(list(binary())) -> {ok, gleam@set:set(binary())} | - {error, nil}. -parse_allowed_headers(L) -> - Headers_set = begin - _pipe = L, - _pipe@1 = gleam@list:map(_pipe, fun gleam@string:lowercase/1), - gleam@set:from_list(_pipe@1) - end, - {ok, Headers_set}. - --spec parse_config(list(binary()), list(gleam@http:method()), list(binary())) -> {ok, - config()} | - {error, nil}. -parse_config(Allowed_origins, Allowed_methods, Allowed_headers) -> - gleam@result:'try'( - parse_allowed_origins(Allowed_origins), - fun(Allowed_origins@1) -> - gleam@result:'try'( - parse_allowed_methods(Allowed_methods), - fun(Allowed_methods@1) -> - gleam@result:'try'( - parse_allowed_headers(Allowed_headers), - fun(Allowed_headers@1) -> - _pipe = {config, - Allowed_origins@1, - Allowed_methods@1, - Allowed_headers@1}, - {ok, _pipe} - end - ) - end - ) - end - ). - --spec get_origin(gleam@http@request:request(any())) -> binary(). -get_origin(Request) -> - _pipe = gleam@http@request:get_header(Request, <<"origin"/utf8>>), - gleam@result:unwrap(_pipe, <<""/utf8>>). - --spec is_origin_allowed(binary(), allowed_origins()) -> boolean(). -is_origin_allowed(Origin, Allowed_origins) -> - case Allowed_origins of - allow_all -> - true; - - {allow_some, Origins} -> - gleam@set:contains(Origins, gleam@string:lowercase(Origin)) - end. - --spec is_method_allowed(gleam@http:method(), gleam@set:set(gleam@http:method())) -> boolean(). -is_method_allowed(Method, Allowed_methods) -> - gleam@set:contains(Allowed_methods, Method). - --spec are_headers_allowed(list(binary()), gleam@set:set(binary())) -> boolean(). -are_headers_allowed(Request_headers, Allowed_headers) -> - gleam@list:all( - Request_headers, - fun(Header) -> - gleam@set:contains(Allowed_headers, gleam@string:lowercase(Header)) - end - ). - --spec prepend_allow_origin_header( - gleam@http@response:response(gleam@bit_builder:bit_builder()), - binary(), - allowed_origins() -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -prepend_allow_origin_header(Response, Origin, Allowed_origins) -> - case Allowed_origins of - allow_all -> - _pipe = Response, - gleam@http@response:prepend_header( - _pipe, - <<"Access-Control-Allow-Origin"/utf8>>, - <<"*"/utf8>> - ); - - {allow_some, _} -> - _pipe@1 = Response, - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"Access-Control-Allow-Origin"/utf8>>, - Origin - ), - gleam@http@response:prepend_header( - _pipe@2, - <<"Vary"/utf8>>, - <<"Origin"/utf8>> - ) - end. - --spec handle_other_request( - fun((gleam@http@request:request(FTP)) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - gleam@http@request:request(FTP), - allowed_origins() -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -handle_other_request(Service, Request, Allowed_origins) -> - Origin = get_origin(Request), - Response = Service(Request), - case is_origin_allowed(Origin, Allowed_origins) of - true -> - _pipe = Response, - prepend_allow_origin_header(_pipe, Origin, Allowed_origins); - - false -> - Response - end. - --spec prepend_allow_headers_header( - gleam@http@response:response(gleam@bit_builder:bit_builder()), - list(binary()) -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -prepend_allow_headers_header(Response, Headers) -> - case gleam@list:length(Headers) of - 0 -> - Response; - - _ -> - _pipe = gleam@string:join(Headers, <<", "/utf8>>), - gleam@http@response:prepend_header( - Response, - <<"Access-Control-Allow-Headers"/utf8>>, - _pipe - ) - end. - --spec handle_options_request(gleam@http@request:request(any()), config()) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -handle_options_request(Request, Config) -> - Response = begin - _pipe = gleam@http@response:new(200), - gleam@http@response:set_body(_pipe, gleam@bit_builder:new()) - end, - Origin = get_origin(Request), - Ac_request_method = begin - _pipe@1 = gleam@http@request:get_header( - Request, - <<"Access-Control-Request-Method"/utf8>> - ), - _pipe@2 = gleam@result:then(_pipe@1, fun gleam@http:parse_method/1), - gleam@result:unwrap(_pipe@2, {other, <<""/utf8>>}) - end, - Ac_request_headers = begin - _pipe@3 = gleam@http@request:get_header( - Request, - <<"Access-Control-Request-Headers"/utf8>> - ), - _pipe@4 = gleam@result:map( - _pipe@3, - fun(_capture) -> gleam@string:split(_capture, <<", "/utf8>>) end - ), - gleam@result:unwrap(_pipe@4, []) - end, - Is_request_allowed = (is_origin_allowed(Origin, erlang:element(2, Config)) - andalso is_method_allowed(Ac_request_method, erlang:element(3, Config))) - andalso are_headers_allowed(Ac_request_headers, erlang:element(4, Config)), - case Is_request_allowed of - true -> - _pipe@5 = Response, - _pipe@6 = prepend_allow_origin_header( - _pipe@5, - Origin, - erlang:element(2, Config) - ), - prepend_allow_headers_header(_pipe@6, Ac_request_headers); - - false -> - Response - end. - --spec middleware_from_config(config()) -> fun((fun((gleam@http@request:request(FTH)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))) -> fun((gleam@http@request:request(FTH)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))). -middleware_from_config(Config) -> - fun(Service) -> fun(Request) -> case erlang:element(2, Request) of - options -> - handle_options_request(Request, Config); - - _ -> - handle_other_request( - Service, - Request, - erlang:element(2, Config) - ) - end end end. - --spec middleware(list(binary()), list(gleam@http:method()), list(binary())) -> fun((fun((gleam@http@request:request(FTC)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))) -> fun((gleam@http@request:request(FTC)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))). -middleware(Allowed_origins, Allowed_methods, Allowed_headers) -> - case parse_config(Allowed_origins, Allowed_methods, Allowed_headers) of - {ok, Config} -> - middleware_from_config(Config); - - {error, _} -> - fun gleam@function:identity/1 - end. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src deleted file mode 100644 index 3a52ceb19fa..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_cors, [ - {vsn, "0.2.0"}, - {applications, [gleam_http, - gleam_stdlib, - gleeunit]}, - {description, "A CORS middleware for Gleam"}, - {modules, [gleam@http@cors]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE b/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/README.md b/test-community-packages-javascript/build/packages/gleam_crypto/README.md deleted file mode 100644 index c499e15941c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# crypto - -<a href="https://github.com/gleam-experiments/crypto/releases"><img src="https://img.shields.io/github/release/gleam-experiments/crypto" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-experiments/crypto/workflows/test/badge.svg?branch=main) - -Gleam bindings to the BEAM cryptography functions. - -## Installation - -``` -gleam add gleam_crypto -``` diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml b/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml deleted file mode 100644 index b5fec372ee5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleam_crypto" -version = "0.3.1" -licences = ["Apache-2.0"] -description = "Gleam bindings to the BEAM cryptography functions" - -repository = { type = "github", user = "gleam-experiments", repo = "crypto" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.19" -gleam_bitwise = "~> 1.1" - -[dev-dependencies] -gleeunit = "~> 0.5" diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam deleted file mode 100644 index 94223390f0c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam +++ /dev/null @@ -1,135 +0,0 @@ -//// Set of cryptographic functions. - -import gleam/bit_string -import gleam/bitwise -import gleam/string -import gleam/base -import gleam/result - -/// Generates N bytes randomly uniform 0..255, and returns the result in a binary. -/// -/// Uses a cryptographically secure prng seeded and periodically mixed with -/// operating system provided entropy. -/// By default this is the RAND_bytes method from OpenSSL. -/// -/// https://erlang.org/doc/man/crypto.html#strong_rand_bytes-1 -pub external fn strong_random_bytes(Int) -> BitString = - "crypto" "strong_rand_bytes" - -pub type HashAlgorithm { - Sha224 - Sha256 - Sha384 - Sha512 -} - -/// Computes a digest of the input bit string. -pub external fn hash(HashAlgorithm, BitString) -> BitString = - "crypto" "hash" - -type Hmac { - Hmac -} - -external fn erl_hmac(Hmac, HashAlgorithm, BitString, BitString) -> BitString = - "crypto" "mac" - -/// Calculates the HMAC (hash-based message authentication code) for a bit -/// string. -/// -/// Based on the Erlang [`crypto:mac`](https://www.erlang.org/doc/man/crypto.html#mac-4) -/// function. -/// -pub fn hmac(data: BitString, algorithm: HashAlgorithm, key: BitString) { - erl_hmac(Hmac, algorithm, key, data) -} - -fn do_secure_compare( - left: BitString, - right: BitString, - accumulator: Int, -) -> Bool { - case left, right { - <<x, left:bit_string>>, <<y, right:bit_string>> -> { - let accumulator = bitwise.or(accumulator, bitwise.exclusive_or(x, y)) - do_secure_compare(left, right, accumulator) - } - <<>>, <<>> -> accumulator == 0 - } -} - -/// Compares the two binaries in constant-time to avoid timing attacks. -/// -/// For more details see: http://codahale.com/a-lesson-in-timing-attacks/ -/// -pub fn secure_compare(left: BitString, right: BitString) -> Bool { - case bit_string.byte_size(left) == bit_string.byte_size(right) { - True -> do_secure_compare(left, right, 0) - False -> False - } -} - -// Based off of https://github.com/elixir-plug/plug_crypto/blob/v1.2.1/lib/plug/crypto/message_verifier.ex#L1 -// -/// Sign a message which can later be verified using the `verify_signed_message` -/// function to detect if the message has been tampered with. -/// -/// A web application could use this verifier to sign HTTP cookies. The data can -/// be read by the user, but cannot be tampered with. -/// -pub fn sign_message( - message: BitString, - secret: BitString, - digest_type: HashAlgorithm, -) -> String { - let input = signing_input(digest_type, message) - let signature = hmac(<<input:utf8>>, digest_type, secret) - - string.concat([input, ".", base.url_encode64(signature, False)]) -} - -fn signing_input(digest_type: HashAlgorithm, message: BitString) -> String { - let protected = case digest_type { - Sha224 -> "HS224" - Sha256 -> "HS256" - Sha384 -> "HS384" - Sha512 -> "HS512" - } - string.concat([ - base.url_encode64(<<protected:utf8>>, False), - ".", - base.url_encode64(message, False), - ]) -} - -// Based off of https://github.com/elixir-plug/plug_crypto/blob/v1.2.1/lib/plug/crypto/message_verifier.ex#L1 -// -/// Verify a message created by the `sign_message` function. -/// -pub fn verify_signed_message( - message: String, - secret: BitString, -) -> Result(BitString, Nil) { - use #(protected, payload, signature) <- result.then(case - string.split(message, on: ".") - { - [a, b, c] -> Ok(#(a, b, c)) - _ -> Error(Nil) - }) - let text = string.concat([protected, ".", payload]) - use payload <- result.then(base.url_decode64(payload)) - use signature <- result.then(base.url_decode64(signature)) - use protected <- result.then(base.url_decode64(protected)) - use digest_type <- result.then(case protected { - <<"HS224":utf8>> -> Ok(Sha224) - <<"HS256":utf8>> -> Ok(Sha256) - <<"HS384":utf8>> -> Ok(Sha384) - <<"HS512":utf8>> -> Ok(Sha512) - _ -> Error(Nil) - }) - let challenge = hmac(<<text:utf8>>, digest_type, secret) - case secure_compare(challenge, signature) { - True -> Ok(payload) - False -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl deleted file mode 100644 index b3b97bcf73d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl +++ /dev/null @@ -1,135 +0,0 @@ --module(gleam@crypto). --compile([no_auto_import, nowarn_unused_vars]). - --export([strong_random_bytes/1, hash/2, hmac/3, sign_message/3, secure_compare/2, verify_signed_message/2]). --export_type([hash_algorithm/0, hmac/0]). - --type hash_algorithm() :: sha224 | sha256 | sha384 | sha512. - --type hmac() :: hmac. - --spec signing_input(hash_algorithm(), bitstring()) -> binary(). -signing_input(Digest_type, Message) -> - Protected = case Digest_type of - sha224 -> - <<"HS224"/utf8>>; - - sha256 -> - <<"HS256"/utf8>>; - - sha384 -> - <<"HS384"/utf8>>; - - sha512 -> - <<"HS512"/utf8>> - end, - gleam@string:concat( - [gleam@base:url_encode64(<<Protected/binary>>, false), - <<"."/utf8>>, - gleam@base:url_encode64(Message, false)] - ). - --spec strong_random_bytes(integer()) -> bitstring(). -strong_random_bytes(Field@0) -> - crypto:strong_rand_bytes(Field@0). - --spec hash(hash_algorithm(), bitstring()) -> bitstring(). -hash(Field@0, Field@1) -> - crypto:hash(Field@0, Field@1). - --spec hmac(bitstring(), hash_algorithm(), bitstring()) -> bitstring(). -hmac(Data, Algorithm, Key) -> - crypto:mac(hmac, Algorithm, Key, Data). - --spec sign_message(bitstring(), bitstring(), hash_algorithm()) -> binary(). -sign_message(Message, Secret, Digest_type) -> - Input = signing_input(Digest_type, Message), - Signature = hmac(<<Input/binary>>, Digest_type, Secret), - gleam@string:concat( - [Input, <<"."/utf8>>, gleam@base:url_encode64(Signature, false)] - ). - --spec do_secure_compare(bitstring(), bitstring(), integer()) -> boolean(). -do_secure_compare(Left, Right, Accumulator) -> - case {Left, Right} of - {<<X, Left@1/bitstring>>, <<Y, Right@1/bitstring>>} -> - Accumulator@1 = gleam@bitwise:'or'( - Accumulator, - gleam@bitwise:exclusive_or(X, Y) - ), - do_secure_compare(Left@1, Right@1, Accumulator@1); - - {<<>>, <<>>} -> - Accumulator =:= 0 - end. - --spec secure_compare(bitstring(), bitstring()) -> boolean(). -secure_compare(Left, Right) -> - case gleam@bit_string:byte_size(Left) =:= gleam@bit_string:byte_size(Right) of - true -> - do_secure_compare(Left, Right, 0); - - false -> - false - end. - --spec verify_signed_message(binary(), bitstring()) -> {ok, bitstring()} | - {error, nil}. -verify_signed_message(Message, Secret) -> - gleam@result:then(case gleam@string:split(Message, <<"."/utf8>>) of - [A, B, C] -> - {ok, {A, B, C}}; - - _ -> - {error, nil} - end, fun(_use0) -> - {Protected, Payload, Signature} = _use0, - Text = gleam@string:concat([Protected, <<"."/utf8>>, Payload]), - gleam@result:then( - gleam@base:url_decode64(Payload), - fun(Payload@1) -> - gleam@result:then( - gleam@base:url_decode64(Signature), - fun(Signature@1) -> - gleam@result:then( - gleam@base:url_decode64(Protected), - fun(Protected@1) -> - gleam@result:then(case Protected@1 of - <<"HS224"/utf8>> -> - {ok, sha224}; - - <<"HS256"/utf8>> -> - {ok, sha256}; - - <<"HS384"/utf8>> -> - {ok, sha384}; - - <<"HS512"/utf8>> -> - {ok, sha512}; - - _ -> - {error, nil} - end, fun(Digest_type) -> - Challenge = hmac( - <<Text/binary>>, - Digest_type, - Secret - ), - case secure_compare( - Challenge, - Signature@1 - ) of - true -> - {ok, Payload@1}; - - false -> - {error, nil} - end - end) - end - ) - end - ) - end - ) - end). diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src deleted file mode 100644 index f62b69f0512..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_crypto, [ - {vsn, "0.3.1"}, - {applications, [gleam_bitwise, - gleam_stdlib, - gleeunit]}, - {description, "Gleam bindings to the BEAM cryptography functions"}, - {modules, [gleam@crypto]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE b/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/README.md b/test-community-packages-javascript/build/packages/gleam_erlang/README.md deleted file mode 100644 index e91ad24d748..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Gleam Erlang 🐙 - -A library for making use of Erlang specific code! - -## Features - -- Typed Erlang processes and message sending. -- Erlang binary format (de)serialisation. -- Functions for working with Erlang's charlists. -- Reading, writing, and deletion of files. - -## Usage - -Add this library to your Gleam project - -```shell -gleam add gleam_erlang -``` - -And then use it in your code - -```gleam -import gleam/io -import gleam/erlang/file - -pub fn main() { - assert Ok(contents) = file.read("pokedex.txt") - io.println(contents) -} -``` - -Documentation can be found at <https://hexdocs.pm/gleam_erlang/>. - -This library requires OTP 23.0 or higher. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml b/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml deleted file mode 100644 index 8f978f6781a..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleam_erlang" - -version = "0.19.0" -licences = ["Apache-2.0"] -description = "A Gleam library for working with Erlang" - -repository = { type = "github", user = "gleam-lang", repo = "erlang" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl deleted file mode 100644 index b38d11e0f65..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl +++ /dev/null @@ -1,15 +0,0 @@ --record(file_info, { - size :: integer(), - file_type :: gleam@erlang@file:file_type(), - access :: gleam@erlang@file:access(), - atime :: integer(), - mtime :: integer(), - ctime :: integer(), - mode :: integer(), - links :: integer(), - major_device :: integer(), - minor_device :: integer(), - inode :: integer(), - user_id :: integer(), - group_id :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl deleted file mode 100644 index 4cd04529eb4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl +++ /dev/null @@ -1 +0,0 @@ --record(abnormal, {reason :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl deleted file mode 100644 index 7fe79877634..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl +++ /dev/null @@ -1 +0,0 @@ --record(callee_down, {reason :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl deleted file mode 100644 index b82b49fc597..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl +++ /dev/null @@ -1 +0,0 @@ --record(cancelled, {time_remaining :: integer()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl deleted file mode 100644 index c476308c591..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(exit_message, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@erlang@process:exit_reason() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl deleted file mode 100644 index 8c75d5913d8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(process_down, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@dynamic:dynamic() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl deleted file mode 100644 index ce552e209e6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl +++ /dev/null @@ -1 +0,0 @@ --record(process_monitor, {tag :: gleam@erlang:reference_()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl deleted file mode 100644 index abc46b2ecd4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(subject, { - owner :: gleam@erlang@process:pid_(), - tag :: gleam@erlang:reference_() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl deleted file mode 100644 index aeba26d8240..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(application_failed_to_start, { - name :: gleam@erlang@atom:atom_(), - reason :: gleam@dynamic:dynamic() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl deleted file mode 100644 index fde3c61706e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unknown_application, {name :: gleam@erlang@atom:atom_()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam deleted file mode 100644 index 7720a71c616..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam +++ /dev/null @@ -1,143 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/list -import gleam/erlang/atom.{Atom} -import gleam/erlang/charlist.{Charlist} - -external fn erl_format(String, List(a)) -> Charlist = - "io_lib" "format" - -/// Return a string representation of any term -pub fn format(term: any) -> String { - charlist.to_string(erl_format("~p", [term])) -} - -pub external fn term_to_binary(a) -> BitString = - "erlang" "term_to_binary" - -type Safe { - Safe -} - -external fn erl_binary_to_term(BitString, List(Safe)) -> Dynamic = - "erlang" "binary_to_term" - -pub fn binary_to_term(binary: BitString) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, [Safe]) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -pub fn unsafe_binary_to_term(binary: BitString) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, []) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -/// Error value returned by `get_line` function -/// -pub type GetLineError { - Eof - NoData -} - -/// Reads a line from standard input with the given prompt. -/// -/// # Example -/// -/// > get_line("Language: ") -/// // -> Language: <- gleam -/// Ok("gleam\n") -/// -pub external fn get_line(prompt: String) -> Result(String, GetLineError) = - "gleam_erlang_ffi" "get_line" - -pub type TimeUnit { - Second - Millisecond - Microsecond - Nanosecond -} - -/// Returns the current OS system time. -/// -/// <https://erlang.org/doc/apps/erts/time_correction.html#OS_System_Time> -pub external fn system_time(TimeUnit) -> Int = - "os" "system_time" - -/// Returns the current OS system time as a tuple of Ints -/// -/// http://erlang.org/doc/man/os.html#timestamp-0 -pub external fn erlang_timestamp() -> #(Int, Int, Int) = - "os" "timestamp" - -/// Gleam doesn't offer any way to raise exceptions, but they may still occur -/// due to bugs when working with unsafe code, such as when calling Erlang -/// function. -/// -/// This function will catch any error thrown and convert it into a result -/// rather than crashing the process. -/// -pub external fn rescue(fn() -> a) -> Result(a, Crash) = - "gleam_erlang_ffi" "rescue" - -pub type Crash { - Exited(Dynamic) - Thrown(Dynamic) - Errored(Dynamic) -} - -external fn get_start_arguments() -> List(Charlist) = - "init" "get_plain_arguments" - -/// Get the arguments given to the program when it was started. -/// -/// This is sometimes called `argv` in other languages. -pub fn start_arguments() -> List(String) { - get_start_arguments() - |> list.map(charlist.to_string) -} - -/// Starts an OTP application's process tree in the background, as well as -/// the trees of any applications that the given application depends upon. An -/// OTP application typically maps onto a Gleam or Hex package. -/// -/// Returns a list of the applications that were started. Calling this function -/// for application that have already been started is a no-op so you do not need -/// to check the application state beforehand. -/// -/// In Gleam we prefer to not use these implicit background process trees, but -/// you will likely still need to start the trees of OTP applications written in -/// other BEAM languages such as Erlang or Elixir, including those included by -/// default with Erlang/OTP. -/// -/// For more information see the OTP documentation. -/// - <https://www.erlang.org/doc/man/application.html#ensure_all_started-1> -/// - <https://www.erlang.org/doc/man/application.html#start-1> -/// -pub external fn ensure_all_started( - application: Atom, -) -> Result(List(Atom), EnsureAllStartedError) = - "gleam_erlang_ffi" "ensure_all_started" - -pub type EnsureAllStartedError { - UnknownApplication(name: Atom) - ApplicationFailedToStart(name: Atom, reason: Dynamic) -} - -/// A unique reference value. -/// -/// It holds no particular meaning or value, but unique values are often useful -/// in programs are used heavily within both Gleam and Erlang's OTP frameworks. -/// -/// More can be read about refernces in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/efficiency_guide/advanced.html#unique_references -/// -pub external type Reference - -/// Create a new unique reference. -/// -pub external fn make_reference() -> Reference = - "erlang" "make_ref" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam deleted file mode 100644 index 1e0aac62a9c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam +++ /dev/null @@ -1,79 +0,0 @@ -import gleam/dynamic.{DecodeErrors, Dynamic} - -/// Atom is a special string-like data-type that is most commonly used for -/// interfacing with code written in other BEAM languages such as Erlang and -/// Elixir. It is preferable to define your own custom types to use instead of -/// atoms where possible. -/// -/// Atoms are not used much in typical Gleam code! -/// -/// ## Creating atoms -/// -/// We can create atoms with the the [`create_from_string`](#create_from_string) -/// function, though we must be careful when doing so as atoms are never -/// garbage collected. If we create too many atoms (for example, if we convert -/// user input into atoms) we may hit the max limit of atoms and cause the -/// virtual machine to crash. -/// -pub external type Atom - -/// An error returned when no atom is found in the virtual machine's atom table -/// for a given string when calling the [`from_string`](#from_string) function. -pub type FromStringError { - AtomNotLoaded -} - -/// Finds an existing Atom for the given String. -/// -/// If no atom is found in the virtual machine's atom table for the String then -/// an error is returned. -/// -/// ## Examples -/// -/// > from_string("ok") -/// Ok(create_from_string("ok")) -/// -/// > from_string("some_new_atom") -/// Error(AtomNotLoaded) -/// -pub external fn from_string(String) -> Result(Atom, FromStringError) = - "gleam_erlang_ffi" "atom_from_string" - -/// Creates an atom from a string, inserting a new value into the virtual -/// machine's atom table if an atom does not already exist for the given -/// string. -/// -/// We must be careful when using this function as there is a limit to the -/// number of atom that can fit in the virtual machine's atom table. Never -/// convert user input into atoms as filling the atom table will cause the -/// virtual machine to crash! -/// -pub external fn create_from_string(String) -> Atom = - "erlang" "binary_to_atom" - -/// Retuns a `String` corresponding to the text representation of the given -/// `Atom`. -/// -/// ## Examples -/// -/// > let ok_atom = create_from_string("ok") -/// > to_string(ok_atom) -/// "ok" -/// -pub external fn to_string(Atom) -> String = - "erlang" "atom_to_binary" - -/// Checks to see whether a `Dynamic` value is an atom, and return the atom if -/// it is. -/// -/// ## Examples -/// -/// > import gleam/dynamic -/// > from_dynamic(dynamic.from(create_from_string("hello"))) -/// Ok(create_from_string("hello")) -/// -/// > from_dynamic(dynamic.from(123)) -/// Error([DecodeError(expected: "Atom", found: "Int", path: [])]) -/// -pub external fn from_dynamic(from: Dynamic) -> Result(Atom, DecodeErrors) = - "gleam_erlang_ffi" "atom_from_dynamic" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam deleted file mode 100644 index a88c57fa7a8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam +++ /dev/null @@ -1,25 +0,0 @@ -//// A charlist is a list of integers where all the integers are valid code -//// points. -//// -//// In practice, you will not come across them often, except perhaps when -//// interfacing with Erlang, in particular when using older libraries that do -//// not accept binaries as arguments. - -/// A list of characters represented as ints. Commonly used by older Erlang -/// modules. -pub external type Charlist - -/// Transform a charlist to a string -pub external fn to_string(Charlist) -> String = - "unicode" "characters_to_binary" - -// Calls `unicode:characters_to_binary(Data, unicode, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_binary-1> - -/// Transform a string to a charlist -pub external fn from_string(String) -> Charlist = - "unicode" "characters_to_list" -// Calls `unicode:characters_to_list(Data, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_list-1> diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam deleted file mode 100644 index 2e780518726..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam +++ /dev/null @@ -1,713 +0,0 @@ -//// Working with files on the filesystem. -//// -//// The functions included in this module are for high-level concepts such as -//// reading and writing. - -import gleam/bit_string -import gleam/result - -/// Reason represents all of the reasons that Erlang surfaces of why a file -/// system operation could fail. Most of these reasons are POSIX errors, which -/// come from the operating system and start with `E`. Others have been added to -/// represent other issues that may arise. -pub type Reason { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 -} - -/// The type of file found by `file_info` or `link_info`. -/// -pub type FileType { - Device - Directory - Other - Regular - Symlink -} - -/// The read/write permissions a user can have for a file. -/// -pub type Access { - NoAccess - Read - ReadWrite - Write -} - -/// Meta information for a file. -/// -/// Timestamps are in seconds before or after the Unix time epoch, -/// `1970-01-01 00:00:00 UTC`. -/// -pub type FileInfo { - FileInfo( - /// File size in bytes. - /// - size: Int, - /// `Regular`, `Directory`, `Symlink`, `Device`, or `Other`. - /// - file_type: FileType, - /// `ReadWrite`, `Read`, `Write`, or `NoAccess`. - /// - access: Access, - /// Timestamp of most recent access. - /// - atime: Int, - /// Timestamp of most recent modification. - /// - mtime: Int, - /// Timestamp of most recent change (or file creation, depending on - /// operating system). - /// - ctime: Int, - /// File permissions encoded as a sum of bit values, including but not - /// limited to: - /// - /// Owner read, write, execute. - /// - /// `0o400`, `0o200`, `0o100` - /// - /// Group read, write, execute. - /// - /// `0o40`, `0o20`, `0o10` - /// - /// Other read, write, execute. - /// - /// `0o4`, `0o2`, `0o1` - /// - /// Set user ID, group ID on execution. - /// - /// `0x800`, `0x400` - /// - mode: Int, - /// Total links to a file (always `1` for file systems without links). - /// - links: Int, - /// The file system where a file is located (`0` for drive `A:` on Windows, - /// `1` for `B:`, etc.). - /// - major_device: Int, - /// Character device (or `0` on non-Unix systems). - /// - minor_device: Int, - /// The `inode` number for a file (always `0` on non-Unix file systems). - /// - inode: Int, - /// The owner of a file (always `0` on non-Unix file systems). - /// - user_id: Int, - /// The group id of a file (always `0` on non-Unix file systems). - /// - group_id: Int, - ) -} - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To get `FileInfo` about a symlink itself, use `link_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > file_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 140, -/// file_type: Directory, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/does_not_exist") -/// Error(Enoent) -/// -/// > file_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub external fn file_info(String) -> Result(FileInfo, Reason) = - "gleam_erlang_ffi" "file_info" - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To get `FileInfo` about a symlink's target, use `file_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > link_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 41, -/// file_type: Symlink, -/// access: ReadWrite, -/// atime: 1680581150, -/// mtime: 1680581150, -/// ctime: 1680581150, -/// mode: 41471, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 471587, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/does_not_exist") -/// Error(Enoent) -/// -/// > link_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub external fn link_info(String) -> Result(FileInfo, Reason) = - "gleam_erlang_ffi" "link_info" - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Directory` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_directory("/tmp") -/// Ok(True) -/// -/// > is_directory("resume.pdf") -/// Ok(False) -/// -/// > is_directory("/does_not_exist") -/// Error(Enoent) -/// ``` -/// -pub fn is_directory(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: file_info(path)) - file_type == Directory -} - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Regular` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_regular("resume.pdf") -/// Ok(True) -/// -/// > is_regular("/tmp") -/// Ok(False) -/// -/// > is_regular("/does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -pub fn is_regular(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: file_info(path)) - file_type == Regular -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To find whether a symlink itself exists, use `link_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_exists("resume.pdf") -/// Ok(True) -/// -/// > file_exists("/tmp") -/// Ok(True) -/// -/// > file_exists("/does_not_exist") -/// Ok(False) -/// -/// > file_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub fn file_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> file_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To find whether a symlink's target exists, use `file_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_exists("resume.pdf") -/// Ok(True) -/// -/// > link_exists("/tmp") -/// Ok(True) -/// -/// > link_exists("/does_not_exist") -/// Ok(False) -/// -/// > link_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub fn link_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> link_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Tries to create a directory. Missing parent directories are not created. -/// -/// Returns a Result of nil if the directory is created or Reason if the -/// operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > make_directory("/tmp/foo") -/// Ok(Nil) -/// -/// > make_directory("relative_directory") -/// Ok(Nil) -/// -/// > make_directory("/tmp/missing_intermediate_directory/foo") -/// Error(Enoent) -/// ``` -/// -pub external fn make_directory(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "make_directory" - -/// Lists all files in a directory, except files with -/// [raw filenames](https://www.erlang.org/doc/apps/stdlib/unicode_usage.html#notes-about-raw-filenames). -/// -/// Returns a Result containing the list of filenames in the directory, or Reason -/// if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > list_directory("/tmp") -/// Ok(["FB01293B-8597-4359-80D5-130140A0C0DE","AlTest2.out"]) -/// -/// > list_directory("resume.docx") -/// Error(Enotdir) -/// ``` -/// -pub external fn list_directory(String) -> Result(List(String), Reason) = - "gleam_erlang_ffi" "list_directory" - -/// Deletes a directory. -/// -/// The directory must be empty before it can be deleted. Returns a nil Success -/// or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > delete_directory("foo") -/// Ok(Nil) -/// -/// > delete_directory("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -pub external fn delete_directory(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "delete_directory" - -/// Deletes a file or directory recursively. -/// -/// Returns a nil Success or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > recursive_delete("foo") -/// Ok(Nil) -/// -/// > recursive_delete("/bar") -/// Ok(Nil) -/// -/// > recursive_delete("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -pub external fn recursive_delete(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "recursive_delete" - -/// Read the contents of the given file as a String -/// -/// Assumes the file is UTF-8 encoded. Returns a Result containing the file's -/// contents as a String if the operation was successful, or Reason if the file -/// operation failed. If the file is not UTF-8 encoded, the `NotUTF8` variant -/// will be returned. -/// -/// ## Examples -/// -/// ```gleam -/// > read("example.txt") -/// Ok("Hello, World!") -/// -/// > read(from: "example.txt") -/// Ok("Hello, World!") -/// -/// > read("does_not_exist.txt") -/// Error(Enoent) -/// -/// > read("cat.gif") -/// Error(NotUTF8) -/// ``` -/// -pub fn read(from path: String) -> Result(String, Reason) { - path - |> do_read_bits() - |> result.then(fn(content) { - case bit_string.to_string(content) { - Ok(string) -> Ok(string) - Error(Nil) -> Error(NotUtf8) - } - }) -} - -/// Read the contents of the given file as a BitString -/// -/// Returns a Result containing the file's contents as a BitString if the -/// operation was successful, or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > read_bits("example.txt") -/// Ok(<<"Hello, World!">>) -/// -/// > read_bits(from: "cat.gif") -/// Ok(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// -/// > read_bits("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -pub fn read_bits(from path: String) -> Result(BitString, Reason) { - do_read_bits(path) -} - -external fn do_read_bits(path) -> Result(BitString, Reason) = - "gleam_erlang_ffi" "read_file" - -/// Write the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > write(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > write("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -pub fn write(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_string.from_string - |> do_write_bits(path) -} - -/// Write the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > write_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -pub fn write_bits( - contents contents: BitString, - to path: String, -) -> Result(Nil, Reason) { - do_write_bits(contents, path) -} - -external fn do_write_bits(BitString, String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "write_file" - -/// Append the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > append(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > append("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -pub fn append(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_string.from_string - |> do_append_bits(path) -} - -/// Append the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > append_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -pub fn append_bits( - contents contents: BitString, - to path: String, -) -> Result(Nil, Reason) { - do_append_bits(contents, path) -} - -external fn do_append_bits( - contents: BitString, - path: String, -) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "append_file" - -/// Delete the given file. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > delete("file.txt") -/// Ok(Nil) -/// -/// > delete("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -pub external fn delete(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "delete_file" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam deleted file mode 100644 index 68326962a71..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam +++ /dev/null @@ -1,95 +0,0 @@ -//// Access to the shell's environment variables - -import gleam/map.{Map} - -/// Returns the list of all available environment variables as a list of key, -/// tuples. -/// -/// ## Examples -/// -/// > get_all_env() -/// map.from_list([ -/// #("SHELL", "/bin/bash"), -/// #("PWD", "/home/j3rn"), -/// ... -/// ]) -/// -pub external fn get_all_env() -> Map(String, String) = - "gleam_erlang_ffi" "get_all_env" - -/// Returns the value associated with the given environment variable name. -/// -/// ## Examples -/// -/// > get_env("SHELL") -/// "/bin/bash" -/// -/// > get_env(name: "PWD") -/// "/home/j3rn" -/// -pub external fn get_env(name: String) -> Result(String, Nil) = - "gleam_erlang_ffi" "get_env" - -/// Associates the given value with the given environment variable name. -/// -/// ## Examples -/// -/// > set_env("MYVAR", "MYVALUE") -/// Nil -/// > get_env("MYVAR") -/// "MYVALUE" -/// -/// > set_env(value: "MYVALUE", name: "MYVAR") -/// Nil -/// -pub external fn set_env(name: String, value: String) -> Nil = - "gleam_erlang_ffi" "set_env" - -/// Removes the environment variable with the given name. -/// -/// Returns Nil regardless of whether the variable ever existed. -/// -/// ## Examples -/// -/// > get_env("MYVAR") -/// Ok("MYVALUE") -/// > unset_env("MYVAR") -/// Nil -/// > get_env("MYVAR") -/// Error(Nil) -/// -/// > unset_env(name: "MYVAR") -/// Nil -/// -pub external fn unset_env(name: String) -> Nil = - "gleam_erlang_ffi" "unset_env" - -/// Represents operating system kernels -pub type OsFamily { - // The family which includes modern versions of the Windows operating system. - WindowsNt - // The family of operating systems based on the open source Linux kernel. - Linux - // The family of Apple operating systems such as macOS and iOS. - Darwin - // The family of operating systems based on the FreeBSD kernel. - FreeBsd - // An operating system kernel other than Linux, Darwin, FreeBSD, or NT. - Other(String) -} - -/// Returns the kernel of the host operating system. -/// -/// Unknown kernels are reported as `Other(String)`; e.g. `Other("sunos")`. -/// -/// ## Examples -/// -/// > family() -/// Linux -/// > family() -/// Darwin -/// > family() -/// Other("sunos") -/// -pub external fn family() -> OsFamily = - "gleam_erlang_ffi" "os_family" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam deleted file mode 100644 index 6e7e03f66c7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam +++ /dev/null @@ -1,716 +0,0 @@ -import gleam/string -import gleam/dynamic.{Dynamic} -import gleam/erlang.{Reference} -import gleam/erlang/atom.{Atom} - -/// A `Pid` (or Process identifier) is a reference to an Erlang process. Each -/// process has a `Pid` and it is one of the lowest level building blocks of -/// inter-process communication in the Erlang and Gleam OTP frameworks. -/// -pub external type Pid - -/// Get the `Pid` for the current process. -pub external fn self() -> Pid = - "erlang" "self" - -/// Create a new Erlang process that runs concurrently to the creator. In other -/// languages this might be called a fibre, a green thread, or a coroutine. -/// -/// If `linked` is `True` then the created process is linked to the creator -/// process. When a process terminates an exit signal is sent to all other -/// processes that are linked to it, causing the process to either terminate or -/// have to handle the signal. -/// -/// More can be read about processes and links in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/reference_manual/processes.html -/// -pub fn start(running implementation: fn() -> anything, linked link: Bool) -> Pid { - case link { - True -> spawn_link(implementation) - False -> spawn(implementation) - } -} - -external fn spawn(fn() -> anything) -> Pid = - "erlang" "spawn" - -external fn spawn_link(fn() -> anything) -> Pid = - "erlang" "spawn_link" - -/// A `Subject` is a value that processes can use to send and receive messages -/// to and from each other in a well typed way. -/// -/// Each subject is "owned" by the process that created it. Any process can use -/// the `send` function to sent a message of the correct type to the process -/// that owns the subject, and the owner can use the `receive` function or the -/// `Selector` type to receive these messages. -/// -/// The `Subject` type is similar to the "channel" types found in other -/// languages and the "topic" concept found in some pub-sub systems. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// -/// // Send a message with the subject -/// send(subject, "Hello, Joe!") -/// -/// // Receive the message -/// receive(subject, within: 10) -/// ``` -/// -pub opaque type Subject(message) { - Subject(owner: Pid, tag: Reference) -} - -/// Create a new `Subject` owned by the current process. -/// -pub fn new_subject() -> Subject(message) { - Subject(owner: self(), tag: erlang.make_reference()) -} - -/// Get the owner process for a `Subject`. This is the process that created the -/// `Subject` and will receive messages sent with it. -/// -pub fn subject_owner(subject: Subject(message)) -> Pid { - subject.owner -} - -external type DoNotLeak - -external fn raw_send(Pid, message) -> DoNotLeak = - "erlang" "send" - -/// Send a message to a process using a `Subject`. The message must be of the -/// type that the `Subject` accepts. -/// -/// This function does not wait for the `Subject` owner process to call the -/// `receive` function, instead it returns once the message has been placed in -/// the process' mailbox. -/// -/// # Ordering -/// -/// If process P1 sends two messages to process P2 it is guarenteed that process -/// P1 will receive the messages in the order they were sent. -/// -/// If you wish to receive the messages in a different order you can send them -/// on two different subjects and the receiver function can call the `receive` -/// function for each subject in the desired order, or you can write some Erlang -/// code to perform a selective receive. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// send(subject, "Hello, Joe!") -/// ``` -/// -pub fn send(subject: Subject(message), message: message) -> Nil { - raw_send(subject.owner, #(subject.tag, message)) - Nil -} - -/// Receive a message that has been sent to current process using the `Subject`. -/// -/// If there is not an existing message for the `Subject` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject` can receive a message using -/// it. If a process that does not own the `Subject` attempts to receive with it -/// then it will not receive a message. -/// -/// To wait for messages from multiple `Subject`s at the same time see the -/// `Selector` type. -/// -pub fn receive( - from subject: Subject(message), - within milliseconds: Int, -) -> Result(message, Nil) { - new_selector() - |> selecting(subject, fn(x) { x }) - |> select(within: milliseconds) -} - -/// A type that enables a process to wait for messages from multiple `Subject`s -/// at the same time, returning whichever message arrives first. -/// -/// Used with the `new_selector`, `selecting`, and `select` functions. -/// -/// # Examples -/// -/// ```gleam -/// > let int_subject = new_subject() -/// > let float_subject = new_subject() -/// > send(int_subject, 1) -/// > -/// > let selector = -/// > new_selector() -/// > |> selecting(int_subject, int.to_string) -/// > |> selecting(float_subject, float.to_string) -/// > -/// > select(selector) -/// Ok("1") -/// ``` -/// -pub external type Selector(payload) - -/// Create a new `Selector` which can be used to receive messages on multiple -/// `Subject`s at once. -/// -pub external fn new_selector() -> Selector(payload) = - "gleam_erlang_ffi" "new_selector" - -/// Receive a message that has been sent to current process using any of the -/// `Subject`s that have been added to the `Selector` with the `selecting` -/// function. -/// -/// If there is not an existing message for the `Selector` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject`s can receive a message using -/// them. If a process that does not own the a `Subject` attempts to receive -/// with it then it will not receive a message. -/// -/// To wait forever for the next message rather than for a limited amount of -/// time see the `select_forever` function. -/// -pub external fn select( - from: Selector(payload), - within: Int, -) -> Result(payload, Nil) = - "gleam_erlang_ffi" "select" - -/// Similar to the `select` function but will wait forever for a message to -/// arrive rather than timing out after a specified amount of time. -/// -pub external fn select_forever(from: Selector(payload)) -> payload = - "gleam_erlang_ffi" "select" - -/// Add a transformation function to a selector. When a message is received -/// using this selector the tranformation function is applied to the message. -/// -/// This function can be used to change the type of messages received and may -/// be useful when combined with the `merge_selector` function. -/// -pub external fn map_selector(Selector(a), fn(a) -> b) -> Selector(b) = - "gleam_erlang_ffi" "map_selector" - -/// Merge one selector into another, producing a selector that contains the -/// message handlers of both. -/// -/// If a subject is handled by both selectors the handler function of the -/// second selector is used. -/// -pub external fn merge_selector(Selector(a), Selector(a)) -> Selector(a) = - "gleam_erlang_ffi" "merge_selector" - -pub type ExitMessage { - ExitMessage(pid: Pid, reason: ExitReason) -} - -pub type ExitReason { - Normal - Killed - Abnormal(reason: String) -} - -/// Add a handler for trapped exit messages. In order for these messages to be -/// sent to the process when a linked process exits the process must call the -/// `trap_exit` beforehand. -/// -pub fn selecting_trapped_exits( - selector: Selector(a), - handler: fn(ExitMessage) -> a, -) -> Selector(a) { - let tag = atom.create_from_string("EXIT") - let handler = fn(message: #(Atom, Pid, Dynamic)) -> a { - let reason = message.2 - let normal = dynamic.from(Normal) - let killed = dynamic.from(Killed) - let reason = case dynamic.string(reason) { - _ if reason == normal -> Normal - _ if reason == killed -> Killed - Ok(reason) -> Abnormal(reason) - Error(_) -> Abnormal(string.inspect(reason)) - } - handler(ExitMessage(message.1, reason)) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -// TODO: implement in Gleam -/// Discard all messages in the current process' mailbox. -/// -/// Warning: This function may cause other processes to crash if they sent a -/// message to the current process and are waiting for a response, so use with -/// caution. -/// -pub external fn flush_messages() -> Nil = - "gleam_erlang_ffi" "flush_messages" - -/// Add a new `Subject` to the `Selector` to that it's messages can be received. -/// -/// The `mapping` function provided with the `Subject` can be used to convert -/// the type of messages received using this `Subject`. This is useful for when -/// you wish to add multiple `Subject`s to a `Seletor` when they have differing -/// message types. If you do not wish to transform the incoming messages in any -/// way then the `identity` function can be given. -/// -pub fn selecting( - selector: Selector(payload), - for subject: Subject(message), - mapping transform: fn(message) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(Reference, message)) { transform(message.1) } - insert_selector_handler(selector, #(subject.tag, 2), handler) -} - -/// Add a handler to a selector for 2 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record2( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic)) { transform(message.1) } - insert_selector_handler(selector, #(tag, 2), handler) -} - -/// Add a handler to a selector for 3 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record3( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic)) { - transform(message.1, message.2) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -/// Add a handler to a selector for 4 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record4( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3) - } - insert_selector_handler(selector, #(tag, 4), handler) -} - -/// Add a handler to a selector for 5 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record5( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4) - } - insert_selector_handler(selector, #(tag, 5), handler) -} - -/// Add a handler to a selector for 6 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record6( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4, message.5) - } - insert_selector_handler(selector, #(tag, 6), handler) -} - -/// Add a handler to a selector for 7 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record7( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - ) { - transform(message.1, message.2, message.3, message.4, message.5, message.6) - } - insert_selector_handler(selector, #(tag, 7), handler) -} - -/// Add a handler to a selector for 8 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record8( - selector: Selector(payload), - tag: tag, - mapping transform: fn( - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #( - tag, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ), - ) { - transform( - message.1, - message.2, - message.3, - message.4, - message.5, - message.6, - message.7, - ) - } - insert_selector_handler(selector, #(tag, 8), handler) -} - -type AnythingSelectorTag { - Anything -} - -/// Add a catch-all handler to a selector that will be used when no other -/// handler in a selector is suitable for a given message. -/// -/// This may be useful for when you want to ensure that any message in the inbox -/// is handled, or when you need to handle messages from other BEAM languages -/// which do not use subjects or record format messages. -/// -pub fn selecting_anything( - selector: Selector(payload), - mapping handler: fn(Dynamic) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, Anything, handler) -} - -external fn insert_selector_handler( - Selector(payload), - for: tag, - mapping: fn(message) -> payload, -) -> Selector(payload) = - "gleam_erlang_ffi" "insert_selector_handler" - -/// Suspends the process calling this function for the specified number of -/// milliseconds. -/// -pub external fn sleep(Int) -> Nil = - "gleam_erlang_ffi" "sleep" - -/// Suspends the process forever! This may be useful for suspending the main -/// process in a Gleam program when it has no more work to do but we want other -/// processes to continue to work. -/// -pub external fn sleep_forever() -> Nil = - "gleam_erlang_ffi" "sleep_forever" - -/// Check to see whether the process for a given `Pid` is alive. -/// -/// See the [Erlang documentation][1] for more information. -/// -/// [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1 -/// -pub external fn is_alive(Pid) -> Bool = - "erlang" "is_process_alive" - -type ProcessMonitorFlag { - Process -} - -external fn erlang_monitor_process(ProcessMonitorFlag, Pid) -> Reference = - "erlang" "monitor" - -pub opaque type ProcessMonitor { - ProcessMonitor(tag: Reference) -} - -/// A message received when a monitored process exits. -/// -pub type ProcessDown { - ProcessDown(pid: Pid, reason: Dynamic) -} - -/// Start monitoring a process so that when the monitored process exits a -/// message is to the monitoring process. -/// -/// The message is only sent once, when the target process exits. If the -/// process was not alive when this function is called the message will never -/// be received. -/// -/// The down message can be received with a `Selector` and the -/// `selecting_process_down` function. -/// -/// The process can be demonitored with the `demonitor_process` function. -/// -pub fn monitor_process(pid: Pid) -> ProcessMonitor { - Process - |> erlang_monitor_process(pid) - |> ProcessMonitor -} - -/// Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can -/// be received using the `Selector` and the `select` function. -/// -pub fn selecting_process_down( - selector: Selector(payload), - monitor: ProcessMonitor, - mapping: fn(ProcessDown) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, monitor.tag, mapping) -} - -/// Remove the monitor for a process so that when the monitor process exits a -/// `ProcessDown` message is not sent to the monitoring process. -/// -/// If the message has already been sent it is removed from the monitoring -/// process' mailbox. -/// -pub external fn demonitor_process(monitor: ProcessMonitor) -> Nil = - "gleam_erlang_ffi" "demonitor" - -/// An error returned when making a call to a process. -/// -pub type CallError(msg) { - /// The process being called exited before it sent a response. - /// - CalleeDown(reason: Dynamic) - - /// The process being called did not response within the permitted amount of - /// time. - /// - CallTimeout -} - -// This function is based off of Erlang's gen:do_call/4. -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time then an error is returned. -/// -pub fn try_call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> Result(response, CallError(response)) { - let reply_subject = new_subject() - - // Monitor the callee process so we can tell if it goes down (meaning we - // won't get a reply) - let monitor = monitor_process(subject_owner(subject)) - - // Send the request to the process over the channel - send(subject, make_request(reply_subject)) - - // Await a reply or handle failure modes (timeout, process down, etc) - let result = - new_selector() - |> selecting(reply_subject, Ok) - |> selecting_process_down( - monitor, - fn(down: ProcessDown) { Error(CalleeDown(reason: down.reason)) }, - ) - |> select(timeout) - - // Demonitor the process and close the channels as we're done - demonitor_process(monitor) - - // Prepare an appropriate error (if present) for the caller - case result { - Error(Nil) -> Error(CallTimeout) - Ok(res) -> res - } -} - -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time the calling process crashes. If you wish an error to be returned -/// instead see the `try_call` function. -/// -pub fn call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> response { - let assert Ok(resp) = try_call(subject, make_request, timeout) - resp -} - -/// Creates a link between the calling process and another process. -/// -/// When a process crashes any linked processes will also crash. This is useful -/// to ensure that groups of processes that depend on each other all either -/// succeed or fail together. -/// -/// Returns `True` if the link was created successfully, returns `False` if the -/// process was not alive and as such could not be linked. -/// -pub external fn link(pid: Pid) -> Bool = - "gleam_erlang_ffi" "link" - -external fn erlang_unlink(pid: Pid) -> Bool = - "erlang" "unlink" - -/// Removes any existing link between the caller process and the target process. -/// -pub fn unlink(pid: Pid) -> Nil { - erlang_unlink(pid) - Nil -} - -pub external type Timer - -external fn erlang_send_after(Int, Pid, msg) -> Timer = - "erlang" "send_after" - -/// Send a message over a channel after a specified number of milliseconds. -/// -pub fn send_after(subject: Subject(msg), delay: Int, message: msg) -> Timer { - erlang_send_after(delay, subject.owner, #(subject.tag, message)) -} - -external fn erlang_cancel_timer(Timer) -> Dynamic = - "erlang" "cancel_timer" - -/// Values returned when a timer is cancelled. -/// -pub type Cancelled { - /// The timer could not be found. It likely has already triggered. - /// - TimerNotFound - - /// The timer was found and cancelled before it triggered. - /// - /// The amount of remaining time before the timer was due to be triggered is - /// returned in milliseconds. - /// - Cancelled(time_remaining: Int) -} - -/// Cancel a given timer, causing it not to trigger if it has not done already. -/// -pub fn cancel_timer(timer: Timer) -> Cancelled { - case dynamic.int(erlang_cancel_timer(timer)) { - Ok(i) -> Cancelled(i) - Error(_) -> TimerNotFound - } -} - -type KillFlag { - Kill -} - -external fn erlang_kill(to: Pid, because: KillFlag) -> Bool = - "erlang" "exit" - -// Go, my pretties. Kill! Kill! -// - Bart Simpson -// -/// Send an untrappable `kill` exit signal to the target process. -/// -/// See the documentation for the Erlang [`erlang:exit`][1] function for more -/// information. -/// -/// [1]: https://erlang.org/doc/man/erlang.html#exit-1 -/// -pub fn kill(pid: Pid) -> Nil { - erlang_kill(pid, Kill) - Nil -} - -external fn erlang_send_exit(to: Pid, because: whatever) -> Bool = - "erlang" "exit" - -// TODO: test -/// Sends an exit signal to a process, indicating that the process is to shut -/// down. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_exit(to pid: Pid) -> Nil { - erlang_send_exit(pid, Normal) - Nil -} - -/// Sends an exit signal to a process, indicating that the process is to shut -/// down due to an abnormal reason such as a failure. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_abnormal_exit(pid: Pid, reason: String) -> Nil { - erlang_send_exit(pid, Abnormal(reason)) - Nil -} - -/// Set whether the current process is to trap exit signals or not. -/// -/// When not trapping exits if a linked process crashes the exit signal -/// propagates to the process which will also crash. -/// This is the normal behaviour before this function is called. -/// -/// When trapping exits (after this function is called) if a linked process -/// crashes an exit message is sent to the process instead. These messages can -/// be handled with the `selecting_trapped_exits` function. -/// -pub external fn trap_exits(Bool) -> Nil = - "gleam_erlang_ffi" "trap_exits" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl deleted file mode 100644 index 39fdc1855ed..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl +++ /dev/null @@ -1,86 +0,0 @@ --module(gleam@erlang). --compile([no_auto_import, nowarn_unused_vars]). - --export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0]). --export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]). - --type safe() :: safe. - --type get_line_error() :: eof | no_data. - --type time_unit() :: second | millisecond | microsecond | nanosecond. - --type crash() :: {exited, gleam@dynamic:dynamic()} | - {thrown, gleam@dynamic:dynamic()} | - {errored, gleam@dynamic:dynamic()}. - --type ensure_all_started_error() :: {unknown_application, - gleam@erlang@atom:atom_()} | - {application_failed_to_start, - gleam@erlang@atom:atom_(), - gleam@dynamic:dynamic()}. - --type reference_() :: any(). - --spec format(any()) -> binary(). -format(Term) -> - unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])). - --spec term_to_binary(any()) -> bitstring(). -term_to_binary(Field@0) -> - erlang:term_to_binary(Field@0). - --spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. -get_line(Field@0) -> - gleam_erlang_ffi:get_line(Field@0). - --spec system_time(time_unit()) -> integer(). -system_time(Field@0) -> - os:system_time(Field@0). - --spec erlang_timestamp() -> {integer(), integer(), integer()}. -erlang_timestamp() -> - os:timestamp(). - --spec rescue(fun(() -> EYG)) -> {ok, EYG} | {error, crash()}. -rescue(Field@0) -> - gleam_erlang_ffi:rescue(Field@0). - --spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic()} | - {error, nil}. -binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue( - fun() -> erlang:binary_to_term(Binary, [safe]) end - ) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic()} | - {error, nil}. -unsafe_binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec start_arguments() -> list(binary()). -start_arguments() -> - _pipe = init:get_plain_arguments(), - gleam@list:map(_pipe, fun gleam@erlang@charlist:to_string/1). - --spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok, - list(gleam@erlang@atom:atom_())} | - {error, ensure_all_started_error()}. -ensure_all_started(Field@0) -> - gleam_erlang_ffi:ensure_all_started(Field@0). - --spec make_reference() -> reference_(). -make_reference() -> - erlang:make_ref(). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl deleted file mode 100644 index 70b92f520e7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl +++ /dev/null @@ -1,26 +0,0 @@ --module(gleam@erlang@atom). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]). --export_type([from_string_error/0, atom_/0]). - --type from_string_error() :: atom_not_loaded. - --type atom_() :: any(). - --spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}. -from_string(Field@0) -> - gleam_erlang_ffi:atom_from_string(Field@0). - --spec create_from_string(binary()) -> atom_(). -create_from_string(Field@0) -> - erlang:binary_to_atom(Field@0). - --spec to_string(atom_()) -> binary(). -to_string(Field@0) -> - erlang:atom_to_binary(Field@0). - --spec from_dynamic(gleam@dynamic:dynamic()) -> {ok, atom_()} | - {error, list(gleam@dynamic:decode_error())}. -from_dynamic(Field@0) -> - gleam_erlang_ffi:atom_from_dynamic(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl deleted file mode 100644 index 8dbbd144055..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl +++ /dev/null @@ -1,15 +0,0 @@ --module(gleam@erlang@charlist). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_string/1, from_string/1]). --export_type([charlist/0]). - --type charlist() :: any(). - --spec to_string(charlist()) -> binary(). -to_string(Field@0) -> - unicode:characters_to_binary(Field@0). - --spec from_string(binary()) -> charlist(). -from_string(Field@0) -> - unicode:characters_to_list(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl deleted file mode 100644 index 829b69aa304..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl +++ /dev/null @@ -1,190 +0,0 @@ --module(gleam@erlang@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([file_info/1, is_directory/1, is_regular/1, file_exists/1, link_info/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]). --export_type([reason/0, file_type/0, access/0, file_info/0]). - --type reason() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8. - --type file_type() :: device | directory | other | regular | symlink. - --type access() :: no_access | read | read_write | write. - --type file_info() :: {file_info, - integer(), - file_type(), - access(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec file_info(binary()) -> {ok, file_info()} | {error, reason()}. -file_info(Field@0) -> - gleam_erlang_ffi:file_info(Field@0). - --spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}. -is_directory(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= directory - end - ). - --spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}. -is_regular(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= regular - end - ). - --spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}. -file_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:file_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec link_info(binary()) -> {ok, file_info()} | {error, reason()}. -link_info(Field@0) -> - gleam_erlang_ffi:link_info(Field@0). - --spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}. -link_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:link_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec make_directory(binary()) -> {ok, nil} | {error, reason()}. -make_directory(Field@0) -> - gleam_erlang_ffi:make_directory(Field@0). - --spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}. -list_directory(Field@0) -> - gleam_erlang_ffi:list_directory(Field@0). - --spec delete_directory(binary()) -> {ok, nil} | {error, reason()}. -delete_directory(Field@0) -> - gleam_erlang_ffi:delete_directory(Field@0). - --spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}. -recursive_delete(Field@0) -> - gleam_erlang_ffi:recursive_delete(Field@0). - --spec read(binary()) -> {ok, binary()} | {error, reason()}. -read(Path) -> - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:read_file(_pipe), - gleam@result:then( - _pipe@1, - fun(Content) -> case gleam@bit_string:to_string(Content) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, not_utf8} - end end - ). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}. -read_bits(Path) -> - gleam_erlang_ffi:read_file(Path). - --spec write(binary(), binary()) -> {ok, nil} | {error, reason()}. -write(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:write_file(_pipe@1, Path). - --spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -write_bits(Contents, Path) -> - gleam_erlang_ffi:write_file(Contents, Path). - --spec append(binary(), binary()) -> {ok, nil} | {error, reason()}. -append(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:append_file(_pipe@1, Path). - --spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -append_bits(Contents, Path) -> - gleam_erlang_ffi:append_file(Contents, Path). - --spec delete(binary()) -> {ok, nil} | {error, reason()}. -delete(Field@0) -> - gleam_erlang_ffi:delete_file(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl deleted file mode 100644 index 8bfcc227db3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@erlang@os). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]). --export_type([os_family/0]). - --type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}. - --spec get_all_env() -> gleam@map:map_(binary(), binary()). -get_all_env() -> - gleam_erlang_ffi:get_all_env(). - --spec get_env(binary()) -> {ok, binary()} | {error, nil}. -get_env(Field@0) -> - gleam_erlang_ffi:get_env(Field@0). - --spec set_env(binary(), binary()) -> nil. -set_env(Field@0, Field@1) -> - gleam_erlang_ffi:set_env(Field@0, Field@1). - --spec unset_env(binary()) -> nil. -unset_env(Field@0) -> - gleam_erlang_ffi:unset_env(Field@0). - --spec family() -> os_family(). -family() -> - gleam_erlang_ffi:os_family(). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl deleted file mode 100644 index 56f787e638a..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl +++ /dev/null @@ -1,362 +0,0 @@ --module(gleam@erlang@process). --compile([no_auto_import, nowarn_unused_vars]). - --export([subject_owner/1, self/0, new_subject/0, start/2, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, selecting_process_down/3, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1]). --export_type([subject/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, cancelled/0, kill_flag/0, pid_/0, do_not_leak/0, selector/1, timer/0]). - --opaque subject(EZP) :: {subject, pid_(), gleam@erlang:reference_()} | - {gleam_phantom, EZP}. - --type exit_message() :: {exit_message, pid_(), exit_reason()}. - --type exit_reason() :: normal | killed | {abnormal, binary()}. - --type anything_selector_tag() :: anything. - --type process_monitor_flag() :: process. - --opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}. - --type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic()}. - --type call_error(EZQ) :: {callee_down, gleam@dynamic:dynamic()} | - call_timeout | - {gleam_phantom, EZQ}. - --type cancelled() :: timer_not_found | {cancelled, integer()}. - --type kill_flag() :: kill. - --type pid_() :: any(). - --type do_not_leak() :: any(). - --type selector(Payload) :: any() | {gleam_phantom, Payload}. - --type timer() :: any(). - --spec subject_owner(subject(any())) -> pid_(). -subject_owner(Subject) -> - erlang:element(2, Subject). - --spec self() -> pid_(). -self() -> - erlang:self(). - --spec new_subject() -> subject(any()). -new_subject() -> - {subject, erlang:self(), erlang:make_ref()}. - --spec start(fun(() -> any()), boolean()) -> pid_(). -start(Implementation, Link) -> - case Link of - true -> - erlang:spawn_link(Implementation); - - false -> - erlang:spawn(Implementation) - end. - --spec send(subject(EZW), EZW) -> nil. -send(Subject, Message) -> - erlang:send( - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ), - nil. - --spec new_selector() -> selector(any()). -new_selector() -> - gleam_erlang_ffi:new_selector(). - --spec select(selector(FCK), integer()) -> {ok, FCK} | {error, nil}. -select(Field@0, Field@1) -> - gleam_erlang_ffi:select(Field@0, Field@1). - --spec select_forever(selector(FCO)) -> FCO. -select_forever(Field@0) -> - gleam_erlang_ffi:select(Field@0). - --spec map_selector(selector(FCS), fun((FCS) -> FCQ)) -> selector(FCQ). -map_selector(Field@0, Field@1) -> - gleam_erlang_ffi:map_selector(Field@0, Field@1). - --spec merge_selector(selector(FCU), selector(FCU)) -> selector(FCU). -merge_selector(Field@0, Field@1) -> - gleam_erlang_ffi:merge_selector(Field@0, Field@1). - --spec flush_messages() -> nil. -flush_messages() -> - gleam_erlang_ffi:flush_messages(). - --spec selecting_trapped_exits(selector(FAC), fun((exit_message()) -> FAC)) -> selector(FAC). -selecting_trapped_exits(Selector, Handler) -> - Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>), - Handler@1 = fun(Message) -> - Reason = erlang:element(3, Message), - Normal = gleam@dynamic:from(normal), - Killed = gleam@dynamic:from(killed), - Reason@2 = case gleam@dynamic:string(Reason) of - _ when Reason =:= Normal -> - normal; - - _ when Reason =:= Killed -> - killed; - - {ok, Reason@1} -> - {abnormal, Reason@1}; - - {error, _} -> - {abnormal, gleam@string:inspect(Reason)} - end, - Handler({exit_message, erlang:element(2, Message), Reason@2}) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1). - --spec selecting(selector(FAF), subject(FAH), fun((FAH) -> FAF)) -> selector(FAF). -selecting(Selector, Subject, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler( - Selector, - {erlang:element(3, Subject), 2}, - Handler - ). - --spec 'receive'(subject(EZY), integer()) -> {ok, EZY} | {error, nil}. -'receive'(Subject, Milliseconds) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end), - gleam_erlang_ffi:select(_pipe@1, Milliseconds). - --spec selecting_record2( - selector(FAK), - any(), - fun((gleam@dynamic:dynamic()) -> FAK) -) -> selector(FAK). -selecting_record2(Selector, Tag, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler). - --spec selecting_record3( - selector(FAO), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAO) -) -> selector(FAO). -selecting_record3(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform(erlang:element(2, Message), erlang:element(3, Message)) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler). - --spec selecting_record4( - selector(FAS), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAS) -) -> selector(FAS). -selecting_record4(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler). - --spec selecting_record5( - selector(FAW), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAW) -) -> selector(FAW). -selecting_record5(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler). - --spec selecting_record6( - selector(FBA), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBA) -) -> selector(FBA). -selecting_record6(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler). - --spec selecting_record7( - selector(FBE), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBE) -) -> selector(FBE). -selecting_record7(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler). - --spec selecting_record8( - selector(FBI), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBI) -) -> selector(FBI). -selecting_record8(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message), - erlang:element(8, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler). - --spec selecting_anything(selector(FBM), fun((gleam@dynamic:dynamic()) -> FBM)) -> selector(FBM). -selecting_anything(Selector, Handler) -> - gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler). - --spec selecting_process_down( - selector(FBP), - process_monitor(), - fun((process_down()) -> FBP) -) -> selector(FBP). -selecting_process_down(Selector, Monitor, Mapping) -> - gleam_erlang_ffi:insert_selector_handler( - Selector, - erlang:element(2, Monitor), - Mapping - ). - --spec sleep(integer()) -> nil. -sleep(Field@0) -> - gleam_erlang_ffi:sleep(Field@0). - --spec sleep_forever() -> nil. -sleep_forever() -> - gleam_erlang_ffi:sleep_forever(). - --spec is_alive(pid_()) -> boolean(). -is_alive(Field@0) -> - erlang:is_process_alive(Field@0). - --spec monitor_process(pid_()) -> process_monitor(). -monitor_process(Pid) -> - _pipe = process, - _pipe@1 = erlang:monitor(_pipe, Pid), - {process_monitor, _pipe@1}. - --spec demonitor_process(process_monitor()) -> nil. -demonitor_process(Field@0) -> - gleam_erlang_ffi:demonitor(Field@0). - --spec try_call(subject(FBS), fun((subject(FBU)) -> FBS), integer()) -> {ok, FBU} | - {error, call_error(FBU)}. -try_call(Subject, Make_request, Timeout) -> - Reply_subject = new_subject(), - Monitor = monitor_process(subject_owner(Subject)), - send(Subject, Make_request(Reply_subject)), - Result = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting( - _pipe, - Reply_subject, - fun(Field@0) -> {ok, Field@0} end - ), - _pipe@2 = selecting_process_down( - _pipe@1, - Monitor, - fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end - ), - gleam_erlang_ffi:select(_pipe@2, Timeout) - end, - gleam_erlang_ffi:demonitor(Monitor), - case Result of - {error, nil} -> - {error, call_timeout}; - - {ok, Res} -> - Res - end. - --spec call(subject(FBZ), fun((subject(FCB)) -> FBZ), integer()) -> FCB. -call(Subject, Make_request, Timeout) -> - _assert_subject = try_call(Subject, Make_request, Timeout), - {ok, Resp} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/erlang/process"/utf8>>, - function => <<"call"/utf8>>, - line => 593}) - end, - Resp. - --spec link(pid_()) -> boolean(). -link(Field@0) -> - gleam_erlang_ffi:link(Field@0). - --spec unlink(pid_()) -> nil. -unlink(Pid) -> - erlang:unlink(Pid), - nil. - --spec send_after(subject(FCD), integer(), FCD) -> timer(). -send_after(Subject, Delay, Message) -> - erlang:send_after( - Delay, - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ). - --spec cancel_timer(timer()) -> cancelled(). -cancel_timer(Timer) -> - case gleam@dynamic:int(erlang:cancel_timer(Timer)) of - {ok, I} -> - {cancelled, I}; - - {error, _} -> - timer_not_found - end. - --spec kill(pid_()) -> nil. -kill(Pid) -> - erlang:exit(Pid, kill), - nil. - --spec send_exit(pid_()) -> nil. -send_exit(Pid) -> - erlang:exit(Pid, normal), - nil. - --spec send_abnormal_exit(pid_(), binary()) -> nil. -send_abnormal_exit(Pid, Reason) -> - erlang:exit(Pid, {abnormal, Reason}), - nil. - --spec trap_exits(boolean()) -> nil. -trap_exits(Field@0) -> - gleam_erlang_ffi:trap_exits(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src deleted file mode 100644 index 7682a9cebe8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src +++ /dev/null @@ -1,13 +0,0 @@ -{application, gleam_erlang, [ - {vsn, "0.19.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A Gleam library for working with Erlang"}, - {modules, [gleam@erlang, - gleam@erlang@atom, - gleam@erlang@charlist, - gleam@erlang@file, - gleam@erlang@os, - gleam@erlang@process]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl deleted file mode 100644 index 2c6bd5f09d5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl +++ /dev/null @@ -1,218 +0,0 @@ --module(gleam_erlang_ffi). --export([ - atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, - ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, - append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, - set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, - list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, - insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, - merge_selector/2, flush_messages/0, file_info/1, link_info/1 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - --spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. -atom_from_string(S) -> - try {ok, binary_to_existing_atom(S)} - catch error:badarg -> {error, atom_not_loaded} - end. - -atom_from_dynamic(Data) when is_atom(Data) -> - {ok, Data}; -atom_from_dynamic(Data) -> - {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. - -rescue(F) -> - try {ok, F()} - catch - throw:X -> {error, {thrown, X}}; - error:X -> {error, {errored, X}}; - exit:X -> {error, {exited, X}} - end. - -ensure_all_started(Application) -> - case application:ensure_all_started(Application) of - {ok, _} = Ok -> Ok; - - {error, {ProblemApp, {"no such file or directory", _}}} -> - {error, {unknown_application, ProblemApp}} - end. - -sleep(Microseconds) -> - timer:sleep(Microseconds), - nil. - -sleep_forever() -> - timer:sleep(infinity), - nil. - -file_info_result(Result) -> - case Result of - {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> - {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; - {ok, _} -> - Result; - {error, Reason} when ?is_posix_error(Reason) -> - Result - end. - -file_info(Filename) -> - file_info_result(file:read_file_info(Filename, [{time, posix}])). - -link_info(Filename) -> - file_info_result(file:read_link_info(Filename, [{time, posix}])). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -get_all_env() -> - BinVars = lists:map(fun(VarString) -> - [VarName, VarVal] = string:split(VarString, "="), - {list_to_binary(VarName), list_to_binary(VarVal)} - end, os:getenv()), - maps:from_list(BinVars). - -get_env(Name) -> - case os:getenv(binary_to_list(Name)) of - false -> {error, nil}; - Value -> {ok, list_to_binary(Value)} - end. - -set_env(Name, Value) -> - os:putenv(binary_to_list(Name), binary_to_list(Value)), - nil. - -unset_env(Name) -> - os:unsetenv(binary_to_list(Name)), - nil. - -os_family() -> - case os:type() of - {win32, nt} -> - windows_nt; - {unix, linux} -> - linux; - {unix, darwin} -> - darwin; - {unix, freebsd} -> - free_bsd; - {_, Other} -> - {other, atom_to_binary(Other, utf8)} - end. - -new_selector() -> - {selector, #{}}. - -map_selector({selector, Handlers}, Fn) -> - MappedHandlers = maps:map(fun(_Tag, Handler) -> - fun(Message) -> Fn(Handler(Message)) end - end, Handlers), - {selector, MappedHandlers}. - -merge_selector({selector, HandlersA}, {selector, HandlersB}) -> - {selector, maps:merge(HandlersA, HandlersB)}. - -insert_selector_handler({selector, Handlers}, Tag, Fn) -> - {selector, Handlers#{Tag => Fn}}. - -select(Selector) -> - {ok, Message} = select(Selector, infinity), - Message. - -select({selector, Handlers}, Timeout) -> - AnythingHandler = maps:get(anything, Handlers, undefined), - receive - % Monitored process down messages. - % This is special cased so we can selectively receive based on the - % reference as well as the record tag. - {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> - Fn = maps:get(Ref, Handlers), - {ok, Fn({process_down, Pid, Reason})}; - - Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> - Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), - {ok, Fn(Msg)}; - - Msg when AnythingHandler =/= undefined -> - {ok, AnythingHandler(Msg)} - after Timeout -> - {error, nil} - end. - -demonitor({_, Reference}) -> - erlang:demonitor(Reference, [flush]). - -link(Pid) -> - try - erlang:link(Pid) - catch - error:_ -> false - end. - -trap_exits(ShouldTrap) -> - erlang:process_flag(trap_exit, ShouldTrap), - nil. - -flush_messages() -> - receive _Message -> flush_messages() - after 0 -> nil - end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/LICENSE b/test-community-packages-javascript/build/packages/gleam_http/LICENSE deleted file mode 100644 index 619ec77e6e1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_http/README.md b/test-community-packages-javascript/build/packages/gleam_http/README.md deleted file mode 100644 index 5c0a7f685a3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Gleam HTTP - -Types and functions for HTTP clients and servers! - -## HTTP Service Example - -```gleam -import gleam/http/elli -import gleam/http/response.{Response} -import gleam/http/request.{Request} -import gleam/bit_builder.{BitBuilder} - -// Define a HTTP service -// -pub fn my_service(request: Request(t)) -> Response(BitBuilder) { - let body = bit_builder.from_string("Hello, world!") - - response.new(200) - |> response.prepend_header("made-with", "Gleam") - |> response.set_body(body) -} - -// Start it on port 3000 using the Elli web server -// -pub fn main() { - elli.become(my_service, on_port: 3000) -} -``` - -## Server adapters - -In the example above the Elli Erlang web server is used to run the Gleam HTTP -service. Here's a full list of the server adapters available, sorted -alphabetically. - -| Adapter | About | -| --- | --- | -| [gleam_cowboy][cowboy-adapter] | [Cowboy][cowboy] is an Erlang HTTP2 & HTTP1.1 web server | -| [gleam_elli][elli-adapter] | [Elli][elli] is an Erlang HTTP1.1 web server | -| [gleam_plug][plug-adapter] | [Plug][plug] is an Elixir web application interface | - -[cowboy]:https://github.com/ninenines/cowboy -[cowboy-adapter]: https://github.com/gleam-lang/cowboy -[elli]:https://github.com/elli-lib/elli -[elli-adapter]: https://github.com/gleam-lang/elli -[plug]:https://github.com/elixir-plug/plug -[plug-adapter]: https://github.com/gleam-lang/plug - -## Client adapters - -Client adapters are used to send HTTP requests to services over the network. -Here's a full list of the client adapters available, sorted alphabetically. - -| Adapter | About | -| --- | --- | -| [gleam_fetch][fetch-adapter] | [fetch][fetch] is a HTTP client included with JavaScript | -| [gleam_hackney][hackney-adapter] | [Hackney][hackney] is a simple HTTP client for Erlang | -| [gleam_httpc][httpc-adapter] | [httpc][httpc] is a HTTP client included with Erlang | - -[hackney]: https://github.com/benoitc/hackney -[hackney-adapter]: https://github.com/gleam-lang/hackney -[httpc]: https://erlang.org/doc/man/httpc.html -[httpc-adapter]: https://github.com/gleam-lang/httpc -[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API -[fetch-adapter]: https://github.com/gleam-lang/fetch diff --git a/test-community-packages-javascript/build/packages/gleam_http/gleam.toml b/test-community-packages-javascript/build/packages/gleam_http/gleam.toml deleted file mode 100644 index 6955a79b2ed..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_http" -version = "3.2.0" -licences = ["Apache-2.0"] -description = "Types and functions for Gleam HTTP clients and servers" - -repository = { type = "github", user = "gleam-lang", repo = "http" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.18" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl deleted file mode 100644 index 78a7d02c930..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl +++ /dev/null @@ -1,8 +0,0 @@ --record(attributes, { - max_age :: gleam@option:option(integer()), - domain :: gleam@option:option(binary()), - path :: gleam@option:option(binary()), - secure :: boolean(), - http_only :: boolean(), - same_site :: gleam@option:option(gleam@http@cookie:same_site_policy()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl deleted file mode 100644 index c8bbae649d5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl +++ /dev/null @@ -1,10 +0,0 @@ --record(request, { - method :: gleam@http:method(), - headers :: list({binary(), binary()}), - body :: any(), - scheme :: gleam@http:scheme(), - host :: binary(), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl deleted file mode 100644 index ba6f07701c7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(response, { - status :: integer(), - headers :: list({binary(), binary()}), - body :: any() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam deleted file mode 100644 index ec17246b90f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam +++ /dev/null @@ -1,122 +0,0 @@ -//// Functions for working with HTTP data structures in Gleam. -//// -//// This module makes it easy to create and modify Requests and Responses, data types. -//// A general HTTP message type is defined that enables functions to work on both requests and responses. -//// -//// This module does not implement a HTTP client or HTTP server, but it can be used as a base for them. - -import gleam/dynamic.{DecodeError, Dynamic} -import gleam/string - -/// HTTP standard method as defined by [RFC 2616](https://tools.ietf.org/html/rfc2616), -/// and PATCH which is defined by [RFC 5789](https://tools.ietf.org/html/rfc5789). -pub type Method { - Get - Post - Head - Put - Delete - Trace - Connect - Options - Patch - - /// Non-standard but valid HTTP methods. - Other(String) -} - -// TODO: check if the a is a valid HTTP method (i.e. it is a token, as per the -// spec) and return Ok(Other(s)) if so. -pub fn parse_method(s) -> Result(Method, Nil) { - case string.lowercase(s) { - "connect" -> Ok(Connect) - "delete" -> Ok(Delete) - "get" -> Ok(Get) - "head" -> Ok(Head) - "options" -> Ok(Options) - "patch" -> Ok(Patch) - "post" -> Ok(Post) - "put" -> Ok(Put) - "trace" -> Ok(Trace) - _ -> Error(Nil) - } -} - -pub fn method_to_string(method: Method) -> String { - case method { - Connect -> "connect" - Delete -> "delete" - Get -> "get" - Head -> "head" - Options -> "options" - Patch -> "patch" - Post -> "post" - Put -> "put" - Trace -> "trace" - Other(s) -> s - } -} - -/// The two URI schemes for HTTP -/// -pub type Scheme { - Http - Https -} - -/// Convert a scheme into a string. -/// -/// # Examples -/// -/// > scheme_to_string(Http) -/// "http" -/// -/// > scheme_to_string(Https) -/// "https" -/// -pub fn scheme_to_string(scheme: Scheme) -> String { - case scheme { - Http -> "http" - Https -> "https" - } -} - -/// Parse a HTTP scheme from a string -/// -/// # Examples -/// -/// > scheme_to_string("http") -/// Ok(Http) -/// -/// > scheme_to_string("ftp") -/// Error(Nil) -/// -pub fn scheme_from_string(scheme: String) -> Result(Scheme, Nil) { - case string.lowercase(scheme) { - "http" -> Ok(Http) - "https" -> Ok(Https) - _ -> Error(Nil) - } -} - -pub fn method_from_dynamic(value: Dynamic) -> Result(Method, List(DecodeError)) { - case do_method_from_dynamic(value) { - Ok(method) -> Ok(method) - Error(_) -> Error([DecodeError("HTTP method", dynamic.classify(value), [])]) - } -} - -if erlang { - external fn do_method_from_dynamic(Dynamic) -> Result(Method, nil) = - "gleam_http_native" "decode_method" -} - -if javascript { - external fn do_method_from_dynamic(Dynamic) -> Result(Method, Nil) = - "../gleam_http_native.mjs" "decode_method" -} - -/// A HTTP header is a key-value pair. Header keys should be all lowercase -/// characters. -pub type Header = - #(String, String) diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam deleted file mode 100644 index 79c9faf4917..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam +++ /dev/null @@ -1,128 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/regex -import gleam/string -import gleam/option.{Option, Some} -import gleam/http.{Scheme} - -/// Policy options for the SameSite cookie attribute -/// -/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite -pub type SameSitePolicy { - Lax - Strict - None -} - -fn same_site_to_string(policy) { - case policy { - Lax -> "Lax" - Strict -> "Strict" - None -> "None" - } -} - -/// Attributes of a cookie when sent to a client in the `set-cookie` header. -pub type Attributes { - Attributes( - max_age: Option(Int), - domain: Option(String), - path: Option(String), - secure: Bool, - http_only: Bool, - same_site: Option(SameSitePolicy), - ) -} - -/// Helper to create sensible default attributes for a set cookie. -/// -/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Attributes -pub fn defaults(scheme: Scheme) { - Attributes( - max_age: option.None, - domain: option.None, - path: option.Some("/"), - secure: scheme == http.Https, - http_only: True, - same_site: Some(Lax), - ) -} - -const epoch = "Expires=Thu, 01 Jan 1970 00:00:00 GMT" - -fn cookie_attributes_to_list(attributes) { - let Attributes( - max_age: max_age, - domain: domain, - path: path, - secure: secure, - http_only: http_only, - same_site: same_site, - ) = attributes - [ - // Expires is a deprecated attribute for cookies, it has been replaced with MaxAge - // MaxAge is widely supported and so Expires values are not set. - // Only when deleting cookies is the exception made to use the old format, - // to ensure complete clearup of cookies if required by an application. - case max_age { - option.Some(0) -> option.Some([epoch]) - _ -> option.None - }, - option.map(max_age, fn(max_age) { ["Max-Age=", int.to_string(max_age)] }), - option.map(domain, fn(domain) { ["Domain=", domain] }), - option.map(path, fn(path) { ["Path=", path] }), - case secure { - True -> option.Some(["Secure"]) - False -> option.None - }, - case http_only { - True -> option.Some(["HttpOnly"]) - False -> option.None - }, - option.map( - same_site, - fn(same_site) { ["SameSite=", same_site_to_string(same_site)] }, - ), - ] - |> list.filter_map(option.to_result(_, Nil)) -} - -pub fn set_header(name: String, value: String, attributes: Attributes) -> String { - [[name, "=", value], ..cookie_attributes_to_list(attributes)] - |> list.map(string.join(_, "")) - |> string.join("; ") -} - -/// Parse a list of cookies from a header string. Any malformed cookies will be -/// discarded. -/// -pub fn parse(cookie_string: String) -> List(#(String, String)) { - let assert Ok(re) = regex.from_string("[,;]") - regex.split(re, cookie_string) - |> list.filter_map(fn(pair) { - case string.split_once(string.trim(pair), "=") { - Ok(#("", _)) -> Error(Nil) - Ok(#(key, value)) -> { - let key = string.trim(key) - let value = string.trim(value) - use _ <- result.then(check_token(key)) - use _ <- result.then(check_token(value)) - Ok(#(key, value)) - } - Error(Nil) -> Error(Nil) - } - }) -} - -fn check_token(token: String) -> Result(Nil, Nil) { - case string.pop_grapheme(token) { - Error(Nil) -> Ok(Nil) - Ok(#(" ", _)) -> Error(Nil) - Ok(#("\t", _)) -> Error(Nil) - Ok(#("\r", _)) -> Error(Nil) - Ok(#("\n", _)) -> Error(Nil) - Ok(#("\f", _)) -> Error(Nil) - Ok(#(_, rest)) -> check_token(rest) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam deleted file mode 100644 index f4fbe9bc30c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam +++ /dev/null @@ -1,258 +0,0 @@ -import gleam/result -// TODO: validate_req -import gleam/http.{Get, Header, Method, Scheme} -import gleam/http/cookie -import gleam/option.{None, Option, Some} -import gleam/uri.{Uri} -import gleam/list -import gleam/string -import gleam/string_builder - -// TODO: document -pub type Request(body) { - Request( - method: Method, - headers: List(Header), - body: body, - scheme: Scheme, - host: String, - port: Option(Int), - path: String, - query: Option(String), - ) -} - -/// Return the uri that a request was sent to. -/// -pub fn to_uri(request: Request(a)) -> Uri { - Uri( - scheme: option.Some(http.scheme_to_string(request.scheme)), - userinfo: option.None, - host: option.Some(request.host), - port: request.port, - path: request.path, - query: request.query, - fragment: option.None, - ) -} - -/// Construct a request from a URI. -/// -pub fn from_uri(uri: Uri) -> Result(Request(String), Nil) { - use scheme <- result.then( - uri.scheme - |> option.unwrap("") - |> http.scheme_from_string, - ) - use host <- result.then( - uri.host - |> option.to_result(Nil), - ) - let req = - Request( - method: Get, - headers: [], - body: "", - scheme: scheme, - host: host, - port: uri.port, - path: uri.path, - query: uri.query, - ) - Ok(req) -} - -/// Get the value for a given header. -/// -/// If the request does not have that header then `Error(Nil)` is returned. -/// -pub fn get_header(request: Request(body), key: String) -> Result(String, Nil) { - list.key_find(request.headers, string.lowercase(key)) -} - -/// Set the header with the given value under the given header key. -/// -/// If already present, it is replaced. -pub fn set_header( - request: Request(body), - key: String, - value: String, -) -> Request(body) { - let headers = list.key_set(request.headers, string.lowercase(key), value) - Request(..request, headers: headers) -} - -/// Prepend the header with the given value under the given header key. -/// -/// Similar to `set_header` except if the header already exists it prepends -/// another header with the same key. -pub fn prepend_header( - request: Request(body), - key: String, - value: String, -) -> Request(body) { - let headers = [#(string.lowercase(key), value), ..request.headers] - Request(..request, headers: headers) -} - -// TODO: record update syntax, which can't be done currently as body type changes -/// Set the body of the request, overwriting any existing body. -/// -pub fn set_body(req: Request(old_body), body: new_body) -> Request(new_body) { - let Request( - method: method, - headers: headers, - scheme: scheme, - host: host, - port: port, - path: path, - query: query, - .., - ) = req - Request( - method: method, - headers: headers, - body: body, - scheme: scheme, - host: host, - port: port, - path: path, - query: query, - ) -} - -/// Update the body of a request using a given function. -/// -pub fn map( - request: Request(old_body), - transform: fn(old_body) -> new_body, -) -> Request(new_body) { - request.body - |> transform - |> set_body(request, _) -} - -/// Return the non-empty segments of a request path. -/// -pub fn path_segments(request: Request(body)) -> List(String) { - request.path - |> uri.path_segments -} - -/// Decode the query of a request. -pub fn get_query(request: Request(body)) -> Result(List(#(String, String)), Nil) { - case request.query { - option.Some(query_string) -> uri.parse_query(query_string) - option.None -> Ok([]) - } -} - -// TODO: escape -/// Set the query of the request. -/// -pub fn set_query( - req: Request(body), - query: List(#(String, String)), -) -> Request(body) { - let pair = fn(t: #(String, String)) { - string_builder.from_strings([t.0, "=", t.1]) - } - let query = - query - |> list.map(pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string - |> option.Some - Request(..req, query: query) -} - -/// Set the method of the request. -/// -pub fn set_method(req: Request(body), method: Method) -> Request(body) { - Request(..req, method: method) -} - -/// A request with commonly used default values. This request can be used as -/// an initial value and then update to create the desired request. -/// -pub fn new() -> Request(String) { - Request( - method: Get, - headers: [], - body: "", - scheme: http.Https, - host: "localhost", - port: option.None, - path: "", - query: option.None, - ) -} - -/// Construct a request from a URL string -/// -pub fn to(url: String) -> Result(Request(String), Nil) { - url - |> uri.parse - |> result.then(from_uri) -} - -/// Set the scheme (protocol) of the request. -/// -pub fn set_scheme(req: Request(body), scheme: Scheme) -> Request(body) { - Request(..req, scheme: scheme) -} - -/// Set the method of the request. -/// -pub fn set_host(req: Request(body), host: String) -> Request(body) { - Request(..req, host: host) -} - -/// Set the port of the request. -/// -pub fn set_port(req: Request(body), port: Int) -> Request(body) { - Request(..req, port: option.Some(port)) -} - -/// Set the path of the request. -/// -pub fn set_path(req: Request(body), path: String) -> Request(body) { - Request(..req, path: path) -} - -/// Send a cookie with a request -/// -/// Multiple cookies are added to the same cookie header. -pub fn set_cookie(req: Request(body), name: String, value: String) { - let new_cookie_string = string.join([name, value], "=") - - let #(cookies_string, headers) = case list.key_pop(req.headers, "cookie") { - Ok(#(cookies_string, headers)) -> { - let cookies_string = - string.join([cookies_string, new_cookie_string], "; ") - #(cookies_string, headers) - } - Error(Nil) -> #(new_cookie_string, req.headers) - } - - Request(..req, headers: [#("cookie", cookies_string), ..headers]) -} - -/// Fetch the cookies sent in a request. -/// -/// Note badly formed cookie pairs will be ignored. -/// RFC6265 specifies that invalid cookie names/attributes should be ignored. -pub fn get_cookies(req) -> List(#(String, String)) { - let Request(headers: headers, ..) = req - - headers - |> list.filter_map(fn(header) { - let #(name, value) = header - case name { - "cookie" -> Ok(cookie.parse(value)) - _ -> Error(Nil) - } - }) - |> list.flatten() -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam deleted file mode 100644 index 56f42d19b2c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam +++ /dev/null @@ -1,141 +0,0 @@ -import gleam/result -import gleam/http.{Header} -import gleam/http/cookie -import gleam/list -import gleam/string -import gleam/option - -// TODO: document -pub type Response(body) { - Response(status: Int, headers: List(Header), body: body) -} - -/// Update the body of a response using a given result returning function. -/// -/// If the given function returns an `Ok` value the body is set, if it returns -/// an `Error` value then the error is returned. -/// -pub fn try_map( - response: Response(old_body), - transform: fn(old_body) -> Result(new_body, error), -) -> Result(Response(new_body), error) { - use body <- result.then(transform(response.body)) - Ok(set_body(response, body)) -} - -/// Construct an empty Response. -/// -/// The body type of the returned response is `String` and could be set with a -/// call to `set_body`. -/// -pub fn new(status: Int) -> Response(String) { - Response(status: status, headers: [], body: "") -} - -/// Get the value for a given header. -/// -/// If the response does not have that header then `Error(Nil)` is returned. -/// -pub fn get_header(response: Response(body), key: String) -> Result(String, Nil) { - list.key_find(response.headers, string.lowercase(key)) -} - -/// Set the header with the given value under the given header key. -/// -/// If the response already has that key, it is replaced. -pub fn set_header( - response: Response(body), - key: String, - value: String, -) -> Response(body) { - let headers = list.key_set(response.headers, key, string.lowercase(value)) - Response(..response, headers: headers) -} - -/// Prepend the header with the given value under the given header key. -/// -/// Similar to `set_header` except if the header already exists it prepends -/// another header with the same key. -pub fn prepend_header( - response: Response(body), - key: String, - value: String, -) -> Response(body) { - let headers = [#(string.lowercase(key), value), ..response.headers] - Response(..response, headers: headers) -} - -/// Set the body of the response, overwriting any existing body. -/// -pub fn set_body( - response: Response(old_body), - body: new_body, -) -> Response(new_body) { - let Response(status: status, headers: headers, ..) = response - Response(status: status, headers: headers, body: body) -} - -/// Update the body of a response using a given function. -/// -pub fn map( - response: Response(old_body), - transform: fn(old_body) -> new_body, -) -> Response(new_body) { - response.body - |> transform - |> set_body(response, _) -} - -/// Create a response that redirects to the given uri. -/// -pub fn redirect(uri: String) -> Response(String) { - Response( - status: 303, - headers: [#("location", uri)], - body: string.append("You are being redirected to ", uri), - ) -} - -/// Fetch the cookies sent in a response. -/// -/// Badly formed cookies will be discarded. -/// -pub fn get_cookies(resp) -> List(#(String, String)) { - let Response(headers: headers, ..) = resp - headers - |> list.filter_map(fn(header) { - let #(name, value) = header - case name { - "set-cookie" -> Ok(cookie.parse(value)) - _ -> Error(Nil) - } - }) - |> list.flatten() -} - -/// Set a cookie value for a client -/// -pub fn set_cookie( - response: Response(t), - name: String, - value: String, - attributes: cookie.Attributes, -) -> Response(t) { - prepend_header( - response, - "set-cookie", - cookie.set_header(name, value, attributes), - ) -} - -/// Expire a cookie value for a client -/// -/// Note: The attributes value should be the same as when the response cookie was set. -pub fn expire_cookie( - response: Response(t), - name: String, - attributes: cookie.Attributes, -) -> Response(t) { - let attrs = cookie.Attributes(..attributes, max_age: option.Some(0)) - set_cookie(response, name, "", attrs) -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam deleted file mode 100644 index fddf362b525..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam +++ /dev/null @@ -1,82 +0,0 @@ -import gleam/http.{Delete, Patch, Post, Put} -import gleam/http/request.{Request} -import gleam/http/response.{Response} -import gleam/list -import gleam/result - -// TODO: document -pub type Service(in, out) = - fn(Request(in)) -> Response(out) - -pub type Middleware(before_req, before_resp, after_req, after_resp) = - fn(Service(before_req, before_resp)) -> Service(after_req, after_resp) - -/// A middleware that transform the response body returned by the service using -/// a given function. -/// -pub fn map_response_body( - service: Service(req, a), - with mapper: fn(a) -> b, -) -> Service(req, b) { - fn(req) { - req - |> service - |> response.map(mapper) - } -} - -/// A middleware that prepends a header to the request. -/// -pub fn prepend_response_header( - service: Service(req, resp), - key: String, - value: String, -) -> Service(req, resp) { - fn(req) { - req - |> service - |> response.prepend_header(key, value) - } -} - -fn ensure_post(req: Request(a)) { - case req.method { - Post -> Ok(req) - _ -> Error(Nil) - } -} - -fn get_override_method(request: Request(t)) -> Result(http.Method, Nil) { - use query_params <- result.then(request.get_query(request)) - use method <- result.then(list.key_find(query_params, "_method")) - use method <- result.then(http.parse_method(method)) - case method { - Put | Patch | Delete -> Ok(method) - _ -> Error(Nil) - } -} - -/// A middleware that overrides an incoming POST request with a method given in -/// the request's `_method` query paramerter. This is useful as web browsers -/// typically only support GET and POST requests, but our application may -/// expect other HTTP methods that are more semantically correct. -/// -/// The methods PUT, PATCH, and DELETE are accepted for overriding, all others -/// are ignored. -/// -/// The `_method` query paramerter can be specified in a HTML form like so: -/// -/// <form method="POST" action="/item/1?_method=DELETE"> -/// <button type="submit">Delete item</button> -/// </form> -/// -pub fn method_override(service: Service(req, resp)) -> Service(req, resp) { - fn(request) { - request - |> ensure_post - |> result.then(get_override_method) - |> result.map(request.set_method(request, _)) - |> result.unwrap(request) - |> service - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl deleted file mode 100644 index 3baae58a314..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl +++ /dev/null @@ -1,124 +0,0 @@ --module(gleam@http). --compile([no_auto_import, nowarn_unused_vars]). - --export([parse_method/1, method_to_string/1, scheme_to_string/1, scheme_from_string/1, method_from_dynamic/1]). --export_type([method/0, scheme/0]). - --type method() :: get | - post | - head | - put | - delete | - trace | - connect | - options | - patch | - {other, binary()}. - --type scheme() :: http | https. - --spec parse_method(binary()) -> {ok, method()} | {error, nil}. -parse_method(S) -> - case gleam@string:lowercase(S) of - <<"connect"/utf8>> -> - {ok, connect}; - - <<"delete"/utf8>> -> - {ok, delete}; - - <<"get"/utf8>> -> - {ok, get}; - - <<"head"/utf8>> -> - {ok, head}; - - <<"options"/utf8>> -> - {ok, options}; - - <<"patch"/utf8>> -> - {ok, patch}; - - <<"post"/utf8>> -> - {ok, post}; - - <<"put"/utf8>> -> - {ok, put}; - - <<"trace"/utf8>> -> - {ok, trace}; - - _ -> - {error, nil} - end. - --spec method_to_string(method()) -> binary(). -method_to_string(Method) -> - case Method of - connect -> - <<"connect"/utf8>>; - - delete -> - <<"delete"/utf8>>; - - get -> - <<"get"/utf8>>; - - head -> - <<"head"/utf8>>; - - options -> - <<"options"/utf8>>; - - patch -> - <<"patch"/utf8>>; - - post -> - <<"post"/utf8>>; - - put -> - <<"put"/utf8>>; - - trace -> - <<"trace"/utf8>>; - - {other, S} -> - S - end. - --spec scheme_to_string(scheme()) -> binary(). -scheme_to_string(Scheme) -> - case Scheme of - http -> - <<"http"/utf8>>; - - https -> - <<"https"/utf8>> - end. - --spec scheme_from_string(binary()) -> {ok, scheme()} | {error, nil}. -scheme_from_string(Scheme) -> - case gleam@string:lowercase(Scheme) of - <<"http"/utf8>> -> - {ok, http}; - - <<"https"/utf8>> -> - {ok, https}; - - _ -> - {error, nil} - end. - --spec method_from_dynamic(gleam@dynamic:dynamic()) -> {ok, method()} | - {error, list(gleam@dynamic:decode_error())}. -method_from_dynamic(Value) -> - case gleam_http_native:decode_method(Value) of - {ok, Method} -> - {ok, Method}; - - {error, _} -> - {error, - [{decode_error, - <<"HTTP method"/utf8>>, - gleam@dynamic:classify(Value), - []}]} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl deleted file mode 100644 index f7451c7ada6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl +++ /dev/null @@ -1,153 +0,0 @@ --module(gleam@http@cookie). --compile([no_auto_import, nowarn_unused_vars]). - --export([defaults/1, set_header/3, parse/1]). --export_type([same_site_policy/0, attributes/0]). - --type same_site_policy() :: lax | strict | none. - --type attributes() :: {attributes, - gleam@option:option(integer()), - gleam@option:option(binary()), - gleam@option:option(binary()), - boolean(), - boolean(), - gleam@option:option(same_site_policy())}. - --spec same_site_to_string(same_site_policy()) -> binary(). -same_site_to_string(Policy) -> - case Policy of - lax -> - <<"Lax"/utf8>>; - - strict -> - <<"Strict"/utf8>>; - - none -> - <<"None"/utf8>> - end. - --spec defaults(gleam@http:scheme()) -> attributes(). -defaults(Scheme) -> - {attributes, - none, - none, - {some, <<"/"/utf8>>}, - Scheme =:= https, - true, - {some, lax}}. - --spec cookie_attributes_to_list(attributes()) -> list(list(binary())). -cookie_attributes_to_list(Attributes) -> - {attributes, Max_age, Domain, Path, Secure, Http_only, Same_site} = Attributes, - _pipe = [case Max_age of - {some, 0} -> - {some, [<<"Expires=Thu, 01 Jan 1970 00:00:00 GMT"/utf8>>]}; - - _ -> - none - end, gleam@option:map( - Max_age, - fun(Max_age@1) -> - [<<"Max-Age="/utf8>>, gleam@int:to_string(Max_age@1)] - end - ), gleam@option:map( - Domain, - fun(Domain@1) -> [<<"Domain="/utf8>>, Domain@1] end - ), gleam@option:map(Path, fun(Path@1) -> [<<"Path="/utf8>>, Path@1] end), case Secure of - true -> - {some, [<<"Secure"/utf8>>]}; - - false -> - none - end, case Http_only of - true -> - {some, [<<"HttpOnly"/utf8>>]}; - - false -> - none - end, gleam@option:map( - Same_site, - fun(Same_site@1) -> - [<<"SameSite="/utf8>>, same_site_to_string(Same_site@1)] - end - )], - gleam@list:filter_map( - _pipe, - fun(_capture) -> gleam@option:to_result(_capture, nil) end - ). - --spec set_header(binary(), binary(), attributes()) -> binary(). -set_header(Name, Value, Attributes) -> - _pipe = [[Name, <<"="/utf8>>, Value] | - cookie_attributes_to_list(Attributes)], - _pipe@1 = gleam@list:map( - _pipe, - fun(_capture) -> gleam@string:join(_capture, <<""/utf8>>) end - ), - gleam@string:join(_pipe@1, <<"; "/utf8>>). - --spec check_token(binary()) -> {ok, nil} | {error, nil}. -check_token(Token) -> - case gleam@string:pop_grapheme(Token) of - {error, nil} -> - {ok, nil}; - - {ok, {<<" "/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\t"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\r"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\n"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\f"/utf8>>, _}} -> - {error, nil}; - - {ok, {_, Rest}} -> - check_token(Rest) - end. - --spec parse(binary()) -> list({binary(), binary()}). -parse(Cookie_string) -> - _assert_subject = gleam@regex:from_string(<<"[,;]"/utf8>>), - {ok, Re} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/http/cookie"/utf8>>, - function => <<"parse"/utf8>>, - line => 101}) - end, - _pipe = gleam@regex:split(Re, Cookie_string), - gleam@list:filter_map( - _pipe, - fun(Pair) -> - case gleam@string:split_once(gleam@string:trim(Pair), <<"="/utf8>>) of - {ok, {<<""/utf8>>, _}} -> - {error, nil}; - - {ok, {Key, Value}} -> - Key@1 = gleam@string:trim(Key), - Value@1 = gleam@string:trim(Value), - gleam@result:then( - check_token(Key@1), - fun(_) -> - gleam@result:then( - check_token(Value@1), - fun(_) -> {ok, {Key@1, Value@1}} end - ) - end - ); - - {error, nil} -> - {error, nil} - end - end - ). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl deleted file mode 100644 index 97616ed4506..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl +++ /dev/null @@ -1,202 +0,0 @@ --module(gleam@http@request). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_uri/1, from_uri/1, get_header/2, set_header/3, prepend_header/3, set_body/2, map/2, path_segments/1, get_query/1, set_query/2, set_method/2, new/0, to/1, set_scheme/2, set_host/2, set_port/2, set_path/2, set_cookie/3, get_cookies/1]). --export_type([request/1]). - --type request(FBL) :: {request, - gleam@http:method(), - list({binary(), binary()}), - FBL, - gleam@http:scheme(), - binary(), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary())}. - --spec to_uri(request(any())) -> gleam@uri:uri(). -to_uri(Request) -> - {uri, - {some, gleam@http:scheme_to_string(erlang:element(5, Request))}, - none, - {some, erlang:element(6, Request)}, - erlang:element(7, Request), - erlang:element(8, Request), - erlang:element(9, Request), - none}. - --spec from_uri(gleam@uri:uri()) -> {ok, request(binary())} | {error, nil}. -from_uri(Uri) -> - gleam@result:then( - begin - _pipe = erlang:element(2, Uri), - _pipe@1 = gleam@option:unwrap(_pipe, <<""/utf8>>), - gleam@http:scheme_from_string(_pipe@1) - end, - fun(Scheme) -> - gleam@result:then( - begin - _pipe@2 = erlang:element(4, Uri), - gleam@option:to_result(_pipe@2, nil) - end, - fun(Host) -> - Req = {request, - get, - [], - <<""/utf8>>, - Scheme, - Host, - erlang:element(5, Uri), - erlang:element(6, Uri), - erlang:element(7, Uri)}, - {ok, Req} - end - ) - end - ). - --spec get_header(request(any()), binary()) -> {ok, binary()} | {error, nil}. -get_header(Request, Key) -> - gleam@list:key_find(erlang:element(3, Request), gleam@string:lowercase(Key)). - --spec set_header(request(FBV), binary(), binary()) -> request(FBV). -set_header(Request, Key, Value) -> - Headers = gleam@list:key_set( - erlang:element(3, Request), - gleam@string:lowercase(Key), - Value - ), - erlang:setelement(3, Request, Headers). - --spec prepend_header(request(FBY), binary(), binary()) -> request(FBY). -prepend_header(Request, Key, Value) -> - Headers = [{gleam@string:lowercase(Key), Value} | - erlang:element(3, Request)], - erlang:setelement(3, Request, Headers). - --spec set_body(request(any()), FCD) -> request(FCD). -set_body(Req, Body) -> - {request, Method, Headers, _, Scheme, Host, Port, Path, Query} = Req, - {request, Method, Headers, Body, Scheme, Host, Port, Path, Query}. - --spec map(request(FCF), fun((FCF) -> FCH)) -> request(FCH). -map(Request, Transform) -> - _pipe = erlang:element(4, Request), - _pipe@1 = Transform(_pipe), - set_body(Request, _pipe@1). - --spec path_segments(request(any())) -> list(binary()). -path_segments(Request) -> - _pipe = erlang:element(8, Request), - gleam@uri:path_segments(_pipe). - --spec get_query(request(any())) -> {ok, list({binary(), binary()})} | - {error, nil}. -get_query(Request) -> - case erlang:element(9, Request) of - {some, Query_string} -> - gleam@uri:parse_query(Query_string); - - none -> - {ok, []} - end. - --spec set_query(request(FCR), list({binary(), binary()})) -> request(FCR). -set_query(Req, Query) -> - Pair = fun(T) -> - gleam@string_builder:from_strings( - [erlang:element(1, T), <<"="/utf8>>, erlang:element(2, T)] - ) - end, - Query@1 = begin - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, Pair), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - _pipe@4 = gleam@string_builder:to_string(_pipe@3), - {some, _pipe@4} - end, - erlang:setelement(9, Req, Query@1). - --spec set_method(request(FCV), gleam@http:method()) -> request(FCV). -set_method(Req, Method) -> - erlang:setelement(2, Req, Method). - --spec new() -> request(binary()). -new() -> - {request, - get, - [], - <<""/utf8>>, - https, - <<"localhost"/utf8>>, - none, - <<""/utf8>>, - none}. - --spec to(binary()) -> {ok, request(binary())} | {error, nil}. -to(Url) -> - _pipe = Url, - _pipe@1 = gleam@uri:parse(_pipe), - gleam@result:then(_pipe@1, fun from_uri/1). - --spec set_scheme(request(FDC), gleam@http:scheme()) -> request(FDC). -set_scheme(Req, Scheme) -> - erlang:setelement(5, Req, Scheme). - --spec set_host(request(FDF), binary()) -> request(FDF). -set_host(Req, Host) -> - erlang:setelement(6, Req, Host). - --spec set_port(request(FDI), integer()) -> request(FDI). -set_port(Req, Port) -> - erlang:setelement(7, Req, {some, Port}). - --spec set_path(request(FDL), binary()) -> request(FDL). -set_path(Req, Path) -> - erlang:setelement(8, Req, Path). - --spec set_cookie(request(FDO), binary(), binary()) -> request(FDO). -set_cookie(Req, Name, Value) -> - New_cookie_string = gleam@string:join([Name, Value], <<"="/utf8>>), - {Cookies_string@2, Headers@1} = case gleam@list:key_pop( - erlang:element(3, Req), - <<"cookie"/utf8>> - ) of - {ok, {Cookies_string, Headers}} -> - Cookies_string@1 = gleam@string:join( - [Cookies_string, New_cookie_string], - <<"; "/utf8>> - ), - {Cookies_string@1, Headers}; - - {error, nil} -> - {New_cookie_string, erlang:element(3, Req)} - end, - erlang:setelement( - 3, - Req, - [{<<"cookie"/utf8>>, Cookies_string@2} | Headers@1] - ). - --spec get_cookies(request(any())) -> list({binary(), binary()}). -get_cookies(Req) -> - {request, _, Headers, _, _, _, _, _, _} = Req, - _pipe = Headers, - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Header) -> - {Name, Value} = Header, - case Name of - <<"cookie"/utf8>> -> - {ok, gleam@http@cookie:parse(Value)}; - - _ -> - {error, nil} - end - end - ), - gleam@list:flatten(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl deleted file mode 100644 index 1769c814143..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@http@response). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, get_header/2, set_header/3, prepend_header/3, set_body/2, try_map/2, map/2, redirect/1, get_cookies/1, set_cookie/4, expire_cookie/3]). --export_type([response/1]). - --type response(FIP) :: {response, integer(), list({binary(), binary()}), FIP}. - --spec new(integer()) -> response(binary()). -new(Status) -> - {response, Status, [], <<""/utf8>>}. - --spec get_header(response(any()), binary()) -> {ok, binary()} | {error, nil}. -get_header(Response, Key) -> - gleam@list:key_find( - erlang:element(3, Response), - gleam@string:lowercase(Key) - ). - --spec set_header(response(FJE), binary(), binary()) -> response(FJE). -set_header(Response, Key, Value) -> - Headers = gleam@list:key_set( - erlang:element(3, Response), - Key, - gleam@string:lowercase(Value) - ), - erlang:setelement(3, Response, Headers). - --spec prepend_header(response(FJH), binary(), binary()) -> response(FJH). -prepend_header(Response, Key, Value) -> - Headers = [{gleam@string:lowercase(Key), Value} | - erlang:element(3, Response)], - erlang:setelement(3, Response, Headers). - --spec set_body(response(any()), FJM) -> response(FJM). -set_body(Response, Body) -> - {response, Status, Headers, _} = Response, - {response, Status, Headers, Body}. - --spec try_map(response(FIQ), fun((FIQ) -> {ok, FIS} | {error, FIT})) -> {ok, - response(FIS)} | - {error, FIT}. -try_map(Response, Transform) -> - gleam@result:then( - Transform(erlang:element(4, Response)), - fun(Body) -> {ok, set_body(Response, Body)} end - ). - --spec map(response(FJO), fun((FJO) -> FJQ)) -> response(FJQ). -map(Response, Transform) -> - _pipe = erlang:element(4, Response), - _pipe@1 = Transform(_pipe), - set_body(Response, _pipe@1). - --spec redirect(binary()) -> response(binary()). -redirect(Uri) -> - {response, - 303, - [{<<"location"/utf8>>, Uri}], - gleam@string:append(<<"You are being redirected to "/utf8>>, Uri)}. - --spec get_cookies(response(any())) -> list({binary(), binary()}). -get_cookies(Resp) -> - {response, _, Headers, _} = Resp, - _pipe = Headers, - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Header) -> - {Name, Value} = Header, - case Name of - <<"set-cookie"/utf8>> -> - {ok, gleam@http@cookie:parse(Value)}; - - _ -> - {error, nil} - end - end - ), - gleam@list:flatten(_pipe@1). - --spec set_cookie( - response(FJV), - binary(), - binary(), - gleam@http@cookie:attributes() -) -> response(FJV). -set_cookie(Response, Name, Value, Attributes) -> - prepend_header( - Response, - <<"set-cookie"/utf8>>, - gleam@http@cookie:set_header(Name, Value, Attributes) - ). - --spec expire_cookie(response(FJY), binary(), gleam@http@cookie:attributes()) -> response(FJY). -expire_cookie(Response, Name, Attributes) -> - Attrs = erlang:setelement(2, Attributes, {some, 0}), - set_cookie(Response, Name, <<""/utf8>>, Attrs). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl deleted file mode 100644 index bb7ef2ef6a7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl +++ /dev/null @@ -1,82 +0,0 @@ --module(gleam@http@service). --compile([no_auto_import, nowarn_unused_vars]). - --export([map_response_body/2, prepend_response_header/3, method_override/1]). - --spec map_response_body( - fun((gleam@http@request:request(FMN)) -> gleam@http@response:response(FMO)), - fun((FMO) -> FMR) -) -> fun((gleam@http@request:request(FMN)) -> gleam@http@response:response(FMR)). -map_response_body(Service, Mapper) -> - fun(Req) -> _pipe = Req, - _pipe@1 = Service(_pipe), - gleam@http@response:map(_pipe@1, Mapper) end. - --spec prepend_response_header( - fun((gleam@http@request:request(FMU)) -> gleam@http@response:response(FMV)), - binary(), - binary() -) -> fun((gleam@http@request:request(FMU)) -> gleam@http@response:response(FMV)). -prepend_response_header(Service, Key, Value) -> - fun(Req) -> _pipe = Req, - _pipe@1 = Service(_pipe), - gleam@http@response:prepend_header(_pipe@1, Key, Value) end. - --spec ensure_post(gleam@http@request:request(FNA)) -> {ok, - gleam@http@request:request(FNA)} | - {error, nil}. -ensure_post(Req) -> - case erlang:element(2, Req) of - post -> - {ok, Req}; - - _ -> - {error, nil} - end. - --spec get_override_method(gleam@http@request:request(any())) -> {ok, - gleam@http:method()} | - {error, nil}. -get_override_method(Request) -> - gleam@result:then( - gleam@http@request:get_query(Request), - fun(Query_params) -> - gleam@result:then( - gleam@list:key_find(Query_params, <<"_method"/utf8>>), - fun(Method) -> - gleam@result:then( - gleam@http:parse_method(Method), - fun(Method@1) -> case Method@1 of - put -> - {ok, Method@1}; - - patch -> - {ok, Method@1}; - - delete -> - {ok, Method@1}; - - _ -> - {error, nil} - end end - ) - end - ) - end - ). - --spec method_override( - fun((gleam@http@request:request(FNH)) -> gleam@http@response:response(FNI)) -) -> fun((gleam@http@request:request(FNH)) -> gleam@http@response:response(FNI)). -method_override(Service) -> - fun(Request) -> _pipe = Request, - _pipe@1 = ensure_post(_pipe), - _pipe@2 = gleam@result:then(_pipe@1, fun get_override_method/1), - _pipe@3 = gleam@result:map( - _pipe@2, - fun(_capture) -> - gleam@http@request:set_method(Request, _capture) - end - ), - _pipe@4 = gleam@result:unwrap(_pipe@3, Request), - Service(_pipe@4) end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src deleted file mode 100644 index 8d43953c74e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src +++ /dev/null @@ -1,12 +0,0 @@ -{application, gleam_http, [ - {vsn, "3.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Types and functions for Gleam HTTP clients and servers"}, - {modules, [gleam@http, - gleam@http@cookie, - gleam@http@request, - gleam@http@response, - gleam@http@service]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl deleted file mode 100644 index bb499bb57fd..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl +++ /dev/null @@ -1,88 +0,0 @@ --module(gleam_http_native). --export([decode_method/1]). - -decode_method(Term) -> - case Term of - "connect" -> {ok, connect}; - "delete" -> {ok, delete}; - "get" -> {ok, get}; - "head" -> {ok, head}; - "options" -> {ok, options}; - "patch" -> {ok, patch}; - "post" -> {ok, post}; - "put" -> {ok, put}; - "trace" -> {ok, trace}; - "CONNECT" -> {ok, connect}; - "DELETE" -> {ok, delete}; - "GET" -> {ok, get}; - "HEAD" -> {ok, head}; - "OPTIONS" -> {ok, options}; - "PATCH" -> {ok, patch}; - "POST" -> {ok, post}; - "PUT" -> {ok, put}; - "TRACE" -> {ok, trace}; - "Connect" -> {ok, connect}; - "Delete" -> {ok, delete}; - "Get" -> {ok, get}; - "Head" -> {ok, head}; - "Options" -> {ok, options}; - "Patch" -> {ok, patch}; - "Post" -> {ok, post}; - "Put" -> {ok, put}; - "Trace" -> {ok, trace}; - 'connect' -> {ok, connect}; - 'delete' -> {ok, delete}; - 'get' -> {ok, get}; - 'head' -> {ok, head}; - 'options' -> {ok, options}; - 'patch' -> {ok, patch}; - 'post' -> {ok, post}; - 'put' -> {ok, put}; - 'trace' -> {ok, trace}; - 'CONNECT' -> {ok, connect}; - 'DELETE' -> {ok, delete}; - 'GET' -> {ok, get}; - 'HEAD' -> {ok, head}; - 'OPTIONS' -> {ok, options}; - 'PATCH' -> {ok, patch}; - 'POST' -> {ok, post}; - 'PUT' -> {ok, put}; - 'TRACE' -> {ok, trace}; - 'Connect' -> {ok, connect}; - 'Delete' -> {ok, delete}; - 'Get' -> {ok, get}; - 'Head' -> {ok, head}; - 'Options' -> {ok, options}; - 'Patch' -> {ok, patch}; - 'Post' -> {ok, post}; - 'Put' -> {ok, put}; - 'Trace' -> {ok, trace}; - <<"connect">> -> {ok, connect}; - <<"delete">> -> {ok, delete}; - <<"get">> -> {ok, get}; - <<"head">> -> {ok, head}; - <<"options">> -> {ok, options}; - <<"patch">> -> {ok, patch}; - <<"post">> -> {ok, post}; - <<"put">> -> {ok, put}; - <<"trace">> -> {ok, trace}; - <<"CONNECT">> -> {ok, connect}; - <<"DELETE">> -> {ok, delete}; - <<"GET">> -> {ok, get}; - <<"HEAD">> -> {ok, head}; - <<"OPTIONS">> -> {ok, options}; - <<"PATCH">> -> {ok, patch}; - <<"POST">> -> {ok, post}; - <<"PUT">> -> {ok, put}; - <<"TRACE">> -> {ok, trace}; - <<"Connect">> -> {ok, connect}; - <<"Delete">> -> {ok, delete}; - <<"Get">> -> {ok, get}; - <<"Head">> -> {ok, head}; - <<"Options">> -> {ok, options}; - <<"Patch">> -> {ok, patch}; - <<"Post">> -> {ok, post}; - <<"Put">> -> {ok, put}; - <<"Trace">> -> {ok, trace}; - _ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs deleted file mode 100644 index c871a8b9514..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs +++ /dev/null @@ -1,38 +0,0 @@ -import { Ok, Error } from "./gleam.mjs"; -import { - Get, - Post, - Head, - Put, - Delete, - Trace, - Connect, - Options, - Patch, -} from "./gleam/http.mjs"; - -export function decode_method(value) { - try { - switch (value.toLowerCase()) { - case "get": - return new Ok(new Get()); - case "post": - return new Ok(new Post()); - case "head": - return new Ok(new Head()); - case "put": - return new Ok(new Put()); - case "delete": - return new Ok(new Delete()); - case "trace": - return new Ok(new Trace()); - case "connect": - return new Ok(new Connect()); - case "options": - return new Ok(new Options()); - case "patch": - return new Ok(new Patch()); - } - } catch {} - return new Error(undefined); -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/LICENCE b/test-community-packages-javascript/build/packages/gleam_otp/LICENCE deleted file mode 100644 index 619ec77e6e1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_otp/README.md b/test-community-packages-javascript/build/packages/gleam_otp/README.md deleted file mode 100644 index 3c313a1c8c9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Gleam OTP - -<a href="https://github.com/gleam-lang/otp/releases"><img src="https://img.shields.io/github/release/gleam-lang/otp" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/otp/workflows/test/badge.svg?branch=main) - -A Gleam library for building fault tolerant multi-core programs using the -actor model. It is compatible with Erlang's OTP framework. - -This library is experimental and will likely have many breaking changes in the -future! - -Gleam’s actor system is built with a few primary goals: - -- Full type safety of actors and messages. -- Be compatible with Erlang’s OTP actor framework. -- Provide fault tolerance and self-healing through supervisors. -- Have equivalent performance to Erlang’s OTP. - -This library documents its abstractions and functionality, but you may also wish -to read the documentation or other material on Erlang’s OTP framework to get a -fuller understanding of OTP, the problems it solves, and and the motivations for -its design. - -## Usage - -Add this library to your Gleam project. - -```shell -gleam add gleam_otp -``` - -## Actor hierarchy - -This library provides several different types of actor that can be used in -Gleam programs. - -### Process - -The process is the lowest level building block of OTP, all other actors are -built on top of processes either directly or indirectly. Typically this -abstraction would be not be used very often in Gleam applications, favour -other actor types that provide more functionality. - -Gleam's process module is defined in the `gleam_erlang` library. - -[[Documentation]](https://hexdocs.pm/gleam_erlang/gleam/erlang/process.html) - -### Actor - -The `actor` is the most commonly used process type in Gleam and serves as a good -building block for other abstractions. Like Erlang's `gen_server` it handles -OTP's system messages automatically to enable OTP's debugging and tracing -functionality. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/actor.html) - -### Task - -A task is a kind of process that performs a single task and then shuts down. -Commonly tasks are used to convert sequential code into concurrent code by -performing computation in another process. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/task.html) - -### Supervisor - -Supervisors is a process that starts and then supervises a group of processes, -restarting them if they crash. Supervisors can start other supervisors, -resulting in a hierarchical process structure called a supervision tree, -providing fault tolerance to a Gleam application. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/supervisor.html) - -## Limitations and known issues - -This library is experimental there are some limitations that not yet been resolved. - -- There is no support for named processes. They are untyped global mutable - variables which may be uninitialized, more research is needed to find a - suitable type safe alternative. -- There are relatively few actor abstractions provided by this library. More - will be added in the future. -- Actors do not yet support all OTP system messages. Unsupported messages are - dropped. -- Supervisors do not yet support different shutdown periods per child. In - practice this means that children that are supervisors do not get an - unlimited amount of time to shut down, as is expected in Erlang or Elixir. -- This library has not seen much testing compared to the Erlang OTP - libraries, both in terms of unit tests and real world testing in - applications. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml b/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml deleted file mode 100644 index 849e41ed186..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleam_otp" -version = "0.5.3" -licences = ["Apache-2.0"] -description = "Fault tolerant multicore Gleam programs with OTP" - -repository = { type = "github", user = "gleam-lang", repo = "otp" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.19" -gleam_erlang = "~> 0.2" - -[dev-dependencies] -gleeunit = "~> 0.5" diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl deleted file mode 100644 index 75faa95149f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ready, {state :: any(), selector :: gleam@erlang@process:selector(any())}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl deleted file mode 100644 index 05f87d87d7b..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(spec, { - init :: fun(() -> gleam@otp@actor:init_result(any(), any())), - init_timeout :: integer(), - loop :: fun((any(), any()) -> gleam@otp@actor:next(any())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl deleted file mode 100644 index 3ed0b0122d4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(intensity_tracker, { - limit :: integer(), - period :: integer(), - events :: list(integer()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl deleted file mode 100644 index 7afd07f0319..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(child_spec, { - start :: fun((any()) -> {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()}), - returning :: fun((any(), gleam@erlang@process:subject(any())) -> any()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl deleted file mode 100644 index b10bd9fa3f7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(spec, { - argument :: any(), - max_frequency :: integer(), - frequency_period :: integer(), - init :: fun((gleam@otp@supervisor:children(any())) -> gleam@otp@supervisor:children(any())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl deleted file mode 100644 index de1c1ac340e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(status_info, { - module :: gleam@erlang@atom:atom_(), - parent :: gleam@erlang@process:pid_(), - mode :: gleam@otp@system:mode(), - debug_state :: gleam@otp@system:debug_state(), - state :: gleam@dynamic:dynamic() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl deleted file mode 100644 index 8d84d3fc503..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl +++ /dev/null @@ -1 +0,0 @@ --record(exit, {reason :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl deleted file mode 100644 index 959bea8e9b9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(task, { - owner :: gleam@erlang@process:pid_(), - pid :: gleam@erlang@process:pid_(), - monitor :: gleam@erlang@process:process_monitor(), - selector :: gleam@erlang@process:selector(gleam@otp@task:message(any())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam deleted file mode 100644 index 4a4ca5ed712..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam +++ /dev/null @@ -1,473 +0,0 @@ -//// This module provides the _Actor_ abstraction, one of the most common -//// building blocks of Gleam OTP programs. -//// -//// An Actor is a process like any other BEAM process and can be be used to hold -//// state, execute code, and communicate with other processes by sending and -//// receiving messages. The advantage of using the actor abstraction over a bare -//// process is that it provides a single interface for commonly needed -//// functionality, including support for the [tracing and debugging -//// features in OTP](erlang-sys). -//// -//// Gleam's Actor is similar to Erlang's `gen_server` and Elixir's `GenServer` -//// but differs in that it offers a fully typed interface. This different API is -//// why Gleam uses the name Actor rather than some variation of generic-server. -//// -//// [erlang-sys]: https://www.erlang.org/doc/man/sys.html -//// -//// ## Example -//// -//// An Actor can be used to create a client-server interaction between an Actor -//// (the server) and other processes (the clients). In this example we have an -//// Actor that works as a stack, allowing clients to push and pop elements. -//// -//// ```gleam -//// pub fn main() { -//// // Start the actor with initial state of an empty list, and the -//// // `handle_message` callback function (defined below). -//// // We assert that it starts successfully. -//// // -//// // In real-world Gleam OTP programs we would likely write a wrapper functions -//// // called `start`, `push` `pop`, `shutdown` to start and interact with the -//// // Actor. We are not doing that here for the sake of showing how the Actor -//// // API works. -//// let assert Ok(actor) = actor.start([], handle_message) -//// -//// // We can send a message to the actor to push elements onto the stack. -//// process.send(actor, Push("Joe")) -//// process.send(actor, Push("Mike")) -//// process.send(actor, Push("Robert")) -//// -//// // The `Push` message expects no response, these messages are sent purely for -//// // the side effect of mutating the state held by the actor. -//// // -//// // We can also send the `Pop` message to take a value off of the actor's -//// // stack. This message expects a response, so we use `process.call` to send a -//// // message and wait until a reply is received. -//// // -//// // In this instance we are giving the actor 10 milliseconds to reply, if the -//// // `call` function doesn't get a reply within this time it will panic and -//// // crash the client process. -//// let assert Ok("Robert") = process.call(actor, Pop, 10) -//// let assert Ok("Mike") = process.call(actor, Pop, 10) -//// let assert Ok("Joe") = process.call(actor, Pop, 10) -//// -//// // The stack is now empty, so if we pop again the actor replies with an error. -//// let assert Error(Nil) = process.call(actor, Pop, 10) -//// -//// // Lastly, we can send a message to the actor asking it to shut down. -//// process.send(actor, Shutdown) -//// } -//// ``` -//// -//// Here is the code that is used to implement this actor: -//// -//// ```gleam -//// // First step of implementing the stack Actor is to define the message type that -//// // it can receive. -//// // -//// // The type of the elements in the stack is no fixed so a type parameter is used -//// // for it instead of a concrete type such as `String` or `Int`. -//// pub type Message(element) { -//// // The `Shutdown` message is used to tell the actor to stop. -//// // It is the simplest message type, it contains no data. -//// Shutdown -//// -//// // The `Push` message is used to add a new element to the stack. -//// // It contains the item to add, the type of which is the `element` -//// // parameterised type. -//// Push(push: element) -//// -//// // The `Pop` message is used to remove an element from the stack. -//// // It contains a `Subject`, which is used to send the response back to the -//// // message sender. In this case the reply is of type `Result(element, Nil)`. -//// Pop(reply_with: Subject(Result(element, Nil))) -//// } -//// -//// // The last part is to implement the `handle_message` callback function. -//// // -//// // This function is called by the Actor each for each message it receives. -//// // Actor is single threaded only does one thing at a time, so it handles -//// // messages sequentially and one at a time, in the order they are received. -//// // -//// // The function takes the message and the current state, and returns a data -//// // structure that indicates what to do next, along with the new state. -//// fn handle_message(message: Message(e), stack: List(e)) -> actor.Next(List(e)) { -//// case message { -//// // For the `Shutdown` message we return the `actor.Stop` value, which causes -//// // the actor to discard any remaining messages and stop. -//// Shutdown -> actor.Stop(process.Normal) -//// -//// // For the `Push` message we add the new element to the stack and return -//// // `actor.Continue` with this new stack, causing the actor to process any -//// // queued messages or wait for more. -//// Push(value) -> { -//// let new_state = [value, ..stack] -//// actor.Continue(new_state) -//// } -//// -//// // For the `Pop` message we attempt to remove an element from the stack, -//// // sending it or an error back to the caller, before continuing. -//// Pop(client) -> -//// case stack { -//// [] -> { -//// // When the stack is empty we can't pop an element, so we send an -//// // error back. -//// process.send(client, Error(Nil)) -//// actor.Continue([]) -//// } -//// -//// [first, ..rest] -> { -//// // Otherwise we send the first element back and use the remaining -//// // elements as the new state. -//// process.send(client, Ok(first)) -//// actor.Continue(rest) -//// } -//// } -//// } -//// } -//// ``` - -import gleam/erlang/process.{Abnormal, ExitReason, Pid, Selector, Subject} -import gleam/erlang/charlist.{Charlist} -import gleam/otp/system.{ - DebugState, GetState, GetStatus, Mode, Resume, Running, StatusInfo, Suspend, - Suspended, SystemMessage, -} -import gleam/string -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom - -type Message(message) { - /// A regular message excepted by the process - Message(message) - - /// An OTP system message, for debugging or maintenance - System(SystemMessage) - - /// An unexpected message - Unexpected(Dynamic) -} - -/// The type used to indicate what to do after handling a message. -/// -pub type Next(state) { - /// Continue handling messages. - /// - Continue(state) - - /// Stop handling messages and shut down. - /// - Stop(ExitReason) -} - -/// The type used to indicate whether an actor has started successfully or not. -/// -pub type InitResult(state, message) { - /// The actor has successfully initialised. The actor can start handling - /// messages and actor's channel sender can be returned to the parent - /// process. - /// - Ready(state: state, selector: Selector(message)) - - /// The actor has failed to initialise. The actor shuts down and an error is - /// returned to the parent process. - /// - Failed(String) -} - -type Self(state, msg) { - Self( - mode: Mode, - parent: Pid, - state: state, - selector: Selector(Message(msg)), - debug_state: DebugState, - message_handler: fn(msg, state) -> Next(state), - ) -} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an actor. -/// -/// If you do not need to configure the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub type Spec(state, msg) { - Spec( - /// The initialisation functionality for the actor. This function is called - /// just after the actor starts but before the channel sender is returned - /// to the parent. - /// - /// This function is used to ensure that any required data or state is - /// correct. If this function returns an error it means that the actor has - /// failed to start and an error is returned to the parent. - /// - init: fn() -> InitResult(state, msg), - /// How many milliseconds the `init` function has to return before it is - /// considered to have taken too long and failed. - /// - init_timeout: Int, - /// This function is called to handle each message that the actor receives. - /// - loop: fn(msg, state) -> Next(state), - ) -} - -// TODO: Check needed functionality here to be OTP compatible -fn exit_process(reason: ExitReason) -> ExitReason { - // TODO - reason -} - -fn receive_message(self: Self(state, msg)) -> Message(msg) { - let selector = case self.mode { - // When suspended we only respond to system messages - Suspended -> - process.new_selector() - |> selecting_system_messages - - // When running we respond to all messages - Running -> - // We add the handler for unexpected messages first so that the user - // supplied selector can override it if desired - process.new_selector() - |> process.selecting_anything(Unexpected) - |> process.merge_selector(self.selector) - |> selecting_system_messages - } - - process.select_forever(selector) -} - -fn selecting_system_messages( - selector: Selector(Message(msg)), -) -> Selector(Message(msg)) { - selector - |> process.selecting_record3( - atom.create_from_string("system"), - convert_system_message, - ) -} - -external fn convert_system_message(Dynamic, Dynamic) -> Message(msg) = - "gleam_otp_external" "convert_system_message" - -fn process_status_info(self: Self(state, msg)) -> StatusInfo { - StatusInfo( - module: atom.create_from_string("gleam@otp@actor"), - parent: self.parent, - mode: self.mode, - debug_state: self.debug_state, - state: dynamic.from(self.state), - ) -} - -fn loop(self: Self(state, msg)) -> ExitReason { - case receive_message(self) { - System(system) -> - case system { - GetState(callback) -> { - callback(dynamic.from(self.state)) - loop(self) - } - Resume(callback) -> { - callback() - loop(Self(..self, mode: Running)) - } - Suspend(callback) -> { - callback() - loop(Self(..self, mode: Suspended)) - } - GetStatus(callback) -> { - callback(process_status_info(self)) - loop(self) - } - } - - Unexpected(message) -> { - log_warning( - charlist.from_string("Actor discarding unexpected message: ~s"), - [charlist.from_string(string.inspect(message))], - ) - loop(self) - } - - Message(msg) -> - case self.message_handler(msg, self.state) { - Stop(reason) -> exit_process(reason) - Continue(state) -> loop(Self(..self, state: state)) - } - } -} - -// TODO: replace this when we have Gleam bindings to the logger -external fn log_warning(Charlist, List(Charlist)) -> Nil = - "logger" "warning" - -fn initialise_actor( - spec: Spec(state, msg), - ack: Subject(Result(Subject(msg), ExitReason)), -) { - let subject = process.new_subject() - case spec.init() { - Ready(state, selector) -> { - let selector = - process.new_selector() - |> process.selecting(subject, Message) - |> process.merge_selector(process.map_selector(selector, Message)) - // Signal to parent that the process has initialised successfully - process.send(ack, Ok(subject)) - // Start message receive loop - let self = - Self( - state: state, - parent: process.subject_owner(ack), - selector: selector, - message_handler: spec.loop, - debug_state: system.debug_state([]), - mode: Running, - ) - loop(self) - } - - Failed(reason) -> { - process.send(ack, Error(Abnormal(reason))) - exit_process(Abnormal(reason)) - } - } -} - -pub type StartError { - InitTimeout - InitFailed(ExitReason) - InitCrashed(Dynamic) -} - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - Result(Subject(msg), StartError) - -/// An Erlang supervisor compatible process start result. -/// -/// If you wish to convert this into a `StartResult` compatible with Gleam -/// supervisors see the `from_erlang_start_result` and `wrap_erlang_starter` -/// functions. -/// -pub type ErlangStartResult = - Result(Pid, Dynamic) - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - case res { - Ok(x) -> Ok(process.subject_owner(x)) - Error(x) -> Error(dynamic.from(x)) - } -} - -type StartInitMessage(msg) { - Ack(Result(Subject(msg), ExitReason)) - Mon(process.ProcessDown) -} - -// TODO: test init_timeout. Currently if we test it eunit prints an error from -// the process death. How do we avoid this? -// -/// Start an actor from a given specification. If the actor's `init` function -/// returns an error or does not return within `init_timeout` then an error is -/// returned. -/// -/// If you do not need to specify the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub fn start_spec(spec: Spec(state, msg)) -> Result(Subject(msg), StartError) { - let ack_subject = process.new_subject() - - let child = - process.start( - linked: True, - running: fn() { initialise_actor(spec, ack_subject) }, - ) - - let monitor = process.monitor_process(child) - let selector = - process.new_selector() - |> process.selecting(ack_subject, Ack) - |> process.selecting_process_down(monitor, Mon) - - let result = case process.select(selector, spec.init_timeout) { - // Child started OK - Ok(Ack(Ok(channel))) -> Ok(channel) - - // Child initialiser returned an error - Ok(Ack(Error(reason))) -> Error(InitFailed(reason)) - - // Child went down while initialising - Ok(Mon(down)) -> Error(InitCrashed(down.reason)) - - // Child did not finish initialising in time - Error(Nil) -> { - process.kill(child) - Error(InitTimeout) - } - } - - // Remove the monitor used for the starting of the actor as to avoid an extra - // message arriving at the parent if the child dies later. - process.demonitor_process(monitor) - - result -} - -/// Start an actor with a given initial state and message handling loop -/// function. -/// -/// This function returns a `Result` but it will always be `Ok` so it is safe -/// to use with `assert` if you are not starting this actor as part of a -/// supervision tree. -/// -/// If you wish to configure the initialisation behaviour of a new actor see -/// the `Spec` record and the `start_spec` function. -/// -pub fn start( - state: state, - loop: fn(msg, state) -> Next(state), -) -> Result(Subject(msg), StartError) { - start_spec(Spec( - init: fn() { Ready(state, process.new_selector()) }, - loop: loop, - init_timeout: 5000, - )) -} - -/// Send a message over a given channel. -/// -/// This is a re-export of `process.send`, for the sake of convenience. -/// -pub fn send(subject: Subject(msg), msg: msg) -> Nil { - process.send(subject, msg) -} - -// TODO: test -/// Send a synchronous message and wait for a response from the receiving -/// process. -/// -/// If a reply is not received within the given timeout then the sender process -/// crashes. If you wish receive a `Result` rather than crashing see the -/// `process.try_call` function. -/// -/// This is a re-export of `process.call`, for the sake of convenience. -/// -pub fn call( - selector: Subject(message), - make_message: fn(Subject(reply)) -> message, - timeout: Int, -) -> reply { - process.call(selector, make_message, timeout) -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam deleted file mode 100644 index b53e1006325..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam +++ /dev/null @@ -1,46 +0,0 @@ -//// The intensity tracker is used to monitor how frequently an event happens, -//// erroring if it happens too many times within a period of time. - -import gleam/list - -// TODO: test -pub opaque type IntensityTracker { - IntensityTracker(limit: Int, period: Int, events: List(Int)) -} - -pub type TooIntense { - TooIntense -} - -pub fn new(limit limit: Int, period period: Int) -> IntensityTracker { - IntensityTracker(limit: limit, period: period, events: []) -} - -external fn monotonic_time(Int) -> Int = - "erlang" "monotonic_time" - -fn now_seconds() -> Int { - monotonic_time(1) -} - -pub fn trim_window(events: List(Int), now: Int, period: Int) -> List(Int) { - case events { - [] -> [] - [event, ..events] -> - case now >= event + period { - True -> [event, ..trim_window(events, now, period)] - False -> [] - } - } -} - -pub fn add_event( - tracker: IntensityTracker, -) -> Result(IntensityTracker, TooIntense) { - let now = now_seconds() - let events = trim_window([now, ..tracker.events], now, tracker.period) - case list.length(events) >= tracker.limit { - True -> Error(TooIntense) - False -> Ok(IntensityTracker(..tracker, events: events)) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam deleted file mode 100644 index 19c77fa6a58..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam +++ /dev/null @@ -1 +0,0 @@ -pub external type Node diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam deleted file mode 100644 index c312494d733..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam +++ /dev/null @@ -1,9 +0,0 @@ -/// Ports are how code running on the Erlang virtual machine interacts with -/// the outside world. Bytes of data can be sent to and read from ports, -/// providing a form of message passing to an external program or resource. -/// -/// For more information on ports see the [Erlang ports documentation][1]. -/// -/// [1]: https://erlang.org/doc/reference_manual/ports.html -/// -pub external type Port diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam deleted file mode 100644 index f710b05c155..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam +++ /dev/null @@ -1,403 +0,0 @@ -// TODO: specify amount of time permitted for shut-down -import gleam/result -import gleam/string -import gleam/option.{None, Option, Some} -import gleam/erlang/process.{Pid, Subject} -import gleam/otp/actor.{StartError} -import gleam/otp/intensity_tracker.{IntensityTracker} -import gleam/otp/node.{Node} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an supervisor. -/// -/// If you do not need to configure the behaviour of your supervisor consider -/// using the `start` function. -/// -pub type Spec(argument, return) { - Spec( - argument: argument, - max_frequency: Int, - frequency_period: Int, - init: fn(Children(argument)) -> Children(return), - ) -} - -/// This type represents the starting children of a supervisor within the -/// `init` function. -/// -pub opaque type Children(argument) { - Ready(Starter(argument)) - Failed(ChildStartError) -} - -/// This type contains all the information required to start a new child and -/// add it to the `Children`. -/// -/// This is typically created with the `worker` function. -/// -pub opaque type ChildSpec(msg, argument, returning) { - ChildSpec( - // TODO: merge this into one field - start: fn(argument) -> Result(Subject(msg), StartError), - returning: fn(argument, Subject(msg)) -> returning, - ) -} - -type ChildStartError { - ChildStartError(previous_pid: Option(Pid), error: StartError) -} - -pub opaque type Message { - Exit(process.ExitMessage) - RetryRestart(Pid) -} - -type Instruction { - StartAll - StartFrom(Pid) -} - -type State(a) { - State( - restarts: IntensityTracker, - starter: Starter(a), - retry_restarts: Subject(Pid), - ) -} - -type Starter(argument) { - Starter( - argument: argument, - exec: Option( - fn(Instruction) -> - Result(#(Starter(argument), Instruction), ChildStartError), - ), - ) -} - -type Child(argument) { - Child(pid: Pid, argument: argument) -} - -fn start_child( - child_spec: ChildSpec(msg, argument_in, argument_out), - argument: argument_in, -) -> Result(Child(argument_out), ChildStartError) { - use subject <- result.then( - child_spec.start(argument) - |> result.map_error(ChildStartError(None, _)), - ) - - Ok(Child( - pid: process.subject_owner(subject), - // Merge the new child's pid into the argument to produce the new argument - // used to start any remaining children. - argument: child_spec.returning(argument, subject), - )) -} - -// TODO: more sophsiticated stopping of processes. i.e. give supervisors -// more time to shut down. -fn shutdown_child(pid: Pid, _spec: ChildSpec(msg, arg_1, arg_2)) -> Nil { - process.send_exit(pid) -} - -fn perform_instruction_for_child( - argument: argument_in, - instruction: Instruction, - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Result(#(Child(argument_out), Instruction), ChildStartError) { - let current = child.pid - case instruction { - // This child is older than the StartFrom target, we don't need to - // restart it - StartFrom(target) if target != current -> Ok(#(child, instruction)) - - // This pid either is the cause of the problem, or we have the StartAll - // instruction. Either way it and its younger siblings need to be restarted. - _ -> { - shutdown_child(current, child_spec) - use child <- result.then(start_child(child_spec, argument)) - Ok(#(child, StartAll)) - } - } -} - -fn add_child_to_starter( - starter: Starter(argument_in), - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Starter(argument_out) { - let starter = fn(instruction) { - // Restart the older children. We use `try` to return early if the older - // children failed to start - use #(starter, instruction) <- result.then(case starter.exec { - Some(start) -> start(instruction) - None -> Ok(#(starter, instruction)) - }) - - // Perform the instruction, restarting the child as required - use #(child, instruction) <- result.then(perform_instruction_for_child( - starter.argument, - instruction, - child_spec, - child, - )) - - // Create a new starter for the next time the supervisor needs to restart - let starter = add_child_to_starter(starter, child_spec, child) - - Ok(#(starter, instruction)) - } - - Starter(exec: Some(starter), argument: child.argument) -} - -fn start_and_add_child( - state: Starter(argument_0), - child_spec: ChildSpec(msg, argument_0, argument_1), -) -> Children(argument_1) { - case start_child(child_spec, state.argument) { - Ok(child) -> Ready(add_child_to_starter(state, child_spec, child)) - Error(reason) -> Failed(reason) - } -} - -/// Add a child to the collection of children of the supervisor -/// -/// This function starts the child from the child spec. -/// -pub fn add( - children: Children(argument), - child_spec: ChildSpec(msg, argument, new_argument), -) -> Children(new_argument) { - case children { - // If one of the previous children has failed then we cannot continue - Failed(fail) -> Failed(fail) - - // If everything is OK so far then we can add the child - Ready(state) -> start_and_add_child(state, child_spec) - } -} - -// TODO: test -// TODO: unlimitd shut down duration -/// Prepare a new supervisor type child. -/// -/// If you wish to prepare a new non-supervisor type child see the `worker` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -/// Note: Gleam supervisors do not yet support different shutdown periods per -/// child so this function is currently identical in behaviour to `worker`. It is -/// recommended to use this function for supervisor children nevertheless so the -/// correct shut down behaviour is used in later releases of this library. -/// -pub fn supervisor( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -/// Prepare a new worker type child. -/// -/// If you wish to prepare a new supervisor type child see the `supervisor` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -pub fn worker( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -// TODO: test -/// As each child is added to a supervisors children a new argument is prepared -/// with which to start the next child. By default argument is the same as the -/// previous argument, but this function can be used to change it to something -/// else by passing a function that takes the previous argument and the sender -/// of the previous child. -/// -pub fn returning( - child: ChildSpec(msg, argument_a, argument_b), - updater: fn(argument_a, Subject(msg)) -> argument_c, -) -> ChildSpec(msg, argument_a, argument_c) { - ChildSpec(start: child.start, returning: updater) -} - -fn init( - spec: Spec(argument, return), -) -> actor.InitResult(State(return), Message) { - // Create a subject so that we can asynchronously retry restarting when we - // fail to bring an exited child - let retry = process.new_subject() - - // Trap exits so that we get a message when a child crashes - process.trap_exits(True) - - // Combine selectors - let selector = - process.new_selector() - |> process.selecting(retry, RetryRestart) - |> process.selecting_trapped_exits(Exit) - - // Start any children - let result = - Starter(argument: spec.argument, exec: None) - |> Ready - |> spec.init - - // Pass back up the result - case result { - Ready(starter) -> { - let restarts = - intensity_tracker.new( - limit: spec.max_frequency, - period: spec.frequency_period, - ) - let state = - State(starter: starter, restarts: restarts, retry_restarts: retry) - actor.Ready(state, selector) - } - - Failed(error) -> - actor.Failed(case error.error { - actor.InitTimeout -> "Child initialisation timed out" - actor.InitCrashed(reason) -> - string.append( - "Child crashed during initialisation: ", - string.inspect(reason), - ) - actor.InitFailed(reason) -> - string.append( - "Child failed to start during initialisation: ", - string.inspect(reason), - ) - }) - } -} - -type HandleExitError { - RestartFailed(pid: Pid, restarts: IntensityTracker) - TooManyRestarts -} - -fn handle_exit(pid: Pid, state: State(a)) -> actor.Next(State(a)) { - let outcome = { - // If we are handling an exit then we must have some children - let assert Some(start) = state.starter.exec - - // Check to see if there has been too many restarts in this period - use restarts <- result.then( - state.restarts - |> intensity_tracker.add_event - |> result.map_error(fn(_) { TooManyRestarts }), - ) - - // Restart the exited child and any following children - use #(starter, _) <- result.then( - start(StartFrom(pid)) - |> result.map_error(fn(e: ChildStartError) { - RestartFailed(option.unwrap(e.previous_pid, pid), restarts) - }), - ) - - Ok(State(..state, starter: starter, restarts: restarts)) - } - - case outcome { - Ok(state) -> actor.Continue(state) - Error(RestartFailed(failed_child, restarts)) -> { - // Asynchronously enqueue the restarting of this child again as we were - // unable to restart them this time. We do this asynchronously as we want - // to have a chance to handle any system messages that have come in. - process.send(state.retry_restarts, failed_child) - let state = State(..state, restarts: restarts) - actor.Continue(state) - } - Error(TooManyRestarts) -> - actor.Stop(process.Abnormal( - "Child processes restarted too many times within allowed period", - )) - } -} - -fn loop(message: Message, state: State(argument)) -> actor.Next(State(argument)) { - case message { - Exit(exit_message) -> handle_exit(exit_message.pid, state) - RetryRestart(pid) -> handle_exit(pid, state) - } -} - -/// Start a supervisor from a given specification. -/// -pub fn start_spec(spec: Spec(a, b)) -> Result(Subject(Message), StartError) { - actor.start_spec(actor.Spec( - init: fn() { init(spec) }, - loop: loop, - init_timeout: 60_000, - )) -} - -/// Start a supervisor from a given `init` function. -/// -/// If you wish to have more control over the configuration of the supervisor -/// see the `start_spec` function. -/// -pub fn start( - init: fn(Children(Nil)) -> Children(a), -) -> Result(Subject(Message), StartError) { - start_spec(Spec( - init: init, - argument: Nil, - max_frequency: 5, - frequency_period: 1, - )) -} - -/// A type used to describe the situation in which an Erlang based application -/// is starting. -/// -/// For more information see the [Erlang distributed application -/// documentation][1] and the Learn Your Some Erlang chapter on [distributed -/// applications][2]. -/// -/// [1]: https://erlang.org/doc/design_principles/distributed_applications.html -/// [2]: https://learnyousomeerlang.com/distributed-otp-applications -/// -pub type ApplicationStartMode { - Normal - Takeover(Node) - Failover(Node) -} - -pub external type ApplicationStop - -pub external fn application_stopped() -> ApplicationStop = - "gleam_otp_external" "application_stopped" - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - actor.StartResult(msg) - -/// An Erlang supervisor compatible process start result. -/// -pub type ErlangStartResult = - actor.ErlangStartResult - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - actor.to_erlang_start_result(res) -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam deleted file mode 100644 index 895c3409458..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam +++ /dev/null @@ -1,89 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} - -pub type Mode { - Running - Suspended -} - -pub type DebugOption { - NoDebug -} - -pub external type DebugState - -pub external fn debug_state(List(DebugOption)) -> DebugState = - "sys" "debug_options" - -pub type StatusInfo { - StatusInfo( - module: Atom, - parent: Pid, - mode: Mode, - debug_state: DebugState, - state: Dynamic, - ) -} - -// TODO: document -// TODO: implement remaining messages -pub type SystemMessage { - // {replace_state, StateFn} - // {change_code, Mod, Vsn, Extra} - // {terminate, Reason} - // {debug, {log, Flag}} - // {debug, {trace, Flag}} - // {debug, {log_to_file, FileName}} - // {debug, {statistics, Flag}} - // {debug, no_debug} - // {debug, {install, {Func, FuncState}}} - // {debug, {install, {FuncId, Func, FuncState}}} - // {debug, {remove, FuncOrId}} - Resume(fn() -> Nil) - Suspend(fn() -> Nil) - GetState(fn(Dynamic) -> Nil) - GetStatus(fn(StatusInfo) -> Nil) -} - -external type DoNotLeak - -/// Get the state of a given OTP compatible process. This function is only -/// intended for debugging. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#get_state-1 -/// -pub external fn get_state(from: Pid) -> Dynamic = - "sys" "get_state" - -external fn erl_suspend(Pid) -> DoNotLeak = - "sys" "suspend" - -/// Request an OTP compatible process to suspend, causing it to only handle -/// system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#suspend-1 -/// -pub fn suspend(pid: Pid) -> Nil { - erl_suspend(pid) - Nil -} - -external fn erl_resume(from: Pid) -> DoNotLeak = - "sys" "resume" - -/// Request a suspended OTP compatible process to result, causing it to handle -/// all messages rather than only system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#resume-1 -/// -pub fn resume(pid: Pid) -> Nil { - erl_resume(pid) - Nil -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam deleted file mode 100644 index c9adc952f88..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam +++ /dev/null @@ -1,151 +0,0 @@ -//// A task is a kind of process that performs a single task and then shuts -//// down. Commonly tasks are used to convert sequential code into concurrent -//// code by performing computation in another process. -//// -//// let task = task.async(fn() { do_some_work() }) -//// let value = do_some_other_work() -//// value + task.await(task, 100) -//// -//// Tasks spawned with async can be awaited on by their caller process (and -//// only their caller) as shown in the example above. They are implemented by -//// spawning a process that sends a message to the caller once the given -//// computation is performed. -//// -//// There are two important things to consider when using `async`: -//// -//// 1. If you are using async tasks, you must await a reply as they are always -//// sent. -//// -//// 2. async tasks link the caller and the spawned process. This means that, -//// if the caller crashes, the task will crash too and vice-versa. This is -//// on purpose: if the process meant to receive the result no longer -//// exists, there is no purpose in completing the computation. -//// -//// This module is inspired by Elixir's [Task module][1]. -//// -//// [1]: https://hexdocs.pm/elixir/master/Task.html -//// - -// TODO: await_many -import gleam/erlang/process.{Pid, ProcessMonitor, Selector} -import gleam/dynamic.{Dynamic} - -pub opaque type Task(value) { - Task( - owner: Pid, - pid: Pid, - monitor: ProcessMonitor, - selector: Selector(Message(value)), - ) -} - -// TODO: test -/// Spawn a task process that calls a given function in order to perform some -/// work. The result of this function is send back to the parent and can be -/// received using the `await` function. -/// -/// See the top level module documentation for more information on async/await. -/// -pub fn async(work: fn() -> value) -> Task(value) { - let owner = process.self() - let subject = process.new_subject() - let pid = - process.start(linked: True, running: fn() { process.send(subject, work()) }) - let monitor = process.monitor_process(pid) - let selector = - process.new_selector() - |> process.selecting_process_down(monitor, FromMonitor) - |> process.selecting(subject, FromSubject) - Task(owner: owner, pid: pid, monitor: monitor, selector: selector) -} - -pub type AwaitError { - Timeout - Exit(reason: Dynamic) -} - -// We can only wait on a task if we are the owner of it so crash if we are -// waiting on a task we don't own. -fn assert_owner(task: Task(a)) -> Nil { - let self = process.self() - case task.owner == self { - True -> Nil - False -> - process.send_abnormal_exit( - self, - "awaited on a task that does not belong to this process", - ) - } -} - -type Message(value) { - FromMonitor(process.ProcessDown) - FromSubject(value) -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then an error is returned. -/// -pub fn try_await(task: Task(value), timeout: Int) -> Result(value, AwaitError) { - assert_owner(task) - case process.select(task.selector, timeout) { - // The task process has sent back a value - Ok(FromSubject(x)) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) -> - Error(Exit(reason)) - - // The task process is alive but has not sent a value yet - Error(Nil) -> Error(Timeout) - } -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then this function crashes. -/// -pub fn await(task: Task(value), timeout: Int) -> value { - let assert Ok(value) = try_await(task, timeout) - value -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! This function does not return until there is a value to -/// receive. If a value is not received then the process will be stuck waiting -/// forever. -/// -pub fn try_await_forever(task: Task(value)) -> Result(value, AwaitError) { - assert_owner(task) - case process.select_forever(task.selector) { - // The task process has sent back a value - FromSubject(x) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - FromMonitor(process.ProcessDown(reason: reason, ..)) -> Error(Exit(reason)) - } -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! Like `try_await_forever`, this function does not return until there is a value to -/// receive. -/// -/// If the task process crashes then this function crashes. -/// -pub fn await_forever(task: Task(value)) -> value { - let assert Ok(value) = try_await_forever(task) - value -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl deleted file mode 100644 index 40e16f7a820..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl +++ /dev/null @@ -1,233 +0,0 @@ --module(gleam@otp@actor). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_erlang_start_result/1, send/2, call/3, start_spec/1, start/2]). --export_type([message/1, next/1, init_result/2, self/2, spec/2, start_error/0, start_init_message/1]). - --type message(FIS) :: {message, FIS} | - {system, gleam@otp@system:system_message()} | - {unexpected, gleam@dynamic:dynamic()}. - --type next(FIT) :: {continue, FIT} | {stop, gleam@erlang@process:exit_reason()}. - --type init_result(FIU, FIV) :: {ready, FIU, gleam@erlang@process:selector(FIV)} | - {failed, binary()}. - --type self(FIW, FIX) :: {self, - gleam@otp@system:mode(), - gleam@erlang@process:pid_(), - FIW, - gleam@erlang@process:selector(message(FIX)), - gleam@otp@system:debug_state(), - fun((FIX, FIW) -> next(FIW))}. - --type spec(FIY, FIZ) :: {spec, - fun(() -> init_result(FIY, FIZ)), - integer(), - fun((FIZ, FIY) -> next(FIY))}. - --type start_error() :: init_timeout | - {init_failed, gleam@erlang@process:exit_reason()} | - {init_crashed, gleam@dynamic:dynamic()}. - --type start_init_message(FJA) :: {ack, - {ok, gleam@erlang@process:subject(FJA)} | - {error, gleam@erlang@process:exit_reason()}} | - {mon, gleam@erlang@process:process_down()}. - --spec exit_process(gleam@erlang@process:exit_reason()) -> gleam@erlang@process:exit_reason(). -exit_process(Reason) -> - Reason. - --spec process_status_info(self(any(), any())) -> gleam@otp@system:status_info(). -process_status_info(Self) -> - {status_info, - erlang:binary_to_atom(<<"gleam@otp@actor"/utf8>>), - erlang:element(3, Self), - erlang:element(2, Self), - erlang:element(6, Self), - gleam@dynamic:from(erlang:element(4, Self))}. - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | {error, start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic()}. -to_erlang_start_result(Res) -> - case Res of - {ok, X} -> - {ok, gleam@erlang@process:subject_owner(X)}; - - {error, X@1} -> - {error, gleam@dynamic:from(X@1)} - end. - --spec send(gleam@erlang@process:subject(FKX), FKX) -> nil. -send(Subject, Msg) -> - gleam@erlang@process:send(Subject, Msg). - --spec call( - gleam@erlang@process:subject(FKZ), - fun((gleam@erlang@process:subject(FLB)) -> FKZ), - integer() -) -> FLB. -call(Selector, Make_message, Timeout) -> - gleam@erlang@process:call(Selector, Make_message, Timeout). - --spec selecting_system_messages(gleam@erlang@process:selector(message(FJM))) -> gleam@erlang@process:selector(message(FJM)). -selecting_system_messages(Selector) -> - _pipe = Selector, - gleam@erlang@process:selecting_record3( - _pipe, - erlang:binary_to_atom(<<"system"/utf8>>), - fun gleam_otp_external:convert_system_message/2 - ). - --spec receive_message(self(any(), FJI)) -> message(FJI). -receive_message(Self) -> - Selector = case erlang:element(2, Self) of - suspended -> - _pipe = gleam_erlang_ffi:new_selector(), - selecting_system_messages(_pipe); - - running -> - _pipe@1 = gleam_erlang_ffi:new_selector(), - _pipe@2 = gleam@erlang@process:selecting_anything( - _pipe@1, - fun(Field@0) -> {unexpected, Field@0} end - ), - _pipe@3 = gleam_erlang_ffi:merge_selector( - _pipe@2, - erlang:element(5, Self) - ), - selecting_system_messages(_pipe@3) - end, - gleam_erlang_ffi:select(Selector). - --spec loop(self(any(), any())) -> gleam@erlang@process:exit_reason(). -loop(Self) -> - case receive_message(Self) of - {system, System} -> - case System of - {get_state, Callback} -> - Callback(gleam@dynamic:from(erlang:element(4, Self))), - loop(Self); - - {resume, Callback@1} -> - Callback@1(), - loop(erlang:setelement(2, Self, running)); - - {suspend, Callback@2} -> - Callback@2(), - loop(erlang:setelement(2, Self, suspended)); - - {get_status, Callback@3} -> - Callback@3(process_status_info(Self)), - loop(Self) - end; - - {unexpected, Message} -> - logger:warning( - unicode:characters_to_list( - <<"Actor discarding unexpected message: ~s"/utf8>> - ), - [unicode:characters_to_list(gleam@string:inspect(Message))] - ), - loop(Self); - - {message, Msg} -> - case (erlang:element(7, Self))(Msg, erlang:element(4, Self)) of - {stop, Reason} -> - exit_process(Reason); - - {continue, State} -> - loop(erlang:setelement(4, Self, State)) - end - end. - --spec initialise_actor( - spec(any(), FKA), - gleam@erlang@process:subject({ok, gleam@erlang@process:subject(FKA)} | - {error, gleam@erlang@process:exit_reason()}) -) -> gleam@erlang@process:exit_reason(). -initialise_actor(Spec, Ack) -> - Subject = gleam@erlang@process:new_subject(), - case (erlang:element(2, Spec))() of - {ready, State, Selector} -> - Selector@1 = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun(Field@0) -> {message, Field@0} end - ), - gleam_erlang_ffi:merge_selector( - _pipe@1, - gleam_erlang_ffi:map_selector( - Selector, - fun(Field@0) -> {message, Field@0} end - ) - ) - end, - gleam@erlang@process:send(Ack, {ok, Subject}), - Self = {self, - running, - gleam@erlang@process:subject_owner(Ack), - State, - Selector@1, - sys:debug_options([]), - erlang:element(4, Spec)}, - loop(Self); - - {failed, Reason} -> - gleam@erlang@process:send(Ack, {error, {abnormal, Reason}}), - exit_process({abnormal, Reason}) - end. - --spec start_spec(spec(any(), FKL)) -> {ok, gleam@erlang@process:subject(FKL)} | - {error, start_error()}. -start_spec(Spec) -> - Ack_subject = gleam@erlang@process:new_subject(), - Child = gleam@erlang@process:start( - fun() -> initialise_actor(Spec, Ack_subject) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Child), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Ack_subject, - fun(Field@0) -> {ack, Field@0} end - ), - gleam@erlang@process:selecting_process_down( - _pipe@1, - Monitor, - fun(Field@0) -> {mon, Field@0} end - ) - end, - Result = case gleam_erlang_ffi:select(Selector, erlang:element(3, Spec)) of - {ok, {ack, {ok, Channel}}} -> - {ok, Channel}; - - {ok, {ack, {error, Reason}}} -> - {error, {init_failed, Reason}}; - - {ok, {mon, Down}} -> - {error, {init_crashed, erlang:element(3, Down)}}; - - {error, nil} -> - gleam@erlang@process:kill(Child), - {error, init_timeout} - end, - gleam_erlang_ffi:demonitor(Monitor), - Result. - --spec start(FKR, fun((FKS, FKR) -> next(FKR))) -> {ok, - gleam@erlang@process:subject(FKS)} | - {error, start_error()}. -start(State, Loop) -> - start_spec( - {spec, - fun() -> {ready, State, gleam_erlang_ffi:new_selector()} end, - 5000, - Loop} - ). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl deleted file mode 100644 index 63a73ea9462..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(gleam@otp@intensity_tracker). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/2, trim_window/3, add_event/1]). --export_type([intensity_tracker/0, too_intense/0]). - --opaque intensity_tracker() :: {intensity_tracker, - integer(), - integer(), - list(integer())}. - --type too_intense() :: too_intense. - --spec new(integer(), integer()) -> intensity_tracker(). -new(Limit, Period) -> - {intensity_tracker, Limit, Period, []}. - --spec now_seconds() -> integer(). -now_seconds() -> - erlang:monotonic_time(1). - --spec trim_window(list(integer()), integer(), integer()) -> list(integer()). -trim_window(Events, Now, Period) -> - case Events of - [] -> - []; - - [Event | Events@1] -> - case Now >= (Event + Period) of - true -> - [Event | trim_window(Events@1, Now, Period)]; - - false -> - [] - end - end. - --spec add_event(intensity_tracker()) -> {ok, intensity_tracker()} | - {error, too_intense()}. -add_event(Tracker) -> - Now = now_seconds(), - Events = trim_window( - [Now | erlang:element(4, Tracker)], - Now, - erlang:element(3, Tracker) - ), - case gleam@list:length(Events) >= erlang:element(2, Tracker) of - true -> - {error, too_intense}; - - false -> - {ok, erlang:setelement(4, Tracker, Events)} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl deleted file mode 100644 index 4176b6ffad7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gleam@otp@node). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([node_/0]). - --type node_() :: any(). - - diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl deleted file mode 100644 index 4ca9f538511..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gleam@otp@port). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([port_/0]). - --type port_() :: any(). - - diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl deleted file mode 100644 index a7f39e5fbe2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl +++ /dev/null @@ -1,322 +0,0 @@ --module(gleam@otp@supervisor). --compile([no_auto_import, nowarn_unused_vars]). - --export([supervisor/1, worker/1, returning/2, start_spec/1, start/1, to_erlang_start_result/1, application_stopped/0, add/2]). --export_type([spec/2, children/1, child_spec/3, child_start_error/0, message/0, instruction/0, state/1, starter/1, child/1, handle_exit_error/0, application_start_mode/0, application_stop/0]). - --type spec(FRW, FRX) :: {spec, - FRW, - integer(), - integer(), - fun((children(FRW)) -> children(FRX))}. - --opaque children(FRY) :: {ready, starter(FRY)} | {failed, child_start_error()}. - --opaque child_spec(FRZ, FSA, FSB) :: {child_spec, - fun((FSA) -> {ok, gleam@erlang@process:subject(FRZ)} | - {error, gleam@otp@actor:start_error()}), - fun((FSA, gleam@erlang@process:subject(FRZ)) -> FSB)}. - --type child_start_error() :: {child_start_error, - gleam@option:option(gleam@erlang@process:pid_()), - gleam@otp@actor:start_error()}. - --opaque message() :: {exit, gleam@erlang@process:exit_message()} | - {retry_restart, gleam@erlang@process:pid_()}. - --type instruction() :: start_all | {start_from, gleam@erlang@process:pid_()}. - --type state(FSC) :: {state, - gleam@otp@intensity_tracker:intensity_tracker(), - starter(FSC), - gleam@erlang@process:subject(gleam@erlang@process:pid_())}. - --type starter(FSD) :: {starter, - FSD, - gleam@option:option(fun((instruction()) -> {ok, - {starter(FSD), instruction()}} | - {error, child_start_error()}))}. - --type child(FSE) :: {child, gleam@erlang@process:pid_(), FSE}. - --type handle_exit_error() :: {restart_failed, - gleam@erlang@process:pid_(), - gleam@otp@intensity_tracker:intensity_tracker()} | - too_many_restarts. - --type application_start_mode() :: normal | - {takeover, gleam@otp@node:node_()} | - {failover, gleam@otp@node:node_()}. - --type application_stop() :: any(). - --spec start_child(child_spec(any(), FSI, FSJ), FSI) -> {ok, child(FSJ)} | - {error, child_start_error()}. -start_child(Child_spec, Argument) -> - gleam@result:then( - begin - _pipe = (erlang:element(2, Child_spec))(Argument), - gleam@result:map_error( - _pipe, - fun(_capture) -> {child_start_error, none, _capture} end - ) - end, - fun(Subject) -> - {ok, - {child, - gleam@erlang@process:subject_owner(Subject), - (erlang:element(3, Child_spec))(Argument, Subject)}} - end - ). - --spec shutdown_child( - gleam@erlang@process:pid_(), - child_spec(any(), any(), any()) -) -> nil. -shutdown_child(Pid, _) -> - gleam@erlang@process:send_exit(Pid). - --spec perform_instruction_for_child( - FSW, - instruction(), - child_spec(any(), FSW, FSY), - child(FSY) -) -> {ok, {child(FSY), instruction()}} | {error, child_start_error()}. -perform_instruction_for_child(Argument, Instruction, Child_spec, Child) -> - Current = erlang:element(2, Child), - case Instruction of - {start_from, Target} when Target =/= Current -> - {ok, {Child, Instruction}}; - - _ -> - shutdown_child(Current, Child_spec), - gleam@result:then( - start_child(Child_spec, Argument), - fun(Child@1) -> {ok, {Child@1, start_all}} end - ) - end. - --spec supervisor( - fun((FUF) -> {ok, gleam@erlang@process:subject(FUG)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(FUG, FUF, FUF). -supervisor(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec worker( - fun((FUN) -> {ok, gleam@erlang@process:subject(FUO)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(FUO, FUN, FUN). -worker(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec returning( - child_spec(FUV, FUW, any()), - fun((FUW, gleam@erlang@process:subject(FUV)) -> FVC) -) -> child_spec(FUV, FUW, FVC). -returning(Child, Updater) -> - {child_spec, erlang:element(2, Child), Updater}. - --spec init(spec(any(), FVH)) -> gleam@otp@actor:init_result(state(FVH), message()). -init(Spec) -> - Retry = gleam@erlang@process:new_subject(), - gleam_erlang_ffi:trap_exits(true), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Retry, - fun(Field@0) -> {retry_restart, Field@0} end - ), - gleam@erlang@process:selecting_trapped_exits( - _pipe@1, - fun(Field@0) -> {exit, Field@0} end - ) - end, - Result = begin - _pipe@2 = {starter, erlang:element(2, Spec), none}, - _pipe@3 = {ready, _pipe@2}, - (erlang:element(5, Spec))(_pipe@3) - end, - case Result of - {ready, Starter} -> - Restarts = gleam@otp@intensity_tracker:new( - erlang:element(3, Spec), - erlang:element(4, Spec) - ), - State = {state, Restarts, Starter, Retry}, - {ready, State, Selector}; - - {failed, Error} -> - {failed, case erlang:element(3, Error) of - init_timeout -> - <<"Child initialisation timed out"/utf8>>; - - {init_crashed, Reason} -> - gleam@string:append( - <<"Child crashed during initialisation: "/utf8>>, - gleam@string:inspect(Reason) - ); - - {init_failed, Reason@1} -> - gleam@string:append( - <<"Child failed to start during initialisation: "/utf8>>, - gleam@string:inspect(Reason@1) - ) - end} - end. - --spec handle_exit(gleam@erlang@process:pid_(), state(FVN)) -> gleam@otp@actor:next(state(FVN)). -handle_exit(Pid, State) -> - Outcome = begin - _assert_subject = erlang:element(3, erlang:element(3, State)), - {some, Start} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/supervisor"/utf8>>, - function => <<"handle_exit"/utf8>>, - line => 293}) - end, - gleam@result:then( - begin - _pipe = erlang:element(2, State), - _pipe@1 = gleam@otp@intensity_tracker:add_event(_pipe), - gleam@result:map_error(_pipe@1, fun(_) -> too_many_restarts end) - end, - fun(Restarts) -> - gleam@result:then( - begin - _pipe@2 = Start({start_from, Pid}), - gleam@result:map_error( - _pipe@2, - fun(E) -> - {restart_failed, - gleam@option:unwrap( - erlang:element(2, E), - Pid - ), - Restarts} - end - ) - end, - fun(_use0) -> - {Starter, _} = _use0, - {ok, - erlang:setelement( - 2, - erlang:setelement(3, State, Starter), - Restarts - )} - end - ) - end - ) - end, - case Outcome of - {ok, State@1} -> - {continue, State@1}; - - {error, {restart_failed, Failed_child, Restarts@1}} -> - gleam@erlang@process:send(erlang:element(4, State), Failed_child), - State@2 = erlang:setelement(2, State, Restarts@1), - {continue, State@2}; - - {error, too_many_restarts} -> - {stop, - {abnormal, - <<"Child processes restarted too many times within allowed period"/utf8>>}} - end. - --spec loop(message(), state(FVR)) -> gleam@otp@actor:next(state(FVR)). -loop(Message, State) -> - case Message of - {exit, Exit_message} -> - handle_exit(erlang:element(2, Exit_message), State); - - {retry_restart, Pid} -> - handle_exit(Pid, State) - end. - --spec start_spec(spec(any(), any())) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start_spec(Spec) -> - gleam@otp@actor:start_spec( - {spec, fun() -> init(Spec) end, 60000, fun loop/2} - ). - --spec start(fun((children(nil)) -> children(any()))) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start(Init) -> - start_spec({spec, nil, 5, 1, Init}). - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic()}. -to_erlang_start_result(Res) -> - gleam@otp@actor:to_erlang_start_result(Res). - --spec application_stopped() -> application_stop(). -application_stopped() -> - gleam_otp_external:application_stopped(). - --spec add_child_to_starter( - starter(FTG), - child_spec(any(), FTG, FTJ), - child(FTJ) -) -> starter(FTJ). -add_child_to_starter(Starter, Child_spec, Child) -> - Starter@3 = fun(Instruction) -> - gleam@result:then(case erlang:element(3, Starter) of - {some, Start} -> - Start(Instruction); - - none -> - {ok, {Starter, Instruction}} - end, fun(_use0) -> - {Starter@1, Instruction@1} = _use0, - gleam@result:then( - perform_instruction_for_child( - erlang:element(2, Starter@1), - Instruction@1, - Child_spec, - Child - ), - fun(_use0@1) -> - {Child@1, Instruction@2} = _use0@1, - Starter@2 = add_child_to_starter( - Starter@1, - Child_spec, - Child@1 - ), - {ok, {Starter@2, Instruction@2}} - end - ) - end) - end, - {starter, erlang:element(3, Child), {some, Starter@3}}. - --spec start_and_add_child(starter(FTP), child_spec(any(), FTP, FTS)) -> children(FTS). -start_and_add_child(State, Child_spec) -> - case start_child(Child_spec, erlang:element(2, State)) of - {ok, Child} -> - {ready, add_child_to_starter(State, Child_spec, Child)}; - - {error, Reason} -> - {failed, Reason} - end. - --spec add(children(FTX), child_spec(any(), FTX, FUA)) -> children(FUA). -add(Children, Child_spec) -> - case Children of - {failed, Fail} -> - {failed, Fail}; - - {ready, State} -> - start_and_add_child(State, Child_spec) - end. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl deleted file mode 100644 index aa5fabd94c8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam@otp@system). --compile([no_auto_import, nowarn_unused_vars]). - --export([debug_state/1, get_state/1, suspend/1, resume/1]). --export_type([mode/0, debug_option/0, status_info/0, system_message/0, debug_state/0, do_not_leak/0]). - --type mode() :: running | suspended. - --type debug_option() :: no_debug. - --type status_info() :: {status_info, - gleam@erlang@atom:atom_(), - gleam@erlang@process:pid_(), - mode(), - debug_state(), - gleam@dynamic:dynamic()}. - --type system_message() :: {resume, fun(() -> nil)} | - {suspend, fun(() -> nil)} | - {get_state, fun((gleam@dynamic:dynamic()) -> nil)} | - {get_status, fun((status_info()) -> nil)}. - --type debug_state() :: any(). - --type do_not_leak() :: any(). - --spec debug_state(list(debug_option())) -> debug_state(). -debug_state(Field@0) -> - sys:debug_options(Field@0). - --spec get_state(gleam@erlang@process:pid_()) -> gleam@dynamic:dynamic(). -get_state(Field@0) -> - sys:get_state(Field@0). - --spec suspend(gleam@erlang@process:pid_()) -> nil. -suspend(Pid) -> - sys:suspend(Pid), - nil. - --spec resume(gleam@erlang@process:pid_()) -> nil. -resume(Pid) -> - sys:resume(Pid), - nil. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl deleted file mode 100644 index b475694cbfc..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl +++ /dev/null @@ -1,111 +0,0 @@ --module(gleam@otp@task). --compile([no_auto_import, nowarn_unused_vars]). - --export([async/1, try_await/2, await/2, try_await_forever/1, await_forever/1]). --export_type([task/1, await_error/0, message/1]). - --opaque task(FFD) :: {task, - gleam@erlang@process:pid_(), - gleam@erlang@process:pid_(), - gleam@erlang@process:process_monitor(), - gleam@erlang@process:selector(message(FFD))}. - --type await_error() :: timeout | {exit, gleam@dynamic:dynamic()}. - --type message(FFE) :: {from_monitor, gleam@erlang@process:process_down()} | - {from_subject, FFE}. - --spec async(fun(() -> FFF)) -> task(FFF). -async(Work) -> - Owner = erlang:self(), - Subject = gleam@erlang@process:new_subject(), - Pid = gleam@erlang@process:start( - fun() -> gleam@erlang@process:send(Subject, Work()) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Pid), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting_process_down( - _pipe, - Monitor, - fun(Field@0) -> {from_monitor, Field@0} end - ), - gleam@erlang@process:selecting( - _pipe@1, - Subject, - fun(Field@0) -> {from_subject, Field@0} end - ) - end, - {task, Owner, Pid, Monitor, Selector}. - --spec assert_owner(task(any())) -> nil. -assert_owner(Task) -> - Self = erlang:self(), - case erlang:element(2, Task) =:= Self of - true -> - nil; - - false -> - gleam@erlang@process:send_abnormal_exit( - Self, - <<"awaited on a task that does not belong to this process"/utf8>> - ) - end. - --spec try_await(task(FFJ), integer()) -> {ok, FFJ} | {error, await_error()}. -try_await(Task, Timeout) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task), Timeout) of - {ok, {from_subject, X}} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {ok, {from_monitor, {process_down, _, Reason}}} -> - {error, {exit, Reason}}; - - {error, nil} -> - {error, timeout} - end. - --spec await(task(FFN), integer()) -> FFN. -await(Task, Timeout) -> - _assert_subject = try_await(Task, Timeout), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await"/utf8>>, - line => 117}) - end, - Value. - --spec try_await_forever(task(FFP)) -> {ok, FFP} | {error, await_error()}. -try_await_forever(Task) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task)) of - {from_subject, X} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {from_monitor, {process_down, _, Reason}} -> - {error, {exit, Reason}} - end. - --spec await_forever(task(FFT)) -> FFT. -await_forever(Task) -> - _assert_subject = try_await_forever(Task), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await_forever"/utf8>>, - line => 149}) - end, - Value. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src deleted file mode 100644 index 79ddc8769ca..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src +++ /dev/null @@ -1,15 +0,0 @@ -{application, gleam_otp, [ - {vsn, "0.5.3"}, - {applications, [gleam_erlang, - gleam_stdlib, - gleeunit]}, - {description, "Fault tolerant multicore Gleam programs with OTP"}, - {modules, [gleam@otp@actor, - gleam@otp@intensity_tracker, - gleam@otp@node, - gleam@otp@port, - gleam@otp@supervisor, - gleam@otp@system, - gleam@otp@task]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl deleted file mode 100644 index 8910a67d7e2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam_otp_external). - --export([application_stopped/0, convert_system_message/2]). - -% TODO: support other system messages -% {replace_state, StateFn} -% {change_code, Mod, Vsn, Extra} -% {terminate, Reason} -% {debug, {log, Flag}} -% {debug, {trace, Flag}} -% {debug, {log_to_file, FileName}} -% {debug, {statistics, Flag}} -% {debug, no_debug} -% {debug, {install, {Func, FuncState}}} -% {debug, {install, {FuncId, Func, FuncState}}} -% {debug, {remove, FuncOrId}} -% GetStatus(Subject(StatusInfo)) -convert_system_message({From, Ref}, Request) when is_pid(From) -> - Reply = fun(Msg) -> - erlang:send(From, {Ref, Msg}), - nil - end, - System = fun(Callback) -> - {system, {Request, Callback}} - end, - case Request of - get_status -> System(fun(Status) -> Reply(process_status(Status)) end); - get_state -> System(Reply); - suspend -> System(fun() -> Reply(ok) end); - resume -> System(fun() -> Reply(ok) end); - Other -> {unexpeceted, Other} - end. - -process_status({status_info, Module, Parent, Mode, DebugState, State}) -> - Data = [ - get(), Mode, Parent, DebugState, - [{header, "Status for Gleam process " ++ pid_to_list(self())}, - {data, [{'Status', Mode}, {'Parent', Parent}, {'State', State}]}] - ], - {status, self(), {module, Module}, Data}. - -application_stopped() -> - ok. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index 44a866e2643..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "gleam_stdlib" -version = "0.29.2" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] - -[dev-dependencies] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 9c903123849..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@map:map_(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index 7ec15580d7c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,59 +0,0 @@ -import gleam/bit_string -import gleam/string - -/// Encodes a BitString into a base 64 encoded string. -/// -pub fn encode64(input: BitString, padding: Bool) -> String { - let encoded = do_encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -if erlang { - external fn do_encode64(BitString) -> String = - "base64" "encode" -} - -if javascript { - external fn do_encode64(BitString) -> String = - "../gleam_stdlib.mjs" "encode64" -} - -/// Decodes a base 64 encoded string into a `BitString`. -/// -pub fn decode64(encoded: String) -> Result(BitString, Nil) { - let padded = case bit_string.byte_size(bit_string.from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - do_decode64(padded) -} - -if erlang { - external fn do_decode64(String) -> Result(BitString, Nil) = - "gleam_stdlib" "base_decode64" -} - -if javascript { - external fn do_decode64(String) -> Result(BitString, Nil) = - "../gleam_stdlib.mjs" "decode64" -} - -/// Encodes a `BitString` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn url_encode64(input: BitString, padding: Bool) -> String { - encode64(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitString`. -/// -pub fn url_decode64(encoded: String) -> Result(BitString, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> decode64() -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index 960d6655559..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,276 +0,0 @@ -//// BitBuilder is a type used for efficiently concatenating bits to create bit -//// strings. -//// -//// If we append one bit string to another the bit strings must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit strings together. -//// -//// BitBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit string using the `to_bit_string` function. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -import gleam/string_builder.{StringBuilder} - -if javascript { - import gleam/list - import gleam/bit_string -} - -if erlang { - pub external type BitBuilder -} - -if javascript { - pub opaque type BitBuilder { - Bits(BitString) - Text(StringBuilder) - Many(List(BitBuilder)) - } -} - -/// Create an empty `BitBuilder`. Useful as the start of a pipe chaning many -/// builders together. -/// -pub fn new() -> BitBuilder { - do_concat([]) -} - -/// Prepends a bit string to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to: BitBuilder, prefix: BitString) -> BitBuilder { - append_builder(from_bit_string(prefix), to) -} - -/// Appends a bit string to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to: BitBuilder, suffix: BitString) -> BitBuilder { - append_builder(to, from_bit_string(suffix)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - append_builder(prefix, to) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - do_append_builder(first, second) -} - -if erlang { - external fn do_append_builder( - to: BitBuilder, - suffix: BitBuilder, - ) -> BitBuilder = - "gleam_stdlib" "iodata_append" -} - -if javascript { - fn do_append_builder(first: BitBuilder, second: BitBuilder) -> BitBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - append_builder(from_string(prefix), to) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - append_builder(to, from_string(suffix)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - do_concat(builders) -} - -if erlang { - external fn do_concat(List(BitBuilder)) -> BitBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - fn do_concat(builders: List(BitBuilder)) -> BitBuilder { - Many(builders) - } -} - -/// Joins a list of bit strings into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat_bit_strings(bits: List(BitString)) -> BitBuilder { - do_concat_bit_strings(bits) -} - -if erlang { - external fn do_concat_bit_strings(List(BitString)) -> BitBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - fn do_concat_bit_strings(bits: List(BitString)) -> BitBuilder { - bits - |> list.map(fn(b) { from_bit_string(b) }) - |> concat() - } -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -pub fn from_string(string: String) -> BitBuilder { - do_from_string(string) -} - -if erlang { - external fn do_from_string(String) -> BitBuilder = - "gleam_stdlib" "wrap_list" -} - -if javascript { - fn do_from_string(string: String) -> BitBuilder { - Text(string_builder.from_string(string)) - } -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - do_from_string_builder(builder) -} - -if erlang { - external fn do_from_string_builder(StringBuilder) -> BitBuilder = - "gleam_stdlib" "wrap_list" -} - -if javascript { - fn do_from_string_builder(builder: StringBuilder) -> BitBuilder { - Text(builder) - } -} - -/// Creates a new builder from a bit string. -/// -/// Runs in constant time. -/// -pub fn from_bit_string(bits: BitString) -> BitBuilder { - do_from_bit_string(bits) -} - -if erlang { - external fn do_from_bit_string(BitString) -> BitBuilder = - "gleam_stdlib" "wrap_list" -} - -if javascript { - fn do_from_bit_string(bits: BitString) -> BitBuilder { - Bits(bits) - } -} - -/// Turns an builder into a bit string. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -pub fn to_bit_string(builder: BitBuilder) -> BitString { - do_to_bit_string(builder) -} - -if erlang { - external fn do_to_bit_string(BitBuilder) -> BitString = - "erlang" "list_to_bitstring" -} - -if javascript { - fn do_to_bit_string(builder: BitBuilder) -> BitString { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_string.concat - } - - fn to_list( - stack: List(List(BitBuilder)), - acc: List(BitString), - ) -> List(BitString) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bits(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_string.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -pub fn byte_size(builder: BitBuilder) -> Int { - do_byte_size(builder) -} - -if erlang { - external fn do_byte_size(BitBuilder) -> Int = - "erlang" "iolist_size" -} - -if javascript { - fn do_byte_size(builder: BitBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_string.byte_size(builder) + acc }) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index 6a67028f16d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,155 +0,0 @@ -//// Working with raw bit string data. -//// The `BitString` type should be used instead of a String type when not utf8 -//// encoded. - -/// Converts a UTF-8 `String` type into a raw `BitString` type. -/// -pub fn from_string(x: String) -> BitString { - do_from_string(x) -} - -if erlang { - external fn do_from_string(String) -> BitString = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from_string(String) -> BitString = - "../gleam_stdlib.mjs" "bit_string_from_string" -} - -/// Returns an integer which is the number of bytes in the bit string. -/// -pub fn byte_size(x: BitString) -> Int { - do_byte_size(x) -} - -if erlang { - external fn do_byte_size(BitString) -> Int = - "erlang" "byte_size" -} - -if javascript { - external fn do_byte_size(BitString) -> Int = - "../gleam_stdlib.mjs" "length" -} - -/// Creates a new bit string by joining two binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitString, suffix second: BitString) -> BitString { - concat([first, second]) -} - -/// Extracts a sub-section of a bit string. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit string. -/// -/// This function runs in constant time. -/// -pub fn slice( - from string: BitString, - at position: Int, - take length: Int, -) -> Result(BitString, Nil) { - do_slice(string, position, length) -} - -if erlang { - external fn do_slice( - string: BitString, - position: Int, - length: Int, - ) -> Result(BitString, Nil) = - "gleam_stdlib" "bit_string_slice" -} - -if javascript { - external fn do_slice( - string: BitString, - position: Int, - length: Int, - ) -> Result(BitString, Nil) = - "../gleam_stdlib.mjs" "bit_string_slice" -} - -/// Tests to see whether a bit string is valid UTF-8. -/// -pub fn is_utf8(bits: BitString) -> Bool { - do_is_utf8(bits) -} - -if erlang { - fn do_is_utf8(bits: BitString) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:binary>> -> do_is_utf8(rest) - _ -> False - } - } -} - -if javascript { - fn do_is_utf8(bits: BitString) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } - } -} - -/// Converts a bit string to a string. -/// -/// Returns an error if the bit string is invalid UTF-8 data. -/// -pub fn to_string(bits: BitString) -> Result(String, Nil) { - do_to_string(bits) -} - -if erlang { - external fn unsafe_to_string(BitString) -> String = - "gleam_stdlib" "identity" - - fn do_to_string(bits: BitString) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } - } -} - -if javascript { - external fn do_to_string(BitString) -> Result(String, Nil) = - "../gleam_stdlib.mjs" "bit_string_to_string" -} - -/// Creates a new bit string by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -pub fn concat(bit_strings: List(BitString)) -> BitString { - do_concat(bit_strings) -} - -if erlang { - external fn do_concat(List(BitString)) -> BitString = - "gleam_stdlib" "bit_string_concat" -} - -if javascript { - external fn do_concat(List(BitString)) -> BitString = - "../gleam_stdlib.mjs" "bit_string_concat" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 66200a8a5b4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,388 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index 86055a003e4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1613 +0,0 @@ -import gleam/int -import gleam/list -import gleam/map.{Map} -import gleam/option.{Option} -import gleam/result -import gleam/string_builder - -if erlang { - import gleam/bit_string -} - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub external type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -if erlang { - external fn do_from(anything) -> Dynamic = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from(anything) -> Dynamic = - "../gleam_stdlib.mjs" "identity" -} - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -if erlang { - external fn do_unsafe_coerce(Dynamic) -> a = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_unsafe_coerce(Dynamic) -> a = - "../gleam_stdlib.mjs" "identity" -} - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit_string, and returns that bit string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_string(from("Hello")) == bit_string.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_string(from(123)) -/// Error([DecodeError(expected: "BitString", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_string(from data: Dynamic) -> Result(BitString, DecodeErrors) { - decode_bit_string(data) -} - -if erlang { - external fn decode_bit_string(Dynamic) -> Result(BitString, DecodeErrors) = - "gleam_stdlib" "decode_bit_string" -} - -if javascript { - external fn decode_bit_string(Dynamic) -> Result(BitString, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_bit_string" -} - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -if erlang { - fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_string(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_string.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitString", path: [])]) - } - }) - } - - fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) - } -} - -if javascript { - external fn decode_string(Dynamic) -> Result(String, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_string" -} - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -if erlang { - external fn do_classify(Dynamic) -> String = - "gleam_stdlib" "classify_dynamic" -} - -if javascript { - external fn do_classify(Dynamic) -> String = - "../gleam_stdlib.mjs" "classify_dynamic" -} - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -if erlang { - external fn decode_int(Dynamic) -> Result(Int, DecodeErrors) = - "gleam_stdlib" "decode_int" -} - -if javascript { - external fn decode_int(Dynamic) -> Result(Int, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_int" -} - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -if erlang { - external fn decode_float(Dynamic) -> Result(Float, DecodeErrors) = - "gleam_stdlib" "decode_float" -} - -if javascript { - external fn decode_float(Dynamic) -> Result(Float, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_float" -} - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -if erlang { - external fn decode_bool(Dynamic) -> Result(Bool, DecodeErrors) = - "gleam_stdlib" "decode_bool" -} - -if javascript { - external fn decode_bool(Dynamic) -> Result(Bool, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_bool" -} - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -if erlang { - external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_list" -} - -if javascript { - external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_list" -} - -if erlang { - external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeErrors) = - "gleam_stdlib" "decode_result" -} - -if javascript { - external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_result" -} - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -if erlang { - external fn decode_optional( - Dynamic, - Decoder(a), - ) -> Result(Option(a), DecodeErrors) = - "gleam_stdlib" "decode_option" -} - -if javascript { - external fn decode_optional( - Dynamic, - Decoder(a), - ) -> Result(Option(a), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_option" -} - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/map -/// > map.new() -/// > |> map.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/map -/// > map.new() -/// > |> map.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/map -/// > map.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -if erlang { - external fn decode_field( - Dynamic, - name, - ) -> Result(Option(Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_field" -} - -if javascript { - external fn decode_field( - Dynamic, - name, - ) -> Result(Option(Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_field" -} - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -external type UnknownTuple - -if erlang { - external fn decode_tuple(Dynamic) -> Result(UnknownTuple, DecodeErrors) = - "gleam_stdlib" "decode_tuple" - - external fn decode_tuple2( - Dynamic, - ) -> Result(#(Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple2" - - external fn decode_tuple3( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple3" - - external fn decode_tuple4( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple4" - - external fn decode_tuple5( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple5" - - external fn decode_tuple6( - Dynamic, - ) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, - ) = - "gleam_stdlib" "decode_tuple6" - - external fn tuple_get(UnknownTuple, Int) -> Result(Dynamic, DecodeErrors) = - "gleam_stdlib" "tuple_get" - - external fn tuple_size(UnknownTuple) -> Int = - "gleam_stdlib" "size_of_tuple" -} - -if javascript { - external fn decode_tuple(Dynamic) -> Result(UnknownTuple, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple" - - external fn decode_tuple2( - Dynamic, - ) -> Result(#(Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple2" - - external fn decode_tuple3( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple3" - - external fn decode_tuple4( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple4" - - external fn decode_tuple5( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple5" - - external fn decode_tuple6( - Dynamic, - ) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, - ) = - "../gleam_stdlib.mjs" "decode_tuple6" - - external fn tuple_get(UnknownTuple, Int) -> Result(Dynamic, DecodeErrors) = - "../gleam_stdlib.mjs" "tuple_get" - - external fn tuple_size(UnknownTuple) -> Int = - "../gleam_stdlib.mjs" "length" -} - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a map. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/map -/// > map.new() |> from |> map(string, int) -/// Ok(map.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Map(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> map.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(map.from_list(pairs)) - } -} - -if erlang { - external fn decode_map(Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_map" -} - -if javascript { - external fn decode_map(Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_map" -} - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.flatten([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.flatten([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 1ee175cf7a2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,589 +0,0 @@ -import gleam/order.{Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -if erlang { - external fn do_parse(String) -> Result(Float, Nil) = - "gleam_stdlib" "parse_float" -} - -if javascript { - external fn do_parse(String) -> Result(Float, Nil) = - "../gleam_stdlib.mjs" "parse_float" -} - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -if erlang { - external fn do_to_string(Float) -> String = - "gleam_stdlib" "float_to_string" -} - -if javascript { - external fn do_to_string(Float) -> String = - "../gleam_stdlib.mjs" "float_to_string" -} - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -if erlang { - external fn do_ceiling(Float) -> Float = - "math" "ceil" -} - -if javascript { - external fn do_ceiling(Float) -> Float = - "../gleam_stdlib.mjs" "ceiling" -} - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -if erlang { - external fn do_floor(Float) -> Float = - "math" "floor" -} - -if javascript { - external fn do_floor(Float) -> Float = - "../gleam_stdlib.mjs" "floor" -} - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -if erlang { - external fn do_round(Float) -> Int = - "erlang" "round" -} - -if javascript { - fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } - } - - external fn js_round(Float) -> Int = - "../gleam_stdlib.mjs" "round" -} - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -if erlang { - external fn do_truncate(Float) -> Int = - "erlang" "trunc" -} - -if javascript { - external fn do_truncate(Float) -> Int = - "../gleam_stdlib.mjs" "truncate" -} - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -if erlang { - external fn do_power(Float, Float) -> Float = - "math" "pow" -} - -if javascript { - external fn do_power(Float, Float) -> Float = - "../gleam_stdlib.mjs" "power" -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Returns `0.0` if `boundary_a` and `boundary_b` are equal, -/// otherwise returns a `Float x` where `lower_boundary =< x < upper_boundary`. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(boundary_a: Float, boundary_b: Float) -> Float { - // Based on: - // - // ```javascript - // return Math.random() * (max - min) + min; // The minimum is inclusive and the maximum is exclusive - // ``` - // - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values> - let #(min, max) = case boundary_a, boundary_b { - a, b if a <=. b -> #(a, b) - a, b if a >. b -> #(b, a) - } - case min, max { - min, _max if min == max -> min - min, max -> do_random_uniform() *. { max -. min } +. min - } -} - -if erlang { - /// Returns a random float uniformly distributed in the value range - /// 0.0 =< X < 1.0 and updates the state in the process dictionary. - /// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> - /// - external fn do_random_uniform() -> Float = - "rand" "uniform" -} - -if javascript { - external fn do_random_uniform() -> Float = - "../gleam_stdlib.mjs" "random_uniform" -} - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index 793a85e71a7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,854 +0,0 @@ -import gleam/float -import gleam/order.{Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -if erlang { - external fn do_parse(String) -> Result(Int, Nil) = - "gleam_stdlib" "parse_int" -} - -if javascript { - external fn do_parse(String) -> Result(Int, Nil) = - "../gleam_stdlib.mjs" "parse_int" -} - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -if erlang { - external fn do_base_parse(String, Int) -> Result(Int, Nil) = - "gleam_stdlib" "int_from_base_string" -} - -if javascript { - external fn do_base_parse(String, Int) -> Result(Int, Nil) = - "../gleam_stdlib.mjs" "int_from_base_string" -} - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -if erlang { - external fn do_to_string(Int) -> String = - "erlang" "integer_to_binary" -} - -if javascript { - external fn do_to_string(Int) -> String = - "../gleam_stdlib.mjs" "to_string" -} - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -if erlang { - external fn do_to_base_string(Int, Int) -> String = - "erlang" "integer_to_binary" -} - -if javascript { - external fn do_to_base_string(Int, Int) -> String = - "../gleam_stdlib.mjs" "int_to_base_string" -} - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -if erlang { - external fn do_to_float(Int) -> Float = - "erlang" "float" -} - -if javascript { - external fn do_to_float(Int) -> Float = - "../gleam_stdlib.mjs" "identity" -} - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Returns `0` if `boundary_a` and `boundary_b` are equal, -/// otherwise returns an `Int x` where `lower_boundary =< x < upper_boundary`. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(boundary_a: Int, boundary_b: Int) -> Int { - // Based on: - // - // ```javascript - // min = Math.ceil(min); - // max = Math.floor(max); - // return Math.floor(Math.random() * (max - min) + min); // The minimum is inclusive and the maximum is exclusive - // ``` - // - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values> - let #(min, max) = case boundary_a, boundary_b { - a, b if a <= b -> #(a, b) - a, b if a > b -> #(b, a) - } - - let min = - to_float(min) - |> float.ceiling() - let max = - to_float(max) - |> float.floor() - - float.random(min, max) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index c8524f15d93..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,147 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -if erlang { - external fn do_print(string: String) -> Nil = - "gleam_stdlib" "print" -} - -if javascript { - external fn do_print(String) -> Nil = - "../gleam_stdlib.mjs" "print" -} - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -if erlang { - external fn do_print_error(string: String) -> Nil = - "gleam_stdlib" "print_error" -} - -if javascript { - external fn do_print_error(String) -> Nil = - "../gleam_stdlib.mjs" "print_error" -} - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -if erlang { - external fn do_println(string: String) -> Nil = - "gleam_stdlib" "println" -} - -if javascript { - external fn do_println(String) -> Nil = - "../gleam_stdlib.mjs" "console_log" -} - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -if erlang { - external fn do_println_error(string: String) -> Nil = - "gleam_stdlib" "println_error" -} - -if javascript { - external fn do_println_error(String) -> Nil = - "../gleam_stdlib.mjs" "console_error" -} - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -if erlang { - external fn do_debug_println(string: String) -> Nil = - "gleam_stdlib" "println_error" -} - -if javascript { - external fn do_debug_println(String) -> Nil = - "../gleam_stdlib.mjs" "print_debug" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index 4e5a752c8a8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1442 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - for predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Map(key, List(element)), element) -> Map(key, List(element)) { - fn(groups, elem) { - groups - |> map.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Map(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// map.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Map(key, List(element)) { - iterator - |> fold(map.new(), group_updater(key)) - |> map.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index 72650163b18..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2075 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{Order} -import gleam/pair -import gleam/map.{Map} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -if erlang { - external fn do_length(List(a)) -> Int = - "erlang" "length" -} - -if javascript { - fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) - } - - fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -if erlang { - external fn do_reverse(List(a)) -> List(a) = - "lists" "reverse" -} - -if javascript { - fn do_reverse(list) { - do_reverse_acc(list, []) - } - - fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Map(key, List(element)), element) -> Map(key, List(element)) { - fn(groups, elem) { - case map.get(groups, f(elem)) { - Ok(existing) -> map.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> map.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> map.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group(from: [1,2,3,4,5], with: fn(i) {fn(i) { i - i / 3 * 3 }}) -/// |> map.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Map(k, List(v)) { - fold(list, map.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), for predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -if erlang { - external fn do_append(List(a), List(a)) -> List(a) = - "lists" "append" -} - -if javascript { - fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) - } - - fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_flatten(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_flatten(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Flattens a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_flatten(lists, []) -} - -/// Maps the list with the given function and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> flatten -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> reverse([stop, ..acc]) - order.Gt -> tail_recursive_range(start - 1, stop, [start, ..acc]) - order.Lt -> tail_recursive_range(start + 1, stop, [start, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> flatten - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> flatten -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> flatten -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> flatten - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - _ -> { - let [elem_pair, ..enumerable] = list - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calcuate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 6f963bceef2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,593 +0,0 @@ -import gleam/option.{Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a map, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a map once. -/// -/// Maps are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub external type Map(key, value) - -/// Determines the number of key-value pairs in the map. -/// This function runs in constant time and does not need to iterate the map. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(map: Map(k, v)) -> Int { - do_size(map) -} - -if erlang { - external fn do_size(Map(k, v)) -> Int = - "maps" "size" -} - -if javascript { - external fn do_size(Map(k, v)) -> Int = - "../gleam_stdlib.mjs" "map_size" -} - -/// Converts the map to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the map. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(map: Map(key, value)) -> List(#(key, value)) { - do_to_list(map) -} - -if erlang { - external fn do_to_list(Map(key, value)) -> List(#(key, value)) = - "maps" "to_list" -} - -if javascript { - external fn do_to_list(Map(key, value)) -> List(#(key, value)) = - "../gleam_stdlib.mjs" "map_to_list" -} - -/// Converts a list of 2-element tuples `#(key, value)` to a map. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the map. -/// -pub fn from_list(list: List(#(k, v))) -> Map(k, v) { - do_from_list(list) -} - -if erlang { - external fn do_from_list(List(#(key, value))) -> Map(key, value) = - "maps" "from_list" -} - -if javascript { - fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Map(k, v), - ) -> Map(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } - } - - fn do_from_list(list: List(#(k, v))) -> Map(k, v) { - fold_list_of_pair(list, new()) - } -} - -/// Determines whether or not a value present in the map for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(map: Map(k, v), key: k) -> Bool { - do_has_key(key, map) -} - -if erlang { - external fn do_has_key(key, Map(key, v)) -> Bool = - "maps" "is_key" -} - -if javascript { - fn do_has_key(key: k, map: Map(k, v)) -> Bool { - get(map, key) != Error(Nil) - } -} - -/// Creates a fresh map that contains no values. -/// -pub fn new() -> Map(key, value) { - do_new() -} - -if erlang { - external fn do_new() -> Map(key, value) = - "maps" "new" -} - -if javascript { - external fn do_new() -> Map(key, value) = - "../gleam_stdlib.mjs" "new_map" -} - -/// Fetches a value from a map for a given key. -/// -/// The map may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Map(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -if erlang { - external fn do_get(Map(key, value), key) -> Result(value, Nil) = - "gleam_stdlib" "map_get" -} - -if javascript { - external fn do_get(Map(key, value), key) -> Result(value, Nil) = - "../gleam_stdlib.mjs" "map_get" -} - -/// Inserts a value into the map with the given key. -/// -/// If the map already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into map: Map(k, v), for key: k, insert value: v) -> Map(k, v) { - do_insert(key, value, map) -} - -if erlang { - external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = - "maps" "put" -} - -if javascript { - external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = - "../gleam_stdlib.mjs" "map_insert" -} - -/// Updates all values in a given map by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in map: Map(k, v), with fun: fn(k, v) -> w) -> Map(k, w) { - do_map_values(fun, map) -} - -if erlang { - external fn do_map_values(fn(key, value) -> b, Map(key, value)) -> Map(key, b) = - "maps" "map" -} - -if javascript { - fn do_map_values(f: fn(key, value) -> b, map: Map(key, value)) -> Map(key, b) { - let f = fn(map, k, v) { insert(map, k, f(k, v)) } - map - |> fold(from: new(), with: f) - } -} - -/// Gets a list of all keys in a given map. -/// -/// Maps are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(map: Map(keys, v)) -> List(keys) { - do_keys(map) -} - -if erlang { - external fn do_keys(Map(keys, v)) -> List(keys) = - "maps" "keys" -} - -if javascript { - fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } - } - - fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } - } - - fn do_keys(map: Map(k, v)) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) - } -} - -/// Gets a list of all values in a given map. -/// -/// Maps are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(map: Map(k, values)) -> List(values) { - do_values(map) -} - -if erlang { - external fn do_values(Map(k, values)) -> List(values) = - "maps" "values" -} - -if javascript { - fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } - } - - fn do_values(map: Map(k, v)) -> List(v) { - let list_of_pairs = - map - |> to_list - do_values_acc(list_of_pairs, []) - } -} - -/// Creates a new map from a given map, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { - do_filter(property, map) -} - -if erlang { - external fn do_filter( - fn(key, value) -> Bool, - Map(key, value), - ) -> Map(key, value) = - "maps" "filter" -} - -if javascript { - fn do_filter( - f: fn(key, value) -> Bool, - map: Map(key, value), - ) -> Map(key, value) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) - } -} - -/// Creates a new map from a given map, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from map: Map(k, v), keeping desired_keys: List(k)) -> Map(k, v) { - do_take(desired_keys, map) -} - -if erlang { - external fn do_take(List(k), Map(k, v)) -> Map(k, v) = - "maps" "with" -} - -if javascript { - fn insert_taken( - map: Map(k, v), - desired_keys: List(k), - acc: Map(k, v), - ) -> Map(k, v) { - let insert = fn(taken, key) { - case get(map, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(map, xs, insert(acc, x)) - } - } - - fn do_take(desired_keys: List(k), map: Map(k, v)) -> Map(k, v) { - insert_taken(map, desired_keys, new()) - } -} - -/// Creates a new map from a pair of given maps by combining their entries. -/// -/// If there are entries with the same keys in both maps the entry from the -/// second map takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into map: Map(k, v), from new_entries: Map(k, v)) -> Map(k, v) { - do_merge(map, new_entries) -} - -if erlang { - external fn do_merge(Map(k, v), Map(k, v)) -> Map(k, v) = - "maps" "merge" -} - -if javascript { - fn insert_pair(map: Map(k, v), pair: #(k, v)) -> Map(k, v) { - insert(map, pair.0, pair.1) - } - - fn fold_inserts(new_entries: List(#(k, v)), map: Map(k, v)) -> Map(k, v) { - case new_entries { - [] -> map - [x, ..xs] -> fold_inserts(xs, insert_pair(map, x)) - } - } - - fn do_merge(map: Map(k, v), new_entries: Map(k, v)) -> Map(k, v) { - new_entries - |> to_list - |> fold_inserts(map) - } -} - -/// Creates a new map from a given map with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from map: Map(k, v), delete key: k) -> Map(k, v) { - do_delete(key, map) -} - -if erlang { - external fn do_delete(k, Map(k, v)) -> Map(k, v) = - "maps" "remove" -} - -if javascript { - external fn do_delete(k, Map(k, v)) -> Map(k, v) = - "../gleam_stdlib.mjs" "map_remove" -} - -/// Creates a new map from a given map with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from map: Map(k, v), drop disallowed_keys: List(k)) -> Map(k, v) { - case disallowed_keys { - [] -> map - [x, ..xs] -> drop(delete(map, x), xs) - } -} - -/// Creates a new map with one entry updated using a given function. -/// -/// If there was not an entry in the map for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let map = from_list([#("a", 0)]) -/// > -/// > update(map, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(map, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in map: Map(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Map(k, v) { - map - |> get(key) - |> option.from_result - |> fun - |> insert(map, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Maps are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let map = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(map, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(map, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over map: Map(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - map - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 979c8c252ef..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,119 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > reverse(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > reverse(Lt) -/// Gt -/// ``` -/// -pub fn reverse(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index f1161cc1b13..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,233 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{Option} - -pub external type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -if erlang { - external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = - "gleam_stdlib" "compile_regex" -} - -if javascript { - external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = - "../gleam_stdlib.mjs" "compile_regex" -} - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -if erlang { - external fn do_check(Regex, String) -> Bool = - "gleam_stdlib" "regex_check" -} - -if javascript { - external fn do_check(Regex, String) -> Bool = - "../gleam_stdlib.mjs" "regex_check" -} - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -if erlang { - external fn do_split(Regex, String) -> List(String) = - "gleam_stdlib" "regex_split" -} - -if javascript { - fn do_split(regex, string) -> List(String) { - js_split(string, regex) - } - - external fn js_split(String, Regex) -> List(String) = - "../gleam_stdlib.mjs" "split" -} - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -if erlang { - external fn do_scan(Regex, String) -> List(Match) = - "gleam_stdlib" "regex_scan" -} - -if javascript { - external fn do_scan(Regex, String) -> List(Match) = - "../gleam_stdlib.mjs" "regex_scan" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index d53b72b690e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,483 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), None, Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index 24409869575..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/map.{Map} -import gleam/result - -if erlang { - // A list is used as the map value as an empty list has the smallest - // representation in Erlang's binary format - type Token = - List(Nil) - - const token = [] -} - -if javascript { - type Token = - Nil - - const token = Nil -} - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Map(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(map.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - map.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: map.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> map.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: map.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - map.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: map.new(), - with: fn(m, k) { map.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - map.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - for property: fn(member) -> Bool, -) -> Set(member) { - Set(map.filter(in: set.map, for: fn(m, _) { property(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(map.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case map.size(first.map) > map.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index b20e7268671..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,1046 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{Iterator} -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/order -import gleam/string_builder.{StringBuilder} - -if erlang { - import gleam/bit_string - import gleam/dynamic.{Dynamic} - import gleam/result -} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -if erlang { - external fn do_length(String) -> Int = - "string" "length" -} - -if javascript { - external fn do_length(String) -> Int = - "../gleam_stdlib.mjs" "string_length" -} - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -if erlang { - fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string - } -} - -if javascript { - fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat - } -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -if erlang { - external fn do_lowercase(String) -> String = - "string" "lowercase" -} - -if javascript { - external fn do_lowercase(String) -> String = - "../gleam_stdlib.mjs" "lowercase" -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -if erlang { - external fn do_uppercase(String) -> String = - "string" "uppercase" -} - -if javascript { - external fn do_uppercase(String) -> String = - "../gleam_stdlib.mjs" "uppercase" -} - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -if erlang { - external fn less_than(String, String) -> Bool = - "gleam_stdlib" "less_than" -} - -if javascript { - external fn less_than(String, String) -> Bool = - "../gleam_stdlib.mjs" "less_than" -} - -/// Takes a substring given a start and end grapheme indexes. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -if erlang { - external fn do_slice(String, Int, Int) -> String = - "string" "slice" -} - -if javascript { - fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat - } -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -pub fn crop(from string: String, before substring: String) -> String { - do_crop(string, substring) -} - -if erlang { - fn do_crop(string: String, substring: String) -> String { - string - |> erl_contains(substring) - |> dynamic.string() - |> result.unwrap(string) - } - - external fn erl_contains(String, String) -> Dynamic = - "string" "find" -} - -if javascript { - external fn do_crop(String, String) -> String = - "../gleam_stdlib.mjs" "crop_string" -} - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -pub fn contains(does haystack: String, contain needle: String) -> Bool { - do_contains(haystack, needle) -} - -if erlang { - fn do_contains(haystack: String, needle: String) -> Bool { - haystack - |> erl_contains(needle) - |> dynamic.bit_string - |> result.is_ok - } -} - -if javascript { - fn do_contains(haystack: String, needle: String) -> Bool { - index_of(haystack, needle) != -1 - } - - external fn index_of(String, String) -> Int = - "../gleam_stdlib.mjs" "index_of" -} - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -if erlang { - external fn do_starts_with(String, String) -> Bool = - "gleam_stdlib" "string_starts_with" -} - -if javascript { - external fn do_starts_with(String, String) -> Bool = - "../gleam_stdlib.mjs" "starts_with" -} - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -if erlang { - external fn do_ends_with(String, String) -> Bool = - "gleam_stdlib" "string_ends_with" -} - -if javascript { - external fn do_ends_with(String, String) -> Bool = - "../gleam_stdlib.mjs" "ends_with" -} - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -if erlang { - external fn erl_split(String, String) -> List(String) = - "string" "split" - - fn do_split_once( - x: String, - substring: String, - ) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } - } -} - -if javascript { - external fn do_split_once( - x: String, - substring: String, - ) -> Result(#(String, String), Nil) = - "../gleam_stdlib.mjs" "split_once" -} - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -if erlang { - fn do_trim(string: String) -> String { - erl_trim(string, Both) - } - - type Direction { - Leading - Trailing - Both - } - - external fn erl_trim(String, Direction) -> String = - "string" "trim" -} - -if javascript { - external fn do_trim(string: String) -> String = - "../gleam_stdlib.mjs" "trim" -} - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -if erlang { - fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) - } -} - -if javascript { - external fn do_trim_left(string: String) -> String = - "../gleam_stdlib.mjs" "trim_left" -} - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -if erlang { - fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) - } -} - -if javascript { - external fn do_trim_right(string: String) -> String = - "../gleam_stdlib.mjs" "trim_right" -} - -/// Splits a non-empty `String` into its head and tail. This lets you -/// pattern match on `String`s exactly as you would with lists. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -if erlang { - external fn do_pop_grapheme(string: String) -> Result(#(String, String), Nil) = - "gleam_stdlib" "string_pop_grapheme" -} - -if javascript { - external fn do_pop_grapheme(string: String) -> Result(#(String, String), Nil) = - "../gleam_stdlib.mjs" "pop_grapheme" -} - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -if erlang { - external fn unsafe_int_to_utf_codepoint(Int) -> UtfCodepoint = - "gleam_stdlib" "identity" -} - -if javascript { - external fn unsafe_int_to_utf_codepoint(Int) -> UtfCodepoint = - "../gleam_stdlib.mjs" "codepoint" -} - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -if erlang { - fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(bit_string.from_string(string), []) - |> list.reverse - } - - fn do_to_utf_codepoints_impl( - bit_string: BitString, - acc: List(UtfCodepoint), - ) -> List(UtfCodepoint) { - case bit_string { - <<first:utf8_codepoint, rest:binary>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - <<>> -> acc - } - } -} - -if javascript { - fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) - } - - external fn string_to_codepoint_integer_list(String) -> List(Int) = - "../gleam_stdlib.mjs" "string_to_codepoint_integer_list" -} - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { - do_from_utf_codepoints(utf_codepoints) -} - -if erlang { - fn do_from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { - let assert Ok(string) = - do_from_utf_codepoints_impl(utf_codepoints, bit_string.from_string("")) - |> bit_string.to_string - string - } - - fn do_from_utf_codepoints_impl( - utf_codepoints: List(UtfCodepoint), - acc: BitString, - ) -> BitString { - case utf_codepoints { - [first, ..rest] -> - do_from_utf_codepoints_impl( - rest, - <<acc:bit_string, first:utf8_codepoint>>, - ) - [] -> acc - } - } -} - -if javascript { - fn do_from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { - utf_codepoint_list_to_string(utf_codepoints) - } - - external fn utf_codepoint_list_to_string(List(UtfCodepoint)) -> String = - "../gleam_stdlib.mjs" "utf_codepoint_list_to_string" -} - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > utf_codepoint_to_int(128013) |> to_utf_codepoint_int -/// 128013 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -if erlang { - external fn do_utf_codepoint_to_int(cp: UtfCodepoint) -> Int = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_utf_codepoint_to_int(cp: UtfCodepoint) -> Int = - "../gleam_stdlib.mjs" "utf_codepoint_to_int" -} - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -if javascript { - external fn do_inspect(term: anything) -> StringBuilder = - "../gleam.mjs" "inspect" -} - -if erlang { - external fn do_inspect(term: anything) -> StringBuilder = - "gleam_stdlib" "inspect" -} - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -pub fn byte_size(string: String) -> Int { - do_byte_size(string) -} - -if javascript { - external fn do_byte_size(String) -> Int = - "../gleam_stdlib.mjs" "byte_size" -} - -if erlang { - external fn do_byte_size(String) -> Int = - "erlang" "byte_size" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 6137910c551..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,356 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub external type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -if erlang { - external fn do_append(StringBuilder, StringBuilder) -> StringBuilder = - "gleam_stdlib" "iodata_append" -} - -if javascript { - external fn do_append(StringBuilder, StringBuilder) -> StringBuilder = - "../gleam_stdlib.mjs" "add" -} - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -if erlang { - external fn do_from_strings(List(String)) -> StringBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from_strings(List(String)) -> StringBuilder = - "../gleam_stdlib.mjs" "join" -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -if erlang { - external fn do_concat(List(StringBuilder)) -> StringBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_concat(List(StringBuilder)) -> StringBuilder = - "../gleam_stdlib.mjs" "join" -} - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -if erlang { - external fn do_from_string(String) -> StringBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from_string(String) -> StringBuilder = - "../gleam_stdlib.mjs" "identity" -} - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -if erlang { - external fn do_to_string(StringBuilder) -> String = - "unicode" "characters_to_binary" -} - -if javascript { - external fn do_to_string(StringBuilder) -> String = - "../gleam_stdlib.mjs" "identity" -} - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -if erlang { - external fn do_byte_size(StringBuilder) -> Int = - "erlang" "iolist_size" -} - -if javascript { - external fn do_byte_size(StringBuilder) -> Int = - "../gleam_stdlib.mjs" "length" -} - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -if erlang { - external fn do_lowercase(StringBuilder) -> StringBuilder = - "string" "lowercase" -} - -if javascript { - external fn do_lowercase(StringBuilder) -> StringBuilder = - "../gleam_stdlib.mjs" "lowercase" -} - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -if erlang { - external fn do_uppercase(StringBuilder) -> StringBuilder = - "string" "uppercase" -} - -if javascript { - external fn do_uppercase(StringBuilder) -> StringBuilder = - "../gleam_stdlib.mjs" "uppercase" -} - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -if erlang { - external fn do_reverse(StringBuilder) -> StringBuilder = - "string" "reverse" -} - -if javascript { - fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings - } - - external fn do_to_graphemes(string: String) -> List(String) = - "../gleam_stdlib.mjs" "graphemes" -} - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -if erlang { - type Direction { - All - } - - external fn erl_split(StringBuilder, String, Direction) -> List(StringBuilder) = - "string" "split" - - fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) - } -} - -if javascript { - external fn do_split( - builder: StringBuilder, - pattern: String, - ) -> List(StringBuilder) = - "../gleam_stdlib.mjs" "split" -} - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -if erlang { - fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, - ) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) - } - - external fn erl_replace( - StringBuilder, - String, - String, - Direction, - ) -> StringBuilder = - "string" "replace" -} - -if javascript { - external fn do_replace(StringBuilder, String, String) -> StringBuilder = - "../gleam_stdlib.mjs" "string_replace" -} - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -if erlang { - external fn do_is_equal(StringBuilder, StringBuilder) -> Bool = - "string" "equal" -} - -if javascript { - external fn do_is_equal(StringBuilder, StringBuilder) -> Bool = - "../gleam_stdlib.mjs" "equal" -} - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -if erlang { - external fn do_is_empty(StringBuilder) -> Bool = - "string" "is_empty" -} - -if javascript { - fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 3fdfc6d5b14..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,476 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/string -import gleam/string_builder.{StringBuilder} - -if javascript { - import gleam/pair - import gleam/regex - import gleam/result -} - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -if erlang { - external fn do_parse(String) -> Result(Uri, Nil) = - "gleam_stdlib" "uri_parse" -} - -if javascript { - fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) - } - - fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) - } - - fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } - } - - fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } - } - - // Split an authority into its userinfo, host and port parts. - fn split_authority( - authority: Option(String), - ) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } - } - - fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) - } - - fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -if erlang { - external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = - "gleam_stdlib" "parse_query" -} - -if javascript { - external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = - "../gleam_stdlib.mjs" "parse_query" -} - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -if erlang { - external fn do_percent_encode(String) -> String = - "gleam_stdlib" "percent_encode" -} - -if javascript { - external fn do_percent_encode(String) -> String = - "../gleam_stdlib.mjs" "percent_encode" -} - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -if erlang { - external fn do_percent_decode(String) -> Result(String, Nil) = - "gleam_stdlib" "percent_decode" -} - -if javascript { - external fn do_percent_decode(String) -> Result(String, Nil) = - "../gleam_stdlib.mjs" "percent_decode" -} - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - None, Some(_), None | None, None, None -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - Uri(scheme: None, host: None, ..) -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65890cc439c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,45 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars]). - --export([encode64/2, url_encode64/2, decode64/1, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - _pipe = encode64(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - Padded = case gleam@bit_string:byte_size( - gleam@bit_string:from_string(Encoded) - ) - rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - decode64(_pipe@2). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 8cc9d3263c3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,63 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars]). - --export([append_builder/2, prepend_builder/2, new/0, concat/1, concat_bit_strings/1, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_string/1, prepend/2, append/2, to_bit_string/1, byte_size/1]). --export_type([bit_builder/0]). - --type bit_builder() :: any(). - --spec append_builder(bit_builder(), bit_builder()) -> bit_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bit_builder(), bit_builder()) -> bit_builder(). -prepend_builder(To, Prefix) -> - append_builder(Prefix, To). - --spec new() -> bit_builder(). -new() -> - gleam_stdlib:identity([]). - --spec concat(list(bit_builder())) -> bit_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> bit_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> bit_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bit_builder(), binary()) -> bit_builder(). -prepend_string(To, Prefix) -> - append_builder(from_string(Prefix), To). - --spec append_string(bit_builder(), binary()) -> bit_builder(). -append_string(To, Suffix) -> - append_builder(To, from_string(Suffix)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bit_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> bit_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bit_builder(), bitstring()) -> bit_builder(). -prepend(To, Prefix) -> - append_builder(from_bit_string(Prefix), To). - --spec append(bit_builder(), bitstring()) -> bit_builder(). -append(To, Suffix) -> - append_builder(To, from_bit_string(Suffix)). - --spec to_bit_string(bit_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bit_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 8896e3b7aed..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,56 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_string/1, byte_size/1, slice/3, concat/1, append/2, is_utf8/1, to_string/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_string_slice(String, Position, Length). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_string_concat(Bit_strings). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - concat([First, Second]). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 260e759517d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,152 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), EIA, fun(() -> EIA)) -> EIA. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 61849a790e0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,794 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars]). - --export([dynamic/1, decode1/2, from/1, unsafe_coerce/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, result/2, any/1, string/1, list/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([decode_error/0, dynamic/0, unknown_tuple/0]). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type dynamic() :: any(). - --type unknown_tuple() :: any(). - --spec dynamic(dynamic()) -> {ok, dynamic()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((CSZ) -> CTA), - fun((dynamic()) -> {ok, CSZ} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTA} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec from(any()) -> dynamic(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec bit_string(dynamic()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_string(Data) -> - gleam_stdlib:decode_bit_string(Data). - --spec classify(dynamic()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec at_least_decode_tuple_error(integer(), dynamic()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec float(dynamic()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic()) -> {ok, list(dynamic())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic()) -> {ok, CPW} | {error, list(decode_error())})) -> fun((dynamic()) -> {ok, - gleam@option:option(CPW)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec result( - fun((dynamic()) -> {ok, CPK} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CPM} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {ok, CPK} | {error, CPM}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec any(list(fun((dynamic()) -> {ok, CSV} | {error, list(decode_error())}))) -> fun((dynamic()) -> {ok, - CSV} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec string(dynamic()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec decode_string(dynamic()) -> {ok, binary()} | {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_string(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_string:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitString"/utf8>>, - []}]} - end end - ). - --spec map_errors( - {ok, COU} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, COU} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec list(fun((dynamic()) -> {ok, CPR} | {error, list(decode_error())})) -> fun((dynamic()) -> {ok, - list(CPR)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec field( - any(), - fun((dynamic()) -> {ok, CQB} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CQB} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic()) -> {ok, CQF} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, gleam@option:option(CQF)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic()) -> {ok, CQJ} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CQJ} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic()) -> {ok, CQV} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CQX} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CQV, CQX}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic()) -> {ok, CRA} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRC} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRE} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CRA, CRC, CRE}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic()) -> {ok, CRH} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRL} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRN} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CRH, CRJ, CRL, CRN}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic()) -> {ok, CRQ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRS} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRU} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRW} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRY} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CRQ, CRS, CRU, CRW, CRY}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic()) -> {ok, CSB} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSF} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSH} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSL} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CSB, CSD, CSF, CSH, CSJ, CSL}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec map( - fun((dynamic()) -> {ok, CSO} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSQ} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, gleam@map:map_(CSO, CSQ)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@map:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@map:from_list(Pairs)} end - ) - end - ) - end. - --spec decode2( - fun((CTD, CTE) -> CTF), - fun((dynamic()) -> {ok, CTD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTE} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTF} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:flatten([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((CTJ, CTK, CTL) -> CTM), - fun((dynamic()) -> {ok, CTJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTK} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTL} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTM} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((CTR, CTS, CTT, CTU) -> CTV), - fun((dynamic()) -> {ok, CTR} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTS} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTT} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTU} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTV} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((CUB, CUC, CUD, CUE, CUF) -> CUG), - fun((dynamic()) -> {ok, CUB} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUC} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUE} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUF} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CUG} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((CUN, CUO, CUP, CUQ, CUR, CUS) -> CUT), - fun((dynamic()) -> {ok, CUN} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUO} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUP} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUQ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUR} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUS} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CUT} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((CVB, CVC, CVD, CVE, CVF, CVG, CVH) -> CVI), - fun((dynamic()) -> {ok, CVB} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVC} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVE} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVF} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVG} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVH} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CVI} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((CVR, CVS, CVT, CVU, CVV, CVW, CVX, CVY) -> CVZ), - fun((dynamic()) -> {ok, CVR} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVS} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVT} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVU} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVV} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVW} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVX} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVY} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CVZ} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((CWJ, CWK, CWL, CWM, CWN, CWO, CWP, CWQ, CWR) -> CWS), - fun((dynamic()) -> {ok, CWJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWK} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWL} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWM} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWN} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWO} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWP} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWQ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWR} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CWS} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index f98da7c1365..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,193 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars]). - --export([compare/2, min/2, max/2, clamp/3, absolute_value/1, loosely_compare/3, loosely_equals/3, negate/1, divide/2, add/2, multiply/2, subtract/2, parse/1, to_string/1, ceiling/1, floor/1, round/1, truncate/1, power/2, square_root/1, random/2, sum/1, product/1]). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= 0.0 of - true -> - X; - - _ -> - 0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - 0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - 0.0 -> 0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > 0.0, - case ((Base < 0.0) andalso Fractional) orelse ((Base =:= 0.0) andalso (Exponent - < 0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec random(float(), float()) -> float(). -random(Boundary_a, Boundary_b) -> - {Min, Max} = case {Boundary_a, Boundary_b} of - {A, B} when A =< B -> - {A, B}; - - {A@1, B@1} when A@1 > B@1 -> - {B@1, A@1} - end, - case {Min, Max} of - {Min@1, _} when Min@1 =:= Max -> - Min@1; - - {Min@2, Max@1} -> - (rand:uniform() * (Max@1 - Min@2)) + Min@2 - end. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index 1b8c6d2168c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((ESR) -> ESS), fun((ESS) -> EST)) -> fun((ESR) -> EST). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((ESU, ESV) -> ESW)) -> fun((ESU) -> fun((ESV) -> ESW)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((ESY, ESZ, ETA) -> ETB)) -> fun((ESY) -> fun((ESZ) -> fun((ETA) -> ETB))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((ETD, ETE, ETF, ETG) -> ETH)) -> fun((ETD) -> fun((ETE) -> fun((ETF) -> fun((ETG) -> ETH)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((ETJ, ETK, ETL, ETM, ETN) -> ETO)) -> fun((ETJ) -> fun((ETK) -> fun((ETL) -> fun((ETM) -> fun((ETN) -> ETO))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((ETQ, ETR, ETS, ETT, ETU, ETV) -> ETW)) -> fun((ETQ) -> fun((ETR) -> fun((ETS) -> fun((ETT) -> fun((ETU) -> fun((ETV) -> ETW)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((ETY, ETZ) -> EUA)) -> fun((ETZ, ETY) -> EUA). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(EUB) -> EUB. -identity(X) -> - X. - --spec constant(EUC) -> fun((any()) -> EUC). -constant(Value) -> - fun(_) -> Value end. - --spec tap(EUE, fun((EUE) -> any())) -> EUE. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((EUG) -> EUH), EUG) -> EUH. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((EUI, EUJ) -> EUK), EUI, EUJ) -> EUK. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((EUL, EUM, EUN) -> EUO), EUL, EUM, EUN) -> EUO. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 4d3c513a1b2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,323 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars]). - --export([absolute_value/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, random/2, sum/1, product/1, digits/2, undigits/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec random(integer(), integer()) -> integer(). -random(Boundary_a, Boundary_b) -> - {Min, Max} = case {Boundary_a, Boundary_b} of - {A, B} when A =< B -> - {A, B}; - - {A@1, B@1} when A@1 > B@1 -> - {B@1, A@1} - end, - Min@1 = begin - _pipe = to_float(Min), - gleam@float:ceiling(_pipe) - end, - Max@1 = begin - _pipe@1 = to_float(Max), - gleam@float:floor(_pipe@1) - end, - _pipe@2 = gleam@float:random(Min@1, Max@1), - _pipe@3 = gleam@float:floor(_pipe@2), - gleam@float:round(_pipe@3). - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 16dced85238..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ECD) -> ECD. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index 82b4ff1ca55..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,707 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars]). - --export([step/1, empty/0, once/1, single/1, first/1, unfold/2, repeatedly/1, repeat/1, from_list/1, range/2, iterate/2, transform/3, fold/3, run/1, to_list/1, reduce/2, last/1, take/2, drop/2, at/2, map/2, group/2, each/2, append/2, flatten/1, flat_map/2, cycle/1, filter/2, find/2, index/1, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, interleave/2, fold_until/3, try_fold/3, length/1]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BMM) :: stop | {continue, BMM, fun(() -> action(BMM))}. - --opaque iterator(BMN) :: {iterator, fun(() -> action(BMN))}. - --type step(BMO, BMP) :: {next, BMO, BMP} | done. - --type chunk(BMQ, BMR) :: {another_by, - list(BMQ), - BMR, - BMQ, - fun(() -> action(BMQ))} | - {last_by, list(BMQ)}. - --type sized_chunk(BMS) :: {another, list(BMS), fun(() -> action(BMS))} | - {last, list(BMS)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec step(iterator(BOL)) -> step(BOL, iterator(BOL)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec update_group_with(BTZ) -> fun((gleam@option:option(list(BTZ))) -> list(BTZ)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> BVB)) -> iterator(BVB). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec single(BVD) -> iterator(BVD). -single(Elem) -> - once(fun() -> Elem end). - --spec first(iterator(BWL)) -> {ok, BWL} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec do_unfold(BMV, fun((BMV) -> step(BMW, BMV))) -> fun(() -> action(BMW)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BNA, fun((BNA) -> step(BNB, BNA))) -> iterator(BNB). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BNF)) -> iterator(BNF). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BNH) -> iterator(BNH). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BNJ)) -> iterator(BNJ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec iterate(BRD, fun((BRD) -> BRD)) -> iterator(BRD). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_transform( - fun(() -> action(BNM)), - BNO, - fun((BNO, BNM) -> step(BNP, BNO)) -) -> fun(() -> action(BNP)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BNT), BNV, fun((BNV, BNT) -> step(BNW, BNV))) -> iterator(BNW). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BOA)), fun((BOC, BOA) -> BOC), BOC) -> BOC. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BOD), BOF, fun((BOF, BOD) -> BOF)) -> BOF. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BOI)) -> list(BOI). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec reduce(iterator(BUR), fun((BUR, BUR) -> BUR)) -> {ok, BUR} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(BUV)) -> {ok, BUV} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec do_take(fun(() -> action(BOQ)), integer()) -> fun(() -> action(BOQ)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BOT), integer()) -> iterator(BOT). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BOW)), integer()) -> action(BOW). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BOZ), integer()) -> iterator(BOZ). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec at(iterator(BWP), integer()) -> {ok, BWP} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_map(fun(() -> action(BPC)), fun((BPC) -> BPE)) -> fun(() -> action(BPE)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BPG), fun((BPG) -> BPI)) -> iterator(BPI). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec group_updater(fun((BUD) -> BUE)) -> fun((gleam@map:map_(BUE, list(BUD)), BUD) -> gleam@map:map_(BUE, list(BUD))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@map:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(BUL), fun((BUL) -> BUN)) -> gleam@map:map_(BUN, list(BUL)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@map:new(), group_updater(Key)), - gleam@map:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec each(iterator(BWX), fun((BWX) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec do_append(fun(() -> action(BPK)), fun(() -> action(BPK))) -> action(BPK). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BPO), iterator(BPO)) -> iterator(BPO). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BPS)))) -> action(BPS). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BPW))) -> iterator(BPW). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec flat_map(iterator(BQA), fun((BQA) -> iterator(BQC))) -> iterator(BQC). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec cycle(iterator(BQL)) -> iterator(BQL). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_filter(fun(() -> action(BQF)), fun((BQF) -> boolean())) -> action(BQF). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BQI), fun((BQI) -> boolean())) -> iterator(BQI). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_find(fun(() -> action(BQP)), fun((BQP) -> boolean())) -> {ok, BQP} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BQT), fun((BQT) -> boolean())) -> {ok, BQT} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BQX)), integer()) -> fun(() -> action({integer(), - BQX})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BRA)) -> iterator({integer(), BRA}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec do_take_while(fun(() -> action(BRF)), fun((BRF) -> boolean())) -> fun(() -> action(BRF)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BRI), fun((BRI) -> boolean())) -> iterator(BRI). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BRL)), fun((BRL) -> boolean())) -> action(BRL). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BRO), fun((BRO) -> boolean())) -> iterator(BRO). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BRR)), fun((BRT, BRR) -> BRT), BRT) -> fun(() -> action(BRT)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BRV), BRX, fun((BRX, BRV) -> BRX)) -> iterator(BRX). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BRZ)), fun(() -> action(BSB))) -> fun(() -> action({BRZ, - BSB})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BSE), iterator(BSG)) -> iterator({BSE, BSG}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BSJ)), fun((BSJ) -> BSL), BSL, list(BSJ)) -> chunk(BSJ, BSL). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BSP)), fun((BSP) -> BSR), BSR, BSP) -> action(list(BSP)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BSU), fun((BSU) -> any())) -> iterator(list(BSU)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BSZ)), integer(), list(BSZ)) -> sized_chunk(BSZ). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BTD)), integer()) -> fun(() -> action(list(BTD))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BTH), integer()) -> iterator(list(BTH)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BTL)), BTL) -> action(BTL). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BTO), BTO) -> iterator(BTO). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BTR)), fun((BTR) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BTT), fun((BTT) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(BTV)), fun((BTV) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(BTX), fun((BTX) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec do_interleave(fun(() -> action(BVF)), fun(() -> action(BVF))) -> action(BVF). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(BVJ), iterator(BVJ)) -> iterator(BVJ). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(BVN)), - fun((BVP, BVN) -> gleam@list:continue_or_stop(BVP)), - BVP -) -> BVP. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(BVR), - BVT, - fun((BVT, BVR) -> gleam@list:continue_or_stop(BVT)) -) -> BVT. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(BVV)), - fun((BVX, BVV) -> {ok, BVX} | {error, BVY}), - BVX -) -> {ok, BVX} | {error, BVY}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(BWD), BWF, fun((BWF, BWD) -> {ok, BWF} | {error, BWG})) -> {ok, - BWF} | - {error, BWG}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index 6d28be2ad8e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1082 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_empty/1, first/1, rest/1, new/0, prepend/2, length/1, reverse/1, append/2, contains/2, map/2, fold/3, group/2, map_fold/3, reduce/2, last/1, filter/2, filter_map/2, index_map/2, try_map/2, drop/2, at/2, take/2, flatten/1, flat_map/2, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, key_find/2, all/2, any/2, zip/2, strict_zip/2, window_by_2/1, unzip/1, intersperse/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, drop_while/2, take_while/2, chunk/2, sized_chunk/2, scan/3, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(SY) :: {continue, SY} | {stop, SY}. - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec first(list(TI)) -> {ok, TI} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(TM)) -> {ok, list(TM)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec new() -> list(any()). -new() -> - []. - --spec prepend(list(XH), XH) -> list(XH). -prepend(List, Item) -> - [Item | List]. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(TB)) -> list(TB). -reverse(Xs) -> - lists:reverse(Xs). - --spec append(list(XD), list(XD)) -> list(XD). -append(First, Second) -> - lists:append(First, Second). - --spec contains(list(TG), TG) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec do_map(list(VB), fun((VB) -> VD), list(VD)) -> list(VD). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(VG), fun((VG) -> VI)) -> list(VI). -map(List, Fun) -> - do_map(List, Fun, []). - --spec update_group(fun((TR) -> TS)) -> fun((gleam@map:map_(TS, list(TR)), TR) -> gleam@map:map_(TS, list(TR))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@map:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@map:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@map:insert(Groups, F(Elem), [Elem]) - end end. - --spec fold(list(YC), YE, fun((YE, YC) -> YE)) -> YE. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(TZ), fun((TZ) -> UB)) -> gleam@map:map_(UB, list(TZ)). -group(List, Key) -> - fold(List, gleam@map:new(), update_group(Key)). - --spec map_fold(list(VK), VM, fun((VM, VK) -> {VM, VN})) -> {VM, list(VN)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec reduce(list(AHZ), fun((AHZ, AHZ) -> AHZ)) -> {ok, AHZ} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec last(list(AIM)) -> {ok, AIM} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec do_filter(list(UF), fun((UF) -> boolean()), list(UF)) -> list(UF). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(UJ), fun((UJ) -> boolean())) -> list(UJ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(UM), fun((UM) -> {ok, UO} | {error, any()}), list(UO)) -> list(UO). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(UU), fun((UU) -> {ok, UW} | {error, any()})) -> list(UW). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_index_map(list(VP), fun((integer(), VP) -> VR), integer(), list(VR)) -> list(VR). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(VU), fun((integer(), VU) -> VW)) -> list(VW). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(VY), fun((VY) -> {ok, WA} | {error, WB}), list(WA)) -> {ok, - list(WA)} | - {error, WB}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(WI), fun((WI) -> {ok, WK} | {error, WL})) -> {ok, list(WK)} | - {error, WL}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(WR), integer()) -> list(WR). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec at(list(ABY), integer()) -> {ok, ABY} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec do_take(list(WU), integer(), list(WU)) -> list(WU). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(WY), integer()) -> list(WY). -take(List, N) -> - do_take(List, N, []). - --spec reverse_and_prepend(list(XK), list(XK)) -> list(XK). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_flatten(list(list(XO)), list(XO)) -> list(XO). -do_flatten(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_flatten(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec flatten(list(list(XT))) -> list(XT). -flatten(Lists) -> - do_flatten(Lists, []). - --spec flat_map(list(XX), fun((XX) -> list(XZ))) -> list(XZ). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - flatten(_pipe). - --spec fold_right(list(YF), YH, fun((YH, YF) -> YH)) -> YH. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold(list(YI), YK, fun((YK, YI, integer()) -> YK), integer()) -> YK. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(YL), YN, fun((YN, YL, integer()) -> YN)) -> YN. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(YO), YQ, fun((YQ, YO) -> {ok, YQ} | {error, YR})) -> {ok, - YQ} | - {error, YR}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(YW), YY, fun((YY, YW) -> continue_or_stop(YY))) -> YY. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AAA), fun((AAA) -> boolean())) -> {ok, AAA} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AAE), fun((AAE) -> {ok, AAG} | {error, any()})) -> {ok, AAG} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec key_find(list({ADV, ADW}), ADV) -> {ok, ADW} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec all(list(AAM), fun((AAM) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AAO), fun((AAO) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AAQ), list(AAS), list({AAQ, AAS})) -> list({AAQ, AAS}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AAW), list(AAY)) -> list({AAW, AAY}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(ABB), list(ABD)) -> {ok, list({ABB, ABD})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec window_by_2(list(AGO)) -> list({AGO, AGO}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec do_unzip(list({ABM, ABN}), list(ABM), list(ABN)) -> {list(ABM), list(ABN)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({ABM, ABN})) -> {list(ABM), list(ABN)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(ABR), ABR, list(ABR)) -> list(ABR). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(ABV), ABV) -> list(ABV). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec unique(list(ACC)) -> list(ACC). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(ACF), - list(ACF), - list(ACF), - fun((ACF, ACF) -> gleam@order:order()) -) -> list(ACF). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end - end. - --spec merge_down( - integer(), - integer(), - list(ACK), - list(ACK), - list(ACK), - fun((ACK, ACK) -> gleam@order:order()) -) -> list(ACK). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end - end. - --spec merge_sort( - list(ACP), - integer(), - fun((ACP, ACP) -> gleam@order:order()), - boolean() -) -> list(ACP). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(ACS), fun((ACS, ACS) -> gleam@order:order())) -> list(ACS). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec do_shuffle_by_pair_indexes(list({float(), AJO})) -> list({float(), AJO}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - reverse([Stop | Acc]); - - gt -> - tail_recursive_range(Start - 1, Stop, [Start | Acc]); - - lt -> - tail_recursive_range(Start + 1, Stop, [Start | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(ACY, integer(), list(ACY)) -> list(ACY). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(ADB, integer()) -> list(ADB). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(ADD), integer(), list(ADD)) -> {list(ADD), list(ADD)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(ADI), integer()) -> {list(ADI), list(ADI)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(ADM), fun((ADM) -> boolean()), list(ADM)) -> {list(ADM), - list(ADM)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(ADR), fun((ADR) -> boolean())) -> {list(ADR), list(ADR)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec do_pop(list(AEE), fun((AEE) -> boolean()), list(AEE)) -> {ok, - {AEE, list(AEE)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AEE), fun((AEE) -> boolean())) -> {ok, {AEE, list(AEE)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(AEN), fun((AEN) -> {ok, AEP} | {error, any()}), list(AEN)) -> {ok, - {AEP, list(AEN)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AEN), fun((AEN) -> {ok, AEP} | {error, any()})) -> {ok, - {AEP, list(AEN)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AEW, AEX}), AEW) -> {ok, {AEX, list({AEW, AEX})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AFC, AFD}), AFC, AFD) -> list({AFC, AFD}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AFG), fun((AFG) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AFJ), fun((AFJ) -> {ok, any()} | {error, AFM})) -> {ok, nil} | - {error, AFM}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(AFW), fun((AFW) -> boolean()), list(AFW), list(AFW)) -> {list(AFW), - list(AFW)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(AFW), fun((AFW) -> boolean())) -> {list(AFW), list(AFW)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(AGA)) -> list(list(AGA)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - flatten(_pipe@5) - end. - --spec do_window(list(list(AGE)), list(AGE), integer()) -> list(list(AGE)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(AGK), integer()) -> list(list(AGK)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec drop_while(list(AGR), fun((AGR) -> boolean())) -> list(AGR). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AGU), fun((AGU) -> boolean()), list(AGU)) -> list(AGU). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AGY), fun((AGY) -> boolean())) -> list(AGY). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AHB), fun((AHB) -> AHD), AHD, list(AHB), list(list(AHB))) -> list(list(AHB)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AHJ), fun((AHJ) -> any())) -> list(list(AHJ)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AHO), - integer(), - integer(), - list(AHO), - list(list(AHO)) -) -> list(list(AHO)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(AHV), integer()) -> list(list(AHV)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec do_scan(list(AID), AIF, list(AIF), fun((AIF, AID) -> AIF)) -> list(AIF). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(AII), AIK, fun((AIK, AII) -> AIK)) -> list(AIK). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec combinations(list(AIQ), integer()) -> list(list(AIQ)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AIU)) -> list(list({AIU, AIU})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AIY)) -> list({AIY, AIY}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - flatten(_pipe). - --spec transpose(list(list(AJF))) -> list(list(AJF)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - flatten(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AJB))) -> list(AJB). -interleave(List) -> - _pipe = transpose(List), - flatten(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AJK}), list(AJK)) -> list(AJK). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - _ -> - [Elem_pair | Enumerable] = List, - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec shuffle(list(AJR)) -> list(AJR). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index a15f5599921..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, update/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, fold/3]). --export_type([map_/2]). - --type map_(Key, Value) :: any() | {gleam_phantom, Key, Value}. - --spec size(map_(any(), any())) -> integer(). -size(Map) -> - maps:size(Map). - --spec to_list(map_(KF, KG)) -> list({KF, KG}). -to_list(Map) -> - maps:to_list(Map). - --spec from_list(list({KK, KL})) -> map_(KK, KL). -from_list(List) -> - maps:from_list(List). - --spec has_key(map_(KP, any()), KP) -> boolean(). -has_key(Map, Key) -> - maps:is_key(Key, Map). - --spec new() -> map_(any(), any()). -new() -> - maps:new(). - --spec get(map_(KX, KY), KX) -> {ok, KY} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(map_(LD, LE), LD, LE) -> map_(LD, LE). -insert(Map, Key, Value) -> - maps:put(Key, Value, Map). - --spec update(map_(NI, NJ), NI, fun((gleam@option:option(NJ)) -> NJ)) -> map_(NI, NJ). -update(Map, Key, Fun) -> - _pipe = Map, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Map, Key, _pipe@3). - --spec map_values(map_(LJ, LK), fun((LJ, LK) -> LN)) -> map_(LJ, LN). -map_values(Map, Fun) -> - maps:map(Fun, Map). - --spec keys(map_(LQ, any())) -> list(LQ). -keys(Map) -> - maps:keys(Map). - --spec values(map_(any(), LW)) -> list(LW). -values(Map) -> - maps:values(Map). - --spec filter(map_(MA, MB), fun((MA, MB) -> boolean())) -> map_(MA, MB). -filter(Map, Property) -> - maps:filter(Property, Map). - --spec take(map_(MG, MH), list(MG)) -> map_(MG, MH). -take(Map, Desired_keys) -> - maps:with(Desired_keys, Map). - --spec merge(map_(MN, MO), map_(MN, MO)) -> map_(MN, MO). -merge(Map, New_entries) -> - maps:merge(Map, New_entries). - --spec delete(map_(MV, MW), MV) -> map_(MV, MW). -delete(Map, Key) -> - maps:remove(Key, Map). - --spec drop(map_(NB, NC), list(NB)) -> map_(NB, NC). -drop(Map, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Map; - - [X | Xs] -> - drop(delete(Map, X), Xs) - end. - --spec do_fold(list({NP, NQ}), NS, fun((NS, NP, NQ) -> NS)) -> NS. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(map_(NT, NU), NX, fun((NX, NT, NU) -> NX)) -> NX. -fold(Map, Initial, Fun) -> - _pipe = Map, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 04e9e354829..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, all/1, values/1]). --export_type([option/1]). - --type option(FI) :: {some, FI} | none. - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(FY), GB) -> {ok, FY} | {error, GB}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, GE} | {error, any()}) -> option(GE). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(GJ), GJ) -> GJ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(GL), fun(() -> GL)) -> GL. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(GN), fun((GN) -> GP)) -> option(GP). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(GR))) -> option(GR). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(GV), fun((GV) -> option(GX))) -> option(GX). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(HA), option(HA)) -> option(HA). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(HE), fun(() -> option(HE))) -> option(HE). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_all(list(option(FJ)), list(FJ)) -> option(list(FJ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(FP))) -> option(list(FP)). -all(List) -> - do_all(List, []). - --spec do_values(list(option(HI)), list(HI)) -> list(HI). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(HN))) -> list(HN). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index 2f7d2e07100..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars]). - --export([reverse/1, to_int/1, compare/2, max/2, min/2]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec reverse(order()) -> order(). -reverse(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2659d329392..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({ET, any()}) -> ET. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), EW}) -> EW. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({EX, EY}) -> {EY, EX}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({EZ, FA}, fun((EZ) -> FB)) -> {FB, FA}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({FC, FD}, fun((FD) -> FE)) -> {FC, FE}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(FF, FG) -> {FF, FG}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index 6738efd4d7e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, reverse/1, pop_back/1, pop_front/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(ECR) :: {queue, list(ECR), list(ECR)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(ECU)) -> queue(ECU). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(ECX)) -> list(ECX). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EDE), EDE) -> queue(EDE). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EDH), EDH) -> queue(EDH). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec reverse(queue(EDU)) -> queue(EDU). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec pop_back(queue(EDK)) -> {ok, {EDK, queue(EDK)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EDP)) -> {ok, {EDP, queue(EDP)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec check_equal( - list(EDX), - list(EDX), - list(EDX), - list(EDX), - fun((EDX, EDX) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EEC), queue(EEC), fun((EEC, EEC) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EEF), queue(EEF)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index f9c649685ee..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([match/0, compile_error/0, options/0, regex/0]). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --type regex() :: any(). - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index e6c72ebab25..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, replace/2, replace_error/2, values/1, try_recover/2, partition/1]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BCT} | {error, BCU}, fun((BCT) -> BCX)) -> {ok, BCX} | - {error, BCU}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BDA} | {error, BDB}, fun((BDB) -> BDE)) -> {ok, BDA} | - {error, BDE}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BDH} | {error, BDI}} | {error, BDI}) -> {ok, BDH} | - {error, BDI}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BDP} | {error, BDQ}, fun((BDP) -> {ok, BDT} | {error, BDQ})) -> {ok, - BDT} | - {error, BDQ}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BDY} | {error, BDZ}, fun((BDY) -> {ok, BEC} | {error, BDZ})) -> {ok, - BEC} | - {error, BDZ}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BEH} | {error, any()}, BEH) -> BEH. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BEL} | {error, any()}, fun(() -> BEL)) -> BEL. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BEQ}, BEQ) -> BEQ. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BET} | {error, BET}) -> BET. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BEW} | {error, any()}) -> {ok, BEW} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BFC} | {error, BFD}, {ok, BFC} | {error, BFD}) -> {ok, BFC} | - {error, BFD}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BFK} | {error, BFL}, fun(() -> {ok, BFK} | {error, BFL})) -> {ok, - BFK} | - {error, BFL}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BFS} | {error, BFT})) -> {ok, list(BFS)} | {error, BFT}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec replace({ok, any()} | {error, BGQ}, BGT) -> {ok, BGT} | {error, BGQ}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BGW} | {error, any()}, BHA) -> {ok, BGW} | {error, BHA}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BHD} | {error, any()})) -> list(BHD). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BHJ} | {error, BHK}, - fun((BHK) -> {ok, BHJ} | {error, BHN}) -) -> {ok, BHJ} | {error, BHN}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. - --spec do_partition(list({ok, BGH} | {error, BGI}), list(BGH), list(BGI)) -> {list(BGH), - list(BGI)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BGA} | {error, BGB})) -> {list(BGA), list(BGB)}. -partition(Results) -> - do_partition(Results, [], []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index bc905e1881e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOC) :: {set, gleam@map:map_(EOC, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@map:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@map:size(erlang:element(2, Set)). - --spec insert(set(EOI), EOI) -> set(EOI). -insert(Set, Member) -> - {set, gleam@map:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOL), EOL) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@map:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EON), EON) -> set(EON). -delete(Set, Member) -> - {set, gleam@map:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOQ)) -> list(EOQ). -to_list(Set) -> - gleam@map:keys(erlang:element(2, Set)). - --spec from_list(list(EOT)) -> set(EOT). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@map:new(), - fun(M, K) -> gleam@map:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EOW), EOY, fun((EOY, EOW) -> EOY)) -> EOY. -fold(Set, Initial, Reducer) -> - gleam@map:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EOZ), fun((EOZ) -> boolean())) -> set(EOZ). -filter(Set, Property) -> - {set, - gleam@map:filter(erlang:element(2, Set), fun(M, _) -> Property(M) end)}. - --spec drop(set(EPC), list(EPC)) -> set(EPC). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPG), list(EPG)) -> set(EPG). -take(Set, Desired) -> - {set, gleam@map:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPK), set(EPK)) -> {set(EPK), set(EPK)}. -order(First, Second) -> - case gleam@map:size(erlang:element(2, First)) > gleam@map:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPP), set(EPP)) -> set(EPP). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EPT), set(EPT)) -> set(EPT). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 275e67ea190..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,393 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_empty/1, reverse/1, replace/3, append/2, concat/1, repeat/2, join/2, to_option/1, length/1, lowercase/1, uppercase/1, compare/2, slice/3, drop_left/2, drop_right/2, pad_left/3, pad_right/3, crop/2, contains/2, starts_with/2, ends_with/2, split_once/2, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, first/1, last/1, capitalise/1, utf_codepoint/1, utf_codepoint_to_int/1, inspect/1, byte_size/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_crop(binary(), binary()) -> binary(). -do_crop(String, Substring) -> - _pipe = String, - _pipe@1 = string:find(_pipe, Substring), - _pipe@2 = gleam@dynamic:string(_pipe@1), - gleam@result:unwrap(_pipe@2, String). - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - do_crop(String, Substring). - --spec do_contains(binary(), binary()) -> boolean(). -do_contains(Haystack, Needle) -> - _pipe = Haystack, - _pipe@1 = string:find(_pipe, Needle), - _pipe@2 = gleam@dynamic:bit_string(_pipe@1), - gleam@result:is_ok(_pipe@2). - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - do_contains(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_string, Acc) -> - case Bit_string of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - <<>> -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(gleam@bit_string:from_string(String), []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec do_from_utf_codepoints_impl(list(integer()), bitstring()) -> bitstring(). -do_from_utf_codepoints_impl(Utf_codepoints, Acc) -> - case Utf_codepoints of - [First | Rest] -> - do_from_utf_codepoints_impl(Rest, <<Acc/bitstring, First/utf8>>); - - [] -> - Acc - end. - --spec do_from_utf_codepoints(list(integer())) -> binary(). -do_from_utf_codepoints(Utf_codepoints) -> - _assert_subject = begin - _pipe = do_from_utf_codepoints_impl( - Utf_codepoints, - gleam@bit_string:from_string(<<""/utf8>>) - ), - gleam@bit_string:to_string(_pipe) - end, - {ok, String} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/string"/utf8>>, - function => <<"do_from_utf_codepoints"/utf8>>, - line => 860}) - end, - String. - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - do_from_utf_codepoints(Utf_codepoints). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 47364425ad7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, join/2, to_string/1, byte_size/1, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([direction/0, string_builder/0]). - --type direction() :: all. - --type string_builder() :: any(). - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index 692193fd0c6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,255 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_string/1, origin/1, parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {none, {some, _}, none} -> - Parts@4; - - {none, none, none} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(EJD)) -> list(EJD). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - {uri, none, _, none, _, _, _, _} -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index ed0fcac3f46..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,28 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.29.2"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index 6967cf4a607..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,441 +0,0 @@ --module(gleam_stdlib). - --export([map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, - decode_field/2, parse_int/1, parse_float/1, less_than/2, - string_pop_grapheme/1, string_starts_with/2, wrap_list/1, - string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_string_int_to_u32/1, bit_string_int_from_u32/1, decode_result/1, - bit_string_slice/3, decode_bit_string/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_string_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, - print/1, println/1, print_error/1, println_error/1, inspect/1, - float_to_string/1, int_from_base_string/2]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitString">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_string(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_string(Data) -> decode_error_msg(<<"BitString">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_string_concat(BitStrings) -> - list_to_bitstring(BitStrings). - -bit_string_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_string_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_string_int_to_u32(_) -> - {error, nil}. - -bit_string_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_string_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:badarith -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(Any) when is_atom(Any) -> - lists:map( - fun(Part) -> - [Head | Tail] = string:next_grapheme(unicode:characters_to_binary(Part)), - [string:uppercase([Head]), Tail] - end, - re:split(erlang:atom_to_list(Any), "_+", [{return, iodata}]) - ); -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - -inspect_list([]) -> - {proper, []}; -inspect_list([Head]) -> - {proper, [inspect(Head)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<Head/utf8, Rest/binary>> -> - Escaped = case Head of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 4fd06d9b563..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,739 +0,0 @@ -import { - BitString, - Error, - List, - Ok, - Result, - UtfCodepoint, - inspect, - stringBits, - toBitString, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import PMap from "./persistent-hash-map.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - return List.fromArray( - Array.from(graphemes_iterator(string)).map((item) => item.segment) - ); -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs) { - return xs.toArray().join(""); -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function index_of(haystack, needle) { - return haystack.indexOf(needle) | 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_string_from_string(string) { - return toBitString([stringBits(string)]); -} - -export function bit_string_concat(bit_strings) { - return toBitString(bit_strings.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_string_to_string(bit_string) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_string.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_string_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitString(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return PMap.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_string) { - const aBytes = bit_string.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitString(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (Result.isResult(data)) { - return "Result"; - } else if (List.isList(data)) { - return "List"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (BitString.isBitString(data)) { - return "BitString"; - } else if (data instanceof PMap) { - return "Map"; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_string(data) { - if (BitString.isBitString(data)) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitString(data)); - } - return decoder_error("BitString", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - let list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!List.isList(data)) return; - - let elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (current.isEmpty()) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && current.isEmpty()) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return List.isList(data) ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return Result.isResult(data) ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof PMap) { - return new Ok(PMap.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(PMap.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof PMap || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs b/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs deleted file mode 100644 index ff849d8def9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of map size and clean up the API - * @template K,V - */ -export default class PMap { - /** - * @template V - * @param {Record<string,V>} o - * @returns {PMap<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type PMap<string,V> */ - let m = PMap.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {PMap<K,V>} - */ - static fromMap(o) { - /** @type PMap<K,V> */ - let m = PMap.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new PMap(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {PMap<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new PMap(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {PMap<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return PMap.new(); - } - return new PMap(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof PMap)) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/README.md b/test-community-packages-javascript/build/packages/gleamy_structures/README.md deleted file mode 100644 index 4d7b812da21..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# gleamy_structures - -[![Package Version](https://img.shields.io/hexpm/v/gleamy_structures)](https://hex.pm/packages/gleamy_structures) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleamy_structures/) - -Data structures in pure Gleam. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gleamy_structures -``` - -and its documentation can be found at <https://hexdocs.pm/gleamy_structures>. - -## Contributions Welcome -Feel free to make PRs, issues, or requests for new data structures and functions :) Especially welcome would be more rigorous tests and reviews of the implementation compared to source materials. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml b/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml deleted file mode 100644 index 270dfb77c9e..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml +++ /dev/null @@ -1,15 +0,0 @@ -name = "gleamy_structures" -version = "0.3.0" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -licences = ["Apache-2.0"] -description = "Data structures in pure Gleam." -repository = { type = "github", user = "schurhammer", repo = "gleamy_structures" } -links = [{ title = "Website", href = "https://github.com/schurhammer/gleamy_structures" }] - -[dependencies] -gleam_stdlib = "~> 0.29.0" - -[dev-dependencies] -gleeunit = "~> 0.10.1" diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl deleted file mode 100644 index 8bebbbf34a9..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(heap, { - root :: gleamy_structures@heap@leftist_heap:t(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl deleted file mode 100644 index e4750eafa6f..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(heap, { - root :: gleamy_structures@heap@pairing_heap:t(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl deleted file mode 100644 index bc5cc269430..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl +++ /dev/null @@ -1 +0,0 @@ --record('end', {first :: any()}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl deleted file mode 100644 index 8b05f955f9c..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(next, { - first :: any(), - rest :: gleamy_structures@non_empty_list:non_empty_list(any()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl deleted file mode 100644 index 680935c5c15..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(tree, { - root :: gleamy_structures@tree@binary_search_tree:node_(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl deleted file mode 100644 index b3310a80c4c..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(tree, { - root :: gleamy_structures@tree@red_black_tree:node_(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl deleted file mode 100644 index 2b57f9253ec..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(tree, { - root :: gleamy_structures@tree@red_black_tree_kv:node_(any(), any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src deleted file mode 100644 index 01611d955eb..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src +++ /dev/null @@ -1,16 +0,0 @@ -{application, gleamy_structures, [ - {vsn, "0.3.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Data structures in pure Gleam."}, - {modules, [gleamy_structures@heap@leftist_heap, - gleamy_structures@heap@pairing_heap, - gleamy_structures@map, - gleamy_structures@non_empty_list, - gleamy_structures@priority_queue, - gleamy_structures@set, - gleamy_structures@tree@binary_search_tree, - gleamy_structures@tree@red_black_tree, - gleamy_structures@tree@red_black_tree_kv]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam deleted file mode 100644 index 7d1b51669a8..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam +++ /dev/null @@ -1,61 +0,0 @@ -// Based on "Purely Functional Data Structures" by Okasaki (1998) - -import gleam/order.{Gt, Order} - -type T(a) { - E - T(Int, a, T(a), T(a)) -} - -pub opaque type Heap(a) { - Heap(root: T(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Heap(a) { - Heap(E, compare) -} - -pub fn insert(heap: Heap(a), item: a) -> Heap(a) { - Heap(merge(T(1, item, E, E), heap.root, heap.compare), heap.compare) -} - -pub fn find_min(heap: Heap(a)) -> Result(a, Nil) { - case heap.root { - T(_, x, _, _) -> Ok(x) - E -> Error(Nil) - } -} - -pub fn delete_min(heap: Heap(a)) -> Result(#(a, Heap(a)), Nil) { - case heap.root { - T(_, x, a, b) -> Ok(#(x, Heap(merge(a, b, heap.compare), heap.compare))) - E -> Error(Nil) - } -} - -fn merge(h1: T(a), h2: T(a), compare: fn(a, a) -> Order) -> T(a) { - case h1, h2 { - h, E -> h - E, h -> h - T(_, x, a1, b1), T(_, y, a2, b2) -> - case compare(x, y) { - Gt -> make(y, a2, merge(h1, b2, compare)) - _ -> make(x, a1, merge(b1, h2, compare)) - } - } -} - -fn make(x, a, b) { - let rank_a = case a { - T(r, _, _, _) -> r - E -> 0 - } - let rank_b = case b { - T(r, _, _, _) -> r - E -> 0 - } - case rank_a < rank_b { - True -> T(rank_a + 1, x, b, a) - _ -> T(rank_b + 1, x, a, b) - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam deleted file mode 100644 index 80f69a31e22..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam +++ /dev/null @@ -1,55 +0,0 @@ -// Based on "Purely Functional Data Structures" by Okasaki (1998) - -import gleam/order.{Gt, Order} - -type T(a) { - E - T(a, List(T(a))) -} - -pub opaque type Heap(a) { - Heap(root: T(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Heap(a) { - Heap(E, compare) -} - -pub fn insert(heap: Heap(a), key: a) -> Heap(a) { - Heap(merge(T(key, []), heap.root, heap.compare), heap.compare) -} - -pub fn find_min(heap: Heap(a)) -> Result(a, Nil) { - case heap.root { - T(x, _) -> Ok(x) - E -> Error(Nil) - } -} - -pub fn delete_min(heap: Heap(a)) -> Result(#(a, Heap(a)), Nil) { - case heap.root { - T(x, xs) -> Ok(#(x, Heap(merge_pairs(xs, heap.compare), heap.compare))) - E -> Error(Nil) - } -} - -fn merge(x: T(a), y: T(a), compare: fn(a, a) -> Order) -> T(a) { - case x, y { - x, E -> x - E, y -> y - T(xk, xs), T(yk, ys) -> - case compare(xk, yk) { - Gt -> T(yk, [x, ..ys]) - _ -> T(xk, [y, ..xs]) - } - } -} - -fn merge_pairs(l: List(T(a)), compare: fn(a, a) -> Order) -> T(a) { - case l { - [] -> E - [h] -> h - [h1, h2, ..hs] -> - merge(merge(h1, h2, compare), merge_pairs(hs, compare), compare) - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam deleted file mode 100644 index a49180e19ee..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam +++ /dev/null @@ -1,85 +0,0 @@ -import gleam/order.{Order} -import gleam/list -import gleamy_structures/tree/red_black_tree_kv as tree - -type Map(k, v) = - tree.Tree(k, v) - -pub fn new(compare: fn(k, k) -> Order) -> Map(k, v) { - tree.new(compare) -} - -pub fn insert(into map: Map(k, v), key key: k, value value: v) -> Map(k, v) { - tree.insert(map, key, value) -} - -pub fn find(in map: Map(k, v), key key: k) -> Result(#(k, v), Nil) { - tree.find(map, key) -} - -pub fn has_key(in map: Map(k, v), key key: k) -> Bool { - case tree.find(map, key) { - Ok(_) -> True - Error(_) -> False - } -} - -pub fn delete(from map: Map(k, v), this key: k) -> Map(k, v) { - tree.delete(map, key) -} - -pub fn count(map: Map(k, v)) -> Int { - tree.fold(map, 0, fn(a, _, _) { a + 1 }) -} - -pub fn fold( - over map: Map(k, v), - from initial: a, - with reducer: fn(a, k, v) -> a, -) -> a { - tree.fold(map, initial, reducer) -} - -pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { - tree.fold( - map, - map, - fn(map, k, v) { - case property(k, v) { - True -> map - False -> tree.delete(map, k) - } - }, - ) -} - -pub fn merge(this first: Map(k, v), and second: Map(k, v)) -> Map(k, v) { - tree.fold(first, second, fn(a, k, v) { tree.insert(a, k, v) }) -} - -// return the map keeping only keys in the list -pub fn take(from map: Map(k, v), keeping desired: List(k)) -> Map(k, v) { - case desired { - [x, ..xs] -> - case tree.find(map, x) { - Ok(x) -> tree.insert(take(map, xs), x.0, x.1) - Error(_) -> take(map, xs) - } - [] -> tree.clear(map) - } -} - -pub fn from_list( - members: List(#(k, v)), - compare: fn(k, k) -> Order, -) -> Map(k, v) { - list.fold( - members, - tree.new(compare), - fn(tree, i) { tree.insert(tree, i.0, i.1) }, - ) -} - -pub fn to_list(map: Map(k, v)) -> List(#(k, v)) { - tree.foldr(map, [], fn(a, k, v) { [#(k, v), ..a] }) -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam deleted file mode 100644 index 0ba26fd70c4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam +++ /dev/null @@ -1,63 +0,0 @@ -import gleam/list - -pub type NonEmptyList(a) { - End(first: a) - Next(first: a, rest: NonEmptyList(a)) -} - -pub fn fold( - over list: NonEmptyList(a), - from initial: b, - with fun: fn(b, a) -> b, -) -> b { - case list { - End(item) -> fun(initial, item) - Next(x, xs) -> fold(xs, fun(initial, x), fun) - } -} - -pub fn count(list: NonEmptyList(a)) -> Int { - fold(list, 0, fn(acc, _) { acc + 1 }) -} - -pub fn map(list: NonEmptyList(a), transform: fn(a) -> b) -> NonEmptyList(b) { - case list { - End(x) -> End(transform(x)) - Next(x, xs) -> - fold(xs, End(transform(x)), fn(acc, item) { Next(transform(item), acc) }) - |> reverse - } -} - -pub fn filter(list: NonEmptyList(a), predicate: fn(a) -> Bool) -> List(a) { - fold( - list, - [], - fn(acc, item) { - case predicate(item) { - True -> [item, ..acc] - False -> acc - } - }, - ) - |> list.reverse() -} - -pub fn to_list(list: NonEmptyList(a)) -> List(a) { - fold(list, [], fn(acc, item) { [item, ..acc] }) - |> list.reverse() -} - -pub fn from_list(list: List(a)) -> Result(NonEmptyList(a), Nil) { - case list { - [] -> Error(Nil) - [x, ..xs] -> Ok(list.fold(xs, End(x), fn(acc, item) { Next(item, acc) })) - } -} - -pub fn reverse(list: NonEmptyList(a)) -> NonEmptyList(a) { - case list { - End(_) -> list - Next(x, xs) -> fold(xs, End(x), fn(acc, x) { Next(x, acc) }) - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam deleted file mode 100644 index 0bf0f8a5cc6..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam +++ /dev/null @@ -1,54 +0,0 @@ -import gleam/order.{Order} -import gleam/list -import gleamy_structures/heap/pairing_heap as heap - -type Queue(a) = - heap.Heap(a) - -pub fn from_list(list: List(a), compare: fn(a, a) -> Order) -> Queue(a) { - list.fold(list, new(compare), heap.insert) -} - -pub fn is_empty(queue: Queue(a)) -> Bool { - case heap.find_min(queue) { - Ok(_) -> False - Error(_) -> True - } -} - -pub fn count(queue: Queue(a)) -> Int { - case heap.delete_min(queue) { - Ok(#(_, q)) -> count(q) + 1 - Error(_) -> 0 - } -} - -pub fn new(compare: fn(a, a) -> Order) -> Queue(a) { - heap.new(compare) -} - -pub fn pop(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - heap.delete_min(queue) -} - -pub fn peek(from queue: Queue(a)) -> Result(a, Nil) { - heap.find_min(queue) -} - -pub fn push(onto queue: Queue(a), this item: a) -> Queue(a) { - heap.insert(queue, item) -} - -pub fn reorder(queue: Queue(a), compare: fn(a, a) -> Order) -> Queue(a) { - case heap.delete_min(queue) { - Ok(#(x, q)) -> heap.insert(reorder(q, compare), x) - Error(_) -> heap.new(compare) - } -} - -pub fn to_list(queue: Queue(a)) -> List(a) { - case heap.delete_min(queue) { - Ok(#(x, q)) -> [x, ..to_list(q)] - Error(_) -> [] - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam deleted file mode 100644 index 0448bfbbb24..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam +++ /dev/null @@ -1,91 +0,0 @@ -import gleam/order.{Order} -import gleam/list -import gleam/io -import gleam/string -import gleamy_structures/tree/red_black_tree as tree - -type Set(a) = - tree.Tree(a) - -pub fn contains(in set: Set(a), this member: a) -> Bool { - case tree.find(set, member) { - Ok(_) -> True - Error(_) -> False - } -} - -pub fn delete(from set: Set(a), this member: a) -> Set(a) { - tree.delete(set, member) -} - -pub fn filter(in set: Set(a), for property: fn(a) -> Bool) -> Set(a) { - tree.fold( - set, - set, - fn(set, i) { - case property(i) { - True -> set - False -> tree.delete(set, i) - } - }, - ) -} - -pub fn fold(over set: Set(a), from initial: b, with reducer: fn(b, a) -> b) -> b { - tree.fold(set, initial, reducer) -} - -pub fn from_list(members: List(a), compare: fn(a, a) -> Order) -> Set(a) { - list.fold(members, tree.new(compare), tree.insert) -} - -pub fn insert(into set: Set(a), this member: a) -> Set(a) { - tree.insert(set, member) -} - -pub fn intersection(of first: Set(a), and second: Set(a)) -> Set(a) { - tree.fold( - second, - tree.clear(first), - fn(a, i) { - case tree.find(first, i) { - Ok(_) -> tree.insert(a, i) - Error(_) -> a - } - }, - ) -} - -pub fn new(compare: fn(a, a) -> Order) -> Set(a) { - tree.new(compare) -} - -pub fn count(set: Set(a)) -> Int { - tree.fold(set, 0, fn(a, _) { a + 1 }) -} - -pub fn take(from set: Set(a), keeping desired: List(a)) -> Set(a) { - case desired { - [x, ..xs] -> - case tree.find(set, x) { - Ok(x) -> tree.insert(take(set, xs), x) - Error(_) -> take(set, xs) - } - [] -> tree.clear(set) - } -} - -pub fn to_list(set: Set(a)) -> List(a) { - tree.foldr( - set, - [], - fn(a, i) { - io.println(string.inspect(i)) - [i, ..a] - }, - ) -} - -pub fn union(of first: Set(a), and second: Set(a)) -> Set(a) { - tree.fold(first, second, fn(a, i) { tree.insert(a, i) }) -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam deleted file mode 100644 index fdae1f6e999..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam +++ /dev/null @@ -1,123 +0,0 @@ -import gleam/order.{Eq, Gt, Lt, Order} - -type Node(a) { - Empty - Node(l: Node(a), k: a, r: Node(a)) -} - -pub opaque type Tree(a) { - Tree(root: Node(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Tree(a) { - Tree(Empty, compare) -} - -pub fn clear(tree: Tree(a)) -> Tree(a) { - Tree(Empty, tree.compare) -} - -pub fn insert(tree: Tree(a), key: a) -> Tree(a) { - Tree(do_insert(tree.root, key, tree.compare), tree.compare) -} - -pub fn delete(tree: Tree(a), key: a) -> Tree(a) { - Tree(do_delete(tree.root, key, tree.compare), tree.compare) -} - -pub fn find(tree: Tree(a), key: a) -> Result(a, Nil) { - do_find(tree.root, key, tree.compare) -} - -pub fn fold(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { - do_fold(tree.root, acc, fun) -} - -pub fn draw(tree: Tree(a), to_string: fn(a) -> String) { - do_draw(tree.root, 0, to_string) -} - -fn do_insert(node, key, compare) { - case node { - Node(l, k, r) -> - case compare(key, k) { - Lt -> Node(do_insert(l, key, compare), k, r) - Gt -> Node(l, k, do_insert(r, key, compare)) - Eq -> Node(l, key, r) - } - Empty -> Node(Empty, key, Empty) - } -} - -fn do_min(node, compare) { - case node { - Node(Node(_, _, _) as l, _, _) -> do_min(l, compare) - Node(Empty, _, _) -> node - Empty -> Empty - } -} - -fn do_delete(node, key, compare) { - case node { - Node(l, k, r) -> - case compare(key, k) { - Lt -> Node(do_delete(l, key, compare), k, r) - Gt -> Node(l, k, do_delete(r, key, compare)) - Eq -> - case node { - Node(Empty, _, r) -> r - Node(l, _, Empty) -> l - Node(l, _, r) -> - case do_min(r, compare) { - Node(_, mk, _) -> Node(l, mk, do_delete(r, mk, compare)) - Empty -> Empty - } - Empty -> Empty - } - } - Empty -> Empty - } -} - -fn do_find(node, key, compare) { - case node { - Node(l, k, r) -> - case compare(key, k) { - Lt -> do_find(l, key, compare) - Gt -> do_find(r, key, compare) - Eq -> Ok(k) - } - Empty -> Error(Nil) - } -} - -fn do_fold(node, acc, fun) { - case node { - Node(r, v, l) -> { - let acc = do_fold(r, acc, fun) - let acc = fun(acc, v) - let acc = do_fold(l, acc, fun) - acc - } - Empty -> acc - } -} - -fn do_indent(acc, i) { - case i { - 0 -> acc - i -> do_indent(". " <> acc, i - 1) - } -} - -fn do_draw(node, indent, to_string) { - case node { - Node(l, k, r) -> { - let ls = do_draw(l, indent + 1, to_string) - let ks = do_indent(to_string(k) <> "\n", indent) - let rs = do_draw(r, indent + 1, to_string) - ls <> ks <> rs - } - Empty -> "" - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam deleted file mode 100644 index 96d9e823b91..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam +++ /dev/null @@ -1,224 +0,0 @@ -// Based on "Deletion: The curse of the red-black tree" by Germane (2014) - -import gleam/order.{Eq, Gt, Lt, Order} - -type Color { - R - B - BB -} - -type Node(a) { - E - EE - T(c: Color, l: Node(a), k: a, r: Node(a)) -} - -pub opaque type Tree(a) { - Tree(root: Node(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Tree(a) { - Tree(E, compare) -} - -pub fn clear(tree: Tree(a)) -> Tree(a) { - Tree(E, tree.compare) -} - -pub fn insert(tree: Tree(a), key: a) -> Tree(a) { - Tree(blacken(ins(tree.root, key, tree.compare)), tree.compare) -} - -pub fn delete(tree: Tree(a), key: a) -> Tree(a) { - Tree(del(redden(tree.root), key, tree.compare), tree.compare) -} - -pub fn find(tree: Tree(a), key: a) -> Result(a, Nil) { - do_find(tree.root, key, tree.compare) -} - -pub fn fold(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { - do_fold(tree.root, acc, fun) -} - -pub fn foldr(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { - do_foldr(tree.root, acc, fun) -} - -pub fn draw(tree: Tree(a), to_string: fn(a) -> String) { - do_draw(tree.root, 0, to_string) -} - -fn ins(node, x, compare) { - case node { - E -> T(R, E, x, E) - T(c, a, y, b) -> - case compare(x, y) { - Lt -> balance(c, ins(a, x, compare), y, b) - Gt -> balance(c, a, y, ins(b, x, compare)) - Eq -> T(c, a, x, b) - } - _ -> node - } -} - -fn blacken(node: Node(a)) -> Node(a) { - case node { - T(R, T(R, _, _, _) as l, y, c) -> T(B, l, y, c) - T(R, a, x, T(R, _, _, _) as r) -> T(B, a, x, r) - t -> t - } -} - -fn balance(c: Color, l: Node(a), v: a, r: Node(a)) -> Node(a) { - case c, l, v, r { - B, T(R, T(R, a, x, b), y, c), z, d -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - B, T(R, a, x, T(R, b, y, c)), z, d -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - B, a, x, T(R, T(R, b, y, c), z, d) -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - B, a, x, T(R, b, y, T(R, c, z, d)) -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - BB, a, x, T(R, T(R, b, y, c), z, d) -> T(B, T(B, a, x, b), y, T(B, c, z, d)) - BB, T(R, a, x, T(R, b, y, c)), z, d -> T(B, T(B, a, x, b), y, T(B, c, z, d)) - c, a, x, b -> T(c, a, x, b) - } -} - -fn redden(node: Node(a)) -> Node(a) { - case node { - T(B, T(B, _, _, _) as l, y, T(B, _, _, _) as r) -> T(R, l, y, r) - t -> t - } -} - -fn del(node, x, compare) { - case node { - E -> node - T(R, E, y, E) -> - case compare(x, y) { - Eq -> E - _ -> node - } - T(B, E, y, E) -> - case compare(x, y) { - Eq -> EE - _ -> node - } - T(B, T(R, E, y, E) as l, z, E) -> - case compare(x, z) { - Lt -> T(B, del(l, x, compare), z, E) - Gt -> node - Eq -> T(B, E, y, E) - } - T(c, a, y, b) -> - case compare(x, y) { - Lt -> rotate(c, del(a, x, compare), y, b) - Gt -> rotate(c, a, y, del(b, x, compare)) - Eq -> - case min_del(b) { - Min(y1, b1) -> rotate(c, a, y1, b1) - None -> E - } - } - _ -> node - } -} - -fn rotate(c: Color, l: Node(a), v: a, r: Node(a)) -> Node(a) { - case c, l, v, r { - R, T(BB, a, x, b), y, T(B, c, z, d) -> - balance(B, T(R, T(B, a, x, b), y, c), z, d) - R, EE, y, T(B, c, z, d) -> balance(B, T(R, E, y, c), z, d) - R, T(B, a, x, b), y, T(BB, c, z, d) -> - balance(B, a, x, T(R, b, y, T(B, c, z, d))) - R, T(B, a, x, b), y, EE -> balance(B, a, x, T(R, b, y, E)) - B, T(BB, a, x, b), y, T(B, c, z, d) -> - balance(BB, T(R, T(B, a, x, b), y, c), z, d) - B, EE, y, T(B, c, z, d) -> balance(BB, T(R, E, y, c), z, d) - B, T(B, a, x, b), y, T(BB, c, z, d) -> - balance(BB, a, x, T(R, b, y, T(B, c, z, d))) - B, T(B, a, x, b), y, EE -> balance(BB, a, x, T(R, b, y, E)) - B, T(BB, a, w, b), x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, T(B, a, w, b), x, c), y, d), z, e) - B, EE, x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, E, x, c), y, d), z, e) - B, T(R, a, w, T(B, b, x, c)), y, T(BB, d, z, e) -> - T(B, a, w, balance(B, b, x, T(R, c, y, T(B, d, z, e)))) - B, T(R, a, w, T(B, b, x, c)), y, EE -> - T(B, a, w, balance(B, b, x, T(R, c, y, E))) - c, a, x, b -> T(c, a, x, b) - } -} - -type MinDel(a) { - Min(a, Node(a)) - None -} - -fn min_del(node) -> MinDel(a) { - case node { - T(R, E, x, E) -> Min(x, E) - T(B, E, x, E) -> Min(x, EE) - T(B, E, x, T(R, E, y, E)) -> Min(x, T(B, E, y, E)) - T(c, a, x, b) -> - case min_del(a) { - Min(x1, a1) -> Min(x1, rotate(c, a1, x, b)) - None -> None - } - _ -> None - } -} - -fn do_find(node, key, compare) { - case node { - T(_, l, k, r) -> - case compare(key, k) { - Lt -> do_find(l, key, compare) - Gt -> do_find(r, key, compare) - Eq -> Ok(k) - } - _ -> Error(Nil) - } -} - -fn do_fold(node, acc, fun) { - case node { - T(_, r, v, l) -> { - let acc = do_fold(r, acc, fun) - let acc = fun(acc, v) - let acc = do_fold(l, acc, fun) - acc - } - _ -> acc - } -} - -fn do_foldr(node, acc, fun) { - case node { - T(_, r, v, l) -> { - let acc = do_foldr(l, acc, fun) - let acc = fun(acc, v) - let acc = do_foldr(r, acc, fun) - acc - } - _ -> acc - } -} - -fn do_indent(acc, i) { - case i { - 0 -> acc - i -> do_indent(". " <> acc, i - 1) - } -} - -fn do_draw(node, indent, to_string) { - case node { - T(_, l, k, r) -> { - let ls = do_draw(l, indent + 1, to_string) - let ks = do_indent(to_string(k) <> "\n", indent) - let rs = do_draw(r, indent + 1, to_string) - ls <> ks <> rs - } - _ -> "" - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam deleted file mode 100644 index 9a61ae14b11..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam +++ /dev/null @@ -1,232 +0,0 @@ -// Based on "Deletion: The curse of the red-black tree" by Germane (2014) - -import gleam/order.{Eq, Gt, Lt, Order} - -type Color { - R - B - BB -} - -type Node(k, v) { - E - EE - T(c: Color, l: Node(k, v), k: #(k, v), r: Node(k, v)) -} - -pub opaque type Tree(k, v) { - Tree(root: Node(k, v), compare: fn(k, k) -> Order) -} - -pub fn new(compare: fn(k, k) -> Order) -> Tree(k, v) { - Tree(E, compare) -} - -pub fn clear(tree: Tree(k, v)) -> Tree(k, v) { - Tree(E, tree.compare) -} - -pub fn insert(tree: Tree(k, v), key: k, value: v) -> Tree(k, v) { - Tree(blacken(ins(tree.root, #(key, value), tree.compare)), tree.compare) -} - -pub fn delete(tree: Tree(k, v), key: k) -> Tree(k, v) { - Tree(del(redden(tree.root), key, tree.compare), tree.compare) -} - -pub fn find(tree: Tree(k, v), key: k) -> Result(#(k, v), Nil) { - do_find(tree.root, key, tree.compare) -} - -pub fn fold(tree: Tree(k, v), acc: b, fun: fn(b, k, v) -> b) -> b { - do_fold(tree.root, acc, fun) -} - -pub fn foldr(tree: Tree(k, v), acc: b, fun: fn(b, k, v) -> b) -> b { - do_foldr(tree.root, acc, fun) -} - -pub fn draw(tree: Tree(k, v), to_string: fn(k, v) -> String) -> String { - do_draw(tree.root, 0, to_string) -} - -fn ins(node: Node(k, v), x: #(k, v), compare: fn(k, k) -> Order) -> Node(k, v) { - case node { - E -> T(R, E, x, E) - T(c, k, y, b) -> - case compare(x.0, y.0) { - Lt -> balance(c, ins(k, x, compare), y, b) - Gt -> balance(c, k, y, ins(b, x, compare)) - Eq -> T(c, k, x, b) - } - _ -> node - } -} - -fn blacken(node: Node(k, v)) -> Node(k, v) { - case node { - T(R, T(R, _, _, _) as l, y, c) -> T(B, l, y, c) - T(R, k, x, T(R, _, _, _) as r) -> T(B, k, x, r) - t -> t - } -} - -fn balance(c: Color, l: Node(k, v), v: #(k, v), r: Node(k, v)) -> Node(k, v) { - case c, l, v, r { - B, T(R, T(R, k, x, b), y, c), z, d -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - B, T(R, k, x, T(R, b, y, c)), z, d -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - B, k, x, T(R, T(R, b, y, c), z, d) -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - B, k, x, T(R, b, y, T(R, c, z, d)) -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - BB, k, x, T(R, T(R, b, y, c), z, d) -> T(B, T(B, k, x, b), y, T(B, c, z, d)) - BB, T(R, k, x, T(R, b, y, c)), z, d -> T(B, T(B, k, x, b), y, T(B, c, z, d)) - c, k, x, b -> T(c, k, x, b) - } -} - -fn redden(node: Node(k, v)) -> Node(k, v) { - case node { - T(B, T(B, _, _, _) as l, y, T(B, _, _, _) as r) -> T(R, l, y, r) - t -> t - } -} - -fn del(node: Node(k, v), x: k, compare: fn(k, k) -> Order) -> Node(k, v) { - case node { - E -> node - T(R, E, y, E) -> - case compare(x, y.0) { - Eq -> E - _ -> node - } - T(B, E, y, E) -> - case compare(x, y.0) { - Eq -> EE - _ -> node - } - T(B, T(R, E, y, E) as l, z, E) -> - case compare(x, z.0) { - Lt -> T(B, del(l, x, compare), z, E) - Gt -> node - Eq -> T(B, E, y, E) - } - T(c, k, y, b) -> - case compare(x, y.0) { - Lt -> rotate(c, del(k, x, compare), y, b) - Gt -> rotate(c, k, y, del(b, x, compare)) - Eq -> - case min_del(b) { - Min(y1, b1) -> rotate(c, k, y1, b1) - None -> E - } - } - _ -> node - } -} - -fn rotate(c: Color, l: Node(k, v), v: #(k, v), r: Node(k, v)) -> Node(k, v) { - case c, l, v, r { - R, T(BB, k, x, b), y, T(B, c, z, d) -> - balance(B, T(R, T(B, k, x, b), y, c), z, d) - R, EE, y, T(B, c, z, d) -> balance(B, T(R, E, y, c), z, d) - R, T(B, k, x, b), y, T(BB, c, z, d) -> - balance(B, k, x, T(R, b, y, T(B, c, z, d))) - R, T(B, k, x, b), y, EE -> balance(B, k, x, T(R, b, y, E)) - B, T(BB, k, x, b), y, T(B, c, z, d) -> - balance(BB, T(R, T(B, k, x, b), y, c), z, d) - B, EE, y, T(B, c, z, d) -> balance(BB, T(R, E, y, c), z, d) - B, T(B, k, x, b), y, T(BB, c, z, d) -> - balance(BB, k, x, T(R, b, y, T(B, c, z, d))) - B, T(B, k, x, b), y, EE -> balance(BB, k, x, T(R, b, y, E)) - B, T(BB, k, w, b), x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, T(B, k, w, b), x, c), y, d), z, e) - B, EE, x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, E, x, c), y, d), z, e) - B, T(R, k, w, T(B, b, x, c)), y, T(BB, d, z, e) -> - T(B, k, w, balance(B, b, x, T(R, c, y, T(B, d, z, e)))) - B, T(R, k, w, T(B, b, x, c)), y, EE -> - T(B, k, w, balance(B, b, x, T(R, c, y, E))) - c, k, x, b -> T(c, k, x, b) - } -} - -type MinDel(k, v) { - Min(#(k, v), Node(k, v)) - None -} - -fn min_del(node: Node(k, v)) -> MinDel(k, v) { - case node { - T(R, E, x, E) -> Min(x, E) - T(B, E, x, E) -> Min(x, EE) - T(B, E, x, T(R, E, y, E)) -> Min(x, T(B, E, y, E)) - T(c, k, x, b) -> - case min_del(k) { - Min(x1, a1) -> Min(x1, rotate(c, a1, x, b)) - None -> None - } - _ -> None - } -} - -fn do_find( - node: Node(k, v), - key: k, - compare: fn(k, k) -> Order, -) -> Result(#(k, v), Nil) { - case node { - T(_, l, k, r) -> - case compare(key, k.0) { - Lt -> do_find(l, key, compare) - Gt -> do_find(r, key, compare) - Eq -> Ok(k) - } - _ -> Error(Nil) - } -} - -fn do_fold(node: Node(k, v), acc: a, fun: fn(a, k, v) -> a) -> a { - case node { - T(_, r, v, l) -> { - let acc = do_fold(r, acc, fun) - let acc = fun(acc, v.0, v.1) - let acc = do_fold(l, acc, fun) - acc - } - _ -> acc - } -} - -fn do_foldr(node: Node(k, v), acc: a, fun: fn(a, k, v) -> a) -> a { - case node { - T(_, r, v, l) -> { - let acc = do_foldr(l, acc, fun) - let acc = fun(acc, v.0, v.1) - let acc = do_foldr(r, acc, fun) - acc - } - _ -> acc - } -} - -fn do_indent(acc: String, i: Int) -> String { - case i { - 0 -> acc - i -> do_indent(". " <> acc, i - 1) - } -} - -fn do_draw( - node: Node(k, v), - indent: Int, - to_string: fn(k, v) -> String, -) -> String { - case node { - T(_, l, k, r) -> { - let ls = do_draw(l, indent + 1, to_string) - let ks = do_indent(to_string(k.0, k.1) <> "\n", indent) - let rs = do_draw(r, indent + 1, to_string) - ls <> ks <> rs - } - _ -> "" - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl deleted file mode 100644 index 5f24df08bcb..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(gleamy_structures@heap@leftist_heap). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, find_min/1, insert/2, delete_min/1]). --export_type([t/1, heap/1]). - --type t(FXL) :: e | {t, integer(), FXL, t(FXL), t(FXL)}. - --opaque heap(FXM) :: {heap, t(FXM), fun((FXM, FXM) -> gleam@order:order())}. - --spec new(fun((FXN, FXN) -> gleam@order:order())) -> heap(FXN). -new(Compare) -> - {heap, e, Compare}. - --spec find_min(heap(FXS)) -> {ok, FXS} | {error, nil}. -find_min(Heap) -> - case erlang:element(2, Heap) of - {t, _, X, _, _} -> - {ok, X}; - - e -> - {error, nil} - end. - --spec make(FYX, t(FYX), t(FYX)) -> t(FYX). -make(X, A, B) -> - Rank_a = case A of - {t, R, _, _, _} -> - R; - - e -> - 0 - end, - Rank_b = case B of - {t, R@1, _, _, _} -> - R@1; - - e -> - 0 - end, - case Rank_a < Rank_b of - true -> - {t, Rank_a + 1, X, B, A}; - - _ -> - {t, Rank_b + 1, X, A, B} - end. - --spec merge(t(FYB), t(FYB), fun((FYB, FYB) -> gleam@order:order())) -> t(FYB). -merge(H1, H2, Compare) -> - case {H1, H2} of - {H, e} -> - H; - - {e, H@1} -> - H@1; - - {{t, _, X, A1, B1}, {t, _, Y, A2, B2}} -> - case Compare(X, Y) of - gt -> - make(Y, A2, merge(H1, B2, Compare)); - - _ -> - make(X, A1, merge(B1, H2, Compare)) - end - end. - --spec insert(heap(FXP), FXP) -> heap(FXP). -insert(Heap, Item) -> - {heap, - merge( - {t, 1, Item, e, e}, - erlang:element(2, Heap), - erlang:element(3, Heap) - ), - erlang:element(3, Heap)}. - --spec delete_min(heap(FXW)) -> {ok, {FXW, heap(FXW)}} | {error, nil}. -delete_min(Heap) -> - case erlang:element(2, Heap) of - {t, _, X, A, B} -> - {ok, - {X, - {heap, - merge(A, B, erlang:element(3, Heap)), - erlang:element(3, Heap)}}}; - - e -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl deleted file mode 100644 index 8677af51636..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(gleamy_structures@heap@pairing_heap). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, find_min/1, insert/2, delete_min/1]). --export_type([t/1, heap/1]). - --type t(EWV) :: e | {t, EWV, list(t(EWV))}. - --opaque heap(EWW) :: {heap, t(EWW), fun((EWW, EWW) -> gleam@order:order())}. - --spec new(fun((EWX, EWX) -> gleam@order:order())) -> heap(EWX). -new(Compare) -> - {heap, e, Compare}. - --spec find_min(heap(EXC)) -> {ok, EXC} | {error, nil}. -find_min(Heap) -> - case erlang:element(2, Heap) of - {t, X, _} -> - {ok, X}; - - e -> - {error, nil} - end. - --spec merge(t(EXL), t(EXL), fun((EXL, EXL) -> gleam@order:order())) -> t(EXL). -merge(X, Y, Compare) -> - case {X, Y} of - {X@1, e} -> - X@1; - - {e, Y@1} -> - Y@1; - - {{t, Xk, Xs}, {t, Yk, Ys}} -> - case Compare(Xk, Yk) of - gt -> - {t, Yk, [X | Ys]}; - - _ -> - {t, Xk, [Y | Xs]} - end - end. - --spec insert(heap(EWZ), EWZ) -> heap(EWZ). -insert(Heap, Key) -> - {heap, - merge({t, Key, []}, erlang:element(2, Heap), erlang:element(3, Heap)), - erlang:element(3, Heap)}. - --spec merge_pairs(list(t(EXP)), fun((EXP, EXP) -> gleam@order:order())) -> t(EXP). -merge_pairs(L, Compare) -> - case L of - [] -> - e; - - [H] -> - H; - - [H1, H2 | Hs] -> - merge(merge(H1, H2, Compare), merge_pairs(Hs, Compare), Compare) - end. - --spec delete_min(heap(EXG)) -> {ok, {EXG, heap(EXG)}} | {error, nil}. -delete_min(Heap) -> - case erlang:element(2, Heap) of - {t, X, Xs} -> - {ok, - {X, - {heap, - merge_pairs(Xs, erlang:element(3, Heap)), - erlang:element(3, Heap)}}}; - - e -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl deleted file mode 100644 index 9a5dd176288..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleamy_structures@map). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, insert/3, find/2, has_key/2, delete/2, count/1, fold/3, filter/2, merge/2, from_list/2, to_list/1, take/2]). - --spec new(fun((GVO, GVO) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree_kv:tree(GVO, any()). -new(Compare) -> - gleamy_structures@tree@red_black_tree_kv:new(Compare). - --spec insert(gleamy_structures@tree@red_black_tree_kv:tree(GVS, GVT), GVS, GVT) -> gleamy_structures@tree@red_black_tree_kv:tree(GVS, GVT). -insert(Map, Key, Value) -> - gleamy_structures@tree@red_black_tree_kv:insert(Map, Key, Value). - --spec find(gleamy_structures@tree@red_black_tree_kv:tree(GVY, GVZ), GVY) -> {ok, - {GVY, GVZ}} | - {error, nil}. -find(Map, Key) -> - gleamy_structures@tree@red_black_tree_kv:find(Map, Key). - --spec has_key(gleamy_structures@tree@red_black_tree_kv:tree(GWE, any()), GWE) -> boolean(). -has_key(Map, Key) -> - case gleamy_structures@tree@red_black_tree_kv:find(Map, Key) of - {ok, _} -> - true; - - {error, _} -> - false - end. - --spec delete(gleamy_structures@tree@red_black_tree_kv:tree(GWI, GWJ), GWI) -> gleamy_structures@tree@red_black_tree_kv:tree(GWI, GWJ). -delete(Map, Key) -> - gleamy_structures@tree@red_black_tree_kv:delete(Map, Key). - --spec count(gleamy_structures@tree@red_black_tree_kv:tree(any(), any())) -> integer(). -count(Map) -> - gleamy_structures@tree@red_black_tree_kv:fold( - Map, - 0, - fun(A, _, _) -> A + 1 end - ). - --spec fold( - gleamy_structures@tree@red_black_tree_kv:tree(GWS, GWT), - GWW, - fun((GWW, GWS, GWT) -> GWW) -) -> GWW. -fold(Map, Initial, Reducer) -> - gleamy_structures@tree@red_black_tree_kv:fold(Map, Initial, Reducer). - --spec filter( - gleamy_structures@tree@red_black_tree_kv:tree(GWX, GWY), - fun((GWX, GWY) -> boolean()) -) -> gleamy_structures@tree@red_black_tree_kv:tree(GWX, GWY). -filter(Map, Property) -> - gleamy_structures@tree@red_black_tree_kv:fold( - Map, - Map, - fun(Map@1, K, V) -> case Property(K, V) of - true -> - Map@1; - - false -> - gleamy_structures@tree@red_black_tree_kv:delete(Map@1, K) - end end - ). - --spec merge( - gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE), - gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE) -) -> gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE). -merge(First, Second) -> - gleamy_structures@tree@red_black_tree_kv:fold( - First, - Second, - fun(A, K, V) -> - gleamy_structures@tree@red_black_tree_kv:insert(A, K, V) - end - ). - --spec from_list(list({GXS, GXT}), fun((GXS, GXS) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree_kv:tree(GXS, GXT). -from_list(Members, Compare) -> - gleam@list:fold( - Members, - gleamy_structures@tree@red_black_tree_kv:new(Compare), - fun(Tree, I) -> - gleamy_structures@tree@red_black_tree_kv:insert( - Tree, - erlang:element(1, I), - erlang:element(2, I) - ) - end - ). - --spec to_list(gleamy_structures@tree@red_black_tree_kv:tree(GXX, GXY)) -> list({GXX, - GXY}). -to_list(Map) -> - gleamy_structures@tree@red_black_tree_kv:foldr( - Map, - [], - fun(A, K, V) -> [{K, V} | A] end - ). - --spec take(gleamy_structures@tree@red_black_tree_kv:tree(GXL, GXM), list(GXL)) -> gleamy_structures@tree@red_black_tree_kv:tree(GXL, GXM). -take(Map, Desired) -> - case Desired of - [X | Xs] -> - case gleamy_structures@tree@red_black_tree_kv:find(Map, X) of - {ok, X@1} -> - gleamy_structures@tree@red_black_tree_kv:insert( - take(Map, Xs), - erlang:element(1, X@1), - erlang:element(2, X@1) - ); - - {error, _} -> - take(Map, Xs) - end; - - [] -> - gleamy_structures@tree@red_black_tree_kv:clear(Map) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl deleted file mode 100644 index 838f1d99840..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl +++ /dev/null @@ -1,77 +0,0 @@ --module(gleamy_structures@non_empty_list). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_list/1, fold/3, count/1, filter/2, to_list/1, reverse/1, map/2]). --export_type([non_empty_list/1]). - --type non_empty_list(HAU) :: {'end', HAU} | {next, HAU, non_empty_list(HAU)}. - --spec from_list(list(HBK)) -> {ok, non_empty_list(HBK)} | {error, nil}. -from_list(List) -> - case List of - [] -> - {error, nil}; - - [X | Xs] -> - {ok, - gleam@list:fold( - Xs, - {'end', X}, - fun(Acc, Item) -> {next, Item, Acc} end - )} - end. - --spec fold(non_empty_list(HAV), HAX, fun((HAX, HAV) -> HAX)) -> HAX. -fold(List, Initial, Fun) -> - case List of - {'end', Item} -> - Fun(Initial, Item); - - {next, X, Xs} -> - fold(Xs, Fun(Initial, X), Fun) - end. - --spec count(non_empty_list(any())) -> integer(). -count(List) -> - fold(List, 0, fun(Acc, _) -> Acc + 1 end). - --spec filter(non_empty_list(HBE), fun((HBE) -> boolean())) -> list(HBE). -filter(List, Predicate) -> - _pipe = fold(List, [], fun(Acc, Item) -> case Predicate(Item) of - true -> - [Item | Acc]; - - false -> - Acc - end end), - gleam@list:reverse(_pipe). - --spec to_list(non_empty_list(HBH)) -> list(HBH). -to_list(List) -> - _pipe = fold(List, [], fun(Acc, Item) -> [Item | Acc] end), - gleam@list:reverse(_pipe). - --spec reverse(non_empty_list(HBP)) -> non_empty_list(HBP). -reverse(List) -> - case List of - {'end', _} -> - List; - - {next, X, Xs} -> - fold(Xs, {'end', X}, fun(Acc, X@1) -> {next, X@1, Acc} end) - end. - --spec map(non_empty_list(HBA), fun((HBA) -> HBC)) -> non_empty_list(HBC). -map(List, Transform) -> - case List of - {'end', X} -> - {'end', Transform(X)}; - - {next, X@1, Xs} -> - _pipe = fold( - Xs, - {'end', Transform(X@1)}, - fun(Acc, Item) -> {next, Transform(Item), Acc} end - ), - reverse(_pipe) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl deleted file mode 100644 index 7537469dd3c..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl +++ /dev/null @@ -1,74 +0,0 @@ --module(gleamy_structures@priority_queue). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_empty/1, new/1, from_list/2, pop/1, peek/1, push/2, count/1, reorder/2, to_list/1]). - --spec is_empty(gleamy_structures@heap@pairing_heap:heap(any())) -> boolean(). -is_empty(Queue) -> - case gleamy_structures@heap@pairing_heap:find_min(Queue) of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec new(fun((EZX, EZX) -> gleam@order:order())) -> gleamy_structures@heap@pairing_heap:heap(EZX). -new(Compare) -> - gleamy_structures@heap@pairing_heap:new(Compare). - --spec from_list(list(EZQ), fun((EZQ, EZQ) -> gleam@order:order())) -> gleamy_structures@heap@pairing_heap:heap(EZQ). -from_list(List, Compare) -> - gleam@list:fold( - List, - new(Compare), - fun gleamy_structures@heap@pairing_heap:insert/2 - ). - --spec pop(gleamy_structures@heap@pairing_heap:heap(EZZ)) -> {ok, - {EZZ, gleamy_structures@heap@pairing_heap:heap(EZZ)}} | - {error, nil}. -pop(Queue) -> - gleamy_structures@heap@pairing_heap:delete_min(Queue). - --spec peek(gleamy_structures@heap@pairing_heap:heap(FAE)) -> {ok, FAE} | - {error, nil}. -peek(Queue) -> - gleamy_structures@heap@pairing_heap:find_min(Queue). - --spec push(gleamy_structures@heap@pairing_heap:heap(FAI), FAI) -> gleamy_structures@heap@pairing_heap:heap(FAI). -push(Queue, Item) -> - gleamy_structures@heap@pairing_heap:insert(Queue, Item). - --spec count(gleamy_structures@heap@pairing_heap:heap(any())) -> integer(). -count(Queue) -> - case gleamy_structures@heap@pairing_heap:delete_min(Queue) of - {ok, {_, Q}} -> - count(Q) + 1; - - {error, _} -> - 0 - end. - --spec reorder( - gleamy_structures@heap@pairing_heap:heap(FAL), - fun((FAL, FAL) -> gleam@order:order()) -) -> gleamy_structures@heap@pairing_heap:heap(FAL). -reorder(Queue, Compare) -> - case gleamy_structures@heap@pairing_heap:delete_min(Queue) of - {ok, {X, Q}} -> - gleamy_structures@heap@pairing_heap:insert(reorder(Q, Compare), X); - - {error, _} -> - gleamy_structures@heap@pairing_heap:new(Compare) - end. - --spec to_list(gleamy_structures@heap@pairing_heap:heap(FAO)) -> list(FAO). -to_list(Queue) -> - case gleamy_structures@heap@pairing_heap:delete_min(Queue) of - {ok, {X, Q}} -> - [X | to_list(Q)]; - - {error, _} -> - [] - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl deleted file mode 100644 index 38ccc7a19a4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl +++ /dev/null @@ -1,123 +0,0 @@ --module(gleamy_structures@set). --compile([no_auto_import, nowarn_unused_vars]). - --export([contains/2, delete/2, filter/2, fold/3, from_list/2, insert/2, intersection/2, new/1, count/1, to_list/1, union/2, take/2]). - --spec contains(gleamy_structures@tree@red_black_tree:tree(FTU), FTU) -> boolean(). -contains(Set, Member) -> - case gleamy_structures@tree@red_black_tree:find(Set, Member) of - {ok, _} -> - true; - - {error, _} -> - false - end. - --spec delete(gleamy_structures@tree@red_black_tree:tree(FTW), FTW) -> gleamy_structures@tree@red_black_tree:tree(FTW). -delete(Set, Member) -> - gleamy_structures@tree@red_black_tree:delete(Set, Member). - --spec filter( - gleamy_structures@tree@red_black_tree:tree(FTZ), - fun((FTZ) -> boolean()) -) -> gleamy_structures@tree@red_black_tree:tree(FTZ). -filter(Set, Property) -> - gleamy_structures@tree@red_black_tree:fold( - Set, - Set, - fun(Set@1, I) -> case Property(I) of - true -> - Set@1; - - false -> - gleamy_structures@tree@red_black_tree:delete(Set@1, I) - end end - ). - --spec fold( - gleamy_structures@tree@red_black_tree:tree(FUC), - FUE, - fun((FUE, FUC) -> FUE) -) -> FUE. -fold(Set, Initial, Reducer) -> - gleamy_structures@tree@red_black_tree:fold(Set, Initial, Reducer). - --spec from_list(list(FUF), fun((FUF, FUF) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree:tree(FUF). -from_list(Members, Compare) -> - gleam@list:fold( - Members, - gleamy_structures@tree@red_black_tree:new(Compare), - fun gleamy_structures@tree@red_black_tree:insert/2 - ). - --spec insert(gleamy_structures@tree@red_black_tree:tree(FUI), FUI) -> gleamy_structures@tree@red_black_tree:tree(FUI). -insert(Set, Member) -> - gleamy_structures@tree@red_black_tree:insert(Set, Member). - --spec intersection( - gleamy_structures@tree@red_black_tree:tree(FUL), - gleamy_structures@tree@red_black_tree:tree(FUL) -) -> gleamy_structures@tree@red_black_tree:tree(FUL). -intersection(First, Second) -> - gleamy_structures@tree@red_black_tree:fold( - Second, - gleamy_structures@tree@red_black_tree:clear(First), - fun(A, I) -> - case gleamy_structures@tree@red_black_tree:find(First, I) of - {ok, _} -> - gleamy_structures@tree@red_black_tree:insert(A, I); - - {error, _} -> - A - end - end - ). - --spec new(fun((FUP, FUP) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree:tree(FUP). -new(Compare) -> - gleamy_structures@tree@red_black_tree:new(Compare). - --spec count(gleamy_structures@tree@red_black_tree:tree(any())) -> integer(). -count(Set) -> - gleamy_structures@tree@red_black_tree:fold(Set, 0, fun(A, _) -> A + 1 end). - --spec to_list(gleamy_structures@tree@red_black_tree:tree(FUX)) -> list(FUX). -to_list(Set) -> - gleamy_structures@tree@red_black_tree:foldr( - Set, - [], - fun(A, I) -> - gleam@io:println(gleam@string:inspect(I)), - [I | A] - end - ). - --spec union( - gleamy_structures@tree@red_black_tree:tree(FVA), - gleamy_structures@tree@red_black_tree:tree(FVA) -) -> gleamy_structures@tree@red_black_tree:tree(FVA). -union(First, Second) -> - gleamy_structures@tree@red_black_tree:fold( - First, - Second, - fun(A, I) -> gleamy_structures@tree@red_black_tree:insert(A, I) end - ). - --spec take(gleamy_structures@tree@red_black_tree:tree(FUT), list(FUT)) -> gleamy_structures@tree@red_black_tree:tree(FUT). -take(Set, Desired) -> - case Desired of - [X | Xs] -> - case gleamy_structures@tree@red_black_tree:find(Set, X) of - {ok, X@1} -> - gleamy_structures@tree@red_black_tree:insert( - take(Set, Xs), - X@1 - ); - - {error, _} -> - take(Set, Xs) - end; - - [] -> - gleamy_structures@tree@red_black_tree:clear(Set) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl deleted file mode 100644 index 296ea98d2e4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl +++ /dev/null @@ -1,167 +0,0 @@ --module(gleamy_structures@tree@binary_search_tree). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, clear/1, insert/2, delete/2, find/2, fold/3, draw/2]). --export_type([node_/1, tree/1]). - --type node_(FCI) :: empty | {node, node_(FCI), FCI, node_(FCI)}. - --opaque tree(FCJ) :: {tree, node_(FCJ), fun((FCJ, FCJ) -> gleam@order:order())}. - --spec new(fun((FCK, FCK) -> gleam@order:order())) -> tree(FCK). -new(Compare) -> - {tree, empty, Compare}. - --spec clear(tree(FCM)) -> tree(FCM). -clear(Tree) -> - {tree, empty, erlang:element(3, Tree)}. - --spec do_insert(node_(FCP), FCP, fun((FCP, FCP) -> gleam@order:order())) -> node_(FCP). -do_insert(Node, Key, Compare) -> - case Node of - {node, L, K, R} -> - case Compare(Key, K) of - lt -> - {node, do_insert(L, Key, Compare), K, R}; - - gt -> - {node, L, K, do_insert(R, Key, Compare)}; - - eq -> - {node, L, Key, R} - end; - - empty -> - {node, empty, Key, empty} - end. - --spec insert(tree(FCP), FCP) -> tree(FCP). -insert(Tree, Key) -> - {tree, - do_insert(erlang:element(2, Tree), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_delete(node_(FCS), FCS, fun((FCS, FCS) -> gleam@order:order())) -> node_(FCS). -do_delete(Node, Key, Compare) -> - case Node of - {node, L, K, R} -> - case Compare(Key, K) of - lt -> - {node, do_delete(L, Key, Compare), K, R}; - - gt -> - {node, L, K, do_delete(R, Key, Compare)}; - - eq -> - case Node of - {node, empty, _, R@1} -> - R@1; - - {node, L@1, _, empty} -> - L@1; - - {node, L@2, _, R@2} -> - case do_min(R@2, Compare) of - {node, _, Mk, _} -> - {node, L@2, Mk, do_delete(R@2, Mk, Compare)}; - - empty -> - empty - end; - - empty -> - empty - end - end; - - empty -> - empty - end. - --spec delete(tree(FCS), FCS) -> tree(FCS). -delete(Tree, Key) -> - {tree, - do_delete(erlang:element(2, Tree), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_find(node_(FCV), FCV, fun((FCV, FCV) -> gleam@order:order())) -> {ok, - FCV} | - {error, nil}. -do_find(Node, Key, Compare) -> - case Node of - {node, L, K, R} -> - case Compare(Key, K) of - lt -> - do_find(L, Key, Compare); - - gt -> - do_find(R, Key, Compare); - - eq -> - {ok, K} - end; - - empty -> - {error, nil} - end. - --spec find(tree(FCV), FCV) -> {ok, FCV} | {error, nil}. -find(Tree, Key) -> - do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). - --spec do_fold(node_(FCZ), FDB, fun((FDB, FCZ) -> FDB)) -> FDB. -do_fold(Node, Acc, Fun) -> - case Node of - {node, R, V, L} -> - Acc@1 = do_fold(R, Acc, Fun), - Acc@2 = Fun(Acc@1, V), - Acc@3 = do_fold(L, Acc@2, Fun), - Acc@3; - - empty -> - Acc - end. - --spec fold(tree(FCZ), FDB, fun((FDB, FCZ) -> FDB)) -> FDB. -fold(Tree, Acc, Fun) -> - do_fold(erlang:element(2, Tree), Acc, Fun). - --spec do_draw(node_(FDC), integer(), fun((FDC) -> binary())) -> binary(). -do_draw(Node, Indent, To_string) -> - case Node of - {node, L, K, R} -> - Ls = do_draw(L, Indent + 1, To_string), - Ks = do_indent(<<(To_string(K))/binary, "\n"/utf8>>, Indent), - Rs = do_draw(R, Indent + 1, To_string), - <<<<Ls/binary, Ks/binary>>/binary, Rs/binary>>; - - empty -> - <<""/utf8>> - end. - --spec draw(tree(FDC), fun((FDC) -> binary())) -> binary(). -draw(Tree, To_string) -> - do_draw(erlang:element(2, Tree), 0, To_string). - --spec do_min(node_(FCS), fun((FCS, FCS) -> gleam@order:order())) -> node_(FCS). -do_min(Node, Compare) -> - case Node of - {node, {node, _, _, _} = L, _, _} -> - do_min(L, Compare); - - {node, empty, _, _} -> - Node; - - empty -> - empty - end. - --spec do_indent(binary(), integer()) -> binary(). -do_indent(Acc, I) -> - case I of - 0 -> - Acc; - - I@1 -> - do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl deleted file mode 100644 index c29bbebf903..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl +++ /dev/null @@ -1,326 +0,0 @@ --module(gleamy_structures@tree@red_black_tree). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, clear/1, insert/2, delete/2, find/2, fold/3, foldr/3, draw/2]). --export_type([color/0, node_/1, tree/1, min_del/1]). - --type color() :: r | b | bb. - --type node_(FHR) :: e | ee | {t, color(), node_(FHR), FHR, node_(FHR)}. - --opaque tree(FHS) :: {tree, node_(FHS), fun((FHS, FHS) -> gleam@order:order())}. - --type min_del(FHT) :: {min, FHT, node_(FHT)} | none. - --spec new(fun((FHU, FHU) -> gleam@order:order())) -> tree(FHU). -new(Compare) -> - {tree, e, Compare}. - --spec clear(tree(FHW)) -> tree(FHW). -clear(Tree) -> - {tree, e, erlang:element(3, Tree)}. - --spec blacken(node_(FIW)) -> node_(FIW). -blacken(Node) -> - case Node of - {t, r, {t, r, _, _, _} = L, Y, C} -> - {t, b, L, Y, C}; - - {t, r, A, X, {t, r, _, _, _} = R} -> - {t, b, A, X, R}; - - T -> - T - end. - --spec balance(color(), node_(FIZ), FIZ, node_(FIZ)) -> node_(FIZ). -balance(C, L, V, R) -> - case {C, L, V, R} of - {b, {t, r, {t, r, A, X, B}, Y, C@1}, Z, D} -> - {t, r, {t, b, A, X, B}, Y, {t, b, C@1, Z, D}}; - - {b, {t, r, A@1, X@1, {t, r, B@1, Y@1, C@2}}, Z@1, D@1} -> - {t, r, {t, b, A@1, X@1, B@1}, Y@1, {t, b, C@2, Z@1, D@1}}; - - {b, A@2, X@2, {t, r, {t, r, B@2, Y@2, C@3}, Z@2, D@2}} -> - {t, r, {t, b, A@2, X@2, B@2}, Y@2, {t, b, C@3, Z@2, D@2}}; - - {b, A@3, X@3, {t, r, B@3, Y@3, {t, r, C@4, Z@3, D@3}}} -> - {t, r, {t, b, A@3, X@3, B@3}, Y@3, {t, b, C@4, Z@3, D@3}}; - - {bb, A@4, X@4, {t, r, {t, r, B@4, Y@4, C@5}, Z@4, D@4}} -> - {t, b, {t, b, A@4, X@4, B@4}, Y@4, {t, b, C@5, Z@4, D@4}}; - - {bb, {t, r, A@5, X@5, {t, r, B@5, Y@5, C@6}}, Z@5, D@5} -> - {t, b, {t, b, A@5, X@5, B@5}, Y@5, {t, b, C@6, Z@5, D@5}}; - - {C@7, A@6, X@6, B@6} -> - {t, C@7, A@6, X@6, B@6} - end. - --spec redden(node_(FJD)) -> node_(FJD). -redden(Node) -> - case Node of - {t, b, {t, b, _, _, _} = L, Y, {t, b, _, _, _} = R} -> - {t, r, L, Y, R}; - - T -> - T - end. - --spec rotate(color(), node_(FJK), FJK, node_(FJK)) -> node_(FJK). -rotate(C, L, V, R) -> - case {C, L, V, R} of - {r, {t, bb, A, X, B}, Y, {t, b, C@1, Z, D}} -> - balance(b, {t, r, {t, b, A, X, B}, Y, C@1}, Z, D); - - {r, ee, Y@1, {t, b, C@2, Z@1, D@1}} -> - balance(b, {t, r, e, Y@1, C@2}, Z@1, D@1); - - {r, {t, b, A@1, X@1, B@1}, Y@2, {t, bb, C@3, Z@2, D@2}} -> - balance(b, A@1, X@1, {t, r, B@1, Y@2, {t, b, C@3, Z@2, D@2}}); - - {r, {t, b, A@2, X@2, B@2}, Y@3, ee} -> - balance(b, A@2, X@2, {t, r, B@2, Y@3, e}); - - {b, {t, bb, A@3, X@3, B@3}, Y@4, {t, b, C@4, Z@3, D@3}} -> - balance(bb, {t, r, {t, b, A@3, X@3, B@3}, Y@4, C@4}, Z@3, D@3); - - {b, ee, Y@5, {t, b, C@5, Z@4, D@4}} -> - balance(bb, {t, r, e, Y@5, C@5}, Z@4, D@4); - - {b, {t, b, A@4, X@4, B@4}, Y@6, {t, bb, C@6, Z@5, D@5}} -> - balance(bb, A@4, X@4, {t, r, B@4, Y@6, {t, b, C@6, Z@5, D@5}}); - - {b, {t, b, A@5, X@5, B@5}, Y@7, ee} -> - balance(bb, A@5, X@5, {t, r, B@5, Y@7, e}); - - {b, {t, bb, A@6, W, B@6}, X@6, {t, r, {t, b, C@7, Y@8, D@6}, Z@6, E}} -> - {t, - b, - balance(b, {t, r, {t, b, A@6, W, B@6}, X@6, C@7}, Y@8, D@6), - Z@6, - E}; - - {b, ee, X@7, {t, r, {t, b, C@8, Y@9, D@7}, Z@7, E@1}} -> - {t, b, balance(b, {t, r, e, X@7, C@8}, Y@9, D@7), Z@7, E@1}; - - {b, - {t, r, A@7, W@1, {t, b, B@7, X@8, C@9}}, - Y@10, - {t, bb, D@8, Z@8, E@2}} -> - {t, - b, - A@7, - W@1, - balance(b, B@7, X@8, {t, r, C@9, Y@10, {t, b, D@8, Z@8, E@2}})}; - - {b, {t, r, A@8, W@2, {t, b, B@8, X@9, C@10}}, Y@11, ee} -> - {t, b, A@8, W@2, balance(b, B@8, X@9, {t, r, C@10, Y@11, e})}; - - {C@11, A@9, X@10, B@9} -> - {t, C@11, A@9, X@10, B@9} - end. - --spec ins(node_(FHZ), FHZ, fun((FHZ, FHZ) -> gleam@order:order())) -> node_(FHZ). -ins(Node, X, Compare) -> - case Node of - e -> - {t, r, e, X, e}; - - {t, C, A, Y, B} -> - case Compare(X, Y) of - lt -> - balance(C, ins(A, X, Compare), Y, B); - - gt -> - balance(C, A, Y, ins(B, X, Compare)); - - eq -> - {t, C, A, X, B} - end; - - _ -> - Node - end. - --spec insert(tree(FHZ), FHZ) -> tree(FHZ). -insert(Tree, Key) -> - {tree, - blacken(ins(erlang:element(2, Tree), Key, erlang:element(3, Tree))), - erlang:element(3, Tree)}. - --spec del(node_(FIC), FIC, fun((FIC, FIC) -> gleam@order:order())) -> node_(FIC). -del(Node, X, Compare) -> - case Node of - e -> - Node; - - {t, r, e, Y, e} -> - case Compare(X, Y) of - eq -> - e; - - _ -> - Node - end; - - {t, b, e, Y@1, e} -> - case Compare(X, Y@1) of - eq -> - ee; - - _ -> - Node - end; - - {t, b, {t, r, e, Y@2, e} = L, Z, e} -> - case Compare(X, Z) of - lt -> - {t, b, del(L, X, Compare), Z, e}; - - gt -> - Node; - - eq -> - {t, b, e, Y@2, e} - end; - - {t, C, A, Y@3, B} -> - case Compare(X, Y@3) of - lt -> - rotate(C, del(A, X, Compare), Y@3, B); - - gt -> - rotate(C, A, Y@3, del(B, X, Compare)); - - eq -> - case min_del(B) of - {min, Y1, B1} -> - rotate(C, A, Y1, B1); - - none -> - e - end - end; - - _ -> - Node - end. - --spec delete(tree(FIC), FIC) -> tree(FIC). -delete(Tree, Key) -> - {tree, - del(redden(erlang:element(2, Tree)), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_find(node_(FIF), FIF, fun((FIF, FIF) -> gleam@order:order())) -> {ok, - FIF} | - {error, nil}. -do_find(Node, Key, Compare) -> - case Node of - {t, _, L, K, R} -> - case Compare(Key, K) of - lt -> - do_find(L, Key, Compare); - - gt -> - do_find(R, Key, Compare); - - eq -> - {ok, K} - end; - - _ -> - {error, nil} - end. - --spec find(tree(FIF), FIF) -> {ok, FIF} | {error, nil}. -find(Tree, Key) -> - do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). - --spec do_fold(node_(FIJ), FIL, fun((FIL, FIJ) -> FIL)) -> FIL. -do_fold(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_fold(R, Acc, Fun), - Acc@2 = Fun(Acc@1, V), - Acc@3 = do_fold(L, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec fold(tree(FIJ), FIL, fun((FIL, FIJ) -> FIL)) -> FIL. -fold(Tree, Acc, Fun) -> - do_fold(erlang:element(2, Tree), Acc, Fun). - --spec do_foldr(node_(FIM), FIO, fun((FIO, FIM) -> FIO)) -> FIO. -do_foldr(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_foldr(L, Acc, Fun), - Acc@2 = Fun(Acc@1, V), - Acc@3 = do_foldr(R, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec foldr(tree(FIM), FIO, fun((FIO, FIM) -> FIO)) -> FIO. -foldr(Tree, Acc, Fun) -> - do_foldr(erlang:element(2, Tree), Acc, Fun). - --spec do_draw(node_(FIP), integer(), fun((FIP) -> binary())) -> binary(). -do_draw(Node, Indent, To_string) -> - case Node of - {t, _, L, K, R} -> - Ls = do_draw(L, Indent + 1, To_string), - Ks = do_indent(<<(To_string(K))/binary, "\n"/utf8>>, Indent), - Rs = do_draw(R, Indent + 1, To_string), - <<<<Ls/binary, Ks/binary>>/binary, Rs/binary>>; - - _ -> - <<""/utf8>> - end. - --spec draw(tree(FIP), fun((FIP) -> binary())) -> binary(). -draw(Tree, To_string) -> - do_draw(erlang:element(2, Tree), 0, To_string). - --spec min_del(node_(any())) -> min_del(any()). -min_del(Node) -> - case Node of - {t, r, e, X, e} -> - {min, X, e}; - - {t, b, e, X@1, e} -> - {min, X@1, ee}; - - {t, b, e, X@2, {t, r, e, Y, e}} -> - {min, X@2, {t, b, e, Y, e}}; - - {t, C, A, X@3, B} -> - case min_del(A) of - {min, X1, A1} -> - {min, X1, rotate(C, A1, X@3, B)}; - - none -> - none - end; - - _ -> - none - end. - --spec do_indent(binary(), integer()) -> binary(). -do_indent(Acc, I) -> - case I of - 0 -> - Acc; - - I@1 -> - do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl deleted file mode 100644 index 710e27d32c4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl +++ /dev/null @@ -1,336 +0,0 @@ --module(gleamy_structures@tree@red_black_tree_kv). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, clear/1, insert/3, delete/2, find/2, fold/3, foldr/3, draw/2]). --export_type([color/0, node_/2, tree/2, min_del/2]). - --type color() :: r | b | bb. - --type node_(GAH, GAI) :: e | - ee | - {t, color(), node_(GAH, GAI), {GAH, GAI}, node_(GAH, GAI)}. - --opaque tree(GAJ, GAK) :: {tree, - node_(GAJ, GAK), - fun((GAJ, GAJ) -> gleam@order:order())}. - --type min_del(GAL, GAM) :: {min, {GAL, GAM}, node_(GAL, GAM)} | none. - --spec new(fun((GAN, GAN) -> gleam@order:order())) -> tree(GAN, any()). -new(Compare) -> - {tree, e, Compare}. - --spec clear(tree(GAR, GAS)) -> tree(GAR, GAS). -clear(Tree) -> - {tree, e, erlang:element(3, Tree)}. - --spec blacken(node_(GCJ, GCK)) -> node_(GCJ, GCK). -blacken(Node) -> - case Node of - {t, r, {t, r, _, _, _} = L, Y, C} -> - {t, b, L, Y, C}; - - {t, r, K, X, {t, r, _, _, _} = R} -> - {t, b, K, X, R}; - - T -> - T - end. - --spec balance(color(), node_(GCP, GCQ), {GCP, GCQ}, node_(GCP, GCQ)) -> node_(GCP, GCQ). -balance(C, L, V, R) -> - case {C, L, V, R} of - {b, {t, r, {t, r, K, X, B}, Y, C@1}, Z, D} -> - {t, r, {t, b, K, X, B}, Y, {t, b, C@1, Z, D}}; - - {b, {t, r, K@1, X@1, {t, r, B@1, Y@1, C@2}}, Z@1, D@1} -> - {t, r, {t, b, K@1, X@1, B@1}, Y@1, {t, b, C@2, Z@1, D@1}}; - - {b, K@2, X@2, {t, r, {t, r, B@2, Y@2, C@3}, Z@2, D@2}} -> - {t, r, {t, b, K@2, X@2, B@2}, Y@2, {t, b, C@3, Z@2, D@2}}; - - {b, K@3, X@3, {t, r, B@3, Y@3, {t, r, C@4, Z@3, D@3}}} -> - {t, r, {t, b, K@3, X@3, B@3}, Y@3, {t, b, C@4, Z@3, D@3}}; - - {bb, K@4, X@4, {t, r, {t, r, B@4, Y@4, C@5}, Z@4, D@4}} -> - {t, b, {t, b, K@4, X@4, B@4}, Y@4, {t, b, C@5, Z@4, D@4}}; - - {bb, {t, r, K@5, X@5, {t, r, B@5, Y@5, C@6}}, Z@5, D@5} -> - {t, b, {t, b, K@5, X@5, B@5}, Y@5, {t, b, C@6, Z@5, D@5}}; - - {C@7, K@6, X@6, B@6} -> - {t, C@7, K@6, X@6, B@6} - end. - --spec redden(node_(GCX, GCY)) -> node_(GCX, GCY). -redden(Node) -> - case Node of - {t, b, {t, b, _, _, _} = L, Y, {t, b, _, _, _} = R} -> - {t, r, L, Y, R}; - - T -> - T - end. - --spec rotate(color(), node_(GDJ, GDK), {GDJ, GDK}, node_(GDJ, GDK)) -> node_(GDJ, GDK). -rotate(C, L, V, R) -> - case {C, L, V, R} of - {r, {t, bb, K, X, B}, Y, {t, b, C@1, Z, D}} -> - balance(b, {t, r, {t, b, K, X, B}, Y, C@1}, Z, D); - - {r, ee, Y@1, {t, b, C@2, Z@1, D@1}} -> - balance(b, {t, r, e, Y@1, C@2}, Z@1, D@1); - - {r, {t, b, K@1, X@1, B@1}, Y@2, {t, bb, C@3, Z@2, D@2}} -> - balance(b, K@1, X@1, {t, r, B@1, Y@2, {t, b, C@3, Z@2, D@2}}); - - {r, {t, b, K@2, X@2, B@2}, Y@3, ee} -> - balance(b, K@2, X@2, {t, r, B@2, Y@3, e}); - - {b, {t, bb, K@3, X@3, B@3}, Y@4, {t, b, C@4, Z@3, D@3}} -> - balance(bb, {t, r, {t, b, K@3, X@3, B@3}, Y@4, C@4}, Z@3, D@3); - - {b, ee, Y@5, {t, b, C@5, Z@4, D@4}} -> - balance(bb, {t, r, e, Y@5, C@5}, Z@4, D@4); - - {b, {t, b, K@4, X@4, B@4}, Y@6, {t, bb, C@6, Z@5, D@5}} -> - balance(bb, K@4, X@4, {t, r, B@4, Y@6, {t, b, C@6, Z@5, D@5}}); - - {b, {t, b, K@5, X@5, B@5}, Y@7, ee} -> - balance(bb, K@5, X@5, {t, r, B@5, Y@7, e}); - - {b, {t, bb, K@6, W, B@6}, X@6, {t, r, {t, b, C@7, Y@8, D@6}, Z@6, E}} -> - {t, - b, - balance(b, {t, r, {t, b, K@6, W, B@6}, X@6, C@7}, Y@8, D@6), - Z@6, - E}; - - {b, ee, X@7, {t, r, {t, b, C@8, Y@9, D@7}, Z@7, E@1}} -> - {t, b, balance(b, {t, r, e, X@7, C@8}, Y@9, D@7), Z@7, E@1}; - - {b, - {t, r, K@7, W@1, {t, b, B@7, X@8, C@9}}, - Y@10, - {t, bb, D@8, Z@8, E@2}} -> - {t, - b, - K@7, - W@1, - balance(b, B@7, X@8, {t, r, C@9, Y@10, {t, b, D@8, Z@8, E@2}})}; - - {b, {t, r, K@8, W@2, {t, b, B@8, X@9, C@10}}, Y@11, ee} -> - {t, b, K@8, W@2, balance(b, B@8, X@9, {t, r, C@10, Y@11, e})}; - - {C@11, K@9, X@10, B@9} -> - {t, C@11, K@9, X@10, B@9} - end. - --spec ins(node_(GCD, GCE), {GCD, GCE}, fun((GCD, GCD) -> gleam@order:order())) -> node_(GCD, GCE). -ins(Node, X, Compare) -> - case Node of - e -> - {t, r, e, X, e}; - - {t, C, K, Y, B} -> - case Compare(erlang:element(1, X), erlang:element(1, Y)) of - lt -> - balance(C, ins(K, X, Compare), Y, B); - - gt -> - balance(C, K, Y, ins(B, X, Compare)); - - eq -> - {t, C, K, X, B} - end; - - _ -> - Node - end. - --spec insert(tree(GAX, GAY), GAX, GAY) -> tree(GAX, GAY). -insert(Tree, Key, Value) -> - {tree, - blacken( - ins(erlang:element(2, Tree), {Key, Value}, erlang:element(3, Tree)) - ), - erlang:element(3, Tree)}. - --spec del(node_(GDD, GDE), GDD, fun((GDD, GDD) -> gleam@order:order())) -> node_(GDD, GDE). -del(Node, X, Compare) -> - case Node of - e -> - Node; - - {t, r, e, Y, e} -> - case Compare(X, erlang:element(1, Y)) of - eq -> - e; - - _ -> - Node - end; - - {t, b, e, Y@1, e} -> - case Compare(X, erlang:element(1, Y@1)) of - eq -> - ee; - - _ -> - Node - end; - - {t, b, {t, r, e, Y@2, e} = L, Z, e} -> - case Compare(X, erlang:element(1, Z)) of - lt -> - {t, b, del(L, X, Compare), Z, e}; - - gt -> - Node; - - eq -> - {t, b, e, Y@2, e} - end; - - {t, C, K, Y@3, B} -> - case Compare(X, erlang:element(1, Y@3)) of - lt -> - rotate(C, del(K, X, Compare), Y@3, B); - - gt -> - rotate(C, K, Y@3, del(B, X, Compare)); - - eq -> - case min_del(B) of - {min, Y1, B1} -> - rotate(C, K, Y1, B1); - - none -> - e - end - end; - - _ -> - Node - end. - --spec delete(tree(GBD, GBE), GBD) -> tree(GBD, GBE). -delete(Tree, Key) -> - {tree, - del(redden(erlang:element(2, Tree)), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_find(node_(GDX, GDY), GDX, fun((GDX, GDX) -> gleam@order:order())) -> {ok, - {GDX, GDY}} | - {error, nil}. -do_find(Node, Key, Compare) -> - case Node of - {t, _, L, K, R} -> - case Compare(Key, erlang:element(1, K)) of - lt -> - do_find(L, Key, Compare); - - gt -> - do_find(R, Key, Compare); - - eq -> - {ok, K} - end; - - _ -> - {error, nil} - end. - --spec find(tree(GBJ, GBK), GBJ) -> {ok, {GBJ, GBK}} | {error, nil}. -find(Tree, Key) -> - do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). - --spec do_fold(node_(GED, GEE), GEH, fun((GEH, GED, GEE) -> GEH)) -> GEH. -do_fold(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_fold(R, Acc, Fun), - Acc@2 = Fun(Acc@1, erlang:element(1, V), erlang:element(2, V)), - Acc@3 = do_fold(L, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec fold(tree(GBP, GBQ), GBT, fun((GBT, GBP, GBQ) -> GBT)) -> GBT. -fold(Tree, Acc, Fun) -> - do_fold(erlang:element(2, Tree), Acc, Fun). - --spec do_foldr(node_(GEI, GEJ), GEM, fun((GEM, GEI, GEJ) -> GEM)) -> GEM. -do_foldr(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_foldr(L, Acc, Fun), - Acc@2 = Fun(Acc@1, erlang:element(1, V), erlang:element(2, V)), - Acc@3 = do_foldr(R, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec foldr(tree(GBU, GBV), GBY, fun((GBY, GBU, GBV) -> GBY)) -> GBY. -foldr(Tree, Acc, Fun) -> - do_foldr(erlang:element(2, Tree), Acc, Fun). - --spec do_draw(node_(GEN, GEO), integer(), fun((GEN, GEO) -> binary())) -> binary(). -do_draw(Node, Indent, To_string) -> - case Node of - {t, _, L, K, R} -> - Ls = do_draw(L, Indent + 1, To_string), - Ks = do_indent( - <<(To_string(erlang:element(1, K), erlang:element(2, K)))/binary, - "\n"/utf8>>, - Indent - ), - Rs = do_draw(R, Indent + 1, To_string), - <<<<Ls/binary, Ks/binary>>/binary, Rs/binary>>; - - _ -> - <<""/utf8>> - end. - --spec draw(tree(GBZ, GCA), fun((GBZ, GCA) -> binary())) -> binary(). -draw(Tree, To_string) -> - do_draw(erlang:element(2, Tree), 0, To_string). - --spec min_del(node_(GDR, GDS)) -> min_del(GDR, GDS). -min_del(Node) -> - case Node of - {t, r, e, X, e} -> - {min, X, e}; - - {t, b, e, X@1, e} -> - {min, X@1, ee}; - - {t, b, e, X@2, {t, r, e, Y, e}} -> - {min, X@2, {t, b, e, Y, e}}; - - {t, C, K, X@3, B} -> - case min_del(K) of - {min, X1, A1} -> - {min, X1, rotate(C, A1, X@3, B)}; - - none -> - none - end; - - _ -> - none - end. - --spec do_indent(binary(), integer()) -> binary(). -do_indent(Acc, I) -> - case I of - 0 -> - Acc; - - I@1 -> - do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) - end. diff --git a/test-community-packages-javascript/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/gleeunit/LICENCE deleted file mode 100644 index c7967c32d6f..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2021, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/gleeunit/README.md deleted file mode 100644 index 2b685d9bc70..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# gleeunit - -Gleam bindings to the Erlang EUnit test framework. - -A custom test runner is included for when compiled to JavaScript running on -either NodeJS or Deno. - -Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). - -## Usage - -Add this package to your Gleam project. - -```sh -gleam add gleeunit --dev -``` - -And then call the `gleeunit.main` function from your test main function. - -```gleam -// In test/yourapp_test.gleam -import gleeunit - -pub fn main() { - gleeunit.main() -} -``` - -Now any public function with a name ending in `_test` in the `test` directory -will be found and run as a test. - -```gleam -pub fn the_universe_test() { - assert 1 = 1 -} -``` - -Run the tests by entering `gleam test` in the command line. - -### Deno - -If using the Deno JavaScript runtime, you will need to add the following to your -`gleam.toml`. - -```toml -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] -``` diff --git a/test-community-packages-javascript/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/gleeunit/gleam.toml deleted file mode 100644 index 5438dd20a74..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleeunit" -version = "0.10.1" -licences = ["Apache-2.0"] -description = "Gleam bindings to Erlang's EUnit test framework" - -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] - -[dependencies] -gleam_stdlib = "~> 0.19" - -[dev-dependencies] -# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src deleted file mode 100644 index f5525522d33..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleeunit, [ - {vsn, "0.10.1"}, - {applications, [gleam_stdlib]}, - {description, "Gleam bindings to Erlang's EUnit test framework"}, - {modules, [gleeunit, - gleeunit@should]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl deleted file mode 100644 index 916082bcb17..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gleeunit). --compile(no_auto_import). - --export([main/0]). --export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). - --type atom_() :: any(). - --type encoding() :: utf8. - --type report_module_name() :: gleeunit_progress. - --type gleeunit_progress_option() :: {colored, boolean()}. - --type eunit_option() :: verbose | - no_tty | - {report, {report_module_name(), list(gleeunit_progress_option())}}. - --spec main() -> nil. -main() -> - do_main(). - --spec do_main() -> nil. -do_main() -> - Options = [verbose, - no_tty, - {report, {gleeunit_progress, [{colored, true}]}}], - Result = begin - _pipe = gleeunit_ffi:find_files( - <<"**/*.{erl,gleam}"/utf8>>, - <<"test"/utf8>> - ), - _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end - ), - _pipe@3 = eunit:test(_pipe@2, Options), - _pipe@4 = (gleam@dynamic:result( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ))(_pipe@3), - gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) - end, - Code = case Result of - {ok, _} -> - 0; - - {error, _} -> - 1 - end, - erlang:halt(Code). - --spec gleam_to_erlang_module_name(binary()) -> binary(). -gleam_to_erlang_module_name(Path) -> - _pipe = Path, - _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), - gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam deleted file mode 100644 index 751587a977a..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam +++ /dev/null @@ -1,80 +0,0 @@ -/// Find and run all test functions for the current project using Erlang's EUnit -/// test framework. -/// -/// Any Erlang or Gleam function in the `test` directory with a name editing in -/// `_test` is considered a test function and will be run. -/// -/// If running on JavaScript tests will be run with a custom test runner. -/// -pub fn main() -> Nil { - do_main() -} - -if javascript { - external fn do_main() -> Nil = - "./gleeunit_ffi.mjs" "main" -} - -if erlang { - import gleam/list - import gleam/result - import gleam/string - import gleam/dynamic.{Dynamic} - - fn do_main() -> Nil { - let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] - - let result = - find_files(matching: "**/*.{erl,gleam}", in: "test") - |> list.map(gleam_to_erlang_module_name) - |> list.map(dangerously_convert_string_to_atom(_, Utf8)) - |> run_eunit(options) - |> dynamic.result(dynamic.dynamic, dynamic.dynamic) - |> result.unwrap(Error(dynamic.from(Nil))) - - let code = case result { - Ok(_) -> 0 - Error(_) -> 1 - } - halt(code) - } - - external fn halt(Int) -> Nil = - "erlang" "halt" - - fn gleam_to_erlang_module_name(path: String) -> String { - path - |> string.replace(".gleam", "") - |> string.replace(".erl", "") - |> string.replace("/", "@") - } - - external fn find_files(matching: String, in: String) -> List(String) = - "gleeunit_ffi" "find_files" - - external type Atom - - type Encoding { - Utf8 - } - - external fn dangerously_convert_string_to_atom(String, Encoding) -> Atom = - "erlang" "binary_to_atom" - - type ReportModuleName { - GleeunitProgress - } - - type GleeunitProgressOption { - Colored(Bool) - } - - type EunitOption { - Verbose - NoTty - Report(#(ReportModuleName, List(GleeunitProgressOption))) - } - - external fn run_eunit(List(Atom), List(EunitOption)) -> Dynamic = - "eunit" "test" -} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam deleted file mode 100644 index fc80c7583fd..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam +++ /dev/null @@ -1,83 +0,0 @@ -//// A module for testing your Gleam code. The functions found here are -//// compatible with the Erlang eunit test framework. -//// -//// More information on running eunit can be found in [the rebar3 -//// documentation](https://rebar3.org/docs/testing/eunit/). - -if erlang { - pub external fn equal(a, a) -> Nil = - "gleeunit_ffi" "should_equal" - - pub external fn not_equal(a, a) -> Nil = - "gleeunit_ffi" "should_not_equal" - - pub external fn be_ok(Result(a, b)) -> a = - "gleeunit_ffi" "should_be_ok" - - pub external fn be_error(Result(a, b)) -> b = - "gleeunit_ffi" "should_be_error" -} - -if javascript { - import gleam/string - - external fn stringify(anything) -> String = - "../gleam.mjs" "inspect" - - external fn crash(String) -> anything = - "../gleeunit_ffi.mjs" "crash" - - pub fn equal(a, b) { - case a == b { - True -> Nil - _ -> - crash(string.concat([ - "\n\t", - stringify(a), - "\n\tshould equal \n\t", - stringify(b), - ])) - } - } - - pub fn not_equal(a, b) { - case a != b { - True -> Nil - _ -> - crash(string.concat([ - "\n", - stringify(a), - "\nshould not equal \n", - stringify(b), - ])) - } - } - - pub fn be_ok(a) { - case a { - Ok(value) -> value - _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) - } - } - - pub fn be_error(a) { - case a { - Error(error) -> error - _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) - } - } -} - -pub fn be_true(actual: Bool) -> Nil { - actual - |> equal(True) -} - -pub fn be_false(actual: Bool) -> Nil { - actual - |> equal(False) -} - -pub fn fail() -> Nil { - be_true(False) -} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl deleted file mode 100644 index eb04c98772c..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(gleeunit@should). --compile(no_auto_import). - --export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). - --spec equal(EIP, EIP) -> nil. -equal(Field@0, Field@1) -> - gleeunit_ffi:should_equal(Field@0, Field@1). - --spec not_equal(EIQ, EIQ) -> nil. -not_equal(Field@0, Field@1) -> - gleeunit_ffi:should_not_equal(Field@0, Field@1). - --spec be_ok({ok, EIR} | {error, any()}) -> EIR. -be_ok(Field@0) -> - gleeunit_ffi:should_be_ok(Field@0). - --spec be_error({ok, any()} | {error, EIV}) -> EIV. -be_error(Field@0) -> - gleeunit_ffi:should_be_error(Field@0). - --spec be_true(boolean()) -> nil. -be_true(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, true). - --spec be_false(boolean()) -> nil. -be_false(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, false). - --spec fail() -> nil. -fail() -> - be_true(false). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl deleted file mode 100644 index 31f9ef9e2c9..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(gleeunit_ffi). - --export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, - should_be_error/1]). - --include_lib("eunit/include/eunit.hrl"). - -find_files(Pattern, In) -> - Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), - lists:map(fun list_to_binary/1, Results). - - -should_equal(Actual, Expected) -> - ?assertEqual(Expected, Actual), - nil. -should_not_equal(Actual, Expected) -> - ?assertNotEqual(Expected, Actual), - nil. -should_be_ok(A) -> - ?assertMatch({ok, _}, A), - element(2, A). -should_be_error(A) -> - ?assertMatch({error, _}, A), - element(2, A). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs deleted file mode 100644 index 339a843e5c5..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs +++ /dev/null @@ -1,101 +0,0 @@ -async function* gleamFiles(directory) { - for (let entry of await read_dir(directory)) { - let path = join_path(directory, entry); - if (path.endsWith(".gleam")) { - yield path; - } else { - try { - yield* gleamFiles(path); - } catch (error) { - // Could not read directory, assume it's a file - } - } - } -} - -async function readRootPackageName() { - let toml = await read_file("gleam.toml", "utf-8"); - for (let line of toml.split("\n")) { - let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() - if (matches) return matches[1]; - } - throw new Error("Could not determine package name from gleam.toml"); -} - -export async function main() { - let passes = 0; - let failures = 0; - - let packageName = await readRootPackageName(); - let dist = `../${packageName}/`; - - for await (let path of await gleamFiles("test")) { - let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); - let module = await import(join_path(dist, js_path)); - for (let fnName of Object.keys(module)) { - if (!fnName.endsWith("_test")) continue; - try { - await module[fnName](); - write(`\u001b[32m.\u001b[0m`); - passes++; - } catch (error) { - let moduleName = "\n" + js_path.slice(0, -4); - let line = error.line ? `:${error.line}` : ""; - write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); - failures++; - } - } - } - - console.log(` -${passes + failures} tests, ${failures} failures`); - exit(failures ? 1 : 0); -} - -export function crash(message) { - throw new Error(message); -} - -function write(message) { - if (globalThis.Deno) { - Deno.stdout.writeSync(new TextEncoder().encode(message)); - } else { - process.stdout.write(message); - } -} - -function exit(code) { - if (globalThis.Deno) { - Deno.exit(code); - } else { - process.exit(code); - } -} - -async function read_dir(path) { - if (globalThis.Deno) { - let items = []; - for await (let item of Deno.readDir(path, { withFileTypes: true })) { - items.push(item.name); - } - return items; - } else { - let { readdir } = await import("fs/promises"); - return readdir(path); - } -} - -function join_path(a, b) { - if (a.endsWith("/")) return a + b; - return a + "/" + b; -} - -async function read_file(path) { - if (globalThis.Deno) { - return Deno.readTextFile(path); - } else { - let { readFile } = await import("fs/promises"); - let contents = await readFile(path); - return contents.toString(); - } -} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl deleted file mode 100644 index 1f68eb95e58..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl +++ /dev/null @@ -1,607 +0,0 @@ -%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters - -%% @doc A listener/reporter for eunit that prints '.' for each -%% success, 'F' for each failure, and 'E' for each error. It can also -%% optionally summarize the failures at the end. --compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). --module(gleeunit_progress). --behaviour(eunit_listener). --define(NOTEST, true). --include_lib("eunit/include/eunit.hrl"). - --define(RED, "\e[0;31m"). --define(GREEN, "\e[0;32m"). --define(YELLOW, "\e[0;33m"). --define(WHITE, "\e[0;37m"). --define(CYAN, "\e[0;36m"). --define(RESET, "\e[0m"). - --record(node,{ - rank = 0 :: non_neg_integer(), - key :: term(), - value :: term(), - children = new() :: binomial_heap() - }). - --export_type([binomial_heap/0, heap_node/0]). --type binomial_heap() :: [ heap_node() ]. --type heap_node() :: #node{}. - -%% eunit_listener callbacks --export([ - init/1, - handle_begin/3, - handle_end/3, - handle_cancel/3, - terminate/2, - start/0, - start/1 - ]). - -%% -- binomial_heap.erl content start -- - --record(state, { - status = dict:new() :: euf_dict(), - failures = [] :: [[pos_integer()]], - skips = [] :: [[pos_integer()]], - timings = new() :: binomial_heap(), - colored = true :: boolean(), - profile = false :: boolean() - }). - --type euf_dict() :: dict:dict(). - --spec new() -> binomial_heap(). -new() -> - []. - -% Inserts a new pair into the heap (or creates a new heap) --spec insert(term(), term()) -> binomial_heap(). -insert(Key,Value) -> - insert(Key,Value,[]). - --spec insert(term(), term(), binomial_heap()) -> binomial_heap(). -insert(Key,Value,Forest) -> - insTree(#node{key=Key,value=Value},Forest). - -% Merges two heaps --spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). -merge(TS1,[]) when is_list(TS1) -> TS1; -merge([],TS2) when is_list(TS2) -> TS2; -merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> - if - R1 < R2 -> - [T1 | merge(TS1,F2)]; - R2 < R1 -> - [T2 | merge(F1, TS2)]; - true -> - insTree(link(T1,T2),merge(TS1,TS2)) - end. - -% Deletes the top entry from the heap and returns it --spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. -delete(TS) -> - {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), - {{Key,Value},merge(lists:reverse(TS1),TS2)}. - -% Turns the heap into list in heap order --spec to_list(binomial_heap()) -> [{term(), term()}]. -to_list([]) -> []; -to_list(List) when is_list(List) -> - to_list([],List). -to_list(Acc, []) -> - lists:reverse(Acc); -to_list(Acc,Forest) -> - {Next, Trees} = delete(Forest), - to_list([Next|Acc], Trees). - -% Take N elements from the top of the heap --spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. -take(N,Trees) when is_integer(N), is_list(Trees) -> - take(N,Trees,[]). -take(0,_Trees,Acc) -> - lists:reverse(Acc); -take(_N,[],Acc)-> - lists:reverse(Acc); -take(N,Trees,Acc) -> - {Top,T2} = delete(Trees), - take(N-1,T2,[Top|Acc]). - -% Get an estimate of the size based on the binomial property --spec size(binomial_heap()) -> non_neg_integer(). -size(Forest) -> - erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). - -%% Private API --spec link(heap_node(), heap_node()) -> heap_node(). -link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> - case X1 < X2 of - true -> - T1#node{rank=R+1,children=[T2|C1]}; - _ -> - T2#node{rank=R+1,children=[T1|C2]} - end. - -insTree(Tree, []) -> - [Tree]; -insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> - case R1 < R2 of - true -> - [T1|TS]; - _ -> - insTree(link(T1,T2),Rest) - end. - -getMin([T]) -> - {T,[]}; -getMin([#node{key=K} = T|TS]) -> - {#node{key=K1} = T1,TS1} = getMin(TS), - case K < K1 of - true -> {T,TS}; - _ -> {T1,[T|TS1]} - end. - -%% -- binomial_heap.erl content end -- - -%% Startup -start() -> - start([]). - -start(Options) -> - eunit_listener:start(?MODULE, Options). - -%%------------------------------------------ -%% eunit_listener callbacks -%%------------------------------------------ -init(Options) -> - #state{colored=proplists:get_bool(colored, Options), - profile=proplists:get_bool(profile, Options)}. - -handle_begin(group, Data, St) -> - GID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; -handle_begin(test, Data, St) -> - TID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. - -handle_end(group, Data, St) -> - St#state{status=merge_on_end(Data, St#state.status)}; -handle_end(test, Data, St) -> - NewStatus = merge_on_end(Data, St#state.status), - St1 = print_progress(Data, St), - St2 = record_timing(Data, St1), - St2#state{status=NewStatus}. - -handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> - Status1 = merge_on_end(Data, Status), - ID = proplists:get_value(id, Data), - St#state{status=Status1, skips=[ID|Skips]}. - -terminate({ok, Data}, St) -> - print_failures(St), - print_pending(St), - print_profile(St), - print_timing(St), - print_results(Data, St); -terminate({error, Reason}, St) -> - io:nl(), io:nl(), - print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), - sync_end(error). - -sync_end(Result) -> - receive - {stop, Reference, ReplyTo} -> - ReplyTo ! {result, Reference, Result}, - ok - end. - -%%------------------------------------------ -%% Print and collect information during run -%%------------------------------------------ -print_progress(Data, St) -> - TID = proplists:get_value(id, Data), - case proplists:get_value(status, Data) of - ok -> - print_progress_success(St), - St; - {skipped, _Reason} -> - print_progress_skipped(St), - St#state{skips=[TID|St#state.skips]}; - {error, Exception} -> - print_progress_failed(Exception, St), - St#state{failures=[TID|St#state.failures]} - end. - -record_timing(Data, State=#state{timings=T, profile=true}) -> - TID = proplists:get_value(id, Data), - case lists:keyfind(time, 1, Data) of - {time, Int} -> - %% It's a min-heap, so we insert negative numbers instead - %% of the actuals and normalize when we report on them. - T1 = insert(-Int, TID, T), - State#state{timings=T1}; - false -> - State - end; -record_timing(_Data, State) -> - State. - -print_progress_success(St) -> - print_colored(".", ?GREEN, St). - -print_progress_skipped(St) -> - print_colored("*", ?YELLOW, St). - -print_progress_failed(_Exc, St) -> - print_colored("F", ?RED, St). - -merge_on_end(Data, Dict) -> - ID = proplists:get_value(id, Data), - dict:update(ID, - fun(Old) -> - orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) - end, Dict). - -merge_data(_K, undefined, X) -> X; -merge_data(_K, X, undefined) -> X; -merge_data(_K, _, X) -> X. - -%%------------------------------------------ -%% Print information at end of run -%%------------------------------------------ -print_failures(#state{failures=[]}) -> - ok; -print_failures(#state{failures=Fails}=State) -> - io:nl(), - io:fwrite("Failures:~n",[]), - lists:foldr(print_failure_fun(State), 1, Fails), - ok. - -print_failure_fun(#state{status=Status}=State) -> - fun(Key, Count) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:fwrite("~n ~p) ~ts~n", [Count, TestId]), - print_failure_reason(proplists:get_value(status, TestData), - proplists:get_value(output, TestData), - State), - io:nl(), - Count + 1 - end. - -print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> - X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), - print_colored(X, ?CYAN, State); -print_gleam_location(_, _) -> - ok. - -inspect(X) -> - gleam@string:inspect(X). - -print_gleam_failure_reason( - #{gleam_error := assert, message := Message, value := Value}, - State -) -> - print_colored(indent(5, "~s~n", [Message]), ?RED, State), - print_colored(indent(5, " value: ", []), ?RED, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); -print_gleam_failure_reason( - #{gleam_error := todo, message := Message}, - State -) -> - print_colored(indent(5, "todo expression run~n", []), ?RED, State), - print_colored(indent(5, " message: ", []), ?RED, State), - print_colored(indent(0, "~s~n", [Message]), ?RESET, State); -print_gleam_failure_reason(Error, State) -> - print_colored(indent(5, "~p~n", [Error]), ?RED, State). - -% New Gleeunit specific formatters -print_failure_reason( - {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State -) when is_list(Stack) -> - print_gleam_failure_reason(Error, State), - print_gleam_location(Error, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "No case clause matched~n", []), ?RED, State), - print_colored(indent(5, "Value: ", []), ?CYAN, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -% From the original Erlang version -print_failure_reason({skipped, Reason}, _Output, State) -> - print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), - ?RED, State); -print_failure_reason({error, {_Class, Term, _}}, Output, State) when - is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> - print_assertion_failure(Term, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, Reason}, Output, State) -> - print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), - print_failure_output(5, Output, State). - -gleam_format_module_name(Module) -> - string:replace(atom_to_list(Module), "@", "/", all). - -print_stack(Stack, State) -> - print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), - print_stackframes(Stack, State). -print_stackframes([{eunit_test, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> - GleamModule = gleam_format_module_name(Module), - print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), - print_stackframes(Stack, State); -print_stackframes([], _State) -> - ok. - - -print_failure_output(_, <<>>, _) -> ok; -print_failure_output(_, undefined, _) -> ok; -print_failure_output(Indent, Output, State) -> - print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). - -print_assertion_failure({Type, Props}, State) -> - FailureDesc = format_assertion_failure(Type, Props, 5), - print_colored(FailureDesc, ?RED, State), - io:nl(). - -print_pending(#state{skips=[]}) -> - ok; -print_pending(#state{status=Status, skips=Skips}=State) -> - io:nl(), - io:fwrite("Pending:~n", []), - lists:foreach(fun(ID) -> - Info = dict:fetch(ID, Status), - case proplists:get_value(reason, Info) of - undefined -> - ok; - Reason -> - print_pending_reason(Reason, Info, State) - end - end, lists:reverse(Skips)), - io:nl(). - -print_pending_reason(Reason0, Data, State) -> - Text = case proplists:get_value(type, Data) of - group -> - io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); - test -> - io_lib:format(" ~ts~n", [format_test_identifier(Data)]) - end, - Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), - print_colored(Text, ?YELLOW, State), - print_colored(Reason, ?CYAN, State). - -print_profile(#state{timings=T, status=Status, profile=true}=State) -> - TopN = take(10, T), - TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), - TLG = dict:fetch([], Status), - TotalTime = proplists:get_value(time, TLG), - if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> - TopNPct = (TopNTime / TotalTime) * 100, - io:nl(), io:nl(), - io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), - lists:foreach(print_timing_fun(State), TopN), - io:nl(); - true -> ok - end; -print_profile(#state{profile=false}) -> - ok. - -print_timing(#state{status=Status}) -> - TLG = dict:fetch([], Status), - Time = proplists:get_value(time, TLG), - io:nl(), - io:fwrite("Finished in ~ts~n", [format_time(Time)]), - ok. - -print_results(Data, State) -> - Pass = proplists:get_value(pass, Data, 0), - Fail = proplists:get_value(fail, Data, 0), - Skip = proplists:get_value(skip, Data, 0), - Cancel = proplists:get_value(cancel, Data, 0), - Total = Pass + Fail + Skip + Cancel, - {Color, Result} = if Fail > 0 -> {?RED, error}; - Skip > 0; Cancel > 0 -> {?YELLOW, error}; - Pass =:= 0 -> {?YELLOW, ok}; - true -> {?GREEN, ok} - end, - print_results(Color, Total, Fail, Skip, Cancel, State), - sync_end(Result). - -print_results(Color, 0, _, _, _, State) -> - print_colored(Color, "0 tests\n", State); -print_results(Color, Total, Fail, Skip, Cancel, State) -> - SkipText = format_optional_result(Skip, "skipped"), - CancelText = format_optional_result(Cancel, "cancelled"), - Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), - print_colored(Text, Color, State). - -print_timing_fun(#state{status=Status}=State) -> - fun({Time, Key}) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:nl(), - io:fwrite(" ~ts~n", [TestId]), - print_colored([" "|format_time(abs(Time))], ?CYAN, State) - end. - -%%------------------------------------------ -%% Print to the console with the given color -%% if enabled. -%%------------------------------------------ -print_colored(Text, Color, #state{colored=true}) -> - io:fwrite("~s~ts~s", [Color, Text, ?RESET]); -print_colored(Text, _Color, #state{colored=false}) -> - io:fwrite("~ts", [Text]). - -%%------------------------------------------ -%% Generic data formatters -%%------------------------------------------ -format_function_name(M, F) -> - M1 = gleam_format_module_name(M), - io_lib:format("~ts.~ts", [M1, F]). - -format_optional_result(0, _) -> - []; -format_optional_result(Count, Text) -> - io_lib:format(", ~p ~ts", [Count, Text]). - -format_test_identifier(Data) -> - {Mod, Fun, _} = proplists:get_value(source, Data), - Line = case proplists:get_value(line, Data) of - 0 -> ""; - L -> io_lib:format(":~p", [L]) - end, - Desc = case proplists:get_value(desc, Data) of - undefined -> ""; - DescText -> io_lib:format(": ~ts", [DescText]) - end, - io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). - -format_time(undefined) -> - "? seconds"; -format_time(Time) -> - io_lib:format("~.3f seconds", [Time / 1000]). - -format_pending_reason({module_not_found, M}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Module '~ts' missing", [M1]); -format_pending_reason({no_such_function, {M,F,_}}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); -format_pending_reason({exit, Reason}) -> - io_lib:format("Related process exited with reason: ~p", [Reason]); -format_pending_reason(Reason) -> - io_lib:format("Unknown error: ~p", [Reason]). - -%% @doc Formats all the known eunit assertions, you're on your own if -%% you make an assertion yourself. -format_assertion_failure(Type, Props, I) when Type =:= assertion_failed - ; Type =:= assert -> - Keys = proplists:get_keys(Props), - HasEUnitProps = ([expression, value] -- Keys) =:= [], - HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], - if - HasEUnitProps -> - [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), - indent(I, " expected: true~n", []), - case proplists:get_value(value, Props) of - false -> - indent(I, " got: false", []); - {not_a_boolean, V} -> - indent(I, " got: ~p", [V]) - end]; - HasHamcrestProps -> - [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), - indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), - indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; - true -> - [indent(I, "Failure: unknown assert: ~p", [Props])] - end; - -format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed - ; Type =:= assertMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed - ; Type =:= assertNotMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected not: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed - ; Type =:= assertEqual -> - Expected = inspect(proplists:get_value(expected, Props)), - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were not equal~n", []), - indent(I, "expected: ~ts~n", [Expected]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed - ; Type =:= assertNotEqual -> - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were equal~n", []), - indent(I, "expected: not ~ts~n,", [Value]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertException_failed - ; Type =:= assertException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA - [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - case proplists:is_defined(unexpected_success, Props) of - true -> - [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), - indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; - false -> - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, " expected: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])] - end]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed - ; Type =:= assertNotException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - indent(I, " expected not: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])]; - -format_assertion_failure(Type, Props, I) when Type =:= command_failed - ; Type =:= command -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed - ; Type =:= assertCmd -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed - ; Type =:= assertCmdOutput -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_output, Props), - Output = proplists:get_value(output, Props), - [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: ~p~n", [Expected]), - indent(I, " got: ~p", [Output])]; - -format_assertion_failure(Type, Props, I) -> - indent(I, "~p", [{Type, Props}]). - -indent(I, Fmt, Args) -> - io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). - -extract_exception_pattern(Str) -> - ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), - {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glenvy/LICENSE b/test-community-packages-javascript/build/packages/glenvy/LICENSE deleted file mode 100644 index b96ba24ed35..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Marshall Bowers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glenvy/README.md b/test-community-packages-javascript/build/packages/glenvy/README.md deleted file mode 100644 index ac251f80ec8..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# glenvy - -[![Package Version](https://img.shields.io/hexpm/v/glenvy)](https://hex.pm/packages/glenvy) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glenvy/) - -🏞️ A pleasant way to interact with your environment. - -## Installation - -```sh -gleam add glenvy -``` - -## Usage - -```gleam -import gleam/io -import gleam/result.{try} -import glenvy/dotenv -import glenvy/env - -pub fn main() { - let _ = dotenv.load() - - use hello <- try(env.get_string("HELLO")) - - io.println("HELLO=" <> hello) - - Ok(Nil) -} -``` diff --git a/test-community-packages-javascript/build/packages/glenvy/gleam.toml b/test-community-packages-javascript/build/packages/glenvy/gleam.toml deleted file mode 100644 index c1f7effe367..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "glenvy" -version = "0.4.0" -description = "A pleasant way to interact with your environment." -licences = ["MIT"] -repository = { type = "github", user = "maxdeviant", repo = "glenvy" } - -[dependencies] -gleam_stdlib = "~> 0.29" -gleam_erlang = "~> 0.19" -glx = "~> 0.2" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl b/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl deleted file mode 100644 index a6b1bdc2a61..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl +++ /dev/null @@ -1 +0,0 @@ --record(io, {message :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src b/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src deleted file mode 100644 index 5c82e5464a5..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src +++ /dev/null @@ -1,16 +0,0 @@ -{application, glenvy, [ - {vsn, "0.4.0"}, - {applications, [gleam_erlang, - gleam_stdlib, - gleeunit, - glx]}, - {description, "A pleasant way to interact with your environment."}, - {modules, [glenvy@dotenv, - glenvy@env, - glenvy@error, - glenvy@internal@file, - glenvy@internal@os, - glenvy@internal@parser, - glenvy@internal@string]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam deleted file mode 100644 index 9cda7d92bcc..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam +++ /dev/null @@ -1,42 +0,0 @@ -//// Support for `.env` files. - -import gleam/list -import gleam/map -import gleam/result.{try} -import glenvy/error.{Error} -import glenvy/internal/file -import glenvy/internal/os -import glenvy/internal/parser - -/// Loads the `.env` file. -pub fn load() -> Result(Nil, Error) { - load_from(".env") -} - -/// Loads the file at the specified path as a `.env` file. -pub fn load_from(path filepath: String) -> Result(Nil, Error) { - use env_file <- try(find(filepath)) - - let env_vars = - env_file - |> parser.parse_env_file - - env_vars - |> map.to_list - |> list.each(fn(env_var) { - let #(key, value) = env_var - - os.set_env(key, value) - }) - - Ok(Nil) -} - -fn find(filepath: String) -> Result(String, Error) { - use contents <- try( - file.read(filepath) - |> result.map_error(error.Io), - ) - - Ok(contents) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam deleted file mode 100644 index 927a88e973a..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam +++ /dev/null @@ -1,81 +0,0 @@ -//// Strongly-typed access to environment variables. - -import gleam/float -import gleam/int -import gleam/result.{try} -import gleam/string -import glenvy/internal/os - -/// Returns the value for the environment variable with the given name as a `String`. -pub fn get_string(name: String) -> Result(String, Nil) { - os.get_env(name) -} - -/// Returns the value for the environment variable with the given name. -/// -/// Uses the provided `parser` to parse the value. -/// -/// Returns `Error(Nil)` if the provided `parser` returns `Error(Nil)`. -pub fn get( - name: String, - parser parse: fn(String) -> Result(a, Nil), -) -> Result(a, Nil) { - use value <- try(get_string(name)) - - value - |> parse -} - -/// Returns the value for the environment variable with the given name as an `Int`. -/// -/// Returns `Error(Nil)` if the environment variable cannot be parsed as an `Int`. -pub fn get_int(name: String) -> Result(Int, Nil) { - name - |> get(parser: int.parse) -} - -/// Returns the value for the environment variable with the given name as a `Float`. -/// -/// Returns `Error(Nil)` if the environment variable cannot be parsed as a `Float`. -pub fn get_float(name: String) -> Result(Float, Nil) { - name - |> get(parser: float.parse) -} - -/// Returns the value for the environment variable with the given name as a `Bool`. -/// -/// The following values are parsed as `True`: -/// - `true` -/// - `t` -/// - `yes` -/// - `y` -/// - `1` -/// -/// The following values are pased as `False`: -/// - `false` -/// - `f` -/// - `no` -/// - `n` -/// - `0` -/// -/// The parsing is case-insensitive. -/// -/// Returns `Error(Nil)` if the environment variable cannot be parsed as a `Bool`. -/// -/// Use `get` if you want to provide your own parser. -pub fn get_bool(name: String) -> Result(Bool, Nil) { - let parse_bool = fn(value) { - let value = - value - |> string.lowercase - - case value { - "true" | "t" | "yes" | "y" | "1" -> Ok(True) - "false" | "f" | "no" | "n" | "0" -> Ok(False) - _ -> Error(Nil) - } - } - - name - |> get(parser: parse_bool) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam deleted file mode 100644 index bdd8726251a..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam +++ /dev/null @@ -1,5 +0,0 @@ -/// An error that occurred while reading a `.env` file. -pub type Error { - /// An IO error. - Io(message: String) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam deleted file mode 100644 index 125217a90fd..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam +++ /dev/null @@ -1,15 +0,0 @@ -if erlang { - import gleam/erlang/file - import gleam/result - import gleam/string - - pub fn read(from path: String) -> Result(String, String) { - file.read(from: path) - |> result.map_error(string.inspect) - } -} - -if javascript { - pub external fn read(from: String) -> Result(String, String) = - "../../glenvy_ffi.mjs" "read_file" -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam deleted file mode 100644 index 898a91b7aa2..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam +++ /dev/null @@ -1,26 +0,0 @@ -if erlang { - import gleam/erlang/os - - pub fn get_env(name: String) -> Result(String, Nil) { - os.get_env(name) - } - - pub fn set_env(name: String, value: String) -> Nil { - os.set_env(name, value) - } - - pub fn unset_env(name: String) -> Nil { - os.unset_env(name) - } -} - -if javascript { - pub external fn get_env(name: String) -> Result(String, Nil) = - "../../glenvy_ffi.mjs" "get_env" - - pub external fn set_env(name: String, value: String) -> Nil = - "../../glenvy_ffi.mjs" "set_env" - - pub external fn unset_env(name: String) -> Nil = - "../../glenvy_ffi.mjs" "unset_env" -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam deleted file mode 100644 index a5d478386c4..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam +++ /dev/null @@ -1,69 +0,0 @@ -//// A `.env` file parser. - -import gleam/list -import gleam/map.{Map} -import gleam/result.{try} -import gleam/string -import glenvy/internal/string as glenvy_string -import glx/stringx - -/// Parses a `.env` file into its contained environment variables. -pub fn parse_env_file(contents: String) -> Map(String, String) { - let lines = stringx.lines(contents) - - let env_vars = - lines - |> list.filter_map(parse_line) - |> map.from_list - - env_vars -} - -/// Parses a single line from a `.env` file into the key and the value. -fn parse_line(line: String) -> Result(#(String, String), Nil) { - use line <- try(skip_line_comment(line)) - - use #(key, value) <- try( - line - |> string.split_once(on: "="), - ) - - use value <- try(strip_comments(value)) - - let value = - value - |> string.trim - |> unquote(quote: "'") - |> unquote(quote: "\"") - - Ok(#(key, value)) -} - -/// Skips a line that starts with a comment. -fn skip_line_comment(line: String) -> Result(String, Nil) { - case - line - |> string.starts_with("#") - { - False -> Ok(line) - True -> Error(Nil) - } -} - -/// Strips the comments out of the given line. -fn strip_comments(line: String) -> Result(String, Nil) { - case - line - |> string.split_once(on: "#") - { - Ok(#(value, _)) -> Ok(value) - Error(Nil) -> Ok(line) - } -} - -/// Unquotes the given string using the specified quote character. -fn unquote(line: String, quote quote_char: String) -> String { - line - |> glenvy_string.trim_chars_left(quote_char) - |> glenvy_string.trim_chars_right(quote_char) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam deleted file mode 100644 index 38d775ac6a5..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam +++ /dev/null @@ -1,33 +0,0 @@ -//// Extensions to `gleam/string`. - -import gleam/string - -/// Returns the given string after trimming the indicated characters from the left. -pub fn trim_chars_left(value: String, trim chars_to_trim: String) -> String { - case - string.is_empty(chars_to_trim) || !string.starts_with(value, chars_to_trim) - { - True -> value - False -> - value - |> string.slice( - at_index: string.length(chars_to_trim), - length: string.length(value), - ) - } -} - -/// Returns the given string after trimming the indicated characters from the right. -pub fn trim_chars_right(value: String, trim chars_to_trim: String) -> String { - case - string.is_empty(chars_to_trim) || !string.ends_with(value, chars_to_trim) - { - True -> value - False -> - value - |> string.slice( - at_index: 0, - length: string.length(value) - string.length(chars_to_trim), - ) - } -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl deleted file mode 100644 index e5405238329..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl +++ /dev/null @@ -1,40 +0,0 @@ --module(glenvy@dotenv). --compile([no_auto_import, nowarn_unused_vars]). - --export([load_from/1, load/0]). - --spec find(binary()) -> {ok, binary()} | {error, glenvy@error:error()}. -find(Filepath) -> - gleam@result:'try'( - begin - _pipe = glenvy@internal@file:read(Filepath), - gleam@result:map_error(_pipe, fun(Field@0) -> {io, Field@0} end) - end, - fun(Contents) -> {ok, Contents} end - ). - --spec load_from(binary()) -> {ok, nil} | {error, glenvy@error:error()}. -load_from(Filepath) -> - gleam@result:'try'( - find(Filepath), - fun(Env_file) -> - Env_vars = begin - _pipe = Env_file, - glenvy@internal@parser:parse_env_file(_pipe) - end, - _pipe@1 = Env_vars, - _pipe@2 = gleam@map:to_list(_pipe@1), - gleam@list:each( - _pipe@2, - fun(Env_var) -> - {Key, Value} = Env_var, - glenvy@internal@os:set_env(Key, Value) - end - ), - {ok, nil} - end - ). - --spec load() -> {ok, nil} | {error, glenvy@error:error()}. -load() -> - load_from(<<".env"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl deleted file mode 100644 index a70577b44a5..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl +++ /dev/null @@ -1,69 +0,0 @@ --module(glenvy@env). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_string/1, get/2, get_int/1, get_float/1, get_bool/1]). - --spec get_string(binary()) -> {ok, binary()} | {error, nil}. -get_string(Name) -> - glenvy@internal@os:get_env(Name). - --spec get(binary(), fun((binary()) -> {ok, FNV} | {error, nil})) -> {ok, FNV} | - {error, nil}. -get(Name, Parse) -> - gleam@result:'try'(get_string(Name), fun(Value) -> _pipe = Value, - Parse(_pipe) end). - --spec get_int(binary()) -> {ok, integer()} | {error, nil}. -get_int(Name) -> - _pipe = Name, - get(_pipe, fun gleam@int:parse/1). - --spec get_float(binary()) -> {ok, float()} | {error, nil}. -get_float(Name) -> - _pipe = Name, - get(_pipe, fun gleam@float:parse/1). - --spec get_bool(binary()) -> {ok, boolean()} | {error, nil}. -get_bool(Name) -> - Parse_bool = fun(Value) -> - Value@1 = begin - _pipe = Value, - gleam@string:lowercase(_pipe) - end, - case Value@1 of - <<"true"/utf8>> -> - {ok, true}; - - <<"t"/utf8>> -> - {ok, true}; - - <<"yes"/utf8>> -> - {ok, true}; - - <<"y"/utf8>> -> - {ok, true}; - - <<"1"/utf8>> -> - {ok, true}; - - <<"false"/utf8>> -> - {ok, false}; - - <<"f"/utf8>> -> - {ok, false}; - - <<"no"/utf8>> -> - {ok, false}; - - <<"n"/utf8>> -> - {ok, false}; - - <<"0"/utf8>> -> - {ok, false}; - - _ -> - {error, nil} - end - end, - _pipe@1 = Name, - get(_pipe@1, Parse_bool). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl deleted file mode 100644 index 69e5d489294..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(glenvy@error). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([error/0]). - --type error() :: {io, binary()}. - - diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl deleted file mode 100644 index d442cb7aa15..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl +++ /dev/null @@ -1,9 +0,0 @@ --module(glenvy@internal@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([read/1]). - --spec read(binary()) -> {ok, binary()} | {error, binary()}. -read(Path) -> - _pipe = gleam@erlang@file:read(Path), - gleam@result:map_error(_pipe, fun gleam@string:inspect/1). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl deleted file mode 100644 index 9794d8dd6f7..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl +++ /dev/null @@ -1,16 +0,0 @@ --module(glenvy@internal@os). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_env/1, set_env/2, unset_env/1]). - --spec get_env(binary()) -> {ok, binary()} | {error, nil}. -get_env(Name) -> - gleam_erlang_ffi:get_env(Name). - --spec set_env(binary(), binary()) -> nil. -set_env(Name, Value) -> - gleam_erlang_ffi:set_env(Name, Value). - --spec unset_env(binary()) -> nil. -unset_env(Name) -> - gleam_erlang_ffi:unset_env(Name). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl deleted file mode 100644 index c271f7e9800..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(glenvy@internal@parser). --compile([no_auto_import, nowarn_unused_vars]). - --export([parse_env_file/1]). - --spec skip_line_comment(binary()) -> {ok, binary()} | {error, nil}. -skip_line_comment(Line) -> - case begin - _pipe = Line, - gleam@string:starts_with(_pipe, <<"#"/utf8>>) - end of - false -> - {ok, Line}; - - true -> - {error, nil} - end. - --spec strip_comments(binary()) -> {ok, binary()} | {error, nil}. -strip_comments(Line) -> - case begin - _pipe = Line, - gleam@string:split_once(_pipe, <<"#"/utf8>>) - end of - {ok, {Value, _}} -> - {ok, Value}; - - {error, nil} -> - {ok, Line} - end. - --spec unquote(binary(), binary()) -> binary(). -unquote(Line, Quote_char) -> - _pipe = Line, - _pipe@1 = glenvy@internal@string:trim_chars_left(_pipe, Quote_char), - glenvy@internal@string:trim_chars_right(_pipe@1, Quote_char). - --spec parse_line(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -parse_line(Line) -> - gleam@result:'try'( - skip_line_comment(Line), - fun(Line@1) -> - gleam@result:'try'( - begin - _pipe = Line@1, - gleam@string:split_once(_pipe, <<"="/utf8>>) - end, - fun(_use0) -> - {Key, Value} = _use0, - gleam@result:'try'( - strip_comments(Value), - fun(Value@1) -> - Value@2 = begin - _pipe@1 = Value@1, - _pipe@2 = gleam@string:trim(_pipe@1), - _pipe@3 = unquote(_pipe@2, <<"'"/utf8>>), - unquote(_pipe@3, <<"\""/utf8>>) - end, - {ok, {Key, Value@2}} - end - ) - end - ) - end - ). - --spec parse_env_file(binary()) -> gleam@map:map_(binary(), binary()). -parse_env_file(Contents) -> - Lines = glx@stringx:lines(Contents), - Env_vars = begin - _pipe = Lines, - _pipe@1 = gleam@list:filter_map(_pipe, fun parse_line/1), - gleam@map:from_list(_pipe@1) - end, - Env_vars. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl deleted file mode 100644 index eece3a111bc..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl +++ /dev/null @@ -1,40 +0,0 @@ --module(glenvy@internal@string). --compile([no_auto_import, nowarn_unused_vars]). - --export([trim_chars_left/2, trim_chars_right/2]). - --spec trim_chars_left(binary(), binary()) -> binary(). -trim_chars_left(Value, Chars_to_trim) -> - case gleam@string:is_empty(Chars_to_trim) orelse not gleam@string:starts_with( - Value, - Chars_to_trim - ) of - true -> - Value; - - false -> - _pipe = Value, - gleam@string:slice( - _pipe, - gleam@string:length(Chars_to_trim), - gleam@string:length(Value) - ) - end. - --spec trim_chars_right(binary(), binary()) -> binary(). -trim_chars_right(Value, Chars_to_trim) -> - case gleam@string:is_empty(Chars_to_trim) orelse not gleam@string:ends_with( - Value, - Chars_to_trim - ) of - true -> - Value; - - false -> - _pipe = Value, - gleam@string:slice( - _pipe, - 0, - gleam@string:length(Value) - gleam@string:length(Chars_to_trim) - ) - end. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs b/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs deleted file mode 100644 index 0e641dbc1e0..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs +++ /dev/null @@ -1,32 +0,0 @@ -import { Ok, Error } from "./gleam.mjs"; -import { readFileSync } from "node:fs"; - -const Nil = undefined; - -export function get_env(name) { - if (process.env[name]) { - return new Ok(process.env[name]); - } else { - return new Error(Nil); - } -} - -export function set_env(name, value) { - process.env[name] = value; - - return Nil; -} - -export function unset_env(name) { - delete process.env[name]; - - return Nil; -} - -export function read_file(path) { - try { - return new Ok(readFileSync(path, "utf-8")); - } catch (error) { - return new Error(error.message || ""); - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/README.md b/test-community-packages-javascript/build/packages/glerm/README.md deleted file mode 100644 index ffefb5af462..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# glerm - -[![Package Version](https://img.shields.io/hexpm/v/glerm)](https://hex.pm/packages/glerm) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glerm/) - -A Gleam wrapper around `crossterm` to create terminal applications - -## Quick start - -### Caveats - -Currently, this only works on Linux. Gleam doesn't support any mechanism to -build the NIFs on your machine. To get around this for now, I am shipping -pre-compiled library files in the `priv/` directory. - -The `.dll` for windows does actually allow the program to run. Most of the -methods seem to work, but unfortunately the blocking `event::read()` call -just hangs. I expect this is some interaction between `erlang`, `crossterm`, -and Windows. I may try to look more into this, but right now I don't really -know what the issue is. Would love some help with this if possible! - -I tried to build this on my Intel Macbook, but got some errors from `rustler`. -I'm not sure if that's not considered a supported platform anymore by them, -but it's also currently not working. Any help with that would also be -appreciated. - -I don't have access to anything ARM, so unfortunately will not be able to -provide anything in that regard. - -### Getting started - -The docs should hopefully be helpful. Additionally, there is at least one -example usage in `examples/` that you can run with `gleam run` (if you are -using a version of Gleam that supports path dependencies). - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add glerm -``` - -and its documentation can be found at <https://hexdocs.pm/glerm>. diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache deleted file mode 100644 index 92df63b06d41e6efd65b6315a7f45eecda1989b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62841 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta deleted file mode 100644 index 698890486b4eefd538d84a817bea5b94838a49b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114 zcmbQ#@07{_11wMmCzMXlNlnbv&&(^~LJ`QxEH2?e5h*Sy%FIg_Ll%oq&d<#)&C4vQ U)KAXO$uBKRP|)c6$?53<0DaOL6#xJL diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache deleted file mode 100644 index 281d600331ef41cc683b222c82019938ad83533a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27832 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 Xr2;?H=(%Don|&{23S|@5-_QOJqO9cK diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta deleted file mode 100644 index 53e1ad9d70b13428390bf75760603d9fea78299d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmY%Gc1mS{0ahr36H2G&q$cL-XXce~qX?ws<R_N!pa>PE7MJFri4~U=W#*-Gp{UEr QEH0To^=sb0;|Fd400}J|+W-In diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache deleted file mode 100644 index e1d665bc07813583c29f571837c1676f1a4eae70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3072 zcmeH}&u<$=6vub$gmqSllBsE>AX%9jp*ohEbrSXBq;V2x5mMFGcBLR86p!tRy~^y4 zwL2TfMTi@Raw&fV{{zaA8wdC!IB@6I3o>tJe<UF(7?fizYdxBMyYKnU`+VQ4&SiGZ z_2n|c4@~^v)BG={i3?}>pUr!DlrtxN&Zv9X6<OB}Jx7l1uHYi{ZQAX!AaFX)B8T17 z48>-L^~i2Fv$vGNg=T}GZ2nL5vYCP3y_sg~lNnh2G4rbR1{M<@x{gP^u7MarjrmNr zF+j5zS%!g-Vc<EtQO#rxqcH<lgy(8_?hIqI{;`hbigP=5{yehYz;p05R~~ag<%<48 zaAy`FjGL_&2%&XcMtNAQ7tU^73?+T>zx;X9WHR)<;4>lzjQEUG>6|dq@tyuadXOd} zj`XcQY<r{~h217JAe6LqSZ&f_a>STtk?LBtLa5gx>uXgqa^yhmz-`Ct>zDMXf6M|& zhC=0^GZJMwedOGdEB|1+W?5vr$0T)lumj5=bY1F?cOIQmcgR_7+fH`Cu-$I!6j|iR zBP_Bgt&*=SLP&B<tQ7fN8x0)ER*7w^U@h{sejGg5sW;`>IU#`@bM~+ZF+0)`UM<bi zRuLjnpKW^8h;{<OL&>%XXGgL|s#`@e@Y&JB;y}t_P_ykm<R|Q`b%kr|sPDt-a-ljw z5V9cgqCEvJ<$R|#6cX|;$3syk&xUX?)FayZE+j;o#F5!_su=ZgUkviYYrO8$?lF-9 zzC-fcx8GmqY1^(t%62TvK$}0z|2jYE3QzhpkVgH`htd);BCjtYa?to(Ba+iaU#J1Z z_#+c&NtRR4GKGo4?`=S3Fn-zUB|yDaK>d`z68(Rr>Zz{!BnJs6M2^HcNhg%UAzurW zs?3U|>DWk#Qj3TaPXIqrdX-IuXrpt62EfqYXp5|G464L^bhf2f2Wm0a5n@^p(yb1M zBGS~UVBcW}Dt9B;CDftkP{SFF?(O9=cwryUBfL<A>o@V)7={U@g3#uVOYh-{<4NX$ ztQlww9ZL1C_9ZawMoEJi_pa;V`6sMYpK4U1Hiatyv~|(vlsFlgO`7{IH*x8y<A&}b zO3F^PSRM77OHm&*PTwLYWn9?61$zpuSbX9Hal`$8og4Z*r0byGWI@Q2H(eFDqK;^q zalm})@Cy?F2-d4eux`Ty04KVBx0AmvMN=kul1u_mv}UD^UUzXd8zgFyB>!B^;AV#g zES0oaveX=)9u#o#$<P-kPLK6cD-sFcjcHL*9Z7s8-2vlfKW3bZ5d;RGFD?!Ml|-x5 zXmZ#ADNc9#KFl;<s%KW;>C_GClo^c&zrVkG8%As;Q#HJB2QQcL@|_qLJo^Ej-N-&W dUU}sE!e87Mg5%jT>@B|VL$>mm@_;R&zW|Mmo`C=W diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta deleted file mode 100644 index e926edf4bd2ba9772666976608cd9c70fb8c7d63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmY%Gc1mS{0cI$J8%n3=q$cL-r{&})mT;j6<zyC@h#`x_C+FwpmgZ%aRO%<^=j4|b NZJ%QI>{9;O9{>a>7(@U7 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache deleted file mode 100644 index fec2276ac9ed8a761261ebb7794f915b24598595..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8464 zcmc&(OK%(373Lk1qC`uUuNgU(Vb|A8(%6J#T2vMdk(j0&<ssOyDay5L#Gr=cNE(Tp zVP=Mw>5ZFgni@qHDGD@37meWnX<(qK+M+;LZGZrU(E>r6EE)v;0a+E<w9SV7&Yj_F zsF%}MkTEaCnRCy%=icx8&Y5E@6#RbhOoWfG@+X$3XO&;G*yjfr=c}>AAr>nhX3gb_ zrdE@h6&S6k#<Kgh(E6G^sPM^++*2&XUrXe^jgJpkbH8Vy7-y;cK8C?1HkZFbgSXjy z{vHO+S;MYdTDHO}c}KMzt$cLWvP_Gy+(9MCvk@L%<wH^5ya9y|ZNM!)7TL;x?}>{_ z5dV+n)g>(ukfxvB+H`^st@4qGyn9nS%@;K1oNj2dfzd8!pWWIb%&l@B@jbVx?W1Qc z)n4)9-^R(5>!f@8rk0uudR4n*=uRLI@a%2l;+*GV*F&3Io!6E$OEXFVrtNHX-m}{E z(56<i6@`D2&V9^+u`Da*pJN#Oiap5xmIi-R?&d#MFnBF^C;vtegKME;eldi>)8Tmj z8(|FI32)@@)8MUvV*bYi7>q<_^1~4fejb_2|B?pbp*#8EAq@VxC!PPt9t^bMbiO={ z!O%!LKRANHA;w}UT>FD8mcX@t0H3%%kFeO6xIP_Zu`h6KL|N<suHWpzC$9Jii=}Z{ zds*yFT-H7odmUFX#$q>dZ9Kwae|m&vUN)ao9Tf{VtORqXSeUaY?dIKX5Uwbkr*nrH z<ATY@qMk|LvIdmtJs}=yp4Us3X=|lG#5Br%)9xziTnTYr%n8i-IFtE|_L}XVdO2)` zo7q~eqL)-h(M{udRj+8}1yde!xg9C~AGz^kcLoA{=yGmB3F34P;$Oy(B>0gx`4bTu z&hR4^KNcCyI%c&!86yNrs*cI3ING<KYZz)(FL^(g8-b(pJAQ(NhewMsg;x4O?l_{p z!uZ%KACGPqQQIvS87ahzj4_3?C$obJA4&6JtX%^CW-Lv$O@pyfI0!VF{@&i-?QJe= zPQeBOGN+(g%k`=jF&rC<LCaL>S*D0wpnw+`unI_!96hJo&QXcZxsV$&a=SqQd3Hs$ zD)<#B(00;YyV8n!RQ?282$SEHIUY;U*5bfixKyjCIy1Ul8r2C<l<DYDe5iTJSToFZ zBg?!@>p_Z3`t0=hoXnk)sr6ig({BO}x69{OOd1xP-^o3WXr3e9;$zWGoop{eZ?+g` zk7h#(4<~r2ou0M5-`(4^8@8iW3r-*cO!Y!s*)GIgoh%A6E)y7uykvO!Lo&jYjbaWP zi1S1IBAXhy8SHf-XxdFNuQ_$gu!n`SqKQ)70xCP=LSDGe3J0#9j7G&XD~?mM(@D@a z9hsA+wVW)QrKDP`+4!4dC+W^Y$%KKDgTs1q#i>>vyO1yB-KaCf38$k0Hhpa1%s^z; zT<Qaohr+LT4}Ot7e?FAyaA+{ptQ$56yHI4hp<0cCV;(IynpO2?f7iGE6Wv=3>z@LL zH)nJwYguXoyWc$?-nmK3Wxt%6*X(+wb#gr9@!$s88ISYv6d#XlgD#Pm^-9~aOx%Xt ze?SbNCHCJILG*|GrE(?+V6EV={ul7N%WVJD-wKz*x1{jWS|s7$-94*2!-p)a?l#Lp zTYCqIG6qWLe5PkJw4CU7@x#GS1|=j_AiP{fL)hrw1joBKft%z=Chu6fvE0rQ`L<pD z)BH$^A0g%;*k8raZ(&CvCpW?zkQ*oXHh+Unjol4(d+){v<t&l7u(YHDopGSmvMp3D zC`PelnN<N!Fv_Y`7P?WZJ7QgTR^)MC)~{=ZsNt5HLx=n^F?&O;)+!pt`0unJ^d>XM z<L7Yb>*}(W7V#7E$7E7Wo)(=yKQk#LbI2brtR0WbZ?72f$cbpw<*_z0rh$wZcUn-_ z7omgUrY0qPL1mSSq%bGg-bA1Ij_6lmf$cH{jetxgk*Q}l`0OfwDY6L>?t*Q0Uq#5o z-pPLiZs%jSV}E08YW(h@P1j)a97_dc3tctDg@ua(AS^`^VE0Lz@>$YsTR4`cA>%UB zMYXiHY?*bVJRwwDtZS7DKBMwCy3ZEol2DCCw<%ayQJt=h(lw1JYc<WlKC9ON^&)FT z{f-EyQG;-+R2rhH)?nXoOreSwsP+@4C0^8Sh#I`Yo}#Vi(Gcz+nL*wVA9c;>d9#kP zf%Y?1c_+nL*vFy7y}B)y>V{;Vs91viu1DQCR@Cb-Sb=aVH$+jx#`nw!JgW-BoHT2~ zHbuj%i?WIDjxaQ>j5RVvX+<lo`8}fN9Sx>1owkA#Msd7kcp<K9NCZ_m^gJ1>+ZtKG zzdDYXUeX=W$x2Vs><Lk<J5lM$I-nd&vZi4jZHK;)Q)E+mFMVn!(6<+mXG?b+M5-e{ zCMLJU%xw0&AO@$yYzw<yTA>XwD_NcLGF#Da=+*=tDOKuacX6Tpz3-U1*oY$gODY)8 zMH2VfBqpZ?cpf&YSP(pbb*ZYP1%!>ANckiOp&Fn}4Xhohgs7P8Xp8mr^^-n*QB@7n z7_IH?s)`m^w6H=ePfnfwN|xjzPEJKm_hD3#53*)!W+*n(091W8GQKyH*Gm6h8RRRy zTzmawbus+SaK>FjPpmBXknnJer<f85x9F&kXC&IBQ76i}>lB3GD)a36CT*!f5mK?e zi0*`?VHex2bhS{z8HIu(Ew_)QSY~0xf`E5@<nICHqg1(|8dDg*N}nv*swZ~ld{0{K zK>HV2*kyj-TDq?I!a}9-i@^^DIlI{`dLl58F{KK;$WXM%TEnjadZfz#Q3&3Y^%SZQ z0TmGK3!p#LGs-O#j5nJ#OTS(y>sBBGL2g=&PN+ZeZKMCN+==tC6lzAl-09c2H*@!0 zX>%Xa=7YgLkKNe%^^Gi8;u275Dx?fiSBp!)e~T3PqCn_w;1gmU$fpVIhGP-V8<UcR zfQUdl7x$LXSO5v&rVeYZX|5=0Gm{}SYSamR2}WA;iFKgo5)rFkR#9Q@7gdXki=Ie2 z4P&y9YNg5b^?1D6C;)XxWVs59q*T&2t6H*Rq7MQbO1ifs=}Ec|Mx%m`-1Nl$3;Q{H zy(v)*^){m(0JQ)*xnJzb{chU;TWDa)-s?H^VyQ~L!lw9LRG7rgm|JPhEdxf0=r(%= zx}KD|5v;a%hj3*mD2*rr>Sfu2L_p5KTc8-Mue1ri2fZv1)8l_y5vn+CK^g<Jv<Q31 zI`oc9bS;jH*e407HikYO;w&NCu~-eSDKg=%26|`Pw`&Q>c%rAs*sQS&p!oy)2mpAs ziR=~#y8}Vh>CD%A@-F9IkpS*hj9nE&LLQ-{{|NbXDN}&5AwC3jdWa@XnA#iZ+(Dv) zG(U(kChD<4MmM4Mi)bbO?9UX#%c?<LKQj<C%AFn5={I6t*^s8n-fI#2;0RzY8-G_N zh_xGk-G+TnU<vEtTj*$}GqX2zh`i3k|EprsM=7ow{cgTJ_`akRY9^qoPzYpPa_KmH zrRS_Ab6s=|!gdq4Wq(1k_D#9vc$yzZvZ77@R2dgTux3AG?_=BDk=u^kV6xKziVIrR z&i1?C<Iv??t$X{;@nb3UM^OfiCuGASxoO|Sw+C_i4rhn%*qQd_uJncLC+kkQiZTt3 zOQQ>Fm+D$)#qae5n9M!Z7D%!=+<`kBogigktGclD`wlY1lUDcWEZye!fPlq8&#BGH z%PoJ(!qjZzNh))wK%ly7U2Tx4w^a0Pz*HrW51`(y1PB+YifUB=W(j>di10e-%0#KK z453eGxo%o(q}gPB?{<tt$t-IVZJ94`BfzBFT<$})<kd}Wcy0XwhEQ*Sbf`vvk1qW= zQtjanWf(WEqxVNJt-IwN5`wxQia6jiN*|O(qD1ea+(JUaI~Au9Oa@fGHh4pxp{ly3 z6;LfftI%7au8h9elhIBBX;<y)y%3SpTyBCs(tHBqcRy>krwh=8#1u_&7KI_IxgZpR zwl3<1{wkJN7I5Uy$tXlEoBqMR_x5pin~oVCDmaW7$U(~_&_%JmFC;oH6YKDyTLGyz z;r~>ePo?-2owyTmej>$B(C}E?J%>HL+^xS*T=The^l^xvLwGa6rsPF<6=1d9ws@%q zRE1MV?}y|R`p7oOmU_PZEnh0hOxvx*T2s{~Pe}#x*MYweaCSNSh{B)P$WAEyo%!s$ z3jfP$_A@0m!cu34nG$=N&7FOQDO>eRs8-;Uk5Yyo`u(iic+Z8H;=LG=#!e*2*e+T) z@}Xwedq($h%FFI{+Zn~z)$1~_>d_?>(7DcgUmvl6G0!OO`&jv?e0Q}|6BM&{ad6j^ zyJF}wfYR?|g~Fd*<=F%Le1f0f%X9Pm(g4q;dF}wemg3jG#$VmwjRX9x1b^!Qe`k*W z^y|Jzc{t9)X==oKFB7FgYH6<SMfLjSJbZ|UQ^5;s?%R4dXbH(c<r$Cuz2dUn(%s@! zKM&vGBM&xzO_SaF72@cOX;$b>O*l2WVAZvw&#M(%>t0OKNFznONa15wy~@A0z3zL9 M*)452i|k|n0tn9F4*&oF diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta deleted file mode 100644 index d76e6b61fe72a6e8f684b40640d58cd0bbc4a62a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122 zcmY$r>zv8}11wMmFO*KtNlnbvPpQmH%*{;ZLJ`c#EG`j55lJn|Nz6;vPb|sL6~!iz SoRL@r()E&cT71TzYp(%&E*``H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache deleted file mode 100644 index 95b84a6370bf85d384448e840a67e10752456d39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2814 zcmbW3TW{Mo6vsu`o@}9>L!{}@VL@28U2G%Eb$!XOChn3H1&XFl24p}{*s@LAY9z{_ zs9XjN+k!pyt$ysM*h60T4fZtb1N3qG6y6~zxoK`qW*D|aiHGO%JAZQiOLNu2w+Fa9 zjsM*le`8JKiC5zj*~jBi)*5y_>iBb%BhO*oIY$J@*JE|cje;DkW=)(ws*RyEb}F?7 zN)I=9;BO1=BGz5!Jm3aGwJ*#RUbk>&fb;fwMhz3^j&Oc}C#=!@R5Cwt;=K>g%@lkK zRT22H@#;s6S8#5Cv8AS*=YY0Yy=mh6uWBWf8qb(~J8QzluV!=mH+hjyzumr>hKrvv zTid^6P-@tLNbBuGW)vLXZGk5@%v9}fl)=b0AZo+Fxw+bmnKF!88h#PZJ;FJT^VZL6 zhfGe1J!u~rQ|cbPkZ&#H+#=5HtZdOR^2C&izm`?cCM$SyfbU!In!H@ZlXI8FRCwx! ziGkRKCeCxn#Bhzaf;L^}h6Ob`$B_&|7!PWH!r#Pe{0~~V-L!{5fM18Ok%}8aKyeJf zgJPuK>9~e5B;WODYd0h%5s;8lvfrbkM>%mwBM!Ym_8c#w#0`nVh_pKc7j43+h&Utg zwi+aE$0n|T*Jf>-+`UWI4;;Vm(Gc$7^N_fHKj4CBMxYilt?{FzJaVWMKbn<;r52}- zpfV7@9s;VYTPpUb=LN-bxvXYy?q2#*viikKEG#a?rc@J@UL^U3Y?tUkpSA>TFO#BV zxHv;PLB!<k6DHuU?}*+qdGWIR(kk0FLeCL=F#4>THgTqc)2JX9HjJgmHnWG)#Iry= zHKqcmP1`YtUuzDp-B{R!y7SsSSg?dtOP*QbyaqDNrQcJ3#61ByH7v+#?8@<}mMEQU z2@SioA|-=$HSE{xgCl$g<m=MjzM`lo=3m#2HS@>7{9oCV%xhMFZ-v`w<~Ll{2AYeE z&;w{Yh=$10KyA6=x$EvxMs%E#<|iG(f|&A96F^*z{+`Q4<aoq)T0NK1X)r4-38(4N zkv(lmnr60aA}ZBZHk9rm+P<J=KEOWMEnZ5zd=3oiX8T}f82Gf#=zd+g78}v5CqOD3 z%QmPXTKXpQLuQ!t9ZDJxG(Kje_dglAg0QQq{#bhlRmIEr9a_jYZw#9*bNFFh7%PDa zV1;tIzkqTnZ3yQRSt2rM5H4N&8K_W5xhk$hAo@hc7$}_-t+;ab`K5C^BeU&*hERV& z91m7(A8Keu#Z|D_@v5?rJCyiQC`gl%mcwZ$@}#OV5`_{p(Sy2oBGwXa0CE~iU$|CR z;<-L3sP@k$Eb^P6!~uAskm@-C3^LM@D*JKzX2~<UN4ZT}0fT=5>w`6y^&>eQ7Lir~ zSMbL5JndR6<(l4o7={I5n)K055|-pk`q|=6*t71~lABE{w1y(kGHsxXaG5_TDOX_P z{Wg0>d173I#zg=wZ!=m1zzt(XgEPWqOYK+TgxuP6LpC5aoYSx$u(pa{gCXdFfX?j0 z6Uv06>I6lQ%*3^B$i8V@(6k;EB-mA`l5ZhHXE(4>CqIN7Cfiy(MYnhnUP-B}9%SES z^~tR|X5#fqb<G?}<mlWc4=wmBdDOV(*=*HRXA(8Ptma>#BCDo!WfH{vQ(Ug#@-6&e z89%s%s})@R<g9ZT@zWb$;ZYEHa(~P$7QW{Zo!W4`kjAGdocSEaQ=7X}N~4s6W9UE5 CnKg0% diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta deleted file mode 100644 index bfd938d1e8461ba9d199d56502092e325f58afa6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50 ocmY$r>zv8}1B_4xFO*KtNlnbvPpQmH%*{+@4&1o8X5AD)0Ik{zS^xk5 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache deleted file mode 100644 index bcc6f81a0dfa2081c8eb92964871ea0f0b07c088..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 789 zcmb7?&rZTX5XN_Qsii~$6H<uA1UMM~BnCwjBNs%Y2QFIVP8KYsTH3fR2TwkMFW@71 z<YIgX6Q9D@sJq1jmzt1lcC))P`+dKeEq<KqxG~4Q3cl`?4rm3<htd;0Eqziwc08L; z8@2$C`%Yst;Z@<eVYE0O*n$+)MJGd1>sndJ#FrDEL=Zv%tS!p$N=I#u`CQstgrd>K z{2WbvIXf-<mNGdyS&I3dRRo4#L+cw@90h|g60T3ck;3bgSsrKzIpu>8G#b_kWrSE6 zIm4=oDx-x)6Ait6r&OG3QW@z)13-MY4&`EA;2|90Cd9H(f{!8_L^zPfhHk;<;`wFf zyQARVj%$6v{cs#GF|F~M3RXp}MS<KU5X{LDIQ{`f<FN>)ij3$|HHB<<nJmTU>d*<< z+y7*q%fcvyD<N?fRDX;tQe0c?j4i&5Y~ymzRdet_U)}0C?W|KY_t7k4y^GsxSZ`sy qT(}4V54C;NnuWfY+0|?Ah4!*yyJv?pFG6io#;}{m>Xi_ID8es7D$^VQ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta deleted file mode 100644 index 7996afcc06d5ef47b53a066d1ed8fc8ff6d3e41f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 WcmY$r>zvAf4*c?#2l@L(90veAT?HEe diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache deleted file mode 100644 index 4b38dc11252b6a5b8cd02c701e01e3383c6f92bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27622 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta deleted file mode 100644 index e194cadac1c0380e6695db697ed205c3b05b0877..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72 zcmaF#D<qWx2AH4>ekh%ulbV>TpOje=pIB6sSjmGTT$EZ|np2{1>gDVm*}3Nd>o*cc diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache deleted file mode 100644 index 724743b1b747f11d9798850084ff30365355adb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2992 zcmbtW&rjS&6!whQn6-j7PXv@yK};%8gGC_=NTo<oSQ4T(0vfYKB&jMGb_ej{wUO<m z;)E1Msv70AmtHH>9(t=(Rm!2aUV7@E&_hq{pODk`&3HE9R~Dj5h#f!AkN3XsoA3En zlg`?3tqCKa^e&QbdT-=Eg1%bskNMT!VaIN51%lVdMN9%7ZjFagm5401CSs!?gQZIp z`dse{$pNo<Rs8vN*?UEDg{7z}2=T5{6G}E%P3UpX+RmVmcOl;du+@^Y<~*b({<ZE# zVJIr;yithbDAs$=pR;!jdYaH@pIF@ClzY)qlr9KvkR8KN>7RGRvOeO-%6IQyViaya z@MekGTOxDiS%QN{bgsNYaWG)I<?AL6elicsKg+?R9KOoo;9tuv|6}36vY(Z^ZDO`! z{`FcS!m42q?-Dh=KZpgy!6#xEkYDwlQxgm5rnn6T23GL}HB1>W2n@I|(1c<8$gogK zqxy-&c^Z*AV&91x+#-K*2rNPYT<<C&&@%&9ajjF3RooG=l#@Xxf45#+2YY_vZv;|6 zvb61ErP-<m1Jja6qj)ADKVDeylXOt&)yutkbDpd)3z+a;X34xH#r#uy5LGS`olc7_ zi?k7k>^f%w9>Aha#)E+A^q88<{E(&Ff>nY>l8Sf~qbbJlvFe9g*{enzi!gQ6f-%Qo zD{_7oR54cJA=?monW(ajeGCPG++aNs!RF18b;iRg+l|F8!lgHMSS*r8kjgFB*Vk3~ z4huvovs}xvyUo6ogRyLvQ8qTF9(4&fN4`=^O~*0F<e%g(a*#%A$a`I5zk3Y(aqpIr z)x{y!94RI`D9n;nJn*LF&kL9)#lEMc<yR3jKixMBBNHatj<TY)%}pO;3@u?##A%N4 z48=53aLe>1ReqYVkk`dnR$Z;@c^8T;*wm$ccC55hvbu<PTyH27&k#!S?}9}3q;#m# z#u2V<WD8Mw@m*^nLXMZDtA3uK>y!f9-)n1rDoYOS@x3ezDBiC_?;&Qjf>1V#*AD5~ z=bX6em^zxf5@rxp@;t~8^$|goGY>GcQI<rADbumtC{dS`A?lUPo8?fJ8{xlLsofT1 zQdr;9U+96Jq|yKF82axJRtLpMVa=$^zj|j`-2#36Pdi)<ZeWM&*kCT!Ae2gL*x!^& zU!h8u^DSN0nxW`FTd4C%$~OXkDA`7->IHs;z7c8ZDr_ZmQbLKc18Iw_E|P?AVFYIi zUfFgsY?T-Aa9=;^9nm+`a%l&daV2bhUUtiy_qiX4>PmDsBMRNb-&9n|1#L!Sc>?B% zoSoXBt<|<vQ4eo7LB*Ucn7ZI0dX;lTHgO}AA?cb`wA9$&Xr!2UU3!#*4U9}ixo>l- zDQKnqa7-x&UZ5-p8v{z9=t8jxpUOto9ukTzkalWWom!og)rU$}w!P#BnWnJUVDFWU z>#@A<O?XU-&@@$&XWyf;B#*Nm&7US3y+~SkR6$l5($Coz;utE{B<3sIA`x#n=doao zFx}r3)luv}I|A)~s}b;+&8u$tW~K&i%G$MBZKjE)8vDL#qW{NGo_SMP_p~g%*yoZr zXPE6X+8>HXz7yFhPcVCKqMl^=TBCB9>AWBbN4kr2mX^9H^wdh1Da^a2d-TL@lpP&D zmK?vI8O~-ZP|HWu@(X-wVlr1K3@^h-7Yx^6q#sHyl=@+D1{V9_i3?A<T1P+iGz9vy z6s%{EKRgZ4$?GGXzAzU>0az|r6NQzyAqMaBAQ9Tk!1@5=<`+AI>H;e{Unc(nzMMkP diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta deleted file mode 100644 index 4423143044877dc88fbf4e2fcfa1aa45a6e49927..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 scmY$r>zv8}1B_6HAe2teNlnbvPc6zx%uCl#EXmK^rz=1CkN%`J0NM!*Q2+n{ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache deleted file mode 100644 index b1ab52ad3ff109aa0ca7422ecccc100f435855e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3171 zcmbtW&u<%55Z<?IXX90)Fr-c)5c$;sVMoDfoCC;+q_L8ys+=ZkQzAfBvWZ{fZPvTd z?%GKXs1Ws3amb-U;?^626UXv5z=aD34xB)O0|yWnxP*D{?KXDeMxkA;ywC5)%)I$# zzL{%})ayFDd<d^!flt32`YLq=;O@}xskesi82a(H!>r~c^Hs-kw<o<o5ff|7ALJ8r z2^Eqz&3=+NUJe$mrtKUkib9C_lB&VGIwTJvWjv8VVi}4Gshcox2%vYKJG*g3)$pCm zsjyTuD@21oH_X3@Hk4P(wVaBB1Fcls*KqKwR;>NP2WFyFTS?$xDOs*nk~sJl2aovx z^lI(0jsvT|TC4XHEwdapn2+XOQZ=(dl0Xb@y`n&B(#)xvqL>N%C6FpXst754wif!f zyPXkEK+E{jMK6+8Q2`XqR|x@%=MG`OkOrK+x1vt}p#O~CXW^RVIBSZ|+;(K={VqFo zv!B};*)k5P4`E<+aNgbwBdK*;(KbV|i@<0JMvE}2quuEeq>GR~bEVT)L~CKgJmQ}R za73okKlOE+CG}uL2zb}FwroW?rd1ZUd^Z@O=wa&EK}fwVidUgl+p-;N!(kM!Wc!}m zWNt{?mT&XPfLi!IIk3YHCJY+3c5$U(7<6omF6>)P{ulq@Gect+p|o6H%r&ju!j|tf z*SOl;M`DiBv0S!xW1&*XPSEV+hV4#nSV1G3NAcpp<(1WWvDomMZ1V23@1Cp{3I(z6 zPF^z%g-jok&&fTm`2?0nU9em{d}L&;&Q@8_azYtdJ<!VbMoYhCJMs)hK$3%0HbeXj z2&~|4GPd$ulr9UD+LqH|=>Ndmw5^cU>7E@n#LBkaW^PZssB1OZImmESBEL&;I(*-W zAm7JDm8gIr-Wx+P=w=OrkQIUtkSl_A#vwrl`58r-{#yM`ot?M*J==}4<eG%ze-I6* zn4YDs^o&GG-ysQh5ZH84e_PK~Y`3-ld>T&?f{@r#;ctC^^v!Mwj*T?l=nA=RCb%do z@sO#S5BcW-JjC>VQ9t&AHK9i#2j_;(D<U{{nC~)&r#DaahR0KVm-$wRL`j2#AY@G* zAh+Ee*V}Wc+>S}^GwQQl&*zbbNxv?*I421<zy1zoh3!H-n+;m77i9D6PYE^YmMH&) z3q`ul(5?j;AiY+k?pTX~Wq?eNrY2JN7JbIbLH+q4E_Vf0EVC!bAM5w^dqEemeA0#T zs(C}yCC>WK#OJ(ZWo0!xMII_AkIy7|JSJ1{S6^&N?<km)OfeE7Yjfx&OGp-ZPU?s} zkjpN8@cvwtvoar4ZZBjdGa&0lFh(RC?~I5e-W^j+EKeAR922ik2>yyDs*&&vmmaZ= z3gnHseia6aa0yv;9Dg%H2zkOi!--1bxaCR}3W>|~dKYXLuLr%c5n1|;%+l{MOaJZf zRM{J!Dr<Ue7GwoDNU&#$?P-FKxjd@f6#alHx^4M&thWKr@Vy4(9g~n4mu$+~IK%d_ z*s}Ul^0OyO%R3Ua6If?x>_@B`68a0_z2N(vpF?x=G2kb1qN>s%ZI)jw2DoQA`7!xV z@_5yD>)u{)OCeZLMThu|HKl4&1nxBqA8dGyPPsiP;HdA5KG|1e;B~ggycdN$@7*rk zb6!{HE~$_nhx9O9Ey2}cc=IMq6$Z<m=Rk5ClEuOI{1(eBT28>C76g(bIIk`5WQ1Eg dEx=MC+7N6V%Q)z~iY$du!Hg+Rwzn^k{{Z{vFuMQ% diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta deleted file mode 100644 index a5a851f1c263bb78396ce9ebd74ca3c7667c6267..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46 kcmY$r>zv8}1B_4xCzMXlNlnbv&rK{?-X61bPE$%K0E>MIE&u=k diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache deleted file mode 100644 index ea7ffa3c47808ae67a2e15b6974cbf163c180ca5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30881 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 SYHzeOgWv4%3SlI68vhGu1`bgG diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta deleted file mode 100644 index 90df4b90772a5995736af489dfdd0d0f028aa906..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115 zcmY$r>zv8}11wMm50p;NNlnbvFD@y{%uDA*5lgAeOU%toMpc+vl#`g3E{LKKBBq~M PlApUORpoUXPcJh7xDFae diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache deleted file mode 100644 index df361f2d9db1c6d104f839b32e4af8efe121dbf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12240 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 UEmM0Af^=Q>Dt6zqR@t}zAJ|)+P5=M^ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta deleted file mode 100644 index 01991ea93819cf78ea5922d9d397c28c0bf7596a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmd=2<B`e$1ME<S2$W9GNlnbvPc6zx%uClVD9TSxEiM+tCYPL%Sd^1lTq1xXnO{<% zUtC#SlA6ndB3@ill$n>#iz1d%nU|QGnJkDR2(>w}Bp=O${DP9q{Je+jWZ$%l-Z%gN D0-Q3b diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache deleted file mode 100644 index 2f2cb4fe0a7c2a2ade829942c989b0f2be8e1794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2254 zcmbtVU27Xh6rDS(?OMWL2SpAp7Ot0;*dmUiH6f`;kX2|KK|(#UA)psUwwAC&+I3c& z7>7V!@=)|v$WKUqNT5HV52a5<5a=K1V^Qy}<dCU_t=b?~cV_3~o^#JVd()BI7M2It zyq2A#qwGiPDwgZn&6yvw?`N#xlaAZ!7K2D07Ck?5{hk*cH>0q1U_Eui(c5Ma2|BFK zNX+%s6-wb*Lq(Jt*2e4Uc#qffav_M+SJHs8U=D!H*{2JMbRQTXZ%sPu?9DsU;NNgB z2$D2}(R0U_Kb-pV2IdA>wzNa0xwX0?acf`QAp;-k>Q^$dA8CL0FX8}(y}M{|kW2M< zS5h1tn~mL9CI|nRFY8~BG4z9@X3sqcgypw;La143sBJPqnV3Hzkhau}G=yM$f{?b6 zc6iQWoU2K-c%BH@SL^ZL0PBS1jDGCdD1_X)DsRYPtKDw8FI-<x#N5Ss{I2CuRCnV% zRBDvSWoi`zDJMW4RqAf<d1s6zK}yK?@y!4wi<fOQusOiD7n8*QE2SCpSJ!F$jFWRo zd|<pYhEeEsn@656taflTrtwdW#@FiSghnQq@s$cFIVcr5tl6kJsKuzOHmVM)*1`j? zcS6mW_DS{E#GnoMtaKqEx;W)otj$wm(m<Wd!+rUSw0!pj{aX$FBXvJPA4{4GZ6oh+ z!*iIkk#msKg?$RkWkhF^1Z?#+mzf)Vhp)`UX`X|Jn{bDSx6-x5^U9dz{SH4Xhi>Qv zZKBnV*YzSHwzlaFP4KQ!GySIV@E;Y}i3$?I+t_fh5r=C9tT|XKYAk4jDQg<5;4;kR z*kXXby3W*f5|hbiCg2p)QE7l~S7&8h?kik`@~7tskCoVkq8`al443{`BCVOnopoo# zDStUGWZsYrrjc~~^+XhGoS%O}&cP$M9J))xZr}$|;CrHS(2TsUJ2vshTD^;EJ<<Ic zT^v_wQg<i5^ir+F_Eg3SCz?5RXT=RWE&mBy`QJ1zt0@Vy!E)8m#Kt``)r+yUEvt(X z`7-iL*yy7)k9!5&TSBdYhx20_hxsK;$N1^#>i1z7gp))9>Q9<p_$~-KFblkWVK02{ RuKv*K^jr-9sG*G)>0hwARUQBU diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta deleted file mode 100644 index ad921d20ba6b51a57503d0e2a53829e220a0564a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmd=2<B`e$1B_4x7nDxVNlnbv&&ez<vF5ruUGm+cKLC?C3J3rI diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache deleted file mode 100644 index e4866da8fe5cda41a5fff257a7c8c157a418726e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 273 zcmaivF$;oF6oq}yXAh&$Gn5sGlZ%Vc618MOuBo(#gEVA3dFi14svp-}4;vkV%N@S^ zodeg7BaUSU-$BdKIzWck25<hkl|}vtMXl|tuoANVfvW<fIxq?&NEu;PqE3XQ3#wzw zVRSIZgQ!Mf1~5BJdG8N|gz9P{`s-D@*HWfReXf!JX%(GN%mU0tzz&$h4dBlEntfJ0 io3e(ng0a@mckd*nkk(O%Qaz!Vb&*Zs#d-NGZ1M%j{X(7q diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache_meta deleted file mode 100644 index ac4a4c20f31bc323bfb14d6bf926cbe2022ef1f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmd=2<B`gM4jR1El=qw~UJ3v{=mo3* diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache deleted file mode 100644 index ae88169bb56694a077f754883ef09345dd2d5381..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14883 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 a5dbf$f`x8%=+4q$LTt&ef^Zf)!u|&!=Jz!K diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta deleted file mode 100644 index a58472ac5a3334d4ebecc990a11a97146d84232c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200 zcmd=2<B`e$1ME-+50p;NNlnbvFG?*g%_%_@D=sO@%u7cV%P%O&%+C`+(VJS7lbDyT zUr>~voLXGWk0O^}QlOuhT#{cTjUk+wSCX1noLN#CUs9BqoSj-Eh@u2)YF>UyYG>nW JlRa5%y8#W;Gll>F diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache deleted file mode 100644 index 766ae18587236f92eb0a1c1c6979bb83bffd27d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5222 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 CU~~Qe diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta deleted file mode 100644 index 830d43596b10edc15b7bc2ceddbff2f713b2ccc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103 zcmd=2<B`e$1I$ncFO*KtNlnbvPpQmH%*{*|L=j9a%1O*i*H0|T&lSNYQBahhoLXFb Md0NZ{gHzJ60N(l;RsaA1 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache deleted file mode 100644 index 6c262ed8ce77420e7064508ac4c562e934af4e4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3940 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta deleted file mode 100644 index 26c03cf3cb81f45c2b93bb6bf8021044c38675eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78 zcmd=2<B`e$158kc2$W9GNlnbvPc6zx%uClVD9TSxEiUFokxQw}OU%toe#!RnuiB(s F4FDhE68QiC diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache deleted file mode 100644 index cf4083871e1a8b155040dfe8f81f756bf266e6f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmaKqK}*~~6vyXHHjG(Z;$u<SVp$Qy5(*JL6uh_!ioNJg>d8wObcoAllbB3s>Dhx{ zzz?BUFRe$9ehsg^2p)y)%UTxKf^&Ei9+`Q+-#?kT=?H8ExGZq_OS9wxF=(FgmF5)} z!zk8j5T=Gf_WHTQx28GH-pfU>@bO4Kfz|vC-nU->)-cj09O$CpD$?OusY@NkI*H6F z13Aqtc?vc{oiPB$(DCIew-}Q(s({WCI@gFobbBW+1AU!Ctdhvj^3*-1YrEqY*U%B- zYhv0XO6uDHi1+d{ZLK@p1N>NjhlY)fcorI6m{9*PI!{#0D!4AtLYUvGakQ7P1|sX7 z5b^E9u*lT+Bs7XyMW4_ssq;5dpWaCQ$6CpH=={Wn?;fh6|Ie19-pqVMjaP|`4)6Ek zNzo%ppL_#cq*|YV8k^B~V;uiHy93or;3fag1gelz73w>wRzp0wKwBfg1*-MYZId(B zFW?gBx0vGC*ucgdwmfXjZ3en1V}tewwAZYIetRd+)7;%o(->`!dhTIf>h`XR3q1pW E0Rs$`IsgCw diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta deleted file mode 100644 index 6beed5ed725df6a3a8e7149a83e1459488f7153b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130 zcmWgo<B`e$1FTR62b50FNlnbv&&=mU<>!@fp$Oz;7MJj$h~$?P=$9lGXN#bSrWWNS X=B4Ww6y+zU78mEVy3OV1H*Wv{xKbQz diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache deleted file mode 100644 index e087e75295da251e35223689a9dd0607ba37764f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1223 zcmc(f&r9P#6vyXH8m1LW`zQ!mD2+m?$f9l)4_>qdS18M_u?vEiHZ_B$#s>1^;Q!;n zKg2)8i+_UPE&GyGlXkVZm-RB4nKyZv@8^AAwpwr?P&>n>z~)iyupkh}wN9Z`yD5n1 z!jb0n=E!7<FVn@q4_L)=?9l=5R5{jrh7L-t3FH16(4@?J{VJ!)6Cd}VX%boT+_mKH z4r2_!_{tUI9@KBJ%A;dS?n^xsGz>>H-Q5|ar-!;d(Su9co?gHX2BznkH$(l}wL(Wy z+z+HMtqlOiu(WBcafLCXKqFvj4@+$<iT!@y*^`S#lH@oaI^92!e&_^g$S5YUdJk9H zxFRTnwu)LCH4$~~pc8+XZvUD_{Is3dg$jTeL!ieQ>NGCpB}aLJjBmGK2vO)c135W& z2_$KrQn`((bTcZ&9F><BEcrn)1cqqGWKNAA37Nkot}l>S>AG&FaRE{lIQeB({>yDs zdGiDwpw6RM{j4bx`R|w_J^exHnJNB<^tsCCbj|6;tJ|dRvB78Ro^->4y8ly0WOe`K zj(EconesU_+jsnt)9<9nvAl=nWz@);%hL`;^$V(P<=0i?(DPg`F(#_(v{(7<g|hM8 IbbMKbKXM>6CjbBd diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta deleted file mode 100644 index d03bd4e27eedf3cf7c1040715866556930eeee16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache deleted file mode 100644 index 7c790c0d491ccc8bd66f0fa11a008acd12df3a5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4956 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta deleted file mode 100644 index 09e2f8acc9336bce7885613638b9b2af3ff95002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd;&v`S@w0Y)f;2TG^sq$cL-7nc-e=B0~Ie!%wp&?033h=d8> diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache deleted file mode 100644 index 734764605f44fe1908f5139e0c3456768538a0a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 zcmd^?O>g655XYaf<2ueZ4WlZHvg#^H)v7N7vZNrPT(XU{NUT<(u6NZH0wwXrEe>f? zJ$3}`1yt<;4oDDjVYPe73GE394jkaj1-=3t`2ryA&5YkllE$bn=E6#mGkN0J{{Nnt z|4eQ?5pT+v8{pcD`1v36*XLx+w&!zmEA#4{?Cf=n=6*>x!LI9lv(qww`)hT}W|>yU z)Hf3XO7EyiNH{gquDK^M(cl2;f*|588KnWHQ`0WQ1XS9X9%5E@YKOLA(T`b%?h)Lg zq#pvUdN-D7bxRQGwfTmC`xUhV;{1D{YYm`aO?af;5GW{$6|EprkWCD=g#-nEB^I?m z-Qa8KSbHo{V9p$Aof&sU=GtSKf-jR?`zlF6Q>keUg@SvjZS8)Fg5s4UZRrXHx!GfF zVHU*dgI@PR(<XUKf~bBA(yQ<koGrp+8HK(?2m5`a&<MD>sseDlQP}Ub`W>TSb}c(& zG+VC#FosG=y(@@}sR=p)D(k3}X)$xhwCuchnedx)vT`qW&YwsCh!wR!Z|MOR=tC;d zJAMB)ev`5@&MxomQ#x=ao87$t%)?l~td4@IcwpqJW^=lakB0K$qB3=L$yGbRCBSTI zTttN0l3bS^fB)+`n6@k0?23C<Ao`nFMBf<|9i0ugF<r(qRgP(Ia^5^-j9r?^BXyOS zWCyqkm`hES8iD4MnV)8=&4UA@+X`TO9|MdX^}Yuq>234%HWr7tCew}=Z{u<qm(T1Q z@lg^^6^O4og3Idy7fx~uC~r^PEWq?d446vlYoj^CG5yr_RKHMaeU^8PJ2X|x2Dg6P z=kUDt5+yVoPnXaK#$-lt`BhFQ<*xBzK%o@_1zB~|gk4OJYXysA#^*j=#KUJ`4g5{j zO&fd{*kgf|Ph*f$QePU~(Ep;;kEhrlsS!gpVdMX&?=xZJVe*Hh<L7%_XH{<?a67%* z3V)12_m0}|bf2#GHZBkG<#W{g+2)B0H4n0YqmbT~*E}YXOwAigkSzcZ5LPym0;aFw zEVbDR9YwpxSk>z9?wTI~Y&;R4i6Lc+<-K+nK#pVH*a_y1(~v7zEMxJ^kYnk@1e1p_ z{Z1Uf43$r1DQv7tZOO5Fb;{X#cxtQ_IA*EmoTJ>d`nRI>=Bx?X6Ivo<uPE;-A0Kez zxoEVtF+&bzN09jpeg;RUvaeg_5d$MghIj_i%O=C3KfB6rb%U9nx|Ej$+vB-E^867p ze^H((PLKd~GL8SeJDgap?+%mFBQPB#zDt~70{^co4_owe)v6{MeaKG?nM`f;zY8nk zO~GqZ6--~n+&bp2R<{kS-?34;hEiF4`-A)~&U-vl>-9P)t<zfOF7F%pH=7;Hcme(f DbZEKk diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta deleted file mode 100644 index b59a80e2912f11ad19fd2dd2d30e22bb976c9293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmX^5A|sUn2AH4>VJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache deleted file mode 100644 index 46c9dc055260a8dd3af66ee241d2438c6ae38c14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1934 zcmchYQE$>v6vywmr70{Uc!Dfpae)yQ9dXWeE*f4KB$^DTu3)kk6IP(iZXKO%iOy)I zuY8I<_yP36Hy_k*;G-|Tndqm$(-sJ1-PB-w=*?-<_MHFk{O`Hff5N(i$u2HRxcD@F zPm(aP7vGRB$6rfQZ`aV&gXOvoPR({Ky}iqr|BP-~tZC@=bzZ#0aZOfkfDnHN`RZGs z;1e%ZKXM9Q3iawMfr4TvUtJGTFfUfBS&@S86#SqdWgB`!15mPDr~rs7(1qR>CAPJ6 zN2JAhtfhAbl{hukvecuU^nuyz7+P9y+m5C-uQ3L|7)Fj2gA0r))3gGvl&LgalPFxu z;F63>Zn%)a1sNBlUP*U~?%x<=DKEhm7o?506MREoM)DYuF|u8#Xm-cwzo&$~Tytfd zmvP=rkj!9G#^f0Z?(4=d0qIASl{5fGyZ8tYr+gkh<}vgDutk@EaI-kgF)@o50Ta35 zDyR-X%u)9>;IWov9x%3g$iMP}dU&X{n?7OX&7_346{19hPpdBDoQ!k9ssmZOM9UbJ zF&g}l2plm#ptI@H>5DlV4@bCM40DX;ahjmc(ps=Pt(N|b&^abC`3zxxtlPDY)4J7% z@?ugb%gR*`O31UqxuRUrInPE?tYn&_ULb*`f!egIc2H)3Tw(RD@I>gjeRlUIlW2GT zJ2h8E)%d2D3RQ0e488mN?vaGLk|l3r7qjHmsqu1yRN?z?g@)N~xL$TAf^sr>Yc@y4 z_~@5oo4P&Nzkk@Y^PNf}hfei+*Ow6_a&<3s66)2D9Ia;S&l&WmpYp$LnDK2mHu6Nb zU6t{!jZ_*arvMG;Ii`O`Fc|po!{n{|t6g>8aL)U)i9DOgU_!>kDLYH!bNMud5rKge zz6jwE9f$txiOyg$hsl}#NrB=lin8!vKXu!(Ov~H&DCX!{?4i}sQg>9t)-J#=bkpAw diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta deleted file mode 100644 index e7f013d77b779ab53ac19ad95a796aa2567c499e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache deleted file mode 100644 index 3c7e20ee8e09fbc83b25777f5a83a38a92dc43d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7081 zcmc&(O>7&-73PqlDAJMXF(W4uYG_0wwj|JUMK@@o#**d2`RQLwF@+r!g?32}sg;(y z?Ch?75*5+GKz%OKOD{EwoQfQKNCO{QG=~=Gsc0{`wU+`pwU=Ji_hxpN-1SnH6GJ^n zT5{gb&-cFfz4t~lWF)gfZszFZI(;ceU;0;RJx?gzDsAOS>5Du$>X=;bUTfH?jBTn9 z8;+YQwoIdOGrjssns(=FCdrh3L2lJQB=GQubh-ZfG(7x0Q?CCl0}uZhS*rhg1RnmJ zU90~k3lF~=74=7>@Ic0@Yh&>D<umK`SI(fx_*DH*<M1$3EZ12P9(b`_x|JrSUyqQ| zr||P`ajEp394T75)gq+!Tsl)bBw0!dsT3ip6wTkQy_wFWQnfMoP3XmWda+6`=HPK+ zo=#NhM6P(tw#{jIusi8Y^b?rn=V`u5^D(n5NmDvsdq4;sU#Abq;`kS%at~32*cx{| zVL4OG-Q*1S$m}+AcWu^yMV*C0fnB=9Ztv;cp2;2fq-mPmNr5d(^V!#R)8Q2+|I8KG zJHq4A>KI$Jd6FsGoN!iU>Q5^70UIc4TA`34*Bkkt<v(cJ-JUME5C8pV3qN4rpyRpe zw?&H!A6;9da_|Y<CH-&<C>Q#nkPY?|bH%sSE=x`ye})bb%0<#cZ9_ON+tE#rUvZcw z*VLG6%Rz@XZL4*>&x~%*7A{j^V&j(4lRiMRQPkz|!W*vdPbBOeLV#H0h1HQX&Cb&i zQrtD%O+v1JeD?FRxvpWIHpR;|S3&Cn#eb8<EyQ5;89u=@$qkJeZN_2KTu6>9Fqr{p zs`2CTgZX191&l+&MZyD3<zPid1u$NjBH#mK^2>0r&)kRfGn(t_d#8`+fkN~E5Uq~l z7LpNtfoaH>K|poU@w(h{ft!+}5>{#S1XT6C7^?VEl8(S`VxXSDG6wN9h?o=y?cDuy zE3Um^SU@5v&00houGMCxG>=GWP8M2J;IdNS+*_7A9q4oxK%`5xdkV{YD8Lzitz<aQ zGM!m~o-mpa@;$*F08)1i+mezD^4u|YxFtz@Jeul65>VjPBG7UfBmz&Vpo1^JJ|L05 zJpbwWBN%sFVOS~B`ASeMDJWLzI9Vr(#+sBtx=u~9NdGx9xMngW=K&JAtIk(PM9mX` zQbyL4lL!_7(Fw6COZrIToZ`)IOP`mH_+HcW9AhUn%{MGtoOYOs+DFK+b@~y2xjq)( zPBNfO=80hEknnBs6!|`U56>G!VGvux!Z7hAG#-$=$D}j*5?c3b0l8q3=aOFX7Ya9* zk#Ya}xH~@G@pKVXWFJPt{)5`4411{6Ai5Xl>0*^G=14k~krmrSuJ$~RM=LSN_0j^Y zpk$=9TECf=v0pk&L-4Pc)q-)qcouNH`9L?#hThy}ZO>}TkcT9N6<I&z2QpNJ*_gg| z4Tt;10n-bt#oM}P`o#eX#9c^oFuCSApwWB}6~#d{aW^5^g$p%xi#bNuGj*3McId*~ zzp9E3*3(^=3#-7|wg;t%0k(FRtMyq=*d3vFA(wTSsapVOhs%=jEj$#AHhIevx)}~G zsSLU06fg<T!j4)-6V{yzjv<rAw+igqHMX#@5I7m8djrdQhP6h*iTr8(x)hGfUc1Vq zduMkyxwQma@fWK23oWVi1Qd*}^gUynGrq&cK7a(Lg7d1C6^MWvpw)-60%$P9WzHtn zR82!PJ;R0aZ4**g(-Q&&oHb0lxm|%sa}~OlYX}~~zra>uPS}-$uG_aghW^mOQ5|#? zSNkkrg{Q-_F!YAWqvtib%l6m}_I`me_H>75;qiYOVEqGI(m;2aXPJlwK#<@`c}S)y zmT3KC&(VY6(N+Orv>4(q&k?#H!ea#=!rIy~96Xx>%4R(-+P3JzG<!X6fy{DQq<Vfv zME-Li`El(D0%PgG)*Gx0>b;x<jv7aUJ~hgBxd{a^pD6=BmRb2tZkl$5mDy|9@^rzs zeTx9L!M12{-S6sMeOrIVtNR-Y=Z3{W*Hm$yq2!yZ&!y?a5`7+8$Tj*Rp_B9Qdqw$* zkfT66QiPLq5j~VjRVTM6k4*i&{SAnlR3;S0k7L4km?VtY#?Iwbtt1ulYOYopqL472 zmQsli1QarrmU6jXzYnbi<g?Oe1QMFK5ZTS+s)<o^uX#e*METbus_9u6$_1vIC~r_@ zA;03Yp@{y_;cd@UJZ^gec^4rfguZ9CSc8N9n)*J+cC7=61-fM?QnwXk;T9CeICY(K z_9IQ|l=kD<OY&h3gjTSw4H98kZ5z#o_uoT^hF=@jPdr2H1NGb1>>PU^SZwdIuD;K9 zIRsk^a{<cDN|{0EhoKQLK(u`2Oo|VG?xDevKu<WvV1z`PP$)}r2ZM)^@q%A;1m`Xa z@xVD^(RlLx2fXJ?;k@z;a%HdE0MFh4;M@fPUANtxU97NIU+r7?N&<usN(<1mUoArE z4l^iFd;v++j0#dpu$R99hg6M7EO6&#;P%7UkI*6Ud;K3@d-r1I^vlnw+9#^B`2;(g zJnSGIqw3b;vQ+<AnOR{C4>;;Vj!@~sf#AT@?zfMsh`=rqQ(#!CaNsn&fLRqUsbEMu zIMA34xk7hs0rkQ=k<te83gkl!Ur1t`Mh9b8-f4tWLWm01GkU6Q86Ig+?y4d*UQfn| z-7kxuU?_`NcCZZV2Q3M{0bvqcT>W=sGMfwU4C&8F|H?2;YS@vchg|*TpgLc%K!sdR z$=xq^uXu-K<;_*O_DH$;5x9A(fE!Bo^A+h2ysjF&KYVtMzI^#q91RCJnWxcEIx%*+ zgE|)@Md<5bauA7r6Qeqk+ZiKshd_UEx);Rd!3*NQjv{lC-Rs{E$Kv?-^z;->;()0i zIDLR(Xrd|FoS-4>n?61%+`p6SzsmhFN6A*dcP{b`Tl^pVuvL2~iy!(BYM<&rGcPxk z?2>62abeSoN;VjJ$NMIH4bB_zSVA7*W(@kImwaULPf{%$c_r$$r+CF*#OFkKefRw{ z@15y8>&so;4f*GZyt_M8(su~bw>Ii4YO*h0l)kWgJ=-y$f5QKrsGbPDAd?d0B1~8g zRuQ`2J<Wim38q17*w;1(bJakP9qFrwCnzQNK`I#@JTfbUH(Pxd$Z(h$y){Zn?j~ID zUs)YX)A1!begV6O$qOrMvO}fWDVnWj-rk<RErc!P4G8`pAX_csT+?!4nBpAyABtz6 Ai~s-t diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta deleted file mode 100644 index e616ec00377dd7ef4a8bfede2ea0cd223bda2c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmaz!7?a8X1B_4xH<V7#Nlnbv&o4?zEix6=4Ak0}oeTh-hX}R+ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache deleted file mode 100644 index 3151c7d4e558903d6f47a6e6adeaf70a985d79d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6045 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 MhH5w(M&d#AFAN2avH$=8 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta deleted file mode 100644 index 701db1ffe1dd588340d9500aba145a8b33520324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmd<{vr1)v0cI#e1WKppq$cL-7nc-e=B39cm1gFoq!w|Z$mL`fm++&ABxRPwCl(bY ORz`h4w=v2;suuuDoEL!r diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache deleted file mode 100644 index 06aca663cd5452cb96c0b87500658f45d6fd42a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12265 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 F@qaeQOQZk* diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta deleted file mode 100644 index fd97a7e9416a1be0edb048f21be7ab89f3389b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ocmX@|G$oY*1{k3X9w?ojlbV>TpI=atnV)y~=BAkQ+a_%U0Mz0PzyJUM diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache deleted file mode 100644 index df828811e1f6acdb6c0306f160245b2a929b56e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49248 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 NGxJ45Xsuhc{|A38CG!9P diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta deleted file mode 100644 index e0ebbdac5a8ca12ffada134deb381bda9ca0a76d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmX@|G$oY*2H2qtPAHw8lbV>TpP5&}g(8rXS&Sx<l9^n>gQ6zCpd>Rt4^^xvwYW5= rL<B`$aY<2TUV3~|X=YAJY7sw*TvBF9d}2{iV&%$Nhtz({EiVE9yu2zO diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache deleted file mode 100644 index a4f51d1f3e36464c48d164dde89796f858cb31f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11372 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 I=wcW9FKabJtpET3 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta deleted file mode 100644 index 8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache deleted file mode 100644 index eb1d9ed0279aeeb838591b0c87fbcab6dcc82006..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5798 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 Xww_&rukeZ&iiIzmxbM(eZjSvIo{p+3 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta deleted file mode 100644 index 8bfae6dc9ba127cf7714d1689d480cfcf6ebdc98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2Wbbd7QGhmnF;_hmjz=0 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache deleted file mode 100644 index 4f95ac68f6ba84f0c04893d7692c072161d8ec21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18139 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 EUoUbwbN~PV diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta deleted file mode 100644 index 7c99d5d905225ba7c564dd44324b01b038d7953b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache deleted file mode 100644 index 9778e4e4367ebda16503f8b508d1629598257f12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2856 zcmcJR-*4Mg6vut-xK6B9-BqEeXedXmCXy0b;vj^oD%mP+bd_K=u7p@MH4eFL-8#1A zAGBRN@ys+N`oKT17bJM)iT?nJ7ZCgpd*Fd*Udp-mCh6LFlPWcl;v8T5`ked8_k4Xn zI8tvJbb6KEH0aGACx0jzl<rQRl-`~Etz?{T`^@bvc%h;wGTuy5WuohQom=Ydib_9y zVy_czl9ETx8w7(t$g1-f557|$INz%n+|!nw6%B)Gq2tsFJkTwtqGRyRSnR+U1|`FC ziUtN>7N0onBGFE};bs(jK}!5!lf`iuE5yF0YId9Gl$eS_h@#Naf?ZKHMX?KbB($_h zOBO8|EhojP+htMvn!Ge4FBzYC{%~9;gwogs{<BM$@MxZjq?l7Fi>w#c%=4}h{7~}N z?Se}6MOq-OM5I%c#`f6B*syY?)h}EbP2ruK!ZD*_Ags%keOC+4fa4NJQ?F&;KyKr^ z^kY1lWdZtfb$&~JCTDmxKfr%}B$`-0SL!!?O<b<n-wXd11~bWskS=38Ak0<TCiU@0 z!*sIHe$&Div6r$0uDc+03TcRu8+6^c3t^T<Sy}@(idfLarU4fMw(olZ<M*XI3~+qj zG+}lY?i{$i$Y*%cZns5qna~6;obLmw%&d6O%X%|a6BZWW{U*qB6R_*d7N2FB3Tez1 zRtmDw26`P8ppJdan|qZWlREuVKc6%g(^M`d;RT$+y)8HlGuU^7lm~GiAZOKKAUH6j z8i1E35bg&cNG6OyyAMg4LOT!Xi!|kJf@l;*=ZNCDBr1TS8Is0{`m0(N2}VWIvQsIw z6s7h|m&tMozL`r<3hinT=E8ePkFQrFvNMDl>;Fs;sf#n$9~H#d-jQ<LK{-C__rO`& zT%0r)rx4^7we4%9hRr;bn#9%kN&j0fcUdRf?o(R1@J7Bdcq0>4(fC)qW-a@<)X#I& z&wtnC6V5Mqjlb^`uw3}s^)ul=L!T1sg-VikF{;9$$9&;dpYZJoB!@xj9&mB3qhZO} zUIH;ovpB$hbhlC#V}o*k8}w)rVvoXCZonHiOYkl)fXIs&@7N@-J%<VttAANuOG^X) zYc@?7#KJ5uSf+fy{k=-PI<(58aIXgS$0ms3yjfl^3gZ+VB}utcY}9LDJ>=1GQw+}c z+^Dh@R1T_e1PAaQ)ZsBcUR)O$Uw!W!SmIvk+8b648u;Xm4{Pwz!xxPEY4MjLe*w$C zf3xpsquMZB<<6{AdRoE_Yf+`+i*$U7PS4Tlsn+K#$^4Y+Z&TgU?(dcF@Qvogav1tl SpTn_<^*CeYyRM(G>*RkRTfZIv diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta deleted file mode 100644 index 48ca73e0ee43502e40d1b8b70f34ddf19d858229..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache deleted file mode 100644 index a4ac54bf2faa670c4dfcd2bf5663a9eff8c0c3af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37907 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 vNBh4lE# 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 D?@Q*s diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta deleted file mode 100644 index fb52d575e15e87bdb03fca9fb3c0bcfa695274fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache deleted file mode 100644 index 9da2217179c061bd64af462f20aeb7be93945c7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46246 zcmd6QdvF}bncvPXK@cE8aJV8xQ<6CZB@0-Acq~XgV3H6)i4t*=#U)5n0tEpJU_dOj z*oF5&0x)&3Xvun5wq;p&wso%9R&*y?zW7u+|8b>KDvokVxl&H-Q{@tu&Q6@OlS)|5 zl}nepxLmFvzwhhrndx}}e3UON&SH0_yQd#tf8XzWbob8GnznVDQX9;>8_f@mn77>8 z*I+!eHr@Q0lxdzxAA2U1KK5*C`E=3F&vq9JiBz>FevDOXiPouNVdCJrq}j5V+hnXU zA6d*jYOGm)z%HGx%{*903{+?HwaFR7$Zboe%>9jK!-(0`tQD3>noWyl%ZO<<2J&eM zk0w+2zkH}%sufCgJ2CK3Ww=(JlV#_+W6SOi<kQN|tx2YgWFn>h9{PrnOz%(i5ARDE zsr3I^GdTRqHTd#$WB>3|jrh{kG%~!Q317a|oEg5@j4$?vq2ZYg`0~da2hF6B{^rJ^ z^yZY2{-D7~H?K9)U)`8Vzt@D{Ek=6tMkBqr$w)ts>w`3&Ux(k@jPy&mF5G~>xUxHp z^boE~ZASVxxZb_hNWX`xzr#o$!}aQIM*3}BBV9(ig6r*GJjXS(7x!>oy3<G}??PGq zM*0n0uN=T%To+Qw^eecA)+W;<xGps%)5+#!x_Lt~y`8R2$#e!+e>#~yhU<;3$@IIp zGTU$u*RdOt=`*-KxCwbaoJ<eyL^-%Jx8ONl9Vi>urB0N)8+m(@>GyDL-kVIf;o5#@ zGM&YBW?wRW0oVHjC=1ub!DPCE>y3Mm2iFIOk^erF{Q&Oc>d)cbxLzGjrr*NVb^_(# zI`c5f!S(8BGW|BL!3pHS^@@#jxZW<{{kSfaa1Yn9D&B?b`E&S<tA7#o#r5ua)a88A z%%sfzR64T;RFCU#*QV0H!S%tqR65y|O24r_mHxN5nm4A>ZMZ%#Q|Zl{Q|Xtk!!uml zw;?aC!5fhu*TjxgdJ)&VJ5%ZRaBaQ?&v9kjQ|TdGZ`_u`D59)x+@mXt`?&i1@E6wy zd-2}eQIC(J9=I+Y!0!Q+bqL>aUAPbL#`WG2q`~#p19%s%#fMVq=W$IO$9G(>JdAhY z8ab6ppTTu$6y-dI`+3~QH8_Q5xE5!S4_8|eb-<OJ!*^V7RnTr+XX;3U>+N%RC$0;N zct5V}6KF54H<s{zT+d%frC+^}8kj1N&6Vd8iQI-{YPe<?4W`kYNEk*UVKy!0-btp! zql97hX3XBK+1t&}_IKwn)xjC^88e?X^WCiv6soly%!9-fMY5#xZH?KKF`KexQ)BC3 zxm*<KP(WBNr0wUlCkKw%)p}8tx(*BgwJ~oxnMj!@+RPJK^F(8g?k4dr=MCXCY5Z8h zeQSdO#@U~{(J+Xs-H6X-*$*1aNhJFoTYP$P>2Z63`Uq@{`e<D5qm#Mw+()Pf`sk*N zc~jQBsT);FCX)WvQSF;fCJb3=q(Hh9Rej|KKiOtJnKhqO4dz^;O9Ks#cumsR2T9W$ z9NuPdC#3PWx8;LY)mE(^maY2=XYG=eKVTIx$X0pU%I>y{_N-m1S+)9H(XMt{(}mJh z)vC?d_*Ow8zK`Genl+QJT6ya<mC<aWGcEjf6Uu_Rtm89<sx@6NP1XwKl69_7ELs)2 zR<D#ean+tIm!>S4x|u4$Wt8i<D_)kzH?H8hLTyIgtJt&Uv-VV1bF+11+A5XhZF&>u z6iHEQt{&G8#g?q`dn=W4r5#k$F>WEXsEH_O*DmYc`TQ)k8^w-~k2BRbTL&mRQA+!% zUF~i8woa?3qtn9I34HDC811xhv!mI1=<)Vl?LD0qrIL?2a2o|(ZgCS%alN8A@zT*N zEN+sDa~s}l?ch2kjK1Md|Fcii6j>}NR&l>R4VH303SkwP5&JXd{;avb8()uP%p+Oz zNPu3G#+u+<Ng55on?A}$HcX&~n7JR3AsN8|&^(Ru!2vEE&E}S;D&@Jcb2ETeMO(0e z+<(wG<;mQ$VO)T?Xh(N$A3gIkgQT(6VUTOxCioa6x=nJ<kZwZ(4F;z1NNygp*c>r0 z8olQ84O(@z_AFcXpe2}nTby|+CsfrcV1mn8z>{dYT(QvPNz5c9o~zhXg~@yk(_76@ zF(s<j`0+~J9;X==Juy@V7VY*^Ak}QA)z@k5!Hk$LS?%*3)+eobYoFC;Jplqd#gF8C zAW?J_JSu4#w=#;|Zf;<%y~#)wN{PgBHD4=Krx!3ZrPGGd_rouByxclnE>6i|`jIwF zOS#uVs1!7`4wS@$b&|ze$Y3>Mu!O9kv`GWMWj@Z$1eM9XC`8H+z)UNRTn}IWAG4?G zlXmq+^tIxpo)M^(alcw9fuUGu^ToPtO)OZG`C<{boY7GO03KMf>^ufYme6UPE>ptk zN_o~Q+S6ddWvfy+JyWB>8K+)xdLLa64wRpo66}qJ*#1PlfR_?eFHa*q9=59sX?wxT zvbg#>c&v49U8$Ftf>2RAU$JV19kVuGD#k8l8h0GrkTkbs%<ByAXDe}EBiRZLUBLvQ zdSeLRy=!Oxa;>s3Mr}(F0kGVKwDw|?lesr9f5tUAGp;FC>L!7KXn5Dhr6O_P#^Sz_ zlZMFGA+QOWn42M8&58BiR{7}S5C$1iveOzDm}gu{93D?K<7i5H2VBfqqN7f0s!*NG zSEi7@nJ26iolHetB>Pxes*;?!%iMmP9ttsAsM!_FC{R|R+H6&!z0KKE7D-kn5fX}i zad@I?PuGi(rxg#WRtr<0sOf2Yvc^wr4Do`6(q~C>3*wJw8HxhhNw8WL(MZ3gn8#?R zxJv}o@35pXf*WJAMDb(O`9hHs34u$3oLEXDWUP;)WSFDSry@iqOQY}S&)xm}5`^At zelEL=zty>7p$39%r5i^Hi!x!}qZ8)qxnDD3Zo;Qw-kUM+&6@X;_{(L?T-MA9{5*Ox z_Y@K&&F3=ab6NAb5bnMqDF2d1i^GQS7-Wav_}mzlbfYU&LP|%L2ABiPK@A2w&Gi}+ zAO&~qcyfo^;oOSu=h#X!esrcx8|b$=Vn{ziP=n=$uh&AlNNX-y;>kCY_HKN_YI zAO!<|1)Wix!rA!Rkuf{6kg`GfihQ9rnO6_xEFm*3OweZU@M<#?ZC{vubJjFQmZu9v zOpdYHL@GarzK{auw^z@VHaT2rQyjm+IGa4$n_~wSX(T9kO*HU(;5{SjwCZb3T(*ue z%&uCPmnHk05KKVZwS1vO{HI(hE{N$bFh8&}Nf>4*jP(^>X!ZaGfv1(MQUDrg0qA#3 zh>&Qwpt?E_C=INzr_;I}0thmT*%e`gQHc)-H9PP-GTU@XfDF8Q-ntE<%mEsEJFPn) z*F<qC4{x~s;F_e_kTKU7LP{BZ|9yM*24~!dH~HtlUq;LUiGLYh966brqhvv{Oo!3x zb<SkRV+=oj<8w>w@Nc2vhkBdIy(6&5kAX${o0(_%hW$`^b^`MHR^Y*NWgc~s;a&{F z16wCR!lSK^X;-twN|i)1P?Cz}(rFvge<m-4Nf{(UKOqU`Yn8mhDUfp&+agE^*}|oG zDFKCg$CP-j7qy%MF<{VcXYANM-)Suf^mv=KAO=;8=v|UPB1=R5Q>>%03f4B+CJHQc zS`0^bwTo{INO!dZvy$#c+8pQ+SvpYu0P2Z8a6pcqWRiW~`tYwmY#OgFS4jL-?J)y_ zbPP~>uF)<{Is6nOr6U`r5ki}*<#b!asAp>|ogfRdiC1$sgHE=Lm`Cy199~n6ZUTs0 z$WOxMtwb-0M5<N>jJw$P_kE_(KOiQhGjXnk;&i>kFt2ypcsYs_3gE`~=e{N;$zNcS zY+fhpsx{Z)jyrxQ+;J7Ul;}_&V^kb&9$+aeCIWHI7&aMG!0n;{nb~jwlc4ZHFhv-O z>^blS4D{A*W7|w)Xc;qgjC2ejBxkgTS7jyuQ~MBDTf73c&0&U=Hfi9uh6-dMNn?B1 zgE;dbGDt}9f{>Wshs6BNT5p4VBr#l=Efn*W?WAChqut}yM7?I^i&d~uyH>Rp%5`fl zUnNGzRwnSn{N!YPwqAq=Jtb7Tc=W3}6X=)z1<^0vB{AG@_4f1t=+ZxlhD+_UuzGb` z1>%gm_y>d@_*ucqK!vlOpwtkeU~4^)t4hL-b~FzV>s3PVGS#-$ot2%YF|iB@0$w*~ zCmO-=974cE(|H__9`Liy<1mCbgmJPP+*uw1^N@un^F;0|V)(v`;d{GLuZV8|kCdu* zrB=NOb6N;BscqY}b2c;~p=8a2n~~^~>b2iOLIb#h7CdXS>NHuNE7-#3NgOhM<W>Kn z_gL;h^bqpN66z7A6ZsiBx3%0V+o(RUu%-A#mC<)#WPZdnGOZ+*-BG*f8?{G6MvX9d z8)NXsAg;O5hwhO$+Mb2PJdzn!n_F0IZh3V**U2}460+{b05V8nLo*-<fekUDe4A#3 zRiC4I>OLveXD5J5$jIT?UZkDagKR4Rz{<+3Mop^GiXh0a4I?nURU#gzXt!iMv1jLM z3!<K+RSV@?*pgQ!AmS`jWspy)T(dw)0*b2|d6AP2oM<2&;3SM~OhaDl8clZxJ%?nt z%YoV<dUMv%n|IXb#z^L~1t*c{`|53fb(?9NA*E_AU#S%mtz=OERY{HcSsgpSp8FM( z)g}f!N@F%i9OSxlQ@EQn>lw42HS45DKbc`qNC+pm$-xCTxg5iX3xXtyT%k8L>9SfR z7F8JQ+Ghefr>A=~0*Bi9^XJo_HI3|!(-0x<j69}yU4-{3-tPQir<?E%Ja>oetP!*2 zWa~YJNf|xRJq4rcWKCK<RU-KCLV6wr@yyK*L#rnHY<eF#lq#D<^|iJwTgUT{gP!wu zizz|IC2pjcz08TLWcbXJKSk-3nA;O|Xy9Uo@*~IYLk#sEHAMig!Q0Q;JmI0h)(ZKe zG^Um-Q+6eu`<{Y|*aw_1ydZ5S!39ne?#JzH54m&j<&Hi=|CV+BfT(x-!~$$krFN3H zLJ&{pt2U&q{AE$5u?}nZ0jq7eJ_+-06$Z05k<^l}lFtvrY-LZ$XDp~m1L1eU{$A^< zmB(o6qrs=>Hati&2jsY3=g|&E1xVp}CsK(9=q*Bn@Rm`Os+t5*lkM#5+|#)iLd4TP zv}!l5ZrJKG(q4~l(5gm$E%I*lp$3F8@D)(BSNwwZbP5_;c9gnMxR)GroDfRefi6=M z3jmg<x4f~1L=wf2xFTsz6G`2<8<}^k;pmVC6{xbxV3I8$e^QlUTQ)67Cd`0lew{|J zn2b*hJ~c=fw@@8pX70tfxtgy=?Cv4gcdW3pB3V=e!I+_(1fwqi&3v%d`(~|jaOv0p zT(gDkCCsUFGdAnou*H(NAeqN<5VMEt9gSIF@2S@E<j^g!=|0ApqdKAe6j2RnEMdkN zHx-7y**Xk#yiz)*5+|wSeEi({KVNSe6%r>kaE`IW4)~>tge|2!S*J6_s|#D$>2SxL zks}n87oM~s>=9+MhEWL!0B?h|aRt%+o0oU~0T~`Sjr2ac^WYjdAlsa#wna8ImWELP zvwh70`D%k!W35$+_y5ivkg5+g2PBym+3XYaK@!GhfE@ySM$Ao^pxg23^FFdivhOec zaPyamS4azLRpS-UYP>>v8-r@lt}slpD{_!{5QcKUV*Mw*fxJzFE#3<F20^lnJs~VZ zDMSk6+N1@6u>eT>Jj6j>0vjLOxm;C;fHy^kFej2lc3M!A3pGpk8NzF|BI7wVN-|gV zYkR%~x!V)RTTb;v<cMNgr+OnYM6xf^$*w5VDyruCzJ+LPgJ^6-s|{n<ziZh@qLIkj zWeHcUt=)V%+8Po|ZS4mP`OIGf@oitvb@I`h)YfiO+M36?Kq5*+3<<R@M1yj?4V<Ex zB^nXmm1tvlov=*<ffbc({9UPJG+JRQnZs=S0YD)cSS6zjGK7Lfuh(%Q!X$)ImQ*yU zlqnsp@BOaL-6T~YP1!7saA8-J=5+ofLswSBGPk&#DMb3+LWBa2IhaF~nc0#xw*hK3 zFG-{L4gx4uh`U_VnI@_j1yPZWGm)|@E^U9`$2iY3><ieBJ`!Y{KndQcJEVZlb8Bpk zZ*}C_PXtQ^!hlI|y;e6Ljo&9?<hle=#l*<L(=VdX*ls}KaZpxPjE`eOlCT^I_NoWO z1)1?|e!-fst-9--XWLL7;dQWSv0>!iN->Y`lV$kofgItK;jv)Lh=}WBPt9a`cD7ui zH$+<-)S%gw@ZdL&gUcfhF6+j@or0DiJ#Q%6Yl>K@Gze{YY{2>92h?nqPMDC#DM9kb z5Ya+?hZg>5!8F<$5v1pkR(gb@i=3d>lji1R&@vgXQMWrls@<WhWYQDrY8s6&c#_Q% zq`z{or!TtIEi_E`#>=(H&Z9;H^X0bO_g%jHelxY%N3zE_II@~y=`5JA68k<`&oLaA z84V_xzAu!LgD|UgH)@H(NjMfWp1?S)Qt~~<Y$|L_`8%N3?rMi|i;bia5s)#3>|vjW zP@z?@h@TyEcJXqk>z`!RCoEf#9S^yXv0Sn_P6e<~QRP3JAA3S7IG|N~KCy!xDWFiP z;P{-)ujhWj+|Oq)OBxyQHlo!1ODejgjiXCK46_{|Sp;l=6;h_8(LsdUCStU;cnpyu z<QAK>f*Ost1sc79#s6sE-u-0Lnw+VZ9(N{S?tiR?x5v-G+ngDQZ>VyoGY<n(CRU?C zZk{|@R=*J)PM*O`qo}dg9LF(ugF-dn`P?v$gyYE)48<agvI^)MpC0#z@X=%-L{!bM zq=ZXffP?`mMgp-6cL)SaJ**5<B_h_6b&K*00_9?!AZwQX_R$9{H0&?LS1yBepH|lw z<nUDyeo3EfqY)a<;a8q}#WaoyNHJ&U6GqLUU7vG%Nd!Ph(%X$uQZaNG76b@x$(mcb zHDU|u+LSBWiLjeS5CIU!0=hQ*?p!x*7(tcae*AAAH;qA#eXrV7bs2IPuq(XC(@u|b z0<m>5$#t&?Jyg2r>ie*Y${<=anER1n=syBYo>{Nzt2M`o)$feKAqC<60^LH;GO!Tt zF8~DLCm|T%B5dG-a}>f~tl0S}GRul^dxj81tW*f&YAAJ}UvzUZKWR^OS{(mzu0XcX zS~ERDI4Rtp@+Am?@cUQd@dd_)zy-{QBCejSii9TUFKn|w1HOm2$vV8Bj}yFzDvZ>* z(8824lb$-W1EKMM_w=66P@Dq-XR)HrA)YI=3id>?VMfsXiUNKK3K&^0-{~WOLvT4m zWACJ)3DKr}l066<$*V;}B$avQM{GpI%_(7PED7s+uymN5!<2hRx7XcWpokKJP0!kh zFDuY`3R+PD0)g$HDu1?6snub;pG6!n;*^+Bk!1$)okjQs%5$(7fVg;ZM>OS#aS^u4 zo-jkDO2B5y-q;kxF+pcpPUJ{=L-|wLbX}f?2kdmi=iu&UC5z%%Rm`9i=YXSLXZVs7 z=RUr|f?O@LiVhR)btGRe(M}||Od45cQ++`;MUP^#f-|dlOE9~L{DMV|1emVVe2q%M zbsxOtty`qf;1Ng|G<if1UE$=}v%=(I^|N27pK|UD*sKGgK7Z5j_ZXB+YcXGSML<qB zsjOBX-W%7Q=tF+4z?Qx;4SKQ@y7vxdd0R8rNb5ZZdfX}|Cu*$x%@m|SbI0|8(*%!# z;*^r7Hm21I{sAYlpMZ&V7!HO!6vtu_0p1iXUal0x+?5e8b9My*;j`pWK;#Sg$gvR2 zh7l2tcQAh96Si#$=X3Wb>UQ1k%F*Wv>quyD#8i$)>LQ(MCPB;~O<d>*d+|qvfrEFS z`IA5V6Pl*18Dsf$B6T*>oYtKa!4I*1omgynJ5fc%n!TiPyR?#wfcQZKBW4XIhlvKQ zZayk_5cVVt!*x7_d5TUZb}EB4r6%VI)^%xu)~&^GOp^YpOU}Y#B~&Uv!`>bij|>~L z^gY{?9i@(CE2y|3I=#1t;3b}Vdb{$c|MX8yW07E@2&EsOHC0|m&T&6ud?yTWX^b&? z{plSJW4y!d_!Xl8kn4&Z|Hv0as<_EmbTPmdwGPmR6|Csu+&|0_S<c#()Am@koJdt% zKt0^4chc**pM@xcAjDi7uQzC9jZj7&C(Wlb=F?g8=@5<ZPM`5tI{tAR9P3W%LiqkC z%$CL-50M{TR=QkCG~yRb8y<6qG;~DLI?812aU}P$p!JtQ>x+$AgSAdswjQLuu&Otf zE9BM$Gg0&ouP5~rkv&11>Ll0;{h+XdDckwUzW-)e#3u7Fi7}7l?#0Tsvfxh?y(evw zLJ3nSc({x>E{eS2cYu?fEn{^H!xZ&q4w27W)%pZ*r5DvA+y`j82H?z^9}qN8P^z5D zOCk5zgaNFy0%kk_V<=cQn9~zeKb<056&5ABsM4=0&+*vnW>AcMN93Z2yTa(S-<==< z`z=JW*L;fnAcuY$K)BA^WTck)D~PJM*Hc}6<8~Z83f;Nei7=<8D?28741J2lZp^_# zY^G8Pfz3qgRMI6vgUvg6U=hqEmo8{bP-x>apWvBLZOBg!idX?fqG6CbV1dl-LbVD` zLfns%A^3sy5&Y(85m+~UHcpY8(~=u<b;(ufz8o?xeGe29zd1A*=~o!OIBXi*Q+W@} z@mtr0s0)%+WSrkeeawRdVGI=gC=pyZ00LEQ&wW=Yx<3O|z0`!7`iM&6nOk_YJtj-S zGap05-(0zhxF1@?CeRQKcBim;_kab^Jf@^<@@#fe6S0lExI$a^Z56}{Iwl*^TR=5L zNdPnD`so?Ak5Z9B#<C3z8Vc6RiEMm>sn!V>?4j313*kI)ju53}pXmj80K8BDUyzdY zqy%u>Mu_yD5N_cfYU9{FGUGI!wt+W<9cSRt^N$iF=cqLFU&5fEJ!uR<V3${ExuO-% z`y7$H&*eBik$gqc7X=5UFK#lEI+i;xq|8?!W!`J>HqS>_M=4sdR@jPI7~m=~)?z^n zn>@Pb@&$?;<tO0m9HS;ioR&tP1_-9*$e=s5?kRqZ)c~^zV=vq7=$&1v{}EDF0url^ zm9b8j;<YIQOxzTc#ZlYDHHaQO;~SjsmtNTWIWoF3<Z#9__rHC^dD&Bbzi-N4(ZHdQ z;K1RgG{XLv`9OLN1ruIcFPh*Rvte45S+%;H@#57?6E@TjA?7_(Qi>Crs8JIcMh<q! z`6e^-3t1><rTr-gPVj?5X%11kbRTP~A>Sx-ej0dOyoUF(KvGA=ik|j7NbRQ(mJc)R zot@TQ7-}+YVeDzpJ@@6%GXXd;ykXgiX&^ggr6Rb{RcGGgW_IesGBDIS?D4u$XJ9E% z9?Yfh?ztN9Z2!PHu)*><mjtg`>KyQqV6^%b{RC(R#W20~=jMdmLCjstu?AURAH7N0 zbDd%kU<cJ=fgz`8AHla6#x4@kRCWU_`_Rim%fkGYlbhqT2}wxq5Q;h6!WeeYXsM-< z0iNInR-XOhx4%eBHL8V0duj}e>>D+A%vBG|z_l3`6vM+ZfuLv7h||z~5ZJU)uXp(H z-02w}>6GyVos3VCjdWZYO<??hiP6g($fCm8+|YaG3jT~(Q^PiIiSe89R%YI?T5@&? zI^0D9{sQQwY)mOFSn8RZx)+=TU_(h0up6ocWD{IW)AVYx%ag_duGJe)cDk&grC}6H zr6_=$MP&W&7wb$oG0~wSLSAthN`ZlL1?P$=JwWKN-E-M^7csn1^$s`m$-C_b@fU_F ztyEcXmNj1=`Z}#NsLxG70FRwcw907ta7$}<?ta#nC|a1T2u)h}uyHr*HV5&^4}%bA z#N2rj`~vAB<Kz#zz$TzdQBGk3iVd}2sR+ypOb6d$0=);cNdb$(UzrCtQ%vF^wKbn- zjUJeu7uacClDM*nYO%QfX5Od;i|aja^;fJsxQM{&?2dW~`j8_Te5)L~b2Dn#V)%GU zS5yaiFc0C=`vCcsEgN5>)nw!j;t~|bU7uwW9h}23(Y3tWAS$o5OvSn8x2~k&GG0*n zu(J+3elBxokt>W81olhOJmnaEi4mm?VYM=-Fv$Fb9wn|&K$4<h`j$_A<Y8&2V=Ex` zh=e)U8ztu7Rp%)l9-sdrY1{*9kM81o!n&BUMB7M_CBmMjRa6@aQ2)aZe;o}PTtfT? zZRX*S+3<{Cr+JebqU*iP45D{&y4TTZ?xniND7}Z7BJYb$MYI~W!QJ85enB0y5Fi$t zgSlS{^o-RF@FTRS=4-t}t_0d4t=h++^>TuM1g>^ulcZtbQ7EdgX^pW@xnrD7G9}04 zL(uqKCC}T+j62E3Nu-^#5gCWS5?|9EZb&R#({g<t%?k;@e5(3Y#1#=uz{t&WhK1fJ zKDj3_K{%`kwrugd57utn3{ELYTCx~#0e)Rv2kcHh&nxvDApz(j2!mpZSQsvAAw_-V zPyOOkjP6J=f`vWNC~WN4P>;Xgq51n=y1W*8JPHo7UECBnkO>+%kO<m*Z^JTcJF0~~ zvX*LLHc~CrNnMzfrTHd=raAt5oXk8#f->^hpH6Ot#>OCu@^q|^M91QNj_xQ`M=}ow zbw?T7sU=>m@+f>Nj`2up546*oikRECU#{E|!h%AGi0lc9IdXtVT-PdBRqkF6hjYty z-Y#@T-Bclvomfqg39hD)yGitYzWU#)gz+GQX6v;)wls!?rRp&8D|FEwaS7Lt(_%12 z(l{b9z?s~`tdy7!gBD*&`D*7QM#-{T;Iu&OFNi_4g<3)eB|)X}Qs0|L3@?qA>zu<l z_DcMW&;-cw)aUy?PYwidS+}>2YhaJJ69pE8*n`0~(qA(~keICf`&gow`yfyTlT>hc zL)W1}c<5R99N#pgZKt+4=pVKJV)sSFsSm0!akmA}YAsl;OaAww#~X<L_vEN5nQ2mh zO>>KSxv!On$c;lH)3aX^FH%s8XL#az^i3La3h8q>0<G#6#%T&<VS6=P9BO^49wrkP zkTc0uVVa^2m;NiU4=OFR0e|tYwE4#j#*y_CE_`RWHD==^;dmT`Du#($HxYS6h;*3x zWl})C|GaJu784Bdj(dSkN$%8P-%{?!;rR7IB6|R`j>ughAAlePS_B1A+NALSQCSQG z6sbP8%2WdE4#8B*=8ql{d&gS5ZSoQ3L7=5dA-_lLTtMvxWx!X;TjE)?B_7Sg<0Osn zjNBlO2&>MN>qst8oZ5x3-PyIIT<NrI+Wn8V?o#qkBvu=mkb8r$pC=DCm!$X~t_T}J z@k`R`d`%)dkBcU@WPyrg9el;oK7}4dN;I02#_=7G=>kLsYlx~VEnkMXL_@?TDzwsC zF6pLCO69U{T0=%_x<!*|hZWEv{bQ^^PehePG`U6Ft~`Mh5Uh^9e#I?Th^t^<1+hV9 z-*4|;I!HuKD;fy2dRG<>0~C4H_$%5U^C1V<J+uOe9%XXRt(XeaA=1sK?T&e2y|-CD zx;~5slM~s2Q68V4#&dzsBKM$EDhP()N;DLrq-(2ss9}uLJ;FVHzMQL9H{6Vo`Ud>e ze&d_RtWQC|j=ON^p9~Q&!}=iXBNqf_S8Yc=c5Up)D2DZiGb-BTP4Ll)Mqj;sBqxU2 zy0Km=AUw@dZB&5Gf%Y2vinIHBOK{LRMu9hFaSX2H;3F{3pgdIcg_Z-Hja&iis&F9F zBYJ@{=2F>|fs5DFOaBfG@4x<`ixh}N415eb2`5rBo}dB073j5aDSCWGDLU*(QA(RM z@Ef1vJ3iUuGs2<IQ2sWs69C-8Q>Vb#@g~dg#R*#i0JdkmU@LdxPK0p*eq6OCLva%& z7vncs=FOGK_)fbm6N4C6wVKh~_mC%-v(++fKtguC-c@b2ELMt~C>0Bc2ILCRe!gC} zfs9wcex9_Y{$#yUMa*@Vb&{9-0ee;p6Nte<5R7a9A|GVT5;+>+WuU$IDQb#66STQl zWdW^~Y$95S39+Sic^0y)uW?^-AJJ5`R>6iQV~dHD$M8E0jH64j%MNfl5oSX8c$}cp zZNeuO%|}Me(LjJ)3P4cpKnv=`Yw-E;L~_L=ahUgv<bJ^*j(38-0Mmu1^*-vA5mUXt ztB5IVP$i;Xw1Ag5-~_*stiCrY3PRP<@)_p1_5)99VoAi0I6z7OqzB|#MB*eO36Ww- z;OxY}ko3w*P<4=nP|ewxP7{xJ_!P!;f@+G&u>vX>TJgsxnm<l}OsrQeX<HwzZdF^- zI2oi@AE_Y)NbTV`5?0Tnv6k4F3H<W`;-77symj^w;C*5x^MJ!Vul;Es9<VNAErY9> zVPm^C$93q+^gqV3=o0qb$39H?xD!Dr$b;#PKAoAP2rD|jIs$|u#I7WN;LMNEJ<^56 z*>%4Xj)eR56KDVZS+X!;PYTyQ^F1F2fA;cyDvvmN$RkAc!Y<{rFS`aS-vj2iZMomF zsfuF;TADXf6@6qb!TcS{Y737#*=fSv8Y&Sf7$}NUdN73uEfrbG_!G0^KJV}<OvES$ z(1c#<7DWr?W@mBO1}sci79~_{b;t&XFqUCDnw+sGA6H?F*zin?IgV%Ds6EFLx%S`# z(i|MQ#|dX)^RU;9tg=PzrJ`~Xp7p*=thA1QnS`p|Y~pYb&&vWE5wEZ>k8yP9D0=~E z9Vl<VEIcBs-I{bH$f%RXh)bV-GctHGvM@Cc=EjBLlmd$?YnEsWXjH*RkVh-_bYb4! zg!m3buF_En3{?d^F&CS}1Kwp8!DLeu6z%TKjezt51tCshWz7P%Zl6~ej!>z?QLsBL z8D@D8Icq;_1zlad#Se&y??Nf?ZOax2z^Ik6gE=8gaDZF-9^+k}VeG`)T_$i*V**#d zcIH%UKcAB3+x}cp^mCESw+#cLR=#c?!XYW>;<O{)sDs0HKBsx43lFs>64^EP&bh)Q z9d{BF^(AUTOKAwbuy%*P&e|EiAsKignZ3R1c8bHr>q=GN^Mv79m85IcSKqUbM)$1C zVnb;AQQ7CmOq?5u<x1OAy=HThx6ZzPKQ3Cc3wlJQe2$2G3Tkz+J}X=x#0J@J4wlFx zLLK_Cat&SE?;D0teFjU)MCfH53qr8>i9J7Q!!(Ia?Is`RI4263A~g>yld-8JZ48So zoUx`v41YVKc5C#zW)0=f=7%RMg}GWs{Gh7wQA?zx?ygoz(Mn=+7)vJ&Zp*R9;wXt> zIe{8?Y@2N)j7>)0#_v4v9Tuy_qC2Cmfmj`N#OkO!=sxM`j=ArF6stcIVs#TxWXr^c zM)ap|n59_lQ4(|YVpaOaTv=GU46*7uXjwk5TCU1`L=RUhSc}C7!RirO9$tKam`J;D zyXq1$AnHPM`Q@s}<;Yddu;b<7Bql}NfbZ<A<_Cu#G>!LpecnucdOBIO$0l%~9fID+ zfcNbAlud3|xkUHZJ`P`Fm>0V`G7yP{qZ09-j!$|lk=${(SkAlWz_^4MU_M^`2+637 z$YMBP>-}6i$QDQEw&PPA_7c@Vjhf*|dg{%ezA2X}Q_xB&VO-0D8^*#g#h5!e15HmF z$ih>xU)xP<fGaoUY^K%Ld$^atPL<lpODrYWxiatRcx;u%r6?H8y(Yx(YhVs<uTwAA zy3~n`+sTZ#(}Gl(D$fGyR<X2C2v)*ALOv+?OTs}mMff&@vKjWND$D`2qZLjx8SkfZ z$F14&R2{Z0pmyTwRp#oqV(G^CgZbJ_mw0zOxv9z|8zy;!en#X>@baC&M!F!-Fx3HS z!fBg=@p?&%JHUapqTku8jRy$6zl$ET<rNY50Miiph<M%Wtk{Cf`;E8Wd&@N5pb5xU zUW1nNmP=!Et(bzIsi$xKxmpi+K6(sSIoB{x^K6U2C(o-l)Zrlr^~B*J;q}&rA2aI9 z-}>us(Tw6Ah8rtkxDj~)qsiAImB*7}J$5i$XhK+%i7~jxv*Bjr5zi@8Xv$=CfACW= z&5rRoI>0wShS}s&legAd!<;qwAF(`90iGCu;3-N{MtK5*#F`Nhd$a49CGY<P9ZG;1 zUMv97fK>T>0>b|S@z_|E#JwqI1-4ruZcWgKXH<=j`orQ@nnZfk6Mz&R@#GT6tKtTz zl}e@1ft5CWQzMAzIW}(KTpXe66~a%^!Ml)-ZESdpJVnR1kR)hi`>!{D<QCI-+Yw6! z#1hM-fqID|30;xoU($3jgm^#}QA@_7#mZDbIt9sYDwdp30(0%R12cx%n!imNX<^R% z`JesYKT}KRY0*Yv0LwPSq7518KBpVbe>l9x;MQM<Ps4m9V?L5KAEE8@?KacSnl>HE zHri&6W?|~a*Ap2&Pni-#bx+c;eUnI=QNbQTa^Fpq9vx(4M|a=~`OviurWvxx-rH6F zF8#Y#%6~-reUK^3McIB5x&q_Xw1cvz-4^-4G&LwDOoTH=+Hy0w?+GzWi>@op+ybq2 z%hq8u3WnA8;EV?!@oWylb|`mWzi`_Zq$L}zh`UI1e~p4~sqekMP_Mm5oMHsiJb5)? z!SKo4xU8$$%TMGN>?(RQzfe<1{APYn-uGYbBjwE-XpWs2b+6X>5Y7bUFYdJ9(+*kT z8wAvhOI#r+aYpi+HeUORr3zU4+S0a`YULvpIilD94#k!Zru>I!b2K*45ipWE<&E~Q zo2SEzID&>$CSa&ucXJWn5dz**`~K#}EjLO0&Ni5YcW=6%_=e@hkYT}8JraI!bu3pZ z1ehPjtPne9$igxrxO1JVxi)kV3&lOJ?;##W7GRf$>BP2LczA~D7R8g$RPVBx$ZY`5 zKthD<XY{7vSBSf4sWfqIwU#*8>1M_vYz3MvlwimSKo-Za&WQk5I4l~+=DM*~<i=dh zj?U;*_rwFnJkBvYvtnZ%K5a*$G<sh=-O?Zk52#z0FwP~?^^jdC+GQ#d0VQ#CBc<an z&Y1`!<_o4gVuw*!qE)VJk#GQkx?YYGcf^i!60O`T6k{EI#LnYk;2Jj@ec-z2yX6A{ zm<z?&xq$o;N9K5%s}T{V!&2MN+sGXYJ%pDyiTF6#Bfhmhkq6cnGG-xb76=KcLx=p8 z_X0(<WS04HDQv>ykw0_NK+1q6B*P{QdTB@G)-6$maePehJX_TT{$6_K<KKkSI@3z} zw#zhrsnN^H+&4m4p^#9K!LVgP8|V>y<4<su_&tNr-e^FGQkWlRa!(2V@eS~gch_>o zwMH#l!)!a4-cIMzioJB;5~H{rvgqRL1P<hx!a-nU<OL?;Kx=ZJVPV^3VVblmcP|H5 z_llqI*s+i{BVu1|H`bq#=FeP$I+pEv@M1yn$NE+XES}2ZC>^Bjf_{&M!Zz84>4}KQ z;)J{$R`LxQVdKOexJ$TSn)#12v~H435AG;_!#9fedq+`f!|3xZZM@NHqc&@`AJGFt zPZTuuPI?|HZQI<<jiP$Kv69jA-feTyBiJ_-Rumc&Es~yfSZ2-uY=tT>(vIFeK^S77 zX7X;JJ)!Y)P8!-M<rLC-`yb|*5UeS(Al+`xgD=Ron|@>9c4L%xV}N(7yq<;k!tCk^ zpQN^_15!V7=CL!R)2Z+mEVG==*Cst%i1vulOsZ3j8UtyyuEi=26K6zAMaWrw>n~r+ z1Frdv)OQfV)jz=7<9axPZYeyO+oxy=Q+tk>cNi5!(+%em6S_Y)@7f99Ymjf&>a}bQ z;<PX5Fk9UiKBc&bpgr}=-Gr155LsdK1<^(kiowan0U}W=5wKryO-sz<FKitY&7pmh zq!Tgxd=vv2HWP^*{AM^$Z=QVwCyNg*@gAApb*VkN^uD54?oT-S!YAU89fqaC+`1Z< z3d5@KA2L+Kq#8<L7BDyrA1ogM_Z9LHHE&VP^Np_vbIT9AmM&hZpe(+5wFUu8Lt%~* z#xIUWRQ50FCxWrd$~Sv;S_;XnSNOmJ1Q9WWte3<#m8x`K1h@#t@Vaz8VZBrWzk(sB zgoCu$hUpMhQiq$1J;WkkDNrHS>r~4nSe#WPiQiMjZ{uAhToCIG3F(4U)ZGrv<1FKr zavdR9)V6kzY;05{V;=mj@}PG&<S$;tNx}?M(E&;6D0MncRsvay*@#?17+w-9-lAW6 zL_z9D7#nuV@Ho*)fu}R*WgUo@6R-~23w)W$|B9_E-P{4p9tbZHY@9yjdJJ_i{7lF9 zJLLBLd^U4pM@0wYzUh2*`~B9Od0mT}v6!ZHp4Vr?CTpFtMlSb5M#hxE&HcUY)8;ee z$Y-|w9OppGU~z1(g1}yn`&xGwF6Dl}(j>5Dz&z?4zvSwigEA>?(l|#=S;Uc(rn#z9 z{|u20pCYb&7y;$Hyy|`mjC_Bi2rQTN*V?#j$@NwJ{`FOG<WfWfI1{f#q9AZWGIqWK zi#@LxK2Dan71mrGlACipRG||O^>tLSOQTdqJqy1Nick$v-&ec%Dp;XF>7i?|JZr(? zIE@DbLyBT07KhPu)h}-?mbWLuR%EGmfJJy0WI0=T0|?!5a6^(#BDjvvBT%1wiV{|0 z@%opfT9EaXd#=A%Dx7SN*Az}DEnXG;hr`>#Eb>h4c6V-`<^#xi5#+oI6*OrqID7!# zIAe&aiAO&DGZvsNM6-nz@?kQ;1RqpFRkvsp3Cv>um;d#b3Hm@)r$erw!N{-z-6Xe^ z6DB#GPoOUQ+syr0b3eH*_GZkzS#xiQ5%iNQ8X-Oz-C%Sn@-vSZ<O4#%VQvJjX;yXi zH|deiFLlZ$RS~G?G->!|oe*A^%S|_7#0}Fq?l@^Yfy(U9aJ#yhEaaxW3EvQ+X6FOr ziknY3oDttdBEB2P>XDM|EWsvH8~jZ?^XgAuB~?KL8@OucI~t{*lxKXb;|40+h_*(X zHhw>>J-;72ILN|y(@`eofi^ES$hv7YU$#WdUwJDqkU(+jqzgo0^7?!1=ZV!Y#G~|x zKmCwGUOFxOqd;f~|B}ZY5<>MH^3I6FJ*O^OUlsi*;1wYfv1=@W7z!l=jNv0#5E<~L zo*(oG9gS8txgGyoU&n_Tuvd_$OAgiG8|X!Sf@-3y!JG=ul>(?+e6fLRKdnY(9e{*t zOaCUQcvNxUsK~A!kl-9glVLYAoaq3o4argx0<f5P&p#(#0et|NU!3a<^FWREqdy|n zEAe)0((TP=1PrR*<?ZeWD*^_^dOF08@Iog<1+sIUcXGzUKS+9yo<VAbC+3#jWgc@8 zXa}!Tx(4(D5pGC(+Kl72S3GxGScX+W@nf=hvDE9B1nAIDI3@+gPLAq@a|UN-$&;h$ z<V-<?&bl2H*+}OJ<q<Z=R&imC0!c>`pg2)e3{E?|Z@lDrp4=_?1_3(H=stjr312&F z6g<M4;6I7)l?sIN&<j=CzgMx>ToQt_|HU`ggZrp$(WkI2`Z*7meOc$S|7ZAqA#S%Z z7n*G|XS3!k$qTOoJi`ufGP{PzT%I^jp3HF=fo2`kegwJmr^2{d)Xf~&BqkId^Cza& zRhUdsN`tW$;kdcu3~J5ez_cSNxv{$FGT$V8kT+H@Zr~v3@w`yC$0ukFVA%fYn2j9C zQlFzKI$ly4O32}wVnhTNoEWgLiUVG{#GWL%{J+eT@tG!>%f`OzV`Ep~9(~e*L->ZC zyg<Sul0jvZTl75G)AqGo9bdm30;oq2+V$>)CXJn$gNGvs>r^LBK!?1nFzP3sBNT06 zAt0f0!aaqNcmgR0n9<lp-m<5s(M8~OC>zoQ2jNiQKa2vRWXkNFY$Uz9s1jbCyio3% ztH6d@ECJVo8FLoV-|sy0%V$V%0A~q@w1io@;8@DNN$`_S<-%0x&6vGevsYk{{pti7 z6(JHN_fI=rk8kMur^3kpsaRo-ER3}JHKZkLtqlyY<H;ModIRwR_5@*biA1XCiQxE^ zMoUY%zYJ?x()bLj%8I5uku2D(r_n5Q2pU9blg86tit<{%ofJqXbV{~wB4+Hnn0;^2 z5grJ~k`>h&vur&;i*~2WTd?&82|AWnel?L-d|=(Kjdgj#CCUY=wL?;nC^;3YX9<Jl z1eq=;+k~p6Dpy1#2H8W@z84@vh*PRLiG!}LE*1sefQV>iNiO^qD}JTU)c2VKzdAtp zc)FOc)ogcX@xTU7kMfAcMiPTcqs<r3#FE-GG)PeR2fZv{aILDAZ+sY{6sp^JWOxf7 z66SCnW3|h8KVgP5VmXP#m2&L@Iu6{CrZ^pMprD}TN0%N1=`}vq#Cj4W_eyU3^l}2( zjjLHwV)3?)x8GskLCPv0dofm*yN5{c=>JF3^Vu-=5p`2aPdvsfe3l0ODx@b$Vd**K zm7d3x^yD7%kw={HbdMrYXOCR5?8JsKPy*h0EHlQATcKUbfNnp(i`a$XdByJ{-M7y< ziU6fe8u*RR=VK=mQZmQOD31;}Udsm!tpVi`E?NQXw=!%XXpfyCiRCR6Z1VFE=VLUl z*qX<5WYO7Cka?8g^a=~D=*{iKfBGHIDseUV-TLWZKd~Wmzsu%atXmMlMRN5Htl7Oi zw}VBlj^k;pPML=ud+lGnMuG~$m-l&0q&(58!(Y<@>(yC>KkLZg&(eU!Xl^g?uzoIV zlEr5QKnUHM^o3XoLB)I#L9|*dX9;*}fe~}uxYIw{1cR`D_K7!fHttK#W-SH>#3LTw z@N5C7<HyxTJbgZ<;?!8rZV#X5PQxdQj+c0u;g%5-%M7=?wI-}?S~FC9lV!@?WcVBj z??x^}^kJ@?Smn)A00%@@T}%iZ=-nO|76oT(13r$%i6c7n?epK3;c>#YZ_t_RQYftR zQ|LQkSc*`TgA${Ihri%Z=oj36_l3m<L6|3Ph=C7fGW!We%&Ep`;{bB{$(Eb95*`)< z;c6hdvwO7^^rG96klMW{$;CNVU=GajLW6v_Rx@WC-Yrny7p$o|Lj7qquS*nc&QLyY z)&f8qK3kPE9zby`mQQO3_UTAM2NI$yn07!X_zy20R;GXfl1Go1FS<9$D8;*CKpy?` z(O-<xMzi7&g0YE2<HA_h?b0iolwXYLQs1QfB2P+u@}!(lr@TO=GcPshwF-1LS#qjd zEjPG8o_7yqhi!67q@dAe-1M_>x?V;oqMDv@`1$}GEp)^MEt|_ykMa=@+=ZUay2-f5 ziy)|f!%wKyi{S#i=D@dK`kyaR^bZ>v-5$TFsXnVE;+Lq$V+00257(r@y|cMbv8B)a z6o`9dt*DZ(yYI7M*sINK^V{N>rlsIVB$f1p6LCZHV9z}q*)XHQbsgX9+z+dXy_5-6 z@MZX>8!{1yUIkyu%{7EdeZKWut+Yyuwo@8|T4sp-l*THpv<%GQp1GfCqp_5G*2_HG zSj8rDREG?v#n+t~b7$7vsh@uxXKNxgNR5nFBc=P{-rcAi%tn37xxyQ$jV(Cp3upcl z!kGB*Z>HLWLA%XL2?8^)*9R7EXF#1sJ%+e8j=%KpzZBghfYdLAp&8uN`YyVJ=qIA= z2pOZA>+g}j{=)VbNzoz=jjS%-Z5l6Qft#GaL7DinBS~M5VU|hb4_0^zz6o3XkTO<a z(Wd!ogSXaN!*B#+evYQ`7U@IbCG<3VeXB;K>Pyp@rZoMn3Uf6Q<7h0Q{*%3Zg-I>D z524R2le~)oPR(P58SK-&qXM)OOXWlqJxK>0k(dfu0Ua5`arDkt?lcWyfL=VfDQO;D zJa|uVZ?7Dz5@rWY+a?imuyRP=-AVWSivi)<=Tg{rDN9*Z;6fsGHv&QLqsra1Xztu< z_AZ)xH=6tV&HY<>iNe;vi_C^0Faq~B_U#}Kcp!{0EDUkrm|d+GYi7fCvmu*$=<yxw Z1>i$I&4vu_wbG)X9lYM$G#WP<{|{H33E=<$ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta deleted file mode 100644 index 6587875a9ea9dec90101364c1e7d76d5ef2dffcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmdo0G9#4%23VmCPAHw8lbV>TpP5&}jUteilb?ttlwXvRTEvB-svt2FO(Z2Vxn%E! Lc~|2ZcNPEuC=VMA diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache deleted file mode 100644 index eb3b7c68476e2ba0e42159d0fb641fa4439c5c1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4740 zcmc&%O>7%Q6y7(x?q(f3+rdfGgqFB21+*%P5(^>u;yOwYRE1`}m4Yl#>eQRWjqSDU zb$?JLLscY>zzK1oLLA_VdH``kMd}4{=!qUGAp}xSoO&;BW@k59ckLQS3WpuP_0Eju z``&xsdvgL5`5!o=(wQPXHNEg~8dCQsfYQsUKPMoyp~I7{nq98X*UJ(#J$t?FN_wSM z-6$x8#xkY?iu!iB31FTkGVQF<SaCrsg%_^kCT%<2QE+g#?es-&*Gl!0dof*iDxI30 zt~T1PEte}2P|cuPi6+<dWt<>RP^n7tCD$AyG7t$L0EvX(3d@9kY?!w|PIX|(asiFc zh+%z7(5TBxR!v6ZeI;YPr=amstYqDap+Qx{I;^5`eJp2P8$;t~t!VwCq49S-XZ;mN z!%P^~Y66WPlZN#}5{>UBa;dWbshbL<KF8<gA^gSXYYkH0<C7bQ)Y);+ckJtJ<R(pI z^A5xo0GatOY#>aDYV+m=B1@8~;P`BMkRXBt$&$jET*USIxoX>;<E*ny@GH)V0eadn zkKs?UNRQzd=f~aabBSbsQXVK>*IBRO76Qp12Zco8NMZw!AT3l|lfa7w@E3UCmO|is z5Iy)-zyZBo{lFIBZXXo5LmZsSz-6e0Zc^2^8p2DfM2>O~J7)O!^x@;~cDcQdaklR; zTQj$Lm|>D(m>oCh@e)0;hQTr>k$$<zzTpgQ*F~zn<Ty1i*f<PAX^$hsfx}3$d9p#& zE!z*WM<e^8FOK*C9QX}!j58cL?v1s4(QbEYe%f&5@xJ@sdZ*e0GZTt8hNTDMq`WLY zsh6AUSIV`HB-=t7tTgNc?6*-)W4cigMD+Dtf@4nlN(#X{GBF`MI!K7cf(fQ2=;e}$ zI4CXBb2!FBI72*00ILAF0$whR5t=k;0>x(*NBwHm-A3WAHY6$gs<N)=Zh1!}W^q3p zeG<VD#(2S?g+*GJ@5_+R89Iz{^OS<>!w?j#=L7{}`z9A#hHVI9mKZUcEvGI?-5uL* zRvTLY*@SjR%UA50?fSwsx+?cg7&;(f@EeB7bHlLUPxZni=Vu9LL0}ljLyiXs3zGn` zASC-z{9ODABZt)|34HMwor`%Pg1fags(|*CofPL{au_cBsa}OD`YDs<DYFMih!B#! z3y&a=J(At>AwC{iGP>pso(>7F^9u%DDACuL&QEa|M+P|EpW(F@1GT}Qia=#b1E;^s zLSG;WVHBz$Q+U0QAap82CxK4o_-Np$ZaOUpI3Rkp;X0@iU&_D9dZp#C4ivkr|3xLH zId4a!RAPFVm<ZNKsRY9oMO2S`vg{B^A?V0{6aPJ~Z#uP#M-AP85&O?BUBr4~J{2#| zBW_-3x|HB=UlpC<{LEsV!7VV(*g68izxmB-&9z(DEO_5`4T$mJ33QVO4~G=RNDw+K zT<Fy9=#>?sJ6G%$9+PDmD(HjpR}!lrd*oQB_fuZ(M3fhgnP-*YW1NcPK?(NXgWkQT zof@Y9_xFgDTaW7~`htLBm6#@3+2MtFPto~8y{}Tp<yre;w*&GH?rQS_r)y3mRg^Ll zm=jl<KyvuiMw~eWoMca`D+p+Du5P!s>;R8-bU(pxJ0ciFuTi2aeQ&jp=GaaQP+xz> z5bEns^<rQ#RB}DEAts_*vOrS+e7XHfyQfjes15sSK$rR9$fZbS_clqwj2|YjGn}E5 zIAXQzX}0k|Aw+m_CHF9-bNNoQQg-(^cX@Q@cFkY8bDvVe7ulIu%RO&iV>9|nA)83x z6z02VFz~W*nI`A+=bLWTX$S~TQ_|V1xUA!JzGw))2m41=U5|+nO}$mu6HTw`&Z3M8 z=@caTt$A+z#yAD_OduIKnmj^h3_5c}+?r@?mc|z4^E-1Zt(Mc`cS0I7@IU=Rt7Ff- MQLeRZ+~P3&3(lYD?EnA( diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta deleted file mode 100644 index 0b52486cfc5f05044b9b56a9fe4cd784dca2c15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache deleted file mode 100644 index d989e36ec8ef38c79c74bfdc93342613440fcf1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7258 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 Pj|J8O*Ho0G-yr`36)Isa diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta deleted file mode 100644 index 8b36f47ca8f554f7005ebbf3285be4ae7326420d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache deleted file mode 100644 index 62529545334bdbdf0797dc5ba7779d6eadbcbd7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2702 zcmd5;U2hvj6y4d6Y`kh@uB<ePX~-mPr8L^4i9=LjA<`I(RVh-lbtE3zs$Sbu+pyk^ zcgKl~ic;~2KuEj*PY9mj9q|wNC-A^;D0gPo0b9gTs|r=JN3%0`=FUC$+%vP;)^FRe zP>1Vt@Z{UvpVM;yALo`cw{o9l?B}h3`Q4jQtl3Q#tFK21*Rsu^Q{OXnunL|@%%!_A zP7~tI>ju1IgH?x&GrCsOAya@%9cFB0Jvx1$8~EG1rb9XJeLxKOCGY)AjNAfQsm>G8 z(Xpe8j!~@68`#O1rRubaopmc;buH|CZ<VUwiO!;3tX{E+VU&A#s7t!xxx@nETzm+? z03h#OAp|Iq$1UL|qh~#(<zC+p9F4#aKN=POaxN&kxTaiuikpnOcup%Z^Er#PUCP^j zD180;o89e%sk1LtJQ^XI2APjM1W(hvX>18B7GSXs%Qkiw3L>+M=Rtl>CUD^exw423 zu;LwJ3^R2&BwI7z7~*u}QQTv^ABV{d2El03^@D&VoJNl+KZ$50NR!Z3=a_{eN=|DP zPTxaxvDxRf4acEZuhR0s?;hbg{HoPzl8_D>ptsd>&qc!<4mNVq!4#A2*{OG@?5;m} zU7`8{q4Eb4p$h!C_3DuF2mc^d?kS|O7PjBCO4crq9(BSYhnpj`y6L%+R;HxY1(Xn^ zS&_W4?K>e~l8HiETF4P7dV!)!fK*u<Ivt1LAdZ^-2FoSXr(wU#;!cCc>?mdl3%Sob zQ7EZ{RFc%0%nudUs-(yIRvPpOgHnrf4+*q6!Jr}-CU(fyYK|b7W4Oj?BkCUcF?)?j zR`MPwkOv5I-W;BA9Od`b!Lx}h!kU!s8a?)dKEoj_%aBn&jId&3mmbNKbi$TM2|J;w z`DEx*Xe8-QI=o#}MOslsYB&xd2ZW%6kU4pWtbs|g!jO<{+q`8O`$Imypltt3Q|q|N zc;x#mN!EE=vz4HJ_4R4Yj!}Y!N&I7s{lSp^LzUf>1E{h@*TmntNGD%<p{$yc_f#eH zsYvM5@U-J$-3c)Wp3Gs^RAGp8J?@7MQ86w}B8uuM0>}9}!{lI|Tk3jIgMQc?8F0?b z&K6Eic+g4sMiRw*_5PMicU=1RLzmW{6tQ|GzN@G(8!0PpU@_enCNAB2D60+$fkoA@ zf3kN&*1}sat*Q1{I$ltWCcic$z(wzw0{9sM{P|Ss{v3Q4&hY(TFjY_}{Yoom>;_CN zq<)>r`iR2)=N=k@{X6-KsOKBD>J{Lj%ENW>Xt+S=Z|i%PbeJu|>}6Ok!17zLvj#ht zcki*JA8@ep_$V~)ezH`K<0w{pLng0&Sd{pj!skx56h#48YiOH2jQecqLqAB^8{}`- CaHa16 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta deleted file mode 100644 index 2395015401100f34736675fe98225d853098d534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache deleted file mode 100644 index a00ce91d6e967cccbc3fb06b812213d5f34dd21a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1882 zcmb`IPiqrF7{>RV&ARQ{5XWF?1<8v+Ok-_LqL)Ce3Q7?{HxUW}ao6rNS>0|zcGE`G zd%u9-!GjkM9tA&vAHky_c+iUnPoBK!JF{s_Y*Z8vozCq1eSXg~6J!@mKHuOcOn#!7 zePNoM-_1TZPiEhl=C@`b+^yw~tLc6>Y21!tE#n3LoeS*Z9OI{}_9E!nX(-pHfGQv1 zc>RN{7<#du(y4MJRjbdXsPfWi)L$8(uSQ~{9eM!v4Abox3=Wp20caYZUbfemu4#6P z(Ny_iT?2cH8cd@<8pD#(0N}i8uhGABgRem;{fQ0M9X~VHMBM9!k%e(fV6rocKx~OH zMn6OsJFeedvMkK!@p9kY>I5R9mg6`|yM^ZmvkLh_X%Wi{3l^5CKjS!-r9tHsT!Y-E z-;LtG6hxAw7+sZASCY!3lHRgp;om7zJO8a9HEBdoN$J(49^QLwhGJ)+Wp~V+b^DAm zNBIFMb#Q~qaie~87{E9`Zub+D`ef1@LoPm9&n$UCoyrf~@#B_qtm$uya8F;fgg0A$ zgc~jy7esBmBhYJy0(+4kHr04fc>abP3(vynei*xbGC7Kc>s8UA)e{SGWd#RrI!hKx z?_WO~nosRf_lL7+STbGpTS%#eif8N^nP|uD42V4&Blhb!!vTfQ+>cLwVzOHWqG;bp z@ZBJMS9P`3WPURf`3<5Tp*&+pcz;Mb4I0TszEEDo5(S=kP&ioSGo;zKEw^)9CP;(5 z$iE*Gy>9OgV<Mw*jP9_y-RJgjBmtUILZ>yRZaagdP22n&DEWy24OD@u*@3+L4gLg5 z{A+6TIFrE~o(N|A;<VgtnV^>Ip(C^BAkhkZ;bGji(2swQZIBCmcpmrQ#D&eU5H8>Y z46%r1d_)u#&hmn_n(zc5Yw3!>$%|8rr;qX(dd!Mc>g`QU%gAE@RKBp1t~AQGOVfw% z=D#sNs8G%fnNy9>ruQ>X22zJ&-mod(lKE3&ZW&|enG8KU5&BQ>?|-G9tUVDsz1wGp zDW))vahJps`UB(&e<hc?m7<?G=}eWUXZd`Q&(E&bMAQpnZXD%CS-*ZSce&ebcQcpT V?SLCa`j)xb?TOqKdYr@|_ztuamw*5O diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta deleted file mode 100644 index a2089a5966a154b5dd61585b9e0a71668b274981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2a#5L@9-R#`vm|lvIQ^z diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache deleted file mode 100644 index 4d6134cf4e68169d226aceadc5fdefbd5f41adf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7021 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 W-%Mz(0#i!(lf#_&1p(}yApZfAnRP4x diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta deleted file mode 100644 index 6ec02d279a3395e477453db0c144ac488b739524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache deleted file mode 100644 index 282e43017750880bf511116eb8b996a120881481..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6600 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 Neknf1VWdo=e*-)qppF0l diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta deleted file mode 100644 index d6129ae46ca64f4056698206dc7d3f0de91184f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd<{vr1)v0Y)f;2TG^sq$cL-=NFV@=I0$1IkMi{#QhNfhQkTV diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache deleted file mode 100644 index eb16341caefa07a4c1de8fb33938ecf99628822a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10378 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 b(1okBVgj+XrwtcyZi3J}D{zV_CfWZ04`O&F diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta deleted file mode 100644 index f4e887486561f8be3945fd8b61344d52d6d64401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmZ4IWtGYR1B_4x7nDxVNlnbv&&ez<xplPfLd0zE)c}_f3VHwl diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache deleted file mode 100644 index 7288ab8ea66c60f3bcc197fd340bcd4f26588a9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6383 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 P+%5{hElSW}%?0v5M-3Z= diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta deleted file mode 100644 index e4e832bc82346f74985f18beddf6b6e9edaf3e83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache deleted file mode 100644 index 803b10a07332be0a84317d77acfedc7e16097fe4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21827 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 YH29;}<h~SI7$ToB%;P7#_D<=40L?3M5dZ)H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta deleted file mode 100644 index 7c72b25579dddf57ca0f1d52e021b5c2d8247d4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache deleted file mode 100644 index 8621e14afe1d360db5a53e513ea69d7e2ca45e60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10568 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 W@@*iRn844H!uq4K?}B#x0QoPNKzVuq diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta deleted file mode 100644 index b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache deleted file mode 100644 index 6854436ee19d2eb620c05cf18f373ecb1659021c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7764 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 Hu#5Z;9viuX diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta deleted file mode 100644 index 2ae412bccfd7739434a236925520c9652e93ff84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<<f}##0 V7N1m_nUj)Q<er!*%^>nW832Uh9(Di# diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache deleted file mode 100644 index eba4407d83485e5a7ee4f182cdc6fdb2fb69ed59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3252 zcmbVOO>7fa5Z<?Id$U%88M#3TBF%!J&{fq?n@WvUWb8JSSS@5(C?yhd*7kF<us_l6 z8f2s@aA*%!FO{g&LsfC<0jUQLtwg!^)=E@W)pF(5Q_nrQ^WLtBH`p{FMb0>RZ|0kM z-+VL2%hD+sW@~WdQvP4^XMT242B_tyCvW5*Ps;suo6?SJg@Paq+m%;DIMUPKASviR z)NkRhUu*g!lFH8#&6pu*Tp<l(4UPVJy6O4hM;>W)Y<kvos6g}?QG$vL=^7~6A-57J zJq!-h@`ziB_$#7>Km8A4bY#W%)_ocT<#U^%<++0JoDdJ=5aTWn0TSXkOK#I^S?;<J zV?Q|(dkv;)0CIo(^a#wkO6WN;zQvJlG*Hl!%ny#j!kz=u6y)thN8@P>@C@I0)??*_ z2(+NLhy=e?@e!r`Nqoe236YBT$bMoxKr4S+)Qnpq8naT>n32%<N-7z5m~k(4-uOO+ z#*b;u_#utP&zYX_O9qW4dDS>0qj7nnYJ4(*22q|ElM0dM&w3ZaF4kdEl=R~y4J0dw zpzH=RAbFsmA0Px&!fTa{ybYx$6|cw*dFx~9H@twpe3)t?%)nnFkRh+ixr<@@ooAx_ zKOaCO09qmjca;cmDDzsT-!k2G>U$k2u)Fo9=U%6NSPw!UNm&oQx*1BGRjis{MAZ}s z5d=^!>BwP(Hi4f6=1MSEfH@h>=^E?$Ik{|bFZ0;xro)<QJbm$&@*H-ii3o6$X9FcT zKwv7{Z&<GBck7{0W*|MMOnn<u5yav~=DSR8!?aOaI0@Dguov`W9CnJsRt|wu07aIU z-S8<;hGy{hvzGnz?`b3k78O+prb;k_r?NcGcIYotcT-y}ukM%@lL}U}Q;Fy@FBj|n zaY0y&h#c7SJk^22#M=ep=VCchz&Oxfi9ieb*Ml?(z7jqcDop%TJvdT>*V$7Y)ZkzN z4le9M6>}e2L0lp|uH6gj9m{w(Z8(i;08mPhH%>KC0xEwi_x+ArXLCd#gXeyfsKX`w z4zEL;y2e?$fKV1SSS-Ne!ic<{!^9D%casuJy$Xtt>bv!R*EJoh$x<<$g;rOX=iiYM zoaQmV3NgPzidByWrC9t!&P?POw+MM@ZfW{`#@`y;CvQ#NRJgmLvI>3mwB@!`(>>f$ zvAC*f+bRR0wmWW<jle){d%hZOP_^0ded>nlrte*)%~0(GC>rV#@57^kx^xleNjARh z<9xp1`PbgeX4Q(@jZdlQ38$s$JoT<xF8960Vy>wz%SX?i-&Jo|;f89eSSza1mKCy4 zmYY@A>d{FnP*J@Ct3`c^@ROJ^ofdk)R2r0J#ZWA_ndLG+o~zc(>!#84t<8|%42Dk+ zVmCVh3Qgo0ua;fvqa%S7Pm@*h?8<-*#{}R+#7CS#yI(=LeE0Oj_)^DE4{&kGj_^Oc z1W3ilnZGmrHojfGZP|iEgIE{t?&yaz!~HO%+9jAS;DWSMwRe7JRK^BD(Hzw}rASV9 zUgFGN)m0{LS78M|vk9o%1kBajZ40*{vO)-|J~>*M5E)zd;+_5Y*>}vaxq**{XC&4L z#c$HTr?=koY!BZ(PT5YRyhHIL@N%x|dE3&?vU))|LzzNMJLY(dV>=%~D$dCoUw2Ih z2dY?)=2YGB*xFimWwyBPVo;5#ECW8~Uwm9W(T^caoX5zcS-ujFhmk=2Q|h18DY0@u zgtvQeat|zPu)Gg0HsJEB;FQ4G2VD)i8R$HOPxrv>8ho~A)D!{I8^v5+eMoDNF61uw z9Xfy7v;*2-8eS;5WFpT>gY76<#^O<czk-e(LV7>?kj`D3U-Es=k9ON}3pkMKfGNYv L2oQ}gM|;VC-XAjg diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta deleted file mode 100644 index 35823f819643250ce036eb3ade6a8b4cfeac4a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0<IM LSG~Z5x<GpX@`M<b diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache deleted file mode 100644 index a3585a7b2363d00cd2098856aa13f726f10532f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1132 zcmb`GL5tH+5Xaxl>uZ`~i9>azQphS>T;ri@)yrP21^3W{`nJO2#oDr|?QU$aZ4hBa z=+TRxz@y;Bi{HYlXZ;#p>%26{ZlMc;9x@qT!u$W`KQlXBXj)X6Q_Z5<n{rKAMD6l5 zb))=DS&Nr}??>a&4C~Wj7zKwSJrJUa52{G_8u~6s`qk1uL6+abe&+-@xrtt98#(!m z?amjI__Ey@N>1!tqf^L%bp6*+F96UNQ0gHlf}#)rLXdr+cTftU3n&4Fc@){#$!?Hs zS&v46%M`s=Pf#jAq9eTtz%Sb5SX?YYyS{MD{aFRV=?(@Xfp_-cIlS-t-Pt7a6ZID> z>UF&xtLHcZ+1^suX@%jbu=%hah#6YC%0Q(#RXG+@t&9XxFB#@z{#$-A4rg6shJe4Y zgB?OZj=A#)*pd%=iwQ0t(H6(dk})Jgfe;x@=F3<34$h!AN*S6frdXyKLa^uOm2P_A ztyCW0mI<9L`-*kTT5u2i$t0Wz)Ao1@PF5uA+NcSg^kFyd!@>Q1e;NfdHy!~4#b#h^ ziA<w1DD$;b(Z^IY9prQ@-r*-SNP}K5^-q!h^Juh}RP$t3&*-i7=|}!|-sPXd<9~E0 z7ki`P$a(D0`n~B3$LM7^*?e5W+sHd#Kq~E0X@e>rRW_1tkh)5$As-*R4^2noT_NT1 One&v_%-u7lUW7mHN#Q#H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta deleted file mode 100644 index 401fd74cd1e9eb44559765e4eac26450d3f34537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md deleted file mode 100644 index 90ab0d56c57..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# gleam-community/ansi - -Format text with ANSI escape sequences. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_ansi)](https://hex.pm/packages/gleam_community_ansi) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_ansi/) - -✨ This project is written in _pure Gleam_ so you can use it anywhere Gleam runs: -Erlang, Elixir, Node, Deno, even [some browsers](https://bit.ly/devtools-console-ansi-support)! - ---- - -## Quickstart - -```gleam -import gleam/io -import gleam_community/ansi - -pub fn main() { - let greeting = "Hello, " <> ansi.pink("world") <> "!" - - greeting - |> ansi.bg_white - |> io.println -} - -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_ansi) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_ansi -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_ansi). - -## ANSI-what? - -ANSI escape sequences date back to the 70s as a standard way to format text on -various video text terminals. Since then they have been adopted by many software -terminal emulators and platforms, including some Web browsers, and are a simple -way to format text without platform-specific APIs. - -The point of this package is to abstract the specific codes away and give you an -easy-to-understand API for formatting and colouring terminal text. Still, here is -a quick couple of examples of what's happening under the hood. - -You can copy these examples straight into your terminal to see them in action! - -- Colour text yellow: - - ```shell - $ echo "\e[33mhello" - ``` - -- Colour the background pink: - - ```shell - $ echo "\e[45mhello" - ``` - -- Render text italic: - - ```shell - $ echo "\e[3mhello\e[23m" - ``` - -As you can see, the escape sequences are a bit obscure. Sure, you could hard code -them, or you could use this package! diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml deleted file mode 100644 index 5da1f7ec075..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "gleam_community_ansi" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "ANSI colours, formatting, and control codes" -repository = { type = "github", user = "gleam-community", repo = "ansi" } -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_community_colour = "~> 1.2" - -[dev-dependencies] -gleeunit = "~> 0.11" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam deleted file mode 100644 index a542ddac7ec..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam +++ /dev/null @@ -1,2317 +0,0 @@ -//// -//// - **Text style** -//// - [`bold`](#bold) -//// - [`italic`](#italic) -//// - [`underline`](#underline) -//// - [`strikethrough`](#strikethrough) -//// - [`inverse`](#inverse) -//// - [`dim`](#dim) -//// - [`hidden`](#hidden) -//// - [`reset`](#reset) -//// - **Text colour** -//// - [`black`](#black) -//// - [`red`](#red) -//// - [`green`](#green) -//// - [`yellow`](#yellow) -//// - [`blue`](#blue) -//// - [`magenta`](#magenta) -//// - [`cyan`](#cyan) -//// - [`white`](#white) -//// - [`pink`](#pink) -//// - [`grey`](#grey) -//// - [`gray`](#gray) -//// - [`bright_black`](#bright_black) -//// - [`bright_red`](#bright_red) -//// - [`bright_green`](#bright_green) -//// - [`bright_yellow`](#bright_yellow) -//// - [`bright_blue`](#bright_blue) -//// - [`bright_magenta`](#bright_magenta) -//// - [`bright_cyan`](#bright_cyan) -//// - [`bright_white`](#bright_white) -//// - [`hex`](#hex) -//// - [`colour`](#colour) -//// - [`color`](#color) -//// - **Background colour** -//// - [`bg_black`](#bg_black) -//// - [`bg_red`](#bg_red) -//// - [`bg_green`](#bg_green) -//// - [`bg_yellow`](#bg_yellow) -//// - [`bg_blue`](#bg_blue) -//// - [`bg_magenta`](#bg_magenta) -//// - [`bg_cyan`](#bg_cyan) -//// - [`bg_white`](#bg_white) -//// - [`bg_pink`](#bg_pink) -//// - [`bg_bright_black`](#bg_bright_black) -//// - [`bg_bright_red`](#bg_bright_red) -//// - [`bg_bright_green`](#bg_bright_green) -//// - [`bg_bright_yellow`](#bg_bright_yellow) -//// - [`bg_bright_blue`](#bg_bright_blue) -//// - [`bg_bright_magenta`](#bg_bright_magenta) -//// - [`bg_bright_cyan`](#bg_bright_cyan) -//// - [`bg_bright_white`](#bg_bright_white) -//// - [`bg_hex`](#bg_hex) -//// - [`bg_colour`](#bg_colour) -//// - [`bg_color`](#bg_color) -//// -//// --- -//// -//// This package was heavily inspired by the `colours` module in the Deno standard -//// library. The original source code can be found -//// <a href="https://deno.land/std@0.167.0/fmt/colours.ts">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018-2022 the Deno authors. -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the Deno `colours` module: -// -// https://deno.land/std@0.167.0/fmt/colours.ts -// - -// This seems like a really handy reference if/when we want to expand this beyond -// formatting escape sequences: -// -// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/list -import gleam/string -import gleam_community/colour.{type Colour} as gc_colour - -// CONSTS --------------------------------------------------------------------- - -const asci_escape_character = "" - -// TYPES ---------------------------------------------------------------------- - -type Code { - Code(open: String, close: String, regexp: String) -} - -// UTILITY -------------------------------------------------------------------- - -/// Builds colour code -fn code(open: List(Int), close: Int) -> Code { - let close_str = int.to_string(close) - let open_strs = list.map(open, int.to_string) - - Code( - open: asci_escape_character <> "[" <> string.join(open_strs, ";") <> "m", - close: asci_escape_character <> "[" <> close_str <> "m", - regexp: asci_escape_character <> "[" <> close_str <> "m", - ) -} - -/// Applies colour and background based on colour code and its associated text -fn run(text: String, code: Code) -> String { - code.open <> string.replace(text, code.regexp, code.open) <> code.close -} - -// STYLES --------------------------------------------------------------------- - -/// Reset the text modified -pub fn reset(text: String) -> String { - run(text, code([0], 0)) -} - -/// Style the given text bold. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bold("lucy") -/// // => "\x1B[1mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bold(text: String) -> String { - run(text, code([1], 22)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("lucy") -/// // => "\x1B[2mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn dim(text: String) -> String { - run(text, code([2], 22)) -} - -/// Style the given text italic. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.italic("lucy") -/// // => "\x1B[3mlucy\x1B[23m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[23m"` added to the string. This is the escape code -/// for the "default" italic style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be underlined but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn italic(text: String) -> String { - run(text, code([3], 23)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("lucy") -/// // => "\x1B[4mlucy\x1B[24m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[24m"` added to the string. This is the escape code -/// for the "default" underline style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn underline(text: String) -> String { - run(text, code([4], 24)) -} - -/// Inverse the given text's colour, and background colour. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.inverse("lucy") -/// // => "\x1B[7mlucy\x1B[27m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[27m"` added to the string. This is the escape code -/// for the "default" inverse style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn inverse(text: String) -> String { - run(text, code([7], 27)) -} - -/// Style the given text to be hidden. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hidden("lucy") -/// // => "\x1B[8mlucy\x1B[28m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[28m"` added to the string. This is the escape code -/// for the "default" hidden style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hidden(text: String) -> String { - run(text, code([8], 28)) -} - -/// Style the given text to be striked through. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.strikethrough("lucy") -/// // => "\x1B[9mlucy\x1B[29m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[29m"` added to the string. This is the escape code -/// for the "default" strikethrough style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn strikethrough(text: String) -> String { - run(text, code([9], 29)) -} - -// FOREGROUND ----------------------------------------------------------------- - -/// Colour the given text black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.black("lucy") -/// // => "\x1B[30mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn black(text: String) -> String { - run(text, code([30], 39)) -} - -/// Colour the given text red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.red("lucy") -/// // => "\x1B[31mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn red(text: String) -> String { - run(text, code([31], 39)) -} - -/// Colour the given text green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.green("lucy") -/// // => "\x1B[32mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn green(text: String) -> String { - run(text, code([32], 39)) -} - -/// Colour the given text yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("lucy") -/// // => "\x1B[33mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn yellow(text: String) -> String { - run(text, code([33], 39)) -} - -/// Colour the given text blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.blue("lucy") -/// // => "\x1B[34mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn blue(text: String) -> String { - run(text, code([34], 39)) -} - -/// Colour the given text magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.magenta("lucy") -/// // => "\x1B[35mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn magenta(text: String) -> String { - run(text, code([35], 39)) -} - -/// Colour the given text cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.cyan("lucy") -/// // => "\x1B[36mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cyan(text: String) -> String { - run(text, code([36], 39)) -} - -/// Colour the given text white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.white("lucy") -/// // => "\x1B[37mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn white(text: String) -> String { - run(text, code([37], 39)) -} - -/// Colour the given text gray. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.gray("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn grey(text: String) -> String { - bright_black(text) -} - -/// This is an alias for [`grey`](#grey) for those who prefer the American English -/// spelling. -/// -pub fn gray(text: String) -> String { - bright_black(text) -} - -/// Colour the given text bright black. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_black("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_black(text: String) -> String { - run(text, code([90], 39)) -} - -/// Colour the given text bright red. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_red("lucy") -/// // => "\x1B[91mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_red(text: String) -> String { - run(text, code([91], 39)) -} - -/// Colour the given text bright green. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_green("lucy") -/// // => "\x1B[92mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_green(text: String) -> String { - run(text, code([92], 39)) -} - -/// Colour the given text bright yellow. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_yellow("lucy") -/// // => "\x1B[93mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_yellow(text: String) -> String { - run(text, code([93], 39)) -} - -/// Colour the given text bright blue. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_blue("lucy") -/// // => "\x1B[94mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_blue(text: String) -> String { - run(text, code([94], 39)) -} - -/// Colour the given text bright gremagentaen. This should increase the luminosity -/// of the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_magenta("lucy") -/// // => "\x1B[95mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_magenta(text: String) -> String { - run(text, code([95], 39)) -} - -/// Colour the given text bright cyan. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_cyan("lucy") -/// // => "\x1B[96mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_cyan(text: String) -> String { - run(text, code([96], 39)) -} - -/// Colour the given text bright white. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_white("lucy") -/// // => "\x1B[97mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_white(text: String) -> String { - run(text, code([97], 39)) -} - -/// Colour the given text pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.pink("lucy") -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn pink(text: String) -> String { - hex(text, 0xffaff3) -} - -/// Colour the given text the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hex(text: String, colour: Int) -> String { - let colour = int.clamp(colour, max: 0xffffff, min: 0x0) - run( - text, - code( - [ - 38, - 2, - int.bitwise_shift_right(colour, 16) - |> int.bitwise_and(0xff), - int.bitwise_shift_right(colour, 8) - |> int.bitwise_and(0xff), - int.bitwise_and(colour, 0xff), - ], - 39, - ), - ) -} - -/// Colour the given text the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - hex(text, hex_colour) -} - -/// This is an alias for [`colour`](#colour) for those who prefer the American English -/// spelling. -/// -pub fn color(text: String, color: Colour) -> String { - colour(text, color) -} - -// BACKGROUND ----------------------------------------------------------------- - -/// Colour the given text's background black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_black("lucy") -/// // => "\x1B[40mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_black(text: String) -> String { - run(text, code([40], 49)) -} - -/// Colour the given text's background red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_red("lucy") -/// // => "\x1B[41mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_red(text: String) -> String { - run(text, code([41], 49)) -} - -/// Colour the given text's background green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_green("lucy") -/// // => "\x1B[42mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_green(text: String) -> String { - run(text, code([42], 49)) -} - -/// Colour the given text's background yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_yellow("lucy") -/// // => "\x1B[43mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_yellow(text: String) -> String { - run(text, code([43], 49)) -} - -/// Colour the given text's background blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_blue("lucy") -/// // => "\x1B[44mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_blue(text: String) -> String { - run(text, code([44], 49)) -} - -/// Colour the given text's background magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_magenta("lucy") -/// // => "\x1B[45mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_magenta(text: String) -> String { - run(text, code([45], 49)) -} - -/// Colour the given text's background cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_cyan("lucy") -/// // => "\x1B[46mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_cyan(text: String) -> String { - run(text, code([46], 49)) -} - -/// Colour the given text's background white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_white("lucy") -/// // => "\x1B[47mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_white(text: String) -> String { - run(text, code([47], 49)) -} - -/// Colour the given text's background bright black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_black("lucy") -/// // => "\x1B[100mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_black(text: String) -> String { - run(text, code([100], 49)) -} - -/// Colour the given text's background bright red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_red("lucy") -/// // => "\x1B[101mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_red(text: String) -> String { - run(text, code([101], 49)) -} - -/// Colour the given text's background bright green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_green("lucy") -/// // => "\x1B[102mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_green(text: String) -> String { - run(text, code([102], 49)) -} - -/// Colour the given text's background bright yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_yellow("lucy") -/// // => "\x1B[103mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_yellow(text: String) -> String { - run(text, code([103], 49)) -} - -/// Colour the given text's background bright blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_blue("lucy") -/// // => "\x1B[104mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_blue(text: String) -> String { - run(text, code([104], 49)) -} - -/// Colour the given text's background bright magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_magenta("lucy") -/// // => "\x1B[105mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_magenta(text: String) -> String { - run(text, code([105], 49)) -} - -/// Colour the given text's background bright cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_cyan("lucy") -/// // => "\x1B[106mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_cyan(text: String) -> String { - run(text, code([106], 49)) -} - -/// Colour the given text's background bright white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_white("lucy") -/// // => "\x1B[107mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_white(text: String) -> String { - run(text, code([107], 49)) -} - -/// Colour the given text's background pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_pink("lucy") -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_pink(text: String) -> String { - bg_hex(text, 0xffaff3) -} - -/// Colour the given text's background the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_hex(text: String, colour: Int) -> String { - run( - text, - code( - [ - 48, - 2, - int.bitwise_shift_right(colour, 16) - |> int.bitwise_and(0xff), - int.bitwise_shift_right(colour, 8) - |> int.bitwise_and(0xff), - int.bitwise_and(colour, 0xff), - ], - 49, - ), - ) -} - -/// Colour the given text's background with the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.bg_colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - bg_hex(text, hex_colour) -} - -/// This is an alias for [`bg_colour`](#bg_colour) for those who prefer the American English -/// spelling. -/// -pub fn bg_color(text: String, colour: Colour) -> String { - bg_colour(text, colour) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl deleted file mode 100644 index 8b7a4c9e72f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_community@ansi). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([reset/1, bold/1, dim/1, italic/1, underline/1, inverse/1, hidden/1, strikethrough/1, black/1, red/1, green/1, yellow/1, blue/1, magenta/1, cyan/1, white/1, bright_black/1, grey/1, gray/1, bright_red/1, bright_green/1, bright_yellow/1, bright_blue/1, bright_magenta/1, bright_cyan/1, bright_white/1, hex/2, pink/1, colour/2, color/2, bg_black/1, bg_red/1, bg_green/1, bg_yellow/1, bg_blue/1, bg_magenta/1, bg_cyan/1, bg_white/1, bg_bright_black/1, bg_bright_red/1, bg_bright_green/1, bg_bright_yellow/1, bg_bright_blue/1, bg_bright_magenta/1, bg_bright_cyan/1, bg_bright_white/1, bg_hex/2, bg_pink/1, bg_colour/2, bg_color/2]). --export_type([code/0]). - --type code() :: {code, binary(), binary(), binary()}. - --spec code(list(integer()), integer()) -> code(). -code(Open, Close) -> - Close_str = gleam@int:to_string(Close), - Open_strs = gleam@list:map(Open, fun gleam@int:to_string/1), - {code, - <<<<<<""/utf8, "["/utf8>>/binary, - (gleam@string:join(Open_strs, <<";"/utf8>>))/binary>>/binary, - "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>}. - --spec run(binary(), code()) -> binary(). -run(Text, Code) -> - <<<<(erlang:element(2, Code))/binary, - (gleam@string:replace( - Text, - erlang:element(4, Code), - erlang:element(2, Code) - ))/binary>>/binary, - (erlang:element(3, Code))/binary>>. - --spec reset(binary()) -> binary(). -reset(Text) -> - run(Text, code([0], 0)). - --spec bold(binary()) -> binary(). -bold(Text) -> - run(Text, code([1], 22)). - --spec dim(binary()) -> binary(). -dim(Text) -> - run(Text, code([2], 22)). - --spec italic(binary()) -> binary(). -italic(Text) -> - run(Text, code([3], 23)). - --spec underline(binary()) -> binary(). -underline(Text) -> - run(Text, code([4], 24)). - --spec inverse(binary()) -> binary(). -inverse(Text) -> - run(Text, code([7], 27)). - --spec hidden(binary()) -> binary(). -hidden(Text) -> - run(Text, code([8], 28)). - --spec strikethrough(binary()) -> binary(). -strikethrough(Text) -> - run(Text, code([9], 29)). - --spec black(binary()) -> binary(). -black(Text) -> - run(Text, code([30], 39)). - --spec red(binary()) -> binary(). -red(Text) -> - run(Text, code([31], 39)). - --spec green(binary()) -> binary(). -green(Text) -> - run(Text, code([32], 39)). - --spec yellow(binary()) -> binary(). -yellow(Text) -> - run(Text, code([33], 39)). - --spec blue(binary()) -> binary(). -blue(Text) -> - run(Text, code([34], 39)). - --spec magenta(binary()) -> binary(). -magenta(Text) -> - run(Text, code([35], 39)). - --spec cyan(binary()) -> binary(). -cyan(Text) -> - run(Text, code([36], 39)). - --spec white(binary()) -> binary(). -white(Text) -> - run(Text, code([37], 39)). - --spec bright_black(binary()) -> binary(). -bright_black(Text) -> - run(Text, code([90], 39)). - --spec grey(binary()) -> binary(). -grey(Text) -> - bright_black(Text). - --spec gray(binary()) -> binary(). -gray(Text) -> - bright_black(Text). - --spec bright_red(binary()) -> binary(). -bright_red(Text) -> - run(Text, code([91], 39)). - --spec bright_green(binary()) -> binary(). -bright_green(Text) -> - run(Text, code([92], 39)). - --spec bright_yellow(binary()) -> binary(). -bright_yellow(Text) -> - run(Text, code([93], 39)). - --spec bright_blue(binary()) -> binary(). -bright_blue(Text) -> - run(Text, code([94], 39)). - --spec bright_magenta(binary()) -> binary(). -bright_magenta(Text) -> - run(Text, code([95], 39)). - --spec bright_cyan(binary()) -> binary(). -bright_cyan(Text) -> - run(Text, code([96], 39)). - --spec bright_white(binary()) -> binary(). -bright_white(Text) -> - run(Text, code([97], 39)). - --spec hex(binary(), integer()) -> binary(). -hex(Text, Colour) -> - Colour@1 = gleam@int:clamp(Colour, 16#0, 16#ffffff), - run( - Text, - code( - [38, - 2, - begin - _pipe = erlang:'bsr'(Colour@1, 16), - erlang:'band'(_pipe, 16#ff) - end, - begin - _pipe@1 = erlang:'bsr'(Colour@1, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - erlang:'band'(Colour@1, 16#ff)], - 39 - ) - ). - --spec pink(binary()) -> binary(). -pink(Text) -> - hex(Text, 16#ffaff3). - --spec colour(binary(), gleam_community@colour:colour()) -> binary(). -colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - hex(Text, Hex_colour). - --spec color(binary(), gleam_community@colour:colour()) -> binary(). -color(Text, Color) -> - colour(Text, Color). - --spec bg_black(binary()) -> binary(). -bg_black(Text) -> - run(Text, code([40], 49)). - --spec bg_red(binary()) -> binary(). -bg_red(Text) -> - run(Text, code([41], 49)). - --spec bg_green(binary()) -> binary(). -bg_green(Text) -> - run(Text, code([42], 49)). - --spec bg_yellow(binary()) -> binary(). -bg_yellow(Text) -> - run(Text, code([43], 49)). - --spec bg_blue(binary()) -> binary(). -bg_blue(Text) -> - run(Text, code([44], 49)). - --spec bg_magenta(binary()) -> binary(). -bg_magenta(Text) -> - run(Text, code([45], 49)). - --spec bg_cyan(binary()) -> binary(). -bg_cyan(Text) -> - run(Text, code([46], 49)). - --spec bg_white(binary()) -> binary(). -bg_white(Text) -> - run(Text, code([47], 49)). - --spec bg_bright_black(binary()) -> binary(). -bg_bright_black(Text) -> - run(Text, code([100], 49)). - --spec bg_bright_red(binary()) -> binary(). -bg_bright_red(Text) -> - run(Text, code([101], 49)). - --spec bg_bright_green(binary()) -> binary(). -bg_bright_green(Text) -> - run(Text, code([102], 49)). - --spec bg_bright_yellow(binary()) -> binary(). -bg_bright_yellow(Text) -> - run(Text, code([103], 49)). - --spec bg_bright_blue(binary()) -> binary(). -bg_bright_blue(Text) -> - run(Text, code([104], 49)). - --spec bg_bright_magenta(binary()) -> binary(). -bg_bright_magenta(Text) -> - run(Text, code([105], 49)). - --spec bg_bright_cyan(binary()) -> binary(). -bg_bright_cyan(Text) -> - run(Text, code([106], 49)). - --spec bg_bright_white(binary()) -> binary(). -bg_bright_white(Text) -> - run(Text, code([107], 49)). - --spec bg_hex(binary(), integer()) -> binary(). -bg_hex(Text, Colour) -> - run( - Text, - code( - [48, - 2, - begin - _pipe = erlang:'bsr'(Colour, 16), - erlang:'band'(_pipe, 16#ff) - end, - begin - _pipe@1 = erlang:'bsr'(Colour, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - erlang:'band'(Colour, 16#ff)], - 49 - ) - ). - --spec bg_pink(binary()) -> binary(). -bg_pink(Text) -> - bg_hex(Text, 16#ffaff3). - --spec bg_colour(binary(), gleam_community@colour:colour()) -> binary(). -bg_colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - bg_hex(Text, Hex_colour). - --spec bg_color(binary(), gleam_community@colour:colour()) -> binary(). -bg_color(Text, Colour) -> - bg_colour(Text, Colour). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src deleted file mode 100644 index dfcfdc39497..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_community_ansi, [ - {vsn, "1.2.0"}, - {applications, [gleam_community_colour, - gleam_stdlib, - gleeunit]}, - {description, "ANSI colours, formatting, and control codes"}, - {modules, [gleam_community@ansi]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md deleted file mode 100644 index 0eccdd7dd50..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# gleam-community/colour - -A package for a standard Colour type, conversions, and other utilities. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_colour)](https://hex.pm/packages/gleam_community_colour) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_colour/) - -✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! - ---- - -## Quickstart - -```gleam -import gleam_community/colour -import gleam_community/colour/accessibility - -pub fn main() { - let foreground = colour.from_hsl(h: 0.858, s: 1.0, l: 0.843) - - let background_options = [colour.light_grey, colour.dark_grey] - - let background = accessibility.maximum_contrast(foreground, background_options) -} -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_colour) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_colour -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_colour). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml deleted file mode 100644 index 07a81bf3b42..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "gleam_community_colour" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "Colour types, conversions, and other utilities" -repository = { type = "github", user = "gleam-community", repo = "colour" } - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 0.11" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl deleted file mode 100644 index 06116dfe288..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl +++ /dev/null @@ -1 +0,0 @@ --record(hsla, {h :: float(), s :: float(), l :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl deleted file mode 100644 index fff139e06ac..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl +++ /dev/null @@ -1 +0,0 @@ --record(rgba, {r :: float(), g :: float(), b :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam deleted file mode 100644 index 1f5872faffa..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam +++ /dev/null @@ -1,1126 +0,0 @@ -//// -//// - **Types** -//// - [`Colour`](#Colour) -//// - [`Color`](#Color) -//// - **Constructors** -//// - [`from_rgb255`](#from_rgb255) -//// - [`from_rgb`](#from_rgb) -//// - [`from_rgba`](#from_rgba) -//// - [`from_hsl`](#from_hsl) -//// - [`from_hsla`](#from_hsla) -//// - [`from_rgb_hex`](#from_rgb_hex) -//// - [`from_rgba_hex`](#from_rgba_hex) -//// - [`from_rgb_hex_string`](#from_rgb_hex_string) -//// - [`from_rgba_hex_string`](#from_rgba_hex_string) -//// - **Conversions** -//// - [`to_rgba`](#to_rgba) -//// - [`to_hsla`](#hsla) -//// - [`to_css_rgba_string`](#to_css_rgba_string) -//// - [`to_rgba_hex_string`](#to_rgba_hex_string) -//// - [`to_rgb_hex_string`](#to_rgb_hex_string) -//// - [`to_rgba_hex`](#to_rgba_hex) -//// - [`to_rgb_hex`](#to_rgb_hex) -//// - **Colours** -//// - [`light_red`](#light_red) -//// - [`red`](#red) -//// - [`dark_red`](#dark_red) -//// - [`light_orange`](#light_orange) -//// - [`orange`](#orange) -//// - [`dark_orange`](#dark_orange) -//// - [`light_yellow`](#light_yellow) -//// - [`yellow`](#yellow) -//// - [`dark_yellow`](#dark_yellow) -//// - [`light_green`](#light_green) -//// - [`green`](#green) -//// - [`dark_green`](#dark_green) -//// - [`light_blue`](#light_blue) -//// - [`blue`](#blue) -//// - [`dark_blue`](#dark_blue) -//// - [`light_purple`](#light_purple) -//// - [`purple`](#purple) -//// - [`dark_purple`](#dark_purple) -//// - [`light_brown`](#light_brown) -//// - [`brown`](#brown) -//// - [`dark_brown`](#dark_brown) -//// - [`black`](#black) -//// - [`white`](#white) -//// - [`light_grey`](#light_grey) -//// - [`grey`](#grey) -//// - [`dark_grey`](#dark_grey) -//// - [`light_gray`](#light_gray) -//// - [`gray`](#gray) -//// - [`dark_gray`](#dark_gray) -//// - [`light_charcoal`](#light_charcoal) -//// - [`charcoal`](#charcoal) -//// - [`dark_charcoal`](#dark_charcoal) -//// - [`pink`](#pink) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color` module. -//// The original source code can be found -//// <a href="https://github.com/avh4/elm-color/">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018 Aaron VonderHaar -//// -//// > Redistribution and use in source and binary forms, with or without modification, -//// are permitted provided that the following conditions are met: -//// -//// 1. Redistributions of source code must retain the above copyright notice, -//// this list of conditions and the following disclaimer. -//// -//// 2. Redistributions in binary form must reproduce the above copyright notice, -//// this list of conditions and the following disclaimer in the documentation -//// and/or other materials provided with the distribution. -//// -//// 3. Neither the name of the copyright holder nor the names of its contributors -//// may be used to endorse or promote products derived from this software without -//// specific prior written permission. -//// -//// > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -//// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -//// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -//// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -//// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -//// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color` module: -// -// https://github.com/avh4/elm-color/ -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/float -import gleam/result -import gleam/string -import gleam/list - -// TYPES ---------------------------------------------------------------------- - -/// A representation of a colour that can be converted to RGBA or HSLA format. -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub opaque type Colour { - Rgba(r: Float, g: Float, b: Float, a: Float) - Hsla(h: Float, s: Float, l: Float, a: Float) -} - -/// Type alias for `Colour` -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub type Color = - Colour - -// UTILITY -------------------------------------------------------------------- - -fn valid_colour_value(c: Float) -> Result(Float, Nil) { - case c >. 1.0 || c <. 0.0 { - True -> Error(Nil) - False -> Ok(c) - } -} - -fn hue_to_rgb(hue: Float, m1: Float, m2: Float) -> Float { - let h = case hue { - _ if hue <. 0.0 -> hue +. 1.0 - _ if hue >. 1.0 -> hue -. 1.0 - _ -> hue - } - - let h_t_6 = h *. 6.0 - let h_t_2 = h *. 2.0 - let h_t_3 = h *. 3.0 - - case h { - _ if h_t_6 <. 1.0 -> m1 +. { m2 -. m1 } *. h *. 6.0 - _ if h_t_2 <. 1.0 -> m2 - _ if h_t_3 <. 2.0 -> m1 +. { m2 -. m1 } *. { 2.0 /. 3.0 -. h } *. 6.0 - _ -> m1 - } -} - -fn hex_string_to_int(hex_string: String) -> Result(Int, Nil) { - let hex = case hex_string { - "#" <> hex_number -> hex_number - "0x" <> hex_number -> hex_number - _ -> hex_string - } - - hex - |> string.lowercase() - |> string.to_graphemes() - |> list.reverse() - |> list.index_fold( - Ok(0), - fn(total, char, index) { - case total { - Error(Nil) -> Error(Nil) - Ok(v) -> { - use num <- result.then(case char { - "a" -> Ok(10) - "b" -> Ok(11) - "c" -> Ok(12) - "d" -> Ok(13) - "e" -> Ok(14) - "f" -> Ok(15) - _ -> int.parse(char) - }) - use base <- result.then(int.power(16, int.to_float(index))) - Ok(v + float.round(int.to_float(num) *. base)) - } - } - }, - ) -} - -fn hsla_to_rgba( - h: Float, - s: Float, - l: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let m2 = case l <=. 0.5 { - True -> l *. { s +. 1.0 } - False -> l +. s -. l *. s - } - - let m1 = l *. 2.0 -. m2 - - let r = hue_to_rgb(h +. 1.0 /. 3.0, m1, m2) - let g = hue_to_rgb(h, m1, m2) - let b = hue_to_rgb(h -. 1.0 /. 3.0, m1, m2) - - #(r, g, b, a) -} - -fn rgba_to_hsla( - r: Float, - g: Float, - b: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let min_colour = float.min(r, float.min(g, b)) - - let max_colour = float.max(r, float.max(g, b)) - - let h1 = case True { - _ if max_colour == r -> float.divide(g -. b, max_colour -. min_colour) - _ if max_colour == g -> - float.divide(b -. r, max_colour -. min_colour) - |> result.then(fn(d) { Ok(2.0 +. d) }) - _ -> - float.divide(r -. g, max_colour -. min_colour) - |> result.then(fn(d) { Ok(4.0 +. d) }) - } - - let h2 = case h1 { - Ok(v) -> Ok(v *. { 1.0 /. 6.0 }) - _ -> h1 - } - - let h3 = case h2 { - Ok(v) if v <. 0.0 -> v +. 1.0 - Ok(v) -> v - _ -> 0.0 - } - - let l = { min_colour +. max_colour } /. 2.0 - - let s = case True { - _ if min_colour == max_colour -> 0.0 - _ if l <. 0.5 -> - { max_colour -. min_colour } /. { max_colour +. min_colour } - _ -> { max_colour -. min_colour } /. { 2.0 -. max_colour -. min_colour } - } - - #(h3, s, l, a) -} - -// CONSTRUCTORS --------------------------------------------------------------- - -/// Returns a `Result(Colour)` created from the given 8 bit RGB values. -/// -/// Returns `Error(Nil)` if the supplied RGB values are greater than 255 or less than 0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb255(r red: Int, g green: Int, b blue: Int) -> Result(Colour, Nil) { - use r <- result.then( - red - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use g <- result.then( - green - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use b <- result.then( - blue - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGB values. -/// -/// If the supplied RGB values are greater than 1.0 or less than 0.0 returns `Error(Nil)` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb(1.0, 0.0, 0.0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb( - r red: Float, - g green: Float, - b blue: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGBA values. -/// -/// Returns `Error(Nil)` if the supplied RGBA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rbga(1.0, 0.0, 0.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba( - r red: Float, - g green: Float, - b blue: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Rgba(r: r, g: g, b: b, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSLA values. -/// -/// Returns `Error(Nil)`f the supplied HSLA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_hsla(0.0, 1.0, 0.5, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsla( - h hue: Float, - s saturation: Float, - l lightness: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use h <- result.then(valid_colour_value(hue)) - use s <- result.then(valid_colour_value(saturation)) - use l <- result.then(valid_colour_value(lightness)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Hsla(h: h, s: s, l: l, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSL values. -/// -/// Returns `Error(Nil)` if the supplied HSL values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_hsla(0.0, 1.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsl( - h hue: Float, - s saturation: Float, - l lightness: Float, -) -> Result(Colour, Nil) { - from_hsla(hue, saturation, lightness, 1.0) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex(0xff0000) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffff || hex < 0 { - True -> Error(Nil) - False -> { - let r = - int.bitwise_shift_right(hex, 16) - |> int.bitwise_and(0xff) - let g = - int.bitwise_shift_right(hex, 8) - |> int.bitwise_and(0xff) - let b = int.bitwise_and(hex, 0xff) - from_rgb255(r, g, b) - } - } -} - -/// Returns a `Result(Colour)` created from the given RGB hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex_string("#ff0000") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgb_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given RGBA hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex_string("#ff00007f") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgba_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex(0xff00007f) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffffff || hex < 0 { - True -> Error(Nil) - False -> { - // This won't fail because we are always dividing by 255.0 - let assert Ok(r) = - int.bitwise_shift_right(hex, 24) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(g) = - int.bitwise_shift_right(hex, 16) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(b) = - int.bitwise_shift_right(hex, 8) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(a) = - int.bitwise_and(hex, 0xff) - |> int.to_float() - |> float.divide(255.0) - from_rgba(r, g, b, a) - } - } -} - -// CONVERSIONS ---------------------------------------------------------------- - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// R, G, B, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(r, g, b, a) = to_rgba(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Rgba(r, g, b, a) -> #(r, g, b, a) - Hsla(h, s, l, a) -> hsla_to_rgba(h, s, l, a) - } -} - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// H, S, L, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(h, s, l, a) = to_hsla(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_hsla(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Hsla(h, s, l, a) -> #(h, s, l, a) - Rgba(r, g, b, a) -> rgba_to_hsla(r, g, b, a) - } -} - -/// Returns an rgba formatted CSS `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let css_red = to_css_rgba_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_css_rgba_string(colour: Colour) -> String { - let #(r, g, b, a) = to_rgba(colour) - - let percent = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 100.0 - let assert Ok(p) = - x - |> float.multiply(10_000.0) - |> float.round() - |> int.to_float() - |> float.divide(100.0) - - p - } - - let round_to = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 1000.0 - let assert Ok(r) = - x - |> float.multiply(1000.0) - |> float.round() - |> int.to_float() - |> float.divide(1000.0) - - r - } - - string.join( - [ - "rgba(", - float.to_string(percent(r)) <> "%,", - float.to_string(percent(g)) <> "%,", - float.to_string(percent(b)) <> "%,", - float.to_string(round_to(a)), - ")", - ], - "", - ) -} - -/// Returns an rgba hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex = to_rgba_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex_string(colour: Colour) -> String { - to_rgba_hex(colour) - |> int.to_base16() -} - -/// Returns an rgb hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex = to_rgb_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex_string(colour: Colour) -> String { - to_rgb_hex(colour) - |> int.to_base16() -} - -/// Returns an hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex_int = to_rgba_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex(colour: Colour) -> Int { - let #(r, g, b, a) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> int.bitwise_shift_left(24) - - let green = - g *. 255.0 - |> float.round() - |> int.bitwise_shift_left(16) - - let blue = - b *. 255.0 - |> float.round() - |> int.bitwise_shift_left(8) - - let alpha = - a *. 255.0 - |> float.round() - - red + green + blue + alpha -} - -/// Returns a rgb hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex_int = to_rgb_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex(colour: Colour) -> Int { - let #(r, g, b, _) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> int.bitwise_shift_left(16) - - let green = - g *. 255.0 - |> float.round() - |> int.bitwise_shift_left(8) - - let blue = - b *. 255.0 - |> float.round() - - red + green + blue -} - -// COLOURS -------------------------------------------------------------------- - -/// A `Colour` reprsenting the colour RGBA(239, 41, 41, 1.0) -pub const light_red = Rgba( - r: 0.9372549019607843, - g: 0.1607843137254902, - b: 0.1607843137254902, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(204, 0, 0, 1.0) -pub const red = Rgba(r: 0.8, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(164, 0, 0, 1.0) -pub const dark_red = Rgba(r: 0.6431372549019608, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(252, 175, 62, 1.0) -pub const light_orange = Rgba( - r: 0.9882352941176471, - g: 0.6862745098039216, - b: 0.24313725490196078, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(245, 121, 0, 1.0) -pub const orange = Rgba( - r: 0.9607843137254902, - g: 0.4745098039215686, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(206, 92, 0, 1.0) -pub const dark_orange = Rgba( - r: 0.807843137254902, - g: 0.3607843137254902, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 233, 79, 1.0) -pub const light_yellow = Rgba( - r: 1.0, - g: 0.9137254901960784, - b: 0.30980392156862746, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(237, 212, 0, 1.0) -pub const yellow = Rgba( - r: 0.9294117647058824, - g: 0.8313725490196079, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(196, 160, 0, 1.0) -pub const dark_yellow = Rgba( - r: 0.7686274509803922, - g: 0.6274509803921569, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(138, 226, 52, 1.0) -pub const light_green = Rgba( - r: 0.5411764705882353, - g: 0.8862745098039215, - b: 0.20392156862745098, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(115, 210, 22, 1.0) -pub const green = Rgba( - r: 0.45098039215686275, - g: 0.8235294117647058, - b: 0.08627450980392157, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(78, 154, 6, 1.0) -pub const dark_green = Rgba( - r: 0.3058823529411765, - g: 0.6039215686274509, - b: 0.023529411764705882, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(114, 159, 207, 1.0) -pub const light_blue = Rgba( - r: 0.4470588235294118, - g: 0.6235294117647059, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(52, 101, 164, 1.0) -pub const blue = Rgba( - r: 0.20392156862745098, - g: 0.396078431372549, - b: 0.6431372549019608, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(32, 74, 135, 1.0) -pub const dark_blue = Rgba( - r: 0.12549019607843137, - g: 0.2901960784313726, - b: 0.5294117647058824, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(173, 127, 168, 1.0) -pub const light_purple = Rgba( - r: 0.6784313725490196, - g: 0.4980392156862745, - b: 0.6588235294117647, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(117, 80, 123, 1.0) -pub const purple = Rgba( - r: 0.4588235294117647, - g: 0.3137254901960784, - b: 0.4823529411764706, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(92, 53, 102, 1.0) -pub const dark_purple = Rgba( - r: 0.3607843137254902, - g: 0.20784313725490197, - b: 0.4, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(233, 185, 110, 1.0) -pub const light_brown = Rgba( - r: 0.9137254901960784, - g: 0.7254901960784313, - b: 0.43137254901960786, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(193, 125, 17, 1.0) -pub const brown = Rgba( - r: 0.7568627450980392, - g: 0.49019607843137253, - b: 0.06666666666666667, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(143, 89, 2, 1.0) -pub const dark_brown = Rgba( - r: 0.5607843137254902, - g: 0.34901960784313724, - b: 0.00784313725490196, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(0, 0, 0, 1.0) -pub const black = Rgba(r: 0.0, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(255, 255, 255, 1.0) -pub const white = Rgba(r: 1.0, g: 1.0, b: 1.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_grey = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const grey = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_grey = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_gray = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const gray = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_gray = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(136, 138, 133, 1.0) -pub const light_charcoal = Rgba( - r: 0.5333333333333333, - g: 0.5411764705882353, - b: 0.5215686274509804, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(85, 87, 83, 1.0) -pub const charcoal = Rgba( - r: 0.3333333333333333, - g: 0.3411764705882353, - b: 0.3254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(46, 52, 54, 1.0) -pub const dark_charcoal = Rgba( - r: 0.1803921568627451, - g: 0.20392156862745098, - b: 0.21176470588235294, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 175, 243, 1.0) -pub const pink = Rgba( - r: 1.0, - g: 0.6862745098039216, - b: 0.9529411764705882, - a: 1.0, -) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam deleted file mode 100644 index 54f75e4d469..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam +++ /dev/null @@ -1,173 +0,0 @@ -//// -//// - **Accessibility** -//// - [`luminance`](#luminance) -//// - [`contrast_ratio`](#contrast_ratio) -//// - [`maximum_contrast`](#maximum_contrast) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color-extra` module. -//// The original source code can be found -//// <a href="https://github.com/noahzgordon/elm-color-extra">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright (c) 2016 Andreas Köberle -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// -//// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -//// SOFTWARE. -//// -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color-extra` module: -// -// https://github.com/noahzgordon/elm-color-extra -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/float -import gleam/list -import gleam_community/colour.{type Colour} - -// UTILITIES ------------------------------------------------------------------ - -fn intensity(colour_value: Float) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - case True { - _ if colour_value <=. 0.03928 -> colour_value /. 12.92 - _ -> { - // Is this guaranteed to be `OK`? - let assert Ok(i) = float.power({ colour_value +. 0.055 } /. 1.055, 2.4) - i - } - } -} - -// ACCESSIBILITY -------------------------------------------------------------- - -/// Returns the relative brightness of the given `Colour` as a `Float` between -/// 0.0, and 1.0 with 0.0 being the darkest possible colour and 1.0 being the lightest. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// luminance(colour.white) // 1.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn luminance(colour: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - let #(r, g, b, _) = colour.to_rgba(colour) - - let r_intensity = intensity(r) - let g_intensity = intensity(g) - let b_intensity = intensity(b) - - 0.2126 *. r_intensity +. 0.7152 *. g_intensity +. 0.0722 *. b_intensity -} - -/// Returns the contrast between two `Colour` values as a `Float` between 1.0, -/// and 21.0 with 1.0 being no contrast and, 21.0 being the highest possible contrast. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// contrast_ratio(between: colour.white, and: colour.black) // 21.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn contrast_ratio(between colour_a: Colour, and colour_b: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#contrast-ratiodef - let luminance_a = luminance(colour_a) +. 0.05 - let luminance_b = luminance(colour_b) +. 0.05 - - case luminance_a >. luminance_b { - True -> luminance_a /. luminance_b - False -> luminance_b /. luminance_a - } -} - -/// Returns the `Colour` with the highest contrast between the base `Colour`, -/// and and the other provided `Colour` values. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// maximum_contrast( -/// colour.yellow, -/// [colour.white, colour.dark_blue, colour.green], -/// ) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn maximum_contrast( - base: Colour, - colours: List(Colour), -) -> Result(Colour, Nil) { - colours - |> list.sort(fn(colour_a, colour_b) { - let contrast_a = contrast_ratio(base, colour_a) - let contrast_b = contrast_ratio(base, colour_b) - - float.compare(contrast_b, contrast_a) - }) - |> list.first() -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl deleted file mode 100644 index 21e4c819749..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl +++ /dev/null @@ -1,511 +0,0 @@ --module(gleam_community@colour). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_rgb255/3, from_rgb/3, from_rgba/4, from_hsla/4, from_hsl/3, from_rgb_hex/1, from_rgb_hex_string/1, from_rgba_hex/1, from_rgba_hex_string/1, to_rgba/1, to_hsla/1, to_css_rgba_string/1, to_rgba_hex/1, to_rgba_hex_string/1, to_rgb_hex/1, to_rgb_hex_string/1]). --export_type([colour/0]). - --opaque colour() :: {rgba, float(), float(), float(), float()} | - {hsla, float(), float(), float(), float()}. - --spec valid_colour_value(float()) -> {ok, float()} | {error, nil}. -valid_colour_value(C) -> - case (C > 1.0) orelse (C < +0.0) of - true -> - {error, nil}; - - false -> - {ok, C} - end. - --spec hue_to_rgb(float(), float(), float()) -> float(). -hue_to_rgb(Hue, M1, M2) -> - H = case Hue of - _ when Hue < +0.0 -> - Hue + 1.0; - - _ when Hue > 1.0 -> - Hue - 1.0; - - _ -> - Hue - end, - H_t_6 = H * 6.0, - H_t_2 = H * 2.0, - H_t_3 = H * 3.0, - case H of - _ when H_t_6 < 1.0 -> - M1 + (((M2 - M1) * H) * 6.0); - - _ when H_t_2 < 1.0 -> - M2; - - _ when H_t_3 < 2.0 -> - M1 + (((M2 - M1) * ((2.0 / 3.0) - H)) * 6.0); - - _ -> - M1 - end. - --spec hex_string_to_int(binary()) -> {ok, integer()} | {error, nil}. -hex_string_to_int(Hex_string) -> - Hex = case Hex_string of - <<"#"/utf8, Hex_number/binary>> -> - Hex_number; - - <<"0x"/utf8, Hex_number@1/binary>> -> - Hex_number@1; - - _ -> - Hex_string - end, - _pipe = Hex, - _pipe@1 = gleam@string:lowercase(_pipe), - _pipe@2 = gleam@string:to_graphemes(_pipe@1), - _pipe@3 = gleam@list:reverse(_pipe@2), - gleam@list:index_fold( - _pipe@3, - {ok, 0}, - fun(Total, Char, Index) -> case Total of - {error, nil} -> - {error, nil}; - - {ok, V} -> - gleam@result:then(case Char of - <<"a"/utf8>> -> - {ok, 10}; - - <<"b"/utf8>> -> - {ok, 11}; - - <<"c"/utf8>> -> - {ok, 12}; - - <<"d"/utf8>> -> - {ok, 13}; - - <<"e"/utf8>> -> - {ok, 14}; - - <<"f"/utf8>> -> - {ok, 15}; - - _ -> - gleam@int:parse(Char) - end, fun(Num) -> - gleam@result:then( - gleam@int:power(16, gleam@int:to_float(Index)), - fun(Base) -> - {ok, - V + gleam@float:round( - gleam@int:to_float(Num) * Base - )} - end - ) - end) - end end - ). - --spec hsla_to_rgba(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -hsla_to_rgba(H, S, L, A) -> - M2 = case L =< 0.5 of - true -> - L * (S + 1.0); - - false -> - (L + S) - (L * S) - end, - M1 = (L * 2.0) - M2, - R = hue_to_rgb(H + (1.0 / 3.0), M1, M2), - G = hue_to_rgb(H, M1, M2), - B = hue_to_rgb(H - (1.0 / 3.0), M1, M2), - {R, G, B, A}. - --spec rgba_to_hsla(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -rgba_to_hsla(R, G, B, A) -> - Min_colour = gleam@float:min(R, gleam@float:min(G, B)), - Max_colour = gleam@float:max(R, gleam@float:max(G, B)), - H1 = case true of - _ when Max_colour =:= R -> - gleam@float:divide(G - B, Max_colour - Min_colour); - - _ when Max_colour =:= G -> - _pipe = gleam@float:divide(B - R, Max_colour - Min_colour), - gleam@result:then(_pipe, fun(D) -> {ok, 2.0 + D} end); - - _ -> - _pipe@1 = gleam@float:divide(R - G, Max_colour - Min_colour), - gleam@result:then(_pipe@1, fun(D@1) -> {ok, 4.0 + D@1} end) - end, - H2 = case H1 of - {ok, V} -> - {ok, V * (1.0 / 6.0)}; - - _ -> - H1 - end, - H3 = case H2 of - {ok, V@1} when V@1 < +0.0 -> - V@1 + 1.0; - - {ok, V@2} -> - V@2; - - _ -> - +0.0 - end, - L = (Min_colour + Max_colour) / 2.0, - S = case true of - _ when Min_colour =:= Max_colour -> - +0.0; - - _ when L < 0.5 -> - case (Max_colour + Min_colour) of - 0.0 -> 0.0; - Gleam@denominator -> (Max_colour - Min_colour) / Gleam@denominator - end; - - _ -> - case ((2.0 - Max_colour) - Min_colour) of - 0.0 -> 0.0; - Gleam@denominator@1 -> (Max_colour - Min_colour) / Gleam@denominator@1 - end - end, - {H3, S, L, A}. - --spec from_rgb255(integer(), integer(), integer()) -> {ok, colour()} | - {error, nil}. -from_rgb255(Red, Green, Blue) -> - gleam@result:then( - begin - _pipe = Red, - _pipe@1 = gleam@int:to_float(_pipe), - _pipe@2 = gleam@float:divide(_pipe@1, 255.0), - gleam@result:then(_pipe@2, fun valid_colour_value/1) - end, - fun(R) -> - gleam@result:then( - begin - _pipe@3 = Green, - _pipe@4 = gleam@int:to_float(_pipe@3), - _pipe@5 = gleam@float:divide(_pipe@4, 255.0), - gleam@result:then(_pipe@5, fun valid_colour_value/1) - end, - fun(G) -> - gleam@result:then( - begin - _pipe@6 = Blue, - _pipe@7 = gleam@int:to_float(_pipe@6), - _pipe@8 = gleam@float:divide(_pipe@7, 255.0), - gleam@result:then(_pipe@8, fun valid_colour_value/1) - end, - fun(B) -> {ok, {rgba, R, G, B, 1.0}} end - ) - end - ) - end - ). - --spec from_rgb(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_rgb(Red, Green, Blue) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> {ok, {rgba, R, G, B, 1.0}} end - ) - end - ) - end - ). - --spec from_rgba(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_rgba(Red, Green, Blue, Alpha) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> {ok, {rgba, R, G, B, A}} end - ) - end - ) - end - ) - end - ). - --spec from_hsla(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_hsla(Hue, Saturation, Lightness, Alpha) -> - gleam@result:then( - valid_colour_value(Hue), - fun(H) -> - gleam@result:then( - valid_colour_value(Saturation), - fun(S) -> - gleam@result:then( - valid_colour_value(Lightness), - fun(L) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> {ok, {hsla, H, S, L, A}} end - ) - end - ) - end - ) - end - ). - --spec from_hsl(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_hsl(Hue, Saturation, Lightness) -> - from_hsla(Hue, Saturation, Lightness, 1.0). - --spec from_rgb_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgb_hex(Hex) -> - case (Hex > 16#ffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - R = begin - _pipe = erlang:'bsr'(Hex, 16), - erlang:'band'(_pipe, 16#ff) - end, - G = begin - _pipe@1 = erlang:'bsr'(Hex, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - B = erlang:'band'(Hex, 16#ff), - from_rgb255(R, G, B) - end. - --spec from_rgb_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgb_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> from_rgb_hex(Hex_int) end - ). - --spec from_rgba_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgba_hex(Hex) -> - case (Hex > 16#ffffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - _assert_subject = begin - _pipe = erlang:'bsr'(Hex, 24), - _pipe@1 = erlang:'band'(_pipe, 16#ff), - _pipe@2 = gleam@int:to_float(_pipe@1), - gleam@float:divide(_pipe@2, 255.0) - end, - {ok, R} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 588}) - end, - _assert_subject@1 = begin - _pipe@3 = erlang:'bsr'(Hex, 16), - _pipe@4 = erlang:'band'(_pipe@3, 16#ff), - _pipe@5 = gleam@int:to_float(_pipe@4), - gleam@float:divide(_pipe@5, 255.0) - end, - {ok, G} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 594}) - end, - _assert_subject@2 = begin - _pipe@6 = erlang:'bsr'(Hex, 8), - _pipe@7 = erlang:'band'(_pipe@6, 16#ff), - _pipe@8 = gleam@int:to_float(_pipe@7), - gleam@float:divide(_pipe@8, 255.0) - end, - {ok, B} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 600}) - end, - _assert_subject@3 = begin - _pipe@9 = erlang:'band'(Hex, 16#ff), - _pipe@10 = gleam@int:to_float(_pipe@9), - gleam@float:divide(_pipe@10, 255.0) - end, - {ok, A} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 606}) - end, - from_rgba(R, G, B, A) - end. - --spec from_rgba_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgba_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> from_rgba_hex(Hex_int) end - ). - --spec to_rgba(colour()) -> {float(), float(), float(), float()}. -to_rgba(Colour) -> - case Colour of - {rgba, R, G, B, A} -> - {R, G, B, A}; - - {hsla, H, S, L, A@1} -> - hsla_to_rgba(H, S, L, A@1) - end. - --spec to_hsla(colour()) -> {float(), float(), float(), float()}. -to_hsla(Colour) -> - case Colour of - {hsla, H, S, L, A} -> - {H, S, L, A}; - - {rgba, R, G, B, A@1} -> - rgba_to_hsla(R, G, B, A@1) - end. - --spec to_css_rgba_string(colour()) -> binary(). -to_css_rgba_string(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Percent = fun(X) -> - _assert_subject = begin - _pipe = X, - _pipe@1 = gleam@float:multiply(_pipe, 10000.0), - _pipe@2 = gleam@float:round(_pipe@1), - _pipe@3 = gleam@int:to_float(_pipe@2), - gleam@float:divide(_pipe@3, 100.0) - end, - {ok, P} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 704}) - end, - P - end, - Round_to = fun(X@1) -> - _assert_subject@1 = begin - _pipe@4 = X@1, - _pipe@5 = gleam@float:multiply(_pipe@4, 1000.0), - _pipe@6 = gleam@float:round(_pipe@5), - _pipe@7 = gleam@int:to_float(_pipe@6), - gleam@float:divide(_pipe@7, 1000.0) - end, - {ok, R@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 716}) - end, - R@1 - end, - gleam@string:join( - [<<"rgba("/utf8>>, - <<(gleam@float:to_string(Percent(R)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(G)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(B)))/binary, "%,"/utf8>>, - gleam@float:to_string(Round_to(A)), - <<")"/utf8>>], - <<""/utf8>> - ). - --spec to_rgba_hex(colour()) -> integer(). -to_rgba_hex(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - erlang:'bsl'(_pipe@1, 24) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - erlang:'bsl'(_pipe@3, 16) - end, - Blue = begin - _pipe@4 = B * 255.0, - _pipe@5 = gleam@float:round(_pipe@4), - erlang:'bsl'(_pipe@5, 8) - end, - Alpha = begin - _pipe@6 = A * 255.0, - gleam@float:round(_pipe@6) - end, - ((Red + Green) + Blue) + Alpha. - --spec to_rgba_hex_string(colour()) -> binary(). -to_rgba_hex_string(Colour) -> - _pipe = to_rgba_hex(Colour), - gleam@int:to_base16(_pipe). - --spec to_rgb_hex(colour()) -> integer(). -to_rgb_hex(Colour) -> - {R, G, B, _} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - erlang:'bsl'(_pipe@1, 16) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - erlang:'bsl'(_pipe@3, 8) - end, - Blue = begin - _pipe@4 = B * 255.0, - gleam@float:round(_pipe@4) - end, - (Red + Green) + Blue. - --spec to_rgb_hex_string(colour()) -> binary(). -to_rgb_hex_string(Colour) -> - _pipe = to_rgb_hex(Colour), - gleam@int:to_base16(_pipe). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl deleted file mode 100644 index 64d37bf2eb3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl +++ /dev/null @@ -1,73 +0,0 @@ --module(gleam_community@colour@accessibility). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([luminance/1, contrast_ratio/2, maximum_contrast/2]). - --spec intensity(float()) -> float(). -intensity(Colour_value) -> - case true of - _ when Colour_value =< 0.03928 -> - Colour_value / 12.92; - - _ -> - _assert_subject = gleam@float:power( - (Colour_value + 0.055) / 1.055, - 2.4 - ), - {ok, I} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour/accessibility"/utf8>>, - function => <<"intensity"/utf8>>, - line => 62}) - end, - I - end. - --spec luminance(gleam_community@colour:colour()) -> float(). -luminance(Colour) -> - {R, G, B, _} = gleam_community@colour:to_rgba(Colour), - R_intensity = intensity(R), - G_intensity = intensity(G), - B_intensity = intensity(B), - ((0.2126 * R_intensity) + (0.7152 * G_intensity)) + (0.0722 * B_intensity). - --spec contrast_ratio( - gleam_community@colour:colour(), - gleam_community@colour:colour() -) -> float(). -contrast_ratio(Colour_a, Colour_b) -> - Luminance_a = luminance(Colour_a) + 0.05, - Luminance_b = luminance(Colour_b) + 0.05, - case Luminance_a > Luminance_b of - true -> - case Luminance_b of - 0.0 -> 0.0; - Gleam@denominator -> Luminance_a / Gleam@denominator - end; - - false -> - case Luminance_a of - 0.0 -> 0.0; - Gleam@denominator@1 -> Luminance_b / Gleam@denominator@1 - end - end. - --spec maximum_contrast( - gleam_community@colour:colour(), - list(gleam_community@colour:colour()) -) -> {ok, gleam_community@colour:colour()} | {error, nil}. -maximum_contrast(Base, Colours) -> - _pipe = Colours, - _pipe@1 = gleam@list:sort( - _pipe, - fun(Colour_a, Colour_b) -> - Contrast_a = contrast_ratio(Base, Colour_a), - Contrast_b = contrast_ratio(Base, Colour_b), - gleam@float:compare(Contrast_b, Contrast_a) - end - ), - gleam@list:first(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src deleted file mode 100644 index a32765072fc..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_community_colour, [ - {vsn, "1.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Colour types, conversions, and other utilities"}, - {modules, [gleam_community@colour, - gleam_community@colour@accessibility]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md deleted file mode 100644 index ffee4cd751f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Gleam Erlang 🐙 - -A library for making use of Erlang specific code! - -## Features - -- Typed Erlang processes and message sending. -- Erlang binary format (de)serialisation. -- Functions for working with Erlang's charlists. -- Reading, writing, and deletion of files. -- Basic distributed Erlang support and working with nodes. -- Reading and writing of environment variables. -- Functions for working with atoms. - -## Usage - -Add this library to your Gleam project - -```shell -gleam add gleam_erlang -``` - -And then use it in your code - -```gleam -import gleam/io -import gleam/erlang/file - -pub fn main() { - assert Ok(contents) = file.read("pokedex.txt") - io.println(contents) -} -``` - -Documentation can be found at <https://hexdocs.pm/gleam_erlang/>. - -This library requires OTP 23.0 or higher. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml deleted file mode 100644 index 8d626035c25..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml +++ /dev/null @@ -1,18 +0,0 @@ -name = "gleam_erlang" - -version = "0.23.1" -licences = ["Apache-2.0"] -description = "A Gleam library for working with Erlang" - -repository = { type = "github", user = "gleam-lang", repo = "erlang" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl deleted file mode 100644 index b38d11e0f65..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl +++ /dev/null @@ -1,15 +0,0 @@ --record(file_info, { - size :: integer(), - file_type :: gleam@erlang@file:file_type(), - access :: gleam@erlang@file:access(), - atime :: integer(), - mtime :: integer(), - ctime :: integer(), - mode :: integer(), - links :: integer(), - major_device :: integer(), - minor_device :: integer(), - inode :: integer(), - user_id :: integer(), - group_id :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl deleted file mode 100644 index 4cd04529eb4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl +++ /dev/null @@ -1 +0,0 @@ --record(abnormal, {reason :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl deleted file mode 100644 index 5dd504715a5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl +++ /dev/null @@ -1 +0,0 @@ --record(callee_down, {reason :: gleam@dynamic:dynamic_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl deleted file mode 100644 index b82b49fc597..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl +++ /dev/null @@ -1 +0,0 @@ --record(cancelled, {time_remaining :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl deleted file mode 100644 index c476308c591..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(exit_message, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@erlang@process:exit_reason() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl deleted file mode 100644 index df0b6b7793b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(process_down, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@dynamic:dynamic_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl deleted file mode 100644 index ce552e209e6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl +++ /dev/null @@ -1 +0,0 @@ --record(process_monitor, {tag :: gleam@erlang:reference_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl deleted file mode 100644 index abc46b2ecd4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(subject, { - owner :: gleam@erlang@process:pid_(), - tag :: gleam@erlang:reference_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl deleted file mode 100644 index 52c9896ede4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(application_failed_to_start, { - name :: gleam@erlang@atom:atom_(), - reason :: gleam@dynamic:dynamic_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl deleted file mode 100644 index fde3c61706e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unknown_application, {name :: gleam@erlang@atom:atom_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam deleted file mode 100644 index 783cd537232..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam +++ /dev/null @@ -1,158 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/list -import gleam/erlang/atom.{type Atom} -import gleam/erlang/charlist.{type Charlist} - -@external(erlang, "io_lib", "format") -fn erl_format(a: String, b: List(a)) -> Charlist - -/// Return a string representation of any term -pub fn format(term: any) -> String { - charlist.to_string(erl_format("~p", [term])) -} - -@external(erlang, "erlang", "term_to_binary") -pub fn term_to_binary(a: a) -> BitArray - -type Safe { - Safe -} - -@external(erlang, "erlang", "binary_to_term") -fn erl_binary_to_term(a: BitArray, b: List(Safe)) -> Dynamic - -pub fn binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, [Safe]) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -pub fn unsafe_binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, []) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -/// Error value returned by `get_line` function -/// -pub type GetLineError { - Eof - NoData -} - -/// Reads a line from standard input with the given prompt. -/// -/// # Example -/// -/// > get_line("Language: ") -/// // -> Language: <- gleam -/// Ok("gleam\n") -/// -@external(erlang, "gleam_erlang_ffi", "get_line") -pub fn get_line(prompt prompt: String) -> Result(String, GetLineError) - -pub type TimeUnit { - Second - Millisecond - Microsecond - Nanosecond -} - -/// Returns the current OS system time. -/// -/// <https://erlang.org/doc/apps/erts/time_correction.html#OS_System_Time> -@external(erlang, "os", "system_time") -pub fn system_time(a: TimeUnit) -> Int - -/// Returns the current OS system time as a tuple of Ints -/// -/// http://erlang.org/doc/man/os.html#timestamp-0 -@external(erlang, "os", "timestamp") -pub fn erlang_timestamp() -> #(Int, Int, Int) - -/// Gleam doesn't offer any way to raise exceptions, but they may still occur -/// due to bugs when working with unsafe code, such as when calling Erlang -/// function. -/// -/// This function will catch any error thrown and convert it into a result -/// rather than crashing the process. -/// -@external(erlang, "gleam_erlang_ffi", "rescue") -pub fn rescue(a: fn() -> a) -> Result(a, Crash) - -pub type Crash { - Exited(Dynamic) - Thrown(Dynamic) - Errored(Dynamic) -} - -@external(erlang, "init", "get_plain_arguments") -fn get_start_arguments() -> List(Charlist) - -/// Get the arguments given to the program when it was started. -/// -/// This is sometimes called `argv` in other languages. -pub fn start_arguments() -> List(String) { - get_start_arguments() - |> list.map(charlist.to_string) -} - -/// Starts an OTP application's process tree in the background, as well as -/// the trees of any applications that the given application depends upon. An -/// OTP application typically maps onto a Gleam or Hex package. -/// -/// Returns a list of the applications that were started. Calling this function -/// for application that have already been started is a no-op so you do not need -/// to check the application state beforehand. -/// -/// In Gleam we prefer to not use these implicit background process trees, but -/// you will likely still need to start the trees of OTP applications written in -/// other BEAM languages such as Erlang or Elixir, including those included by -/// default with Erlang/OTP. -/// -/// For more information see the OTP documentation. -/// - <https://www.erlang.org/doc/man/application.html#ensure_all_started-1> -/// - <https://www.erlang.org/doc/man/application.html#start-1> -/// -@external(erlang, "gleam_erlang_ffi", "ensure_all_started") -pub fn ensure_all_started( - application application: Atom, -) -> Result(List(Atom), EnsureAllStartedError) - -pub type EnsureAllStartedError { - UnknownApplication(name: Atom) - ApplicationFailedToStart(name: Atom, reason: Dynamic) -} - -/// A unique reference value. -/// -/// It holds no particular meaning or value, but unique values are often useful -/// in programs are used heavily within both Gleam and Erlang's OTP frameworks. -/// -/// More can be read about references in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/efficiency_guide/advanced.html#unique_references -/// -pub type Reference - -/// Create a new unique reference. -/// -@external(erlang, "erlang", "make_ref") -pub fn make_reference() -> Reference - -/// Returns the path of a package's `priv` directory, where extra non-Gleam -/// or Erlang files are typically kept. -/// -/// Returns an error if no package was found with the given name. -/// -/// # Example -/// -/// ```gleam -/// > erlang.priv_directory("my_app") -/// // -> Ok("/some/location/my_app/priv") -/// ``` -/// -@external(erlang, "gleam_erlang_ffi", "priv_directory") -pub fn priv_directory(name: String) -> Result(String, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam deleted file mode 100644 index a27289c112c..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam +++ /dev/null @@ -1,79 +0,0 @@ -import gleam/dynamic.{type DecodeErrors, type Dynamic} - -/// Atom is a special string-like data-type that is most commonly used for -/// interfacing with code written in other BEAM languages such as Erlang and -/// Elixir. It is preferable to define your own custom types to use instead of -/// atoms where possible. -/// -/// Atoms are not used much in typical Gleam code! -/// -/// ## Creating atoms -/// -/// We can create atoms with the the [`create_from_string`](#create_from_string) -/// function, though we must be careful when doing so as atoms are never -/// garbage collected. If we create too many atoms (for example, if we convert -/// user input into atoms) we may hit the max limit of atoms and cause the -/// virtual machine to crash. -/// -pub type Atom - -/// An error returned when no atom is found in the virtual machine's atom table -/// for a given string when calling the [`from_string`](#from_string) function. -pub type FromStringError { - AtomNotLoaded -} - -/// Finds an existing Atom for the given String. -/// -/// If no atom is found in the virtual machine's atom table for the String then -/// an error is returned. -/// -/// ## Examples -/// -/// > from_string("ok") -/// Ok(create_from_string("ok")) -/// -/// > from_string("some_new_atom") -/// Error(AtomNotLoaded) -/// -@external(erlang, "gleam_erlang_ffi", "atom_from_string") -pub fn from_string(a: String) -> Result(Atom, FromStringError) - -/// Creates an atom from a string, inserting a new value into the virtual -/// machine's atom table if an atom does not already exist for the given -/// string. -/// -/// We must be careful when using this function as there is a limit to the -/// number of atom that can fit in the virtual machine's atom table. Never -/// convert user input into atoms as filling the atom table will cause the -/// virtual machine to crash! -/// -@external(erlang, "erlang", "binary_to_atom") -pub fn create_from_string(a: String) -> Atom - -/// Returns a `String` corresponding to the text representation of the given -/// `Atom`. -/// -/// ## Examples -/// -/// > let ok_atom = create_from_string("ok") -/// > to_string(ok_atom) -/// "ok" -/// -@external(erlang, "erlang", "atom_to_binary") -pub fn to_string(a: Atom) -> String - -/// Checks to see whether a `Dynamic` value is an atom, and return the atom if -/// it is. -/// -/// ## Examples -/// -/// > import gleam/dynamic -/// > from_dynamic(dynamic.from(create_from_string("hello"))) -/// Ok(create_from_string("hello")) -/// -/// > from_dynamic(dynamic.from(123)) -/// Error([DecodeError(expected: "Atom", found: "Int", path: [])]) -/// -@external(erlang, "gleam_erlang_ffi", "atom_from_dynamic") -pub fn from_dynamic(from from: Dynamic) -> Result(Atom, DecodeErrors) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam deleted file mode 100644 index e5b6d65f6b2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam +++ /dev/null @@ -1,25 +0,0 @@ -//// A charlist is a list of integers where all the integers are valid code -//// points. -//// -//// In practice, you will not come across them often, except perhaps when -//// interfacing with Erlang, in particular when using older libraries that do -//// not accept binaries as arguments. - -/// A list of characters represented as ints. Commonly used by older Erlang -/// modules. -pub type Charlist - -/// Transform a charlist to a string -@external(erlang, "unicode", "characters_to_binary") -pub fn to_string(a: Charlist) -> String - -// Calls `unicode:characters_to_binary(Data, unicode, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_binary-1> - -/// Transform a string to a charlist -@external(erlang, "unicode", "characters_to_list") -pub fn from_string(a: String) -> Charlist -// Calls `unicode:characters_to_list(Data, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_list-1> diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam deleted file mode 100644 index 48e11a7ad80..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam +++ /dev/null @@ -1,737 +0,0 @@ -//// Working with files on the filesystem. -//// -//// The functions included in this module are for high-level concepts such as -//// reading and writing. - -import gleam/bit_array -import gleam/result - -/// Reason represents all of the reasons that Erlang surfaces of why a file -/// system operation could fail. Most of these reasons are POSIX errors, which -/// come from the operating system and start with `E`. Others have been added to -/// represent other issues that may arise. -pub type Reason { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 -} - -/// The type of file found by `file_info` or `link_info`. -/// -pub type FileType { - Device - Directory - Other - Regular - Symlink -} - -/// The read/write permissions a user can have for a file. -/// -pub type Access { - NoAccess - Read - ReadWrite - Write -} - -/// Meta information for a file. -/// -/// Timestamps are in seconds before or after the Unix time epoch, -/// `1970-01-01 00:00:00 UTC`. -/// -pub type FileInfo { - FileInfo( - /// File size in bytes. - /// - size: Int, - /// `Regular`, `Directory`, `Symlink`, `Device`, or `Other`. - /// - file_type: FileType, - /// `ReadWrite`, `Read`, `Write`, or `NoAccess`. - /// - access: Access, - /// Timestamp of most recent access. - /// - atime: Int, - /// Timestamp of most recent modification. - /// - mtime: Int, - /// Timestamp of most recent change (or file creation, depending on - /// operating system). - /// - ctime: Int, - /// File permissions encoded as a sum of bit values, including but not - /// limited to: - /// - /// Owner read, write, execute. - /// - /// `0o400`, `0o200`, `0o100` - /// - /// Group read, write, execute. - /// - /// `0o40`, `0o20`, `0o10` - /// - /// Other read, write, execute. - /// - /// `0o4`, `0o2`, `0o1` - /// - /// Set user ID, group ID on execution. - /// - /// `0x800`, `0x400` - /// - mode: Int, - /// Total links to a file (always `1` for file systems without links). - /// - links: Int, - /// The file system where a file is located (`0` for drive `A:` on Windows, - /// `1` for `B:`, etc.). - /// - major_device: Int, - /// Character device (or `0` on non-Unix systems). - /// - minor_device: Int, - /// The `inode` number for a file (always `0` on non-Unix file systems). - /// - inode: Int, - /// The owner of a file (always `0` on non-Unix file systems). - /// - user_id: Int, - /// The group id of a file (always `0` on non-Unix file systems). - /// - group_id: Int, - ) -} - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To get `FileInfo` about a symlink itself, use `link_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > file_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 140, -/// file_type: Directory, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/does_not_exist") -/// Error(Enoent) -/// -/// > file_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn file_info(a: String) -> Result(FileInfo, Reason) { - do_file_info(a) -} - -@external(erlang, "gleam_erlang_ffi", "file_info") -fn do_file_info(a: String) -> Result(FileInfo, Reason) - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To get `FileInfo` about a symlink's target, use `file_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > link_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 41, -/// file_type: Symlink, -/// access: ReadWrite, -/// atime: 1680581150, -/// mtime: 1680581150, -/// ctime: 1680581150, -/// mode: 41471, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 471587, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/does_not_exist") -/// Error(Enoent) -/// -/// > link_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn link_info(a: String) -> Result(FileInfo, Reason) { - do_link_info(a) -} - -@external(erlang, "gleam_erlang_ffi", "link_info") -fn do_link_info(a: String) -> Result(FileInfo, Reason) - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Directory` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_directory("/tmp") -/// Ok(True) -/// -/// > is_directory("resume.pdf") -/// Ok(False) -/// -/// > is_directory("/does_not_exist") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn is_directory(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) - file_type == Directory -} - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Regular` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_regular("resume.pdf") -/// Ok(True) -/// -/// > is_regular("/tmp") -/// Ok(False) -/// -/// > is_regular("/does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn is_regular(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) - file_type == Regular -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To find whether a symlink itself exists, use `link_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_exists("resume.pdf") -/// Ok(True) -/// -/// > file_exists("/tmp") -/// Ok(True) -/// -/// > file_exists("/does_not_exist") -/// Ok(False) -/// -/// > file_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn file_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> do_file_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To find whether a symlink's target exists, use `file_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_exists("resume.pdf") -/// Ok(True) -/// -/// > link_exists("/tmp") -/// Ok(True) -/// -/// > link_exists("/does_not_exist") -/// Ok(False) -/// -/// > link_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn link_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> do_link_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Tries to create a directory. Missing parent directories are not created. -/// -/// Returns a Result of nil if the directory is created or Reason if the -/// operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > make_directory("/tmp/foo") -/// Ok(Nil) -/// -/// > make_directory("relative_directory") -/// Ok(Nil) -/// -/// > make_directory("/tmp/missing_intermediate_directory/foo") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "make_directory") -pub fn make_directory(a: String) -> Result(Nil, Reason) - -/// Lists all files in a directory, except files with -/// [raw filenames](https://www.erlang.org/doc/apps/stdlib/unicode_usage.html#notes-about-raw-filenames). -/// -/// Returns a Result containing the list of filenames in the directory, or Reason -/// if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > list_directory("/tmp") -/// Ok(["FB01293B-8597-4359-80D5-130140A0C0DE","AlTest2.out"]) -/// -/// > list_directory("resume.docx") -/// Error(Enotdir) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "list_directory") -pub fn list_directory(a: String) -> Result(List(String), Reason) - -/// Deletes a directory. -/// -/// The directory must be empty before it can be deleted. Returns a nil Success -/// or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > delete_directory("foo") -/// Ok(Nil) -/// -/// > delete_directory("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "delete_directory") -pub fn delete_directory(a: String) -> Result(Nil, Reason) - -/// Deletes a file or directory recursively. -/// -/// Returns a nil Success or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > recursive_delete("foo") -/// Ok(Nil) -/// -/// > recursive_delete("/bar") -/// Ok(Nil) -/// -/// > recursive_delete("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "recursive_delete") -pub fn recursive_delete(a: String) -> Result(Nil, Reason) - -/// Read the contents of the given file as a String -/// -/// Assumes the file is UTF-8 encoded. Returns a Result containing the file's -/// contents as a String if the operation was successful, or Reason if the file -/// operation failed. If the file is not UTF-8 encoded, the `NotUTF8` variant -/// will be returned. -/// -/// ## Examples -/// -/// ```gleam -/// > read("example.txt") -/// Ok("Hello, World!") -/// -/// > read(from: "example.txt") -/// Ok("Hello, World!") -/// -/// > read("does_not_exist.txt") -/// Error(Enoent) -/// -/// > read("cat.gif") -/// Error(NotUTF8) -/// ``` -/// -@deprecated("Use the simplifile package instead?") -pub fn read(from path: String) -> Result(String, Reason) { - path - |> do_read_bits() - |> result.then(fn(content) { - case bit_array.to_string(content) { - Ok(string) -> Ok(string) - Error(Nil) -> Error(NotUtf8) - } - }) -} - -/// Read the contents of the given file as a BitString -/// -/// Returns a Result containing the file's contents as a BitString if the -/// operation was successful, or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > read_bits("example.txt") -/// Ok(<<"Hello, World!">>) -/// -/// > read_bits(from: "cat.gif") -/// Ok(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// -/// > read_bits("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn read_bits(from path: String) -> Result(BitArray, Reason) { - do_read_bits(path) -} - -@external(erlang, "gleam_erlang_ffi", "read_file") -fn do_read_bits(a: path) -> Result(BitArray, Reason) - -/// Write the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > write(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > write("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn write(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_array.from_string - |> do_write_bits(path) -} - -/// Write the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > write_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn write_bits( - contents contents: BitArray, - to path: String, -) -> Result(Nil, Reason) { - do_write_bits(contents, path) -} - -@external(erlang, "gleam_erlang_ffi", "write_file") -fn do_write_bits(a: BitArray, b: String) -> Result(Nil, Reason) - -/// Append the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > append(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > append("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn append(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_array.from_string - |> do_append_bits(path) -} - -/// Append the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > append_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -pub fn append_bits( - contents contents: BitArray, - to path: String, -) -> Result(Nil, Reason) { - do_append_bits(contents, path) -} - -@external(erlang, "gleam_erlang_ffi", "append_file") -fn do_append_bits( - contents contents: BitArray, - path path: String, -) -> Result(Nil, Reason) - -/// Delete the given file. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > delete("file.txt") -/// Ok(Nil) -/// -/// > delete("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "delete_file") -pub fn delete(a: String) -> Result(Nil, Reason) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam deleted file mode 100644 index 339415c9a1a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam +++ /dev/null @@ -1,62 +0,0 @@ -import gleam/erlang/atom.{type Atom} - -pub type Node - -type DoNotLeak - -/// Return the current node. -/// -@external(erlang, "erlang", "node") -pub fn self() -> Node - -/// Return a list of all visible nodes in the cluster, not including the current -/// node. -/// -/// The current node can be included by calling `self()` and prepending the -/// result. -/// -/// ```gleam -/// let all_nodes = [node.self(), ..node.visible()] -/// ``` -/// -@external(erlang, "erlang", "nodes") -pub fn visible() -> List(Node) - -pub type ConnectError { - /// Was unable to connect to the node. - FailedToConnect - /// The local node is not alive, so it is not possible to connect to the other - /// node. - LocalNodeIsNotAlive -} - -// TODO: test unknown node -// TODO: test successfully connecting -/// Establish a connection to a node, so the nodes can send messages to each -/// other and any other connected nodes. -/// -/// Returns `Error(FailedToConnect)` if the node is not reachable. -/// -/// Returns `Error(LocalNodeIsNotAlive)` if the local node is not alive, meaning -/// it is not running in distributed mode. -/// -@external(erlang, "gleam_erlang_ffi", "connect_node") -pub fn connect(node: Atom) -> Result(Node, ConnectError) - -// TODO: test -/// Send a message to a named process on a given node. -/// -/// These messages are untyped, like regular Erlang messages. -/// -pub fn send(node: Node, name: Atom, message: message) -> Nil { - raw_send(#(name, node), message) - Nil -} - -@external(erlang, "erlang", "send") -fn raw_send(receiver: #(Atom, Node), message: message) -> DoNotLeak - -/// Convert a node to the atom of its name. -/// -@external(erlang, "gleam_erlang_ffi", "identity") -pub fn to_atom(node: Node) -> Atom diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam deleted file mode 100644 index e13597404bf..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam +++ /dev/null @@ -1,95 +0,0 @@ -//// Access to the shell's environment variables - -import gleam/map.{type Map} - -/// Returns the list of all available environment variables as a list of key, -/// tuples. -/// -/// ## Examples -/// -/// > get_all_env() -/// map.from_list([ -/// #("SHELL", "/bin/bash"), -/// #("PWD", "/home/j3rn"), -/// ... -/// ]) -/// -@external(erlang, "gleam_erlang_ffi", "get_all_env") -pub fn get_all_env() -> Map(String, String) - -/// Returns the value associated with the given environment variable name. -/// -/// ## Examples -/// -/// > get_env("SHELL") -/// "/bin/bash" -/// -/// > get_env(name: "PWD") -/// "/home/j3rn" -/// -@external(erlang, "gleam_erlang_ffi", "get_env") -pub fn get_env(name name: String) -> Result(String, Nil) - -/// Associates the given value with the given environment variable name. -/// -/// ## Examples -/// -/// > set_env("MYVAR", "MYVALUE") -/// Nil -/// > get_env("MYVAR") -/// "MYVALUE" -/// -/// > set_env(value: "MYVALUE", name: "MYVAR") -/// Nil -/// -@external(erlang, "gleam_erlang_ffi", "set_env") -pub fn set_env(name name: String, value value: String) -> Nil - -/// Removes the environment variable with the given name. -/// -/// Returns Nil regardless of whether the variable ever existed. -/// -/// ## Examples -/// -/// > get_env("MYVAR") -/// Ok("MYVALUE") -/// > unset_env("MYVAR") -/// Nil -/// > get_env("MYVAR") -/// Error(Nil) -/// -/// > unset_env(name: "MYVAR") -/// Nil -/// -@external(erlang, "gleam_erlang_ffi", "unset_env") -pub fn unset_env(name name: String) -> Nil - -/// Represents operating system kernels -pub type OsFamily { - // The family which includes modern versions of the Windows operating system. - WindowsNt - // The family of operating systems based on the open source Linux kernel. - Linux - // The family of Apple operating systems such as macOS and iOS. - Darwin - // The family of operating systems based on the FreeBSD kernel. - FreeBsd - // An operating system kernel other than Linux, Darwin, FreeBSD, or NT. - Other(String) -} - -/// Returns the kernel of the host operating system. -/// -/// Unknown kernels are reported as `Other(String)`; e.g. `Other("sunos")`. -/// -/// ## Examples -/// -/// > family() -/// Linux -/// > family() -/// Darwin -/// > family() -/// Other("sunos") -/// -@external(erlang, "gleam_erlang_ffi", "os_family") -pub fn family() -> OsFamily diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam deleted file mode 100644 index f66030612a5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam +++ /dev/null @@ -1,744 +0,0 @@ -import gleam/string -import gleam/dynamic.{type Dynamic} -import gleam/erlang.{type Reference} -import gleam/erlang/atom.{type Atom} - -/// A `Pid` (or Process identifier) is a reference to an Erlang process. Each -/// process has a `Pid` and it is one of the lowest level building blocks of -/// inter-process communication in the Erlang and Gleam OTP frameworks. -/// -pub type Pid - -/// Get the `Pid` for the current process. -@external(erlang, "erlang", "self") -pub fn self() -> Pid - -/// Create a new Erlang process that runs concurrently to the creator. In other -/// languages this might be called a fibre, a green thread, or a coroutine. -/// -/// If `linked` is `True` then the created process is linked to the creator -/// process. When a process terminates an exit signal is sent to all other -/// processes that are linked to it, causing the process to either terminate or -/// have to handle the signal. -/// -/// More can be read about processes and links in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/reference_manual/processes.html -/// -pub fn start(running implementation: fn() -> anything, linked link: Bool) -> Pid { - case link { - True -> spawn_link(implementation) - False -> spawn(implementation) - } -} - -@external(erlang, "erlang", "spawn") -fn spawn(a: fn() -> anything) -> Pid - -@external(erlang, "erlang", "spawn_link") -fn spawn_link(a: fn() -> anything) -> Pid - -/// A `Subject` is a value that processes can use to send and receive messages -/// to and from each other in a well typed way. -/// -/// Each subject is "owned" by the process that created it. Any process can use -/// the `send` function to sent a message of the correct type to the process -/// that owns the subject, and the owner can use the `receive` function or the -/// `Selector` type to receive these messages. -/// -/// The `Subject` type is similar to the "channel" types found in other -/// languages and the "topic" concept found in some pub-sub systems. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// -/// // Send a message with the subject -/// send(subject, "Hello, Joe!") -/// -/// // Receive the message -/// receive(subject, within: 10) -/// ``` -/// -pub opaque type Subject(message) { - Subject(owner: Pid, tag: Reference) -} - -/// Create a new `Subject` owned by the current process. -/// -pub fn new_subject() -> Subject(message) { - Subject(owner: self(), tag: erlang.make_reference()) -} - -/// Get the owner process for a `Subject`. This is the process that created the -/// `Subject` and will receive messages sent with it. -/// -pub fn subject_owner(subject: Subject(message)) -> Pid { - subject.owner -} - -type DoNotLeak - -@external(erlang, "erlang", "send") -fn raw_send(a: Pid, b: message) -> DoNotLeak - -/// Send a message to a process using a `Subject`. The message must be of the -/// type that the `Subject` accepts. -/// -/// This function does not wait for the `Subject` owner process to call the -/// `receive` function, instead it returns once the message has been placed in -/// the process' mailbox. -/// -/// # Ordering -/// -/// If process P1 sends two messages to process P2 it is guaranteed that process -/// P1 will receive the messages in the order they were sent. -/// -/// If you wish to receive the messages in a different order you can send them -/// on two different subjects and the receiver function can call the `receive` -/// function for each subject in the desired order, or you can write some Erlang -/// code to perform a selective receive. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// send(subject, "Hello, Joe!") -/// ``` -/// -pub fn send(subject: Subject(message), message: message) -> Nil { - raw_send(subject.owner, #(subject.tag, message)) - Nil -} - -/// Receive a message that has been sent to current process using the `Subject`. -/// -/// If there is not an existing message for the `Subject` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject` can receive a message using -/// it. If a process that does not own the `Subject` attempts to receive with it -/// then it will not receive a message. -/// -/// To wait for messages from multiple `Subject`s at the same time see the -/// `Selector` type. -/// -pub fn receive( - from subject: Subject(message), - within milliseconds: Int, -) -> Result(message, Nil) { - new_selector() - |> selecting(subject, fn(x) { x }) - |> select(within: milliseconds) -} - -/// A type that enables a process to wait for messages from multiple `Subject`s -/// at the same time, returning whichever message arrives first. -/// -/// Used with the `new_selector`, `selecting`, and `select` functions. -/// -/// # Examples -/// -/// ```gleam -/// > let int_subject = new_subject() -/// > let float_subject = new_subject() -/// > send(int_subject, 1) -/// > -/// > let selector = -/// > new_selector() -/// > |> selecting(int_subject, int.to_string) -/// > |> selecting(float_subject, float.to_string) -/// > -/// > select(selector, 10) -/// Ok("1") -/// ``` -/// -pub type Selector(payload) - -/// Create a new `Selector` which can be used to receive messages on multiple -/// `Subject`s at once. -/// -@external(erlang, "gleam_erlang_ffi", "new_selector") -pub fn new_selector() -> Selector(payload) - -/// Receive a message that has been sent to current process using any of the -/// `Subject`s that have been added to the `Selector` with the `selecting` -/// function. -/// -/// If there is not an existing message for the `Selector` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject`s can receive a message using -/// them. If a process that does not own the a `Subject` attempts to receive -/// with it then it will not receive a message. -/// -/// To wait forever for the next message rather than for a limited amount of -/// time see the `select_forever` function. -/// -@external(erlang, "gleam_erlang_ffi", "select") -pub fn select( - from from: Selector(payload), - within within: Int, -) -> Result(payload, Nil) - -/// Similar to the `select` function but will wait forever for a message to -/// arrive rather than timing out after a specified amount of time. -/// -@external(erlang, "gleam_erlang_ffi", "select") -pub fn select_forever(from from: Selector(payload)) -> payload - -/// Add a transformation function to a selector. When a message is received -/// using this selector the transformation function is applied to the message. -/// -/// This function can be used to change the type of messages received and may -/// be useful when combined with the `merge_selector` function. -/// -@external(erlang, "gleam_erlang_ffi", "map_selector") -pub fn map_selector(a: Selector(a), b: fn(a) -> b) -> Selector(b) - -/// Merge one selector into another, producing a selector that contains the -/// message handlers of both. -/// -/// If a subject is handled by both selectors the handler function of the -/// second selector is used. -/// -@external(erlang, "gleam_erlang_ffi", "merge_selector") -pub fn merge_selector(a: Selector(a), b: Selector(a)) -> Selector(a) - -pub type ExitMessage { - ExitMessage(pid: Pid, reason: ExitReason) -} - -pub type ExitReason { - Normal - Killed - Abnormal(reason: String) -} - -/// Add a handler for trapped exit messages. In order for these messages to be -/// sent to the process when a linked process exits the process must call the -/// `trap_exit` beforehand. -/// -pub fn selecting_trapped_exits( - selector: Selector(a), - handler: fn(ExitMessage) -> a, -) -> Selector(a) { - let tag = atom.create_from_string("EXIT") - let handler = fn(message: #(Atom, Pid, Dynamic)) -> a { - let reason = message.2 - let normal = dynamic.from(Normal) - let killed = dynamic.from(Killed) - let reason = case dynamic.string(reason) { - _ if reason == normal -> Normal - _ if reason == killed -> Killed - Ok(reason) -> Abnormal(reason) - Error(_) -> Abnormal(string.inspect(reason)) - } - handler(ExitMessage(message.1, reason)) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -// TODO: implement in Gleam -/// Discard all messages in the current process' mailbox. -/// -/// Warning: This function may cause other processes to crash if they sent a -/// message to the current process and are waiting for a response, so use with -/// caution. -/// -@external(erlang, "gleam_erlang_ffi", "flush_messages") -pub fn flush_messages() -> Nil - -/// Add a new `Subject` to the `Selector` to that it's messages can be received. -/// -/// The `mapping` function provided with the `Subject` can be used to convert -/// the type of messages received using this `Subject`. This is useful for when -/// you wish to add multiple `Subject`s to a `Seletor` when they have differing -/// message types. If you do not wish to transform the incoming messages in any -/// way then the `identity` function can be given. -/// -pub fn selecting( - selector: Selector(payload), - for subject: Subject(message), - mapping transform: fn(message) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(Reference, message)) { transform(message.1) } - insert_selector_handler(selector, #(subject.tag, 2), handler) -} - -/// Add a handler to a selector for 2 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record2( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic)) { transform(message.1) } - insert_selector_handler(selector, #(tag, 2), handler) -} - -/// Add a handler to a selector for 3 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record3( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic)) { - transform(message.1, message.2) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -/// Add a handler to a selector for 4 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record4( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3) - } - insert_selector_handler(selector, #(tag, 4), handler) -} - -/// Add a handler to a selector for 5 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record5( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4) - } - insert_selector_handler(selector, #(tag, 5), handler) -} - -/// Add a handler to a selector for 6 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record6( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4, message.5) - } - insert_selector_handler(selector, #(tag, 6), handler) -} - -/// Add a handler to a selector for 7 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record7( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - ) { - transform(message.1, message.2, message.3, message.4, message.5, message.6) - } - insert_selector_handler(selector, #(tag, 7), handler) -} - -/// Add a handler to a selector for 8 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record8( - selector: Selector(payload), - tag: tag, - mapping transform: fn( - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #( - tag, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ), - ) { - transform( - message.1, - message.2, - message.3, - message.4, - message.5, - message.6, - message.7, - ) - } - insert_selector_handler(selector, #(tag, 8), handler) -} - -type AnythingSelectorTag { - Anything -} - -/// Add a catch-all handler to a selector that will be used when no other -/// handler in a selector is suitable for a given message. -/// -/// This may be useful for when you want to ensure that any message in the inbox -/// is handled, or when you need to handle messages from other BEAM languages -/// which do not use subjects or record format messages. -/// -pub fn selecting_anything( - selector: Selector(payload), - mapping handler: fn(Dynamic) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, Anything, handler) -} - -@external(erlang, "gleam_erlang_ffi", "insert_selector_handler") -fn insert_selector_handler( - a: Selector(payload), - for for: tag, - mapping mapping: fn(message) -> payload, -) -> Selector(payload) - -/// Suspends the process calling this function for the specified number of -/// milliseconds. -/// -@external(erlang, "gleam_erlang_ffi", "sleep") -pub fn sleep(a: Int) -> Nil - -/// Suspends the process forever! This may be useful for suspending the main -/// process in a Gleam program when it has no more work to do but we want other -/// processes to continue to work. -/// -@external(erlang, "gleam_erlang_ffi", "sleep_forever") -pub fn sleep_forever() -> Nil - -/// Check to see whether the process for a given `Pid` is alive. -/// -/// See the [Erlang documentation][1] for more information. -/// -/// [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1 -/// -@external(erlang, "erlang", "is_process_alive") -pub fn is_alive(a: Pid) -> Bool - -type ProcessMonitorFlag { - Process -} - -@external(erlang, "erlang", "monitor") -fn erlang_monitor_process(a: ProcessMonitorFlag, b: Pid) -> Reference - -pub opaque type ProcessMonitor { - ProcessMonitor(tag: Reference) -} - -/// A message received when a monitored process exits. -/// -pub type ProcessDown { - ProcessDown(pid: Pid, reason: Dynamic) -} - -/// Start monitoring a process so that when the monitored process exits a -/// message is sent to the monitoring process. -/// -/// The message is only sent once, when the target process exits. If the -/// process was not alive when this function is called the message will never -/// be received. -/// -/// The down message can be received with a `Selector` and the -/// `selecting_process_down` function. -/// -/// The process can be demonitored with the `demonitor_process` function. -/// -pub fn monitor_process(pid: Pid) -> ProcessMonitor { - Process - |> erlang_monitor_process(pid) - |> ProcessMonitor -} - -/// Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can -/// be received using the `Selector` and the `select` function. -/// -pub fn selecting_process_down( - selector: Selector(payload), - monitor: ProcessMonitor, - mapping: fn(ProcessDown) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, monitor.tag, mapping) -} - -/// Remove the monitor for a process so that when the monitor process exits a -/// `ProcessDown` message is not sent to the monitoring process. -/// -/// If the message has already been sent it is removed from the monitoring -/// process' mailbox. -/// -@external(erlang, "gleam_erlang_ffi", "demonitor") -pub fn demonitor_process(monitor monitor: ProcessMonitor) -> Nil - -/// An error returned when making a call to a process. -/// -pub type CallError(msg) { - /// The process being called exited before it sent a response. - /// - CalleeDown(reason: Dynamic) - - /// The process being called did not response within the permitted amount of - /// time. - /// - CallTimeout -} - -// This function is based off of Erlang's gen:do_call/4. -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time then an error is returned. -/// -pub fn try_call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> Result(response, CallError(response)) { - let reply_subject = new_subject() - - // Monitor the callee process so we can tell if it goes down (meaning we - // won't get a reply) - let monitor = monitor_process(subject_owner(subject)) - - // Send the request to the process over the channel - send(subject, make_request(reply_subject)) - - // Await a reply or handle failure modes (timeout, process down, etc) - let result = - new_selector() - |> selecting(reply_subject, Ok) - |> selecting_process_down( - monitor, - fn(down: ProcessDown) { Error(CalleeDown(reason: down.reason)) }, - ) - |> select(timeout) - - // Demonitor the process and close the channels as we're done - demonitor_process(monitor) - - // Prepare an appropriate error (if present) for the caller - case result { - Error(Nil) -> Error(CallTimeout) - Ok(res) -> res - } -} - -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time the calling process crashes. If you wish an error to be returned -/// instead see the `try_call` function. -/// -pub fn call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> response { - let assert Ok(resp) = try_call(subject, make_request, timeout) - resp -} - -/// Creates a link between the calling process and another process. -/// -/// When a process crashes any linked processes will also crash. This is useful -/// to ensure that groups of processes that depend on each other all either -/// succeed or fail together. -/// -/// Returns `True` if the link was created successfully, returns `False` if the -/// process was not alive and as such could not be linked. -/// -@external(erlang, "gleam_erlang_ffi", "link") -pub fn link(pid pid: Pid) -> Bool - -@external(erlang, "erlang", "unlink") -fn erlang_unlink(pid pid: Pid) -> Bool - -/// Removes any existing link between the caller process and the target process. -/// -pub fn unlink(pid: Pid) -> Nil { - erlang_unlink(pid) - Nil -} - -pub type Timer - -@external(erlang, "erlang", "send_after") -fn erlang_send_after(a: Int, b: Pid, c: msg) -> Timer - -/// Send a message over a channel after a specified number of milliseconds. -/// -pub fn send_after(subject: Subject(msg), delay: Int, message: msg) -> Timer { - erlang_send_after(delay, subject.owner, #(subject.tag, message)) -} - -@external(erlang, "erlang", "cancel_timer") -fn erlang_cancel_timer(a: Timer) -> Dynamic - -/// Values returned when a timer is cancelled. -/// -pub type Cancelled { - /// The timer could not be found. It likely has already triggered. - /// - TimerNotFound - - /// The timer was found and cancelled before it triggered. - /// - /// The amount of remaining time before the timer was due to be triggered is - /// returned in milliseconds. - /// - Cancelled(time_remaining: Int) -} - -/// Cancel a given timer, causing it not to trigger if it has not done already. -/// -pub fn cancel_timer(timer: Timer) -> Cancelled { - case dynamic.int(erlang_cancel_timer(timer)) { - Ok(i) -> Cancelled(i) - Error(_) -> TimerNotFound - } -} - -type KillFlag { - Kill -} - -@external(erlang, "erlang", "exit") -fn erlang_kill(to to: Pid, because because: KillFlag) -> Bool - -// Go, my pretties. Kill! Kill! -// - Bart Simpson -// -/// Send an untrappable `kill` exit signal to the target process. -/// -/// See the documentation for the Erlang [`erlang:exit`][1] function for more -/// information. -/// -/// [1]: https://erlang.org/doc/man/erlang.html#exit-1 -/// -pub fn kill(pid: Pid) -> Nil { - erlang_kill(pid, Kill) - Nil -} - -@external(erlang, "erlang", "exit") -fn erlang_send_exit(to to: Pid, because because: whatever) -> Bool - -// TODO: test -/// Sends an exit signal to a process, indicating that the process is to shut -/// down. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_exit(to pid: Pid) -> Nil { - erlang_send_exit(pid, Normal) - Nil -} - -/// Sends an exit signal to a process, indicating that the process is to shut -/// down due to an abnormal reason such as a failure. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_abnormal_exit(pid: Pid, reason: String) -> Nil { - erlang_send_exit(pid, Abnormal(reason)) - Nil -} - -/// Set whether the current process is to trap exit signals or not. -/// -/// When not trapping exits if a linked process crashes the exit signal -/// propagates to the process which will also crash. -/// This is the normal behaviour before this function is called. -/// -/// When trapping exits (after this function is called) if a linked process -/// crashes an exit message is sent to the process instead. These messages can -/// be handled with the `selecting_trapped_exits` function. -/// -@external(erlang, "gleam_erlang_ffi", "trap_exits") -pub fn trap_exits(a: Bool) -> Nil - -/// Register a process under a given name, allowing it to be looked up using -/// the `named` function. -/// -/// This function will return an error under the following conditions: -/// - The process for the pid no longer exists. -/// - The name has already been registered. -/// - The process already has a name. -/// - The name is the atom `undefined`, which is reserved by Erlang. -/// -@external(erlang, "gleam_erlang_ffi", "register_process") -pub fn register(pid: Pid, name: Atom) -> Result(Nil, Nil) - -/// Un-register a process name, after which the process can no longer be looked -/// up by that name, and both the name and the process can be re-used in other -/// registrations. -/// -/// It is possible to un-register process that are not from your application, -/// including those from Erlang/OTP itself. This is not recommended and will -/// likely result in undesirable behaviour and crashes. -/// -@external(erlang, "gleam_erlang_ffi", "unregister_process") -pub fn unregister(name: Atom) -> Result(Nil, Nil) - -/// Look up a process by name, returning the pid if it exists. -/// -@external(erlang, "gleam_erlang_ffi", "process_named") -pub fn named(name: Atom) -> Result(Pid, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl deleted file mode 100644 index 14a55381864..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(gleam@erlang). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0, priv_directory/1]). --export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]). - --type safe() :: safe. - --type get_line_error() :: eof | no_data. - --type time_unit() :: second | millisecond | microsecond | nanosecond. - --type crash() :: {exited, gleam@dynamic:dynamic_()} | - {thrown, gleam@dynamic:dynamic_()} | - {errored, gleam@dynamic:dynamic_()}. - --type ensure_all_started_error() :: {unknown_application, - gleam@erlang@atom:atom_()} | - {application_failed_to_start, - gleam@erlang@atom:atom_(), - gleam@dynamic:dynamic_()}. - --type reference_() :: any(). - --spec format(any()) -> binary(). -format(Term) -> - unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])). - --spec term_to_binary(any()) -> bitstring(). -term_to_binary(A) -> - erlang:term_to_binary(A). - --spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. -get_line(Prompt) -> - gleam_erlang_ffi:get_line(Prompt). - --spec system_time(time_unit()) -> integer(). -system_time(A) -> - os:system_time(A). - --spec erlang_timestamp() -> {integer(), integer(), integer()}. -erlang_timestamp() -> - os:timestamp(). - --spec rescue(fun(() -> FHH)) -> {ok, FHH} | {error, crash()}. -rescue(A) -> - gleam_erlang_ffi:rescue(A). - --spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | - {error, nil}. -binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue( - fun() -> erlang:binary_to_term(Binary, [safe]) end - ) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | - {error, nil}. -unsafe_binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec start_arguments() -> list(binary()). -start_arguments() -> - _pipe = init:get_plain_arguments(), - gleam@list:map(_pipe, fun unicode:characters_to_binary/1). - --spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok, - list(gleam@erlang@atom:atom_())} | - {error, ensure_all_started_error()}. -ensure_all_started(Application) -> - gleam_erlang_ffi:ensure_all_started(Application). - --spec make_reference() -> reference_(). -make_reference() -> - erlang:make_ref(). - --spec priv_directory(binary()) -> {ok, binary()} | {error, nil}. -priv_directory(Name) -> - gleam_erlang_ffi:priv_directory(Name). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl deleted file mode 100644 index e9ad5300ce5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl +++ /dev/null @@ -1,26 +0,0 @@ --module(gleam@erlang@atom). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]). --export_type([atom_/0, from_string_error/0]). - --type atom_() :: any(). - --type from_string_error() :: atom_not_loaded. - --spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}. -from_string(A) -> - gleam_erlang_ffi:atom_from_string(A). - --spec create_from_string(binary()) -> atom_(). -create_from_string(A) -> - erlang:binary_to_atom(A). - --spec to_string(atom_()) -> binary(). -to_string(A) -> - erlang:atom_to_binary(A). - --spec from_dynamic(gleam@dynamic:dynamic_()) -> {ok, atom_()} | - {error, list(gleam@dynamic:decode_error())}. -from_dynamic(From) -> - gleam_erlang_ffi:atom_from_dynamic(From). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl deleted file mode 100644 index 9f9c0fa1c55..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl +++ /dev/null @@ -1,15 +0,0 @@ --module(gleam@erlang@charlist). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([to_string/1, from_string/1]). --export_type([charlist/0]). - --type charlist() :: any(). - --spec to_string(charlist()) -> binary(). -to_string(A) -> - unicode:characters_to_binary(A). - --spec from_string(binary()) -> charlist(). -from_string(A) -> - unicode:characters_to_list(A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl deleted file mode 100644 index 1fe6628add7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl +++ /dev/null @@ -1,190 +0,0 @@ --module(gleam@erlang@file). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([file_info/1, link_info/1, is_directory/1, is_regular/1, file_exists/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]). --export_type([reason/0, file_type/0, access/0, file_info/0]). - --type reason() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8. - --type file_type() :: device | directory | other | regular | symlink. - --type access() :: no_access | read | read_write | write. - --type file_info() :: {file_info, - integer(), - file_type(), - access(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec file_info(binary()) -> {ok, file_info()} | {error, reason()}. -file_info(A) -> - gleam_erlang_ffi:file_info(A). - --spec link_info(binary()) -> {ok, file_info()} | {error, reason()}. -link_info(A) -> - gleam_erlang_ffi:link_info(A). - --spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}. -is_directory(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= directory - end - ). - --spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}. -is_regular(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= regular - end - ). - --spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}. -file_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:file_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}. -link_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:link_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec make_directory(binary()) -> {ok, nil} | {error, reason()}. -make_directory(A) -> - gleam_erlang_ffi:make_directory(A). - --spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}. -list_directory(A) -> - gleam_erlang_ffi:list_directory(A). - --spec delete_directory(binary()) -> {ok, nil} | {error, reason()}. -delete_directory(A) -> - gleam_erlang_ffi:delete_directory(A). - --spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}. -recursive_delete(A) -> - gleam_erlang_ffi:recursive_delete(A). - --spec read(binary()) -> {ok, binary()} | {error, reason()}. -read(Path) -> - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:read_file(_pipe), - gleam@result:then( - _pipe@1, - fun(Content) -> case gleam@bit_array:to_string(Content) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, not_utf8} - end end - ). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}. -read_bits(Path) -> - gleam_erlang_ffi:read_file(Path). - --spec write(binary(), binary()) -> {ok, nil} | {error, reason()}. -write(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam_stdlib:identity(_pipe), - gleam_erlang_ffi:write_file(_pipe@1, Path). - --spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -write_bits(Contents, Path) -> - gleam_erlang_ffi:write_file(Contents, Path). - --spec append(binary(), binary()) -> {ok, nil} | {error, reason()}. -append(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam_stdlib:identity(_pipe), - gleam_erlang_ffi:append_file(_pipe@1, Path). - --spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -append_bits(Contents, Path) -> - gleam_erlang_ffi:append_file(Contents, Path). - --spec delete(binary()) -> {ok, nil} | {error, reason()}. -delete(A) -> - gleam_erlang_ffi:delete_file(A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl deleted file mode 100644 index f57d029ba1a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@erlang@node). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([self/0, visible/0, connect/1, send/3, to_atom/1]). --export_type([node_/0, do_not_leak/0, connect_error/0]). - --type node_() :: any(). - --type do_not_leak() :: any(). - --type connect_error() :: failed_to_connect | local_node_is_not_alive. - --spec self() -> node_(). -self() -> - erlang:node(). - --spec visible() -> list(node_()). -visible() -> - erlang:nodes(). - --spec connect(gleam@erlang@atom:atom_()) -> {ok, node_()} | - {error, connect_error()}. -connect(Node) -> - gleam_erlang_ffi:connect_node(Node). - --spec send(node_(), gleam@erlang@atom:atom_(), any()) -> nil. -send(Node, Name, Message) -> - erlang:send({Name, Node}, Message), - nil. - --spec to_atom(node_()) -> gleam@erlang@atom:atom_(). -to_atom(Node) -> - gleam_erlang_ffi:identity(Node). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl deleted file mode 100644 index 6604255b55f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@erlang@os). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]). --export_type([os_family/0]). - --type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}. - --spec get_all_env() -> gleam@map:map_(binary(), binary()). -get_all_env() -> - gleam_erlang_ffi:get_all_env(). - --spec get_env(binary()) -> {ok, binary()} | {error, nil}. -get_env(Name) -> - gleam_erlang_ffi:get_env(Name). - --spec set_env(binary(), binary()) -> nil. -set_env(Name, Value) -> - gleam_erlang_ffi:set_env(Name, Value). - --spec unset_env(binary()) -> nil. -unset_env(Name) -> - gleam_erlang_ffi:unset_env(Name). - --spec family() -> os_family(). -family() -> - gleam_erlang_ffi:os_family(). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl deleted file mode 100644 index fc8e0ffe15f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl +++ /dev/null @@ -1,374 +0,0 @@ --module(gleam@erlang@process). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([self/0, start/2, new_subject/0, subject_owner/1, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, selecting_process_down/3, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1, register/2, unregister/1, named/1]). --export_type([pid_/0, subject/1, do_not_leak/0, selector/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, timer/0, cancelled/0, kill_flag/0]). - --type pid_() :: any(). - --opaque subject(FJD) :: {subject, pid_(), gleam@erlang:reference_()} | - {gleam_phantom, FJD}. - --type do_not_leak() :: any(). - --type selector(FJE) :: any() | {gleam_phantom, FJE}. - --type exit_message() :: {exit_message, pid_(), exit_reason()}. - --type exit_reason() :: normal | killed | {abnormal, binary()}. - --type anything_selector_tag() :: anything. - --type process_monitor_flag() :: process. - --opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}. - --type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic_()}. - --type call_error(FJF) :: {callee_down, gleam@dynamic:dynamic_()} | - call_timeout | - {gleam_phantom, FJF}. - --type timer() :: any(). - --type cancelled() :: timer_not_found | {cancelled, integer()}. - --type kill_flag() :: kill. - --spec self() -> pid_(). -self() -> - erlang:self(). - --spec start(fun(() -> any()), boolean()) -> pid_(). -start(Implementation, Link) -> - case Link of - true -> - erlang:spawn_link(Implementation); - - false -> - erlang:spawn(Implementation) - end. - --spec new_subject() -> subject(any()). -new_subject() -> - {subject, erlang:self(), erlang:make_ref()}. - --spec subject_owner(subject(any())) -> pid_(). -subject_owner(Subject) -> - erlang:element(2, Subject). - --spec send(subject(FJO), FJO) -> nil. -send(Subject, Message) -> - erlang:send( - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ), - nil. - --spec new_selector() -> selector(any()). -new_selector() -> - gleam_erlang_ffi:new_selector(). - --spec select(selector(FJW), integer()) -> {ok, FJW} | {error, nil}. -select(From, Within) -> - gleam_erlang_ffi:select(From, Within). - --spec select_forever(selector(FKA)) -> FKA. -select_forever(From) -> - gleam_erlang_ffi:select(From). - --spec map_selector(selector(FKC), fun((FKC) -> FKE)) -> selector(FKE). -map_selector(A, B) -> - gleam_erlang_ffi:map_selector(A, B). - --spec merge_selector(selector(FKG), selector(FKG)) -> selector(FKG). -merge_selector(A, B) -> - gleam_erlang_ffi:merge_selector(A, B). - --spec flush_messages() -> nil. -flush_messages() -> - gleam_erlang_ffi:flush_messages(). - --spec selecting_trapped_exits(selector(FKK), fun((exit_message()) -> FKK)) -> selector(FKK). -selecting_trapped_exits(Selector, Handler) -> - Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>), - Handler@1 = fun(Message) -> - Reason = erlang:element(3, Message), - Normal = gleam@dynamic:from(normal), - Killed = gleam@dynamic:from(killed), - Reason@2 = case gleam@dynamic:string(Reason) of - _ when Reason =:= Normal -> - normal; - - _ when Reason =:= Killed -> - killed; - - {ok, Reason@1} -> - {abnormal, Reason@1}; - - {error, _} -> - {abnormal, gleam@string:inspect(Reason)} - end, - Handler({exit_message, erlang:element(2, Message), Reason@2}) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1). - --spec selecting(selector(FKN), subject(FKP), fun((FKP) -> FKN)) -> selector(FKN). -selecting(Selector, Subject, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler( - Selector, - {erlang:element(3, Subject), 2}, - Handler - ). - --spec 'receive'(subject(FJQ), integer()) -> {ok, FJQ} | {error, nil}. -'receive'(Subject, Milliseconds) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end), - gleam_erlang_ffi:select(_pipe@1, Milliseconds). - --spec selecting_record2( - selector(FKS), - any(), - fun((gleam@dynamic:dynamic_()) -> FKS) -) -> selector(FKS). -selecting_record2(Selector, Tag, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler). - --spec selecting_record3( - selector(FKW), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FKW) -) -> selector(FKW). -selecting_record3(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform(erlang:element(2, Message), erlang:element(3, Message)) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler). - --spec selecting_record4( - selector(FLA), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLA) -) -> selector(FLA). -selecting_record4(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler). - --spec selecting_record5( - selector(FLE), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLE) -) -> selector(FLE). -selecting_record5(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler). - --spec selecting_record6( - selector(FLI), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLI) -) -> selector(FLI). -selecting_record6(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler). - --spec selecting_record7( - selector(FLM), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLM) -) -> selector(FLM). -selecting_record7(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler). - --spec selecting_record8( - selector(FLQ), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLQ) -) -> selector(FLQ). -selecting_record8(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message), - erlang:element(8, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler). - --spec selecting_anything(selector(FLU), fun((gleam@dynamic:dynamic_()) -> FLU)) -> selector(FLU). -selecting_anything(Selector, Handler) -> - gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler). - --spec sleep(integer()) -> nil. -sleep(A) -> - gleam_erlang_ffi:sleep(A). - --spec sleep_forever() -> nil. -sleep_forever() -> - gleam_erlang_ffi:sleep_forever(). - --spec is_alive(pid_()) -> boolean(). -is_alive(A) -> - erlang:is_process_alive(A). - --spec monitor_process(pid_()) -> process_monitor(). -monitor_process(Pid) -> - _pipe = process, - _pipe@1 = erlang:monitor(_pipe, Pid), - {process_monitor, _pipe@1}. - --spec selecting_process_down( - selector(FMC), - process_monitor(), - fun((process_down()) -> FMC) -) -> selector(FMC). -selecting_process_down(Selector, Monitor, Mapping) -> - gleam_erlang_ffi:insert_selector_handler( - Selector, - erlang:element(2, Monitor), - Mapping - ). - --spec demonitor_process(process_monitor()) -> nil. -demonitor_process(Monitor) -> - gleam_erlang_ffi:demonitor(Monitor). - --spec try_call(subject(FMF), fun((subject(FMH)) -> FMF), integer()) -> {ok, FMH} | - {error, call_error(FMH)}. -try_call(Subject, Make_request, Timeout) -> - Reply_subject = new_subject(), - Monitor = monitor_process(subject_owner(Subject)), - send(Subject, Make_request(Reply_subject)), - Result = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting( - _pipe, - Reply_subject, - fun(Field@0) -> {ok, Field@0} end - ), - _pipe@2 = selecting_process_down( - _pipe@1, - Monitor, - fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end - ), - gleam_erlang_ffi:select(_pipe@2, Timeout) - end, - gleam_erlang_ffi:demonitor(Monitor), - case Result of - {error, nil} -> - {error, call_timeout}; - - {ok, Res} -> - Res - end. - --spec call(subject(FMM), fun((subject(FMO)) -> FMM), integer()) -> FMO. -call(Subject, Make_request, Timeout) -> - _assert_subject = try_call(Subject, Make_request, Timeout), - {ok, Resp} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/erlang/process"/utf8>>, - function => <<"call"/utf8>>, - line => 593}) - end, - Resp. - --spec link(pid_()) -> boolean(). -link(Pid) -> - gleam_erlang_ffi:link(Pid). - --spec unlink(pid_()) -> nil. -unlink(Pid) -> - erlang:unlink(Pid), - nil. - --spec send_after(subject(FMR), integer(), FMR) -> timer(). -send_after(Subject, Delay, Message) -> - erlang:send_after( - Delay, - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ). - --spec cancel_timer(timer()) -> cancelled(). -cancel_timer(Timer) -> - case gleam@dynamic:int(erlang:cancel_timer(Timer)) of - {ok, I} -> - {cancelled, I}; - - {error, _} -> - timer_not_found - end. - --spec kill(pid_()) -> nil. -kill(Pid) -> - erlang:exit(Pid, kill), - nil. - --spec send_exit(pid_()) -> nil. -send_exit(Pid) -> - erlang:exit(Pid, normal), - nil. - --spec send_abnormal_exit(pid_(), binary()) -> nil. -send_abnormal_exit(Pid, Reason) -> - erlang:exit(Pid, {abnormal, Reason}), - nil. - --spec trap_exits(boolean()) -> nil. -trap_exits(A) -> - gleam_erlang_ffi:trap_exits(A). - --spec register(pid_(), gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. -register(Pid, Name) -> - gleam_erlang_ffi:register_process(Pid, Name). - --spec unregister(gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. -unregister(Name) -> - gleam_erlang_ffi:unregister_process(Name). - --spec named(gleam@erlang@atom:atom_()) -> {ok, pid_()} | {error, nil}. -named(Name) -> - gleam_erlang_ffi:process_named(Name). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src deleted file mode 100644 index bb1b8e635ed..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src +++ /dev/null @@ -1,14 +0,0 @@ -{application, gleam_erlang, [ - {vsn, "0.23.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A Gleam library for working with Erlang"}, - {modules, [gleam@erlang, - gleam@erlang@atom, - gleam@erlang@charlist, - gleam@erlang@file, - gleam@erlang@node, - gleam@erlang@os, - gleam@erlang@process]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl deleted file mode 100644 index 872126fec75..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_erlang_ffi). --export([ - atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, - ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, - append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, - set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, - list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, - insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, - merge_selector/2, flush_messages/0, file_info/1, link_info/1, - priv_directory/1, connect_node/1, register_process/2, unregister_process/1, - process_named/1, identity/1 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - --spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. -atom_from_string(S) -> - try {ok, binary_to_existing_atom(S)} - catch error:badarg -> {error, atom_not_loaded} - end. - -atom_from_dynamic(Data) when is_atom(Data) -> - {ok, Data}; -atom_from_dynamic(Data) -> - {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. - -rescue(F) -> - try {ok, F()} - catch - throw:X -> {error, {thrown, X}}; - error:X -> {error, {errored, X}}; - exit:X -> {error, {exited, X}} - end. - -ensure_all_started(Application) -> - case application:ensure_all_started(Application) of - {ok, _} = Ok -> Ok; - - {error, {ProblemApp, {"no such file or directory", _}}} -> - {error, {unknown_application, ProblemApp}} - end. - -sleep(Microseconds) -> - timer:sleep(Microseconds), - nil. - -sleep_forever() -> - timer:sleep(infinity), - nil. - -file_info_result(Result) -> - case Result of - {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> - {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; - {ok, _} -> - Result; - {error, Reason} when ?is_posix_error(Reason) -> - Result - end. - -file_info(Filename) -> - file_info_result(file:read_file_info(Filename, [{time, posix}])). - -link_info(Filename) -> - file_info_result(file:read_link_info(Filename, [{time, posix}])). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -get_all_env() -> - BinVars = lists:map(fun(VarString) -> - [VarName, VarVal] = string:split(VarString, "="), - {list_to_binary(VarName), list_to_binary(VarVal)} - end, os:getenv()), - maps:from_list(BinVars). - -get_env(Name) -> - case os:getenv(binary_to_list(Name)) of - false -> {error, nil}; - Value -> {ok, list_to_binary(Value)} - end. - -set_env(Name, Value) -> - os:putenv(binary_to_list(Name), binary_to_list(Value)), - nil. - -unset_env(Name) -> - os:unsetenv(binary_to_list(Name)), - nil. - -os_family() -> - case os:type() of - {win32, nt} -> - windows_nt; - {unix, linux} -> - linux; - {unix, darwin} -> - darwin; - {unix, freebsd} -> - free_bsd; - {_, Other} -> - {other, atom_to_binary(Other, utf8)} - end. - -new_selector() -> - {selector, #{}}. - -map_selector({selector, Handlers}, Fn) -> - MappedHandlers = maps:map(fun(_Tag, Handler) -> - fun(Message) -> Fn(Handler(Message)) end - end, Handlers), - {selector, MappedHandlers}. - -merge_selector({selector, HandlersA}, {selector, HandlersB}) -> - {selector, maps:merge(HandlersA, HandlersB)}. - -insert_selector_handler({selector, Handlers}, Tag, Fn) -> - {selector, Handlers#{Tag => Fn}}. - -select(Selector) -> - {ok, Message} = select(Selector, infinity), - Message. - -select({selector, Handlers}, Timeout) -> - AnythingHandler = maps:get(anything, Handlers, undefined), - receive - % Monitored process down messages. - % This is special cased so we can selectively receive based on the - % reference as well as the record tag. - {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> - Fn = maps:get(Ref, Handlers), - {ok, Fn({process_down, Pid, Reason})}; - - Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> - Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), - {ok, Fn(Msg)}; - - Msg when AnythingHandler =/= undefined -> - {ok, AnythingHandler(Msg)} - after Timeout -> - {error, nil} - end. - -demonitor({_, Reference}) -> - erlang:demonitor(Reference, [flush]). - -link(Pid) -> - try - erlang:link(Pid) - catch - error:_ -> false - end. - -trap_exits(ShouldTrap) -> - erlang:process_flag(trap_exit, ShouldTrap), - nil. - -flush_messages() -> - receive _Message -> flush_messages() - after 0 -> nil - end. - -priv_directory(Name) -> - try erlang:binary_to_existing_atom(Name) of - Atom -> - case code:priv_dir(Atom) of - {error, _} -> {error, nil}; - Path -> {ok, unicode:characters_to_binary(Path)} - end - catch - error:badarg -> {error, nil} - end. - -connect_node(Node) -> - case net_kernel:connect_node(Node) of - true -> {ok, Node}; - false -> {error, failed_to_connect}; - ignored -> {error, local_node_is_not_alive} - end. - -register_process(Pid, Name) -> - try - true = erlang:register(Name, Pid), - {ok, nil} - catch - error:badarg -> {error, nil} - end. - -unregister_process(Name) -> - try - true = erlang:unregister(Name), - {ok, nil} - catch - error:badarg -> {error, nil} - end. - -process_named(Name) -> - case erlang:whereis(Name) of - Pid when is_pid(Pid) -> {ok, Pid}; - _ -> {error, nil} - end. - -identity(X) -> - X. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE deleted file mode 100644 index 619ec77e6e1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md deleted file mode 100644 index 3c313a1c8c9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Gleam OTP - -<a href="https://github.com/gleam-lang/otp/releases"><img src="https://img.shields.io/github/release/gleam-lang/otp" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/otp/workflows/test/badge.svg?branch=main) - -A Gleam library for building fault tolerant multi-core programs using the -actor model. It is compatible with Erlang's OTP framework. - -This library is experimental and will likely have many breaking changes in the -future! - -Gleam’s actor system is built with a few primary goals: - -- Full type safety of actors and messages. -- Be compatible with Erlang’s OTP actor framework. -- Provide fault tolerance and self-healing through supervisors. -- Have equivalent performance to Erlang’s OTP. - -This library documents its abstractions and functionality, but you may also wish -to read the documentation or other material on Erlang’s OTP framework to get a -fuller understanding of OTP, the problems it solves, and and the motivations for -its design. - -## Usage - -Add this library to your Gleam project. - -```shell -gleam add gleam_otp -``` - -## Actor hierarchy - -This library provides several different types of actor that can be used in -Gleam programs. - -### Process - -The process is the lowest level building block of OTP, all other actors are -built on top of processes either directly or indirectly. Typically this -abstraction would be not be used very often in Gleam applications, favour -other actor types that provide more functionality. - -Gleam's process module is defined in the `gleam_erlang` library. - -[[Documentation]](https://hexdocs.pm/gleam_erlang/gleam/erlang/process.html) - -### Actor - -The `actor` is the most commonly used process type in Gleam and serves as a good -building block for other abstractions. Like Erlang's `gen_server` it handles -OTP's system messages automatically to enable OTP's debugging and tracing -functionality. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/actor.html) - -### Task - -A task is a kind of process that performs a single task and then shuts down. -Commonly tasks are used to convert sequential code into concurrent code by -performing computation in another process. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/task.html) - -### Supervisor - -Supervisors is a process that starts and then supervises a group of processes, -restarting them if they crash. Supervisors can start other supervisors, -resulting in a hierarchical process structure called a supervision tree, -providing fault tolerance to a Gleam application. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/supervisor.html) - -## Limitations and known issues - -This library is experimental there are some limitations that not yet been resolved. - -- There is no support for named processes. They are untyped global mutable - variables which may be uninitialized, more research is needed to find a - suitable type safe alternative. -- There are relatively few actor abstractions provided by this library. More - will be added in the future. -- Actors do not yet support all OTP system messages. Unsupported messages are - dropped. -- Supervisors do not yet support different shutdown periods per child. In - practice this means that children that are supervisors do not get an - unlimited amount of time to shut down, as is expected in Erlang or Elixir. -- This library has not seen much testing compared to the Erlang OTP - libraries, both in terms of unit tests and real world testing in - applications. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml deleted file mode 100644 index 26e451baecf..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "gleam_otp" -version = "0.8.0" -licences = ["Apache-2.0"] -description = "Fault tolerant multicore Gleam programs with OTP" - -gleam = ">= 0.32.0" - -repository = { type = "github", user = "gleam-lang", repo = "otp" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_erlang = "~> 0.22" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl deleted file mode 100644 index 85677d1b257..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(continue, { - state :: any(), - selector :: gleam@option:option(gleam@erlang@process:selector(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl deleted file mode 100644 index 75faa95149f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ready, {state :: any(), selector :: gleam@erlang@process:selector(any())}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl deleted file mode 100644 index 52874392c18..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(spec, { - init :: fun(() -> gleam@otp@actor:init_result(any(), any())), - init_timeout :: integer(), - loop :: fun((any(), any()) -> gleam@otp@actor:next(any(), any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl deleted file mode 100644 index 3ed0b0122d4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(intensity_tracker, { - limit :: integer(), - period :: integer(), - events :: list(integer()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl deleted file mode 100644 index 7afd07f0319..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(child_spec, { - start :: fun((any()) -> {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()}), - returning :: fun((any(), gleam@erlang@process:subject(any())) -> any()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl deleted file mode 100644 index b10bd9fa3f7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(spec, { - argument :: any(), - max_frequency :: integer(), - frequency_period :: integer(), - init :: fun((gleam@otp@supervisor:children(any())) -> gleam@otp@supervisor:children(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl deleted file mode 100644 index 99ab4cb7299..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(status_info, { - module :: gleam@erlang@atom:atom_(), - parent :: gleam@erlang@process:pid_(), - mode :: gleam@otp@system:mode(), - debug_state :: gleam@otp@system:debug_state(), - state :: gleam@dynamic:dynamic_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl deleted file mode 100644 index 7c83874c276..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl +++ /dev/null @@ -1 +0,0 @@ --record(exit, {reason :: gleam@dynamic:dynamic_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl deleted file mode 100644 index 959bea8e9b9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(task, { - owner :: gleam@erlang@process:pid_(), - pid :: gleam@erlang@process:pid_(), - monitor :: gleam@erlang@process:process_monitor(), - selector :: gleam@erlang@process:selector(gleam@otp@task:message(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam deleted file mode 100644 index 9f6a6c41b06..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam +++ /dev/null @@ -1,504 +0,0 @@ -//// This module provides the _Actor_ abstraction, one of the most common -//// building blocks of Gleam OTP programs. -//// -//// An Actor is a process like any other BEAM process and can be be used to hold -//// state, execute code, and communicate with other processes by sending and -//// receiving messages. The advantage of using the actor abstraction over a bare -//// process is that it provides a single interface for commonly needed -//// functionality, including support for the [tracing and debugging -//// features in OTP](erlang-sys). -//// -//// Gleam's Actor is similar to Erlang's `gen_server` and Elixir's `GenServer` -//// but differs in that it offers a fully typed interface. This different API is -//// why Gleam uses the name Actor rather than some variation of generic-server. -//// -//// [erlang-sys]: https://www.erlang.org/doc/man/sys.html -//// -//// ## Example -//// -//// An Actor can be used to create a client-server interaction between an Actor -//// (the server) and other processes (the clients). In this example we have an -//// Actor that works as a stack, allowing clients to push and pop elements. -//// -//// ```gleam -//// pub fn main() { -//// // Start the actor with initial state of an empty list, and the -//// // `handle_message` callback function (defined below). -//// // We assert that it starts successfully. -//// // -//// // In real-world Gleam OTP programs we would likely write a wrapper functions -//// // called `start`, `push` `pop`, `shutdown` to start and interact with the -//// // Actor. We are not doing that here for the sake of showing how the Actor -//// // API works. -//// let assert Ok(actor) = actor.start([], handle_message) -//// -//// // We can send a message to the actor to push elements onto the stack. -//// process.send(actor, Push("Joe")) -//// process.send(actor, Push("Mike")) -//// process.send(actor, Push("Robert")) -//// -//// // The `Push` message expects no response, these messages are sent purely for -//// // the side effect of mutating the state held by the actor. -//// // -//// // We can also send the `Pop` message to take a value off of the actor's -//// // stack. This message expects a response, so we use `process.call` to send a -//// // message and wait until a reply is received. -//// // -//// // In this instance we are giving the actor 10 milliseconds to reply, if the -//// // `call` function doesn't get a reply within this time it will panic and -//// // crash the client process. -//// let assert Ok("Robert") = process.call(actor, Pop, 10) -//// let assert Ok("Mike") = process.call(actor, Pop, 10) -//// let assert Ok("Joe") = process.call(actor, Pop, 10) -//// -//// // The stack is now empty, so if we pop again the actor replies with an error. -//// let assert Error(Nil) = process.call(actor, Pop, 10) -//// -//// // Lastly, we can send a message to the actor asking it to shut down. -//// process.send(actor, Shutdown) -//// } -//// ``` -//// -//// Here is the code that is used to implement this actor: -//// -//// ```gleam -//// // First step of implementing the stack Actor is to define the message type that -//// // it can receive. -//// // -//// // The type of the elements in the stack is no fixed so a type parameter is used -//// // for it instead of a concrete type such as `String` or `Int`. -//// pub type Message(element) { -//// // The `Shutdown` message is used to tell the actor to stop. -//// // It is the simplest message type, it contains no data. -//// Shutdown -//// -//// // The `Push` message is used to add a new element to the stack. -//// // It contains the item to add, the type of which is the `element` -//// // parameterised type. -//// Push(push: element) -//// -//// // The `Pop` message is used to remove an element from the stack. -//// // It contains a `Subject`, which is used to send the response back to the -//// // message sender. In this case the reply is of type `Result(element, Nil)`. -//// Pop(reply_with: Subject(Result(element, Nil))) -//// } -//// -//// // The last part is to implement the `handle_message` callback function. -//// // -//// // This function is called by the Actor each for each message it receives. -//// // Actor is single threaded only does one thing at a time, so it handles -//// // messages sequentially and one at a time, in the order they are received. -//// // -//// // The function takes the message and the current state, and returns a data -//// // structure that indicates what to do next, along with the new state. -//// fn handle_message( -//// message: Message(e), -//// stack: List(e), -//// ) -> actor.Next(Message(e), List(e)) { -//// case message { -//// // For the `Shutdown` message we return the `actor.Stop` value, which causes -//// // the actor to discard any remaining messages and stop. -//// Shutdown -> actor.Stop(process.Normal) -//// -//// // For the `Push` message we add the new element to the stack and return -//// // `actor.continue` with this new stack, causing the actor to process any -//// // queued messages or wait for more. -//// Push(value) -> { -//// let new_state = [value, ..stack] -//// actor.continue(new_state) -//// } -//// -//// // For the `Pop` message we attempt to remove an element from the stack, -//// // sending it or an error back to the caller, before continuing. -//// Pop(client) -> -//// case stack { -//// [] -> { -//// // When the stack is empty we can't pop an element, so we send an -//// // error back. -//// process.send(client, Error(Nil)) -//// actor.continue([]) -//// } -//// -//// [first, ..rest] -> { -//// // Otherwise we send the first element back and use the remaining -//// // elements as the new state. -//// process.send(client, Ok(first)) -//// actor.continue(rest) -//// } -//// } -//// } -//// } -//// ``` - -import gleam/erlang/process.{ - type ExitReason, type Pid, type Selector, type Subject, Abnormal, -} -import gleam/erlang/charlist.{type Charlist} -import gleam/otp/system.{ - type DebugState, type Mode, type StatusInfo, type SystemMessage, GetState, - GetStatus, Resume, Running, StatusInfo, Suspend, Suspended, -} -import gleam/string -import gleam/dynamic.{type Dynamic} -import gleam/erlang/atom -import gleam/option.{type Option, None, Some} - -type Message(message) { - /// A regular message excepted by the process - Message(message) - - /// An OTP system message, for debugging or maintenance - System(SystemMessage) - - /// An unexpected message - Unexpected(Dynamic) -} - -/// The type used to indicate what to do after handling a message. -/// -pub type Next(message, state) { - /// Continue handling messages. - /// - Continue(state: state, selector: Option(Selector(message))) - - /// Stop handling messages and shut down. - /// - Stop(ExitReason) -} - -pub fn continue(state: state) -> Next(message, state) { - Continue(state, None) -} - -pub fn with_selector( - value: Next(message, state), - selector: Selector(message), -) -> Next(message, state) { - case value { - Continue(state, _) -> Continue(state, Some(selector)) - _ -> value - } -} - -/// The type used to indicate whether an actor has started successfully or not. -/// -pub type InitResult(state, message) { - /// The actor has successfully initialised. The actor can start handling - /// messages and actor's channel sender can be returned to the parent - /// process. - /// - Ready(state: state, selector: Selector(message)) - - /// The actor has failed to initialise. The actor shuts down and an error is - /// returned to the parent process. - /// - Failed(String) -} - -type Self(state, msg) { - Self( - mode: Mode, - parent: Pid, - state: state, - subject: Subject(msg), - selector: Selector(Message(msg)), - debug_state: DebugState, - message_handler: fn(msg, state) -> Next(msg, state), - ) -} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an actor. -/// -/// If you do not need to configure the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub type Spec(state, msg) { - Spec( - /// The initialisation functionality for the actor. This function is called - /// just after the actor starts but before the channel sender is returned - /// to the parent. - /// - /// This function is used to ensure that any required data or state is - /// correct. If this function returns an error it means that the actor has - /// failed to start and an error is returned to the parent. - /// - init: fn() -> InitResult(state, msg), - /// How many milliseconds the `init` function has to return before it is - /// considered to have taken too long and failed. - /// - init_timeout: Int, - /// This function is called to handle each message that the actor receives. - /// - loop: fn(msg, state) -> Next(msg, state), - ) -} - -// TODO: Check needed functionality here to be OTP compatible -fn exit_process(reason: ExitReason) -> ExitReason { - // TODO - reason -} - -fn receive_message(self: Self(state, msg)) -> Message(msg) { - let selector = case self.mode { - // When suspended we only respond to system messages - Suspended -> - process.new_selector() - |> selecting_system_messages - - // When running we respond to all messages - Running -> - // We add the handler for unexpected messages first so that the user - // supplied selector can override it if desired - process.new_selector() - |> process.selecting_anything(Unexpected) - |> process.merge_selector(self.selector) - |> selecting_system_messages - } - - process.select_forever(selector) -} - -fn selecting_system_messages( - selector: Selector(Message(msg)), -) -> Selector(Message(msg)) { - selector - |> process.selecting_record3( - atom.create_from_string("system"), - convert_system_message, - ) -} - -@external(erlang, "gleam_otp_external", "convert_system_message") -fn convert_system_message(a: Dynamic, b: Dynamic) -> Message(msg) - -fn process_status_info(self: Self(state, msg)) -> StatusInfo { - StatusInfo( - module: atom.create_from_string("gleam@otp@actor"), - parent: self.parent, - mode: self.mode, - debug_state: self.debug_state, - state: dynamic.from(self.state), - ) -} - -fn loop(self: Self(state, msg)) -> ExitReason { - case receive_message(self) { - System(system) -> - case system { - GetState(callback) -> { - callback(dynamic.from(self.state)) - loop(self) - } - Resume(callback) -> { - callback() - loop(Self(..self, mode: Running)) - } - Suspend(callback) -> { - callback() - loop(Self(..self, mode: Suspended)) - } - GetStatus(callback) -> { - callback(process_status_info(self)) - loop(self) - } - } - - Unexpected(message) -> { - log_warning( - charlist.from_string("Actor discarding unexpected message: ~s"), - [charlist.from_string(string.inspect(message))], - ) - loop(self) - } - - Message(msg) -> - case self.message_handler(msg, self.state) { - Stop(reason) -> exit_process(reason) - Continue(state: state, selector: new_selector) -> { - let selector = - new_selector - |> option.map(init_selector(self.subject, _)) - |> option.unwrap(self.selector) - loop(Self(..self, state: state, selector: selector)) - } - } - } -} - -// TODO: replace this when we have Gleam bindings to the logger -@external(erlang, "logger", "warning") -fn log_warning(a: Charlist, b: List(Charlist)) -> Nil - -fn initialise_actor( - spec: Spec(state, msg), - ack: Subject(Result(Subject(msg), ExitReason)), -) { - let subject = process.new_subject() - case spec.init() { - Ready(state, selector) -> { - let selector = init_selector(subject, selector) - // Signal to parent that the process has initialised successfully - process.send(ack, Ok(subject)) - // Start message receive loop - let self = - Self( - state: state, - parent: process.subject_owner(ack), - subject: subject, - selector: selector, - message_handler: spec.loop, - debug_state: system.debug_state([]), - mode: Running, - ) - loop(self) - } - - Failed(reason) -> { - process.send(ack, Error(Abnormal(reason))) - exit_process(Abnormal(reason)) - } - } -} - -fn init_selector(subject, selector) { - process.new_selector() - |> process.selecting(subject, Message) - |> process.merge_selector(process.map_selector(selector, Message)) -} - -pub type StartError { - InitTimeout - InitFailed(ExitReason) - InitCrashed(Dynamic) -} - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - Result(Subject(msg), StartError) - -/// An Erlang supervisor compatible process start result. -/// -/// If you wish to convert this into a `StartResult` compatible with Gleam -/// supervisors see the `from_erlang_start_result` and `wrap_erlang_starter` -/// functions. -/// -pub type ErlangStartResult = - Result(Pid, Dynamic) - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - case res { - Ok(x) -> Ok(process.subject_owner(x)) - Error(x) -> Error(dynamic.from(x)) - } -} - -type StartInitMessage(msg) { - Ack(Result(Subject(msg), ExitReason)) - Mon(process.ProcessDown) -} - -// TODO: test init_timeout. Currently if we test it eunit prints an error from -// the process death. How do we avoid this? -// -/// Start an actor from a given specification. If the actor's `init` function -/// returns an error or does not return within `init_timeout` then an error is -/// returned. -/// -/// If you do not need to specify the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub fn start_spec(spec: Spec(state, msg)) -> Result(Subject(msg), StartError) { - let ack_subject = process.new_subject() - - let child = - process.start( - linked: True, - running: fn() { initialise_actor(spec, ack_subject) }, - ) - - let monitor = process.monitor_process(child) - let selector = - process.new_selector() - |> process.selecting(ack_subject, Ack) - |> process.selecting_process_down(monitor, Mon) - - let result = case process.select(selector, spec.init_timeout) { - // Child started OK - Ok(Ack(Ok(channel))) -> Ok(channel) - - // Child initialiser returned an error - Ok(Ack(Error(reason))) -> Error(InitFailed(reason)) - - // Child went down while initialising - Ok(Mon(down)) -> Error(InitCrashed(down.reason)) - - // Child did not finish initialising in time - Error(Nil) -> { - process.kill(child) - Error(InitTimeout) - } - } - - // Remove the monitor used for the starting of the actor as to avoid an extra - // message arriving at the parent if the child dies later. - process.demonitor_process(monitor) - - result -} - -/// Start an actor with a given initial state and message handling loop -/// function. -/// -/// This function returns a `Result` but it will always be `Ok` so it is safe -/// to use with `assert` if you are not starting this actor as part of a -/// supervision tree. -/// -/// If you wish to configure the initialisation behaviour of a new actor see -/// the `Spec` record and the `start_spec` function. -/// -pub fn start( - state: state, - loop: fn(msg, state) -> Next(msg, state), -) -> Result(Subject(msg), StartError) { - start_spec(Spec( - init: fn() { Ready(state, process.new_selector()) }, - loop: loop, - init_timeout: 5000, - )) -} - -/// Send a message over a given channel. -/// -/// This is a re-export of `process.send`, for the sake of convenience. -/// -pub fn send(subject: Subject(msg), msg: msg) -> Nil { - process.send(subject, msg) -} - -// TODO: test -/// Send a synchronous message and wait for a response from the receiving -/// process. -/// -/// If a reply is not received within the given timeout then the sender process -/// crashes. If you wish receive a `Result` rather than crashing see the -/// `process.try_call` function. -/// -/// This is a re-export of `process.call`, for the sake of convenience. -/// -pub fn call( - selector: Subject(message), - make_message: fn(Subject(reply)) -> message, - timeout: Int, -) -> reply { - process.call(selector, make_message, timeout) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam deleted file mode 100644 index 2044be09787..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam +++ /dev/null @@ -1,46 +0,0 @@ -//// The intensity tracker is used to monitor how frequently an event happens, -//// erroring if it happens too many times within a period of time. - -import gleam/list - -// TODO: test -pub opaque type IntensityTracker { - IntensityTracker(limit: Int, period: Int, events: List(Int)) -} - -pub type TooIntense { - TooIntense -} - -pub fn new(limit limit: Int, period period: Int) -> IntensityTracker { - IntensityTracker(limit: limit, period: period, events: []) -} - -@external(erlang, "erlang", "monotonic_time") -fn monotonic_time(a: Int) -> Int - -fn now_seconds() -> Int { - monotonic_time(1) -} - -pub fn trim_window(events: List(Int), now: Int, period: Int) -> List(Int) { - case events { - [] -> [] - [event, ..events] -> - case now >= event + period { - True -> [event, ..trim_window(events, now, period)] - False -> [] - } - } -} - -pub fn add_event( - tracker: IntensityTracker, -) -> Result(IntensityTracker, TooIntense) { - let now = now_seconds() - let events = trim_window([now, ..tracker.events], now, tracker.period) - case list.length(events) >= tracker.limit { - True -> Error(TooIntense) - False -> Ok(IntensityTracker(..tracker, events: events)) - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam deleted file mode 100644 index 4e1b4d81285..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam +++ /dev/null @@ -1,9 +0,0 @@ -/// Ports are how code running on the Erlang virtual machine interacts with -/// the outside world. Bytes of data can be sent to and read from ports, -/// providing a form of message passing to an external program or resource. -/// -/// For more information on ports see the [Erlang ports documentation][1]. -/// -/// [1]: https://erlang.org/doc/reference_manual/ports.html -/// -pub type Port diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam deleted file mode 100644 index b99ad8efb82..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam +++ /dev/null @@ -1,410 +0,0 @@ -// TODO: specify amount of time permitted for shut-down -import gleam/result -import gleam/string -import gleam/option.{type Option, None, Some} -import gleam/erlang/process.{type Pid, type Subject} -import gleam/otp/actor.{type StartError} -import gleam/otp/intensity_tracker.{type IntensityTracker} -import gleam/erlang/node.{type Node} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an supervisor. -/// -/// If you do not need to configure the behaviour of your supervisor consider -/// using the `start` function. -/// -pub type Spec(argument, return) { - Spec( - argument: argument, - max_frequency: Int, - frequency_period: Int, - init: fn(Children(argument)) -> Children(return), - ) -} - -/// This type represents the starting children of a supervisor within the -/// `init` function. -/// -pub opaque type Children(argument) { - Ready(Starter(argument)) - Failed(ChildStartError) -} - -/// This type contains all the information required to start a new child and -/// add it to the `Children`. -/// -/// This is typically created with the `worker` function. -/// -pub opaque type ChildSpec(msg, argument, returning) { - ChildSpec( - // TODO: merge this into one field - start: fn(argument) -> Result(Subject(msg), StartError), - returning: fn(argument, Subject(msg)) -> returning, - ) -} - -type ChildStartError { - ChildStartError(previous_pid: Option(Pid), error: StartError) -} - -pub opaque type Message { - Exit(process.ExitMessage) - RetryRestart(Pid) -} - -type Instruction { - StartAll - StartFrom(Pid) -} - -type State(a) { - State( - restarts: IntensityTracker, - starter: Starter(a), - retry_restarts: Subject(Pid), - ) -} - -type Starter(argument) { - Starter( - argument: argument, - exec: Option( - fn(Instruction) -> - Result(#(Starter(argument), Instruction), ChildStartError), - ), - ) -} - -type Child(argument) { - Child(pid: Pid, argument: argument) -} - -fn start_child( - child_spec: ChildSpec(msg, argument_in, argument_out), - argument: argument_in, -) -> Result(Child(argument_out), ChildStartError) { - use subject <- result.then( - child_spec.start(argument) - |> result.map_error(ChildStartError(None, _)), - ) - - Ok(Child( - pid: process.subject_owner(subject), - // Merge the new child's pid into the argument to produce the new argument - // used to start any remaining children. - argument: child_spec.returning(argument, subject), - )) -} - -// TODO: more sophsiticated stopping of processes. i.e. give supervisors -// more time to shut down. -fn shutdown_child(pid: Pid, _spec: ChildSpec(msg, arg_1, arg_2)) -> Nil { - process.send_exit(pid) -} - -fn perform_instruction_for_child( - argument: argument_in, - instruction: Instruction, - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Result(#(Child(argument_out), Instruction), ChildStartError) { - let current = child.pid - case instruction { - // This child is older than the StartFrom target, we don't need to - // restart it - StartFrom(target) if target != current -> Ok(#(child, instruction)) - - // This pid either is the cause of the problem, or we have the StartAll - // instruction. Either way it and its younger siblings need to be restarted. - _ -> { - shutdown_child(current, child_spec) - use child <- result.then(start_child(child_spec, argument)) - Ok(#(child, StartAll)) - } - } -} - -fn add_child_to_starter( - starter: Starter(argument_in), - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Starter(argument_out) { - let starter = fn(instruction) { - // Restart the older children. We use `try` to return early if the older - // children failed to start - use #(starter, instruction) <- result.then(case starter.exec { - Some(start) -> start(instruction) - None -> Ok(#(starter, instruction)) - }) - - // Perform the instruction, restarting the child as required - use #(child, instruction) <- result.then(perform_instruction_for_child( - starter.argument, - instruction, - child_spec, - child, - )) - - // Create a new starter for the next time the supervisor needs to restart - let starter = add_child_to_starter(starter, child_spec, child) - - Ok(#(starter, instruction)) - } - - Starter(exec: Some(starter), argument: child.argument) -} - -fn start_and_add_child( - state: Starter(argument_0), - child_spec: ChildSpec(msg, argument_0, argument_1), -) -> Children(argument_1) { - case start_child(child_spec, state.argument) { - Ok(child) -> Ready(add_child_to_starter(state, child_spec, child)) - Error(reason) -> Failed(reason) - } -} - -/// Add a child to the collection of children of the supervisor -/// -/// This function starts the child from the child spec. -/// -pub fn add( - children: Children(argument), - child_spec: ChildSpec(msg, argument, new_argument), -) -> Children(new_argument) { - case children { - // If one of the previous children has failed then we cannot continue - Failed(fail) -> Failed(fail) - - // If everything is OK so far then we can add the child - Ready(state) -> start_and_add_child(state, child_spec) - } -} - -// TODO: test -// TODO: unlimitd shut down duration -/// Prepare a new supervisor type child. -/// -/// If you wish to prepare a new non-supervisor type child see the `worker` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -/// Note: Gleam supervisors do not yet support different shutdown periods per -/// child so this function is currently identical in behaviour to `worker`. It is -/// recommended to use this function for supervisor children nevertheless so the -/// correct shut down behaviour is used in later releases of this library. -/// -pub fn supervisor( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -/// Prepare a new worker type child. -/// -/// If you wish to prepare a new supervisor type child see the `supervisor` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -pub fn worker( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -// TODO: test -/// As each child is added to a supervisors children a new argument is prepared -/// with which to start the next child. By default argument is the same as the -/// previous argument, but this function can be used to change it to something -/// else by passing a function that takes the previous argument and the sender -/// of the previous child. -/// -pub fn returning( - child: ChildSpec(msg, argument_a, argument_b), - updater: fn(argument_a, Subject(msg)) -> argument_c, -) -> ChildSpec(msg, argument_a, argument_c) { - ChildSpec(start: child.start, returning: updater) -} - -fn init( - spec: Spec(argument, return), -) -> actor.InitResult(State(return), Message) { - // Create a subject so that we can asynchronously retry restarting when we - // fail to bring an exited child - let retry = process.new_subject() - - // Trap exits so that we get a message when a child crashes - process.trap_exits(True) - - // Combine selectors - let selector = - process.new_selector() - |> process.selecting(retry, RetryRestart) - |> process.selecting_trapped_exits(Exit) - - // Start any children - let result = - Starter(argument: spec.argument, exec: None) - |> Ready - |> spec.init - - // Pass back up the result - case result { - Ready(starter) -> { - let restarts = - intensity_tracker.new( - limit: spec.max_frequency, - period: spec.frequency_period, - ) - let state = - State(starter: starter, restarts: restarts, retry_restarts: retry) - actor.Ready(state, selector) - } - - Failed(error) -> - actor.Failed(case error.error { - actor.InitTimeout -> "Child initialisation timed out" - actor.InitCrashed(reason) -> - string.append( - "Child crashed during initialisation: ", - string.inspect(reason), - ) - actor.InitFailed(reason) -> - string.append( - "Child failed to start during initialisation: ", - string.inspect(reason), - ) - }) - } -} - -type HandleExitError { - RestartFailed(pid: Pid, restarts: IntensityTracker) - TooManyRestarts -} - -fn handle_exit(pid: Pid, state: State(a)) -> actor.Next(Message, State(a)) { - let outcome = { - // If we are handling an exit then we must have some children - let assert Some(start) = state.starter.exec - - // Check to see if there has been too many restarts in this period - use restarts <- result.then( - state.restarts - |> intensity_tracker.add_event - |> result.map_error(fn(_) { TooManyRestarts }), - ) - - // Restart the exited child and any following children - use #(starter, _) <- result.then( - start(StartFrom(pid)) - |> result.map_error(fn(e: ChildStartError) { - RestartFailed(option.unwrap(e.previous_pid, pid), restarts) - }), - ) - - Ok(State(..state, starter: starter, restarts: restarts)) - } - - case outcome { - Ok(state) -> actor.continue(state) - Error(RestartFailed(failed_child, restarts)) -> { - // Asynchronously enqueue the restarting of this child again as we were - // unable to restart them this time. We do this asynchronously as we want - // to have a chance to handle any system messages that have come in. - process.send(state.retry_restarts, failed_child) - let state = State(..state, restarts: restarts) - actor.continue(state) - } - Error(TooManyRestarts) -> - actor.Stop(process.Abnormal( - "Child processes restarted too many times within allowed period", - )) - } -} - -fn loop( - message: Message, - state: State(argument), -) -> actor.Next(Message, State(argument)) { - case message { - Exit(exit_message) -> handle_exit(exit_message.pid, state) - RetryRestart(pid) -> handle_exit(pid, state) - } -} - -/// Start a supervisor from a given specification. -/// -pub fn start_spec(spec: Spec(a, b)) -> Result(Subject(Message), StartError) { - actor.start_spec(actor.Spec( - init: fn() { init(spec) }, - loop: loop, - init_timeout: 60_000, - )) -} - -/// Start a supervisor from a given `init` function. -/// -/// The init argument passed to children will be `Nil` and the maximum restart -/// intensity will be 1 restart per 5 seconds (the same as the default for -/// [Erlang supervisors][erl-sup]). If you wish to specify these values, see -/// the `start_spec` function and the `Spec` type. -/// -/// [erl-sup]: https://www.erlang.org/doc/design_principles/sup_princ.html#maximum-restart-intensity -/// -pub fn start( - init: fn(Children(Nil)) -> Children(a), -) -> Result(Subject(Message), StartError) { - start_spec(Spec( - init: init, - argument: Nil, - max_frequency: 1, - frequency_period: 5, - )) -} - -/// A type used to describe the situation in which an Erlang based application -/// is starting. -/// -/// For more information see the [Erlang distributed application -/// documentation][1] and the Learn Your Some Erlang chapter on [distributed -/// applications][2]. -/// -/// [1]: https://erlang.org/doc/design_principles/distributed_applications.html -/// [2]: https://learnyousomeerlang.com/distributed-otp-applications -/// -pub type ApplicationStartMode { - Normal - Takeover(Node) - Failover(Node) -} - -pub type ApplicationStop - -@external(erlang, "gleam_otp_external", "application_stopped") -pub fn application_stopped() -> ApplicationStop - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - actor.StartResult(msg) - -/// An Erlang supervisor compatible process start result. -/// -pub type ErlangStartResult = - actor.ErlangStartResult - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - actor.to_erlang_start_result(res) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam deleted file mode 100644 index c05646baa26..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam +++ /dev/null @@ -1,89 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/erlang/atom.{type Atom} -import gleam/erlang/process.{type Pid} - -pub type Mode { - Running - Suspended -} - -pub type DebugOption { - NoDebug -} - -pub type DebugState - -@external(erlang, "sys", "debug_options") -pub fn debug_state(a: List(DebugOption)) -> DebugState - -pub type StatusInfo { - StatusInfo( - module: Atom, - parent: Pid, - mode: Mode, - debug_state: DebugState, - state: Dynamic, - ) -} - -// TODO: document -// TODO: implement remaining messages -pub type SystemMessage { - // {replace_state, StateFn} - // {change_code, Mod, Vsn, Extra} - // {terminate, Reason} - // {debug, {log, Flag}} - // {debug, {trace, Flag}} - // {debug, {log_to_file, FileName}} - // {debug, {statistics, Flag}} - // {debug, no_debug} - // {debug, {install, {Func, FuncState}}} - // {debug, {install, {FuncId, Func, FuncState}}} - // {debug, {remove, FuncOrId}} - Resume(fn() -> Nil) - Suspend(fn() -> Nil) - GetState(fn(Dynamic) -> Nil) - GetStatus(fn(StatusInfo) -> Nil) -} - -type DoNotLeak - -/// Get the state of a given OTP compatible process. This function is only -/// intended for debugging. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#get_state-1 -/// -@external(erlang, "sys", "get_state") -pub fn get_state(from from: Pid) -> Dynamic - -@external(erlang, "sys", "suspend") -fn erl_suspend(a: Pid) -> DoNotLeak - -/// Request an OTP compatible process to suspend, causing it to only handle -/// system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#suspend-1 -/// -pub fn suspend(pid: Pid) -> Nil { - erl_suspend(pid) - Nil -} - -@external(erlang, "sys", "resume") -fn erl_resume(from from: Pid) -> DoNotLeak - -/// Request a suspended OTP compatible process to result, causing it to handle -/// all messages rather than only system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#resume-1 -/// -pub fn resume(pid: Pid) -> Nil { - erl_resume(pid) - Nil -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam deleted file mode 100644 index b2b2c5c968e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam +++ /dev/null @@ -1,151 +0,0 @@ -//// A task is a kind of process that performs a single task and then shuts -//// down. Commonly tasks are used to convert sequential code into concurrent -//// code by performing computation in another process. -//// -//// let task = task.async(fn() { do_some_work() }) -//// let value = do_some_other_work() -//// value + task.await(task, 100) -//// -//// Tasks spawned with async can be awaited on by their caller process (and -//// only their caller) as shown in the example above. They are implemented by -//// spawning a process that sends a message to the caller once the given -//// computation is performed. -//// -//// There are two important things to consider when using `async`: -//// -//// 1. If you are using async tasks, you must await a reply as they are always -//// sent. -//// -//// 2. async tasks link the caller and the spawned process. This means that, -//// if the caller crashes, the task will crash too and vice-versa. This is -//// on purpose: if the process meant to receive the result no longer -//// exists, there is no purpose in completing the computation. -//// -//// This module is inspired by Elixir's [Task module][1]. -//// -//// [1]: https://hexdocs.pm/elixir/master/Task.html -//// - -// TODO: await_many -import gleam/erlang/process.{type Pid, type ProcessMonitor, type Selector} -import gleam/dynamic.{type Dynamic} - -pub opaque type Task(value) { - Task( - owner: Pid, - pid: Pid, - monitor: ProcessMonitor, - selector: Selector(Message(value)), - ) -} - -// TODO: test -/// Spawn a task process that calls a given function in order to perform some -/// work. The result of this function is send back to the parent and can be -/// received using the `await` function. -/// -/// See the top level module documentation for more information on async/await. -/// -pub fn async(work: fn() -> value) -> Task(value) { - let owner = process.self() - let subject = process.new_subject() - let pid = - process.start(linked: True, running: fn() { process.send(subject, work()) }) - let monitor = process.monitor_process(pid) - let selector = - process.new_selector() - |> process.selecting_process_down(monitor, FromMonitor) - |> process.selecting(subject, FromSubject) - Task(owner: owner, pid: pid, monitor: monitor, selector: selector) -} - -pub type AwaitError { - Timeout - Exit(reason: Dynamic) -} - -// We can only wait on a task if we are the owner of it so crash if we are -// waiting on a task we don't own. -fn assert_owner(task: Task(a)) -> Nil { - let self = process.self() - case task.owner == self { - True -> Nil - False -> - process.send_abnormal_exit( - self, - "awaited on a task that does not belong to this process", - ) - } -} - -type Message(value) { - FromMonitor(process.ProcessDown) - FromSubject(value) -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then an error is returned. -/// -pub fn try_await(task: Task(value), timeout: Int) -> Result(value, AwaitError) { - assert_owner(task) - case process.select(task.selector, timeout) { - // The task process has sent back a value - Ok(FromSubject(x)) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) -> - Error(Exit(reason)) - - // The task process is alive but has not sent a value yet - Error(Nil) -> Error(Timeout) - } -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then this function crashes. -/// -pub fn await(task: Task(value), timeout: Int) -> value { - let assert Ok(value) = try_await(task, timeout) - value -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! This function does not return until there is a value to -/// receive. If a value is not received then the process will be stuck waiting -/// forever. -/// -pub fn try_await_forever(task: Task(value)) -> Result(value, AwaitError) { - assert_owner(task) - case process.select_forever(task.selector) { - // The task process has sent back a value - FromSubject(x) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - FromMonitor(process.ProcessDown(reason: reason, ..)) -> Error(Exit(reason)) - } -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! Like `try_await_forever`, this function does not return until there is a value to -/// receive. -/// -/// If the task process crashes then this function crashes. -/// -pub fn await_forever(task: Task(value)) -> value { - let assert Ok(value) = try_await_forever(task) - value -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl deleted file mode 100644 index 0606147ca13..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl +++ /dev/null @@ -1,273 +0,0 @@ --module(gleam@otp@actor). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([continue/1, with_selector/2, to_erlang_start_result/1, start_spec/1, start/2, send/2, call/3]). --export_type([message/1, next/2, init_result/2, self/2, spec/2, start_error/0, start_init_message/1]). - --type message(GAS) :: {message, GAS} | - {system, gleam@otp@system:system_message()} | - {unexpected, gleam@dynamic:dynamic_()}. - --type next(GAT, GAU) :: {continue, - GAU, - gleam@option:option(gleam@erlang@process:selector(GAT))} | - {stop, gleam@erlang@process:exit_reason()}. - --type init_result(GAV, GAW) :: {ready, GAV, gleam@erlang@process:selector(GAW)} | - {failed, binary()}. - --type self(GAX, GAY) :: {self, - gleam@otp@system:mode(), - gleam@erlang@process:pid_(), - GAX, - gleam@erlang@process:subject(GAY), - gleam@erlang@process:selector(message(GAY)), - gleam@otp@system:debug_state(), - fun((GAY, GAX) -> next(GAY, GAX))}. - --type spec(GAZ, GBA) :: {spec, - fun(() -> init_result(GAZ, GBA)), - integer(), - fun((GBA, GAZ) -> next(GBA, GAZ))}. - --type start_error() :: init_timeout | - {init_failed, gleam@erlang@process:exit_reason()} | - {init_crashed, gleam@dynamic:dynamic_()}. - --type start_init_message(GBB) :: {ack, - {ok, gleam@erlang@process:subject(GBB)} | - {error, gleam@erlang@process:exit_reason()}} | - {mon, gleam@erlang@process:process_down()}. - --spec continue(GBI) -> next(any(), GBI). -continue(State) -> - {continue, State, none}. - --spec with_selector(next(GBM, GBN), gleam@erlang@process:selector(GBM)) -> next(GBM, GBN). -with_selector(Value, Selector) -> - case Value of - {continue, State, _} -> - {continue, State, {some, Selector}}; - - _ -> - Value - end. - --spec exit_process(gleam@erlang@process:exit_reason()) -> gleam@erlang@process:exit_reason(). -exit_process(Reason) -> - Reason. - --spec selecting_system_messages(gleam@erlang@process:selector(message(GBY))) -> gleam@erlang@process:selector(message(GBY)). -selecting_system_messages(Selector) -> - _pipe = Selector, - gleam@erlang@process:selecting_record3( - _pipe, - erlang:binary_to_atom(<<"system"/utf8>>), - fun gleam_otp_external:convert_system_message/2 - ). - --spec receive_message(self(any(), GBU)) -> message(GBU). -receive_message(Self) -> - Selector = case erlang:element(2, Self) of - suspended -> - _pipe = gleam_erlang_ffi:new_selector(), - selecting_system_messages(_pipe); - - running -> - _pipe@1 = gleam_erlang_ffi:new_selector(), - _pipe@2 = gleam@erlang@process:selecting_anything( - _pipe@1, - fun(Field@0) -> {unexpected, Field@0} end - ), - _pipe@3 = gleam_erlang_ffi:merge_selector( - _pipe@2, - erlang:element(6, Self) - ), - selecting_system_messages(_pipe@3) - end, - gleam_erlang_ffi:select(Selector). - --spec process_status_info(self(any(), any())) -> gleam@otp@system:status_info(). -process_status_info(Self) -> - {status_info, - erlang:binary_to_atom(<<"gleam@otp@actor"/utf8>>), - erlang:element(3, Self), - erlang:element(2, Self), - erlang:element(7, Self), - gleam@dynamic:from(erlang:element(4, Self))}. - --spec init_selector( - gleam@erlang@process:subject(GGN), - gleam@erlang@process:selector(GGN) -) -> gleam@erlang@process:selector(message(GGN)). -init_selector(Subject, Selector) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun(Field@0) -> {message, Field@0} end - ), - gleam_erlang_ffi:merge_selector( - _pipe@1, - gleam_erlang_ffi:map_selector( - Selector, - fun(Field@0) -> {message, Field@0} end - ) - ). - --spec loop(self(any(), any())) -> gleam@erlang@process:exit_reason(). -loop(Self) -> - case receive_message(Self) of - {system, System} -> - case System of - {get_state, Callback} -> - Callback(gleam@dynamic:from(erlang:element(4, Self))), - loop(Self); - - {resume, Callback@1} -> - Callback@1(), - loop(erlang:setelement(2, Self, running)); - - {suspend, Callback@2} -> - Callback@2(), - loop(erlang:setelement(2, Self, suspended)); - - {get_status, Callback@3} -> - Callback@3(process_status_info(Self)), - loop(Self) - end; - - {unexpected, Message} -> - logger:warning( - unicode:characters_to_list( - <<"Actor discarding unexpected message: ~s"/utf8>> - ), - [unicode:characters_to_list(gleam@string:inspect(Message))] - ), - loop(Self); - - {message, Msg} -> - case (erlang:element(8, Self))(Msg, erlang:element(4, Self)) of - {stop, Reason} -> - exit_process(Reason); - - {continue, State, New_selector} -> - Selector = begin - _pipe = New_selector, - _pipe@1 = gleam@option:map( - _pipe, - fun(_capture) -> - init_selector(erlang:element(5, Self), _capture) - end - ), - gleam@option:unwrap(_pipe@1, erlang:element(6, Self)) - end, - loop( - erlang:setelement( - 6, - erlang:setelement(4, Self, State), - Selector - ) - ) - end - end. - --spec initialise_actor( - spec(any(), GCP), - gleam@erlang@process:subject({ok, gleam@erlang@process:subject(GCP)} | - {error, gleam@erlang@process:exit_reason()}) -) -> gleam@erlang@process:exit_reason(). -initialise_actor(Spec, Ack) -> - Subject = gleam@erlang@process:new_subject(), - case (erlang:element(2, Spec))() of - {ready, State, Selector} -> - Selector@1 = init_selector(Subject, Selector), - gleam@erlang@process:send(Ack, {ok, Subject}), - Self = {self, - running, - gleam@erlang@process:subject_owner(Ack), - State, - Subject, - Selector@1, - sys:debug_options([]), - erlang:element(4, Spec)}, - loop(Self); - - {failed, Reason} -> - gleam@erlang@process:send(Ack, {error, {abnormal, Reason}}), - exit_process({abnormal, Reason}) - end. - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | {error, start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. -to_erlang_start_result(Res) -> - case Res of - {ok, X} -> - {ok, gleam@erlang@process:subject_owner(X)}; - - {error, X@1} -> - {error, gleam@dynamic:from(X@1)} - end. - --spec start_spec(spec(any(), GDD)) -> {ok, gleam@erlang@process:subject(GDD)} | - {error, start_error()}. -start_spec(Spec) -> - Ack_subject = gleam@erlang@process:new_subject(), - Child = gleam@erlang@process:start( - fun() -> initialise_actor(Spec, Ack_subject) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Child), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Ack_subject, - fun(Field@0) -> {ack, Field@0} end - ), - gleam@erlang@process:selecting_process_down( - _pipe@1, - Monitor, - fun(Field@0) -> {mon, Field@0} end - ) - end, - Result = case gleam_erlang_ffi:select(Selector, erlang:element(3, Spec)) of - {ok, {ack, {ok, Channel}}} -> - {ok, Channel}; - - {ok, {ack, {error, Reason}}} -> - {error, {init_failed, Reason}}; - - {ok, {mon, Down}} -> - {error, {init_crashed, erlang:element(3, Down)}}; - - {error, nil} -> - gleam@erlang@process:kill(Child), - {error, init_timeout} - end, - gleam_erlang_ffi:demonitor(Monitor), - Result. - --spec start(GDJ, fun((GDK, GDJ) -> next(GDK, GDJ))) -> {ok, - gleam@erlang@process:subject(GDK)} | - {error, start_error()}. -start(State, Loop) -> - start_spec( - {spec, - fun() -> {ready, State, gleam_erlang_ffi:new_selector()} end, - 5000, - Loop} - ). - --spec send(gleam@erlang@process:subject(GDQ), GDQ) -> nil. -send(Subject, Msg) -> - gleam@erlang@process:send(Subject, Msg). - --spec call( - gleam@erlang@process:subject(GDS), - fun((gleam@erlang@process:subject(GDU)) -> GDS), - integer() -) -> GDU. -call(Selector, Make_message, Timeout) -> - gleam@erlang@process:call(Selector, Make_message, Timeout). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl deleted file mode 100644 index 8792f143c9a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(gleam@otp@intensity_tracker). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/2, trim_window/3, add_event/1]). --export_type([intensity_tracker/0, too_intense/0]). - --opaque intensity_tracker() :: {intensity_tracker, - integer(), - integer(), - list(integer())}. - --type too_intense() :: too_intense. - --spec new(integer(), integer()) -> intensity_tracker(). -new(Limit, Period) -> - {intensity_tracker, Limit, Period, []}. - --spec now_seconds() -> integer(). -now_seconds() -> - erlang:monotonic_time(1). - --spec trim_window(list(integer()), integer(), integer()) -> list(integer()). -trim_window(Events, Now, Period) -> - case Events of - [] -> - []; - - [Event | Events@1] -> - case Now >= (Event + Period) of - true -> - [Event | trim_window(Events@1, Now, Period)]; - - false -> - [] - end - end. - --spec add_event(intensity_tracker()) -> {ok, intensity_tracker()} | - {error, too_intense()}. -add_event(Tracker) -> - Now = now_seconds(), - Events = trim_window( - [Now | erlang:element(4, Tracker)], - Now, - erlang:element(3, Tracker) - ), - case gleam@list:length(Events) >= erlang:element(2, Tracker) of - true -> - {error, too_intense}; - - false -> - {ok, erlang:setelement(4, Tracker, Events)} - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl deleted file mode 100644 index b2057392ae4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gleam@otp@port). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([port_/0]). - --type port_() :: any(). - - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl deleted file mode 100644 index 39118f1a5ae..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl +++ /dev/null @@ -1,322 +0,0 @@ --module(gleam@otp@supervisor). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([add/2, supervisor/1, worker/1, returning/2, start_spec/1, start/1, application_stopped/0, to_erlang_start_result/1]). --export_type([spec/2, children/1, child_spec/3, child_start_error/0, message/0, instruction/0, state/1, starter/1, child/1, handle_exit_error/0, application_start_mode/0, application_stop/0]). - --type spec(GLS, GLT) :: {spec, - GLS, - integer(), - integer(), - fun((children(GLS)) -> children(GLT))}. - --opaque children(GLU) :: {ready, starter(GLU)} | {failed, child_start_error()}. - --opaque child_spec(GLV, GLW, GLX) :: {child_spec, - fun((GLW) -> {ok, gleam@erlang@process:subject(GLV)} | - {error, gleam@otp@actor:start_error()}), - fun((GLW, gleam@erlang@process:subject(GLV)) -> GLX)}. - --type child_start_error() :: {child_start_error, - gleam@option:option(gleam@erlang@process:pid_()), - gleam@otp@actor:start_error()}. - --opaque message() :: {exit, gleam@erlang@process:exit_message()} | - {retry_restart, gleam@erlang@process:pid_()}. - --type instruction() :: start_all | {start_from, gleam@erlang@process:pid_()}. - --type state(GLY) :: {state, - gleam@otp@intensity_tracker:intensity_tracker(), - starter(GLY), - gleam@erlang@process:subject(gleam@erlang@process:pid_())}. - --type starter(GLZ) :: {starter, - GLZ, - gleam@option:option(fun((instruction()) -> {ok, - {starter(GLZ), instruction()}} | - {error, child_start_error()}))}. - --type child(GMA) :: {child, gleam@erlang@process:pid_(), GMA}. - --type handle_exit_error() :: {restart_failed, - gleam@erlang@process:pid_(), - gleam@otp@intensity_tracker:intensity_tracker()} | - too_many_restarts. - --type application_start_mode() :: normal | - {takeover, gleam@erlang@node:node_()} | - {failover, gleam@erlang@node:node_()}. - --type application_stop() :: any(). - --spec start_child(child_spec(any(), GME, GMF), GME) -> {ok, child(GMF)} | - {error, child_start_error()}. -start_child(Child_spec, Argument) -> - gleam@result:then( - begin - _pipe = (erlang:element(2, Child_spec))(Argument), - gleam@result:map_error( - _pipe, - fun(_capture) -> {child_start_error, none, _capture} end - ) - end, - fun(Subject) -> - {ok, - {child, - gleam@erlang@process:subject_owner(Subject), - (erlang:element(3, Child_spec))(Argument, Subject)}} - end - ). - --spec shutdown_child( - gleam@erlang@process:pid_(), - child_spec(any(), any(), any()) -) -> nil. -shutdown_child(Pid, _) -> - gleam@erlang@process:send_exit(Pid). - --spec perform_instruction_for_child( - GMS, - instruction(), - child_spec(any(), GMS, GMU), - child(GMU) -) -> {ok, {child(GMU), instruction()}} | {error, child_start_error()}. -perform_instruction_for_child(Argument, Instruction, Child_spec, Child) -> - Current = erlang:element(2, Child), - case Instruction of - {start_from, Target} when Target =/= Current -> - {ok, {Child, Instruction}}; - - _ -> - shutdown_child(Current, Child_spec), - gleam@result:then( - start_child(Child_spec, Argument), - fun(Child@1) -> {ok, {Child@1, start_all}} end - ) - end. - --spec add_child_to_starter( - starter(GNC), - child_spec(any(), GNC, GNF), - child(GNF) -) -> starter(GNF). -add_child_to_starter(Starter, Child_spec, Child) -> - Starter@3 = fun(Instruction) -> - gleam@result:then(case erlang:element(3, Starter) of - {some, Start} -> - Start(Instruction); - - none -> - {ok, {Starter, Instruction}} - end, fun(_use0) -> - {Starter@1, Instruction@1} = _use0, - gleam@result:then( - perform_instruction_for_child( - erlang:element(2, Starter@1), - Instruction@1, - Child_spec, - Child - ), - fun(_use0@1) -> - {Child@1, Instruction@2} = _use0@1, - Starter@2 = add_child_to_starter( - Starter@1, - Child_spec, - Child@1 - ), - {ok, {Starter@2, Instruction@2}} - end - ) - end) - end, - {starter, erlang:element(3, Child), {some, Starter@3}}. - --spec start_and_add_child(starter(GNL), child_spec(any(), GNL, GNO)) -> children(GNO). -start_and_add_child(State, Child_spec) -> - case start_child(Child_spec, erlang:element(2, State)) of - {ok, Child} -> - {ready, add_child_to_starter(State, Child_spec, Child)}; - - {error, Reason} -> - {failed, Reason} - end. - --spec add(children(GNT), child_spec(any(), GNT, GNW)) -> children(GNW). -add(Children, Child_spec) -> - case Children of - {failed, Fail} -> - {failed, Fail}; - - {ready, State} -> - start_and_add_child(State, Child_spec) - end. - --spec supervisor( - fun((GOB) -> {ok, gleam@erlang@process:subject(GOC)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(GOC, GOB, GOB). -supervisor(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec worker( - fun((GOJ) -> {ok, gleam@erlang@process:subject(GOK)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(GOK, GOJ, GOJ). -worker(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec returning( - child_spec(GOR, GOS, any()), - fun((GOS, gleam@erlang@process:subject(GOR)) -> GOY) -) -> child_spec(GOR, GOS, GOY). -returning(Child, Updater) -> - {child_spec, erlang:element(2, Child), Updater}. - --spec init(spec(any(), GPD)) -> gleam@otp@actor:init_result(state(GPD), message()). -init(Spec) -> - Retry = gleam@erlang@process:new_subject(), - gleam_erlang_ffi:trap_exits(true), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Retry, - fun(Field@0) -> {retry_restart, Field@0} end - ), - gleam@erlang@process:selecting_trapped_exits( - _pipe@1, - fun(Field@0) -> {exit, Field@0} end - ) - end, - Result = begin - _pipe@2 = {starter, erlang:element(2, Spec), none}, - _pipe@3 = {ready, _pipe@2}, - (erlang:element(5, Spec))(_pipe@3) - end, - case Result of - {ready, Starter} -> - Restarts = gleam@otp@intensity_tracker:new( - erlang:element(3, Spec), - erlang:element(4, Spec) - ), - State = {state, Restarts, Starter, Retry}, - {ready, State, Selector}; - - {failed, Error} -> - {failed, case erlang:element(3, Error) of - init_timeout -> - <<"Child initialisation timed out"/utf8>>; - - {init_crashed, Reason} -> - gleam@string:append( - <<"Child crashed during initialisation: "/utf8>>, - gleam@string:inspect(Reason) - ); - - {init_failed, Reason@1} -> - gleam@string:append( - <<"Child failed to start during initialisation: "/utf8>>, - gleam@string:inspect(Reason@1) - ) - end} - end. - --spec handle_exit(gleam@erlang@process:pid_(), state(GPJ)) -> gleam@otp@actor:next(message(), state(GPJ)). -handle_exit(Pid, State) -> - Outcome = begin - _assert_subject = erlang:element(3, erlang:element(3, State)), - {some, Start} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/supervisor"/utf8>>, - function => <<"handle_exit"/utf8>>, - line => 293}) - end, - gleam@result:then( - begin - _pipe = erlang:element(2, State), - _pipe@1 = gleam@otp@intensity_tracker:add_event(_pipe), - gleam@result:map_error(_pipe@1, fun(_) -> too_many_restarts end) - end, - fun(Restarts) -> - gleam@result:then( - begin - _pipe@2 = Start({start_from, Pid}), - gleam@result:map_error( - _pipe@2, - fun(E) -> - {restart_failed, - gleam@option:unwrap( - erlang:element(2, E), - Pid - ), - Restarts} - end - ) - end, - fun(_use0) -> - {Starter, _} = _use0, - {ok, - erlang:setelement( - 2, - erlang:setelement(3, State, Starter), - Restarts - )} - end - ) - end - ) - end, - case Outcome of - {ok, State@1} -> - gleam@otp@actor:continue(State@1); - - {error, {restart_failed, Failed_child, Restarts@1}} -> - gleam@erlang@process:send(erlang:element(4, State), Failed_child), - State@2 = erlang:setelement(2, State, Restarts@1), - gleam@otp@actor:continue(State@2); - - {error, too_many_restarts} -> - {stop, - {abnormal, - <<"Child processes restarted too many times within allowed period"/utf8>>}} - end. - --spec loop(message(), state(GPO)) -> gleam@otp@actor:next(message(), state(GPO)). -loop(Message, State) -> - case Message of - {exit, Exit_message} -> - handle_exit(erlang:element(2, Exit_message), State); - - {retry_restart, Pid} -> - handle_exit(Pid, State) - end. - --spec start_spec(spec(any(), any())) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start_spec(Spec) -> - gleam@otp@actor:start_spec( - {spec, fun() -> init(Spec) end, 60000, fun loop/2} - ). - --spec start(fun((children(nil)) -> children(any()))) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start(Init) -> - start_spec({spec, nil, 1, 5, Init}). - --spec application_stopped() -> application_stop(). -application_stopped() -> - gleam_otp_external:application_stopped(). - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. -to_erlang_start_result(Res) -> - gleam@otp@actor:to_erlang_start_result(Res). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl deleted file mode 100644 index 622e5ea10bf..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam@otp@system). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([debug_state/1, get_state/1, suspend/1, resume/1]). --export_type([mode/0, debug_option/0, debug_state/0, status_info/0, system_message/0, do_not_leak/0]). - --type mode() :: running | suspended. - --type debug_option() :: no_debug. - --type debug_state() :: any(). - --type status_info() :: {status_info, - gleam@erlang@atom:atom_(), - gleam@erlang@process:pid_(), - mode(), - debug_state(), - gleam@dynamic:dynamic_()}. - --type system_message() :: {resume, fun(() -> nil)} | - {suspend, fun(() -> nil)} | - {get_state, fun((gleam@dynamic:dynamic_()) -> nil)} | - {get_status, fun((status_info()) -> nil)}. - --type do_not_leak() :: any(). - --spec debug_state(list(debug_option())) -> debug_state(). -debug_state(A) -> - sys:debug_options(A). - --spec get_state(gleam@erlang@process:pid_()) -> gleam@dynamic:dynamic_(). -get_state(From) -> - sys:get_state(From). - --spec suspend(gleam@erlang@process:pid_()) -> nil. -suspend(Pid) -> - sys:suspend(Pid), - nil. - --spec resume(gleam@erlang@process:pid_()) -> nil. -resume(Pid) -> - sys:resume(Pid), - nil. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl deleted file mode 100644 index e00428491f4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl +++ /dev/null @@ -1,111 +0,0 @@ --module(gleam@otp@task). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([async/1, try_await/2, await/2, try_await_forever/1, await_forever/1]). --export_type([task/1, await_error/0, message/1]). - --opaque task(FWJ) :: {task, - gleam@erlang@process:pid_(), - gleam@erlang@process:pid_(), - gleam@erlang@process:process_monitor(), - gleam@erlang@process:selector(message(FWJ))}. - --type await_error() :: timeout | {exit, gleam@dynamic:dynamic_()}. - --type message(FWK) :: {from_monitor, gleam@erlang@process:process_down()} | - {from_subject, FWK}. - --spec async(fun(() -> FWL)) -> task(FWL). -async(Work) -> - Owner = erlang:self(), - Subject = gleam@erlang@process:new_subject(), - Pid = gleam@erlang@process:start( - fun() -> gleam@erlang@process:send(Subject, Work()) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Pid), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting_process_down( - _pipe, - Monitor, - fun(Field@0) -> {from_monitor, Field@0} end - ), - gleam@erlang@process:selecting( - _pipe@1, - Subject, - fun(Field@0) -> {from_subject, Field@0} end - ) - end, - {task, Owner, Pid, Monitor, Selector}. - --spec assert_owner(task(any())) -> nil. -assert_owner(Task) -> - Self = erlang:self(), - case erlang:element(2, Task) =:= Self of - true -> - nil; - - false -> - gleam@erlang@process:send_abnormal_exit( - Self, - <<"awaited on a task that does not belong to this process"/utf8>> - ) - end. - --spec try_await(task(FWP), integer()) -> {ok, FWP} | {error, await_error()}. -try_await(Task, Timeout) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task), Timeout) of - {ok, {from_subject, X}} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {ok, {from_monitor, {process_down, _, Reason}}} -> - {error, {exit, Reason}}; - - {error, nil} -> - {error, timeout} - end. - --spec await(task(FWT), integer()) -> FWT. -await(Task, Timeout) -> - _assert_subject = try_await(Task, Timeout), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await"/utf8>>, - line => 117}) - end, - Value. - --spec try_await_forever(task(FWV)) -> {ok, FWV} | {error, await_error()}. -try_await_forever(Task) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task)) of - {from_subject, X} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {from_monitor, {process_down, _, Reason}} -> - {error, {exit, Reason}} - end. - --spec await_forever(task(FWZ)) -> FWZ. -await_forever(Task) -> - _assert_subject = try_await_forever(Task), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await_forever"/utf8>>, - line => 149}) - end, - Value. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src deleted file mode 100644 index 5c52295ceb9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src +++ /dev/null @@ -1,15 +0,0 @@ -{application, gleam_otp, [ - {vsn, "0.8.0"}, - {applications, [gleam_erlang, - gleam_stdlib, - gleeunit]}, - {description, "Fault tolerant multicore Gleam programs with OTP"}, - {modules, [gleam@otp@actor, - gleam@otp@intensity_tracker, - gleam@otp@port, - gleam@otp@supervisor, - gleam@otp@system, - gleam@otp@task, - gleam_otp]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl deleted file mode 100644 index 9381ad2ac22..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(gleam_otp). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec spawn_task(integer()) -> gleam@otp@task:task(nil). -spawn_task(I) -> - gleam@otp@task:async(fun() -> case (I rem 500) =:= 0 of - true -> - gleam@io:println( - <<"Hello from "/utf8, (gleam@int:to_string(I))/binary>> - ); - - false -> - nil - end end). - --spec main() -> integer(). -main() -> - gleam@io:debug( - gleam_otp_test_external:get_message_queue_length(erlang:self()) - ), - _pipe = gleam@list:range(0, 1000000), - _pipe@1 = gleam@list:map(_pipe, fun spawn_task/1), - gleam@list:each(_pipe@1, fun gleam@otp@task:await_forever/1), - gleam@io:debug( - gleam_otp_test_external:get_message_queue_length(erlang:self()) - ). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam deleted file mode 100644 index 69cdd5bb1e6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam +++ /dev/null @@ -1,27 +0,0 @@ -import gleam/io -import gleam/int -import gleam/list -import gleam/otp/task -import gleam/erlang/process.{type Pid} - -@external(erlang, "gleam_otp_test_external", "get_message_queue_length") -fn get_message_queue_length(pid pid: Pid) -> Int - -fn spawn_task(i) { - task.async(fn() { - case i % 500 == 0 { - True -> io.println("Hello from " <> int.to_string(i)) - False -> Nil - } - }) -} - -pub fn main() { - io.debug(get_message_queue_length(process.self())) - - list.range(0, 1_000_000) - |> list.map(spawn_task) - |> list.each(task.await_forever) - - io.debug(get_message_queue_length(process.self())) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl deleted file mode 100644 index 8910a67d7e2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam_otp_external). - --export([application_stopped/0, convert_system_message/2]). - -% TODO: support other system messages -% {replace_state, StateFn} -% {change_code, Mod, Vsn, Extra} -% {terminate, Reason} -% {debug, {log, Flag}} -% {debug, {trace, Flag}} -% {debug, {log_to_file, FileName}} -% {debug, {statistics, Flag}} -% {debug, no_debug} -% {debug, {install, {Func, FuncState}}} -% {debug, {install, {FuncId, Func, FuncState}}} -% {debug, {remove, FuncOrId}} -% GetStatus(Subject(StatusInfo)) -convert_system_message({From, Ref}, Request) when is_pid(From) -> - Reply = fun(Msg) -> - erlang:send(From, {Ref, Msg}), - nil - end, - System = fun(Callback) -> - {system, {Request, Callback}} - end, - case Request of - get_status -> System(fun(Status) -> Reply(process_status(Status)) end); - get_state -> System(Reply); - suspend -> System(fun() -> Reply(ok) end); - resume -> System(fun() -> Reply(ok) end); - Other -> {unexpeceted, Other} - end. - -process_status({status_info, Module, Parent, Mode, DebugState, State}) -> - Data = [ - get(), Mode, Parent, DebugState, - [{header, "Status for Gleam process " ++ pid_to_list(self())}, - {data, [{'Status', Mode}, {'Parent', Parent}, {'State', State}]}] - ], - {status, self(), {module, Module}, Data}. - -application_stopped() -> - ok. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index a978a7ff425..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_stdlib" -version = "0.33.1" -gleam = ">= 0.32.0" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 6e1e2261268..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs deleted file mode 100644 index a8309e0cdbd..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of Dict size and clean up the API - * @template K,V - */ -export default class Dict { - /** - * @template V - * @param {Record<string,V>} o - * @returns {Dict<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type Dict<string,V> */ - let m = Dict.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {Dict<K,V>} - */ - static fromMap(o) { - /** @type Dict<K,V> */ - let m = Dict.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new Dict(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {Dict<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {Dict<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return Dict.new(); - } - return new Dict(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof Dict) || this.size !== o.size) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index eab2f0b3fec..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam deleted file mode 100644 index 79860e964ef..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam +++ /dev/null @@ -1,157 +0,0 @@ -//// BitArrays are a sequence of binary data of any length. - -import gleam/string - -/// Converts a UTF-8 `String` type into a `BitArray`. -/// -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") -pub fn from_string(x: String) -> BitArray - -/// Returns an integer which is the number of bytes in the bit array. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -pub fn byte_size(x: BitArray) -> Int - -/// Creates a new bit array by joining two bit arrays. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - concat([first, second]) -} - -/// Extracts a sub-section of a bit array. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit array. -/// -/// This function runs in constant time. -/// -@external(erlang, "gleam_stdlib", "bit_array_slice") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) - -/// Tests to see whether a bit array is valid UTF-8. -/// -pub fn is_utf8(bits: BitArray) -> Bool { - do_is_utf8(bits) -} - -@target(erlang) -fn do_is_utf8(bits: BitArray) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:bytes>> -> do_is_utf8(rest) - _ -> False - } -} - -@target(javascript) -fn do_is_utf8(bits: BitArray) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } -} - -/// Converts a bit array to a string. -/// -/// Returns an error if the bit array is invalid UTF-8 data. -/// -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - do_to_string(bits) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "identity") -fn unsafe_to_string(a: BitArray) -> String - -@target(erlang) -fn do_to_string(bits: BitArray) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") -fn do_to_string(a: BitArray) -> Result(String, Nil) - -/// Creates a new bit array by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -@external(erlang, "gleam_stdlib", "bit_array_concat") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") -pub fn concat(bit_arrays: List(BitArray)) -> BitArray - -/// Encodes a BitArray into a base 64 encoded string. -/// -pub fn base64_encode(input: BitArray, padding: Bool) -> String { - let encoded = encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -@external(erlang, "base64", "encode") -@external(javascript, "../gleam_stdlib.mjs", "encode64") -fn encode64(a: BitArray) -> String - -/// Decodes a base 64 encoded string into a `BitArray`. -/// -pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { - let padded = case byte_size(from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - decode64(padded) -} - -@external(erlang, "gleam_stdlib", "base_decode64") -@external(javascript, "../gleam_stdlib.mjs", "decode64") -fn decode64(a: String) -> Result(BitArray, Nil) - -/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { - base64_encode(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. -/// -pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> base64_decode() -} - -@external(erlang, "binary", "encode_hex") -@external(javascript, "../gleam_stdlib.mjs", "base16_encode") -pub fn base16_encode(input: BitArray) -> String - -@external(erlang, "gleam_stdlib", "base16_decode") -@external(javascript, "../gleam_stdlib.mjs", "base16_decode") -pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52ec1b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0930d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 91bd6b76129..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,428 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{type Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} - -/// Runs a callback function if the given bool is `True`, otherwise runs an -/// alternative callback function. -/// -/// Useful when further computation should be delayed regardless of the given -/// bool's value. -/// -/// See [`guard`](#guard) for more info. -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "Kamaka" -/// > let inquiry = fn() { "How may we address you?" } -/// > use <- lazy_guard(when: name == "", return: inquiry) -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -/// ```gleam -/// > import gleam/int -/// > let name = "" -/// > let greeting = fn() { "Hello, " <> name } -/// > use <- lazy_guard(when: name == "", otherwise: greeting) -/// > let number = int.random(1, 99) -/// > let name = "User " <> int.to_string(number) -/// > "Welcome, " <> name -/// "Welcome, User 54" -/// ``` -/// -pub fn lazy_guard( - when requirement: Bool, - return consequence: fn() -> a, - otherwise alternative: fn() -> a, -) -> a { - case requirement { - True -> consequence() - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam deleted file mode 100644 index 20c145d93aa..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam +++ /dev/null @@ -1,197 +0,0 @@ -//// BytesBuilder is a type used for efficiently concatenating bytes together -//// without copying. -//// -//// If we append one bit array to another the bit arrays must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit arrays together. -//// -//// BytesBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit array using the `to_bit_array` function. -//// -//// Byte builders are always byte aligned, so that a number of bits that is not -//// divisible by 8 will be padded with 0s. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -// TODO: pad bit arrays to byte boundaries when adding to a builder. -import gleam/string_builder.{type StringBuilder} -import gleam/list -import gleam/bit_array - -pub opaque type BytesBuilder { - Bytes(BitArray) - Text(StringBuilder) - Many(List(BytesBuilder)) -} - -/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> BytesBuilder { - concat([]) -} - -/// Prepends a bit array to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { - append_builder(from_bit_array(first), second) -} - -/// Appends a bit array to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { - append_builder(first, from_bit_array(second)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to second: BytesBuilder, - prefix first: BytesBuilder, -) -> BytesBuilder { - append_builder(first, second) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "iodata_append") -pub fn append_builder( - to first: BytesBuilder, - suffix second: BytesBuilder, -) -> BytesBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string( - to second: BytesBuilder, - prefix first: String, -) -> BytesBuilder { - append_builder(from_string(first), second) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string( - to first: BytesBuilder, - suffix second: String, -) -> BytesBuilder { - append_builder(first, from_string(second)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { - Many(builders) -} - -/// Joins a list of bit arrays into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { - bits - |> list.map(fn(b) { from_bit_array(b) }) - |> concat() -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string(string: String) -> BytesBuilder { - Text(string_builder.from_string(string)) -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { - Text(builder) -} - -/// Creates a new builder from a bit array. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_bit_array(bits: BitArray) -> BytesBuilder { - Bytes(bits) -} - -/// Turns an builder into a bit array. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -@external(erlang, "erlang", "list_to_bitstring") -pub fn to_bit_array(builder: BytesBuilder) -> BitArray { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_array.concat -} - -fn to_list( - stack: List(List(BytesBuilder)), - acc: List(BitArray), -) -> List(BitArray) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bytes(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_array.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -@external(erlang, "erlang", "iolist_size") -pub fn byte_size(builder: BytesBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam deleted file mode 100644 index 280bf9d1d98..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam +++ /dev/null @@ -1,544 +0,0 @@ -import gleam/option.{type Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a dict, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a dict once. -/// -/// Dicts are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub type Dict(key, value) - -/// Determines the number of key-value pairs in the dict. -/// This function runs in constant time and does not need to iterate the dict. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(dict: Dict(k, v)) -> Int { - do_size(dict) -} - -@external(erlang, "maps", "size") -@external(javascript, "../gleam_stdlib.mjs", "map_size") -fn do_size(a: Dict(k, v)) -> Int - -/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the dict. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { - do_to_list(dict) -} - -@external(erlang, "maps", "to_list") -@external(javascript, "../gleam_stdlib.mjs", "map_to_list") -fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) - -/// Converts a list of 2-element tuples `#(key, value)` to a dict. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the dict. -/// -pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { - do_from_list(list) -} - -@target(erlang) -@external(erlang, "maps", "from_list") -fn do_from_list(a: List(#(key, value))) -> Dict(key, value) - -@target(javascript) -fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Dict(k, v), -) -> Dict(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } -} - -@target(javascript) -fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { - fold_list_of_pair(list, new()) -} - -/// Determines whether or not a value present in the dict for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(dict: Dict(k, v), key: k) -> Bool { - do_has_key(key, dict) -} - -@target(erlang) -@external(erlang, "maps", "is_key") -fn do_has_key(a: key, b: Dict(key, v)) -> Bool - -@target(javascript) -fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { - get(dict, key) != Error(Nil) -} - -/// Creates a fresh dict that contains no values. -/// -pub fn new() -> Dict(key, value) { - do_new() -} - -@external(erlang, "maps", "new") -@external(javascript, "../gleam_stdlib.mjs", "new_map") -fn do_new() -> Dict(key, value) - -/// Fetches a value from a dict for a given key. -/// -/// The dict may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -@external(erlang, "gleam_stdlib", "map_get") -@external(javascript, "../gleam_stdlib.mjs", "map_get") -fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) - -/// Inserts a value into the dict with the given key. -/// -/// If the dict already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { - do_insert(key, value, dict) -} - -@external(erlang, "maps", "put") -@external(javascript, "../gleam_stdlib.mjs", "map_insert") -fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) - -/// Updates all values in a given dict by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { - do_map_values(fun, dict) -} - -@target(erlang) -@external(erlang, "maps", "map") -fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) - -@target(javascript) -fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { - let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } - dict - |> fold(from: new(), with: f) -} - -/// Gets a list of all keys in a given dict. -/// -/// Dicts are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(dict: Dict(keys, v)) -> List(keys) { - do_keys(dict) -} - -@target(erlang) -@external(erlang, "maps", "keys") -fn do_keys(a: Dict(keys, v)) -> List(keys) - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(dict: Dict(k, v)) -> List(k) { - let list_of_pairs = to_list(dict) - do_keys_acc(list_of_pairs, []) -} - -/// Gets a list of all values in a given dict. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(dict: Dict(k, values)) -> List(values) { - do_values(dict) -} - -@target(erlang) -@external(erlang, "maps", "values") -fn do_values(a: Dict(k, values)) -> List(values) - -@target(javascript) -fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } -} - -@target(javascript) -fn do_values(dict: Dict(k, v)) -> List(v) { - let list_of_pairs = to_list(dict) - do_values_acc(list_of_pairs, []) -} - -/// Creates a new dict from a given dict, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter( - in dict: Dict(k, v), - keeping predicate: fn(k, v) -> Bool, -) -> Dict(k, v) { - do_filter(predicate, dict) -} - -@target(erlang) -@external(erlang, "maps", "filter") -fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) - -@target(javascript) -fn do_filter( - f: fn(key, value) -> Bool, - dict: Dict(key, value), -) -> Dict(key, value) { - let insert = fn(dict, k, v) { - case f(k, v) { - True -> insert(dict, k, v) - _ -> dict - } - } - dict - |> fold(from: new(), with: insert) -} - -/// Creates a new dict from a given dict, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { - do_take(desired_keys, dict) -} - -@target(erlang) -@external(erlang, "maps", "with") -fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_taken( - dict: Dict(k, v), - desired_keys: List(k), - acc: Dict(k, v), -) -> Dict(k, v) { - let insert = fn(taken, key) { - case get(dict, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) - } -} - -@target(javascript) -fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { - insert_taken(dict, desired_keys, new()) -} - -/// Creates a new dict from a pair of given dicts by combining their entries. -/// -/// If there are entries with the same keys in both dicts the entry from the -/// second dict takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { - do_merge(dict, new_entries) -} - -@target(erlang) -@external(erlang, "maps", "merge") -fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { - insert(dict, pair.0, pair.1) -} - -@target(javascript) -fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { - case new_entries { - [] -> dict - [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) - } -} - -@target(javascript) -fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { - new_entries - |> to_list - |> fold_inserts(dict) -} - -/// Creates a new dict from a given dict with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { - do_delete(key, dict) -} - -@external(erlang, "maps", "remove") -@external(javascript, "../gleam_stdlib.mjs", "map_remove") -fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) - -/// Creates a new dict from a given dict with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { - case disallowed_keys { - [] -> dict - [x, ..xs] -> drop(delete(dict, x), xs) - } -} - -/// Creates a new dict with one entry updated using a given function. -/// -/// If there was not an entry in the dict for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let dict = from_list([#("a", 0)]) -/// > -/// > update(dict, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(dict, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in dict: Dict(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Dict(k, v) { - dict - |> get(key) - |> option.from_result - |> fun - |> insert(dict, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over dict: Dict(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - dict - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index c71c6f342ad..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1508 +0,0 @@ -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option} -import gleam/result -import gleam/string_builder -@target(erlang) -import gleam/bit_array - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from(a: anything) -> Dynamic - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_unsafe_coerce(a: Dynamic) -> a - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit -/// array if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_array(from("Hello")) == bit_array.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_array(from(123)) -/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - decode_bit_array(data) -} - -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - -@external(erlang, "gleam_stdlib", "decode_bit_array") -@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") -fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -@target(erlang) -fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_array(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_array.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitArray", path: [])]) - } - }) -} - -@target(erlang) -fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "decode_string") -fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -@external(erlang, "gleam_stdlib", "classify_dynamic") -@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") -fn do_classify(a: Dynamic) -> String - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -@external(erlang, "gleam_stdlib", "decode_int") -@external(javascript, "../gleam_stdlib.mjs", "decode_int") -fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -@external(erlang, "gleam_stdlib", "decode_float") -@external(javascript, "../gleam_stdlib.mjs", "decode_float") -fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -@external(erlang, "gleam_stdlib", "decode_bool") -@external(javascript, "../gleam_stdlib.mjs", "decode_bool") -fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -@external(erlang, "gleam_stdlib", "decode_list") -@external(javascript, "../gleam_stdlib.mjs", "decode_list") -fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_result") -@external(javascript, "../gleam_stdlib.mjs", "decode_result") -fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -@external(erlang, "gleam_stdlib", "decode_option") -@external(javascript, "../gleam_stdlib.mjs", "decode_option") -fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -@external(erlang, "gleam_stdlib", "decode_field") -@external(javascript, "../gleam_stdlib.mjs", "decode_field") -fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -type UnknownTuple - -@external(erlang, "gleam_stdlib", "decode_tuple") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") -fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple2") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") -fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple3") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") -fn decode_tuple3( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple4") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") -fn decode_tuple4( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple5") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") -fn decode_tuple5( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple6") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") -fn decode_tuple6( - a: Dynamic, -) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, -) - -@external(erlang, "gleam_stdlib", "tuple_get") -@external(javascript, "../gleam_stdlib.mjs", "tuple_get") -fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) - -@external(erlang, "gleam_stdlib", "size_of_tuple") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn tuple_size(a: UnknownTuple) -> Int - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a dict. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() |> from |> map(string, int) -/// Ok(dict.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn dict( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> dict.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(dict.from_list(pairs)) - } -} - -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - -@external(erlang, "gleam_stdlib", "decode_map") -@external(javascript, "../gleam_stdlib.mjs", "decode_map") -fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.concat([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 5d62419fd0d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,546 +0,0 @@ -//// Functions for working with floats. -//// -//// ## Division by zero -//// -//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE -//// 754 standard for floating point arithmetic and does not have an `Infinity` -//// value. In Erlang division by zero results in a crash, however Gleam does -//// not have partial functions and operators in core so instead division by zero -//// returns zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/order.{type Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_float") -@external(javascript, "../gleam_stdlib.mjs", "parse_float") -fn do_parse(a: String) -> Result(Float, Nil) - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -@external(erlang, "gleam_stdlib", "float_to_string") -@external(javascript, "../gleam_stdlib.mjs", "float_to_string") -fn do_to_string(a: Float) -> String - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -@external(erlang, "math", "ceil") -@external(javascript, "../gleam_stdlib.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -@external(erlang, "math", "floor") -@external(javascript, "../gleam_stdlib.mjs", "floor") -fn do_floor(a: Float) -> Float - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -@target(erlang) -@external(erlang, "erlang", "round") -fn do_round(a: Float) -> Int - -@target(javascript) -fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "round") -fn js_round(a: Float) -> Int - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../gleam_stdlib.mjs", "truncate") -fn do_truncate(a: Float) -> Int - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../gleam_stdlib.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Generates a random float between the given minimum and maximum values. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(min: Float, max: Float) -> Float { - do_random_uniform() *. { max -. min } +. min -} - -/// Returns a random float uniformly distributed in the value range -/// 0.0 =< X < 1.0 and updates the state in the process dictionary. -/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> -/// -@external(erlang, "rand", "uniform") -@external(javascript, "../gleam_stdlib.mjs", "random_uniform") -fn do_random_uniform() -> Float - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index d93c16afaf6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,874 +0,0 @@ -//// Functions for working with integers. -//// -//// ## Division by zero -//// -//// In Erlang division by zero results in a crash, however Gleam does not have -//// partial functions and operators in core so instead division by zero returns -//// zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/float -import gleam/order.{type Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_int") -@external(javascript, "../gleam_stdlib.mjs", "parse_int") -fn do_parse(a: String) -> Result(Int, Nil) - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -@external(erlang, "gleam_stdlib", "int_from_base_string") -@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") -fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "to_string") -fn do_to_string(a: Int) -> String - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") -fn do_to_base_string(a: Int, b: Int) -> String - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -@external(erlang, "erlang", "float") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_float(a: Int) -> Float - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Generates a random int between the given minimum and maximum values. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(min: Int, max: Int) -> Int { - float.random(to_float(min), to_float(max)) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} - -/// Calculates the bitwise AND of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "band") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") -pub fn bitwise_and(x: Int, y: Int) -> Int - -/// Calculates the bitwise NOT of its argument. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bnot") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") -pub fn bitwise_not(x: Int) -> Int - -/// Calculates the bitwise OR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") -pub fn bitwise_or(x: Int, y: Int) -> Int - -/// Calculates the bitwise XOR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bxor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") -pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic left bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsl") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") -pub fn bitwise_shift_left(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic right bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsr") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") -pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index 0c0a3eeffe0..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,117 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -@external(erlang, "gleam_stdlib", "print") -@external(javascript, "../gleam_stdlib.mjs", "print") -fn do_print(string string: String) -> Nil - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -@external(erlang, "gleam_stdlib", "print_error") -@external(javascript, "../gleam_stdlib.mjs", "print_error") -fn do_print_error(string string: String) -> Nil - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -@external(erlang, "gleam_stdlib", "println") -@external(javascript, "../gleam_stdlib.mjs", "console_log") -fn do_println(string string: String) -> Nil - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "console_error") -fn do_println_error(string string: String) -> Nil - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "print_debug") -fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index c57e7fd9473..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1530 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option, None, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_map2( - continuation1: fn() -> Action(a), - continuation2: fn() -> Action(b), - with fun: fn(a, b) -> c, -) -> fn() -> Action(c) { - fn() { - case continuation1() { - Stop -> Stop - Continue(a, next_a) -> - case continuation2() { - Stop -> Stop - Continue(b, next_b) -> - Continue(fun(a, b), do_map2(next_a, next_b, fun)) - } - } - } -} - -/// Combines two interators into a single one using the given function. -/// -/// If an iterator is longer than the other the extra elements are dropped. -/// -/// This function does not evaluate the elements of the two iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// let first = from_list([1, 2, 3]) -/// let second = from_list([4, 5, 6]) -/// map2(first, second, fn(x, y) { x + y }) |> to_list -/// // -> [5, 7, 9] -/// ``` -/// -/// ```gleam -/// let first = from_list([1, 2]) -/// let second = from_list(["a", "b", "c"]) -/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list -/// // -> [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2( - iterator1: Iterator(a), - iterator2: Iterator(b), - with fun: fn(a, b) -> c, -) -> Iterator(c) { - do_map2(iterator1.continuation, iterator2.continuation, fun) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Joins a list of iterators into a single iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [[1, 2], [3, 4]] -/// > |> map(from_list) -/// > |> concat -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { - flatten(from_list(iterators)) -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - keeping predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - groups - |> dict.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Dict(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Dict(key, List(element)) { - iterator - |> fold(dict.new(), group_updater(key)) - |> dict.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} - -/// Add a new element to the start of an iterator. -/// -/// This function is for use with `use` expressions, to replicate the behaviour -/// of the `yield` keyword found in other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > use <- iterator.yield(1) -/// > use <- iterator.yield(2) -/// > use <- iterator.yield(3) -/// > iterator.empty() -/// iterator.from_list([1, 2, 3]) -/// ``` -/// -pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { - Iterator(fn() { Continue(element, next().continuation) }) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index a5cffa9b951..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2154 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{type Order} -import gleam/pair -import gleam/dict.{type Dict} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -@target(erlang) -@external(erlang, "erlang", "length") -fn do_length(a: List(a)) -> Int - -@target(javascript) -fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) -} - -@target(javascript) -fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -@target(erlang) -@external(erlang, "lists", "reverse") -fn do_reverse(a: List(a)) -> List(a) - -@target(javascript) -fn do_reverse(list) { - do_reverse_acc(list, []) -} - -@target(javascript) -fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - case dict.get(groups, f(elem)) { - Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> dict.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> dict.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) -/// |> dict.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { - fold(list, dict.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Combines two lists into a single list using the given function. -/// -/// If a list is longer than the other the extra elements are dropped. -/// -/// ## Examples -/// -/// ```gleam -/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) -/// [5, 7, 9] -/// ``` -/// -/// ```gleam -/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) -/// [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { - do_map2(list1, list2, fun, []) -} - -fn do_map2( - list1: List(a), - list2: List(b), - fun: fn(a, b) -> c, - acc: List(c), -) -> List(c) { - case list1, list2 { - [], _ | _, [] -> reverse(acc) - [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) - } -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -@target(erlang) -@external(erlang, "lists", "append") -fn do_append(a: List(a), b: List(a)) -> List(a) - -@target(javascript) -fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) -} - -@target(javascript) -fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Joins a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn concat(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// This is the same as `concat`: it joins a list of lists into a single -/// list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// Maps the list with the given function into a list of lists, and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> concat -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> [stop, ..acc] - order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) - order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, finds all tuples that have a given -/// key as the first element and returns the second element. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") -/// [0, 2] -/// ``` -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1)], "c") -/// [] -/// ``` -/// -pub fn key_filter( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> List(v) { - filter_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> concat - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> concat -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> concat -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> concat - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [elem_pair, ..enumerable] -> - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calculate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 1f8b228eb90..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,127 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(map) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@target(javascript) -fn do_filter(f: fn(key, value) -> Bool, map) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 12ce01136ca..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,133 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > negate(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -pub fn negate(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} - -/// Inverts an ordering function, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > list.sort([1, 5, 4], by: reverse(int.compare)) -/// [5, 4, 1] -/// ``` -/// -pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { - fn(a, b) { orderer(b, a) } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index 9ffda789f6a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,214 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{type Option} - -pub type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -@external(erlang, "gleam_stdlib", "compile_regex") -@external(javascript, "../gleam_stdlib.mjs", "compile_regex") -fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -@external(erlang, "gleam_stdlib", "regex_check") -@external(javascript, "../gleam_stdlib.mjs", "regex_check") -fn do_check(a: Regex, b: String) -> Bool - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "regex_split") -fn do_split(a: Regex, b: String) -> List(String) - -@target(javascript) -fn do_split(regex, string) -> List(String) { - js_split(string, regex) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn js_split(a: String, b: Regex) -> List(String) - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -@external(erlang, "gleam_stdlib", "regex_scan") -@external(javascript, "../gleam_stdlib.mjs", "regex_scan") -fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index fb6dddb3110..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,482 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// "Updates" an `Ok` result by passing its value to a function that yields a result, -/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) -/// -/// If the input is an `Error` rather than an `Ok`, the function is not called and -/// the original `Error` is returned. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), Error("a"), Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index df8d500e804..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/dict.{type Dict} -import gleam/result - -// A list is used as the map value as an empty list has the smallest -// representation in Erlang's binary format -@target(erlang) -type Token = - List(Nil) - -@target(erlang) -const token = [] - -@target(javascript) -type Token = - Nil - -@target(javascript) -const token = Nil - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Dict(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(dict.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - dict.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: dict.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> dict.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: dict.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - dict.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: dict.new(), - with: fn(m, k) { dict.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - keeping predicate: fn(member) -> Bool, -) -> Set(member) { - Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(dict.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case dict.size(first.map) > dict.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index 7254fd9fd1c..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,913 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{type Iterator} -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/order -import gleam/string_builder.{type StringBuilder} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -@external(erlang, "string", "length") -@external(javascript, "../gleam_stdlib.mjs", "string_length") -fn do_length(a: String) -> Int - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -@target(erlang) -fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string -} - -@target(javascript) -fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: String) -> String - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: String) -> String - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -@external(erlang, "gleam_stdlib", "less_than") -@external(javascript, "../gleam_stdlib.mjs", "less_than") -fn less_than(a: String, b: String) -> Bool - -/// Takes a substring given a start grapheme index and a length. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -@target(erlang) -@external(erlang, "string", "slice") -fn do_slice(a: String, b: Int, c: Int) -> String - -@target(javascript) -fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -@external(erlang, "gleam_stdlib", "crop_string") -@external(javascript, "../gleam_stdlib.mjs", "crop_string") -pub fn crop(from string: String, before substring: String) -> String - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -@external(erlang, "gleam_stdlib", "contains_string") -@external(javascript, "../gleam_stdlib.mjs", "contains_string") -pub fn contains(does haystack: String, contain needle: String) -> Bool - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -@external(erlang, "gleam_stdlib", "string_starts_with") -@external(javascript, "../gleam_stdlib.mjs", "starts_with") -fn do_starts_with(a: String, b: String) -> Bool - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -@external(erlang, "gleam_stdlib", "string_ends_with") -@external(javascript, "../gleam_stdlib.mjs", "ends_with") -fn do_ends_with(a: String, b: String) -> Bool - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: String, b: String) -> List(String) - -@target(erlang) -fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split_once") -fn do_split_once( - x x: String, - substring substring: String, -) -> Result(#(String, String), Nil) - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - do_join(strings, separator) -} - -@target(erlang) -fn do_join(strings: List(String), separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "join") -fn do_join(strings strings: List(String), string string: String) -> String - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -@target(erlang) -fn do_trim(string: String) -> String { - erl_trim(string, Both) -} - -@target(erlang) -type Direction { - Leading - Trailing - Both -} - -@target(erlang) -@external(erlang, "string", "trim") -fn erl_trim(a: String, b: Direction) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim") -fn do_trim(string string: String) -> String - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -@target(erlang) -fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_left") -fn do_trim_left(string string: String) -> String - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -@target(erlang) -fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_right") -fn do_trim_right(string string: String) -> String - -/// Splits a non-empty `String` into its first element (head) and rest (tail). -/// This lets you pattern match on `String`s exactly as you would with lists. -/// -/// Note on JavaScript using the function to iterate over a string will likely -/// be slower than using `to_graphemes` due to string slicing being more -/// expensive on JavaScript than Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -@external(erlang, "gleam_stdlib", "string_pop_grapheme") -@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") -fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "codepoint") -fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -@target(erlang) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(<<string:utf8>>, []) - |> list.reverse -} - -@target(erlang) -fn do_to_utf_codepoints_impl( - bit_array: BitArray, - acc: List(UtfCodepoint), -) -> List(UtfCodepoint) { - case bit_array { - <<first:utf8_codepoint, rest:bytes>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - _ -> acc - } -} - -@target(javascript) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") -fn string_to_codepoint_integer_list(a: String) -> List(Int) - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") -/// > utf_codepoint_to_int(utf_codepoint) -/// 128156 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") -fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -@external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam_stdlib.mjs", "inspect") -fn do_inspect(term term: anything) -> StringBuilder - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -/// ## Examples -/// -/// ```gleam -/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") -/// 58 -/// ``` -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "byte_size") -pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 5792ca8699d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,298 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -@external(erlang, "gleam_stdlib", "iodata_append") -@external(javascript, "../gleam_stdlib.mjs", "add") -fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_from_strings(a: List(String)) -> StringBuilder - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_concat(a: List(StringBuilder)) -> StringBuilder - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from_string(a: String) -> StringBuilder - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -@external(erlang, "unicode", "characters_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_string(a: StringBuilder) -> String - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -@external(erlang, "erlang", "iolist_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn do_byte_size(a: StringBuilder) -> Int - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -@target(erlang) -@external(erlang, "string", "reverse") -fn do_reverse(a: StringBuilder) -> StringBuilder - -@target(javascript) -fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -fn do_to_graphemes(string string: String) -> List(String) - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -@target(erlang) -type Direction { - All -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) - -@target(erlang) -fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn do_split( - builder builder: StringBuilder, - pattern pattern: String, -) -> List(StringBuilder) - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -@target(erlang) -fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, -) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) -} - -@target(erlang) -@external(erlang, "string", "replace") -fn erl_replace( - a: StringBuilder, - b: String, - c: String, - d: Direction, -) -> StringBuilder - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_replace") -fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -@external(erlang, "string", "equal") -@external(javascript, "../gleam_stdlib.mjs", "equal") -fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -@target(erlang) -@external(erlang, "string", "is_empty") -fn do_is_empty(a: StringBuilder) -> Bool - -@target(javascript) -fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 11f6ea68cd2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,462 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/string -import gleam/string_builder.{type StringBuilder} -@target(javascript) -import gleam/pair -@target(javascript) -import gleam/regex -@target(javascript) -import gleam/result - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "uri_parse") -fn do_parse(a: String) -> Result(Uri, Nil) - -@target(javascript) -fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) -} - -@target(javascript) -fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) -} - -@target(javascript) -fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } -} - -@target(javascript) -fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } -} - -// Split an authority into its userinfo, host and port parts. -@target(javascript) -fn split_authority( - authority: Option(String), -) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } -} - -@target(javascript) -fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) -} - -@target(javascript) -fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -@external(erlang, "gleam_stdlib", "parse_query") -@external(javascript, "../gleam_stdlib.mjs", "parse_query") -fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -@external(erlang, "gleam_stdlib", "percent_encode") -@external(javascript, "../gleam_stdlib.mjs", "percent_encode") -fn do_percent_encode(a: String) -> String - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -@external(erlang, "gleam_stdlib", "percent_decode") -@external(javascript, "../gleam_stdlib.mjs", "percent_decode") -fn do_percent_decode(a: String) -> Result(String, Nil) - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - _, _, _ -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - _ -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65bc3f63e4d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - gleam@bit_array:base64_encode(Input, Padding). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - gleam@bit_array:base64_decode(Encoded). - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - gleam@bit_array:base64_url_encode(Input, Padding). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl deleted file mode 100644 index ba18dfaabdd..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(gleam@bit_array). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_arrays) -> - gleam_stdlib:bit_array_concat(Bit_arrays). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam_stdlib:bit_array_concat([First, Second]). - --spec base64_encode(bitstring(), boolean()) -> binary(). -base64_encode(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_decode(Encoded) -> - Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec base64_url_encode(bitstring(), boolean()) -> binary(). -base64_url_encode(Input, Padding) -> - _pipe = base64_encode(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_url_decode(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - base64_decode(_pipe@2). - --spec base16_encode(bitstring()) -> binary(). -base16_encode(Input) -> - binary:encode_hex(Input). - --spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base16_decode(Input) -> - gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 284c6d46cc3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,66 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). - --spec new() -> gleam@bytes_builder:bytes_builder(). -new() -> - gleam@bytes_builder:new(). - --spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -prepend(To, Prefix) -> - gleam@bytes_builder:prepend(To, Prefix). - --spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -append(To, Suffix) -> - gleam@bytes_builder:append(To, Suffix). - --spec prepend_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -prepend_builder(To, Prefix) -> - gleam@bytes_builder:prepend_builder(To, Prefix). - --spec append_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -prepend_string(To, Prefix) -> - gleam@bytes_builder:prepend_string(To, Prefix). - --spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -append_string(To, Suffix) -> - gleam@bytes_builder:append_string(To, Suffix). - --spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 7dabaa3bbc1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam@bit_array:append(First, Second). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - gleam@bit_array:is_utf8(Bits). - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - gleam@bit_array:to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 5f95f4d8314..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,162 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. - --spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. -lazy_guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence(); - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl deleted file mode 100644 index 2f6dd93a9f3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl +++ /dev/null @@ -1,87 +0,0 @@ --module(gleam@bytes_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). --export_type([bytes_builder/0]). - --opaque bytes_builder() :: {bytes, bitstring()} | - {text, gleam@string_builder:string_builder()} | - {many, list(bytes_builder())}. - --spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -prepend_builder(Second, First) -> - gleam_stdlib:iodata_append(First, Second). - --spec concat(list(bytes_builder())) -> bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec new() -> bytes_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_string(binary()) -> bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). -prepend_string(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append_string(bytes_builder(), binary()) -> bytes_builder(). -append_string(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_array(bitstring()) -> bytes_builder(). -from_bit_array(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). -prepend(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append(bytes_builder(), bitstring()) -> bytes_builder(). -append(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). -concat_bit_arrays(Bits) -> - gleam_stdlib:identity(Bits). - --spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). -to_list(Stack, Acc) -> - case Stack of - [] -> - Acc; - - [[] | Remaining_stack] -> - to_list(Remaining_stack, Acc); - - [[{bytes, Bits} | Rest] | Remaining_stack@1] -> - to_list([Rest | Remaining_stack@1], [Bits | Acc]); - - [[{text, Builder} | Rest@1] | Remaining_stack@2] -> - Bits@1 = gleam_stdlib:identity( - gleam@string_builder:to_string(Builder) - ), - to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); - - [[{many, Builders} | Rest@2] | Remaining_stack@3] -> - to_list([Builders, Rest@2 | Remaining_stack@3], Acc) - end. - --spec to_bit_array(bytes_builder()) -> bitstring(). -to_bit_array(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl deleted file mode 100644 index 99c231e18cc..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@dict). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). --export_type([dict/2]). - --type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. - --spec size(dict(any(), any())) -> integer(). -size(Dict) -> - maps:size(Dict). - --spec to_list(dict(NZ, OA)) -> list({NZ, OA}). -to_list(Dict) -> - maps:to_list(Dict). - --spec from_list(list({OJ, OK})) -> dict(OJ, OK). -from_list(List) -> - maps:from_list(List). - --spec has_key(dict(OT, any()), OT) -> boolean(). -has_key(Dict, Key) -> - maps:is_key(Key, Dict). - --spec new() -> dict(any(), any()). -new() -> - maps:new(). - --spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). -insert(Dict, Key, Value) -> - maps:put(Key, Value, Dict). - --spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). -map_values(Dict, Fun) -> - maps:map(Fun, Dict). - --spec keys(dict(QV, any())) -> list(QV). -keys(Dict) -> - maps:keys(Dict). - --spec values(dict(any(), RG)) -> list(RG). -values(Dict) -> - maps:values(Dict). - --spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). -filter(Dict, Predicate) -> - maps:filter(Predicate, Dict). - --spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). -take(Dict, Desired_keys) -> - maps:with(Desired_keys, Dict). - --spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). -merge(Dict, New_entries) -> - maps:merge(Dict, New_entries). - --spec delete(dict(TF, TG), TF) -> dict(TF, TG). -delete(Dict, Key) -> - maps:remove(Key, Dict). - --spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). -drop(Dict, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Dict; - - [X | Xs] -> - drop(delete(Dict, X), Xs) - end. - --spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). -update(Dict, Key, Fun) -> - _pipe = Dict, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Dict, Key, _pipe@3). - --spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. -fold(Dict, Initial, Fun) -> - _pipe = Dict, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 2c6016f4222..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,808 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). - --type dynamic_() :: any(). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type unknown_tuple() :: any(). - --spec from(any()) -> dynamic_(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic_()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_array(Data) -> - gleam_stdlib:decode_bit_array(Data). - --spec bit_string(dynamic_()) -> {ok, bitstring()} | - {error, list(decode_error())}. -bit_string(Data) -> - bit_array(Data). - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec classify(dynamic_()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - gleam@option:option(DGM)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, - DKT} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((DKX) -> DKY), - fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec result( - fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - list(DGH)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec map_errors( - {ok, DEV} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, DEV} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec decode_string(dynamic_()) -> {ok, binary()} | - {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_array(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_array:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitArray"/utf8>>, - []}]} - end end - ). - --spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec field( - any(), - fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec dict( - fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | - {error, list(decode_error())}). -dict(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@dict:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end - ) - end - ) - end. - --spec map( - fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - dict(Key_type, Value_type). - --spec decode2( - fun((DLB, DLC) -> DLD), - fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((DLH, DLI, DLJ) -> DLK), - fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((DLP, DLQ, DLR, DLS) -> DLT), - fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((DLZ, DMA, DMB, DMC, DMD) -> DME), - fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), - fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), - fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), - fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), - fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index 33b3d4a3e3f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,181 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= +0.0 of - true -> - X; - - _ -> - +0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > +0.0, - case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent - < +0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, +0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. - --spec random(float(), float()) -> float(). -random(Min, Max) -> - (rand:uniform() * (Max - Min)) + Min. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - +0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - +0.0 -> +0.0; - -0.0 -> -0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index c58c0fe151b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(AS) -> AS. -identity(X) -> - X. - --spec constant(AT) -> fun((any()) -> AT). -constant(Value) -> - fun(_) -> Value end. - --spec tap(AV, fun((AV) -> any())) -> AV. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((AX) -> AY), AX) -> AY. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 2a5dd2c8a1d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,332 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. - --spec random(integer(), integer()) -> integer(). -random(Min, Max) -> - _pipe = gleam@float:random(to_float(Min), to_float(Max)), - _pipe@1 = gleam@float:floor(_pipe), - gleam@float:round(_pipe@1). - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec bitwise_and(integer(), integer()) -> integer(). -bitwise_and(X, Y) -> - erlang:'band'(X, Y). - --spec bitwise_not(integer()) -> integer(). -bitwise_not(X) -> - erlang:'bnot'(X). - --spec bitwise_or(integer(), integer()) -> integer(). -bitwise_or(X, Y) -> - erlang:'bor'(X, Y). - --spec bitwise_exclusive_or(integer(), integer()) -> integer(). -bitwise_exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec bitwise_shift_left(integer(), integer()) -> integer(). -bitwise_shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec bitwise_shift_right(integer(), integer()) -> integer(). -bitwise_shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 82865bbafa6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ENH) -> ENH. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index a667ae1ac4b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,744 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. - --opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. - --type step(BSE, BSF) :: {next, BSE, BSF} | done. - --type chunk(BSG, BSH) :: {another_by, - list(BSG), - BSH, - BSG, - fun(() -> action(BSG))} | - {last_by, list(BSG)}. - --type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | - {last, list(BSI)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BSV)) -> iterator(BSV). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BSX) -> iterator(BSX). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BSZ)) -> iterator(BSZ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec do_transform( - fun(() -> action(BTC)), - BTE, - fun((BTE, BTC) -> step(BTF, BTE)) -) -> fun(() -> action(BTF)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BTY)) -> list(BTY). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BUJ), integer()) -> iterator(BUJ). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BUP), integer()) -> iterator(BUP). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec do_map2( - fun(() -> action(BVA)), - fun(() -> action(BVC)), - fun((BVA, BVC) -> BVE) -) -> fun(() -> action(BVE)). -do_map2(Continuation1, Continuation2, Fun) -> - fun() -> case Continuation1() of - stop -> - stop; - - {continue, A, Next_a} -> - case Continuation2() of - stop -> - stop; - - {continue, B, Next_b} -> - {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} - end - end end. - --spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). -map2(Iterator1, Iterator2, Fun) -> - _pipe = do_map2( - erlang:element(2, Iterator1), - erlang:element(2, Iterator2), - Fun - ), - {iterator, _pipe}. - --spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BVY))) -> iterator(BVY). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec concat(list(iterator(BWC))) -> iterator(BWC). -concat(Iterators) -> - flatten(from_list(Iterators)). - --spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec cycle(iterator(BWR)) -> iterator(BWR). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), - BXD})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BXG)) -> iterator({integer(), BXG}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, - BYH})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BZU), BZU) -> iterator(BZU). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), - gleam@dict:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> CBH)) -> iterator(CBH). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec single(CBJ) -> iterator(CBJ). -single(Elem) -> - once(fun() -> Elem end). - --spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(CBT)), - fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), - CBV -) -> CBV. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(CBX), - CBZ, - fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) -) -> CBZ. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(CCB)), - fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), - CCD -) -> {ok, CCD} | {error, CCE}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, - CCL} | - {error, CCM}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). - --spec each(iterator(CDD), fun((CDD) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). -yield(Element, Next) -> - {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index cb6c9e44af2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1136 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(XF)) -> list(XF). -reverse(Xs) -> - lists:reverse(Xs). - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec contains(list(XN), XN) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec first(list(XP)) -> {ok, XP} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@dict:insert(Groups, F(Elem), [Elem]) - end end. - --spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). -map(List, Fun) -> - do_map(List, Fun, []). - --spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). -do_map2(List1, List2, Fun, Acc) -> - case {List1, List2} of - {[], _} -> - reverse(Acc); - - {_, []} -> - reverse(Acc); - - {[A | As_], [B | Bs]} -> - do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) - end. - --spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). -map2(List1, List2, Fun) -> - do_map2(List1, List2, Fun, []). - --spec do_index_map( - list(ABJ), - fun((integer(), ABJ) -> ABL), - integer(), - list(ABL) -) -> list(ABL). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, - list(ABU)} | - {error, ABV}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, - list(ACE)} | - {error, ACF}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(ACL), integer()) -> list(ACL). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(ACS), integer()) -> list(ACS). -take(List, N) -> - do_take(List, N, []). - --spec new() -> list(any()). -new() -> - []. - --spec append(list(ACX), list(ACX)) -> list(ACX). -append(First, Second) -> - lists:append(First, Second). - --spec prepend(list(ADF), ADF) -> list(ADF). -prepend(List, Item) -> - [Item | List]. - --spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). -do_concat(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_concat(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec concat(list(list(ADR))) -> list(ADR). -concat(Lists) -> - do_concat(Lists, []). - --spec flatten(list(list(ADV))) -> list(ADV). -flatten(Lists) -> - do_concat(Lists, []). - --spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - concat(_pipe). - --spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). -group(List, Key) -> - fold(List, gleam@dict:new(), update_group(Key)). - --spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, - list(ABH)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold( - list(AEK), - AEM, - fun((AEM, AEK, integer()) -> AEM), - integer() -) -> AEM. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, - AES} | - {error, AET}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(AGX), AGX) -> list(AGX). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec unique(list(AHE)) -> list(AHE). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(AHH), - list(AHH), - list(AHH), - fun((AHH, AHH) -> gleam@order:order()) -) -> list(AHH). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_down( - integer(), - integer(), - list(AHM), - list(AHM), - list(AHM), - fun((AHM, AHM) -> gleam@order:order()) -) -> list(AHM). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_sort( - list(AHR), - integer(), - fun((AHR, AHR) -> gleam@order:order()), - boolean() -) -> list(AHR). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - [Stop | Acc]; - - gt -> - tail_recursive_range(Start, Stop + 1, [Stop | Acc]); - - lt -> - tail_recursive_range(Start, Stop - 1, [Stop | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(AID, integer()) -> list(AID). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), - list(AIO)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). -key_filter(Keyword_list, Desired_key) -> - filter_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, - {AZQ, list(AZQ)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, - {BAR, list(BAE)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, - {AJV, list(AJT)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AKM), fun((AKM) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | - {error, AKS}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), - list(BBY)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(ALG)) -> list(list(ALG)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - concat(_pipe@5) - end. - --spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(ALQ), integer()) -> list(list(ALQ)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec window_by_2(list(ALU)) -> list({ALU, ALU}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AMU), - integer(), - integer(), - list(AMU), - list(list(AMU)) -) -> list(list(AMU)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec last(list(ANS)) -> {ok, ANS} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec combinations(list(ANW), integer()) -> list(list(ANW)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AOE)) -> list({AOE, AOE}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - concat(_pipe). - --spec transpose(list(list(AOL))) -> list(list(AOL)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - concat(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AOH))) -> list(AOH). -interleave(List) -> - _pipe = transpose(List), - concat(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - [Elem_pair | Enumerable] -> - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec shuffle(list(AOX)) -> list(AOX). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index 9f45b107384..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). - --spec size(gleam@dict:dict(any(), any())) -> integer(). -size(Map) -> - gleam@dict:size(Map). - --spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). -to_list(Map) -> - gleam@dict:to_list(Map). - --spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). -from_list(List) -> - gleam@dict:from_list(List). - --spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). -has_key(Map, Key) -> - gleam@dict:has_key(Map, Key). - --spec new() -> gleam@dict:dict(any(), any()). -new() -> - gleam@dict:new(). - --spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. -get(From, Get) -> - gleam@dict:get(From, Get). - --spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). -insert(Map, Key, Value) -> - gleam@dict:insert(Map, Key, Value). - --spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). -map_values(Map, Fun) -> - gleam@dict:map_values(Map, Fun). - --spec keys(gleam@dict:dict(FED, any())) -> list(FED). -keys(Map) -> - gleam@dict:keys(Map). - --spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). -values(Map) -> - gleam@dict:values(Map). - --spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). -filter(Map, Predicate) -> - gleam@dict:filter(Map, Predicate). - --spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). -take(Map, Desired_keys) -> - gleam@dict:take(Map, Desired_keys). - --spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). -merge(Map, New_entries) -> - gleam@dict:merge(Map, New_entries). - --spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). -delete(Map, Key) -> - gleam@dict:delete(Map, Key). - --spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). -drop(Map, Disallowed_keys) -> - gleam@dict:drop(Map, Disallowed_keys). - --spec update( - gleam@dict:dict(FFB, FFC), - FFB, - fun((gleam@option:option(FFC)) -> FFC) -) -> gleam@dict:dict(FFB, FFC). -update(Map, Key, Fun) -> - gleam@dict:update(Map, Key, Fun). - --spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. -fold(Map, Initial, Fun) -> - gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 812aa1fe854..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). --export_type([option/1]). - --type option(IY) :: {some, IY} | none. - --spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(JF))) -> option(list(JF)). -all(List) -> - do_all(List, []). - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, JU} | {error, any()}) -> option(JU). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(JZ), JZ) -> JZ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(KD), fun((KD) -> KF)) -> option(KF). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(KH))) -> option(KH). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(KQ), option(KQ)) -> option(KQ). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_values(list(option(KY)), list(KY)) -> list(KY). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(LD))) -> list(LD). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index a9eed8f39c1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec negate(order()) -> order(). -negate(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. - --spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). -reverse(Orderer) -> - fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2452a9817e1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({IJ, any()}) -> IJ. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), IM}) -> IM. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({IN, IO}) -> {IO, IN}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(IV, IW) -> {IV, IW}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index faec6923a14..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(EYN)) -> queue(EYN). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(EYQ)) -> list(EYQ). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EYX), EYX) -> queue(EYX). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EZA), EZA) -> queue(EZA). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec reverse(queue(EZN)) -> queue(EZN). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec check_equal( - list(EZQ), - list(EZQ), - list(EZQ), - list(EZQ), - fun((EZQ, EZQ) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EZY), queue(EZY)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index 2d1c5fc870e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([regex/0, match/0, compile_error/0, options/0]). - --type regex() :: any(). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index c80a7048303..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | - {error, BIK}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | - {error, BIU}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | - {error, BIY}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, - BJJ} | - {error, BJG}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, - BJS} | - {error, BJP}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | - {error, BKT}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, - BLA} | - {error, BLB}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), - list(BLY)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. -partition(Results) -> - do_partition(Results, [], []). - --spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BMT} | {error, any()})) -> list(BMT). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BMZ} | {error, BNA}, - fun((BNA) -> {ok, BMZ} | {error, BND}) -) -> {ok, BMZ} | {error, BND}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index 3374ebc293f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@dict:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@dict:size(erlang:element(2, Set)). - --spec insert(set(EOQ), EOQ) -> set(EOQ). -insert(Set, Member) -> - {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOT), EOT) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@dict:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EOV), EOV) -> set(EOV). -delete(Set, Member) -> - {set, gleam@dict:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOY)) -> list(EOY). -to_list(Set) -> - gleam@dict:keys(erlang:element(2, Set)). - --spec from_list(list(EPB)) -> set(EPB). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@dict:new(), - fun(M, K) -> gleam@dict:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. -fold(Set, Initial, Reducer) -> - gleam@dict:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). -filter(Set, Predicate) -> - {set, - gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. - --spec drop(set(EPK), list(EPK)) -> set(EPK). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPO), list(EPO)) -> set(EPO). -take(Set, Desired) -> - {set, gleam@dict:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. -order(First, Second) -> - case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPX), set(EPX)) -> set(EPX). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EQB), set(EQB)) -> set(EQB). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 6cba31d1895..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,352 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - gleam_stdlib:crop_string(String, Substring). - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - gleam_stdlib:contains_string(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_join(list(binary()), binary()) -> binary(). -do_join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - do_join(Strings, Separator). - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_array, Acc) -> - case Bit_array of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - _ -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 693e840f370..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([string_builder/0, direction/0]). - --type string_builder() :: any(). - --type direction() :: all. - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index a36df375281..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,252 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {_, _, _} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(ETW)) -> list(ETW). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - _ -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index 76aa1ea673c..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,31 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.33.1"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_array, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@bytes_builder, - gleam@dict, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index c6ea1257110..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,529 +0,0 @@ --module(gleam_stdlib). - --export([ - map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, - parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, - wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, - bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, - println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, - int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1 -]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - --define(is_lowercase_char(X), (X > 96 andalso X < 123)). --define(is_underscore_char(X), (X == 95)). --define(is_digit_char(X), (X > 47 andalso X < 58)). - -uppercase(X) -> X - 32. - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_array_concat(BitArrays) -> - list_to_bitstring(BitArrays). - -bit_array_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_array_int_to_u32(_) -> - {error, nil}. - -bit_array_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_array_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:_ -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(nil) -> - "Nil"; -inspect(Data) when is_map(Data) -> - Fields = [ - [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] - || {Key, Value} <- maps:to_list(Data) - ], - ["dict.from_list([", lists:join(", ", Fields), "])"]; -inspect(Atom) when is_atom(Atom) -> - Binary = erlang:atom_to_binary(Atom), - case inspect_maybe_gleam_atom(Binary, none, <<>>) of - {ok, Inspected} -> Inspected; - {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] - end; -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(Bits) when is_bitstring(Bits) -> - inspect_bit_array(Bits); -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - - -inspect_maybe_gleam_atom(<<>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc) - when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, $_, Acc); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); -inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> - {ok, Acc}; -inspect_maybe_gleam_atom(A, B, C) -> - erlang:display({A, B, C}), - throw({gleam_error, A, B, C}). - -inspect_list([]) -> - {proper, []}; -inspect_list([First]) -> - {proper, [inspect(First)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_bit_array(Bits) -> - Text = inspect_bit_array(Bits, <<"<<">>), - <<Text/binary, ">>">>. - -inspect_bit_array(<<>>, Acc) -> - Acc; -inspect_bit_array(<<X, Rest/bitstring>>, Acc) -> - inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); -inspect_bit_array(Rest, Acc) -> - Size = bit_size(Rest), - <<X:Size>> = Rest, - X1 = erlang:integer_to_binary(X), - Size1 = erlang:integer_to_binary(Size), - Segment = <<X1/binary, ":size(", Size1/binary, ")">>, - inspect_bit_array(<<>>, append_segment(Acc, Segment)). - -append_segment(<<"<<">>, Segment) -> - <<"<<", Segment/binary>>; -append_segment(Acc, Segment) -> - <<Acc/binary, ", ", Segment/binary>>. - - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<First/utf8, Rest/binary>> -> - Escaped = case First of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). - -utf_codepoint_list_to_string(List) -> - case unicode:characters_to_binary(List) of - {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); - Binary -> Binary - end. - -crop_string(String, Prefix) -> - case string:find(String, Prefix) of - nomatch -> String; - New -> New - end. - -contains_string(String, Substring) -> - is_bitstring(string:find(String, Substring)). - -base16_decode(String) -> - try - {ok, binary:decode_hex(String)} - catch - _:_ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 45c28cfc87b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,878 +0,0 @@ -import { - BitArray, - Error, - List, - Ok, - Result, - UtfCodepoint, - stringBits, - toBitArray, - NonEmpty, - CustomType, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import Dict from "./dict.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - const iterator = graphemes_iterator(string); - if (iterator) { - return List.fromArray(Array.from(iterator).map((item) => item.segment)); - } else { - return List.fromArray(string.match(/./gsu)); - } -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs, separator) { - const iterator = xs[Symbol.iterator](); - let result = iterator.next().value || ""; - let current = iterator.next(); - while (!current.done) { - result = result + separator + current.value; - current = iterator.next(); - } - return result; -} - -export function concat(xs) { - let result = ""; - for (const x of xs) { - result = result + x; - } - return result; -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function contains_string(haystack, needle) { - return haystack.indexOf(needle) >= 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_array_from_string(string) { - return toBitArray([stringBits(string)]); -} - -export function bit_array_concat(bit_arrays) { - return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_array_to_string(bit_array) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_array.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_array_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitArray(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return Dict.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_array) { - const aBytes = bit_array.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitArray(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (data instanceof Result) { - return "Result"; - } else if (data instanceof List) { - return "List"; - } else if (data instanceof BitArray) { - return "BitArray"; - } else if (data instanceof Dict) { - return "Map"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_array(data) { - if (data instanceof BitArray) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitArray(data)); - } - return decoder_error("BitArray", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - const list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!(data instanceof List)) return; - - const elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (!(current instanceof NonEmpty)) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && !(current instanceof NonEmpty)) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return data instanceof List ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return data instanceof Result ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof Dict) { - return new Ok(Dict.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(Dict.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof Dict || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} - -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function bitwise_and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function bitwise_not(x) { - return Number(~BigInt(x)); -} - -export function bitwise_or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function bitwise_exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function bitwise_shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function bitwise_shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} - -export function inspect(v) { - const t = typeof v; - if (v === true) return "True"; - if (v === false) return "False"; - if (v === null) return "//js(null)"; - if (v === undefined) return "Nil"; - if (t === "string") return JSON.stringify(v); - if (t === "bigint" || t === "number") return v.toString(); - if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; - if (v instanceof List) return inspectList(v); - if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); - if (v instanceof BitArray) return inspectBitArray(v); - if (v instanceof CustomType) return inspectCustomType(v); - if (v instanceof Dict) return inspectDict(v); - if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; - if (v instanceof RegExp) return `//js(${v})`; - if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; - if (v instanceof Function) { - const args = []; - for (const i of Array(v.length).keys()) - args.push(String.fromCharCode(i + 97)); - return `//fn(${args.join(", ")}) { ... }`; - } - return inspectObject(v); -} - -function inspectDict(map) { - let body = "dict.from_list(["; - let first = true; - map.forEach((value, key) => { - if (!first) body = body + ", "; - body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; - first = false; - }); - return body + "])"; -} - -function inspectObject(v) { - const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; - const props = []; - for (const k of Object.keys(v)) { - props.push(`${inspect(k)}: ${inspect(v[k])}`); - } - const body = props.length ? " " + props.join(", ") + " " : ""; - const head = name === "Object" ? "" : name + " "; - return `//js(${head}{${body}})`; -} - -function inspectCustomType(record) { - const props = Object.keys(record) - .map((label) => { - const value = inspect(record[label]); - return isNaN(parseInt(label)) ? `${label}: ${value}` : value; - }) - .join(", "); - return props - ? `${record.constructor.name}(${props})` - : record.constructor.name; -} - -export function inspectList(list) { - return `[${list.toArray().map(inspect).join(", ")}]`; -} - -export function inspectBitArray(bits) { - return `<<${Array.from(bits.buffer).join(", ")}>>`; -} - -export function inspectUtfCodepoint(codepoint) { - return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; -} - -export function base16_encode(bit_array) { - let result = ""; - for (const byte of bit_array.buffer) { - result += byte.toString(16).padStart(2, "0").toUpperCase(); - } - return result; -} - -export function base16_decode(string) { - const bytes = new Uint8Array(string.length / 2); - for (let i = 0; i < string.length; i += 2) { - const a = parseInt(string[i], 16); - const b = parseInt(string[i + 1], 16); - if (isNaN(a) || isNaN(b)) return new Error(Nil); - bytes[i / 2] = a * 16 + b; - } - return new Ok(new BitArray(bytes)); -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE deleted file mode 100644 index c7967c32d6f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2021, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md deleted file mode 100644 index 3ca1c63e98d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# gleeunit - -Gleam bindings to the Erlang EUnit test framework. - -A custom test runner is included for when compiled to JavaScript running on -either NodeJS or Deno. - -Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). - -## Usage - -Add this package to your Gleam project. - -```sh -gleam add gleeunit --dev -``` - -And then call the `gleeunit.main` function from your test main function. - -```gleam -// In test/yourapp_test.gleam -import gleeunit - -pub fn main() { - gleeunit.main() -} -``` - -Now any public function with a name ending in `_test` in the `test` directory -will be found and run as a test. - -```gleam -pub fn the_universe_test() { - let assert 1 = 1 -} -``` - -Run the tests by entering `gleam test` in the command line. - -### Deno - -If using the Deno JavaScript runtime, you will need to add the following to your -`gleam.toml`. - -```toml -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] -``` diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml deleted file mode 100644 index 74b7e202e47..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleeunit" -version = "0.11.0" -licences = ["Apache-2.0"] -description = "Gleam bindings to Erlang's EUnit test framework" - -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] - -[dependencies] -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src deleted file mode 100644 index 2f98842c95e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleeunit, [ - {vsn, "0.11.0"}, - {applications, [gleam_stdlib]}, - {description, "Gleam bindings to Erlang's EUnit test framework"}, - {modules, [gleeunit, - gleeunit@should]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl deleted file mode 100644 index 32e1a833d01..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gleeunit). --compile([no_auto_import, nowarn_unused_vars]). - --export([main/0]). --export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). - --type atom_() :: any(). - --type encoding() :: utf8. - --type report_module_name() :: gleeunit_progress. - --type gleeunit_progress_option() :: {colored, boolean()}. - --type eunit_option() :: verbose | - no_tty | - {report, {report_module_name(), list(gleeunit_progress_option())}}. - --spec gleam_to_erlang_module_name(binary()) -> binary(). -gleam_to_erlang_module_name(Path) -> - _pipe = Path, - _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), - gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). - --spec do_main() -> nil. -do_main() -> - Options = [verbose, - no_tty, - {report, {gleeunit_progress, [{colored, true}]}}], - Result = begin - _pipe = gleeunit_ffi:find_files( - <<"**/*.{erl,gleam}"/utf8>>, - <<"test"/utf8>> - ), - _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end - ), - _pipe@3 = eunit:test(_pipe@2, Options), - _pipe@4 = (gleam@dynamic:result( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ))(_pipe@3), - gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) - end, - Code = case Result of - {ok, _} -> - 0; - - {error, _} -> - 1 - end, - erlang:halt(Code). - --spec main() -> nil. -main() -> - do_main(). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam deleted file mode 100644 index e5d4b460cad..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam +++ /dev/null @@ -1,92 +0,0 @@ -/// Find and run all test functions for the current project using Erlang's EUnit -/// test framework. -/// -/// Any Erlang or Gleam function in the `test` directory with a name editing in -/// `_test` is considered a test function and will be run. -/// -/// If running on JavaScript tests will be run with a custom test runner. -/// -pub fn main() -> Nil { - do_main() -} - -@target(javascript) -@external(javascript, "./gleeunit_ffi.mjs", "main") -fn do_main() -> Nil - -@target(erlang) -import gleam/list -@target(erlang) -import gleam/result -@target(erlang) -import gleam/string -@target(erlang) -import gleam/dynamic.{Dynamic} - -@target(erlang) -fn do_main() -> Nil { - let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] - - let result = - find_files(matching: "**/*.{erl,gleam}", in: "test") - |> list.map(gleam_to_erlang_module_name) - |> list.map(dangerously_convert_string_to_atom(_, Utf8)) - |> run_eunit(options) - |> dynamic.result(dynamic.dynamic, dynamic.dynamic) - |> result.unwrap(Error(dynamic.from(Nil))) - - let code = case result { - Ok(_) -> 0 - Error(_) -> 1 - } - halt(code) -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil - -@target(erlang) -fn gleam_to_erlang_module_name(path: String) -> String { - path - |> string.replace(".gleam", "") - |> string.replace(".erl", "") - |> string.replace("/", "@") -} - -@target(erlang) -@external(erlang, "gleeunit_ffi", "find_files") -fn find_files(matching matching: String, in in: String) -> List(String) - -@target(erlang) -type Atom - -@target(erlang) -type Encoding { - Utf8 -} - -@target(erlang) -@external(erlang, "erlang", "binary_to_atom") -fn dangerously_convert_string_to_atom(a: String, b: Encoding) -> Atom - -@target(erlang) -type ReportModuleName { - GleeunitProgress -} - -@target(erlang) -type GleeunitProgressOption { - Colored(Bool) -} - -@target(erlang) -type EunitOption { - Verbose - NoTty - Report(#(ReportModuleName, List(GleeunitProgressOption))) -} - -@target(erlang) -@external(erlang, "eunit", "test") -fn run_eunit(a: List(Atom), b: List(EunitOption)) -> Dynamic diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam deleted file mode 100644 index c393c232724..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam +++ /dev/null @@ -1,90 +0,0 @@ -//// A module for testing your Gleam code. The functions found here are -//// compatible with the Erlang eunit test framework. -//// -//// More information on running eunit can be found in [the rebar3 -//// documentation](https://rebar3.org/docs/testing/eunit/). - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_equal") -pub fn equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_not_equal") -pub fn not_equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_ok") -pub fn be_ok(a: Result(a, b)) -> a - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_error") -pub fn be_error(a: Result(a, b)) -> b - -@target(javascript) -import gleam/string - -@target(javascript) -@external(javascript, "../gleam.mjs", "inspect") -fn stringify(a: anything) -> String - -@target(javascript) -@external(javascript, "../gleeunit_ffi.mjs", "crash") -fn crash(a: String) -> anything - -@target(javascript) -pub fn equal(a, b) { - case a == b { - True -> Nil - _ -> - crash(string.concat([ - "\n\t", - stringify(a), - "\n\tshould equal \n\t", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn not_equal(a, b) { - case a != b { - True -> Nil - _ -> - crash(string.concat([ - "\n", - stringify(a), - "\nshould not equal \n", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn be_ok(a) { - case a { - Ok(value) -> value - _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) - } -} - -@target(javascript) -pub fn be_error(a) { - case a { - Error(error) -> error - _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) - } -} - -pub fn be_true(actual: Bool) -> Nil { - actual - |> equal(True) -} - -pub fn be_false(actual: Bool) -> Nil { - actual - |> equal(False) -} - -pub fn fail() -> Nil { - be_true(False) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl deleted file mode 100644 index acf032e1e7d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(gleeunit@should). --compile([no_auto_import, nowarn_unused_vars]). - --export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). - --spec equal(EYG, EYG) -> nil. -equal(A, B) -> - gleeunit_ffi:should_equal(A, B). - --spec not_equal(EYH, EYH) -> nil. -not_equal(A, B) -> - gleeunit_ffi:should_not_equal(A, B). - --spec be_ok({ok, EYI} | {error, any()}) -> EYI. -be_ok(A) -> - gleeunit_ffi:should_be_ok(A). - --spec be_error({ok, any()} | {error, EYN}) -> EYN. -be_error(A) -> - gleeunit_ffi:should_be_error(A). - --spec be_true(boolean()) -> nil. -be_true(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, true). - --spec be_false(boolean()) -> nil. -be_false(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, false). - --spec fail() -> nil. -fail() -> - be_true(false). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl deleted file mode 100644 index 31f9ef9e2c9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(gleeunit_ffi). - --export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, - should_be_error/1]). - --include_lib("eunit/include/eunit.hrl"). - -find_files(Pattern, In) -> - Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), - lists:map(fun list_to_binary/1, Results). - - -should_equal(Actual, Expected) -> - ?assertEqual(Expected, Actual), - nil. -should_not_equal(Actual, Expected) -> - ?assertNotEqual(Expected, Actual), - nil. -should_be_ok(A) -> - ?assertMatch({ok, _}, A), - element(2, A). -should_be_error(A) -> - ?assertMatch({error, _}, A), - element(2, A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs deleted file mode 100644 index 339a843e5c5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs +++ /dev/null @@ -1,101 +0,0 @@ -async function* gleamFiles(directory) { - for (let entry of await read_dir(directory)) { - let path = join_path(directory, entry); - if (path.endsWith(".gleam")) { - yield path; - } else { - try { - yield* gleamFiles(path); - } catch (error) { - // Could not read directory, assume it's a file - } - } - } -} - -async function readRootPackageName() { - let toml = await read_file("gleam.toml", "utf-8"); - for (let line of toml.split("\n")) { - let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() - if (matches) return matches[1]; - } - throw new Error("Could not determine package name from gleam.toml"); -} - -export async function main() { - let passes = 0; - let failures = 0; - - let packageName = await readRootPackageName(); - let dist = `../${packageName}/`; - - for await (let path of await gleamFiles("test")) { - let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); - let module = await import(join_path(dist, js_path)); - for (let fnName of Object.keys(module)) { - if (!fnName.endsWith("_test")) continue; - try { - await module[fnName](); - write(`\u001b[32m.\u001b[0m`); - passes++; - } catch (error) { - let moduleName = "\n" + js_path.slice(0, -4); - let line = error.line ? `:${error.line}` : ""; - write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); - failures++; - } - } - } - - console.log(` -${passes + failures} tests, ${failures} failures`); - exit(failures ? 1 : 0); -} - -export function crash(message) { - throw new Error(message); -} - -function write(message) { - if (globalThis.Deno) { - Deno.stdout.writeSync(new TextEncoder().encode(message)); - } else { - process.stdout.write(message); - } -} - -function exit(code) { - if (globalThis.Deno) { - Deno.exit(code); - } else { - process.exit(code); - } -} - -async function read_dir(path) { - if (globalThis.Deno) { - let items = []; - for await (let item of Deno.readDir(path, { withFileTypes: true })) { - items.push(item.name); - } - return items; - } else { - let { readdir } = await import("fs/promises"); - return readdir(path); - } -} - -function join_path(a, b) { - if (a.endsWith("/")) return a + b; - return a + "/" + b; -} - -async function read_file(path) { - if (globalThis.Deno) { - return Deno.readTextFile(path); - } else { - let { readFile } = await import("fs/promises"); - let contents = await readFile(path); - return contents.toString(); - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl deleted file mode 100644 index 1f68eb95e58..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl +++ /dev/null @@ -1,607 +0,0 @@ -%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters - -%% @doc A listener/reporter for eunit that prints '.' for each -%% success, 'F' for each failure, and 'E' for each error. It can also -%% optionally summarize the failures at the end. --compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). --module(gleeunit_progress). --behaviour(eunit_listener). --define(NOTEST, true). --include_lib("eunit/include/eunit.hrl"). - --define(RED, "\e[0;31m"). --define(GREEN, "\e[0;32m"). --define(YELLOW, "\e[0;33m"). --define(WHITE, "\e[0;37m"). --define(CYAN, "\e[0;36m"). --define(RESET, "\e[0m"). - --record(node,{ - rank = 0 :: non_neg_integer(), - key :: term(), - value :: term(), - children = new() :: binomial_heap() - }). - --export_type([binomial_heap/0, heap_node/0]). --type binomial_heap() :: [ heap_node() ]. --type heap_node() :: #node{}. - -%% eunit_listener callbacks --export([ - init/1, - handle_begin/3, - handle_end/3, - handle_cancel/3, - terminate/2, - start/0, - start/1 - ]). - -%% -- binomial_heap.erl content start -- - --record(state, { - status = dict:new() :: euf_dict(), - failures = [] :: [[pos_integer()]], - skips = [] :: [[pos_integer()]], - timings = new() :: binomial_heap(), - colored = true :: boolean(), - profile = false :: boolean() - }). - --type euf_dict() :: dict:dict(). - --spec new() -> binomial_heap(). -new() -> - []. - -% Inserts a new pair into the heap (or creates a new heap) --spec insert(term(), term()) -> binomial_heap(). -insert(Key,Value) -> - insert(Key,Value,[]). - --spec insert(term(), term(), binomial_heap()) -> binomial_heap(). -insert(Key,Value,Forest) -> - insTree(#node{key=Key,value=Value},Forest). - -% Merges two heaps --spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). -merge(TS1,[]) when is_list(TS1) -> TS1; -merge([],TS2) when is_list(TS2) -> TS2; -merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> - if - R1 < R2 -> - [T1 | merge(TS1,F2)]; - R2 < R1 -> - [T2 | merge(F1, TS2)]; - true -> - insTree(link(T1,T2),merge(TS1,TS2)) - end. - -% Deletes the top entry from the heap and returns it --spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. -delete(TS) -> - {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), - {{Key,Value},merge(lists:reverse(TS1),TS2)}. - -% Turns the heap into list in heap order --spec to_list(binomial_heap()) -> [{term(), term()}]. -to_list([]) -> []; -to_list(List) when is_list(List) -> - to_list([],List). -to_list(Acc, []) -> - lists:reverse(Acc); -to_list(Acc,Forest) -> - {Next, Trees} = delete(Forest), - to_list([Next|Acc], Trees). - -% Take N elements from the top of the heap --spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. -take(N,Trees) when is_integer(N), is_list(Trees) -> - take(N,Trees,[]). -take(0,_Trees,Acc) -> - lists:reverse(Acc); -take(_N,[],Acc)-> - lists:reverse(Acc); -take(N,Trees,Acc) -> - {Top,T2} = delete(Trees), - take(N-1,T2,[Top|Acc]). - -% Get an estimate of the size based on the binomial property --spec size(binomial_heap()) -> non_neg_integer(). -size(Forest) -> - erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). - -%% Private API --spec link(heap_node(), heap_node()) -> heap_node(). -link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> - case X1 < X2 of - true -> - T1#node{rank=R+1,children=[T2|C1]}; - _ -> - T2#node{rank=R+1,children=[T1|C2]} - end. - -insTree(Tree, []) -> - [Tree]; -insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> - case R1 < R2 of - true -> - [T1|TS]; - _ -> - insTree(link(T1,T2),Rest) - end. - -getMin([T]) -> - {T,[]}; -getMin([#node{key=K} = T|TS]) -> - {#node{key=K1} = T1,TS1} = getMin(TS), - case K < K1 of - true -> {T,TS}; - _ -> {T1,[T|TS1]} - end. - -%% -- binomial_heap.erl content end -- - -%% Startup -start() -> - start([]). - -start(Options) -> - eunit_listener:start(?MODULE, Options). - -%%------------------------------------------ -%% eunit_listener callbacks -%%------------------------------------------ -init(Options) -> - #state{colored=proplists:get_bool(colored, Options), - profile=proplists:get_bool(profile, Options)}. - -handle_begin(group, Data, St) -> - GID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; -handle_begin(test, Data, St) -> - TID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. - -handle_end(group, Data, St) -> - St#state{status=merge_on_end(Data, St#state.status)}; -handle_end(test, Data, St) -> - NewStatus = merge_on_end(Data, St#state.status), - St1 = print_progress(Data, St), - St2 = record_timing(Data, St1), - St2#state{status=NewStatus}. - -handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> - Status1 = merge_on_end(Data, Status), - ID = proplists:get_value(id, Data), - St#state{status=Status1, skips=[ID|Skips]}. - -terminate({ok, Data}, St) -> - print_failures(St), - print_pending(St), - print_profile(St), - print_timing(St), - print_results(Data, St); -terminate({error, Reason}, St) -> - io:nl(), io:nl(), - print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), - sync_end(error). - -sync_end(Result) -> - receive - {stop, Reference, ReplyTo} -> - ReplyTo ! {result, Reference, Result}, - ok - end. - -%%------------------------------------------ -%% Print and collect information during run -%%------------------------------------------ -print_progress(Data, St) -> - TID = proplists:get_value(id, Data), - case proplists:get_value(status, Data) of - ok -> - print_progress_success(St), - St; - {skipped, _Reason} -> - print_progress_skipped(St), - St#state{skips=[TID|St#state.skips]}; - {error, Exception} -> - print_progress_failed(Exception, St), - St#state{failures=[TID|St#state.failures]} - end. - -record_timing(Data, State=#state{timings=T, profile=true}) -> - TID = proplists:get_value(id, Data), - case lists:keyfind(time, 1, Data) of - {time, Int} -> - %% It's a min-heap, so we insert negative numbers instead - %% of the actuals and normalize when we report on them. - T1 = insert(-Int, TID, T), - State#state{timings=T1}; - false -> - State - end; -record_timing(_Data, State) -> - State. - -print_progress_success(St) -> - print_colored(".", ?GREEN, St). - -print_progress_skipped(St) -> - print_colored("*", ?YELLOW, St). - -print_progress_failed(_Exc, St) -> - print_colored("F", ?RED, St). - -merge_on_end(Data, Dict) -> - ID = proplists:get_value(id, Data), - dict:update(ID, - fun(Old) -> - orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) - end, Dict). - -merge_data(_K, undefined, X) -> X; -merge_data(_K, X, undefined) -> X; -merge_data(_K, _, X) -> X. - -%%------------------------------------------ -%% Print information at end of run -%%------------------------------------------ -print_failures(#state{failures=[]}) -> - ok; -print_failures(#state{failures=Fails}=State) -> - io:nl(), - io:fwrite("Failures:~n",[]), - lists:foldr(print_failure_fun(State), 1, Fails), - ok. - -print_failure_fun(#state{status=Status}=State) -> - fun(Key, Count) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:fwrite("~n ~p) ~ts~n", [Count, TestId]), - print_failure_reason(proplists:get_value(status, TestData), - proplists:get_value(output, TestData), - State), - io:nl(), - Count + 1 - end. - -print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> - X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), - print_colored(X, ?CYAN, State); -print_gleam_location(_, _) -> - ok. - -inspect(X) -> - gleam@string:inspect(X). - -print_gleam_failure_reason( - #{gleam_error := assert, message := Message, value := Value}, - State -) -> - print_colored(indent(5, "~s~n", [Message]), ?RED, State), - print_colored(indent(5, " value: ", []), ?RED, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); -print_gleam_failure_reason( - #{gleam_error := todo, message := Message}, - State -) -> - print_colored(indent(5, "todo expression run~n", []), ?RED, State), - print_colored(indent(5, " message: ", []), ?RED, State), - print_colored(indent(0, "~s~n", [Message]), ?RESET, State); -print_gleam_failure_reason(Error, State) -> - print_colored(indent(5, "~p~n", [Error]), ?RED, State). - -% New Gleeunit specific formatters -print_failure_reason( - {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State -) when is_list(Stack) -> - print_gleam_failure_reason(Error, State), - print_gleam_location(Error, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "No case clause matched~n", []), ?RED, State), - print_colored(indent(5, "Value: ", []), ?CYAN, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -% From the original Erlang version -print_failure_reason({skipped, Reason}, _Output, State) -> - print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), - ?RED, State); -print_failure_reason({error, {_Class, Term, _}}, Output, State) when - is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> - print_assertion_failure(Term, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, Reason}, Output, State) -> - print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), - print_failure_output(5, Output, State). - -gleam_format_module_name(Module) -> - string:replace(atom_to_list(Module), "@", "/", all). - -print_stack(Stack, State) -> - print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), - print_stackframes(Stack, State). -print_stackframes([{eunit_test, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> - GleamModule = gleam_format_module_name(Module), - print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), - print_stackframes(Stack, State); -print_stackframes([], _State) -> - ok. - - -print_failure_output(_, <<>>, _) -> ok; -print_failure_output(_, undefined, _) -> ok; -print_failure_output(Indent, Output, State) -> - print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). - -print_assertion_failure({Type, Props}, State) -> - FailureDesc = format_assertion_failure(Type, Props, 5), - print_colored(FailureDesc, ?RED, State), - io:nl(). - -print_pending(#state{skips=[]}) -> - ok; -print_pending(#state{status=Status, skips=Skips}=State) -> - io:nl(), - io:fwrite("Pending:~n", []), - lists:foreach(fun(ID) -> - Info = dict:fetch(ID, Status), - case proplists:get_value(reason, Info) of - undefined -> - ok; - Reason -> - print_pending_reason(Reason, Info, State) - end - end, lists:reverse(Skips)), - io:nl(). - -print_pending_reason(Reason0, Data, State) -> - Text = case proplists:get_value(type, Data) of - group -> - io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); - test -> - io_lib:format(" ~ts~n", [format_test_identifier(Data)]) - end, - Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), - print_colored(Text, ?YELLOW, State), - print_colored(Reason, ?CYAN, State). - -print_profile(#state{timings=T, status=Status, profile=true}=State) -> - TopN = take(10, T), - TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), - TLG = dict:fetch([], Status), - TotalTime = proplists:get_value(time, TLG), - if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> - TopNPct = (TopNTime / TotalTime) * 100, - io:nl(), io:nl(), - io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), - lists:foreach(print_timing_fun(State), TopN), - io:nl(); - true -> ok - end; -print_profile(#state{profile=false}) -> - ok. - -print_timing(#state{status=Status}) -> - TLG = dict:fetch([], Status), - Time = proplists:get_value(time, TLG), - io:nl(), - io:fwrite("Finished in ~ts~n", [format_time(Time)]), - ok. - -print_results(Data, State) -> - Pass = proplists:get_value(pass, Data, 0), - Fail = proplists:get_value(fail, Data, 0), - Skip = proplists:get_value(skip, Data, 0), - Cancel = proplists:get_value(cancel, Data, 0), - Total = Pass + Fail + Skip + Cancel, - {Color, Result} = if Fail > 0 -> {?RED, error}; - Skip > 0; Cancel > 0 -> {?YELLOW, error}; - Pass =:= 0 -> {?YELLOW, ok}; - true -> {?GREEN, ok} - end, - print_results(Color, Total, Fail, Skip, Cancel, State), - sync_end(Result). - -print_results(Color, 0, _, _, _, State) -> - print_colored(Color, "0 tests\n", State); -print_results(Color, Total, Fail, Skip, Cancel, State) -> - SkipText = format_optional_result(Skip, "skipped"), - CancelText = format_optional_result(Cancel, "cancelled"), - Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), - print_colored(Text, Color, State). - -print_timing_fun(#state{status=Status}=State) -> - fun({Time, Key}) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:nl(), - io:fwrite(" ~ts~n", [TestId]), - print_colored([" "|format_time(abs(Time))], ?CYAN, State) - end. - -%%------------------------------------------ -%% Print to the console with the given color -%% if enabled. -%%------------------------------------------ -print_colored(Text, Color, #state{colored=true}) -> - io:fwrite("~s~ts~s", [Color, Text, ?RESET]); -print_colored(Text, _Color, #state{colored=false}) -> - io:fwrite("~ts", [Text]). - -%%------------------------------------------ -%% Generic data formatters -%%------------------------------------------ -format_function_name(M, F) -> - M1 = gleam_format_module_name(M), - io_lib:format("~ts.~ts", [M1, F]). - -format_optional_result(0, _) -> - []; -format_optional_result(Count, Text) -> - io_lib:format(", ~p ~ts", [Count, Text]). - -format_test_identifier(Data) -> - {Mod, Fun, _} = proplists:get_value(source, Data), - Line = case proplists:get_value(line, Data) of - 0 -> ""; - L -> io_lib:format(":~p", [L]) - end, - Desc = case proplists:get_value(desc, Data) of - undefined -> ""; - DescText -> io_lib:format(": ~ts", [DescText]) - end, - io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). - -format_time(undefined) -> - "? seconds"; -format_time(Time) -> - io_lib:format("~.3f seconds", [Time / 1000]). - -format_pending_reason({module_not_found, M}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Module '~ts' missing", [M1]); -format_pending_reason({no_such_function, {M,F,_}}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); -format_pending_reason({exit, Reason}) -> - io_lib:format("Related process exited with reason: ~p", [Reason]); -format_pending_reason(Reason) -> - io_lib:format("Unknown error: ~p", [Reason]). - -%% @doc Formats all the known eunit assertions, you're on your own if -%% you make an assertion yourself. -format_assertion_failure(Type, Props, I) when Type =:= assertion_failed - ; Type =:= assert -> - Keys = proplists:get_keys(Props), - HasEUnitProps = ([expression, value] -- Keys) =:= [], - HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], - if - HasEUnitProps -> - [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), - indent(I, " expected: true~n", []), - case proplists:get_value(value, Props) of - false -> - indent(I, " got: false", []); - {not_a_boolean, V} -> - indent(I, " got: ~p", [V]) - end]; - HasHamcrestProps -> - [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), - indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), - indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; - true -> - [indent(I, "Failure: unknown assert: ~p", [Props])] - end; - -format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed - ; Type =:= assertMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed - ; Type =:= assertNotMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected not: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed - ; Type =:= assertEqual -> - Expected = inspect(proplists:get_value(expected, Props)), - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were not equal~n", []), - indent(I, "expected: ~ts~n", [Expected]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed - ; Type =:= assertNotEqual -> - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were equal~n", []), - indent(I, "expected: not ~ts~n,", [Value]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertException_failed - ; Type =:= assertException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA - [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - case proplists:is_defined(unexpected_success, Props) of - true -> - [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), - indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; - false -> - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, " expected: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])] - end]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed - ; Type =:= assertNotException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - indent(I, " expected not: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])]; - -format_assertion_failure(Type, Props, I) when Type =:= command_failed - ; Type =:= command -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed - ; Type =:= assertCmd -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed - ; Type =:= assertCmdOutput -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_output, Props), - Output = proplists:get_value(output, Props), - [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: ~p~n", [Expected]), - indent(I, " got: ~p", [Output])]; - -format_assertion_failure(Type, Props, I) -> - indent(I, "~p", [{Type, Props}]). - -indent(I, Fmt, Args) -> - io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). - -extract_exception_pattern(Str) -> - ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), - {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml deleted file mode 100644 index 9e8e814435b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml +++ /dev/null @@ -1,7 +0,0 @@ -[packages] -gleam_community_ansi = "1.2.0" -gleam_otp = "0.8.0" -gleam_erlang = "0.23.1" -gleam_community_colour = "1.2.0" -gleam_stdlib = "0.33.1" -gleeunit = "0.11.0" diff --git a/test-community-packages-javascript/build/packages/glerm/gleam.toml b/test-community-packages-javascript/build/packages/glerm/gleam.toml deleted file mode 100644 index bcd667357ad..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "glerm" -version = "0.1.0" -description = "A terminal wrapper for Gleam" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -licences = ["Apache-2.0"] -repository = { type = "github", user = "rawhat", repo = "glerm" } - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_erlang = "~> 0.19" -gleam_otp = "~> 0.5" -gleam_community_ansi = "~> 1.1" - -[dev-dependencies] -gleeunit = "~> 0.7" diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl deleted file mode 100644 index b2b3067fe7d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(drag, { - button :: glerm:mouse_button(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl deleted file mode 100644 index 9342c911a37..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl +++ /dev/null @@ -1 +0,0 @@ --record(focus, {event :: glerm:focus_event()}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl deleted file mode 100644 index 293b9c94bc7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(key, { - key :: glerm:key_code(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl deleted file mode 100644 index f7ab57fb003..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(listener_spec, { - init :: fun(() -> {any(), - gleam@option:option(gleam@erlang@process:selector(any()))}), - loop :: fun((glerm:listener_message(any()), any()) -> gleam@otp@actor:next(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl deleted file mode 100644 index 4d1e4b707da..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl +++ /dev/null @@ -1 +0,0 @@ --record(mouse, {event :: glerm:mouse_event()}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl deleted file mode 100644 index 858e2ae852d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(mouse_down, { - button :: glerm:mouse_button(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl deleted file mode 100644 index 62eefb79d0d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(mouse_up, { - button :: glerm:mouse_button(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl deleted file mode 100644 index b54f205f739..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unknown, {tag :: binary(), message :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/glerm/manifest.toml b/test-community-packages-javascript/build/packages/glerm/manifest.toml deleted file mode 100644 index c6a2c505615..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/manifest.toml +++ /dev/null @@ -1,18 +0,0 @@ -# This file was generated by Gleam -# You typically do not need to edit this file - -packages = [ - { name = "gleam_community_ansi", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_colour"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8B5A9677BC5A2738712BBAF2BA289B1D8195FDF962BBC769569976AD5E9794E1" }, - { name = "gleam_community_colour", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "036C206886AFB9F153C552700A7A0B4D2864E3BC96A20C77E5F34A013C051BE3" }, - { name = "gleam_erlang", version = "0.23.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "C21CFB816C114784E669FFF4BBF433535EEA9960FA2F216209B8691E87156B96" }, - { name = "gleam_otp", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "18EF8242A5E54BA92F717C7222F03B3228AEE00D1F286D4C56C3E8C18AA2588E" }, - { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, - { name = "gleeunit", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "1397E5C4AC4108769EE979939AC39BF7870659C5AFB714630DEEEE16B8272AD5" }, -] - -[requirements] -gleam_community_ansi = { version = "~> 1.1" } -gleam_erlang = { version = "~> 0.19" } -gleam_otp = { version = "~> 0.5" } -gleam_stdlib = { version = "~> 0.28" } -gleeunit = { version = "~> 0.7" } diff --git a/test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so b/test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so deleted file mode 100755 index 3a0e947838344eaf03b47dc7a9b0f7baa8fd0a94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4550752 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%0AR97K*PPR&ES6o#1ZAkNG| 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 *o3+j zBxrf2xA2D|?aE;)ecdKprUcWhaW+c^M<~Gz;}M(Va3vV{-e(hb{FQ_OJg1E*H5vTV zUr3OsXag}OgAXgmp(JE(qRl0GQ;nJHc)RN%-qfYcMBc8`w*&Qd0dME%O%sL7FsGUH zrb)@1#@l|moLUN>K+#O6GKcW?vffNim`m^>z3Duz)(T5aOq?af6RVQ%<L8R*)Qj{6 z*Uc<kQUEQ#q*SI>w!jvXYS)#?Ay#14)g7#LpG@Yc4?C9N{_||DrCOhRkja}w#c019 znfy=!qa~Arewrhb4;zw^I^^4yQeJSjD5a6FwZG+_7qp|1_&>D0O(1Gr9&#%-y4CBZ zpBzC@a{~|=8wcQ01czwgGi-bzHd-Z-wc^<jjV<|&mXW5kElYhq6MIWyLMXGs+HZD~ zciAOjIXa08ydzxvC)>-j3T5dg>pa)!v=Jj6_lPb9Vw$lZ4r}pL=ElnR(}xQsy{`B= zwnLUVI}Ph~2cV9SDu7oilDw$ghKv8O&>x*s<rgUWz*n|RcBVc*+4;+3yzH-pke~1* zC)8{4>H9pU&+7=g-}M0xU6WmB&f~giyPN#&_CPH{WT0sE_Sh$p1TLP_fZG<gn$4`_ zy!qb&HVPMXy&=t!#JEuAlmh*J1b;*W+pW>~n_hS)!liWmCDFiJk@z^GeLNoGF7D<N z8WS-za#vyH#&>XIw0hHw$8|7Od*3%xKZt#f28dFo`umI$!Hs`CXP$!hb{CCJ(RWi< zWXnnE*M1qW=0bs-F4EZBmIey6?buWN{aBN3j*f4O#5r~VRcF^CTv<Q;INe)s2eb=L z>V;3xfC8UH#FyA#x2`V9ZiLLHjqZP(+Sn`{Aw#BXQDx_z?HQZaB(tLypQ4+dd&Ktq zt^_2Fjmau6V#A}!8DFlrIMWL!f81Shfjs;zk~j+!-)IFCDJXW|^q=>!J(_W>`SnuH znC`*`@M%hzbEK`?dlK#|8QjTQxpY<Pm|5sSlEDwnTOovtkhR#}$2a2#3tzo-RsQ|S zJN0hm7uh@o=Yi40aMS|V-;VZb{%B*#!~iJ66oHRop~R?DJyeceyvIkKnmN)pi=h!d zXK0M095Nj$GyC?nqr?c1r*AANicLk=1G0=NF`!M}7)o8mZ7x!Kc%+?kYHWya=)}G= zYAEg~vBQz`hvqC$^Qb9nf(x&>iy1dM@laOOyK$%&?(rjJfp2Q+k~OD40MSbJ>-;)7 zlffTO7q!BvY^5kU@hp%Uv{9=`8%Z;K&n)Ij?9K~cY^WI>lj`M-7Ib?()JqiVJv;2w z+|<y0N^<l~MlFl9Sx6pF6G#65NLEos>ZU9tAJ0MZyR<4u9@Pz!GYDW3Nw$^k21-!8 zL{zr~Y0TjMaxjYS{ci#IO^W3JIKIy8W?=*Z;>sT)jL)Or&%h;-xNn8y_@EiSL{Rgg zvGo=UjqB>WLt}Dx`$Bm%aeAb6P6?{RdWk!n4&u;6QZ#+E!G*@;Wb_euB41cGu=(r2 zd8GsbqaNRvY1YQ}BH4Six+4{@a;Iyg`h91?X;c<TTwZEa89$&zB*6|{WGm&|QU%^c z5_1MZ^|b9^Cy%l{2=j{uGLiV@rRfutA^xggLGzK3#OQ%7H}&xLi5(2hNIj`rijbY# zr2tYUnYaB0q&FA{?R9RsAm2(>q5o5&Ji4|G4rSDl!I&7<(?6;BnY$BDx`A#$!RS;* zn)p)D>TdMj3;&FP*C$HrwPt5BRU?ja+7}5b?XO4+UusQEgcdRX(6+3azE58H;%i;d zN8Af8OY72npTKyyoLqE2+$MobS6cizTVd>X@I8^$Or2<^53|%`)1WCRR&Nwg{`kHD zO6)oVkn+m+iLKc6HVT}lh?w*@Yb#Ud<coICr#A0dig2q52oS;sxJ4`8&w{Z!HM6fj zN9IJgEEO0RvsMh$V*^uX(SF1u^xx`2<2Sf@=~A=0-@Mwa?&q&#nDICLwf!4|rC{!T z*DKjDFbxg;{~e(A!4z*L!V(!0-vG6b0vKMnlTT)=r&XW1$%-%Es}pJ$*nh{FLn@X? z9z{K8e~+a-fm~V>*`>W&OM8Hbq{v@<)PRf)a$MOdB1w3BIa%#SD5c}4uj7Rw@K{M( z#>YX_it{|7-u!o7h(84MsvtO%wrNAPCog5k`gaZA?9!lcrC#`9Fvjp_6s=PAp_B*! zim21@Nu~)C4N1-LAghRvo%ydQ;k&-yotL4v{w+zWjOi`$&K;oJMvagL{T|H?x5XR? z#o>KV|B3KUIE$q{<Fb4j%ENZM{x-<>TUKL!zSPOdaDV8wPkdHF-1n|0ACwU#@=||) z7h>JdOa;p;72{@IsTxXBm;IL|RjWp7KH(FPI5zNEeQ;i0Y|0a>bpT%SV(S`7pIT?K z*xw)oc*HI{Z*DYkw987>VI%(Kgc>jWCfJl1D7D3MnnGiFnG}tuLWZDS(@}Q6`zYiK zDD0~9{$ds=E3vcrgeU<-E4rqi!Qza>pQcRgsY)+3o(Mq^uUA&E$*CS|-kM6|n>epg z>bCwFE$Zu;=YiQDNi`c_BDVy9wc&H+M3{gb-apAKm=$ov{DQd&eDQIATk1ou92T?t z!I^@Uk<W~?hD0N-&)yf?Pa9MP)Ed1e_)VU0EHr3aQ-h@~)kHD3)p#})H6xuESENi| zM)B8|4M~ue68uI@xsCzhLB*N4?4uAfgj>hHy7X2PH$O#Zk~POaZaP1}c0PEG?fhsU zh#eFW#&q7W#Z;4QZ*+fSjp0hB|M~faLAwlK6%@i4AvlVbtZDx?{l1<2xqf3@zFSI( z%%I9w(z1(j^}Ck}GXUT5piME?*>Z4YQUm!6VRqUMAkhE==`d8l%~|qtxQr%`ewT&~ z{p;F<j~DzUNIEwTJIh85U=47&VgtIEM)bEAnRU(*&+FbGqp2g{jXL}ZvYe+gT{5M` z8Y1!cBHmNzy21AbV@PX&Mp;AJe%6pSqRb0_{@w1280L~DiGE!`zZ%-S*a2>irzoPC z+ujwMjg4VJFRkZ8%v#2Oe8oIQoRh^)V%1u+MdD^wOan|R@1EB64%30L;Wp{!T35Td z?b`&j;RwX%f5%_)Uih!jle+lYx|VH$^m`Bi>;$B=0i<v7vS!qPK>7x)Lg|I<Ky!w& zL%Eb&9O@HVQ^dhlM93jj+P2i2?ZO{nQc29>MdxsX7rC`6`;m0pEt*7790ifT+ilWb zc$`QY<X6-;OMJUciU`e}SfjCVX?uRZBo>G_&-%mDL?_h42|@NlWA~g=sbX`=%x|z( z#ccbaw^DcHI452}O-SrUr5il|dJUr<Z}%*lm`1BN;_j%_**tH9CF<F3<wa#Q4#P); zn|2Rxl9R(S%4_%V<CutoWmL_vNG+r95WiLw^EnuusDb)bU{7iiO}xhJ>9<94WDy6O zO2{5;r}$15(Scrg12`gjh$<Xnc!Bn+r?9Cc8sGFD5XCGp#H~!i%Ckc6vS|Db(ZZ7r zEqsb1v8VH!yBrM+zRnmjsXPtbn0W;nc)x)HidIZdJHhcnb!~U~bR0u)+Afnc$pJwH z>c^J8UK@Nxg);Ob(t1-rb})Sv2BozN7o~Nv_o4)WT`*FmDz-aqgLqJoMNCb`M3XtZ zkRQmWsr_iOn9#RdL<*2fq=Lw<HYdUf%&ZC`RQZZj5VLdqX*VTA{bRu83zQJ1zyF#3 zVb!_G5ktE1Gq=aMy#7H3LPS>~m^3)ou`5rx)f=7ppMx3lWEz+`U8M{7p_`b)b{z|u z)j!<Ke#l4-(ZJu__;oq`LseG)po%L}M*m<8G(=&1Gj-5a5NOF7YBO_RxB6wxyqD%R zW0f1Er6|=&W^AlD-gDkCQQwCStf!l^Oe`BsBJQ%)PsiTQ1Z5vyAF19x9hvA;UCPjy zJfXjt)q05{6{{#tc)<#W_+t$*Amt4ltT+;wU}m)aB=Thj*{)&-PEDOu(A6|7OgBih zt~Sz69&wMk${=ns{J7W}Te$FrFi<h;;Gap+8m`jPtp#7q8ZPIT<r;kdk8nf2y87B= z6NlYRk<1x<9gIx-#bxi`TiMSgFhB;%p~uPYYh_RV$yK4O7x^V|JxnD2_il@&O})X9 z>!!YYt{2Z)utcRQIB$G24|ctLj#J)LhzrCbtRWnZexuOaW3z`Z%zNg3cvq$8c}18r zR_G6hg<kY2$2)S*6X~cIdw{XFNqJ|(Q}@Kd->ckOfR9Wl_b&ucplzHr$}H-~z=t(% z^>g6Eu*r+O@R3l%M3wk~FI#!x50MhI4SSIRvfasiD=+WKJ-^y>=6CVQH6gKkMv^D= zWu#oJrnRqggv2E0s_da~u*^uaJPOOd>{dKRulj;!TsFH_O$6S6)_`UKH*k?(_!BTm z{3<KDJMC|f5=~yo!q|%s4Mx!m&fW>M?;}@E3V1&KV_p&5tq5LKz>$e9KopZ?_|&fn zA=y5zGS~o8ok5C_YVUs6<Nsh0vRnu`l+J@q!w#Z|LC9OL{j##9dn@~O6%pHJUxxeA z-lhIyUbjqt*K1a|f9Dh{u-5wi_^t2N8fOOMi%OreQKCZ^@5zUU?f9xXNo<M>W%s+0 zh3F;*mHGQ80MMoHPQ$9qxh!R*)G_gwTHoN1d>~fyuWX;@$Gb~j2shW0WXM8oRu{OZ z1JEclG%s~1zZt7{*_^tInUQR>^<>MMPg~f1$!6{K|Euv=bRR#szT5aG{%7OI$Ea{s zYy2er)A7Hmp)!7c^W*oma9b<=@h5g4e_q}<^2uD|PY0nIQPxdHNixfjoy)(6j8ay} zPgwsTetn{<KJHnG<s!}b>CkpOO$sHJcYLz*v?P{8v+5P8;|b<#)hjVw0X_qlhtsaG zKy?$x>tOnUnM<)kpgnoESfIA4%?&xB9u;$pRl7Hl-uI0|#eCd??r=q-K8U1feE3ps zNw9kG9LEXYc{x2W`VcRi0{yhER%e^Y3DeKKV)5&j=6AT{>cmiiIwy~G*Uv|FcR>Pw zWog&HNJSq9qyCwSe%J)`C{{(Er;XkGBaPW;E>z(TsDj;!H8({Phii5kvQ$yZ`G4+J zxTU>2<iN;RNotIrB!%5=ojJ0&%D`wh&%AqIwum{OUy2AuR}Zn|ryhNcIo>eEL_Xg| z6m~)wwXWU8We&;Fy;`b@@U0e!Y<-Md4L<#by;niR6=Dzd$qDw_PHdQH#r-Cp4>z+X z!@8&}(xedz<OT$-L>e%+SCH?(Zuww?h53R@r3aufD_W><=4%|srW@MuqOn2Q_SjCj z@wjG#R@*9clGv3DE-tra>0@x(1mV&b_J*-!+b}(#K6d=CbFUoe31;Hjd$|mcJH|5& zQ`Is+k^{;nL(O19+p=GXzr7oUv-S$>k0d|6WO&ZQ^elO&b<eTtW7>M4jkc1*zQRXL z0Q=EntjlWZbtD5Xd>e$LE-})aYO621&Unq}4?Ym`hTxCYu<0oT%==!a!e+Y$o4}c8 zF=LU?QNdlFc+`>uDsVFwx(AwNMh-H9c$Z}p%}1rb1|YofI>;X8HUHp1_A|P1zDASN z7|b}f?z36>wPqvFQI~EGu`K#wOi3XzWzio=k};t#*8owS?(aO<Ty`J<I7{6=f8{6S z_IXB59s}hlw1_-<$%Wg{OI6Obh!<i$`Tj<{jMK|{zswZ9Y~n?}W-}H2;R9ac##-H6 zHbB=ln(E6JmM!6fQ_iiG=J(FBPW^IHdk}v4WhdaFUpB(&KfWxgGNyXIjn~U2KjTz4 zVdHEFnSki9?=pYP<fO|quMeBqmg`h#MUWEc3!rKL(S#n=@}(1c>R0wMq1$j5`VS{` z(!4z;^n8;3e=wnkpvGrHzjx{G6N-4xgnlAo;ZL*|zKYpFHIn!5Qar-7k;Iwipd_nA zKGUHWEcZ(N#Zu_?6^3<n)Az);ceno<|4L4;^o8rQi|FAj_$|#VW?{b{{~W@S^MOtd zi%VRUWV%BBAzrvY%UP;Q)a+jKss8>{ax%tQV%1AKSKTslsIz!g(JPtCKLm^x41df& z6lb57%iR2j;>?iB&Uqsz$EHq&`LKamyh<h~xy!LN$$QFG<7}E76);z91;;}dv(=!- z-1KYpEj(u&*rdIp7tVl1*e~+(5Q?t5`GS@^nz)`YPuGW9clOd%&SQpZjm;&rLVr|U zM@a2BO>}Rfv+N4_aC43LdDY?rrP|_`*LHBK#3|SJa^+;@R%%sq(cgt-$XlGi!IQ5y z|9u5-$8jCevP(yBx!serZR}yULhU%7++)Ut;_sCk%!Vj8M|CYD4jjVm*4!yy{X*;` zZB^ctqN#s+E)`5(WDja^z3Gfd^*@~XRX{Kj*cz$$N9>Q83G5#$bz4TkevkUjH1(~G zRPUs|4RRepm)$>esM+6|16i8DzHq`o?6A6)Gf#>g<OW_OyE7lpPpaP)sn{9&CBD*m zAhdAHS9^l59KakAaBk~rIQZ?llBXC~FHxo16(M@drr|lgHLWbQZy%x2Z2Jk%=qOi@ z@S01c27U~9ILoG%^{#9A+)w(5Bw<=<N@uS$;rN?yd&VsX^D3XbiE>LX75os9QFNt- z0f!c1VC=*30t)LUuH#WKI`fMuA>E&R*i%FDwZ&g$cRH&p{Uo^=na0zm4QkrD&Ks7E z$y^-;IR=<BC`3byx0NkX|LLmJrYBAV3_z;UfexJx6#(pscH?O)FFxf0L$BbhWB!I} zP=z(SKk`P;%xoc!c|*m6-UbJ%IcUhYx=#HrH}I)6E}0AeX`bTDP{ZLf72W1vTL@W% z0iv@kTGrciu>A@~TDgIsdpeUIKm!D9A2IzDY~#C9f1`*G&tH(9ho@o(8+c+tHc)8) zlr44UcG-BU^HY<Pm;L#X+nuQ|c4@Y*>DOlKiM>n|f_kh&Ge_iW@b#^J`HOPpu~FN( zoqk-lJokUhdNG4C6`S%FHYyNGt@NB2YtFyFav{`8(hruQS%?hIzQ$Ax(YS{%CVBnM z-FH*Mucpe*mbqsXIqh9$;5(dUmxNk~!!ln1WVzFbzy&2O->fQX?pf(&W=KU^>9u^? zi@AHYd6KiN|D#f(L*{4yq_`+@<$y)p7U{j|CccR?JvZXjaLyFZ6Pz}a-(<?4px6%9 z9^Vux=!?D;XM#re!?hpNhq%?-<nDjzDi@<R*DEH+aD;A4^S<{FX&HG^b02-V|0GU* zRFyc3l`9#(VXThmymgbIkNN$~-<@TbS7DDK@E_}WIo&QgxRYH+$vQ&rx9sqmdlI4X z0&bzZsq75auHLxoZF7ok05+WMM8O>%kwAjYgqaQr1nZiQ0|d(j0wkE^U0MMHzV8M; z76|G9L1)iQNhJYvn~7z?QX|SK|A(zf=H~XR`8qrmVTTw^_8jg<mE;h%&b(ypmu~f% z=ApRRdvf>p9&5Sj6mJNd&lm?*wz(DDe?~2<sD&CTBObvjK_oo9b~PXS`#yxHC~iKA zzk%3EbuCpV#mfD@_i(<~nH*5t`dIHw`1ku{`kRmY*0szIoa8KitmWfAk-$fd@%<V( zof?VH4Apg9tRs6l&ntU?Sd)6bKdH}21KZkJk~a6moAbqc`COdd4lIoroBn_&=IYh+ zHCLzO_$}pV_#N|FZe9Ta`>g{0W{zlY=bYEfs=Ah4J)AbSETH@+q)e`6t&(yeDGgQc zI1BpeQ*sos`IcQ4B5p<NXN<Y4p>hLHz3P+ENN>K}ct#Yjzi9Hr%$=Omw)T&PHvEwn z07Is0jXBFE<@1_RRmIrQoc8Yl-nwPQroQ<xy|jK7B-Da^>gBY*&XZY&NX_*fH<dXJ z@n;+3FVx3hO?`(TU3KvcHww_?Y?^F{@1PgtF{kszJLF57{%`)|=AW355Zs=s-&wX# z<jVRad+n6BDUvwL;8*%>x>vvtxhPs^?3^|Q$3S>eFx^6a*)pPJ2(c!-E|;S?A6H@s z`iONI+YdCTw*&)!%8!LRJBqpEL0YgAKph%??h$$SIt?#m4izpPn8%jF`i0>bS}I_! zFRKUgL>Vq$!j@0>X&&Rp6*(&uNn8N>Ob2~7u#P^K!WQ%)R5Zid>$hUGFtN*-hd|x3 zfTq9sL{0Q9QBmh3IbF!80idSD^?DGrk@IJS@~sW^%JiXB4?XUqThCg%o$-mpku%+r zx{jt$<_*;@_!*kUChxsF%!2OV?n>{?Na9-n9GdnuTk9WkZHoPLZ?kviw){Z8<qz^x z!NL%}FZ`A#eA}D_oj}_sE#YsOp7@uSW~V+=V=Fp)FAFhq#20>}5wip}^Vs0N?j{Z} zcgJE|C1O}&)X+%0b|`l+A}pSB1OZ}Q{i*FAiR1n@yQHCGTqsSrX)WHCbG3NCg?pV@ zym4L)3Mr_^q-^Scn@oQ*)R;2&@rs^`^B36+*A^B#(WK^8M0?7&#zv(j4-wFk|2q3a z95<Y0=T^7u;Qcb*>#Ck|7F@ss>%E1GpKt4|TM0Ca8V=rCSF$FO9D}!wm5&kO)=Q)< zf$m>_hSogN&>(Z0?Lej#M8n>V3^WK1IUkxr4!qTnjWY*Y`c$`OOm*P?fN60PI~zs& z9nQtL7}cHjS0uf1i>s-ox2Yy}ktCK|wu`59x;<q1tzI?rq0G5H{ZW0G>k0d~jlz{r zaHH(>pSA7`HvbrD-f90kiK?K13S>V2jmea0LEGxr<=k=&!jGiODH3!(CnNMoTBK=y ze6J>F+2XPmz~O{ynPit80Y)|Bb>t>oHVe_Rk?!%7cji|xA_a|Q@jC7JycgYHobFHc zxD|Lm;OKtIB7giEHj`q9{WckQANB<G`rA0WFzotxT4GvkEEjh?Og{?gN5S~1WzX@G zXvR-Xl~16<za@RI$!A5==HD1O(ph%05l<smp87yE@Q(M6FI`^13PvC$2$~ph;$lRT znJk_?q|xKPJVSA&j}b*BKjmah8G~-IT+IjlJo@<WgI+gV<v@QKxCrQRdII!>I|V^v z;j}`G7UJJTikOYdc(Q8(q&vk!8h43ZsZX~4C%q{x?9J1(dw($~Kl3~3_q0mv8Zi9Y zEQA+H6h=(XVuXo8<#*^gze8X9k2>^i4bfs|toHum%!0!8W6;Ll5zEqX+O7s=&GPvp zJs0})`iJrAn9ltw3i_elZj=06LY%9F73jTGyWgRrd?JC;h>hg*<<PWPF~fozU1&E$ zf1^(0BjYSX<ml%u7SqU`td{CGQEORsJ2_4K=GG61?7Ky8jKH)Dcj}$KhZKYV`Ao7d z7G~;|ZX-p#p&SyX5v_NZ!ZL%uJcD>?bER79k##@pFZV-6X+YpI<R%!%dC&qE5ERvR zObKQ7GX=7}-Dj_xkat{B_t(7eKW6$&;XP8s58loueBviOZxXuGcb#{V6JGqYD2M5y ziHl31DOXqVXSDuYU(KI$t3|pStN$9itf6Xk?BcqXoyD=HI`BSrHWMPzwytF^emURm z8rp?jCow#NMkM}mJ<5vS^=K=4MMdv9Z+rvWBJE76lvMtbK{CW#a9vX?-N`6GP+vAA z%MJ@%wi2h{*mZ^gjXb`vY_QM*v;lXFSJy%lo=*x@9ma_y4uW%>7i!tjtNAcyms)Qs z8v@M72=G=X0|lly*{+~gzUmsz^Y*A!9s{a%D8CBb*8)03`IUyhwu5Ms{7TQNRvi?z z(x^H8+sb6Oa{4bU`zgQLwX44>zm#{~$fNyGJ>_-0zN4+oShb0_*~x2^-*rk}XjQq? zuGUq%=?%3%$7j|42ES75s^8Kj2*>NGZoBziShj=Tjyub=?UC+poU$eDAiQuzbI+od zhs||i`#5bIO&-pqM#-><j8O`7l8ErU8OkaR3C4>1%34Uv3k;UH;4(l>ODIK6zb1n^ z)nPg%^*@JT)wB-5PBFiW&0Wg!zAbbBqfDnMGYWYK-M3#v)jA<`-}>#3=U0C`!1}X2 zXHWK8>c%sR<bPP58(;hb+Z(k67u6{lacBDefEf?>o6KO~XoL1)2b<}INwF9U-@MgY z4F!ArJ@!NM-kVJhsS$}t9%vakq`8M~*+72p&FdLMnoUI9#s1x{cCrWq=~Ac{b26P@ zMT4BiZ&9(EoLY9n{k`h$FGht1RF{w_Y&}i8hi?0e`m*yhwU3fPwgo_gKFq1GF{Fi> zDk}Ug*Pn^<nJU$vDXcw*|E6g!RN9R<3>K;?zmQ3&==5(4x$%tCzk%B#9~bJ}L26z6 z#g4@$$ZJFVsrrtEW#W8|aeRlkcTMNtk|+L!11EA60ZA<8JYdF6k}mj3kspLm3n0WT z{EXmtzNrPL^lh386-zxbLbJ#H&%9_APLw1tMFe6RH{E94{aC05Pii3$gGC_DlSp+t zWuPLqcRbj>LnTgv^bAUjI*yD3fvMB}AbdRi5`RYQ6GOx8Lv#oeArgY})rV-QQh;cP zUvdqk0z&gq85ItIL>0$+a}og?H+_}4j%iuqzW{Q3v8wVrz|lY#Xsa$k+tkg{m7YgS zx62f4D^o92c0KR)9Tu7*5HImA0`oGzViRO}g-2CCfa+i8S-@YyuNR(t9eiNkYT;)A z21{Pb+V|8QDZk~Bhp+07ufjSrqO3S}uAJLT{&)7?qAA^NEZBSBzgiv$nf}X*wiFc| zg$1mpsD;ih?xa_0`iuQCe$ACa5)oR>@3z#}`|n{NH!)he_y1M=oBr+o*V5TSqaXc0 zanJtO{%ifuaKoPZzsme>OZ__3t^d{@g7Z^+vyovdpGZ9s^COfH8N*nr3xcx9u@{pD z={=21p%ovB_vFM`w5+F01Dp*fJ_-ie;Xr_c2R4769`A0C$?J2PP~D(@OUwza9UX!w zdfZmgOkk!nt^}0B1F>LYRL{&rY_se^K*hwBn5mn~dU9^2as%=NZbaB;V<$_Oasyl; zQS%&0_;;O!|9hfbF~45GAN36Kn{sRgy%%NCeN}^5+XK|({05O$Mw>`0NCl`Mx_ec0 z{jHR%ZHWMPogcDgW4H59*4|=9;q5VsW?ZCX%pa%D>tUiA)Wei)%Czi*mI<HQ%374d zzr@!EFkT$8IBFum$kFRpWU6bGTK;18eDSHMm*SJk22i0^GHZ|HAuEr#kWU{H$kO<E zF<Kng$-QSLL6Kbh(Myx-{bKQX6NQB3=Le@)M7?n<QixG3<~0CW{<)!aO2Gq|6dC80 zl@k-+2W@fsd-NK9Fj`$NZVma*9Gcf>5n#_u&Wm!m`#E#FlBU6&*H>t$9GTD@y)>C{ z)4I^Cs2Rfs<Qe~Xjc{CQ;TR}6ypsKRfWlkr%Z?!4)J_JeB6pc0$N5EYyC*hq>e76X zXUHdtbwpVJ9^FnnvrbWa9V--!R2rghnzFzYkkS)<Abmh-W46in$51OT{MuxV8}Owc zB9EP>&w0`m^~}Q+LrmmR4U>O!Q7~O`hSm&{3GG(CkEtm$kodJwGkd;d9MBY$HZxFJ z1qgg|Jg$bNGmc)NuBt23Q0%8RR_plgRB=`-4%y6dX{vbBnSWqVbJJWlI}-TdoaBgO zB#wUrhoxxsXPmHBC?9%GFG;@mt8~a9goz?sEeDyXGv+O$TWe;bw9B1;2o**uR=WXI zA=w5~Zl9FX&ixXeK_0^(foMJLa)-}U8M9jGbCKzJy|$#-DK-OHH5WVB3nv(?9rjlN z=7^)3Ur2u_c-v@@Z6AZ=+@o>?E;T^I44v~y@pn_NROJSLXPKH1+n%k%fx<j<)G!5M za09PqJDXk#=k>yesKIjoj_u;Kylz-k-DfL*9EjPvzbZdl%$4Hd9SptMKzD7&?}mwK zzOJL+jqwi~D>lc<xd6R%#*w-C;!dRxQssV^xkzME*%X_TnTS?=?9891F~b5Ua)A5n z<cL!=S)CK`h^qdOvB)h}lV$c;_sHqYOx7&M!vS7SM>RTQwwcM2pD9Vs{01tFRII^g zO$QRu38kWaHaYEty5D`Kgan$YZt|W#U$7MB>vX?G&DSdo)(%_ej?8?`1cdUaVt3gT zY5knJYSL&x({Zx%zL^?wx}B?W8sQWxU-=WoXD>Vwx)BNdkLjq1Lf8=BmI>Bt#JKBu z;lTjHtT?;YBpS*MygYMt!Rj@uKEHa8rwl;K7qd5-<<_w!62t?9?WnR+6Z6qldx#hQ zJA=z(NxqhPrfxtqF>E1@KoC=03F&1>;ed2yOR1I$;|BlO46hRbF*K{~N2bfjYLR&F z$XY+78Ea&k#Q3m9-2#_@V+3$MbCALRJh9MYpf{frH}>@zXMnCGZVdTvpWsN7xN(60 z_BZo3(0_Z8H$So%{V9;pV2yYyMwuJ<JCeO|5Mmj-iG^h?>N?4;1paCA2&h6aj6)N` zY9xLhdHBXdxgJm=pNDpWJUk2}oY_#@PpADt5HEcZe~9A<$n&sG-@~%Z`ee)WS&CKp z*bcNQ$$raD6hjGmT7ibq9ZzSx@K0EJ>9^Fc+%Y*@Y|8>uY_2V~bhlztRLsT?3D=)0 zP-y4og_kl<X>mF9)F+s9Y0l^;>6y8W_`@fIpPxb(e3DH$zPpLVhJbtFBI?atf&)4E z{!)<7#;wff+sM+%u)l}X>R_zKIns9cnG?)7H=o{poDWjK+4oPSbS?Ayx<}3L{LG=5 zDuR*V6E8$dU3ngUw5M?Xk<R80`wU3kc|Kl-WC*3c%Ts3mOwUYlh7l-cRnOE1jrQxb zRCAMk8kf3OPkb#&Ej^bf4hl`_B@r^$(hia{@Wmg3eFe#HD)}Dxmr2GhV19Rx|FC;} zhTY$d0U^D0GW^`=6D6<Kq7X9asn<w%6Z^`>#a^fcMGm_~4uhCICZjAD(ML|y`QrIk zk(XsxUWEQ1Jx|rVPm7+sV>ov_lyt@Rm8d%ufv=WBid++5pA>&VJLnCw`(dSazQbc@ ztaqkD6s;`q5uxj!xMTQC9W$90p4U}$+EuIP?NFUFj>Kdee^S=xnk%LMONQ?}E$6B8 zhMkdQ%@k~Ye0rjWPa~O2FMJICoQ21iIIlu{bT>}uMU6w_)9`#!@{R@;O5HQb4h$K{ z3~XrOz&Ko~onWhCtJ`r^6*xp?<yRB%x`}NywmM|+{CUQH@4*$F_Vx4*9sfayBHfNO z%E_nl6;4?`K{n1Ky2ivQ9~ejTfZ)_GLl!e9JZ~GK#R4^u+*@U(Twlym88dga`X-$O zpn+i{x_Rqi`k34Ia$s=+2atmi+O{zylEZ3v-peuMnUF$VlHIzxNz~0mRc3A+a(m&2 zaH2{dZYa>1z(2mK<&!|V+`ON}JE#4AxF)!nwH(MSq9@L>Pbm5q-c#3Wxo`shk{((R z1@>th-jy*BBFtGfL@reQ%&KEOvJAvFxT*0KoRA=i&_#fdInTu0t&hLi`eqNVS&5Bo z1c7mqHh)k>dKg0a+093EBz|dl)a|xi+{KX8=r}=}<)Tn-ERZG$(I^O+o=XMi^6VUh z=&NS<=6N{jAs5&gvWXB2X2DRt(J%^`nM5q5Wt5nojq0V$QV2-xA@dT=+Ea>e_@u8z zA82$Uzr@t!HdSsVbZ$c(q3r#X9fXkuj3*Nn2_#ZSN#mw-p)pUh^)ys6^b|((ILk^2 z)0mPQ=31PYLY!5+H`x{JSA^aTSQCowmFC05IBUf?xzHr*WoNdk>o4h9WHf9`=vWRv zDBrILbxbnongQ$`WZht8_5s4!@L_ZS#F;O`N$Z|YLi??Q<=NJ~@I^F@UZNFZnxE;M zd;Snk^Jwqho8JroGNipWRds=-!<&lCRzBxTCw&U^0_W>3ZsKgSnnF&f*xc!wI1lR& z{x%KICN3cZd-S!bMUuu^SMM4B-j7eL+4Y0qCwk+|u9MoBgj=g8&AOcVJ5ZB&5L=0_ zb3@RLgp#?Esfyx>49=DNvosawb0!VHco0I9<_f!-<XATj(s$A@rjKQ=O<k%Boiso{ zNWMj#nVWb#uqbwQUCYhv`X&l-2GSpcou%B$Qxa)CQ|B}V?O%cJI@BeMW=salW+QSH z`4^dL>48ue3WK6$v(bvC-aedtSqH00)9PW6k;j0Cfp?^@71H2yk`SkJIf*Q`dIAmx z;(?Pqj(BmuL|%V^zooR|24LKJ+M63Obn%qnM%$FtZCuI2j0;_952yVFbu`fsGN%M| zM>j9V-@k-sgVc1YVQ5qVow!XS))!15-UA4uP(oD5UT<q^1Qj-L#cCZCu=!a2_GrdZ z(@PxcU|m=wn3QHKWL6-)8FSUJL{d;s<?5YLoeha|2h=4lAH-!cqfK`W*JN2m)$v_p zn^M20C9s7~HI{ZTG_6(v4#hMz<v=xImBhqS355uZ3SSW#Z{6&t>BB_nFPBolskpOj ziTPb@jTC5%TX=^<Pm`CD2FQ8d3z%8Pa)7*l<9~@Jz7aAA5gU`iW89i6BuFi%q>5n2 zxj?j@S`>xmPDDuU4Y=w8)yJ*oZ4!}5vegiTH(B$&WO32TK~$hU7uOwEOy!RAPSNIu zflOlh5Lf}(I+X2@e70hf&1tKmR^5LTNPonWk0_y3kFzbJ4Bu%GCFj4T^_dvM;sky= zY+fPd+2+*S#H<rOW%Z#gG^8UiAUVFp$-~NM-Aaf|Xh@zn*|TnSkLs;$gAFi{Ii5&s zn9AnR0`jDmTqv7UdEOwe0fs?8T?_LpDJ{c?aQmbxO`MM*F+$<j4Z&}hdxnf)vPBv! zW}SKA4<K)XF(OC%w@oooXXTq`-o)Y=V3Y8TbsjtkUkN2l<oS$GP!aJA`8GKW@eWQJ zDsWkbkwQ$@vt>fU(>xYaW}?2;D#<n9vSLE`?hBEl_s6Br_TI!yiZ)T#ywxpK;zy5S zB?IrDkG9iu=VxYmax~PeXDM_I8%rGacb%|-dq5oioW5IKNe+7tM_|Fi^&P{v%cUJ? zG!->RwJzYg#=C+J8oz4gh4NsS@WOosQ1X@+HD9N^EDr`M%_%S!EdpB+4ZK*Gd+QjY zp?TRv%SG@%-_29p!A<T@MMb6bY7`+lf+N*wbg%PPYZPYO_=F<!7PKY}(7;A&T4NT7 z5Ctl%3saFYtIS$5Dxg+Ypxl)~i}7Y15rP>lkqzgXl?!eK%3|j2Gg&KX{qdPqdFrz> zEuc^NRDfQ@c`2ljnw{q$K7~jkA9p7`KsRx&Yd#YBdXk%DEC$fOn=YaFe1R;!aZRgo zF+6n2CPPu|YkFDRs@xLSTK^Q{sW^5_C4_S9c`C)(`HgNoA(Bc)eb&Fseq0B3h(0CE zC&G{f=A5B-&s1iEl;Gc}b4xWZU9IWv_qD-hFV=dz>dnR<IuXu;<j4O^C>qnR)a|E= zZEs7}?&ywNyW2agX<N21=B2lAz|E2d7ER4dX9J`6wtuF8Lj^E8mSxs{c>wZ|T&cl; zkPA?FV=ryg)^$tWnp+H@G@}z`p`zX?us4HWCTLr$DOVJ0BzI)3tX~Fvb*(0-QgLj2 zW86fWrZ7ADTLd*2Kki<)mh$MA;7JQhq}*Rv$(r9yHjt`1+(7Dv<A9WQD1NM_0IW-n zVZmwoV2~XI?=FJ!^;6VF`kEI(MJVV!gfbbNy3tY(*i&%bk*dcYLXs3JWVh6!t*nJ- z{d41+lx2w?$)Xhu=;)W|V)B8q7G6>ht`fqoO*t@kFI){Aoqf5I$+4knYE!3kR|XTZ zh^Vn3!Z!~y!@E|ko8gV74$fs=Y=)N=(#BF(hA3RC{Ao(fKbZua>WmOKG4<ag?YcO0 zTQ~lYmnS&S3eUQYy2S^QCr<CX)0@1gF>xj#xk?%nli_J^H&+mqOBXoj^yz0O>W@d# z;|`*;6C;lI*4u!O@5MIjhLHY>g=wx<@ag*tsfFm|<$hN`R<K-^y2-pt%eX)2SGcX% z<`GcyHE5yJF8v~+fN=o!kDPK&lLcqve`=4;A`f;l;gW9Jg(NcmGHJ%3r0Gls-#F4v zG~!0^8|4-yzJTN#+_fa%%$~L3l%{rd(GdpA?q-!AAg6{-M!aYCdP+Wf)5Mux_<tZk z-A5OGf+V{`)ZI#Z_P4U2zmFXIzv^#t*nKJh(v^DQmuN@yVr{mMIeCBN5=%G^GQVER z`}^($q^L=OD_VDjW;t&4#{`0lzc|i2`oRd5XJy^iU451tdgqK<1E(|mdd(PxhmH}$ zqi5NrC;~3c-G|^E{aw0~x6ft$<MAnnJQ)e()6lFz-0L~(AZQwTvFyYHB=6`)B%kG4 z{<M#w8?G}7LoO|Ie@T><<6V`V_!J)>O_Xs1(Az}dt9~8LH4+B;GL-gYy9o57dN16Q z-VhG4ppgP~1^O7nKQLDc1c$iQugwbE6GFH&8ic&uJNhND{9K>*fQD)BkE3(lIwYDn zm2Pcq?oS6~L!djC^Eqb#yu6?X;$L9*Y*6;&qiF^@HBM}LqCrcEB%nGI9XxfqMeZs3 zI?X1EzEeP?>le>kGNyG9fLtp53l961=$k#lTY&omQ^k*3E(`kSgO&b^*#DZl2loG& zBrjaUUug91fl7Z#90_r>If^F{UTP4S`#sEW9(N3X%faW(vM+<rfE&IPKJ6Rw@Ofj< zzXhK+iBTkK`|rSKC0M%~b@(+&?Cbfv7x>)5MnmwqTpNz?A}FT<DRr3N?(nhn-RRq< zne)swAD;!A4}N6WJOYaj^FOp4gbB>T`28DjxdW|_+52sZ0tgA&op3pWF(x_9oN1tt z@e7PrX`uVix<j_#bL!Mz#TCD(4|jM(S~+2JhRMEy>>@rUy9wFNM!Y`)x;VsP?#dth zWck#t>1D5QswTEyBzXlJ?X_(B4v2759HQY+$@EpJQ;oMKjUu8hH`|e9zl|u5Br6}_ zCdMM9ZfHhdFpArI*ST>5DH}zUmH<4UR^?z3;_^Hp?FjvOny9DVdcw&j*c+<APVAU9 z!Ox*H0WBp_HZ9Fa>&g~Aawfr#J9oG~OI9gL{||o%;?}g#a0fiTSU4`01sTBvIgI5p z%d|;OG8*@2^5%jdZp373mso;6>}Yz>P2;IpGtziAU?<YPK75%G0}%dGmCOoi%7b!| zp62>-)tvV2G{jzeL2v0Pv$557t(Zr0F1FeRP)jm)>6+kvX0&$ymLF+(cBDgScJUG9 zhMxdLG{dPss$1^^{MfL}D29Gf!XLUq*tiOBqfJHbCeZ`A4Y2l)Y~p=AWI-UlfvJeD z3S?^nj5wRxRa^3OOy5haG!#m`bUWW$S5M1n$_!e~7=;$~NzmU5ZwJGy7L|j!yr+1V z)=($s)-({?&1{qj#&;d~k_=zNP*z$4&M|g*5l1(sPyO~AU_>o%pay#(5q+(w^&kr& zGpsOpV1xRUtoZ<&G{s&#z!Y1zTd@|38A1IIflQMhI<h3S&!}A<2_s3!1(YmF{rxOe z$X+aUTn%ztosq#mVWg>Voo>IBrj{IIN(T9+1H{U_a|F7BSGcK?Egm-m?W5FCY8Dwq z9)`TX2S3ltd$5%$HoBT(5h*$|D!arbM)VQOIO_=7WnqvY697-8T905waE$+HD9@*q ziW+F0u^gZtOg|4*`~n#<AHG?ZB~4ib3nweGnd{BbF6pMv=0<{T__EYlSckbE&qIi$ zJJ~=5kwgP1wR@z31Y~SCk~y0sQ2;qY>!@|xVPL8BROiqbr&!H#D#?cCP;Tmm%|6a< zRmZZOz}<n@y>=wMgfEqyw*=S1h~&5N2=9Pk8ap)&bD&0EN}C1*hH~)rj%&dYzFKz6 zM~bk7a^t@-*K`aG+g`?>IiYexYV|v&v;Qu%Ce-Z#t+PpDSrIM6kI_6~Rn9oa!S@{0 zb@Kf{JpYAIAKWIKcs=#kcZFDa{tJ412A@WXVMYngnyfka>t?OpjI80WwG}K_yKR-b z)*!X+=Y3xgN`|ZRd2cm&%@)j3rDmbw=F~}q3GQyMvhvY5p>XS50)t&`SU^@9V?Ii< z^I=GJM0Wt7h|p1#knS>SD%~^YZK@xA)AAAxK!9GSaTx+taHp8R!KI2GMyKZAq)ZTU z+u$hEo?lEVmvZhRs{lU=uS>eP-aw(*ILtFbdZcVzu9OUag>4`6Lu9whyIryLt`D14 z8P?V+<KLvI>2Z>sn&Ihg`#ZZg`WK<&5*AU5{Y#<qWZ&-4xwm02&`E}WWTYth<25PR zB>&%>y5dCJ#~-9D`qZNnmwqNOSpN2p3S$1XQ#A}y!~y00z-XMcpA28C3R|@a1Re!h zUuM+{7u&S7SZUkIdnS3=a;ScDe>QhqWr<u9>QEO0<);Ds9XRLzH61^kz&iaHWddp% zxX=@^M)Dwoz_20!xu<bAM9DdWRm+}X;+a;WNn92(@7w7C{<fWHM*5jiv(5OFfK6U_ z4VWVnwND$YFu}dsTKwUIO*KU3QZ>BapReYwLm8`fE9`5iX0Bh20ph(VfVBoM*eoD+ zqvx|5@P3K^S#i*l{a!{ITrOPXYTqu-0CqZYnNM9K0PxVlVd`D(5$hn8#m)kWFaY8G zt1Pk7KH;0D6Y9Eg5?~>g*LO@pf`Y6YE-{5ngZ^X%=V?4o@e5d1U^OEJtYAu>6__Q$ z3S(Yj1*u>C-lxQA^&-2qcG_PyuN%#U2(7CMSc37A!17@w+R`c{+Ed>74AuMHl4J?v z9*x_l)}6)9EkCkj`{5x1YL-)F$%4<Rf}c#XBe%SY5{3l$9qeU0h`Ke~xmX?QyFELW z4Hv@pE+0v2)9^ir@6#mVZ^U2FBN?3OH!iRj``z3V?1ybeuu1gDU#!`DQ1(*ISiknp z*?sI~n)}jpvgS|Z<$hksEFR!kbZ!j6d`FkY1_{^J3l7X7ehNlnAP&+9M4Z99f5V-} z&{Jk9<TaJAM7r|0bM=(&mvF|^-Z`ed7e=x)T6YF!9l#mJ=KZM8D0T0u_6K^^!Cy89 z*I)T1b1;7?NP^PrWf?%iJ<m{$dyCR?E%(ESAfCl<#xb_5n%^SlrG7e0AH3ATZ)@Rr z;Y;y@C}bvvUSu`#MtcOOU`9Yw;Dg~8m~pd<{_s@JR9)fN{<0*3Ka%iA`s}PDZ5F|% zSX?q24(n>E9E(V`t3cXP$}tf^Z<Sq4r95A@Um>LSSWI9?R<1JDSPfNGYW(jklpa88 z#4nVUQ8+~3emEA_i@$Oxw5j<(&ig!Ls07X>bSXACeJ=G$9Bl36zfIfSgbt5E1$(DY z<_lM)x4hxB?C3k|uR3~|4FBqKU~r{>G}uiHi4v*VZGF5X{Yx#O#E{A-Fpw1NNtaD1 zioe|Y=3MvrH@WFJ(uZISUA^00nf;F9bPTC?9yG;^GuP^kx-t`Zpo+>T%=|cel()sv z{&301V?t1BuJpF9s&$?E7h8AmGwMZ}A&4rSa~}1pN9QmkdZl?`I)^Z<&UDX~H+r}1 z=;<uj4(vE^4iVisL8BY-9gdZIH1Tfc7*{cYMwh^RW%J@{2i67A#W0sAF2*E9{L&Sa zjs`yEB>y*wu(dx9J(g?fYVCq}|Fhvpt#d*>V*5lBGcgg)Db4ifsT9?a({>lYBZ-=& zvVxs(KRrvUj&Nf@)m+pGk3x);ZDy2AEv#nFG2BchHvz+v*o$e7t+P1#G+BL0WFv*Q zBg0GP!7@td7>OjcCJY^FBhIW>=>$lvPJlEy<;v85Y&i#v20Hym!L^Qx#%I(<<2SmQ z-rT5SOy8}mXZss77;bH0yo7niK3yMQXcXlQQUP#32S@8p7H9R9<W8urBx|CL3VW^w z)gCZ<bA`DmEn;uezBSg*(DdUuZ4#wbxh`N!Vn;1Fu~@zzwu=SRBP+=)h^z>h3?6)i zU8SY^SWW@f={vxawV_?&4nS&}!jHR&qVjrSby<}@gzb=PiXo&?m^JwDi+$A)z=78v zF+hx1js+~mi6W*`^eNwmbQf(!vfPp)!OOXo%`RNz4fdLPw)xGxCWA4f#$*0+k}JiV zl+E_u3{Aa1!SDU>g5K-4m)(0mX^MJ(E2Pd%E;L~EyWekqMBSIYG~fMX@TR@>>Q_d2 z_Qkz2oyW%`@o-rSeW1P5Eo^@*c(y85#_gnwEI@BG7H!4ao>LlofVsLdwOe@l&;(<m z<eE`oEYaM+!SSGSqM=s3bqxaerj`!Xk_;X-Ui0c3XYiBkW1%}ykep(`mJB{BdlBWE zlsHa_X<5*0ZOPygw(<I$pTV43HyM0>{9du>=kNt>1vS33LVNvRjOCKcx{YP%o@1f^ zO*F>9eU?JEr)gBP?NFP`n!Ip{>09hje|*DEManQ+U;G@*1T_z^2mPq1U>8_Npelk- z5iP{!NW&6761(XpUK7^j1(5F~(XN@;&Dzq#ylOs0bo9byh%~H|n@a>ryH0k5{>eIF z_8P7ibpJVq#Xt1Il{oQe;nqUyvs3qv{$D(GCk`Y6yOm)9P@Vv!Pqp=k+D8%uaAn~W zZIs=i(fzmy8)i_$DA75=r3~6PoS$0eHI=Fl51X=Pt7xHO(JL9O?`_d#9OqD`&^g~R zVmIof-CL73q`R%|bN#MOpnB#&l0qQ%Rp779CGZ!{`$NyqzX;6Jy|T?B!0d^~dui&e zQ!Erd=AwZtG}nf{5SnHy&<%_~vlX;`<x@=Y_fbm$vmcD`*&B3t@?yG`JCshmOkrXP zgD`>3*LX*N!#HLI508+py<Il_BAfnA&|^jag7g}jeu2`Rg7l+p`tiG`_p|8%rSD&m z{~rJvux&&$*scCoZTbUB?^}@nahv`<r5i1@OjPv$H#YrTJVd(n|2CUGPWksOsOM&z zewxzvDM-J{ruSERzk>8eoBrW9cFRA^ra!6l!u*HX^j|8yu>V1uezVdG;rTw32pq;L zy%0Vx*z^;XuBe3Bd3nU9ds9i*jg{H-U)c0llwR0w(xxw0dLbNQHht??NiW2Q2{wJM z@)yFn!KRPjy`B?odiCz<VVk~>(sk2kwx2ssHsgH<EmgOE{>`R8wtM>1HvM*`7sBU{ zHvOdC`~PE`{uSjfgj>5!KW+E=zhToIr5ED!MK=9yG-N9dDCmEUP47~AAv}+^>DTO@ z-p{7DDZLO+{!wY*@YUV(ziQL#l^!f;_i>v(c=vjKLwa7{f*DuQ1}Zz_Pqw@pbe4VU zoVA_kXQBAZ=5>Q}*81A27oGMvHDmQ%8mMjYdNyBN>nwXwDw!BDr)Es6dWn!XYC0Jl zGFIfHFM*J_S2vQlxHK~SlG50eNMhDN-SXvy4<Bmm%@^}+DBp(0qI@goTX|;x*fFG* zkXjNujZh4zHt{FJF}%I=|MB)N;89lB{(k}q1O?xT5{(vhY@;TXmc(L93TPrh-hqjY zl~!tLOIxM1QcJ@Gu%#N9q%a-FLtA_5>9Oa~)^m=hrKf47f{Kz5E)lCDR>eEsXB<(~ z3Mj(-KHs(9NhV<XKfmYsJ^y(i?`>b#UTf{O*IIk+><FZhi^>~6O<>9!yPa1_f9c2M zOV9483%*IdMHbuZCnn(<a^A8g3o!cY+)&W!xq$3(ZTN1r4n7R_oB3Zy>@EE=>t8={ z-dDI37<Z45mpMNOeZ2VrAR|YK_mmvQv|gekJ6MQn2B}=toOq|1XpzHMWQSV`YV)dJ z^Mtp2E7OAJVUFG8)S*e|$e-dEnlW&08__N?fj@%a%yNgVRIk<WRa@VtVm}0WNj62Y zZyLC;mFgFnAryFL80b5jdHS8=_jAoj?A8<za&2&RFI<_4sPcOD;`K(nX-`Yh)S>7O z3VOKwLT+@-Me(*~O-Rjzi|eds-i}VBM_%X0xgE4$FTVk--#^Y8p;p@luutY&%?7Y1 zXsc^=*T=2Zf6b%}pSID2*i~$NV*{8wQQ;LWl>p#->5m2d5U}uXmj+6Qhp>~M6;=bx zB2xT@wKT(7PwWPI2~qX_A=2WqEa9ZoZEn#XA9UJ~bE-cFQ8h^Dmnn!|S@yA`3UJ}^ z__QH<j-&<^93`w(U@FZ12P^8jA|cDO*5O}{)dHTEB?T`lA!d8|@4URnjS`FfVtZXU z`=b9G&<|pPlD@3{8XQ$`Zye#>e#tSh(O5gjt{+lThCgT9X9>$yhC?Io&R<{b-f_b_ z(sDM}cSmI}&8I!9{hDKo+UnY`8CleJPWv@DuAf=A58YcCA+NF@3v$QG^BFsK#wr^+ z_GwFn)(V<2B8h2bnO}0FGGZZp9qrw|v*-B{@$C)S<9K$?NOyLVX2hmsO;hr#CGnTu zAMuFjVSnOvb}ndl?8E2S{<^jcqKQewG5lEe6IwY>-oR_oSFYkucz0@}pxcjq+Cbj? ze(Wf+U)_`J5i7}7<TrBZT_o|9GPIjWx{1@>629M1;u@N{67)R+-pS#E2)qFP*xT53 z$58<X8}AktZPXugCdpM?%rG0_%;cRJ%dyMa8c>OBO>(F1Y^NChuvgPNQ7`A+b0C!! zrvMtLsL#8UPlfR^P}^2U>Yr{~>LSr5gzf3G4og{T8K6qHj|_U&_CYlDVhixGYiQI! z^l2e^SVx9zYt%&TV(tDjH{t_%?@aV-uLG*;fz?Fr%;(Q4DOz-i?DS);38oW#-Spby zJ|axliDPYN<=tv>6(cls$KFkM-D<^UV80gyIa|7HLLwdL#~P(TL`I>3n|PuTg=b+a zdJBR5-yc=^wh7IYd+7rwJB@nL4yPDwfXkpY8<@{f3hoAP?W~8KzwEv1Xq&e}=X^#} zYt0u2tTIQQL$IQ)9b@LG@qW%+@1Sqz<nv>-A3JTCIT4f|Uo0!aG)@3yslehfEm(?A z`6(AE<er<wC=+iHBH`sa44LjNp8WEl47SLx)@_Yj_3GMg&#VQ_5m<kmhDUdV4AIh? zB}bU%<|>xa9^nv&jc>33JNC&>o;ra}+$jYm=i_V}&XqA{Ew~M3xbuL&^H%$qozVY6 zYa<eI4jj~$4d*H*0ptPX$(&$aLErF1`lIY*aGO5`Q#b1l5Rv(V1^Yo(14V=R;Q;1~ zIp`OikXj?Jsa4dqwP{Sa0MbPB;KSK+m2!|i!6+Edir;9O#$VxN1%(CaId+dpaxyTm zEyGX7&T3AarE_D|U$+a>+|SaVX4i}6Hl}8>KOu**Nl;9#;>VzgXqDNf!TXo)C5y2E zrSr(TRI{&n1GQD>-_`O?isvvH2VfIP49l*tRvOdCKFL({XK2qVVgEjRxzFcd*)k3* zhgA3C1S`PwlUQ%A;z9Z=6WAbrFMiV~)H~=l2`Y+hc6MXpLDX<=H)H7In6vN2Gez4C z)83DJWcnJO-NhyLa8vPn%igp7h9?pFbwTg4O}5|A?O}}n7$C{X##Cj{Ak&1#3f+lD z2yNz>3uzOf7{=4*!uUPOq4<F`;p)?9K}R{Ytl68o4P_k&lIuT^S%M)dSz^)R#lk6; zo!!@z!@rZ@Ye{TF{J_<1L+bX}{<;EIBj4#xSrCZhTEfKWwm42P*!26WBEKE}fDL<F z<UEGt^6$7R4j`lUV<OL;t>KbH2Yfjn`&S4a1vZ#-`)x4Q*kG!h4QA9*61AO#Pto_e zp+)oUQhGHP+on028_wUQ=<E{%73THxa`{7uCN2#&aiNi1X3rq8pK2)<(?UV{4Ck?Y zm^a{gWl?NoaEyKCRSg8(Ff86!ts$wE24jL|lLo#~9Q&m8BxPrjzaAtg(tjl_Fn*D0 z-ds{Gz$8J1wdoIk1n(0I-G=Zh!ATo49-#&1t#3~K%a&H5g)1*=^RnkR{CP<JF;?eF z*!^MnEY$Mhf&4$S{Kn4FoDxKF-<IOoG1)WSUE8S&G88+h{os(;@$D}Zw~c}Z$|8x2 zLxyiq4s0Ivv+b{R{CYs%0fro@i;D?@#BKDCI0j-136xBzYT;!t0aFD3D(s+$OMr!D zl2WD?j?wsdG5me<ozD~(_^V2hj?EvGm-@WH_^NT!@1LQ<8L3BjG@RWT`-%cY;lZjC zqLW}4sLv+7%XxdxA*?OAii_yJJKfPW29d;h^0fV&Bai{x<k@HxT#$Nm1;|Svxifoh zHhdOgo(Y)qNO(+aF_OSzAfF6-L*O52v2HBnB%Q|`Fib6<Be{5<AmQgKekAk)nS8+T zH1G;s`On4x2%MU#2xX_)giutoFgJXGV!~W!bNvX{aAI_ow{B)t)m&bbc(>22I&0<3 zDja}kR-G+)57(=4yz=yFoL<@8r*wA`(eq+IP$l7&AZ@awid#-TVevDUyN^j{JPfzQ zacaVFrK{B|k5>~kAfD86Ohz=`<}l84kP(%{V8BI~JesO}b`}s#dfPA|eU>Osu2Uxk zy~MW6u0bWXD!AbU0}5_jd65oZ2@$5JT<sY>m%9pmI+0H&1w`jucZG<If8O7|+zA!G z+vbFdELf)V66BEK!<0pV(sUVhh1elc20r{J=21<_AJg&#Roh5H@5CBuz-anBQeVEB zxT=K6!hyGm)*)YF0(byC8kkWOde{XRf;^N!byd5%D#o2_tJa(MF&%>FBemnM(#;2} zaSCN!QIL3uOZ=S=NW9P`PV}-L`RwCdUpH=50R!v|{&}gonm>w?!^C@t_tK+@6-kpL zd9D;ms$V!sOew=umKgd)`g0g!8r+{?g5hgn@eTd{9iXUUO0ga|T_sMcDvGs<Czbhj z2!>{t=ott6J0xnE!URXvFE%9(;CVJzz{DWY_F247(Scsa|7o`Uc^YU@;CDtW$6Un; zcz6u>oiSwt<B+kS+?o47#AHWl#aSF^zhAa>s1C|<ACVun=8Nw4zu&mP!R_Z<;Tq}d zwj2e&LHvwh7LU43Jhq)#F0ZxlSvHZ5i_O5!;w^@8TEy-C^)u&Fc;jMc5O6y}!0k6V zb+|iQxp5p&V85O1So;aECM2^>20)>~yK#&3-+}EuJ+VS7lFb~*D7s@p!6moQ{pP2F zx7Pd$eN88$2^KC5CPft{o1af6(HM_6?H2ds0bGaZ<gHZ1SSLN1cH(@cHqok$-Cu}b zXe{1hD$IPEbcU=>pDvXMj(sLFEoU*Iw_)S#>EC?&FdLbsQrG7!o)jFyXgds|!N4It zVkU}^>FC!RWYZ+vl}(A!#8tDr>e3J6UyIdq4kph9bGJ>YR0D}Kurk>vqTMzn%%x~s zT#~PT+u|&L?YA<1FIP%f<x0RKzz)C?Ot_U`tsh0y>bfm1+fj+#t?s|OHMrXvm(vc3 zx^>~FU1Rah6AE~IA(-z!mBFkmd~=uH49ivg4%~#e6TNsi@dp8-mw6~1z4~y@4m)6# zlHMqu1sAPOUpdNQ=AKQCdwmS7mxS3*Z-DWjpIV`wnod>Zoc2&rf&zXbKgT8)GQ~_; z!XW|+zb6bz&RBqb>`i~-lzDPy{{B3Ki1fYRr7oqi)H5(+mGoFoIdLE{g&kyh<(EHk zVT*iCzTc8QGp0ONI`+#q{hsGg5RGT4wX}?#leB<OaU#b_G=L#j96BH+9c%}g<+;%T zBpjlAZzO&qC*&%o=K%y8NngoJIa%%L3Homz>3;z|E_+QxW5?8Dv7TiZd{HISITq_Z zv~!yauao%%3ReYFl@(IUHZU<H+tDAC8)(l#ABlcPILZDw8SB}a99Ci$bRoOiOFk=P z!vZZ5=QY>A>~+lGV{_`-+Gyg1XwBPxyqCiS=3BV4e)`9mo-iZ5J1qT&NRJbc_G>v& zCz3o4g(nE%LaWMty30oN#;V<1NejU<+Y%&}X|%?ck8T;NxdR#MMvK!JO=Qxa_%!qu z-&*S@H@Mx=&^F-+f-Tb$!oCX+E{sKR?}-q!;y^`G7uQNEo#)^AyWhH>uzdgX(fa3N z-|~B2E%j3+pVhI+I<GmtwZ(#;cL+zYE>mT^x0WqFu?r%pFYjin{%$!%j7IyLF0Afy zssm;4OWzl}S0_8+T<7!_xr+1omR+l<e~tuH7=>bZQK6q2-(ZFb;&oa6>usO|*FfU7 zu%r3LO}^KZ@r!r*1gh0|35=C?b>pb_wZZ!d!TScgt}!9JaDAk;xXMUh`uZUW%U(w( z`gc~re*AkV;yT`^&$dNBIWN>`I+I4zlz?)vu(xs##-u=#f;x9U;sm_big}wa5IkJp z#L=0yumD-?%q6K+7`dy^s(cX#$R|~l>{0_tnKf3_Rx4_i6$LS&#bLEQ!irMJFenv@ zo{c4%UhJTy0hS;hO3av(K2E-iAc!HEwi}KTPJkqqSV;1|)UE|1a|^_p;RtpPr){S| zMv!%a@Ky7Opx>cA08yrCpyJd(DStS~G+XvtOT=g_FlcuKS`M^B6d+Tow=QuC5`i9< zC`oGM{Z>h8OeC^xGi}oW^RcV^)I3naodVXJI25UoF8whR`~NCI^QO-3s5doTcdwoA z*t1@qRGyD#Wp6r?+e{!B1tb5nMeWuu?4TWJy*`?O&*(&{etL~2Z*ff-Nac0Bf>qVF zwFEionOZ+RdHr)?nh)B}E*TD;&d!`plLy65Bj9eAgWDR{dwI=tsIP%Fd3v&Aw+itS z89xU&jiaYNcX(gV@Yts`<IRpgH{9R<xS_(_Ro=Sw2C-zv0n3$|RHsvpVYzq>v~j9B zhn#2dt{v_zzm9rIzbZ(-L+Ss2d&H~kK-+R}-Ab!Hcdw+{umQqJF^U)<-YX0RIf<ss z$MiE_KAbDy!vtAw=e1XJqeYSyU*2ucE<CNDbU}CXo&w&wKRImTH1IcDzi9dbKWR(m zsJHG%l?LTab0=Dx7QU3NA81rC7$#!5csNHlu93!NenI_+$*GYM)=_=T;)r9kxDO{P zac5ej7V^5UQa%f!D<+&i2>Zr9%_-{d1V8b4M4*m7F&eL&6UEkAgkrZmbm_E0EDuuP z5k|>O10p^g#Dbkw3&gXR*g8^>X;)Pwoui}+lyr&W{Mzf9AWN;Ela+*g6Rf>KOynZY z)&{4IN=4H1hY3G7IPy)daOlab34$tb-db``I}i=H^HRAiz_oF~gRR_-FM`&#G~3*U z=DR>VFpdG9KV3OQ4d~lM=3Ym;ZW2!fvx1A7#y)G(Wv=9t5W{@cRvY=q>m{+qMd4<m zZr4kmSLq5f{xn;3SdRCkiTK52zZotbNxUBEdAVd|FII-3+5vhhEW{K!7sKUXt!<T= zTS#ZyX|sfyK@-OW@MB(yLC+C(%oENm0Mv}+m^~6H-4<BwsVH-$cpcM}Bh`#HoVC7Y zAC0`jYg(#N7sso%YloYff~{(JrfP=bAJFV@onmBG^5Uq;4(~wMB8J3jX;&_|?Mk~| z@1ivUlGQwCFLwGFmFnh36WaX57?|<=KxkWQ4b^-gYScsx+YQ8tf{|M#*I4KyEM%UO zeq5n7z&VB<Xyrs@ARpvCGQtY5&&6U%^BRkX2w`>~YX;dqSS)}Mv*i;RU^>uI&C%pq zBNm06>b7SWpgxkidI(!|>>%Rw!llIY^p<zAcw|NmkVeO}v0_R4`*$$(7ub5lW>`*K z>^4!Ve`;j*Ohv20=_kHM^HJ`LRB5@J9KDWXtRHI~Ij`4%@M}ks_B!oQLQFbioJj{r z0K;d}m*CfIYB<|w*SNLh^vN<osDsYdV=a%??_GF`pr<@60Mn;fHsE2|tbj;r(&@IW zdMj6P4q^|dE4yMCOf@r#H0$KVn_c_j2SZ-Gm_};4JiV@aU_N90IUKR&a(zRdukUT! z10Wcv&Wsgg5{Sr_W*SEhv(HzQX{t0~lPVMrTZN#8@Kd6^9b%Eu11ME%FUK74C$2TT zZaY<Q7KW$4b*0cFNRrRLtz<97(j=A&`66X<123wDe<B!_C0g-1r)mDBJUyj<`wf-n zl4L$6f2YFvyN-ptGeUg&c%x~r<0Od@G+-9Fx3+73Ee_Bmk2QG%!MbC~LeX7n8q!eb zVZ81#<*MD`Dx-u6H<H+cMbGOv#D@${s5wIq@sFD_zvZ!jHtuG#p~e;3fWci$xo*P{ z<3A^upTyTwV;f+X_%uUuWBgP})?B_7395kXPIj%!8vh{SX_m0m9*;=+`Y~FID~4No zVnGYqeylmkU|Q`&W1Zn!D_8@cd4hF08?wsT2E`VrWt-Knf`u;YxGS?m?KqE9hr^V$ z0wDhFNM!e=1Cr`?xI=b+uHsI;zhXcb{*&I%q=#*|^Z!yGr*YNG3#4cLq!|vHIWp;< zGpyWWM)9d?fV;LT>F8X=*OZmuSdMeg=B+KOGo#dvy!P*rp)4vf^}Iu3`z-X)6p>E8 zc_^28T?6dWhSTpdj+ymV=T=Le`B(Q@Ya1t1Yq-)6y>}>={Z4<j<z-aC+VLm(Dzc01 zo8u(uk5Fp%%3Q@l`<yN1TlVWg0^wJB=YAF#;se=f*%S5kGxim>nqJ4JY-u*%#Ip3G zdwDU5c#-+K@?0!EiE8v<MP3&aIVb%e^s=8~c9npHET&ig$t|XLgGjQ2?Xv3tuQ<vd zW>%v-#^F8K9}sjxvT=`Qwwc8L(aeJl0F;^Fhc|Ia-k`sAJLB(`upHYowX@rXzR{cd zPE+!()s}E+RTB~EI2ygXgk;{-H%YlIn);2t;`Le*^_re<O5P^ji@&T_m&W*E754<2 zAOKaRxo@Nu^UbU-nrFh$fyqW3<F?Hv&PLA6@;X#zW)%%&4j!WbKRs#K3$s)tzPUt| z(INf!r+Q6?Osb(%Q9p&QmuBp4OpZ1)OJ!5yFb3d1GaFcy(g1{GU$!cvi8(=)j>MA; zrUkr?AI!x@Ng}u!JD9K6^kYaXTA(lS!rIsQ4(;R1B-A7Y27}z06G@SrUp1yV@k*rU zjWBB%T6?$z#@Iqj-%&*Inbu0cvWuhJ1eT`6KH6BGZ=)I)wrXQYsTP~7v22^B2SGU( zJI;bB?;IMmjXhe{ervk7`~uh|5sldomrsxx%PYzOjGNE~P;{)Snt0?ivo_I2XyzZ3 zB|bM2IF}?o7fSqKbmB|2=*lsP=5S(a)wZcrtBN%!$BGpX>aY~{G$;LH&QU{4`qg6S zYN%)d@KmSo3qJVihx$Lz=Z17^@FA3*r#tYw`wvH|ZyU6~5$^#f5j`w!s@Z|g{SE8C zGxfw!`mpB{#ZPEpM}}0#sq?OwDy9TQny+TAVw{E(G^j0Vn<_03kPvI<&KKu4n70(N z?75}zsu9uTc%mxLmc+AH^6j$CYLBcHk_p4A8sC7tjtOR1H%|4An)Ap|ri;?YUy`W+ zX)oBw``<9efTxKq{o-ACgTc$dlH^gqxb1%g3}^4CPTY^Wkjhh|mYze=c~9VNQ${i% zIku8$h!~h^j1~EXnv9QCycK6Ga;FBP!j;}Q+|d3`v2M;FOwlEH;UTK$DuyuU<jtdK zrfi+@diwn*@SuhOkU=_C2dEj!{9bpowk-W^wpH6_;b{me^``cCohiQaJdzM&iS3-w z$4jgeiAzUjKWkHM{JkNI!->c48HU#OPPJW*NSZHX$(WMZWKK>T?vS{&Ea>8(9@2)9 zGSLLRw+=!(bYo}$1N<n;j<kUETXY1ZetY&HePkab7P!-KPD^P?xpVC<=e3{w*a(`7 zXVeqm1oruVr2+yuU7Q*}mU$**q0FK++3d$9&J6HmH_w@%$##AE=XJzsYDNwK;@4E8 zi58!+&zK4-NDp9&T>4mbc3wew8_%aP&LidyC6av~n<pMe7wYVV2`9Fly|wfkl!ySd zr)^nba`BIW<R_3kS(GTL!X*IX189^zK2p2|zevyf;aNOpD#(CABX(T;z_GDV{J>d+ zi{sVS(yT{t53sA60<qULRgI;#L1-4nzEWN6uOD~Cm5au;wSHBMTMMt2tFQRZxA`{H z&<D8*$}@l3T*Yle^0eu7N|F&(PS66Z0eW|m{(@Z~8<r`e-;==DodY|l7>aBVDe$`v zuZfGX2V_rm{%dbBY)SLZ>|^9OQe?J->~kUHX#ESV9Q*XV9cOSD{|K|B-H#v`yBz;2 zov!(5G^W}SjOWS&B+FIIJ`6F72-LJnSb=b+P{!(c37&ud5YBK*Ra~}9T5}4(*Wd(r zPv&6&2F<zm7Rh1q@r}kSZrowK;?(CIuki2r5J}mOHiBHgR4&CuGf}fN^H;aa5rb{% z@1Ii*O@ZS9O~EVzsJT*)lJm_idF@;3yz7+#cww+EhK0h1h|7l1ri5j<kti9$4n0J6 zr6jo7=NhbqZ#`%&{JIq|vnt=hC!vFWZsw<NW*<cM!}u>T`Pl3JIJkbgoo@g!Jwd_^ zEN;htJ9#E#Y2Er(=G_GlMFMVslE0&e_T)*jU)`hV9T+tfHgGf5?}M+g#YS9b<7xcC zA5hLpsji|h7@so^bH|5^h7>iLAr-F}m(Pa#YG$e+SEYF(KZ}t=C)7+oI20deuk+4< zV)twCi<$CfSA_s`C0`8QVO1okhU61fN0T&Nur`*dX#o++QDp?T$iEU0h<LvnJn0)^ zaMw^7xS@#B>0i)t#q9B=XYF<))1t0x{bSWNa2*)lIr=7w;njJi%0NRJ(7Vu^?A6%) zfbKu4?}=Fh^*!_K|7Cr5D}$@=PXMPM5z5j(mB^cqfn1jE;8A1#)PK1#A7jWjchv{l zx6PoIH*qhAer=?PDIJ)&fu^k7l}Ge!iaX{<(|{7#`pnA5feVJXUVmgh&lfKP`t>Ff zFzp;w`kgSOLbx4Odb@_<|0_Ozp+DX#(nmCvKOBT=GnpK*b&$bvxg;BDVwN$c@~u+@ zhk5Aiz!B9LPy<#j*}M1ya-eC_Cw>|Xe6IEY8hE?#H%c*g6*cfFIclz8iFew`IvCpP z7{Mn!TG*SG9R6s%7V2%<vsR4pt%E=fhBy(7EQudD5ubB11qAa7B!Y#9<C-7v_wVx0 z;B<GZeH(d#+D}szsftd!ATh|jt;I~|&*dssaK?_zsL=6i6cuDqlqWcJbN`+)7fBuc zit{Bn&L^abJ`x{-To$d;w3z1bcbnSO^8&<mA16P3IXL-=?aF{pZYg!$xIH;HK#fN~ z>+Vhe>IsE6l@p)WnMDnd*~_0oQ*aj)1%@*awd7Q{K8rMlg!kZ6klMwCAL`wQ!}@Su z;fE^s;m>>!4=W+8X+e2I+}A(oEBisE-y%4a|Db3_gF~lnmtEeNlD?Z$Bj|Q|i%yTo zQ(Gv#=tW0uSKs2O?SD96DTp^iJdZ{TXI6<OB%MMpi^aJ)dA81*6#y?qWoSo`D*(f# zA%p2x-Wv>N#w*GzsbHh|EuKP86T-L&6@>v0M^wQLKLRG=6T9Kvp#j!B%xN|be;y84 zG%`=FA`8x-*^0a4z0K^bcDN>_AGz4Y9(bB-uHxDE)ty|$V|E=7whHa*K_K+_;qunz zjoK1q%URkZ9u7iZ$2k;~jyF^b{~dX`okN=3=|rVHfv%`KZjf*yAJ)gRLz~sw$<&;m z*+<~rgY!sv>xZ`rCd7_+dPNJ#OozgOcgx9up#QPAuuYc*!_x%Rk{9I89H(bzuhZ&B zcq(@R=S%#L=|5NTYa>ebMViy&QjVeSgbUoHGBie9!MuDRvRuVo@AMO1yFLZNz9v(H z0#|NIs_dH2hvuH+eu@ABY+<y@zeUNQF|bDl1{Rt%+u3f!(gez<^_TK)hA9EyPB|JC z5c`kpt3n?eHJYncp1S^awo%tZk3&RDnHfV*2<Vb(=*R>smzyvp(4*2;%pCgKps#@h zblx8Fs<&a{qvFCan0jw?<tHpntZMXNT3qD5#`Sf87B}1{iW)#Ui;ojTQi)G)qmCl4 zQ~Ia$^C!DVt-oL}rCXd*7`W({8YJM>u~Lm^t(><XG?ZzC@Bj*NDN6s+3Nc1}E@y|Q zQ$e9qRj8KO3qt<HT7}hrHhqbX8AvWfG9_L~-lt;{L>(&&d^!SGDi~KY)CSqXhy&!@ zz>pL+a5MBxKLh_qEM9x@r;R3u5zE$39@CVZURJj+Qs39${cP(-GuJjBuG`mCf8WXb z8ai^`)cp<Zhleb@G!@tJDt=<SzyAq7`uiUun#6W*N^i8dr>Ukdv8m_P5&k!K#%DlY zJ+Gea7eCbc?QiZ>o|+xFsg~g^7z%s@p&Xoc6yO<(bh1JED~S6JVRiNrbPMjm)-EF7 z#W=&FmOJvLEkBt621+X(vRR-M<_ekeSQXGo>6p_TR#oe3fSBh!+e;R;gZTcCPa!@? zehr&+ihk~`p|+ysTt-_fnD6((Y1SxX1jsNmfpejh0fi!R?^Ug-QP<Hlrk4eesXBaa z0|ml7V;3ZQ>^vo_n85eITl;4WV}THM9F}jP#@v5%^T2=F=K<`UyDIl!Ja^6F$}W70 zN7a6a;=Vrm4!?MN?s)_o&i3i5?(O<WZ`Y{auCsc(#`JcL?Cm<ex9hmxF0Z$1bZ^(G zy<H#b?W*kUI=Q#2ytgad+jVSj*J-_7XY_Ve^>&4NyN>VeD(meU(c5)QZ&zt=*RbBM zp}k$hd%I5T?HbbCRnpsaLT}e81uluJ;0}#%st*DGgNyC;6O*)G@SBbxzxSxd>p7e8 zjm0(Y9XhaI(AM)}nq`b+W8wi=b^??7L6#H~5UjMMxSuaXn__9}br74v2~_T^V|fhi zhVFFT5nQ{2Ygcex9b8uh*LJ&NR2&e<bl0FisD-2;;!nteoW&<U4B;1f9aqzaNMg77 zlQbpXx+BMAldD+AM^h1Koh`E=MWfiio=akT&+}!=o-ZQdvgeBSg7-boh5Zo^dAINI zM{H*`G15PiP*pj9#13rO?aFw4RfjS@+VgVRvX?F6^Dg7_WPHoJ{Y`(wqm(kzr$Ed3 zCOT8iF6HJ?hpXMK<kwGT=@vyW3D|i8At5m(EJO}-Q!OgvTI=EAJBAo2`Y@UoleSG^ zN)v;d;p<&B?^?LBg>uR)y{P48j&2&bna9=VitQU{a<hc%5<d}dR}tLL;od-^HEqHi z0W*KlxA^3xkWo?WD}=e(SGUuk$)O?a$K<tiBiClHj3l1hC{ft<DzZ0%wIDE8q7g7w zLA~=w$QHSZO-$zn6uE7vQ!Py?%U)y!sD`?GU3S}Gk*nDDwyWl(Ttx@D;}ec+8@aV~ z8<NJ5%)en|+FE)S_r*YuR?09V<TS>MCaT|c#nvl>^ieXpChkiR$NO(^UselqqNxp4 zI_VIZIsHe}Ayd8E*Hp<QHnn3<Yy`95hKHFf$Fh?KM!CT($QU9yX7NRWHDV+c(t>_E z4A=*=Bo!FHbbj4_^5&`uly1f@NdOpft62S;q&Hc%_qsiJ^xyP{_lXP@*rVfHLXrB{ z6@jnhoUJM~c8;0Bh-NbB92104P_ZY5lGJeNS&#QADWKnH(L+GL`i!T(eLl%gZm4R} zL(j`Y1NVfdIZIMqEJr+<L&zUg%U7^(=QVOJ+bl5k%kf|8rC&E%|6Jglx4rMUc=B_- z>pH6Ds9Y#S)GVv$0-h6wh|#L?@&;)k8Ti-;u%yx|jxE%!k{8G3<pE?-SWa#{hFK%l zq>vX45m>zM=eFaz6Iyt(Otd>=Rdx5aPdaWKA#Za%e*N~gx3b5Z=P>cAnKcT0hTFWz zz}Q&)s9@~UqaGR<w)}wMkcP7q=g@PmZKE5w+lqlp!w@e{SdyX)p~%EG1cXFMRkE~J za$3*+hxYe?;1|e7TNe9J|E`;IcHN8$cHImkrA0qG1SevD43q)mJitREt|r?lu!yy$ zU<jq4%4`CUNiZC-N1XLM9`nJuibC9{0)S(N7OKtl-spZ?qp+F>B@|c{M!{YR+;-EK zzuCo&bUp6is*Sf%{GGG(4ywIWSR=CS_!Vzhx6xxYEU~5YNx{eKe3SQ?>Eww3oLa=P z|D^l<{qQ<}&SRcP(wpz=2Q<N3mhwr95f{Ft()$Ts;d)XhhIl{e@tXQ@N%J~pl1>Y< zu*q`cp>7u0e}n~S5&5%CUdJa$kO}iXSMe>R0r-kEs!o}z!nT%fCpBOH3aAr3^e0vs zbfoUdd{=ODi(4P>BR&kJpqm_EP`2|epECC40;IS{V??yM^J?LO9}scwWWBEVI<u`T zHOMmUnW06u6=z-mWO?<}pwioZE$5;ua4w1@9=uDX_g8WMyB}D^?Rs5NG*HE<RDsV> z<mo1Cl9h;5U<qS38{3qmFFp9F*%)lfxMQ_zl5hK~Zm8Q@U_LYUYt%4epo9MgA57go zz(lcQP@CJYY)2H|4>1gs_PTZ!3CfRIH8yN!Esh^3^E$7jYtqG0EpmXs0FI`)QbrNG zv8pcq%+y(|bw~!p!hX*yW$B3+uM%6tmseTi(MyUsuO)g1+|=H|+ceh5VTX4d%IQFc zM=8O(Kfk-ZV9Y3X48)9)Z%(da?<;VLS@18wWXwyYfo&6Lou+2ZiOismoZfEq2y+SU zSZpEWX0eOaq=LVX=2jUHr^moCxPz=rfs&#MV;!wxsZF_xrS644WMPQ+EkhQbLU`or z%=7PJL0noD%~gESC1@Ga`Z6zOq9^4=2hI^2U6R`1jM7i=ngrv6$13+Yfk&_7Mv`(4 z9<MS9ZZ)6!iP1pai9C|V7c|o5ZW_vcneI2c`}ujCaRvt=p%dOyZU8v9lJRGKKRmG| zb3FV&6t1D<+(3LEAQTp>PxGu^7sXD4cQ@seNb6fgZkOn{E|FgpJA*`6mR&i{lvD9O z?8l{B?$U9XkkVn>4bo9JmHxFq-Q}d)hk{*xA1;YZ91C*p^ifyVCtX?Wa6VIsY`kMt zIAc7$CtuwOB$<nWEKyRG9UiR9VZoQfMih9!TQ?qAIS-4A`+M^gt?4QjFw@s;70duP zD;T`FpKQCzPnO<{k&>8!<TUPHF_U(SPNwEx-80Ji^CAt=d(OCWm54jLEWdi$wXtns z5_{~r?s#7bjm&&YV^lGpe97wUEKLcT+oMSf71huT4lnRiH#%}lIj6T=#oZ)l5Wkw( zVk`#Xq6$t{djuCFUcIz{t0e}|95>9<VKMo}an3xAN<vft8vgP{J_aV5%v}d^xwpM* z9d)T07{n|8QGLgQd}2&cp6ab0RPWAoVZHOIcdjUR!Cdd!ZiR^LIGgG$to9Ucf^Uu9 zqZgGx{~TThEgPvq--GDX$kU5|Nv=#^<4<0>=_hUufaZ>Pw?!wG+;lxnJeu{y|033d z@rwa4)&}3uxFIuEPZmOSRLygbcic-y0<IzkD9!=W4b1GiPo4K`lG$?FXVg?u_EVHK z^M99lvXZ4n-E$nfGrN5}4gADZRtK1&uL5wHH(g6EL$3DkpgR59_xdBs4DP#RBm-V8 z`BoY*8~RzKIG+<^aVu{+ke44&Wh#Wpw=_#b2w|q%=Z4CyB>wJ@I}}obS>3xg(YF#y zHpcPto=m7GUCGn&E1RlLVCYAS{rjn#15S@a%^ku97TBWXvUE!ya7+fH0k`jZp4B(A zUFRu)&vsp*Hw6K`V~?6HIyI#P1rJOY4{mqU#ZBY~wsZRaR|69vS>~t80)_-b{771g zfMAFjQ*jpkDD~XGS1O2Nxyjb0q-0yq)leazwmfLl@2o$V%S?35yky(|s+sSREc2Rc z!?3^ChQUq!r;#Wqj%W@ASVs+~iCg$>8Asi$P3Jzh-nB(yzB;gkEC1|Xozt(7BHDv= zE4jLk;=__>ap?=bAVS%e{`qq(>MD9bLv$^S%hvx@hZ9PcD&2nU5a#4*VU7>4R`q87 zXnR3rY42A6+4OH7V8nRPNTuiUKr~P0g>Q(Nr58Pgac#CGM-EA!{Roex*>b($JN{-5 z^Wq{!_YGcb(Tk7pn61#CGxQ-}Q|7OSG`EjQhba{TOW#CdO%4s|XP$O<wdty7C}3!i ztrqB{TetA0g7X`hIfACko#kJjJcLDJfBNmDR8EEGZ4ysG3#@QN3K^!J<gljX+!9Sm zaQcgIS(3S+<Qbb^+CGV=#RLQdj#B&rLF;k9c=c&G>M9nKP03oB;vb&$5wEk1mbjdc zXjXczG1-i?Fm)uQj>NDw8sk<AeH$4l|NoORNY^$=ejG3wN<a9Tm3}>6<S%eU`L}`u z1Np5EMAs{-N~k0>HHohjvj@$ejt|s5w1pY}!k~^%A)qdDb^P4bQOy_R&%*ZqH|6(d zwc?+V=@>2gRkiX5L4)~yl&@^xd^=-J_c}oEqWE1#i8{o-q^%-(*9NQE&nJ;<aQrS2 zZE@Q~9P(sQL(c&?<s&c0kQ1aS$yNMYKF2yzn19197?6RG*YO{`p>kF>xtNFF!&AX~ zsRiP9b@R8l?S$lQ63b+Ve-T5lM&P^1A`dWmvyJbBjS?AD&9j<y_4QIe`MZ_8j3$30 zyw+i8N67Dl2MG?ZR2<~w)G`7^3hSh1h;QDDz#e<by3Mp$hIE=eBUcdu0|6@fiEt$T zz!3Y=I>LP5eowO-<3Awf2ri)^3s1<N)|mXk$Xvxw-Ivgi)=?TqbE&(IcWy6wVOWe@ z#UE&YK?Mc%|04S<New`0kB-qP{hUfjhIQtu0$7o2epQKF$24Cts!JMB*)PadG=mDc zipyNN%8V#eT4~jX;|GT<JYAikBcq2b#NpBU#KFMv&m&4@F6U2^rpg^pVtC4@YuzP0 z#h#;=1345I#16+MPLTGij(kEB!5itBE1gF8M%+0H_16RXC*oa6>l8n~xNW$$(3fQ8 z>Z6rVQ6s%VO^x|7@rH!vli*$=tMSB-`dvob$tIVGp+Qf%idOCh;zvy)qJuKl?S#^V z63?jU#=!HW5ppU)`r(DGQqYofUO|5}hP>z_yKbQQ$UZf&_EUXC-sT*Z6=m^vhqiHs z^QQ`8l>mwB&>Wn3GANF7K!<wb_SdH-pNf?yUAy97ZmXSbIfQWULt>+4Ny(q2^Zl|f zW}dA(oEyA>zR2PcEb)_*Ul6Ht4(Rv%<ay6>-!CdUJHd_62c4^g0KY2eL4)U!^3Q`( z3Qy#A`i+6a<CRzh*2`=Io?HyXyE&2IkCR);%AvOjj0pcFfhh4TM>i;(hl^J*OTEK5 z@CW8hYzXh)BW`E0SqWc)QTgpIAprByZ@ZQG@3;_^jw#iYD}^f^THwkwH7#tL%&ED~ z7YWN=X{O5+<V+=EhRRcEd064Q2r4$Ix?t;-={GKM^XW8@k~lG7ZXqgqr#BHV2D+$* zOF{U^ix>YB8N8`|xrgvie?rNz7ZmT(P5=HzVh&8mojEeVKRcL*=gmq4ehlC@HiDaI z8%-REL|9}&d)LuwHesUOj_UYpM9gSnTT~!kE3!&#CG{BV5TL}Jma)1DY=X9+)iFdX zc$)j!(qi+a$ILcSiK!MPIw}SBeBh8+6KwJ65oB!zFK#H!!z>5uRB6>l2TayRO>Upi z5<q;uz3r%KC%LTe6H!DCi{!S-%RMv+uDzTOG6{fm3<=vw(=&c07&GkxK@<<bU!Jd_ z?3H!*iY48Owo7_7Kh=mSjb%#w2YO1LdX8ET^3j(!IAss@W<w4K+&63{h3IuJu{Vs~ z2v`e@3U!r<S$69dGWOv1#X_qZ+s|jq^`hb>1ZAfgh2IHQ^yDgDoS1kt{xb3HU#4UJ z2)1Pt-+t$kmn}UzX)xUYwXrm9EcX6L{WD(tIV#q^3^XtMt=A~LFI`Q)JGB6K)$4p# z2?oA>s{h-2UT5#%Zy)Oa_Pp2mU-~9+DUg!k<5BI~JE(o;t{pAT`1NejYmG*W-?ck0 zJ`?T}Exv+bKmlk`H2nDEjNywBujwzrKy)lVj2C9LKxyj=gqIpUh?KIY-ytl`r)(xA z_;ACU#YM@ImB3>pU$EqC7D^XzO#CX1s)%1;*HxG&jXqTYxGFSp0r>?tO}68U0dT4W z<>%&V@IH0~Q5Mh-Cu3vyj$bgOt<_I{1rKVJKtHF{X!1JNVgY}}3nagx=bNGwi!Aa5 zAyyeiiYux@{AH~LcM=Xx{&!S17FDAP7KjXSQRBYN#j&Pn@gBcE+uBTYNxvrB_S@{a za)FIIUlDhrY3|HlVfrxfS7-?;u=(m4q)D_QC0)g~e{4_&g*Eu$?V>Wp7-F6>eq#Pw zdH)!;s1R;{F*~~V#i}jNhLmfxcsD{jb`|!gh)N)=j-=X;@jdGtj%Z#qA@wC}((RL* z_z7pFzv|-!R{GS)MWU>b_M5V!6tzitNuP_qfK_GRLbgWCD4UTQO{%7ckRfJ16w3EH z2+T11E{QC7q|BiA@`)MBOvVB;Xx}00lspA+5^7;N31>>rYIk%0O_p@<{8=!*%U*+L z0v_XF($2lDC=9pK(T!|iXJ#)#h|y7jtQmly0$7~3P#I>zG&;qupFOPELEHOrEyH>x z>hO8$Q=$IGW37}sk$MJ~va8jV(x6hvo*MPfD#%K?v1&EBR8T{{pa%2NV*WU)pnnPq zn$TZRb3s8O6%{lgU(ke&vPGcRIjW$Gf`X9AgBFz(6lBbsf@<>x)oQ|i9?BWqucDxo z>i$yhIW*8O$;E0;b-tA9KxObRM-{a0yAD9&=?*|`1qHPS1%>kkh0WnHSJ84*L01O_ zu_g!#8rxscOl+?-r!rqk<wo&${Pd41r8+1DItfa7`Tcyqw1JjVLitic8^w9>zXdS| zL+5#<3kwq1ZD-Dm`ZZ<1z2D{k?f}Ko&&=0OD4Ql{B9bua&cd2`9}U}hycPTHql!&Z ztdI|*Bn58)nIf*>jM`O}Z&%qyVz1Dyu}2j!-P-l2^-bB2aed3suDu%x?n9>i5Yphz zRH#<UpCg@i7YtkvOr_UXp}OVadWXh5cLyIE^sz7aXsF5aj^HCQ!}V3Wf{&}HQ_s7D zj|dRgSEYlGhDAK@4L(-u<ALB~dyun8bWMZ8`dAh`EYU+Kc&OAvW$>^-58>beUd7gD z9<+(I)~>fyO$a_BzFc3`5IoG&gKsI;RJ8;z%k*-V9ujM?<f@ppRrB-=?s!c|E~EbY zJwqOZqmHTtmh#4`CAy-&Y3HgRVHsBHR=q$(Y;=@>q(rcXQoU}Z(H+6Q?MB>WJKVO( zP-BbkrQ6};6nr!SzmHI{7mC1vFJU*&7x3D+xoS71D{#RMyE0C8b*ivD|J&t;Jr#s> zaXj#ptEoTF1C4v_dN)rE1KjH<Hh7z65}4`W!tVdJD{O!jCJPG7bFiaW;oJ`_tUV}f zfE}J+P?(_=;5>>Qp8SD@eIh7qfF-_pV4$0MW;U25KKSSd^)WNw^>KhL{#QXs?Z925 zd=y(;{(*(v927Rd8ZYlJEZ}HI@x=)rSkh;Mk_LEVsGua{YDe+L*B|+y4weNa4e-aU z`}3d@8>4qe@yA;}u%vsga-f>k&uN$Tmvm#54_2$NS$U>5YvTx@ho0dB3;S+RnB$C_ zp}cVv23vbhg%of`$6Am7z(U4S2vODgx#Mg5tY?lpI+ptQUq1*aZ+}Y}iB}(R<=e<e z-O6|%V5_S?FyozMRCTFQ?N-;+KI0qc{8tNAp!(GY2V13Ly|4%8f1r<D!N&$YtPegq zmWshK_z1u4sOk$oI+lt<Snv^kOPHtNV|!5N?%*T*Hc&nzki$~pFTt0v9>5@mNVX;( zii|C@2-AZ!nfe0PgjWR*Fxw9Hw&+WT8(yBn!AF>FM^!Zs(Znszw}$NS*TDFZSYxg` z;;+6Xf(hGoL)9#m03V)X*BhPT2kyFnXZ_%=OLR*NwkRMHms~}|H}2(KaKPkKI~Y_6 zzO2nD3t<{34bt4HH0G9fuJDCshty>(5n|osh<!-zJ(YUdvwLVke5m*C!^NjAm;IPB z-KtUoCs;uR9^VjdTvt35=h9AvsL0e%952K#ZM><!i}!c#CMWTKK^<Cu!@3V{{b~8u zpZxb)9~15k@ZxmSZ*V|Qx^NbRyD*E0;8IIR?8Gs_RxM9k|CyfnpoD!qdm(0TUCXbx z;6z?ImKc4nb_J-Q7M?X$bGZ7+uH7m|0iAS)BRZ&I-VHxi4Kzt$POts7mJtruRgGTe z+hgNmi+bb?!(zr-?NY*9m5}x@uGSvcuArR-?dehjz@=`k8yol&4EzfZ1Ov}WIV9Mk zJ}9kX)pXl6m@}(`IkbEhXHgAACBVw1uFCFQp8Y6iU=O?iHCUZ|tLsqio(4)9@DO|U zUJZtWndAl)pnB~J>{c_1UWoJAT5z*O-qIsecee%?yfOT>fhH-f*0)u5y}qhlSBhF? zX>T;d^U8<lmHUK6T1m<;<Q%Q()dq5&{ltY6{NzZs1xwIaZU6`&XOu5rEf`45C||zH z-8OLBZnuMljPlDDc;%lZ&vX)B*bq&$hO*z&0IOT+um6F?+6Pd=97rHGPK5N)JYmey z6UXzJD0I!dBk1baeWF8aswKp|?x-}^D$O$K$O@GQh4jAmFZc(XRru!DdNUfu+p&e{ zaXoMQ4Os$9`WOF$od`_<kwTtL9~vV8-i=_tIm!CFP|5J=8wwlfFJP4*am{UfIVCVX z*_&_Z%>>?LKM}mPnillPT7@vi0HrVeBWcdj=REt+!eNf%A-Ev2c9^3Bzms^mq(7;g zEMwCj<3`r2^S-Mka(}!+6avd$v&liunD3*M3DY&(`&tDutk=Ws!fL9hWPfY8xIfCh zoaW?f)Ij$wa@;BKo~=z|8wj4lazf_CAj0t<WjCc+)kW+?$1eM89w|>d4a+E79xEKs zd}ijyDiIY&tyBjSR0Nt>7Ha91U*ce(M6vJM{=>ws;9T%Ye(Eav_kI3PAuy}{+72Sr z8n&6r$JWAm1zT|=ucYvR@USq<<y9nbGReq+WuP|tlD>fLMXpu<)C3%fg<CQC4d#EE z)Ii*YJBmUK#J6^$s$vWp(0mPT`+{v>aco6&se#jVb#Pr3T-)u+L@DR#Ir@X(u0l{# zQ8w%AufY^#K$s(C(t_+6C@<U4*w057k#_x#eI@fVipiVgiC7Qry?&=)X&Shxi37G5 zbiG)bisH0WU>!k88#2eYNMcM?_Dk4*w##`X?>CY!zHMTZv(|wf|EC&Qr}l%Dy;Itw zc0T)!wiH6uR5c-9<)La_8NSKLPY5R6orUAp&cC2&8!H_n{vZb}2s{6aYxYb_;l{K- z#qaGXhBwlkN`XCjGv%lI{w$<^B|YbAA@yK=kL_PUDTwchg~nwUm><8OD0WH^dWlF8 zxL23%gfn=ZtASiL3?gIi12dTR2c>%UAyTznyHW0P!EEtoF&2plNwSI<h0NTVX&|J# z0UJST@;FJPriZK;!|1wzVdbUmlq(EEPAcut{kGC&T&RT^^StHm&2?P#^HYFCE}%`s zSFM<;kCYfre?;Hnn`_POn)56M+W0th*Ka=<r2k4|gi?GXIza<kk>8n+U!H6dZzORj zn!K<qdex&7nu|9nY|*A@5_WPqbHwyoKfY;#f~v04_R4eo#M8t9f$pXjMT`4T81IeN zrx(BI51m@Z&7vm@;&BoTFj~K}ZEfZ{Rg=1?vN<`oT4yGVYvzPg0+nI|<8++5J%PO= zQa@=NCqdF1f7zBIQ7AFq>a%UH_#74V!<#Qq2Oyv*3O6K6se7;5Hi1)!ionkKMU`Tg z3&>?U+E>%Z9fVf#bJZ&pD+ed3-)n<_ifk)T`N)Y4`pi%FKKB|&+c@B+<b0vQ;hv~~ z(xtOh5)LjZq0<gzYVbNrfUjf{RVSH5<$DATyveRNJ6VMZJq-NCBtp8D-)QOvul#0H zE-1f~Wjai+pl8WECSxf*&%1(W(;^^>)@nTIxynm_^y_L8D0;bo$lGr9EU`8H$1Ax4 zj6R+L#zcK)Lf&DY14)9yyY-dENlfVPxujv9>vpEUI34KH^KRPEEEPFEO_URW9Z&Qn zd=O|{=L5k}<&jQ}H(-cETE1XGlYn#DvkRaXr91;dzVoEtOMCk}&vTLKMS{f%`9s0; zUeyndV4V)uCp?7pP^2D-BkDm54atKIWK*$Pm8jdb!L!ycdJYH0)+#;n=LEanXloJW z)7nGnx`MIS+C<N*jn>@O6|GHH24L2Np!yf6yU020CR@s^M~7`RwT6IS<D(M<nvEtN zX-+(ay#rHObK->vq2-vG$UvgHdvW#hI?h#96loAl&?Pk`kO3venm7sC)#|;v6nr;` z@?DVB`@MGMIVjH{N_n9my+EPz3`C@FvGQ1U1?dG!fpkHTezjeZUxRcz><Wf)l|y;Q zGlFFbrJA9PYq$#NvWoHz%{QEmSOY<&;QL;?x(2HQbL{)|RSUQZAR$#mdF_@iXfPd6 zgO$GBu1Lg6M|$xAKY2-58!2`xPoPEvc02S)mTs<5BvV4@fmOkD!A$eMMg`NzZ2oY! zK(Y*44Sb`2MUKp}36!iZuR*svz`<k#Y-mo6A16ZF0Y(I;I^ko|D^W#XmTfIkvud)0 zpwc!4CQJ=}gT>nY5;JWCX$(Q&OW=&7LMucISe5AHAb;YQD%;A{#yN;*>A62uXuuzY zX<+Q6NXkw_5+lx=wuWf}4+;pHgoIK{lcI?$@t!ug$^;IovYTH*Uvf>L_9TMl9)sh} zPID?Av6UB!WIM-b944!)$Wnyf61<!hyeva788)?UUp6FrXnbo!wEi8h<6kIZN^<mg zPSS3DRk9}%W7rfswlnJe4YU|?dXNn($F<$-C(HahKmLuY+rDzem0$Dgu<0}m^Y6U! zYi-|{|IMqf^6Pf^Bl_BYGbO%sd`X$tG1=Nn+&@|{BRO+?<&0!>JcUDN_=ERSau76m zv=Zt}?_;^Cd$N7$sbEFNy`SVQkrnHoXxo!{6Z$r3Eb|j#Hwb~vo&6d{)lunDqY1)i z7zqzxykQ$88x}@_p|t^K7NVU<`bdmlWoYRrqY&e}^q%xBL3w$MpA)2Cz*XrN*hqHt zQ%HA^en(LMD!cNXYvv{Op0UBjseh9fj!fNc@2RME8@@mRK-CL)7R7|grKV`?^&ASG zHSBs8cI$gc&vZR(SHb|=)gh4-*n4eWf-vn0McUQPSDLuBO42V+1;Sq==oBkwd+(OM z>C6lA=z;L^vy{lRLniejr!n#Om1-W%T&3pl{C_ij<>yJ|vpJk{{vS?bD)t{uTX)d( zBFzw;&#)^Ydz_)AJwL$n2cf3nB|DTD&K5F@pr(qljX^UtMN^X+rq;a}B^22b_RO)L zIuhSp*<Alh?6m30*qLP57uz#Ex%5obcKOJ<93q!}TqW9IP@*Z!@+J1qbGeFp*F$K? zC$rRS8z6B~UlHzLFY~Kf<UP0{P$*$!AsPD<<v~KSS>gvcqQ%UkB<+@xykb!)7RAJ^ zi8o3!Y$B$dcAjnIUpiMKkNrtB!AwoK8$(F3dLiTvUD0$M5C)*>N*iM4XQ5zL;(fL9 zk&ctttvu17%JYNrjP@u`v}e*>kbX&!zCB34GDt6)Q~gGRl)K*2BQPmFGt>^+VUbt4 z`iYLJ-S&J-712_8URzaZ*PE-tc11^_t7a`Fo)tWpesvBHQChmnuHd*nVh&r)HIn=? zE2e`bZH*j;R!tQ}_Z0CrGIUWmPiZzou>Ymojh`^xcHJS;aGU-DnvlDcQR(%je`Yzr z%Us3dHiS*`8h~r)JL5UWpLlv3je912=k*6UYV_K$=BkVHb5-IAzvp>PSGkJIDO)8f z=fGTLc#$K*#h0r!UC(R#B&(-s|4Ot_a}?e4C#{i=&elv@)KAI+S;*I1bHC#C&TCFh zEhePMEKY%)!?GJZ|9ayc3KU@bx!DPs_t(Ng#*u0@2Nq57A4>bh2Q+o`yhOOocUe=_ zmz+a{fo+Z6h3|62ZE@_O2JdzvxpyzisVL5fP;jjs<X*f<A@sKS_4~aQhd-^A(==b; z0mQK2S4#cjXPuUYYy?B-vmq7!pl4YLJeXUTXd?oqWub`SzUEsI{e(gMn}yUIT(M<$ zUd6gc9H2oRgg+qA5PQ2C9<ouQGy4NC8ZAVD&?3n{w5#)fXYr)>Vj%kIUc5bjU&%cc z+52$*ed;qUe(JKYpIqGHC#PWvaKekawM$*5jNSRPAgV}EB(PUkt#$rVt`~^J!48IK zRV@;PwqZ$BlV_GB4N;6JUD@k)wqFw|(_szC?}nqrhoh<Sk0Se(`9sSiHIE{8lmJ#1 zraQCMh4Auj&nDi8zk)m0EB=W0aOENu(T|7>c+Gg}T)d98NO+Od;^HIwfTz{z@pmt1 zySx2h@uKyapO6gsM*C{#i#u9ZQqyz(M8A6B5B#g%UEmL05^lflTg8w;&UJro{JMD` z$LS5|;g5mDW9OM6j;vznQI14<UgC7%Iz?0laAI`suAMtf5gDCO>F3~d^xxdTRI$Mq z7<N8_4_2lHrh{8=S>swxEulAIhKjvSP2Rc{=c<ycb}jI?^&p1k?pZ*otNhg1Px$de z3t}Hb^<97CgS%lFp!gPd=E1bIwhG6$uHxLb;@HDr`yL!cOS5yLiJnM2Q|vA8mOPx? z@Zbar&;CoUVx;wIM}Cx&m-u-uljj<2jZL3be>jKR(k({xjqUHxu-<qbH&A<K0Zq2H zU!k&V_6vqy$9nbdF8-_+UgqH=0NiA98mxya{$#y)DiKUM#1qGyl#J2j->obp72+gY ze3J*13x;M43-)8U#ad<+@6*FL*)C8!eBA4}LyUZ#6D8sYKIe7FJ3W5j_}FLT2g=)0 zDn+^S+$eq1WR%Ke*GsCE;m>Qzx05H=1FtEaxtMVPI}7EpBMY0M!f3kHAX3qZ8u0_e zz0Ptn_XDFn=wTihOQ<{Z21%{>0(tMq^0Si)%7?bBfcSyR*d-QS>sLV+%I3z`>#TxO zg`X>0X#2xhhp&<pr!H2vuTSgCdi|lhI|$k#uY;CG^BT%rK~pRp$9goNjP&(D0bN!= z&0F5`vw(84{U)+|x4$1L-tT*VfDdo?mXG2?r1-%zi{P=7#d_LKVv$hhEr0vNd`J$@ zR){tT&<xPuEAf_}_Yrx75BH1riht%C@B%KqoFR>S>G`4}`M@VFu0*1Tja8bmSbtrH z`g*Y+O--xyQ{QQr8-KTy_-t?a$rCvrB+Y`0d@*c)YHkWtqLoVHg{IB%lgTdiJb7EU zdVn}#hy|}}S9S2im0XRN+p|+DLFKD?^nTh=bqiPgO^-sRiP3@a(GpDKBVM?gt9&=T z&TUlKT>t(;^t13ui*ioe+D=zdA@0&EhpC9`1OJ(|CZQ{)B23m#l`M)Ts(M)B^e|g* z*GtrzGqv7{ZsLFjtRyOw_KVlE8~cl3osfGawHCK6gm)CTeOm~+Kn<z~y}fu3-v%|t z>vU#^ph5dfk8Y3!ah1-z+?0yhGO-1(b0)R!>n)ZAftF=9sbp$z=UU9>LDl|wM`CnP zNY60}Wq$pxg$;umV4ZbA<P9WkAJ789Li3G)(vxMw4;^2np7nFsg^1lQ)^{Fu{pqz9 zF$nO5nI2fq0=o^E{!w6*UDeQoX;A`|e*Q!}mALm453~`oeS<xuPX(<5PQTV><ZNj_ z<M)+1HFBSYkFcCGiGReJLPZy<FIU;~%?{PdXZK<MoY@!l%A@#r=KVX($=p>jsLSo_ z4b=<H`XZ-FB8ydc@eUx(-4Jj2@yCFDsf%(m%y*OoG^wv{XXZgw%KTXWtk>~*Yu&qk zYT9lI_VfJu%MN%yyhLwP*X;J|FG(+YEIP4q_afH$OHc$a=7h2RUi{%25_~gPtGb3> zx4=mQ$QDg3{qpinXPEu>nH8r)@@r4X4sBd3&4c1w&IW5~w?<pbAZO**!(c1_=rvk@ zpt@CKNZ+C>=@%<qG&Q!Hb2~>D^5^&#KT^LZb{UqjbFggTbH4PPFwKd*1R9<rpCLBh zxH{U+aFwg*`km^Cor9m#zSup=P)jJ0(%|b)_?o@7-#?i)<QG~e2IX`QSe~yWvDSBZ z=w$B4nI@1C)!l|n>Aqa<kH{_N-4Bp5e|twO<y#EL#52T-0_ti`yd3FyJ(PJEwkh_x zRqV6)em~J>YbQgY@~PNfHl>?2>(JMtNUm=N3rLY0%GvP;{QB5|%7sta3JtP5WN2KR zWyeyqrrS@=Kg2;CQ|yEl6^Hc*KJtB>+NQ!EiHv+;XzMB;kDL01wF_7Hi9?iIPl~4c z15DfXoN`m2=8)=2B0PxY)W>QnTOZHN;=XZ%9C<S5atkch2WN~O6X7h4fA02HOsZ8c z-|-*X11j!OqudECeri(0@CHDDQn635I>}Z1=6?YHIPdnGtG-Jkfqp9&#HF=Wi@32p zTqCv$cp}uyEzBZ{ohpz#HI7at)>L&<gAXU~(-n%=jHaLNHEZYZ#kql^y%+bk_Xf+9 zzg`Q?mAv#*{tn%19^^i)`_;OScf*&FK|tX;>=kaiLiWVFRFG^Ux9Tc;P@|?x!lUK- zI8j0`Q=dN!aW=r!J`3(?F+B#G&X@<i_}hHet`cUxk?(NNriHOYct=#>{^Hcg>c%@& ze4%_2N$iLw9*VL=ioaUisv{#PbiVMRX$#peDUPN-laAE0aO-U)tmxmGYc_k!GasYq z`hDJt8@OpsY>LF+A0qv0HOH+`zW-1rI&_V76Mj1l9Oy7q^+LlXsR?-^Y;W`v)7YP3 z*n?fuCE-NKkd#kK!-=p{fzviv)E4B{d)scyey(u?9|9>_5XxM}Gre7;0vx<Y_6b60 zMLg~AiPk^wb)2b0$zq-L74Hdpv+yMv-dyuMFPo)7+)rurV}!RtC}zD&(YqN25XMrh zCN;7rlDeFLmVb-XJmoEac&ufCY5s&PfbNUphA_+$Om$e^{7TNC;b<~1)KEY*pQGdW zkyyV~<IvV=Yyx7gCPVGQiATzJ$qPw;AtW>eCl0{yV5I&%+zU8(A$4J8w0=5Rw5j!R ztxh@ExOp(KvqCSo9w(llqGP<}=Zo?%P#JQ;C55)xlcKEL^d>vXEl+e$AN`5g(@3C` zAOne*<^PN!n(JLwsiI82go1P!A5*rKoQRf!hgX!cP-0_1kd|$S-trHN-WaMr0SvS- zbV;nSXp3&VQZvw~-z(cD9C;LE{UwFO?|GimV;@CkYZ?V)w=SB74rHje{C)*2NKN5@ zh91k3jE*Yfbevkh{@q0vNKN7`-%l6(;s;<jAMIOoPG&VZ2J!!cLt9U=Vvj5*THn)J z!pp;cYDux?z4)OsD5~d`5|U4*`5bnjW<@KI3}O|kgq3G=%{FiO4Id3q=&RglVQi8N zq;Dbx6pGS0Z-SaF*$fsYh$LrDMu~!u3)(f9xB&(CfKVKLJ9~>z42i~VlW$HO*1EW! zgFR<Lc=6lFKRs0vkiC?tnC?`jZ9gFjIr}MKjgjKloDYb1!&y*;T+41a)yM<U)tZ1} zOV?CMpGhW1;A4cTD(z34k#4Ps#5bp-iRZE>6!H_Dsi)ZH$x8w>FXpJ2Xnl6k2sj?3 z_uAsSBZ;Ro|3MWt-qiC5_pq8lO^zlwHk&3l|6WrqoJH;K?7ntMq<)(<>)N@&v^CIN zd@ts%(#b=~6VMav^CzC<{bW;v_fvMFk6*-pRv;H1^poESMH1hJ{)QWWfww?KFE2cM zC9csN+Ljt~ABP~dt~Zl8{DVT}=kPRFt2a{fH#?<~w*7I9+NR+%8L|FxFa8p8ivT~t zAQ}uRdy2q#VL&uh0&5<R{%$KM6NuPD#joKT?1u$p!&tC{`c+9GMFX$74^t4-(7W4A zOz-`ds)gHWlt2bsIN%_uwZn?L!ESRc$*f1VH7#G}f23SyMiDJbVkr!dh7Zp3_yI}u zYc-Kdgz3Z+a%fs*pCJiUp_67EZ`QMkSTsNrsicw?T@$w$tGC|ixqkPeNoGtHM4TAa zEq8-DaP=iO@Z+646ivKIT$X>ME;_?D*3&b$oGobHY!zffca`OvmaF)<ngnA}msF*g zkR)YEhhB|qVw7>v8Yh}qb3~KUM>VNI2R^Au;{6O$zpa-heUv6?#|TXdXR2sYUU<ls zH`->CK<@j+uVjsT&hN>T1;UtGXp>#f%N+LrgW6pd9kCa^(_j1%>^^Y5np#3SIc|+D zDYeW&OuMIuE)~T*v0jyte)tCb&8FqyDpo7FYptN%e&U}i$)HEAOL+|IG4Vs0&Hcm; zAzilpP=)f@y0FTw=nf@BP~%1=C1O!DwL*81q+f}JwC$YC4ZQB(Z`Zz2MX`{3@e~!a zLbV1-WAh?75y=PY0htOr$fmj<@N3>()Qn8vvsuyPktS9Q6PsQwyGse$A4V1|dDXl9 z$@OZPH*FXCxLBWe`$4CK^*U>)LTW2y6r#@7yu0`|Cih74=j|j%o(<(eWROc=<sZ%w zOHMGOmFHV49jxxA92g!(UqLLAjD(t#jg=-1|Bx?H!t(E7Cf4$xK)(V%sd;_T4F93m z{bJ5j-ODJl)Sj&_%r34p?MeGix-h$#G2Ud(U*5D$lZs<o*ylLe)X0^#>?SD1VTxM( zXSU-<ys2=>*R4g&X04+$3Z|$1!*%<3_TruDTfVZT#kkPtVzFp)baCCzNaA3&ynj4+ z@@pPj)Zjn#hF?t3v9WAHx8_Ca$GqzOtotstz`L-Q2K_bPAg{B;K#I`uUKGo1&0~wZ zCH^72TZ<Ns9O%D>6O)V4QLu7mu`7k8CN1gT#D~LTM0+ifv&;04Nh)vk{{Da9<AwkY z=%p1v;zQA$Jxhq}5SS&9NLJ{}yBoR4ANnS)L>90*fI5B_=))Dnq4V3Qm^qpVb8ngz z<Db|>;P&S)eU%j_k=(W7{I-VQ>Bl9#<(OsqBJs^-@uhub=pe7NN=ElNnoC}c(dwcF zb$i<H`4@mzW+$!VQdaW-D~;C?MA79&6OT5oo6vX<-%(|9K>HQ=4KClvlVJkqih4in z*0<EyJ?K6Gj%X{jn8<R|!hZ5H7fYXN^^+Dx-Hie~!G*#>5Wi-tbZy0iQ+UkZ|CnF= zhBgOh&t%A%kD!yp)A5(kcfaJ1NSnTUD?%Xw(h_f}NccNCud(OK`4h$`GSEPYS9rIN zIadnr4N`coYg{)hTW-UhIfb<%di7%)*PY-Ozg71nEAEK)(YAd}qRVQEh2WTjw3~XX zxR^g;7q<_Ji!m@QK1XY59F>xLw#LrEA9piiE_gAon$rbpqlp&w=Ns=afui4Dt=Nf` zMX?h#Dq^htTq$!3Q(2>e(x6N(c<*(7i&#p{7$HNM{c<PM(rxt_)SU8}=EOWFUhFR% z<uvx!HW+33$!n_{*EtRPPH?~ZNDcZX1Y@T`KSJICmIeCsj>q!)bh9;i(=vW;(+B9& z5vf@eNuPd&C@s0+G1I3fA!D!O61}P+Ha0p#AZ8|oky>1e4*18E`_H#9ziCx6mbADv zvXLc%+=(UO$t(xza8lNA62=eIwT&>7scnjnD^ltkUI*LTOjG`G&4k?=6G;oaJVH}0 zqV}Or!;w^=DSzr1)0FEQnsPR(nx<TI9zSr=wH@&T(_*RkfvaP~Cl3#^H29Iq)|f>S z=nZaa=PsIB6U@s*;&9ZT{`^@i8qnkmT|kwUk}$p7SBcETDY|vlX_qfFC(`NvK1Ye& zTbx1_VMMj;uta$&^=4Z_WQOabym}5x-x0LsA2j6tGygXYQ7b+&xD|2Ljx1sem!LJ- zC2G8hRr!v7Tjl3vEhb|LCXIK5lsVr|_#T+<Oo!?FpDyU@k>#6oM^>yp^e%JxNT~`0 zLgYmI<A9N2MF#z5ra&-!2ay_tMf`N{b1%tB_bmnQLky{YdM{;QK8-{sdrx}{F@)n~ z3tJuqVN}hx=$I>@C0+D@I<r|@?p@x-_8i137TM{MR`O6wDOY-**FPH1SDhRTg&y)> zNyZ&3#aU>>np2-+F_>Xx$CRrc6YxLYvl}A#h?yfE@e@CQYc`jm=7Q@?t(1^#tNByN z9m#EvCU&w$3o@t1vblXr*iTLZ4`ZPaE5cB1YuV!Me*F)M(6$eqsa^f)Xw8l&;pcI_ zW#Nu$E7XiumBsgTp#FrkTno?2uIQhC2a-g~rF~_+y(#Q<d`Wnj8p{(E*2l_gTOajS z_<BiQt=lt`xdlvXtK?M-TABazx;0ho6lB_4<5bk(kw!^8-C`CS%mx&VH9v<*DApk0 z)KI_)kMiYc4}{Z0|4iBu*{D#G(Tyfv&79299OA6IR0Z!fr{}+GaoO`aOVNXVPnIEK z2s0U$5lny+*Hq173{5k4{TLOs2hE&2I=OV<=;Y(%7H8*DVdIx}!s*z)Mh?wO-84ez zZA(qAMpj^=h+IEmr3fp3FFML&=<57?Ly45%B?+aSm&^d&x;I@-ynDAQkWQ%4oW<*& zY)-tU#XuK@X3I^{)|^23LqMoo(XllrcAJjvIzH=g#Z;_{`Q14SB$tAGsgiN-*n?6( zHQIw3JWwb)F4TIwpZv79;!R<8{RA(b)(vC!xhMg1BrOi582~ryNq^2!HfkE*&olds zzn9R>t?9)z7|~FjhgzQ|g4Ep%r%k$n3dZZ~<4xu_{Hfb#C)~f|E#E5PW}@30?5)^w zvZI_<Gz3maWnl?EXQYiwyk}%El+^+7D3ou#5E#yRt~JgIttmrPFLhIBItb0Da#JeV z+v*?{!~jjukud1KTe`V*^vLUw_5t!miI(NgRFMNMJdO6|0XP(C&*YhCYHp4WHP^i4 zE&poJ1#kJ!EcYwsSuxaLKP?<ho{j(o$S<pH9lm%`w7zoTccaP6Ak@!5sIC{~!@cs) zK;1YVuw0-eLl>T%o%BKdC7D-_vj7@$ygFWoz$Bol?57u(Qg$nPl>>}dRHq}gz+hT{ zrO#^NMZBKiK}6@EcvNZ=p=9ke8c>&o`)38zWn<o8Z-nGn;U|PH<P|ZXE^AIy4Qo!! zA9kdcO!O}tl~w6hyRreEk@uFjpglW6K8X(K%aGZQE8^%;r!K?)>)bT4qmM%p-nz&K zyPd|YL>jo%RcOq_S4+_6kRs5SO?DcyRpJQ64@|F*o!hslCi9pyX8r3q)NZY(xN?sy z#p%ngLSOa+r!QM`90eh_M3N=v>kMwxWz=_KS#xsIiCBP}6Yoc)POd!(ibHZ)QN+#B z+A_4!h1xPk)+tsf>U;(UWtubwJug6L7>OdB$pDYM7`Y9RsWh5+$**CMWd^Lj-;1vS zpaHXz&O-dh;&!5LQaqPmXbt~LbMebsanx#Uc!SQPV#(&+a3(j=p;$^8Lgm$%tcs+X zcSn++-y2D`LC9~R6-!+N8Napo0zX-YiZD{YX!pVqm{9CsuI&L`p?dlZ(scQ7xi<Xp zF|{eaZMXKX)E`*9CbN|n<jp>WJ_}@UOj1!~tdaFJGQwIEEN62(4f~Vw*T0r;lXrs_ zlTo7^rUvC6SkL)MA1Sdp)OzgVDx7k;En4^?IuT|^0+SzVFZ=b&=YDEISWF~!X}F)r zW<WYa(U33XOf$kXscX^tcUy0XNY(gow!T?0t+Fh4vuC+mb&RL55<m-TQTBv_hkVN; zHT&=+wocCc7bYwge5l4`ji`S*PZeJLE6712Dba>hOYK~v_!mee!q7xgCC5dJ--Jk! zG?8vKTE&N@VFOQ?!|Ogk!<HSSVY}%@)%|xgY{`BN+a@N&0v4|ssL@<Haf6H2JP`Xt zGiR}}t*bucEq{i|men@q(7ny6W&(LJ1=MGt!Nog8i1qI++@86UG%U2>hI!4q*ZB}D zoXi^jI8|Qs@2c`_<JU?5q=vgq#Qjo(O|1h`!`n9ug;zR>A<yjvI?0BbJZ))D=f&^+ z`aV%k$mz>WPzWrc+I9pWOYR5u%)4WpoPpvuSMlDDq%Yg-^kx4l2Q_F#dC`|`&>S9! zB;N`e64G=NOgkE634@xZT|?XgB3h63)rl^PCTh%GTV5`e-fp~*4f1ztOEqCJO>i#a z`CM&hXTmf^)MQPmyt|+!yHikoP`u>K7C%0rDCRqn6QL?^w{@L_KjbQYPZsKS!fnT= z-ozILr^28GZ=k)-Rs4t~nN#^9AxmQKV4+F~8Or=8C#|p>UIfo>PZx#U&Oqqa8-7v` z${|ER?B?ntcWXqG#mNY}+kpw-N=zS`7$QBWIJc@pGGrs2WGHU*qYflMR|nY5Pdc=o z7t12?znqX+|C~-~dv*W@Zq=W82Yd6~N}c(Gcpv_J4Z?>x(Zp`ksz^%H>QO)4OUod* z>b^aA-^`Mn4Q2=jwJIYyFDw?MV%T82nSB5lu<(jpZ~3?jqq%44p<<(nx9je0PP~~t zd4PXK5|2j{_n{N_e)y7VdMN7`-{+>h(&?#^k4EZa6`{qCx1JVBq{TY$O{iYPmP>MN z$!_uM=ONT?S?s3V$FpnMsa8=Loru4s7oW#6P2M)Dy6yDzPMvWlp2DMuN*&6#%z4{{ zXQWCtY8=tHl;CC>l^(3*P1E)T>1F@YWM8VIZ)={(Ycjmfu*8P5n1REzb41_WQWl{B zM=+<?W@&(;vl9W4g5x=O^tUEe@@6Etu3i0)Zv~dP`OL0bpebukls-3DercC12^gd< z$xbxOW><S~Bcw*xn#{~g2^_2Jidl~<M7Wwu6JoTynY4VnRafd^-o<!lFX880O%o;* z?B*eoTCq}%V>q#QlpNxohk&8NTl&B$?Fgar1z-R-O#~%hivkj5P~u>ryq21J2r16k zsyC&t|5Qo5<^^~TOE?F}nM0|R4H~25MdithM^l>^3k>Z9E?(%Ouy~A?6yT<M#T{)3 zpisZVkei({dYkeO*pfosN-jCTk$YapU-__dHmAWSzZ0ICTwFD^bC29AQI>()KLhZQ z_;r=6)Kg><mh7-DN*e`ZX(w}fC&4{YOzQ)R>Emg(sy9X^71m5LCSHvo%;Irc=EW~k zK^(&&qf~N!ALZcQlR1~SnxG5jXQw~a)+jot(gWgC2hp^8@q4*xOgz<?cs6rwki8(k z_+2!KsIyPr{di}5f;5mR6*A1;x~^&p5`H08vu#G_51wRv4v!3|LgP%FU)DE?*8|AX z1e)!dm250eMl=`=l*(XC;UfFK214!aChdC501C{3RM0Ur7$rp$hmaUKWT8!M?(Z)h zaS{Q7Psc4*(|8S<n^mldxeAZwG$!82{1fjJugd>+<qq$50>rIETtPcUi2=3Zm|+j9 z+~GwN354wdvNu5!Yj|u<e#)5G?<ul5`JF+~$=uA#xrApP1g5}&_Z5^gIOOEz=Rq(6 zGblQF;hV|ne>)mR8p}M4`qPAXnMZ2iCpZqkPe>eY(!jt`MN|#h*8X-00Kzzx09zAT z1OpOOedM^1R-;B*jT(sx>t+nQ>2;o{8WWE(GIKE_;w=E4RHI=bIOvx#mznzVk*358 zD{nUR9NYv=VbX!v6sC4F`i?64n^S(FC(g8&RFVr0a8<&2N?2rMv=lZHXyEi^0%0bZ z-kKC#5r8x%Oje$gAtEiFwlEHy<62LafHb=Q2&e#a9_a*g2nm^I)Uhu{mTeP`6Y$V= zDR~yvBNSXHZtNIYy`PMf1yo1l9IFFlVz!2B`PLe)(a;5a%(1PJqosxoiilxN(@MJY z>&y?CR{r3CfbI9dL2t#`+j)xbejol+;@3aqtvHbvoKjwD3`b=uJCMf*C08*eA))3L zo4!oPk+T-fW{zSRs?_SE@K1bwmvPZss-)hQ$dTqMQXkP(+}J*;YFuncUAMTq<>UJj z@*z_w`>>TARXWQ=;)|w-q9H!~Pl)N~yIOJe^$4A}Ltwm}bd1;WBFXCR9b1Y;iu02B zi$HvsUJmhAh+C-ugHgp~ljLx4Xu^u)+xAA`HR~Q&=1-_i<4upEnrIXtw>RW<{E+t+ zO>;87jNa{O?M{?Lwi33Wr3iUD=P7USegf|^jihBu%G%GPt~y3e6RC<_+?x*TGwmb@ zy97TC5<EzPb@>DzSArZmM_&HvGKJnA!yE5deDLwXF~hnbD>-F98p&5Luwv)MDPMf7 zxlb#J0BE4NQx<^8LUGd=1OO341z9sQa>!izOSTqb?_7Rso3?;=9%4g4=D;=~PsM%T zP;*k(sW}pV1=oCp39s{E68&$YOx(Tvs3;S^<yGdVu9E)*5X7~#O6vB2lU06Z2*}%b z549PBb#oOJ_vsl-=~whkWR17*ERDF5xJba&=`+8e4Y5ITIEIp2h*b{BO-&jmM6cC6 zP;DVk&Q1czVpg0435Cg!Hg@cV?MpwI8;1qdMP}s~gCYeZ!GpKGeq37#+gT?Nxpk6X z@0Lq#98l?+V6aW!GOMrwtU@TXacjvZ#|6@zp2bbOb*<TpJ-aHraBRK|(O@_|=L5=+ zGbN~8#$n3jHfVs)Wq#tFNHIQutYYQ4%XAwCS@3@m{ukqYGGEBB#`SGvSFt)$Mn^=K zb}xa&XpRr0WL^VJpip6tD0DklQD`66q9Om!NIO0I_*{-Sy2kXG6l2<<yK9-E;(DDN zzA|{Mp;eZ{4rmL{$pb4t=5?2GKK3A>z^H<OH?xQIR8%x*=*Pn5Aa1{yp?9OCLjZti z`_f^#aj{7M_@14w&W-Qp&mUEp%Wj#smedvwG$@1+J}}tv1Eq@x%7cX$rDOlFJR;lI zmb86i+y9~N-Q%OIuKoWE1V|8kf)a^}7&U0(HBqcYKr#|wMkj)Tih@F`QYv0BnE|w3 z24<p6<FvNbw&xsMJUzW=wO(39v?>Y6#XD+MDk=z7XB<(`D!0n~-k<e6a|v3%zw`T^ z^T*GZWS)KBd+oK?T6^ua*DkF;UiY6-(8fA@Ylq7EHgrXu?Do0WH=yj6Ofx7O2sFC- z^T^TNh6EH+AD{b`QMowdjjEPW*|~6c^u?e{=zB=6J^|D)_*Yh+TSaa;vi^?W3rl~0 zi-)CNP9eDI{|#%QysMxLbp24V99uEWtXPgw3a#U^^s8t;oF)Bh;1uy^WHCQ#$Z}uF zQ)m#OEZ?I1Lp^G{7WFSBT~Fh+U%oeTc_)Vb=j9RWaTRX(BDHSvzkmw!x+Spmd*3;M zNr`;dTSv`xy#q^6h_tnyaK-nSs?xeZ@*)&nE-FG$|Mrlt#BTBiI&_U3bga!*UU_ZK zNXUu5gbZLV3)f@5<4$X@{<&#Ihz$4jM@NeUt<TNpod%Sz%;!6)Az$se*ALaZs<evv zGz-h_^SLh6xU~(2=mFdGhN)L3eFX|db!llyZzV10I)tF04`m|+$y-yofv~2&iKP0O z<gx#1$({Yx4*csSC*VR)3Ty7`2yFHo4e1G&jKVDp3LLuVrsP)%Y(P4~Zq)UYcsIOt z+jL1SNIT#LmyC^<#+=#>ahbl#!d+@Bk*!?(ed-~HP}<HxuJ2TlCrq3w<jz*kC1ZNJ z5|fo5PLQsdY~h+I*~*XRk)mTCZj1)b5>0EanQzJX9R!WF9_M2phscornaM7z$vK3a z_AFLqu87$`a?!=hpH%*tZnfK5$b2m7D+)fsx7UQJMydK7@pC<~6l5Eg?Df+^j@4de z^~!OeRaSW?4Pu8!_0B$ayk-i>k8dQ0EU61o>lGz=j}`qJHdc(hjFEd!O^*e}$R&yG z={Cu_9F8S>9hhsG=%B24KG*5@B+@z2C4Fbe>w62f>y58Fu`-g<=kh08dD-=h@mixj z+y$6U+nL$f$_a|SL=zGf)zGnIvyvuSHxUD~mBSQnDuinkuFqBuR8f}Fs3$pm!zbwT zL1r!4>&c7hL-KZ$ro5q?2y~o%GDqn!VsFP<b6<4bzMaKy`Z^$(p%?hHbQfsqgYRP7 z#~G=`2#Hd!5tFtHHE!fuXiDm?tIf}rFs35)=gY`3n&IFFggy$0R@`#Fe(9Ilrbm3~ z5=*bhr?Z|UxohUD)AjbXBE7)<Rc|C5rV?uV3NP_e@AqNvS9{^~(fV_P8>3>@W{)`( zyPrsRJ>)xNb>1<T#2;JYLe@a{#Q92;2@CW0mBiT$MQup9N&RXTIrZdfwsOQ*avny% zHE3BvXDbiRrKkUsFbccGiVUhUgHeT``Ri-kinYg0o!cs9U(RhoY9?vvO;*pV*LmH| zOjBuaNCVOwRHq)eglw{6%vRo)%a#XYk8hLsD-yk8u5{*}1g7qo<~H6*dTJ5Xz=#;6 zb?jP#++U7drWotp_?h6xdD+VG)=0K;biOgV)2-f7#r4j)vRl31Ca8M*=j(moJM<#4 zA@%!e*J1w$a54G#-(bIv?9ICSD>Kga4|}y>F4Xxdv%Rb*7G5ETeaAn*B8Cww3T4<% zASISRTshc#H1R9pU!&H4`j!Y>#=rdAy+*{7Sos+{LLCa1O$}wABVIZ~o45FzngQuL zOq3RH-a!r0e$+}2$#F1x1l~0bVR=%){WPayTFrc(@4MA?c2bAlfEsiPvWRjHmpcOr z<N2%Be(!Y8TS@<gmp+Afd+7OYBJ2@icLT{0yJWa(lC`-~Hrvr11GZ}9T4Sa^ls8j> zV4~%WyB6Xs!{OSaYm&7qS1)qTcJ_De{qp{H{zlrEj>#u;n6;^u6MbVGNcw*>cRR@l z^a!oQTCU6vh&)SI0cg0_Q@7%uc1aVjyI!@1aDRnoI_vp<qYD!h^xTW_xpT67?p$kq zc-SC-&z+OybLZshKeN-|{GE43SxyFf5vANU_py9qE;+K6xxSkLB3yEpF7mN^v3>QJ zi2w^j+hH}v6vN7qcS9l?js63SC_E>U9eQq<X21$zivE+(sc-4t+I90d;MFS8z%YeD z`}2lVoKA%>-nLi7&p8Q?DBL<&S*7>G58;B_F;e*;*>cgZ&=0*H{$^g#pf=mB3oB9E z_rzMi$vdxlyp67b+w0UX?a=Bu7-EVyTJT|WfQ$bVmL^NePJrg~og01ox9NQP8jV06 zd-D3sg1;UkE8x-`z$D$*4Dvdl>I^R|%u#rv7Z%be+(eiMDqWoB!$oq9$i>QAU8JtP z-H=hfY3nIrSZlweTMb$r?gv#V1y_nQ7@KU)AVgZyfutt|!TBsp5^Zg&?oOR?vFxO6 ztCbcRsn}bRMbj7e!^XAdRFgAcOp|I0Sgqfm^7vge#JlBSnJu$Uf_&U+b1avA8;NiR zOsZ$?omtJFF_>eF2qk8-&uE+I0XbY5r17G;%~tkmWjgjoGcL2O22E=9{tu@w+t-GC zDY3-iEM44)NI1Vp3rsqre#|<1+4wnh)Q%Z2j@1hPw@znKn4O=05p{6jhljAbxwIwn z<i22y{VT`ddrU!bvoL{86=qk>He$$|SO_!}MFIAnEMF12YJ~%4`RNi0X~Q9V6Q!<Z zVEAscIlJ9`<^gQ!R2Z!7^N=rks?-6v*uW15(9(HNlZF+*VeG`-i$XQm>4CNRu71v) zJ`_jU%9rOu^-<1g_NAO#OyPf_oQtbo(Pr*hGFtaqMEDweR^t@|j}tdDWK<OrGz?6a z^x|VlN`j{#+QTJPPJ9yaW*Hzb*=?Wc@EsBGCRG)%Bc(CX>xbE%L*!LerXNusAQ6iQ z=sy>ZI$&HuOkrVbZ3+(Ddzym?`a31EYMb(2YjLmoeW<AZ?d`P|<&4~`j^-VatGg?{ zkTD-3s<;E`GgUR9ZL;q0Av$g`MgUzU7<wA8i+vQQgwjCu;!q%S9Q&nu1E^^wFe*wN zGfs*p4If;dIA&GpX(t5n*~$6>D#T=ZVw~1e_fHHy+77a!E|R4_9a~(m1rI8&HmTY$ zu#`#Wbt9|7tv-PTGVXeg0XX!c!9z2S6zDulkKx#Zw^4%bd7|N~=<qLC$Qj;P0((SJ z_b<TQHUU4r3ix=L!&QaE!h~E+4!2GSi#34w0Ok)*{Sq^NaYRk7X{|TON)c?p2+=*> z(|MY@sI6%fjFnb;k+&#r(=Sy@_a#^^{v8T`H;BeSCu+he7M*K{B?c|F<q>r*1l*zu zz%9{ua)V8G8s#ySxWZn4*+S^4-yex6Ff-hqdBP4A;e#8M4dT0%@<wFIBdWKNu*h|V z7hdayOT2KW7v4%2j06fUMglcjk-)p`_f9)@wHHLlX)lQIYr>6afz6o_3A(D^)E{Jo z1%)^q)pN-AVW9Ct{B2<L#thjm5ry4N-~c&7>bLr*?8XMG6zI+d|9pikA6RVxGk?i> z6=QW95xkw`^l@gU;@SoX26NQY|0YXQ{t}J2)|1*`VAU4B(_>`(s$Ljcwf(yMOE5O# zRx}3>GAG4zaF-X(&B1M6xKs60K1%ri%^XaV`)H080Xm{4e_1r&%qzdVJ)1S?J%=9# zlr6dAfDZVU!Ef?x;CH{AG$cnQ*iErr-lpwx4PDAs9>BuM9G$Ja@k)LV&oQ3)5Twk& zY~?J)_RG=P?+|N_&e1bnE;{Q`y1Xyvcb929nN2;$Z{~XC5M@tYcmYA2KNIvYXg*so zH%5ZZo>V|#z4M#Taiq#L5`(;`B_h1rPjMJVu8OaZ49V0Lq;sM&xPL}q(ATm2Q5ns3 zYF}@&*U4y8T?zmgSI3rmg>8|7RjH*@+}-rn{oQR#J>$mj^jG&Q64rHfg8SNuJq_z0 zYa%QKN#b?AD(briI^{Z&yqyE6T}{qUy2`qE{xK6i2%lrsWR~opN(v(CiUl{6+%z^c zF7kHthSDC9H=HG7d+k{>(l_sg=ncJnk=4-~di4l*g*vW8XK?apPN=XFa^kf@tVeGc zY4<<mE^21%hEtm&|K{~*M_~KAb8gi>Q8IunC8#&2-(A_tsjN*6yP8FrbDi+2bIVk; z9hmGnkB&Xf735F0x@_`4Gk*GEw(`(!WouPL!(2GT3cu6QRI55G2yuNHE0V5Fy>$Vo zGtl@_fJ<!7&C<NY=9iYqB^K8KdFvqHTZ1(l(UM4-OuR5_pi66pXQtVxkkd*2n%?{v zgtS2{R&ndd9s25+&)9f&L*9)btT=@0w0hm2Cie$pp&h}ljlF}bSJGW=mr<g_7wQdU z1$jEym~!Gr0`4G+?%2vEde3=eQ&Z%97|ikOV86$2%mJ9qTefny@ghE5AVU?YvY9g& zf#!2me?cBidd%}l@dtT>+s+-&54jlbUR>t4DcIQMEPRH%9nHt50*$Mko1Y*6;p`o| zzISO)r~Qu#`nKkQ2<&Qsq#By#Ec_9v2-(PM6SZMkL4E7OXT`1`Qo3JcYe(~tTAX;} zaJysj5T+nBB#$63WGhD*uce@je;9&#ua1wT%3vampZf6q=@STelf)y(I|rGZ?wV)^ zTyRR?_algn2CklLr3bECES(q7BfyAvJ`apT1jZpA7+Vr6vz1F&fnNu|M=+Muqf?I; z;I}5Qebe6X3kZG*@-kQ#e%GsD0e)91_%Go%fmE*Scpyxl#q7ICQ!&={y#|!IzQTLz zOcw4frpZUcu{{k?-zBr|tH)MUIZMtijc#(H%fIAwCKcVar}gcbv1@ymgkLw>h3}KC z_D+DDvs86VO)Z<jLN<+Iw(_{kJ={J5(#N`WYLU6IoKH-tkYqRqot{B=zNCvN0h%pw z&HP1m=V<1za{bte_p}aiK(vYuP4qgX&b&J_HlNPCi7ivEAC&1Bmx96GN^POWD{AIM zs!WiShKA#y6Hb+WJfwGmHk^?xy^>t04^m#|O1luHR5CHStAgcX7o`cNuNHZ5(a?!E z(H|ETKN2biK*h~_qayF&z_uj8O)Q|`V@Phyics)R>H7$1=;E~cPv6q5lzHEG@vHyr zLN#ZzN1MeR5jxeoi(jd9V76`zk|b5y5IK<KC`6b$2Vqo`8_<DL6HjkAPx7w!*3p?> zOPk2-cmK+h&Ey)K52XftPYfk))dv&f=9s~WGCBjs&5$^ZEjb4IH*%dDMHk^&<f>{( z%&aD|RuK@TarFfFy{ZY<mb8p*0+E0L4J#j0(vO>%#A3NrGAtY9bQ{aD7<V4ygx*t# zf(fbXCcrnV@S{01AB~caex+uRB6Z!4elFh|ZaE6HulxJMO9RJH<`KN31?t#~+WwKv zrikWn-cw~u2`_b>JL*`rz0-UwIq|hLrS6k9%k0a&r`iK3n=lr{G^`1$IJPI3;+3K6 z@8%i$fc*Uc>8n~A|KY?FRC9XAz>^R;<sbSJLyS;jr>U#n`Hs*<Hf2bf&j&_Kt|^Of zE@?t(weYAcTlwK-ULG#q-*bBG`jgO7wU=pmC40U910RZ~)4ymwshr5;Y|X96j8M0E zMq^_){Yt0&A?p>9KCM+t?f6yP^rSwIapX7sqzOICyTS*FbgW~a1iKg1irBrCENkr> zy{XSK=ZBZjl1(C9-Cz{vYVr(>;<!U}p%!jzbsu9$Q2HFW=7SZpnlKMGNDY?tUXlHt z3ora>52U!@6%f3{#zo6>@Vfuo-QX45Ro1#H@YwO!*}3KPKw}yAZ_HOEvmCjPJ2|}6 z-N~YG0g8Rzr3F|fJy^!=?xZ`>aNv$PwP$opKB?-Aj?hWfyuSfb8i9NluB_9{WS}gR z9C~E}bfWo?Gv-}q;Y!i~-Gbp4hJvR%?Q-deeS_I3#de@m{Jo_IV;}bmIj4W-?-*7S zj6GfIyeL*NJhg3+YF=%QYqWWgLzP52br7^N-pLL54e9S%`Sc8a1iyy$@^38v)@gg6 z_+RzCHrID9W3pggGfeZ4CH^X_kHNs^cuf9R>@x$gEmaIBjdzd?|5i8)w~{3`oE_tP z%B#EN)?dH%S9ftk$xG$O6+7^u7Xc=T&1^SKVoSFqwzed8Uf%0+#P##lk=WA}@=RV6 z;4bUWR3UV_$!YK4Gt|h2-nqTAVg21c2F#xFOQQ}PFg2qmdc2P<MO(QqW-I@5x(Gt? za&P8+`B2CBIl8A3|0S8Z4>hZy({+T4OV1Y0JlqQ%d3|Frf$?<L++pUA0najngLo8Z z9QLMj$8x;jz8u}<3%`XQ1J`lEAalF0CIo-1>zem`AeO>Jx2yGAaM$F(U`w*!EBMF( zc5B*(20OU&vvuCV!JhsyK6EFpj}~`dzdXV8Jinr?w4rk<=O@@+%f>aa+6cjGoTC-L zcz;{bc|+`@DMp?&xHniGjC7(FcgWXC6%aCPdHAT+M+I6rSU^+eu&=DI&L*u?WGbrp zA=UViW%@)uz*j{Tjw?WXBZJZ~BuZ<tl^K>wsH3z-YQD~Jr%<0;JRME-{>O}oWBbwC z&+odm1<517(uw}RwIt8przP=RaQpfo@1t<Odb$=ID-dl@&cc}u9=17hInTPr>M1jT z`(-V<*$@T`Zazm`m*<~id-{QfA3F>E7V#>Nx&)JF{ewl_Zy8g}r405cV|F<U4<o%L zS<|ECu(#MrKBlx#-6qoTvDu5X=8hXmxtHTC+`%%KkUaLV7T=dGhrKN;^SbooR+Tfx z9!{QkMsgrl6a9bG&T;??H1a;t>-%I&!V_c~0*%%C;vz|aT^dT4M30}LQ4$V8%hCL5 zWU@bU;m5qSA40L%4P}VH`}36<bQ|t@y&7d7mbov}7jDm#ZZ_kst-7fgdwNO{0p1JW z?fvX?{gWpxtq^;A{S;$wy7XoHJPAHYI~c;V&7uq3#R=e1y}pTamX^d0?i09+^YKf( z#o5W?tSE^%p++=05xh$wR<S7I1!^MSl@)vMFZI$n+X3KF4N2^Q%YoJ7CC`+k?HZB@ z8mNU$%f#==rX_q1b}NyqgpAdpWDPgIo~{mGV;a))VJqAQPT9r;73l_6x)I-T;x~yJ zo}7}5gCJR<`tjveHTP`bHWMYmj$h@iWGbfRtYqGqWmYobpBR(kp+mP{8^xl$=eAT^ z8DY~?TD3gk{Wv!;Wij)+1__R8lPSknQm=bx1rL7p<$T|6-=+14s0T`#kXwi$(cO3X zpQxv_|H<?DYkwdp9|cAXtBK&Q?1R*w9+kM2tFtpx+Ens()1qVRb3RF}md#Fdci*wO za{X2AIxDAUO5V2e%|(T*ddoH`m(B9z4Y*X!e8%~oRPQp!?L{BxgcT_62`=G;3)SIS zWAK@Aq=vRkgQ8zt&0;*(;HD)S5A`z?f5`@~Yq%cse5|@<Z9q9_Y_Za8^gl@bCRaLr zovp0W8d(v_uuQ;u+-%CK>op6sV0G_hLl#?w0hyNuIi15S>3MhYo7z0iUbF(cj;UfB zIn)Zlu&`1nF=fLCsb7X%k@B}aT#@oU%UoD<d(mSK{?Mc#J>rmNeRy1SL<xs)GM^X< z9d|E%IdN?%oJ9i+b>9nYe=X3pWwZnuDgS$kU&8Z|>8`}xL;7tnFc`a`q9lCqQbR@| zI=0&lUyOAgy^-s-*~lfC6UAZKs@Izol-rw+6*3Dtl0+d(Dwr#CLc=q5p(w3gf;lYK zT7(?KV)5Ly9l8a>&Sein1ns;5I^5DR7e>If_syktMXX>Eat5o*7G<3pMplU}FAL7z zJ{*0;GX;S0>eXqS985b6+Hm=fK;j^CxQ&yd*y`atnHAY!)L#7#1Un8;yYMg_1o2g^ zO+u|5cxyN&KsJfKP+_DZI3iLKLA&=!YSsf^W-X>;Y*}FTi^D~Nm9MN`yCe_+rlWK3 zdi=tcRpS@7j0>Bk+<8KFiB!P6yHi+gmnsS-!C|;XVJ<L!0|#&5-`74t7w8y~t-K5C z-{Ob;z=tGJ>0u^*ZLo>|>xJkhdvl&LMfjJiF|Ug}_g)tdkK-4+9SAp>H0!C^Eo_I_ z4xDLm*tOele!t;AZxTD1-GPpqYB|QKx5o$Tty;6x;ur_LXDuTx<6*Y!(9h2`qOSm_ zfYOOtv3x&Fh~fpjJF>gn_ZjW|x}Z+m56xxn-p0N<DpFFm@)uOjq0v*rK{`7$wzuH2 zL!*lSn#M$s$e*g>my?rJwKZD6CGF=5m1TzxSLYd4@9fay_=F)fmDu=~PM&n`IVBfP zXbCj-iJXM^aoE4X78}P`M~-E!!kFjP7u8d_b+Q)WI;o#sxIiV2B@X>Ew(G?r=FHnB z@pfO6WVwzB;OOe?*;V!sn-<|?`Bsr@u+8m%7vnHtjPJ$2pa;aW3}mhk5)WS{xOn=K zFF^xI85}#Ay>h@%mlsx%>4dtq#ZS6IFJezOP0bE{fKeCMa+8ZpGU{P<rzE#)f4uHX zO<uOLYOm1<ULeab*y#tUBS6k<<qeZG;B4g<@YUYql&96YwdjckHDrU0JpFt+?g3u6 zpTx5(X5QxEn*@%!*PWlBD&6M%Txw(As|}s;XV4z6i?AR3B77M9jP(z}!J_gsuwTO+ z$SsP-PtmQe(|*$fzAZ?@Nco3AFY0QAoztHUB};KOu*;cuk{t<)@HBKbyi&Y>Y#KiD z09*=*BqjSDAYzkUF2|K0tia}D^-O0*=cmq`PL756!;!|mSb>=J2c79Z(|MxPd33EU zc2v*X1F;WaL93xvyP8_R7feoMbZ^X?k=P#lz*$<Y$*tRgfx)G{w^GYSz6ST^V;vup zdt+h}UdvagceUHZ)tQ-2<|AT0<#!wZKF8=}5A^(dQhdsWKen11^KZ=kV=&po$Le`p zm){wv+hz<pzh9xxj$7dyFSoxE3A+93s-VE!&7sECZG%4ZJ68wPBaQ1B?j`qvlV*lD zbOM1lo+pgwtS6pv9z`r4$OVz*Tix*zxtzh{M<y43<2f=j4rP8h;9H)Lf0p>l?v+&J z6RkzcWO_X&5aGJiZKm4IA$$o+6x^+sCC&=Ou7%ef#v2!K&@VV0?P&B)e(^Ne*<x4{ zY0AL(z6cL{idhw5$X32+E59>xB-RedfnzF^qN5%+M4-f)%Q*HENQ^<|Z4;?a;F#HH zAJC9J7yV&H4~G}H*XN9#_W^gH7u!Hg?#=HhH&=^nB(SN^UswTQ4h?pk1rb;k*#3H; z>*LW{-UQ(|#>P-xBT|Z%*^an6fN==P@1%B$4WNLjhFx<rOfLze+HhY@AafM|6nX*R z>ESL>zLDFyLvlfY6oL5v5c3Ny(;q^my3?m~HK4?fP{%lA)f+3o2qz{Y9_YYkTWnm; zTJ{NbT#R+fSt#z72e-e;8<+tfD&MZ^nYZCVx1#N8p4G$^!ur->fy9j{Y{%IssLR_W zo&It#IrvnWT2qo@{=e8LW4nEkWk@F-eQ~2bl}*pimc})0htrVuLOaV^Mx0&Nc4$jS z!-V9(b0&0zUN4)_G5Ph1jI+8)Czfn2F1~05FT@6U7pD;;o54GwGp`0Z&Z!F3E$^7N zv!Wxkb6`WZeZAhOY1q>KjBcEU5)35)ZJo#z%h%e(s>J;2#FQF5ttA4-TAc+J;>mB5 zC$W#kIj!EslUp&FctD@}#CDtz?iJfHEpmwtB^Nb=Rt2QH0NQ8*&&i@LI-GJ1HK1op zpsfGe=;pSw^fV&M9(K7XPZ815t7*`jjMn<2H~BiRKa4=nx#a|UcHU5$*)PH-;?eQG zQKwErc8p5_ZKga3QqmEw5BH6Zo)+ob^vJZ#2~CfjkZIr#zDjzu9%i*2EY~J;%e>0^ zNA}6r6@I?y)GJ10!$$>246cb(ni%>{YC8u8h58Zw4`puETLdi$;<BG_<)}-iokqV` z!5%`s&n%0CYkNW0t&H?kpObbM)t6b7t$dp^TMVP~3;4COJ^teI4{ms$0>MQd2BERO z*k869++NCwDMQWx^pdMDVh##v<Sb``vqOhay?qQNV_~-8A1jJOtoNtnc+Rz88@eNe zoc4=CI7K+1$9P$hsAV8I`y)qHa3`|VE3t|k-D)KNO?b&y0p`UmP*qgmj_w6!-j*Hu zCN^G$P6ZgaSB`fD^9^03awgB54}=N?lg~F?nt4=?W)6X7q9!nRu|K5lfE=@m5{7U_ zpE+KX^Atd4#w|aaXzAgN1&WyAJ&L`kCPWfo`ls{S@DA1XO6I|0`7%#09}p62`?D9l z?DZGZ42fPoRulY*{>M*epz%59XUhY#KbvDGPteapjDF7UoKr+OMKZNH|61yq`uP8z zbWVb)h;&XejFkM6AJ2XN$MG-<bbnpx5qg&i{A9wq4@O?U3vA$<2Xol}{a|heO*ELB zp)eBHnow6grJI=d+>W?;N$C#)K4iDb?Fw}al)T1ZtK`Y){7%#t@T1k^T@JN+e6_$% zxRxJ|m$Z3C%0-nJNZ>*$_H>ouW05{`!AFZQhcROUwgXqq2<Ub081Csu%&To1_Gh2@ z%)~RJGTD|+Rx&#w^ddDytEzGicL>rONpRX@nu6F(xUY)uZ#l=a4pCIfT)3sf@jsp= z1FsiEPh{Dik?glpoeivB0fFR7IqO@FSdJF5-M3CROihhD{uQyRSl13|bKh~6Aip^A zd!a>{o+0i}nqSJ_il%qO*O_0+U$wCQ#R1~&>Q9GbuSMl9|H$lco#K-}vkNZB^4e+N z?{;aR-M;s_1iX=Qj>Ugy<9+X_KX9y7&iJj?pXEE6qI-Pdx0{?LuZsyi3qGhvnSk|Z zGd*hQc=#Rb(NB380P|BF_{kv2LK78|xs-*P6xs@y2$k0GhneFq$~gW`WA9ss>6T!O zeb8F_z155*RqR2+%hZmy8@U>^GO+)6e?d38R_mGnbRwv{vO(&!U$3rOuWnqUnTNEA z?6RlSE4zB+3}|XH^CkMq_e6bb6nxK^x!R^uo1?o0&ERS&`N693Wx>_sO|DC?AVS?~ zzncvWqwxT78_^arKtyvP0KwTO311I|X@VjLvrZlM8p>K97;#FZJaq(@;dz;*HrO$~ z8YO}%P&)&f%Vv0u@Hx>wn-tshuUZ%|4ZXux6%F%h8`iVOS@5(LO_4&%Yv+G&VhxXn zfLn!@9t5>4WRSZn7Xlovx#PbY8YmPcvruS`{qj_?{bGg9?@WK}%YB^K{hBUQY$k^x zIb@ueaD^=nJG|9!r4#~%si%-cZT)he5w;yn-1m+!pwP|#u?e2NVh&Fg_qLnTvDI?| zvstlo*k6e5Tx)%kRh6zm4Lwt*9daawq=h1hgA#SMx_EV*O)*;?eeF>{H2p<O1hMUB zA_Q8-+h1iDtm0KO6TeX8nH}+uU6K*Edmh2rFBqQf3re~t`5OGb-SBx|LsG-%eMt@N zTfyJS`&RRJ+P?Kp-PhoAZ1+CSEznRpfhJ3q40V_}zUj0tBu-<(++(TrL$h>7a#)I) zc$-;6<M9zoKREmIIU(N{f!VLl5g6bXNM5g!pt2P+{fV1xgaiPSYqt<c#O>Bb{tgM_ zsTXRnh~{f>)m~th0u^3hiUK8GAfUijI-xSd71&5X8>QNkpws*gRR3PJE1tw=>TE3Q zhCRpY(;7&q@k8h41F0yGI9?!hDdqnZ{@7it|CO5kSQCMqB8YBh2Q>Gdp-_~eV|UTq z8)9kHj8AAN5O-=tw`xVfYMFa7P3v9H-^sl}i2<SBpvQpH-ZRH0j2{KF<15lJNLwHo zvl&m0Tx%<Ejk^M+OwBFB5SWVA?hoVKiLT~;{R)-&p9g4QHp<;Ox}!cDNq~<Hxg~j= zHO>Ufeyi5N)0GDg@aUO`jsh-l^!2r{0W>{DihEWAn4Z%4_MF+A@Q}#GSK;kl#>qT< z1?_J0!iKVhqh5F;b0W@XIEwYHAugQHuo==gNBJO)Gwc@+a`sC*{08OABmQ@J#E^vz zF>1M9IW+fP&T20l^}-ciST(3+tC5yxSUA_>oo3&wmbYpt)!mx6tzJtw*m1Miw-Ky; z;H~Z}W7V=JTEl>JSWpGg`c*wk3#Dv`ZfT(Ern(nM@*Jtc3I7ar)w(#q59C?K>c#+n zlfKoIy13DPy{-V963cS|({MJk5M&a3v}U-;<8~aw{HA6NMWivQa27s~3@Y8FON@Up z*2P3ZAcKg{a6wHb>UqkXm%Nr~Bj?F44~+3Bbjd!dnw@%AV0A1f#n8SHFdY-r${d0t z86Va*P`a5eb_6?aece_IlAeGRnEk8>aI;INAEdt)>c%}qr<qANt@LY2^*3`*fy23F z7+zIE$?y0=bsI4)bJ`~n4kmAQ*Y02R1HInJk~J|iTRC#P==DEbdi@&o`U=r&4ttLv zL8P)4di_JuP0i9on;nm9gGh5M?Di{=6xsc%1g9b8B)GfWZ=3xG-R~K~6ax~IRPQ|c zN2Ag5cpCe%pA<ln>Uu5Ny=*XB@+{-=#H>?KG|$Nd84q=b6c2??cG-iCGI0Fs8bf zLI_aTv2Uo70yMAx)Ku!-w6zTG_7_zokoc2kc4p!SLSei}w)G;%+}A}xa73p;>Ak6n z0E+a9wNAwp<1GdWmdXr`A}`N)GgQ%J%*aMw(PUgoBgb%ImJm=Q*9`|D;#XJ`ivRC* zXH7h!0s79hlWsOsy~QJ&tXY@pD_rk|qtvKywS}Sl3T(7UkMMBup+t!lIl}W*0U*7E z0tJGf!q0QC?)fv41K%Sa9>1o^T~}xbZF_gCk@^4iZi(ubxm5p4(fr`-zaoT<u+E?w zbt!)GTwh@J|0v0CNnVD<v%d#V@3b|z{O+fQH_2fiB9tzdnNpo>y?bUW?;p*h9Ab$8 z#_f<{H}GcOpKAiYW+r}W!cXISPE5YfniHwIHQ7#395b(;;p14D2qnvv6-wJN?Abu# zS3=L^$hw({rwl_mlW1In(WvhQIb?3VoF+0ZBLBig<hv~!v8pAIuvna=&P*)IB?O8S zdK4v0EKcZ|ONgz+@a4V8&omfAUXb`M5oSn&5Zfr17dE7al107nM5RO6XV`CdlA%52 z9Oe5)uJ<uH)UsOC@)286%ePrckEIZ{7HQeo3gITp_kYLrI=mMO(A9`C1`~QU%W2;S zBh(CsPc9WQnwiT<N7X@fG|Em*9j*2{%IyIQTL<ar3@^Oa1JOngL|g4Q$CmG`LFr~7 z0@L}u)xGdZ`D(&;Sg&*Ldfn>68tPK*IIh5?2!6yXDLBIr`Iut;u=c$2P;aXb9&7cZ z&6$Ci1I6Ilb`;EX2Ha^vrAk^)xz>G`;tAVG2tP<zQxm0TjkuF=F(aKh(qp8TNQ5XT z0%p3qb`{Qf8F|o97z=8tMlim_GR_2#nX7LW)<P%~j&}8M&T%t@a1R0{1&X=oxTYc| z+MCp~wA(ok$+qHR_B!9pK=rg?`}2a)ql=6Q#dh|^4?GcU7G@@Hv$({aYmAr9-X@Mt zPcY({p|6Shny9ZPeKqm*l@1J;R*xVvxxN}e*CWc5BAMK`#$BcD?%KUWgEgtUKdx+9 zwV~u}-%NS6{-<Eza&k7K?|3_xGm;}yx^$~8v3G;p+Z6{AE-a-^#P7xkmu6#w9k*?A zX!hngFwP@`v%iG-Zx75y6+;V9)by!6jfZR`sAqCbUfqjrjG^;K@+Wj;1%D?WS<T;R zM{?-wvK~UsM>Z)`&n#JJVvavpXofB&N^qkKALn>?awMZ#ZM4b5gKXtAIwNA5X|>H` zuJ^X<q53960^9X?jj?^vuE*<$g{&jrG#YY!-6klI9NVKM@tb#yZhKNtuyLgmn}#+d zk*@n2l(_EgK<wR~;p4q2F}nRqpkpL=93It-o}L_h^vuL!BfLCq)A({^Q_%MsvJH<d zR#MHG9k+fg%nv0VG6ZN&+@rjTR$X4SAGS6#@#9>IKvYP9e&<src1wYPTM9<LrF1;< zlk~6AfEDW^lEYD9^ahC1`5wq|1_CcD8Ts$OSi0$t2o<mAi<MpO)iIRYay?47WaU(q zswE1!;9I21Zj#iO+|*Hp)ITWoKP<KKJVp1jLL<~poX_HJeQ^rbEv?jES?Ciw1c$tt zsnmXrTl<EpeA^*v&omYH^-rqfc<M+fSH0V<G74t)C-PQBR=bf?uJh6RzSN-mefR-- z!UWyaZSUg;M?O!pm4{ej<}gcUe~}tUnwh$$K70?u<K)9uBy%Yl@`3X+5G@OCq>@Y^ zU$_s2GpxiyQ!A;&t?pj0IxE7ZK+1Evt2Yy^rU&6AoW`VXS2ivij(khD83p;)JC8sw zZH5^f-ZXR32I4fHH8BR#G@jMa)2YDce1%-lPlX^&=im9zB=-r2#Jm|Z6X(xbG~sge z{DGKzj9fU1mb)Y5u+&LayR&jS&vpF`sovI`?Wz0Mckd1QYwB1%zMAouct-;SH5mkl z>xW>IepinV=!f7$H#kK<cFw>f6yy7KJ8y>(n+bpp+wd0JhL7L2GC5-Tep%{rn;D`y z#vm<k)1wTc#Sko6Yy}dea2UY>6~@!w=caMCm(%`hnp&oIy$#^~CwqKrDRHv!WLdE+ z&~~}NL?2x-1_+)B1Si!4MF5MwdVuuS_QHqYRpA!;;3@s4UeydI$C%8_9|?(=LURD* zb*@1#UzvDmui3h`hpTmaiM@i`-?jtw_=B6jc|=7ZOKrKKBr8um0E|{s*~(9j6)G1G z=(ocZ;~6Qg*-TfMwUReoyPl?#l<3+sOtb?`?(3fq06Du%?6?3polir%dbe?z4r>;R zO7?oQ(rZs|R40~aE3bh#6r-Ydp7O=~UIE{{D)4bzU^@?)j^|$18mjV6j#lU%T4H>a zH^0uKFEw<=y7t6&&YM@wI=!z=2T}bvh<Z8u?t{J+3*O(u5sn<=Vp8nd4+R!{^b0{r z7FANd*LAhYoCMR&1y3u%o$5nT_w@`UI3^~Wv?=X6WptM8?<|?>OP;<qwxe(BL9u76 zW6KxEmiJw12SQ_($97aWv3X=nPFfq=r5w*y$5t$kt?2u>o8#5kE^?epj?RsxWy|NE zwP<opKlz2|kGsg`8V6b!uIXp$30p&&PuD_)_*zyn_hunfu9`A@9Qf9)-xiMU>U0*K zKzq?$8{4KWg#zGhzEcjkr0HObi&{gjmJk4Egp&R2K=@E+$)P-Ax9DRshmz;}66;zT zpLN>5OX2iN{#eDq#4d}~3u@^H_!Hf=)rnQm$E8R;CH@C}UmeXfjb@s#w;4?Ve#4!G z<LO!`c~%dex8`^s=fdZgIZJvwOXm8LQ`W|I3u<esW1Wj*oqhk}LTz1ax8vM$s6?xA z9^_xFj;&f8Ta|<Ss@M*4d`X{d504cM4gHB==jPI~b&9K4G|nf0%(H-2R8?9RWaN*6 z(NFNj-W?s?y}`NpGRA{7`1l@O@Ame`Hjeg}uZiy7>MS%L{K@l6$=frwu}{~={rp|r zFnxD)b9q<!8UxI5ikf@4=&l{SbprET%1q;{i*|z8s5=YK<crG++9Ccklo$jiBcU!C zz`tvJ$qT*F=dj8f{hK!W!x&8RJP)gKqxZ1tb&S-UTg<~SBL&QR5EmpaY4mv4(df_X zF*eRt#2#uBJ}>N~d%@)CJR{V#E0Eyc)C6^9KmMKZO$bgya)6gS+w00R)v>O{v926~ zzieHRH?iDA@CLN(;|$+TC|fkKXL=rR0MB{=L4#fRlCjPb_3+x+{^*X4t(Wn4YwL76 zbD=M`c{IQ0^oVWJ?-@Orls<rdzpl;wxG`P+CR0%UGLx`ir&fb=d)FxaMh?ng=YM|B zu8sYg%R8B#$S)uASxUGp{tVtxF+xclB7^}mAsrB4ebr*V`Fk%G*C1?#6pLb~mtSMz zyGgOt`U((xuTN)*+&1NV9wbiR`CF!%d@bWy{KAG^ckQ`*m|8MiQeUV-=pbj|C+`@e z!?Z(8<p2_}8#v11=#k>S9H_X_Zk$^|W!mD7u{dO%dy!7a`4?h6&v-MAQxzml`o1MC zQj#lzjkTnLIN;e==IvwNtN&X2m|wvG?388{>0e_XbJdZaeaz=478{?)z7nHXS+ipA zf;H>V-=45{x{TvGMjKb@D`_G-^da&%730eg)MY>b837h0{8sB%RIHYO$p~hLYF0m~ zKR1v@`EKSjO=RB=%#WP!D|uWX%?`}~fuiwu%igRi_EfiF@cZyk06+9sjH{5@>{)|} zHL{z;SN9=E>um=_NAA1qChiby_q-g;t`qPhT!4XXJ$u34^<$h!c?{rpsfvTCV(!4` z$OD#%l~M)Q&W?5~*c$NhIw=|5YI6SUi|iw0Y0-g;*Q-$pVvd`w9A0aWq=ZilB~N~O zUnWY?!NlJK$>VxG2ro1Hg~Z?*tOF1Y?FQYa+1G;E7b0n|hJ8UuS7eyxzsR+^Djq)Y znaE@TeIa_uf<00GwmD6U!ZoGFw9>Z`k=VLmk1iUw9nzKR-LG>IxtpTzk8X;-7*)<* zHW8Wck*UO2(sp!Ls$aj2%9Pkj{+iMKq6B&sm+1YtFh6rjS8BhSKK-`l^7hN+EiTx* zxL}{hZ9yUh;zTu22iuXy31<mDo16!IxV^<a5P*l%mS!t2XY9x_v5x{mSXMQ%9J<uA z5aZ6P){#C60vY<(iEt!OKB>REi~&BfTDJ1f;1!??benMSkGf*ROR&pW9jKeA4m6eR zv>rf|!ab2#@W)V*9s1GHpv|F8#s2@aGGaI4M*Dg!9MKkD9B65LE*udr=MKgJm|#|& zne5k-*Wf~lXG4w8II)XB@leNAQvw|qSDcwFMV!$J>bS8f)G@P`w{}tgEDzL~7+Dqa zp%GwBVGWG1$9f83q0XTIpS5Quk3FbGUbf!Mgrhf}S`y~D)IM51>1+7wEV+1iV%;#` zqH(O;^Qag1;Ml3k#N;ZGOkCyPJe`l|$ckmokEZg){mNki7aJO3cz{)fulCLW_qDaj zL6HvS?T0ZbV-T+iHooe#-^K^zzm$9B|Fyd9{FcUl@}N(PGyWfFHM1>FGw;H0l|5-^ z+tgrkAn#*6>%>l>dx7LcpR=T2&r?IaXmM@$Z9Ozu8%UfNP{GKe%#XV1`;iMEO>UwS zpM(6NV*w)57xB&gR~k#~K^$TjPV-j$I&?cP2sW;2YvPg}{cvJ0(q)W>s%#*y6L6Lc z?CC#sVBhdMRavceG}<cF>a_n8o|twYQq?>q##s-;(7bU|)Sjz8Urjw?CKoW1md#(0 z{*V}_{kN3oF~dlI1iAJ#M7i-x`c=fAnP28lJd>6M9l!qAyGT4&RQO`=jgIa_<hg}- zM4sk~9$fQvWu8=Y=hoKmD-M49F8uagSKQf%xYOw`@5;;s%VcddROE}ERAl->-@`{> z10Oz^5x4z=mkauKUjIoj@l2*aX0~poo-(*?d^zZhhnAfe2qmUqqQQeit6BUk>LX~V zx4%4{QH%Y?mUqS1hld1^5cx+YGu9DVFSclL`F^B))wolAX<TZ$*Ju0-c1EeOb%+VT zghYc{EA&BACYJ?b>q=y?mKX;<sEP4v!us(aExvbJ8n=O8+hC?ol^dJOuqmi~mTxn~ z#msaGBB?lQ<qH=1Qb_3hpBCvHs@A)&U+A;Uq_3*ds=|bRrStPnmSTm@NI&H6sI%|| z8o!&H&nx-GUO12#Srh8`mg(J+<LM+59_*N2ZSMr$ypj63MBTU&xDE2!Q`TH%2m;^? zMVQ4ZOyzb}wAIrTb9P|fzH)f!zG0kLb42iL<TGXxWRLCeg@>mbD9n6viNc@do!6Hw z`mpptM7uWbWJ9q{usi<yp6B{rOX9n{a`%?A@JfmLBQE8v^_K7O38W?gsi%w#%gW<Q zk-2?}&fALnFYE9BkNvOBgx&oq{m)juglv=>!oHac^Zk!ZxGk9PZ%g96VBOo!Lfr@S zx-2_rOv{g#Bnx)%9>8lg^3>(D%iA$pyP8nqYS8z)6^{XjlFWX=#MPQi5;73Mku{oF z=NlO4Ui5u_ATf;jK8g!Npb5yxd{?=r1{Im3Tz+kha@T!VwsHzGNgM={&R%!$oc0+U zcFJ#Eg`U*nEuj!$v&T|GFgYG2Ify4JTBEnrKS$g?K66nq{bSLUKbu$^>$GiFb^30` zRh-USA#R!zOKN&zU;3Pzcd@dlw0W>^Bu*L}J8^vhse<ZXN_0g<Y@Q)KJlGd|fAq)= zb5A8Od2o-e_j@DKmw!5PYwIE_-V;Itok6H)+f}}{e2pu}ADsSA8gS<m>QKHd!Bvw( z<1~+J6ziz7(A-yJs6G&9qt3$n)S>9e!SqH&CC#vRe&43>^uxHDD<dDL{dUrV$<o1Q zfz?unjK*TolXi`v#w~MeV4258NA{$Wm&mBEn+{12XLLpQ8f<*WX@8JpWe#{eR8ya= z{F|_jvz}_UUGZTch!H^DzOLd`ZNlc7>R>OSEINFa)83yD%z)k5k0EscB{bL<-P!5f z`kL2Oj<VUjB!0`#4IdKEMmGW8SDYpDeX$Qj&F6-kC3AXoeb5_Nm+ui3pXw|L^o(ul z)3s?oft=maw(^&~%~HIMc5qfv>h9;-F3McfZ9S9JLz}E!iI=?`BQg_;#!q_Bu1)>Q zUr%iFc7zQ)7grDx=`WM-B^?m!zF9o|+1O5J-e4IX#Q&2kx6TrTplhE`AI0kO=$T&1 z7-ABlfQp>ed8L%E7acCtciOL}l;G8Ric2USEg3bv2DiFgbGUx6kD0rN;c1FJ6M!<L z+iv6IQ8?M0v4~kkJfe=6W78t+0{o@C_Fm(}&tqC*JC2WB6HHF4!O%F%1T`aDL`TrX zKyRjMkRY8!4<MT+){q(FVzg_;UGHUG|26ohu0KpFHTA@s0qEF+iVjg<V^8<sEz&(^ zCkXwWkSrb9z&il%dhp<GnG@eG1FOVm=ndkp%twoPtuHgrOHaHWdmnu8`&dEIT^r_( zA+@Ko<a^p^!|lsgqOxfn;Vc;xd%sWD`}@J}wFEyb|8&7F+dRkrLv_cx@UPWY8rxM9 zIU(~cs?b_3UzPYY<8-~>ul)1Ghq?79tMs}T13d7V*h%(qd2AOWKTqV5mvG|C0b{Tc z2}4fT+!gtwm-$SaQ&Qwx!P13*X6qGT(t`NygI2L2VP~f$S+7msa7sbMwf!a(U_wd) zOPT5t{Zl*}@ayqUEj3x{W*qoo$TtHH_1rE|Y97O4C&xQ-N6<nbd6vy#D-S`O#@c$a z6sn1%hS<MT6`kxy+&#nvlIQhE|C_3JiLQ~4&2V=u=vRqPZ)LKb_Ma<nQI<|OOZzLN z8Wes{UW39<-3FjbKhkG<H6?AM<RSNamkYV0l=nYLx;2DX^=$eUYiOVv(yh_u7<c_b zq=Nf<74&!@uxqu%wHY3}-Ql!fN{CBSrS@1gF2peWKAFEg!c(P<(`6H<U5c*sy&O$D z?Wd95=t<D`R<LdZrF1*|BUB_Tf_+hKOr~eConxFh8%O#;6}HWe?Tk3_(W>VX>cP@U zd8^60VCSTXR2g4Db}zcGMW0S|_$n`I$M=-;oN+`=^`hRlsL*7h0$$W#Eo!`?PWGaf zySY@?;fmt%H@by3#;s8CeXW=2C<z4+ClJ~W8{*EO6hP_YDadl&cqrox*Ytp9nn0`) z#7wT~nPXBAQfJ{uZgi-o)KvhAQ%U($ZVNu{sKz9D0;^Xci-W<J>H^l6THwBj(>_{$ zB~3GVFU{tb{bIg@;BF6IAkqsAi5;1tIkNj^j_kJX=kh=4+IIGKV!vis+>&zQF+PlL z&L0Sk^Jw(nGMjVs;Mth?!xSme#2kL-ESc4#YqQaUx5XTeE@BQ414fh1F^BNcMU3I* z40kzPTK`%i?Y85@B;TdO{ApPKcm+MdpC8JlyM5t<(&uc?X8-K-V&Ah^r+pNWfv!|_ zqHDpnl69yIx=Knu$x1f=B+E%4+Pl+T?HyXYvghE3<Y#TyqARK#;Lcn7&M&A#9368P z*z7{iG2)#@#GUx5toF=BQYvm0369@DxG?+4ljHcC!!P4t6^Wc|)Vw8mHM&_*^e;hS zQS=}EgOBttnMZVo<p@GlG)xsgf)>38k3Yqpo?o>82xebI3Wywxg6#yVN5-8{lGnZc zodZcu34L#|=Uuy}ho{RoZwxqF%2tL3DV@aUNHixAUu4cll&Yyitucct51*+j`~Mx) zHo2Z8mlO;$Jk{PP+iQ?;X|_<eUA_7Yuvo=EA;l`*W4DQrODx6hQoGwKE&^QdN!iN3 zSSk(gN4ad}^?=H%IjPV9+Y)Ze{v_9ckCe=f^r0!=5|lF2O3YPMpShTiKkDOLx6QhI zn+>mULTaG-CBw_~b-xcI-R8`CO~(M!&|G67C9+_2`!?C@$ZlCVOxVf$$EZzpHz`i0 zZu_qVA5EbkFMa7^D)=+y@e;xfcn;4Fkfe4d+p;yfP1VGu9w%O^b&O>UN(~(h!iJnB zB}@v+OZ+Erl-Ay<%mL#)PFzRd+^lYJABfM}54t@1K<%&=WTWJ9+Qm`QcZi_F|2%$u zfvr#Y^=RYOx%COJ9*<kZo?p+b!#5bCcI%CdP5Z@fVqM0o-+@hd3CE_<11bSpX1qJs zlXwO3l7@=pwZ!Bnrs$R}Vn%xt>pF8_pyQ-K$0W8t9P+=<DL7ApVkcYD09S<>YvWPh z0;35eOT|Y48OwF)69#GRHI@d5TpIOK@GZi1+ovDmex83>4Uta*WlpDF$;}tcD^%C% zaz8v<r6k<hehm+13LLcbAPOkui{-v>11hPO#<#+KgRBV*eUaA)I(Ky85gm2jp+?@j zjZaIf4{}<3AU#Y57Dsm;)LM}Ytc_y36B9m^eu(!-X#{bU`CiEJZ*`(+`q<+8)LFQZ zk6_~q^N!|V)I0)*>OMwTvuz%J?BD;BFNiplSm`V{S#<FsD`(1)>Yy{GOQ5NC7XCZY zf#d{Ub|5H6CgoTIepnsu%lh2D4R@!RJ`JyI-{zNE#rB<_av7f6;Gas>UFIyjQ029) z7a?`p&HK56CySsW-h7fBC35O4)E0gLDqmNyJ3_@`*_)hOba5fn_|n`Xq>o3?3XF;Z zQzy2L_>Rd>Og0?Ae4ug7yp2Iui{ivyQE@eMdZPK(DS~nw%H+z(S{0$hTJ<N)ao$=D zgd-=kB$<7h6;w#dz8yTZtXzR7oe%HYSO25(PVBIO>teePFTsHYdvtQuR+VW|%JyyD z<68m#_M-g-b#8ypj>bRkh11L$ko)}8=xSp7yv@OESF%+8>PwQPov~F%;<{n`7u@UU z46;#+fv2UW8`8Yc*_TXr#1^CaJDd)%&11Z}lp{UG7KjRO+rTt%(#>56DN&9gMKct@ zKLE+3p|w2uBOaP?IgZLb;wB98vU2*0s~G$NT6B0IhFA-p7F8-@C)9CIQ61@<5h`TU zF*uYQ^}~mlIaVCUQCDy<MfYlPPe%6#+l|}zc}#<D?2F@F-Yi}5&&Z~REt&tI-<h8U zvbv@@ZdZ?zr=pAuKHX1blDIQ+aiPRZ_#L$90({Ni*W^i@nJ=Q4U18q?J1V1x^1@f` zcNeF5A2+2$8zdsYE~(6wR~R@O@6^d@N#Vj-X_pS?{4w$#)LIvQ>(&rgG4D{fqQ;#O zrU{c9nF<$@=e~;?gu86?L7>uQ;TGTakZ&7w#LnI`gL3V?A)^PVU->R%`tY;PlE$WZ zcD`KcCFiY;?djY4R{G~ular5j$2KD$T_epzQ#89_ZV)|aP$U$sCr7{Ah}_!R;w-tg zXKZtyuFWVx-|fvtySe<O@(l|xEkI<6n`(<aliPr^aGnS!;x?psbMNxc5*u;}7b{_~ zk>bt${N;aZPP~*$8bcE6G4@h*Z1v*U>b^Md+L723%W_MhmLwSRD;Jw^@uwZkA&$|Q z!&~56-7P3exUl^hT6hiwaEvpz%$=Tw&X&Zp9(<Dhdf;iIEd;Ubw;w(adZ4EXCZ<*- zFIXGIHyozL+2!~EYkfU=!Q$xd-mNc2cTSI>fqgkthm!DRTr`0C9Cdx#b^sfX0i8Dt z$Q-r`ziXaucIt}Aexb(YysAJW2O;9_mtA(#5wPk%({01B3pt6BY00aBy3eFAp;7L9 zza8|w9NfOn%mK!iP37*d%fIoj*jvXP94Y8LpzUB9Et?)e)`gs&g}T;r`4$5pcwT&* zrQc0or83j3OgPAp2bVP`r>^yDfJY=JEspLwsI7l=#XXt*bL}N3EmLG&bj4<WV!hW& zaQmh?gDB1Yy0vY8%=F7Op6!hET{YfUg55(Od@FL6&r8>Q6_(F!^k1DHN9WhH9nE0q zOG#U#I*^=#GVWrcpKCjexT@)qgCz8$i^gq8=GxrA+zRs}<9y?}wr|swfmP96)5GJM zu^F(@3{9RPUe<>D<a;ueg$^XoSf=RXqstl3tGWkFqZ-d(DtQiph4BpVqM3Z0xBSaN z+5Ql#nTo)O31w~7oMgdov5{gTCcr|iodeN$c5SSN%&#z&D67^BmM(61rQw;82RT3O zTB=n8LtCCpD|ENW-`PYYHM{Mvm#$jSmTzmr^}ty4aAgs1{#z<AIU%97e|iD)j**LU zU8`K`TIt%6<@07+2U{xe-EgWNI_|ik#QzwVTs(cE3e<oXPISfE=<f1)RbKWW9^n!A zY{u7Tj&y4t5a>9U_WMqc^zpI*z}E6WVl3U;I`?4zs&Qr9C`KnGRx7tJ`D0VHtG3Fb zBOTA<258Tt5WEz5aCBs!Wj76Ck^Js+#Cwia<aqwXeY8#@=}>Z{BSWmZ=VZTO`@Mh< zA!$dzw^L_*$)PhY@G<r+?)*^cxIl7NHagNb9YbFZo|FB*Yt?dohnD8eRPbHwJ`zvs z5h<<%Ci{Q8Tk32}g;&37s*5^kPfOxRTrjhdy%8J4i>uP+_%d-C-yC-K+BC%nUl><` z%l;}2+#Vi=*tqK#`$8s?hrqGUT0Op68Srm-0MCrTsN_JW+65HWb;(heBihiRUu?C# z&b$8*Fg87f5*S)HX+MF(^Pf-)VuU&l)nm(XDQ#L<WGyT*`F}ZJ44T^M5r>0J#4)X= z^gU|TBMw+P7R$R2`B+g->>uRNsybM!>YC(rYa#o6TWgZnE#~8(wsNhifs)sg*DX_w z6I)IR78SN^qMx>=oTzSSG&xJ&5S{pKdNHA3$9dIIOec<P#@I&P%MeX-!mw-2g~&lj z;a(kDfLB6=b%=S1zvHZ`EH*8lBMdpQ|59B#{l$qYpEBy>ABWMLLGz~+XD{O_{E4$T zE@+B>!SOZ%L1I<vk8H}FT8sm^#fjd30EGrXHQlyXAcn8^I;dxGdQCvjNgqE3pUjok zj_5X@vji`-!#V@87dh0v%0d3`vZM0;9-jLbT@2OB)%a&0^1VCc$o-kO%wHEr=>Pwn zuiapG_xZXU{`J2$U!#uv@66ZY$u?i7(Z{c!uctU=|L@J0`E!bWRBe=ZG&U(tT+&hy zSwage2)R1obm&$01ttY23+yp*-%w&@(SGtF==0}JYy$}_uM^zmbs?m-Z|l(Hg-93& zwe{2DI>3|1k{2!`&b`#H<ps-HiFbEc*1JwrJ7<q3|2};yf&A)PNdU}kIlnMl)vT_I zvP1uZK<m|^<#mC#ye4#CUbm?-Gp@MtUoS0|RO<Q4ubZIE87!qO#Y?Gll1<Hjv7)|y zYL1{^UzwV#+@)k)UxD0SSWNe2-Zc8Ym%R_CBMp9?6YqZND2BkjjXvm(m#|U6zzxEo zeS-XkpBrUjlE*#uOPx~kgj#wVxkb<X%fyTy>%kv?EPK?v!<W{R(u_G$^5l&Z7{et4 zf5w|6*-cBs#HVlI5Ba8rkM-w-U(|Nw&t@xk`fL-_WP!mP^CAHZfXs)FZ$_m#Zs}EI z%#2>zsvqsDo;qBWWnXi<Al?>{czhwbV{3fQlbx}xgS%2aVq5z(CwAue345I~^#8gG zP=fZQg71Osc^Qk#Z%|YCvwt1s%H@Yja87JUtfCeAvAG%JshDh|3v8KgxPV*V3&8On z&iaBdQn0^a0~Gs+TY8+lbH;eCoy>m;zP-Z&bg6?5hbQ*+U?2IGj;;L79hcR%)cv#V z0&@OiA~~fYwL^p>$qD~+0;|VrASJ8DmchZlaQj!`?Qkv<OFX5h1^S*(%MRTHgz-dt zP}_n2*wf!`M%9cC=6e3fuf&ziMdnz_ZwC(xJ-nYXwEJ^YOe;5P9db`camU!x*8{KO z;WroS&#+X(^^#+{u@~sGNJ0>jAPJ@(X=A+J&z=v<#e<t(4VFSII<j%P)4qu>$+pIg z*QYT;<W0l;(lz%TV&p-?*HNo67BvF_^m1hY^kGBhs0wXi3w#9w0+R>ATr)%9FWGUm zHa;!R2{M4mt`zbEZse_u6aT9k=ScVU-0FPcDfZh?sjQ0>Po;;FHQ$>`w-Z{vIkI0Q z#$|_IL6>NXsVIt0zkYy*<X`ITK8om{f#N4Lh(Ovna(XzDoP})hW#87rlM`+Gv2Q7o zMFHr^iMIc^q;xYcBV|_`G!yHB+c(ZZj9P(gu`=LW(RNSf^xSX`V3IF9hu&&b*~;fx z|IF}Yfuo6D`RgvO%>;8bWmkmD;ayJqjX)|_!-3Rr?pf3z^vqWNKomqkM}%@kSrcn< z3f!F7*nQmC(--KG#Jn7SJWowrvp{f1bqano7=9ch{0QJB%z!c$NW1tkLNK?z&lp~e z`67KTL(wyj9g|$q>0W9xD~9{s$@wjG$-|Jhd*?AkY81neGe96P<kLIBkb|>hT=akp zr0UV6c<7<`VPz>0AFe7vk2k#5!Y_75k7f3TbG|EE-5$KB)yyZ|F2;lG&=&fmPMrJ( zIl$H{=|ngEqd{cEn6kFMfMl!_XL(b}7GEna-E6qw{hva+DjYLqj?*r2Prcu7u$>3C z->5Ju==NtKe@f4wIG}PdPxQ(_dkC>EzB%!Kl6`NS>uWe?{KUmKCngIr59c&P*wTS> zPE@Cy+}RP{1%0d9{xiLt2(ZH}%W^&D8N^X<Xifks2o!{pY6-3;6zI@1KjG;%F)PRe zFS>wBUHSb1YIpXNXBs^4tq}i>3JD(AO1bcGJb18P{|ZtbB3Sf3*!B<X$5egfaUo}2 zTW#iix@I3|!RzrkSCKhg%4`P2TchD}{$M4?d1|h1q5g#^P(9TDQE3kK_YJJpER?Jo zBf|VOm~Z>PGeK9k;dgTUr?4Je%TbqJ&IU3p5C4-Q5J8@*z!sZ*3#BtB3Ox$zpV1j& zrB3puyIDm$_CaZGl=m<TvZ{)3sFpaMKnde)*ag`UHWQ3(G|SpUqkjs~3~hK9L_jVq zPbc<15#VE+)Bcu{3d^)@e=SjNN_opO{RHU^okjf>slUkZZD6CMyX%vey9Dm2<mGIh zzVzg~oPApIa`sPOBH-0gMgkt2P<Mj1zvn~;5(%#1A4B`6-qvN02-Fg=!vc5RB}aX` zB{#PCTTrufxpKR8G5Jn>jYbmNfdKmyU%B}a?ZzkS9iM;%v5_?;;fu}noV=H5D}_z3 zbo9ARRiI-wB!~y(E~5o2iVyWh6sE%OKTvHB&<D^N%<f!R$4^mzI!K;*8)lX;S#Mry zdH$PO`C&-1VXt>FVhA|RJB+A%TP#<BJITYorbV;M(%B+>)fwX-DCXho2DrSzgmuB| z2YHOu>uf1VQ=mxFv3!{ia_izPPu|YI=ODvmR_Z*^6oLYR_N14r)_W2EO}XI7SGo1t z8$Ha}us^uhS_Ktd-m0~VZr{V^%MP>!+t*vLk7f3AUuDho%`YU3T(;)>o7eyC-M`j+ z|1M$O(!YJav411Kv48k~-;nx{^AY-*>)KQQ$F3ESAARlK{ksfb<p#f@E6z~=j+^~6 zi3WLk7es#+l>W?x-&o0$yn}MSI9=HBc+UqWn#ikWHZ_%l2)c*Db4AdmDDp(+z=rj- z(XFFFbZ}}{*8|=xfbq7y`^QU^UjL48`}f=(-_*Y|zNvph>7PriZXUFECm;Q9bg}@@ zVtE4kIV+gJjf+b{A1Q_Lbd0UacKQ=zc|B;9^diw$eWU)t@7z;@9p@Sd4`GEIk0kjN z2nR3HdAa{llOU696M~++?O$|JS^8QcP%(By5Mxb&hrKva=>Lb|P-P;L?70>G<c&|o zvV)vk4k0CwJmktT+7gZY3+_a+AD{$xVluQr4-V<PkS|ClV(tyDgforB;7T~>h-za! z5kym%K9PK^`Oo!~z;Ro!nt9Zh{-et35ar|4vmBK~p-fKvdP<3Y_;Q0g(db97yYUmu zFvoul{m526$4R<3;{Tx1!icXdOW#t|@=u{rUcNR($G3!!$h9MeK4n~<q0gsE5xg^1 zp9g1U8KEpdA2^@uWvL~L#x+)=Ry$<|5s`iv%B0w33=L_*|HUc{vm|lkz|gzUnfJ-d zixiAJew(1?0_BmE2bA^<S-tdMD_zEWUZzf}4|E*MYxhv>kydyb&%t$lT&*)RsIaaf zatKxB*Ig41ZrVF&49*!TS6}1Ds%dw8P8`DuNj?noEF@K1nCQR$=|Vy$?I2EdAaN`v zz^YqU9A&V^yOp@{+~oE=TiG8SW_m3ldQs+&zF(NivGFh90dJpfQ+Yj*6e~alNsGfe zU2R(lt$9;qRd~odc2T4({RDM3becS2BHs;!QLu;wJMkq<3I_vHvJCN*EWM;;adO&~ z3FP*)D{L`9S25pHtqRk4-<P&G-R!`Q9rth#;9X3a2kXg9h%rzn{tB_(nCL_?Q9Ntp zG?N09pz=K3qB!q=e3~EFcH)8^H;@5FeJ=s*=RF|*GMAJ*`4*<Y4pp<2mvD{*J!~-W zvxDXN<T+a{YKYa7Jb7v%^S3NBug6oBmRZ88G)m#buO-0r9;oT%la_x3XZI&or#b(% zg$H49^R~yp=k$a8$;HHN(~=z3073AO<7`hZkZG?Au=dm7-T4wGpd?4#!|HWqnAp>^ z@{}4))d0%dMveK903-Rr6=3e-OY7$WfbLbt5nOWA<6w{1^}pii*29(Gc)1S)Nxi5a z6XlQYX$c>fE3R$hw^f|=$;j`ZI8eQUR#4B+!`O+?#l@K?6xy2QW*%*W#3V1<Qk6L& zmscWnpC&4HcatM?{o(<Y9PxFv9a;1|$S6f1;A{%vOG~LXSDU(dqd?49=;p`n<gfI{ z_KXQ1!rw`eVY#e9vi{WXjfm%wJwnCfHKRtWhCWuqebkUSK*-aa;2{e99Sks(9BDYj zg=bVCq6i#R%VU1{J6=6bd|xS(lB0GN;4s6*uJ)5i=}rw;IJK@-0bh&=nqw<KE_bcD z&p&YqiJk__w{V|QlcWBv(88YWZnl>#8_S65>H~>VbsYYXt8MWXH`^bIYrEL3?IJ*u z9>ceL{)@AIZ<ii!33Z%lJ9HgQHX;6pB8TThf6PPLzGb3+eNOb}9A!BmB;T1lDCKUi zke?d9n3}%D(Zb#^H7#8ZdSF)%V*5)~G|eMS;ql2<_68imAC+unZ?NZ}whED@K}GwY zWGnjv5^6=BUeE6hHqIFYuXsIw{%TtWIuXJ9zq{uVL;BIEJl;M1MUT9CwOBIN8+e#) zBvwsLANCRVxw`Gws!ZNE)DFIOFq9UP4X)&n78SPkCWr>dgzz=j0?ka0TRifhwgJwP zHIFab{X|dazj*dd+wp>sVxoz2%l<?r$1RKP*x$M3N@y%6TsK2KaF@M+<HPJmEV*;Y zszv=DT09g1-Lss`dHS!Z9%BuGYhF}<sOWBgWO%N$K=2)vrV&baQCe)f+AV5zrrzo= zNsWs;MCK7sX3Ug5oU&<AjeNo;H{lB`d~+nLNPC(cdNEDpT36rq9hskiF@?S_R+Ytz zKmCJ3BSy%sR|BrZwojqlclRpiOY;mxu01C%D>U4XcLLAz{s!sn7|BUh{}_Y7FtjT@ zQ7f5sZki($oM7l@bTKX*5qRxkfnUO(J#a#(0Ov%f{REq%Q3t6{I?7ESZG|ymDjw>n zTs_>wDOB<>SzELvzKjpfNk)W_3spR}61nio3XgjpxgjUx^&-((qDuuHy{eC|M=n@- zs>ubHp61F0&JuLNIk6!9S-#I>DV>L`WZDKI#3@deE1Lb3N~11O|MfqJ$};j?OPa8m znlMlSbooi4+K<VlS`KA}c+gpI1zSo?32~GK#<GzaTjs<LBqZwLv^#vUC?(~310D5F zPHr2-bm*#*>*xGNtHGFSSZI5<pvipFkG}Ln82UZ3&<P$UP0fSvrLnWHPF;?am*&~Q zZsYh93(96STluVn3s-4;q*vtpPi-6~knTquSK)k-qdYh`ah-+GhieLT+)N$n!+WIU zvpwr(3ly?VC!5`=q;$2S1xdrJu}ZnQxb$vG#K}<~p>XtA<6&+i@pnnd-00f+!H<p? z<l8^+ARoCbH(g?dw`#f=0ASj@O<jzP!?e8OobchfTw=d>fIQx$K1nVEM&uAxyDyhJ z+~B@0^DY(h&MUZz);1gPDD4#AUtI9f-9+U12ake+Uyxr<%e%I15Lj?-1Z$E`soprg z3N)^5Ezg{eI-+rH+X&+vCkK*q&;hrxLwenb4Ph+Nkqu*<c2U<Hr*R()L<R9qBLwLJ zQrMk1@mVxCR%WLz!5_j%ZxGO3#{Mb{+&xco+Rq1*IDv8ECu=!$w221r=udLgWaVeS z?@rQPMMb#RM<lPrN}QjlD<)Gke1&ExG)qtqES=6@{S!-{qxks*$n~3=D8Dm#ReKS? zELzv?Q6Tltl}x)7O&*$=MW?yJgq3sOkH^8Sr$40qppQG@t3<Eb%V;hw#-WPPSH1U^ zR?o;9ohw~nyBR6`Oh~CRmqrDc{NP)R(G|XyA!X!XGDeeCq$27xS|Px;OKeEL#-DD= zs*~K!<_M|-a&Iyfdn>E5l@}K^ut~jj8<5@#abYbn(I;vWK%~TJzmE<O5`37G>lu8< z!!=O?k@8UE9-b{EeO26Y`$BblLOq!b%^Tzk)f<oAY{Ri57=Mu*2&xv%L6e+s2lV*B z6umt#OHU8Xmy>c7d0ep0??G54ex?AWJc#i{xSA17WJJa(t@7Kg@^GIAedz-=kRl|j zQ%09IT}7@OKtEL%T=n)06#jo@VS}>Q$B}@x6f_!n{kE&`xomIUHiHIzTwQ-;q4ZIg zbLBy_rxk+fsmmV6z{2a$FnYd9GfXF;0&gSvd8f#id6@@g>OGyBS0?g2gbzF0oaSzT zSy1icWy09(m|W$e#M4x{%Mqf5%Guy<NUhbyiv>^LP0NLS%L;UGx5PAv&oliSwzz<9 z|2fzc(pEg_zMUSx26WqUEd@7R66TVt`-r@z^De5C#b<pGC#7{SX=dx$#YaYF{^(UW zjtco~0(Gv?E4OU?BIPZOpRj8u1<y%-UrXI5p`PCEU)MnmM2zS{VX$<we-&5{CcBnc zT=IeO7d<gVqFsk|;v<Moe<7V~a?}i7Ucy3l&f2`iWo4>IH;c>e@*`$0=&NKk5xz0l zaU~WL@W{qg+cmP7I6ZQB5Zb3FAOnpbx7`pOdCK(2Jgk%u493bzX#+q|#$d!B%wn-Q z)??ghxG;EM;8%l$pvh5B49laz>lx!$@h_>O>5(28jIgzjdw`OOl}#mEOdDKVG-)|w zjoW0O@v#$wE+U2uJVhG(Gd$J7H`-_PrGTeFuvab3KI3zm&)a9DG^g&9mv98v0Lr`~ z=<wLz(PG9;Qr<bYNN#{1RkK1h0xU4b>Q9TQ<oP4(rm<KzwN#0TC78itn<nKQ&{B~; zkeNf1Cp&FZ=ky^AzhG?+XC6V*jZty)7Q~j8Zs$$G*e9I7<v8g69#LRT8p3E-re>ET zL<oWIB&=p=Bl1xC*MuJOp?S>}*Yl5ku)Jr2e#ZoTz46D9ANJ5Zsk(2gI!`#3W~X6G z`YfWb;gIo%Nl20VGH<h5g9!$CB54KcvX{Oz0CP@V4(|FN@r~q);ETYObA6XEa5;(~ zB<gQB0fxlibM(N89ZoznVUE*Y#a9vWkfILx9L@9y0}5l>a*}uI60S{Ot=zJ0dx%NP zt+pdiv<#jN%EihO8^OfNOwWC>D^>Nn2!Zj$ujr1T+w7S0bemHuR71SQN6~EMvW)_p zPhiu1(j3_uWYn3?EzEV!X<wprXx3nF)^vvK!J*w=zOJW-*0c7R;E7k26GvOGsVk)> zkHlWbl25G6%ran9=i4OHNT%7#bS|0v<eJV=2^K86OPD|P8R4q>K0V%$;>W<}tExWH z6&qQ&zdx}hQ^mJ_v2PaRDQRBR24WD?{FQSZraF@@V1&D$b?sI3+MK67AH+t+dvQ&7 z9UAdY*2UBm>AG=R<A=0XWmo#S^i;LrOLu8P*-QM%tCq#S9PZrmL(OLLkgDSt!X?Mv z8}PlIeJ{|sOPYcKS8@BnY&@txXwFT{PCPkkeSIEECw!2fzX#E$GpEf+_m9yxZ&v@E zSnnApsq6jO5Kh{3jk;TnX9@1^Zt?B+^EF<qY~JJAei%ZTFCA1J(LLv2zfLa?q?eaP z_Rsf{=2OR&VI;87YM0q$JkAKA8R<XpTZlavF0EKUzfH~(PFZ-r^bPpLSR*+I8dkW) z%hslBs_hOh;!yahZHV4aO<OBu<0iYrQ(Hii2vc{ws3oz(7dhS*)VnI6P0FFUf%BLH zD<7nL2+TMBoPLN*xn$c#-*zl;aV5W%@8#h#PT7j#Qj%^c^ym4PiuxlCWc!d*FZBog z3u^J(JLNi~D_zaCs<JL?Fp^Ac{mN~lxxm8HtH&?bl1jXhI_qx$sah0H7-2AZ*n{w! zISAW;`?!M(o`AsrS5V#}O`=SWdW=YKnSK2C{IISjm(_}j({evbg}~>xAg7nRvyfW~ z`}7^;aF=EtY$v*F^SonhZGNsL`V}?&wS{WX(B@$|7T;B6Y4FeO>_WHseud8Z3+0xp zoIsH4?D=l)2WZgi?EZz^x05>!%W^Be(#`tkLe|vgJQTjScg3f>xqmHG;1dz?@j~tq zs<@iy-1xbl?dCtXQ2P(aPdB|4S*9Y>l}UuYoDeWRs*rnHq4u|P73T)|j$8MBg}xkL z$o&9`=_mL@Zmm(Ch%BZWFEb;a7`k&)ez@0>pT%b*OATN%>-F+Gs_aI$GA+&{F=8i4 z=-bZGO3`>PAjAkxDPYOJQ@uFK5Y-_TNrzO&@=b+0dZ?7vBZ_He(O}`YHH}b5`2^Av zy_#flR>=2(7FBZ8fI_}nFW-Hnq}TArZP6XoZns(W=vJ#o%3j&6YSS1T5vnO`JHoqn z5oGsR5!*4ziA$u4?U?MurSXXEI5!+Av|r*X9@=W@r%N2}e%D4Ee;)v5j?U%8%~Eny zzua7*nJ=<6oJ)xYSBlKXuJGW5DC3gv$cC|Th}uXF4{~)n@#6_m?;A(wp>#BLrTcZu zRPJVaP9TD0mt_8ytH6{)_bZ+S42ZXEbSLW?2#h8v$-dZTc}9*B+uWEpnB=JWDoFPz z_^?-SIQi0(i!xgaZFTwXb$A&auZ8vRcrC~=S9&Oa3e1-C|APJ)`$$jtcjD56`xD57 zI$J)sB9J^Czw9FiHEg*Jzh+149>`>l`ud%~{VVni7wPg9hG{yl+u&WhdPCQ)NGEsp z8Qr@YXakE=vF={6dl<Crrfaz}GIfQnY4<__$~ALOhbYZn3{>#ud+7#G3FNeQQ9dVa z`rUJwzo&(VUQs80r&_@JBR63nLRn$skR3Xk$|AP}vM;bL=h}E`{c3}cG*A~+2NDCp z*7e~FU9|=Mdd+J(d@BB|m4nog)c=7XuBkD5*aLDsj2z)sYq2H7vhhKe$W2OjUc!}m zWmQqHR`{c<7DGf1YWtQ>P#<&k@m+1TLFXyXQ~O`dV5Ae~^H{)TnqnF3E`CQ++tZo* z=};J@CVRa*m*@9-b#Dr$#k1YqO&^9ozWkJj=YMss-TOH1d^<6tEMGt8>%BRDl{t6X z2N+$+&pXe&z7h^<&e<C>=ch5}-|f<z4?zExpK~WJl@a4OL+hMR=vA?owCvD7z0Jfe zXX2W^Sjq9bd%F1E9-M@nAjKC@M(oq!TeVZ$Ybb}9^0!&5o2L~;=QHRkQcHiA<%%%} z=&jpO+u~{U+j%{EjE2eb)ZzScKXIKm`;lwD+QjlBye4FaT#>p&m0E4*7b+O13Yef1 zbC@ml<~<bjF#Daiat-W#y6Bng4KJYX3ZCA?m>_vv@N5C<xIbOR?daXEq4>*m_c7VP z$95kzZ-|+|C*H&Y{$iTyZULW(#CA^$A0mt_f7Q_QY<(XGt~}<MyEi4)WhS`R?g7`@ z-LDZHC6Hi-&Xy0-;tu+%-?BkpVZ+9kkw{YsfAC1$-TpoCH;(*JHX^o})q5G={X{5P zESL(}T!jBfBe*xAg>cICBA6WYp8B8cf6HI&Le<8{-3wLj<<TDCgR@V8esRTjDOF0p zo9urE)I(k5elOBFk(`w#*dk;re+tNTHrhnwoi)E8(TPi>(9P!gdQ+!b5+o0B<7+wu z&%$RVUc=*IvPk_u3x8_+>N2tpNm?NQ!6Z^XWoLvi&j?5fG$oXHPKwbguDl5!xp?+g zaQj=jBGSY?{1+Quv4<5^K?4<tkPZ)W{MNP^KaohCxE9=vBg}e6B7cz2wH*^o9?K4Z zGrWerbd(1&@HKqwq0Ofrdte}u3BT3idq3#=IP-heA4+WKZjafx>;GZxTmYjguEw8D zHY9<-4ay24NYJ23MI{O~(I8n!;I3|vDk`mLX|++R6-;&kTZIjq2)FAhpS6##Py4p5 zZKc|PsE|!C1XKv`SCxkXS(ZmYg@i};|2uQ<K7wd%zrQWnduQg(oS8Xu=FB-~&e8le zG6d0e=rT3`D5|(6IOqnw_#@4K3gawke~k0S>;WD^7K#A~oym+rIR8GG)bC5@gD>U1 zAoT=UVF{vwWI^P+j+a1*m>^89NFPwU+E>)5y_zQ?H+KNq$_OGA5)VK<v|7nkHb}zs zafkE*T$g}LG?jk%O*UD9&KmPUjQQINWGr78^T)f5xpH!B3RPXfagcRRPbh`8=g?c< z795USQ9BX3TO?x0B0jIM?TQSx^aIRCh4C>&q@)7>YBDCjpoEOc05vDO#LwI@w{g}g zk1sBqL$*|3$wMzp!!>^kM=-4(c?xkOgWs@W=jObztTz*}$Fm{whZBHc(`t88NZlW2 z=($Ayw1UHJythc?sW@g}TUL!vSCvu8YCU*I)On*Finh_S!<}ZjURFxM_(0-{Cr$I; z$B2bRE2PymscMdUM=Aj!gcKX`6Ph1hF@;No*D<`3CigTkzi}H|3pc1J*bCPyLL9VT z=eBK#TyPHlG<p_m^#f~nihrKQ;H@ig-%}M<5iA7Xj9vZ%+&{m?#%*)FkBk40Z;Rt` z@zwP%ZpW*};{iL(e;^}tKsoFBU`$pd>vW862_pk8*sW@xL-dPpD15(Vtus!WiPeL{ zbIej{p##}jXN`!NuFV%Rw8(#YMAZfU(>H4KZ|Bv2x|Dkus(4pg^#tXssO}T`jE|+% z(O;V=gCueT*Q%8aRa9-@;buY3;HVv!+PK;oUQ4!Cw~cHxcQV3NugS-wzWz0Z7PqAO zk4>!13VH5|SLvDcnlN{i#Z&k=X{_ePuYdh(6SX>oFwztZY}C0zh#zIrwfRQ`!+hVh zub6iab8*WOJi<t3xF?z*iX;D`c&y5*>nMunz7Z5XT2E2Q2=9WbkuF}>T6nbj<6I#e zNhDn{n-#XLF5AZtk}H$#on6H%J>qdIgN0mbd%Qg?+6{CuTCI-<@IIrqVNPa6aJCI; z&^^Xm{(a(EYM%J!!|~y8p7D8(Z$6x^ox<-Su2W_cp`m_4ntxwLXkWth;aibQ$r5+0 zS!W{`ng@P4Rg;(&+LxWR*?$&m`5^GtoHcFPM1P{j8w>ekYH+`PJ8rPtPT!5UTXx;X zTJCz|f66;d&79<T2h#dj<+t(2>?jq40(7lHXT{0jY9=*(u)10d(}nyaGF8f^ijPOJ zouq6kWd#v%<7;0*@hyX-c(ml=*;l!2pYX)cssG~sa3mg1ZJi92uf%SS;UQ#Zs)3#2 zI@65r>NXJd&cQ3+G|1gUJWtBijhXpwV<u!>FG33;dsWirPUBytaRLmaX-_>ONTiSs zT^%svI{x_Wv{ISXsMV?yyRkN$ui*YjG<>-dxR$88XdS3kT#FaUuOyVp1HZcbsvQxz z`rVsNQScu@I|-_gD_&*t5$OnN(Q0Qg6I?aNd1KzSp*=a;lF4~ji;tJRx$JHQdKP|N z@E%Q|kxV@+gyU5<0L?Fim2+Kx`wH&J`{(m^Tm`1p;mznfffZ!~9-&<baGwd-@=YdS zea;7%G*kPYEYB|to1FQ#^M&%^yoLv1LA7U_d15)W{F6;)F6&9Hm+&SQ9)s*IIHo+` z@aSC1W|`uDtJQxtOIz@D^3gU8>P8>AlEH-m|5?26yg*qlo!}A2Xww!E=c847u2EbW zU%`j98#tl!>ndKW)jD`!S}&^I@c0U2v$@3Xi+NBgA!n{~adu!#)-G{(DDFn@iY+i} z?PVQ|IXrBEytw?$cIC#52eszjGY*Cy06}<H%k8LfN}U?nmA#h`;h0uWm1}i!6F%Ha z$`L6h+Tz)#z?(&l7I+6@;LQ~ZAPyNv!+T5=5@7ll=@bCv)Di<w`4`!Xe~~o_5QkYH zMt&B9@2qh!@{9!>-jd6VHR|#nQ=Df*#MKtQ#e`vOnyl6W5R%oJ#%g8cqTvcMwYnQ+ zx3g`<sXPmn%YDw*nO5XHI7h0c027>XF|vH$%{X+7NRIJQMX+C=e_Z2wZ49s2e6a_9 z!o(O0c#QN`=N+y7&J?C)j?tROw$`E5d&RSgbR4IX<;vwNu3g)u*KBon#&$NGQ$i6N zvrd__;;9lBHo>vG{2dop-$)22%x7d*J87J<5{E^`lc=_|4x`aZ%!w4jMc@t9e6PA3 zN4C3n`5Umk8d!BvaP05>9hcAU0bdfT%Jerj`%h(5f6raK85t3yqSylC{qW;RMam1I zMHSqLe1sQ?c2?Y_YZGvM<9PM&a`amMmhAYvZst`TPhV0gIE{7}pKxmvu<dmi<iV3i z9gAY6pH(Tih@PubVy#4Kl_P^olwUi?x1~ym3dE0+lT}IP;;MgGUeO{~@Rlxb%&Kr9 z%7?mrwLnD9<u51a;HT|iiwW!KY-SVI{zd_Ua@3#)pU-=NN-P%(?dUmG9a|S$`()$= zx%gTtX9A^vS(loE-p1y=Dq-)7);(9W?nE<^*igiX>PxJszG*ta=lv^7F}GWlCV<A@ z6TGkRKPm!G;O_jGy@?r*3d8?+yrz3~iGrk9QW;FY0GXfuyo1vts-j6^bUlqT&pmn& zu2sq*Zb|>=FJw~^vrAGZDT_(`@5um=m@D*CIJuNag;FpD?qFx3?u>V0+H|e<PXe<t zPZie`NmYOC(^XSlF2xzo^xw&_(#8mBLoOGRC?JtkDoMJTG|K*0DMxH9hA--P>Rp+0 zxA>J>?HNLExac!#5#TQCM-2+Lhu>DG%^r~p$?mC~5MnwDY}^CHM_V;q@f}5~q?3{f z$VXpbPW$~d$h7xU(@vwyZ=mL=<IGx_^TeD;)QRAz0%`gJDKPA#HK|D<FBa8By=jFT zBrJl2MERT5+X2!wIR&ac6CPZRMT<4wiJg_I0}24pJL;I$+`VnV2kPerb9)nW#zn0y zQO6~;4}h`zTXLU8Y*<$<7*HV1NQ(<{tVefn$siuxfzekZ##tuG+>MNGT_#K^W20U` zM8*vVQi@)6JO8#wbz;OHSa2p^1gWXof+yKZxih01Z{#(QZ8Yf9x4nQ7Wkqo0kn+Iq zRNE4DtU%&n@@JC#DV0A81?KQg$}(TJ)jsEEWH+vwGedz$^M63)ih1M`4yQ6sS?N-= zaCN-DT73ytK2d`1+(OxC*&AZq;VOQ|yT1&48Ck}GyQmCmQBsETu9PFR{OV;q$XQ%r zKEIO%|1x=)A`dy7BB#ocn;IS<@gYgf<>3)|$d8OqlJ{VFB5CGNZsBU2_?$3bFj<f+ z@mOHk^MsZimTO6{a*)pk{QOM__RA_GsHBg+jSC|5vyb5bS<9O<XrC7>NnuDAs<*Oo z;?>HlNW6n~3d@UdM8SC0^X7L}p2!_UjTW>|FbgZOrBKay$_uIpqNRAs??`bO$Ak9q z<~J`&31dspKGu8}IVj$Df_A6*{<5lp7$5PJS5*qGN2$}+KyQQ#9W4f5o}0>TE#<aV z<+ihBwutRLr!Arf?0IE4xMD&wiTBO;=GfYtw#G8s7Ta;#dfPgG)TS-CUiRj?55*d$ zfy%VngJ4FbI5lGkBgIam)o44}sx8}ZtCS$r+KLu!NoaH_U*UnBzl7U<V`54s4+@_v ziuY*#KPq%zhwr{2f@TXYr<@y)gPbLwzd;bJvK*n}CRpS(zRtdyzd!kbN1mP&EVtp@ zZ%**BsJInRD{R0NJFPmqc7u0H<RP<ur*H3><nxem#J}Gb+MgP<HyaWE2dP<2#*xqw z{OH=U-Z$DpZE619wxE4x=&;@CYdqs^wVkNl;2D&lH%7D3W)@k0xND8K-FCv)*{k~I z(NWk+ZNW9{%f_0}-mI*x%jijpzHzUiP89L;1l=zg538t;PGNmiwTDl`)eMub>D}=0 zm0a!aTV^zdj%4{dv$gquB{wplvfQwbcLpbQl^Jiva^yagKlDi?ulspL#{b~@BmCV= zHC^yVGbng+vpFG~WkTN4mbBHJ9V0Wc;6s3<;g`m%8Nq^S1*>{I@i%3HjGVII*sjQ8 zT8P8%G)WB_p6ekup3-QG)3AsSA-tY}{g9}Sj$c5%EfvUEL^}|~r74$0E)%30u&OkN zR#QmH#$cd(N>7{}B247G)IyP@^AdGFE_KSM+^ayIq4=36B~1u<)UhL$RwHSBDTj;1 zsG}*CJYSLp4{`Gtb-WZy_9v1l{li%D$1hnGqqT`TW+|RT==~ioe+S3@CaSMMKpTpr zb{~Htwz!A3C_&NFfQ9Nr^Z!sDjE$U@G8Wo36$de1C_o-@<!mmwo41G;RjN!wBt)E> zc(HkAu~bz|l>Sz+)b7Qq&0=Y)*qlVMG+g-EDe8*iqxh>JDc%;@wssIYC5>%yLO)x| zE%y)d;i@6}fqUp0C8WER&jtMXugg#d9XI|>H~_}zF{HB$egZhO6=p|8{*mZqtRghb z%18&lXVuix$bhSQ3eK%ZX((mD#H=S)kEo)o0lko9chJdLA%=^U8N1L<grdgOSZk)e zbV!^AYW{&{Mg19e7`ve3Z-0@tnf|}Rj4A|rRi)6YpT$y^#mX45lm=2F7&1E6#j+la zWo?!$g#3;VV_A2^vJR30w;Odht(5fL;8f%Z3eV<2fpJBw@RKS9F#5#``=#)06pq8w ziNs&QEbyoiJP=E1j<voymhz5jot`#XDd`(j8MtpkS^h0nOyE~l{amF~E<!7~fpG7P zCWxNq{gy(7V_<+A`{$?Rfr;tQp!e5_VeKA@u8(ovOFE(Xu+3v;M1hPvRa=<dZDLdz zCQ9Mv!K8|&aKok5UC>&Uj=5dc7#D6_ZzKwla{E~5F5XZ*%3ZKUo4=Y*+{Mk>{8k?1 zfUh3hJS-495SQ(gZaWnzb{p%bgzw@!D3CAMAs-nbw~gXq>$?SF_NNzYQI**QIc=x- zTAfU`5MgRcbXX5gF|3QDjE<W4E_o<rGJ416>5-+@WLy}V%dc4}=@+XMbD+y(#Rie6 zu;F?uW%OMr&ZzP9pQ*Zxhn~^~*pYs*niDxDsku4`YpAB(rqb8Bh0ENBT2K;4=a{ve zrIzKF)32!GGGt}(^0DLA@2yJG4^fZ_7h4%YgkM<oI3(RID<hy%;{04UezQZ3CY&P2 zow7i!IxmzN&Hnv%#3(o*_P5z|ZR}gdM<;jc7a!KM@YYw3@%$rjY;|o~-HUj^s4(7k z2cB19vn2xMg6BySIsI;`hLe3j_|`={D+!W2IJ_s~hiAfHVtxZp?apVj3Ov)MewJs$ zEej`ys0pR@Q+D-=o(cI=Kj(=C8-_q-R4hysuc@!4p5bAISVoj-Wu41;6Ac)sTDF!d zCgHQGW>3mlrLQV+1)s@P^*yaLM!X6aq8m@Ei13m-(0qN73V3ZmSthxHn!M(~Z_8`D z`RcP?+jvcB$hIvk%eyiby&T8SZgfU^8DLK?{b$ta>l~mh*gHtJW$|R!`}IDcN$l#C zV%#yX;PjFsmAO_ub%@cB|D3Cy`j|)Q5sxWAuR4dI?@Ff;iu}&fXOJfckqaq?jWcHq zx3RIzc(?6$A0Y!W!Y*Tn(reYC_RBy#4TqZJylJ_7QoR!P8zaGf+#uc`>1)-;4RG#7 zzL@HL7fEI{%k_xo5W!LPjk_fnaTa@6zdU~^Qzog9i#8v>nCjUQ`E`PyVCmyvnbS9s zOG0O*m_K?U)SUrfDcnitWh3zI&2TP!zK0AmL4n}n#r}8-``9A9t-A~MAVy_VevVCF zMS*L@G!6gw^Lf`tr!fvygl6pQtu1J$-!L4UP&zKHzSK!yj1WAU-m71p%fFHx5nvl~ z<&+SyOHYmUHG53nY{kflbtmRrq%B#C^M7HT=I7x<z&I8PXGN|{^3Qp43*p|@__r`; zT{TgY$qIrjPHn}jbA_vlhNx#dsGg&5JSYtov`Bj=n`OSVx+ND;YogUb6YF+Lt8d3z zy;EA<F0Bq%t)ASd+S^Ebr(^96HrxAoti7Fcws&i*qId^XS}>Tg7%_I?$Q)PjyS9@} zCIq8_z)c7g|N2CUsW}87X-o}2120*L*bUz8GTgBe3DsCBsPZp(S%oTrAITxs8F;Fn zAYg0ps_OeVxG~<ud-Y5GZlg`2^r14;7Mu_y42;Y(+ARinMeX=f=mAzx3*|0`wxlK2 z?cNM|s3WVmQS-mYSK+ggJ)|rprFaz~Q<&$PQ|1X(fCitzYMm3x%c_M})gq2MMxZWn z27V-<>9O*Emaz)d3)JYt*uLifgOt&$rTztP$Osg)a~lZnK=O=Q&OFJzp;VmQXMor` zqtD3c+gwg<_q2;>jup*PVnH!FwR;)0u;`4izmfh%2E%gG?e+S`{h(c{-b=LABlG-? zIR=AOVeJ0&h|I}0LZQyAVR9iZa;=(r)&G;N%>P<BY5iohiEY;pP}s&$vLAqL4Rdyi zh_oCa^o@j!8ktwHMw$WZvT<ZxJ)|buqIx?B6IJKJ+M9*)#a7wQ$Y^gSGd_eX0@v&C z2q}b$kiNR}W<rGKKq5rM5S-J_p&#i(7mWwXYDZ9cKR)ZFEomB-GK2|Riy+s3s#n#7 z*C3=x0-E6TF4cu2$z4cG?m}I|<5|J!w&FELxO#mhxMA$1D-}i?$XilooUSN7#36_3 zA(-q24C?L*L|8UGi(u$7u!Mp$2@oN^XIGwQX#1%Hk*w;fiGpOI>e5KL|5RF4>FWY) z@Zs}-IE{74nl?vSf%vekc)Jl%AkN7^zFh>AaS+>pSF2rZ3b_GJO*=F)t2vxXxyt1! z7i&w_XB`){!9J7_CaJY6Qp<JY1ie)B_SA{SRPQDsxFdw%Mo=vX6%&HnYEn{@;BJ86 zQq;3qYz1oRip(5dj1NL@g)A$2YlQrJFy4Nq0~}t@**48-JSF%HO!i84NLZ7fWvV@B zKIc}h|1Ql1U2>_*WjrP82I*#H1_fXUWW8y9eLnS5I#cUgI*osm_*cq5#I2>d{6pL- zA33d$WS1oMvr6hqGpzqakKRUM-EijceP6!U`r7oRnbv>6^AomOvU*rmzi3u14R+h@ z>gA$nVz=W?w9#C%KP3vHdYO*c_R0`sh94k-0-?4{e<yZG8EheJsNqQ+YI^(0f)*0T zIWf`~`winLoWzL`@z>WQkQ9P-YcC<FM?D{E_16k|?vq>MS!yNv8#84oa&y8s!#AGR z@Xz@Otm#(mz;5#&um3Tt{(k>S{Uv7onG)tML*F<&&%e7v_Mcdnor}}MUT$=q3q#D` zX;S}=L3X8oZ-TF1xPNc(ky^3!GLEuh@e~He2^-^FoEny3IV#^T`2m#<<qO+c!<ZZh zQQs{nu<@wT=-;dPk7tH<<A=?xhe)6L^tQU3v4om9oNF`}99e(FhIq$rd=&a1z2JRY zbD7cL-<_M)j_z|gEC#N%g`B|<u3aGyftM6di^Z9}Oe<fP)ym(s<;GL(K<DqwDbvQS z4c`rfj1IaRr4N9S##M?U-=PlSUyKl}N*|HyMjIH}oWc`gM_%_%rU+>5n*R!Gc_TT$ z-Q=bY-~c_gKGpbkm7Zu$^|tssGpm0kBYRM*zk$6%;SEtW5**bD@J7mdHbs7F%DWgl zkGOu%mT@&2oeQ77NI(hCgjuRE4wV^QVTpm{T-*<vs2s$13qO&!4B-jtp5Qq=2@G)? zs73c_wS(33PItjZd{g29{XOZpUfjgvHt|-upo3X*8N0AO(B|8a{p<9&v;yv7K_+i* zBG-=K2oeir_;*Yn(2hijn?o?s3T^y8;Xq0Yw#hg-7x$<zPN}U^1jLiWN4Nk^HY{fe zQeqi#SLGs<SF(mMLMq8CXcf#Qb`>3BZ`*%z%TR92_x@u#bYV&MblY~P@$}ymKN96A zAXBlLNGf$-W7BeSxaHW&oanD%8X#dvfZf{EU}oSU-U>{9X{LhwG!8El^8>#t>)ZP( zT!D%wB_y~_tG`)TN&J;Tgm(#a{s!4%)!P0T1%NE?ca_ppy5d~y7!9?7$H=6YGWfOo z;OI4foA9hqf7mj6UqTx=7iWj}!JC@{(JwEO+g;wIEm_C01>FciBec3ykl5eRM_Z82 zW)^3SQ>%-USjwj-iaMZf^_+5T$uTZKP*R&e4_II?u%Ysc+B{Mf>#yQeWVe#u?bowR z^lQkGu7!U^QGZ9Ts<P#>Pbz*SIJfKMdRUTE{`D#P{he`^l+LkTK0WsZhqTR(KG#;< zZgf?ztAsf*?xG^K>aPJB7bct%8>d7u=LZOkAt)cz)t=_>q<10+GPc$nuvqgq=Bge= z=M2!69L2muHuA58qFE9muMNN=W&X}yRb$>%oB6$6C$|FM4*yo*i^kx4674YXQIo(I z1-^T2#bM(;fiJ2Vzo8bUnM=R4EbyfQA2HHo!eij&sKZNVpV@QH2ihfZ(6ss3DyAs# zsw-4{TA<VBbB<5>JP3F8`8)_0ZU91~h5cTkM}l8Sn)p}Ei9a#t5{@mMSvC6=FInCl zpUk67;`{TRXWj&V)Okh*%RJ8rhxrbRsM|TCa)oWEziY7e?A^lr?H|J0%tqb<aq3gI zn$hY<!c<9ElKmL3*{|6+daSU?Iw<Q5U&cqWv?TBY0}c+RC1c=#@Z%IPIDs5uxxffU zWd+oB!D5wa^{eE7QFj|VW4Ktr3fS|6rE(j4BZH;Gad|dj#Gr{nL$$gqDGtrm{NIEE zxQh>Z_G<OlDY{F{qxNLR3c9;V(cRYYamcw^zZVMY;g85)4&B+wix^UynW79+ov*RJ zWxr|Rsu=r8SxY#B1A}uhL93Sw2L?qxA-*0td<wu4>aU}s;E*U~@?Ew=#@f)4w6fy; zPHo)B!4eT<r4*?B+g0$f3r2Xsi=c_x*$=wYewVk6d@;XK6w+M5Oz2Q#KO^&;iw9UD z90EAk*3f8z2k0MujCUba1isrNc*6WZwEA%#;{^v*WIGq<)^uWT1rZy^YgD2VGNW10 zHKsVTju5)fhpcHHC5cPyPNBk1-|9Z$zI>t8H--*os+oEx3zRa}hff`$Sx|wXOa$7g z?&DlMn8AC1gYj;1)Glx<F<{)qJ7@RTFGm%K+)$hUF=S6&)s65_QP;3kR=V>w_9ivd z;onKEGAA@&%1GuU=3h<S4YckyWSes%{k)2hM`8*55JFI{FIu}DTM}E@`-m4^#<mLM z09K?G#+J52IKHSbj$=$(VVqI>mU;NI?SOI@yoc;7$NRJJ<t6|*kzx_Nb>|m2eTv{F zw4booYqAKV^^ClB;~f^!5yd-v1JWjF0q<~EjCUY<Z8v;|KQ#G=mBK$f`$hSOA0_yQ zi&=39MBvK;3Kk5%vet+1XNoNj;z1r+WX)>oj<KDJvpC~exCHNjNUbEfwh_b#uO(0I zT>cKu|DqB@4#UZRDE$!llc-bnL}<vutt{50Z7CaDM{8U9E05tbvX)nIgM*bXyY0!X zLr=yIwT;3_+eBWqSPTCH2LIm`%yurmC~T;LO|cq35H-HVU8o8<Ol&^|Oa;n+Ms1#t zsenvKuQ-wW_oQ(O(`qjk7C7+4J2M5jI8<wOTPdRlpTz$_RLK(jc@$w>pH|1~@G{9( zM=@AO;pY_Vh@l%83S1Y2k40Eu+LEV)dE@t)OZh#yUM-)+msYY**R7Khi~GrmxVDMs z^AVZwpUGGz=QUxRTWM5WZf?ZS<gd}{Te7~yvd;>CS5-P7T*YtYYblq7!c6Sy@cq2X ze1)%M0<d~S>NNCy7XhtsiDqll=DX;eZV63pm$5K5isz5PawhzV8i|s8tsb*#qJWR3 zX|+b2Hc(Z~S5H7OdA?HzrBegL$K_XB0){ZnG5K7o8Y+wT_ysgt%#O@Oxj`-1wwqav zX5EXksWbc+su4FN$YV0qjLG^(^u}{PAqJT4i#Up<ibSf9Hh&kDBApgH82{-@t1om0 zkSHKL+s*D{cV(^eH{~Mjj7h8P;}NbPoQq4TUIyLeu#y#*(4?Gf#e8d>2siHUh%+0Y zvd9i%^0@}&fz7UsM+@HmlcKJ5O$^!RwWG(|x#3g$^?BOs{pt2-O(>tgoSF*Ww)U!# zeMJtaVDR3oM1VzPTbX5jl?c$1uPUjkHeZ5A$0d4wG~z&WfcPniF5?uMa^!l9<Y;rt z_#Vll&Fx|$0Ll1{V6`F8a2M<sLtyQxYcd&_PY<~@BRY;0)+#n4{r4S0+3T}=AS2$v zGvc(F6%fTi`l<$5%4NoCChcTv+0YJpT2}D3t=-`47oWM>@rq;YK6{73ZFBZ4(dv1I zvJnJPQ)jV0OdSoVZWg@l?-;Bt5KCir!OI0Iv4sitep~^l_P$aUg<E=FKv?ADo{wgr z&(m|+EzBMnok<-kIGqL}gTJL>Z99b>q108prn;B4Rmy3`X|%fy)80d^65V(;uK~1D zTbQ|8#0yXhN!Cu5`k}0Gvy{1`xdUbawW8c<&nxSZZV2FiLnK-pQU1U@bEXO3$O1&2 zk;DAU>s7ou7he{>oL@O8j8O-L&p0D=f*_3T(`s3K`i$_BfGV=S>8f1pc%V)T786b! zs<^DLqenMJyku@&bk5~TO!!)=Gnw$Ogd2GlFrU~jU}DFxn1s(`#wVJfzF~rT&T(PR zEZA_PC24O{x`W=yTz5=@n{qz>`d)TN#a}1%1wbb(_Rf9GQL@^=fS5TK_YOCbp$;f+ z^(_puC1R8#TX-e+RhP>uWWR88G?hzAkU+tpY^gy`;Zu0&XA)sAl@TKEtQ8`UI9Rac z?7lBk0~-QX`IoWbM+Osp<YMRI3vmom!R<3>Y`(QpBSVcXnBovIlr#^rzxw9UqHnXZ zJuc%DV_R84TbXUQa5GM0oilVa%~`w(0ZYf&pdBq7WJ!3(Oyfx8QtLAzSkE`0Aj7rd z51UJKn@hWzG2W6ItVO~S(UB%!j(OKYr8I<@5^bT7F!qCIL`TSDKaxdzh`dl#iYFRN zwYs0tqFCQ%;l`Io5!ozUz=Ioy?^nH~^p)EDoeZu(vEUF71RQr7A0wg?U7OCXGD6e? zIFCqSBxj20{Y<?0L>-OncZ}~$gj`ax%-B!m-f{llDb*xnWGXye#=ktp&YP4HuT*=! zxisZOsjry`CJbR@nENVIXDZ-WABgQt{8Lq|!gkbMaN2GApmgDE*oq;#F(XH3hpt%( z1v<x=<{iVbhQWXB|E8J><E61QWt;GQl`O|APu`^P)lha$40sE1RT%qJ(m;}|sX@rB zAn;yNT7L#<64OGdu=t9BnTdd+JtDm%MTFwutBEq!$7aa-pyMmC=A({2F_1>b(iBK1 ze_}ye`3%qtdyii^mBv{FZ2Yntl$qjOJTx+#gM(FlBo_(xy+KU>f4~PkPnYNKtGQLB zFZ<jjq52iB;H=4~J)~XX=c0~>W3X&^8om8ZWPU{+aNp|apn-^khXs;yIS*Z=C;_8o z6Ln4O<G)fu3CM_Qb8#%OjnY;t=~i0$J5p5!+ucqcl*JP_2bBtc$8W7c*-nnKLM3MW zKYwE-u9V^eu^Pa?S!H{_rOHwPI+8U}$Cg+f?@2mnC1|V+4IYVA)I?4U(g$P3f268G z+(npy+hd7~V<o$|XBzwb=PHp6#*;_<*(+jYpA1N?2P8Q^>X`Qn3+gUaFG4=La**|- z>>0u&Cc5%Ltmfn2H%G={qb_ypD(YxfnIfM}*e|#Yq`6Bp{>{LH)drV;?-@B|hT3}Q z%a;7){@4Go>~WiZa<4LpT7S?zeQ(2EvNvw5DEOdKJKBH^tRz%t@v=Hx$@r8{@01kY zH&kjf29G@^&ohSI!mo4rW4;U@(gsX}rMy&Np0D&(Z<YQD-Z~~<tJEHSDc`JS+QCZg z8~p1E^Y1M(p3YyX>Yqj|)Nk;w>s|hZ)E6yg#;3n{=R99<@gT?hBRyT3(Q6u|eat?A zm4-f!RBAI1ALh@oPk8%?hZDSg^GKyuwOQls6G=WKh1z)dSn_$0{8NB4LlWavwExFd zyoHd`rTu*^{#ve`zWNwa0%yUyC}#y!&A$$60l%RSJA-^ut6j;O<%*j-IP*-IaXfS| z6%#rC-ZVl1hW4g%TZ)NTRO!?n9W=aBo3?{7<6qa?GG=l+LoYt)-J=(@Aw_ZdyRxeu zC%Upso%$~>4^rPF?u~!Ho$s3@)!olda%?J8wURuwU*`EsXP;XdD>Y>2t=^xPYk%Kf zZhMc>bM!u{kcLJ+2H2T9Wg_;-DDLIqLz#$wF%cV?h#A9<agUJHh-8yGbEk}bY-YYm zb*BJo#<t|D+N3N<GIO(3MGLB`nH#%Rv5EW*GN<I9YT{)*lRI}k58J`hx!ab>v=lT3 z``y0O#A-AFf8VBuBG*ojm@{_RY1>TkZG6{7`!k#FRD-6?ZM3asK1m6YGB?DtGx+om zH%2kh*SZ)=l`bef7c1j6NNzj@W4Y>lk?o*uJtBIWXCSYSTx7G}Q$0O-_gs`J_Q<ft z+TYs|rd&Jygo5yRrO}^Qq}tzE)CaGf-l!5omBwwUNp_@We9w>Efg2!|(8-_6Ed|eo z7{YKDiCYMGX}B*s?9pEdDdnDgZ}Jm)l+053H$RukeoDc&ewlpRK;mnt_@VLo?>v9~ zYky|d|5qN)Q~!xr{lECpIrSCM#(yPcs2rewMU4{?bEA!F3>G0u1@Fe1K&3x=%= zs9ci8ds^`75DKqFx-kd>+@yR|?&oH9bh9h^t~YFbz4phz<?j}8E+HyY^8KV(!RlRS zAn|vm>4ABf%H%mZECdK#R;XpQ3S;!C{9h;M%k2ocn-Oi+YJVx~TY|Q+&t;26DR-ET zaWc$$opT|U%j1Yuze7K{f$7C(VT0#lS70K1j_`l5T=*U<%M+{6lt`9(<caNGZX*U& zk@wqflN1g~xqyXHJjX@$oe}y{`H25~dU3P2KmErG!+khkn9IOj8hfReUdDGM6QcFv zS8dEHUMMD$>hcdJ>JxSU<2fm~ZVfz^DZ|196{}HE_pWmmF}hsHD~${gr=BB~+Y4qt z>bR8JB<BhO%)-o$%Te8saI@-7fKxz5H1(q!;}B(6s~ZiN_9~=h;fg(sb<xG~lpq-6 zAtNF3pKcdjmK@}r+<eI$A+>YS<#-*Rm`F7H2hvGZ-z4mP!BKhhse*wCDCF+WiQRwV z9Ltp`l4iqdu8Iyj1Lu}N8PV5u&wqfPCg)Re(rq3okCXkb^y&-M6=_6G2KDMp@XQ=8 z@pSd@Fh5=C-U7)%7nR6VwtUMt`6A*<PS^d-on{_F2YQ|O!W=K!3rx(_2}h&ljK@$Q zqZ@`N#mnJd8B%|wqFOBi!4&O(u~N!rWU=fv!_3P)MtB*H^-)I!Xu^bQwZ|!HMcfb+ zHCCBHjiZj={#0gYDl_Ciol{+?{LB<KuqSojkGOW+KgBan%)E;?dXLEhkSm>$n{X7V z!Xv}KvuGoBF1j?3MTBM!8#sm^KR~YIX5wmcJZOATq{ze^K7L=7kog~>iim8JHNvup zI?l2-T}BU=aaShsk=3zJLiG5#7#9mdi5>OmLv4aGj;($;va9GJ_Vfy6uwPccv0>=* zL&duh4O$SZ?I_m+AggT;-iV707SSJ7;RHGe{p7xs^G>I72>2h2_j|zo`Qv>(i246# zybGDz|6k)BWCXszct3GKjrY9y@$oKUhmaxs-T%mMY`lM|22`SNtMQ&EeySMnlSSru z-=IF~Hs0ngG6Bp4J++(+abBwKPJTpL=6yi7<xr~TM<_NXz(lkjLx@p4#_sYyi4lM+ zy2?|Dh&N85Rivo#tX-)Rk%Lehld>rSt*}b~#plHykh$$;0T=Q-K#}KMA)_1%x{+tk z#X^Vg1mB>gkvoJ&R~X1DPkV78D_eNmUpl$n93Z}RV0>n?ovN&G*An?t`Y7RYtxmRS zc81lzas=d_`*p+>RpZ0(QCHhoDw4rlc7r*1r)cpU|1%2}McFKVE3MmqS2F?9Os<YL zB40W;LPuT9%Id|@Q93sw#q(`hcC0<bcH%hHyoM)^izcbf!1k=*1Q8?9MzJ@1O(uf9 z<yHy%c&{QmeGorDZQ2PQi_?mzV;4vOX%WicjHUfRAqEG=H6O~Z3Mp{O@B?v5q-O<U zL#ToX>MT!-;on2bR;Z1_z$dZftLc*RSbEID^UMJutUKDiTYZXSoaBqLBLd^CBX_W9 z(Yq{oovUP0wH{#J3%FI=kt!5$z-$L~D0dbzPuHtzC?=kFGI4-8B=yZo=PLV<qbs<a zf`J-YGETYT)@hDA_<;O*ByUnAUkGHJU;mu1)#ziuL7W^pPO7mt{e_)({EegBYvtsv z8w7CP5(6Gb@SvyoG>2Jgn_G1XeS+${j9su~2uEMxq8ytbKyKSd3T$k6pzmt4#~*<N z369mKZfJ_X5^ETw-nIfN6)8hb_*zwzSrU)w&~OO3TwI2RtLd}j<Vtpv-AHr<_2MM? zUU2tkfUfn50Dcqjwml%1v%%goBL#aC<CUPV66Ag^tmCX4-G6h6r?=a<N%##C21MM# zpIim5&AG$e)kI7mb<9?nxl-^9Iii_%6=_;8%LTsde&U`w>R8D_a2waVjr$d+qAsyo zQH%lh2ooYKMJeFQ{>##o{kO-t+b{XBf6FZPZ;Kurujwb>*M~N<tFtRL=TznEwyvtn z^`(NR{O8jPTDgQ$)fW!(I`OK*3IF6aeP|08bc3T;>;ajBy|+Cfd~v$#Ntx`u)&}-l zwf0r~Ik~S3-|B{^;dcD2YxThQBnpIQc!HHHhrg0F%1B(9VB?0c#v#TOj|_0C#bmO? zj=v$savR@cC>W6r2FRp160eIn+J*^`P@GBEo0Mje8l5;l2mZ0r1?l{&Af`{SvVy%o zrVqN2jl=R$@6ao{(<mvz>ALxoV~&|z=opAtL=kd}U(e{aej;57+>rU`M(*J!h1O4k zmSuAj(BE;Hwm>eQ32WOQ*D?N%t33n#9anjW>Cv^G?_r-7xum>sgA=FpSrl{r!^R^s zh&s5F$?>1cnf(o3)2i?BpX#YSRZkk1M&<6P+#cN^_LI((9j<7|EnYL4$mY10t(6(A zC-&lU(22<(E(ibRU!Cg@{mLKe>D0!y7;ocjaJAW#lJKdjf267=!n;*<T;9T^AJ2EB z)(lmv6UQBinlDVQd9~DB{fF|}oj64#ieJi(>PF{3Qt46T+QQX<tHx8SAEf!4T8lSo z{yDT|R*L0!N~8FtE?(<>pUcHq9hPBO;9oiEo+dh+d>@sbdahKx^oLrhyLf$>Hg<dU zpc8v(Yi2WJQI@jJX}n#%CGr|IF$9stbT;ymT+>$u4PZn1AEq)XLN0hd^<BXXHW;Db zMNETY{d4&RJ)kX;S1Nh2tNq*M19mDlskxjOlc@#%x&;Arr?CMX;GVIC1hQE;Er#-h z=MoDQ1_>$*1{Jj0iGn4dgC;Dk3WXwQ;JMu?I50&Pb+tT$1b+rDHA}+45+YLjd!wyQ zvAbK$V8D!U|KP*oa;0jo|Lt6V)35wZJsBh8y|UtsRqK|CUW3~pA5f23qajabl`_=o zzxaM3^W{X!C-ZJr+Am%y=w#Mf{pV$3L?%=Jds|!8udS(Uip)@xm%RUADWUlrTg!?! zXnt|>so=*srkeY`k(<rwPOLFC)c~L^YGlI8z_1&+uKZ;lWZt=cT{V_DXTm`YFDKpI zxrG~;_ee%zgX*ap6W6R(P)Wb%-loD0e23E+<X@Qx_GBc&$B>yR=)(tik{P$ljH8H5 z_kGR862X{Fb4)BTkAQrruw($g3QN?9+VtC_@`9sYkq?AfBYqGkMX*HSf9(8DOei?G zYwlEWHC=k(CKaz2EEC$zhv@;U!K4#uF#RHCO`uCYh+@SNbqs@O#r;N@$8mo%<kOPU zNJ=;~S>zc@OYXfQZ?dQAFPuo_{2RDghx5||rL2Wfo2Y*o7EvkD-PZXvaCc^KeoD&G zsOh*xng43zTG&4@5f6^4+eH=kXFsFcjz#x0t(t)0d*76$tge)%KnAZ;tVyfCEt|5_ zlgl<w$WB@Mq?BXl2xkA2r<9Ecu}}`)ayNRVmJvRXeOyQ=rw~isxS@$pQkQ;DKH({C zsn>e4o6V7CBVKuQ*f(pFPt3A^vp-o!PVUv@R9`J;$M48Olk<~0FMj)+^WtC*b94pP zZ)D=!IGs(24b1a_u5NB_^JZ5lk;i?=6(W7*3qD|%yDLYnbdD(;1<j4iI&6C1iu}Q% z0uA2RB0r^lwRc8QDfE(U2iFzdHk49!qC*eqK{;=j8=BYvPPs?0fK5wKK}guvyCp$! z(THi}X@r{BS&Anu60j&$Gs{F_U5MGFG?gfbPVp&{G|fz!EFl*+FQlx0<wML460^HA zljKtqa*{w?gfJud$U{8j3AxGn3I54{XeNF(+<`0Lm{?t-zP|@t6T>qOW6tPZ175M! zax-cmqwWgOUj~|uTrETk$Wr?7Bug@KT}6O!gcCsTqtQtN^w(MjcKm7NBY!mX;uh~W z#MKwoCw-G;Eo0Sh>kyUxJFhtyxzh7|h!-QI>;t-O1i{JTju9q}Lqj999&fcz&@yAL zTl<2)ff;c$e^n-6a-J^J0_W7bTvP`<PmwN6lc$HIp;+rDJjt!crlQoGIm#8qrXt>Y z8Lb;l%ID6^I3EkXgC7i&;D%C6LvVQ7(k5~pVHgE}07_DW>A4C@+0ugPXDkTv1uW5C z{Tq6w2-&l~?%SQzZ?tRm+|==)zZ>;~ZA>X=L{brLJ;p*L@f$MF0*^|Z+HG~76W`(? z-QaM@sfiPyc_0+v_>^x!O98c1K;>7*Y6{|I9>kSgmx1O8g=kHX20tZ*J1Hi>q(ll6 z`-$&~>!Lly=RJDu0SnP43wwwJC=*PoFwP1J%8htJ(bzGfl)I41ZvRE9aW3gekdeO( zrNRs1{E^BP<)}pDF4*P@jzj{=EwL*LHwX$7i|3-Ao~spkY4sw2YeecKg8C~XcPje3 zLiK}-2hmL`U5ku1DFlVQ*NJ>@n|QzAkP>b3JV$G@gXKjfJ-iF#cIYmY;OE%q;_&ok z!WSNO8HZfOhdt#C1~)Sy6TYGp&tP+MRG)*R_H2<6G`kLBUyAz8U2yQ$;K*ylY@}`j z+aY|yM)ea(jd>)p4kh<m^3!heb>{Ch;m3UQGE+PQ%NE|B**q?b`^+3^yM+OD8S7l; zL<g=4l#kHrZ_Rqq?v`ouRu^s{qDnAbdmq?>qk71XR@SaPkLGF(I`b!ixLoE6fPWc# zWqD$jY$h79M7|Ea2j<DrR#{q|_*b;tPg~s%Q-TmKUW9;V&3qM<uVnpMUybA|pd{i% zhD`$3i1?2c<j%{GWt|(S7>S>=BA}nb>(qs~-JukMQC2Yz>Nu_oBLKk=;v7sbtTGq> z2n%k<ZukR1JQY1OII1TAs1Hoo9U&|GFN!}A-@CXgiqD%?C!S4|d|nbq(1W%AO7t7= z%Hb*s#Pkd1erU?0WS(BZ?E5J?TM@X~>6@FCg8BG~2_x)Y+{TX)8cTKGm+C|q9Jwcv z_&rI)2rDHro{`bGe;~3jH8Q-)8qDR>TPbCBMGdIq1goE!BOrRL^5IgCtZ7EuXmT#R zFH@n5C1R>vbcb(V7KULHGCidrS8c<~Ht$H{yqqWnMu#3Kf^iWTKiX+^IdWklu~ibS zx)+YiyoXJ!o4j-;HTveEe;DEpT=lYT;kX<;|GAB;OpHw;v&c6PSyRXzxIfb=qx_=X zJGQU^#gUMbVDCA!1Qd76k5+a}O`KlP=n9nNxvZJ8qImt()FjD<7kP&7y;sExQNcB_ zZYbOnH((GlWl5}Bjg7QDPllR(#w|mQM9c{_8;P|nM3Rv&C8-QV)R`1!L{KqTJt|}b zL*!e^fyL>+n_(g&TN;K<04I<MG9I$9N>NAQ4d?8zh8WnwtqP^!A5DA;WN7tYS9|uo zu(h>2U$J>72|4p#15))R7+3|O6BDs=6LUXKYP9AD=Cwy;kQ7Vg|5>(^WZcM!x%NuX zbCdok@wZH8jQTj@)W^S4O(X)#dr?uzJnBhQ$9oN17opSQtN;1!iC%)KOHFzqgCc&) z{{*eLG^zA_DIM>D_xmQD(BgC=X^IkbB0fDaI*}Wr6WymK>(S4cnp`MSeB+X-c~1t) zB6PCgqiS}1tSZG{wr!QURJ`RPMVr%Jwwa8bxqM9Ce`$QQcPEB-(WKZWTGJ)<RrfDl z=*hFIJ`2X!@t;wXn)1~qqn)c!Fu>LM7>Hyy;IhG9>f1l2)VJ0rU!<E$!u+BgHsY&I z5=+LGQavivmYuy@${X!`nl~of$4h$h$30BxpZW1C>f=z`1$i0S?Xl0YW1l70(IdHz z40G!<>zJYHFwZ|R{z#;0ITI18-IXh$1&LDyaknVisOCq6l~G(29AVT^FQPF2O1%mG zcT9BH5aEl4$oQm8BH`Z-+0l9b>5#ptzW6VP%%?v7zYST5szdRcx||6hADN#!WIuSg z`;hrX+$KYoK(3fPGwApcw+gKDs3^AsJ#@|pvZLgPnDcHmBmCjWW2z#s6GBoq!mP3= zsmkv0`g9jIUrS|La``7P7ePWx(}a;6Aj$HOuO8wov^#K_^4KSL=F|o#T1hcqa-q6G z(w?b5+*U+9I0&<XKX9Qa8}QI5*a5AFURHNlti!j=I&#P1DtKi6Li8862HYcag=81q z8kjsXM_!2>zQL0x!DlYOWw4#o#6r0}P&_#^(}R{W(nq(2^gtH>H&-2;FdRR~d268G zNT~qL`8gF#_;(fLO9dn3V{CzFGa!c79++Sn72+?p!}K)=541(HC*oVb?gFSz<o=4l zgZYe)#7&<8DMy<X`p_O54)%jv0+X*-0I@m8M&y>j$m`XJc<;U?@Wd!q5>1VbP98;D z-ZI*deYc|cV{c<5jbW|0X~ux6UXg39$LcGX2AbIin5sswfEx2@DL*s%6*eo69T{V) zFxE(UVrtiWO?>LcpTaq@2W%p$2V#Z0$^%c1C^OFb_t`*^zA4K@F{_oeGQM`V?Oo@I zRS1I6GI(_E;N)uDe-spI(T%rp$w?eZI2u&ZuutQe<-!L1*@wl~gA3maQnL_&tNA2e zk9R3fu!({wmx%jOkeC_+Tm?sFjgz?;K(S1%E+`)aDvEraY3dZ9m4|AnStwC$Z<^u4 z3%jaTCwg@HD~m9UFEY&T))IUL6#WjzpIzu!0(8P<v;b7wcWFz-1QzWeH*Hq1QNTol zL%R^Hhu87S5m&lp;OZZjwEqiBP{Hk_uaZ-Nsd1ouq%`DQRX$SAVz3$IMG)RJ;>#2f z*7`d%doRsmefYjKOPk`FazL9c*05H0D^=k_8UD*9(oRSNLwR($R2RJ?ml<pe%Nbnf z?udU6Zg{`aC6@f_k6`9vw2RL*Tv3=#v&AwH3F&ooT0FyMidrv%a;05g-$o0r^{AIf zMpID1rY-~G4BR_Xwe6!dY2VX_P2G4udZ#peG;*csY#%021-$9jg_{A2^-#N)<`~1U zpI_a-|BML*)?>X()+mEC$A?pyogt-+&XN+$;U3*psXc&|+O(a=F+3BCG5NC-i?L1H zDDp(VRLZQP47Oa;8Yt5sW#rG!MwO54+@lA`-$VX~<bNpn@@FTOZku-V?*mn?$7k0= znU&bkp$2I_qt(fEG&zyF+_t^Ct)cLQKtFf23H=p7Z^|bD|GLiwAFGmPT#dDR#e%H` z3${%ymAW<;7k=A4Uvk^_xPtxg03Meg7oPAH!y!LzE7g9{tlQdkE@l*O^|tAF%w)Dj zjc2Zjx<g!z0Nq#?YTA_SG8vEm!R#qK_FPbgO3%MCKWVKCLYvY~QK)yz!vhDnDY!4! zsqTPYcvlEd?lj6dxd|RGEQg?f82OVRfRxk0f!yewl%zfHb1ED&0ZLrvwa{CG_L1<m zQBU6(8i8G4(t$|2ihu6D3H)<v&#esK$&f4g*W^1U;cS{E#zhBYV3rT;3*`GP&M1vp zhl9&RGI@!d80ZWfo9IyK3^sOCMdKdbt!P~A6#|!RuPc%ulfgy5?iR^NU_vfV>1-aH zISJ8lupZ5)e9%~;MdsfY%)SA&L*Z(MMnZm+LYwhQSFm389HY?+Jy6@h&=Vg;tDVn- z8#iRN`+3mnzeEV>$KMsdphL9!Dsco}>N|@IbQb09;tJg9-#f;cb)3ZZsv-hkr1?L{ z2z_vYGqhLYUzBBS&U!D_#1Ey3;8=TPK7Yl#d)7zBd*LcU+Thr<&<EMhtQ}>>=CH&8 z0|L)OTs7uiz~eV@Z(?`VDE_urT`Q3e{JY0!_1{g!8#_Rx`S)jp_FoX%oh{zQR{>7e zsjTDH_z#1QdoFMjtg9DNV6EZF9>{Uiy*Re(V4=9R@?-q#z{pao-Ju3-DmrF=S8nwn z$c>61@?%LxPvgBr=znK;8t+V;5*Oa_ZLH>JsRV5DK8vVTqZUvEEhPQ#Mp^d0Wv<Qd zPvJMdo`k;i|J((t=u7{9LtpxTLHg4Fzo9QU7PRQgrB)xB5m5gh=?k9sg}!v&8tiw& z7ojf&O|!0)V{uVo1G}lUk+QfwEPB~Qy<fIA(1<f}0_P-TD&$#p0}|v#NXS(9-TG}2 zu0d{Nt3ev4uUBRp?0iiXf#G=-P!9H*NAgCJmzXcY@_=K;QR4__NZD|XKvN=L=Z}f` zp2=j2H3&2($2@y`on`=d<ACerE`61{Ya5q0;%;_`qCSaAX^(pMN7A@q<1S`fcy6Uh zAd`9kt*8aVz%h~M-v+1Zf&o|+-2>Ht-&Seou=D5g+sY07n==&`Ulgwo(aeZEdqZ2Q zB@a~ZISp<0<oDc$wsh-V?0qf!PfPQ}M$eUsNeuk;2x*WQ!Ul-M5HfdPQ+IwI2`wzj zDwpvNM|}wtK1rf+2gZp&P|Xl*Ne&#osHU#|rZB-lrcE(A*zU5hkKtA-x>;BxW^0O! z`7{v(KO_vx%;;vMzIa+<Pss6<C{fdwm7MKdVbfFWn(928ENr@85?Ssd$m)(gN!WnC zUi48e*fmkjVKrfD-(q6`RS~lXBvDpiVD0&FedXkCIW&jA5PLr*?qD#8%#9><ld32- z4lw8Oq0lX3CGB~}1S^-AvB?T(lO8~dRL}M+Ou<)_$mUkHf5{f%%~wO=8R|SS9zokc zSKwx`4@1=OY)hh>rX(+xbEY|wV`(ZB0*a|vVm)-@#}o63Joubm9R7@61g|cZE9eF{ z&*5KXTGfO?b7eXw@sixJ+f~Qh%13v%j-4o{U&(@>`c(<==@<vPxJ>A>&*<5`GAjte z<HT9yi=V>p;HZ0(sy;84Cu&%fSf9CSeRdl!T{I&jbfY9s4-C`;xNU+l&qoAG*<H&o zljTi9QM46$&{qlU^#l=Xk_9tDM3%Lag%e<y@EV&hr;k$Hkp@S9r%}F#8E_e$TK$;P z+UT6V6}S(Md@qUK8Xb78;0W*)8=GmVFUoFDnKV)!OO<VX|ClVUGDh30t|zI;zdIwe z`vN!tw&SdmS*vQe8NmvxeG|T#&+L(0{-%a@_sD8BRz)skpU!GFPA1z6IB^(A*uLmx z0w)?jj!L2_$eDeW^9?yZuvZ5iSF(HJ^V9UV=6u7W24am~aIpG`a4}8!qf@;(PO&;v zi4TVJNOW>N+A-{YC6Ml2CYFOb%Yv!z?X2k%HMUl_k@YO}Av63EPtG?UO;mh&c(+Qb zA}JYOvk7g!xN{H##DVVO!_`>(+w*)S`3+C@3jc`=t?sufd$nYTW7(N2=Jisc<g_|5 z8bTtGr>BW+p&aOh5ap{wv{rW+;=D3rpYzr9$Q8~vWkii5F+S=Y1>!E4%A#`Ph@9m= z<|>{u_>}1I>6nx@mH1;r&Nro-uKVo^+_sM8905@KFMpCBrfwxt?ME8au-52!z9&GG z@d^8&|E$gVYO2%sFHogT9M~?SyxcWt4ed)UGun;tMttIFLH%z0+^!u_f)f82U!vFx ze@ocmSJRe@;+`avJ$^NH`S+~%a+PmafJpu*-WLI)avqU4+Q&oHK*1bt$Rla2>N8pd zh;NFDPshupnke1&u0nGet^p!1$k7Wzx~)^ciHL@b9Agm~$7BO3Zqv)OH+MVz9}jYd z4yE$TF34P4Gw8pWQN~Q{^c10$C3qIZ10B~>zX!%}y-xhj%hcX#P3?+#_J|YH&Hx@1 zZAV-MkT1y7!Q^Rsm;+9HodRDG+eFg(jPCY?Xz#b(+T*%c)RC#0H2Ehn&=W&`4#=oj z`#hLz>(Ko?z%~n4fwWp#cPI*RB}3&h-b$hm>MUW=v2uvKKYHctDeP?+ameZd3Fa+F zsB{0w*L2(3=zcRt)|b<02LH}y8lsR&O(N=rJ$#LQ$U@E&(LGLChsCOna>5aPfzN-F z{5dX*q7Kj3m9DIondfS7$2oyCO{ko~1tzvDY7;YA=?0f8QE?eN$R4v}vcA7y$1)QY z#J(0%@CCnK!>WxB%YQN;|C9Wo8jv4+i%2L|WYTm-B;xq=u+YUX2v}iq{pvhu>>>iG z(2;joJHa|-3UoF>MaH$nruxJi@je*`)nG^WP+MQ7>4Zgiyo&|@1q*S4VX}BJb#iyg zvrN@xw<wRXIf_G(t{CBwvld6HFut?Lg`C8uFt(N%$2K1IAJBrg-EDM1cG!W0@Q9MR zIb5vhib-c6LtjcFL%d#+M0I%0<~6Y$<KNvsH^&ypkZUw^b8Q|D)o^SRg@5J(^_1wI zn5<usr|LeUkWgG;7=nv;3`MD`FAjx!_*OR{0Jg^z6-+w1(+5T?9Y}sCob6k^Tk^%B zMh_pcB3Ju(O}C1h8j#4SQ1}Ah>h@T<>_oZlpT)E&F{KAU#V$Jk>zkr_Nc0eU#hODu z0T!ZveWcBpm=kz(gwZAr9X*#2xuYdhggdLn3z4T6zJ2ap!tT{~T#moRZj2-3qUo*% zqdk*cAl$+Aq;bl(SHpg5Ij6o9ZESmK$`<FsnZ!_Q!BkIz-QZAt_LfR*UUuFJA4S{+ z>u~#1!&5a8u^qRvv|f|p5o8haA9ZxG>a~0rR+=^*9)Uf#fQ&^S#V@#nOCCN|Y{oR9 z&56!g{Fqaigt<7^KhU8Uob(hUfC6<+;nUJ{HKBOqzc>q5R%Gv^)xJV?$|iB0_lP@q zOFNNaXJtmJ<dINn%c5Q8f3D>|>pwhdZqr}0S^sfE_wD%oFZ<1UVT%}WoZRTP5uoBD zy{<_N4$5xMJWoazM$1@Hubb5jl(TQ<j9R?aGoTxMH+y=EXUpPKVo$O@e#Nabl5Sd# zz~oq`CkXH(x3hi8@dD@dlVlXT4Noa~cqF2p{<<+cvl+(~%@g`38#Q<1Kc^trnUGTs zcR3WBK1bm0zFPf^i}cXGe6$F;dRAD^TK}>Q_AE1!$--chW*ALn(EtKt_Fp(TFN5$f zm!d2l6u6tD8H3G_Kj7ntp0%;`pCZUV><-LO+i>V$E;yivj^>*CIW_0P0TxywqaRhe z@R7V5<d86le?^tBOC_>6`DKw}VFs&Q3aDD`GXg~@oDcAOwEBb2qC;$=1QA}zoFSS@ zUn(4gHm;HU4tLOt_~r?`QJ>sZ+Vz%xa;HL%#Q5J5v|q2z-!~x#yg^_XC9hiT3t%k9 zs-BV8nQR9ed}(x2F0w)DVZ@p-%PHQk&7V#=#e|E!yZfd`xUx|D8y=;Hr6w!S$i>h5 zuwoS{FQ+0e2!7?H|J0?kuX%kc`!5b7IE?*;)o6vUE<7CF`}$Niu!wR{7{_OS=TvXT z>r-LwBEy5u-6dbw{72}na|xCO9~y5L9!7OC;Pt8OU6Jh9r(VWS`s-7n&@@nZm=S4* zQwr_QtYqj%G0ugYu1DFl`j1p6;WAO-K#eUXuzXFqc-5Rk1MtxvDVwU*qi|<Vq^vV@ zr7CXXsaD=nUi+c9!q^sSlT-VsG`XS^E2}5~wOkX543JEv{mDUWPd%lXj3~`6<s1X= zS>D1lBH*l$5hZGhOH@{BWb599iHnqqS3nIHN6;n+hQaE_pdH+`=Y)0-AcALbkgcX^ zDqz2C2LtIkW22Pl80No56DCf_aWJ2$%7oI7;E<fbY36x>LK)>p;W&heoTLv8$=N(~ zl$8<A)#|r1kE`$iU$jjdA7WT{`%cI3PF~vyT8;4g6W7W2x|$F*C-4n<&v1or*U6S? zYg;%KG#BZ!8(bS++zr==jo2lkptoPPxr@(MnHsSvNhd%$U*?8dDwdgn*13l>S!e<o zSH&_AqvP)^mfVkI<s?FV#Qiyyk$?~R(L=K4)Oy39gprXmC{_vSk6puH$dVO1l^i+0 z<;yEZ4(UfKgesL`FA15Lq-Z@4MT{dXr+iJGX_Kn*(7YEx#PD+hbDT`Uls@{i+CPT+ z?K9ec=D%$JnY;gk_8<G~_OJOb+wb$K_U}~Y%^hf9mE-oX=7#S<A#6GnbO*<0xbTSS zDrk2ti|tiN`-6k0FJ-CsVf@7Me!b>@p0$Jjtv+(<zXz>B)Uywlz6I|Rw%7{|jMEbl zmtW+r>(|Gd<F1?BC)3M@6=K6WR&|his$cPy^hufXS5@m8@A2?xs_nMFLL!F`aW1y` z&)Pl1{b$oWclgiZN>s%>LUXDUty4uI@|9e(0^77_a1N3ZzC`F_EEfl;Ksx-InrJ(D z9%oJTV}89lG~n5}_lNf>9I|TK%!`zTAKdMEuqJv~N<K`<7qq7r@*IYMrj+{Lnn}`# zsw=`Ts@GK-<#EpcQ+caBtQr5KlFv41ehwBu@>LXI8>?seN-kY7j|eo=(*V2rK>>Mg zS!713Z{Kcd!c#zi=+nNYA->bu)tRKMnA<<%D)k-cqWU9V1T2RizmepIYGNf#r^?OM zmrEV<3RuXx5f0z4%ywq7peEspSvN!?daqoFiS*{rE4E0FS5hOXuW<KI&n#Q0=PaDk zSKZu>Y)Z_Rk{7D`!NCb|K%jyVausyCijU2{+J(c**;l#<`&#g}%YQnv>XM1Uep<P) z4WBL<dU1zV_h-f$8_;V+UWCdV`-d)jbzc#jcZMG@^E%UIm5GYuj2?8JaTyJ+P+KY& zfRHN^Dw#rV0v`Bxcg1z4j?BM`Hekl!m&eF2-d>XMOItEX)EggYOQtFvMg$!w8qafd zpdXkz&<AkUG3_wg(YHi9+9ujj%5MtG$D-h9k_XXXyiF~QpVG7<lHRnE92{#*TTLyi zr55?Klk%J1HFc*AU0U6Paz-FTj^|E%vI=;u+LAH_9^N}<3@gH1f@=71+6JoGAl1m9 z8CS2pS#oxwD&0i$58#DFDTFu1N~j!~--H^tyE65dR{JZ+w1_Tj2*l#+uW*CXr#@!W ze$l85gO3rr)*B92QJDF(R}W^s9%R&G!+mtM3hq-kmOey&NX%K$GU>sI2*X-%=98++ zOo=^%w1$UG|6X&Z@WC^~ao=C0q8WpGsD3b0i<lprtEl<WM91{s&W{$GAMO7zKOuD6 zjn@3UXwHrRC$pn~Q?v8aKY!NjjNtV3-^>n+$8#yuBIo16)xI$edhl-M136O*PNs;! z<qa#X;nNTcw=!wyATp`1q-TRD!JVR#oyDy`-xED;4Qd*<ke2HCrkR$SNK5lfG}F=& zX?D+zW|}>bmhQR2OiNFs_3&I^ruDGWV60E*wq`=`rMX^<61zeE=Ykb8|5vHak||FQ z{E3aBIL?0-o~Q`+gEfh`3WyPWOahqU%g#M?E%G3aIpR-d1htAfv`)A{?gOY`$6_&2 zVZ2viY<1O~ZXjcY{BdbxPa}tQ)_iz|Hzcr5|Nb;FC;ADxD?H?+>ckxom#e4Z`YPGV z9tU?hoL<1cuR((va{&~ha1`T+86e<M{4!N<&fw1``Lhv>is0U-dV@T$)OLagJ6l<0 z8(C#L#AIQIoNBkz1&o|_<8OEX4TuBQVYdbQ9dHH5M_sRzBL59>4Q+xprU})<omW^+ zhODqQ>5RCA*{S<KIK#!}9j=<Q4J0m=KXmi0VbVjmw^h2oAxEg31bv;glP7Um5ns=A z>4BDZ{tj=UGar-v5x-~oJxvd`NPo7fo=IQ!^R`(Yj?$ss^y3|V@kF#~Gn+6Do8I=m z%!_y;YLs3!N-rB+#XCJEw+6G1yOzbyr%CPW0n~}B*kUY4F&WH44^Cq4p&NB#n-;J0 zzK54cHSKLodkZ+uv^PLGnD+KKZwV<yjZF`auEsldox~RpH}PjtV%z9#ZW~`!+Xi>8 zKWoeQrox<%3!S;DRGfu5HvhpSL{ApWuQ&*^^qCex-W?;zjK+VnUzDl+qCsk5d>>^l z{=5Cc<q!S){UTF!=6w6bFJXb1(*I_^@C=Xb72Wu)&)6@_`4Wd-*7k4*xE}e#Irnj} zClO7n_?gNRy(^SUj@3EdaZV+efeTR#hZw0#NCMrsUN`PQOLKpYL|*GVj?0VV@>vJu z+%ckZ)wm*?t$EyyDdDfmZe{F1N+>7I2I^6<>AA0~>Lo~PY<~4%NgC1)WZ4x3Yr&x4 zaBNRcbG)g(>y}_irn@+*`3F-Q=d0`zXHoX>s&~Ctv8TC<F*ORga2W5>${P@t>o(LV zEs^CiI?4DS{GQEhR4&wPkNi>rqF_3#z$-jq@>D|ssf>;UORf>=i_z&W2t!bVgOEX- z#i2&^oxpRAf+q;O1Uz=&u@9Q9;6a+h9maOxX#gHTJE_|+m}@={JWtwGgN69aKOFg$ zc!n+xyS4GhDzpjVisG}{f;*{Ru8!D_X!GS+?nW^XUD|@L^2Yt0k?P7Cx{8d6sRRe} zjHr;&J5o{n33Ytp3Qj<K)QKx@&XEN5_`6z=a`{KJAK?#qjm=Bp25Wj(NAhCwtl-F= z60^hj#9i=i;Rd&Xwh-3z7$%|~uO76c6zQmbM0ksntzyGeuvNFMQlsMID5u;Dw4!Zt z7qn1N^Lr#Q_?U#Ru-h4~lB!>N2dUdq#Ck(WqlOEO#}=X0+~t1OoD%{yS&e!FP9<+; z#tILc1Ggb^WrDuy!I7}jD9Vq!3O1mhAs7nsF$@8Uk9%eTZ-K!3og{dV#^7yL2;C<A zupu{WRq(Eq#AJA9D|oSxMStC9!P_SKI)V4C$g?JN(y-O4_xrBm^+=!ASICULLVXnm z=d)H({mTSswa==JV?2{|9B+N*B+0o$HlPFHS9ub95x6)>FlQ~%U#<Q|46P82|D}U} zZDI-~&-_wTqg|zA59r;hjGqcmaOS&CB{HYQ$Gq*xt6~9SRyE27h{Z(YJ8Daob$TMg z1<Mn$#t*;`)?;;bo3z))zZRaQJ^7_QENFQa`$O+m)(U3Ixwswdw*FYQ*Q!Dsd2l$` z&eksi6vPEM>A6*r5-cKwj^r{_^!(v`w@99iY9s>VN=esACjHh)x=}p^Iy22QA4xWT zLA>z*rkt2-1Rd4#(36MxJU|y1%cx`RI62po_{r#0>N*<9=h;R9B@Foq%Sh!OC6}eE zK0mEW;?slA7u+TVO!^?UH0RuxC1C&tGd=+{NuFABsD%Wf9&#u4(M$|hbD3eK$0w-$ zVp}a*7l|Ox^$>*acy*C02vfv*dQQ|484oPViUroI_U{x^H(v#ZrirBLArXB{lBb#S zRD`>4t@c3(1QN_Xl2R%W-IZFvBRX})94FM4-oHl$W`L3En6m%&WM%(YQTE@Wl>K|g zWUc2c+g;heM=AT)C6xW!S>x1ak6g~*xU&BuQTB(7bqXC4_#4yrU+IRbG1Z8VW?$=k zGp6eAJ@U5<SuDJ#^G!sdjNn1N0N?Dt;5odC9*UX~pT%cm8MTt}H!_sU|2pPcwERlt zf9EadsQf!*fitWFWFQeFEBgw3J&0C0Q!jW+x1F_g$!j^CtGJ5JHxav9P*h(ME|-Sh z6lI{PKU2WXzm`<7?!3rVynR+LBnM&(Fpxy8PK?1tpL~(K_}yx<kO1@wM;SD&u9LqA z*G5WASY5Y$qztv+7pTlTkXqe8C{bn{ekDEfC53<I+5=#o3}SG>daGp)P{RkGXAXeM zcjj*Z$Q<Kjs{pMYbxZI26PblO<2C`Wr22L;1plE$fY>Czk}wFEEU(?|0bWU%1ALiW zwK>!KkxJcGHSl#h)6E*-b=Cpa0Kme0F=7#O-p(_j-R3e?>;gt6+Xb{a{hweLa2UIQ zPgv1$gs^a}P$vH#!4>ATA9JcbMF_nVB@xO9r}9|1Q@6eED%j58yNxwYWln5eD8{o= z5g{EwC~;zi^Tw;coWpF_{vOy1O@%}Jd?0f@iOq2U^5zUTPU#m)2aT7^pufTNY<Ni> z$Mrvv<W;qKFYrt2Y*OiB`XX5`T3Ij0vudqcEPwZW)?no+XpiW@=T(JK$Gf^(AGe9U zV=-zLt?pr_A(;-{KQ@UD)jf&Fy2voCHic3cGfY$<KqT1=cfcz|9VHakdM&m^@ShYX zbw&t&;Zq^(`Tj(aBDm)Fh{U3fGfw$FK`)dsL<j6_vVCI`{YAft10if6)QS8>hQ=MZ z6rT>k-Vgqk=b+>03!HZ^RC^U$j~w3{HUHNrCmbbis_(Ydu73OgV#`5U{?m5PHJk-K z6aA-=S&pKRE0}#DU%0e!Yqa_--yUpDeOlcm<WOU3<Rw>dkd?nftG~q8+3uN8)2ZZ@ zZr|x==ROb?8D_UaSJiaxCXEO~{H^H}iKSL2&mvOPp8h#c;n(@&YntghJ)-Ke@ZaPm zr1?6LSh6-#YIkaeNG^S+kync3l0FassL>U4-;~-7P%jM7-Dy@<TDL5%_Mm7^?u^Sa zuZ*~ix4X$Q9g!P+d%Ap`N4(dHB=bv3l8Jw%&uUCGn`z-6Q>_dd9FJ~r5o0_=6~oK{ zE*s*7IqdgS*!m|85Y_G~U{^}s#B3w4t~s<#`eZz>a8{y5t6db6Ee5@+dZ}Q)Z-x9_ zF>mNn^fA22-xc#NT-v4H<nM}k=}XV@s{*i#cOG9!#tQ8jG4nDth-^FqoGR2ED`^+w zDl6#)zHrl`T2aNvXI&TGE_Fbm0U8oPQ4hNi$C>k#))uH+Rd{Ne59ZPG8to~Uv==m& zpSfQL({FT0m7@O$T76@0o+c>|iEf0JWJ?dG-`?LW2Uqa4f=tH3r{J;HcQE~mFU$H7 zor|bf6m8@omqIiv>;ZZ3P$*(l9_$4i2tLIB0P6$CQ+yncvhb~D7;gboXo!3?2>|}5 zUmQ>itZAgaevz39uraU*6DZ#RX!^HCB?H99r>@}T@_Q~oDlZO@LjmN)azKqWlM{Xx zOv1^65sEqvz>5Jc{G|rW)tUHoX?W6(EkB}hz<*vv@)56Kgt+$yX-g)k73;M$>;PK0 zV1VACrCL1D*D3hcDM#wRE|Xe4_qv1Gny!v4)VpGCx*lzb=qNkzGHN^J`)+i_+#bky zx(Iw9T?23L86HnNi!XgMZ9qKjOeEV%v-8zykr{GCy97k6?k7k%j|pz%fD(1|RlV{8 zbvs^mgQGA0S&HdB)Gf;VhsOwXxKl!-KBo`N65-(JSy)aA#(MuAZe(~e<VuF`)UH`y zM#t#RFt23n;Y!9a->LShFL7TyBh9}jBeaJr8L(}8xstIaYmIe1A{e=V#H?e+nn+e? z5BD!tml+ZW*=(ogl#hn02ECTb4_{>RqRE%Gl-JBXcss&tE|J7==4llTMR2H<FJd@U zae?^^vRm%C1cz?eE|zi%;bWhhIKRB!%m9@X%GKuiq_SXoxx&R5-p3H{X>*s1ZI8k9 zyRJ`0KQtGgiGC_Cj($J7Ne%XpQph^?^0uv2CAMQVozc}ly=hi2!~veGYeFes{?<yP zCDfLsPjB$wYRBZD?Mlv)RaZ}MNLlmKn=nH(I+STf5p2}xqF)KzjynNp`K7=Sb=+90 zkT{rru>~ZD9@eT%syr~j@<sZE|H}_!V>)gz6Gxr6j(!0xo}eN(N;Qf7P~a`tT6I(L z+Uh=H@q(AXbv4ZjqP22c`m@00h~J@ZA1QGE_)7)ua@tvbIgLgg0fm16^lfPyfX)x@ z1286^0(U|J+!7PqIKQLp<7Fii|KqeX6oEw=d6!r_7{|5x`*4oeoQgntNLkT9Z&^k0 zDQ&*&5*6&(3pVoLvaK^c0>|q^QAb!UR=BgM1RIw|?~%xiWckl*{GqbvpAc^%T(gu@ z@f~j4YHi8Zmu<qoySTarCs4>;qd6C17+rAu@hc+NCw3$xq@Ljvc%1k#p;Z6=dBmm5 z>MA%sM;mE#6|eTLh{&xXyr<;ZOe22ge$tQCVE($0!8E-A|5D)>_~0c?-5^5QJ=8)7 z$266=RZ-?a=kPz1{L$QMdtt*@n_jm0qw}g$xmeG3$Hn?<#rogWtBxAMt_1J?I6rVc z|HEW1%V)TpONW47Z405K=4YwaXN@FdU-Dyxq`lkt;j`brz-PnNXDj*J_7(LR($ZB3 zoEwl^&ggv~{05%t5ueU*eA9eJ?!Gg<lIP=E4mz+Ij&G~<qiDTm41QESS8`GEDCK7K zw%*Bmn6z2x^8OK(*J{m8mut=2kPB{Y`qQ7$=x{ZfKG!h&xF(CX+s;O{=SWy2?)P%B zWs{8p17M8x;4p%tw*4B|djs`(Zi<ZhSEckX-8I5mL}ITnK=})ZI^JR9!OSCeEu@EB z3-LhjSLWV>3k8;?x*URIbZ*foPbAZsTxHy6-UCs^VtHdEPZo4MZ&CQ|zb6|UE}FEg zr;P1C{~C?v*`z;CWh{f_6a6cW12uo=)t*8A&Z{sXldH7!OF0hghi|*AhOE|mnv~l+ z<vs8Sf77eKB%aO+S6lK2_}KpbrdI#ytl86TtAp8wZMzb;ZSn4lOn`BzbOL|~@-2Q^ z7+=k3skB`1nP1+73%(nO=6AX$PWX0Kmf5yjUify37ru9}s43iFU^Cv343hO+xPi~` z!G{aJ8s&j6UP?Unv71=sEO^cCTb)-9G%ppeiFj0^^Pscp{1EA)>FKXYdhYFGc{xm^ zWmOLqUxdi3l>b5hsjS&MgLYrgK33T(to81XjCHEuaOKEF8j|~;J;Zr(kLiEV-<dVL zn9h&#cS_gSm)TmY%FzQkjWzD#_mlh&S`Bw|LWui8KI`s&5D}hoP{^#&_4r$YzPRKv z;s(z^BCu%nJ;Z_N#nOMGO|HS^R<t=X(AivSO9``3(Es8@pr^ds!Zqf5-|B0+`_H8R zef*8B(tq5;+I_g$G{=B|Xx_b%o9Mkc422C!o?vu>0VS8Z%n?}C>c_Bl?7HfoG6;i^ z!P;7?9Q2<cPhM<oOEZz+FNA<KGzk<?J?kyeA2C<)AIi5@Xl`PKeoKf_U!b;DXbuNn zwWX+y4-2r1p-7Ip;qf)9yhMK@{F*F7xypnmg>F}wP!(ENnJ!K_&sC<CKS-=b1VT6^ zid|(Yd@hk=U1iFb+i2L6a{gEdkSs(oew9ZSjdR%u9*i~Q8!dTS!$EsV&lPu*gon&i zr75eN3+GtYuf9&rSU-Em3LlwCX0MmgwaI{^xG7|Emf35D^v?8MES9eM+>u`{Uq%(5 zYWjEk!tmU{hyMvYD;b1y;F&$L8$3U`G7irt<Rrrr$oTZ|G|GM&I*5t0Zx6@S<Plnz z7$G8`8m+Upoo|G$`!q!RgjY(8P>%#e_bZ6xyeO0Oh2Tky&=-T}H!QkyMo9R%BzR_B z5g(zA<Y>KO@L(1DsR4pJ;e7jV2MDC*7}Pp@^ZABI`!q<6!fYjm=!0Q#kV+LuiM6TZ zmF9STG5F3qV4n-$j76Usvdg-|H!cC+3*;ordXnG^j34nLzASb#wJ+vsb(gcLx&!@R zyOMWT&HrQXO~9k7&d2|m$t0PCkbts8Kp7QbkdTcKhOh<#4jLgs&?sm!$xN7$WF}@N z5L|<x4HXrYYFf2LOKsfo`?DolTR~ByrHXZnmMU7*xYS}@n*IJi?_I(Wg5uKU`9BW4 z`P{Rgd(OG%oO`z0F$gAIc|DrBzf-lE&N%mK=c`XuX3>rLg!z?&_nglx)4%qS>I3{w zh_k#6FOJ`tw0$QlWBfZV;jLn4>)@4bp7HHT+uIjhdqx-gudTV|b2j9SvdZNe^^)&D z{E=XleP2XVPp`h0<0{Hlr6z5EqOUI<N!zJ!XRIU&e5~~x)-m%*PNt0Il}}FhUH5lx zpzewE`oe@*PUHUIpD2%z6~=tr(U+Hx79PQ?$o}vl<?oy2FE3?7ufOiF{GB7+D!u&4 z=b}lQq#y00@AyHSI+PfFK5j_L0@fI7sgZxJHDSTJ9kyI8KgV+*;LuSlrZFnU48{>Z zPCMu;#sg38E!7tio>WEaNju!o*l^r3g|ciFCk-}VJ7mMP2`?sXe{tuB2`iuTIGCy0 zLC^U0Yt=a9$~xz<kBq_LhCLs}Ju;Sy>G2_(HN8GB!7SgX8~ETMHc!EV8eI;&j)-mG znnPndQ)0Vrm*dGzYJ9fG&XBTJy_j#|$}6MQzvDE<J9f4n>)#^=<B8z28=m8fUH(6- zW$?qnD?8LONK(w0sK!7oJ!8fsZBJNK&H&NaN948aqgiSs%H?h;f2!vZ<#>-r^_leg zfaJvK>6%ly3*5wq;<-^P;}g$*G(2fL=`wVuYR@`H@`i6s?Ck01X4n4s(3?FgRliwz zUZu59XZF=q#yt4}Ia~g!FLO71mY?KmX;L4}wVm42`WSK0QZVvi%_V%9A?kgf<MU>H zp4Yd=Ka;fm8F|uL)U^6&@X9AWqQ@|Gt~{@!&Mn`tJRzE^>1)^~z>~$ofVG|4)B4it z`;Djdxt$+a{LiX>d@y)ryJx)qwEmvV)Sp%>1!)IQD?2PY;zPsLC)H|`0in_Pte~N2 zuipOA-zX&;R5uA{k-nN6(#=Yljx$Qh&VRkS^OMn}@Z1fQpbf7{nNFUlCR}>t8NgCr zNWQ#lMr(-^nOu*n2^g7N#}KR}*H@+2>xb8G2R!3H<tyT@YZvMD+lIX9-BP_>M7~ew z-TQ_9((BOL4L|;=)^3xpr96;cXG`s-mKnWv3k{R>8lo1j-sEcfXg^~J=c!J#D&R=P zYy|B%38i+8B(*-Apck`)H!J-!Exq!OF1_9%@&D`Tbv}{!hUs;x>g21_>%*%LO|M5! z?Ki#jS7hxBz)z*)D??ws=YP{=B>k42_rP^{*E{iQblWvos}8z4)Zi*HNKm~y)W9tU z1Nt$TaU_HMI$X%Wq7rdBq2xC!X|A1YAw9I0?o&D`76(hjCgOkSc^6bd*RUTu!*$JB zta@V)?Q@4XkV=YAurY<N8s2}1p;o?lo5xQ^7UYOJCg)uoQCD#I5p~MYP1^H($oX^| z+IH?6FvDbut`8l<&`r{fJJ&t4cAat}qZc;yqZ>ot8O@Fhx-KUDB_NZg?O=OWkjq}q zo$m~2IuRSPl0SM5T|SQQN16LO(fnvg<nzCPjc4PVSIv?$OU%u=*9@t{amJUNzb_vJ z=6&E(j?OWMTV^Ny_IZ{~F{X(ZH3O+4<wKI=n^!;m5rgRL+T#ecA3Z36Tw|?gXmhCO zuvPw%*LZJzWVD1kc-}Sn_0|PDKN!leJliv?;~r)Gq$&60A@$<Jzg}cqEj)AlYYP<C zLK5+TL|pp3^6RbN`IhCY__+E+UOTfa=1-@#uTElsf^qel{rS9HF(yLiSH+AL30lH; zCC%AMRl4H@IsvMhd>z_xqNE$zcZ;^94D}e_zg4w+-|q|7vb5A}T3xWAosE~W4v6L$ zN2l>N#<Z)vLJm$^w-(py-cI840%F#Pnaliy>>(l*Ch)-<&QaZr-Zev-T}i*}P)DL< zc*=EcE-N$Jjtecu)f*gf#MvUJ--FJC&_V{}PrsL<yAp@j4vE{*5$j6&!=GJ~hA{BD z$Mw<<K3mO6$Vm(K^!kV&Umnk`43@+mfvQzh$BByL^@qM8stM|Ca`#<!weL*%*M`8f zC$*k9=+E6!*M@f~98~P4K_=6xQM@S0h3hI0r>Cv`NUn9W)%)|u?^X3(=3UP|DI;<x zaK_fhEWX}lL;1t+hZOiB1%60@A5!3l6!;+pen^2IQs9Ra_#p*;NP!<x;J=UpZ;tLz za!%0XM*X_XT~Xon*h>~wh5f-mPEJi=b+x<7F}}ne4A|ZFl7+#5x5U26T~XsrtF8%! z%hJlrCQr>O&zPK@JvG~zUhbZf?#Y}yx!mn7n^fkWR9-qceM;G+tn|rg75>s{clDaI zP}q|esxC_ltqGK+RaRA&VG;_bR)_q7u(vwkuCRNntAo`!cCV<3OiiHL>n`)TODnwg zvY_XC40yGBrMH@pzrR~43liyCxf>%T7kfiB72&=q8L*ektFG2lvaC873URNMIXR*5 znhI}DPC+$^F?}qV5iAo;lq+&_mZ+Q=VZE%TIz&?CoEco@Eeu8&9O94eO=*yHU7eFN zH@JE_Ue1j4NJ96M_Lx?9-PI$PO>>!MPVP`P@`YwQvJ4rS-J$sT+_hvLnaMpa_Lh15 ztH>fX$L!_R!Ag5!;kh|>yA)@$UZxF}yZutO!a;ke%Dp;Z5Btbh&v#9G-IvOshX`p3 zd%#`kwO6{=*aN{ZMJ5n-`vZ2hc=?0X_CQTVg}ro5*c;L!Sndu}=&EZ1VL#6F!WXZ5 zRjp>9y~-W%m#rlBJO-ZXU{#tgSm{l3S9ojFQr#g>d73{E!j}rID5YhjW=}~?PpkH> zplC~(C&^a$!@io*)UsgZ#0+m)S$5{ssh-lQ-ZE$Aq_hh6#cPW3AnY%jn30-=Q*q%B zRQLnlVlm|2OjrNDU1|G6yRrqAAZK%ZEEE}qeEe9uG6%h*eU5VM5~A1c57`6WRo-fQ z$Qzd2@dtRm{T}TpCyf>b%CIE&Cl@|<$X-?LUF8qfgeun9OTFHJy(;JrQ89RoGXI~d zJ%U6?QpRMOd2WZ&w6sGxyRbv~)7jef(Wb+9ErACsvWvadLE`hDP6o9S{U52z$ctZ> zb|^0)XO(p*tC8E0F4PYAbu!!2q3rQ>D989altScY<gbY7LZr{n8;~ZUxZ1tCn5W-s zT2VnIR$N~0H<d{pX7XTSlD5SgFjYx~Y6|%;_L?fGD~rQHlgA%A)P1SfU75Oy2fd=g zEkWJCsY4l~i$~{wC2QT))o!T){__R;f2UB9A4WT36oZk=&KS8Y6UjJz<g!UfCUUyT z^kPGY693Z<r3AT{>+kw}`-5p(>vFIGTV3s^;#}<u(j_UaDKGa{mj|mW-C>$htpO=e zYebs(VD<EwIXSBRVs{|qry?z*9rl)msXW!T#_Rc>8<XB{z{K>_%<R+*wJo99sdNXV zjWo&BnEVVzY06%8U;Y1lvD1<}<PCU8Gf%PlIOo{u>{Qby)cXz6Y;i~K72kXMNxzn= zL{iVGx5VDSDpD@sFE3U*0^g(-_<lPI{lrb{s1Uv2O5HRk#~lt<hEB|}m%2T6xu&I; zF66<Un_BV$wAms0F%{nOuqU`WK!v%YB1os69#eI&BINUz)29iS2g_<gE4^zfY4N>P zZt1Cdr6yJT=hgldzHm)dsk>|?y}B|l{q$;gnRF+`cCmP?UDZ@c#p?-CIx8wvef?4l z#Hz$XyHfqsE-U>WPla~{{Wq_tCJ?HrstQ(zy&m$zUmXloN^zhZR8<GdyrIxUf579d zqST=MJwH?ZrTdyHZzzopy1Syd$}dmWyud0t>xAzZpQFCDlm%A=NGOk83JmFQ6x}dR z|NRl{Q)ubE{`<p}I}4>rkyD?SiXbmo)Pa;kclC;LcLiO{>Kbnag@|HQRZO3^x~42# zTwLy_^Zr%!tF+^GD&1=QuC|v4YXTm-zmklvqRJJ+|J1$dFRPW_%3$>xUM{NE*n{Qz z^JUlW;6D`=?V%>2OL=u8GV;{f)t5b9BzRGg*ig3@z1E?8j<}K4$oCw*qk4CF^x<~p zH@|IHUWS{IL0q2(MG6o*()Amz-|SF|{@S4=!|BL6t~1~2P-Y_K$aZ80a<pyI(Z1tI z6Zk*>o}+dra&i{C{UL8IkC<M+SFfm%itu~R)_!U{^--33P92}giHHJ`xkNQhv0sv- zUrd+cIP<d0XrF?s9hz#qrWkKnzRbALDu~O{Jl<7l;qaRIj1=T~LuCttE*b!DU}10p zEs?)$iQ0NBtx|g|M_UHI=Y;9Ed&T>6Kt_GO=deQl6%5Ku^aX<}>5fcF&6unW4CwV> znl!t#Hw5esg}l|hPrcVe!B^edXU?#vFVQXoHI=2*mb~K!?G@C=-c<X7a{HQKO|^Z| z5<7!274%8<Ha5gXnNRm5#a>Q^F#cCsvqJYv9a`yaj~Py}duy>2*6Qa1B1L<r*$qXQ zgernzd0#)aqeHn9c@#OZvqPERJ2vDG_``nk`eGS#sHzD|ygc6OGB>>of0)Xak&5z) z;A(Ab#Vg$!yPEp;5I4dA#cIY`7?EHclQG0F4Nzc43SN<9URs?QmHuE(ju?N>S%tr3 zkux=0%^?YZT=^y)MS0-9#c--x-|Jm`?zv3LKq##=T<!IyRl2LvD3{gp^7w7vg8KJ= zmA9<e<GqMcV6Cq%52SHutU;D+AM*R26I?6bNAqmt@?KV1MYmB#w~TT_AELTctz3*J z<=+@TV<1o++|ypjv=P+9AKPGASxuGS>q%YV4Hs9|gdO8k=}$|hrZNV{Gw$$vQtX=6 z_*8$WSbFh}@rQfl_te^_+vnyM<j!4Cc<%R`{aWz~FzV88)#LS0xA?sBYG9u+gK@=* zazi=Mo^g0oc`r$=@CF>?#kPmZ09A3gz5e`FBcX?d=l|s=F5q6}U%{X%$+CnuE150{ zQ;C)FHYH=Zp(|%~DtFH9R4zq!&g@jjw2rnN%dszE%7oTb-YM+!q{X2~`*=g9Zq`ef z*6|yw)q9#573B9^vX9&XrfGF>T1~)Tn?{XDG89k~+NGDSMQt_1$E&4Mw%1fit5I@} z%)u~10!kw9PkX%k-j{l}+|mC|Hvc;wEb47iuHw8-<tF4=U3!)uyf*ZXhOguPV%&Bi ztw_xIoys6&na+Qr7j;3WG77O5YjT^;-S7>h75P%v`*De8=O^%9{n~J6)ztwQMy}A+ zTXY)sBKaC-?;<x5{;Tdz<sIZ-h`F>=8Gt-XxQ}7J8`+Dzha5m&tmsr)khhTckiR3J zBc0z+3M)I6V&p=k2B|}?L2gEVj@*SjfczHu1M)QTJn|~?Ch{Kg3GyY<gTw?nl|*D1 zGP$}_nF`NB{K#75r^rLdv&h>>J2E)fsf<T*k#muYkPXP)$WG*S<gduv$h*h~$lsAq zkuQ*Tq#H3;bt)r}9ON{l5OE^`<PxMF`3Z6-@*wgU@+`6!`4|~`QKvE!S%KVuyo%oY z$RMt#BBjVR$nTKfAdjr<RDzg4q|0p)*M{EFa0~8!UDK)DkNh6_6Y?7JHu7zsFveNE zYR8E8<g_Yva5lhWH8)sO;ZeJ<RqpB#z1o1*e@y)k){<*NS{13rfH)oA)M=y2sZ6?6 zheO5Er*({7R=RxL^5wM|bC!=wv2(p_`MC4@Y4~-gbipGXF8)f(Ul)!V-mI_mqEC1= z-^6m+H?e&AH?e%?S6V)*+x{NBn10l;C|!P%n#Id9)6*|se$sgQ)y8<dY_^e~F<#GZ z2K8r{$M#Xj^ido3j+TkK`y){|{?Egh2r?4DND%$TjQbv_$4qt=$<Ih1o2E3y=``#c z=0@M*C{}KK&sE0JztTj^FBNHT*^2@dYmAs5&HVfKJ1-F#^CQ0O6jZpGOkj+%v|4(A zDfSgC&sexLKi^KL5Fh-3@}Rt;X`bml+v-$%E-P2Ubo$7z>igT3<=fhojW8eC{b0MI z+^2~Rbqm)`=pB8ZnkwKZ)<8&6`JW#j{3hA|Zys%s^!m2#cK;&|-|3a}=!=646s*yP zi)1O9yj>pNI7hzF&a|iZW8o-YXoD4=Vs*BQ*{^_o0@DesLb6Yv(fitdxYy!Drpi<o z4DP8;j`se(#=E1Az`-~hF*w|3ro$OPWI(WNWwE@t7t4UeCCdYLe)-(MqUyymK#-Fo z3I;W5dHbJfS4S;o*dy;Ur5`t{)4q;+V}*;$4v$d4yZT_tMWpe6`LT%@GWg$#$-m>- z)!u5=*#UbQ^UUhVtqhdr*wsPV(3+4ell0fhB&v*L%F0IXzkR5dV71P;5onqkCcW}P zX{Agi`=$29^K$cY=j6{jXYqnUVZq`Bi?}>@vA)1>i8}N=-y>()e(U!YV_|GClveIZ zW8$1aKv~@OJ$EuHf-4xP&PvUgqP`qy<B&}6PgGa+8sq;mt?sR5*oHNcte>plHOXVI zWQdv-f2_=vl~b(DRr4_H^V&;Rt}14JJ}mkr_HwT~T*J%P_uI$dWoad4rkE*&VtKdY zE~chxHxXe(lKr>Bl}0b(XLM7Yx}Kpnx~-4*`5o8iClzJn&#-O;F+%?tYQwIf{>2e~ zhIt>Fjlp_D--xH7PF)eGVbGsBAQpu%nz_<2&}pn2mAN8Wfg7MF$1}_d9a->O=Jm0( zByuq~%S-~=d<CO?EDWHW$pnwA*;VKF-4!zR!xB?<-Lluis?&0R?Ll+nepR}|_FRvr zdSNh}yNbCaDTf8jKl(!<hR*Z60Y=o9um+~8K=nkO!IY||*jwult1EA7LS<Dosb%G% z;)`m6VRvy&NHt&W?lm{=kC`)d!d2cQMCAQJUO|3!dY9rpqf5C0xea*)c@?qccPXoo z+mRQM=rg;N0J0e=!u&|m5n<km--f+cxVA6sQdS~{UL<co|0(1hL_uCE>Qb6Zx|G4^ zb}3Vl667-E2_*KsE@c*SH}W?maT#`yJCJ51b$OR^2C@pd3E77H33>1AE@krhUCMIg zd1NSIJa|r*@>i~};<^Klx}Zy$i<BTgK~662Qr03rN1jFAL!yY69XSK>Ay**^etYpN znd|?wbP?_=NMoQ&SyypT?yu}peu`{IBK3cXT150V>3jgUqSv1r!_H3KuDBC_MgL*k z2_=k3b5R@qHFGWY`>GwdJq^hY9+Z`+e}vtiMd)Xs7CQzb?Hl?h5GT17w}#%4>_?i1 zs=JiTaQ`yrB2EAHDxL#f47*<4Y##bo>DPwYy}J6V{C-}yGYR*GyZ&hS@w9I5Js9cc zQ~VhcaSv0u7W3s$;?|7_4Zk1J?Hc~>MXl(1V#m<$%h7!DO7z5ULnJPSzd|F9{e^4T zn}a{bbzgeF!mO`dQA<4PadR0wsZSn=d1F8R8F7#F&(Jd%X=YqE<JSd*^E%<Yg}jU0 zKpFi|r<kRZK2Br~aw2ku&dcF?<j05~xlQLE;fu&?$WG*Aor4K$3Gz$i{~-gpmnBH) zD#{`9JLGAdaxJnSIi{ApMoN(iopLR5EwZbwOR2h?bX!Z@kx!7qE4q~YD|v>I53lM{ za<1-D&O*-DDc2%l#EPs$eu`YFQ?5nsLN39t4af`YyOai<axHQf>euQC6Zsp`fy8Xk z^h7_>%us)yG{Tjz`-;Rx!s@GUg#XI*q!DuBP2?SN&y8Kmv75V;6A&Acg$zS~Je-Ny zudw^_4PD9s)DwO}x^kWSGt&OSF2$o$u0@uho_8DV9`X?Gs&DR6x^VM4GMek3BPqze z$d^deEnUiQF?(*)L2=^tCiFhV{Y%&pvn70;Zsl`b%KSfeDLwEcDC+Dzv{~O!Zg{av zx%tmW=dKugujBtUxOoz>a{ccTH(@>Z9%cA_+Ir+R<O$?1<kHqIWh1f`xmBkReJ9uR zkn@nUbe@X-M@T1fEPC;XaQ<su%9}0Z<?b%!Go5lR68k!N^BK=4a&ug_@<*L=E%FZP z4&>y|yOcWAXX%t{k;_nLe?fbNEcqw(fKIs<8TKX5ZF09VWcW9iFL0N3+&6dkZNlo$ z&86QW&i(n*SMS^U8`jg}Z}8X=-O4QFbFO1xGV&|ZYrM`=;dEpn@&WqAIxkG?R>H{T zNF$Ozsats%v1fHF*H6Y?cDM3}DVW1I;XBA@h}GGx3`NEwQ;@kxA>u_=AwNPIkh_sb zkv}4Pk-sDDNc_}pWh9b<%s>_*#Yh#h7P%4mCGs%x6!I$aKJo<;mD8;ZMn)qOk!i>R z<Q&9{R4nUO9z^a(wj=jk(5*Bf>BZXhUan1C-%!%6+={dya=jgS3AxnWtrV4ZE7w7} zUd{E*$gZ+(<q8jJ>(#Dr)vu37osVol<l2X<N3KVHioB{{{|3H@+~ez39zm>r?fMO_ zJCXR6-HIEz3z6$9_3P3*x|M2V3-SOW>e@RGmF?&$$UyYPd<slJ1|uVoQ;}JBlSW7o z`4RF9WIOT#@;;&<!|&l4Lrz1Ak=4lc$gh#dk=KxaAhGw7{>T($5wZfg0=Wfw5P1f9 z3;7q4bYHhJ4w;3Vg9MQuA-_PjBQGHDBMRcYzgu|&j)jre*S_4X+=;}!(yh!!Uf)l7 zLf%5&(J9w&M_h~gU8EHe`=S>42>As0R9Alv|AlnuYQtVPYSX)vHzWp$LlTfA#ISP= z*F$x6G8~DVpsNi#|9|C)+~*i%9CE6D&l6#~el7PsDdIYt>#4eWdW8P0i0jC-nuGom zkG8AQ0zXFH{+)W#oyjr&+m4DJVI_jeSj)<MgFUZCTOpN`!#MSK4oJ2#tAmG(OBg>{ z0m1Bs%&>X<tNb3euC1}lmes?D%Gq`!vk>Y$hq@N;J4cA+Z)L2;U?Pub8ROhXF~e$D zJ(?-afAgGH-vbP^jaO+Q_JF7(wFkGaXlt06R#bP3rRdw^`?~KPc&^qq<{h35Rg9e# z%T_D<iLBy2qI*5Fzil4<FyHpWeA|C=zU|*qP7kiT{qEkgxLse?{@wjj>phv1C}Y?- zc=RVitngP>_?hA8-N37!l_6`0d#m+``kY#_tcKMUUUnGDTHs1HOtNW0+Y8}Vt9z<m z*{CM<Jq?1fI9V*pSpC^7h0Cp85n_VHa|R;ktVk`kgkk<FFFP(cGh+c;C}a&p8tw~n z3teu;+ZR-=%0{y01jD|?jMmS`UY<X+GLMDNbAp~V0S-fvJs+}bPJ)(=JuJmjPyTQ% zI&+@1O?(ATUE?I1_!lmkSG0<_$WFg=XrjJpvPqmWC6!3J3^{`1;Fj0##jEm~fVvo; zOz8jEklZraiK@;ol(_>km*G}**gR9H-nBhnc8uDW=rbeQq?@Nk-N!-}xy!k8yN9hR zvN4jmi@vqK-s-6PPKkx=<zXB28acltATz3(c}Thx+NE7>px9xn?NjvR<Y@XiIr@fb zmfgz{AVjr_b7=g`oanKTvZUD^7qY7X+C7|=q8<UFp8KIjGq}d<IYK10y&){H^vjNS z>Fvn8jNTl|MhCP#Y@?UWMRJOUwzfUuE)F)SE4%?&LhfY($<MYE<K7nJu?fx}R_B+P zuk^W@q4auAl42!a$vNcLS1rrM?1-^^%&?roe$s$9$9|?a%(m6Ao4fFrGk>IIq}P+@ zubwBHYFHWKAyrlyTa%`X!t0r7oQ5J(rfFoUo(<#pSflzoMrWZ~9u|1!x~pWi6o1tN zDLe~guM&$-<XI_XKW&~KP9c3d&!U<zb6oRTC*oNm!G+Jx)|s_{lLa`$XN5d#l3IBj z(o*JKxa4dv`)}zZERnUO5_zV)=JKrR(J)Ckve}Lj7bqi%b4x?Pikh%@G5d7G9PeXy zELm{cf<@!CWm#-2<G>AhhEp$ACj*NYFI`etJSTVV8HI~;=gvErW!fPLQi!w_sbsYz zXWz2I@d}2yT&S+pLz%wHqU4ZflU?ev*I0}CieR<6-&$Q{K$XO!q+PO)jLJ{jv|B@^ zRK>(2@nOxX=*x^{#P0HgyA{-RHPtn;cgUFaQ#Tvahh__1FtDQc@gqVjWkWl=(AmRC zx=SHiX(#(Rvw#ZLTk9>WQK!eXy>z8Dp*75UYFpMsA#u>WB_t*~E4=g%>9E_?=}5|U znU{U<o{-mzuk4;+FOYYo`Z$SQEv==7mChhHRl|Zg?HC_PbK_duQO9gKF`|$$Ur(TH zQCS_VUa7@P+fEV@d_^!=CAUGN;Fn`7sFJv~N`Khy@TRUv<+-Jy;!efhcxj|2QfIAE zJ=1Rh$HqJ`QS;YSY97h<X{mJ76<1V1(o9JJ=&RM{LFK{xSgo$zE>#~iZMN8$BxW9$ z-F@1^LVJ~;Qvme4k`oA|RiIW@gL50x!-ggmC6%KDsZU6Aj?uxHX}7FB^m+{6BF-X< zu*94)UU*n7p-(tdfy<1u+6+_@GX3~PA-f~UnhM!FYaicF*_O1U{8N_uF=TCsx|>FS zy42%r)Os>#mo3h;_0|2j((2!XPbAq|amcA9ZV%_(l!-@vChO%DEyVhcH9;N=9v(kC z>%Ek5-$5U=a`qJmpQPqU*^vgUjM;WFlWf#h+pEW(gsN1(gXH#7rr+7KDRo%isIvk_ zCg0OY^)$&Q(&Qw&!(B?F$i}zvc863y@>Gp?(CR_Y_;RU=-4)^~^ZcCT(~qAKt7;a> z>YDk7wOi`@T0c3UR(FSIjDGG!KMvG0q4eXadf)O_`&i`1{YZM#;%ghC)C0G85Cey$ zg8o{krl;Jbluvn-dAw;-BWf|0&}!$Ig;{IInIB~<C7rxE@f2#>G3o1(AvmqzDXXR* zz|%{aPLV!?)<rBiv<{yk-947^kb7=Bt#)aU-b1gysqw|d@~T~2%Ic>;amdFLQrv5* zn^Cj&HJM%$SQ+4HoGFj5zSOZdZFmaVu}ZT_La@$=L-hJ)Ahik0ekv=20eaD@4bokW z_n8Y87B4BJ0s0CjS|eO6ON?=L_^WoLdGDsme?0zs{hSB&9a+mT+6yhU_0t~W`-ZC8 zmAJ`jDYZm#QjNZHs@h9Hq=9OtcMxfFStv<jvtg3GC{*<7;fse=1FBcD0t&z91Z$_$ zySC>B*32Yb)n{PlxP!;ku^eU`n?$q%aKvoRD4_*Bc#;YoZ@=22s3Sz7stQifW6!ry zo{S^$w0KYowT_$q5J;ic9v{0}XG%Qd<9qFD{aRJY@iY~y-Q=cf&oQ3etoj1))FTC< zp1vnOMp*5e?5U|~{O^sew)1CAWoc0MlI!nt+L9r?<I}f4XspjNDAw#qlw3so`nofW zjC~cNwj+Jr*(Xxx^=_G;ONrpYl;&Wm+U?T&E{mksLN9Mo`I+hwBTIXGEAxWoYS&Qf zkMOppu0qPE-75?R^XZH%&|3WYRKQXo&^?nkgM8_k%$1&rH>7n5L-Tq&BVu<By$?p> z)UJqJi=Ox>{Sdj<n(?z_Rn$Da7qT!IUZQtD^cNX<@jFLO#X65Zh#rwVdLH`a0@=z> z2eiVwP-~aPW0$&h^<WVBbRpy=auFSfgSzxswO#>%&Xd*I3qrY(dIuHfNbg{d)GoQ& z(lL6vbPDFEyA2BH6X;>*@c`z^%WGh1h%LHwhSh~=UXOl37bjP1_H_qK51v5kVi8+} z@}LV+&};aF2aB~X!NCT0L2!w*uSWCAJB!}9_ASRGx7PZp4L(htT1JXF^o9zY_k<(b z4~D21Sag>rPh^^m-KNp&wD)#+IPD>%8QM8qNj4A9I-+0tL#=v6|3$BO@n233<w2Y% zJJKd{lIF}bIkH2J)HFr3NbFsgK}`;xQX`+ESCumKOlK}&R~^v;ij{+%3+VwJ!AP%v z)!llmK9u((_0@!ivutG!9n!vM%NlEX#k|;PWr+X5(B!mB_8=eTn|(!%yV^rtwt}|v zh#qV01s=-ds-2-3jBxoi?pVW0XQh}`xA@RcW3;N6?tPhhc87f|ySa7sbo;_3^X3*8 z%v)RxW!H>9JFE8<M9u`@ZB0!@c?d%Cp0IdzK9@&~j%qKhT-w{>>eZs^H$t?CH32d8 zdK@Hq*gKvaS6e}CsiurJP-J9ML3_!QWs{66&^M6HmR<@AuVOTQHPr$8BK5UMZ3>PU zufF9^x`SF`+vnypM#SAqCtojDbb+N4qTM<-O=yQ$J6p~()m!hwO?y2#JR^9GqTWhX zd%cda>Y1_XnG3;{j`3<bs3RvwK0NhsAIb852lKzW^-@OzIXT%K^7WfPob6Xt?5?Rj zcpgOGlsyXn@%dZ0N|VDK7~iZ3Rm-WsJlQM|?xRXAt?^fQCi*>T#l=;6PfI=CLOoTs zjD^IfEnI3ke`AkQ`7PvV+#QXbuM6Ao!{FE1H_S`E=AI(`>+jmoGbsK>UK`;=^6Sha z?fxgOB|g$GGMV<x)z+E+L+4v_(L?JWxw`pIlW7O)w^a2$<sY+k{T;#`%3HIArhP$; zrji|^H0>y!J&*A(dAHIwWytuK99I<9NG-UeU<vi+*>hDcU6`jbcTS<o1&hy8Ie)=f zOSRV&d*13LbUe<^%v-Gu>gJtOyr`f!;MG_W)~Tyk=;{@^+Ix{^PPg7yTrLAH3-l3` zU=^<+9&fGedz#0_D6bK3_v*#&zzVfT;`c7_9A0@GdZbIPyacLmRCa=zJ3qJhRO(^c zXBjxA3sOie$j}Teg7~Vvg788h8#rX3C{-Oq)LtbuUl^<BwM|Bks$~5CFmvjk0OMeW zIe`}Do>shM>B3@OUZlY<UgfUUkMyIXqMP$*i+QCSlV}V)aaFbw^IQfF7cI`uU6@y# z=dGyn`RQorcMz=Ri@NI1*vFfst7X1Ge#SVeu|IjFrfnLo^Se*paBNGT6P5nWN8Y4r zBdY2tipF(~R$6o=*;^beFQ@YoI;f*xRcm9vhJl*xhN7ybG}2d;@`_-XR=OFw)P3Pv zeM{D&LZdI^$%aLgx-}_TlGhPR{Ze&p6#8Nx!#9RPx1c@^`gPf%w?_e?tQw)IV?SCv z+@+-)I{r=PaQdG`)BK{*GMVnArnv>#fLx3O5HC`MoQcdqCL!aI5l8|eo4h{dqr~qZ zuOLq&k0JLUw<6agQUr~1D<7|vpHWVYa%}8NH};|TwQsmH?8j@~m<+YypW%<8Z_x11 zP#f-z=f==C+;7{~qs;#r8ISpe5q2($xc)k~M{8c&kDp%jUL%n|LhjyqxSaL-L-lUM z-m`u5`g13GVs|iHx2s2aiOk%Ge5Uh(XEe3w9ZBANsz(uVU`Is!`5o^5_)?GZHWGaK z+sO^M6%qIU)M@($etr7q9_2Xf->thDPGL3Tl7fF?E)+fE+Tg?pyM~_OHqyRcBo9H~ z@sZhcw32p-F$=-qXxLqQSz+~>JZ7q?w7m0V7-ZaEdz9^azgq6ayd}cUTM^e^=k{pL zU+%}x_t105VI2IvZM)LD3M^Q~4$p%V$=}&OYT=0UZFsR%KjFfF#Mgaz<eOHf>H;g~ zx3o-?DfZM%{WLqyXfBhN+2Z2!7P67sUXzjO^doW}bZIbHK@VWMddvgUbuw_t0IuCW zai%>dCw2CzW2et_jGvog#QbR1dVRy?6i1Hvs&ryqQeMeMbhQ+ga1@31)=EE#6NZf` zaT)O7b&vs3&GLNX!1t1>n!p<AFI_V6vh<_fh<~*9WO9dH(DG%K;+k-|(_xnb)OzPH z8Bg)KdFRitOFDB%kEE(xa>$wtOO(qzacXL6@rmWxS>=;5*|2-Dw<bHQhRclX8mC{> zj3M|ZW%@I+{Z0bAgwZy>Dsym}kMV>upVxEQEXI>1zb=uz+jQ@8PF{9CM;1(zX$c0p zWk%9n&g4FwNM7<!I>}xha8MBJm)Px>sV6^Ql4DP=O|7U{Rhjxd7CiMsH0pENx8CWi zKGJ-DWaew%uqjzWvgFGoCzC{#;am?h^j^N!BWcfPBPe_Hk}pvg=4n%*MjG|Hn`bOV zAZA89jPYTE#`thw8s>&O<J=#EhWU})8Rlj+RSupXWa#&GXM|(uAIYBKpNmllyEc_= zEPd!bmGzruEMJrHF=@LxAeBjG>Lhj4p6_-<94o5dg$9X(#8=`f@r)Fcscu%J82fV# zN<Sx3_-wI!y0}+teSUF$ezARi(S3f8<r^u4r~HicG$^L5IM?5URV$`Q7joShVZNC6 zK}JO9%hBj__*~IXKkiYU_^3zu0LkEbA)U}69X(1GGUZ=A%I5YS<yEe4>FiN{i_Gfk zQ69(6hoAK*O_-JZvqw3$yGQwJTaV&`S?FC&XZBrWgGEusvIG1vWD?i$QHrvAAbr~} zdz1ivpM{$zxIX-y^suGEg9aaCvc<;5#77UXCPWRiB$|`HX{lfpi~r){U@gOml#9uF zvEaQzmbj%!JF0fx^&~W#%@%%9{H**WS2Pno8G?!EMn}iQ#KzieadGkS0|q1{4CF`t zSWVIF-i~D#cbqBSG=Ls^l4-E%Sl%E<nns&WHcc>1GEFnhH7zlfnL?&@reB(#H2uwF zF;fKjC(!(e#r;5B9%nkylwry>xlL<LI|+O(;hUq(R&$KmW==2<GAEnu=5+IHbBU?W zRQLU+iZ)bPtSzM>c}NxRFY<R$U2I*Xd`d}-6r=e)ijIRZPN)vc8_#Sp>m~{KusY#z z%Y36JtxSD+Jh&G8C>s64J(6j5g6th=rpcZz(<*ic3rbjx!Y3zKYp0I3s9FnaD%3`v zWU0FXAqDD8!?(Zad~Rgoc``Z3;0a!E2(7I9Vk)|-q9!CWT5~z)Kc9&ZS&ucB_H{n% zJy;J}S<W<;ya~%#j!dx2F{bi;FlifVoVA&L1ZKf3=!C{`5X2#UE;27Nk2F2e5q-6G zFbm}B@y8FfshXl?yw8#2hy0#)bt@NSuxDln`&FX5mEU~ar4;P#;+_xv?W4}&l~wfX zB877e>UhVj8=YXPdnejd$5T~T@YnddeRo;vPH3`-+JxGK+Jst-qr}OOx4(!sMasTD zzpg$%d9RNA@c^kmyi|Yb8JUx^CTCA^PIZ@-dAy7w$gq|y;nFgAJQLDny)0v46wqEG z`NTWMeELpmrsuH)(c@hjF3-qT)w-EjQ`O7_Qa%c05f8IVUXK>)Ak)OTqds~kd&DeL z-M%Snp3I$FPVE$;N91D;TU~MCP$vfLxuG(@e@VD{j^E8<p!rqw(pUu>2unHQ913@U zKC;ZvEC`4XVXwM8ixV$o${HopkztOx_f|7hsm@g})}oRLTyKbp{tzFvq9;~Omy{#Y zSzN+&YcYz2y1(+=GV8mBc0)Z>x45{H4tS{#W=_slIXNS<)VJQQC^sTkA-5r6WD9Z+ z@)Gh_<b9-M7VW^-$U8F?Wm<%tg%Q_Z=k{pLI|yUUY(>e#?;>O~G6b~?{u22N`5O`? zb{JKTWzgoU<j1*+QWjz7j)?28a`#=$-Xfd{#BT($m+Sd(B(j_9LU<E$C-RVpi}Xk8 zbopt-wW0T2xuqXJe~n)4`HB+#HS)@Gh4X_C+6zQnf1TT-HUE?_`q~w}u@{i{gtr{| zIWi1&KD-xcLq0%a(Ytz$qWl7BLS95ZMC6$^+PR}>an$!NUW)k0oQK0=cx&UVDp|@? z;g`=7s1uD^HB_=JGsQkB`}`7Cd8lt)y;H}%ul;;}LGRX%Pfg|6HvJS@UY}TE71oyD z$qc#rxi_s!lNV0b8<omyT!^n3$cR2w9F3dN7WVqi8!XFbnPy{ICr#pE=29)P48~i@ zD(n8t-BNpDFh@OY=ggY0)=;XiloGBMAwteMxTZ&2WOP_ingv;|Q_aF`KAb5@<+d9` z9^3}Ylk~+;d|(!z)wANfp%Z7!m~nUyv&2zB>uR^F$GeR$iMNvm<zz%jNlLt?Dc1<! z9lazzB|b&oIa5>PFH7OC{W4VnE_1{?QsS4Le^_)S<;WW%n_ioqo}Q7OnLa6<FV?1K zr%y?DrccdC&&bHg%$Sssl`%OZJ7Y?QGh=FIdS*suX6B^Ktjx)o*_l%^otaZ7rBBM3 zlsReAq^wDkCuL8XGRZk<YF2tyMpkClq^zv0$ywQ1Q?i^{QzxfS&X}AzdD7&p$&)8% zPo6T_IeBV!dUi&3X7;4)tZcrdn>{7lnLTw%`jm_*nNucB$(k~GO7@f~Q=C(#I@6sQ z&P?YdXO?raGut`E>2yw=N))FO{8YT2inFO`^?Q@Xa!|g)<QT6NTN*Hmo|d<=Xjn>{ zX2O7tUL?`dmVxSO&9>^2^@L=Mj5^Q^s|tNZvs&5=XDkHp1X)=slTX^IfU<Ew8d(`- zIMnJPJ(&N3LTmKD%U^jHIr2~5QX+ry#uC|0*EjVr2}ey}q;$0`R6$+ouJu>eRLZ$) z7x%6M>a78&ry_;{4=Vv;%*ahhM(LK<a)-uyf8U!m^yR(Tju`K+hP`DBD4j1|9;4h) zDI8K!Ng*mx7l%q$S~_SBV~2@b9i7rDG(K51jZb=s5!05kA9cLyvfr3%W!G59gM&ji z%pT@OUp(9Epue@Zp+ikWOp(d@V(B~@%X1H}M_Gv?-AGnO(Hh8VNs`lKj*>S_OKc1; zzJudO4LB}g#K1v`2}#yLQO6u}Y}_#OaBH&pxTq1aBh8~Mqlej}CPYmfkZMkk%CKab ze{H$ja*y?1TZg4Hy4%tdrNrG|yXKl}?@T|Z=$eh2M*TH0>5Tl&uGF+y%g--<XZ^L; z-EiaG4?X(3r=EWHxi|N}tC*~Vj~SnlH6>@-j0LBkzy3N5AAa<APe1qk3;W+SSqCPn zra9B*&0lc(1s?DE8*aV*+2>yvICwl-3(i@#`~psNyY_~=aq`r&Z|#5gz`()t7I?gM z>;LbuKRo`*YX?4Echxmp@A|{zPd)R(8-H;%{Qgf*KmWplg^SKP_k!XL*Iob6Z?`|b z^XX?^8$4|IvgKbgOi)*O(VK52jt&Gz9bbIe<qte~#qS;)HvELq^G{p2sOY@q7hHbD zZ=QPjmAwZ({h~T_eYoc4v8idlesKHa&%E&3TR)q9OGEngqyPN!^UA_S=Pir1B@G&v z_Q^j2!6`Fl&6&69h9xU%nxEbCV$19Avyi}EeA1O~S+C5qjkLxLUVC3+-M!JH<JOLh zI?iUcrdhMBu~FvOnApMb1xd%mE{%<{j*5?qvPH#4$rwR`H9BfQj5%>=^upMYvFF5E zVumLaSm#Df<UM_GOj1IQ_4reY?UmLGPpNB;zH(dCh?pz8qt1;T7MC11Bw<Lxg)#9l zBVx{toe(`gKE;|~HAiI(NU@HH84y)>A4X{zXGYa+wM~yoikcqlv`vV<QW>0VOB*~f z>cpfIlj=5Fue{~B0YmFIN2f(ki?t*s$JPDeq;Nvrt0NMk>y+raw-Ww&d(@P;wabUp zHQDO^7#*KHEh;|7X`63LhzSokA?iHqxp8&tl1If4i_5px{W#{{tqH@e8FyIMzA-j7 zAv(J5u0d<Rh&9_!jluL<Yuz8BMn)wKG{u-@5W*528*5<*#KORgCDA&_JlJwf^s$47 zn1@=1TaFtzD*AZaX!98Jh1Qjp2csUcJZ5>p@}lMCgjeETwY+9|!@Mv0ZOi-CR?8>$ z1J*W6M^vXdVcfKt3m0Ag^Pm6Xl51|d`Og1)^y-IVV&k%B%sl(EJug~^Bxg@K`<yH8 zdEmj{Pu_RTk2YNQ^WMTJWpUvmk9YZRw~rhZYl|N+WO(+}oW{FbUXPoy>4wJG_-QlC z{ny_(I9UAnC;vFFl;d5N6#nei)U<JqrMGXn<Cj~1-FW|_kL`*XkTCT4oLTeEy6e}w z|Fk9cxDh9vGIQ4ZAOAyn>S?R}<Wt5vCOLClr{@<eS$ejVy^=C-`N~l3Wmo)o>pc%{ z+p*_?2Lr)B+;qW7mqbTdCq|V=nbT71t~@>}BWaX%Oxy|46Qc91iKo`x6Ens-#_F(T z4OlpL?UcA-@wVh?^QK0X+2YcNMV}ZoGTJ=bX+0x4%^DvY7dzWN&YBRH9hDP3BG#G^ zTd-itq=A!SQ*H5U$1Xl&g6-5{BgT#zGCXb}0ptxlE;c^KWg8b)GhoilQ)8w@$H$x% zV~!pa6<v2t=?N}deBE6aoHTDhe9XXOb7JDNQ>?@59+~c0lHiJqpFeM;%eG|Tg4p=F zFXzV}A9dP-DN%{G_?W4&@oTe>i=7rV>TGjT=D>Bgme&lZ+x6r8vVrT<2MxRao-0qg z<B=<;#-3_j9y2z6e!L_4*eka!^PXXy8asHl6p35fZ0lb=HSW&$*G@_@A0LxwwXNN_ z!MZYfU{qY}pc_k0iwjS$`!YUcs~S50VtEwKi94?DM{7@ux@u0+(DenQV`A!FnGikm zM03@|s1a7n+S#KA=R}*=?m6|!_v-#NKHnN|wX7SQmp`NKiRm$B>(c0vS(delDOOLy z+3|G`IFBEgVvXa8h^hP8x)$r;sDV+dt;I1sUr7m8CpYJ?owRUmVZ!mmCEJ#W)wtNY zKb{i5KIX8R->9H<7Ryi$b+o#4xIn)6z<aj#zVBVJh@Q86OspUnGA@m^%N$1@)<+1I zNY`0)qV<Vs5Z77lrW>M5Oy?iF#dOSY`{)FF$>@KiY?*Lsx;-U$*S-`>W68u5I!jVb zJ@)LMD<#?8=C`xW@h46hGw|&x_a?fhrX}AoHGP!Z_1Ot`<j>A>7aX|oj<Xg8Ph5Qa zV|Oezz2IKreesSZrZ-M3H0^tP=>zY$&-r-&iRbQVz2jWF>63F0n6Eg`RK>96MEXY- z{+V3^(uWQ*d#TGT7PIwa^9duD4akX$GbdZkaXk9b6QZWuPG#(I3J$C`>a5s!%kkzM zac;F?CEhZEfzqke5mp&5HJ@OKG7k`SG#1Q5EW@Zlu#Mj~b8J++<plFI+$P}Cf%o_t z6-@;bYZ;*WDp4X(i>OCgrV>9Rl;h1V21D_j;n1_pme>Saso4@YAa;ReB>tJrQxeUD z7(Ku|CeB<gqo(wuj<Z;!23ZGk8DmZ|(;106-f{x}W?Rg$HnU|woSB;2Tw^)Oyei6S zi8IGU{e?szwz1-)#TFB9F{h8tu%@GqHap@HEOu_v9Oc9ihfz5;i=`pTJkT5~0Y+J# zo^3Ked7>%mT62lr6yvv;tmb&TrGVir8OS}(5^cW4GUAwl=CQWp2Bb!%b8i;QIP+Xm z-eO7MzS7K-@YQ08=Dtt0*vy|uvdI|Uph1J^a+%*T|0LQJ#a&t*QC9P>@ZV%9h?+kj z!+ME1J83-k86TB_pRwi{QDdUbwwdMxOI92YkGVKXl9EI*-)@ew4OLUtY#wG#jE#zZ z(k3@ETvC<15_@LLN5m}#j<hVbiOz+R9+-Ng$kb?4oZ0dPIZuf&Zz4Ra*&gqRQFAKB z5|v7Vn_@{2^WtGd1z#?XApp{x(k4MM_&vaq6&)>C=9nZC&6&wO%X*d!il<tJGj<nc zjkeh=u_stJN13KrGi~NX^RQ@h621;reT?>)x8P=ml@y4rj5U?i9WW&%#l)ECNLdHO z42t=xpRHfR=$J&>;23j%hOzx=s(J(EZ(K~&gbC3nP3Zkan^E_ww2N^n1`nP&_|)T* zhl?W4mZBNyf5(iPbBNkdn2d}5nB7Nn#`Fn85(imDcgi6~IftkwOqe$D5RLQ+qfZ_> zENS40=ngnx?4-#fG7@5s%XDPLMCHz&HP<;IE_K3qd#{tJ$6AhwPwQ1qn0m_Kkq1>1 zCP;t3hoKZj{mn9&3zw=t8Q<lk%h)e0xm?=Cnn|@HFA7`~ccFcNizrQ03m9mwjdh^& z>bAZA)@aNw(e$G$G@35lwDq3TmoEMD(xr}hOP5|&tZDQ2-cxlOIFc*zw{U6U(tEUc zO?dVBzdZEHpC1^^Bu*03H^%a&q*>ULm=L`^o;PQyZlfJmHRkGw&@9tECPs#4zt*F4 z;!07jxI+9^{xwBlx>yZ~@prqbRNWK&J?ow0W){py+9A5Pe|X9cQ{5=EH@&BZ#t^C+ zC@G=2QvO94vk=AfJJUm^driMKZ6yk6Ofju7)tD;HH=8$`uQOk5UT2<d*=o7bG9>E8 zsEtuqTmR2`Z@!z4bm{{#jIWQ3nl}9ulj$zr8-31prHJbW*pgy0HNhR3a9X>vFWY3Q zpWd$2Ei#!J;md_4lWTUnvVWP$l$_hHRF&dx0q$30e_^|F-{qWVyom2=T#5NozOAv= zWNJRAT{$4?bK8~a>)?6q%44t|mfVE-vUa5zww%vdNwA@$U2$$UnH**9iVxPpOJOT) zxE1@Jc4ZH2@U|<q+lYTT;oV92Fy)u{v!Y$u)QEk!@k#9axDV9H{&wYI)GZg{-`)7T zvRz5og}Vyk1?wyE{~qoWZiB7x()&y%XMp>A2nPA?Ff4+Nu%(Ll!lsMbmGyrjzG1#S z{EErc26w-Ty&C*~pKw?4JrU@Ddt31zZutmzu;gRx!vh_}XLY+0M%@gzL04_NvJ3iP z3v^zLJu!zHKPP<nFl>c;VH>o5fj^hDE4RUB*!(5oT}u4MV*hgTk$i4kOFp7*-Po=; z#*tq)ai7q+8UIB6Gvbdu2iym1p%wcLFc~(&6xal3L))$7g9H0;6m-FK=!1E%4Q>+k zZImn6d^_K6W*wB{7u-Lr-@^UE);l;O>s0i&wkw6O{#WhFR@i!1yYe}7HR2yNO5@$+ z6KsO_!DhGvw!oKRD{O^runQ*N+pf4$xDUSVvKcnQM(BG0e<l(h-+F0*PQD$Tl8XJ` zlCPLMph@)M5Lg74W8MlKsN3LlXxmP{LkFyY_0X4w{$r#kZ23L;jk`AZu=xK6{7ol5 za5`*-&0-GsLfhl*N-g@0@Br#2_%LeM4)Ov2d@va{z!caBKgZm;vt7x`z&|(}{We$# zZBJ0H&~JE>aCxrVc5%O`ZBKEZFc}u1-vZY|+tb|dB<>ex!A961^#QyOHbd)V+&zo` zu;F>q6E?p<d4aaqs26bOfa{^Hh5Uss*bIx{Uf2jtS;Pm9fyuA)+(QS<hfY`m>*0Fn zdjo%96Ksafa4&3u2Vg7AqP}YQ3+V?Pdx;mc{gw2h8g{@G=!COj5iEqQa0_gM4@29V z_%D2$dXAY^-+Q=+uJ_4TSo8_;oJzd@LApZQr<7CJ0{1}QKS`e)!ugEn05(GpbbLWL z!Y@gGX!{rTrr{3e!NxYy4c4|3Z|Lga{$O$^`7xb%LKk%PP@fQwR=5YY!HOA#XXU%* z&==jIv<YK76wgfJ8P}ogfwc)8$`~3lXJUuafIq%L9ZD-~f(h7ffp*vmvtS!^LD%38 zr5<-a*f^W`AJd`ShPnuDgSBuMtcNYI74E^F^Vkl>3X5Petc5AC9?pghFd>)w8$vkH zIkZFBEF9LM6k_gzyHGa|?@)ZGeaCeu`{$5uBZ=Q!II2Ujp-zSss9WK~u=aSqRWIfz zbSR@RcfzbZ!h==NF}g!Z7k}&>%5qo)!_WuoVJ*B3*28VE0q%m$qQ<@Rqz>hP_;)h? z%)_5k@E110hhfn;%%NjE-=Ck4Kc{vmwa}H)p)|oZxbZZ?nb@H;!xq?vek)8s-H_U$ z<U>~)>E|L|nS9S47UdB>tc4W|un%{kcFrSRU_ER^zi2-0U_DHR&Cm&Lr{NDwhV`dY z-rz1+@50_0gtGvDVH<1}_ow3@YUddp%3j!<Px--q3rx?){h9cSx*6t+J}iN)FbvyZ zJ@#x1Nl%yzw?PNo1)Z=3y5Ip=1g&S1j?f9~7j-C?!ba#^h`WLgWfN*A+zNeg2dsrJ zL)%$|EB4MIU11}%!6rBg+KNywB0T7TMQ}E(g+;I)R=`HM8MeSi*a{zmwsVOu^g(L@ z?qD)(f=<{13!&q@4y6tj!3J0hABOd?88*PZuu*sx_p^-qM_mN1sC_UQ*1{B64`;&$ zSO^`<Ne3~9qZXroKIsnIE+C#_UQE1EyWnHc2U~?DJeRNmmMkIOFbtbvJ#2xu!DKi2 zTZn!c?nNK&fld$cgbi>I=55filz4clXJ8AgL%$Vn7IWALZRH)x7R+rv{1bh60Cl~e z`sQrz`$Ezm`d|f2UP(Nl18##(xC^@AJ~6K#+;h+m@La(nxDnRFEusz*UttyH=UnVp zqZZb5D5fIZ!6DEE$DBtxKnLnp=z?u<Ikc@JoiMM5Rj3=_de{hWL*KTV{6(D%TTnN^ z`@~%>&m(lgHt2)Ngx>=5p>GZ9WrPD=(04KU0G*fM9@;J?zm}s9?XVV(IUoJYsK-z{ zp-ar62mKbf1r}XSd4kPwIp!^}3bw-J3%HLu;*Yu!Hozu$A8dw2m?y90c|z@gFGDBX zEbi8k?!tP)FUH+Q%7+_wH&AX+yKW?XVG-O9YhfF#hY2Ovhj!QuvtSE!!B)5&w!!t{ z-%aE*Y`mFxqwl<h_`znlU+gy!zf!{cDdi6~K^JU=%V8Vr68)c1@0M{NKj%4t^{~Oi z{oT`{d<<LQePVtu&zBc-xCeCu+z%UJo2c(2U9jH>D_|3>6Zg=EyW0CH-{KxV1{>iX z*aY{(X4nQ>U_v?h_Xy<)Ha$wYhDDE&&MSyFG{NNGlTJSJ6%IjN50|5^f1L7(x)Dx? zEwBK#LJv&d!E*o|a3gfWEzkuYh7E8V{v<!aa|a!}xNkq<JjH#%=4VJ(*a}~UZLk&E znsIj_?qL_|CO8OnD?9*;p2eS)#0QQMedvU3Fdy2U<9=Z>3_}O3hfe6jUHuEB8*FRg zc@lfC<9`MA-k>~GlD>Pnf7JD`3O2y?u=P#qQP}bp>4Lph*aDmPlRmKFec~11{y)SW ztc6(@5ucB6kJ|Zn@(H%V1JL#f^=^>xVKQv{lyG5D8}Y_nYdh&%g}RgUfGuzjbaoMc z%v}oct|lB?r{aOG0rDMW(raL+(umrb)Ty+IJ{%MxelQER!Xj8Zs8gwh$;Wgm`(V+K zP9;6eeZvCS1bwg>UJ6^_CfEkI!sMZyN)vRz-LMuOfWBe4uc6!w#~mz6CO)tQ?t-op zI+Y=-h{s9z4_i*|RGLK%_d@5`PUXJU_y^Nr1I&Ysa35@jpTm}Mor<HDcsM#07j!_G z9CpDfSOnKY=Y&pW4{S~4JK<~aFSAprfGyd48yvPx=UdXSc2=h{{bKyd<vw8pY=+Hn z`X%@?kNAoCe9Tcdz-CzM!XH=<yF?!jx|Hxv=Ns0rc@g&yYZrGa$(NDuOGqcw$<T`0 z0gFVxuv2M(uBF5m7Qt571Ra-S|7_9=I^d<S2sS_;+#&i!gb$r?&=rIa^PuBg$_H$K z_0Y*T)ptP`Y=K4aV^|MOb)*Y)z@lZu3;JLMtc7*332uSS@L|}poOnX{K6{tw^KEw5 zTJ+&^*b1v)8(a@<d@H>{%wd!0!!1|hj&G&!hEBeZUa*evp$FE&TG#~l3;C}4X4nF= z){`z?(igP@)}wBMO|ZV4bcT)4dKLG(f_On6-1RW_{G=!9W_T%Vftz3}+zMS65*}=T z)~kspOo7RKH+(j1fc3Bu-UgfDHt6FU?gvB-(|?4&Fb}rDB530~>lM%k?}N2`Lwz4C z3U(?9_1r(-6L-Q|SOA-#54OQNXye=En_)6+gbvuo{WQYIP&dInuo>=$tzr%v`JQ{; z2K<3VFgZj#U^8rjEpRt%h5Mi_%yR~lq2o8WhaTvxA$?%&s!qlBW4O9g$%oF`PGuwX z!7Z>JwqdUoX8jiPHMoau@L|kt7xVl;2iyyt@Bnl{>oueYOop{E1=hpaun`u*X6S>h z@KR{Ig#3dpxE1<f6X7)pQ5RiGc^C7`I+ZaSF^5iA3-e(!tbp~GV;?%Mz&>n+W3DCM z&<UICD96yYmT;g0elFp_Ce$r(H>|yq^oI?w4Yt8i*O8v<C>O8@=D}K61nXf1Y=U*L z6>f%(tB415!H;1PG+mE5%!iJvN#E_5{|NV}eXtHTz|CS_Pkurt{2UfR+a~P6QLq-K z!$z0~of}9;*aG)L+mFc?=z!K6Fo(&o7CK=)%!f^|0{X5Y9bg084ILY?e<SgO^~AFU zrl4+xv!U%;$^rTfun=_<^uab*50kIs`GSt?iFXs`uvPRo@jRn$hC^<`{*Bm&tv7Ms zV((7;+l)Tk1Z}@0zhEoeBl@sa^tY0pKS3X+K<BSW2Uri6!xk8Zj=Lz|Vh*>!Mz|L? z!2@FcYuw+A{x-@ZY=)a)+e3sye0)#RjyyuVpTQs4{2cWV=Dz2N|1HGhC7uu1_A1W@ z^!)|@vDfxC`SU38d583GAU<#mY=chd`Wxj3Ho#ig2sgqexCJ)DhhYnBhQ9rjN9cMN ze}77R-XpzX8{7h$->1C6hF02<pOMcWkj}8^L&_C&d_?}jHh2Iwe@y*wEB621sg%Il zPq>dq@%NwP?`@d(kRH%Al<)Gvh7o+L>~_-o1inx8bM!~^Z5-GHH^XE*-|T|*Cv_?N zgeP|?3BMrxQ@WHq=p4uQlVCGk50f2T%6+hYLYLA88?&*u1#?&glc#hkO~l7lia)=@ zyqxd)!PdtKA9Kg9F6A-dOMJ8M4)kBf945a)yrAt>zL^D`a3A!+&tWqhbSL)sKF}EG zgih#!597a!Zv|N&!#`MpejCgeHQx*hiyCf3-Tap>WiKpxt4m4$J@@f8-!sF!;T`;e zO|Tg@!@aNt9uWP%@qHug``+zRYJW+(!`-Oc;O8*;1N{F3@%jW}-UxTYq66ILR@}i9 z*bIHJ1-4?p{!{!#-2`tFbNH~B!%>gpFW)mNgbo(B+y>je<eO!%rH%OSK;2Hd!KMzr zxd>ajNQa%IV-Mkre=zx1*faC(3-lYUd<#j)K9440Ot*4C?A!P@4EAc_>?a5>u3OoP zx;~!o#h`9Z>{ebz-2z)-Qxf0dxeI@f<-0hrg}oyUuwfYXgd;HjHU8N#hm9w9E000n z*luNq_&=^&>4L4$)<`-zh#&O9Jm?tDH&&iRKa+TfK5T-ua5t=nrn?CT4uLkl3p5+n z!{x9QZrVkD@SUK&u!-*iJ&b-EbUcOse5)r6i>Bcp`nB+L)NRv=$J6M~#9TOw@L_Fk zH~aeWZw}_q5bj*m5)QQ9gFBcE8}hmp4@{m%dScHxzgyV|i%#oSwn5(++&64GlW+TA z&$+N$DQL!g5%~h!U>o|b0={2zFZ!?%edk%-${tu>NV=f!TZ%i_dN%&U=5xB0X4rB* z@wgAQo9`FF#!}(~Ti|W54Q_))UefP=?3MF<AlL$J&k}!Mw^D-Ic44=&8M;=Ie$ZDz zx;=n7oDCac5wum3PS6#=Usx0*zwxKFigbf57m+^?68~z_3w3e`f1bmA4c`b7uEHI( zT}?Xv5&QMH7jEcQvc%mr_=CFnI?@F;Z6ck}PriX~4#8Tu1J=WrVFOIrP5y4ie`xy& z<rV#An6eFj;cQrY3;6?!8t@<1|CI8Dedo`(U)0U;0BnKQhw$gtZe<i~zMcEPUc-IF z?@!$KHq!h5Fn@@2hE7-uYheRy`9Janw!yv7_W$q~CPVB0Bc8AYe;mIhe$SK6Fd2Q< zcJc+atBL%DMb8i}bUw#-pTzu+*na_khjZS*pGn6tJxYUcLXWZy^M<q@CE;QGOXutc zSfAOW)I!^&9_3@~wN36(roV(eXOFTUwn6*L#CvLwvI%uP+$!d<Nz7pZ=FK_y16$!H zXq$#T=z}fLIip880Gna*E4ZK8qtwHuSv|@Q=*neY|5f4%XTv5~2%Dh~w!llFZ4UlJ zC)^5MunGF$KG+5ay@tEF>`{dcc`Pc0O>i@8gSHmZZF!Hf9Ja#y(088SqijUoZ~^f_ z-3s@?<l-LXbLfICnEO2JnSCAqVIgdVKIrmtKhOtngSBuQY=FC93)~Bn%kfY2;q*7K zw*r4)GpvAZunsn@>``{ZmP*p=FT`&R;lSF<xnJn0>rvWZ8yvM4`)lzJ)?eA9cwj56 z75(*u4{cYG{-VCRM{)j@c-9jRwEY-!SbGiW_9o<<Egx*Sj{Jv>H}oj^Z;@V`xi8oT zTVTUaNQZsI>t^yFw!)3j^>gkI7X6|}8S^&&Z6#e`!`--p$@iiE4)K4WM+w7*-}ESZ zVEuOX6aNi&k5XP?E$5)L!WKAaKmNlp(AP{l!FpIH`fxL}J=>!+!Xo%GY<V90?{dE{ z_9%I<nR7}iVEyOhFKl2xvh6+Y2fAQUJMn}qa1U&S`=PCabcPO?_dfdYQdrCW=&i6B z?uIRJpP0kXp{)!5TX6?RK_^UyjW7>3i}?rW_mF<DQRz{N&~Jeas9RY4u?IG=2Br#q zhgDIwK^NQwo8XuaQAaDv0n`n!2z3*zfX%Q@$m*M|ur&_<pf6rgtRE47m<$_W3Um!n zl-aNd7Q!~T9wu{O(ZjF-?uLzUA8dl3!)9pvnE1j`(3z+x^{@!u2AiPm@AwBt!KOiq z;)A|p@E0Z@t0?<L4Nae5K7>7Z&^eU*hDF1$2Yql4Y=HY=?QlgI^bhPq2W*DZVPi7> z!!}q4ZO5_S54zxeuxKQEykN^{_J1899J``4Lf;t9X8II=p&d3sCv1lKumzUDRv3oK zr*MCwhWnvoEb;j#YUqN^;}m5Rv^m&629x1#=txnNtj~xKbisx+;stBdF^5GNiqa+O zOz!J*%;9v{l+7MX=$xV`&7y_}MC~LWzrbA%{=t^nq(7`@PvAD#d>a0VJ{<HV@q=Ta zlf$XP&;{#Z5xfmL7O}SwHZCE5MZXYt|KdKDQcj@rY|;(7&LLf48*CPH4!qh6li}yW zbBTW&JdgOpR#*TVm$5$(I@yQU0GnYGEMm`H3v87=c(9)RcggL<r<i<zMQ+j`w!&K2 zQcC*5WDn&7y1bMRSX-_rAHxP{>L8pI?Dd32&;fmLI;@8Uun~G-E4&mseE17%{rC%u zF66%8MbOr1Qh!4<n9LV1HkoS&nMWqX+BTU@rZMP`LTtw}_b+x52hC4RK0Rr`YFnLY z)`)4RP8xHPXuFU+q~KiE8d$i<O&l~QF?mj+eNLidPGWj)qBAeCWL@mWm}{f2vtA!{ zwIyn_InkM$n68>*3%i4I6K%PPC4+Fj3CUvJ(J&}KJF*p-jout6{;#u?i~T`)iMIKP zI1+cwNCkF``w=~w2vaS3Nl<>GcK`{a7cCn6><BATO;zaSiiYaH_YnUj9pq=exFBCm zrPy0vzsPJFX{1#?W@>t!-L6a^4Xn4kd^G7$e57<Jz`roE`#jcx48XtDNAPc(`H+N- ziSI9A=Ok|9{=`p7qb6^=GB^f5i;v*vrbGSw$l9NuxrtInvhZ&dT+jM52edB1PjZty z%}uoDC04DoUKe$}#q#$=d#;+zb0k@-)VLI4|5Dbgy+B4-ryU_Kb%(~KA*%nl)Zv%p z?QYV(t@_Y1uut+M)UKR>x%|Z5=jaVW&&XFP!?q~y1-+}pl6DVT8K$JJi`f``t#&IO zDb#wQ<!<In0Y5}11?PqMRf1oEgMN`7dSWa&m=bo(rR<atpDoyzG_hXsQvYSAATp~h zpY@*-1*(7B@NXOCS@mz$clXc4{p?^3pz5FU=kFZ90{q*vO84*a@8+MB>n-@VZ#B<~ z<n<N(`gdC5fkVsEvqyON4v+_uC!gcz?lpQGm-OprUg9^%lRPW+(Z#xd$9{MJHsjyN zm+1bz^x}8Q6G_AU_}9hyN;Qvf`fmQ=o%)<Dr=GE0-mXxEsXux4s-*5g&!~SzZ#{Y@ z^djr&2K2fvJ5=vJ^xDu%P<_+do*n3Yj@~fxt>3n1%OUx0>F)2r!Ku^%39;0X#A7k# z=qUV(nri9aGr6ZC{MuXh|Iv0n@O91i|Nq=`&rNP_(lj)wlxT0;WNNxD+qx~AY%W4G zVlsk`j-V!+nxNad2||k?2#T5_2r`0>qA1O*$hIIO=*X<7>89H{x=Gucp5OERIp^Ga z&b{Z>pYP*$9=++guh0Aa{=7f$&-?TKyg#4w=W;(F=W<9~s2BagR&s9cH>BeXfl>S@ ze5JvpM%W~H5+fV6{gxwRRiP87>WbqccLiAGrGERZ1&f1;3FHvEbzl`>Q#4{@n?xR% zYd@jmbw6q)m_FxgIiFIn6<~WvIVycm&xYg^e64oq=Si8Kxh2+%{=ZDCA6KfD;u`83 zpuLZCZl3d^$EF0$y5huQCnGQx7SBM4ClyHOIbsp~^%rclV%W_*(#xO9E#?%j_w{f1 z;7CxP><^jU2ZP8oFWG9nE;=29OuG%Djr75}=|&_}0-7ZBTcE#C==Zbf?fK1#=Lfp+ z{9xZK7l&RBvFrQ->~@uZURnfJn}KzLm3M8m_)j0g+s&8K3~VLX3b64Wx&g4-tNrub z2v|Ls>w_Y1GuV7EFRvM+o@@MmQ4Y2o%=L?Uc%$%^cWkxJB379Dz2NCj`h$6LPVovu z=1M2eyTI_zjylPcxk+R-A*+G=wx6M2%(Js))fF@Or)8O;09i8c*C0!5RC483>jcit zlab}~%OAO2N(a@s=eV2AD>j-9Z;SALC6o6|mp+hJY}5hoa^VeU@)`{;^FbLE%h+gw zHwmxytM{JQI)75X68@#|_u)U6NZk(w@Ym<|OW_}u`r*G{_|FgE|6XqXW_U^o>Ye!D z71Dpl!LLJ?llN<1==by=vCWq#;R**A_lM?Wq5Fd(-5xi~2~_3Ra&NIlY-|NsDVQ6> znkef=mo9wzDA8s6pkEhv4dR~%!sBwx|J`==I@VQ;BVIBF)=2$soT%1u;u^PaX{sLM z_0Tq;*FGLy=Yd6+ZnX$s`jD~I3TA@2<F65{nZ|66Y_<N&*f5U?)PGKKzv)c?!<{+w z@5fjb$XtocP3S&{b8`+dnLmChaXfDO{V?Sf=zEBif01(EnEAfjyiC{CZJk|=z3<p+ zO@LR98GP!&mV><}0KQ<apj!3JagP3LFtgEj6fcCfk!K_J6Iy0J^wM%W!54u$U7+F= zcY`eiJ3wfWo4NKAnzhh$LnCdqX-?BMde?^=p&5im>X$?MA_=w*%<T)oO87Di=H@4H zuu8BYu>Co=<@?u%y8X~3p^<q-Xj-%eIoc2HiaVV)(f)JY_JeN($4vSVeY(LmfYDtk zY$e!wFe#U#flm)@S<M(YM11J%KWH8Fgc?uHl^OYJ_!l``sId`wTSOlIai*-#P7ahe zr+COe_a2*LtvE!7&PHavv~QWSR(uGV_?#W{cD`0@m-gPc)%p^1v3XOVE_%A~ZZcHm z&_(8q1iB0(vyc9|hja6fDP4lre5d(WcrxPcT%vXt;uHNKF*w~8CoeeLjh}kR>Gm&x zei8I+b-Uxu&Heh^0Y~n4sOMbs^}sh|@+?y}-_0IcAD{Tf2z=sC-W+f<*cLF?zlF}+ zmG}eZu954(%E6Lg7ddsNe2M0Nn)R^ApO37>U49>41Xc?s<#LD*cY@V`ZNrBhd(s~| zS8QG!>C`Lm@F5{jvZ#~gW;!U9KI%nzvn_7~dG+_F$7HGv?wml1;qe*c%HY&dTt@3R zlYqAlc_w}+V?0Y<#vD_W!v|%KkvP<bypCtKS~qYm@{H?>qhgPx;3dzd*G-LJOK3|4 z&y5`+<8hyX;QBN6Zr0=&;IelkdDA*%mh-IG7x`}f`#IO<*pf^x<oNOHzO;6Q*kUH1 zQgkfhxv@pU`wqP5f3b1kxV%O?s}JuUVkdF`qC6TT@v#p2d5^M3$hrAfn_drEgI3%7 zf7;H~l(#~wR&BMe6xx@)dO12B>mOSpzenW5qvb!abNNFe|1n4Y9Um`WY-Q46^WZr~ z+Izm2M=wF_-66|otMy_liF*ln+aKR*v6V|~_VT9VUcZmERoiS4eDzQ8jFs>m?rYQS zUYkii*8^=5+Gm9JK%3U~&y2O!WuC#JGxCJ4YXkh9Jm;tRck|VCjkm7Z$S)~lJ@e#N z>vvLDp}#%VP8VI~YfrU2CdmCdtOwzHUijX7){TL4iWxVu__{M4%w&jY+qJ<n|EaAO zwJ7sBc<gb9kJb^0F#E-Z(dE{q+hf<Y622sSx~@AuzAlMB8{t{TGm6bJhb~UlWzPw2 z%<%2`gx}6F#2Q83yxoxZr>)j>iDyCa!XJOam*o&910#-zKIAQWId?9^P*X$D^gu&* z>O-&%U@O3w@>19+SRWYSL?3bf7L{`i0c?Lk(08%n&vP1u2EHXck2zc7&<%J?cDu+` zeQ`DXa*jCIPrJmQnvvN`ywiKg=OgnI<OMD8ErYM+Ii49sj(KXJE}1z`X$})N8Yc$@ z|AX0yp$<MKwn+|<^NMeL@e|b*&so>0x$BbpTB&QrAGTV5m%9GFHps?V`3`T33B0Hx zzSE4%wa9FEeyjDA*y^ttGMUrGP^sm%@mj#btkF0j3$^Woc%4r->`vIm-*q10>{m5| zEqRIORfWjG7J_wyd4044tPd<AbQ}`XmxJ|!9VI}@C!7F7wxgk_UH1UAGx6O$g_cA7 zegv!r%v;Z9usSfzpbw!l+2~4udB;aN*vKpCoJC^nOt87HZMAL{=9J&-_{z-dZhP$S zO;B`1lKHk0mU`-5HRSC7T~72whFlyoj28D2n4Xtgp(~-?hlp-MM?={sB<4w&%)K_N zfxZu3vG=*cd$P^TJRrP!jyl9O8wi_Swh7tYsE2+dyaVv=E<W=06mKdgcK2kQYaxH} zyMxZf#NBj$FdJJf$EI6Ek9@bSjkMLB?i<f{8r_(HW<K<7!>l)??)RT|`#V*4I_C`U zfq^ydXs;7;>Bm79zN3Hk_w9PH4R56Pz{Ib%fNkcP>eo4!KG@k>EsjI={3Uy>Rs%i) zj{E6D>TdvB2PWro$p6h?!(c@kv9X0<LmoQRQ5|4|V0xTrzlcltmCQ)zo=YHVdv&XI zv)Jdo-+KHn=lbsRx#Ew+++pMm;>)^!euuo&_!5t_)0w;6dDTv{^>yAN^z2!;)uM-# zdAH4%_D%0zn?aVQ2MJp}OxDghZm0K#n~*b;zPeE4oZ+qCseC8<s<rSeg})8{ON4*l z0RElqf5|u*hCd1avBIC9*^c?Hx|ynL-Af2?@z<TYU+eeS&e44*b&Kwe@R#6!r-i8d zjubyWtz$`RYOS-IH<aj3Xchi0_!Icb3BrHvPWTIh`G??desin!W8q)C6MkN&<Xc&B z@isyIB`her{<_t=mvi%MFTcGHoF1#jf`Fl_V_Xw5lE}D8bl5K?1NW%o+OloO@S!1} z2TB~3IMoGjGw(DQ6yE76-c+p65>nS}!!4nJK;^E1Mv%4PZRfhzM{7KNsiU192;qod z4+(P859M+8_cm;`9uqy@@bc=E*5>`8pSK%YIfTD$D&ziLdk@wh<4<t?kNr2}=k6Db z<DTl+vKsz%e@n*}kvRl540gX%;+r=<UZ(JuOk;lJ{ScppU&hr;>Yq=W&gI;E|0$0> z?LN&l{|IjjyuI-1F}cR(O~;npW3mz69(ZffJ07OqtKik4$JvjzbN8(Ms;}qBnTA5_ z&m(gbnbCi2wf@PTiMcq3%zneWhro+2gY&R{1A!beCoG&!{<A%umsEgtfK?>7T89b| zx-(Jgtqhp}q`a5%2FmMF<?O0*_lwLAB6C2>$F^FitPkNC0c!#KrXX78nJFGAPg35I zqg-TGkhJtt?#^A(M@8_M=-$G)`C(=s<-T503w=Gj>)`#p@cz!`_2wo9?5Tu=j<?V8 zdg!I@KJ<yIZTwCPhdp1V#(X;FoaYZY2NhRKTQ<VG+}P&3ww45I3G=M7$m0;Yk}CQK zOwQ$y|0}^-Gq4)41s+WFn}NIz`si}bP3y^w@n@v==Q1aiM(F3mI|A<;!uwa7H?_ay z-*fw^zk%8Jph!X_GFM6a=szv<*8jUq-T$<E3o>;ZPx$0*tVW-Dc-QUV-8<68{ZjhS z!Opz7!0mG^1dX(z4W1@ztJT4nG^eL{0{Y!}`IFd1#`O>~yYZv7oSPr5-ia?6Cw&r` zh|zx1uow0YZA-0TO2C`J=4W6F!J0F$4zPJ1tQ6kmU~@f~ThB`HMsO}&>O*Wh0M-C@ zydd`2z^<~Yvvaw_Ju|70B={uZSp?4u0%VLQ$pTYTsPRC+4BD*QoFJh#8CRmO9Ma|{ zur4q+Zj^(yfOUd>QHY2|N9yY%HvJOHx+ycIj6>S93{1vrhX9`Txcf^dc-kZWF7*z= zv#em7#U(a<NWJU9mV)gsh>n4$>zc)v*U^6IuX8y!!%ukX+4)@62z@DXr9Hdl!TZ|d zT6Su@x_d?4{(X?|<d|<HCy@9kHkupVW}PSc?3U8U&I=_5ID6p6A^x<C2%xX|4ergH z1^?IKm$kOO3Kl<@8N%Lg-b8shwm{|7A^m24o_+wAZBh3Sdscu8eW3#iRt;7PHd!!d zJzoc={yA#jPv>BB!HS^M>lp`I05$`R=ITTGryZ;kY!5-`AMd>;%N_c8Qiczta{>Ro zCZg8>wDXYT`cMVf2-sY(eT5&{sIi!PP4t{8btfrbL^<1jj&I<VoYD=dd>>*DW#4tm zH1E$fFXQUFwh+q1e)2B2ZfK_pt#gR{dEl$SwXL-8&C~Kl-$j(IrYzr~7p&8vciSLX zH`q$(A|ASxV2K#-%<*6YU=3hy-wN*tSUs3K4h7o`RtF~Ma>)NCoh0&HUKtzZV6|XZ z3Q;OH==BNr?bz31j1&ESxPNg%+pY=TE_e?~^QL2b!j19x7v=5H&K~F3&h4XPZS&Sr z-iE$w@oBwI9KXudB`t3!>%;{7tKn}#mr|V0eB)7<-yTys#djOik=YnY^YxlnHZ-aW zd6$OBc+@MyUhg=2XZE&8cycHpST>5C<(+!+?lSEUd>5=8Y>5XGe_9IGg-t3sSLArd z;x!97?LZIV*VhsD3(_Nzj@c(?X>o9I!Z<q%rPIEf1wtxybBK<WvuHp1uvF5AU^QU1 zU|wHs0ILCWeOmgLw?6Cs)iFtrfunT%J%Kjq_ET<__<5FsDX?b#lNfW7aKsnsu_H29 zQl8jJ`7q_}Im#R0AHu%tvE$w3<YwU`!Li%F&z~!F>wc|cQfuU$a_;z%cFhHA02|M_ z9D*$XlXuV+X~d2l?O=7hKkj|Oa3tez#nDDi7t)5o_eQO2!sxj8;UFF76nFX89=qn4 zU%F_gjA?l{<G^@lzB?P4sd;th^PTXT=vjnKzbEH&Y~FM{Zg$tDS@(;Gy%X>@!~2np zpDBTDkqcp-OR?d-a_n8T&P1NPLsDV0OZYFd4S2Y3-7p)H4bV43zt*8gZyB<3$>};* z@yzS)(q9!{Vm^gW;(#1dcQx1+um=RdpY8RF+&)O2#kHv0-MoZ_naF5{ej)D#^u}*_ zhh?h=D~GNFYynuYBX=>kkI7tA$ESy~X3Cy-$};i{MzGg*#-l+iQ0WJGN9IQ4#PJ75 zcRP=^^OX!a;kR=1K|<7!w$*-_`E6o4ZxE~zY%Q3MU3?dtC8&2jnCNdF`H-$#I>4EW zF}>03%&d(<-wJ*EZoErM{N?M=+jGC9q|#@Xru(c}>#>$POZMF6+xuS!Rsl91d2&eH z*aX%ACUr>r7aQ}7qX*e@jp$zV74k>Q-ToFV4z?6b`a%xD<XxgAll|kp9;^t=txxFY zfwg!r@kM!`=mxM8InVN4?ikcVQg%#J>tDOhUid1eq;m{u&uXw5uxgQ|+jDAaeJ_~2 zo3x(tGo;+Mq0F0N!@#{+u}cX`E`jGFhsWpNJj?Mjk7kX~R8Yq-efy~N)dRl?@~b+z znZPr+jeCL|bbtMrieB@HjS}VCtnCt?&k2;7wU_fj4ri6U9Eo3Rky)|FHtRIb%}bE! zvqx&*IxBt&uUw?;hWC8oJt32~&2`5>-dcFg3f^}py!&SI{@CTs+!E01fkp7vz`Ia* z3p06H1?1RYhg^@lk+0JK_}V9llalimeU1Gd=;w<7pM4CT{nEisCSrZfwg%cw(0-bj zN^?{zeBxh&={nq4obz5L=>vKH?Ys@6pNdbaka4&H-bCC#Hb=n*!AJ%4A#_C~DI3Au z*d<sTZ2mMq?`*K<46Gh3Io+R=&jX8A`gvQy%nWP^SR+`Gt%}xp8CV0D=pcvKpaY%D zvE2!roB0o9^ij%(1AS>NybbVPD7>%TuX*jU?Q9V2B#)N5P4r2^ugA|FHh+5lPt_eb z2IL*Z)!0>!pYt<$cRqgF;9Ur>uJ^c1UPG(EBpi5+X%)QkuG<?WHtiG8<}Gf#MeS6) z6%V)VJqmvd{d}mjf3M8CPjrVwmc8qtpN-L$!^>}Fu*Y<tKQ6MCpHtjEL6UXnUiq6c z77b(%`$K_WAgdi&-T1<&iL7@rWVw6W>wPgc{B(|I<<?^hkvWXahP}60pBI@g=a4z% zmw8MMnG$2`klDaSbIq5xS!Z%C^HD~gBIDdU4a^Oi2E^Z&BBvEO?*5iwy<iK#_7vG1 zf~^Ky1U6nHHZ}yd5X?J<H-L44d2_H)uud@2Yki2kA~p&-z-Ueii-RozD|9d!3$wwh zzqZY~OfWrRGi~EQTq{fO(eR`oo}^76{z;LJoAO@lCGcLE=9M|w-lS`E{SlX9YS5xd zJj9>mJ=!Dim5FlMw#~@hjAcQ#g-G|k*r<IUVhaW_3;TlPWzN~*Cv)7xvjTl;QK=IB z7JO-&^#{()*Y5S(ML+A~>=|S&vlF^~^Wjgz|B{TCd%gVj8e89Gm)ejF|0iR-XbX#P z%N#R|Le*d2X8oA+oc(jGzkhW9e~a-BpLb4>_lPe6b7OM@BITXp-EWRsZS+k*Uu4~z zvmuA=+R<11sTqCa^zE^noBzH?>zt0QxvzVP-Iw!c3%sj^ca6<!kGl+iJl@}4@yAAZ zM&Msa`&wn4c?0~}zD20=KYOq>$2zl}SW=G6rf)OezR5dhITv}0c{VJ1U~x&DudS3- z&hhTY`tLE5epm|43TV9Jx)-bu%<YGH(5(iOcYnXld4S%TV`5d%m|&-)E(jMrD)ys) z>iv3DgUtqW*ZQT<)qz!m?ds@pC@VLyZ4LTu{Khux0)mHm@~?w*<X*XmHz<Zz7X)du zKV<ee>qKVdLA-w*`Q{VIwBt`YhRk*2M(~_A2>%xNj}iVmZ2q*br5-`dn#XYy6{Vdm z*!x$)drpd1Zp36wk>bU*JeRDiA?6T!E=VvR!|(0acCfWzVn;cIZfSx&8ZbGRL;mkg zkgsK6tHDH`+ZT<{^`WE4`-0f~-@U;$Z};z;+>*oQ?ZhG(?}~c5kKkSHj90TTupcw# zw(yZTmLvMU&_?8`Cf-Rc@?HznF;m`wx#Wp$<hKPjALU<%uLEm1+MkbZ0+V;ePk~1c zZQldPZ^5`Us}I3S!P>#R{WJrt4a_^Q)`Bg|plbwM3Z`WvOa7k^)&=H{-3qWpV4Yy! z<=l=Db{yc%4thRVh^}qeXgS5^i+5-H`FC7DXRb`$RKR&a9@j7SLDr!n>ndAT+UHNq zna4FkpM<v(+kO~=_k@%l_Pz<8p5AZ`pBVZC7Yk(^iH+7Dv&}kNWbTK|RLmu2%PxnT z71HbJBtoZz%`#tf!5{xV`HTVoloUTPz`Ylpji^&xQ)oV!8udIq2=A6-w^?72y7x%& z+WCw3ncPP*tG088q66VSj@T}BPw?_HPrJG3kbiuw%i+93$PoWnBFW?N{ur<ftO(5O zgMDC8Fn7EQZ$H>lFt1M!gLQ+=q+AZ6+X&Wof?r+|tQXAnOQ9<{i2b$<x=OI_46Fuh zc?NF-*fKDYBZvIo4A#W^{Po<xcisQg+xP=#Ew=s6Y~TKvwOAMYo8dnVdFFFAf7+jS zz7`vVw-Vc&FT8hT^5$NPH9{YyEd%f#6oL1AcvF7s>HDsjZ$5h_N8fkFumLjXA#?4? zw50%<H{_7n?w5I1j(cp{ktw<I@WK2!eVb*7(`W0LnHQW9G~>z@5b3}89O7ZC-*0Av zm4IOeeI)o>4^{-$fKR7$&Y<f<#|NdZjq_lW-%^p^czB!hPoVdw&Sy3uzZdz^E;(=o zZLlRj=RNd+dUGdUI_F*=q<9xLmVT^6_VNW>^FxmL^`0R8^=)~c1z`AJfxdCDez%Os zT!hRh`o3%;Ge1yf)_Xm^pJR=>89fuo97N{)Uu?5}Eqaberg#0OHFO^|JKY<6_4-2E zDz=;b9rBZN(sQBsTs>G@8}IQKJ7)V_=6r7CNTC}mU|))?=JU2$PjJpPp#<0e@LA&~ zxga3*ucTa^pYBJ&2EdZ=xUnn&HUc&Z_Npv$y*e>(i9+e^hj$GBB|trAG?vre_#x<X zA$v{|biFd{SfAOa#&JP|=^(l^d}d&8OVNorc~l^eynV=+lZ$Cyt^(t?xk?WC)CGE- zSxZ9Ea_KhfWb7oiAqMMf6wJQ%#;!eOb3sNnPwg+#zYF2(zHFQIQ_h9Yz9Z#u>E#kx zKP{C+<#KzUPs-WV=dV3pS5VgUt8LaPnSQ4GwB7s6{pkUH+AgZf95hV7)-nz*<lNlr zHg_DP*AY9JgX-WZMURn-S=%7c{IJ{g4fvgB+AzY9F9m5eT0P$ncHRRu4>=35g(2(D zH7PlEeiiIv;kh{mj~k1`M%7m^{}&+hhCrE_af4eAYp|f6$Kv*;jqWcA8!ExaY#_d0 zzs-6YyPL-$(;qi5yn7$P>7K+%hYf9W*i}7$qBn7WkJ#*s$e>rV_Q?F#L32H?)GF(x z)rYahT)xd>+DjdA&g3_ws=@aclsYn>;}V)tXy!q4K#IoyPBrmU`K_rAXf93B7(aDf zQOyS{N5&}SS4(@&zcsi${yo3IIm^BP7+`-MFA}@8OM7nFW_?p^e_)P!{O_3K&hY?w zykkz<wS{)YyVKVJ^}RjLvle34(!;5b@-J}i9ui|`g4csfIF&=N1XvxIn+pim1eO5X zMTj^AYXNHjE7ORLwSmp`@Wv_Y0&4=x)pzrtSqV)$G;fQnY#++ZZvt(eYu{rAB1;?5 z?>6ouqhCcnagFg}ES8t|?Gti?nSGyB0@}*kSsOdLXj-oK$+hrhX;Qr}v;f*(XwMc} zjNUBH6t~yd^J!Dj9owu^F{F9z%|Y$ToI|h5v8|@xUm!M`*}KiU$wc1bKzZ!F_}3|S z=g1xU@jJ1*{D#@0zW+aV7a!?Fe)PWdypFk48-GkNomaiTJlHOzX`eK&l6tmKPvQaY zUF2L2!J<dd4`A-vO6nfvPt8lCR=Mtzz`C=p!+tJ@4TtchYGgK0_mcbh9XQU-#mFR% z;xjVuu!nTK_86ij3wa1QM7JJv>xakPBN91FkuwMulGrmRB}ebQ$_4JbT}fO<5jU>j zvk5u9v~fSq?YJm!-mnj;r|3xXD9XosusGOSFt=`@n+-PPv6asMzy`tI#8(2wWaj-X z3v*0its-kFvYH><X5EpQx4HA7e~zfjVe(dqo$E#ahxwhbT(TIeUf)@iL)Z$8DDvd@ z^eP|QW__7)70}Kse^{SGp7?{r8u^{Q*}voW$i!~8FNm$^!thTGw+|_5<RicBw{bOb z6(=>%U>7nw_GOLf7jgs%8Pg(j1evq>{V=_^cVM8*%(#<tZx3-gFKjxBIR5OXzy8n( z-vE5>yfY7Z@_U0#fB63sb9DQ${}Srd`~N507;Mu|vHw3CotuuP{pft67{tz#(s^Z$ zdt79EcEUFR->WiUb>0#l4ml%K#$6xf9fSVy*$=h^%$<J|&<%sNgMHSuxY%V2cJF+_ zS$m$bEZ8oa{bOfmYtK4l)}vSX%g);K=g9QukVNsFuRRf=<Kap+?@L}yul2+>17Jm9 zaxO<LpH<X1_Z2tCPt}+1i=E{7!aoZC0Q~DXH$S|=V*~an$(G%HN~7D8^6IqNzSdcT zPA%x9_ZnY=KjjO~8iD(X-f`CiI#q7f_fs#O%XOmH(tS$xx;^rnlr7*4SvOWV^TrR{ zNWr{ujOW}vwfQ%}-|-pw#jZ2I&-?+uxThTDd=g+iV0#OI&$3pNGu=<~C|l*B7a6T! z=Fq4`N-H^#-p^eE)(zc5j^C%Q-+A|fZ})CTU}UF`et0YYoW2jY8hjWm4tA&1VaHU* zPR1p!MF5U)&t>dIk7fS`o^J{d?a(>#*?QHg;y^PfUrqT>q?|(IXq~(r;ZC46zzxtu zU*Be3BQ##$*1qCg|K*8L>b93yy3g%rH#*>5053~6eTc2(w@F*T+?+(P6=3thw7vOW z$!9HCJJ`XTi|*tT`kK_m&g&e-S~Dry1YIw5zYsc)FS^f^{Mh4*Qdh-sjDd{$tHHK- zFtJ@7*k-VAirfs_iJbYAm%Nc~M>SXzx)gzpqtDGZmZtUQ9!FB=D|O%KvD6H;?N9QX zsvA9WBv%j{Z2<cV=jNlfoYb09?+NI8!tL8kjC%vN1QKxC@{8t?-;SjHTXc_uEd=wf zdE~cSTQlh7cU%{EunKtPw_97lek&Dlw{pn1MVzKf++1Y0QC|L+^g5{xtP8B}<x%Ut zTzQmlJsEy4$2zak_)*XTkOgJnzLEVNi$?0-gpF4Yj#@>MV_bEu?w6E3?ffh2{U&`m z-Z|P&LnX(N-?nYU4li=<jK@@-y4D?p6vg>0p#58*J%w}gWa=kW8gs>Ltsu-Hd{!cF zXn54B7enH28Tv`o@TPQM473rf(g*5z;>9bY`aJ;hRj^X9_2^J00Eb{Rz&3$R)`%VZ zYQaXqz9txYEH=(a#U=S2-ip8auRksTYk4a@#%1ibgEhT6YMmr9{IM!^kE-OIOK9^T zb#153=8;60pmzK6V&lyq4{+Z<K8(EOZ}Myqer8U|A<yq?$v``@c_FGxd}%m=>p$y1 z+5MK1C$&L83jLr6u-h)VrYv7_-U}&xu@b&6>{uau90@)>*l{`7^_-h0U+u;>`?{Vt z{+^i~e__$<qoQW?K}M+nx<6ClUHiaH%Ii0z?}ZXw5@2;1SQA*ngVjRU0#*z5S>|qO zXD|Ho;1~ZF-6X&p-2Nxqs^Uijly_3zB;~Fx^?eBjSBkZ>==<?EL$?+>*S94vGf!kZ zft@M5npE!RN?p^+$p0CQ0b5IAiw5LG-%aOWf;EGgU=u_(huC5vSP9rN0ql9mu208n zy)W;)V&wvVyk@=>{*~~z!v9%pDLQR|zYBivTpMKoc6#&_x(cvm9y+PJ8f@ujth*Zi zR`^%KUl`(x-FDIe=UrapgBv|_Fy_$lvj?88zis>2cZ*7_9fG#*y^p6AAD7?Q9)(u# z2hhv%9#X+ePbL;`%*JPe*Jt2jr#kRf@FLFT5Ns~k0x)-7BG>}3mJGUfunie>OTpHI ziHYP8-d?Z~uw6A`&jYK$HiA7UScV^^uiF_{f81>eB0oBx@%8s@)`5<E!79L(fqCn! z2I~Rq5xP{J?s~w<@fQ1I49}<5`4PKKZODrL!@r*E0yDu(j~+c>3T(0mTLo4GCVI+| z;4=u;vdMlvF0Gq;4VL9q>RP7pcGkdxU;Mj-iMR5f+pNbp&z9jGo403)5M3JK?}2|W z;pY%+K3G546ph%}BCy(jr}Y=QPOus<Z#%oe>N4n7f+fJb`&0vtJa4W%;>h#XyV;TF zr89qM%Zq#TD+g<!jtUPp6KrmVehIMoU|!xPuvW0IdU#vFmV-@lFp=8^HVSsLV8mSl z`cn4+7K!uADPOdi-=LTBl&{(S>FLYgeG>oPh^&hL`0pQ1g3SPPeModFIhFngJ6!6t zb>abP`$Zd~Q#IvHl&_TX+&W$RaXRVtBWnOz*NQB=uFJf2EvLNxga3P7(!PzzT8*qc zsf$C}k_1}?wpM^tTQbJ-9sZFUG?t|;^)2}Ghu*!_pSexZW1xldd6c`cM09Ec8wGQH zLSk<hn7M_0d(O#y+a(4HZ7+By_@07u#QCfSTLyN70NQ@PaO>oo&9@$!VQ9Q#Y75wU zFt2|`e?&a_ub-|0tQ;&V@;OA0YOqqUN{!f99auHkbO%fD|6H&Juy3d5InNyLjYaaT zV>L$C#i@I~rLN`3sQ;gT46Xoc0*g3x)${*autu;B!BYL0HBL_T*OC3+5bggzW`0Lj zLS$*1{@k^x-G0i4Kl0nD4s1Qx4B_Dro#uii!7dRXw@yF&IGw}}J;+Lo`s3Xyuv)O) zL_UYm4T9B!xjrt~dayb$@7%n_kvCNsIYi&+Y4|5}7YmSE-%~zLUy;>>tZroKxRzU1 z+sDZg{kxI11zA<17l&Xg!AiFJW9|T01(@4*>B|wYaxk6W=)Sa{y*`ONN8}_auc6$X zM|A%$U=JItnsU4U)6W!2+o~zAqx^O$&)v2QK1ti!kkyMUcif2lF0i#=9Xpr*vA!(r z8$nidn}7Ul2I~PU5cwQJXP%Co!6g33Ay_$B?e=uM65GrKs|QPP9yB%@C~u+M^+{<@ zGuT3~Xh0nB%wg|+oV{iss}ETN$!!+fvfB3P>t?C@_Q<7ee_jV|-`M~Cek6%=m2CRO zpBqhG4`!ZTQXD;$7gpac8xti5;!m~EH9*&5ZL>CUp6MI1h)SnluVh8MI4qs;k5W&O z!58G}HD377A-%|BF(CF_0nLWrk6KSUG+BEe{xy4hj_YiVvUi(A)?D^_E)`kqX@<XG z=uJ)C|7Q>ninm)|p-Az%55Z=Ft$HE7cPm%|Yzx?lLdVXFU`=4n@VY)Geb?g1dtK;g z+s@uOxfI%x@!Re9*gz}K6Nqp2fk!iNk-ZjNfqxR&o1t9^?E$c$um0@;ksWPie<uKs zgIAVh)7OB{%fO}Wjo?ecqavR}_J!wzb%ALcrDBFZ&mb6PZVT&i*bVR640$WT`oTzL zJ$~kwXC$%(HbA}^-YxK+EuDjHGyI1esQvc@bVq|$`~02|K2w5-1e*qxyKhg$j%u(b zuxhaBGUn|%(raAqp)f-3B3EzlR*PO8@Fc&o-MTrP;_>c5=o`Den|jqbuB)!6PLa0` zc@1CRZe4HYke6}oDxTvy>1IdXjI+o`_T6s%JC}Y#{%c{Ya_A@5eMP@T$gACNyLIX( z)URwO`blgaKwjG++pU8*7n?6O+I)G-M#}prck@8uNrJ5ct4r~u->E0%6=#z-Q+{Zw zJpE2S>HAvB%Mab2T0aQZ2v(Yb%?B$1D-t;zLbnL4$U`?1tP?B>=E<4x8|T@;fcILg zhQ0;*H$*7oN?-S|_YZgadlFkjpN8$9YTt1-Rm@z-d=1~Ht#3YjjfZXb?|<8RcDs9X zneX3_`j*4D5x(cM+jq;(_=e$Y|E?1c{dT!`XM9CJWj%QKcI%bw`tI5pUmbiy@C|13 z<=n@W_O-#+()j85R>G&gw>`CP^YnYp_nAn2o8Vgp->22H@@K@eBR+k<&x5aiVDwY_ z%To9@!}n?R9E7if++b~XKjgHF%unXe>A$14TlW<4#r2njz6WKuSi0jA;ZqFHH#^Tt zz*~3HcB_3NyxH?f=6yfUmjzEJ`o5n|WGz~>-TJO9?mk}DVL3u#tNe!JI%Kt-OKg+) zYPU&ZiCkOo*dlHmlx`7kSaLSXp`7PAPrW%d13xJTjhEhgeqs)KqH4Ngejimgoy0Qk zW%i!uQqD``J@?Xk&v{ldRafd30_sgYLc=-Fmf19R+^**0@xu1)b`FkdC6?EL^@FjU zq7T95f>m6w-M${dcNu>Rz*@k5V&|JR#?z8+*6>Dm{hz+gzs6Xlzv=hj;hd7+^}yG? zc)Rrx=aQ##cez++q5f;X<WC-(({&6%yKu>N>sfpN+H#{wsLFM^S#CV8zv%nP%QbsB z?E2bI^q0&>7jL)zV)M-ie>WtwGkDvMe*f$Y$_FpmZm-Kk2VP}|4!Yh-s;Z~Fwqv`! zf9&(Ob5aJZhprX6`Oqy0&Lc9eT^hFr50_@WW?zl0j?1@OyA&cgXuSBZgK|Gv4XX(D zMN(TW_62t7ujo1Cv)8BdIKe8wTEH4OmqY%q23t5KY1PWO%C0jjPpi#w(NOZVxrk^- z-u&rFYin^1d0k=O#oSAaikF4=FYXS1r?@K|UYbLCSGW#wBgl?^IcYsEeQN7Umq|Xs z9R_dc=O?uR;yhX+8&7=UxnKJRExQ04z*^aco?l6(-kU`Cr`}DUpuCRqF3SJOxwGzb z>bXju3P$n)+F7{$ApIrvj&yP;*gB9=J3Hywcle38v>snQlr>Vex5(!Z`c+^Hz>XJy zXJihM8WJ}BFl8$!J5b6vq%SvuZ33I15gSW_je@y*CPG(oF8SNqQ9I{Du3(j5?O#i# z_S^)k0bB6(WGbhVaoPYj`fV`B-rOh<X080HvwrOl|5%@CeHKAGvR^WlkBZDru#I5S zZaD<&2HW7l2nlK>*m|%(36ZugW{opgx%)Eg-a}?Q;a>njD&uc6yi0yJYE4M{gm;~h zdGGj3!9ymYb*nuOefLk>uNL`@U_FN<Gv2+BwHL|tpwuAL&Qa~?*9HGD{I><`mvJpN z%tKm%V_LtLZv<I24awBKD`LCNV6(wa;M`|BB7<wXU-~UaiQN}7&u7ef<W(Rd0cIYS zwD+(WWA=M(57WL|N_jKorIbrw${74EC4w&kFUr8Bf4abDe?MtG?9gYdPc!>xVQ}*k zI#!J!s~1^QbH!S=p}lL$ALj^=a>I_;Ze~0A<4MWXy&AS|{&n}c0k)e7ZwtI_Cnv3= zrC;s&!Mz72yl2RrBJ7*B#a7Fp-_(-sJDETGz&3*Ym2<JBeGk9_XLwcDyC)<y63cYI zNzC5Rj$MD0%ze*t#=CR=kz?&DF<a)k*%uHGPEYG$^h#wVdK#C_8qT%7=0R8U6DR(9 z$EnBH!gZl6i-{jBgLm~AN$bD4`p&=4b#RWZ)6dUrKvwJ7=o_3@X3bew<+z_o+Aq4z zzK}n^NLrr{)-CIOA;p3Av}Ls;Yr{E7YqjJ=7%s!#`5`+0{MQ}WP`h6Sk+tspr1e8Y zrTpUz*B5@GPsF#jKo@UM`<ApRx|q2R>?wygLyydHcU`V=C-R$+l~^-s@Bh&z!CJuj zE=|`dSQ}Vx2G#}E<H01x^nk5L-hrGm*H!B$1*_BZ<66qw;fYB(#|%E}z}mpr26k-G z$W%1XF-D_3Rw$CW)LcUT3hhFNmYoxEVLkW9DXY9JY3H%bhr9`n!bH6UI2n@(%A0;W zs_#4U#Z!sY?jvy-_XFto2Ve4vq<syJgo0m6)pJT0_>!xgc@aEL9X((xZcL``{o$@8 zF39R6SnoZHEeD_(fySN7rB6q|)`4BixlcFG_{(@L4j09^zh?&Ni*^7>T*&!gpK%fK z?^j9tnN2%>NshyMDs`J0_a3L;$tP``2hYZ*N3GqZek{sud^&zC1m6rU^Q99D9a#(A zK&WlM9J+P4JN@FuOnpz2-N&mbAMJ7M;?wCTt{mjrbJs>_EAC9D-eV>DCBf={owSBU z5BbRw{*yRgdNDlrB(3uWNR3H1&O2``<8j`!nTWOyZzH@-_a?0ozWZ!mC%^LNI>hfi zyxPQizUqW`6yC6OVya%9uXBO4hPdM2o6YsSRy(mod}0K7tA3NT-Vcj1w!dx$Tl%n1 zKe4_2{;fwm`6;)N>yS;u#8xxdl&gKj$wARg?(>$hnE;=U|Id*M@Yf&7@Q6!K+d4E; zJ{!JWrJO_NqlI7zu<r%OJUuUZ=jD5IBsuL)JYI{u##Kq{L|=cU?3NL`!igN>5@NHG z4)l909jC<iE5WLtAg+phZ4{QoylbRA&$e5*DdcWw>&~o$Y%V+tRwu1}(>!*b$=K6r zYU*N8cv2|qYS8{9viAJYjhy*UCav9q+m^Xrd?z?AH|sv!gshsU(z)7+^pf<gc`5b- zmt~~*-FLtxE>?iogEu+2!G$i0^%$w4tdp{D`t)Lq*naK|lD)GANi(t*!rQebX^r>s zrur-Enfe!l8YQnuI3}pTj@#>~WA)QX&%F_6Y2|-F+v?F_l=9`TC-v`{N}Kf_B70sJ zbK|sZc<B5oVf@we#oke|3+xB=IF~U{cNzZiR?<3-bCI>!SfuOX`A$7X=2PBE`S(-h z+#3R&l#9<Tp?n49&M?*3GO#`mmVmAgto+@i{a%EWA2KO9!}oHJ7wYF*<Fv{i#Eb!Z zJZ?tDQe+e$PmW4H=H>JU*!50-=wEL#coVm6g;ZRe30?HPr1hpSrs{Vpzb9Q4KM&wk zYd^*~8}b%-`{4bY)B&%yx4j2`aXMHxrY8_K#Kkt<@HPECX}^z`?}Dua8v@g9z>ea> z17L$-dvh**An{3J`FijT;J@+38vK;Z%5Wdx3EymZ0y4d7&jS^m%s;C~?R_V^z4kiO zGq-15w`;U@oD1*rC!M(uJraBtfc1jOZ~TdlsT_-#ARDFW_feE(gaqw$tutU-fs74L zjan~rZu=TH0ZTf-b{2nA&!>xzk3c(PN7BAO(p#T>AAd$%<k^_OrDQ_ee8v^D2U((n z9OC!2V5`8sA^`Fi8|<bz?~|ShG>`Iilz-1@ukLf!T(bSrnI2fOywY`aLLXIQR-Er5 zPxn7qDVW>Wy8ppSz>0*9L$Cp`A`jLKHUd^39<$bS?z6Yu{*1M>aY0b~c{1X}AY5*H zuSRU*O8jvm`Z<10pE5UyXnRWa-_P5q_q-Ouv-#&^)>|^*v-{<+;`U>F>(W^{Cam^j z!rw58JB~S^xa*ihV3Ix=LiUn##`NzP+kIl(r-Kc*zKBn3rhInWn6-;<JmieM;nBdl z?YXJ;D*EfZF^g?BHy)(sxWkJ3k51q4&{{lj^Z~^~M;`*3@hhs#m}1BI=(U_@eh))0 z^Pv;9UGzSivDOJgae4OMj!1EGQFxZYGh_8Oi_0F$yvgR#K1Pm+i`l!|dgxT^STF$n z#;5FekD5P+-i|}`m%c7=up5UmU;bAs@@Z@B8vFhzbB@hx_qEf}b38H66LwKmKWAG9 ze<%Fk2q9}iia%wqw5^QW{Ch*$_o)#sbbFQ|v*T&!y_tV)&S+2W_hyRihT-jl_W;h# z2Qqn6IX$MZ^*6hSuh6d%`pa#4Z~XG;f7mD0e=ah6*E;W|J2X>=6W#7$5@91>j}yr) z=?8RJ3h&H6IL~(Ok<v%{(jIs_dA73={$cnx@qDY~RpxsqWcjbBJx_j;_J~e1t|lH1 z+wTi8A4the>%_GbJ&h2l;~738{4Ma;ykg%oXr2?mpV~7H=I@2SoaZP>hj}N!r{kB{ zuo3<N`0o||3EBK4Kq>Xf1=C+L+9LLyeGR$(8~o-$F|uAeJ}A!VG}xQxPc06Pw2}*p z%noEmxi{{VU66T04w)<b?`oYfE?DLY(_V{=AhR;I-MXJT%m)HxX3P`e%E0X$CWHob zoXKK)$v8*e`TsY0(&jdiH+8#p5o<#8@IZMwlkwW|fE@c*D~PSt$Q(ju|6bem`<u<_ z$h32tw4a{r_N^Xn+V<vB=GWQVt!u?j;XpmI)@@^fdsX%xr?hP@GUv8!x2pC*<{y6$ z>?7^@zPYewui*Y{&$oS~51F&?-fkU9|C)0G_00O+m`IKb$z9k>^i<a|&)>V<l4qUG zJ#xrwFZ1d7;Ndy+EVKQt37MUHB&{Uk%`+Hl*?B<5+V01}0-ITXAfpF)wG~P07Lm7a zN**2PJX^$s_+2;ZFemb}kW8=kz;&ib9alFYrw2KI6FK8kF~H4x)4zT7D^JGE94-qC z?f=&^m+zUho{_lvexR)~$J051DF)+7`#<tFOio%Cir+nvLmoRTUjM%-hu_IUM&jHM zGUL;d)-1_2WX#+CpPGv^*5?mpB;&fZ5|gC86*u5-pG#VIN_)@Ap`U-R`hZ;Rm9^Lc z<n`=j?|GSr+Vb>1f18v0Fo1D!wG_G}bQ8rcUrDur{?_3@&w+DispDrUet~M9{H4EF z8RzrPp96{q_zdw`$7elDt`){%v(yh}sRgstA+wZm(kun*cW0@e%u+|rQYXw(^Jl5X zS?btX>Zn<&$#olThZV-zv(zz~Pv^EXml3Z%pS0o;^m>Rfor*22Dh+#XKEos7V9@aQ zLmuP+K_-Mf2$y>enyosJz41#)>kiJ%GrY2$IsXiQ+?oyDYIs(14ft!)KXbf1&bZ*2 zyOqAWs`Yr<0^e$`>6*efJ;j&u5m|Mows4H!1nl70<DvFO?7=nG7sc1!pZ5vId3a6^ z_iawlo=)VMTz7p<^m-0?Dc{w5FYT#4#_-|Zy%*hAvR@`XJA{nxnxwUd$hbRDr_8ls zcX04Y=sZ0BEA}_O!F3*Fo2S|G?A-krH(~#ddm>}H5qkAa_5{TyhX&T4HJ6;5W6(&O zW+1KynS=YX{+BjQuw}|4_iXxK<<za$nY#VZ_9v27pVS}DQGcs1q`a7;`d0C=_)UBc zOxnLC|3`L#Qa&#s+)hXD^7&Y^zIHGdzKt&51D}jf^zVXiMV-BOWnK$k_S})#e^##k zOCWDO@~RI`+Iin`DLqoY?s4>-zh_>#oOm?HzQ$<om6G9$N8$hZN44Z5HPqh>Z#UOQ zALZN}@8{*VTHAo<_zXBiH*4PI@K(-uc;7qLV|$|bPI$!+*TK8-6z;iTbHQ8#Z?+w? zt_?n&7i`J(C?xTF=FRL^^^Dr@jFDe7K&Hfsv>PV$Z)-O}H}B3->k;wS_fvY?^DLn< zeILVj{1Yt!GaSy(8r$8>12d_=54rR29<>r8_aR#@v%Ji?T&oG2q4Y{h&#xoUFYFz) zo`u)EDMJr&U-yzl#uKau7dNv6m_h&QRiJ%`OS3({R^P%H=i2R|qQeQc4ZLebJ-Abw zUB<iq;Hk5bc3AaX-G;2D)}(cojMeGcvUD$}WQ8Bhn5(rgaTb~P2aq*z7W2O7^&!bz zDt5B}!J=Bf*diU&$NYNf5ZW(#wecyv6<c#nc`woH31kKNj{kZMbEk38EXA)x8pqG# zMu`q~?z(t7znyo<1n#`G8$!?g`qNqJ)LH7xS&FY5GG>-if7?%!*3YCZho{=2#~bO8 z9y2lp#64@XZfFzm4#C_1GwuNq-sxW5nM1S@oENYg&w6@Tn^L!5{H(N_{k5Mbtq(Xi zKb)&=NmbOZ_fmS(ZWh=2)<NI5i0c?)uh(pPd;i2UP6vGI>M<_yt{vX4UnZ@7&do>R z&9-%Byt_Tvq6zyRLF6f}xgRO*KgX*}`n^n#`&4OFaaf|av0rg6^Oo=(muj=VUcunf zG&7;;InSY)lT9Oj*a%HG*XhHuM)^ucd+<Yj2_@~*YYe|5>W+}Ulo+-gS@Rbs^}D{z z=^3)zeNG(0n;)Aw5)6?keY+W%>o2meIhpyMHni%#<<2?X0p$FxI_AZ1$EPk%>StEX z_m6R6UNbT8d}r!y)^zpI^<I*+)>DW1GIXAK(z%AA`==GU=8mMbzvQ-SY<a2p;kIdo zuTA=WtiA9J+-%=(l9SJOPb9Bf2pD-1+kO^Q!244r4=o`9U4LiNx(a)l=iBYjF_v^g zg6t`tAln5^4Lo)5)ZU%6-jTMSYPU)AH0!;}L$ytH&o-y7Em57$Mcd(R>`m%De{(;- z-Q0IKo$K*eb_|d3e8r>eyl((G8<BH`fewW^?CQ^ZVmVwz=RM^;<X&8_9+NhGcyv&I z8h82>Nob#Kgl{u^M~sK>J@~T6Gw)mV-}lm-V;^U8n0+(q??Gnr@udBJ;$w2OjsEeD zgHr>OI=QfDycOL2T_N57cjBL1leMJX`F4NMm-@09{cm)o2Z#(Q-R3%YI=SX~8Ty*< z=V)`rdj@CcFn&96L-bgN%mJ=({!9GukG4!bw;IL^&cJIAxtVu+NY8<T@XUWEX?2PZ zJe2CQRIcZr1H)Yz^J!`ltfl_)yBN>UIevMqSC(Fjr1uJzd8QF9A)({JT=)kDllom6 z=Bcj!)r*Z&9qnmkBlWaHw|<B<l<XxQW7B2C18kq?>suZw4;b03B=hXCFpSK3e@$9< zNq?LlC^KXKC45hg?r0VrEAJ+DlJ~WWT@MYEr%mhizw>kG*iV0o%tgqoe-}T~<28p& zl3cIMmvbm7lW7Gq2a&nuJ=VjVn=c+kU@ETG_iSKm>C;V8zR{W2AEi8%BW3hy!2XZu zJhPYeHrHFn$=JRM{-Ckl74_-7Img)UirRTwJ2G2GllE_;U7jIR=WPUw^n7_@(0nOz zViY?LBC9mXT8G5KJT*g>J-6UX#a{i4H_6x}dAoC#I(n8mf0hcL7vj(R{5ehUikvu0 z@lO)F<$O+|>`@`;;tzW%znrBG=G!8^{cx5#VwU=`-c$LG-d16MCH#Z|*Q@NT@ZU{* zpq338gPogjH(bV{e6HqmA)j8rlLcf?hTR=xg^%HD`1@i0tdxR>_}tBhdWDnCAA{5p ztqk^a<iC@loGv^|<<GZZ6v#MkmO6v~*yZ6ret%m?ADLD1qvGD;?-Z}#(_I{HhJ#%q z;}<Y)NA2+4QsbR`HuJ$W#!8*5lHqE8{ySaguhN!5scv6s>|1=6^5rt&Zsn7($+5{1 zImT`A&mp^t&;EQ4*E>{L;6%Mo)uL5iq*G*i2>Y>rWz^a25vy`4y4^lYeP1WkKbxg! zfx(`ZvDp6qN7|Y~*am<pqy+|hV3^MM9v}J*5rAjueK8D6XOf$v{YiS844vpq{)sW` zwO;(?JGJnSbNCO^4uCBDi7w^@L7dY9+Gl_D{`Jz(F?{78EuwwY2QQt3OwQrrFSVe1 z3W1mnJwUa9u{pqnoq>bK^mAV3nx^2f+3g>jM+C+b7NODbF@Z&dSca{RUp0N?%twq_ z9}siR_j1&?-WR{PbvZC>ua|k0A*(u(S=u~iy(=;Cxj>njar=fGdg{16g1nU{jafH{ zygPEp%g7u4kRxtOu2+JNP4_cjoigToF17`11gwa1IcD%_16v11tr_d5^U@ha+|D1D z+{gN9{+RUxNX_YR5SPh0ob?t@nb;|L*0s`^(D%bT1n*hG`{9vpOc!3gPW*+tZ3=fK zG@GICMz5!Z{zd4KEgJ}iagm;w<!zCrl$E1@{SU|VJ88_{*>t-7577VMlcAA=sYSJb z%>xtt{kj`=?yK{Hc<LIw$X^am2Rt%&xrgYt5<Jl|miqnCv>l8KT|>-<ZUnks=++9e zZ7*jZ#QO|jqo@8xz5Xa&fxT||bk9*reGTwMe>CR(jZ(+PTzq*<8(C-gal`(hQ@-dq zcL{u(;k!cG>76f`+dT6czv+;EXhaLburg<_g+FoH*k^tpp7|T{S@>NummsqoY#x}L z%OU^I1e=?ICBT}%rfVw4|G`?pq_5-<-WIS<FhYSo1ZxB90F%5#4#B#>DzSaD0E}eu z-yX1b=q?c~wPv(^*9dqnd>H!m(7))=>vfiWuh~wYw=Q~+oNK|@r+V&IbgqN1<n*+^ zi|@__s{oV!p&fDFBBa~b3O@UyG3yY)Ii&4Nz=kd!Oa0~r_jlt3_Fs|TL%F(S%=$e4 z$syP(kq<UYBX+#)rQI9R|LENqxBE8weaX#j`u*2aznbG>c7MLT7m!5emc?V%66!IJ zM5ccn@vxj7c;tSldT3^%SI?3$>sXx0{Gx}RdvaJB>7i<G7FHXchxDscZ>`p=RXgS_ ze+a+9E@cq}+x2pBORurNpRRXBhzmF=Emlyk*nAzl4VQoRF;TvfITQW~$dW_)X(rer zup<OuQ<tZlxXn`DnrQb)1LdnIFOzZ(>8EC}wP4<{wGgZyY*$Uie8&GBV1r;^5)6~d zn`8y=2HyfMdkBJa=cwKjSOs3uIre{gXQ#+l4>Nv|vtG`T&s$@of|r9=TruW*Pl~js zTIj)LT*@JRUI*3+_82*~FMhduH5q#fIb2RZ1Kx$K4PDrV`8ZIP|61zSz^NG420kOm zT6N8sHMcN_EPTnkcDg6W@1TlLiM*MQkU!l#W_?ZkQM*02z{FGc&T+ZP|68`#=en-| ze(}*Z<gL1W%(_FI!;Wk2{y&<z8}Cap7tf-Oit||w|BRk7Yk+gnhY7k}hYqqR@k#O7 z_0SAMgDG5^Uuzm}^49VBQTG4u9MivB?Z~LJW$-RJWXiqZ((f~%tGH{-I!felNWa&D zwSYY*3T4|Pb5Hi^;M6XmbD<7oZMu8Re(#_?)}7qur1ap9<7-s4655j9G3$QEZaThm z?>6z}S(liBDN}>iigqNp`62xU86qc%oJGI>zsX66tX0_go-ymDv>njhxi6ck|99>l z7?ZZ>^&8K3RMWQXKt^rfm~~QGhS#?;@0s{opx+aOo6u(%S<Uy2S^weO*Du6Y=eo7? zKJ=D=o#n)lSs+R;Le$L1$Zzgvo(mqEnf<*rsJ{^v_y+QWu*=_r7^rtXpI++jdtl6p z2FIApx<`XVQFr+D9EM9!hm7%($BAzbj_Kb=^x4jhW$pf$(Vk;*(M~_sAg>vDD_4#M zzU$a?UG-v5YDXsQ%zyBfKRlN4{FZ&K%ENm>5brv8+u-F=k0-Wd@m>+cTlxh43~$fQ zd9TUjm40f3x9Jh)fAWVw`(<2<cq=eQvc3!%9|rXy%gfMAM6aTrh9}2T&yW!Nc=VW? z&xv0A<tI5Ldd<;suo?P|(9e8o%$gJ&yEDgEWuTj|@CgqF&R*Jg8dg)!(@wsU9S^gv zCFcdUop)>DI}%@)BX8AnW7fjp@s_d9<;MkT7~pz3Vp5X3GxZ{&S?jhDS(|=O{+&x! zhF@<CG=P2Y-duF6d6Mz?$1&^V%zn;{G2ujBP&}#60woeMUid6UcK=J<A0HeGGspVt zLG6|}dvQ<!+)~FVbu<jKw#;P@U(SL%1=yC~a5O#$D&WGH#FBYW(SNV<JVOy*g8X5# zKbG|6xVK<4cBn)|AM!fhcJfc;={5N|PB%C5l0N!d=IUYS`k~X$Oz^#q&qlD-U~;|K z$))wB0+}=~OHYmMA?H`?^m4pCl)4dIdS2&$Ysg36@#na8U}}S-*P-@1Bj$oNfbB++ z;u^#Z{#yVx7wk~M?0hG+2O%p14H5gqcFUk`gSIVryk<QMIg(>6wbQ?n2W>=N-`~el zzfZQ<2tO9mF~YWOv>*L8jam7QKae~~0AZyr;e;HYhie*<Qw?3yzs9W9alQogDNhx7 zbIQl|40aH?_eBorn<f49SMd(3#N<o1OrN}DIBST*WapEE{rJbOJ3iAsKrJ$ge#<=j z8Tq9h4e$@Ze<tSv?Z}9+xqnAsDRR_=9lkYFFIW=U<szFyd~r2c6gn514K@T;cjc)4 z9J`%IO1<LdSEb!Nd(S8OH0uTAGfdLs<74<LAx*$HA02qC&gFCR*7RPK=-L9^AavUI zNx}qc1DlJk-e;S-z_vi=#d^RtyBK`Jy9#U*m|nv<*dW+w2DTo|EZyOIpZpdu1$G+$ z$szKhzaw6Ox$9k#TLD(T+YW1*5V40L&rXV;%m$C|vBT;V+#biN>xZ7a<Sc)FU@z>Y zu7&Wo!tY!Eg0+F2Au_ooRp{i?4PJM}sQqj{w`Yi6E5RBoQnrlCGx_3wy|il;?U&yp zHecQ^OE>2kJLk70lKvS;2fS829ycRrJ+{zt?)_|X#20JOvu5HBONl;<Q*!j$z<oY! z&|M4Y`WyAWc`JMhyFX&UcN%=zF(K<(;yF3;(0=N!M%-FtcJ6NbsX521i?ffGanHZl zzTz45_w<us)nIjCh}B1&zja^<uq^_jt0X2y_>hpBfJp3bfu>^59oFu&Noe$%P2c+< zFL9EknVqbNu1ldUnX<z=pYzmQWsgPs-U!=PsTG~*H2}{%cx0(BhhQUMbHOHQ#Kty* z%?D%aS|37ZKFgo@j?~`dOum+bC84`ns50lOHg~R~D}|O%J@gBZp?#XxES8xAT;$Ie z`InE{?=_-Ke0UMqJm}jwXKb|^yn0h;yTI3i3$Gl4^?>z*MKoe#tH4%gV1r<*JXiwy z^<XQ(j+eg47_07mM)rUR&k1FX2)nMz=NNC7jk@ous1}`Sz>;8xbB_Lvf;E8kPTgU@ zqn>ynSTop4up>Qm3&BdT$3h!x6}k?vHn1|m92+eM>j3+s=q}ka|LO4$o**V%B(##n z@Sn&S1ef|{?8#BjXFb?3nCBf}{&jW6dgQjiyw{dBbAbP+@34BMLUhcy2SJ<DGxrDn z6ui5BS%j><O2-dV{v}hDz9hqo-{Pr^Nc^i8`k7Tb?BC7P{>62ZD0ZN1EoIG=$^Di) z@8jdMdRX+C0bBI<`0wX-=w~Uj{C$Dz?{<B&q3wruQl=er?vFuJ*W%~;>(fKLJ0$H{ zgpB2T?XZeD7h5hi8dBqBDP>)hRY@6#=+_I@2lj>l(DULw{+_A-+V5+Tw-ea@F$`_< zj2*t;wGsc=1l|E&ATl^auKEM{7ucI}jzoPgL=L$#p{?0_N7kNb9e69a8+*h@=YlN& z`>M!gzL)pA)N|SjzEo(PIGE)_8SAhQa`<C2vQ{H&?monj;Jh(oeHeZraOKKPX5R}+ zQ4c6?7JcJ?WWN654r?CgY2V^r5c=BPqRe>b6+0yd`}ZtiZRWE8SslolkxO6y-tJ+6 z`W{f+Xgm_6upI-2sH5pC<kHk9hxEk;utu;N0q6@-dmS&5;ETXxf^!H@$sp~`z$(F7 zJ(%QuHDC+Cz9@{0Uk0m__nqpdnL3wfcI2%UI{YiEzkO}y4S@mcO!3oR<Rqz2@~_PC zc~*LO>g$)o(3Z?5e@N5X`^vKU=WZ)!{H{qIv_;Re?t<@S;rn=99}m)1Y}16C>aRM! z@3YP6Dcgvx+n}q5&h4xDU|nE!U@<d?4*v0RR*(*|Rt;a5!+V%5q`pz=*;JFxL7Tyf zUH}KH3kTMnvF~t7aMg+M*@3Cp0mX?5#I{n$hJANfuW~LnCa1<i#={c3W&(9l-cy_I z1N_Rq=EXkpL+Lz8Ujq=o=!d@PTeQQ8{b@fm{_7fBvJ`3aCTQ!wy~CQwxf~7h=SBDh z%VqB_{~pE4K(pFEYAJOzB5(G^>0C#!`Cugn?C{O^i@+)}=sLk#GU&R&%nZ7fVEq|% z17MpjO6L?}%Mq~h18G}2*2)-Vg5@Rj{|M<(qo<^}y?!nlVjet*yfY7Gdrl5m*MyJG z3s~4lI~(AyKa@FL`hr8SX0T!Onj-+?Ph#pqu%U(>*1nR^ee5_3ug<Zxp>wW&WUc+4 zKVKXM>j!h^IqBz(V5`9n4z4q6KV^K5XNcReWeM_X{)D`vcUbwH%OO|;*eWnwSs&t` z&0s6R);hTY{wX&+haU+!8GpI`DmLNogm!dEdOa+$yBn--?hdO>{L{$+C4X22-ZyWD zbvNf?S0f>*Ktku@!;~d{u*15`DLdaT(&KA0Wy6%Y@1Y?cJ3hgKfUmiMR7MPb%qRX5 z^vCZ=?KAV@H+szeYrn<E{wuHBr$8tD)$q-QukVB%)&rbNAM0m0jZ>UPSEo*n)rf7s zPIzWCr}KQ>ey~cg@s1pMv!=*j1zrKZ)xj4VWEj+AT%-T9-@<6Wkx{>lQ|!A5o{jMQ zPk1;4Qw00r6L;w6f8=W=pHi@{lXh5ak-Br6%p9_Z@}L`2B$m}eH{;|T))hjhf8SQ; zV_nkKQa+FJWjiTvqdYo)hjmqoUvIjl_?J_@XeZ^XDc?x>H7S1G7b*S`%3DqeE|+#D zg`e^n5+6i=@k)%y{oneBf<%z?LFF*}FQ+<s(vfVK>TBe+;4LjX?B9D4{Jr969Qr2k z#E*99XHM<D=lQQNKSL{PT*`I+3(dSA@34O(1K#jts&>kjQr3D}cA50o3d)u&@ULmt zf^~siOSv3Ew+^i0^c}u?5jKI%0Mq^M(5Y8wADBBQNLeXZHP{5s<tXJd1FROzo6ibu z0(?HW&aF-;E{TIRfpvk+amIW&q|I8QU!4e(*nSZ-tACQtyNzSC-`Z~&GjLgaS>$&^ zxA2T~dqtNn+M(J;t#kR$ylR$=|5ow0L1<5e_8Xjw-7hu{9GACnT)s9ekY$DTekHWq zC8qjUsOVo|wJr2K8a@}U;^yEF!!h2!b(uN-4pZG|?kW<5zD5lbFoz@KubZgeiR{nZ zoHzdBiRz&|bo*W2_<xtFm-4z9n;(?Lc9f}0Cr;{{sBWJKJG^yj1&PFpaNf2;wK;$H zHw)FO=&8>Xs#^<gpxQ@bRnHZwH)8uJb#dXeWTEOUoW^RTF!pMpdaH2!2k;b5)p9Bx z2$f!7s5e5<WJtXe0$gJ3+HI)o4ZEI0SA@oGiK!<;?F8c|qthQORO{tkKfMLhZ!T1S zEI3c8-^WVch^aSYMVn&kqgeF1LS@B@t|(O9h0%Ko)x(8RRC%&cT8-XCkA}i*Pd^^| z6>5Hl@6*&>45+(|;_FOxQFzyjP4#ZL<fE`!X2$wVb-Qic&mcEbuc}xchAjD<QeP|h znL0djrfT}UQs<55v7BFpqJ1HCd&ud>o6175Dd%^GLbrtQ6Ix{-)=fu+zH{I%uM~!x zieD}a|2lMEi1WL`*M!y-hCeb#48HY63x8c0ekp2<#lqJYTo-z>Fnn*U<krH-+p$TU z|EBP37Z!!zE1WJ8L+9F}E$S=Wy(iQk3O(hmkTypr8*^3sByHDo%8LJ)uPzLYe>ST6 zLU|kW)ap<k=c|qAi}`AuG5x}*`cpV>d!G7}S^h}Ax;auZoUa~?lsu8Io{z*{%~P*M zc30{@k*ekS>Vdqf%ktHq^S=0xsJb;jc7MKlDnG{gYx%Kv^KrlEwtRI_^f-|9QQgls zeIqn;V*LeSb!NpzL){jN{muwK8!~P*)IjJQoZBdP$58JZ^-qS?Lt$;lkc>Auq#YBC zZ>zFH?DO4?gH;7d2Keq}kyF$cBF*Y+k#p3(Ut*0kd1**pW_LtJ`=is1AE+wZ7Uf0J zi$ZEz^oQ!(#%Zb}RC-rPEf+59roBTIU(dTX6#mu{toz&0y`g^@>OV&8qOjU713=6! ze>sr9o08<~{!paXP`?jFaKslvmq@QrmQdH=m)971>murAW7pqC)B{H0JrVVc5d(SA z=%@6m$Ry71i^Lv_sI`&UP(-~EiT*Rf*cV-_koncfe)4}we%=?<IC{N0dVs32%f9h& zsJz!yFNO-PFx8z#`CX=3V~pc`(D*q94Od-ds*Pb>^cpjEi>dB4$31PTRq0rBOGs@- z)y<*ZpJy~1d#sG%1Q&w59xk{nrrrrZ#rbWK-EWMk_aoy!EKoP)m2ti*Z~TS=HJlgY z{LMV#@b&pskHpkp^7CNYlAi~BVRZcS1?pE(A?b<!LaCbzCLsO6f=Q4J6~smg)O!V! zE{v%wVzIx+)Sa<NUrap~i#<bWY&^(cV`6FA{c*AAyweI^9;a>!MgB2Pb%$Od{{7dC zY#*n#nQvg-SMnoQ7OU6uZ{>VzLDlMU>Xz6q$q@>x?i@$_X;SLyqDfHn6-|QYnWCvm z{jI13V6><NpkrK|s5UOPa-3Q-F80T9>eX?vx5ue}j{EYji`A{g+8NNXNbRfCzQ(!g zTc>NCcTx9}(BGT)Rjjf;?*nv_w%qiEP+Z<vF?YHZ3f~l(cAcR%g?8cG3KekPVeBPj zUf<eF$*#8*Du2~bHyBLf4;UrCHPl)o`hubUY>eA%sK05Cv~JonG(mk;sjo(shr-`$ zA{5;j!dF~zTF1SW+S{0~_BmN}`Ly(|?nm?(;r`IHCk=JAu?y!tMgiyd8913+87Jbe ziebpdcrm1|5Bcl-btrs%)9R3VFhnSI+2ARbi#@dlcQt)m4<WCfH-^IBZThu@Sbw|5 zsb+G1<HnFW=|mAGbr;J<NZkPsh1A8NISw{Xoubq!#?2vhYO_GO=)Sy5;Tlsl?eklc z5NX_OGPD`(_ZkJD>kMOiSiNrigO;r|W9v-yLTYaLy1JZf>hkFL>tgu*sY+c?Fs>t} zt}I}#zPVr=gXf+CBG&&3qU|wtd2BcQ{q|4l<FoDzmA@2LYeF$@c>H~cwyL*{swcwg zlJM7+dMX_ILs-2M9=9p1-nIiLHrPvjfX{zmRBZ{X8^T{^Mh=&}5ms-8iy-?b9J}09 z7ii_7-EVzp_h%xi*Vv;kLLB}n$$oeOr+*ADrm7drs{14ALz5)xhKRtwiNv0asDa4% zw<1gk&N!X<(}FFAI`38(ZZ@iJ4XdXO{P80rc0*WQ5H7kZtZom-9to>H(U3Z)PRzS5 zq`q2uaY%iq@C?;7S*f#P=c!9Wlf3h2aNH}}JMsfn6FE+OE1_kTePKLTf@+_p?j4~R zF}K5x({>-XkTVzZD=TMTK)I&htuqw44-XFEgX(!B@^?eMWK6NkKBry>d_82mX{eFV zflA$K<h6&1uE#62I2^q$tS(R4xU9O2x1#*gcsK+@bW=#Z?au#JC^o^kEu_lsbL;fZ z!`^u)T5Nnnl{oX7XMWn}8+n6<YAe3SU@|+4r9)`^qlUWN_@Yve8_~4}(?^W?^3V48 zw?g|==P{j}U3`n7E(o0=L4Ewa2C)PB`;F)-gMN*@X3$!vzxLTD?|DO=Ui522{em4T zwKX)JtA8B^Gw5SR>={E18PT^5T;8ECvd89m>f3gVt2ll4q@gYeEra(~!+70LOTrP} z)pe=UzZIwM&XbPsg?7CytZp<6o+!L899bJy4~EGg=>I*cqtsV}jntn*#!`d%Cqjdt zcI(@-BeeUka2j2~<A%Ybbhn2izX_|mZS#waOh542vTpahO%WCUk;0{hj0^JApTkA3 zMMw;P!V1(Zr|biB67cd!<mrgIBNFM4sDDSITO(>oUTj&Ox-!r9(;Y<VVpg)nRWD3e z_l&Q4bh_F&zN&k=x~rt>(&=hLN!16_)a|=ey)jL#-=*re)6^}yR^2^~EBjSfOjEy_ zQ1#(dwQfSypQozpORLsQRl}uKcTQE;lvQ0mRSlI@{U@%joLKc*Tn$dFdNQsq+pX%3 zxEk24>e9HnxV-A$Q`Fk>s#m6{3nx`QF-7%Hs=958+A*o>k|}ES?p6PsthVi5_3~u3 zYLBYNCaeGLQFZHNwX&k>qRHyt6;<!=sqWdc>Q8&B;XPyT?5X~>XKZXw)iF7C!(?^) z<k)W}tJRZZf1Ipdog902vf4a3#<Me*O^Mw&MfFUHJv2o<H6`}^6t!+j?7b=KgDJ5K z;;J(qyD6^jipL&~b8Rs8VqCo*kNrKaw!~wLr>ZNb#%`X<wXoQuQ`OT`V}F{eMyAHz zpQ`>hHFnW7)io`4>oj%GwAf?Q)Y@sWm#3*Wr^Ws;P5pOT?1Jg4b9!vqbalt{*aOqm z<I`i$PFH`L9(#AXdSklddr?omS5_45W_~b;8xMq{zYVEJ(_^koHY%#g2fsl+xFACC zIumEJ$MraMno_4lo(-|k-5Its8Ks9u7%Io{%SD%kqCFvXP004;X>+1|28u+9LRT2k z9vNm)g2vyBC~o^NLo0#5mduHw)6JnMap%qu0VlwRuMDaGnamSr)o7tw8L4`!P<;@o z`a_{wkyrIlq54-|)$&5smtS>Jq54OD)%!8k8?E|NO#Lld^=M4pR#0_wOpO#&Esm*+ zV=<<p?pW-Bn0h=G`+ZCe$71iq)W2e}v6$*8j4fqhSQxvvP(4x@d%93PUl{vyq1sRw z+gzx&7sjqCQWq7u_D@95RP|re`g-G7h3aSc_J^jw8&VrX(N2S?6I)`i%(d-OI2tM< zk}P2bqIrwu#@hMg|4b~V`)q8td%}gC5%qAGFnzOGa9Kp%W$HkUZ4&BQ=CEsxybtr# zfU)aHo_fc~dnQk9F=8M)4B~@YmbZ_T=Ea8d)L-*r@8_xi<;7T-wCCI7H#0_*6z9!W zrPG!Adh|PLKbvOO?0<w_535^b#(LS9{*1)<=`5um3P)Lt41}XhzJCcv`6bSGQ?b8< zenjKYq*WpH2&(|;%PCa__}7ni{cA{_^Ic}#P!ZF^+o7V-5bJ-(mV49}UKv(LwvwNR zejnoW>Tv9Vu(~NM`w7VS{$Qx^ng}y{@g{PQaNhH#S{aTFnCeQi<PQ<mW0u?&QID7< z+f6lO#x|Jh-)8K?h}vPsFx_>L*!$2#qJ*?Qeg1r;l+w3k*=EZxiRB%jN}}IV2Sra- zhcW9?XK6|FDD}BWquPh)KW~?xtJ7_}L<<Y{Q>6(_!}$q32Wg*s*J7UaWvMH>{0mAQ zRC==dzAY!G{L1LjYUX}gX3h9K63Mfo>;v2#%HxF*kB9PjM6y2=Wj-GXMLG=iR)~F; zUm2yBhUul5SBI4)BMbeb`H`=wB3sUv)Zt1UZu~v0zQ^=M7nVF^s%OF_J*IjsT*BI@ z%Zx2I)!pW9*z~FNS}38`;7x17g|8Q=6=rOxK)o3m_d)>+AIW2_yy&9^YAiqR_5uc+ zu_LPPEQmf(pdK%XJzJpG7R=UqeDS%^ge#&lbN(-%=_UF~KFbjD2(>Oh_OE=kH9vMy zRCPt8w@1}7drizdcv|6q3e?ZmN0oZDU=pWW3S#7qI|>|sDPe7+_>_=j-0Q@QZz{4k zK9g>d(Nc10M6EaT9*(GuX2~{FjhV6gBC0bIy`IuYg!5IAD6Z45Q#EZbPtGynVB;sM z{wQ(f=t>DoxU$epRio4~Y96>IPhFQc>B&5Ge_p9lPv?ze+u+5#sZeRUJ42`BvFEof zRCV=4a*}cHl&KfOzr0CytaklFnc9(8!1*Qlhq0%XFMyT52f#}Ok>@6=M`No)e0jF0 zKzNJ3$y_}ykJCrS<pHlA_b{gW&-fF&+4Cy7gY*CHy6fX*>hTE)Xg(?}yKkbpvaICY zGId8;&DM!(W7)Wm%G8Au_vU=X#BpmTsy|Ph$oaozcTDSASyh2C4~-Cf8X0a2%K3I_ zD0*#3-4cqf2&udD`ky#m7Wt;yofz@0=;7)h+lME}1I-Ic&Lg|Zzb3?nfzv-fCNq=l zY{JSib(Mkn)us6phRW3P{9B4h)h0}Osf+}m>|bT-g9#-sl&MQfCvkpz=@(urQ-3Ng zf$N>p>g&qXva(oTnR>Kr+_Pos^|ILC%G7_##@#$oT|9BzofFly6ZHV5UnZ(eSYneg z=@K>%!_nnobxkTJO;jV4jTn<YA_g1L&ak>LRTix@&QhQInYM#>ynI2?a6Zu+!))~l z&l5%-vR^Xtcmw7-gC%lb_^bS&$6K~2@r?>4S>LiyS7_K^)j*2*nh|@S0V>HG<zH6& zvmF}U@c-ER4)`dm?Cm>~LJENi9U(e^ASz%0MT~4ViVa203fOm(0E1)=$!rpuWj9tV zC~;kTi@j@XYuDJj#$Hx5c3pLiy{-B^=e_4lG7mGv_W%9A@B4Xwg!?|{oO^CRx4!RW zxN}0M$eR4?uz*7{u-wB>h=2f_3c?E+!@iS^P^+JbQ)Kd9R)&`^Lw%0GgfEl}{6Huh z&mF<@d(s1r3J=B9_S|5m7{oW)!EQ}l?}kiQn|ErayCxLIqUX90a^Y@4SI)#@4Ncd# zf$rniPqkMI-R{oq-sgfm*Bn|A#^`!oMn1qDvc>XlMn4dq&6@vxF1knd>Rk71cHRrQ z?$hin&{y_~+@6az(fd-^k6uGh%5``3lC^zX?tt5|N02+<i(Gej-X?gyP8NkI!?_sz zagdeO>xV*jYt}8u%I7)ZOZvGlbI=ao$SruNpX<!UR_+;j1CH<KZp_bquh4y(AO5b; zeV+dsG(T5R@NJ=cqd;~ao-OQ$=MM@ewe)k3_A7X!pL?;Nm3h&%;Vcx~jp1hzXk}&u z`$Xr$fXHqUirSai9_}HutB1mU56g8I_llg8i><z)ujjZodPUlE+~>W9J|bo<a(#|# z$$|N}F(>by9QSli!6Uiut(?4XbKFNc6YzXqZoxgd?&{n;Jl~uv4LWE`Vy0gYXJHcX zP8geL*b&RY5O<31e|4{~h-(4A1;=J+8{vu|{8(&LJN&KpMwYuc9KJKleUK5xPTPMn zz61UJtgLUcT&L<PbQhvDF3boY+7IpUh`yFT?AJi=<>4?a=9OVA@x%pb^YfcN@5rv+ z3DEayI2+Gzg@*?G4RC;iJ(v?i7|jn0kA6`)14e?E!+F@?{50Gf1Jw_<o|$k#DF25H z%vs-sno}}HACl>A%Rv3TlaY%idw6DEbEZ2Zv*6lHcS&MTq2#X2nV00b53;ha$#W}m zv+#UL?oezh-IF^MvpUT4u+5N{eOaD6I<E*!Y@odgX5RXm{*A5-6}*$<jtKuV{2nSH zv)@}e?)vPkuX5bY+1DY*ALJCBnCp%Xh8oH5k7)~KPOS0`;dQ>wb>C)YJ&@y?vW`ND z9hEZ_l=E{UujjfOaw6FMYtPNWSo&6O9tO4l=H@lal+?HFoZeX*yF!=^#5qXU+u5&& z+*_f%uS4#mz_bc)eb^PTEjNTe%y(yJe-i#E-@Tg`0r(`p;OO4&2RT3pbfmY5KXx4Z zzom_@=QhXObmFa;Bj;dec||B2kJp3-wujvPHs%a>*t*8wP%N8o4uwC#&UHA;Od`r- zUALEWd-eGkdtD2#!4VpXr_VyYU`4-8l<g?_DCF!28u)y)!d0PcJe`D(qhMN^15@yb z#kKRX;Yn}g!-6-wpYNW{%*FF7nLFULB}*P($SQg#-yN5|GW1ryd!X0S_wq5cA0Gmz zBX1ezJ^8t)tj_$r!+X1Lg43R$zA|^q{-dwAGthF*$jEsW8!Q=-Co-@M*iPGS#NjXp ze+8JhotNqRTkckUur$~;*wPEaf0Z%xs!Vr6X4JWBGV|`sbhjq@PR>U8Rc^Dbg7|Xs zv-Wlvx+P4`$nd^y{kg&O@L5^dojfI!g`K0%LOJ-wmQ%tx*bq6#=9S&%NzgIIMJ5H| z`cBTO#nxudjdEl#%G-*ZzL<j!K;20k-R8stBU!ItA4q!rccGkBVf4np^agUHVZ=7@ zX-V1>>b4J*yL}jWo&g~rPsANtgt=eQ`qvb>tBd^nJ$7_<|F1{5GqWGWEb`4heZCvv zKI!uq%-fyo_B(eZ*7(JTj&#SaHx$p8t{3@s1XlO`FB##UTQ7o8@2@xhsS)n<=+F~J zxErF8FQe|GX!cDb+&9sJqer+4M&_*^>8=`yjQRM7;m8MDHrYd0VTzj_#o0oyyo-8a zXp>wa?>+I?cNqBbcXar*-k2S}9)6>@dpSP>@OJNl?|QpWWzh*e1(W+Ma`Bu)LvC53 zyas=hk@H!$J2dlin1wI1^N#K14zYM~Wp_mcA1#QST=2?l_tn@wAIx&6ZCvooEO+Ag zet14(^Mc1_yGu5|5JmLZ@1u{*cDI!EzInDgf2-a%&UT+}9qpLyo|#_o#BBG{HhoT? z?cUwyUPN-m_I*B{<*uEP+cwADI^*VEcvYgj|4nn;4S(1Qlp}T<e90Vl?rwumoa1iU zZNMROT>EYVKAG)Km^A=07tiW*<1BZ}tb#{pxzA=5{C&1NWOm+3ySuYy7hFBty&XJ% zK6_&89QW9qerN6OKA5u}xX149*EFMWDD3c;e|e6(I4l3s9CvAU{%twvWcgR-xTkvA z8o4Fo>Tto+n8O{@JMs{`(|aFMfIc;}@Ns~{h7UXi-UaIoIuqWfBYy}BY~G+im>uH_ z4uyC7#Oz0|4!Q3q6+Hy+jL8oTLiNljxE|pCT?$sgyL8unN5MN`R=*?Ry)wJsYcNd5 z?lbTucqhjOz5ws;KW9G#@4@|xo`!c}W5MI_K5x7tB-C@4oPeUdc3I>KfV-Fd3-g+@ z{#tM`!0JOn1?RzUUKxr!fV8x%40WP@nokN9-UoOs{CnVEa(bxuOV@<lqo;>*Pk`Tg zb|~v#pkLS$>M!(%T0(<_{zFTsQ1At~Q!V(-b3+BELH(QOhq6WANAN}8jTeN5wt)UD z{IlWTc2Q{TYGm!|t3m~L0l$4!Xy!M-k6#@s_ym3j{MKtj?h2fH--_^^t)Z-=C7x?S z{hosV&uc>K2>-)tLW6ID|Bq`!S%Ocy7TfUR(4GhN$@(zl`ripV@Kk6h9zP6aVY?{c z4eXP(D&)ot!RFAyp?F#q$~swCLAYUKV4bcEWjz^k*N1xJxy_%NK<Ds%{(wE!w?dIi zGTi5(e<H}`!Hz|6d<y<n*gAPW8{4n2{O;_`ysNV@xsV;{XS4c0o9+Ic)&Kr%_e0ho zJfD(12+!AM=iQO*UdkTyO}6Wl4N#wkLU$w-;6C8tnV5Xzh*RmqoSd=!E8HJPqrooM zQ5pGXWw;ZA2|eQPJv}nV?U`5O=K4Ne=&<s}-&nj@aBt>QK^7&Ch1lJ}3l-r$N9MWb z!VjaD!GWIh`|xtN)!g7YvLp+m-BY2_=Z4*vA-~qouPgj0gtda4(~A69CkK{ygmP}l z!eEJA7fj8YLjaFw!hRi*H5rdLWepBwi_QuSzAD4L9|~j1^I_;-2w#(thau?JU?;}M ziS-M1w?k#f{;MIJO(Bll>AlVmxg9a%^KlM#_d({qP#$)NJ_>~&%Wxluki<ZCkoy9> zFGBr}31eR{59Cw4@elHR8SLO?n2TboCZkD01Yy>8rm!|%A<9OYRu~5c&xFvDR3Go# z7h$IktCdjrm>l=-5c2D8&I%uugEa;gjT)xF@AV&teb(h`qa7d8L#AynE_6+q>l}lI zlGX3-LU(G`e-O!$z4{(s=uYZ&E}s9H)2|KHoFhkP*XH$IS?KP{lQX^t^9Lf->iktm z2=>@d=;zMwJNlbK_gLTl_ZGUh`fhoDp}RgZ0ME}vMmHC_6ASasK~@Xb#ZsuV5SH${ z!n~vVxqtM_!`epbCxXcmsxlP0Cxo+mU)SrnrOquKj1}(jq2rOuGc$5f^%o@8odaAW z?)>bC!TImuJRFsr8O976x&}B@bG-24kh?6Dho*JCOo~A7eMTtn>M-_7E<#km1Kr-v z?H#@`(>)owCH${UY|ZRv<rcxp0cU8Tbx)Dw-mL@qzCn5p#Ek!wkj$n7ohxuR=rz<` zcw~ShZUs0i!uaU~cT(7&5A_MoFmtefx=1E~f!v^-26W&|GBg@@@>gW6gI0KM23Gk2 zuaB#9u5RE>A$Pd6-hft!wJR)aD2#c|-$Qo=YJ&J-iqTB33Wc$mD|sZmnR^fEc`w}S zoL<=ADZHtdyDxJPZil>?+3V<D?)}W0q3MF`(Wm!v|H>YHsO-OXwZTbRC*kumWmyhM z9O#^j1&|yyUXvlGtk-3X!|Ey{d`>1d8iEaaq#^Q$!RW+qhay<YeGwWFq(67p!Pvf8 zfSp>Op9oHuaRVVV854kqw7xgRYz`xJDExgE!kvQW<1)fc*=|(^x~{u6bIX=&_hF{k z%k#5)-<*xBEWTbx9utaSMtXV(HrQPn?t=z%V;D7gc1GT{8Sauqdl@(?AIrW8_n|;O z4d-E-;k&LmT?D&yu*0E|PlPb@##oAc6a@3}Fix-c!KB!yd$Kze!4D1hei2){VJzgX z3+LhS{LIKRneK+n$P=0Ffy``BKF-WLA`43`BvEvYaXUG;Q}2!t?(yV4ByF-ko*xb6 zy&zY$ay}2iq=~4=-Wl38ALl?#;iC73V~eoh!y;r`D(a%_;m;PiNAj-^fpk>=zBd=S z;|9*SvB*6)P-<uOp!`#d+@*sH-W=|}9$fJ7aMv=V&sjz8f}wp+9_}t%C;#~(_uqB; z9=@(?9+r&=P8~Mr<s#QQtPh^=8`kHJBKPdDp@$T?&S8Dd9`2fk54d5tJ9l{AmBZal z!wc?S*F82o@8#j{@S?otBG*z>a5W^0^8Q=oR;*j_@Vf5Ybq7P{rgi;1Xvk@yzSs^} z8SZ;j7OuAS{TO##G7dx0A%6p034YdLFbvwYq0#6S&&!KNppSPiVVrp>v;QkNCCD88 zMmEm(aERZMJ^F!c_i(mcWO_S04~?`l8<F_38hl&0AFLscr`s}cb!O<>8SZ5p$2P!~ z3!M0e!w+Y=`@;t~*On3a5c}^LEhwzc%)G<1u+OXY)3;9+T4GT)TEQqx6?{6Uk4Ar8 z7{w|%ly|0_8~OIObiK$;MQ*!6XBWAB4}$@GHDlA)Q7+hb9_~KMF2M7<IR%dn$Bnvz zTZg+Ba#6*uHGk6T;qLYPCd{H<k31g!ZkT&+z}2C5hP$T+^}l^M4i9s#819Z4a!m+g ztA?!u@X4@TJYPM0QEQPqvuLtU(;$Z%4*1JJ?_Jp|=j>kYAHh^w$}i$@Z4Q4Mqxn6r zYp;H9ga&_ve1>qifwR<^Um|{y%^aFDA*hQ#%Ca%mfJI+OtbB*&amMJ2vY#lz4WC1L zA^M97--hOugCds~xpM{=d^p^FKP2Y`w2@&2psXAoIjzW@Jv_3a2nU&w`-i)ShHr|G zwS6~SY?hC2q>XcDWMQ1cI`_)(P~1kiG&B6Q>{-E9d$~uk>lako;ICmI-pi=@65g|! zuv_l9-UaWUBr|0k!(pFn(D&fn+9zKGJ}De6;-~b(ITB7?vmS@silLZ1+%YugC@}6H z`gbs1SnuV~M?kAb7TpNza_iWFRgimh!&L$Gi;W9T0lZ<0$i49H+v3e(FeY=hyba*Z zipWFoKC8F^i?d7XvcAFD!kZ0;_j(0d-aP=5Lig-JLnIw<9(;Z13@}^&mix%5A@}6p zazBO0OMlxJBWY8pNJO4)3eCji<d9JKb!=dtdq@aY|CB>R1CB<p%MX<+0H+@o+FelR zVIdeJcjpnI4Fw*1WN5$&_~#rM+Q+$Xjtt!t7I^K^*td0W9v#|U(3{7EP7ilL@%Jl5 z)rZH0<_miA_z=v`nX6!QfL1hz2Hu8rUD+HOB+2Y(4)vFGHlGmcBlueQg4<3&S9Q+- zJ%NP31OGz!pPvv~2wU^_(17bvCZGNtH$UJXe`2W5OGv=k@LS<ubz&%6O5&d<hQ>;q z*Zm_@@D%WB_@BUk@}y9~8wmFw_)XAy?8%{mv*2F>{{i?nz`qq~c?$kJz{j5wD!3YH zdf=2$-gEGeJT=ts9`H{;HME|{y#jpxX=n++XTU$<G&#)lZR&*3di`G*;+712Xb86O z2E0B5S7`FvhG5(DYxLeDaz^6$;v7uW-B-E2@qBpRA5f!t1M&Dw{*2RyxU+i0Hn?{S z!Ve5~Z}i#eJzO5_i`|zO`}W4;D-jXArZ9fR5O;I`g0BX<YX*&M8|=OwH1wDu?jM5( zfP2~C0Z{YFkb?7ux*vuhXwU~IU>8t!0wXsUxD#Xx-JRdNcYA@mx;Lh9I7i8Qu)sZC zP=Fh99R)Tv*uLrAq5HGkk(t{)nC0HcEWmSTCR)WKSvjk-+|#;mI%;I?sw~VIWR}{T zk%Obhm6_q^GF@Bd0MNh9%v%9t09%mLH@u}QM5~nN{^1?mz&{4hgK*UbH|;_Z48IqJ z^6+MCYhsMb%*w%`&<~*nFJxt1J;ANc`U*w)Y;K>9@z~{-7v)|b(C4G^u5-YN7)uY^ zICAp@ck0FikDcJI-8k~$c=y1@L-G99#>M{~?@k{VL8vRn72i4Dy)rJ+GTxm!KKu6Z z?)>ouH{h6Kyv){o+A0g`+#)|W9Iodd1vq`YJ(xGQg>#<5om3gpk*?tmjR1drU`;L# ziNSv$oQGx4lRuV!B(|pITy2W%QfK4w?NH8FdLRt_<8bpvZr>D~gK7xF(%c@7;PLW| zJuvDWnmH1)s?5oFd_L3fcc<DH$y}I^iPUfIw-WfR1b!=l-%8-O68NnIek+0BO5nE= z_^kwfD*-A2tl?6+W^8VWD}Phj>i@n2J05UY$_DNu{67_cOqZ=>9Mi8smlH4Ck8(Gu zp55>)PVNM6fIp_=RjS}SIZVG1bXo8+{j4<fOF-Wwh5SEMKJPW3FI<BN9IlYLf%xkP zA;EAsOb#5*BLi1{l&24S-G{SsEK=;b&aF$hqbRk$%0f?{s`6Os2JR{RFPyEF?sp$h z<|H>9LL$fX@oDIjlzyb@!Hvwo-GhwaMghLBB-(u4if{RD8|CR7?qiUnkc)5N`6h3E zbZ6h5+*r>SS#id9i+nleV0%`al)bnj#Xc0uQ!%bO1a6vQ>@)^W=u%fNC|%l`xbT}^ z@A@9Pv5Jj<uwrai1a1}n$18F!=Pe)3+WWdlh_pMVUkF+%`W2uTrjUOSG->aw=ONI> zrl5<wlnKk<16nFQ_kx~EkI1Lea~J4i@OQZ8m-{8ttzSN;^4xD+nXj=N=oDvud}~iH z+sgY<#SxWH*Uw&h+t-8FhK;8RAKq|>@{QU)*Pgt@Tf~p-?)lblKOlb7KFQ%fq4+!g zn9ToD`KGV9Dw*F#;oJ61=Knza=-$cvig$eetzPy6TkI>-W1vf$ev#zOzB1kFk?Ce% znQr!#>6ai*v9C-w`?@jiiHqZQ5?$u=nXcZ84@}MPkd6q~rvAICe?~xct^m=E!1KiS ze7v~e9XM?B1+E;&hT=Hh7Hy9mrK<n;-rrgE^bJD!z9o-shk3rWZ}THMK6Ge2ZE}(Z zx1Z|q2=5{)9uaVHU0iXkVzKLz<|j0NkEs8&`VXjokNR!um;c-6yIl1g0e?LHWD{N7 zkl_EWe%U5x0&ov$xP{7p8a~d|T}+NZ;Pwyx$0rZqOZ#h4c_q6~RL;h)K48e%Q00wl zk9YM4UVo!1lC(;^fBn$YEj>8$2<V?Ey-wxxp<ZHWZu9YQy|yX6Mg4Sg#mYb7KR#Y= zH<fpL{Z`NB+xYglhO=}@dlY-S*GFF8Uo^d=;Y-;teFSJC|CP$~xOQ8o*JI<>+lp;m zi+r5Sk16JHt@Tl#k96(e2@UsWq($6F{9()8F<r_>=)1^|tief}5VxOVsY7v%ioKL` z2PpQbz|SEow(>lT_=hXD{uj~vLMCrMjwFNl-c|XU0O4Q{zLfWDydEZQdGNn;2gA?B z-@lbEGUC2cT<YN(;r<G`gqwmJh~jXN7`Wdlw)qLicNnB3T+3>o&ZZ!gZ@coCj^5ni z<vVZkIW<4>f~U8tKAmMb^V88IGSP!8yV>hAKR&?IEggXn{`0ZGejJp{=YG~C=NE7- zZ>z5fvHD3zZ?|-8?)A5pc|W4{$?dddo-g-w{5IvA+>l#*3Yt`3i~7wfXY^*J-=Xz5 zF31hqhvMFfzfdf7DUR_E%AfDqPK(tY|G7_hrP3Fpn4)<8kJA67bh%z5c0c|_a(i6~ zn)I>vlrD2Wagi^*oY~I^!i(MQ=;zBZDnf8p5AB7X-jS8;v!0n?OCSDF_2V=!a0h@c zd1ty@Q%XfYHVyq5BwNzSdUi*<5xc_llhe?zz&T-17hn5w!0}k%Ed56*-R$PIil?gF zzZD;(_)Pe+*7`f{K8mw&EO!EUWAMjx87C*;?;Q<q>A3|ovG3dAvpVAT4*tiHAN;ZS zW4cUlhJk*`_g;QimA?sei8rEOjXqH6$HJHLWcn9r=wGIxXG4D~J-yP<$E2alaxj&i zKc%66nuh*a8u}u%t5o`H)6maMLq97G9bY9#sUK&;Dd{hOJ~Bo5PeA)jmCnhaOFJoF zihvR>_`j>4M%3O;&+sFRjayqoZVLXGeivvnQqb=KO>7s-KLnceo9|S=*^l*5-u+V0 zM}jWx_vK8V9_ts`Sst$sp15Mg#y>*wOwV?!;BSb(|0=yw>BT4pvGtYNULV^VrklNC zy4joeRga}(U@xz?zsASmo`QW@FGc)2BVAHXEN}LU>4%}R#cnbkm%~!huLE7|9n0g@ z?UeHOq@m;W?v#4wfSxM-IZB_L>&wOLl-W(D=b;=Vowt*`*)^u01X*cE!}Gj;ws%Z7 zd$&a8rLBoOR<YELIL4PLf2n7?3)FANMGkQ`?wKD^dgPAO{J8SR=KFM`n+9%U#inO6 z;VlX8sdyI+e=dBfhbFl$+RdR`1uh-E^KKtwvxaL?zg7K9G@kjYXDWsZiKnW!PyaHd z?~jONUcq!(rV9N<lHU<@u^Vx`&M40EZGOCuFPYYS?>85CKb?Gs^4nCtv-jHND^-76 zo|kLsLB3P<x2XQI9@5kDq|eu+^?W(m`1%COPs)SoFM=LRLBAONXhaIS^y>j>=puip z#w&9=ac3yr!9)2xd|+?KMSc3L9m#cJSqm}!9MJMp&~s6IvaieXQatOVpue0(&m*9x zk{7zze%Aj9+E1$V$h35W6!P->9Fo%xyfZ7#+L`&b&bIay2;o0O6S(4fR1jP`e#<l% z__guxUVHdTJr{|*@6#6zv~{J^_OUH~OSk#aXMDJH{HCWpzg_FQQuW(9p?!pJ2R1I+ z_{Ve`|MnT_<!$^sLa~j19L~l+rrY?(bQ}MeZu57h+x(sBHeNE_#!IH#c*%4dFPU!R zCDU!ZWV(%)Ot<lJ+4{a*dAwx0jh9Tf@sjB_UOun-ZN7vrat8ft)My{?j@m9ppgGGJ z$@EP?mpurkPX%4(S4@{~A^n=^TZ1n1m_-`z&Uh9l+kRr#n0_1R($<+SuNKK(5!2g1 zm$u0CS)gwSdb)nnDid%xw$Ga*y{YWBt(Pts<I8WSAT-wP@MWB2y6h)PIWb*cca!-# z)8)0E^;6L0`fqUxdT;2Fb=^mro^m{k+ZOVYZ>C=an#{X?zkyG`&5LF$MzFwLq}b+3 z7l9%5dY{tAs$8+!k*MOy@TH!28te7TSRw9Zq!UA!Td4Fc11hc*E8bi&hnu7AX7`P} zz7Z-Xbt7)6(k(s5fhP0BVjcfPMqG=^jrY)nw0x{xSia3~#%tf=jL++-O0}=X_tN-| zv+8eC`;4zT1Qcll;>><m4nf0&<8;Qy`+Uk+C+<MSmac;oTe-@3IR$@A{|+>%=hIYP z+K9N-NRG5qrgx;F--=|4{Pn8G?EM3ZeeTxO_pye1Lgj2;g1hoTJ7)R=pi94gm(n{L zG;u7yJ{ptcFJpo)uMGmJHRZ-YPTC`fw{xA1G`z$u&e~PS7d~fP@5OOn!^O{eeq0vn zaNDUKnM;YY_LxpjWv$l}dESRFRz2zD+v>c0^jR<8sp0m}c%|Qo6I&|o7^RQ$(0vMD z+6mJ?25o)(y`=rn+S!#FUgqrLxSigtd~2uoDweh)u2|<aKGj|QqB$&9psQcmK7q+~ zX!*XP`fUIET!azb8Jqa}w*J%!n)LT!O1Jux;uIOCe+Rmh3DfZ<$zWc~beaB38kjyf z4IM8k2m3ZGFK?obNudYdF-=Lw2d!N+g*?8Vlv4k7Y3O&P(T}gu1@TVOaueGw?r9XS zj0sGCBn@5W6CyuT^;kcW^@g;?RCMVZ%~W5fqTxyXUaWMRXIguHQt5IBLR|C5z8^#b z)MZyYv>(Os%BQ&3HQb&mH%Hr*wR3LQ=M?+)Wp+pQmqz06DWz|ydc^i@kb=H3XfkGg ztMVcvZuCU2*T<#eF>6?V#A&^&BmaN~K%59;8_MtT-EgJnCA%#N|6{aP8_B<2^QU zW$L%ZJZ`P_er1jKi~sG*)zV?(Ri_NZaFsG4hl}j#{U-IJh8L*ZBJa0Q`aeflsndlU z`tmUSPpX{R&kn_Crh()6$s5YIbu7nIifo83rvFaq>Bi+IUB_Fwvi)yXe!BM8iLYLX zi{Q0waq0B5Djy$C59B6J^5ropKwaS!Cf22Kji1}?JPkil1N=j=v`2B}G*7d1**InO z(5C&TRr`<0P4#NJ<}bRB)6wG7f2YQ`smd)u`<1vqRXV2gf#Y=ZJc9Z0$-Z2y9mKU? z**MeI$Mdb8cBlT$?Z)zB`8B_(hxK$h&G#&v`R%%nn7^4%&nV6B3dJ^#iJg`C$c0Lm zu}j>IB==X)MDAIo%UVI)SnsVNKMd`91MpbSaHVHV@#(Vm^$}!)@s#K*wcc3%T(w8# zDsT2EPVK4=dd0>ueFbPTM`8L=poy;YRIl0BM-<yQuo5y-9-k|H6FiG!xn|HrZvD-D zen*NBoUAV-zf70)ucVjhyQQJaen~1l`=EiQig#fe`oT)yPSYvli8xNjJjhA<_EouY zfs}K3@MR{|O69*bXp%mr%YCjLKu_2H%eDPJpz*8^S#j?xw)S@*Xfg&f{T<LG-rr62 z<!<Xn8^8Be`Ua2@cbMX051r_hd|sz?TQ9KOK`O`eCZ#{B;jO>1+#xFW?;g?<PZQ5# z(6_}O>s_Mqg<JUiTY3Fnv6bgM#WvqcS0C+ahuhZi^JVkX$+xO}yULq?u*NqH=@T~s ze|_-Bbm>phepjo!tQEw`wKb^=rq2Lf#+v>mKEEX*40jp+ByUV_g8YV{uT*(7>%euC z`tZ`P#MwS1(`_G;>9%jkblW#%y6qcYSLWm0)ko_dg)i-w>C=&JY41$mSMy(asjnX! z2h4X$k3N=~-}Hp1mp|_PV#Vp?qmO#IsoVN=mutHJfOH7wD5YC|>>PpVc8-vWJ_33y zepR2CcN9PFNAPs~Xz|+lPRqf<BiVs7-{FJ6;y7Kl565)dhYN4#%VSm$+OKiNHZon> zXDa&d($E)xJ}iYEu?x~4SbsfeGLEI9i``{<188FNncfJR*g>Ytd>~c4hk`yfh5QQ8 zq&`{C;c4i{fWB=C`C~y#RSrUz`5o&&3pBAMOurs98H<^I18B0B#q>JR`s435tzT=` z5~s|Wm@aXqqEAXg-y3upBUsN)pox8C`VpXsU1PeGo7hdJ%lWh9i|G?VmwIRVrl5;` zWV-ZkX%7c&@7wtncow&pmW!W#<I}0ixB1TVip6$`W4&U(Qsw7P&}9#W<<||TPWLF# zQ{{7g(4#5zh<%qdvHoW;Af%F)V=_tSfjcDIy(-XB(HDX)?ZE6L9s|eW3y@E#|3cMU zt>qb0|3fXm{>txEY;qx`XQ=-v@$;4bt<tMh?;q8FpX5z%9}V}t@{853zf1BtD)*Jr zKTv<_j=r447Kxj!*!s`jpozWs^Gq){M}**HejLRg)3daGnSLJVQvOWG_rC%=$n?uV zmwv)@xgH_yhv|2N9!)`)@7~LtlI7)|V=Dbov@5A+mKVB=_e>uF`p7i&RPrO!$O}D{ z{HQeYLQf@MoJL;gsq#A!^f4*YFZ5LMlhViwJ(c`8&{LI<&{N5ePorPxspK~TeN>9{ z3tj9o*Vmq)Z<>O>7wD<<3q6&*tlv`6_f4Zm=rUe%dbS5WReKY9s`}jl^i<_3^i=XQ z(#Q)vmAvdn%e;Zp`2gst$_F1P3+yw?UjTZlep-TQo2>O%{sGu+8Ml~z2_~zl=*^&~ z(tir*BU0$uB#oZU($J@XE^`M?kI+-uvG<YwjZ(-rBfqkiYTDV`&p+W=oXDms|Gv<l z%HECuJypIo0A1!XoX)L4AC-bW9rRT7I|FoShs{+;FkDXXf0tig>FLH-whQS)<SEbJ zV;7%Kn@4P^*v6M^*j+^B7Ajrh6gLivBn;E#eNmxbqw<n=aq=3S%++2~x{TrC9#$-K zCUG5#EuEHr&R;9#kNFWTmr-+k{-jRDRVbD@ueb`d1IgckN=J4B_nl%(e<P?;KW8aD z8c1Q^e|N9n^7GYfkCp8<SH9(k@ixTYRx!F`;NpvXJ()h!6V>}mJE*+$EpdC`uLOUb zj+0f+@^iIfOZQ!h?L6=?#g>kr8oph_TY5P?Pb%Na+w#fh60J*o{>%UB{o=oQ|4R*T z^%z5*2jI{2aC?YrxF+>0o4lTv_we;)dJaG*mp0DyLqL}{x|-^LA!r-m?|ao_<r&%2 z>lNECuC3hTh=({|N#;*dZ2e#d#bU$7%~342RotHyi_H^vfTqjJ`=q_Rez9BP?o@31 zc3Y#-OI@d;OPZO!JLHQ~&^JRdN}5<+UYAKlpRe>+G(FaC_koTv_+$E9(4;=TRe5VK zzuVjAFCRQ{J1DmD<M#I_<;xsH+>l*;cy#~3wNw3Yc#f||^+}q=?eGV$&)VJJm5=NO zj`f|Yd~0{|zJ!#;bxOB>`lw>-7Y{>5%9ZJ-qNB?A#B_Y)JD`u=$ER;JWW?p+Pi#EX zWvm>FzjXbmQ}>C|@ynHef2EI4bcu@~f090?%l>03`bbo?(5*cm;ngMZiG<HmZ1&5w zATXTupZPl8S-CdjbNJ${{H<R~{>8N@-^M|!*U!KIp-%XxYC}Y~2wd<Z@OZNNZd1OL zv$%s)fwfnwPqVL`AA137-_qB_iA@uy*-PACx#`qo`Vh^CrL*N=&zCY3XYtwiZF1lK z;PYeU{Jr8!w4i=aoJgnQm8$S-#rQ#u{}I>uk)<?Q{gf7uw^Kivi}rT9Pf+<iK4%?w z`jRbIdZqjpS_;=P!D`SmE5%@Sb4~Io&TcLu7a7ILLKm)y<(K$)nswhEKXw+#m07y< zy~56Wyq@+OlJz%V;^`g7dB63QAh>IK)%*N^<ar-oD?a|XHrH~Wrdx&D8&tpU(?(>0 z-rYTxEZ>RGCyQ&bhTdHk&t>`^H<8oA@^+u@$ay}V%GDm1-S2Um?mwFXyT6B@eho<N z%e~)0>1opP@4#o%Q@Q4cz5Wil$Pd@{PcPN6+WYo@tA3Zn^p)xR-EEKgawz`6>u;X# z{if-u<1>B5%d~u-^Ku>g`}mDtd8^08r)&E3J?2Q04_7H0d2pSv<Zu?g^Dfn|gtFT- zecHY|sU4S};`MYs>jN}D;r-6i<a~5?_;%I2Fge~<i`e{{WWJH(S0uN~)-tc($~CU@ zy<#~4fNKhS`S^n#$M;H3PrH0`I)!UmrTO_JSwDVtGfBE!%e{SXFIQ~epHZo}mUEl- z%XX~?Q_`gU*Kqp*$@y;4b{pT(>u<T*^D7&Z<svtD-1LUm)OMccTl>4|H@{W;YqRQY zf7I7^%Sx}OL(>~kISbcm?daa*dT5t#pTm_sms~y_$9sA?zAxY1>F|>vwP`sywG-vk z{!B2c`YQiM?Nj@4RQqWwe!!`_YtnLSQ~MpcI+-8s@Y2Ok`us=b!YNz}<+DlKQTtt9 zuAJ(j<#<mwyW_P&kG^+lxKba=>XXw^j30p(SElvesdljQN-r1D_E)U!rbXL-<S-wu z^Et0LdZ5Q1!7gcgHr%lf#jEw+uK6=L^V{$8Pf=Y*#q}OjllJf8G~-Fr>ponkmSgm< zT5lbuIoU6kpG1M{)bY01?4*t>tyRhCw$QEmzD!iVH(+%0BNr!!Yi~;~ACqg>c$)Nm zSfiWYbgvKB@lW;dNN(>Y*L;_!H}B`=inZMtzieMmkIO+UTvW@yT>E2Z$kW@NOip(T zzLhPm{kFh!?KI9bS9<xjAzrRb?Qyx@>+4+M<87sRLc7*u)8jt8rKkDf<bLL3#s6w= z3^%{vpPIFw8NG@6htWIn)2`y8S}tw>P0pvunO}aNFV8Y6$B52Dn(p+Ho!5K4Wm<nt zYVRw}4w5~KYkz9pO7pFDD)PM77uWQ+YyWA}_aH4@?QQmy>^DE_%Rjy}b-rx8YSwy> zsNITdx@~?{toFQ9`+K?0%Oa=we6~E{{Y30-soP_R&KILv&+&tNxOR=dNqu*S>U-L! zyIjZH==qwTH0_~D+ifBp^iY104{zkwKY9HvI!-m~e4<$UZ}WGa-*IAc{))9<H7UPR z+qda$(R%D$;@fSD+MlS-2O=ZAzLr&*KeaFA`kk8ivgG)p8ei-E$>rL#WwKlu%`3_e z_4+Mc<`?VyDWdTjJxX@BwaM!*J0n@oSPjs5j_0?lJt(`(<H+{O@}|F2`+KvNM}q#E zJth0ilpf=@YWTRemu4MzJN2GwtG1WOLz?~>sncWn%(s2I7G0-Qs@*ic`Q@75W-afi z&X?M5)%w<XXXQOU{$`!OTX?@KfPG?JPucs-Ir#0^?ymS!pYBki+Wkt{p!wTRpI#Cj zyZtV6HjGZ3JYnL5iP1^LlO`8$I%x~{!Cttw5a`UoC;fl;A*xF^dBstjUDdTEy{G!u zSmoKS8XMoP78^EspHV}W!7jXA*JJRM*y2#SE%8lkrass!%XW3f_#9rYVRUz_kK<=N zu6tlS+m?lqEj@-0vj_D#zGABzy|TCi$=4I+^vqDcU3r{M@;bvxP`NyIQjWbkDBEq_ zou$XF1plQw6VI$qj!L>at`9E11G)?2nahvk<MLyDJ@Gj`RT{rtiMFjVOBU<n@K*lz z3SCd_%gWRAv;04dp+4u2>&Mb#uSoM!<t)<2<!SYAVpbmZO19}YKGzSo#}*S*pUbaz z4}6yA^jdkF8jIhqymNR?|Kk=={h0dAdS#yLgY_A1Re8gvmg|T4mL7Yh(y)d9vDjXn zlUH)Z*(-cH6Lj_}o?$PAUy8N|^$puAc)usUVSA;|u!$Lt>y=%@%s0&CVc4$xTKlk9 zH<Bk}ek)&ewQGDPZ~CkC!CswOVhr^yJ|o)^R;9iI!tsqULG>BiKx|i;&HOc~KGWZ# z_*&Id`H~-4r<4Ap6t^nh!nZ5FK>1Dbv!ZZ)6`QxMJ~S(zCp4D77UkO(d7EOhf9;Bo zSACT)`}mGj+^KjAYkzW=3GQp<7r*N9&5F$%r4OCT-@q8^Tl<f8`0(o~y-e}midz(K zt+-S1or+su^WiN&ZHg_w9mMZcoG8!NefVtE7g22KDJFiI;;713Dz+mPB|FpCq<l+H z3x#h}yqN`j!>312DqK{t+3&bwv-goVz5JUNUSHiVQXExm<x{M9SLHV;zFu+J+g{&^ ziaQh=zvZ3e@=`Hp?X6Y$_nLnFl!@7kHpSN7EqsN=r~E?|$K{S3oRvqj;xm+QUZTGA zRY1#sx#HbauvM|uN4w%g`K#O|>f5JIOy1(N^xG@LW*>}i_Nh!?DPG?g>c6ahT=~{t zOf0SsEy^!7gQIlo?;Rib@=3J64?VW}h$uFD)1tUc^>ip6Z2CX);Vr*W#bZ^zT=5DE zuh{xir{clNkKorq#aVxdDmHswtayaVS1LC9qhx34?^M3Ee|x2Iv<a$j_M?qnx$RJF z>FHE#?X&n3pI*yPnc`y7Z%6J%w)o>Jf1Wa;pL%^(zvYT8KNjA~yF>Yj`uxm?KUxKw z72EjMqIiJv+Z0><n0~guyDOtyem@@0+H+iSSwO`rS&FSb+ZE?ndr`TQ)wfRpSp4xX zy?%>N#e&cD$#c8%FE@tz#}fV*;TyeL*YuTt7^~RCj?;&-yZyuFn%>rLyx<2WsD8#T z#8e!KBYjhwZx8AlZo0=4<dZ1kn(y<zp1iu2Z$0BNZE)oedj8QWAJ<QVP4?u(|5n}| za<>9*XYaY<NBl#T;#LiB?McaQfjy}IZ5nK!CVPqaj5)mV?NeoTrNPvgynR~D`1a|v zM0ouq+SVG-KB;Ed^cl8Kq8VmBWBa7rkCo@}hI8ye{n9kpJ`rc~_DMIZFAK)uO`iGo z2|452C+lJ=*rA`8YtRN@pLj8Q(xjh!8AT1;#_QIhzURaWEoSc@pg6j*=U=5AtbIZ< zwor2AS6q|a;f6CDo#OGyHsA$Z{K_?9{MdKk+DiO`;nq@*_ak}3(dnLlgbfI)-*Btk zQHDE4>18{5yshG9#b&=-6>p<_x09FO$*}rM)Gt@Q&Ce<c#}(Un*+hI(YwPD`<(vJD z&h+so?B~uNKdJ%S6&t^G7ten}`Axfe{FtS;++*v1#eeYlS>;D|^Vsxv5N?%kTfyC{ z@=ddo<;&-IZ0TuHdu3RI1+PBJbCX77@s(>rO@Hz3Uf+q{bM11M9`3T<f#;eQc-%C| zV<+!8!|jsgak+fE1a2E`KP^XkZ1xpDG#~Ky3;xIcsp8p++ZD?vdBv3-<K@5f(3KtQ zvF+qXj`LW*Xzn_X_xLE4Z<24az)e@&uDHgNU72RIPzRXGvpvK5vj%h4UJP4%Hk@d` zO6UpiYXQ~YgRqr{k@Y0oHEH^0Dx+QT=#7=|uuuOiE&s~LJuchJ^IJCX4E?g9>)6=i zuXViaDDn6fvR{)dA?inaB@@m_hR(2kLUA1NZ9k}86Y`<*+kWTcxA|kI;tiE=M_+$Z zY)9AAN&j_<?MSpg@ol|e<ni{P{#f<x>I<1W_YKMGv>`#Y{JY=#{QNh;@ek7smwEo# zildMF2eyA+3Re(RUb~yKt21w#KJ{(<GP2Fj?PyKAv$3764~+2kFnjX;Gt?dqOJ=)5 z-^>!!6B1AU;R6b9^>1R@{S3OZNPaiMRvs3>)~klC{Tt@_uC+%yGS-u66Hk1?-L7z{ zSxfLU)IJ%(^rgeRUhYZ$YE@)MffFdcb1WkD#}Iy*%BzU5>9=4L>_L4_-vZ(n5a#+i zRQY9kbl98X--yEVN#$zdb9!vQ!o+&pgZi%!W_!y0o%M5haQG3V-{yBlw*F@LcFI3v zKJh=3<ZmOq)D)}F_&egSPvQ3`{&K<%gxUVdry;t#J-Y)uC&qiFA4&Wfgu|qd!;^V& zb13{igpVey!(W2R@n=x{tdGN|OOIXsvH7iC`7?WLS1b%$f_^TxtA9_LBK6rmGA<<f zp0JHK7L4_k7(@Nd33LB=f(nrJ@%+p7TTJcx_MrY~!ZbZeTzxk&TR;3*Tw{Xj+kC{x zJpS1H*7)4NE;fexod2HM!z~p4iyq1|OUIA+PClj!sl9XmW_!r#WBbPQ*OxVYah=cf zr}%jMsHFVdPWXLlfLkcvKJm@z-+;n%dbz!9py{)#zl|E+u6z&D@@+5oB@w0cu)SQ5 z;x}xc*!#2c?NfW_YW()eJ*!Up<ev2(`xKw?Et<3JLH*+ivwSV_xqb6|wu0)9+j9x= zZzlaAn!kKa{GRl2`dL5M??lz#te-4ApW+)uco)L&5N1C2kJm~5E5cV$`LO=~kUaN) zo-aEpkh>|o9;+s(r%?R=N^tzcV8R^VGsL(2+m$&k&%@Km8+n91sBhS=_M3gStDlA~ z7~`qNP@m@$yJ-IH%GngfcI7`)v8iGFJn{8d)x;h5r-jO~E80&```2U0M0hJtBXIry z-10PiTwXn4F3-~_|8pom6Nt~{x4ZJ~$|#rTU6xSwmy$kPFWc4VVZ@J9cq>o4YHs6Y ze6F|O{V4rkQ22$a-(Ka}kmAcDdBzsMiShWzd{Xb2-`f<aKb+FPD`EMRPj~kh1@=kU z8x%L`r(ETeDB|o>u~%q#`(*5Ap6x32ldp!A>@K$l_4m*W*(b0K+b6E)s+@glo5OEU z_Koe+YAP@u|Md-%M5=f{p5?jz^d@d1ynF(qyW5`P*PF=+5nj(;mf-jY#!HFM;|=5c zNPcz?cxy^8kC!|jT8H#)N_YfeuD=1qXM4l;jWO4U@3mb@sd*&sQ<wxz&w|&bjVC_q z>(!l!XAaMp!~aw~h~ne%lkr%R=kgswe6By<KcMF9#!`VYe+udEiGL}zH(tMS{wI_E z-xFr}65{`k(m#pp-vp9>ittdvTz)4}1#^4;lEO2dN&G6p2NC`q;r$5j-UH_N_9FRR z2{WJTm-G7()i1|aN&0)r&juvFK4DG|@8@&-kWcD$cRj_=>7U;{FrJxTN&KGl?@97I z5$=i4@$>!_mk;k>F{bX4__Tl}i}kVnV@%y+4g1M_#;os`VjfR=!ac>u?f<7@&Tnrk zX!W_g8T0!C^C>*HADds9nAs2e=?$BY8~-@6mu#=Oy)fqd{Z!2Te~Kkc{l^INe30ue zm*knx;|KFUq411(|7sFt_;?D>{dEW8Z$x-svR@p2f2uFOKsAf>ar>wu{eL8VEfoH0 zlBeuC9<TdoczZRvr}EjE;`_7*+)VuQd%!#%Gv1EE_hiqRUrFJ4zQ*?ZP%6*cDLmIV zkN2#P=YxzNB>j4AGC^f|-v8n8)#}$2@O+)^!*~-^|JT;f_LAF&^>2G+m(!O|>D!+$ zkJqz_&zReX*<TCB;}Msyt<UV$$5$<&`rQ9|5r0R*dlNQ$VXroG|FrX<)&qS^7Ju_W z9`pSW)^Gbk<$v|^pKF2JE48m`g%ls<`5RG%<alx-)wd*`{KMY~pHKbi6v8zm&;5(b zZz;)JeHgjc9@Mw`wNDD&M)s7`*G%dAjP&&){x`&D`+WuR8IMuEeR|_Y#rA0r!={EY z=fBhh)#vey=jYttdHkg6UgNxOTZ->g!aTmQy`<*F+vjWGaiqT|Je=yw(qpfvFCcw$ zNWM4mM-twWFw3+3<ML#@9_h35Y9q6LwvT+Do#W^7W<K{fv(FYkmpAL<@H`%IeB55A zT14ube*1)jVH30dZMdiQ%i%dbs}K9s%^jv#{lnF_PgWJ@CJUH-wofz>JMsRAg(7pb z#(o&*XOsn0f0+9ANj1(N*Vp<Kp7~MYpGpb*Bk`@gj9g?7>NB?ZTAuI%FQ}Y-s>IT7 zpL8*7YX4*p>a+ba{U&DeP3@jC-5Ba`N0|Ah&pwU9^QoB>zC^Ko%5IV3HvP0pBgroz z%;T4hclN0Yp3fXW;ko~Def^c>drD7F{B-HHXnIN?w{M;wvAy8=<6dO1FR_T#Kc4W# zgpVQ2{7Z>{I^mls{u_uthWKX_-}JR>`_wPyB&6<2Jo$$f!j|9Wr#$0i;&b^}e8o?D z!7@tUyA=LB!ggK}f5tQJCw`0K7X7r!PO882Om8Xb)t=Z-L~f??_LFxuKeeB>+d$<b z=lk&Ms(i8HC6s<Xf80pr%{!Uox1t7S_Y+Khusx{H<DuDi`y`s($B10y(`)+^_KB>) znjiZFN*n3t`I+fAF&^K?sXpV6Abcz3_YM<OKZo!T#hv<zmRTCU{Bob49hBdq*ov=J z@rlYW*H8Z~R&1XF?5FzdlWT@m%-u!l{hMO@q+EtihKpY3A7)a1|6q#LA3@mGbN1=3 zb(C+PI<oU@`vjZWKl^FP!ImEV3CS}wy#1u4m5=?jq|MJF`U#&7mA6m&Y()dypOtT( zrO!SQsol;+Z}<7P@-g}6^r7Vr&$s(t#<%;FO?P^JhE<>naC@6$0o7-FzajB=CCq%r z+mSqvzXOTS;eRRS{G`M7Nz?bKzF7WnO7EqF|3R43&-rJ}<vW-3@%X~wPat{bv;Hlp zKQ>T!%YV~DsoUGRByaIm>L&$z%0Kga!rWdaQT&WqpXJAbS$YlMYY*zPJeNP~Kaj#3 zzvWra*q-=iPmMg@9@Mw_sgZfUJwX}GTHgIkQ2jj#@2=QB`S=I2ultbvk%ZIfGcgX& z<-3~+s=p~=4nLasJU-7Lej&AIzOOjI?E7QBJ@bB!r*<i2Z0WI2J!W)?22WcN*4Mfc zRG$Cwd~_hCzcUfiKd}6<%5T<BPxAgC>$CZ)ee!t$#aFG^KApKG@z0?OXr=UxB+PtH z{~xIUr(1mb2}K)^qxxydQKWwgVeUU$5`SmH+@86AMM?gr@^7^KsGi}Zk8zm#V;<p5 z!Xro@+Y9a=?~}aEXYCWiHlH!Eo9sb-YyU>J^{e4t_MraNgw0+Vd4WBs&+Em_h;R9; z)b=o&_*qom-x5Dpahrxu+@ID@f%m2G11LP(SJP)=#<x$wuOfZCUN5$Q>h~qg<!k-j z#CU#xx%Q`)7rf<qLj{{(^w{igr{brTZ=ay%^JwGSC*i-dh}Gx$IFA>TNxmm+_O|jB zO|KS6+lL<Ct?j?L)8ijhfAhy4??L6w<<m)go}d2G{n>g=Pv<8-J^C7Tq7-6@C;#xY z=BMckFaIA(AKNDzzfBE~mv)~h{*~8f{C360FaFx|&HR=Twoe|f)bw?H>*cLI*e8c? zwS=h8^CKUsOUST&f|mPFt0hQ-T&4o{Nn2ar+b92D=~5j$ZA{pPtBBr=vGK1=KM{R_ z%G)QSk5Fu%zPI!>>!<KHRDPS{Ysemtr}~>t>6uHI`G)PM0KQat`!u<&7wr?vf1&tn zKgd2QZS`f*-e(W$|AjEmuWh~1l;unEi9S9+`2deEqWV&HLaUXZ5fWHGv3;#E)aU+4 z>fIq!-Yn1dw2bug_{8=h9p63)K9=+~Qv%C1eeoB)V4TuhM|gkh5UMxb`mIyT%j{?I zP+$Ih-;VS10i`!l{z@M~?dMFAx9|5Dd1sQ}k?^a8w<XN-^3%LYj_{31Oy}Mp%;77D zZ|&KB0w${bR{eyrm52QVd~fC3PrMtpPagk3^|wUjJBoaL*nBj)uE!n9H!p$L^ZZYY z5%su0$GeF91|!^48eiu`k8`bjCVPDOOjF=}uK$R#TmR<e?Rz4XD?R=s+Y3~l=<#dX zp3CL8A>r=xY!^M%<3deO+36l1sQfm?`k6l0dY0#(Lglru%Col;gs|JKE*C$hDBpW7 zZ}H)6zSOGN#@Ax|l)EY_Q*8BRpL)0Xq5UM!-74RtpHAobyrpX<$|dZg_}q|BkI~23 zgZd8;W_z>)@y{j9`Z)Y7l4riPUlU_}Y~NWQ%lDK%mS=r4Eg|Z&y!A&DV?L*s<u|l| z>c<Fk`1!==^fnWp<&Px3bw4B9e9G|eNPy@6_B|PsXZy7eg}+y^{e(a}@xLK_DfPEa z32#kUKbvXEN&J+l5qN(_Kl@|sHO{ly{@8rY0$fh%-J9@nCaC^dgga=wUFgk3LMlWF z=uLbIzQ+CQ3rU{Wquk#vO~mXU#?u7iLW+>X+xTH>xP3FOGC}pn5S~l8mT*t{n9rE! z_gr5bKc~;;la?&j-xI#q0;<pHnNIwkFze&;;_$bTevbbz;v2joL&lTw-zCPA2Yf>t zsO>HKsDCi~)TFq-DNx_+VT<y2GyY?$PjOVSb+2N@{ghv>c%tHF#ZwixD>i#t{<zoQ zq5R?}Jl<MylVY>yt%`3(zQx6#_VV`rr~Smsp0wdq>cyS?)S3K*w7BB8{R7|UTj1HQ z;~md`P;u+K9^ari{+`DVD=z!D$8!|7C^q{X|G@LDy|yX7N((gpAI~=&?ezEz<+pw8 z@m$5lpL+bU##j8A$M(Kx`4=ANXn9qB?XlVO$bUUPRl~O`K2dS`cb<Qa;!edEC~o=Q z^Ys@^@uA!7fMfezkzO9_vceVj_So8Id7;ORI)1eG_c&W|$3Tzgsr@T2^7u8)f7yB- zx2wGUluWd@PoVv@i?!!w{i&B+O}}|oANEs`OH{w{eJqCj&t7+-uJ6%B^(VrtKXsRp z=NkNl-DNF#H2>rDSoHRjW0rpV>AAtAcphPcw?T2(U3o6YmuUj(TmLmO?@!u%-}o#~ z!{Zw7V{&|4p3G<cJz;I$mORJlWt^9g^bd?VKHDF$V64yVmGMW~gZh&Qb9k2Dh~&o- zjuPhZtiOchIlWxptdG;f<-vT$9A6%#ho(1)?=hPg*9T)x59?=nE+57$&-%GMS)R); zY8g?V`8}n#C;gm0*3bE4d9E*R58S^vJg5JsV$L7i6V4Co=lpSa*54CmeOw-ss6H99 zJg1-I@2Nal-jBLniD1m}b9phJ)5r46->56<;Av~Zte@psALozxT%XM6@@IWKzVw8- zJQ;KRoZk{EkF5zapTn~}=cgxrPx?6hT;GgY-%rKdzB&KAzt8#YDL&T6;U`h~GoRDf z6QAXKDo<|zte?x<lKV0S#<08bdYiwMSNfTgt>;<^Tez9_pgzwpo0T4^^7?E&X2E!U z$l;mK^W7n;s9E*fe6~fg@!JSn{Cr-@<4;f6;xm1;9CVC%KZg5Pl`4v?_78U`?$Gob zZkg-L^BCpZPXh0x*nS$8%hUMw)6>ki_*Kms`)P}m(X2m7YT;WHTmNYzZ2Ic#LH&mb zzee~7D&UV5cc^}|ul5tE`%`$Xzq!P>^jFUJ<!SA$N%1_5&weW1u&FU@KUr!0(|-Eb z-j_6a({H$q@;B5N>h~qg^Vbo?|CTVvS5N#&gsnV{%;EX`<2(~opT|#b|2)2NfBuN{ z$vU>XV|&Ks!TpP|F4q$(-=^~C_W623(m&kln@NIt2{o`L)n`9(|IctjG<e|san28) z7q%n^cYNN-^T*{R&-R{@zsCMImltE!|0jwsO4!<O`TjoUmCEl>%=x$b9;Sxd8@DIx zZ?4AcxB81KHv4G$mf3^)hC9^WHm2blnfcs)8Be!>>K|u#kx#GLV<XS72laVBw<o+I zg*W&zI(pb`G(2DTgUU62EC0A+>JDyOQ=tB6!kZBu-vhpn`2Qrl3t^6*=U-cq{EmdL zCVUU!EW(2bzeIRj>dys)^=Bj!p++R0`~%0w{dXIZPqc5PbN}V=e4fYs_h8b$Eg5`n zU+a_nCWOiSt?@oI_uum=y!BTj+jyJ~Z)yznpP&Xi!5XykAMTSJfX9<n$!zx#4Pbi{ zUtg0+Q0;q<Mp$4E>aQSNOX+=y@b)Cn<-aTO`Fj8f`=W9@o^X3$dqvH`@%m#l#m{`! zZ|QGR`|=s(cOmtkN@`G(6*txSmcI_kZ$$VU3V#dn?L6AD@dRafXJe?p72%@@lX}?L zWY-ghSx$0Xem@mkd7DzkW?x(W;>+`IDj2Qzn8(+drbvCpJpW=or=QE?B+}3AYd7L= zN0{vk$ItU=YwyLH-*kM7hRcubpXoDsYEJHt#!#Qjqk;HjzTD%)--i0nG~$;KUZnEn zn%}F4|7XI!6?75V-thc_<LCDLQ^Vif6?O2$n9G~f%b4rW+P_7^<0042O(v-RaKjBg zCXR2F@*~PW%jDI!@7cF1pX;03|5OUk^I2}c)I8i}6yEriuXqLxcZu_mc1>TChA(gQ zIW_r8#WtUb6K*2htoTowfVjrLnd)y<Z1qw6s%KdH>0IpNFH-r)5|3voZc_Qg{Jg_6 zxV><B?ylj@V{GT2QPuZ|roZzwAL0lN7}xaJ{G?U!EtcP9KE0PHjvnB#^~ZL_JFC9v zfu3*gr^gTSc!}~m6%SQ?k-vI=ALW~8?J25!!^R(L59;&x#fGVV6Z@+@sDC|;xBPn& z`m>>lQ2ae}eqZ%g(#PLJvitm|@HvvV`ZE4T_MrYLnxAqlkAEq>_;0@aey=#L*yf{6 zinW=#$|f(rHR&I(xK;T)o?3fvQ@&w$h}V~|17zedkDGKrX<p&6jdz`j$I^hq_v3C- zebJRZysa0C6?1<eb!(ijTYtA~Tlu8JJU=k`xW=Dn0o6C$MEqvLEs8gx@aHIQSN^@k ze}gc8ub`OPyS<Oqa-1(e8}B+4|5Np~9Pjy0lm6EUe@B?#_xw=#O{=`VMEg)W<1Llm zrt((57R^9=P+yxvg39By;da%RrwyXxM4z6-c=ZpDx6%Greu~G>spjHSJ?8RwI}x*g zu<<K$nwRJAElkz=C_dfu2T}Mk!dnpL`Bk0uf73?|-sX=@T5&es#n1Nf+xXH<{7&Mx z5I=rSa(GK7ulE@9d~UV{RG;_D9#VR%#&7BE)c6O5lNA__oafW0X3jNV;<4QivrsSD zgZeyQ;`YY;8>oNrekNn9k7Dh(Tt1fHGX3!WmTI7yuJ-A-`fFBf_NPVhb}HX_y_Zke zs~eKTM-=n=@dho2CQYB|w_>vNcKp-p)6XCp+YLxO`G@6HK8g9J${DWIjp&Oh{H2N` zxB2)kBL0<xt$i4InLVh#l<-G{I|)BR`0zx5dd3)Pf9sRH+4D9{zrF9)dArY#-S@L# z{p~@0p6{~#F?(ad7;}B_e2V#2AEuA-Fk`5{Ibn|9?z5U0@2}YW#Q0m=gZlds9#42O zVO|d%Lwv5^9jX4_C;8I}PbK@h1BKr~#}5m3fjy{y81cEj7m+;UjfrpfTaC>2>Of<t z&*irn@wvRY{e4RE+Yw$(_)5b3zC>Rtk3m$v9G>^1xxMjxo-xZGOZMq%O7F{rZzs(1 z+#fjn3lyIBKREnMN?#)WJH7qj_?t<8Vt%7^Qpd-+KN*js`1();{ClU*lRU4-c>d0K zTMEAe;XMfR{Jtm5_K~s8=Per3*Q)hl*!UctG1nLC?+LU0Fx;l;>8lB8SNyf%Hs5}} zFnpKC_gli%FQED)=y-f!%<Yrwhx;STGyiEyAE(E{x7_XXljtuR&iJN=`&&=)XInt^ zZGK{8*3akTtiLCG5@nF(Ilgx+A?mX{_dm8rf2Z)j6yHnw_9V>hpZ6CS+x*wmFsA95 zv;L4yp2Lr%@tp1Frlv^!GQvv<vwh_G5VyY-zc4%vr)!*F((t;*ehBl~p7o~maeOS# z`WUnPudScc$MJLfVtGy<hiA;;na}aDer~@Uo^em{ar@@*Jz;M}yDI&s%5(ZSzpVez zuBd`1#zzyM@gc;w@Rj%Yn2u9^Ct(YAq&=w5{qa=dGq(6l>@a<3y4T0QN^#`AWNh+B z*n|3(o)(oidt7$E4{z9ly=M>V^Lpnq;xk@J<IRTQ<N!s4?fpTMI)K8zOn4xLAE3BH z^D~zCHvf-2l)Ai1RDX-|KhT6UKkVhFD8Ky?k4I5@62E8pSZe;)l%Dl1qw4ec&=Y?o zg)bx=CCvIaAU?16dg70!@Vx#XMSRwO4RvT9-*~>Z3F+hcq0I-1ANS?Y;d%VdC4JWt z=I`q<=JA>BafI}7e7qiJJd?t6`r3Nnb9{{7qwpL*$EU}LiBOzho=>k%NcsoX|2FYC zKE^kYd>&!W&%?w&fH3Rl^jZJ6U{~0K`kel$#6OlW>n~A$xwh96N&er2uOrO)ZR>&0 z`DOi_A8s#PzsFE~?-S<s!TLD;Rvw*N9&9gIp8Fr??_5exPwC_Fm(y$MGqsk#$P?b) zaDU&-1l8yCT6h!V^j%{N^|}5zfBzzRp09C!nBSkmb9%Y`GUoEP@i408W9L(4iY>lM z#av#z9%anyQRcJ#XUzL)J@Gj{wnvOvo-wEQm*U>kp!oYKZ_xbXVyf>?2y=Q*AbvK@ zf7*#}=MzTe^5*<*Zi4Fb??I=-E!uv}{&py4dApxr(HOt@N#B2&&*@{#<<nFCj30T* z$H(oB@pMb5`i%cf{A~#L#Ggp*p(lCH?=KC{>1F*-)BNzK#`jCZ_f#It|E2L|^h&P4 zpQ`VdhUfA<mj(>R93Nv&e@~d>?+J7J;ri%_&-yt$^Ev&@XUy_kK5S3kO0NDjzF$Sn z!+9&x6^Qx9k#$wroqAsZeedKh6CmHqZ}0%iKR|K@58pmp?{>>K{*HRkx$4^av1JvD z7B^0-s;Q})S5neYQ#~(MQnDykzhA7Pp{~BMq-3|nwd10T8>$b8jf<+3dfV63&8?~_ zb<^i&xOsK)<rNF6Yho4kRka8^uc~%__57;Fn46Bzjm7I4svE28YNsupIxgDKIKQN1 zZq>Z~8|$m)LB0XeE?+dat_D$*l<Zf%sHVE4Bv!Maq~yTrMe&+Z6AuQpc5%i0*xbeY zRn;`sRM+lb5wB`o2!VMubq$N_V->O5C8LTDE_FLx=3K+VdPpR4)Cja+Ny)6hPnU)I zKd+Gm_de#aRrBYYqPca;Vo3Pbb<3uWoxi*`I<KxC$*qec`3n};&Xeqwlx$bKGYWI; zhU22UE^dr3Zv35>s*g1+u930~{D2>nLUkQ-T3=sRUsAHIc%`M$jaBiYs`~w7pwEic z&R>(bymlVqNLd}FZb&@SH8fUK*VefmvDS|-ZdeG=7^|<Xs;Q`nEs51k3u0fe00mvw zP|?tccy?{D60(f>9PJtpDlUD1(lqIC^4Y2Ru^^3Aji>`u()?+Qr))Yds&!l+t3rWR z&7E5xTT)W8Rp3`cv<?j}W!BsaxnZ}UzHU(k3bcCu;;Ncy=@T2TubUTZK<#Y1th#Yl zV^!ng1|&6Qv8N%Iy2j$Lt8HAUv1sS0MoFSx;x*NcyL2_^hUJKAac%Xol9I-SK4<gx ztFK!u?c*<t>l&-NT5Hgvx#^a=)fZ;FhFD`oRn5|><qZ{8bJ6|W!2C?NABc7JsKV+- zcNBiyNxQ}72fOXRL=o55#lfqH*Pu78r94vBc4?`*9iMMnT8~UkLu0R>gx-Z_-K|Ay z+ujOH6lbZsX+$=vbwL#xG^(L$enn%Qv>;TlZ&lq20);Itd=|XgQuo#Qp&%<zxG*+v z|JeM%@c0T`6k7zVQ?-0<tO8|-jFyz_END&uG*@wHr?qvp6}5|NYD!9WsjJ-u57s~D z)z#F*f^LWspW9d;LpEyb=HvgFv8n~T;AyR`ek~2W6z#^^8FU8*4t-hd+_b<jq7;{& zmF;R{%Ni?Sj_T|76T`PbOQ^en{Sk%Rb2J~`=KHhHO2UZ3ESWu>6`0a=9jM8h26VDT zv5MM;*gUu0zcZ~tO`LqN+vZXjP_#Fcbp=c~?09_IShfB^5hdbGW4L#&ipS9w(pe|> z>f<4|U{RyBm0Aosi{gu9=!r@7!4Sn`^??y6b=w{5T<kB?_E|jjkLfa0kIUYRkVdr^ zsTu*;D4*GA5J=n4Yy)YcSHsb*$tSFiK2*%BTeL_<hUwnCZdG4jwfrXp^L>3XhCtLr zqYialrX(@&9fp_a8kSoAda9&gbS<x{Z-~uDdnt979o@^x7==c$xOORK1@4Xe#j;dY z*SdH1&k4FM`uMaY!wqv@T~%A5R&m<^&64?piFtwQ#^vaO)s2lcF)xGOa`+Fv)_kW! zpV~RrScTa_RT@h?E;_fau11+U^apc;DU(n#)eXVSBSopa{NEs+3XHMVLcFQ!nh&J! z_Zl6h79}OSSJejt^tkAP+Og?_Y#1G1>W7%5P^Ip_C+9dM6D8vAdkBqsStA}R8tWG~ zG{)w;KR%Ix;)f}%YOGsSJr8Yp`LxB8Cuss|W9SuesVta3-yVvQ>mWew;ze@<vQC6B z30k8VL>0<>!O{?o720RI&-tV#F!kG^t|rZJFr!umi22*ms8H(Od^a&LO+DDnDGa;0 zFqHEau4S_0HaW$)d9atU+Qtfu0Cn}tr;SND2vMxo!2B@lo7vB4hiQ7XI~ONp$-}A^ zRejaciX|}^tKF)W?jD;rZ7oefD=+1!o6b0vx;N%?CHa9zI%l^DWY7YAKPbmUc<aRr zG`ck>l<o%nJizREahRW2)gre8M*HNf1-f9t5|+wOUofRufU$daFqfHu=Tdh!K8!hc zd1I_WhJ1<Ly^Xfq5Rc8P2qtAP;EUXs_%#GSov<M@X&$*2JM9N+8K`%QEwJvI%Ak8e zn;`GH6zy?srQJ2ECZ!~OFYcPr_8hy+Eq1M+p|k5!^s_A=cMj!)W|G`YF|R>C-l`E( zrMZh6W4l+?EKXR;U)Yd!eb$w3EoEDvEqbbJjNkNNHxnDY4Y8{Fc?)5IV(938?bmZ= zXDq@}5t04KIXvV_T?b|?V)+)u8<+pwS<59ay1+jEug?Qrv?{|bh&9ez=;m&m8BF-5 zRl~Zvp}Cn(>~=+6Eta$k>gwmkTrn2g7)|SKP;S7Y4U-+zJ=O?VCdQU+zqqP?e)pNs z+^YKeYO&{A`v+OJ#B9~#!^i8Y8)QCF9{9na)Lp~RP>(iy(I+A2#~#dI=jx=^O*=1y zVqX$WD^i+e9tGT_Z`UxKUDMv(VhxziHzxOrpKrWN-HO4zTw-G&u`A%7-Y1NyQ1t-^ zU<~s%NdB*As9uECCc0&#EVsMH(FQD>&@r)|t3unJh<{Vi#HW_Jv9S!B8E<j0E5|O7 z-&qjrw*dJ_StK-4>8dH+Ky%F)X+%qX1=e961S5gQ5sdgU9onzH3hN?W?_p%e9u1c8 z67d?Ne5pI<(_XH^t=H<SpnLM9*n{Otx^(Q1PY|HRRrT0IOWi{&v)rz8W|z;IT`_&D z^4W8C+ty7zQx`hHYS_$vx|Py_hxC#Kfctmv#1uiNl{Qu0MmBmdUhTSI0hS`#8fn+S zZ<n~;HVM0$Sgo0`U~I-#M_q+qq{A-P&A@W~*B_`4ITjH&pnJOie#mWpjS)359WN=V zh-0PPSb+jaQG+Mq%}!bD|BMy#T1K-{HyFD>sFr%Pee5pORLomgU4zwpZ39N}VDcrM zr@^<vloOVpK7^LKz9$EnN$&1`cVRp16K-4Ei0R(1v!Jl?uhhMB0cO&Ru^EEdNyXA? z{5Mb5EmkAe!4{x#N+M)5)~Q3cHJosRx=m3<V?RbGtEit}gYC#*+;n#}VC!&6V@2%& zuK)8=&e#Y=1H?W>-I7>+jb9F<XOy~PTyzQs2^i^VW5?9Z{d2J34Hjdw@Q97C9k2?B z)lb=UT7nrYt7rj*`D2iyM7v6}7N<>AEcg8ki1(h{Ex3|}>IkNBK_|wL7H<&iUzOPZ zOkOyZx`BhUoo~#@?cBu+7R0bcwLmruf@SJrtS#M_2l{p1&z~oc)yYY6><K%TOtx|f z7GGT!UiM{DROJ$k6IBgZRiQgpp)u&@WH4*V$8SbRJL+mevZtG>8O>W*w-m$i8b#WS zugV8)ff_<mi~pbQ4)^>n+b=8^*Tm*doHW%nKGw@E!BW!geX^60M|a!Y>o#iqsCG58 z8f&}y<+Eb@EyB_*Q5jlQHtW3NM%}BDO@HN)$T<%?hkbRlJ4{2n?W$wFp4by#bMqT> zhBb+6*%5a~cdbUp1Q`ql*oHc6Lc$;hqv@;w$Z)OIyv9n(U51Si=@3|@>m2@9GGC=` z+u}?)YN(i3ADiFc9(&Gjk@=C-Py77rOx6#wLoi2<V@ln|Ct>J`)nm1ks%6fot&P?1 zh6Ha@U0>>Ej<X?NGOXLYiHSj}D?A=kz=mK8NcLZ+)l|>LY}L<4&`cLEtEj2oADgMc zb8sMoxopFJ3+F?39ZrO+8e}_H_6>jS!Pc#wnjuSw#kH9JVB6T;(TT35TgaHMR?J`Q zHw@j*t9`+ZK}x!I`lZfbpXBHU&1z|EK9<WkDH@w2Gl%^!L}=%zSn?|_$x7Wbhj`mJ zZ($YMl&?#9#(_iwjASgB<&2AVrM3GSd}-r?sW2+R9@iF__yzNYU|B7D?G>>=1E#ZU zn4J?3!d$FDMxVsG&NrZ~>gQQ2;blnD>`AsY(so!`--iDha&`OTK*FnATUXj0XFXm0 z&9<<llLdQ^I)}^bhe>c<WA%dNSUttuYkOq`mMLCUUGHAmQOwjb-7fys<|d191iYZG zX1=Zuk`8u)`C^c2F#$8`f-Oy~!MbmP3&#(6awLeSplTA!ip@}CzOwvsLxiZNeBp^6 zL?zy=#`$%NF-u>HB3^;v7#n)1LaB*~Q%c>#yW=2A4=_Z!yMf#Z`?YC|mat0QowI`e z6PsH#e}T(u%W!qIHOniOOmWZG<T@M_)>bWwt$o7b9@*DYB%AT2Zs*2y+el_JWD*6# z6HN0;-LZe`YL-FS>gE+}SM{<|H{pj&H{DMhT;`aZpvtiUg{HnZn6mt8hW2LMMNgXO zV27fh)^@B?TgHc83posPSeQ3V^TWql+hLl<lrjwJ`rW#$U_)*#4Z`h)(w|%1i1V0f z)!HClJX#a&_dSF8<<V!+^1<s&%o4ku5^aZtB?gcsSUx2-XLM{%wG9*;p>%bOlzA~5 zR~H-@%Q=orHhmIO1`uQNC%l^xY)3ZK)GgKC*uz<1(0uHOH5lWdXF<19ENnktb8xrw zg}_2p$915e5nr;YSfK8fsT<R?Y?D8A(5_v6=1b^O_naO4rCfvKRC#cQ3yy@{gvA(y z>M+Mnniba9?pIUY&?p^9R>Hg0?l)6lve3`pIH8sF&sNlZ>`Jt;G%Jy=EeuRL*D!|T zqGLBKbr06CP0<!<JqqWQn5!?ua1Og109i57QN>IgPt1z_WpNA}acCH?;6jMZNxF6I zuCs00toii{IQ49ILboZ$#3{e>bmRSVl1`ibmTs^gvepsZmd<X~Az9AGs8O39yf$;x znzGema@M`o&a9jF|8=XKc(8A^55LmwJUi9UT<Y>rw86pw3uW}SR7G1|D<i)<69?Wh zU332#AC{e<Y1MwBf7d+R0tqgYxV&MqyIB>l2u@;L7Cr`)e4b<bZ%Kz8I{l2vy@~1g zUrjC9YU^*oM)j{XVH7j}W#f-sPU9vRRv7ztnTS*;nx$^)`k0R(xxs$>8pE8oHdAcg zY|UB^%TaH^q}!KCFtgsSu6_|#buk+ilFeD;@^}o!cxyTO+O>X<>iMx*!F?CltRuUP zJJ=+?|1{eP4MwSi8XkGO#!BezexGDJTy9F-DLLY1T|g&|4k#Wh!~UnX(9*5cGmsX) z8B!Imnujy}WMfH*^5t3Tu8QTj<P$IV48At4C&NkE`US&Kk{(@DwET?a?A$4vmXs`; zI;BE<+1r)#tER-ddF)2Atdtq~;@XC)1+l1{;@8(kM@}Cpw*r*AAzDR8B$3DNlijtS z)ViW%3!Y+?{^Od>#vk*BwD#*@7B<gc_ruL8Evd(`e<{m+9FXi6ua3up?TrdK)vaDo zjn(#bn`B^)GH-vJ595>*7e?p1yVscgr!+c2-n;Fqro9_8OO`+|6Vv)6$}Oo*kvweR zB{!tx_V)`~kH5i1lOipfVNYfT_YGlTFt6Ktc-Z-sx4(;8fd=6IQJd?Hd$1&%_6v4( zOWjeIVJyK-zgQLSO$4PU1Bxy|yDjm4$<lM;+J^R0w;V55t#SV=sWN2Gh)!m@O|ELH z4v_0U_`lmQL$?>YiFeJ#>@4wDs#h%7lTz&~v^3q#3wQpHoYVXdCGQus->wa$#BlR7 zCgC=nc>qnYKIyu)@7gv85AMF|Y<_bLu)&>2iMVUT)?qf-yXa>A>T%FojjeXMBVN^5 zF~2Uwo_wjBF@@(dN!6I@vM}zX?h?)Jn!FZwYvHLcs;-&VAf0w91WUBpVIe)cmz%e- znugf4jbQ&88l&pTIy?xpHv3jBJFti>*v6BaSyHetwDGDnjtnN^^7`9&5x@HuY`1<Q zoh~@RMPBiF!Q>gAFJ!y!JY5d=W;J487$)n*pMRq0>-~T4&TXmt0NY@?2PUH~PSAQ^ z<yUjvDk1e!>&P6wDBg9Sjwk8e3~OM+?JmA6Nq?M|)F^54^DCJMTbY%*oCR6_N|hWN z`*ERLt3&Nej;zK%!xBQykYzJIagLmvr1?v$>aiWZjd;nNpKXTFWiTVhb?0D-j)UgK z^$m#|;VE~2wA9n^QrBwqs*saisGS!#I%E^ki9xByyu`M!Q*B-)Ul-eEInuTE$kR_| zQl=Jpe*~YvXsp^__G?RB<$z4g2v879@LtNYs(Fp>&<s={4x{Zl%KyqTtXnhJCL`lK z_MGvWik;f7VHmq+oJq?`t)5@^WTDi3j4$UVn>LN8+q*aWj7{o$|8LJm(p_sWb*tX9 zD|=fMAMEb&?@-A*Ju-i<s;662iDA)BCTIES`#il!A4PAG<uYy^s9CS7t;X?QTs*z$ zSuW3V(Gzo|Zbz|eyx{a>b?6IF*x6h2uoiY^P2$>4aL@fuV!PX}bBNK~L*84lvzA~b zztwykBjCahnz+1HhUGOD54cj5Y$Z$Gm3$C@j{Dq1J1wtmtk!p=B$lM<wru1CH}n=S zkh4{bO60oY@Y^}1?r(=+vj)8kuQV)j(}VY+8s;JMKi*uy)cxAVY7%~r&>!Fh7dh>w ziDWD>^v$TneMY%8H-GV>I97ZY;+sD*_{cbnMe+ULB<>61(w1Bzf~CXZX4e}r?(bV? z;YfQ4u7Jnf4;O@zrf1fLlP-Ko)1!5T_VgsNt%B{6h9pU}*i@n^G<KU(b!|xp2a{y_ zuuMv_GrweHjNm&&{-zA>kGuT;^wMjETTDFIowdK-vPn7UsQF7ds#Ptime-8@VoR<e z?|}0mxwijfZ}aL%_~UN#$}V2^>;8qvq=NaMp8On}%`>@fb%-mazv?U|(T=)xhE%jt z_v&-M?v>;pUkfww^DD`Nq;ER^_bjqq<R@Gaz-8OORtHCE>8=P2UDeCsZVZ}x1<sG$ zllo?^?YZ^5Bljt;JJFjaJ+2|LXK_Jm*GinKbR|6PT_O$gf7tu-IJv4S|C2p{I_@Yx z9Rp}&Q^-PqCOmBtB7qQMI*SmbtaMd(7hPS|bX9c{Fe5G_>Zk~afR2iavIwJtI*cMR z;L4)7;l7~b0^*K3Dk{J4Id^&YzV~izU7bWf`~gY2YkBX!d(ZMc-}62C4^52%8|V3O z44e-yXG#dlRJI14X$RB~2X{-{h=c$0D(Fcybarpc4Hf9kPiN9{onCt^&^l!PNFxey zszLi>{Di+hlgrj%hIL?Jo&Ze{e#Gziknb{NsapXYep{P~T{UzOXW`t}jtfQ{wG~*z z)*ZRgA~35&l|V%hoqnSn<Myw$xer>h6Knr3wxlo(UQ=P8^zJV+Z?z1rYOP4OJZ&y| z0qWeap~=c9Tj7?F8`Hs;%{RVl@lLv~n}DV>uS1J}6#%pCA#8PyBf8?|SrUbz1(Ak- zH;+^=iuPj4v8S69>8VRlVp72kz2UrhB$NsIbE*#FxT7_0?U^3_+&mi7eT|wpqFFB} z1VnTQxEGQh0(d{CNY!irQi?r71K<zuRZNobX<Y|5y`})%1q4ipQ`z-NIar|_{3mxI zI^ozScTRDlikNi>Wmk?)6gR6jQW~SZ&zwm%&!JbLlnR;v8qRVJ@a@>X(QPnlfZ!80 z?Xo{7cVQDV9d^Y02y2P8*T8f{_kjMuVTVgq@Hf<rm@mVm<N`WaYINW|XitgTK9`GC zl@;<_X>9iR!*iwa$z_@eBmXuM1?H0kyk#)*3!hfE+;cYPvu4gB*b<0S^rI>~ST5!( zjdA+ZXCzZ<K+2#>7s0ULA)u33dx^{dSbF<S7hp$b#d@FCpL_DAh~E4#DqzJt;G8iu zVWK}5oVm%R^p0<7eUP|P$Iokh6@~m25Lr&WWf`3a?F3nNq?F3R*qWGuZ2`yte!dS1 z9!a>I&ix<G;&u6zGqFq`N<%*t7piJh^rpA*R}O<f1b#m69FX11W%g_I=;6I+2n<00 z0DMjgIa7`48P$kRJ_cRE&L&Ni$99ahYIR_eg>mEpMQ{~zqFT-kfiMOxgZkGhW{-9C z*`~R!El1znT^|8Ph%yTRB>?+F-loJPF8&wj+xQ7%m+Ei4>}cs{5_3B8=;B7&F9Icc zLb7vT#2x+541{qG7PqItL=nx|IggYA###^@Y4t;K|G#=PfqI6pTFv9r$Eu&5iI``5 z(mZ>yVPXgJPlkE@7jc*@(Fq=M3DP?-u}R7s(1pyi8_`9!RreTl>JCDRSrI>JCwjQ@ z9fC*GWfU20aGIWJ?S0A;!UZ8SzJfDj1%Gofo8^aGpN2JK(6)D>Oy)|`#dBeSL0eE} zc4{!*v4@)8iCrpBfV6P8qeJ14%bb=3hb;UCKuCyk01c?7XfCYk@~n>bSd<23Dc#Kx z(eIHYi+wT;$){baq)4jL7)n1z)up%{NVhJE8B(y)EP!6Y-bv_4^`SYiuywyiu0@w@ z*Qsi%#wMD*!GMzkT!vc*{!9)2N*00l90DEN$Q1Z-M2Ei+aVWo#4#n!QnvJ|)!ngpi zu*ri>0xyciN}7LEg3lcIG_(j^KSP-L?rC-k)7QKX?brajV^><M?<g1PjPI-TtA=*C zVy;x68yqkhu=|q`a!Zc~lIMu_!!$c?eWq2nvB8U*iroH-_$#v2;~@0YRD|dax(zN@ zt<k=3=D1s_XK7QC?c(wkpalJu9qGyi@+Um>Ogj|OGcZ0TWe<0$9SK|-J+uz&e^vmr z*;X?);!KTr0y)W-OT&m4MOcRRiy&KO<wI!rNkqU?a;OR9`QfR(oSC%g0}=S0UQW;D zda_<7^!L3{Y?cx?v!QA`$+xIjpq)m8%!`ZA0kdvDqj$4-89eo~UNsX>IbT2^JxX_c zdoGRP9Mc>~MFJmi4~&VinZhnncdv<0=q6mOx(R{Xp!`w-u7lQIK2u7o;wB`TD#=bj z7m~TG{)y;yu*907yl_$b#ULb`Q=(C$$2O7?qL?kmSOQ@KZ;;!dRkW@u6o5N##Rvpx z)90Onw!2-uNkEK&NM_t(m3egOw+Oi$ae>x5vFF7)dvaTUw|@#E`rE6Fqg}qxE7;gt zv7@($?F`ZKLX~wDg}1=cZz$(+J*lNHvKOgW(e(dbbrZ;w%=SX+IY#F`dJfgf#o~Bw ztVZA58#b{tJW|h%PMS!#^)2qs<%N=j=x0Xs0E9po-!|7R7DBUXwa8m&MQ(_L`(-<+ zI8*l%GmWJr(wy9m+N;2r&NG^(NdFtK0Ybg2(Z?WFqrVZjqk6ot{bpS;SZ$W5SzqL? zw|u3Jb+<l3)gU0yB=k-j=fov)wrL7+W6^?2aWj|bbv@oMlACr%lY%QYi3sR$;Euf5 z^5!_KK)A@4olcjH)v*FryX_8~`@==y{!$l<d)*&OEgu0gTrDVm^=4QZEE#T2?Xae{ zFcWr^1;}<(p`Ezw)ibpD^K1h@yy@#Li0F;zT69%D=`%qeVxJ~&2o@xjJ-Gsae7VS6 zB+*Wa=<H9*>Y2l+Yds15;)os`Px>mgl6E^|kE?}up5cHLJ=RN0?k^DgYWU|Els*<a z-v7v*H0MI4zQ`g&xIS|=wnmY5w1Ec$002^qpzT1LODQp`t70MMGUyeG{A2e@Vt*|L z0;M~Kj)oqjcvwkjyl#F@v*2?h8cm5@K+7tf@~|$^;7FmwOjZr$X^L+|Z#^b^T@?Zb zNk=B*;Qi7-ivK|xs|?^P@j0r^sd+e<rN5D%7{+H~$#H?)E}i;d6AY@$X$r`}yfE#a zbvC(4DtU$BGiINpJZ-f{7PBlRw}-?ck6nGF=TZHeNvth0o=_C8o5<1+w&n71#*Q=` z`s04<PgjDlz|n2s+05vyl3pw{-T=T6&qH56U^Z<nk4l;BDR<y_Xvs)yNm{#_iAvyE zv$PR_c>3*KT1(SbI_TzSyUk)~)d_WROCo$wri~4~1qQvd*CSC3e}6>3{HEpoLErhe zko0nkbM*AR5k+wxU7)3J@Y&)m1UtsTEZ+t(fUl=DH)U_PN~x2z_3V)OH8WI0IrLVs zVpjJ8f3;Z1MwHqFFpcP{XU(Po*7T_N^P`({q+cvh3!7<5;_dD=Cam^C4c$0{O=Ln0 zHtun#g1>Rf7E|<DW>?BHILZL*+mvn4WWR_Wd$BTx#{6eRv|<PmOjhGd&Gg)XZ51{{ zxW&vz646}<w#&t#zsFenFJoSFRrX0U1V-7R9qDMnxNRC`2@F;*uf-A=JbQo}EZbA# zLJ?evV*KdbIh^p6Sq&>In9xnW7sSGMc;B%LSlrq(i28IqN%d~1PwMP=M)apop^uA| zS(O)R??aNhPF)_r7MAFQ^3bxSxpk}@q<vDWo5Kgza*$kOQ@|XsalBVKYJO+Jv!Zw% zI12PNM@7Z|PN8Q)RFlQ|R*f0TZPV8P6Zzm=I<Z<ErEh#J;UN*AEuRLuPUZopRXX_W z{WnJRE&$R-PDsN(_hVeLRk34d%9}rikYkF=@vKU$e;v_6;DU%c+rtGj4|+ScFU#cm z{U1I~5}VlsTG%00*y#l`g7~~_t-`E8mpjuSf8{mC+ZenWw+cY|<Vh%sm?x&KiYZa7 z+*VzU2;fpx6jg+gwBZ4nlJ$M@WKqtO=PI~-Wf^z13{HwhAiZ%8!Y&<#sj>?L`>%O1 z=rxdx|F=}OCC`q%uTI;pe1~q77l>G`UJE!@y(mz>)h8qT`1!H3w6rpWJ#x8-j)NP> z!p#v~g0>}-I|3?x?uR*K9UDi&QmNPI`&qq<wk~C8A*c^U^hr#%^dfP#Gt$_WZ5b9` zFq04~R#=ac5k1q2P^#6CLDz^*gBlXV4e;zt%%V#l>T;KfgaRZ9j9k9<Oh3MNE|^tm zn@oFQ6r#e$d`^rJWC<DOdmd1gIvO(F)DqUAPjtDMm%|oJ!O7FuzN%HM>9cQQUFenX zK~Ej3__;hZ>gzzw5`sO`3!8)%?cDA~%+y)RjI6^+x=Mlg5ZjJ)U6XT5bAE`;D--kY z;Hd@D<B3l4Q|3uz1=@?97G69U{>%ZZk7kaXx_pz==LZKHRx5ew(f9^v874vlbOtxM z^G<RK6S++P-AW36*JAkGG1h!hdssPH2E&vQ(Q#Dz$L{T#l~PfZ&qu<Cr`Jl3MEWx` ze~eK2l&{WG<$6&~RTtX4@T@O8gRjV%hf?~_f%8(rn5qOG6VZqFn@vz&MIyXiYvssw z84dst<UC-UA#n9TDZm~Z5Gi%~uo{2^RXH;Nhm0#SCNKlghv|K*c38@7s&y4YT2Q{_ zYFD1zom)mf+iq(!M&CB<x!P^(Vei(_;DqU92gM<H_{L2A_JqPPYuvYV;eVG4;n1Yo zxJ9!hV4Xrn<{A)~eKV;J6&oFFcHb(}o0h>wh-hT?0i~a#W7>H^uVNq?jn!_PDLs63 z2wE)r1@w_0&LeIs$T4nLzkD|FV73+5wRB53UX1UvR9OS42qH1i0Fb@HnIPv`uJ`dX zHi$_j#tOp5HzkH#iA+vlbBTkrwqgRkZxzhk`&tYDLB*YmI%qyc&5AFx<@TPQ2-R*n z{r#pm`>T6hjbUx_CaWdn2k%AWgV2Hz3IzOR5p#zm6-UFU`Kx|u0FP_+U^Mi=0kwIc zy0N2iG$7OV`K=m&hyTb=j^#P>t>MoM2eS4&#kG=}hqC9m6&Wzc4Fob@?sWWRbyiKp z#^(v%nEG~(KDezQ<6959OznGiM~xa40dh;g%mRq_{P%291)iF?P<j-=Zm4w&lp4{m z5F3Nrx@;-^EBa|!9nMSMu+`w|rdcFOV*t-bLl_gWp$iQMJpb`R`Ds2tK#Wqr=CnK; z#xDBFJ4SS9k#)WIT4a#nOF;DUe^;wDWnO*2yIWzl#&xr0s%B6Q7Bsfb(D}jfhGb{p z{?GW<Y!SJj{jR~F#VVv3Pz+Rtzr8A;k@ER4h;6dB<h~tR4y$}IldW1|z9M3qw3wbt z2(U-D>GTSQdd8rSrq)h+@l_=Um|Z5!*F;sX-p)Xg4b|0^!7?`FWIToOx-*Q&#Fnzj zg<3pk0b-{j-4-`5R4QLQ4Fd`JpvGlXrVVg79%1Hu217C?pUybvH$JQ~VVHhBnX}0z zhoNOUSQ|xw@D>gjdWg{heZYj(yv)qS!>H(UY9DJrEy^$WMD(<$%!AlG0~a6()pF+m z0H8+$WljMSa*dsRdf?*eM#z6FBmkTa@W}Kz-_t-K`j(ynGQkWxz1y9=(%f6HFci*t zaXSx|OXWGQLquYmemaaquEh{XE6}xPjMm#HU4GnUK>1z20@1j-jrKkd#4D|_OgFr9 zt`4$s(v7e_{rg$-iKWY-`Mm;CMxbUN4ce4>IM5_DHifnHGbu|k#VYks-S@&|+Hqj& z=RTz1)F^?cua|OV{JPkX=^~`vd%^2!hf0+i5Fkgo7Z=8#p)Z>M$QYc$1Sw1`>eHO? zL@yNJBG!DCWoX?xrhHL4BAo)5nCZ&Wd4?Fz80-p9-kFDajFRJN)0Wju(S#WH$S%W% z8sMEIG%fvf+T3Lkot1^X2lu&po|YsaZSh<=4jgdjD&i}o|2ujnw|HRkBE~I&3`G~+ z;mp9{T3W~%E?J5MUk$m|n<W##MT#5vHEPrF|5Dn<pPjs@)e&ml$7ul5w&H^L;AFKY z9>E1(SPxJ+Q2hm}iHVEZZ6JwLnDt>&E$-EaEp|%JmiyQKhp#gOnFBijxq%%)<dC=h zG|;6Badyr#ng`mO%KZB636*Xh76%*^Y2I*lVAG5mcz3G%N>-wcu!wOXl^;9j*~O9q zKaS`J5VBC|bh7lxgA_9Kpt4?;sW27Mf<IZ!D;e3qQ<drNv@o0hydC9l)t4I4$0m}T zN&hXfnKdEdc(cPreFDq`bc-=#Mft(R<d!aJE3bR%Ot>HgjB$rM-JB^!VIn3om4d~- zde$hOV8C>}i91J%xE2MZE@8t>4*f+;Gv*Byr*Q@w@bnN{?rc+ncc;K3%-M2_YK=1k zd9Fepk>ASlGyox`-+=ae>0HtkcG$1c;so7#&ukiDIi6~@P7gyTN6BsK(so-m(XljM zjHC=NCnSGY8aW>YuLrlpO%x}bO}`$|vId+jAyuUattUH5#c}~-v9?k1$)LlrghLsW zfLsy9ht}Av!Jj}S)V3#pWQBJ}<{PjD{&F5hJD|OR$++}mXu?!5k&GXr_Rm6{RE{1a zYK>qNEYB%2Ap$HAOtBITsk0)7p#gn_JU;LY6b_4Lqi#qumn3(x1|)2|IwGh|$)VM@ zStwIjGU%s%_GZ}OcrcwQ$|>e50ybu_u0%sxL=)ilN->UJg8GHDftoeUX5>V49eM_s zrKuMvD`K{X0LNM?&MZ|eiXw?~j#vVk(?2vLJixK2|4@cyfjzvG9{S}>Vl0@>xO_et zO>=sKeZ?~R<By0`H}Wp-@jGzL<PG{UDiWh1YDDyWY;!&2n+Z_u@9_?Yd^dr$niH>t zRdg?q?5(8=Hz?|hRdQUt=dxK3V@$D#DrJNO4#v_v4(+8x<b82)fx&tjWq;WnGcYHr zG&st}SS9^-V>gR<|G}*L^A1FU)F_W~A0Y^Y(l@A9Bh#ifGtg*QfrNmbg?bAFqfq8k z!$-FuoC{`Ne?B~EJN<|)Bgng9vq7R6Ku*R7_%~;V16rm1L$i`X1wz5|$~!{6vYVLg zpA~C;nTGkAE{Z;<`VUhE{4SUXB3#|<81HJOQTi9ugT=zjx@A7)h;H}=)FDa*2ol}} zEngHf#8OwFk;Je(_w9xyl4dfWroB|!JUZKtCTx{8p#3(+PpsBVJdh^3AoQq~p&8}L zDHsINkT<Od_0z@lr^Rg&_AUOSjOenXQ7<YE<)Kl9K3-^jc{KF(vSZB8Q*Kc09Sc;u zw8My2zJ^N(=q1;6D39ZdT31YGkrGg|y(Cr9X=8F|-xc0AacwUhzi00=yWFjbEL@#z zhsa{0Ng=*ObmMyxV;lcrIkC2YdhlH^s9<l2lp4=3=4PRYt~~-eJCz+xBVTRa9T>qx zmxD&jPG&2{JN!US@yx;V{$Wlb{pgp0YMnindQZz9X{*^gq9+?NtZc_Fjx@~&Q&{wq z=%Gg$ZXHHLZXHBv6Y~|S6?!|`JdG@aiJRNq*%2+av#p$<XALNuhT;;@W1c!YE|1WG zUs1y)m`n^QdKBeAVRj>5M-FD;`M%MR1#l*9sxh1qEt<jlD4zaG_^5SEayykNg3UsL z=D%xc%FJ0#FcVM>j}>9EZbzsJ?0NaH$J<ly$kx&N-_Js{TtXFPFBZxtw8AX(0UthD z?64KLndR3PqW>^b%n_Y4H#53ZRhRK<sa8dqYMuNkL70i=l2tNkZE%0NH9vs@A^`W} z)n60^6$$4jA(58glRF1+{jL#6D;_hKh6e}fV8DN4yb*<In`?|?SOM&Ek&b^@6QsED zRv#0NT74weW#2hQd5F8bCG}=BNy3hNdY?yBLvyhx#I>vCZT+$T9O<|Rnn>*!jh%jl z2t{=Dfd~Nc3C-q5F2#i_(ec#zWU`BFH9sG-|3Zz02P}irb?4>H9(7O*NMC5^W<T;G zsHIjLtdOd#zA)GHgMls~kC6nQM7Ar2W&X9Lcf-0YR$UCcX7|B6-p*pSfZ@~(5@wNr zjFTJTe!2xWqF1aqNUuL6a5AMGipP4W7WRH%XAvFv?$lE6GHSsSUP@_pKxRNWg$OjU z<IhDBW5b$YYr{lwlBHZGb$}1)X;w`&jROc*)dotI5?j12qSqPPeEZRA*f`tENHOZ2 zHmY}llOb#tmZeF|AMLte5Yab)x#~eBg1d5)g<6vk^m^Kl=8?d)*B2qdEJkiIhV&eR zZYrEZy7!oww5kCE`qu9mToK05v5hv%N{~n6x|cq<S3KIz!_?2-NBOehfY;BGqC&AU zNeBPH!jtNjroxbX>m`XiMK9A-KJzaxM^TMMGDeWEE0b!%`3)oNHBivOJ!|hHreaho z?k3S?dyz8F5#5*6tUy%JTc-FYFk+rHLwGb`9N;_gEt_zC-4gnudIN2(lvlLxFh|)Y zCAa;B=kzRRBRL4A%rO+)%HVCT)PFl{LGm{+{N|T>18oJnB&&P{Yyv0&+Xep9xqc6< za4`qD#iaK~DDwa?N;D72;IoTQXFb7s)kLo-WQp|c3WzgverLUzzl$M615teg+IXPX zF5xumqm{6(zZ|w_8)JIjg#lU^h)rKL1!gB+^Ao1!M$J+S@!WjSOj^&iQp;AQSA7zZ z7Y1nDj#&f}88wdXSq*>eR4xJm{NV;CI8^#)u=&l_vb?oKQ<ptno^$YB!*q9#{rTU~ z9fC4IaXX~SYuXkhfTmMEK2P=u-yoMv=`kbrAwiVsXK$I0rQRm1O%1SR*r_pYhoe`d z`(M?B-5}fB`!>BMj@f3$FMl)Qq%4!O=viPDR=4%4ByPq((m7~!1Jy|Nx?R6xHo<$t z78Ixt;usAKDx<IU&!OYxtQ8BIt@snf2E3ZgFv|A)DnoUhf3qj7KC2Chq}0w*-_Sz3 zy@MA?r{bv-s4l_}m@Vr45OxOL6y{eduu0#WyEnL7LpDjulZ4jJ*)KMjGT-Q3jQL^c zGFD@YDoJ>}4WUPem$C<(+(Zw2Sf76y9&$vVN11b6_!){Xp+E!m*aGplJiEZ}vVFmI z7#jjNsZ(8Do!h^<mo(v6GO19lknER+73&HjqgU$=4rr-DPl2VMkP_a6`FlJ|Pwk=1 zvAxensLN3<=*K<s4Az`H7ybajefGwV=p&n9I1r4{&G2+0qerj9m<}F068A$mBX{H` z93#n$F!(kEpQ*DH(W60i)ba9?opjRs)i7WA2q$$u-f*52Vai4g2?zb@qcmSY1&C^Q zA+k^d7f@Vdw!{VuUPO5r{lAJNVUDA`jvaRmg3e$}M)Z}8O7wJ8q4jk#BhQTmvx?xU z6`YRi$zs6mAyx5+PA_RH4+nxgfQ$!BdJ*Cj62G^-5aVYiQ7g;lHnO`{n{^Q*L8jM7 zYiFdM4P=+W>uW{jwyB>fu$3wZqTi0XhxOLk8`*4MHX`a3tv!kemWO7H-~^;Y9Fu!> zUrI4o*TUgzTL=amYS)Y}=0=b?^nBLP-A_;EKiY^$U59fO(Uh_enz`MaFCojq{}rIC zW(EZOMc9|b@V{@jA{vHqhe8j;kV=J|CJ*&yPg^7ZP`b-TuC$vX)b&>w<pZ_vTBQ3B z3y)|7`rf*x!wS#gRf@MuyHzXe4zj8$%@{`zTmmrTra}sD;G{MwXrk`4#U6HE#D`Zx zOmq#SXfZJ`0>;jY(!^i`ggq56m}jF89e*q8^FtuX0UToJRZPbOk14a;5xddv|4&$* zCGE?kB;-Qf4ur&q0!a)nj1GaETW>4g+fD1Uw43#jqTIF-$p4w=z+$e(JR?5O9@^vv zhw-k44{7V(<%INPPaN6KJ>#JPdDmjTGDWLaUsVCSbw#;aYfKcEJFUFFpP7=(j=QuQ zP;%PLtE^E(^)-oY+F>tCx=qEdt3KgK3+<1l_xSbno0@Lqo_<r)?Zc@aEB>Kmof(8Y zvN`1R2!h+xHuv<A?LnKvNOy=aJXpj79aqtYB^0%*$zSL|8jMe8a=>PuBw#$E2n_Tq zeQ_0EI7ujuINQ<zkqkpP^2GOHoMK}uD%>>;uA%?1I@CcF_Z_<SEyjW~fm8G#SI2(n za;re?hb?fVZxjZma))K?JP_?=%cp;5-fUXGjdgA0<|N>x<)2rQ_F7f;k{Y5GRb+yA z;PcMa9Zu@Xh9Heqt?@eb^_^N95FuNAiGheU8{s(aWzOKK6o#kbf%FH)1EvyhktZK| zS41>>j^sOxC}{KV%(gc1lH8$F@==B2!D^#|%7w6xz*0yBFDA~S=kzCIfB8UXo7iN` z)Zu^vjxpH-_2fygG|;KpUbv`zzkEJ#Jbqen_SjPG4iQ)8Q!!yg4?QsAKI~=NA=;V4 z?9pwpru^A;2DqS+!>xtANq$g^x=zg}Q|&X(*>+fI4`mc^Virb<C-PWSri7m2T_cC< z&X^3Pb7B({Ki{JlnnJnDlZ(GHF$IdNhUi&Bef{$o!>!sci}b9AQVfomu~E*S1K8NK zr|9#PsPH+95r4J0+g@Re@M_*NsUjqv_K8nQ9!0%Iuv=2iRfa2~tr-5svRN3*b}Y1H z*{0IJonx5vc#|^qe8zCtVjIuR-}GMMf!Z<-P&plMxQFpW={yq_!IHZb0D@xi5WYfH zpcxE{F>dvls@j5hS=U(~KpPM{7zmTNPubabGxt$#UV4g+by@bC_k^J}dKh!crbaZ+ z3@!#@!X0NxQyM=F09v&1Zl4V^4Ky6R(Tv5Oax)KXu(x-+#}y;`ca(rddtFU6WOxfA zz?Yc84vR4`=1=PbCnDL6Ckx#LY!lJ-2hEbk!kP?W!~fA$st5Pc#e>+55N!VZ0r5O) zTKASDzr(Q_&Q|_0^rN}`6tr#U1p=mL8UUJ&N##<Lt`$*<WiXy*7Qm4~^0$uhd96nL z8Q5B9;A7&m4JA2bW{*jX;OY6E0~-BCjP-+_ldLFBTyAhNZ{ygGNvA{K#w4o&^d>@z zc2HQQ#>asV=%^h1n9s0Wk(000qd7S}lRcv%vUT8ld11I`{*3r&ny8Wb3|R34YJokQ z1XEWVC95fNIwSfx#)+tDu?|MhX5WpyBl=Bd!#cJax2WrW^?voQUY+v9PVd@W^txgF z<EQgk(=zR<WT!fTZ~G!tDXXlBCS08xj+;v>x8*0aq!4W`TUCLn55lOtP7mdZgA_20 z<m-C1{*bYMBUpGKD}xDf8)gd(f(cf`Xb4a}Dl+OsPC+_n5!OKXcM<&}YjQ^5b5u~# z0=i0Z8mBOjDP;Z5Juq-K6^k9zCFQbBfoC-)CQaZ>zx3_Kh{=*<Rbhq69MPk0KnNNh z5NY4pW@D-j0QDcH9r1k!AyG#*%(fresq~T9X<}gF{w4^qjcrachwInzAV(l85p;7` zeFHsfMGP2fZv<<<3BI3Y%;_|Ek^eN~7Zk1Da~>K?XfwFs5e@tyV&L0)57@33=uDzk z7FHgL5B{E@=VR(N01MU>$ZdtsDWEx<j)3T{1h<@#^!16w-z26aup<LMrtka$^Se~% zrHmkW_$6q4<xNVj`NA9;5X6R_m}$@P&1L3>X@d^bWQ|b8ycO))5GRwDu0N<(7X1he z^JBWmyfzo3SC(~8^K51v_TF2B8R8gn#qy-h^KDqb5*ejo`r{!mHf$ph2>;L8IjG-5 zt@>mP#HNqE56l2PRL<}y-}JTldKi6=_8XB1YC@L?P79hJiug#s1It<s<u*C8qKc$O zT7K>=Hle_zxZE{qAq8dfJGIQpr)gwJ0gv3m(;h*ktta3siy}DYc{A<5Q<E}qO<FPn z@_Y6C)^t=H(H}3ECj(Hj>7;uhFENocQ)9VbTrQ(IUwd+?Od5>85ATitVMFreM$be( zG69eR;JNEZ=sT$8AQ(y?n-#!A&79pSgBNlQL7*dk%8baS?!^xs6e^-uD)^E9aG=yj zngWRNJ?ca8z~JIlP$$aW0uQOLXXhSQ?C>|vC}TeT6jk}&d{wG<$jLur$Si@@_0HyI z$3uU^z-X+&7+8%%bsD%WrpcR1OIybVfNxXP`|sUv+eGwr=rKUYSGO-esIa4=t9=s5 z#)}~pV-ZI_wNW2$)Q?l!Gyy#_)km%}mA6F;4%HuQx@ZUBb<;mYbP#6Kd}bB`8t8%` zIuM~c$nI}<<39Q7rr~>*fKcWeuxYa&)8P#GSQ3*a{`X_v0`}0ZmEDb~$cfwt`jDnP z&Twz=%K^rA`#Ip-OhRj=3ZW*?V=|Rbhj1G(duqDC=iMH^840<Y5b^5z9mcb5HlhHT z=EWfLIuQx&x4U_3X#`FM<TlNd#7<dE^)uA!V}W74eOrg`T%&miGu{+3M899047HM< z<UL}Gfpw-DcCs0UpuH70SZDW8(|xE8cqA6O^+1fZM<rCo$<hZQ10!`CeVuZi+tO{I z|98-Q%9{(X(LAJU=)y_@V#o7vL-oUyU8DECTV<bE`}TU|K$<hfzBF2(>Y))`aKC6k zu*zKy%>s1G57itwARf}>qUXu|<Z;|0QYm0?1U&&0buk93J&H|d#lYAXcS&ArI^zr5 zZ^>GWVgadNZRSja9Iu%NYlcmJ(1Je~Q8()c0VrU74W72h?ZvpY#`avfG>USc#U*M0 zu=5yML|5cz(W(M71L%Znq0)$^RI&Zq-?cZb0h+ON7vxa5BS7sZrqHXempGJj-XhSN zzCK{^+d1Xse?>Iu=zu~rt%81Y`tUYGL6$Y>EcB1)%!4h};Fz7X5p6{rWZ_BE!ysbw z!q6eVouO>Hoz4=`Q_z;>0{Pco=Mek5s9n&O2Mhs(QHVJH>xKaWq!^p2U<L_q-BB;r z=%m+sv$I7msmVTzX!9pC1|4LY@I-{z!jhl<RXuM=+PiQGc(5~Xn<ajC(UFiQ{0Zaw z+j5hO=*T<glBmMwpyOQRLq`|AY#sqvWtpkXBl$YL4|iD`EsfJXrsgco+0J!xl_svF zn6v^LPS9~QgbKsnSe$!{^Qmz(GnE^?qTSn4$iuf24MC;=9kj(Ufu!G!7+hHP(BbEv zU`#!53rum`nOI^!yy)8R2W`XCaM1Kv=?(d<<sz*BhoDqJGcV){a6agE4!P=jnUd{5 zYfANcxp;y!2SxOZyLBlHRj{!VD^Tc(esWA~FYs!pPx8)bBOkSRNGiut8@lTch63g? zo#;yO&ZsMyjM*f*m|2g;2fxc$JMchV9S=Emu@SxR848XW<B4GZ2Pamk)=NV>Sc96r z@^KzvUQu^st(qgdCm?kwTv~_&g>VUnYx$C6V6M!JQ7IzX@Rn~9h8GQ$_*}LU5gqem zoO))RsW0}ERUW1LAPODQMZjfS>5r0lL;8)Jyh$1{&}fuSZLnKIsSW)h)`Y|f<~gs> zj*fpOk+se>j{K6EV56=xF8!fq*;0jDHi&BV4kT)UAEQ)aVDh%SjRoGmjTwv_zGBT# zO0CmIsKu7JAmN|n0+*+dDexcuZ@NF@IDsJ0*~X9MX`MwIyL$Co9Y*RuOu6C-!#%f; z7`crsAFG4dF-a$hEnu5@!ak8I?{o1qqOTtcz-eM4pODUAPm&@tMf7;|>gn0>Ass~o zz-sV)?kzswL$-rCEvnQ+ms}hxmC5fNW*-kxkLbdc*cO9>#ql~l1dGDwae2EHWK^fo zRU;A$Jaey}<LOep+BEb=X=mX9M6ozki?$ZI#X!)icac*DL7r2eDB>{)KTq^cU?GL{ z$+B2#_z^m3Qf5;f_`vtHaSi^44jIrNJuTC~bD+vPPZGO;f67v8t6&u;`#mLR*j;lo z43sjSmAa3Jem10LRp;wa=|<Z+%2Q05l{WuBj+(Hx$<nFbpJ|hp)YDR%t*Hs8I!;Ei zc0#(9DGpFtzg|mAeh+*T$X@4)`N0tyL#$~;xe;c*v7`3KIy!&>uwjdO{vYEr=x3NS zX9WDhOQ6t*Zbv1>k;HD}$u+qFt~6_6Ut)bwRgfLy;^e#S4j8Dw)#yJU4wAZ9Y%xq< zifF8wJn)&&uETjxfgsoyr_Gma1XJ8`=C=Ze>KWEYH$BCfSy3qt(=TtHhoPnAq8NVq z25K*+V~hS!Pu`5SA`Zyi1mixn0+lreu{Fpo+7kK`eDfL6?T?3W8Q>W}GI>e8nwg7c zziVmd3}OzhmCT8Vp^)rk?yv=0)FW)sz8Su#=*1D`T)8HFjWF*Hhgau!I%IUWy@>}b zgD$=M=rL!`<rI*i7NGJT6eH=#*hKMcz$I3;)X+0j><)aSe(KN=KEU=|I;roJY0|w4 zClUpADLY3z@A=D^Lm&_b^_?-3PRZ9s>50&HWencA4>yI6D1VinT`2)H?aZ8CtTE!m zgUZ~)^w(Qw(aKT{daOHuaiTw!mcDQ%ZLAL+Ef-36;v1as)I5P!L|lyzdoR<JJnxYO zv!O2-p-6q%tugFSG;`@aj{XLh_t7b|1E|{A2K+su7k!QsghFw<Y0AjNj*X*BoHiC- zj5nWJcYVPoX;_$tPi9NSW|4NhbcP|VOM-V89=J+RBq5T(eeWxU8B?mzi+?hcIWnax zJqGF{yz6s#7i44DwkDAWM~LKqUSTP_a=>ve4aOL3f|2h*I`Tn97*ccZv-ixGutSPx zhhkB-1&B9RKnN?A+)VBp4X~`{bXYFYX88dcN6Z4i`N%LO=db4=6xSpm3cml^KhFS4 zQ-u=L3z6E?Mqsr@>B{#2Lsty390>e$;_S8?*X1e$k+)u^)^VCK-x2-mo0a~ROlYUu z4$zCmB?RX5s{JN8Q(vFzgi=ik>++S-AonO>;o5pxM6)q&0EtEp_{Va8zT(<yy{LvO zE?Jz~PacxR+@!-6m@TL5uNa8r598+~+ZEr*BjLRu5<yb8mw{O21E8(Tc@>A-Rb4!y zvLS1@*2TgE&T!s^jwO!s@m-5Z0xP?0KFLPWwuU|d5nt(ygP<+&?S+Pbt1OTXbkw6* zwhT!aBd^>b$*x--TSTwf<*^HEX78G~<qN1RvKy5%%b{vqy~5vkV~R|38v|D9F?Y}9 z@*0Y&bvg|`iF;-+u?5tjY}<G$x(KBYM83OuHAG(G#!T|^Ud@`ILmUXk_^))XY8`?n zQFG^)-4c~tSA7t@gc}CO<C0Y0V*`<Pva7|b7H0xbf#r;78Nm0L3l|EE?Aud3HW_TD zh76_6kaM`*FiTU^oZqUW#J#-=bK-k|OEqRK%?Rt^upso$&Izou1VxV7(#AJS)@IKz zWLJZ^&m-8To-vsXoe0RResH@9kao0;Sz)G3uF@!@9<a7rS&P4zh%oHe*`%>Fe<&7e z)qN0gmQ@eY0ap}p4dzC@ldElyrGcpLpCSVUXn-}C_>15MjC2Uui_3F$NQK0kUKfO7 zi@po4kXH1T;c!Z$?%s8#n^1?!5)N_ZII08=YEHjih}hfc#T&pHsyW3GT?N(Y3GVBn zPi#&eW?6I=9pDZ*D5ZY_DIO;b<7l}nZKu&o-GE14+$vc18MhE7bVpz5z0+$n#F}9J z`6mCl?B%Kx77~FqI^r>A`Z`|4%}KJ9)PJ6mBUq^4o0)<swnRDtkFkfAIgVo=*+-`y zA)1OIq&i-$m3S`)Xf)@P;0I4HnW@WZ8jZv5$^50+ajI^I6q%ct97<2dWgYccs|+q1 zAi)`7PlfPKxKRCZ9XSQk(aT|fM~f)3A_m$ufR#TeB{mibyKR%`Ucgp03mD;1&_Q2q zR)c5k2}Ultf}0FQT|ysm`d(E-k{jo}xyhv&kL^<^Wbi9nJCaB07#MYn33rGMkmKc6 z@?2aHT>v7}Nl4`Tg+8(IXnM`Hiffd_6G9E)Q^ujblNf8%%JiN9M!g}iwR)}QX}5`h z=qv=w^Bb@ol{#yFJU>{f?_jn2W~NjBPXA#n^F4PoI~d)NQ+SGMqFKVwMrg&iL^HvS z;2FRb22w;vV$!)VxqB**h_2DSfW9&92rTtdp^?{$65ZKPCqB}+hR&rQ`y8a>2-fJC zzqb<au(7Gyd)Gt;M6->fk6myyqQ$3nV!|_nM-^{mNeRI-={*t-c}*o^cNq5V2!*)# z)(O!zq8Eb0C`h1o=sLQXtd>x`zGu^H8ZQ<{X%S}r0@PGoI2!&Y1A}(xFnS@UFF)w? zA#ufSABai|{dr919<6K*G~`(d2>*|0E|gPro4xvO87HJiYD)HVI=Hc`mn=5!y6L!~ zS+;4Pi=r|hqYYc+hIq)e<REnr$yIBM!P-qk;1R8z4}2HjE_0rshR+j|WV<)1=9XZE zz_CU@N9qI3dmkxBXGoVqg9s>y6tEo5E>@ev&H?G{T@Rfe*3ywjAo-+DE9JMT<;E*f zj;3S5$Orpx7)_E~?dT;P6{T*7!DWyaO|??9mwt?q9f@gGYE;!euq7%OS%+%Q{^!o2 zLa8>GpOERRTs=GbGE;2ej<zAzgAHPZr-2v;A}NL&Oww;~ig2LOdLS0aSu@|&yb_{U zNKoo<`P|<Cm6sT}FM~b@5%pzD;~!~}dJoG7*=s*b{5}ekjDCnUQM^ZeaCO=e<8ELI zH_&E(EX3r8FzP6f87UJJtBtYIRALFvD0?L-i8_s=Q<7*Q(<|WECcOshc%}|&D9Y_( zt317te46?WT!|C)Ij+H30VEvn-tt}!&v~{c=A|QT(j(EFu;jS_$#vH$6Sho{)!I7( zSkR9!ov^k5g_^xDqAwy<wiA>}+(|3{(?$+i73gs2WKea^7`kwZUb#X8qCCiN)8~&K zb#Cldj9N@PmDkkQ%P=R1=NcCA3i%6)-e(TL-$IxXllBT!#k?YK<F)>-h|Yh1>I8)S zO+?Rrkyc2Nh*^oFJnsp~ZDaBY_W9Cz@psKEs5}8=dvShxWqPn-JC0K5J-?nuIZU!r zBdXC(!rX3d+k_z04NU|nYo^mGCN}Fcp?;utwJ2>e$s37^Ldr7s^A&eu-Z`kDxe~ag z*nM~IHHVlOLN}#`T*wxVzY$~z{iROvyv0bMwdm8+`HQKP3KFM_-Kx^s+B(1KX);#} zwYpkqutqnbm<4lE+^*z8XCjZ%U(#jq^M((j;RK*HC?B+SB|KOW!i+^^NaIkm^D2nk z4{Uw6w!tefpR77&69xSSom1*1bATuQ)ZErm9f>MrS@4L2<r-HgQX$+bD^X+4q(>s* z(znMTvGf}6Wtm))h&~PZ5l$eOcU%MMntKmkl8Oj2x4OR3q#J=ThbQ>~7{i#Siu}&3 zVCxgN`-hjGIuY{`{;JgA%;odBstlWwF;a$~n-(oQ%0`eeL_bU&;@R_ve!$*$sYKj< z5z!6PFsB|h34HR`(NkphkDYbaDiP9c2?NDp9%h}rk4@gwLg^`u?sCtZalxn&+Gaxe zJK(MI(6Xhubt45Hjwc7J)z#tyAtqdwu@#`>=Em_}xK(UMerLksft?E^1z1E=damjA zdI6>!Z9jS$oo3NexuVQ?C8DLF8f3E8yJr*{U${>a_fh0kuM#a`q_rQ)^{dd5p7&F0 zWvv0!n(|yTqHEELhi8K<nrk{+H_RocGESG7X1BPZRZfco82fO&vN*x*CYLa6M1hFr zAf$>(3$6B~e}Z`Cv1!GSvUsm}ll0r)gM(144~_^`YX$Z-Q#~_{v)R-Cw!*LlFrH(O zM~6b#s#GrIxah20S?2yW2Y%|>5Kn}+Mjpg?qaC%Wzy~v0T->;gExMd4p7nm^TDgHF ziy~*RjBuBIM1QkMsM&GGm|2#H(askBDJ<IdQhfkTT@3_n_MqrUK_8{3q{NKXBUIA5 z8!NT^P%&KTR<BJYh)%K=ld?>cRL@xFnU;aUw@Z+ND>_z_pn&E=^IC~e_IBz|L{}O~ zIY#KRESj{rv0U7e#gb*?-x2-vU9+JUk{_=j@%oC8UiCPno{wSLf+D?TrKo);1L8Iz zeLod_mLEWXJ6IjxA#K2G;D&0o;$r$^Sp;mcWQFP&-9Dq^6lV7ZR3~qW=uKer8s96Y zA=B8PZ@?^oyr`AEO;+>I1t_uWi@33goX*ni2k_V@O2Z=}>8VfG-&-iX)j`)V_psj^ zYS%OGxE{^_(zi?}6+o(z8R_9Y7e76Zr4xQbTnf@p!Bh=jc1RLC(Jx2_g5l534!U7j z$DgSBzT1BAx=XLaw%*no$}etV)WG}ZkxFrx2c>GR=uK&q7{wa+naPbrzCvGoGK0Ec ze`WO0?pQ%*=>#k>i*$(%+&@$EaRLLt9RW<Klunm(n?hw$#sjrw$W(yB^D(jl6eWMz zV67vxzxx16JD~O}fQ<6QDdli%z~aza=_?P-rBk<_1=<lEu6(GF;#G_hsPRe5vpGKc z+4eI^qO*sry}Dsy$NC}!BPNUTA{Lpnd)^)swHnMRRm};BWKIhd>W|ld=tCIM@t_&Y zuxAe|PbZ}ETo{gVk{2gZn<m1W?Fv&XtMVE%lX*&0qmm^CC6=kaV6{~b+T}OQQQ@<V z&ID+C^vZ8&ZiSQb(I;Mk)O-wG&h*uPolV>F=vx<1S}`o?3pdO{P6-Y32|75Xb*eXj z1<2bvaDJv{w_tKJo$0sgNS8mlJ-82rcfW*?@_imW3LXkZpmWMc>mbU9M-3rzh!}ud z21RcCe6*(tS45wMl!I-J@9Ad;R)%g#LRaoMjFg38P>R+@N%yGEKzrFvTTj&~<zw3| z^^iIJXp_$8i>T}1=%_^t#+zyY^I9lN*#)utEm+0W*2I3Ofq0dWfru5wmMu+`KLQ=) z_oKZ<2wX<v`FKovqFY{rDcsz&_0E|5cnFvu3ra?})q$CHu6fhlTv0_)v?eDjCF2HN z^V{bU1Z4Sxb7OkQSH{b(M;Z?sueY#D-~-xp=l=jLeR_EJLS82Iz|*!^Mx`EWM9rIS zr6N?UXyCQLKhoSKyV8M9Il~j9A8wMCIK3q@fNT4dGk%9)3>s;*ZEcD&^`m?$bBx}D zlAd2*SIdz=R=O))M05s_Dm5Mh7v{$ZFg_@1wpV09g=tD}=55&4S(V%^j(ckABI5&L z>2c5Adk%7DR7Dw;MjHYcYmG{U0W3vLsL_>gfJ<@bvYT=mN0D+dtr5c1E7YZNi<tD! zOPiR1)a|wX?fXU-sj+Ao#_QRtZRVquOJOm*;CLalBn~r3Eeb1ehkPRd%%CA$D@{Ug z>!7))NvWzKgR)#)P&dd2e!Wy^&CgRSX;;D^SGXL0+W?dCVJ<%e?1rVK!lwd?Q2>9p zO{n->nr#_?l=|V0%OTK<A<__We(NXH&<my*&w0))It!y(sA2TJ@Bp`h2C8~|5g71Q zL*1FqG3~XcxWzZ}_g-+ec0@0#NfjTModn@Muxbi9hxa);5KsRsqP-Mha0-?pqIZ5? zwZdt$4t3(bKGd)w=Z49F@+YW3ygMS=0AvQK4dk2iddFr0K-y&ney0~Pv6kO^|6CN) zg_DHJei3smp&-xVNw9hJ+M5%E;N>Ok${8TO3v*rhLOGXGhH$98Y`690WH8-1Ra2jU z;${i6CsU^3W3NCR1R{cpie%-I=o|T@8_@S70YzaVUjqGPCI1oTM@95!<-z32z1UM< zviCDkW4|+t25b|=rloYq_q-o0qt8NUstxZHwriQsjHCapQ1=&dLlNeRD-M`4@anxp zqc$cO#)H&$;~Y33!Pn^N9x>->4Z`?XC^CBs-n=i0D=dly3n<ZzuEhirXZ;~zu!TXE zsWs2hm@%i`;YV->E+=<Woxrfzs_Mj8K2Yh6==&GUfc8cO)bR3-l@rx*`X@}Y!yRIy zGOfP*5B^LXw#o)h@JRUb`XLFSw{kj`Jq4{u=DgYJw%YM4&@&|Rzb4phe{}sIdYLDx z<=hYiw`3AH|7#Twhf$jzO2d%$0ws~_|K{Vp9|9Q^O&s-lKey+9F~3Lg{-mb~=^#P@ z)#Q{iAj(@OZpxIB5<kwo81uu>WiTe7E(rGkU*6%Rcy=bW>TP}Ll<v6((-P6uMy)`* zplr}1V4CP%po(j?VI&pje%%(fO$g!<XQsxlc@#{9yJuV40Mkvd`{mYLGR&6ypb1lx zW?%{XCQg^x9RPMr+~_CR-Zoi>=`InS(ov^#rw+$#`;dD09@PEZ>8)YIqswItupV~Q zQ&jAH$E!`H*0bYXN1hS=6QC|oo&eo(ke4gu>v?6wGLK*UoH{PMg#D&DGweSBIH7x- z1CKIIergsN5<+XL(R-i3HCUE4Le3UnMxu7-=@%hnyy3WHeB_kcHL&2j#O{|8VpdPo z*C-7=&92k7hvFKKF+P7!U>eaapJh!DIAecVz`{lb%>G@J@HS0@q;@FlT5^TkFYY|Q zm@1LbuhHO5JG%ri`T0#?2s`{G5$tFL<VfTbW24CUQ%*6WKfJYz&jleUH;$RI8J{<Q zS#m3TCLl}q7mcTo=K?dKgt-8m*ROpNxCxjro#VzZAbb4ZBD7Du2}A9WxI-v9IVS?$ zW*|T4vrDJXo2{&v&R`(j#GItQKBa)Wdf|Muk1%Rp#Vi5u^141&y7Us!y@x07e~Vm& zg%2G$Z3X<o>^|eAbJ5@dt}z|4FH0)sONgb1b37`cM(cd7G9i^*>M74FTi-%*P`zmP zB@MxCZnZ-q`rpsP%5#`SpGJ$1l@fA98m#<qp~xfM)OPAM(dV|y5@Rimp^WGj;8+Mz zieuyT9VRFd7vxVpfm%Djb%Uk>IRK~!wl_ai?jm8G3Dfd;+M|;jMn`Y92Cyd>+=yOr zEBDwMuy9=tt>UcQGF}=l(jS8I=QiOMm;+?Z0W|dF!DE+0k<7jVKL*1Gn2H<V3Lx5_ zVI~%%y@*&@5Rn2v{7T(Cq}G1DBT_>|FFucz<nn{X+)#yX1)rZ0s6k=r)1yy<cgj~# z>6mE2f0Sj&jA0P->>bz{j)q9fNZ(M+r;_mpTpm=So;{!X9R>Fqebnjv(AVb2>}W-L z3raz7AlxfeqxUx*MQ2VB!?p3Kx|G{#g+4ERUuy20XZAZnF77#NFWS6%)xhc(tnFWO z!b)0X=B^I|MX$(2S9;*$gjYpAqc?ZLMWbqq!e4wx*`>N~f}{tdQC1q1^m~kcL1))C zV3GO3X049fQ;mAzyui6ITVqYoPE|a?^5U3LT-;s+6w8DQZVFi71(p9G9tmLw49at7 zp(qJP5PkUviX`)Qad#1Y<)dagmk&6uuWk#RXgVcj$c5w8nXx|ZGooF~j2jf}G-eq# zbfIf`Ewr0fRvQ=va{>~of`OFiuJNQ<l+VWYwazA>{Vf!51Gqsqf_LwbaG>oC#>^bH z3DP8qsCf<k-bTlDME{9v_WYEZKCLzk3?bwCb(WF_`=~UA;XCk90OOG!ns?di-&fJw z<W$UB`>);0!{w~l#d2;!D2G6)fFcFQvc?Uol0F8dOUJjd+etRQd9@9Jf;0%m>HgCT zhMmldA6tyB8_O5Y#W4--$)G<Yf6p<|SLN|7J*>e6^!iUTDN;ldBYMXjV3rie21h0^ zl8mdjSH6A@#oLsATElGRNi@0hP?EIg>A=8y8<PhSoO>scDm7Bk=&sbt#jT4LAKjy5 zDx&v*;>7+X$7vu>;;W8xvt-Xc|6L2FT<hl86=uU0x!1Gk0<ArG7HyC&Y&sm{3DM@B z<Z?J|?jOWm<_l*bX6*I-J$RfNNdx064~Ets(`@4J@k)}FN1!0i!g+N95^a#wQRTah zO(g!tZ^#gJwHX_hWJ^Yvj=qR_b{vs0--bHCZx-{g9v{B41oZrt`)3j&4&+gzH1G5L z=$P#HOW^ZncXFj>O575T&m0R8uGbg}%@n>3U)4q_$2dI52*VPgg2DpYDMzuqH`ilm zIs82P`h-3clV+rMn4>=ZBSfJx2r+#z=40doxYX7*FG%>l*e(56XNp6_Ae!kn(&$-4 z*DOVqU~sT8Mpw=U5-T7v*RX2zKOchVL8CU30T*q-*KkKN#;qt_a#x8W_+=L5In>IH zgzM;ZKGelgDWGSkxQSbmDSptu0USE%+vw-#go#Iu9%p6q`7O?dm6j(2G(1_*gO~MJ z=|2od<Xqcw1}F{1P$xnG363j?b`}994ZRQ9j2ix&8^Q-MmPO}n;|FD>ni51a*9*(Y z=qj^-`Y^&zL2N!Xr2U-|(X$?JH5twAdmz7ymas#tp>XOYdz!QOY7E&xfKsa(DJM68 zROBy207Ec%%ARwD4pfu>Qw0+IDu)hio>?O1D>H>R%bHl5@EdqM#r+*B-<_feQ(&ZS zm+1py8%+R}2~Dkk{2V5zK>3db-p1Tsq0F;&&AG#TTL)jE$o<#Q!DzcvD)S*WSt9$T zZA8SobZW~9e@$+UEzT)Gp3I)VR}l>C!nyBCny~gvLPQ_^t3yk6(thK$d0=<|iqk*# zUkS!~mJjDs%^wvL+1<BAv<cfptNgGohS{^NpDS9y&2?nS>2-eWI@nWwp403yB6{XO zn_05;Y8*ddsdUgN%=PPs=8ATjn+x&$E;v{5yWFW_wbjxdR~FtWE~qyhg*V|m%cr1B zR)d1HNh~9J7;;i(Y?IE0)2wOFlXs@1qJ~zebFH`<`2tj|q4$Ky0t`*2hS=L<uA8|S z|JVL?KN8(>|CA2RI(i<6HqFCq5#8+=+gdHBv50PcwHaK=Qgp`3<I{IRXpM^6oFoU< z#K}4qFzlOE!cxN;rDKGwpGEXM%;9S>!yE}z17cvql?Jk<Wl$)F-barAtd)j=*Md44 z(cRzG^dKFWxt`hxGh*CkN=Mb)2J33zs^$2zInhy@Cgo=S7%c4nP|%sOHP&hbIvSD< z(D#CaQBYwZgv?ONinS|x6#iH{oQPI8)iNQ!)NIqsQqZ8<cL;Hy3L#*%RfkB9qzbGh zqSnv7YYvT|YzJ-l;?{g&NVrMYzS3=bd_?EcoTmWvI*q8S^Wd~=4R$~%q06Uyg|+aY zJ}4Vl*pkBPq<7AqBaSg<4ttj!R?E=a)q<O@F9!r(gfT$O63;qo9a=L1F@0mFZrreL z<A&Ud{&gERu0Nr#FPB3O%ZwKTgBT}Ii*V8tdX@Sjo#LT0J6jlSPTpI=^-9g^R2f5Y zT;@5lHLaupilWRJ-02^J)ej@4ugpL6s4jvL?97pIGjvYuVq{k!S0~nv11I&E8PIav zTDrv6!?7`RvGl^l@_5S^Cdn#5+rWRm&+A^d23yJueSK1S$bml!Hj@gT%$~xHD6L7o z*#|__6=v$o*K0K)=^iyM*Ng0w9w?^?@_kO|uM%E3XQLc>cB5L)#~bTFj?<F63^24i zL&f=A0rbbmP#@fe)^MN+;0;KBs!6O_lFkqCEVgo(9S3iM1~0$YyTtXEtSbtCgf+PT zFEfn9vVNUkebzUg>8{|~_d(-;l_jS4rsbqMbD8EDB!l2YH+AyYDD)y&7A8IZ)F!B{ z7kLkRHNV+Je&Wm95vkQH)Ygrvb7s3$QjgSFupWFE3J<-zvc)XeR<}r+V>v81ZysHW z>1)|a0kcJyeUj-X=wuK>tE->RSHwm(K?m#=G!VM59Th~J($|W@EDR%>b>W-5>8}#F z0{<UHdZvR|7LDBo!S)By0h(|q)@EsugNSYgCMcGxy#UkilLsL1Yhx2}YSl*wZKw^k z!_#Lv!xkA!R!OMY{wnd&!Lk3tcoXxBSePPna-zbgX=A2jNM6uaSY~Ob)*_g_d!Alu zG6jlaZzV$(-lXXT-sQnJvCrBa4BU@w!dT;Yt_*$Y3dWbfRIQ`c6*XN*$ha{?j}f`h zu>%(sSyP81rPI)t0TotIt@Kf)W8d2@K?x=1YBejwy!loB^r)n#RfPpsv&eMCf(r6$ zFbmjF>FCnOSa4r>>E70o;~P=QH2bP<P<%KP&1{i7qn(l~S8}#hcW}y0NxN`F=b@Ng z8%2|5k89cY9}8ykNPdF(1faIo=*hoK0>#N_tctn>lSL#_JnX`>Ab=bHMs)KtXR~<E z1Py1DTEVCO_M>Lg@tBKJ0^<Mb6iV&*CLD>C+wv1by)s=;4KF7%ce5F!p?7mJZ?zt5 zV4JG{MpOgnB7G_P-A)pd{z*@!%m<EhL>K*uM}dR0SEJ#512<>IhCm9~R2*DxTE3JU z;vgfTrR+R|J$-<BaAAJ+g1Mw5b%fu{v_`5v8+#v5NCtz*gyr;!7DJH!F&y~9^iNSB zTNV=ONv^t_s#dY5AA<yM?yG|uPlU`#ec4iq#^y-%GZslOwGD{WZs1r19Y8Gq_%AE6 zrBPLQlbMLbv8R{#$n9jl0im%z1^N$D<t@D!NdE|A7rGz;u~s;9Zc^qlq8(_k=HfXD zhMX>$%rwQ~vH@Z{lo7@d@CIEP(GwhX%<ue;Uy?OKVZ&nsXVGFU-ezJ*!0A=)k-;-L zY~XodF4hlSQ3E|^T>95#FvJ>DDyM%(uedx+R-bOs54~$Hp1^EU?228ob$|BWxw6M( z+%}z8WImHXX>`mBXOcweaMTrAc_UO9x7QIBGv9wq=UWU#WFLvMHti)|zDJ7&mhCST z+tq1O71w4tj^4g2uzN+G&{Ho9j@4_?0IVebF<9o-r?ZQ~VqovngyHBlkd^lAuFu6l zK&78&=IuBx%#BV$&*4xIP>S2Z?o%+MH5EGl(y`vpuapj8Q9Y)&WaeHf;gH0Oi_QP= zN{vsC^$iXx2XyZ_3*zSidJ{|%)QBBB>M!uee>bg@^A>@p@PRKVn<tOhfgFv)<fn$A z0x1D2eSWR|b~adyp{xRdi@jt&?iNB=f!zjZ53;QTf)Z}XgHcY~(8tC7Wd;jq8y}-f zFa^@#WoO`!fs3FAKvXlJC-W5*yqN^{65wDO(z8d!z%I_iWfQ<ix0r%OjLaz@8H*?* ze^bufkS_ed0r1#hs^pf5#>&MQ@K_P0@aFel*=}|TKb+<?M)ZZQfFzJgk4Q!Va)CAo zL`t=zUaXxuvAI;hrYp`$R*93F&NJSLph1<615Z1vc%1b!2pz$%$_!5FY!}6ReHE>l zFdg=+Jryc^+D$ClNr!*WIhacIV;y+4rR@>D`y1+4$<jqccc8D4!9ylxL)*i2F@F4F zw;Y-(%<gUSH*EwsRGip`zy}Y1{WgR>qw4{_ss0RkN%9kbEvl()Tg#)|Q$h8^q1uV} zAq#^ht5l*hYgC?4D*ymnDPQLeH8U}{q}}RBs$vOe?uf4$#=!3+SDDK9p!*(<FCI6i zJ}Z1(bWC?@gpODxZGcA72zrZ;`|J$-2_^dKM4et2F0MHscy?tig!nJr*{k>hv(xQ( zly>Ys>S<3Di8v9=%0XABI5Eg-mKT0#Mr?Bz?^L0yH3w}GAMDmp`Y-DI2pbyf2oH;l z5FUj&(cnC$4Xkf~+WbaY_x9hZ?LExB6g(3bv4qPVAKJ=fWCYCTgFmZnz~Y_sm3Mlo z1!@dcrcYC|KImsI(C&H9_DQ_G#^$@c46MrUKg8M{5Pn3W%X7I#Fd+a~Z62e`q`{n? zi4Io<>Pwp|9gHzx*pM!cY>!JsPy6s}Fhyz@7qkO2#9$#AI;B<X@u6pjvL@}l(}{gV zZ$=ZmN}bi4oiuoW(_n5nq366sp^54xih>}CQWu;9dhW-J)~^W+bo`N+Nf~f@bk)go z;u;fBObIrr?-;mQDQe~n)sLS3CnIiIVtXFZ#&kxZb|cI#io0eeR_L48BP-lC0?Un- zA<(kvl5><!q#UC3;^Gs73(uuwx^v%IBsK8d<RbcU{Ex+S-V>5BhIZEuDCshPgTX3l zRQjFz4-MNybn>fgI)_OH$3D)2;whdjx8I}Of=>K(_?x~ZC&>1HAI<|FgzA}kHjpaF z500qaq=Et~z=iNy`77lhjj}lZ>k;*_)piv`w#@|kUi(yfJ!N|)e=OV|wbD|54l^b@ zc#$V2XC9>YLxedZr}@MEQBGibT&{wKAA0tuEW(01R$~~-a#~QaQ$L!u+s&1zEfo`m z6KPQL*N<={z+X%F`Dx%tKuryEpmTWSc_9mQXHBi0Yn{*}>GjSAcRQRM7RDC!k{0SW z;R|Qkvu|Dwy$;P#!UwS|P-fJbU~Du89ccW2p;x3o70s;lr8C-b99d2;>?!U&V~%26 zh?uiU^W$(KM&3Dj6)<3;Hc~<w#30?~2|iZ?_;>sctdz#!QOw~81K`O!x=ZKNL_3z9 z-xSw)GqP*GtaTIBVN}>u?_iHoiWr*rzEtCke>^X7hpx!Cr8zo&mBFiEW&EKkqM$Mw z598{PAG+z4rT;?eY8-`hu*x>&*J^A>U$y<i{yzL%<6NLA^kZ_N%nS34vhnk~c7llE zd+`NM@7=P7z;|0c3GiX<Q_z?~#>2pca*dbSdpgH5+yiqo6E+(#p#2#9g>QDig!X&F zQ^0L!KZu^*DL;Wf@C2e7^yp);Prr^L>tvut=?}-dK7bxuE-*`N8EH>ufI6j(%d?Gg z$Slfmw;S;H&HUH)u-mqRmd*g)DW8NTnH$cSdIw6L@;3nu%Glb|@l8iI{U#1;^@)`~ z4t79139mWt5gXUnx3-88VFM!oc2<-o1{<htE7*g{2#@S8A%QpbDv#{0gTYYQjLCo{ z<W3Ws8WDgWOl&(<md7h!#5S-|Ggiq(lQ%$z9hG3H!0AZm`Hxl2-y*+;!<ZYZ(K7JE zw7XimlTKON*44||4%}H*q8HKjxN<3PwjwlbOtZcAP4S4&%yrXWnVDhaC((DuEvIYp z=j`AN<3#D^G7wkhdxZI7q<uOov%oEV=Lxa$1PG3w)N`OzImM>UUNuUaUi(WyitAj_ z_Fkrnn8_ELaDykxNYjXkDg}N3-<?i_FrR3uB6BW_%4&Z>P&s7zU~1(Q<&Xy6Ig^fW z4AD3sJEy3U^kj+b+^L$ZK)u8$$s=C2l3d&BLr0sd<QY|RmCBaj-8luirn^F5yw&68 zIt=C>3pOi&Y(zf*gy>I|(3>Dh1T*wI)1xNupNitTO=$HOTHvk#%^#&elE=vcyIwZB z|4cCk3vIT*JkcRq!bB|H(<}9;0$McCaQLSg)Gs4WR!gmG5U8w~e`z*td#LCN%m~*V zEzFh~u4AY-SI-WhnWj%B8O-|pfUR3JE(jyCytHg7V&El^#QWv^WZ_gHlT}ONRK$JA zbaN&rlXkYR)c?|(x2@NP5KAXe@h|x0FKjA&#d({~kd|T>vW~cd%)JA{X=)9ET9U*y ziDKxlhhqy?+tB&Uv{_*jif!M_peb6O6#192K7c~!S&dX?ucHWrX;y(uBVe+-zCiy7 zv~k_6L<-$Kvyod{U*sVAargS#TYtBaPmLdlf4_9aju|NDf(j`@Kv~$rm*Bcw?y}l% z!hBYX-VSt?$a^As160^V0+e?FZM!rDVDY#<eXWU0z9=C7(Pl@qeirFhXUKpgUnHTo zZ2RPIBKqK^^I?<FB3}W%>@8&1EiVz>g;A0^v^jDoH4GnCE`bdYP%&=Rx1q?oQehQ_ z#>(#<xX1op{{@uHN}S|#JsjX#>cC+_+1KWiNHW=mm>N9|Qfxei9mF|hS_~1&Y;s%{ z*HR%dd_5XkP@Np9R!1rS?k*rI_!``y!?4MQ<f5m5&Bx{K95{VCw{2gv2y%U>l5*X1 z5V<jUSQYA@m-G*M4<_A~EHtAYt`*k{k^FH)hot0e?fc_&6@N1r3?dokm7ot&US}2> z0ovl*W(ogmF?8iW*-COO8}^Opq36tGj;i6neB^f!U=p{T6VX5Ml#fn{f9ZHe^hY;V zYWbm}G?wcHis^0&2)6$YQd$GY95*>WZx&x423{9v0?L-<Jd_4IBN*)wwwL}Jg>V_! zYoj3ldD5%yaOl!Xor5;VWT$02>7yWmz%Qa(9&AAj7Qo=CZh|utj%w6KnU=phGRWsK ze9Lu7S$<GLe7L{rYVIQzLW*aUvnDx&wj%weWy@2_!kS=RH+T0>OyqYUG&WO6y1f>< z@nUDIu;v+fAIO8X)$80B+k4h=q@rGO_XJ!5=s_HQr#yq&dcITd;)9@DAP2$!poorp zBEkVZ7~0rmuu>!}lo8Q2Z4i4UpJk#)xGuL$r!8Yd&;O<!e-+{^YfmhqIfG-h;gJFo z=OySdg<nA?#a*0!RG^68*0Ju&SudaXvcsH|Os77G`E3|)um(EeMT7>Rbz&x$i5@xR zrG5+rz%NlwEf<G+iwvQKl7)*|@T>i>x+A?}$j$AP8PD}bjUJ5oJg^dU6y~XLz#>!s zXpJrwGO0n$Ss#Sc59;5y6Q10SNv_h*u$9TXK4+WBDa`zaRc}vgG@{jzre^MU(&Gj_ zY(y`;$|7V(?WB{CJ%hq2>9E@QO(D0ztH7}nBZ^+k%U_|oX7!h6SzaciVOC9>7*)sV zR2#j;%DZM8hn5#^Kr_FTA16@ZTQ=`Jc@tjUR97>6fw7!S*7t~0)A@ih(c44DIgo3H zzuDSvy+RfgdNE|4*PyHo-F-Uth*ZVbjG}bX4P(#SQe(-KW}&01dja_wDg*bVS3pW$ zk9{7U<Wh&g1WjE)8@Cx;UtkXtOoSCrsOHhj{L<0MfFJDDQU{&@-EqoH5;nK7$8_|S zFyN($8pgw*abz)!5TnED8KEs;rtWlurEX`~T$hWb&bit2d|V>>@VAv`F%H$M4WNq? zQT^2ixjnT^PH3j%<cc`)`!h9|><@KEVxzK+MesQ{kr@da<=+GNC#oAa{2Je{M3Zw^ zy<DLI_8-hIeK6)JYETh$GCHgCp&1>do|w*YC|blgI8^)DVy!^UvCnz4Lk}4UcSNs& z-PdRTXf(;8!_u&G(wrZ?7eYH~@4Hw$*mw{>sg3BLQ{#@C7)?LUZnl*&_eA&&vBgaq zq(7rukc*yifXXeVO|DVxRC9XR<1{rMonC0@O6ib85pw_l8AbwoqwXo{Dz31)Xs;Xv zAa3S&c{#)sK&Cvn#;iGKV1{hR+3Bi;_TF({0rH1MVM&ux1q1QMU~pYK788y`z{L+z z@V#uKwh;LMI1~7BL>~t~9W=5{V3IDJi@wycV86K2{-biKtxB_kPqK(t450VE2nz`O zQWbt!WE%X$rkgQ*K<ol%d9t)|cBh*xL_v?&Uz+RX8xkB|XrDSiUWZs%FOYhjGDCvh z2f+G>Uj2S2QN{TT1G;O_Etgpcv*3~A<$}Az&#t;Z4t80SW@mqtv7BU1|GKjVgC~!5 zaI0*@W0gSteaWlZYd;&>AG4GG0O}r4Lq&|Fw~wN06s?msxuC-^{A<N2124#}ebI&! zSFWeWLuV1=8A=#3!07|Gi8YQEl$!-wk@)VOdBh#_W0i55*6EO)+CPxOK+QeqVU;hb zbim8C2i#GD@*79}2|PM<2Nvth(QQ#gZ1JIz+N%S*h><=ni>CtFh>q>oV&8Pg9dk)o zV`vDWFTng&ip4^W`{cP`(_~=88&aJmYR!<}y7IM|huJhjPgnoDqK`y${ZXb-q+AHF z;4t)tqsB@7>omd5xq-NOii3bS7FX-d%Pr%W80!HykcV3&mcDn=ort5cQPhenzJrj$ z0BP~RRD%m+q3UmPSrWSi=CZhRDC}J_kIcDC=q>TDdS`ik#heMAy;ZB@4x|Q!yAu+d za{+BHGw8xSik9%4jU~W^g<D&8??Oo<%>Tf+Z$&L>6ws+mZL3jV=VK1T0f@g8E^zAD z??tFky`b}NRcpMb8FcU2hi(}B5{M=VZ>7^2uG26B4>jcDTE!glh;8QCW{+<m9yx9S z8X37SL(TeZuP%Y9*%AFmTO;?>#^}7xfiHNGtM;otXHd$RQouA!SsnM<q1%EffCtuK zN=l)~6TDNcOGoU~<a#*#_aw%e2#>0*t5z@S06nl@dJU7$(bn76gVd5?5xo~v*2E7K zM{-KnpXOn(oS_nNM~6E6Fm$S-|MN58J<(Z53pkEkw=uWk)QxL5(9T3N{xlHQwDmSs zwGag^<r_l1{<ybZIRv^68kw@?MOlB*%vq?^4ugxpOto)}0RjLgBwwZzV|?i#5j4a9 zLZMwmWB=;ZXk2U+%a7o22TCzx8}N6u#;3_M-mP^|>7*~6?C~an3^^k|Ps!H@M^3Gj zQOCS=XFPpMhFM<(9V;Y9T;&SZA?Q0EIw(a4bpCR^8`Sk`<#haIBa6<x<aS;{bO=sR zA(Sv}MSZXe&dLgeq_|8R?>99)-kFEX<Zz}_L+y8!y`yN?GvWJjw18t`G(?pfLqkQ# z&JD4eYn{j1fcKoHjmCb)15m}QuiR%A^Nfn9(@oN$*MP8@q2th=CGaO?z?v{YvMn1T z@6<^Jf?Ro6iO3eR4fHuY5+*)qFQBX~$a7+FGoOfjJGQ$e-l|#xkfOvWGXx*aUyBt= zToGGohIC)hnbsZ$@4H757*d5uzg&CVmLHLIF*O*~X=Fi-J*dim&JSi_njX{<P!ly8 zyHZNQ*i^PVnmJ+4LPj1Il>2}+xae|*`K#M1bk<hL;)7+#%z?&sy7~u7Gov(4e}LRR z3ZaJ}im%ldFhC_smnLrg_94mQSr0;Q<%E}Zvm%CVcxs=Y%t!*7rJ$rx7tdnLYXyZ# z|2QJFw-f4Muus}O_ZY8j4JR5TJ)-}GVy`v>OHh>f`L`@j!d;PR$LyeYk$OUb+(CrU z&7RWszn?dfen9$1-Xfq21*vXvVzMYNIvK?!d!Q^?Uo8XEnU%0$%J`TH1vYnUL6C^9 z1jz~F^_VvX<A)?W(_A|74pgY5j)lGd&dzELDVC)zH{2^j2H>|CLTI|%^s?zcjDTzL zbkRTLrpP3o43yG?lo?}==!~rRlh0$JIFtv7g#Jp1+~b1GA{ygpbSl)>I84dGOO*UH z!ZFwY@JnKlCb%v8@fvV4z~6zqAV<h1R#d2RsgCmSno_+kquon+jKg~I9E5;8Dun*h zsuNcS?e-7zT$`c^&WpJ6CCE;*c0Vtf;q_C22ZtK4f?gwi?8Q~u2GBiAYp-cLq&ZK# zP5Sy`6%4oeG(I1E2Se2|t|fpy>GG@oqtko0HhjwW+_W*%+_N~3oE`?l@hE)BDxN>I zLJcll{z&I#`H{{`Y)U?c12XMMWGN6KaJdC;JQK8ir0F{z`}s&)ZZ}QetV(dr{)mFn ztYOEji*alP^_`+-G9y)b^-JSCU;B2IK|mh5C&@CM{i#{BdVF#j`&`<o^~L2XrLKi} z7VNR1C^9~|lwX5!-i!_ui=$}Qz(nzbS!+yN-x#sV4vFPs18l9V07eHWneV_XZ9PC_ z_agmnoZb6+3|l8&e@!t{KHM*BrQ=*LY3aTYAJJ1UP@<0_jZS}gJZNnojyOE<rXgwg zX`>9txXF0AR0n+?EIQ!NwD=x;d}FIXSk2!0VE-K8FC3C{3P$JqbT)nO2B*~3_tgah z^tC#AaWsY~EwQu^$fED2I+OIcJh|j#<{C_BKjZ2ynS+c76gP%;GJKYHR>cV%xEnsp z{2<JjG+{6Y;VO`HW)L)$6Q&Cxbh4^K!}p;uQp;5uXyR_cq%V}X3zXr&(eKHVQJ2|j z0ews>qW}JFvdcPirMS7*BxsHhV)C^s8Z~rC+2qepcVKV-TbKLgeVm1yQmi8!uIB?! z;;;qGv+xojwF87(gOv*BW}DDut=qM*+xSrAirZllQDc^gK(z1uGs)}sqh%=tFB4mP zFypis`iTDgagRSEOJtv>Lw7_EIU39ZYfJ}xLzOzZ<yS}4-%*S8kVee3i?ONkUYP!l z)tf-JWcvm?=uuG{B->4yhl1_n));L!%Ax4l1;up&^S}<$&&q=<wt`rK8iAsK?M@!P zxe;%7h3^~@am(BB=*Atq{)EDCv7OKV2VO3R0NBC8p_u`3;F%wV+%157E?eXW0e~>$ z*7Nhb4<)DbtH}bl+IYZlT;7p}6J-A-9VJZng<*S|+s1RgP#uA2$2$-ZR|>`Lg1;I| zsid`2BEt%Wp(<pR&#Gd<G&q$y^`KmTMtP~_2OYv87njgb;{joP0S||ns4O^O#Q~fy z>fauWa6*5#{=*<{o6*|?T91QNt4{Tmn&oa#i{wvbRn!mT+M<R;@x5w6{Wpc1;pKf1 zonFt>vaqEc3Gj8m!)g{lQYtW~iKvIgEMB{4CStQOje#anCZRDQXVJe-7Yghn&lou| zWss<;5+O{E-UL6r3FG+?y^d82rJ+)>Kr=w#mvGh@?<f~)ed1Jz7<AK~qJR_8>(RT6 zQcM*S%g0NTP!!*J`CK9V(#n_XF=WN<ARwp!kB=tSK?k5(CHx4qo!OCHtV|`Xc_v^p zVDNw->o%IQ6ppRM;Zg;81AdT0fK({Q+6O9^DVH-g-N*l3A9bl{8()@i%B)Uh9dqCC ze5wu&@lyq@yOD^OyU&E^yU$guMOE~67$u1^l<c3js;6`sni2&}m*cWrXAzzhy+<8h zwlr>B#30B#hM0K}IO4lyiQcg8Kg{JawvdoE+IS1Q|27y?l!c9DRMw>xcQS}w_vU)c z&8SREavEq^t2io7!jT*xQpS!n0EnrAn77LtnYz<nZz*b)YECc;8Xv%PT#z|jcp+FX z@gsrm_j$;v-EuYTMHR6Jvc`qGvRmx11>AE+S6t+?qKqx@;#%{=gn=-|L0hHZ;lvn@ z!O`4sBR`R*gG4mrOp#Jyf;f(RFm(o6Ha1Z_JEDEmw3$M2lK$g1J?Gf4vecg12ms?B zZi*-E`)N2;Ol3nV%ro`6fed^*5ZAI2QARQd8G2;ueTo*@Yen~veJG%VpIH~{T;Xln z9HNfdlD+Eda!bPeDd=+!d{IO<qW@Xv+U*6S;=Q~qUd;=M&4B^k@)N@_9Vk-6wJ_M0 zvg&dAYWt$Z-)F+p!8;heo+rm`XUsEw4TdxnYTUNy$Nn$GI=~zY1p1?<#5)!Lrh_t% zSIe=Trr0KYnGK*{qQ=m$gF0*h{(tNOp3ZmT=eT?z#e=Uc@#BwO>WP(e<|#@nN11wd zaqLva_{=UmGL2uB;1%or*MbQx%<5-n^Fbt;bWzxqtJkOZ1f!VjGJwaXZY!cHsK4fk zarwn57R2Ggs^pYIAsS}BG!AaEIEB6ImWk-)XU*q9h^#4zHq>$h1Br%nHAGB3ie~J_ zeI6!OZG{QIR2rG{Zh|xAhjp&J<oTk-1;HKNo30;k+J30>6w$)>I-|i1RlC#Nv1`U> z4ei2%P~+S&hVfw;`{KOMBVd6z<p{kD92!g5!DzEuZHHN56)9%WX)a2aCoH9huKx8r z%H<{snCrp3E&4YwZkSHep0n5N_krRt_Z=H&pT-Q_a{<asV>{@Bqd3^|cPP1*hn6kP ztz(rRePmiKJwC9O!$ou8z*CXO@m`pE+ylQev4o3+s%oyTjg$mJP(1fYePH6l+T9$< zrIF?B>l1II&gEjJx2ezy93<32GPuj#JqG<<`VWO>`L`d8#P+;rhst|Ix1?$L`tFi& zMb^CoJ^Sfg8XIkIH6_oBO(zQ@6pC9Lm^x-`v-RBP>d~0`OEU<!5fKyx*(1ls$g$O& zIIQO?lQnQpSAv{^IkqP%q>oGzh0S(8>b@2+LWn(A0n0J%Um+F<?_aS@b1bpydj#c% z%e>2(D}aacAxNVrY4h9=e%dU43jYpl)0vKBlq!7EOOR*rU|kb-$opFv1)!GW@H;^` z_rK20hPD&9kA9d=;c^RH4dSHCt%Y?MQu(2@s4U$-`5kiUR?%(+t6~laaS7V+XzvpB zPc&{+F>Ii$ZeY1IfqWOuwfvE}5wts~#Z`I%OzsrIr%IB&6RVz2R`<CgNO8ayL(Sgj zMRYd=*2XcZCOhuP){h9R3e^Bps=a}J`5bpuba43Aak~o3UmK&P?=e1<S#27r^V!`u zcJ0NpVk{ZAIeH~#s1*wIo`5<{ThKH(6>6JR;50|+ao(&>gGLypM5v=HL8y?I^-Drk z^WX~{p%w@Xebh!3j*17O+a&1$a*7c>4zrb!@{3XPBeq7p1h`lRF)N(X|Ftff_&?M( z3?_`DKK{^ZI-0ggf{F~C@4<=vB_@E!?_KW0o$V(S5v_VV4k?sKw$ms69ys$c`KVQH z{(|AXNM-?`**T%L*gYgk_or=IAmI*ezwQ%$y8KeKu2e>f=%=Ma0CM0+!f%1a?v-A< zzB}u|m*i(sp#ew9&XvAg<8PIiJ<ocHJGBlkRE+*I0P~Nr*#Z+oH(8?q)e4jwna!#^ z2dsTxpPI!jmRnL5oRy4UM|Ak>)PAIAUO1OFoVfmk{*}4aYge60$Ni_SiTa+@VTy<_ zR>+(`{8W4{uAkMtklC>{I|{{HFRoEV+<1${DQmXti0ESUdh#(e-p$sSPK3xcCZC$B zO1_?1Qt9NN_NV-^*<l{;ob9Y(VPG^SuE820kOQ`qJA(f6Ck*{;!$ern?<dAs6QDqk znVr$1*M38^C^$83h(7AKpxSXqfpo_{^}%_>i9@bh9iz=Ji`k{l&RGFE69BLZtneF- zNya8>4SJLj1x~V#nz~ASnt!DJ<c{*2Gz8GSMd8Hc$%e5Aror-qOt`AfW~+Err-;ly z@K0qRAW(jfv&Q`7SY8@;@MkLQ!3fJsI53CuY<sYle7Qj@%`mk$&q=DbXC4^OcDfoP z+tycxSpfG07J!WFHs0&CcTfK;qJ5EDbf{r_N~_Tja-Yq&RG9i@xKhG>q9=WS76yV; zp^P|GCAvme)X>qrTS{s>{+gs^rgIo4=>)TR<+l7puduloO7{*V4#!=u^}Fuc+U1gd z+YBJ0wSc^8qor}<rh_=wAH%aX<cm=)G~p@ZU$W8H!~3i(v30*R(IM!pS8GR>`v&GQ za4f1B_H+X-nty;Ewn&R4O)#uRTQEQwZljyj1O^-<D>#gfp@j6&jnjTh4bolT$WPEy z2N5OJi;pG7KlRJa=~pI()o{(LQ<%qM_kOg2@p91Bw!M)diI^qSQ$;1;(mG!RW2z%0 zSsVV%lvzneTAe=(pUQs>#Jxvet_0dueWF^<v2l?8HU8Hs{6m>QAxEGS<SDbMPy%N@ zzk}}j>}*on*n$PJcr~4@YYd7d2>c}|nGITZR*3{{tL42&Q5vWSzK_z{(~nCz{4fTX ziT5Y~0oNi?sB#9`q(JpMR|Z>-Ga8-6;IrF2_#mF|f<XMuXaG1~)F+AsfEsjzTT$a6 z*i+EE;0?Y(N#M%EthIjq(`WNXZ>Q^OstN#-Sdl&m1$KMx0zM$q!O1Sld_&0Y(bea( zRFu>x%r=!R3F_z9H_sxaMMwX29k|zwxifwZKBJT~v<3AIDLrt(JgSZZ4ntglJKU$t zP4|@oCoef}ycjIfFuLy*jTz&Ia>X(R07^wlf0FGp606sJSYY<L{@DI>ueYa(a5Tp% z<{shB^?Zd?$kO!%*?h(O+TA*EA)=!&fTRFzfAwssyw_|)x8r7A=|7iUrLGx)V=Rp# zKlg1Gte5g6$kqH2HoiGh<UUhCQJ>AJB&tMG5fKG$X6RY!UvL)1bY7Tq(YV<Xm~TlB zbJ&9YVIV;BWuTMx`Bm%KMwPMkp45M64lh(UF~Sn*4}#F}QPy5C^O)N$=6^61H_gNq zVu(z>eCkAjO82W)3jHeiC|`RcqG!Abp$z14xYkA+JRLVczUFMDQWQr3?x=`PK(`eh zVKW}3eM3aK>oDpD-7L`BLe-++Lc6y15YfK??>CL)#-#_GKqp>2UqNqwpe>zESsbgF zz|6!UmNTKG6<IHA9Hj3II<vQGVec!_=m*2|9Oxx%E+fyb2Nw`x7$XLq<yzQlWvfs2 zP!^GnylgJ9!f|Qv<l+wc9Ul33wI<_=<hgqplaE;Wmzz3Wt)l3NUIwHHcM26-B~hw3 zbYl0<K5Z^-1$Uor{%5V%mCM)Z-3QDj5G$dw0ZpYrT5zWhi&bkCJ_5b7CfgOlI-*Pv zka3mPI!PEkT$(Iaq$M?V0}=hdGiNfQ1|mPkr{IZWBQ;oMfeu5+gD$VFrD5LcVAWa- zSaOO^;G!9N)FmT#$}@9U<K1ww2FBLwfiL&;N3>zLnT8srDyF-+kx3gTwI-bI^HqdI zIwE={vI5k-XulWD5<NK}?z9DC3y{|w-$1nqImjRMWORY(6tp<?Fiv5R6NqZo-Y(5? zJl!*g2f$?|dKJ`baEe@m!<e&?V2<cn-%*-uLJIu@=;0oih;5GHEND+t6!0dtJEEV2 zG#QiJG+E<TsEnU~2CRQXo4~d=p3AmMJI-x@of~Tt(6^EDxireKq}z3I*G#zzSX3f7 zEvUrn@n3H>BzhI9wx%n2)=>&QTL0B?5hr4LB#NEr3oaIyZ^_)(q2ec92pnCiNc?PR z2T1GC`lSzJM~d&GPrnATRA(#nHlpFZlbDifJajU1u?i|ePJ0LEm&S_lit7T9Mw8?r zCx0B#r~d;_VFZVDlz}s@SDT_4TO1im`wvLreQTga8055w_Df;nvUaIjbqSh0$1O}& zC)5_yLqZh)Q0dC8<JOSX0LJi)4qDj8%P@^&Yz~<$odz+mOv=!5HG!C{(_Ag0x84ea zq(l`RjWWI6^&h73>!Z(sDIF14gzDZzo#uIG<R5A01dsNo9u5TFSr{q2B7EEiSddfD zI@avLHTzxW!@vObr1x?#0p4QxCj=|+o1vw0nVq68fvte3_xJTFIVKr2-d})Pq*37V zEjBF48e~fd6MuyAj(Si0abkWnY@@{|`}$TY7ze2tv?!NjglI&^|0w19dMqXp(K2*# zz}2$cXRZc#NjcsBeNz{6Vf8d9P*QUog>h9~Ml|sc@I<)D4zX57Aa>&`4d$ShyGhQ; zNiPy58FX&Ere;x@_r@xf_<ofWuP<`qmao(S?H9M}#KhOVl<mY1(U=cclS_?pk{#ge z2)u>gFc2enJxZGQfID!uGY_GuG;k~v>y4Y;ADi^d3MLQZ@tWnY4EFUgTwr2xjyr{v zE*OH8Vp1QKd~XVBc;vC~nvLr`cI<8>0I5f%o;un`_hveRIgIWDd<2I|s8R?Hbu1JQ zCyD^-!N~~69IbMS6<`zdu%f^1HAk=;^-0Q-h2?v-J5*-1R~k{cieIFKD8;pLLmcxP zfPKI`%0K$?_dp6n59?8et91sB!bOelyJ!ZnQ^MHx1UPR=-~2WF9Vlagc&`g(aAJV5 zTcH!QB{e}?96+n}M^M7dQ1FP+#w2dtM*lsd%t1@*0PZU+j?!x`ZfDa3yB9Y|<jD~< z9@ZJhCrKMyc=4Pug(js&1JBu-*A@dGy1RJelEuQYOa0>b((noL8hq7rfs~pUjt+mX z3MDw1Z)bF?$OEU%4n21Sm2y!T9fNw0GB|Pj!Rb$iC{+a*H55WIKr3It9J=jLrK)a& zuy=JRSKn5pXPUlt3xcRmaf}{(xlXp{UN#?;TI@(f4K@0wyA{S@PLc=KKy>WwNz}na z_C4GcuYTrik`mOJs7J}<T81Tt3bfC&K?|+r@>_u+p<!Qoo#-@-@8Z0}#Z6k*pDRC( zm7tVu(fIRZwN!}cX|I=Hu{btf-$DQSQc&TGV`w;;pcg*{sehw93UFzfW)c4YK$;Rk zr3azWz+KRZ?Hle8q=V-JPUH|&C~^KtH*v~Qh*PqolZf{I+I%LFNHd2T7-S5L%K3fd zRGou?cI;3FKpdKl0J+5`Xl)1Ii39pii)R8&L0_D9Maep@9kwJ(rP$q;|HUfWYHv*G zZOwZ5i)W_{z%IQ~EYT}@ur@!!Ty3P>#A9c|3V8pS`<O#otd$B4%oB9BYkUw_fr7!r z!CpPvY%Ozd<EYv>-92-rF7&2UpfzBop8Ei7-MFHS>UW;mNO}_4CJy*!kstjR)G9$D zGbfE}hg^l&j+%3R8xq2G{Eq?tJ45UJvLMiTejCQz@i0b+sO1H4maoZN@aB-Xw%S>E zL$isDmH?u5dkc^>d~w(f_oJ<mhsxKO(?ZK(PE0a&VDHW~?Y9r64(j03LdkA)u-g)1 z$HfNINqX*|t#+QGrYc4yJ@pTm@X2H7&3Fzv|APurYBIj^N)Z3VNg^na3GY-smuORd z5dK`Kgmf<&r0lrOB-IB14)+4cj<@?j9x>kvqClAZW{T(brR_?j%Nv{{gn#ol4RAoh zM3*^l?h26!ka|7^Z_2xx_16pZkuPF&Z#4(^D*O?&pz9N(|1fCg1BcC~{>osfT+UDI zU~NYFAYgkby$Jz6H+f{Q>=@nGuV&srTmCFo^W(@|n_+}Gt|@_i8cVs0h<<(REDgNj z^~)C>8PWW6Vq&wlh&DXiR$Yzw=0?n3lAuYpLqx}vla@}I0+n!W6fH1GyYxZ{H+fTW zP-?50YltU#?HlHSud^+WaVmL82i56`-}i&d%(*w?W589oERC>Ma}M!Ygc7De=JdA) z8mGC|<Jo#HG6P!Vu0u`({9kq*wIBfSzNPCA(z63)@3%_5R27q>BharB&s#O-M)aF_ zn3G$OPrKXc9cW4WWC@-$PmQx9DuKf-67HIE`Ls1?Z)l94SgoODS{5<=9bnc~%ab_h zZcc8Tgy}yG9r)YNLzg%YJ4cGm=)uTDwF2l>_gT1?W1n7MUrx<c5{TUUB38=X^0>MB zRO0t^!HT&QznoSx)lh3Tj0owq7U!AWNi@)B?~uZwX!oJ=dDaFs{F_<W^z*E_7B+VA zIxPQ^VzKMv4ddd~?Y)Dc-ADRoOg;!|2QlvfN@Wo}{z5e+!zij*^Wub(t@^J<FwaL9 zR%>;-%~;ir&FTO9viJy$?!n{d8uF%N^-wZxE1&i_UFK<Lezw}}iGEqx!I|M5431vz zPGh);epk!XJ2XTg`?!OlDm1Q&+l#Qi-ez8m&3q=*{7eMFY)Lh)UAqVrj}Sl9AkA5n z^+(c#A0@{N@Xx%LIi%Rc^6*Px^8f8B9?*o*zcRv$pTtSyNiUUjN5LuINCmH%4NA~B z-7!Nb;Zk8gcEM6q^VEG{NO~URs|^!7SX57vTD_}9?Ira>Wu}?0DLgQ|C$VtQJ>bK* z6u0unrM@;y3md3@ElHVaBj<2B261AFxNIdS=!_{asuqWnlr>HTs+JM$b?zJ{Nzp!- zq6Er;vK)skz{J$~?`BM8vbN2XCau*AG}`zSkcjG##a9M{=x#axxiOgdTpkm!E_^pa zGL{%Z3|6nwSFcS_wd9smO2$;(x{A2+^<1Hvfzng$M~E^YUX;U~tOUTyoMq1rO~Gk< zpHl{5g98$TQkdjZFS0>erzD?x_JzvC*v7~YqMvWPTA<Oin1jLH6fVO|Jg*<w!&}Pv zb9iJB{_jBN2`0K@Y12_ekM1uSPRaR-B4!UV^;a{W`}#~6{w)lUSGy?T9y^kTG_r#9 zxI-1KxPea6FJbR{io)^X!v3=fiO`Xr3DqqSGwCg}38z9Ty{Hrp<whqpIGa+`g`?~` zQI|+a=(n&ZLh?HXHb#H%C}x9u*4c=wWO|dfu0b!oUh~kScnjLMHZ7w=Uup{2mNf4i z*L6U?QP$UA>*RP<u=_ADbUcR&dFlotx<reDBt9yl8gz+8Ev#F)_0a9S&4dRk>FOxo z+KxfN!cK#wk@|lsY6<eyBD&zULLEcr>m&%Pd@zOHP7j0I?ATzaKAsQy)nEe(?-<<) zM5YQlcGEN3j~WMR0--zJ_s2+}AXPz+dj~EbMJoWyIri!B+k1x0<_))lMhiFUOnYnP zc9N1oUHa8f-3=DMfq4`sOt;t)eDO&S;Hl{GAMHHmh(3m+SRKVNT&@{oDpz+bd?KvU z2ffF|QGM7A4V^nUK#1ud9K>E!_MI-gB}2Vk&U!kFYh6VB;&!1Fo4XFoS=2Whj-pp< zKJ;2}by!<Hk?ChmEsolW&Zk?!zr9PfRv^3prajjzL_0TU-qY?l0}W*?g9FRg1`&v* zjK8s+t*>+C4)LlzzyCFG<<4w^h+c8qYz7HA0%gt`eI8Xf#e;PXaPxGOYN$%8vUxT> zlMs05Re%-I2d-9aK=8x#o09_hlB3k*=ow4%Nq=R>f<tvmWFGebo?IwM!w^;sMuOp$ zQ6xBay&Xpq(U-cPXfHM<Gcv+vSH2?EI%FE}=~K`cg-1@rB--4m^n~LbNaNs9pE}O9 zE!tsPWu*Mdf+G`Hw_ddmMD)ZM_LJ*!LM+1&&=<%NY|(-C0b>Y)jXljsd5`v+O;iq8 zW{U7Ckk2~K64)BHM4Kkp+A%*$MU~)BYK-z2Mr=Sf28tf#YIQs}xs>+)U)us<JRVm! z`}z{|F(NwmFWH~5j4nVGOQHRRZJ0irz?!>GC?h)bPHx8?ES2aNcj!(Zbp38cZqN9} zKcj1jOU*tO2vx7v>i6$EQiD_>>;Ru{_Iw&xz%L_u-Q}iN!sM2=XkcLVM2e}?WAA01 ziDNO;Vo%&T5I>Lr5OJ)kBqt6ZY+6JQ8Z~y-j=<4k&OF%6Z~G@JbJ}bqSwtnA1MUOv z^%2Nx3^QZWukDkI=oIWMPVO*u9Q=yjAr%^%T$&Q>({_T%sxDvg1+4ULoUesj!-)$j zFux11+v9*z?Y(x&$0l6V+9_x<^f4%mx;g2pImD1ljb8TBnNqAm@<>;NTZ8uiGO=0; z;s18iL%avvfdeIC=LC7NbkF)ZAR0AlMcQaJ`kcIFeX+)yzDH*a#%bS6=hJ$Y{iH`{ z_ux3LaJ)1QbKeh%$aVNzM7N<p>Ng?KQ)1Gkbkkk)`ZnMotcKu0&wm<vf2+VUh9SrB zGw|`WW-_Q7W%|>jcoa8&amO(zv9i=uaU?fhoTydNd<m^#I%F^zl*th-Rsij6%1`K= z>G*4bIZX`HPwvug!f6PV*GuZ;jwh87rrP_<F9V&TB}_ZjjMW5^1lzhG^V%4`(Ydg# zBCIPFR-usmu?ose^(trr1sJ|z+#`KG4pK~v<tc`FpsFi?gr^H1<^5W(#(yt{`UlGJ z+%HKrYy~MaFycYCPJ`@G=4H#Ohl0tL>81&#l^D_`s6kXQ(u>tfg8|!<YRQM8zeUWo zbhs*Bn$EIV!=W%yMgPJ|{9hS(GqDSSS~v5&BHH*>q7~I`^d;Emwbjb$AS!QMwv>Kz zELRuN%>3CmHq{rg6lT4BhARy;o-AA1*SG!XWjX#6n+8-)1kaG`{Gp1+#+fVdX+6p^ z)$eF`V4{u%D4sC~y_~K&P`>~bOZ~;F{0uPA%O;|R7(yOzGHTX8wqGfgQVHmH&1E^l zv*sq`5-^+gG}xdW<EWt&G<fN%$LJy!QhR-Xp7m236x$m$MI^cj&loTYEnP8NI@HBF z(6X~ZB}H|CwZcmUuy210$pa-WU}v4F{TIvP)bpdo+%^dI!v1c+-#7DL_4OrRYpIu^ zh}Cf?aR9|AMNH;aJKrA&tZ1tVprMD#{oFt2TtbgM9f}p60ZiCOY*ZQ9?p#3IYtT!z zh2!s>3y}=iAP!<R*}YnBj8*7jz}8}?v`CM0rRlm-e{;-wVlK=+Y*`0!D($loo*aUu zAcBAmC7a!`1^BnF?ZBBM;Y!lklZu>-@|bRc2tBRZ8P|$%uJFj5wrLyD!sRYaxLmLn z6I+xA4K9gwkVMh?vG5am)T*}q;(&aW6q_TvzgycV>!V+Oxl^*yxfWe;I5=ZCp!DGE zl#_{%mk6A$MncNM8of%G5X^lFqk*LYyo4S+jN=?s-d$`h-Y5x}Oz#(H&%rk;c<ukQ z_vHa{RaN?jEF=i7Am~rgC>jAlNeD4C@r_v}kc5~{h>BWPcU5;6UES5x(w#;F$cT=J zGA;usBI*Dl0*>1-s52ru%A%m+E)K(>s2~UqF5trNJLfL%zWeU0rMo&rC;w#WuI0V^ z?mf$QzVjWuE?q^mR$i7akt9wf=Ot~=o<5pT#LADu&q3VwXMdS3!#Fus)WF5~Qo0*W z|LPnsIbsK``R#1lS{PGMI9>7to7kqYPyLLS20nEO-FNa{v~AtmRVQrRvToznHLK|m zgrtK-5R@^9kX6)m`4Z6`(~<Q?Hb4@_UXGhZHlkc|oLUuSz~T~7c|dn(slIeRiu9Q{ z<Ze-Kksx8DHptU0=ux1r8TQ0Ioc0jt{a{MS514ML#xl^Wd7mX7<dmTtJp*VlT8Q>V zzYZb<#Q1e&^>p0tRTR@#1xb;SDawCe(H`;mBKk0BN*VyrbacC(j<hf^9~nZuP~VQt z(34Lf@DBZk<T60!81tfAN(9J<heKR?{O2ILhviaq9D2`r8Z1&4Q=xwLDzk9}`ZHwZ zq=e4BNzyseX|x^Djjsiz1T;TEGUcLS;%!(bmRQHcJhfr0h|VZ>Lji-kKPFr1gSTi0 z-H}#cX>E$$fzdgVYN^u{&dbnQ1LTjHBjEU}X$2d=36i-nS@BPcQ<A7k`WjPlNG7N& z{($CkIZ%FC*!H(*^I&&t1`}v~2||9=Nju=isu#6-BQB(~0X1sfR9M-p$Hw$C?H*3U z&~n?)8<BR>*knBL4xbw+{)hk;J`V!G#eqDWAb9VPfrT}IaY;HPC~Mtj=cO=B){PNt zN?<L&hPC5(SVmr8BpP^{siU9qQQ~2pkX4%zwj!*%<$cVO?scjGNtxtK8mr-{412Lg z*Zh}4j3augC*zxKj+>yHaf7_KM24T_8tBKYIj6}Dv?K8tyO_u94jgzkv%N^vDnLNT z)Y!N$nx36qo^azR)&@iTBGX`bzz(bO(yb59LClixD}%Q5QLvw-;~4BW9b|-xeaUt+ zsF9fHvQw^HM17D?77|#NqwIRQDg-iQb*pwWtA4^_onK1(%V+`1ec3(ebQ2cflEph{ zKaa<+RP*DA{T661Bt_xcGT}aZ_oDw!4jgXlLr}Ei{tNH?b1TF?m+7*md=7764LxC7 zMD)D#aMO*^xMN<;)swLqvG$>p!}IM{N5V|P&mNdcXPwa0!At>-RXDR<-eqPX(t#&6 zyMz<bGnL3dJoCO*CSzEi=7;fLJzH_)q+C3Ci2qHpz-^dX1rDq8q-bNCivz+OvyTY> z&`3$KTII3_y!Oafjqo-XP*wZ=XVG2D;U!+BfxZkzmdtE1C1`zLEBN6^4r}i?VN8Hy z0$(du$BXi!;~}4EU&z3dBpm8^u=<W->3BO39>{U%t>St6@&3vW&qn#vNECyKq+}Oj zUHNow9-@$Cd_4VQpb0x;9rcAJ)~T-!9WnHafy)M-HwaC_YLjOfOy|sF@EC&GZ;+tv zBuu(=3~{QX!+a{TebctE3auOtByV%HiTc1YJSR(UmL4h#+vSSVO_EMmBANr%Bet8F zZX;J5lW~N6EC4BUZg|Hz2s+3*=)lIGLL>MPK1hdK?m5`m^hsz6;z(Pabv|-9N!*dU z3bn(^2;86ky?*Yt+OBlT6SkzlGb&L2>E@^k9Q$v<9bnBF)ZxiJm_*t~2i`x2&`?k+ z^8sbMUswf=xJI=|dzg8sy1JF+wdK({&cNgw{3HC1|B9n;wKZ_u!_6$Vaany?GAGRU z_cypVM|n|h*s00?lj21gRSMj9PtOKh@JLf<x_KLHW8Z(O2s?68ga-OK0B=p>l}e5> z(`W@5Z3MXsH3A$#9dNncz`i%!yLb@CIHo2X2B?3HDU%?K=lfB~wt_%^%PlD5H_kKh z*O5D@=MV!Iz2s<wV;8!Lwnyzy56IcSy;d-fK2rChoM33fg?4cBg$vO9LHv@Wf~+32 zK4NTkwei>r`zkIoq91))HG<k%85(v>I|i_m;`#$7sX~bNyi^ZDCbUPFKZLyslLc^D z`m;49=>_LQ!kzmKiq(-)jfZvA2*RQ&iLm~Yo|KXik(1?aUxC)P^pEk7Bu26I4(A2e zw=K7v@#Bat8a4bfgbv8(p-K))R3;+AQ3LC<0)_y`Kw8l>KGA6oljZd>e+<MXC6(6F zt^d^#%Q+6=Oe&iZnoJVgC6)hGE`-A{?_f!eKe5FE>avpYZZaUdNt7C!cOxY_t*{lG zQ4c%{M%rt&^v?=a?ZvdU&mxwt0P2#^Ub>JVWL5xGAlth9V25dU5xd~S?EKmK;LEQB zu7f?~pKoI5PFur6(fB35Qy}~U>t`EjFKF}>`%43*e%gixFC8r`K{ZZCobt74qbW@Z zCN}e0<mD~Om`m^>L!<>fVNaZT7*Kczm7ELS=n2au%z}wKFeIQ_&oLItov8dD*wbSx zSh?WJXOvITko<ry?Zs7cHly3Pa2}NY)pyuNg$D>yM>XAKIy~iq973nJqQsKq#00dq z)q~~gJJ5jCM1-E6jg?LLN%mhT_k-G}UcPt{oc|Bc;fw*XBR4LC+vu!#5<z>x+|*OV zF4X#iwx%xs=$bqS^p^qfo!VSS5?BNGvyI^{CUAe}VD=^t%h&@Q*pk;Jk_nr>Ld~hv z2UXTyeLjH9Fk9=`TX9Mp4W^9cKxod*RnBkqlHv)-K}0$Ml5cz%(t&3e$vbrE{?gnd z9Q<4Zw8bh)v_-lblOQ-qVMPisL+FqMzeU%~Y0KNKVK{0B-S=YuF{?PtOR76LIR`A~ zsWPRJ9Hyg!R9e$Xi6qqV#^qPU>t&=(=<>QL*XyqoW0mBJ;BYp#qvK0fv}sAddzPwd zi;+t*<a#CU#jIyBwwUu;9i^cUnC^n?t1|#XswpSYCU8CEA!`5(Iqiqy<p7==eG{D% zvW2rh94fBwaWZX{M~{TmhUn3c%cR;ko_F!e`}Sv5d~RkVI^2*~WD#t7l~E~MpD2xD zz{15cmc<Mzp{vmwAl{)c&^5b2A4_!v7&1p+rBXI44p)p)941}J-|EIW8EIfF9P1F_ zSA2q#BDZqWe)Juo7h}J7>8VZ3*`@V1X<D*$2UTay7c#$8<iXeMmiebS_ZXMPz*PL~ zvVEGpe*A-PqgS@=dJqfXOdbK=Cl5nf{fmV`xY%|hS>38ApPvyi1WiTu8*o8y{*B*% zAums@KaIc1q^#f)<*K?dEBgymXBWv7zV8Joo_z-&!R$KF$)Vtakw>5d<Z8t{^iv^F z$JJQZbvkw2u%l>$-3f>{;ku?1MASYrkK9ys?OSwLdIKqSJV%t47y?Z4tF71U>jS~H zq<!U8sO<`B>9|3T8AQo7eA|p?x9K0ddHbhnoI;FiJWNxznpcByIAh*#l&g|xmxnM0 zeASy!HPGm*vm`M%Z&HS?nTK#+!N<OWNq5@;CV+szy&6XFt20Y(6FO}m6!*-SRs}|S zgq&uG;$zRypy%xr8Q}PF$FYrU`P7C<p0Vj1@7W(p@YdqEJiZvS_c#!eh5}>vxbDa; zNO~YtA}HC2ox}lT88b)au(aAj$(n0;3q|y4v~|9^G)7n4Yn&S@B~$cmFzed4t*|3w z7cGtGqp6~?y5Samd}dV=y*<r57zzm(ttdW~7e`8%&xj-Hm+YWxKRZvi92DrypPZ}W z1m+1!UQJKhpz2SkA{Ee-z|#$ZA%LWS(XHxgOqz^{6ZtWhccruSA0g>hic@FT{kWN% zeF#%#5+y%v+J?Q0iBCkm7bJ<a*-*=`piZbw_zt=W+>e!bT%wLhA2?fqx$*9<)hEkE z+Us_FIL?ba)aRu;u;l@AgvA<y5#0t<T`L+%E3V=(#C1Ffi2b#el~dM3JB5UAKx}l8 zt@x^iP=`7gEkYj=J<Ghe0Qt!1MkL_$AtWELIO=_-pBCkGmR}hF?HF}H6w8FUAJHoG zH}=WECF9~aZp3Mg<6dcPJm3Xj=HpTw{dmW>n{TnRMo(!}>iOLGBF|upN~!-$kry2H zW<^gy4N)IQk@joLUdliajqt_0ugV1z;Y!P(Bpn5+&C3y#L@<NpN*}L^K`RXQ+1B^M z1%zoW5nauyex|BO7u08>vpb@H{yuaI8NpPH1LhDzI}fIhSAov{3+UwAfy~sk3AA($ zkZWQ`5kF~o0e;dZI#DlI^ThEEjgmh7w0SH<4HP1$R#$O7{s0+Bv$k~U>GQ}w2>R-$ zq2kB0ec2tT@3p_oNQZq7m@wh$YdH277ALwF>&!pX3B(kirT>j$pxfF7@=kS4SwyfS zSyJ&q$jb3B4S<B9#n&S@-o7s<{slXrtA(d^q#IJmh@DCa-9{)sKmAfPl7vCIT`kdi zm+p#?^>@)21~GejUX4GuRECQ{8b9?uR%}3wZeldno?}bLdyU?KvZE%}L%tNbKR1d0 z1`628y18q{0P>+f5q~n|f7k*y;AQ|&{ZwC<1wjVXgf;mq#~t3@CS<1DH_=W2rRyrD z%W-8<J|byo_3@+Mg48JNe|b&N?3*K+dgjZOT)Z}h&W*7QCUET$P!^=U%DciNcCb{2 z`Pd{$g8#=2Z7OV1|7wdkpK<Bh-MIuUw#Uh2D|LNp#hQO)!jUF#CNs(E;t~oI>R~jB zK&@@(>gGlC-HJhYW!G2(n`#4s+AV0hczzfVrPnK)FJ@ZP*NtG$YPdcDr-U#K8!NZ| zT-Eaau5j^P8GU);{W&#z=N2^7Foaj5`%mP6UpqDrR%h7;^YjD10{__^g~Plhtc5<) zW^&)|>3ewMMF6}zdu*g*6Pwf6srn4iON;fPN})#2$E>c66*N))=)>p>Zopo_{zG*F zGZ^Xg*?I~F;x(lm)Hrf+2=od4ETZd57*wJ{xubW`DYvQ8Mli+o<63zA?@U_+LHPC{ zL!S%5Uv(WQI35F`3ud_r=+HGJjJ{T$O}JIse+$mpNapO>h>o~$7L{d689nU^J&8&| z;5tF}6t%2PNSNq|zP_kMr<?VYy3T@wogfbeAvEBrSv_t3=h=_bpK5=PfACgRD=zth zbdERS8LBOj^qsp1!LW_%7w2{2^|Kj!MJBoYD2R?-Ia^8J2=_u(#tp`}NgP3e5u#NY zAVeopu3N8hM4NZn**xmL{x7IAm7jtW2cVFnJ<~$0eJmb3NDfvVVAEyb!wgm{jWN3K z62Ez*>y0&blN?|s6q=(Jij{S?^v!!s)(JMwr=St%kT7y0579DOiRgDQ@OC;3r$WaH z!B&l_IxVX~C8C32yWE7z6i<~GVB?`}7FOD~E(UOM2Q1fyq;@Z^hBL{g#Ae`szNzZ9 zlu}52ZdS}r=5s))r9i*aDU~u(oXP+M(ta|cp%Io*3k<5JRo+dy`X)}=xLfyxmV6Df zIY)qsH2TB`(kqbg1Hvq`QtWc+Jdh_Aw`9HQy_S{(xB<=(-WM%e@aY9eU8}cF)}b3P z2egLLXoYfr_UpXbohtLiQ*9IbeTGQ?2RtSvAogK1T>`rOS4`lLMq7VnRZoRFJ}p2Q zdCUe7wK9e;mI}v&NxEE{yUKvy7im#@HR(%jmoTGPU!E6EomWKfG^^sM>$HHMw64g< zIpKA09c=`ve~UgmAVW<VEaCYT1=@%tv054&s`DrV{VlEYIlzP(ddNuB)pdDES@wOl zptwp;lgUv%v1a-*%5Hd;NMl&fURg_<7H8m&nue1Vt=^a2b8he_=3bTo#}~4|{;UF0 zDr#~|QEhyBs9f0`mFyxn0IixsKI6@9x7gR=U*gmdW~^)s2>Zri<KPXvJFzXbnqoxx ztCLkhy}491sM^j5m^zqmN!qO1g2)9^tR}Y18!%UysY&{q_=0dq>=;C3bmu|(hTB?} z8-Fi1+G=N^s;`xA_IVoo1Vff1mBwgYN|lrcjH$svDSHI3(P2Yy!3Vu_31hGDd2HQy zC&bB%suJ+V#66mz#S}XdA2Xc_`tpiNQNe*cVn3~v1X&Z5B=FtC>JWCxG(@x-Nk9Ch zYWRz&`bi?i6*u&8dM46jtOv{~Y9zccDB9DZP>hr*RrHp(p{UGsN|1LZ@JN;~bR^FO z7>p0z+EEFaPiWM~8ugbl#FW-T$8<RRL(MN%ADpY@2bddB9M~#f)QkTjDinRurOWrE z;t;*_aXw0s))7pIm!>h^q_`<Q-yT7C3upW|qIdq+oVWx}cVbeg4hg3}%*Jz5J5utM za-}MYsZIdD2Lpcd#CrU_87ED(B+E-=Rfkb1?&&!ebN_H0_y4lfcINDT=gB2|46=;- zU#{~;Q5d%u^wj5LcXtS)b~L2`q8~puypEW(C~V85UM<4-5)5H}5*Bp;tOn%m5ncOB zs4|>FZ@o$D%&PI2C!twWYNfQ{{g{?6b2mS96-vbt2+&yx{);j}Eg~KDqFt>UIilN9 zq*TTaw9+%6VX1>UWVq-BxJ32ac|10&M&wjYn&}D5hf*D+FF%6mqxA-&Cc5Yom{d4a z8UR&1Un;j3aQJ0MwV>e`;jg98`D9ETo~Y`kV4O%=v~CU|SKN*$w+NBmv(MR+25NNu z0+<{23iQAFfyA7`LlLzt;DLSGF2t2K{0q~IF@Y0Q1gYzL&McyJV3sln*Yx<_y0;$| zXcJ|n15gP+5rPasi{gcN$)s!Q4m86uMO4l~bVG0fFrjK_kQ6ah=;4pn+Z>h<(Z3_L zfl4pnoid#WT9*v)3*Ma<xkhyFaO(*Us$Y+_1>oe&(zi|+W`GWDSF!cCdnp3|N<+q- zo?(N6h_ny2lv<GO9gK$_+krwY^SJB_?_l}OGIf&Wwc81*Q=hJk7uq?iAw98Z@*e|o zhp}!9(d9r)?5AhFQPCYkfS<-eU;iTbbHup=D24s0GKYsFV4CJ{&(9#Vu16jaOV|G5 zf9H{;0QCO=|Fho2kw;@D%;ys6vo?=#pb~s3z`{OjFTPuWf^IVDGH-Xrt#GbY9W44C ziWXEv81vNLSu|LuHzt^8@m!COV7d^KYW0V=KJPo{LE3Fi-+8s_;%S=qWFMu7E{C+b z+R4jy(7mZuRaQ!&JX_;I?CQrJ$YP#AaIm^6^<sIzJJK%{dIo#IOfo1}j3R1W?w1A} zr{Zoj3-Din-u5H`N9FUY41G;RDo{pB8%7-vsMqTNk8wd}iV6=cmE1=3@>^tRGwvtp zr*TG*lC8x%*I?*M_rzb7wn5g>xWgsGaW8KlXFC{AiwaAbXBCZr9OSJaT0tTjLq`~^ zv?^s(dUr}Iwb?#;=3*IGr8b6NGPP>!@(JFvs97dOhi{9h|J$lm-sE_qPzxw%3lxgD z>mmCNGT0p1Z-`xr{&p?;3y}TzS+r%MvMmoCQtmr~lFEhY5xVlp7Sl<QXtJK}g)EA} z^NZEJc$tJi!JN>pE+Gy1_79yVN#~W^TX!4??3>WTXvQSobSZ0MvgAG*Qm=jOEMml% za%$j>`7VEskNP<ySP29U9|GK05IDXT1j=%=Nnlv{6&&wR9}Lej+K(~@TD559N!*0W zb4lwJqq8I<u$MvX_!IjQ@!WIZJ^7g9mOjMN79X@x?L5!cR-PScykW4KZfAy8Ifq8G zx`Gx7Zj&p*9e>5L;lT_!_2Y^M(Ph;*`t<2$rimhZ(8B<=AibFDD?z2CG63EycrUL% z9L$XZ&Hl5a=$<Q<(f(lbS|7{Q##BTI(1cgdjq@1xR6g~S^F4VQSA_3SX0(P=HQvWS z=MsW7wjuew{{p!<{!S}BL+98o;N;<J1=TBii;he~fJ?xc4b*cX^<Wy+Pt2Da-BPPJ z4h`BkzcceN=v@{B5LMc?Zsl(g1nAu?9*1?-96j_J@O-nu(99q6N|e`W3(-Gs8+Lky zuKzFmHAWMc2EiO4t7-6ncVz!iSRHZ)QevaG6SPgPPuBcmn8#W_BD@;icddsV!b199 z+yvZNzGG-+NQpDx73|7pk|lBOnTX9=7%7V~gYHUSnB&TD{z`!+Q_;btdsD(&a$Mny ztr(#IuIqs`H^z>w)J$<R^$Hz|A`)fq$b$+~w;j<(F5Hv0!EbYhQ={8AA-BOY#WGiq zhH=U1U}4LD3`Koa0HuF@1Jh%qww<&}2nCpBa6)xkseqAad++NfZzmbD4~GstJ$(J% zv`6P~@Z53;P2x`}I;*qfRok4Gr(ybJls+9aE#U}Mc`P~vZu|VF^XL>anGF|1_aBwI z=fs;sG-rI!Sx=hFoh`#w8|1}Xc#1}y2M{3rO2~(CK0lr>V{F##;kb{nW)8?CIQ-TT z%!{n%ig`@3RBPzR-x51>*lf&|AL&fF6(A0tB?(lUTlAy;COG<Z5GSC{Nl?yb6XexP z+avn#MoU?QCTzjoYUctXs6Cm%KZ(;3&cO{MfU$zslmP5av0h0V55hp&;A*k+FQ=*t z#>yKF6T`^jDAD>hoF>GMAi(o)(P0+&0(uEru+h)e-T~D`9d(S?ae>0#NX%`vKf*uw z7WLU{#RkNHsEFS4&IJF_069s>E}}I*gFIwyaX)=ICI6yxWoKa0NubIjfYZP5bLk&U zxd<xv*`?GFb9-&WY;8yv-h!Wv;SxMqg)9AGn+hBW4@OWSen9F)=?7QoI~iS-V1|?- zsS9z{mNS_3uCjnaMo!a4D<Ph=p7SP4*o9Bz=Cnr(s26Vs*8DGMhZpL8%jh*+qikcO zhKC96LJD9JMUXoitJGAdDg&Q^9iWcnBCag3U_r|6#7T_<>KHa)vOPL}Z$e+!WXTad z<L|{&0i=nGYHgp+ht-U)HLqN^1p~g$0e3C+WI2@E%w3W8h)?;kIv*7lH^^#^?dqhI zhn@-mZm3cL-3Ngg^Nw1OSJVUcu<~r{1T(wlLd|QcV{{Z~T+lo=rnWU^Zr3?!O6hD! zuc>K%$eWhK=tgu4*iEQ$5028ipJd0pNiyIzrLJDL+3|=j&j&1!->2JOa}&k<Fg@X? zDDD)z+4XRD*v&HxmGol<B-1gcM4ro9z0;O*GvI`Bs3`!Oe!j39$_3IQ>vwoTx!_J+ zGfpH7Q%+kvQr}K^CNi_OI~OmC`iYO)3D*zFklK74p6-nlr|3Xz7z{zofoQ^$Zpw<x zqV`u?E_V~FG87OR03uQaU34Ul6zK|#Jw!6hV=L&+RMM%9f;A(Fr3~eu83zJY<e8yw zXB$R)CGFw!j^;5fL@CP!1@$Vl{-B*x&Xu}6oi^el1o|>fbQo(0F$LU}-!<q7$n_%? zfKj&B$OBRI(@wl>g~I$3uRH`!Xn6BpWS|o|k7Yn4d&Sg~Y9H@3s+oZtZo|&zVr^>| z&xr|-d}KmJ(GV&{aS!!XMA9)#;lK9(##m?v@KWJp8_I=UoF0Y4>65~f7Z3-cUFU@V zU`q02PUsAq!<lfekW{htNA<KaH$&lFEpco_XT(iaZkz<9q4mJ|G2O$O2M~}$%k^h| zvj?q^u?1UeAR9s^i7RiQ{wEBx@^SW5Cx1ERKmci8;#;QtL7k+FI=7M3W+JsISRy2% zJrFx8Y2D<Vs%4nr@bOuwxR%hM40+~Cl{Fa?sW_84RP$!bjGQiBG+Rp9OuwMZZQVYx z<}=biM?VejB0izoH>|)vlWRNWhri41BGLcCF4`B8Sjx9)oo1<;@W}XX-8miin%UGp zUe68YOSBzA!{EpRC#1*g)>y=L!o2|<fo=!UtX!ujd}|JI@kRxDX$UEzpM6NgNyX{Y z8(#0n1QH*ywGtrHwD8IVs}%(dL5f+)HpXj0ucGVG5Q;@AQ2#KtJ->U3+Z{GQW~|X8 zHxU|*wqvo2#pNeCUcm$tS^aBSARt|(wdPc{f$l`s%4H%R`i4waf9)P~{N|R#Iok=Q z!?UJR4GR4%qN}h8P#vg<3<7<=7ZM1f`~Vy^Mr>oJge}E=DiJNYZcpkf4)S=0Jm~2; z)rwT5XF+}hp^%%LGPMWo8X1YZ{&9Ny32{cYSgRZap0E9Z$$%8;lgIm8xk(f*oEcp# z=do$HTWQgO3K3>NDHgvO1Qpz3DTeuNA#f_*lHTiWt}$h>s>w(D;8pz6IC7J2I?p|J zRgm++H_oGxVR{H^nP?}M{?+bh5p?JmEX7w=GMnm2FZ;aG$4?wvuHMWXgA(KKAg7O# z9I|j|x-!(3M~72CygvTZU&IK!YAwrBPmg1!_rB%~($cTva8xEnF%E)NWo>(dUs+i{ zjnESnrhe3s;b9=8$XHgmKp{C*oK4{h%s9o~u`&=4ZWV*i=Mjhao!~L*gS-m7)}v6r z8|9gI8afo<0t{v`kj(GBPO!D@Mnlr1yKqKu6`b0EuiAiCFu?O3RKuW}r^G1PL}{`e zohjAqvZ=ZxK0~g1WA{LFlazXpu5v`OGC|1K{9gWc)-Cuk7*lk!mLNt8Z>dZ#LQim# z@UFh3J!-a?beB_Nq;xQ03}S>s>`&M6v@tC5>(RsKD3_}J-^v}};fIAv>3|o^7ZwU< zJTl1znpsG62HxjQ<j{{SrRt=~cb@>6Wwc25VKBnfnj&QhGCW@Jd1b!=+rNqLQhiEB zGXO)hsQwBG6PHUf?j*omO${*kjwQ?|Y~PHe2AHhyj${pYs$|lLjznJ~6D-Hn$Rauo z!y_e-$p~W5?}q*-J<v)mxo0!XHgyZ*Agc&_J|mRDv&jA^F08kHzk1MksdB%Imt@u5 zBD%*Yk;Py~?7h97J<hR2!CgOQ&*Z=D`Dh#;8!J!dFr`4N$>j^<?034BpZw)jtkDCv zhFm~qm#R6}G28mJ5Rg$^2`btEsq1loJudo;$6=1h>t<DSXW%;Y0ZRa&Z1)oAX8_B} zsw{R@;NspV&mop}RmVp$fco;)YDu{C>L0zJiGV@3?Myw=11>n@0JQ0UHFncAcTP9A zYIVq9CTL-l-s0d0imG<Yc&Fxuxqg}#wA~3qS{)rMV`wK1xB~D(Nm=M;&@0HR{JzSj zTN@w;H)QkTXj*amY)=o*9D#E6Xaxeh%%KMvxH4J>VbK&IOzoZC)cVskTE-TMKR4GO z_?TCK8O&yw`_vNm?FG+kn+<oTudtlBqus2Q)yLBP;7~Q&saJ8R7F+&Sgrk=7V?sC@ zg}qgC)m<z$$?pi8*8@KhdS|AwPOjW^z_9S;T>URfSIdj0+HU)~?u}4S!UEInC}l~L z78+#K0KqbbP?YI(bbT3GLTS9BjYzAo?QgL!;4H8!laaC?R@j+S`X6ACW1z3`|6I4g zd{8DUF<ll%3l;c%W`n&{s?#f=2+Q@_0UT{)fGovEw?Ous8|#o^MD(Ta%ubvmAzGY; zo*CPZs137R6a#rWEz)?A|67Cz?7;0Dl9U06k6fWRkcZ+B@<)JUP2Qjw28NQzA%6~- z9b_0M=<8pa?O;)h7eN>RBfL~l7c{hT7j`{Y4VB7;UNwI&qCf628#F-r33Aq^eGmHa zWK#Wi6JB>Z;kCIgGKP~rWiIKgu|Th8#$!iJ@<e(rexpSpZB2P#>5|;0p#nn>vR_(R zwvO;g5EN~|A+Wj51i10HEkb&$t7#{=F>##orkQH;yWrZvg1j2&9kN>83F10yTR62V z?1glXdm2172NE#DOlr`$ln0B*Ll36!`1Y^Z&OCXU0yiLhnlX>&Ce(M?LxjIc**S%) zI1MJ=_2`?3WicHqhE-r)bKq7TH@jo%{jD-_1u-x^7wQ9gbRmNZh6A`O(N<!XO|zOp zL^rNbN~O?!yh`;Ho9-=>?Zh2X2&vTqK8C{Zc$z`RKNb7tP($=?51!-483*f4(Yo@M z&LzyAwe;OpqKk|==CU^lV1zYky#ZJbW^)W5x85lyOh8Do*`qU7$=m)-j-x&2t-n2` zj`QDc@lda3_Qx0*48Ci%je-WE+3m%4-?K_LZ}Xq7et}DlR;HpwgEykWtkNbV*gyxb zCivj8vWj5}n1U(B+$yN1E-^->b2P~!nOJ|%GKf9$dBMv@fge?A76u;!YaO9`(M!+5 zZ5)|mLJy|xZG@DDKNHn8)^UEcHYI5ng1llRNAxDS6bH!5yUH$tBy<$2?C46T-=TbE zmV(=SWz|}FVW;_lgM8FLa)n}F14@79qik;e!1pn<ua+Bymeq3GfsX3qH{{0!5ZaMl z51IpMy?~PNm5cFkf`l>y(uB5xVs0nK_sH1vY6S%;{C`uau(kl7_sZY$6gx!ve2qEe zf+Lu9%atqfrQOPB>F1wRv&s2(k$!HnE%fc~{n&uu;)Rc)aTr~?iRjM{={rG@r)$@J z*TF{DX7SNb=sWU$H9AlZv0@J7K;j>!PhAe(iwY?Ac+m3Ps$i&>@q96&029R!lc+S? z+arc#a`Rhopm0~{q0~f#XMh$dExHv{qY@yTAK10o3M5y>iDCd!3H7;kB=UY_Q;~OV zIr+<{{Y_}Xuy=xg@Mrc~9bPM6uXdHcQZ9v4hvqoHW|g_+zQ}r>-YGV#pLhtOxytW^ z2s$?-Y~&H1y+fdSttwUf8$e&><tEMO%B>&O{ML2A$ubu?ZQXl%R`Gw=jv|I!Rj$+; z)uPgOch^Vm0EcQ?6F}Uh-GXr&+mOPWp-28>@X$a1*Sq(#-OoF3`>={1gZBszbs<bW zmff2JGbuciu!|VGox3?q8<d!}LlV3L*p4<VA@49{cEolf%B)u_<s2iRVy5_iYw;hO zO}F>4v9`_JuW4*Nlc-4hK`M|@ZyRtqDt|dHA|j?}jM~h@i{&r=PZxa8$Px5=ytkeg z(-h+P7oaes8r_Oj%u3L&Y7qHBE<?wmyl3%Zwf5ZGgJQOxrxM5?<@a0g=hOyBGDUCk zh^Cyt*@v99mV#Wk%g$J0Z>?hs{1r~%`&itkmQ##NQx~VcUl}RvsgF1}Jk5yaLTXRC zyO`>$19C17JRa#6n`bxWviMj;JI?i}89H*oy&wQHW3V&or=V<U`TwoYfhM=E0ibrE zo@5ZCr>`EWhxkC)>&5tXhrZ#mg?2t76VWpfStA;P(49V#K^!1IUK&K!qvT*1PB<3l z1_4a7_uz!}^ca4Qo;xW^oM9P^@#|pL{IAOy=z&IWh2@kXPwG}Tk>@p1gOlhL{}3k~ z3A*+w00o?YV=`g8O$v7}@UK*s!pUCk&he^cn^Z;`(Idl<kDJI>2j~MxkE{K3;tzmZ zVnAv3qGBLC2ET#ToG%|=oTUB0NHo#Bb|Yz+TRx3X_)gD*T4W~@7UK`36i{YD+UJEG zfG1J|yX;4%lap>c*qxZfx!Flvz;IKH-PxOA)9wz?cL(UGz3<N6H0`n_A!v8@Hnr?+ zrqj0<p!k~P+vwoSxbW=0b*FVF4udgfDLqbk(b5n@FZ8pBo}QX><cBnd`{KC9Bn!vJ z8t#uHT7`L~HOxc?<W4_ZJ(s&Ez-H%xcJzjn2AEaFbz&)D432;jm<kahI_=$xcTY>d z#|jQW_8X(3&Vn9P<yiSo{yqd4DscgXivOAFPDINeK>{JYj{;^iXdqU#r&fP5bl zh}=BdDP}dBO9d3t9ZjXK27#tK-^|`FhiHjq3yiTsT4KjonMk}BG<Zyu(wj&Br5j{2 zeoU*u^-?*@!E&pNAYh0MW?wB}-bQtF!E;wVm+>+E+e1)K{Wpv$L1(7aP3VF*q4rRx z0W*eJFLbdCCZ`nt6KJqA8%lNH_49x=(8aWHcIv6x)P5m^K#_H#M$<s!9~v2s!K_Bq z{kXu;uSyLnTyB--X(mZTzn>*de_YG3$V(zaS(r!-dcgp1KP})s?86qA58%z%)3b)# zE&U&=c#dti>{$KWeIQ<~s#iju&h;TL`r~|`32cxqIlNptYlym@2&}TD!D&GoWwFl0 z{EkPL4WNxhn({DuX|P+!4;}TW;&H1c47t*JKQt}2^pEw*C?jp5<TtGO37&6<x6<N6 z<?HlQWV%yOa11oSdkj9((WtORN8w3b8;eVY3~{Rl4SF`sh4>B@f0(XCv3p3mXP{b& zTIWc9yU-nr)f$a2)$(Ip+Ue&BZd#zLNgk?~HzV;6nj(4-0s)xk$6ZWuv-D`8l!x%j z`cl2l(;oPL5uJ<qpov~p9QKY*c?&Xp2@N>8krCWx1ET$R?E#dtSnFrVM_+jmGMRDs zgYLWuP37#slrO@?Ovc@JvLEFnB^bBzdbA1l2@%&NIUs$8>%yq`&(0&1x&Uv0MD%yJ zVFV2b@qI-w4~x0JN@0@TU*Q(9?I7s_e#6KKYzhEDF>IRvR_KSA>L;$ym9L5U4_-4* zw@!SPBfI5ktn!^})CZR3_=Mq(8lwdsh;ZHMs9cZH?R7uOlCvb*_a{OM>V#TEN28ku z=mGRXi_++$_FA%p322v>I;J}xX>IrRJS$H6w%dk6_y>PfFa8?kRxUJv{YhCbud7D7 zEY@?!h1XV-=uXh?B<LF2`#_aDwfEXY-6P>9+j~Fm_NF)QAyd&3TgvFP)1eQm8Uv1a z4wM@-ak-(y$_kw41ejTfq@aHd3la;7(BJ(?$u-NEizTmx-AK34fEtmtb&lANM|Xqo zEy0{o75L)g%y7-7<}bMX^2mcW5zBDbC5kJa%a5S$0wbv6&#<lhOpDfDo-K#Zye&Mk zrafEvx7fq*+B>ZRj(S2ZIA$F`#)uxeJoOyqxwi^H{pAinc(5cTJ1Q0iI{@QxI+}ar zPVdv6nbw}r<08`EeZ=bM0o1ML#8=EfOJaEaZUucw4z(oF5Um0GiuTUP85~et?8_G} z!|+9J*3S);s=6=bi68~);TIKdF_kucTDmCN^<_e6g;%%Q3OW}-EN$LrQ%(F#C<$$C zsTdT_kB{V~bp?N?Tv0^-fcZb1bC*%*>8e??`$Rttqsy?;N{hu|FR%7C)@zxz_|D-M zuqHAd6L@I9{3dE9FsPWdL(9-2uB2KO=|^8w_8xAx=+!Yj_^}_J2`At3_6>p{lN%#C z>;ssBfk0|yV}R-@EXZtC*_qSGt9TpebXP)|h(2(J4iMy{ZQ0B;Md8J8?a$p4vlkJ8 zjc~svZANz$hhyOkKKwZ-Gs9)Rx8lcx$~Jnaj9xo@CGsH--uQ2AV@>R+E<d6h_Tzy% z4PZ|7N!lm1aDA0ZS-;c2_lzG$^c(1_n1GULx@|wo87Rwku#tRU@Rhq&gr+;^21;nh z74fE?o)c<jO&50RoFY2;#z3OPkzTwxJI$0tC*_6@sgXr?+_5`QOFrAfBsm(@-|GEF zLj$G*Ibf7mq(uIMJ5lJdSsNvyk70HUYN*Q>>MhcC4@IVvf;4VlrMxjeV(!eo5;q~E zj#*$`l+(->wWRuj7Iw>M{1&sJK7)zmoRyBHQzs1ic>OF1^y#?!{p=w2j@|PoV}EpL zL!vSj%D8mJ8K5X$;^al1<<Kune*%op_;IFXi>D!|$33GX+GWpXWF(j%_;YDKW8EaQ z{h@1D0e`}r&y`EV@YD<glvv<~X1_-n&SthqD*8KjXyn)aiD(-Or$2Bb6mFO{R4f-q z%th)$VZxIAUeX3%!l1Vjuuld4RnIj^C*}VE)d6&~&i;#AKQcMk#@$W>?M)%kaz~h3 ztn&Ey9M<H-1NcpxXSkijQpA~eD+y1dY1nQBtvmM$1=I*grV#}+6t#@4aNZ5*NEt1l z{bvM48r!O3`6YVicpK<n5vo{%VTlK1$RECIP^3e(z>E_)1FdoeO+`$tc0}(2oo9d{ z$!lz1rYfV*4`88~DT7$3x!DjcNy9tU7rz2}8vPQigkAZT>f~l6d@e6K9?N212-Qy( z!7-Mfk#40ck-Gc@yaV~U7DM$S`r?te+w6faMSz-oW?+QYn1AYfHw99hBz2yW8@01D zi%n{_IY*QTPI+`p=#;2~gG3`d&p3GzQ#dX31Mt%%d1Y&%^0a1wHadWi*I{zmV?Nh) zoo@Cq8&3$&fu5yyXS;SB5d!=hDxj`ctb;yP&(mj$ko_1%yD4kp<gopR(dCDdquxNO zNg1%Blq%))ax@X@)#2JiThp)TOjIoZMHffL>XYpua2f}&hs`rK??qwTSY+F)XZl^0 zia;ED+PR481%Ojop{~DCl~F6^UFPF#zuvcRM(#B^h92?)lkJdcy*x3}UDl?()-IXC zp>H8vAJ30M&S%BwWV(cn+6%muesgjeP<dXSvVQs{N;jBEtgIhwc3<$9)3txFR3(h~ zX0?xi>0=9vU`hR@qYZRDK6x&1iXl{)&|gSjK7;ASBTzx1OELdv)rQ`e=hm*<+`Hx2 z)tl+7vEV1qV3B2a;_j7(#JsjDak>7c<QLKsf`l-V<RVr6I2+R?%k`27W1_Z}8(%`F zLIRfcD-9T@%pDU*yn2IE``OiJMq*?nNV8h>T$zm)kgwFlR=seJh${~AU}n_+%(;-s zx9rvv;d=-3J?NWE>gDEGq_=8WYjhDrh;UW?LshyvHLN0N>k?m&cpOe}-6*#+moc`P z4H8JigV+jPDz6#31p=t$E9Z(T7K_Kwx|$D`=tze(XQ~rySJ6N+u^xX5vL{-@YV$gj zk7Lm<icdcGoIQoC4CD?aF1kGi?%dEJvy!+1nFwl_uo7`)GJdg&wRVEs96cjJJwVoP zEwA|M?l2I#!E2DqacBxhH_Nzx_)+e>7_H}_CBkK6`T+!+xZPt2u}EzUbvdeDq~Jli z{3p(s)R2)<2m<P=P?Ap%Wq_?mm0xvtaBRo_>*c;AvzgTk0H%4o0PXDTH)b?+#9INz z&a>5~{rCdgj_vFwOQkc8Bo)SNso3W0{)a7POm2}2a`Yg)X{n|i=?}+(hlc|VoFe|K zS9)#u^dJ{UHBvA!+5n9p>3XLdfK@u3CHBT0^)vAY5gh<+cP`;iH3p67tB|o&Ix;yK zkM68Xe9G3Q#0`|k(*e1YQ7S|}H(X2$_=Qh<>Z1jR30_6~H3IUb9<kX+I-H;Cc4L9B zkA6pFb4T)ZI`hgolw-ZX0bqWT0npPFl}sppVi@_MB1PjgU&kBTUV27idSk2Mq`Z3; zo%pz;UWWz2y2rE|e{^Xh4U>huB$ja7xF&#g>9H7JMeC6Kh<XM#8Nywp@+Q>}-gtt( zv+ER0wNVRWbhL4vPu7zSHB}z&_va$)Y2>Q~TJR*_I0ZruC(uxBQC)t7(2<|(Uxo{w z#jP-4C9$U9xOu_?N!V1GgQI$dfi=M3q3B@el9I6LZ~vj>f+B;$-t^M9!CTaXV8nq{ zPE@qiqYM>AB6=B2OJ!JvQZ1f#ME~K$ob(1@oZL*MQ(cA<7{-+mCxG|_qTPUkL3p8I z+~f^_FL*iCi_&<DwRStbrwnk7{qj)0-jRw&Q*Di|ep3r63tcpDpULh%r`>%{2tgwH z`qY$m7ViK!&1Bn%z6og^H^WusSPoY7@wKS8-iP*t;UD}m6>%~6E8(b>MNfqxCURC* zrz>07GgzJ3qE4@$*ZW_$cgP~?m>sf<iN}5ayge8UapQ9K{06{>zCld11kidK2*8-E zobN}5=DsIR6Lzk<rMpaJQkhS$9^0h9hK@PH4?lG1Y|9=X?4DTc&&K0as+$2_qHkzz z#urEcV?Q|<{bhdWJ^pddD&7J(VhOZ0Rs^=q3|iyTmPK!u&}N_+sW&d9{oz)ei-#N@ z+m2MJRLkT7(Z&->nH}%>WL%wpTl!hcqtF&^w{R_2+;U?O3|33cPuyE>h$pg{e8SV_ z0o>{5mx~x+zFfzC8>XRyK&wW+%VhjQaU8e~9sF%r43?xonpOvdf`IrD?zpST$R=?% zO1QE4^tFh#49@3zSHnU@(@pWI@-F}-A>XA$?FRQ(oe;UP%0#h>@rSwkM1`LAYoCOo zca9ue?n1+2tx|NRh<<%PI0ls*mw;JOhW`7;c`%n~oC6kL=H3_Oed8O(+|G0K7t~k| zD3OTG$S@na_6qcHpv>STOAh#@?@s?^xDyMm2Fq=9oXh3(C{$^S=$AkTiQvSq=v+D; zV78207M9<p(pV9F82|BFo$cb<=%}AsT;I7&6sq}3lZ!NEL=oHgxLHuB$8GUWl0qR} zH){@!jE(fuGhaQ6S4qiJFtdcoPc{0~B-p2T2Wx#-F}6dTCwfjzk)Qbl%C5DjM5q_x z8_+$b`zoQUR~g;N;+cB&v!M*;+O-sLRbSyX5XylIx*R^(5q;x*b4c04qmI}?XL@sw zTxY|Z9Op5ji|?~cB7NbVOM71P@o;Bn_)2N(%rND%7svYJ>}O&KwLTB>vnf)j0{9)y zpryU)f7q%*FNffAK(zO6=S}gcLRnRADFd4He;m>L2*RbML9|fYIhjko=>YyxRxs?! z6+l~<FM<|t5Om!f!+vR;q~l+F${3GW*%;U?|4bqr*nH=H-T5x(Rv83A$K%QdCM6V6 zrvBW)v!#Nkrt^vBD1G;<jA7fVKX}47-h|1Yrgn<3fUeKfTh9z%`5sl_DOBa9kD|GN zN64^OySWdjO)WRTo1gyu9vmaxkY~&H%Ive=5Zob;>ydTxehO3g8iy%pV3--T6mlKm zqlTw)K$+**i;^yvz#C&U2q<y&)(sn8MVFu#0?1YdpyZ0!?AFOFVVt8ftu19cb`fj} zD46D;z3A<zlMDa%s6{*I7m$PFmJ(!2bO44(g4+>73%9{IR3@aPXrg@ym$2gz=A-kM zWf@@WROK-pY0?}2J<tnWf?Pp3O1b4gP#_xRVFYDGSg>+&Ku`1uZf$-1g1?LCg%^cf zyJ1h50LD(2_ec~vj7z+1g>a&h?VaGaJo8rKkP(Rp!l`6v(?GBT&WxD>d14oXU-MwI zmhzed=ddxu<Dv~Oo<(c8&9xT+EaU8)pV3ob^0gtS1wfsp0I4F5G)iMQc2i*0MwI`0 zVm7w2!}8RU(f2V67G+7s)ALZ!7JhIa+MXv-)TV78(xWtm0_p^rtzChMtKgIZG`EOG zU+?Gr>Kz?m6Vcg<tz+V;L?;SL&1n6cC>82M;&|3vz!NVpQWD`R^HYJ(;OALS_PE#V z$;JLr5E^MtWiLdtT!W|E&Y6|SROm1aT3cNPJ6H(Te=@`{4sdyhEx3}dZ^c;_9x=8^ zPmkXH^0YUh&AM0sQUYG^6yAjhCb6lM4dNQ8^nF3Lq@M3XNj7U7;uO9TM}tW~?Y}d& z>7kPJk;s^7*%d;6Q4{eNHdBppC1ZH>X__vF@WTF3h&D{!$6PIl*h9jFD`f*)<^R3- zFAU6Qkb`Q|y?6)ReXo)k>|n=Zq+hC!KDeW0$yDs0$qxciTd%Ep;aH_qtH2d(lE0;J zuEN6BpTp_OgL}<Y{pIR{6t`1|o$3c(_G8YI9UkjkGIsV<2hc!-7IR5esF*b2Q_oK6 z{m0Lh32EG%F1!MIAsXM3qET}BHhYl3KcZQ8GuKc?3)2@CC(-|d7qVr*A0{<W(I*@g z_HL7*8B8*GLpn#}3Dfl3cej{TrdK^Xb^0p@(IdJS<ZbaUSocx^-GD7XNrfD9n-xHa zg>x7U;|DQ{AJ8#x2Ynf;7Qhs^fw@4BVhn>BQzuL5j$+vM5!1Ge`I*?lF&5F{5`soL zqE8;LQ83V6`iJNxdj~lPDdyYO!kE$t(udnmEi--`(cKug!g^eE#iL5Vs~Pwq<)F4& zjO1VhL%R&Wi0!?0E<pgNkdp^F#<O5vpV2SsS(O<XVHD8{)S@zB(unpinaR=meCfXo zX1CF!wmv4Ou#M-CZ5A>R75fCU->LlFVrD(E1OY?O&fHHg(?G9Nv&(GuyWq;BFLR?( zh*kwt2Fk!tr~7V71hPAktCATPf8I=3P2kR!%w;l<USQd!0btnNJZ6{Q+iy3tKjz1D zBnZ<HUi`|pAqRpEFz1v=dYB}GT&U%SZ3_j>etZZ-g3phh4~KSYv08yjOAzpU8OF)F z;7-d6H5+-uV=UDHk#+Q4xtA`h<0DYoSo=SQcG0;=5-MYpbj?3b!{v92g_!+hP14}m z>FhTM^u6^ju(v!mc8C!@W=~{zEz6jY4`f%@!N6IaG;8fYRLu~wn<t_>bCfya&jo5a zP!uW*{*{5B^6PLR{8umjQZiFGRPSAYAx**Qwz>*ssAUn|j~bn@(wwZo)`UO@4`LyV zd6xg|SI3%#-A-eW^F^DBH4#GZR^Xg*s<9#)ZD*zP^_ls8x2^}U_KQ^Kai0iU3E*IN zPW<E$<AZPz(eG%M7Ba!K$5g>EaW=W^IJOBb+@<Z3IblQ^-dx-cbFH*T)zgr6ef@$5 zuF>NviVW${x30&y;r@CNJsEF@X>fo%u1qN=PcN(DDD4~l?G7|=Ot~GwD6HHO?zcl~ z$2y<h=8otUrU7cj`gJegNS{KAVutzA`R}*orzJb+kh*E;g{#*y8Is!_epME2uas7R zHp-T3k%@?)YWrhbZBz@^qIMT{mVJF7s+Pn>Vy|7OIGl->PB|I$T9Wjm{NlbWcf{1^ zwyqlIHMWZ$c4d1T4qL$UtJgqFM@OFOqo-PZ05w<Qu9me*IS;{jowNL#(B5yhk*%f# zUmZUD=DyW_&g8?UT0WL54qbZJ=c|KQLEzyaN-(z}z02WhZ=I@6Nv()vT(MxxT^r9J zl6JCKiBen)i%BWFG&a6eOP<RArD}r<PJ9|uIq1D;3sl<1p>T9<M$3mjTPD*Ocne^9 z7IzZj2mLGhCV1P>z8g?DDuPQPqhF7Cr%QB@dr%n9RDl=zr;A+-SC&R?*VKcw`x~+O zCs1j|kirrw1ghr+F|CY4no7cKc2>9v=C1{wJg65@p{nj2wS$)3tT!&U(GuB4v>$v! z|Hv5YY+coC_^SGlMU2l17K(^|JLdD5if1msC}L#kMeS1YvK1X8y7fx0ShTzW{FFuj z{WBklhM^9}1TrW|quuOa{+R*6TsUI_B3L*nvKpK}it|*v8`Y2;v|{sPsUc~66R(Ne z$}(#drtCtO?BHgx9H<|~<pQET8$y{%zD&HnNIB3Iwh*j(hqa;aAgra;yX@R4b@=&V z2=&ISIqw}1Qq81m&uE!k-F;#^f6$VX7wGtn`9Px$xPyd=#kM$X!E+)S{?t5?G}?k@ zdwLuTeMpA|J$0!M=xWP~!m3i<KybrE(L@+w({m@{2>U%4`0rsHI*ei!5h1KI_!E!> zV6ah?0hqH_n=<&3VQbN=Tt@aZj*Tr0^oZ8}O#27*RqnIXf(5vqVWx)2OlA}V<i9w( zXsKi#9Z&cKfslbYsdyC-wU)+|X==Efkz`5A{;#J;w@UtoX&K7UVZQCJer5EzJDFeR z1i$*>_ev`#7W--Y`p?s>Q9?ae{m?5122&E_fRh_w%5fxiV`3+%KoS?;51~t@XQIb3 zUj>)Vuui00uNI8YCDIM%Flb(j)sZ;kW)Q&G<_SrTzPoTf@fw#v66fkZ^!kOjNe`oY z8b%MTO_o&bET%1E7_LbPMM~_6H4uC3t>^2FnvQ$#Ld}OUB6x77RB~YNMiXG~p;ZC2 zPP{iMfdQQh@Q9eV($ka6!N_oVJ#{yi_bdG|uDjC>mj#B>anWP)RxKdRC`k_4IX!hR zA1XJ}Mve$zw-xqJfq5SptM$_p5y)vLVZK%t#h!r-UNpMFWCC7>0im1Wr~tdGlPfW& zK6vOKL6o@yVWVDt|Cj1lP)w8S@PDh`DoSd>-}Ae{M;n+=aF1&Lbm<USAAC5*mCL|E z?0Yz3XmeD{YBiGIv=e9;m`ML!MSW96@?dTg(VowrZ_L+AcF?!}-h>RsuCg*i(4of1 zCAHzrd*d$U$IPGpO+^IQ)c_|_%Pj!`YCFHMkb{JOM?RH^TbbdP^D#ga+y*A)Xg><H zXFI!KVi4*idDQ})%44;FMdTa@FBu+YBEh$5>+{r$rV2eww>ZGK!yY(ca9Fj<2;2-O z6Xye~G6M@UIFF~65Cy)vWO{7VWGDxR3H}m0M1#+20TgIq+UfXzeuIob&*1OEGu@|A z^^bQO@B^mmg~u4{D>f0|A0I!9`aq8A9}1@|i6{hE2kPATc*T&LnQrr7<U=bl41`x1 z=MKg0her1z1S>3w6>Dh-J<1a!p-aaNFv$sJD{%6`7Xn$WR`ZidzoM{zG+Sf#2{u*o zms5`MjC+gdtUWRA1NtI}wj%oZA~3t*=}}*+moz=W3BLGscmfiC=L~r#4*cYu3?-%Q z8NJa=&J{#ixs$lGaOx&LG5Hbz=3k&dI0Qa64WW9(T2#T1*XtkTH~<7}$fxdOL-%Dn z=pKA2sNlr`HkS0CdcuvQ=~W2V;QJuiOq&;jT2VknrvhSJf2mx?Y>*sl#Hp+FgE8|G z6jHDp#ri5#UNDIV#mQZyF!_gHTCX9-)&_TJQJ69yT#nnc!17eBXxjj;vQ_Q-Bp%|Z zlih5uG-DF&k7Xg&ENMFnVBE5Zw70Qf>clQ$jpn=zHA<b=)>U=$osZ=jvGa!i{d!6; zO>Y_PI8zg$yU)*#=viOa6*IQiboXU*sCN<s^N}r}bx1}^`(yIF89ktbmOMKCdU~Wq z67VwIhn;zI#OeBA$_Z9Ac2&YVY=KG?kus?)!2P9UO8onX9(Q=UunTvQs_G7bKeRJV zK(qL-jlKKW9ro-CZ{xDfarv7$)?HbRWFCQ|{MonK@#~J;Uxk2@mCF+G;FLoje9g-| zzN>S{R+%b9n<1_7Xiei@2C~!(Q69lygDQd&L>{p1LUdNY%8KCm=TaO&*2lrMaB$NW z+x?KZc4<|SLbq7M1%!UCMpU{V*etIoo`Ql;lM4%fL-?ode`nVg!2Qa$*G-r}zeY!E zl4z|yD-_;nBMlS~%pUB(p8{f5wR0L;0#wy`#u*u7%O^Rd8!`JbYxAwMiRAyy$1Eq5 zZbLD~X<br_6>k=}&z_zQRxnH8aP^u5DMoqhYRkD0>On%#+$sg4(orkIbyy_+4q)V# zgr<&?YQ2QY0GDr^(o-=lHfS;Q7&JGAz<i1d5f_V?yP)c+^A=Gba7JWZkcH`zVW#J8 zu@&Z{chGqtlnHZ1pf0s4Ex;w9CJ^|4PFwYrz_Rr+GY+5d7Xw2{9qBL6^gmDD>g2_7 zBK!06fEH^-ZCq;w3A+wP1@cPvqS?4Xzr-*l>aUm5I@e05Fc0Db{0O<rj<eOt3+F)l z6AewHb-L>o(-qjHmFpp-y`1XilwAU$!BCCA-w27Xn!=%UEv}I2VYeQz2d_-og?Byy zjeBX4o_o94XuW>_y!nJ0>gLfwo~<c33vEu37WGr|tFBI<0+J#VBD=R-`YV(BBcitr z1A<Z$Ip|tDr#svGI0%3`*e}6yVDesnkdoAgep)q>Pxg5btJU@*_&WqU!Rw|Uzm!{! zFp^8a?0-9bKCzB0X32JI!DtaGLADc?zWpN$gg6f=lghcmfJi?^3lk$xa{J6AG!lmN zZ%45sn9wdd2+SIf8vJEMFJ3*HR1Q<62T(R-RV}VfDom7KdUaUg!g+!#jaY%MRv)|p zOi&(f3k;f}S7}|P-#{oucq~A^5)p+7<uF-^J&f89OO|0nphMp~AK+1hql(=v`<&)$ zAaUrguw|c94;PKcndR^Vn?)xo$$)V8W~qpj5k!3sI#M?R1u4cRqvBu2wEVxd&EkZx zLZakim)I4E6Y+5H-XVy4uPRmh8*qlovKh13?&~A^JorE`+sX=u?4N3njOdkz`tg}| zKf>xRF=0jRW<=1Hbx3G*^&upyo8h`5`ezKz5UU4z5r)Jx^NiVkIOr}BZ|;S-7s$Z! zli(O3pZL@9j2mhadc<DMuz|EY%e<pkL9D}JI>uhxX}~B<j%s@#&&~Og(G!FpiFcjQ zsE;-3FBK#s==U?OfQ}7^pYX!q-|&14zJqRs2D@75DWh;uaa)Zlm)fGtV@h<A!D<Y$ zj?o6pf{#g`X!o}Z>O3h&EnrGBbTD23I7GHckDuf6GzQc95uYhHSaNbuoEH9#t~(&q zP)u2zPl$wsXtEJqjlQJKhz{wQ^XE9*RL&g_8_J|o(tnmP0-k5!@MX~<S8*%{@X!zD zP`HRFcd44@DfBEm(lbar;~Y;>r*ef-RXA*kA7Ja}MxY?iiZv;=*t5$SCt8tNSUe-S z(Pu=|4~YZ1msK_5YtSNK%2M}Y@8{nJ9zO#Wxf(Vu)HW=kn_hee%E~+!0pf)`b&9V4 ziQ+M7d*SBBkhW7W2mL>Uu(d`X=B(vLO8wPJjZVbuP|)xJI#kMVGr56$sSJfd`t<p8 zh=tVYbx@&UrL7ro07qZoq7iUR)y3@AdwQG}xE<Jf=Gh;#ct`S)PC46+=&4WWgeV~? zJ9rWf@fTr90;AC@{Mzr$hY&pI>iPa5JqZ2p@u<e&z3Jak700b@UyVXI&k>>rE(uI+ z&+M0?&%KkogJL~<N&J*+oNAeQ`eYsY{XTXjP5i4D2D??%Cf8P~5H)~b3oY346nj(5 ziboMB14JkaE0q_JAqD=QV-E$;Ne%#E`{@1{O?v+n(w0&y*a8MiT)M$?68iz-te78- zjzDl43q>@uLa}XdNHe~>8r@iDrO%`Rx%NE+==mfpg>--Hl&@U(In&0ZS}zo$7LV@M zSLj{nMsBYVsjzBkaH!j%-}h!ing-!BJ0G2FCr1xvN0R^`*~ZGQ)eLzx(r?QUAGUQo zlh@=UnXiRePWdYZde23_mWW(1xIlk08UU_o<)(v73y}5TzlWhLj*ZUdb(oszV@WYU z${?+Y5skHV^s%KdfL@%!_FnmSr^o&Ph($8QBpBIg3z&H}2F-&c^H^wxAG}Hv>RDhp zRzh%{sg@khdK5p~k8MB|Y_>9}6uDwyuxMOo>&K#}{D=VzCN^=(m*{KAegiV0KPJ6~ z9}hRS>!H(dy{ub4INCs-y>v-W&-P_YbNu(1J_!&Hge-4FF9AHtp@CCF&<iwPDS@~3 z2XuRfig=HeM%34N5MX{13UoDe_i$WF*Lcs_nM546SigiQ+gJroN7@%_2t3e9gb%DV zfcVm8i1s0oq`NT|Tbd`7?VV<q<s&jIS*O~&#Ecz!@u`a0lJJI8j>5cvK*fGDMav9+ znNFX0TC~L3DZAaJc+-H<5&Z%)iuB-2)^YgMb5OMA;t~DmWAKSXs7DPmYjOZ6j}s8D zM_9bMGLdC;o_9r7iOl6|Nv|zr>Kd6!G7m5F2u{G;;w+DIN3EWLpQo2fai`oG9$wCm zb2WN5VThg{-?|tq=}f5!;ZyfaEA}U26cK&9JM~xvrD%^~tF-F5ODz_?0>D~QcLV7_ zJP@z$XyRMBe2bq=vBBpc?UmYCi^>kD*;mS=75d2G7%>YnF^ZL#uFP$IwCFAc>S@E3 zjKDAsax;V}PH7qp;w=$veX4J@^#^K1L@n7;W;k*PV?sQg_Uvbw)@=tf5fxJ?<4M_` z3?SYgo)vc8-a&~+sC)@>$x7#tqLcmGQ&FHkAS`N$LO<ey6Gm58E4uBf)gw*{ZDNam zXT272>*o|ebU2z7wjvt%lAaEHDAx(3YBkDgk_&*ZAWB;B+*QxzDuVv)Awaht!N^FV zU%K`oMiIj-ZfiL7?W%`q)jXMOWRh$nc;GB*8=oHM?(vJYah++~%Kak669G_Z%>){m z2X72pCG`96dO>#bc-VE(yVhh<hkl}oF^=!hTkI}53nUo&a=feh&hL@`*DFA7aQ=bv z36<hMF~U^PPNf>me1^kcr)K{0Ii(e7M!?=GZl?$C1^A;h=G7|D^$+cV+Ae?K)*~0w z56|W-0<hV1floT}cXOyvs<A+9fyx-D?xbQKmCNK}3<YvG3j7oQWm=fE;m*#r#16`I z#ncv#=mlq3ITgK>fk-~0>mE^9T55LpZC}LD2^_@H8o0#tJxoslPKE*B^oRF!2y(K( zWPE|)S)v!e#_4S_5hT_Hm?GkGSVjgkdR5CaJwBe7rEe`ey_hkA@46A}Ed7YOl&{#m zpM5(fiS?+i9lZ1S6JawhzQdV$;9y0oFgU(4645o_9qH;2y%ds;QmVrJwod0}LRB@} zF?Mj@ov)Y<lpZTR$608uwzQE}-dInXLZPE?PvW?e51l<n7T1xmQ~M_7FeM^T&kI6h zx9OaPj!QTjP$F^Qi@2VRf3eTv-g$LxoRjcRvd8|#k$G$zv<jWcH|QyE;EdGdkj*wx zv)_f?(Y>$nLn{3`r-pWt6Gm_nV`8%`VNCSPK@1SI8vwU)&B!^OI^H}CL`mpffVo{R z){Fefo2nJT)UU$)AiiVMm60k*+w<aFX2#9im+BkS;Q_jcZ&S8|8~iF5iK7JoGCl@A zxtWoKa5N@6iJ~}Ua0hAr$$EA(OLEp_FgVJX-AcJNE9xOEvu>S<sr0U1-G}TtvLudO z31`s~KlfK?^`WNqvV=7E%0DaIKo-c&5aHf9Lu7)Pb1YocUjI1oCKh!G|5l%FrrHWj z!;Ph}_qFmFe}eoR_NR`}yHEgl<$>V@rL77>_U3`JYFvsgj?yT%Q7WYnExhk00bQp` zYBrN|g!RJ8x<as%_h)KdyR=hr)2BafE_zMPWFfG(bJfNuRB8vgxB}Byqw~P4R5fNj z8k0fW?1i+uIJsNt#6PO-34qvxiNxG!Ybty$yhNxv`WWrMr>{MdIHziXwqluPq`5kL zv570t_Hs{XtJJZ2JUNhFv{Up}+wpC1OeP`oJZ}@{7SZ30LFO5X>!kuMgEYS+dnS=c z1LGF;5gvc9CZvBB!Viqjx2OEjY)_eQ4yQ1OEjX#I<F8)y*wt}?uY46$T=c}yv+;K} zZDlu6m4WKNW}+%Rb52HuR0en$cA@Nf8<sFaj^0{?(GW5KO{tb+rS2RL&y<=<$`7cn z+K7H~xmR>|eO4xxvI2;b%zx8{cF%`>>_arp=)?CYA8s0u*%l}Qi8mR_@nYrtsQ|pz z<4<Q`iOTGGiVJ7>;cGMyQ@31P$bLr=V#@D5G*7Hru2C-bEn2*+TVF_@JW~M|mY9_j zSBMhC=%7uN4CG*XaGdDO3&YC5q0<pSMDPFb9x-djNC&pc-;!u5oNkw=0Z{~*5%CoZ zRp^?Sj>Tc9a?(qeG#4R>=+N`Ixdkv46H#h(s5Cc#5SRGCUQqD>8@2nHtFp2wRYhD; z)$_2YS5%DX3RFY2N2H%V*;02@2Ye`WxC>1sN+3pc@$CQI+39DSQW;yq2Uthv@=K|& z+3c2~XMPm9wiI(&<@4c%Af%ZN5|15(7(yrlad;}~w|wMNW+|dKLP#~pUxePV8p@8q zR?n4n?SPxVLXl{zpZ$ux)Q?BB@VIpZ@FALAn23ss5}MHZ$LqPO8b_sHZxOyR%;Qz7 zvN&+nCqRNkoQ|NrKPW1Qm*r!E92fa;&YR;fEOuM0sxw;L#>&B(xy`S{TllYDK^Qkf z5gj3T^@A=&Pd>EMW1JBltrbm4EmXM!lu{D_vd%OYLgdRFd!u50&{U16@+pl<Js()9 zJ9s7(a~1gc!-sUuc;0(;TU7z$CHMr03)9(#mvkJ9;eGBstMVy70o@zr_KXWxyrl|M z8?Eom;8ikKN-v)KY_r6xbpDsRFfjS_ujCnJ?Xp@YT|A4Lwtz%5`$Z^YU^Vj)tfEs8 z4CuPW(k1jtEMy#%(({4UR*PfhJj90el4oPdf5XstTt>>ieFLRynHw#Ck^$vwMI*0( zBU>Q&jwtSb2ws65N21L3V)h9lTWzgx>ToyB?Tw*HXMo|$V^{@sJ{<rF-)l++E_}Rm z_wYanSl9v`;8o}q(O-(VF((6k3%`Nr?gV<?8CAUUVht?lQr#ivHVNE9s;-J$-%j1> z{&?s>%kwhT(uTxxiRdE4p|$u-aKE6W-qT}ttXIm2==qrYV6=d+W`-$;e_9ssR<JHL z9`Xk~c;=`rZ^`_+3i@rXIve$Y;qBV(#9d8;3&q|_^WU8~hS~q#F+jImcfJz`;Gdy> zj#N(M(7W`Z^xix7z;IKv))#ALVrlRIqUF5PBir1fNHvBXT(`}{`(|OcfW(BS+uEg= z9g0$q4q`IyzKP|eyB}wY3W`TMJl@rNYI@LQ8TkP+E5yq2>qed7ac?)8>@MRbJAK0T z%CsrcC6|mJ)464|?W;s9cSJJ(YCoaFMpUx@b(DOqJK!#ka()v0FnZQrfuZs$(%-H6 z%P9-W;yl82bCI_VWHhk%?R1<Z_r7Vw*mho`50;a)WHzty9Ds-pcodK(+NGeNUff>n zr)8(@L6u>i_#hY5jEWdaVmY)I1sUy5ww^jS;S=m#;vdPJiq0s`qLE?ryV2XBRlt?b zk+J%ux(p}ykLbg1pSf<I_S`WifP24jE~tm2+;pTZkS^Jw^X)r{j<b-@o-vF3Ep%48 zPFR^4&SxROSjdmzAGpqr%k$yde4IFUl+vJEEqfneY0uxrJhlFDTj7_El~^#9E&*XH z))SJgM)Od+!EH%>9En-;ILA3A#k6KoGH=T!AY>J3!YP|(AkY(`6oQau`II=b7(V|V zI|}k7cNXMWrCc5;9J63C>J`VFpJM1bK~yHR+^y&-%O`yvj9W~XQ5YlsJZ8Z%T<ifD zha<f|eMMS~@$X>qmQKx8wwDS;+VbE$%H^tsGWsyZ|Ih(w(dBk<I__P>f+pN+;h<8o zuN-WIgM9&+HUm>zT>{oL=gl0l4CEQhmREPlKSSO43p_Jal@haCmFUNpcnOQT4DX`7 z;=lLXEO_~Oz%XHcF=>MKItg4K#AP7O)8X}y_|h~&a#^@mcvl>(1D;F;N2>AbE{t(< z&6PP63#X14BNR4oW*`+wP8pnh9SfPjO&GpP)hKmk(~XuQ`V*!!^LH;-lO{5DSoZEi znme**GZfVs4FB>*zN&>QRN&PIVeb-~`<3b+JgKAztNNdi`*D}Lt!J1lJ;3^W*cF?l z^FRXQj=}*RhNxUkT8l`&$o1eBB?~(zFjK@`slOrip*}zToKpCk_rWc&K@)+)MDTaC z6ctI7|B^mpijJ_Uyo*WHgT9+R-BcDv!;{XfXJe<%iyou(S<);}$XcHm@id2>=}z%t zWq`VRWzq}O*1g+39;zyI6dWDZ&OLMBDKR@M1#x=@{=0S*$;GO&hzBj-t*%r)h&ilH z#Xp)Jzph5SO*e8^zp3f=;TG-P(p!Su?A{!H0?wPmgkNF>51E4W7K;@d!#pGI7gKDX zt+=EHa13{HMs(T>3|p9Mo~1s-Ox>$^zUlKGztXLTGp$ir5YVkPqeze|GDxaI7B`xA zTS4jJ-_ORBno7RVpRd*F1vkuP;bzWo;8y6rY?amhvN)S-v%I?KX(-lmr6q^1+9oLw z<_sLb3O9M^)D8-#sYWX=#bj)y+pF6Ks1Ny6Dy-}{;>}7KZ-#0>L8X4IJit1{YK%ma z3y=3-y9KYTZ+|DWPu+Vnd4)v9Q-D$X&rKj#nTiA4dBF+0bhDwb8_}r?vFVWkt5LDZ z(A|VN+>3&`I?ENMVr3j{we>QSHl=Wf%wzZxr4*W|dT@ZN80o@w=@L?)<8@dJF*p(Z zJ;qxJ`j{)0YZ_N$N(;W8B^WGWbyKOZwuSJtbH?o3%+}R&9AgY$V#cvjVF0JmJaEf~ ze>Ljn=7-F|&;Wc0)?<Mi=n~@3&BcM%FEkaA6DCHB=5{iUjtRy)-qP8ZX};a77}~>- z{Z6%Ti@VbNH02x9kHNN{ycfOx@-r<_Vu+7Mwnk+BSg6M1Kk9v+c$uPg)e^6aOKiz+ zrn9@i(UD-)Y%;s^s;NG3{nftOq=s6!HHwS3&@{xK4l<Cjsr08M?<b;{epxk_?M%!t zqLVHGFMuKc99n5;^10!Tk#??W1xzOxF_0PD7hqwnSBaS~ev0MvX__O`39f^R8)tac zP9coAIml1Yi)hGTE)iQ{i8W3BDc=D+%K3eAaIFpx9IRwF)rn_TD$ZT(*WnSeVGEtX z<KaSh46=TLEstQ-TB$|_?CeBaOgNJA+Sl!Vnh%KqAxCty3-7#d9;VFIhUgzoHMQ%V z5WO@jv4h?Knq;ylNk^jUR>O?sdM?j0;SqhHIV+Q)b*>za6|0VxcesQ5`A~CU9j=z7 zlI^xTE)jlMPK=4<dohE%G*Cj<4w%FdZTvZujJRr<tJHZ`bTUB7&>>NWlab(&;gs8N z?;|7-j6VlBcdo!{vZ;^5UR?K8_$Q3+<j}k6^AB2O`por^IsvGRD3~=t@gjQM5nAzr zvCDpLk=&W0dLO?OeCfFJf&S@Rb7+;BXhhHW4s@YJp;IId<bkBP(5Yd~NiOtJcr@xW z5c8Kx=|!a{{B|~R6)x7wsZr?|Ej7ZSu9i!nmv<(<+7FGwN{GMzzeyo0L%r2J=I?+o z28)hhE*T)JZa3~0kTmqfe7R9fzG51+7!^80y7v{#^D2qJ3Qv@zB}S}Y$*%QHqQmXq zPu`1GZRmY@ZuN>SD`-gpONCx=k@2t5@6eopHYZew^#;vM7WCots{{Ky(Yja_)@5{U z38}=GbG_YHuuh_84J?KVnXfR^rVfmaUiHTs;gWT2re18>S=kWt!Ooc*^Xl0pV-NFR zy_N<}zq(VEayznBZ+n58$^niOm_?+PIUwl))kb`b92sweJ*u^A<#&8BZuL4MD4xXG zGMfX29OShb0brMcZ~96+2GmIMAg5~~*z*T(T6lA*<yRd6SDsO3QlpQi!;Lqa(c|zQ ztap*b+bt9*Wu2X@(>yv$%U>n@{6moKwtQ)b!M_N-9_K(vb*wUmW?odtMloKejN__j z=g#mW-umfzw4qoBhXkf2hwcY8O(de{9KWZV9@EXoXH+f`FTg&zX}rnDP3~p;P;vY| zbez(v-~%b+a`88P0`+b9m=WMWYevWEhgs7&?ep4MNnk{4ADzSc#$YDg4Y?qZmcZSf z0z*G-)u1P|<4arg6<H-e#?OMj^mR7$5;@Q<fKOc+UwYVdkATO9UW1$#>r2?aDZ4Su zNzA%Q$GOA!il^s*{KO?8{+Wu!c;ry?z~PM5a}ocJRcYvEOXH#k4x6K@+33K@^^epB zhp^=?1R)x3tb=%P6Nfzo;AvUDXfI?TvOz>MLPvyVrz+0ERzS!J^Z}oRo7ObwUA<2; z>&CwTBuyF_z}nT8H5+6y@YD=wDMj>&U!vn|WQ?9-m>NM(C?nqfXL%~h?&rC8O&x19 zr>pPW3sAnf*IeSx+vAIq5>3)GRLfm5PJ~H8SUSUz<n{yS#TI?h4mzxji2`c<T1bV+ zsu;hhVrC>pheA&hu5lul#|*nVlpCkWjmz3~+pqPKe%8WBn5~&cx5H2TCAcnb+;k51 zdcf?EGmU67h&5T!PE6!?fFgsTn?S|~rG)XxtP%dyR3;Syo-~f4|B^@NM8V3?wydJ^ z=n=Iw)CCF227$n|hCIo=Y=~!I&hUH?Y|+2m%{`|1u`v#+wc}%mWbw~c0$^9iPH%hs zY22tT#hBaxPY3}?k@;CjEJ1I?7MHi!1Pf2ZX($NSa4>xw65Wc?z{y-qP?|?jt_ca? z&_&;KWZc~DTOJv}gz{Q_OJ%qS^ke|jG=NNq0CeBYL~u*E<|3Gy-qvg-Qbhx84Lg=w zS5s;&U=ZFWylGTZCU1K6ui`1`?dxu_nB_b(V{EY<J`eRZU6|$2;QxZ_KJqWKgl=p4 z1Rg?)F84moy!@wDA2(r<cZ#2z|3s%@e=+>rH`Iv<#sacwgE<y9#Bn#GrVdCF#|EJz z?^=4LL0@3%P%AgH5|`qHC@z{Bg+lLp3X1&W7%s!2pp4(aSrl<ZN9eK#WG0P_P^Al@ zvkqGCXt9hB8=IsWgfJ}GSTCK5zDsr1@F>;m<>H#rLMe{}e%3`SUoFTG2xHKL1ByuR zn9wBEh0ZCD*#sU2o^+T~kMq&Z*{M5LQ&O_L`z>feD~;BQRmcYv0UGf@pr)Z&r%yNQ zi=T0bdXnPO=u6L-1G|Z}oxpIL30k*hPd+Z3y8u$~3;i-`>x%dAh4UaT*;*zns^RhS zn5tg>n+M{cgL7X$qgMBz8i=+E%;E^Pco>FyEqoCe@4JGE3y#a%aa`<4Y2#t3*daFT zUH~9OBgsmQNN!2w6VgCSzB-8D1D=+LdI6_Rc@kV)?yWd>lOu=;hw0=qok;k|9rTX( z+U5(l_d@6ifoTye0<%4$S3zqshV+6q#JE52*)=gbS=(~I_d3d;4jh&4gcwHL%_cly zc)d`#`PuvayV_lj{;>x1`RY6+<JU%bT5irpKp91vB*dI`)BP8xQ;6)fYgQV|tnxqY zFr(Y3qxme}*^=V`Ugt-1N{hVNRdi~JBKkf$h=s?1=$Fp2LX^_(q%X_Sp>%*J7bjlu zLLHKu47(TRJpDrit67T?(YrC~L^>R@?;(@7gERK{Q<}ZqEHJJBxo(&AeK6|sOBhbh z(k?8mxBSSXBf1mSkZtSM_HH?0)2216X$j`D$W1v8k%1V^<$F8L0y)V57x)Z#8ZHO$ z-+D`7W@}H+iTSFoW2|_QauM1wfXJte9p_OYqIkP)p7a|`a+125>j=aJsA`bDoGgtp z?witbWgh3mGO^D6m6O?Yc1R-{3W##LY3}B3&n{QXpig96j}7HTDU&~=7pAjkXG6t_ zv*^sIK-YT;Ns~N{U<(Y0Wg1A(SCUvM<yY4sT#fgo$zb&s%G#<O^)xhX_|#j@ctCYc zk3CKhI-lLUY3?ANU-QE{ZTPgfItMcoTy$!;q?X|wBl^atAq$E#kB+KhPQ<?z88jV= zfL{HN^9YgWsD^}8n!X9Mp-^E4(M|Nhnz|Z^#^O9e+EPTZT1}jJsoH^FJZgnnc)z*M zDvHvcsdIPr<{xKZA!w1yBVAg-e`z%21I=U^H9%+0<OL&2IgdFr33l*C%*0X(cSkOc ze<S&rmz`nOkqs>@KL*m*Kmd(dVAg3{(UMkr?=23FKybkB2Puas!y}`8WOM^ML#t5q z4~)c})_3W>q3Z6*L!BAGYs2lBqZZNin)1NXCAm$g&zNdzD;I?itmV*0%-_KrnlZc= zNdT^v-|0C8lv;5<fBhyqBtsV8WN2GNV>zP9`;mg@hrvo`>H;^OgMTzssSMLYXBrU& zoHKNyE2m5kKGQ$&^0{u1p6CWRcB#P%nsiq>t|g9DT-u;o)p+fv*dOPj1on&E?`hHQ zaj^RVT@L^jCX$#cW&*PSrA`MC#)4Ua(-2qC;uyht;hLICo7xK9a>mKCU>uy<j}`32 zbr#`lDM05grTZ-0pYQY~mX^b*EOGaS7f+@4D4R&S3+z}Sv99|FrzPW}faa`k>|#Br zZUwfvqCXes>ydi7@fo0;(Y}uKaHDUz3<~`QW=vT%QYZg77IrbBBM<1XmBOT`Xl-ql zwVSgw1^A?O0ov=2pbvioz#W_kXb?b425mxU(p4#JCauN{jaXmwAM-F%RmXJn4ki9R zB2yDfm=ajr4oJG5oETzzVLbg5h_FIfL{KUfpoNywzS$CWM&T!K@(FEO!KD!0GNlwV zo?+I9v4~>kXMsoe?Jp*3G~#KSs~PFYB@w`&83O%nLe^kQts<jz*enP@_PPb%zz#{x zhW5U3ZwU4QXONi->NC+WV54GTm#iDDYlva>(R&JJf%0O#q?usJoDGQ#gBqd;(HPh) z|J3&Z2gzM*c!mdk(lFcgxay!3W7ZXK1uTUTDNR-f+{9l%)JO5lWy|L4xk9B*SE3q_ z;=(vq&Ia7!wYs<n5kl5D0o+#4s|(=U$K&R|dhyrjdVuf|y$8{p5%e=*m+oPNI)H?9 z-~|leO)9>Vk=FFFlYsiwq`EMG8V%~UqFb{Bb6>PH+M)k|`YXWa{vq}4tpZW>>a+GS z==JYsm7_6G9%$$*0fs{6uxq*j<;O%90}~pYHH$sNTBy-5LteXttmpUUD{)r%!E<D6 z28B%JuspcVk8p#BLO;tSgoa)Cv+&$&Yj#uy=^ztsrkL?#RKFk}T1HQ;$cG*a#X2iZ zM+e@Fo(JiL<uD+RIuhLg0W|EBS_QgZ>f+g+qNA#Tyg`}`-nK#$%&WzdVPB2z3F~Ph zTZWYw?djQoVoPb&5RkxAdW-ogG$*R=>*DYe=%Ld+VLHE{>U{#zKcNIHJz@tP^gqr4 z<BiQH8V4I9FH&<V7FIR}Fn#GpwC7f8rR}-eSbk!ZjzO`JQyhwZYh?46VXOyo-K2Y( zGQxxz9xUUu1Ts$1tl3=g>YpgkPp?auUj4Mg!1S(%7Gxcgxg)csjR(ai&J+qL^bQv% zF=|ICh02CWWFb>t)rj8mF~zSHL)FTn_$3mZZC-*{%SK{B57a!O(vMC5Wq9<T{-`&! z!Wnkn4*M&3A%?t!`3{C5h`#eqhs4haQE;EPCe3@ehb5v9{zf@an9rP&*p_F<XH^?1 zGd}TW?*mtW`=(fk9sTV6ATkAwcQ~xi+Me$WG%}_OqiS!sX}f|4Ogf5gJEkFE>oP91 zTK>0&{}X4YRZdScwb7F>bHXOpN+Y;iZD+kS8-onu_zz)8c2=gpKr*AAcQLO4Zlp3v z4`XVyHkhC+-u5Khi6Wg9{=?AG(>0h;2g(JovK&SxUG#0k^yI0>bj2_2L~`W_WbgLp z#w(=)L>|#=Q7sJ))pMPYSzG2Ya-qRPVjq0#j0NGLv<F~#^*A8g26O|s_LK#x@$OSS zFQ=@+F6LOOib=E0E+y#Jv)>TMy4e@6A09W$Dg|)tN!8RQblcR1nVIWLn!7gEyyIs7 zmRn#3*4CuaUMg#EFL~GW#SlTg3pVO~x2Z5jpdx7kqhlH&X+qQQDYb6Zh0vvl1v{}j zP8taS&Xj89Y2~5S)@HIS9CB(S3pz=UpX-Ot`k@GTZ!=Jqv#eLx8ZURzzBuIfyhity zO<zuOt3-4*V$4%ZV<x&yadAPDwYkzco;a--437v}(@}}{W8)n_+VAN(p^9|Y$+?q0 zjQ{78M)5W@IkI0FVSAr?2FjSEzB6=z=1SW7()PY6<DP3=h3G+e$zcNeno*PELz7sb zO{mNv_E)-I{M&?RQ(7%V-J*UMKK^U<;J|L@#_c!A&)i}K{50nw0KxnM3eP3__@^Dc zNh68d>ZJIwtg?lv!an<FCREpjG}$-Fk$A>ZclwRp9<CM9UEa*H9FU!E9ZMR%AkBPA z7&xvE{OxrT9RLxlk;-_HkssL|+WsJ@hLNp|<~ZnKC7#iZ_=kaLvx5(IjO@v~8dUJ{ z-Tt~+Gz9BS-@6r3`6{6Y)%dxXu*+ws^_6uTU(7%nWaEVF1<Z&rB6`j3kZ{&B62|jY zdUSX`W@wIe?Erk>4Yo?_I!xwGWFly=s&VN8ag9+4cxkGiG;x$*=-@dtBH1l1IWHbj z-w~YP-K8Zn<!JMFL|;5ThP)iZZ+kPKr1McUx-fdmhpBZMan|Q&191cLB$LMIHN%Ei zr@-axUDWYr-=&nZB0BjssMuF>eWm(HzBas^Cw!mxJ?wvM{9L6*6Oew_-9t_^%^S*e z)<6R7f;~a>pQNjMLGiO}#SXUiocUVw21US9p^>-NFEfyoXFdhEHv@6a_%ROM2LMNk zvIZ^xfkQ70rn}%rrJ5>oqe%8KH|mOB3yy-6{Z7<N(2Y}N#kIJ?A4kLn1n<)M@iPbw zC4Bq!x<LkJox`r&2;2$1=Hs|!K%$>RS#<LRS0XmU>WeZLz4#XB#aDR9LGsF!3E;wv zXzewpU|)WR(OHqcZu$yD6`0|n9NF$sEC~2VDgfkng;6XxXArYW#i`g(Jc;EgkHC@D zD<c>sETw*FtYSrwKOe2?4R&ILW{EYHp#-V|WR;7=93MwwY>iPH%goT^__qp^*OyS_ zs!lS)qOI4fP=~>s{P;*-!ZiGyzIS?Z%(7xST0aDoAn!0(=8}v47sLUOIBKt<Z^OT1 zuO(y`WR%$;O6)MlCv7dHUU;9<=cnNhV|HtPRFBJP^I_W0Z0kZ=J<+i8*B4M42D~aW z&$3GSiG+3?vUkYxfkAG?$mH@ENjKbNdj46KV3%NBb~IYppA(@C`FRVW8;l+~H0>ts z@-*r>|9k^ixeLYZg2U=(r{QG4*HCcp)olbC-qtTkK4rQbo{q~;s3<hgcLZBA#zB9` z3J$*H9_>y{1Y%pNli-XMtK&s^(eb!m`$Ee|jyD0sgF|_L*ah!wP-^Tb0i|dk*bOdM zWEhQ(%;eNJ8XHaXZch48658n_NzQqnQN!l&qDCM2s7*(g?4YOrNroq>JjlyP^p??? zknyL|6T>~^Ns(0Vy)h9}Z5&pN<>nI=1gE?~x6WHc-#J{yn(626ahddiP{C36`ir*T zCuMJmLp6&gNeL4>W?01OKF^3ghM|3cCn3LPwu@{O4h7qrmTr;OGj9c~hph%)I!6?^ z<4Hv*l53DyU%m*YM?D!kcbo|+sRt9$D9;j3PI_tKg8g5E^#ju`j3Y*`6Ud%=Et`Jj z6kTKQq!VB~3>2$endD6@*-^Elo{ax<6CZSvZ(IS&s=Mcg?A}EcIYXwqL`X-w=Z2s! z93kfJ%`uhDG5xtA#zF~Yg&mDBQh?yI9%=6ooYJaNwZBn<G_mydM^pw!D%9ZFURvcB znx<U#sR_L=2gLvsqXLfejtBN|a6FsJY-4E8%qIeO7CmTcI%n(v@mk)Iy>%2js|+0h zBsg>X9(I^Fm!EYglL+Md>d@}tD#%RDB9NO1f_64x$iAS=LcuNH1s4aw6WEIYYrw@s zftNnfo@90#SEN_U^rdCL17R41uQelBq1cSa?p>Y_cm|v;#aiuFs7iMo#}p(?y)E82 zn`bv71EZgJs{RE|337}C_sS2y1R&w$u}uLmp{eLk)PKpEC5<G^C5M?D*Qq#?btWb7 z1j<nlm=e>;$RC5x(;HmPMm07-UAm#9?OdrawURS^r>G1@bo#Q{TvL(N!af`3S~eYP z^^m4MJMwp@L%I_b)j<Uyb68C;MN6Uv$u)8PxsRJmR%C|G+sEdEN9~}8FF-{o#w(hk z>MKmQ(d`gClJ4Ms(4Hf@{f|B&QbqizO1MHaveFKzz;eCyKftGiL{3jn+^*u}1F(zS zIVTw^7W8h=mK<5GU4b7%hd;@u^#n?aJEPne(L0|?gg!73z>9gop=9kd?0B=^wRAdR z8*h$xHY@ccwMC}RBL)xsWj|0HGxbp!nZJN-M!N$$=dIVwAu;S@Ipu<A(~{W$AVKDJ z`f8kQ%I6jImjNEcnyXIme~kr{(X#wb$xj0j!Q-H0?WNKQxOy8-US&em{j!O=Y$JV= z6Y$?mUan>i>8!hLUM@PJ6OS#Mm&+aes$KC3mU^o<iUqs_Tfe<Bmj^4U15ej1(jZ4; zlpg?naAJ-MwdkOv{1zy{5#9eyulF!y)jXh58#jbCp%*KU$Fx4dQc{n)TQNdJS3yCF zaWjN`Dn86OwZToFeU$NR^&?6|N3f(|1XRE<%y=t?b|0iVOPqORm;+L)K$Beb=LY*B z-6MU>#i3kYdXT*3Sp;QJu5P`j&0EX36k!2|Z({Y`d%z72Vi?b8y+;4_kGj24zgVGv z+lu*NwW3-f)0wPnxH)$FX7fp4LQc8Zb(wOt9Ng%VMdA>NYu3H#YatkDQ<`g`<!J^m z7*R<BxK4X~RYYGx3!d7uOPB7T=gptXdrAXwN=q(VMJ};wUBgTrUyc>y^*UkemQ7o? z<W{ZNv}Nn&H9bAK9IlZyj}vGG^9#TDI^VOZ-5&}tSp1AFjq`n8?C^!JLvCIMf<v8^ zezHGWFp+o;lq(b1VK{eXx^mWhC0f^5Mo&CrK0%yi^XMQ$;1Xb62WkE?rZ(n^1#su} za<xu_B+PEMx10U0?Qdav8!X@};L~`SsRB}|;P6$%SKQsGcY(KdL94e@=oHZZzY+*O zE_ReA-lC_fSTvuBrySlIxjzF592<{7p;vuS5nENGB$75I(*bS<TDGm+jN{UIj{sH< zQCVNVHx7;-)n&C<0tQ2#74PC0MRF3PmC5c~ew{oG-KL8DWUK4yvu&RucE2zOIkd2k zEpR9@Em_wt%(-ZJIO%iAWCnU3MwKQzR8K8dE5!mgmu6Z~`q6>h5i3OtI`d6)<0Wqj z+tcNrhmK*RHnc009_dw^EH&vRJLp=>eBxd&%)WxB%yD}?J-;&z$-bpadV01mTbkp) zSx|E6l87!lkogc}lQ~db*-n*}G_^h;E#hZoCU-TaEC!D*W|b;X-3@e*lP!eSY7B1! z_XH#ons_GP_$Y3<PMZ#PV-VH?s9Hh{{;imrwH2e28}efj{TOn$y#8^6UK4jQfMHV= zGy(Icm;r*>zGLpj*|cKw%TLU$+qiB^ZpG%!D_%u=8+F~LHdM!#5v{4KHke%ZsImHb zTX8|+AU55bVq&zTo~5>1C;Q9Gyu<<pqgIAO{^$1y)ud9nvQjD2u}ApNO5Sd71#Qo0 z4dec>;#$^L2W#@RDiv5vr$Y)9Zj5;hfV!$Vu?$niQnKRX9|28ijIts;X3n*AOK-Lg zEEPp1GNKt$2|0c5c{o=RgVU`@f~0vu^-P3Krt$E4cLG>kieW3kjU4->Pzr>ukHig5 zok0`PlEeKyky=dIB%VhXF_z76DyvIXY_yTLX(A5wgP7FUz#I>xE%e|cK3J8wZv9}m zm7+^G6qB!Cb-{cSlrP&s=edIhu;L=||3A<HbHfjnmf6#gp`5FUV=jas$V-zHUgNwj zzYr;!$z77LYzTm8DO_dhL>=7$0}FvG>$Lr@H5W0W!9Xanx!Yo;df)25Ok@3}4hcUy z@7{Va{6ukdus)P)EbFSO6ZqC`j>toh%)__`M;j_2fx`7m@0bT@kvZ;+836sAbr9sx z1tg=hZ`DnoC!y~N0Nn>qWTLbQRS|SIWGI+Y+1LWD4HnYZ&dWK>$=^qGd}56Kt{KzN zCr`DgyMEk`3Wj4)vBy?V<f{W+vMyP;PDJ})gR>|^^1Hie*kEHT7lkAuoNwf>+syeJ zCTU>)QZg#jMx3Refp!(K(U2k+x2s{+0x<5suZs5($pHjyZwg*^_>tw}w_K!9TG4Q) zr`!{FZYXY78>kR1!zn<8M-Bpb&EuH-N~gXJb6oTFejMOYU<-N>40Eo^SQ3Psd9*f~ zJM+>j6OUbUwyr7b&|^kp`Rt|R$n7@WKWfwL%-mWBnmp8XWEdlCy?bLwXLYRFpdvQs z{0nDIjekoU2j`dY7IMX$sU|QU`fM9|_gy-G#=U24u2=loH21(P(8}k|AyIA10gLIU z*FmqS#<f#3E}16{&3m#%)l*B8s+k$g(8{z`j1Lb*<<26HmBs+7tUy+|3IAe=wT!hK z*w;U|Y5V3*4~n~SJcPYV3m%~>T3><wOZ!!HIAbWU1x?z*y4Ev8Hdu0qh)}#Sp%0ya zUPhT`S169vhq`qubZIIYRqjn;w9}pU(d6!Mo{#*tqcp`5{sUlJRwgjg7@08twHDeZ zA37M7YZ!6r)nk=gpMKo|%A>0p%94g0?%&n3tfgCug|keYYm~4kn(eo<HTCtH`K~uX z0)K5raBucPj9o>#2kOM~si%?IM%3=x#3g7BkB~OB;pCx~Y86wf)U+nl##bkfj6U-j zxjJ19^|KN7Uzk6po`j$zaUvL2G@~~|pU71gqPISI4y}Y3S*cjvmPbG!ya4*<F%a~V zs_F!ONXu_=wj&IcRqUIn4=n5H*@izO+Ga$!RVR3YJB=}%OP9oS>aYNJ12a>Q2cm&c z7E2?$V<U(`I9q~TAIollhY(TmWZlauuWXfrC0S+>J%B3120T<c7XvVoagSO{AQvfi z1fN0`Ba55kKnjpC3ZBLK3j90EMo0AW>Kr<yQ3A6B#nETM3`%2Q=x7+qSbn_3v!MW; zVG<=54UUEMM7e`<#_CBa$Tiz@>PAD3C}Yb-bVs7L#sISU5G;*b2}o4aE_^mhI^1l~ zsE;);@FG7}Z&ZtPA$mgCg7a1aXrVI^rHir3%&*T<<S^gdIv4(HRU9#Qm=IctXx$EN z0vGb~3!8w!R#1KP{%h7#z%NS~t%#llsYM`k#j=?<FQ36Pv+&e1wt2I!NxU=VNOt_O z(;gQox%Sqpo_q#IwhJ5~N-G*CG7(qsEfAx<dfHkj5&ixq)WJr^xQ`>ETTw-TdT1FC zsKp=CYA@D4VfCeg#7+dLXg`j)zd#Wky~ixA8LS-&PFJ(4DSa~3*48>PvP?y7iW2T8 zqOaaRiwq7xcd043NS5GnurZ*R5mPZZl#y|%3-<QSss2o5%2BW0d7{kaw>K#~YX4#_ zx+zTaL|=W7oN%0f%lT*eVbP~b^QpnJ*t-k@ec|N!YQoeY3^{AyR^jZ?&MvL!v>XtT z(3%pC(n-_R&!<%ajp#+V2F3_f&lAlvyUY&SOq@2pNbiJ(4y7VQCcD*O!8EWK-ignE z`Y$uJkd9Xb*oq&K4MfBst%tgKW9-;U4Z6M;*OU+ddlb4C?f9xt;I3G(u*(5;3G|s$ z(`VCtuM3KFVYTfYG2jxsE}J{;!UbmxOnxQ8Qm!sbcL3f0WK0-jJJ&uFV+M3{BKi+B z6Du)0y3&bkhl})U{Dw~#l~$%~SJJ}8+92~WPYe-_xyc)`J!=!CQ%?nNc=Yjep=4Yv zj?qeNInDI-txYyi056C0E@N;Y+4HEI?s(xRqWxkXlEpZn+wm^^TW=xnb-w@3!V<#o zZueVw%tuiO!pgsKgDGd^0gL(81$z?8<Xm88(I~m$_y84(19?Q=ij8f5pZXX>iPN4D z3G?Q6@^aU}GJ}~YLDU>I<|ZCFBgUmW4xJ+?#Tax*4>y7jD#}%{W-RW|W+P?CX^?&r zHfG4ED@jhHb5g8!sO~3fuI(pC%|8qjRJ!-FIaJUB+;qXd2;iBVu9vw5-9ZEhGxCKk z6@8WtTfp-G`(x^AqW*{M3p<K^bg2){u3JD)5MrVwXQ<P+Q2Qj=G0+4_$ONbgkxE)v zpwF6d8(CzYb+y{ur@@vT6LUrWHVnwFHM2UMplimVJd22Uap57I+w_*~I<qg*p>z14 z+G`7;HLByvkl&9#5p$uhpDpE<qkvMJem)v~fT|Yg8VCY%Ng8b#=YUiQ8wz67vTp4v z`pEEJBtzbk7C<ooI_x9A?ZqkQ<dr{?$J}9N0D0-Fl<k5gA7(_a+cA&SOK3YRv&lv* zy^do@&6s1{3rmE$V^(N1&4BY{BpGqLi!+4nWhWV&9>*_s7Px2r#@@IykA4eWICT#m zsGtw2`l&jGOSmen#<8V+jVx`m&xqj)IHI*>|53^N12jebC|W0K_|(fDoJE`it}fR4 z>B&|9EA&T&PJ>{VE4QE*aRZ=Jxt8FWGJr$-h*0L9x^tm3e8`JO{78Xm`zTOrjk?t0 z16904<#GG~6ceqVH$fJ46jl^Wq`>EV?tZrcR4<qcKmI>^UjiprRjglRB_Jw@iYOXD zA_xkZgb+fwnuG)*WHA#!MQnOzdS;rL>F)G0$$$|MmnZIufCz{P?kH|geTpb9D1x~0 zR8UZ!3i20lf8qlFud2>D_uQ?QnI3{Z-|xv}db)4ldzLy?Uw!qJt3aV)v|BaGaM4}c z4t)6(X#Ys%Rpijp?ZR{C$%vu#E{+#~de)IiFx>#|WXx4SyBq!HY^&)7ubQy$oq&Tj z#^F2`(?Z-R_orZMD?CuWP^9|BI0H*CJ*keIe9o+Fci34`jsBr(xlzH(TN>qhirQ2_ z7ovxyzfT#>0-ys_OW>S7(9eLhMDRvSK9MhN<sD(IqxNUWMwT%9kDbk$9wYSOM27&g z7CcITd<B~pleyHM0h#N4ZHh}vdnJgDcFlP`eUMdWjrZfq4DN>EMtHWzIAEB(UzTPQ z46<t1{Q?AXZ166fS$M$k9_%--$9C${^_dS5eu1vAj7XuIl(h$-QsvqrIe*M0WlNw+ zfG3UQeOptIu?pz2vqA5ZvsN%ubbh02#%5`$0(6_`;1A7V5F<2P?Q#tQy6qtm21PR} zXZ5_rX{xYp3@cU*n9|Wk3Fs*R<eSyQtp!*gW^h<Jshy;b&wI;?pfr+#)WAemRdlDu z*#FiRY`X=Mxi(gETcg`nkY-Qb*2xSe_GOnAcK#skbNAYK5boA$A7xs`9Eauy(P*TM z6cX~D>dLgYiF#1vR#Zgl9Y4mN1VT_7Mg(wxY1PLPp^J>4(K?5YGRO4#lt2Ag)l``% z@-7I1o{6j_Jd6fc;KQM&AAx{udXyb#4ujUtUoxajoU*IrxJ41)0msiK)`$aVUQRB$ z`AUw_ful(IHeC(zYj$~Td97gyE=40VWIUOx?ZhqHTHfI)YaYk^uw=@;#?!h=;0{<+ zvaf-vElBRd?nWG@$+MGVf&8Q|1m6qrZhJf2_(|d>#d}Ivp4f&r%%;Inl*Z(WgOctX zEkHh30;#lM28mKGLZX+(5JdK*vGSPo=}xhYMPY(mdOYU2W{RdE>qZBjhnAG6Y0Sx4 zK&RU>YRMYV<Byn0Te)Sj{0hEkRRA}pV6VI(>X@~)4x;&WGkg)JQin-uvj3TS1{}2< zZ5_)EV3myu4PG}FE+n!E*SMorMyFZ26rS#TXF+XQa%Sup&|&}2g&3YQl<o1+F1Bgh z)^c^ATU&+B{&Ga5VT!%&>ADxiLsA(UFAm`(TBHhqW}|p{O=&|3Y|Ou)d!sB@m?0I* zwg$3K8tXxsv%D31h5L-hF*mk*2hBh}3{@c5wz(c=HYuLy@=C@d(j^%^XQ!lV;y3Z$ zj16`2FycIehsM1f_~~%>;jH_2(J`DX!^+;D6=5~!1HXhK$A9bc!9lWtWjl&$0sZxE zu!EV1k{@IbH+^<c4vs3<!noS&7#LJ@eouVPTYL=Mi+{u`UgC~{XCycoD}?Qg7$l&h zzD0yMHU~8z9OVNOCBx7WNeYzU%|F<@VA0WD9Fho<(~s}#4wyy!^&HE50ErPLJFS9h z9UWqYEo%it)vSP_BO|sD{sn&wYqT=Hcm@7t)@U=*NU<`$#C%FnMvEXs=90<DyS!%x z^>PSJZ+UMT!CmLCMKVI))IQYZCOAtp1sHRpX+@KnWXA`LiHv~{=+sT~L@*b8i>}o= z;V2rjeh4fDec_FBX#?_b8!C(g)o2qGz!^)(?B*<#vIU(E9adN76~k~L0{mwpUp9G( zW5p%@ohzg+1_QaNfK@>6Da})mUwq@`sHOwD_*S$3YLFPvCEWbXqS@5X2qP`bEBRKr z0?W|_DL+`4&lqyGG=INU`!SqlAndG89mbiH3Z6)PF<8v92}J0uE{K>(sP6;ZOfW`{ zF%C|&m`I%*eNk~h*FM)fHVnumI6}tD;2NtwJPuf6A(c$Fx&}TUP-!^x0e$TSsA`lp zzDkfa@7#f95$jS4$y!-a+JxT3aHc~dh$#+9f$-gF93H*+7tdWvpKm^*@d5tP%Zdu3 zG=R+YJA@xeH+@V&D7j`UeA87Grd#fZ(>plFmNtXZ9^;8`tgW^1;Ln{48;RVoo`JkO zsJlzPsx9IGOt)q>_`&^%))B5$tS*js+ZLyF(_$Wn-_6}%Dq!F;gFZABOx=n(41CBu z<<F@7*b0L1YtS&nV_H@6CGdD*2$wB84qT&vo`W9CC<JVxrtpuuuqhgS+-KIu7x@GT z8724rYz}gT^&*(~Fc#?WP=q%4XFksb!=PaH_u~Y{q5I-wwMPi2CL@S0jXyBwa}I`L z3GPG;-)?i`l>m%NMizoGCCS$U`T!)(T^~J}C(FIdFg?zPmp6MWI01u5vLQF#lQN&z zUE&aquo^wO(Y%zY6ticX&2$yi?O^lr{Sa94Co~-YSZNJAK$yR*>ka+Dc8+1>$@8Kj zG+K4Nn)^}<odi}+n$V<-!<=`tLsw-`t$(zTFEtRc#2v7JPEgcr2o#xK)Z@X`)4Oid zW|?*u0qut_P28VJDp6=NBu2r6;A1(qnrs(RZ9rNS9%TAxVy*C@-ZLLGmBKhZ`G*Sp z>j5~NuMNWh7x7HJ#maH`tx#RKD4@T*G#<L@`!Q*L4FDdq+M^bZ_ik2U(l_6(SF^qZ z^ZBeWopv5NnI&hnj#5@&+@?VI6f|XNef<Agh-KL=phXb@J@f}WFq*#)1JR*A)Mpx1 zTvnoOpMf_GYz^J$i6kcsX+XEmn+=T8k}j=xQQ*FT|4ceq@0**xjAB8CIj<cdI%=e+ zM|uKHKtGI(Zxv-;g??@-E^-D}!GRsiPxL{bqc~Wm|3a&VrcCz4og0H3FA=s2tu?eQ z@~ithTCumoHg&t$-vB`A-qL50{?k4xj@ryFoRBO31)FyEG;<?HQE{YoN8aYkHihA- zw+5vFLMVuw`jf`s5phQ@BrXM4I=}qCA=KfCfJNRl>950i6599hp+eX?onIN<y_5cS zJk}<pN|YOK==M8jkRaV@Xlan?ClUSl=(s(K`a8{Nr5pNA2TctGj80|F+pSaUxWS|; zXzS29NaI6A*@2?S=bVYw?_Uj7LCn@??o!V}YJe`xA%H`*6nn?^*bngu0ljn`an(<y zz(^z3TGF$k*Tgu?Y=j<(7&;X-XmVupHhjl>)JFkAh0+*EW}~k+w|}NzUy_E(wZHZ@ zviAA_s0C1yS_NW#aclrsPpJ+i`Wk)mbxn$T967=Z5;(ZX%-22-X#?1O`p5e)n-DjX zV{xDosjW%n$_4bDh%z^WF|%Jb1KA;jhX4+6oIdH*L`ZGI!=bGaTBA9FQs~41&GLE= zs`3EmAz7aFycIKrmyWSU5$QvF#P@cp^|B_pTRn0y?ZwM|il#1{7FcVug+%+97@$T^ zdsS2yIQwH6sA2X8aF(PU{3hVcnBhOoAQ~B;KB?c<wuWufhU!|Qt`g9Fm-%Dgbz$0Y zSg~g^t9h@vY7UhDpvIj8M8;~8bWo4w4WWiK4`PO{iVjmD_S^Miw&?)>rt;eSFUg&w zRG7=brDix`Lnr&)vUXxw9iKy#bysWM{S~&r05-X?^lwOi)gQp*Nci8`wE^(IGR#S~ zN?)~2_|eO^U<I-L);C6ro_Qkp#F@!ay_5$LtS|9FPRCvdG{)3Uzz&r`u!}f^(+f$a z+m(RsK~Ee(>6_Rj`X9vSI56Am17HU*k|$|$b$4g2&5SiL4rtTwnu=9l_EDAul{$aU z!P3k|;=I!G1&?!UEVTDZn7)*S6ME%J8W1w%1`!oFTIBK4Y<!04$8x$DAdAVQn1ev~ ze^vXP!XGH0YhP}loL0p4*mojD0A3Yc{6~wp-~^`KA+Di>h49>9csk4u@Oo6zjq0Kb z7?fJlU|2u_?TLbUQ@aXPm80e_hQ^Lg5mY<!usNHn6D+tONl^`xXbh@~uH7q~RQrht z#hVR@RIvxN9*#ce{!~c7GOhVHw<m?QrFKxgSxXJiG47WzL~xNVHpi8AJhUq~cDT6G zFKAf3)K+;owk{7IRyqIZm9EVvz|V%x-EVy^zib13iwtJF&73g4a<Kr6Iq|I?sTAIP z&&flIL7dLRi^%sfT}uF<s0o{VR7rb*`HW*4I#MPuX$8@aDM<zY4d@wf1z}n9kmAwK zvpT<=12ie!==I!hNCL4QEY?nwJq(z!?aP>LE@c4$Er9wkOF1_nJ45@!jABp0>&9}1 z3Y|t^sZL!phtC;IV?`{5@wFSYosO(>*&hMD?Q;?C)T7|QIrq?+un{cuNWZzkNUK^L z&g}UyE;Pt7tPCPcqvWi8s@0@-zc(de@+f%F3lIm5F>`TP6mhC__K_J!i@=X2(HB;C zfn<*E=8^+67?M%AYPxLF#>kpfHHo3mq&vvbypn_wB_f-(=!L5J>JV%rxNDqz!H!Lu zRGeA|v|!Z!A7Imd|3;7FWM(GY%i$o3(Wa*J+m0g@vkSjPp2x!F=1({wB{QsHe?Uu+ zCWlvGVv?!&Q=cE6M=qGBnOE>vLwmhepruxCf%9Jfz&-ieQt=ylXy=sv37*joQ7X}F zNG?EH!g&P0a!f|fU7{JLs2ArHCHO8#M1U~@XJ{m+UYA95&2EGQ@ZQiVD~{8hmhcko zoTN2Wy7xBqR?zK6Qt)y+?fY>7oq}R!_5yPw<JMkguO&;G>w1C=+@yp6t65YoixM5_ zHnY_Mt-N~<jg2tFyIe=YQ@23}6ULP7q#`|YBrZYX+D;pn3o{6I6C7YJ<Ee6YL;bE; zR1LH`jPrE<nuWMp6QsZb>>>swu_{x)##-kVA*bh*HqqmDK5$B0YQHG!QTX+L;}+Z= zaIJ@xBqvd4LPs$?Oj`gD(ZO%~W1M%iAD#9Eg81V5M4|WPb4HR>G~=wPv2^7U3auvx z%|m^?OG%Q%`%`Fn(~?+=yVo2bptsJNt^2<)#ELN0+yFC!b#7HQ)ypcj%8ZM}OCjCG zEn{XU8=hzM>J4kUqc*hJY2{@h{x*kkC#X_p#q=FA{%G&}Z1n2lTuBlQ6ahWtCvu7w zphQZ4Un#8q<vk1WEX5_DtCn-JnkMPdxIicSoYMufguP~6x7^}`S#LP3S*0Yo5M^My z6?3(5haKk+TOQfXp1>@)>;bcmfrZktP$&8{_^4iMRBw}p=vItA)-5o=jjDMX8{n27 z`FuJrtTa;uCn6GJP9FIPXdBeKN6RjMYSL}v<sx*GKh~C5x(Zi-_6P(svEl<d;#N%o z7uoZsgpRDNrzm^{GOEH?KROj&QW^PzI#`|$UywksC$Dd8<~BCPAG<IuC977sMOb1T zq;_#<*r?e6R<*)5bjiIi*K*dfG$Qur5W)JDE*$9pm8hv9qM>hGxHGcCL(stP)@q@r zzg*$ZW=25%rq1j}6am62i(*CgM})SY{8T`%i^y8EH4X5sBMwVudhSyX0v`cwvDnW& z5J$^sv^Bn%c1J#fxs}lh@y?WpOaa2P|B?KHCG^A}IY#(o7jHn{T#zjr!#wRFV2W58 zBA_Z%*Cteo*TbrTL?+!l=&Wh#3EAo9a3;9*Ng})yI`$(HZgV3FRvtr3iuU3+Qyt)# zwr_{%v?E=!yTt#Cm|E0up%Do1Cv)~sw}m$FBh1CAYz&7%p+|S%Bq-*pd(1yD5}wQ; ztEZtw1Jncua%>Xv$>=bkyKhrNEnCrApUnbn2L#hiR%BaB>*%>L1*s_Rz@_Uj0t_`X zm)PT`#Ecfp<?RLxgUeD`iH06J6UA2`nXr3jTsI6i7fS^6dkb>#yvTh{*<gMzP0Y)? zD!#>JRf-Tmd2ed3n08GQ<f-fq8wK3<$hBTYyI+#RcO#9WHw>@ZHls&fGFL93etWDo zME~y#bLp63RW)??4&uPE416nS1iO%F<h}eOpuZnIQ}yF59Q|a}-LHhR%pNnO4JIH7 zdfgxsYsYMt1vXz)-WPS{ET+bbLCf8|x#3<9yf9eoE1+LI%kQtqB1zm_K~9%!0~9%^ zaCVpvp}Q0cTEb|?I0_DA$_}OIdhqjIyprMSXWvii2eA7ex<6k3dWyLx<FVny2M=5! z)l&m{#do~ToV;j2uYNM8KL7{HY$o4<tr(u9ZF@De=uGtxFjuH%HUC8-%w%HaE~PBM z_PIO@y(-kxZ;dN<9L-1vkmlK}W{+=1xV=-zV;}|eF!s6i%^34*`%2Tv-}LT~u6ch- z-s;g1W_=rC+NeOu^+O>5^+2UA`L6aHrN`_so7Wq#AG&UG%->boVk4lRJuB5RCXpDg zh=tD**fJwOfPZyX1Nly@E3P;~pHM*<SR2JOgzwrGzUii9-pCogDe7N1&(3TJ8(i1G zQxc5`n2Oe$WjgFYrzY7wNypZqjZdm`*~6M|+z-~}?9rHcypZ(Wx@yDS?M0_3pljmi ztC&tbK%KIu9Jg6@={R0fKLgGhGHxtz0(YTapjSV81_@^;y7?WWzpoE?x7N2oK&oze z$es}DmY1Sf5aP8o_FeBB^jwF8zic)7S8prUS0N9IE=nM_D#uBjHIA&B4s=&e5{Hb@ zQ%vi_Nch1r2cEL?N%_%6w?qf6g@luPZLAx5lg9>ZoDS)DV=bVq7G|Q;Cj9Mm@p9V3 z_LZZLp|b~ERb5A+i)K!8eSuw_%0|G=#chVn_1wwyoa<%(p1a2(;U+Wa-FW6A5luw- z5K><9DYomttvG*U?q=N#c?Mk-h+x(g>PWoQ^O+ymWtlQ)K=$zt;;vVCEr=|rY6;op zS{?T%QJu@+#S=`O2>7^Ul-krJm(F`UmyY2~llQt>Ku+wimY>Lb)N%&Rv5u91UR@Nx zoZJocbP<gG?XIj@Dovj0{7*>=10`kB8=PSY4W7CyJ$GJK`IH4Z{9>!9J)Sh|Y)wrJ zTQM8wU8sBq8LvE&!!wKWo()7KdN8}}L~z>V1IcY`v5WSRQwAY^a>33le2d;rrUo*y zPbU4W0bP5*&fu5=cqwdY6j;RTX>-vt4yP-J&~z@~j+KqUO(KOs7o$y*bYw85C|MQF zZ}ghWo;&1oLCulvytO7_>gCARF%QmqTkU-2{MXx~R(JNa3YK*0kZ}t0;KNa<)ELXC zZiq3?l6J{i@)XT5h9ey8Ckg^WPtIZ7xB@AzrWM9~F*gd$A^LDI)N*_laHv2<aD{|m z-9r9m_2}S|#kq~c18D2_g0L7^3F0XzfZ1gk{v3Vo4xI8_VsAz(mSvvW3|lv5DvUCo z(9*#Sb#JRLZ!tEFeoR3?2i<}&qRevwmpN*zm{2}_nk!j@{O&Jk|7uxT4l;|Ak^=e` z6vSZj8YQlc9H3K>ipOC%g**hr%dLu&q|cTM7zVOA+F@=|PFyd-NC+-g>D~YEvO1po z!!>~x2F&nU%*)Yt0(vv%3m1UL3LQ@W4Pm~=e>I@jUX%h!*y=3~lmAug%-`CE(z>Tn zXAVF){8Dx5k}tx{z_T-!C}xo8MH6Vn#Bc()oK(3MX9)2RgMOPb3;F`GiYSzbZmubu zj)!gSuu_%N&GBS2AhuXqfr)ot{4Z_1?!*dgj3+W&Q|rT)I+pZiG%FBdsSKbCAFPBr z#xS7EI$^s`%?fjJtfd8>#5oIvyajRS%M1vsDvK)t(XNvU{mY9;)TEA8K*uBAsa0UA zwYrGu0UMAKM|}chn2|Wr#*w=>I$R%YRG=@<z*x$fxChN<_~eE14+_dq7BmGLivyNZ zamKQ~>9tO@nqlvN{_xHed*+2WnM{@y&4rLQd<zxj7&jHvqm6Jcg_&E0Fkg3k)|g+e zN9WoS7n8Cg^9eXgH&)A>X71V-YS!Ea2DINdW}_+`+HXt*p}kP5!6}tYca~mpr6_P> zRyn;%7eAkC%-NThjVJ&_hD=mIbqHl*$zjfzxiwm@)h6f&9En;>21c+-Ey<OVVg5OY zR^V9b7sU=w&P}yGIK6lA+BJE5PTc3pkey6f#CIcS65gGzwwK|K!_+lvxMzN|iErEk z#k<TUzEK~JpFJJ9$@l<2jpS|N$o=VwGiZIe^b!<8uU*tbcY}@(^Eh5a!GRi}QUja? zbF`U4Jvfna$OSYHhYsAMzI+X}hPpfGbCL3fP?W^78M?GIGbw6sI+JKae}AJ=EDUI- z^b_cwWtCiM&JTI_J6=`HyOyy}MeH$F^RI?slqx<tK1zwT-ca`svd;Ll({LZga<zIg z&wiSX!WcPk_2eS#jxppg1aU7WQ@a<N(<~eIpKfiJ?6qTYlJ*yyJDjs0$8t8=nFu#S z>-UQSOdHq#7alGz;o8PP*nvhPzUJ?CUGGhrh-sn&1zDHS{KFY0?ttq+o!l7HvVzRM zFd4mop773{wf(pD6M54&;m5%qqE@^-2G-r^=)`hypX6rbgqCd#06oNh<pVew`dB5_ z!oF$FzA4ZCC6w~{(mC!7tfy85<zHnGo}faBimHC73<{uJ7=~P^(i-e_4Tn-x6zGpH z(E=UzM)f{L!f5*~noc?ezky{@x>}`ZvmKL9!4t8nJf@4tS})g0pNkrJ&%A~1p{;0( z`-Pp^?Dj4luZalnBAk^pbK6B29#pdg<;W~9i7Ys*i2t5B0d6OmPq^jzKS@E1sa}*; zM<{xLK?LdmUoW7KBNjz@SocHGfNntolrdvKUO7FYWJ`Izs0&2RKb$6bFNgOK*IxxJ z*mNeQI}PcZvuthj5j3ap;jlqtBk5gP?;0^Z+BtAQ+K!eyMaXC(z6ytXYoQ7jZh>Ze z5FJO6?oQ<WfR6|CdFV#r!RU~+(whg3oM{=fwYVv)Gj&pVqW)wHzIMbnNKGueSmecM zZ#+24T*eZ8(S(mviW*J8_^k71gXvNlfPO}yFF!D7+hqT&4U-V7eQ4J*ghtdDJHN;( z-0GQE554U0&1L~S5^mT5w}ukYlc!HV?t>7}MX;R9Lk6dgK*<zfHj5H7%n1GWv2!Sw z<5GDHC{jGb+_cBxyygT7wXpk8?uAV%>SsFj-nr(^pMAkT`~jX6JLTjTLcsw7+UTlt z-|JMr0e~t<0E}-NdzI~qO%MK)H5PZ>7pEwS9de^#4|di=5$b8|;0@?7tbE?j9LIvm z4KgT-sM42c>`V-3pZ2vT)}W1jzMl0M4?tqX-Wh5vx)ny!Um%_;GX{o>%wF1N%G`OH z<%u3*bO$;Sx?4rYNiE-0QunbGS^QFi#Zdrr64f(6r{C9E9xWulF{~sBsA_Gv7%5n2 znps=4J%l5$z@qRpJZD*S{OXjy2^F92V$=Ighd2GEfL8rL-A==B;tKNRPY_kCn%-h6 zlrZh#pcmiJeNBo|V99V?+x^eT7BbJ-os7SZS_6Ms%OrH^2?N^ceefR|eRM6d@cqN^ zSZM7X9!Jcujf7XU3V<gBMoK{Kf4L5yf@zY7gj<9F%cr9ufmv!G++fyXiwtE2(BxL6 zC|?r7#2)Yk<ssGxT(-<$WG60M0&}>17U63u_@)>B*t<o~qORo9xDC~lfulk51n4<L zC;TcHUMWAk7-|+$40Hr~D_#eiffPBt^YnSNYF+QKx!#Q{R;{K(Q(E(etACQPADxGC zCyaG?A)8pIjRz)aU^qebou2C&?mI5O_{ig-8wO$u#1qZ=Zy-i54{3Q;+03k)-XC)t zjUj8{GB&F%Grn6upTjXEKCBmRiQ8+)A6ci)XMXK#pqOmFR$;zB8L6auuU6=|my-j7 zh_N}o&HBPUzcsz__)@@Te}=bQDr1Fq!(A@z(SZzLGn3KMZL&ZNyHAcp(N<KE{k0g4 z6_IjAZ+$opTxhVdtPR<16W5!$<#jFEsA#o>^ht4y*Q{BdbJirXXE>O>)L9zb640Ty zTlPrH;hZ*rZ|xZDuHE@*Jrlz5Y`1{LjbpY`?XQj&Kpkkrh>FonoqZ;wh<(mCIqR9< zTB5!<pBmVUSFHr%pWjv^jg+R@5dc>F$$)M|SY6B48&HB}6p#<OFFfL##xj4xu}@#i zhs-}^s#^*G++k=kBMD=X!_0{*+E&2eCOYO)KMzWPoX(p>w`<w_?rd&LG{ba&ZU2+a zgY6!W9&Rut+UB{!{u%Nm$=VbfMLK9L6G~%-u9FUD2OC%99~I<H>p8B|m%0||-D@;W z8&D_@F^6<Zawqr@<-tKXSJ6<*fikJb8q(`yQ8HpI>7fbbfIfR2To5>J+<Z!gU@~F; zE50;`HgeRyF+ag#33U7K(5zM;l1}*kENHnD$8y!;&~Tl~cY3ax=gHV?=w>*NHQfF; z=h8Upc*->ccO@O%fS&7@Kg!)ZD9>_AkTS(XqAhG;3s(jQH1iE}SoD#;dKL<)0JtMg zi?|C@;OhJXb-I}65^LDAB*P8M;>e>dO4MXJmw$3n9UFD-rE?Yj=flMS;oG-|s+&j! z1oYD-Gr*K>Kud+IKtA<=m4Ct2yt!*b{^iXd02iZJ%0pqxboS|s^q^voOxsF^LAY)$ z#xavJUfqKM0($DuJc@<+v{Rb$y@{(sMI_Oq4CwGv;;9Ld))-}J)EHNue)uXiXWdx= zFq+|bSp;T1cXQ~@_4zmrzd$F1YoIuv6`BzXU3Td^1NypYe`QRjr>s1Uth=+m-P}xU zEL6veV6&j(DD1$m?N(r^;kNg}q9fsU?)Bw(HIMTe1A5crTtF3Pg%~b|VPL!gs|#El z2`R)SWv6v5Kp;9C^0&DhV7p?SPC@mrBcU)a<&gP|jrK#va14IzDBPiA%)gA^mU&+4 z?6Yt|ayv4)@97JH%JXu^X-)4tPYFWPHed803e;R?kxqLZCXZ!^;iPFBZZXc84`Y_< zI+Zv;9P4ve<fD9$ni03n8O?HxIVi_Hh#{5~Dl#XamvDstRlnHVJ96A%5zqSo*uZ=Y ztbmegKu<#{K3BwYo|b+J24i6x0!ULBuH8`Aa_<s`L6#$;1G%oRJQ|DXnCGJnd6p~= zqrK8VF%JUM3B`JSw6I!!!yY&JkFUPP)H+05m6Hqkk*GPDo?c({whzpK>j;pUQ%}94 z@slihQ!-CebD#oxQYysVbv{i%N8YUVrQ<%t0ew1;0tGP7a{cr%Paj?V4`c<o$-Du^ z%q~{Y%)N?5HI4$z6+pGPNREEeGYfpRK6Jwvpl<@VMB<OJ9y7$PL#=f?ILz~L&KnK{ zY^aSCXpxrqd1scX4UaD1$$MNeBBrs$hq>a9sMU#=6=a5Btb%VKg{(N}!5im<`W$P< z>hxetCq-*BJ!2CU;}`-v4!~)3f}Xi2Y%|+R*m2}NaAdR+AJ@1r=FiKcCVgahmthbd zGnF@v+X%t#FGg?w*{cZ9_7XN41{)BySpU<Lq!&z!%kjHI34Brw)so4#h1(I@>5RI! zO91PBL(WH(>I3=`Qj<K6t+(&Lfgd0ExeS3Qcdm_9Su_hr1KJnd1C{oLOt9{YWV$V? zRyHx#>IBAyi5iY(SVeQh;V@n}v7+H-GR5q%L7sTHkkScbGMLK(Ab?$a7*v5qOlG#y z@g&e8Y0a~BGZMC%idnp!zQl}{i5i_(KrRFX9y7tJ|GKF#C=#$TQ(5WEc6*})wDEl@ z#R!oI3W2#_AlE!eJ{xgmSm@HU4>B};H48v{KESD`z8w3MT);q2bO)I=(EV^s%kUVx zP@!W_kr@2g#@YAQ+Z-b09qk4)06Wd}fH9ucWQ$-eP&y3-I_^-<cCG$JZL=NJ&?m?q zf(S6*#*i6H$n+I;V3UwU+aB$XPhEIEEgFIEJX>@x8T%E3W5S%u82GYV(MAOM3)?+R ztLt+`*zsddT(|DUa4R(WPYeh2`kp+Oi_Dqv;u;yyhNm+nwldLP)>XIhWH(t`45%iq zC6oUTcp%PeGSeKdbu%xU<Soz-C&=bjSJXod=vaf#wRIkw;G)gbdo_HGcKa9@V4}?{ zoBO~Xvz5NiP0a8l%qPOi-&P-({+kDA9`=_KB<0!cOXzZo<lpCkDS^YWu?=EdBL%t@ zY*r?zVSaOId5g(Md-M|4J`>0uDxGI^3srSQ)-S%sRVX$yRIa?h>V39*R#<~-H0-js zRp@24o0r8lyz^d1V>x^~o&QHE5CmjKi%tSHXSjiaDI`@tv8ZE*xf6L`togXR8+KE0 zsS8*_aq^hyWW9I5dp5I?FqCo6x05^aZ>U9&2HUPK=Dl|EZE*Fag`jQ|r3X&h-|x=- z*yu-N`@-lTmxtTZ4w(jN51}t{^JSJ;NKS#hj9j2|G_&nS8Qpnki6)--oEgM10`2-X zgQQxYH?pnFUhirq82j-RU{L`TuGVW(B_L45*NUk5;htPw0>GT<y5wS@{r$td!#{3` zYbUH;Pcx65O$;p2fiK4)Jz<NVv|=|B-newKCmxq^EYoRdw#@nLVtp)M8=*bl$yMnC zg>Ay~^Fo4<1RqQ2tw0v5Py-Cw_-Z`pXT1LIqgB<G3yYA0xqvktUF$)sUbL14oY7kT zXXqo0DdZEA`rt0`*@G@c=<;2F%(c#Vj4P6Qi#A`^wI<i8;AB7_2F`(e9gacxe6_|9 zge4|Tu(t<AoQI5@4+Pb`s%wXK37m3*Fy@Z~71DS#Nst92RvsPaK7aiq7*HOugiXLA zpN}Fo6R<DYPM6<;Outl$)6zDS@a@Kv9JtMen>*5833^I!{a$K{6B-HaHP>!-)HXZn zBLpS(mA$BdHk|8MnG3g|e5KOK+N=#?-UaIKnE4xRA{Y=_v#Dx<tKHG8W-7vKmqGiG zFuE&1o}BZO+!dSN_{v!{0!?vx5mc{2eXS_00{RM{Asp+hw1QlEQ~W**G5_erj}o*k zur?k7O}R<gB|UeRD;nmmY0c&+)oy2hpp)p<MZ|RR-bi7xouP*Sj7KZR>{2!D;>5P( z*cC-PD)|L@=;O+xg|@g=7@Khu<8ez>2zpmXHS-xg7E%$XfKEa(7be}}%kJC~gQ&yk zryYRr$X_<$ZlP9$FaP01rrxZ#Ufm$fqS{JM@*Q^nEW*?YkWEARSxQI&@ks={=tW4) zsa2IH?|!MCJ8lewtA?dz^QvjU#>~ms3T^Ywk<g({tN!d_Lz;m8c)Cs7v@~7QAq1Sg z?cDse#*|{V6b-*ZmYZ(&7G!gM)3m}Kof;irA<%|Bc?NB$!brl^qW=vm3y#=M_rSLD zzLf#gUE2qVouU|2{fEf=0#W&;6h$L~ZuE2E+<1kaH5U$Egi&E8zcnw>oTzM_4TD1R zq!}*<^b{!H+w%yNL~CbSPio6F^mHs8dII~q8&Axw+Hm6f&ADFc|B#Ujly7rDikJND z6@o@UXQ1&UpJ+L)pr<`HfnK*o=O>o2H-i;>6<q>uo&y~ov~Zw%A@j=@GahH`DBdAE zwbKPWh5Z}Q9=DjmtQBAZ*{jfY?J^7EUuMV`6f5IPjDIPUfzs1P1&5Yhf<k9w0n-0b zc4c3I-UqJ_4_C#>)V9uh_S%D|@`CtzFYlH*RBl&?Vgs&V)w)#9QKIT7Hw-5lj6;;@ z<tr=8+tA1K%X2Bmd>L>v=Yf2i>Or{e8uch*Bt|zA=3TBT|HBXaJ}0*^&)mktXwb1~ ztLQ`Bh#f6wYBVaER_obhykRE)hIYAw#VWU!f>+&PqnBw&4j|?norg6wR^hl5&KzC( zt~s<77MN~dI8${%QAQ7}euS<-0~6DSMHn1SJ=g4ENS|XfovCg<hHWniu%M2LJL41P z%YT>)ov7kCuep!Zch*jIk+>djH0eT4(Di~T9QpI)(b!mcJLwB`!toEiEF7dU6QQYg z9ACD>3MXs49ip~duOOWRa$JX&xCja$vBwZV+jBZ(iij24++V>UqFgg$<C&M`z4d;C z;ob*qI>4u&L@yd<08%ax&^@2D3J}(OL}KTF&RS|T(q-Mb!!IN4AXwf;7Ka+ZnP{WP zIGB)H)ZEsa9%WPvgoW)7OSsh19D1Qbbn9YVmhwyJpG4U&T@PylT41#JGHa#Wo{mI5 zD+ChMNYT;au$JXAvSQQXrIb(Mr2So#ohvydfVK3Aha9gq)oros9ZId}?@;ZxyOV!K zUa9~MUAUixZPr_L=WLU59lIVZqR5$8G!I$P-;XoEa0#zpGaJYVc$qVQ4KSH|?({Oy zL06ubalogC<8qslEoRb;(DfC+3}}`S@N5?|ic5E<R}GEyS>1DtoD<=;qXzd%b%(Kp z4QhkXAfUfCnmMtu-u3xdKMMS6VJW#B0_$$5=w`yI+AmH_mt2!?Aygyi5N9%*y2*Vx zM3{SnMBGY5H{L@<)=}4Pj2{jcvp-VwDi4{zFNcoHQSQU%&H`StT*u%aB}wPGQYeg| z3sgP@m!+RPk=?6pK$ivzIV|sTV`$iT%KE^m{)PFzjK7&3XnxqnL^q-WD?c!fl5=3i zjE>c4%e%Fr4DO{Um7osHR->mEp~_IFeruK}GaU=TODO>E8d^{5Y<<um6FIwg-MyKO z3b0>#Qy!RV+>}|G903@p&fbsl%DR@BT;B_l#@v#MV2?MkH3Is1HE!heb{qo_CO19a zHM=VGoh&P+G>Gl6S(;|Dz%;M>@6|Pf<8MW_FSsEwEe!v=(vrko>Zh7A>;ighn5H;# zJ6-fH0KH7HM7PfYsRk~WKq$ah(jP93OCN}=-KIT&zCd7C9!pC;dMD7AevFG1&B*cw z_wg0<lzap8kRc|)dNz<G%7zEBcL2ucf6@1G5cx8ojS%Db9dd8Sn46{-+&Pzq%eX%O zWlyxQRMp$%kuuciO$|f7Oiy?E=r0|QPj0}uiz!%1-+`w42lNTybN1n^?N%T`FGhhV z;x0B=T$p(UYWPJW!qs7=hf3%`g=qm`BlR+e%(oe89x2ylXzo$0OTyc)EFc4|LRehg zDuLW5_n3>nvB-Z8H9PfuAHCT2Pt6<;0mlQnX$zwrL#zo`%?)r0<^6}EK`0uu(&>ka zcw1qtQlGF(+MTy~R1~rQ!gWPI`%Fr0cBZ>R`ynNS&Ox=UY);c0uBiyN2Xy{{zBJ^4 zF%Cp)(lks@bkLf`9L=3;_J^;Ch(TZzhNch$n5zBoCD4R<UX4X^Mk-1Z#!d20?X3f& zt!kp`un(z9rS&l*F;&*uD***?Xl~MUBRCK5I6^m&QA+&)_IiHhY~)zPRt(a$8)q5h zflUqz>TKE<i+7+fPM<^H4A~>mG50pEEYz%<KlJr%ax0KRfN2_JF9ISO19S)0Kprhm zhH1f%Rc=KtFQI585v<M1Rv;-H(1Q>km+XJk9;EXLOyrU7OME^$=j;WcbIh`3Lfc85 z@~f-3;aYBRfR;a(`*sK=oX&<4oTi~M3tIGjE82Rf2z=pmMh)52nROxn364cByx|}M zJ<nIct6IIq_W$tTrwf-;QdlG@d0WsvR?IZ?H+)5fZe8Gk{@j{D{cagj*4dBuA_t~9 zo)e%Sl8S6AV*YACyB;}*c_sZLR!=~<qPnW^ex~MFN6!2j&;`$#MP|-Q{mAp8@S83{ z4;91Di!P#!jca;=BZ_<<>+3@>7DquSEh+q#VfZ@GA+O;`N|?Sxv1L&^aC1XJ&U-Xq z5>Gi>wfdt=Y0}VAK&#&rIf64qsCadAHV@B(1nXvuaG}nx0mjz_^mAktm~)sLMv0aU zGG!NYLv{GzrnNAn2~h&7M-i>LcTz*_+O01|YGVxSV&3r=95e$B#wXYcECy)?FeSG= z(@}N@cgEDkah~+;H-0BhFf1mRgaNt}EEV$|xxzL`0b_o%tjQnFdQ^M3z^@RSz*$S# zOb7p?UG6d#M~^1tJvpM(fkeyA&l5{bq>}++RH$w(^{mNx@}G>bM3=d^dxKnOCEtrG zVZDD+h|9~6Zz|My<fi+1Z+O<usJt1XrL$&BWf+5MsUCqnTat&f56@=CEyl)XzBfE6 z_zn_F&)iZhO=#~4hCA)NYxSLaEDSaBRXD)$gCjgmBTwAoD+4<2KC7+ZA|O4ziZ}%F z6Xp~`jzND1H3-d{mmkjhW@p?xgEm&n45!i7#Wsy12pH&s1N7FDpx$bA$fa<a4+499 zX{ai%K>DO*7uCf1Vlm8K_V}b3X+U3w*n{j$)eCKn5@v0yi}!@PJXR5_h{impK(&ft zCQbk4D#Zc#B%eJBeGD0t%yEfG4#t9h`j}8pf_vjcaxts9KWab|AB@MKZJp0?BQLHN zuJ-zfEUsWQa#mNdQ3O>&+sv-F6Ax&&-Qw7RJcYksWEq8A#DG4DN;r<*R6Ymp1zmZD zbbrK(qG#@>q)=|@ZPpAs@{`65={6MVVl8rF7iqp*pP^MZaYmMB!JOd_s5fcqB2x)3 zZ@T*sXRXZJej%HV9n0exxW4&q@b$GIpP@huFFg(zLajJ9kVEjyLYm*MAV`K&%+XVg zZi32?W#wDn*YMupBZEzb|F-9MSeMb~;A`Tj6(^omOET+V9YwsYePM2bnfWIAa4NA3 zmjU!`FK`XPsQma?p7Delem1kSu;Og%s^!t#AXMC07D9eogI`>eTK{H*wSGyurOS*R zuqwA5V<L%wPPp3(+<1SiE%)-|0jUdUe~`ezcP#S^(ra-*4(4lhT4+54sN{9)bf#zH z>WQOQB5}1#<|y+h7Rs*ZhX@9C4uS~Qdj+Hn9dd(NMk%tI+YRXDjpkYJ{{tECADx_P zYBQ~)noMEw!mwgl+#h#>Wn-md6m;4(`tImb*?|V{l#=5^hE96x(t}+A9vZD&zn^&c zL0b?IebC7Vqv@ypdW5{}Iq*3HKdD<^MyFcIG(QUIvJW26r<TF1%L59q2-Omt($@22 z@}R7w%#{ddaT5+Cd!F$7@B#kOiywwZ{)eMemv^h67Ya^X1cCns^dCP|t2hm~X&+kZ z`VXAuFQ80k$zq(>;qq(_fI?V3;!R9`%>~qdm#3p99#^qq=yvGEwqynFDWLy4CsZ2b zlwv?{*#f3fe}%q*)?Qu?BRy;}VQ?x#^wC)@8PLaepz^EnLp1biL3D0niXmcUNta&J zDEWX)Gy_<!cE`YfnC_E+rH5}yCYHqm_dc5&Uy}54=#H1hccr(ynQ8_&Z){IXS8DPU zv>J<#^WIH6me?>g61z6JDqOoxKjIwfv~?`T#O&H50RJihFflG_?@~|BDcq3RUz&3_ zlb8A(h`H|rg`-K^av8EFT!}U~9AQ!ygP_!#O$BB`LIDqMCO9}c@)-%3Fks_AP8(db zt<&NV5GInOl2F<qdpruBz&q+NB|vo(O9{z;p@lqQ*Z4+@oDI{W{zqHp#LEpLUkZXZ z5=Mw`R>(h8*sx1ymaS<`bC=Ry3uy0NH0Uljs>t8}xJO|bS>_rytg>2sH5YS4B>G^d z&g_KIJ884h{w}6#cXz(2XI0_79kVrG9qiITV}V5`)xb}0fqX7bd=$^-2J?W<2RH$8 z$b6}9e5&Qh6id8$2XfY1uF=7;;wZZ<jH0P9I4G99l<B3ZEoJ>upih!Pv0juT{C^mw zy?(4s=Z+Y9S~G`3YBt-IWazj+%4j!;KNlIj^n7Q_8?~AcTo8o`Y5V;~E&nwc3>}0L zzBs<QY)Zb$eWm}m^^H+o3}DWn$kk}+nTvSxzo(!+`&4%Y^LJOP@OX%Bn*d9;W9CvY z<LEo=clFO8&SWybrbbs@VhYUtSjH|rE^m~@XyY|@X%R_<=WPs4_Y|&>P2F=Y^)*22 z<fPYY-Z=}U*@$KgmQ4NI=YmHEz!;3M9OP{1C*at?707`*V3UAYyHX+oph1%UW*F?t z{B0-J2bao#y5kGCgoqiWRi*MvES~*G-7D;NAo*xJaVHN9q)*k8QWJ%$Ce%&G8t1Gv zds(z;n!it&y|V4Ui-e<eqSv~0x_+Pdk!0Ko@3FwZDUAm-ayYEX0H_9NGfHQtv>o@O zk;NK~%nZBO*z2~aU+2>lQ&I*xsSB6xSPs{d8Iqh!r?1bRMQe~xr~7vc4XdUA`cOxt z*c?~pRWpp@Q9rWPO*TRL_bf$REEDG2qBJPK^`x*Br{Ti4Tj+Dfb7q27fyu_QeEdbe zzQQ!buyi9Tmms!JpE?td*(il=Ejei+s@5P<2v^(h;&jZ~P02OOGX5MvfRUE6LZ5b7 zEVq#@84=sg0bPzsTnXL-5}DL9-V*gwzIxXHmDpi9>5#m0$eC4glI1QUNebfpZ&9_r zQr2)`V9fwsUxLa#*NI98f`roaiHmxqC061OD~m&`Reu^SGH{f`=EJu)o_xI6LxQ1o z2-(ztVB5elNp66dGuF@YQ$1T@0kIr}&&i7QBC)D%?C|Map$0aR-wMNM*dv}f#KMhH zM+m6*w5O8kkDTI0Ittqm^G&zCnayjdfju#i<LW-z-4j{Q7%NcrxJqz5<IkSx(Q2!I zWQR39>B6?ofcjw18gJR`L;hP@eAQ6{K{Rs^v+IQ@y%M4*Tkd&>FiEVMpO_97;tMCA z<g@)lux1`u4pGfQbqL(|DhvjWWl-Gsj4uqJSCl+lYWQqMG2?IMU^hQ30e+tjy&Or? zZs=ncT0qYU#p-J;vY<9rca?F-w8z=G=*enKu{6hwxSl%@d%qtt*3(uC8PGbIc@t~W z=P&n9L7`>;H<)N_cXUddVO{}kNAo8x)dfX&2z2RjnpgBHWUMn6o7`V~5@1Sk01OgY zG_5??XbK*A)fdeGvAH~s?t}IVjQ6aTaEY{fg|)WgH^zB+Q*9=cQ~J4hL%f=tR3Ke> zhF|-O2n1w9lQ0j>Im>%-#LFHqYmx}M-cs<GR=sHsndI<;u0)Hr{ysG^<at|Q099EB zs)B9C_Ine459nFxDNN6xu<{K+543J%xo75~rZ@{5U!@v2UEZ;u#t|vrnDQ)R2PF?6 ziXmGM*^SXwb7tlEVU(c+W&}vI+Z)?})**)#&>O+wkO~Msl9}7@_3;pLY#0lzDFK3$ z_iT{iJz9-PEFR3R4+!QTY=Bc6nfBu7OTLIYJluzQ=-95g1=UAgZ(-2PYMbv*!)>_& zD(o>QQ8qnL&In%^RMgr4tYj&j=j_z6%%{STVj>Q^dk(?xVH-lvYghKPRT)D-=eDB; z^axmaKxv5dqGhO)GJH>~TiXiPNgWc8DJ+-tj6tvSF6ck;{VBZm3|_0Dc4V!?S*XO& z@XqsPV~jhw7vEFOB>d3<sMkP1M|WZQD8k+}V<A^gbtT}nzaHr|fELh9MMzCgPO^zS zZ<k%&O^ml@J?DlSc4Ar7N)64`Cv#Alki<Ci>UHV?<+PU?+~B4UJX+{Ojua*m#(HvJ zD=3<bQ(Gsi-V=vIX(ic<wqt`fVm4Lai=9AwF;2?JI2{KC)Imln^XQT*U)~fa)-PSm zMQDnCWITK9BF2@By;{R9ZvWOS=E!r!*6O*+Q4NzW!Y4FqGOQV%g2MDYka@Gfs>{cx zu1dGM1iaA4?g<|ot~4}IQew2Gr*ql?VS%|8QDw5~LutlI$U%#$5L<$8#rkcD8R9C# zt2M<fr3sqi{*V3R$AIntSodYiHWoqOR)ok^bnBC<fnd~;^(S%Vt6V^2K9J%A1a$Nz zbHuU%$%0!~DFfUIO(H!nqNpitV20q=7Qwma(kJnD@A-hurfQ9+uC0yW%?5PWE8q#6 z!V5$Ee4wdOIRWr}Z;PJG*Ps|O)b*5A$yVD2pY)4MnxI9_#ei`Q!A|}cd_Prpj1s!g zIR){xhz~Y7&jot09JZ!QPwuz*N;lu*5bKBGVH>d9$GMo>!tf{h%&kjbG8u=8eeMdH zJRw(R+C5>(Y<O}^kSF_Q0mr-q1%-eDSq&9=820<GyV|ct;mQoiF`#Z-AY0Zv321%7 z2iMh|x$BJ833H<{dal`b$tVlHWjj)#V<<eWjbX@hQZd6W)LY-1tQ3z#wv6j*Nz-cX zmDHugSD0Zm3n01<X!(-(ESoo^IhfG}*<oHN`o-7*M`Mi8N43tCMmTXx18_Z2-d3YQ zXJkYZ_w1#t&WKVm7;8~yRLB-(_*&hiu=lAmonqr4;IiyRW=(S1I!@g}Si{eLHMe!0 z0Jj~D4Zr<DR27e-R*F~W?DXz`$(0jwQgFF{Xzs!;L%Vk@tg`}T$7Tt7@uvjL=4F1T zZEhb*?|bIQzf>r+<9{rmTTYmPwzH!})aD_4uF=KtA*<Y#$AEIlQ_1pKjr+t{C@eEj z37jHAvSto&9>ST)V~Kj-&IwJFQS=ww^^*)2SJ`0oM*s?70&a&IJ{Mzm3*xrhf?kTo zgIwC``Ji5a2|-%E#TA-m!-zStW+*qGjo4Zs(|kQ%mM!2&FP3Wuu*CUc0i8{I@YVnM zTa>*Q4U>^r9Hpn`L7+rSM|w7Q0peD%wv1iIi*umuVmNc4V8+Qx`UYf}IsI5c9+Ru; zO#@}$U)Tge1UJ2O-`#LYv0`)iL5HU4yW1d7d=(z%VA-|bN^TJAwy{Uh<P3r#&GB^- z+hn<1z;5z%36V5!qorFIy`82d2_{}pA&TT3HnXh8#{Wxt)v!XBqcFBouHnckm%`{p zSC0wUIEvItBPqc~T~-BNI@A1ZWMb1jG#kpN1~yy4IR;w9M$VI@@4B%&6iPC}8B1xg zKItT1K<A;WqZ7YI?H3d%3?w!s7lHb&;jXNVs+70U{Po(_x7qU39oPQB?!v&RZ$e*# zNP@h?&5AfUg8gr^AeIh3O}v8~0vdK<<43$Z-^@R7d4yJ29g;5Oc%OZYl+_ZzifJD< z+Vilu&zAk*4r~DJg8Q^@sGbaj9&7or*Ux1CAGUM(!o%TZ-{euJWA!(qEd3#O33z7P z3Ffze$~Wt0xQ)U2n~a{UI4;1&KMQ>YA<WTx7ue!E-~i&nP2|Q8?~;ET(3|fw5S2WO zjJJ4S&0E7u&E_qThH!=Mbke*y4^T0$*l1wHpol2P^0r=I9WnMkUNnH$g_q0@1Wp9G zxeSjk{xV{rh(v^kteT*Aryf;d5v?8CWj&K9z~_;~4{Dxv->+qnUlUJf8vww8DqK0S zb7p@;wuwDa5{KYsL~l|g9Z)VAmp6-fn)exe3+P#4pFwY7>)v6?5U?)MQi@002ciCR zIxK5IuLDqFP5+|pbQ1$^T#5Mo=~kBuW7mH(lPArs=1qr9$v^rb&Rc2#R*Rq0hMIgk zs;QMI!X>m8FB4DaBru;c6(h3FnBODV;*hfH`ICk>rLe_Xc2Cnz9`GQt-Ampexvd}o zFf!;Q#cYWy9y6oeYT6h1-y^%cNrk6hR<^0z>IVxVMx$C9;u8rmreq2@MR*X?Ny9^0 zADmq=-iv@9i)c(Fhf!>LLH~$cdh$+?wT3!(P5o=WB|%a;oQoYg#8NvvnIZ1!+7P$h zR?B)rSRs$<6)S1hr|%>zTR{+xn!gkjW4(Q$9YH>@I>D@3scSX>&?$|jDR0y@zZ7d; zHoFilVx~-t6zAAK&Qz{2j7^#y=crix+flFd=5&=?t}Ex9VK}pcTE+0$%9`uB%Za1l zIYw-;7(7yMSlnS~bQK)*7u&yK$A*Y&0&C#kr`?VD{(hzj>%|xIP(iOSc}4%Du}54N z@&H>C*1G>#$iM`&&qY=fOT<rTWTuF4A<aO~Lf(bhhxFY0=V|~$zZym5`zXY}?THl~ zC|dYK&+qr~LtqmO$Q%Q@B1C>bM{U%LqcxiUo*1dsV0kSn`*cj(kIXFB4-!*Hw4u-t z!I3({-TXtYJ>#8uh+55sn4VxKFdz;y`z#9n2{N`LdKlU*)au|jJ9ui(ES7No4_Tw6 zGQkwoNwkW(7jP^_ixv*Yqhn{y(&(b?mgCX4e_&|woKdCM{xMD$J7uyAiBkibw-O>H zk}p!SR$&WWcow!WTpDoOq{Ux_#xhh}ELse#sXP7B13Gvfq8bxKxlH=MD=F;=@34r= zi&wCyvnwg-LZ@3OokzGmO+eQI5fIKCo%}M(S;BGP4p)0bv<_;}dE!K5#5mRv(k5*k z+?ntlD6AN5bWbezxM$3v99WhB0qG?m+IebLY3a!*{|($ga{{Mk^_u_9oRY1-g;{of zqr|uT#-dT3D2M@p3+O-3o+aokkU<tSq9a1Kb&>>e4iX^dSYX@>8Rpt#vnilN!KH*1 z`Yyl=iAiXmFQ|}SximUKb))yC&5CF>#DBq$DM=^yetb857TuUlwbWy-+9_f<yojOe zQK30`yst2BqaXJr-McOYd;zU|wDqp<*vVpda$iVz+J$5qB2RfC{pR8H{B{=j9m=A5 zKC>7WQ{!e{cAxh@;5C}Dd35(a^A8KMhaU@5;_kiS9|L;+&a;u)^(3#2mm4kf&mQl# zNR|PehByo%h`D%bP&L_z!=PH>j?e-mn0BF1B(_E9aBn?np3%yaI+7~1J-f7J=p$#& zCcyIjO!QD+OnDmKvDRy~aOfVtuY=^2Ahy^KRvr>eP+7!d)S9w9#Oup2{l>h<Vxj*< zgQ?Y07$)I1o$|-IOf*w<b2A2t5Ebj7g`QBX*GCKbfq+iDRyDFG>jeh1--RGZF!$Bb zBM=E2)Jl*p4_Kc-HptL@J>@Yti;+s`5D`lv{oR_>SgoL76lrK2vnvISv$w)tt=3zn z^keAO-32r-V<vHIT!&6=gzepFVs8luMk)mjq<ApLg4RvfU$%8fU6ed#%E4^ybbu2G z%1s{3w|V7xX35exm@F)qkM0ftQ6{C9jQ$Hx@+yaFjXt{Ub#qaUQAgVVv|C_m5X`M2 zu5>*zd~SPa#)r;Y9HrpuAjB=3s}qzx8fRZ%B+_2*EKo0O0ezeCzcFOvlPp=Cx!5;n zeXsuz7E9ts;>M4FwA{Z6TM}k9!?d>?0RJmP464P)_&EQ~(mBY*59VP9Brj;{ISnl) z6X3Z88u$z+LDr@K3k$7GPU>!IR*4tmD>l#Fk*U^KM>e?uFuB=(O5I6WZx66KnIM{B z{^j7${A&n$M3`w=7Yk6`@ZdUu1-ML>)35XjRDENgKnRx$nB*>8sxqUrLol9=@z!*S zysFEpUWCSX7Hp+I?V?cwtSJM(d=L7qz7Mj)0@fy&!9SmPQPUJ5U5Z)pF_V8YxeyyJ zTehJFk_5t2cf3WMF1z94Cj^!^2(AuoPwoXvw37|ynYETgIKj~04%Y6v{6t>?gcjbk zyKO?jLV-zvaG7WWy#E1snAI|fDgtPz1yb){gk4ijl6kUN4Tb&+V=%eCeX!}DN5O+O zJ7S+nREOlT*=<gVlDyFnB8<iWoDD@btOOU@3RositAHw-l$i;V8mvjTyfFIFm#rW= zMwRu_=~KTBc@yXte$^$wevNQ5QVC^zchq#Y+wJ9Bk9DFasdLn&P$t#urSC$Wm0^45 zz(-Dz9lD6%+TFUdP*a@K-L=_$_Gd$%gF8jj*KZ_5C)+^GFBFy!Oq5JEPIj?%|B+rQ zZ9pLB*Y9c`U%lXnnF#1RAArD8v4mzWIn&0fZ^CCsgqO`yNb+!^@XcX-EU`&K>MOBD zx;1D4y*t!HFkUL^BavG`0GMNzG?%~x^n+#bY=#+_Ea@FFwzkGT-RQ!k)Sn3C0cAcp z$jdWzh5v_LdDM9P+x$gqdJd(pZfl60dQoO^X+SU9i=b{Z$`u@?p;g)>l=l3Vw`fjD zovk%dK7N)Q7rl6yd%A6?)6k9`Z`fUG5fQvWgO_fd9Vh!mEQ30?TsXEC)u7deF!{SQ z_qO&R&4#4C7SI<H%tRS&CL9hTPg~v!c{-f5{A0~Pa|kVdW(2eg*t?izX)tdQpPJul zzB$a2YGvj2l3qS$8^N9ZL=4?nTk1!ix`;kM8cPOLGX)misIIvDRAAd&Flmz<u~Rx$ z=}5<3gt~%;bjPJX-86^&ZMymc5RO1Mss6tyyeTzmk!2(3ha)#248dC@;xOUyY}9yQ zWw$un0{X)_>eSmKkqc<=tf7-5*HapqGrG3~Hw8~be>uOM%9<vwIQu~VZf0wdM~gpr zs3g`i7s^`q-ctAtHE_x9Ud^?W;n7J>-2~wth&TvMca1UoY2c7J%i^%%7KJ&(vQw@K zJaOOCb7#>5JLBY`=RF-MJ<aI72(_N30#%+|(U^^>@m<*%j9@YR8alMXfWw1D1Kui~ zvrF83XI>(1@iOcqgu!j?sfPRE?YL)&>gU1ahVQ|dIyPlYwp#@sSiwoNgcrR-Ro4lF zvRbWTT_Pr5McLC`I`uF>?`}h`na?yFz75Dly3EYRB91kDepmGSaI!`KCk3NA{WUuo z!|tyDsRcuFE5n~jBO>{DNv7{Yk3m)fF<}m%Vm?H89*JEZ&2C5Y&Y?kx9jY#6aLD{q z^xW+>Q44wFJ3hiSl-o?FNtp)Tbe20vzj}Xj-`x}a(0eq5#4vD;d;aOV9NzNwE-5ug z-k-v&wjc+CTo~C!lP3pb?SA4#anD-D$&1ywHusn!Dra5`Ay%%Aq+KuC+0+&+>N#vX z?dr;+y{BOpbyImOim<Fx0#812+tw%Ht_<vvELDeui<i&+DpL87-K>l+rZ1rwSc<JQ zyn>7T(Av~n_S)F=Aw^n(t5_=bqp?<LV3aGFHuA3<^An@x{6Ijf&@zIxT8x+q{S;AX z%;I!wlxa4~O4pa`1&hejL1>h!dXWfSzz3nd)7qzWnV1mJIY^=)QZZe(Ig4`E476}Z z;K4nghoG<)nV`w9D|!G8p1FD%fiwMPe=cS!jnFR+;6NYxH3CD^RS9`>>wrg`k1pL( z`r?aRTvLR!Ux?I1{+uQ*4Vlfzd(0&^d=cxnK1!c>0<T?Q?#y#)#}*zD(5t<kj<OYP z1i(4TQ3O_K7ljRp6p!i3_w!hLRoE4XTR=cuVRvX&nBLsN&t43>_$J%2qJj-T8$Ya8 zGRm%KOMY$7ckD#mA`1HCzE+2vlV}k)g8UYngd#VYr<;bkG@5HLl|9(C#rCi*elIea zY_X+7M!IJ#rY|C#>{JlV2#w1$?C7I3po{IaMV@R4eb~{Q)PYv#Z<Vd^jd-l?RVeO% zqLOMy`G^b&srZ*|58)k9Ox$LsglJ}qHd{ciLVIW1u9?<iW%x;7?_{tZ9e}ndY!c8j zfxjrxv<QV72x+NBKwXoFXy;0eQS5;A<r2ivM{U5I7I~;o!oJ9QM5bMhD>#|CD{8J1 zIeV`V(u5q*$b;tn2udI|c?gIK1@!6L(3+BEf&t{vH3^T<vbJUQwMx|?CBcGtFt<;B zmj$qw;%vU@MVtkMM#)%hi0W6t5_5fkQMBaN0yO^uB@COfZsCSSERs=QqW6N2Vx4nl z<r<TiNlE$07i1umzY=}CcH#81pw%Qb8FUHsJ+<+KT@Y=_dw%Xblx<`170sMLlbpze z(#vNtt#h!R8yUCP&0c6$rty)Xc7`mA@1C_Y`Q1O*!JsEz!KlkP?>--hW{1p*O`%xh zr|IPtF1E>Js0Fn9%fl`c%}k^G&2uC<gc?Rya+Y07L~{XMIu~WbkR&ZstEDnM56*(| zA#1cY<N`)dsrIEg9GUbV_qhGBa65e;<e6%5Xt=X^esrA+ZycMA_6f#J)0rQIdLxoq zmVK|~8XR}17`s6+BSH6Q{tV`g;lExI@liwCV&+7;MZM#AB-L0w0Lz9e>R922UWXhi ztQh@AR2w$45SE5^Vwg+?fXw$~Z*@LT;Iy}I69oM>XYda9A(X4s<RQiU3x6Jo;lw6w z{nY>L!_#DF)Tc1`6a$&8k&0MGDQ}3N#tU#x>^W$l*si)B8QTC3$=6>;;_f5n;;Le7 zcHCI&*|H}|OD8GY%rknIni#!!Yuvl^e84rRBam>|`U+~LCLeJI)b}eyJY}OXkNYi_ z>2Z)7hr<Q0zgWyQDwRUDKVK`*@vhhIqMmMjKkf8XRbrD|4wKs?`9*&>@+GPV_*sP8 z;_)FyqhofBL&cJe$$)_~UJmF9lPi2|I-@2l6ue=!oWUn^scW@&xHv}pIC{j=p6yh= zlYvkCF+KG<HSfLc#hD5lG<iN@+WdHae0gSHrWy8o8ajIm(^<aI#_F4;$G4fYOaRwr z(d?&Uwgape0F=6*G)`dOUBKltPe$m#K^Q%Zuohy#|FXDmlX(P^vE0e=M>jHTAWkoq zD=hYb;B-<KtG{fPJfOch7_{ebxRP&2L9m@cj)Kf?Hb3m@f)C8NjL>xv%Hq(##sUnp zs#xuBfFh||&)e-`C=OV~v})|AmB``ET8UUt3f>c%&zl5`G)b@3r6h0FXt{>Y0Lw*Z zK_7yR0Y3%wpzt(PDqi<hK{lgm?_?GTF~&r{CL|e4HW6`d#-D*K%6%auz)$lg1K8`O z*7EDJp8PC8H-~yrv!V9Ww^N=}bSHLCf`9M>^*ROju6|R~<-^h!OlpR+Xy_CFUL3A$ zHRcTdpIjUk#1gZ1kYso|vxIPNUjaZv>hHZnP%qK~tU{?kKu^6gCXn5g9%?JlBf(Q$ zlD*gpql?q&)BWZbhK=|1Av4fVDUEf`cO+olT%ADfs8Ag*n0&-LZJMXC6pjM7jf!L~ zChc}3dCQtF3zzUwyddsS$)H%@MzU`PDgFugQ!<w+ZC^M~redpb&aLEx-e9b<Eui<; zcLw4t6gWBp=rhEcs}NKYcMMz!q%1E+iw6b=wls?UBWRC9?{R1LQmCS>`WW!$VdN)9 ze55P{s52>>sS(csVIEZfj#~gGYdMbrJ^VMYxw)KzHhoAKTf#Ag{RC|LhcH!yM5(t& zQVZ=4na>=|m(){-+=JXWce@GsJ;~o*l~IBt^W=a(U*DMS1-ljX5H^yGK9Kc<=**ji z!C0FZgNrgkx6c$l40z>r`Z;pO0Fp$Te2{}agr`jS8m^X0(APGMGv7mYyJ*=m<>Ta} zPo49uSbN9*V);(=o{>4yoJSAEkWq%W3h#*dB+|S`+Eu5k@x?#OeB=>(0cNSU!AASH z_+10VuvKP#hTdwsN+!PBf;GuLP1DL2#yvo7GHG%;3W)s(5*@a>DFbYi)t>RUmgtWK z`fY3)(1*{S3*-gb;i(JTTg<u;7xO{{*ilcG{vrLfBq1pjcY>$bs<5+KMakBR+nu2Z zXHRz}rg>g95L*-X$Z+#trtI=IZ;2SOnT!Qj%cHr$QSB-#zpcS9HYgKapT$-$UwPQG z(e^M>p;*|K?>9AT(FeezFkZz`(8|Uj+gCrZFiW==E4ZZH8Xpf?{aBrh)5_*6Bje$^ z=9+LsnscB~a;!WKk+FPQzU20gDCP(A%11p&`h2_DF!w&l^E;7fJ99EUZk1-#0ovrE zxwlqt4^1xC4re7HDUOorVqc2kz6s41_yOvu4j$qb9rS_19Ae9BBDkosLDSXLww<B< zUuh>~`2sy^<&0TT9cqk$uZrCG;5WEy12Z?;8X?yN%dGlz*Dm*WRWHG_;^@nvhb|tx zORgAX|G(!FTZ^~TUiZV6untb8I50RsH{Ad-z0k}fo*x_ON4~emZfK<k+`P=)yq9}z z^ztQSp;nY8lAZ400A?nE-fJ6Bik8sKBT&<B8D5(iPwU>VjOz`S2d3eWk5}@zCIk z;47>BlFIfyfU(LL{=$X?ZVWhs+GvPwJKa=LwLB`OBNHNPajIuml%a`3bg%oZG!Xnd z9fLN6szn;;#ztBT=uimtm_lD;Xj5s3wYjH@L_CG)MR1F@Hn>?rIK8oYVs^}Sfu8ra zxe{!EOGhW(qWN{}$VVt`itz<>-10dveqi4fN?brOpdG1@!hhKvh)WEQ_{=ACTVE>m zp0bw~+_IL7-TFnmwgS2mL>DA`j0JBeNWbk75}e^Upl!jKAD^Y=G+9;laHdj+GVA>q z$j;v1j$%M(SM2x>0@@g6d=B4EkH490ZwUI{+tmS))xjMJ<e1M-K>n@0sh2fp0RpwK zZmnqyXSUrU-FGIn8QXq<+PiZh>tIIjD4+=liw$y_G{+W&ZFI>tvo3V(Gw_*~d&b5P zEt9XQQ`}^~GAP^f+m91kv<>Vd@KGO{2f!=Pe0Rsk*t%BocAY*>8xLd6j~&u>2Ecx1 zHQJH4^M11wxm&c-NR!L3<)GW|+>v9HIR20R4s*ca>sE8j&hDB&dfSuO<t*f@e$A$C z)eIM=$(p8~UE$rD{8UW&Q+6d(8F+K*^`{iBc?luh5MPRaq*U3_-zH+va?Y4S#5@A+ z$pgjUxc*@<0}^WohbBb6a=GeIu3R3Y>pmEItw=2nw<t0{!Q=K}yMSM9y29w9Jv`NI z35lBQgCGhOg|VDTnXL}>#_WpFHzXy-;6nDiEsF?_4w?b&h8{T_^W=u%_BUMuof?OL z7Cj9OUc`UOHCSSL9exMt14@;Z;R5hR6@V-Z(0*qFD^gdKGl8@V%Ib7{mM+;&U;8<c z3CQ#wTDUFxrpelV-h?gfev|FMB;@naS&(OrPCbT20sS8EG=WB|PRE9s)C!8*_1LNw z-fRIMmeoTMtfE0|2pu-YL>X%j7c(|y_)CNVWzW>jT_HxGfeXMIfD2fX%(YQmI^6pP zmEl@bu5FPZ*BXz=ZB5Bg1hn+n*%D1^vf=!M^z!62_pUh-p#ggR<_g0(@Rn+2sH$P- z<rvMTuU*H4ML~V^nVWTWbjPPTolK)u+WQ6All1~h2ASsEbW=82h;)+|UxN|!DJeM? zE+sRkvp;E;SjI`v_DLE$&FHaE_$*uOh<nDORHgwzG&DxDzHjtZGzGptu9$7UJ+5St z39X^F<tqv+_^mK9(@55yPTlMt;<})#IZ~$?@^52BhBf5piHdGMaS!m_x%!65LW*p) zJ;*KHm1fi2_P0c*vf27T#V&CFShXI#8dPrA?Tt}KF8y3SwN7u}Mj2J_*5Vmwprhl} zA5vm<1VDQPh(=i(_)vsmNI^>um6pI>WP#VV<!V5Gztg%EOQCIa>8}-K(6u8wu|GFn zE}}YegAvO0wZf7}wGZ+8UJjfI?}U&(8TllcIH0HFlmbM&d;wd!{@g%e3?eh!Am|wL zFOc?O+RakPgq`)fI7Y;9;QfgsD4?$)R1LYYYL@Jgq=6?r)~}djAwGOB5Jkk`iBnU| z?FkSRYE+IZ*Xr2*Knmb<XkYU(%R0vMHmwvA>7s3@K#`%cQn+*xWUrYk*197~=Fph6 zYT#*vIoS=Gyv&jgC?{I&*RyvBXdH$V&lW#P74K;C9{gKqvxS2xtU`e>e;5y;3pUC$ z;@{%BmmTJ>+I#}O3$yb5JL?onWGE^>K9(2%1wRwx+ICx^w7Zc6*JTGmxu`KZf=$8a zywtfgJ(6``(?keT&uKWJr=$9+Ki{Z1`I@$huO9P}8HBdD@XZVTbop^$4{$bsr;xTy zr68w6W1o$B*g!pcCI$49AJ3wVqTxV$?rXr?nE&Y+LKqG<n!Ox82K0`XvG^0}(nrhX z3hn+5KCN&moe({_Bay5*INNA?5YXOeG~a}XZ7!u>f^0`Oz7v!Gad3}2YJKqNs++n5 z9Ii;wpAJi#W}vq)#JR$NJ~T3IDIqgn)4i+%x}Y9IGE(6S=D{OlDY@y`Apok?T`v8& zbUR(ZO+K;gSeDtOSVfM3WnEa6LE}gvg{?(M$u_l}w*~adgCNc$U5PLK>rO}%BmTXl zYzzn-cG?N3Q>SI#E&bb0?V@wp+OsgQ4e-vpe%I6Bl?QYn)MUjWF-M>dO=mo7DcrR_ z;=(C3Q;Xa~)E}4<EnPS-U_DHVMc$>SV~A%S+QXVKr(7NDR@_Lp7)mS)1qd*d<8~?b zP{1ZfR0EwO8#iznMd$_le+A((&9C3%8dFkkYfzyh*_{qhZey7f&4L+UJYp6Qk^XTy z5k9jlPg(piB?PE-#Qk4e#gOVgvZ!soANUqqvV?!8;}!b~Gfw)d`q7Ko(^C|364&qq z8?Yei=)^9BP)L}fc0Ce`P8z>;JkHlcr-ng^kas%@g@;ZUx#Kts)ekWflx+YzPAomD z3TXo>Jtj`RHIE#JjUtn@LkKqk4Lko(_C+(i5VYdIOIXf@_^MIrcAatVSC+R;nYIIo zLbF$@Fd>j!9YT}>`ZhcRgaJT1V|!)McC?27nS(Em+)lUS{0H|F4FzZuh~Oup<cqFE z_bDjX^p!_9=lg)!^gXl_IzT~B)@Gy~oeXEbZr~^c%=04)7$^c~RZbQbQTR>_pK<At z<=&Lv8U|^4WmR>;#SQcR+#_cIcmNJ%&Phfm^q^XWZhbIF`Z~AnLrWoapsAp<B{(yo zy>(bUH_)_)CYK)zWliptL602zVdBFKy_hVSBS)Y4%2_0=Zh8<DvCyE<Z{KBF0tjo+ zIytcashsnG)~=jwiXLbLl6eEwas|_s)5>{SSYGhs2<0&)i4YlLGUB#et&-<_*hc=P zm;ar|afANlsmvllcVvKi>s8e=_?M*>9kyNI4jQ{2xMR7p+=lrw(5-?LI4`0H<F;<> zz<l%dvnY3ZxmcpReruYmfqw+f5hfJ-5Pj_y2k{xsuy5w&)^Tday#%!79B`;7Duo*T zmQiY!#9^?`S_0jDsR)GGCK-P-cNTl}D-pFy^Fbs&&@ZQe{C{g2gargTipT=$MRo*_ z;#Zfjo!Z1=+TeeEO6n%^eW;H>@|u1JISbJ%9FxX2Jjb*E@eCmQTBksE_Q7i(C5~;B zKjiU)IoFZm+8bn$Nf3Oa31cIMghM`~<|k$E0sU@&dC<Y)V4405bztzCA=Lqlo=*Gj zEGi3X%Mx_7>20w%)X%6t8}P{dB5o{hYS>Zj&qIE=2uBTR=EQ9Ubn_W#H(W$dNpQEd zmQ^mowjBR(C=FY5+SeES_UNeznfT>x#jJ<S-_WR68ug=r$)z$|lP`jmiikLU`M&N? zvxOf`tKZ&^y0SCFwyp=~797coex_yXxuMZ=Uw)Jh8_U@3Zd;qXfd$6A*_x(|n+)i; zdy5)FU%})jb{$V6imEpx_M8vfF8Q-Sh$BAN6ddDDL0yhzvEO40&=N%Zu?X$yyuW3e zMVFxQD(HC=wh=1eMP9Qh%hkU3D+{0kWlP<A;p`L#u@N}sN#8|Hy0{<mag9ngS|Q_< z{oPwZmN|73Yn?9_9ZC^r@_GP~V9t<%L5-on0d(;<m7oB{v#~x@NC-c>nn0T5Ql8^r z!_M@5ZY&Vj(Ug(?kB#(U@Dl&Hom0T*NTOpVzHYH1s)OKhSH_pD06)fDT>dB#Hry|M zeIu9W8Q<;VoyBTZ%0;B#K_GedXTr35W-gds`eY(DtsLLbxfiCl59#Q@x)41`(BpJ# zE|2~r^{{Hr`2g*TrY%F;T9LR$&LM3<!QqFRb++1c+N8g+Dq`71=EpNXlJ?reH9Fy7 zJF*kaz+PvIE2LO!l75ZBe$tI(jl0ke!&a3Bwnd{^$OD-A(j|+-zX;hWR$uBA!*-we zH{TQT5GdjDiJ{hw*s+-YS`#g{!{D@cydxN&J9d;}t{xKBuG&}+ffi&p6w+IFFwybK zQ}X8iNiT<PAE));&vxlJkJ%9Q8PJpi`lh2uMzG_sQ9Dz2?F+@Wz)O0})fRAA$b^Z* z@v9fiw;r^B{(7T11C^8mYc(OqtC-Tr=@Z7qLRza8a4cy;+qw*vxyENt%g?iRwmI|c z=hN7Ec*w)Mfav3P*pJa?Xrsu&m51u`d$d6JojwL*^v_G`oM~-Y90&AhxtY{3c0md? zz(T3V8Um?T?L^#ixIT>T$5B~lvnHHVkWtGiA{54nf)6!RYJhhGzzN%G1VnA0%_-|` zAv~&^5*qO~7)ULjizE<)U9$<GGD{F3eYY<J8Q{Xu56)y~O3GWcrJJni48KTMN&CEn zjPaw_T&)x?bNljb{Yn{H1waXbP1YxuF)&fCLVnA9wsm|B5YWs?##3cKaX=q^Jtn$_ z9^9;!4wpQ21e)DSe!Ms&Y#mnhWc%N4!G}F1J3~4!wdj1JkRUS*(TZaF5sPcz+9CoL z0hqVXlb%KD@FLD|fGU<Bmkh8%1}{N?UYIhJ5a?Jtq<B>UX>6G*HgSl>CNFRR1|AYP ztMO&ULJe30?ScJ_WTR`JsI)V?yV65#!F{n70TLymAC1!B_ezkKdL4A_`i-sk#HGR~ z6R6vk$7wzEK)wPn-Y$6u1!M+4SOtgq8U`|IYE(klxw9mkGSDWIh_hRU!J$k&fVSQg zCJp<?(Ef8n6~rCb3iw2A(9!s8<0XgV9Ke+Ohdq?-p{_Tg2Vtmr)`B)@>`QEfI~(Bt zqYbH}4()U<kboXQ+}&F!jL;9CrL347%g_il1{NqQ1r!m>iqsEtwul#>C%cwNAVE@S z|5dX%E4Gb`uL}szDHrP$af;uxp;8_l9UM4neh;*qo`(L~tjU1#mK?hq$SkRyXqGt4 zIyx7AU3kju4&iAP8(Kcu%80BlxdB}>Sni<dLD_Bo+Z&*JuQfxFbbMBw6rFz33>tNU z4=@EClOmWarD-oC6dBOnEb9R-<p7#y;+sQz?%Eu^J0?u&7b&=Ggl{xj@pAnOAOp+S z=u+r~RlOjB7==;-k~3kR7&Cx9UpkDNgznqG&D0<)fdotJbOhiUx%8xAVP`s`VGIA( zF$38jN`Ef=*B|jA7P~T;A@1qg5W|yrHu9dP4ag)RLgW9KAC@b0{r3Q;!nm<vE0!R} z#57JnL&u0h*eT(LE$HPVRcq3qcr-VF);sjfXU^h$5}IDJrWt6w^c|SF-a`F^0=fqu zgUmQR*H0t)ePj9hXpNQGCH86MdEhbitYl$(+W31Z3mrgbHx4Uv+HQwtK-zkYWlmJw z8q!8a-1_!gnGA`JrD(_rePQmkK;OLF<@vco&T4SB$MWb&q?JK;oV$~nPVv^%Mv6?@ zB=pZ%O~p9X>Px5i&G4WZ;b>Pq$@n-;?#mTAvgU8xuks#hdTz|i-{8B_>V%~mC$0ZZ zddCe;cWgi=V?%|{ct{VGUehE8%C4w+Bo}5krRAQ6!XU4JkgB&DKnfX!Mx{o-OZ1&F z+r@eNmc+-Cwrm+2smKWwF~<L-jU<pCzHpZ8Co~vl5vmml@`DW&B955ML@UH)OxdLP zFN|6axdi0MnD?(&oNNWL1-@HW5oh0cDl8%5=vP2<=FuW59)k*7fUYtl84pHhjAkUc z)wrC@&CTTk(bBMh=7V&ekm{!Iqv-<kRN!)8Q{XJIfpRuB)b^}3d5$a>_)JJ`0>vw! zdCn&ZHStP&a|Xjc6RbLu>sCk$X_JuqARu6CI9XglE4tXS87I<Bg2}qc?Rl0j1QeB! z2IGNKGKGz1(+E-5X~&VZ@gV#dZQnm5zWZMlGtjBU5^UE;v&0^LdZwlnWgMdhM2Jwx z=<?~mp?Y$0pkR^7=$j*NF^7V?l6@lWw=D9j;nA4P12D+@#Y<H(AZ!qc^D-rx_#=W@ z08EAa804yI=+9jS5-qo86Zhzk_BR6sI(A^H719?0c!R^qC>;Ov9kCE5Ut>DOO&8fu z_W|a1d!nPgMyh<qVxI#n)DTz(Ku*JLm>vv<nSqw?v*$Ojx<XR-G5#{f@>_FgC756$ zGAeyj){NEZZBZmUotT>-EWsy}wQ2}SspIbqM&eewz+TF-UBjo%w6)uG1ZWmU+MzHi z&N;|$NO`4u^Y5D(@1i1-)Jx%AN1{EM;k4HRdd~&cJ&x|Mj0}n`rln^&1%=j?mAXL& zi(svo8s!Z&-Pe$@-V><MSVen;B856MgZ=Z0@UL}>GMoe>0j}>c!?S{;1oN=wrO0s< z(*{2tQUGpfUB*hyA?NW_9Xqrg7Own1;S?TgTO-Qs#VAUV#1_5#!&tOD^sIvhPau1~ z-DsQHv0>?T_pxKHO4(k6PuhPM4(MQKh1#eW-mzH>7lClJml`Ry6Orx6JdAk)ws4pz z{?Sxunof3f2{uH!-x5R!*SZDmcfXa-@H8c=8bIq5X0C}e`4QM<%%q3v0sbor`Pt?! zpn*5Ekr>QgeK_KtY}^;l8hF)T&hE$7d6o-vKN?<1NzR%9y6>fytr*EDnX&DyBiOH= z08QV3zPBnqFmkWfIo&KkOF$Q*^OSm$*d?x^M(B-%SGFX`k0!)-%>D}FSox;Z*uboZ z)W6}tHdl&nSV;Dd%x2YxsK;w#fasg)CqG9aist>Sx0H4m0RFVAD;a2}-X4RY$~TCZ zc|+Bb&~q*4@R~h*r(cOhv=7=X@Gf`Wq66OHC>ius5Zg7<V^xr*fbK<;bwO#ZXUB<8 zF`Dc}M$YTWqqFpJ@Fi2T7oK|@^{Ct!#%ApkHxc3}<W_(t=f>oZbk;WwmmTFrGj3B% zr@`GAJ_<1&-pDZjrX<E(%^j=A_?}cS#rK`wOF-w<qIKr!KHsD?lp&BZgBxXxB5b2x zTfG^X4~{G!d8O!G&?$s*Cv8}~e1U5S(rIC0fb$t%lx~Ag$DW@5r<v3ksL;W1HbWtI zqqoy^Yst1tc+&Kl_Uk0u<!y9aPuUT{!|jkXD^mj18Mtr0I>MkXlTDgirRe*Gj)`vA z&q3Fad?nuxnKN1kmU#boJ%<9sMLo{n2wesV!ou?t>Dv;PZo*APQ(=JHI%A2c4?ix% zo|F$Sxy@+;df5<{rU5QAFJsGld$Wmk)^V_8@z(38#Q_jCUIFa^{yMv7^!m*+2&4tt z6-*c(=8?t8<(HY>51opGn76(ha#gx@IRg7~4oW~Mnre2WH2Yi25z(1h!tsZE6L-t& z9|7Y+yL%>PYN~e<9k@1@ddGVWfp;?>qxs)jj+ejlHdHOf81BL7^U){K^+;awV-;r; zn@7Dy^~8-)?9wMja$f3Jv_NdZ(aOw(U9n2EJei#Vj~NAus8@V%ZjKf7ho1j4QD-#P z7^T-E`zF-f1Eorg-E=e>$`2OibLD-tG=INU`*Ei_^Vfs2ygC}fh1gqZEmdkBJvIW@ zO`no^w}d4Om>bX$?@APwn5S`0b0+YTwE`AG(|%xUzB))nm|m&F$rVPS52Y9(<72QV z4FGAbGHqjVU=2Ws)T1)A{T6?7A2a{JngF-OMpM$4nLA!2j6^_-FXhu4-#$X?4gR{I zgXfj|%iJbfb-o_iU~|jvo%Yt)oC&SYnqY&a0064M`9k+iR;HvM{A323SdqqBeTzxf z`Rs9bAU36sqhTI^h_qq&Dc~hYWXj_xb8Mrn2uqy;kQQIzq1CB}ka=b!@w3vxmA&<e zQ9B;yZyYqZp#k+4Z%CP{6=2rXq!!IMp_!bTZ)`%UW6N@e!lWA=*h^JNYq>a7Q#+~M zJm^V~?L&lQmZljCQTKBB4z6YOM@s%G%q){VAACJ3ys(Ot(#1jaz(mQ12yCbW=NZfZ z(7yOR27pyAi-vD8JMv$B&dfmo`kGcuS2eZDSrx)+YD{OoL&v0RI$#I~e{qKigp^Y7 zp7pb-m(5jS9oX#op#mNDaU%)iIZ`LUq=N^MWl07PLuJ{(cphVhB2p7yMudi>T5)|? zPvIdK7EtKdH21P)TN>rMr?H3f%jB{P=o<8rk=k%v6nY2fF07S=QBqRAuTO}XE97U< zsLMveB|%^Vdg!n5M2PqN9VW|pxKJ68@->)%g;ykFUW?IAhG@1zV)$Al)1P@}_Ca(f zIa8t3g;tdcYcZf7p$TFQ&N?Fg+_3OK==UJA)be%F>4lTW=lLsb<H1nNoS)y)a@-O2 z*5W+Q!FCNhc*fZ?5O6Z7hiXS=IQMcmGQfa}b!_{bqIW*`C!oh0WoX@oD1dd@9sux+ ziNH%UYvftK!PG%`fx}a8b%b^!y$dDeP|#;lUFC&PUS7VL$F<JTF$yJ?`_#@+xXvuY zek~FmQP3v!`)smpg%+cL)16RA_D!N59szw~A5fwOi&T3;#<+Pwkxz$e^`KeaVL&fD z6{JtDgwaus3Ogq~2QO%3opK$Oq!pk;mt;IZTI?$b+se)8n6VBgNry^(QJWvo&pszq zStMTLtAQ7P6I=PE!p;CF^7T9yUNpK_d1nr}yRgfw*TVdOhz*(oQa1xa=Fooud(}q% zQW2c#bkg$qF`46-_-2@b-W{}94G4V7Lg;x^;fSJPDU^alFv2_$=1^o)0=fl4<|fRe zyB-TP!tkZmZI31YeT9lF3_X(vaOyWgSql0jq&`OTtoh!NB*`NaTe_%{E{K!Z#TaN> z9L9&4l`tGoh>%~{h@7+})C_3$K9GCcxmG~I^)s181scNgo`nI8KxGA71g79{H5XK* z!pd$23Qdn-Z7bZW>^q<}&z%L`Wgy##j|T{}2vQ7=K8=360)$wQ-?M1VbV7D`+8xDN zkIk@Yad0}awZV7*I^?t^PMQYWlHvV9h2?ye)Q{YdM3%^uae&z^D-_W8Lth(Bp-0i1 z8I4%D`GUat61dP+5J+JpdU@Bqs(`M5sxZrk7b>EbLcc~ysTMoZ@%w-qP_9hmpl*X! zpw&?|Q0ByI4Xp(91#tOrD4_3mAurZdwpd0Kml`!>e;|aI(vHR`%*!xm>)h!ndIv2Y ztkc^J5ET~sXHla#KsTfJr^`?8;MORq&tYGTCDLrcN9fnMLPiaCVEwo^3+!M2NN%W+ zucie50UfjpGi_@9)uQl?QJVzV9cvw$TZ5zdp&EVWF|()-3cE!v7;+-jkH9XxX=EOW z3j@opP3j}ro{o(8A@if3ofvCn_MO_t%?D&yO3&E)?yK?4vc1%6uH_^mDzH$t%~r)W zJ<r&J#wU!phIZd5Ycebk6z7xu&a5>f{Tr}LWea=ZalSf)<%I~Hv44o$B)#B()*)NK zfCVS+X~u4|0a5YF;s~F<^nPi0P#CM!S<fJ#6@WoZEQ02<4LDDaT(z`2LRuT4<4+3c z8TZ1;Mt4dx!mXiBwAQ@`Li!+N+Lpbs;Ht3=J%&awhzKbd*+k6+a{Wud19?myU>@9Z zMqKD#13DUqbn+!|@!4chRYbYrO4s6Z$=uHWJ=@7(%4aoF>Yc!19NP@g5hecUy6lQ! zI3+&<>(W47jIOMVVrX29bDO<F@IZDOK*UzmxFI*BAB#t1X|DpWo5~rdm&_o@nJLa* z7gNo>F&+4F^lHO_A~2NRO@bN}Awi6<%rG!<SB%|g)5ndCOo)A?nF!p--wuyoIAXOO zYGtLuP;2sxSOcM$#Ddh%-~L8aAhFgKjYlelGNJr{9=8HQXTok;h@PSE-ZDqE;LW<V zv@sYRc@G2Q4npN7qW$qTY+HOPaG6Ru3n_95Tc%LA0fM#SA0Bx(dj&SRFXw7Jnv0VH z`U-lQcE2vAJvf9n(Gx7yGO}c+$K8Jq%0M)Xi+mZ3H`X2NgRwxvM3=$~i&O^mnFW6F zx7iCJrNKcH%a-L-q%D#xN&~F91YEA;J{wQoYE}xh;BNt#&e(!6%+m~`zxFPNOhVqD z=AJiwg)-LSwo8`_Lzak#g~kSc|0g4@!#}hl{_RFGU;BkH@Q{V|093+C8cA3oXkr3M zC~~8l7LD;beWVWjA3pCqh5+rn+f0J=Papbzp~)a1dAbH(xD>WZ0$@rw%KA4(sj9M6 zQ@!4RW?q&^Mf)YtnHX`Gc4_9ScrywUK)fDe@_``$u9OysqFjX86s__{bVkMLXD;c4 zJwUa}NA753JhAYavSTK_)}p(|Ey3u^^s7qTCDAW*{v<<VvM$(<oRYQ<y%g>2RE@#9 z_OjNZ`c478bXL4zBytMGAg}JNugJHU0*&Nr2+#*y;umdcU*UC@lX3F1)F92>2*-X) zgT<DZ@q$3?SO`^h)RXCvfsfhn1oVcfd-^dCwTVrES8>EsL3My-8$^9P)5qXZ)90_4 z3oFcWC<7@u=}bezICi!&8}($Vz`5|!^X4b{B?0mO?SlqsGiVbu0=|uZ4MKEFy=W{J ztQ7)E0Wp#SXa*q<VN#r6s^V(0odJW>ariC+iVDCEsW_-@6WS`qIM4DrXyF)d;7`CD zN4aM$dK+x(F9_lUVF!GO%>Z4V__Q$}9@NtEdKsn%)K3hJ-emz#;yQyCXaoKr-$1CP zuz#RKaWe=bX#{^233`NM%UgasHXN=20t)ZF)9_Cd_H3t%@Qa&_me<L63Odt1gc(wL zF<#(=cgrgV^lH4-FgpopZHBL9GH74?A|p+U+n9l=E~J2<%|lw|L|5RSVAShU$l1Gl zzP=ja+4tC+)Skznu$r+2>+gH`#jHjh2YVqr4vjyNH^}_jJlYL@=RI4M41`c5pvpG= z1@LnJFj7?bDM)iKy43d%7pj{I<6ICI(2;e0qg2?@j{%{VkY5_0+h2)<Wyn-ud-6C4 z8IEbfma3q~mI{Rdlm=`$4p+b+vujR&d%C^(MMyCG_p5mQCoz3qLOkClD(1-fSo_;T z$dA5lPpsDB;2@3RYrI>g_gB*&YYq4LMc#jZj0o}zh;OQOx*lVo->?)-RF1}<Y9mDm zK|Gvs5$}u8M`k?zn;<|0rxDH&8hO}%u0hYkuk$FBt4P<Nxr7Yza&PQq4(uSwY{)A% z)9m<hH}4|%FJH2azIq0`(F2Iz`OLEpObjh|s<fc}VNKMxmbd07=;Arp1yX>*empJu z4=kgxF)l)>6&Lm_B`_Dv-)rpb@yeqQPGC;!!?MBec4OBAbNg*v*lc%nyqkshxeA}~ z&LWYPRN@Gzay6FJ7z#y(^8n!(R^{#ox8v*O?!s@sY#-8wlRUU<O0>o-ObJi|`T;JJ zAKym%pQD&2FQKQMi?)VU%@c7)54wS$049U~_!l#QV4l%Bd`PwrQ>*C-c$ZmuSZhbQ zb+{0#<eEnMwCk`UXx1r4TY=d6=r2PHe^q&_RI>;4=OMO29BLG}c)W*(M<XvRqUT|6 zprOyto`K=PCdK%_3`>Y}y`x1i*@0tX>j)dTMqkD5K#WYM@*1uc=zi=nL@gt<3xpZ) zHFP#sN|f)yLvUhmcny)$(WKk)d=<u{Q0XJ)A!k=69qA^z2NS)|iSaePke0nT{#p+$ zep&prMO1{b!2Kh&$VbhCYlw7@u51)Xu~q4<m~Mu`=pH;m4O0Hn#99cGR<7soShSu9 zaXcm9_32%0TlS^}{cb7ZoWPgXhRcmn7J9>XuNa6-3N657Y+Jg7hxk9SNcfX<owH0m zSRZw>k(d-!s1%pdk-SIoK3Q{L#k_1n`f<HjMp+7UDJ~>W!83BOH=<Y;bPEe>V9V*= z&e%bq#_BoEz&tCejMGwFhZp<?>;P`;hB$mkW*Av5+#zOnfPVj4-SgZz((L*rkqv_- z`6k?)uD4+<M^7qg%VY7KuswPt-HErwXb1c>-@#Y$v(x+r-VKFKYw=_=tR1Tav<#Qk zy>>XVCAaat!3NX2FlzcT&bY7eAb6dlc>UYnQEu{R=CEuOoL<!)0&k9Y4ga!;=3uL+ zts6zQ2V7w6r5_p_Z;fUIG_kjdpZI^~XQ$e9(7~`CK+etA>AdIL1&ouEmg4H-*PVg^ z^-f8il5cEqw?<#VoyjPMH?}V>2~U}owQj{|*bEmzu#k*#q2HM$V|D{Z`hi+>fbE^z zBTLWn$NAIC+`=(jNQZe5*6!>l+Bq$uyrfYY=`rh$9|eg>?*E6?4^%EUhBKlV&^Ka6 z&VH?~Z<gqTng(W1zXSN!XJ)dSIZB_yi*A3?bs2ZB76Ahq&>L~$53zJ(v0oPNeHbSD zaP&=VD~4>DK2>H(Qa}`qrSyGXm7X3TFUece-YSW_-(s}ARmSTUZK+lFm5<Z{@C4jS z)2$fLCOp^~Sir|b*K8sWVsqFuAIFRF3+S`PL&Gr2@o$IIdvNcBxeP-h?U6vu`K>t& zrTp@HFK4TTP2E8AI00;|#rz*P7obUg9t#mqB}Y&@9tm%z1f&AdbnIY0ENXP<aWIM4 zTaTG9<F0NHvyc!qeE_4&4hBOrWBJ;M8pk2bM*Qq=wdRh)%;PjHY@z44)w>w0_fqUY zvzE8h7w~n(rP~%Rp?8@tW{o>_Z61c}VjAt#>U1$y<Z=1hFufg{gG<AHf#-1xp3cUr zqZrH3ejbRu%@*X1xc9-W139&VX2-O;`J6i}7Q(RYmEnY2XQFqwI9LY`f_re)#km^H z@;o!$@r5G06Q`56N?w$)rqXO$FHcoKn=!%|E;=-0TUPUZfOYd##Iihc=raSa09%7s z5?z65;B7>Ic54lW{UNqkD6;1mKu*HlUajjvW>ObJF5~O$HeXdP4Hkz$O2gS86%n~S zry8;6aB(ILmB$M1gt1#E?J?OMKP#LFn5F09rZwk7KQl*_;d@?;S!TN;M=QP0dd>7V zv%ez_3CNLnvl$#(iG`vI@^CCqj{MASqrb9GVEp!g{^ZUu$2<<c7@e%eaMnsX{X z({_ohsG#^~TM>4k!0rU7*Kq4zEGLW{gqJw)wFe7s>>Nx(V~nc!X>2kK!G@RF_b;M# z*u&OKr9E&UY_w;eEDkyckBF^zU<a!T3(7t(UFO1urC1ez#czG;@73rUfFWw|=_mLS z*;W#p0J$RB3A7Fqy+O%3|B-P6ZurryRh%qcp=Y`=MzpduV@&Nr3uq&+4%0jmEMI8V z$qEDWto;@C;phpF>bu#XE%lF}&YR;k)k)C>8qhtj^nx4?!|%c9naM?n{h_n4TN-_` zQ7(U>TZ3)IpyErVnEVR9Ask&gJLcWly(iWPF&UJi7&7pT(s5X!HW-%Z=Rgdw;rZSA zg79zc980{+Q||E|yXNrZc9;{VaD<Jp65GJLsYSFj!@IG2&zQV`7Gb%BE)VU71<Uc; z8fRk=MqY#`G_$f47H2Q~&Dkc}m@$I(n>KGPpPZiv=#+3bW8dBbm#`Ni{Kajw941@* zcz5K}n_<($>(%ZUNNi))s*tv(Yr;*4-SB<vc(pEcA3O@)cdbsbGQO=*FOJe__=i2w z>CAKO6CyMmXRm-&K1wxsZ1nt$lg^n|_*T)lD4^eXBZjAa4xTn??P%iyz2{tgD;)-V zg@d4gz6AfDy)yx?tE&3`N?H++K}8S+w8&tA0!=y+%GFXRMA`x!K&Ws{liT)6CUTRu zK`V+1ipZo03Jy#%C@6?HfPe!kpdU_v-~cL$uObSHz$?P{TWjxqraR=ONlNjp&x6gK z&e>=0HU8H`Rn4k`{01Jh=$)M9m5b_&KSjGZg_F1riR%ug8FtA_c%}IoZHtD_FjFcJ z<K{TK>gIl)BQQkOd1{ys(lkG&x;n|d(j9&tpDDz4IQO%R-KYTvV<>Y5>^kO@ZzFB> zsAWn=_7R)pOm8zOMGbhX=}#-N-)oj*6PSft`xLnoapblWrT1121Sud7LGAc_@?L*o zyyGUP^gqLnsL*;f-yG;AL98I#p`3j5N*BEYl!T2KOxW$Wurn?>x_@{}d$pW+zD(wK zS+iHWku2nW28e+8fn$)<&|wlmFP%%6a6{4j$x!1mXsI3i%a!(RzXZuzDm2Tc(39gs zb+aHKkz3!S$m`z!*-X}6Dstu<c!ah=MnDo%BavKYvTTBvvzBr!8dcYT6=|1%rxP?U zvYi&@U36N}g3wiyp(nMkcbP(R5TQ=u4GJ0&c*jZO&kVU~l3RY8XssHXck07(D14#S zdGL~XcreSFHbz40ZhZ1J8H`BYxOK{V)pPpW%UHR`c(*6~OZhB5N4Q6_y6XsCCbbg& zmXC98bGr$#$u&Ex!ot6@_4|Fd)#2Y_$l!QU8;4|3#K6JMe`g`F1+4419=eH8p>QJ0 zS)A@rpUu5@k6lr<`c#y#?5wW`Bwf^wod!+o1@(HFeI^l0&&+2q1`W+=C@6=RC5PA{ ze)eiEFWf5qPYAQS-?)1#M$^xa^;NcWdLJ6nnoDx+m4){5d<t7gb-K|3k@U{&uFw=D zT7_xGI#-^Pnb8UA5oPbZh_u*w#V#JDV{TXfY(F_AF`*%I)+A+it1?7g<cZX2iwjuf zn2GKz9kmbep`3A4_?p%SbTZ4K?A|fA=wM!VO+y(or`HUZTmY6H4%btmJB(7#0Eu^; zhKcIs^e0n0VQzPgyVb{=+%-8|VCbW_aAlQ4cjS|48LAS&4+h8{OT0DpEtWC!fkua* z4wW&W=){U5<*5Oczr0+%LYqqe2!@3^g=EswjGZx}Q95l!_RPs&I2(Iz*&HF`+t#Fb zt%j&MdwaD#G%S)}OEUx1%Af$WRlCBMFc7@p$jMDC(7AZGv1;8#$Pm8Q0o=$pIei*h zEjR=i28W?J?12n`@%KR_Lvtp;pqcr!a4pW^N(Y}99E&mn>MX2iYmbswv=q~LBizZt zJ_vO7gPjdNFG|F=#uORCzAbQthlxPyR>)&)o40DP@xF^Rtv@1j8nU&QAuY+ra<r;0 zCb_bYp*}RvSNAC=A4M}JIL$N@vvUz-ozjZbSDhT4L<(oEB@@1Y4#SqSqgY1%bw^v@ zpsd-2TMcv%8W}O>18OSU)0ob+uw75l#gH<;%LoL-d3A=V)~_P)M}`S2>Rb--kC2x8 zs?7BCQ+CrjDMEgj)_)q({Ru~|MulgS?BhgY`QSAx+pPG)$)fD{Vq>G67ImobDvmUy zZOC=drRLbE{ZQOajXW~t<rQ#CN3qn_wX8_>jY8Sj?|PbgF9Lm_ZD(RL8QL0~K#o~c z0%4A#(4~Wei85)#){#EI+9WT-91meNU{csKycR<v6*0UROD%{WH71`{lM$t-QNw$A z_z+Eed;C4e6??#Po&hn)FI*USWW=g#8jmoG(+@&ItC0T-ED=K;b!W5mc#t=Rt%C}= z!$b;A+GvG2jVUVZM9hEnDXzfABh$xv2HCX-ZjR0QaB3l<PajbHPgujifHjoW$Tl#T z_kSEIZI1guB>0z`!CzXURJKL2$g5AatMxNYsh)9up6lWk6>|{kG}p*J3QKfF;=aHq z`yf(;8!|CKxBSIea)%byEGRBp*2x%`H^BK$JL`^B(a@1%ZoAa@O+LyV%vTqRo^$F! zJ+>{fG#JJ;Hl&8}E8XJ*i%vnM-^d-(4=uN`R4`k)1F7Iut|iW0K=70OFgUQf4wFOi z1)XBlPWJMOT@WSx%V%1%3};#v`;dofcgS>vrxO>`!5iDtYBQr>(yMeXqIp}GepNqn zZdgvv43engrnRb{kdxbDOav_FpYCxDU(a4Y!=2Z$aM#>Nx-N0%b)bEDClqJ4xJCT0 zMPM2=JHflpIku&4h7YQ`y&uJ)S=hJ2;E|)3Lfe0}W6}nb7H^c)Lsj#j)mAJNIXsfm z(}9An=Rv)&r<wrMX8)K%5aK(yH73|V&cjOKoAO$&SRf2c5^5anKTRLeTuIX{?}wVu z&vFxfwzm@HbZDZgi6XyeH#H9-nva*=eP#S3)Nv}fF_(^;GUO7ALsRIE5YYWq;f8R< zoa}~4k(i$0E}yuHybfL3OQY8g(%4qYPuSLk%C?+HQ}SvaYzKu~`<qsuDlYe9<m2IZ z5#*$A9B>Uz_#C%`UQShv{g;#d(1KS!7HRBg=IC&?uhLO?eP7LtmwzL)^ntU#tz)(O zvbAO!$@|Q7T%BLlB*&GDT;1tixsC3oJPgITZIlmqQu58YENKe2ExVH8Y7(`lZr?eG zE=}Rs@|6+x<PA|Zl@57>(tb2(>s|zEG8<X*B94O5gHj1LO-#Bkv?kY$36iYLb-=c7 zMYy@+M|^Jzhu3sK6FGTX@xu%Xkurf*OsV*A#=4`>YOKOp4?4fKDqi)X+0m3~P#u}l z=P~SIFC@{*!kT=yH#1%W#d(E_^YNe>Sz2)9U}|_{H`plkPF1c9$6CcXkCV91o)Cad zRDzdkCM*-U=1EAMs1P#lx!}$<lhJRdUirk;J#WLDf)ouKo~CFQ@0F2exqat+_?#?< zZ5<4&tIZ06$Xl!%#JeBwHo{BJLa!y6IeYn7&Wwt0Ek6Li!6LINe7O*<r7!x*AIlV` z0@FjAN^&ehDuP-pee`7HX;4t|9fYqzKv7P^zR1{2)TI)lKm4tI-t5n|KKYo+NIP(> zm1nR$ELxY{+@MZ|BHT0GJ^|rpuP~f#y6Vlr%GHe^TcG0A+*)dbveQu}uUea=${NOX zC;VNn8!>4Dp5p&<c=ZWdwIE|T>4a@9fW8(=yKY|LaD`uoT2jMs=IWskRqe;j$)2rt z0j)&TMltJTiRPpY6?jn30OIUmP}>gGcm^8HMMMYaR1W0$T$q|cqZ-?th&`#2lx`v( zh&+mS%zKqQ*&)vJat?=u5ANj(W{n163&Nj7g(IJH1;Wc5A-Mn|BXl^xU{m!vy)ez# z*CSvas=eLG$!|QaWNyddh*AWY*Lv~{j(?VN%l!3W5o{-8@2Z6raR1Bg!ay*rN*~uS zyfR%g?0CVwJeU&<sOSYyfkKIu72Ytsft=imAE!vDyHw`56qGQV0VcCQjh><F+TV6F z$oT<)ciNT?2<9l5(;B?J4ZW-)z9c(A8%ZVVmYXHF`i@45&=k#%+USMcQCK#xg1~RT zbYZa^t)W;s$B|q|aRuPYxAq|K%e18Y9L1{lEy;;IHCDKc=bK%H{*^r)CAr<)U%JdO z`-L(R&xcw!W_4g1)@F(;K5>W^gy^Rn3a>h5v@P8p#TFla6$4l=cC>jvM3VXn?;yz| zY2HMUmqq=3L2S^l1{UrskfTk%;lTKH2O&=61Y(qF#FSaiSFs&b3#fV&f5M_uh&vSu zbbv3(53nR%OJ3_OktK^rh5PvXH!cahMwZJv*%XAS+zR{=r@}tSZ4v?!QIrg4we`2J zJiNP;ETq@)Yt59sF~tX?uNmOdA$3ho-km%nxrbfpXBzaZ8m0r|HQaNWgG#Q!Q1QY@ zGhBor=It-syhji-?gS#4B5#}w_bP}czc-_ecs<GJ>fi1)EN-r4yQyZrIJNgf$*xJ- z@V{>P_NKknwCXR=DK|g8S>6rH&F)))6723T$)8ObX|{q~&J$(vo3V|ZS0Zw^Q}qGg z#I$7-B$`WdGs(kvm9&th)<IjxLHo|~^D)ooJ#)y#oNE%h&^n5pE)8@60@A`4(31xB zDq-ZK@Z~8Gp5Gvuh!{oU+1KPLWPYY~`_s4=A>wQB;nh*#LoZ4+(e1uWfD$x(<=*`f zG^wfX)(qGKFjWGAL2*=pHB=XUg-QZX?>HQ<g|<yW<eMhT6=iZYqh~9fRoy7{Pcw?e z!Lcugxt-6hFd+3F#PVedUW_XH>Y~E?d$qq{Vsg@iWj#HewZyb~FaW*fwvW8sOO+Hx zz2(wih-$Y2`CMa=JW=Sw5n1pmb#@SG_46a+C8Y`z*s6nsD(&%b_yI{$>tX9-DkYSw zkP+_2n(ICTo=Ra+vMK7m67s29stWz7l-r8^3QitV=HOi8D(g${;wA?~oJR;}Pw2x) z!OuX5vg@iI{V+F6w8Wi)mdM~ylVp%(8K-&{ya~=&HCb+g!BN&!MfA&jXhXeYtNx8J z1=*Qjk|NvXI`z_31r=K;=@16^`)K%k1F`zuE>%uXF%k-fRn7Fb2&(IZxqT|7V>kEn zWL#ll1ynQ^$#W2Zgeb?><w1leB0c2{KU^Puvmn3oI)DMAz**x|n(EV}+@45@YJazu z7Mqn};yowlsQpU?$Dy$$g75T|QI&zZuhk_>jNxchGqW!mS^h2xiTdmT6j&FQn5$Pd z6?P3el;V-cf)sS;o)U5D{5#pEtaT<oF#ea_U~OOe@$pF3Xbs6XFkzz_l1HH|-6*{E z4m3nbt_jNC@zf>=rYuiYiYTe$GEDmFCXK6#OI-;AsxA12OIyD!1~oGr3{F)NLPztG zwW(n~lo@8uR0Z+nDYIhwR5nPne(RwULtrwORF!c~u)=HGrL}HSpMFxB{HFIo^(eg6 z|G|tsUhR~e@T=vXeGhk8!FTxrB=5f7G!y^eG@j7K`Mc$xgeMZdye!h!hUAig)Br=M zhpZ(3PwZ=D0z<%x%I%sr>Cz0d+Z`;pTJl-9x*3C>*aBP;8TE?~(9$k_qfZV(*jgGm zss41dy$Dbsk)NHt>G0v}A6C$0mANh}(POhH;6Ev|B12U^5h}jO3mr5J=TqIn88&40 z9VER^QBXl=K$bk$8`$5NO^!kW+X)UI@pu%vFyz!*A)mbj!wpSHj>C9Jws)Yk(g*t| zAd!8^RyS@!mmhER_d3{W=zWpLB8e6y%#A+4kdrT9q!qd?ozyH#IvvUH&>6IeFH(#` z0!m3<#)GEQhUFCW5)3O}hVxaQxFmHp$tiRB50}k)VO9Akk&ju$Q*->Sk+LXYS5ErX z0gs&ZdD4oswXEA+jC7V;IjP|U4XRVITwj61*R#1+eRacCre`LkI9_i_rMPe06PxZ= zsAn7!!ui(U5Zmg?nb>~Wp=!3|DFmh$L0#dn3Z|5*-IjCkxPAVk{0pwO=D@^XG$W|C z-i+{SM8pu^qyS^8^G}H0$$l9Ic48(=y<t^lbV#5rBC;tc!4G3Os41<*+0{u@wt`~_ z&pZ5ihcs8p&IARW%#dpnsG1@#S0WFQPr4=9B}ND+QnKo29vyufDzL*sP#RC7p~7@j zvagDKF0&!k422q7@>xWR#;PLvi3D@C7}SNx-Gjo(AA?ZVwkSG~$92TzkBZM5Oo~wZ zq9$I2BYGPf%%QBHH`2-i!7WS-_t+Qii^0LjFGdm3V`$6R(q1cH!?rd#=h0BPCBY~7 zAde(199|dU5W{<Hi)9m}r~_=S<*N94X6?L}Yp8lrbHLuXo_&wv0)cZKMiO~N-liJe zvYh%EDkmM$zG%s)l`d*tXIp!_!SfE8*a4EtqNC;Z%$#+}ZmaD)$e!NIsizDs*u&|q zt`+T$;vvKKcN}rnu%yExhOpa`uqLTjtJr8QuDuPp;|iri^hZu%Cywx`GSUqOW%UVO zNpBMz5KAQgJ1hZqWLYEXEQYo4XEd;G38(CF!rDIakdDbNs>~z(p~y;j5o&(q!DGB7 zX47y+RPCm)_uJSV2c<b}V0)Ylf6t}XDGGFaU@+W#NU$QN=?rwafpKk4-i1V3)<!*g z-tw`Z38t<gw)G~iRFJ6ZVtqG4cRGv93p(w=6^}Xe;%yO12|C)ji!&N4mL=7Y>Z6k> z^=xEVS9AYm+PqOPUvyJGmsANz%0n`mw6bY26!0cLgW(ee;)~w^=f(x%T_~E^_O{w& zbCeM9U>43SvKUV$+fEmQH2DM~BO3&Dl<WgRx5G%;FR+!^eiZ#Jw5as#?vDA2<>q7& zi%~>cZHC%bSY;c<iOk`NlTcbBE7%x!fhItP_p4ErNC2?@sp*c%1)g1j49zT*o3XT# zaW1X8?%OLwfQSoj!f6i2e+XV5=d0#el^hZ|HAaW4T5WY$bPr+}CQ{e4mx@q~$otC4 zGWN^HEn$?1{4f7C%GICUT*d(&eS%l*ZCFLc{=t0M7Wp0Tx*aC^@CYxkYvO#+vv@-t z%G3E*i{6&?^{no;B3U(m967LoJ?)IkX&dYrAgVOa{w48>pHNz+N#5V*Py3dtCixhz z=JK+*jGlh|gRbfZ<+qsk;~;G}uQHj4HE)OcAD#mNrT^P;6Mgz?F5X-==RBT<<4Q$h zl{%Jt1uvFOpDMGk?7d3I0lE!J_tXlf9~8Z6)}6s~@q~!q`QS^#D{X|*9=)2u?;hc{ z?wiy3-HDu`do_*U?Hzrl?Y_=-OR^!KW&*H2NVHFuZW?~1MaaL47RlAm!AbM$Xy(?B zC0^=R$y~R7Y4Rri^52`z2iwHUz@b?KAGr^w06#wqm-w$zDf6D_6(8-(Hq!55ja(H! zK6jlLJ;pR%eIMGQIisJOBuk^^PG!CA@h<ZG+r1>Z6^nW>`b>+LPKkGsSDQqyrt`aV z;^p(Z=c3PMa)+-)o3$UGoe(XQi)^XF+U1&Ro0KmlHj5wrEBay6WbSc%ykj%?^3?dt z+D2tp&dOhE8ZW;eUwJCOeMkIKyAYme2fIQ?xaIrh6KqI#Pk(+5McAEuLN}2-wAUOz z6RyVj@sS|tJ`)`RFVyXDx7HK?LG*x4Jj0_b+Dee*s_0C#4CrVKL-(6$eCwq6NLc%G z(e<XV^i!f&+WYgQXixUzcYAXDI!{6_j&^(oKiMsMrKGh}^plxf{Ax$jz0BtOP`oKq zS<>w2nYhHH_%m&yyeP5Re7ZJq6nxqczf_i*lQ;^#tVsm^WR$5^@#IF0qAs}KH#Yc| z==M#T;1GSL4*rqxQSjM4(PvZH{TriKQ{ax9SPC_Bc$-#$tVx`|<i|ejAj??VitYi? zl3RCcr8^D$_=WH^D;mQqrK^LYy;P$6L41gO^MvS?lH69&E2X%dq9av;`$TjG`|-_L z(W{w!^S1a7eDhvbt8Fmlk$6+r%C?F9XBqcJ7igNyI)3BMRJ$M!(5TnF(&>vYNt^^f zyE1VS{Ot6IQn~M8@n_2HeTf_L>D}?mW|ll5UYm0NMe)lS{PvjmL^#)9$LGpv{WJP( zDyQ{IR)9<`nappCzR0iifB%chXq2zsu(_00h<s}wIEhr;zCLQbm-50CmNxU*ex9Y@ zkuqWK{cW5>S}}PAh?@nbp##+P-<*`@fPc^kq+9Y_!MIez7d>{BzeiPjs$K3qKB5Vp z_ivn$t1Fb>@H`fhlaFt!7A^RaHM`H-APjjE7v?RRt=dIz;dvbnA_u-vSE)DOHZq~6 zLFz|L40lq||5twCDU;1x!e<Ih*tNb1(PHMPNf~GV^mDDm{5ARY0)1@>0{PV|X-t&2 z>POibIUj23--WN>u##$R@qfwFqxbl2iB_NTPBx$U%&T2r-UFbqR5|+`wnVF7Y?m2s zS1Jw4`G-Z%!T#NRV0fkNuHU1~9biu4E4w?_IO%~0!<J>@#hSuU7r&r{0|jU&WoI^J zeB8-v!!MnA9WVz_6rB<8uQZcOk$+wG+f=-~stZ~kTDCZFxbg6ptOL4U$4RI9Ny#O9 zaFPRkI_gk6X7?~MOAUTc+WsHc_CF`z&upo4f?_rZkFF&>92Jd&3VrQu+S612KhGiK zy{Lt5IbQ5;Nm~_#L-NLdmF=OJIn~5AgVF2Ly?QrDhFsq0*kHRFPxDTmMqv}}kR%^~ zFS`diwV}B+ERw$<Hj-7_zgG#9ASd_i&NOvY5Fe!io{lfVj;I5yo>x`iX)L$Wa3HtF zIk0s}_v*ZZoyC6-=dTUFL80>MdP4Cvw(Q7A7+Je++iZ4Ca)%plMh7l8<31bKNoa~r zwuetbD)o@~O!d+#gatQZOav1aYTWDKT;S$u2=0B+6fS_;lbxchq35`ea|!~jBNq8+ zgD3Vfkgdk8c0fs4tCyIRQxbh9sc_4B&=9NTJ0NjR9P189*REWfz+#PyKa63LX)Z9( zG@a4dNNT4XyzH&Ub*qttNMu)E9&hpXYLY-wRrtjz68iRQ+lA1?rd+7#QXq%-a}PMy z-D9A)*YT}<YKL$JY9yY8YJisH0;If>6Azt}D^U$TNnP$@-$TN>-^#=g7?;`R-}nD` z$&!<H$BeQsTGj(3F7GAJH9bZl*TaKI)GAM$!SKqTb)*6`%D>o;jYv4?P6(JpHi$JR zH<X{bdzu5GBqJZ(X&WI-w%mU}Wqg|er~3?qFUcY<;vMNjU*&)1w4XG<Z`DO=mHin~ zg36WU%hn^-K2~hIOpPpx>2TzitJy=*u%xPrBqzr~{7y|`o4lGMu8Hp^YL1@+`3!<( zW*n4~A3_?5{-0Tq7u4p9P*QINpSylh@+}M;qn@Y~_*01Qg>9>kDzwMg%}4f4Cc(%r zTEkYWr?C~ht5U<K`f|E2#awkqq29*Fjp&dnCZo29WUzW0yKUuv8@EE!i4EF2+ml>5 z&p|&qd3Mj(tgfw-`y#qvt()=Wsu$(_S!PyB1D`rOx2n92CV=m<9HP~M&6?a?Zqdn2 z>|8f(mP>i$o|>IiFPW43d2rL5@?Eyicr_)t0ZXGzoQ`?DCURV+sd)|0Yh(ZA%*cb? zpHV}?*_tS)4`TG1EOb`yQK-3WBT&t3VqQZ%ET1L&oV*e%+}#b9orK&{iw9>XOxJS) zB{(mU3JPz}#VtsLj=a=Pj^t~_H(6vhxyioh3d!%d1!zw*N4?%*3g%RV`YuNgx6|M& zBBx3LEE=HmH5XA0PvNzUyU%n@^HdoTp2`d5FJhCV%tLtvoWcaEj?R2fPnXPsP+UdX z(+E0+^0A8m>E!C8OgYAC@ngHHO0Q)o-N8;P>6T=7Xd%>`{fz5cy0x_tl-;nw+>#YP z{2+_*4*(y&HR3$Q57)+8(fIOvTkAzx@|(kNxWGxQ%H<QNHCKb2AAFM%nU-S7RyC<g zj!2pw@$>iXW_PN6mlaTUX(cZ43Gz69(!v(9!^eIE60hh-I}6Ju4H>88WC14<Bg5An zrdTwCxE_Taoy#Tn$9xB;t%W;d#!Q6f_dtVbvQsLoobe#4C(S0aD_UAAl>1VQtGZ_h z<NihAD`XYqkVZqU-aJ5M2g~`($%hXy%Vt>IyB(w$f)^O)q|J27+amHu==Mh3G!s#G zId-}VFEr!PxP%J^I!y}58IZ2dnXAPgTOnUu4x*QL^%}9y1FQJz0C(7Mh<1?g&f_Fe zx4fXIn}u|`&cKnROaLn_EsOgG7dkJ=OD!8ztJEbIuxnmGAQFxT$#So>Y-Jt<9>l43 zpmCf1-%4?E`ApBxZmVRKid$c>ax`)j6{^80c@&X>dUrTkwBi0#1FG?^h>DQA+6Bx4 zY3AI_#BX(uYVcj<cMuj<xlCinU5|RV%URX?BC$Bvf#2nPrxnb#r#=*^zC!WR>yW<A zEmZgRhY0D&(3D+ayOi#=?LCZlO)Ps{AT;!@c2d`x{Y!V;WV>Ei|I3Z=T^Po(2qo*; z1pDd^)UQitfCv))!YnkZmL58{?4pPS&>|n^Ib2G6<naBL!%q0x<!9|l%0BR1ISLq9 z_CA=>JF+-;1IyDtfL-PsX66;LrM%kZZ@mVX&lO<eO3P<3I9o%0C$puT3qf>ObAPFY zJspJ{#%vq{Bl#R{pL*$^EFI<b8$+>;BmRnC@&fEK^~`|Ss=5f?E%(4|WtnBZeE{pq zA;XQ>E~IfWL~PcNEI!DYSn_J*m$Sjt%UMnvkg7hplsG3d&n?7&ij_~nJ98G9u`d5W z-6)!$5O!wHwX{U;0lC`T*Rviv>8<=co1p$p07P@&l^X+mm|)BH$OuNo4PyQUTE`t+ zjrUhtjr-CEPE7#rP}H<j>Yvo52MTXOsMvEv6kg+@Z{y1W<gf9yx1=9MR=_6q7$BO( z4xQZX_GQHSUZ*fb(yz8*@Ost|oVj}L?!MzWb+)QU+q}B&7JW(gl%vDHqNxn^6zVu< z*s*DCu<QK2B8+eAtdU~5Oj!+NtUkYT6|ssjC$fX&S(iA7yq<+5je7Y6Z@l=?qwG%B zVY|y|y9P=Q`k*#IbGp}?=7u)Ffl1uFUOV~sU@svSKz%}f2n78a{8hE(BS|BlQwt;> z(Q_^@ouEMDZ<f%II0AE6qe&|H5lgS=ct%9M(2%t1av&$CO;E(Zfe*3`W{1i|Pv=R* z!;4L7;ubhAjhtr+)mC)1$u$TwTA^r#^_P)B7P75+<3Q|XiLX)8>*kaFF{&{j`?Jc{ zG%h1e$Vgq4oPBV#S;*LTy)?TiHg4w^h+gXtuBO~Bpba(gSv{O+DOY1414CHT7n#gY z-N~R3x|GY*5=g1~a?EgqIK4Mc!lpT{c+rGt=R>a!1M_567q)diw4KN+)fql!7COqm zm9tknJ86d1jeh9<X=zYPi%MVj*MAGzQEp(b1DbI)H14B8M%Z)$gt^TUtIE+ic>u0A zGsVs~!m1)on^vB(Hu$A-7k~BQx+n;u05)j~$WUv&t^rbRnUg;tnOwb{0s%ol@wBP1 z<{w#jYPQn@)g)wHG<XD;OH~TV&$0^NARzx_w)ajpj7Gjd`BBQ_XacIMtY`NXEF})h z%O-51g_8ki6jkbUlh$qXK9`iGKG9_HdNj6DHejTi+)im8fivhcR+ldz_IsNqo}B0q zs$?_3_y|%20a_CDDB^lco*68PSupZH{Atd79Qg^JK&5KvoXj2<2#|BBMt|2K>a?68 zU+f59sf*A)#nXhr7A`olO?112KF*T+V#p!1C5l}RJMw3sj--EI{!r*a^onZ3Z^Bz- z%k&ks-ASArU#`Y1^mP$?s-A*Lf~K6j1&_>|KGs9Uc@bn<p9@906l(bsfASsO_zToh zayGZTV{a}Mo84i{(q}DG_d%gM_)9^V%V256IaDg#7L+=F=dt^O2{sh$@*YlKMU|Vz z7)dC9RtNU1F+ekVKfR!wtn}$+(&OzV?W+AA@@*neR$K1+#n?XiE2J+Zm+)jBjI&RC zJfXyHIdnq)wM-2R9mIwa%fM~9X0{i^1_8-L2(F?9XfBP}VBq_jJy(4hIXMer!L+t6 zx(RYinty5#S<OWfdv=4&H^Wx7%s%8c2P1FBRx>@&?&wt>+g-^N_jrg%XHF)e)?Gf} zZa_FzKX0<`uMkRbYU70eXGqu9<)-|=G^|4|0<7hrZzY&ZAsAKq@+I8%7)7h#x4+v+ zOT)(eY>R!>NKTxQPxk4PFTf4PD6)uCOLSF#cxOJa*=3frtTu=IwGvh!v!Md@I^`26 zP?u|1h4SP&rQ6V1dDE5(Sffl_4tw;q8@1%!W~esRu-`zzzabB&PegW!Sxk<H7((Kg zTm&7XNT^567dk0UrRiLCLXxxh^7)QK@!y>ZIq6Q%l%3gjDg0$u7E>WSCDZDmd#7M# zpkS0mln;7(4;g6dQ`u2vhmrHDVr}HRZ*BWS2!VMpG+KawX>Y6au!{Y1Ab{M<k)&({ zPmX1tP0FQMhCQW=s=g9wp2zVT(qG$ueG9Z%Sc6qW|20~ZSd`#F&l&70gEb+m1SVbM zmX`nu1xF{svZRL{G0VavyAiu>!q%_#Y^^Ch8vd78<Wy2?-TEa6<NiJ>tdZC?Zm3Dl zmSQTKPvT-0Tdnc+dpeL)?Q%6wyvTug+Z>L5$1nx6FIbeQA^<ZaY#?7lkjK3@cZZd= zr{+R;1TM2l&;9?s0j<iMGuaGb-%(iJrW);RzU5-HD)r=E<t^guwK-Ym9WpF@740d5 z-BCF;U?Cjn2w8{JUzb+vDpguq0=E*h9U`SPqIzSu(KA(tyAH73_i>1<LQz?ryK)ry zJ{N7}Y!-P38U-<D{+^oqaoV<)#5*^D-^u~dYt*)}4KfYJkkRK4urw_Dx{V~@eo{_q z@V(r4aJ0<;vmeE5RL$bOpX>P0Yy;T>g3aUux`zmv896yUC=M5h`8f*0v>_U~25Enh zM=}25Yq2ROeQXWy$ZNQ-byD>fME0hwY@Kaaq8s0~`$J-6a>~vXnS@J(u9|b$V<riH zb!$(^Y?RuCe}G1{z1hA9D^G&JPt&|?@hf3<EiFgYdNz!8wj|Si?2SAS_Jw=~Mhe>_ z?`8qMuh?ZINI5jg<1WwfgBLJUGAF-=zFZKER%n_<8jBs7uE#?`gJsaJnPXB^3G^}K zMaa3?I^IQ6TLyVl->~QHNE<aA5|Fo5zNxltX_?(glDYnw6P>S|?1i&4Kh#Dt)3_EZ zlXKr{#Hpi?-uq^iPo?(0Vy_Kux}UEk>8D;x_m$i-4axgsPn%f*nX33<{h)khKQZAU zl)H%jj{ctrn7<0Xan`0Y@`Bci1Yr6H@_P=)2Vt%{Fi^V|RE>u|9ql(m`=91Km-Y7* z3bG3#Dj2<*xN$ku5iB#4K2v$a_bj;tYJoaTjmQDy&dtHtdlsHZHQU$|A)~%uekJ@M z?Lh*eb)H3|_%%Q|U4hlp9WEZ_egtde7Z3$tibls={iKZo(QJ#ym%(!8OGs{CZf=&s zaXg29wbWiL#^nvtj)&uJIh9S&wtjvA#HQPM0{2QQnLjbvNg3-(^(+!2nbM-}zyqeV zA-Jm6=qW7Oc{f|8WlODak@G#+C3(2Df$FC{cYK+2U)3nhA8QP2os1;k{Jv<hO&s8> z?r(5iqA_Pl%ClzOj_<0Dunn|rUvMT6l?8om9mO@}<fz>%a<b+@<-Ydj<yZ&1PiNPe z-QKS!!kg6LbkbP|P1QCyYq?HMT>M48fwFPawcj<f!S(gEG)_=B+t~eYZg6gfnxNQ& zWDG=pkPT9onU6PMakX`qz=zs=J@P-ktnZ~z(yXRl-l^5{I#t>I5m~RUEqf~#O)Ex* ze_NGtOUuDlxNhcBoGVrH!inHlM(c##ExU5~z|@o~sKj08kQYFiZUF!z?l0#S5KwV_ zmBo17R`lfyZSC~o(e6#<2dL`^w|0ny*61j5!IaVP0jI?-XzpJGt|qjp=MAdiDh(-0 zv}mp8`Z;;U=NpnpPIjNo@+47j&Ja}*%u9tbKXh-3{);Mb!c&a`2TWNz%Pz^C?)^aE zLoJK_+1l``i4e`7KiPoYR)WIuTJqE6C!}z&r}=@V=9zN+eh@8HaVs&}$Z}TlS3a?> z>ANR*73OM&pR{GMVtCNyLG}mHW@~M=)O{BjtbLrduO{{1%ni|o&e7;f71hUC8;XfG zg>BM=V$*cMoFmZ(5hRwRiE>a(KjnEJxTYZiMx?&BsF&^lX8XA%8LhOIW~<CSdL;*H z4W81ZWLQgUX+cl_!Ck%m^!eZJbt+SIRs=sEpuTf?vC!Gk#6KFgmT7xN8?4pTn?>K& zUNy4!Q!EYy$H0_dUE7c}UQ&>sa;LTB(acW_Z`Y#7ih>baTA)$JGK?Vj4#G*FF|UQC z4!<0{uE7Tk63^^tcMcb(VX%8&?-ENCbEv{cwoUrw!1?xRPOg0thM)?a48%NKPPY-Q zY?LW?Ix*^Lq_?fRsJ$F|a6#!DNH+)n7hc@1VXw4~^zw(<4$EHGI@0qHqrt$}wbAzN zr10$~VzFy)ZxC9^G5^|6FT?1YW$jn}b2^~aT~J#IWxt$1p`bIyz3~_-1nmlm%Rs71 z)GaOkk39Vk+W^Y749}HHlwV`Ylt~k2G|x~rf0yGS*GF`DaSh0vv5_`l(aw!-txltj z8XGy@nXq?`NfE9x%JI_TzD5_Qa0{Om)+s$d$A&@*Tf?|9TUHr&qcp~51CSeiFKg7W z1VM1q%Ib1D5$oCFUso!t;NnGzgk~(xd_|+o?(gX;wzulnW%a$W)dEqz3Io#de*Zu( zwWh}U(<0X2xe<IuM}2?p8x0szY8z+^z63dyfl-P2qw8*g;zN;WLP{BRFf-i#RY^>D zyd+s0!m*-aN4ul*>_S`y{lqWSuV0;TYmdf2LdGxC!4(I*C-9e+)1UN}GLt1GOIy_# zL1>q2{ul+Zd>i#zg6&hzD~T|NnZ9KrC|36MXz55~IqpwgQYCr#JgdAT>&x2=idE`& z5-X3tk`Wn>hf}vY$RSe6y&2Bxhg#i!tS;Wt^}eu?ns#wyYdD+Ysn74TJ0~rvHybb` z#u2@d7O&?XIr+h5f%vt+|Ab#OgfO7fJ>R-7yunyppV|AlSj1Q(>O#qj8hPng8|2_M zZSDPwkRi$_Y5+^yTon&)PLUQGTUIUBv#CXcEaVjzdh-A!;XE5R&wWYomc03IqJT@B zROsum-2Y?wqZOkq(6@cTqxjZt692*3$#N?8krGd;V5K}Nshq6`74x5?%F#P~lZCn= zeLbCdJTtQW)SuwhTwX-}PtEBG-gfCCr~pn}P!uz40f0>WrirPDB&t1$zR#(2k-V&p z1;QU0;_@qV7m0;k2J+2*T(5gTQKR4a8qZek0a`t+vG}fDNUFv|=-I}MSl0#1rMFvR z_EAT5C&v61Nm;S}Ns@MeKX&GF<p+&~`&?jwvGU%*$_Zhr;|Jp9$=k%LiID@%%7$7L zBe^wY*|;?i?b!vMEHi(+mqMxVkCMC4-&SI1?`q~`;PkhxKAJ!Jj#{kkJ#w<oUXi5M zZbw&BdKtkw!9Ow^&4D@}{i!#_>NCR_iaI$b^RH~w?T{OjhVeubg}5TX4~d@5L$l6? z0(azOkFQ6Y5vhvmXL80z;u^`Ln&hMh@DjiVrZii|Kdr}pGCMj7ZA!J{7t2h>p}b1B zdFoq6j%a0Xvs@9yk~iX!bvE8AE;H7A^_UQW#IwRMySQQ5Zlk`gk!o*UP<Ybe?1~+# z+ZumJ&Dz7LitRR>J1|MJK7$6_4H>46cYLs;!@F7kZlg_u*mhgnib0}+*BLd|cGeOD zQpQ<0?x9a(XsbqVkvNaKF1eoV8owKr_5CQ>PIiwM+Ol~c`XJcO*~;OhWLx4ewj^T? zTei$WFgbWKx?1H8&dTHAd-|iebVr`mHQ72Vi)a&KSvQ<59hz;{uT6t>QB_&w<g=G0 zZO5v6x-J%UJvcbsv40H49z1*X$(=WU$731+riBd%dDk-14)<vQbVLO+Z)#8)iNxf) zm~u$lVk&oV-d*n2m){v6M{Q1aSuvPc+I{SrPq`=Ey<@Q3<M!Uk_s;$G<Dz1XrG|9w zKVj-|s7S1KO_^|+Fjsvc704=s_2z?F)@#{=ai0<6Aj{im*a*~WqtMh{_(Lbl_js9# zfGPV;n$SFB8ly39s4g3ZL#e|tEaX?j4ALor6P-b`RR7t3!j$7M?L9#Jq04I$6`f=V z)yDl~LfiDA<Fq;XpIaNs+O{FE<r?HA7Eu*^VR^9=Wy($MU;m}l*^NecE9hd|*CpMh zw&ewjfGyTeJURJYh+kQT4M1{#u~Xwea!bM$fNU?nIz?hxo-Du+ii)v^2Zui^JyENf z4+@FMibVbZoN!e&&nzkRHy~@bY79Cj4|Oz>Xs{~uDxLVOC9oLInMeeA*=a!#XoKv3 zZQJOoCJcF$M=wkgtDRlce4ld*lRsL?4b91kdxju}Li5^i;+pFrJePJL^FTUne78%? zP`MOn!q9+9pknF^H8V4siA!@u&T~O;IvCZA;WniS$?#BCocM(M1NwPnISrYry2r`Y znKl`zBoBNpgbuYg_4j^IeK+QlKu|Pe;l!{j)E+4NAIG9f582*_%O1qGI(J3eTHnT= zv$gVv8d%8^?QeK!VGUwLA5$(QBCEu2!KI~yG?!5{M9fs)vlCnH>Ip13C{qy%aV)BC z@he~Yw(6c<a!WL<Z1O-ZtFgj)+Bwy&PzCgB?vEa^3A!3+Bw$2hiw(+-Z3pwyOvNOP zG<!ER#|SYggXAp~US?M3WWuUOS>~dT7Q@byA;VCGJa~CZF1xT9`?n7V;xZ|VB|B>` zC5#lwH_*%;139}ivOHS@`6j1&KN7g5N%I_bPG?)_*`#Q8WJIk6QjVy<GNDmS3Zn*? zd_jY+pB{tCXU_d)?DKLUlNIAYmh_}ha>??3d!Q_$zeM$@BZc~SuhMhmWIDOZtBV~> z+TMS4qlWveVp#q#&?ucfJtqwG%2x9mUA)q7Zy6?(2ve@EpuIS$H;`TCcx48${J-9) zkKHBr?GVmk8sXDHpBdmDDGBl!!k3e&?+stq&ghSQshlNJ3NNUKut}9;aPDsYhpDfq zW@CFaE`tE5kYgbaf1*Ja^mJQzg$Da)VzafaS~IPwdD&`tifF3F2&@(O!B;q$Q)DaN zp5Q5T;g=pFk<2n;<S8;f>M2vUxT;%sR&@q5!0ojb?fEnjJy(rcm$BW5^Gdu;6n5FI zDCpL)ZA`skZG_q(dz=?Yv{^?y?43vufMnl~ZjGyB<HngknvqN<gc>ZFaIX)-C3L{Y z5+ZO#zoTW+f_zBz`7$AUL{F*z2m<+u@K!96bJBlFQsI?ROx9M-e!;@@L&p}(tT5FX zryXj*&JqCGnTfUG-^eBP{8%ObFmspaSFtk6E`Os(Uq@PGnrZdb3!9W#%cBp1rXD|# zEHtDo3Exac(WJtHbi^)j!c8`IahbC6iPJHe$amD-wU8w3%u-oeh_o2i&>=B17VA*O z*pIsh;h+s~pFjyFo!`m=J<ENSL-Cb=`vNEf82!mOqm*2UNATnwE-R1j*k~|=TWl>O z;(I7U(_6K?zCZ^i61<kHqNvN19<5xrz+BfZy?_1{_d>tRyp@{m+ASv$FvyzP73>OJ za>J5y@*C1*!8GJjY;DWsCje#%S`$s<di_Y&*_Uy9Bi~kjteL3ht;_s<17S32e#zRi zqL-R$wfL;a%2+Z}I>^atTUOGMrmJv~Wy0o-z(`=Ed5Bm(Mp>!1v#>3mitQ_$;ufrB zMyk+x%@qy0sR(9i`=s`_M82O(U{mjJVT)!`YI>QxHsypUZZ98V8xa*`#Nmv#Y2{W< zK2Knfk_mfw+2+?gb7F#;78lF(^TPu+>oAh%cqG?*c>2^jE%*cYNqeWx?^r(Q^3$&P z6<Ur{ct20+bS!5Q=d$@H+~IgkTph^u8Ft^2E}|SRd8&kRCDo0hK%WBH)J(2s({w<o z$&)5bo5sHs(l@V+wis`6PjZ3aQ9JKAVZz&y?j$t5R0*mA748|k?N|%%9gg+iT8GF9 zEK=1ypegi!aQBP&hg$m}LbXfi=Ay@Y9yz=O{mGo6G+BY1y>9X$V(){6JJjOlFH>5l z<|pGA{{DMTy0~H`JG`>EoJ>fLF*tDkgl>uG8OD}>yi2p9DC@NmLJ!1@p`QHXcO?y* zfU&vCG*3raYalC5>oYS<GbD|f1L1^LwgoIyF2L&VA|pYXLBCkDRywx#%ZWZUeNggW zOD<Dojaub4!-kwDUYhId3S}PNANmZXAX%d(7}YPley$##4Fpl2c0QOi(zcFOZQbn! zP0)6l!34THINhDr?hXbWQ}=lHepGW8=&n#~U#Mk0a^*bTtTxR~T?j@M?OSDSxUNU< z(%Hjvx#LTvx+g&ox9tDEgSz*_LFny=|Gw92gZ!R`SJU`_7o}BrF0#Ni#6l61|61VJ zdNA?tA$Cj$hngzQ=5qyAryxQOEK>2%F}GLlK=?cC&q06wRwn-<JjlMluy2dKfC*7R zQe3V@2*DbQ+QJ_T3Td-~WWk7$FP%r~ia;vdsIQ!SE0`Rbbm?e2g;PZ7#GZYsCO40^ zJc;#PJ=`AFo`zbSimaNc8-7&J4RZ1r5&|ozcAgp*%Jp%yK;fu4p9tjKtP>=^0ZeBG zV6nTs6DwvFrT@qwwBZ6QHri;T`#P<K${Mfy_2aP8w1A)xD12aIEw%`fMo|Td*p`|= z9%Z<^5^h$uik#eZkGrCt8qn@N=@?8oxjAYw&nUFQKdK4)zI92XETP%ooRtIJCzK>l z2N()j<=+}5h!*VRU>v$0GvS+)f5oB+r|h;bIA!ZWdztZ}aJD+h@AmJhnkaVpLRyM6 z<t5bZ4WT*eP0qz)f<s50%i_Ekv$8alyfG&l<ID90+?YR9F`KHg4fNlXKePi`3vm^d zd)}dQjcJU!o!aYbtiZc8Ky!;VGG}5C5<1f0r{DA!Hg9&9dCq$wI`cFiR4u`Z>RkJ% z@#-LmQbDM1eNMPfla53>2@$-Exgx9SbrgH5@*ZNWL%5Wh@DgDZ6>hX-jjFKK@<0>P zFjTcuq|QV(j2$fz?dc*W7FF-MWazCcS>s7f;^EeuY#QS0Jy`BuN13KrvZ(dggY)xe zFFfqvg=OnPHty~rkwk{H{cf%WJ7H>IlIy5RRs9ip=KcnwrBl$!kuO(OUzW@9SeZoz zt<&Z}Hp3{mO75rmmB~BRW9Eb<Z*Z<g^(2O{<a!>D0S+-lYt)jHckJcKSe^r}z|P;) zFuG6$RBpQ@0z(x)q+GwAT=&+<0CWq<$@%*!oaLsp(#2~{e%ZisZ6PIBJ&hS*Lt^FF zDwUdkC9c~D#qNbJ#v-G|Qf^1nT53MN?`#+^)7tu|Z)j;bf+Bp7wu7iJo@MOgt7Cop zzg0cO4y?0DXGD$~0N@l73^cP#Z9c!3B$)+>r?Q17=hw&&IJ~{Tt&?kMa=;b;27_B! zXg`6n<zi>gie_2xQ^jqqKuZ38SYw3&5#PQjNWf;D8on#&a4W2C6>z`b6v0fpfwmO| z*$zj}0a2E@P|=TbGAtR_|3$*C=jp#g)=^~IjkZ~)d^{Yw4&P0n8(w@=4|as#)W<iC z<Vm<vaw|?g1~oEvsXE$1!euoa+u_}RxjW^vWW{wPHP;me2)j}9!t>+){Z+8N3If<M zf}PA9jy0e=NkxJ8m&(6O9HXUlEcP7^sQ=U(M4q~RZ(gyxP@3I6$l`Kx*MA81(o;}w z|8A1a6BpDqM5x#8aK#ad@3(d@?~%^a1OM!Yr#h`3AvTwMlBkfXBSQEU=2jEoJ_YEz zt-Y>wCZp-AoQ7dS`ccL%+3tP3YiUGL`KjhJJaz#NV2`218iMfoSg*M*`EX@NHa0=$ zV4oldbK8eBwnQy{bEw7NXG}AG7)0SSe$K5gmgK5wbMkZKr<t@SupL!aN7l)R%gJ97 zA`gl<G2Mlxg7Q-*RbJ)m>AVU_=GtTn>b4+a61qRg;pE&z64k9Qd$c3<^s{ohy4f|d z-24bNi*Hzum>p6Gjoc>mS>+>H*NXvw9&Qc(o1a&XwjM%q5~?nh66g(tdi=l6f0AGA zgQq_(25V^sK=zhIzeuAoL_xM54yrwNTIZdIIro#urncg&<;<Dxcb?o;#RfS6Ng{Wv zjmB8HLCql2HgEg=a`a)kNbJgUztc{i%R_kY;|m)72$UU@b-3k@=q!>SbJ9sUK%#Zd ztZ5p3ojRSY-!~k~CyHyk*4u{sYmjY61ZLqx9fM?5T^5pV+i+X|G!aGCEV1*~(Zj8k z{NY7?Dl%Xhj6q_hKB*x6vVuIa*VaX%4Ry2Oi`tQjwDl0Ih>X5^o-QYUJ26e}Mji5H zl5Ne(Qfo{O22~#;g`2c)1C3O$jbk<B2xO$^ptlIOt7o6WcN6xpC&<z2-1oIqd_I{g zL1;1&o6nssl1R0bZ~s+=U01QMAiuWE7$$kE80+YYlnQ9#YlljnPTA+@))T-)3o3dU zLYUFZG9cl)ZGsWZ?nTY$rUWbaEt-9y2E8?SS~=nnr%Udq-CYLLpqHXdz>GY|QdxVt zWi2;$-n;zpNX-D~kQ2`iH5$!2$o!c^rU#q2cVmD943m9af3L`cb?<g|XgbDQjtyLf zN<2bCzTr^itzbz>{Gw^Hd?(<V+L$ZZ(IIK;Za^GRy-HrLh3<ToNlAWzW)0M_3+_qO z+wI!>fuLze+P*S$1l;LcA)2qbT>k)zQ<G?-AxJYpXJ5T_=z+F`gr2|rED6HLGPcZX zNl-cM@1}F<^S+bx5JNV=m}Kv`6b=;cKnkHqh!l0XqaG7UDHvrKI|{I$=$9Qv5G)_L zj^dqU_e$9&P7aMFs6pK(QK)cw2Df=R295TOlzj@RTyN!wkAUB}*4jycJuavr<9l{T zTQBGt)8RfDV1eeTu*>P7lpO^=q3L2l=e~8z*$Mt45V}(ZBS~8xMs`#Xy94Xe;gC$Z znUrzn<bECtrt6pY-2)x<F%MgwgyJlq>Yu8TrI3^HU3@E>gsTMkEU=<QJ`Axi+`(U{ zg0HKUWLw}W0MPm`C6CtU`@W8`aUEqHJL%TtI(FWfEk&(obV1gZ8cqZ`vLdn<8P(vO zypLAJfHple5@RBTTzG@y#sMqp)b5jeB0Wm|gtKA#HRs0CnM~46&JE<&G=sdwHzyj4 z#&Il@)a{>3GI{oiIE^BOS@08sZ;~Rmg46%vL=CY9u7a~Eys>`awkONT6IM`O%dI0= z{);I7Qh!0)a>?Vdh$ZUyq{@MkwuGY*wq6N$C=`eHrHjMg4R3+JxUX^PICEgwY>bi! zHJ3R#-X(EYIik^|%OG~Llroz4pr-5EBvn>aJ>gBPg&{g?=VS(!lQU)IEm1>XtD?)V zWMudr?A}Sm-dbWRJa!cs_Pdphvbb+hb?97;<}NC<mrRYw&7ijshY3-cSwW~ff$o); z^B<l0yndVBMzoZZuYW2CkLKwJk6SXPN%*FG|7XcVGSwOKkVpo-nOL=Rj9jDeu)8tn zpFr`W?TtSj%7+L)smDdhNpU_pq`0EkFNa>?G#){A9ZmDr@41K2$zwZ&%w~|86>{#+ z9hxrJj9vl~`Ystwc1$!<b2VesZA?GPv@g>B1IXH_WO&S)7ikPPy35dKYwHL`e`sJ` zS;>x)bagv1=C@$KBO7V`XT;^?^|v_)H9idU3d%dh%i+Y@T}4nRs=$JMt@nFusKhC8 z!G)TpIcfiJkdFId$R8ASnx(O<pM{|&K#)#BUuZLF(!kW5v$vd4SHTUROEi(MS@pSg zm}TYQ0<@ofD7ur`D3=jdV$h0QkEd;rtgf!)OEgw^*QMBPV{T**5+2kh_cGW-bsyy} ztC|ST_pP9rhmOVha0Tr&dM*c0u{Bkf{XZHuuxURWoxc&vguLY&!wjwMmy;d6l~7br zXJJ{yLA{Z`@vaNlIjSEz{t!;C%t21n&>tCPyIZ-I&w1Cn678Uq$DMjjh1&P5$&?Mm ztrK{R|5U}ecb4cmcO{i{SG80Xw>y@pa#Y(qMjcqM5&C+bANv&qU`V$QwOe#Yz-@Ki zf+#7YuSYgtUzUoZNRY6NOSst^&~oyVxQ<ppy+vOICz59OIeGlul|IpP{@yVzvIHb1 zn*!5^b{EQj?VSZ?8oOty<hGW}=L&v|Gd!9@QCMCR05gn=?Oj=jj>?e+3as=5_{-zd zX4mo}#Y%ZgE|N!mg9h8e*@5Y+l+hj?Wg6&c3rjUvlaBAmr#~B5wRtA2dH@*8>=Jz; z3bMa<kzx^B#xGGy!}~dJwT!J1QF835Y+ECdDbb1rKK|ho4UX_k_}%Y8FYj%=-xqty z`)+i^9ulu~yiAa9n53uf&Br0x(u1;<6D@BTQ&H%fXff;LyXgw!5F-l|Fl?ugRwltb zCs~08A=z?CfFCWFY??ud0TQ{H(A`}xkMKfbm_K1J8DgMWBFdvcLkVc{kQn7H>%5hd z4=gmKIA7A?nez2?qC-~r)eE?&$s%w5)KEgqvE$0N5(9}!MN)eg6?>beEYwWj5*JuH zV(8pe2UUj7??Mde^NmeDY=AHWQK+I1V;1~p<vvAKxwh`PuodoAkM9+hJ+wWX^cIn6 zV?0)>dQx9xyVmn~IXU6tBylEB$K#g|!G{JmXr-DgqG^c5bg=Bgi~y&qdw21(Qy1%S z61k5Wd#%dV4`nB;KT5VW>QP<2VY)(zN$fVubz`reWOLMfs1;9Ojc(OL#em-N)8t;7 z)gCoMTfDmG=(fSo^(!ZrRpGk2fuTT|Wk<GN*l8V8%M*F|8yZJd5BCm}qfUl|)L2-g z7O_@v-=5Yb!Kp&zh7u#xgd9u$Cj=fzVfm;xhbqyY!E}k(ahF4Eo2O0BFSC}Og<egc zmDWwv;^nI3ktf}!ILzaLDoPCWdl^enBdhnNa~X>fM39VRry`$$GVKd#VUf8$mMAHn zIeA`NTa@zcR`M6%Wm3RjvJ>uP7<9hl^=Wg%?Ms^c|F7h>$>l$WT3m*|oDodrIEwmv zApTU}4D~%W%f6|u%ExhFgSwR;pQd&ylioF*OXr#X`P<bcnoXozP$+chT!fQZL#5g! z6M``!jQy&P4mLnE%sE36N^*BZ;A>}xr`q%}TiL6|Jzb#!dS!y6h8K@e2~1L-mTu%= z%Hx$z@vda#tE#Lde@F00JT~~uVRio)c8|h>&cURLB$)z{lkZdOtcjFV!ulfT|3qgy z6tM1j*&VFWkvrW0tyfD<7~alaoEFa2{lI;Js&t+kU0>9$!P&@N>6?d?id`Kt8|W(x z7nI2uL&`|<^E2b-I%WzT=KWtDC?_{yBmrmnlS@3KYo?oc^wv_f5s}I1katgoU9&D? zG-Xz0!1G`Ch>~ltqHis6&TyHvlM0C(MfRBYSD$-}h_;!QSJPoClRTDY(}XnMkQIM5 zLK>#t|1H}wg3;uOnzF3j`@%HZI<GRPW*0YR;C^{vNpG!)2T&bBlIV{YAP5lyM;pU2 zdKP0y6fbZz=C&~axuV2#dd?2h<&7iEb2MTSbe*XVeJ2r>o)fxbhA*XsGd5ICwywjb zj*Km*j_NU3!W|u1lrwTGjO;o<u3yxohL0y_hw!;<Yfckux0ZMN{#0uK0B#k2&&m6@ z2$r>cmWG2EHm=>BH*c=#PA6SY@wsX;?<ur{>)u6xW$mgm7{yJ@mS61dVH6Ex$SK$n zHs)1cIR=FlK1&}5?E56r5q;1WuX)w&B{@BlHxbdSY|%x>cq^2lNnnBg2DFatlBxI+ z7Nql5!cS7IP~>jxAm3nG_QBwY_f0o-Yg!O$i7zR#$A2<1m|E3?{We&(l^EM>9cS@g zS0C`MMZ^a_j(bC)%5Q75?nz+v?)rDtxPGWm*5Xt-uz{`US=|jZ)=y9E<$lD)wBV3A zj>#BO<Yv+na$$kayWMib&LJcPamXW=Hj1La@?6^Kwml6@H41*W_6)a2&B>2nTq(&l za8LOSu{9lKpn>H-J*VeBC`S+;NIJrFQl&-q?;%EVMQ`fKa-qDFBz)K2aTyR!Nsg*P z3ejjnwW5DFP{Bj<JpJ7NCWb1wJf8RBzcXOG(AMv!wS4kjI^s2?i>vEB{=)3yT>AfF z&uA9e^T#Mp!8K{5g%VM``!7)-8q6b|fTB_?&KF+)*$sh)M@KQlR@jF3B>IFKZB=I( zI#nMl{r~FJA<}2-kr~RJn_QGc*V5s?Ls0{TzGkG=(xg+LnK7!8XVZDU6Nc+_s&Y$K zpuK(gHQzx;57`3^>qiMJA?f#<Bs{3;<&qwn_H*qF<qfY5x$23k_NgINeW$cqbMUSP zsR4cZb8@MN1L_#<9E%_)2m%0!Q`bozG6g>NZ-j-HVT2n6nYMVX*{7|dW14yse1p8v zp+xdVL8cvG|1S!%KpE>_x#r{v0$NcjlQhl{LEOl%_Oqa}>q0}Bx29ofZTBQCDDi1C zPAqlyH{+wUv^YlvVEQ2QSUP;jV5zgrht8)vZqfwOk@lFdcaG*_O9y89*Ewm#LU+Yv z@~8XoUP}2=Pghhy@t{xTakuGJuiX;PG*ywLo*0!s(R)74lJnxzCbYQUB^~xu{=x=~ zrdBu513A?LAmrqeL96K|&`@3n2)&7LVBAZF^1z>fW}9<}FSZ-gof4+5{29m5)h)ao z4<5m1xmS;-dS8`kpPt^LYM(jwZ-C`1Wj5k7zt%Tjsr9w+%vEB(7euoRn(0>c^_0u( z(wF31@Fx?&aq`5_RGX9D8a7B`2$$Lq^RX2mUwT$_yMb7<>iex)Fjs0z3o9P7h`=*A zlMA)pE9z_}M?GVkFHbwxEv@Y7!>=MDv|hNk0^{ENH6H=-=Qi|ihC?ii4QX0n<VZgb z!T~MHU#K9oyk*AfkUc8<rfNd76qikD8D)I$@NI)Zhop=uw5J7&?v^S^D5JGXR~Q@i zFDcH(x<SMc_o_z*g=M?V*nmLHs`0AGmaFISP+?4FBec{hFQ@)15}gR5TbOl$XW%+{ z`Y9Ol1#-Ax+CqB>SL&P#^r|nq&&fO#m`N%hnDP9TrKM4d7a_UgGL7|jk6L7ajseW6 z5tzy*$PP_eX0L~%SuaI4>uq1-(@Q%g^6R;wzeO`m7SBaQ`P$q$8u{y&XFyMhz&jl6 z08p|dYW7~t2K9`n_%*fUEPzFXG6DR8rcMjls1@EUE}X#r%w9O6QfD9l{9`i2F28-6 z?j4%^5T|CzP3Z1r#qKs7Z9jH$*`SuB$ZvS4OyoRE!db;o$p{G&%3BwyjC;*Mi{wG- zld7V(7H!uPr-|XXdgM>##XFmSl=}5w!m&H199vnmo(j{#j%|oyV?AvFX7_A(XE;g1 zX=bk;F&)xY$;o>tOvAm@Ve0cAMo6)Y(m-Ef7sS+ai98=tgP!<u64^@{Bi@f&)X#7& z#tmaIy9NozJ(8&7mts_q6!fsa@8`ekF04_rSG+s&k!j61DL72b#MII|A6Phn>hL7< z3SHg=hg4?sul5P0R3hKo*+!pj??7iI5%YcPcZ&WgSP8CyF;#!B)8VF6G4xx?AHy8J zm<~tm9*c~jMAW*A6c-X#d6;IP7<A0GA{&0^$I)DUcK@@h8&*5;(O=k$Kuc)R&1Ffb zh#)mhqzx?6v1aQXEc(rsp-8E9rZh21JlTeDiZ7^=gEFi-wo0plp;vyiN{cUa6w5C( z(QPDUFs7Nh{1IBCToY#sY_!i?=2(y=Si|L(rR{jay?P-4;M;*s(3{0>>HO+&0UOF} zqjGZ!YeSIyFs4?lZabkMZ`Gc|zOy_D1Jd$Nk_0+Cd)j4i66!UZK#M=C!z>d0PtSr= zBkk|Q>JGA9|64T_{ci{??5x9B*^e0mTawmLJCc$J<)KA)kh*Pv_O1gO;h#~0E!LZz zj0&9Wd;89mg+~OJdMfkCeqJLNDuE5VT&O9Bgr7FkH}Q>a=&pffGz7A)Z(SK%91R<C zLFXjX6O#t8uN-r`Y(LPiR?1tHmjjQt_YM?0q<=WY3rj|+c;Ry5-G~K?HM`|nY{^Zl zWh4uBE`$*mw*aCm3SLH0)G|*BmU<JF`Lczt?6NTzuOp~Yp)5w0Qr2N;gwHJOWZ<Xm z-F(Ul-iF^Ww_A(LUY;s0PUH}{1OhMQ6Yr->i(jYsNm(O2O_D0!tYR0S#r%`FIzaY1 zB|OYju)_bj62AphkP3V{bok`I$Eb|((K`z7ulcoAPUyT`E~i6uI|!Ya57!~{US@y| z5rKHh@E<9V_Z>~*lBTmin{=t_E|X*|a)AwIZ~&n|ZEGs0yu(X>`61I#-7=dr{_+d0 z@E{3Ni#y`y^-W1m&Hz4RYn-hoF)=JjIRv)3QS>TcsQ(MQn$mI<c%Bha+hn-n&(#8A zW9p$)2#Eb~edK`0igZNoYz0LU=MvQi5p2M*^BU>tBn@Ahlz-`sFzm`hN~<%21uA?q zCyR=K7N-JUEv4PhFyZJbiaw*yJ=g_D#HW-stg`eleDEdtgsC(Mr?l%Mi^^7Cc5%bP zUPgUgwVc}|#)pgh!nL1>#9ux8j*%LJm~?)fNWEyG)ZW%xKmixE2d_Ltl?9fSZe~<7 zEMG70^Rm=zkNqc1Jr0a`4^#Qxa=HXdN~<iD2BWUC%on5UchLSY!B-w?z`oL3GJUpb zy6b;=ON~^BDE-??0Up0MJq`<Xn6McuRmY~jkWSvtn2<UQ3)Le1JGlh+=H8ywluERJ z!#$VfCFSHI%2t?^3!d9wSkZ@}bJP0j;uW5x64;oN4^i%6PN-(EC~kdYvdSE9LT-uX zed~PWf9Usp(SI-~x4bHxRWm(35BLo@JmzLzYcJ#%8E3pQC%?%2H<<x~k!sIfd2=tN z*#seiQo+STOWrIsM+JkonX#e1kH4ECnfz{s%Cz#n3&5Ug9;-<xX=K2dN~VF^Yi|n8 zO_Q@e63(Kjnd5rf6!jp0Q#$gHC83cUA8(NPZG+1S$l`9=oV|?nxWu41yJDaiTj$7_ zgB}vj>&VHTxJV?}^%V>31M(u=CF_>v<j8H)Wg+egawj$1y={X4Kpk>5MAn|F_x`{- zc)O84a#UGGKgy;x<V?aPhk5q*<!Dw81yCpXr+w*%6|9gc*S|8~P5nqm#8lI9IS-xa zC8D(#w`HVC%H<933#U32KYxcaafJrD<w82zct?)@dDkxBRyv?ORN4F?<a-@xt*T_w z&y{Ft78$C`!wHn7PDSkq>EtyzC(j&*PlnEtx2LZVNzqytU`*N4sBFiTq)9LCS`wjK z4?<xhyyYCAaOPP<ZxkgkPL{OSV3|;)r~I*R9pBSb#+L-NC+=#Vf_oerXd|`iIM1D_ z22g3xrFp9F=O!oZ6IiWDF||X_3oo0Skf%RFYY$DiW1b#Dr$&T+#w)0#gTirFOmWS8 znEJho$d09Bkh)!kw3m7;)bIpZY95hiF!~D{scR4mui<P;I`PPHNY&h(7#OMN7CBjV z|7cDdi0YSf^4?TNZq_&m2cGoahJjgM&_)N!kUQDcE2m_v)Ag{?a!Lv+2vDi3R;Yqo zM&vxVv#lS5*?(<xHwUTRGnTDM-TXUwg4*ByL0rgU=!s;|vf9D;lvuUP6{9b9^>$Jc zi#V^)uezmWLC+D+5TrzUo|}=V<>=?7+Xa;gJs^40f-;vrKkgnnh<e(yb_wJAeB4d( z(Nlxyp9&&4DRy$`&3#|!M}W0eB0*=+7ng5cVFx#mDGZ_60q6YZW_;5SNG%`8m=ART zZZhNTnB%@vqWtw*V|%%353b;5<QzfZHa$01E;=jhT$4s2W-@l1qG|O&aEwd)MjryH z$?ChEpX_YFN=>BQCsp({ZKRPz=D{TQxvJ}ulMC=eG|h9TRN84$pm?_+CxbX#9X+I2 z#7R<1GDw2P;et@AdehVwYJv%bt6f<-b4rM>S?{X5K}Z<ZoL|)>AJ7&Au!Q`(MwBqv zSNJ2lkO;@B$cfAMEcZ@m2(>UiEt=Ii;rNIj09#rXg;!HSeVUlYlwPyp1PzEzmwYDI zRLP`u2a-q)@u*Qti~qx_Uumj)LXl!I+H1GdVK-P;A)h*-8a}#zSQkFiU7e6o$nj&_ zqN!%DUk4|JR>fbMT$?9+f`J;Xe_`&*5$e{@(b%ZAR+HbsBUqlL0ot6eVXtL!Gz%tC ztlJbyJ3hp0RNGUVx*fF^khdpzgROt$j)akywZ&cpMn$0e`b>(`A?|^0Vtnx8vQEVq zeHw_I#=&clQ2V-VyO}zpU?1J9b;j-F(1-ytle3=Jf*M5$-6Y(`u?n8NIKvcj<X^#~ zR0uOmz+$?T?XCK1QvOyoq}B51k0z-FtEIJ$0ZDsb5afL`<%cqk=<>0}UU@~RSLfgu zH1IGjZdj8Xl5U`Z4BPpG;rG*Vz;*%nfzi6#y5-Lxl@X1=ddp<bSEPX>-{Ipm?+;g) z3O;#RQgDDz1-&Tue>1rg;SuXM%+_gpa`G4kud_wiopY8T^xK#WsKsh4k7yL&?wND6 z^QwI1^Ocs@+F$7M=3r8VnN5tQ|J(*_kAznBIeGaJ3Y{}SsU$lGZSDu2XuQ=K0HdH? z6^$f&0$A>f<X)E9iOxv;*AJ3ks*4`7j{ooiaV)HX)N-xR8lb;bZ(mP`Rt3`WwXbK5 z96>=C_*pwd%@ozQ2Dyh55L$g(sAJMWz^s&Ss;q3hG*;d6<5ag;8^>XjGFn>ZRvMsi z7}7N-U;ToOFOx%`!;t9dBSQmwheQ#%iF5L^LleTVlIu)xv^VJOnJDhXzYO%QvtCQ! z&tc5Qti&`44?CN7r7XN-u-lVC`U6cCuKbzB(jDbwj;_iN*!|s)3JaYIpt>_=tIw8a zjwS%8_TO6GW)pMTVNL1_N(}D|1e*l+eKRd}RJxBP>u5<GWSo<qo$ilLeVI9974|jJ zkZ3=bwJWM81B@*A>)rJDcJ){Vf%&WIB`-PGIrKXUs~V{xrgA$x=WzBU;r{zwsFk8H zoIB)X+qm|9t=tj1$2oQ?7nkmR>!cR-HV&ho7<dobuTbR>t!FR;YGoq0jI=s>&nQA1 z6WNBB@{7hEMtjAC_q5?XigM+~0)!2z0}V_RBe_|jIZ81eyN9OIMad-VpE7gu&wJ3$ zC(fcsjj$_zAF*_8DkJYE>Z#~qN&Z4aID|;#GTe?NTwr{)QB3@wX;S4GBOy*x37|nc zI+m%W(Kps9`6h7n)+u3EpM+Q2p;OjnDS)KUa`6e@O=PI7=qr{6<b7v|9L<>cf?St$ z(ZTk@+%dUztN<Nn!DIzy6nEKZWoo@m9ag5?-iXVoj$(flMUc<`PKzU4e*fG1m^s1h zg_VV_0!3S3CLOW^d4*~Om*j~=&OaX5yE*P4!N(%zl{6HG=6tsjHyC5=lQ^r}@<CSB z<0~+wl)f2Vh5nU29VOW%0;TaCqJ~4w0hK=LLjfn72^4ip0O<5+a`M4t!8e{x)aH8f zm>oGxB^uV6irHqlXk?&Bc-kbo6$NNcqbNkHdNj1uEdLuf!7)&A3b}4Hkdpl)X9fUq zvkE;!<kImXQQtTDFcBg!M!=T-{y~|&n=kEY?d~Rl?)5h%v#6Zh7(th+DAg(_M`5BQ zCh3;BSw4ChHl*xxhg$W3m1F<Nsb_}6Y-;9+zOz&4HN|nr3^K^9d`bR&BD~iw|C&eq zLUY4Bo0VmBMQMCn5iDhMvcb~#!sD1<R>N~JW9UK!r^2$ga!PF-tJ=D0W1wC7a&qC} z9+*;;YDFNlWRmdwuh#(Isv|ge5-W?Qa>@ihpmteLPiIb^M8CKWGEl#NPV-sgd0R)c zb<B1}g#?ywPOc!~Y|krp7nt}tpJi7Zs^m&`p^5gD2u=PauBFn`2djKwi>XZW!FoaO zTuxrkszM(z+0{1YS91TM$jZMH#yx!+A_at6(XD+7W%U7pA3@PRPw2#jPUT+0ni-jy zWSs=wk-+W#TZP}RKUL)n=cu~L$yq;1exBYZ*K$PGP>|-smGUGWML0%n*zLH#66l%K zEcM9gz|^C25bGh0B`0tCcn~nn4E~hQeaUSl4L@`8%~Vi7s}LfyYWV3aUh;?SGOpCK zbQP*WFXZIaRM)xy>rA<lsF$VP16H``psYduScRx8Kw!A}T&Cr=!#-8+Y3t~4;c~fg zrpSP%)HW5G_LEQXb*J}cqDxMSp=<(6Zw+l><j?q^q0dz{ff_Yow8rs_uZVJnTS)Co zQknH(@rl`~{Oq!QEp}R6v|C^^*)x{8KyJAo^;sr_)O}9vrT>9)f=_!0J*{=XXxZ;0 z1RzbfG`Sh*3icvUIw5|0otA)pXR=R`H5bY|Ak56%Hi1~L{~Z7ZkuN?Kyqb_)MjDgF zD7(s~admMq>H;}F+~LR|Z&>(sdMl4JG+h}8Gib3uJ@womCx0Y!0>(hG^~<4A88Y_d zdl@vZgka1d=Wh`@vK)x!mL2jgf2e2%*a2IG50}i8n-ZBuu;5cEc|R0o#nCyN=(f1f z*F`_LetJ?U{YOM*LdKN-?C!z&ZM_`$G2eHlnvHpoBS;M^oG2$~*;6029@JagNIlEu zAKEsg(bO~Erj&0FVFRj-=SJQ1Vao@@MLrXm<I{1QHeVA7DQts}ubUH9m!wUqxwHt- zSJ}w|>(_xAtzO3$VDKAD=%IRJt+UW=c3K`f{?sN|&;_a^jw&`tp3^V2_Z54!y{z0B zh4xA2`QZ1Gwnio<=`4w~0irXY7>DvX?Of|+rNzKQi-QA;E2cEBnL0VJV8suKzN#{! zdL!SX_V;K8Oga53miQht98IKsz?p~AGCbeal{W(xAG)_VQ>LtH)LxMoz4%qXNoD6- zc>1U|9kbL5n46PR_hI)!%A$8PH1wdoU()G{3+^_r51ZTFtk5C%;j=`OQ&H{mjt0?A z8J5WQM=IKERfM&9BbuamK;$gj0`n^iYh>xKt?US|B{WO867Eu3kES8Wqg<PN_!Fy# z{V%7Zg07}sXEG-{Y#m$~hqd%;eHVGnCAsgN5$_{bw~svf>6mCwBw;npd<ng+mey0J z<~Q9Jtc5JXa+5&jR>(Qg#+sv&4j7<7N=J?f_9x`kMLgd6I?HLF2*^b946+R#`DS?8 zq@YHtq9MgTIqOQtj0u%nMslww!!d|4IX>01$f6G0pB)y^q>#whyEQS5T0cCro<7ZB zlV8-RZb=l5S>DEJSPF^m@)f;%XfsYEFtrp-Fn4NtiW+@ZYQ|XCcI?{z3O1W8MhnNC z+GolHUgOedU^)2aHM?lr)Zh}!1!<3W$WokT#eR}ZyI1s=r*-C}^C>e0NJG<TjeLY4 zaYxU9=KUdNx%bv5M}&;<-0GNUdQ`qd7D}fSQ<#%&hSNam4n&P4(-PHOx*#qyzC#$d zCYOR5G5pDzE;^1(2eyL;o|A{SRI{&x!b`<FV;;PcdO7bTtd%qI5%50f-(D)Vm*fqw zni~aEEHx*kI_%}@L7h-z4ne8CSX`uoXzya*-SwJglAil~g`$Pn(sP?IL<FOZYyC>x zk7Ij!lp==fsbLD*@^cC9huzzMWzB8yNmX9sV#)n=L=Zfg#L>ZejN3p~*)5EmU4Mcj z$W$4Hb=9Ja^=qCrS8tS_la;9&8OOwPkgZtXI{myAg-Z$2*rwv6AVVttOH-I{%xh&R zsb<neNa@<7x&<wYGTG%6ngM8wu6)~ShUHpcD%5v}ob(MpF+(wwzirnji&ys?-8Q($ zQsc3aevQnWgGiA1r$-V7<#*SG;Z^fA6w%+yea>KQ4w<i8ZqUcVAWO*`)4^ISJrRd2 zVMYusf7dggO{?a*$N3xe$TwOfMPU?d$*14dC~Ia;m)jEp7u|HnXPjL%F;2>4&?CyM zdvL;DK7%vV_$)%v<0$NQZlK;K#nhxL8er;d2bl&}Bx4gpnAA>Zn=@pJn@Wv-G{dP_ zh{bMaBfgHdXt?^Jf5n2S3al#%NRpb?%41FQ#R0NDSN05a(sB%|E>R{WA87|}r=ZC< z+B*^ZT`m5EGh}x*tUV|HSmfXfi&1U!wUIweP&H-ZClO5g@s^oXc+zC%fVh-a7f(6~ z)AZyTUad?a^R=U|Z3Qmue>mq-sn9I<ERLRHn)Lh>pQ*2}ZBRNWe6fxU_xh9HeHceS zj%K^&T&dkGb5}4-Aed5eXGXe5IOQnhfg_BqWy^^~U`Vu2RGNJ0(}5V9XF!aISq_@+ zcgWn6&x))t1zCP|y`ywTZb85vZjQf;#Jw(6<ilm;igzU|7Ss{_75)fSRD*dkhBe;P z=@gtfrY}cJg#GA~kG(!>zSB`KOF&MWQWk5^vk<wxy#J1Gq0zj%k7X{Ryx{tZrciZw z(miQCvLX=ZsM<oKzp#-SL$M(+oJ|=Pyo%sjTf>P=3`bUzVOArhn1#|nXTP-8_bctK z@WiQ+r-fi&F=|*qGc9W_CiJVV1QscZFUVQf!*Nv)<wV8KXd>HpSa?(g5Zm1*MSTfC z=G_2&hA4wslU9&g=G)|Cr>_U08y{IM;rUi+Bw?jXM^pEHGH`wK48YWfKAq(HEPZD~ z7csz`a!SiQPmsPSAwMT)+!xNHNl}~cyP_@3zi&*9_}vZJQ)YkYqU4GaRkDZLj8gB| zCElmSXw>Z@Cp%JAV(6D#>j5~kW&E@OUnR1tr${ZxO2kc9+ZtEKi@?fv0dVL0S5k_# zt55O96V7Y>p1-R-sN1AefG)^~#OK~SstVeMpVY%?IXOPjYbY7wsuW8il25?RI#w-f zYd^s+y|T1%BCrZJlln0Ad*y(f{1(K*ve>IQ+mU^(VbOIdCJTF%CCk)>aiPjjCq<rV z%mmsD*BydxcdDoQUh^<z)z%r~M1|M&Hzf%<qfp)6CRY~6dY_}1e>sJK2Dx8EbSO1a zTqWFpZckp?jmBEsH>lp)T*Z_Z71~QCW?a$JXDZY)JMc1f#ExXONkOGCLS<rTRN&9Z zhh!JeyEw8{_5<t4V~Ne~@98SGFVUiOnHgDlrG8A{Oyoko0_?3}jIJVhT7UaWmv_>F z!K0?EW>tR(GlIHv`@1a!5inychTwL>S=nPe&Qrq-V|Y8N0WpM}Q`Q+^`z#Bsn`93( z8W^Yo{gyl2BehEOCgFzlNXziuVF=?WG+NK~b8?Rd+ub1!v9;NcnSlq|Ly@BW8$?%9 zkX!H;Dos5|YiYLPr$?{kdZk_l=tOI_=TwPYYAr43=|8xuw|_AG;gW7G!L_d}?pXu^ z3yFAMaE~yA2MY7#<XRAGKy{nE`6fmf&?BS=7vPPA^DxhzM5$Y|Hr&YmVlR(l11Tjp zRQz{$mLIP+xecvsQxz8!%Mf3pO*fMGc0qRBlu(7HanI7L$rk~PNNca6mR@8SupIH~ zM&ZyR&}=1<$F@~#n&q62u;++;-!^f}+X&b9X#AmD>tGR)z9Z=-K5H<BFp}Q<Bhv{F zC`dr382L*AnFok_mY0bP&U(n?Ef=!)e%ggPg!f}_5-uPpx`JLQH)f#z^}*Y6LzK;; zSuC(PeeAK2G7>T=%Y0IyV-85F;+O$@e-6UQnS%D4VD*+u!HuvZf}y2lp?P!G9M|n` z>=H#%z)8#vM{QKkTpuptI1a00ZujBjEyzC!DwA2Ey@$=TmY)%jH5ulNl@$OfhxAaG z{#LaH=_hQ0Qtr5)pV?egvu}ti{_=@9yr)*qUc;}mE|a>Jl;f%2eOPY(k1dI(?zgd- zp8BBGN;G0ap&sicGAdH%>P-JpYo_=1C}NX#pHugAV$-aeby-ySO+61yM~<r!gF`IK zEr8{h!Y@fLHaKcShL!-ruS>dN^%;7xGI3^JLdT?9<c7yHEt4?pa`FRmcFem+U#}p5 zW+uQgwf~}aya@n!H~LW|`XLv|%?OtsCE!`JJt(lpp!Ar>Owi=XuL<QDiFQ#_LSfDT zS;v0bjO7%X5{N48<Aj8B9!Q@}Qbz}0M7~CamTwV^2}4-CX}a7%X#o~Tv#gGip4dpO z5W)eJi_!inQWJac4o|gtlxk5+zvtuxt`TxaEp<NOr6iY`s84XWtA}303DsIc_)Zzw zIj|+*h)o-#no(5K9l(ppyr3K4jF5`0NqSh)J*2ti<T=GJ{N(8fhyhy%{j@+l(ZGR{ zd^VMXn8r+-ri2c`M<!Fje4C<V8^8b$YB`lPu<Xg(TW(fU1{Z1qBp=9F`H3QBL#cJ) zeLbCdEe~pGQJa}p09UI$N7nVFisjC!H!&zD?lGiQspPP+=fnTmo)7X9LN)Z>ql7nD z)LW$zUQIWJ61=0Da&kGQggM1(ZC^*ApuMNFv(VlzMQRRdW1qJkh!&W47)UQRJ9wKj zIDBD@6Ga1V>PY?lBNOf2C_bnd?@THmuOpMD`f$|GP^x8}Q@=)KT^o*rST)F_wKQ8s z*&bHI`v*pM>&mV9mV#*|`P0iWBRktxl;o;W2^*4{oDs@8Y-7i-`m}%P)NGNqHNgP> ztgkVN;h|(pG8&0e&90Onr;K=Yn!2MSGb*j`7S`voVzTPOMgjsIv~{m2Br-w{O61uP zR-8$ZZnDBu3w5VVGf1pdT-NC`VPvrn2uxHynKWUk{<HstDaVnx^PX1)o7LNj%Zr81 zj;X<Dy^yX^{W{R~q7m<d+GMWVaD{_94p`5X^~N@;386Sd9Op3Sqz(E?<$QQ0S|+zT zB2zeFl9$5MJ#|Y>Uxth!AZz}=3aGkn@r01044dqAviD@zd*A=Bs8O^nZw}Qe$*4~_ zXcy$!o)oLL&R)8#7W#|r^5wqrOKH^XiqAyxr5O;+nw@!Ki?D053i(hg+Xk2=zp5ZN z;+`y7)Ozf}`T4UK9(M3TX~aTO37!bORt6{%d2`-sN`248O-s|2-wD%c4sRk2%a?z+ zR<F1E9IRvw`4iNnlX%@FKO&%)bUut@5^OVUy+Q&}Xd9Z7kGj&9X-&=fWu?x}q87Jk z2fssm&~;_gJ1yCNPaOU_lKqobWmdTu1@V72_NR<3+}3X_8r8^As|H3A5M6dBLxjn> z<LjktR-0$Z{0~>)JHP>X)%}$AF`MbsGEr4Q3Qxy*NRU$Y;Z7>{wzSZ1H#qNgV3+O^ zVb^d7V#LfKkg`ezWz$9O!X|V)uwr#Eg?z=rVb=#DC+A`h9%N-72W#4;-c+jw@x&tS z7U3^t89QDhGo*;o1$!lgM5aD0(YpIcYV>^MAHd3D{&Ev*aGhu<kt@g#AF!GM#Dmp% zQ8NI4`_Z%AmMT*Ka@HZd?fft)R+9d59KRT)_?ae7=vl;7H!0^W4R6%4_4wHk!(x3U z`miopE`ip^ZjAjslu=)IH|osVc~H}>3hx@gyJV%WdN%L6Hw_#nW%no`hs|*{!uv2x z3?^G-5S{E#z|-)|sOC$49|6iyMuTBvj<x4F*e=efb8p8a8|ju1^Q&;W8}U2Bb0$DC zkV(9aQQnmYde_<i8xbh#4!4#>aHssjH?}eX=UBQPw;RhVblk|#^zFmXBF}+JnhuJD z<nm0uUEPt2Ao!BdfE__jrZ5oQ4XPpk(T^ZF6uiO>AaQFqZqIgrZjB2!t4afk6ufUa zp!WBp|IfJ?i2R&f9d$iu1+PD2bRm){lP1h)o`Iy>l%z0AN4Fq}ndFxK^*kx5u1%3S zm$JwDfl@XcqOAd0$a$D+rInqs^+}cNeLcMUFchpOiY%rApn^}pY5&i^wM@USZ!olb zT3vU<WJGm=rWaHrgtQEQwaThBE7C?9Eg8|$vuZ25xDm+PQCQc8L%g+0ElD@OBy#ij zBZsNylnN9|wT#SqE-?Z?o*~TwgIqoW*+%W)R!7-(a$tb*+^|u8f7}CH*pkj1X;qM} zw~?0?j{%dHM8bBNO)zE5bfNtOd6sW=_V|RkLnv3M;&jOW+YbavAp?5$D{w%TSD&H< zlO|{vjD)cEy@Oj?a2yyOgU@)7{n6no`<A-z4xP_++@uM`rs+0%V4@9vcCT~tZ=&X* zz#&hPe0wJ~o!%!)K^{@=M(lJALFUbxfgGi;SFqG9WSqT-nRxT#T<|*l!qhqqnhA<B z^+^O$$!!xwn=%X(<VRm{s%&?|4`~4SKa`?%wUtgNNgF-Yl4Rj=Ah+JujO$+MMqv@v z0i>I~BCY4d8Gt=vxKe9T?77PhBPWmC=5``6>iqhD5s>#KU5}9-dU#)ld~$RZd>FMN zo1=+>Q6C_IIK^UY9fJ|c)QxJYlGGg0mO2)Dk*KM_<@GrRANf`m<d4N^8H}W5ARbD} z$@?iyaa9zpAU}`NSF^;hs!t=ny%R@InInPR9Ewr}-5*`Z#~plDfREihYEgt?P66}s zJ>dRJHUanN2g|IkTh{IrMYgDuy^9*gxMhoLVB7XZC&qcT|AeV1v`5Aw#1Q#q*Zn*w zNu^_;$2)#$ji?fhO`3<O9I)=eI3t0PD(G2-807{k6WSTYRw^zZltD`VT(Y|wFRKgW z&wiR-?rLqwOfV+eI#xOT;n){h(taTTd5~2_>~ivH49eNQ^^SbfS+|y<p!RCs4AHi} zK{-pC@oJYZ-p$E7>7b;=RQg5v;N{@SCmO;{z|{I3pK^GB`mJ}-U5F>6D08m=8MO;) zqKs?yh|Le3f?hFDSHT<^tOsXL2*^njnx;&~nE%E@TFKtqR_vo!LTP{*m@Blfq`>^j z$h^qni?!s+h5|ta?x;`AY)5l3O)*R6cgb4Ln$~<X*G!R%GKpPEEW^1&_-+Eb^;)QU zj=gkMZ5U`BZ(Ca2;=;8JjS4LVQ{Q05%2)`s$QGU8n*@8t8vx8xGVtRe+&I7suh4QS zFJmeOJW_AwWUD9}KsVd}utqw-TG~7J(wwW`8n!(c)lB-P+<kb17BtsRkADXRBXd@s z`K{+>10Ch85p(SHh+`|T=;Cp}`@n8gRo9h`Ob#TWh)^1#@Y7Fjb;`;a5&;H1+_kC* zmEK*z*&%JKgdTY5@c|ZSqOZ%7L_E4k=5Um5V(X+Q*@fjrnHUw5c{kZ8%C=lvub>+* z)^JI>(yB_Ul(W5`=vJCc!0bo70HpcStfGeBZV0K`vnKjLw;uT(ktF}~BXmnjH;s~? z?MUSt-_mMWIuev*OVpi#otiF6(6uBBG7f20J7qOnnfv4xpK(}x3Rk3lbrHl5tfD1+ zCJ%FP$>j4W^jQ@$PI0jVZ9_gthLkjbq>1PMc-lY_3mD0-$lPdSY%%RkJ{T%|txf1e zQa9L1|0ose5X}FV=5Pcq4Yn@&3|DnzqV;&(-lec)maHAPT(<o2FORHp1_tC$ib#_l zEjNLaE+^AQZgX%?=mzT09*t#=8QN0;=vlCNfUxwby1}h%O!3j_WFooq9!}adi9J8l zCM+bD$Sqenw%wDOYkv}{ehl9@h7p`mi$&S}&Lo!`jMmZ;aI%(`c^)xiTGrv(VJYrX zd&gpUn{Gy~ui_agu%sfHKKR|_oig&okxcS;F(9-r(U}gN1Egm|b%A{1>lr`I&_Z{K zq0zRS6rZO*PqCYp6pRF>b&zY@B;V1V?NAO^>s(oso@ayiHU;nP4a7J=EDKuqYl7?s z;`?5$(&6Lo3f)U*mE~OoBCe7-M8-DFd~{H2iS7Vyw7Dfh<W0|H=v>ncA5J(KUTYbH zlqFjP+cYN+l6Tv)e0ix5^kY3cb|0o^^z`*_^y3*z#?lZHxd=mJ3IE-m<C7n6kTC02 zbH84BcSsqKuM&ogY+|?Lfn`WR>1kDnvl7#2`{zJrX?C)f9BN%B(&vUgfETBU-SmP1 zmR>8bYce<zj#>@0d`icM1I-#0+0fO<;%XyY`cR8o=eXLatZTz@BWnbOhg<3Vi=Tyj zw|ZrAprl%GCf>T{6TS~E=^|URY&y#Wie};<;I|ic!N_vA%$|DI&K>;-ku=bPLCsIS zw5j4Rk+ExdlZ;CipxS4LF=fH2Y4%;_t^sKvfFy%aSIQ=OpAKMQSV32BC-q#rG?0p4 z@}=NAkR}Caidrt@N$1x|RUj8wRBPm$n3u_>L6+S&`-(>F%6|4pPAA<VBf^cn-Ighn zM^%t%N$v4@x4{{S5JmbnV4S3CkKRCi_2DE(ek2@SlR{kcfY>7XBbC}=WP6+`nwW1B zXk>rlUqj~9EP=YiLaKU5Ik_l!Hrl&rqV9IWw{b@}QkfD*7wXxNu;z5c($RMHnsV8J zDF$Fo76Wxd6Rd6K`;KzvyU&1{dve%on!(G_Ee1x}oCsM&FHdji(o%g6W^akso>S!I zfPjS)2iiK}Gu<3e6ecqyY*_gfIB2LL(EJqbRPx825)COaNksq0_voE>!R=ehSy-oF zF-*i5=<4a{FHVs?c|~*cUi$t4qz=%}ho0z?=X(UhHDk+~<&@+I-cgQ`6Z8+?8>Npq ze*1C(kQyoSubKDD2J`B+`)X!6mhb!L!_FU!UqN$Acm<7E3&K(_gX+lSJqheG{C2-^ z&G5#%`9U-@0zX1l={FSqIZppjv><(V-t~|F#_zkwul&G%Q@E0D%74}4FX-7!z{UCB zrtF@`j-uPD|0}qE?El}h>n758>N#6V<9WPpyjcJ53jIGOh{-tWYGiMI-T0G+aoB!B zi&km;Si`sv)9vhk`A^?J?vh4nAT-zbm4<P*+}0>Zev7|9-!Sg|{JYb)`TLHBacADy zDF5L<{r;(UHOihpbl<=4&yDhqzqs#zhkxJpsC{1=CvU-xHoK-##<%d-7q-+_l*&uv zS81g=Zsx%vf9Jo(lN+RQx5>P7^IZSV3f_6*3tZ({{%`#DT;cp{d39K0!}!DQYm{R? z<zDC$UjElDW!z?L(Omv}>8l#X6==A23IFNeuRowsj^n?VzO12fmjfGR+$8?*gZ%f> zEgHt%!BuvnIW2$7xU<e{lppe+{_4ZbS-FG%_|>?xF5`Xv)Az^!KOhtS<8Nu~MlCj$ z_`mTd@qf0Zo3gwoHx>EzX1v=pu3`Ksn~PliGQQW_&@leIZ8@{;_+*<+8pdz;YLNxo z^T|#8=H%BRg?8YRzw(<Mb{5&}4ZQddFZTF~$WAx%A~(Ka{D<c>$jJvaxEH_qdxKod zSOvS<%m2|Jd;gOcck!DK0V3Y?1TR+dV$-J@<n_Q)<CpN_ZvObjGrV{WSNlL?qkIe; zbo>dt_!EEpdOR-<<HeTSHo6O3&Tn=_#oO0D%qKU#rcplsTK~15@5L@n;)Sky#@>yx zbRS-vI<Da*t0p(Pn|^d0AH9*id5ZsRr6qupvuPV`E8Tu!qio6>w$eQpvALAS*-C$V z6uW*jFLb4+y}eOB-o^`EsVr-hC;87-dLWZF?E<>eo|6BXu5@#x?eqL+U%T;CmVFv8 zbfx=#kX}~IaIuv>aJs*#t@L!v6XStHIFyI6jjp?z@99Av_IYSZ>G4($@*OueO3PRI zL=W<I{`k+=_(Tu##&2+=oBWLye%Eu()BNVdpLllBOF#azM!DtZ{?hNhr%~>?*I)Yb zho}Vpt-ti{ziX7^fA25-7yfwYVSnjyfAdVHm;UJUjq+|8=k{uohH>&Q{u{qLoA9Pr zj*~sN@t<78A7{MEfAWEe<7D9;yx4_@d(+<IWQ%?Li#z$_fqi+giVGauJWh6>!izol z+RCZpWZE=dupygFm_u<G|N8*6-*EJC=WijOzhDa~z51m+aN&{u!>9Q|X~&&6J>-?~ zd$5O$9~}Sc%|7)Okz@Q9=jog89KY>mJN`C)lRg46{)SDq-E`~Bo7=u@{3~U%x17-+ z@9@8ev-GRmZ1&8(l6rH~uQzVF*-JXp-`wO|<6pVy0hyowfA-!3ysBdBA6~nh<m{Xi zPDtoARB2))fC`9F>;<BtsGvl^0*XXYq$yEQ1Qi3QAP5GrU;%;+!4?%!P%(gj2tp9C zAsV}4;s0A}&+N=TnD5@}ckg}Q|MPwOc~&y(H+{{_S~F{x;}p7Bwd8e0WfN4f($;5F zvZ8I1Kxsj=O%u#zvjxwlcqILLSfNLAyT+@2X%PCLs$V8p)vr>OznR%D6Ab!gf<eDb z(CpWGRjjl?_sayU`n6pp#qg5L{i3wjSjzQqgSvS$?;eckoa6l|(3F$B;U=Q}M_V*c zfgI(YV0qr<0812DUxCs3(0)%FDI@b7JRT4mkGYeF8r;=xYwtc7sTWil8HhD*GjHfr z=r$Al*=g)e$Do@a3n%(6eviroSvaUZIt6ufJHc;x4Q|gnZhNWgWCf-&SdIp8T_I4{ zWr9InCaCK=<x`7loZ{Ejg^S(bHjOgaSAmBrkW$mJ8dj^0@x&k5s$TR02wY>*s;@Cc z;|-AVZPiwo7aG~Ne*7GCD#ygSw3ZV4C=6DIMt1Z|Jj?9o*KR9{AA%B{6a8jNiJj`F zzK6QoD-33eMjqQNdIGk89TgUg?^ys3S0D?R2R+&v<9mbxVfe`(-?YzBXd%y_<7%gE zN4NyxYrAJjQ|p{mH73{A@|&u$pz|^ZD>+wYmdwG|RV6T>RdaB4avOOLu2CRfu=d-? zb8xc)AwJbcnS(j?jXAher3uZ!5UA&c2?q1R1ogb&Ie3ifFMf5bY7X{RU}z48KwXy! z26dUBu8XJJjVJrE?ZkEIIk;AVtrh6c!CTB>XzUMz#?&xi#_-I1O38(l$+b1Ih~g>Z zi5jR<xx$gXYLokEPZ*?Qls$R=IEN-dvxq(U4%7V=Oh&OMNG_LePZr)6r*G$oJ$Z#^ zq`I^{8Hd{R6|yH94A~P6hU|$6R_R@hqI*^L!~|K?VoywvMJ@Kk1WmoG@sK?+!79D0 zQE7qLlgF_-^%dBYd>ABs1@@#@66p8qY8X0w1@<Imi-w38lzwHxPU?$6>DQ2??7CmW zcIl*0+z7%*WJNDb0{wn<ft}QsVNZTQ9}BS3*q*F0Ml`S|cVXG;E6_Lh8(?5ha<P{6 z#VM6Nc?WZ+M6YFK&?H%~mQTd{!uk@B*VhKv6MZo#>#Gl+oYlpkUSC^{`5D*~v#ww* zn{^48To;1})y1H$i`TNgx*!m&Werx@lg`Gh(e~s!)_v-d28ca5)=0^HVS6%&6{5NX zgFP`z)b`{rN`!Xkom?X9iN#serR~W;m=1jf<9nq62KFS+7+=GlG(e%{JcD3QYH$S& ze0yRxmB)nb$zL?pqcom_`J4;(#GHeHJ^6=oFt8`)95n0+&%t8UAbT2fUi^pVU|>(o zx@5F@PxJ4cgCTpON3zPE95f8DCx0;vm@y_=WlyqTPxKYolMa(y`W+;PuXjg8>D9uh ze<Gg#ev~fW1O~@4Cu4JzuG|u(k!hB5_Xkn>ax228TkgsoQJTCHiTG4^LPeB@?~3}z z^KTK@^)X`j<aFVDj}CnRo)<1_H3H2Scv4oA2R*uWA;KtY^P?UuT!ch&LVOJ1<DOsE zE(F#;ffz2U^m&gSS^*}<h1*~q#=_l<Kix0^+}b$5rC^E<2f01LjK+MbiAm``f^*`2 z_yjgLf|Fnv7z>MkD#*RTveF69;XDi)vB|NV5uaOB^9wMqS<VOezvN4Vb1Zl3H+a$% zZUQOm4!8#@*+qaV(?9;xqWcbj`2bRwW!ZExoB{6jsHJbjrcXfbS~R9(9OqP!F!$B4 zscizx2Z$L3@BT+1X>*G@HcbXeZ(29B={b<(xgL)Or8ZW~ZUjcc6i5N<TH7@L5HK02 zv`HJAz5}^+ZOb{MtxcKjz<g=BkHVvH)nN!{BUNfwo3?-?%le+ke+-zTkcIMWs>@kE zw%n^uP`$YoS;m}*)ALD)V3|!rAopb3ms!>+Ha!bsnaw!Wrpr%57&42WZqvgcky+$S z-0J{|%<dRqQ?Cobu*@b7w5c=P5+bvk2cyM9z_83VT!Kf-E>+B%m)q2DDCa>;!{IjF z3=)~0ca2Rif<$J;*V~khn=ewp&j?H&qnI&cZSwG?b19(wW}8YTf?=6;on%wmEnrw? z;}FQZ6%1td>=c{EPeqtzwzb%%$EK?+L+9AkbuJi|*%Aa!;4F~Y<`UH#mf7A#HuZT7 z5j;0{ErB$bg5kMYfxyyIFjK&ceAcG;b6|L)#$L4PGmuQw4I5AmJRDNM+7E0xe5)$p z8w6hdP!(|7PMexlr~)qCW7Bb;ssgtBXjAu}Q~^IAFzIJ7EZk3i!5yk!!LU5(Hypn~ z5_8+{Hr4w>#kBqta}XpkH`@*!>tLJtIr5}M9a;ktrgoY`V?ff-Mlpw;1WBIaxI@|L zV7MN)hC_FQBxY2?p_B|2^Em>eYpNK#wnMLir07Ns9NGpFrhbk?yFl(LXoERj9kPx9 z1Bp80x;r$!heOvwOMQ(0dyhu=D7c&Q9LhRY<>-bj`2vvSm~y&9Q_t{or1W+u(Z|p6 z8P3jyH$W}&Oy7*axEo!6re{xZ=`|3~^dUtqb-M{+%=9i3U0Mf{0nFSMrF|fqb-?KD zQTiC<o{iqm{U}NiC{1BT?vBzipMW_X$(}>trafTVf+>8+qthOS`r`u15NP)ZG#(f5 zE&@kDQwnp&lOEMy42BCBi@*s>z@PxKn_>%Sx5Xbf2Y;UBz)8q{<})^J1__h5!=^Vt z!n8Zwp`{>U&gllX6-bzCAiAGfd|bd8r#Z9%#0<)u`;$dGLGJt%%kBz2=p2JT#US@g z%ZWl4UI21Ww49CoZEA@{&-jjuY|6o!2Ttz2={9Wxxf@YL-}>+>UyMIe#MPGb>~$*J z)kwOr1*T<7KdC$YaCrJaQgs=0mc15#+#UF{=2!%dhD@%y-}i1agVsi_u<29~SLIGc zU>!4Py1S*wrbaiZm>+Mq>8LwY%#BziFN54QNH%G|O{+k{+~_*=GKd-5#mwi;kzDg& zU#)(>7RPDe^f)})k&vO5tx8d(S@eLhgXBGqJ1x@CJDm4(>XHM>v`9^_UWJB;vJrIO zNof*|C4v6&pbU0FU+@BPQjel>7(so>_T?^A)zhd-Hve~_s!kO;9T7fb=U3G#3G}Oa z*QkoUeNt7TKB_AD7~ITA?Zm`|7L_xz-pWkOoP|Ny4d2(ZRy}Xyj;eZC4qma<KDs&y zlzI@En1L;84zjv4A~mDu8TCrLH=~PQYom+O@L7@CUNP#|mw-F1Om8W-LtP9?d#3Ev zkl$}<&-f%zx5xV<X$$S%i+0^%w2SxEuCy!HXqRj!?~l~?<{9l05c2V!xu>dK405|t zKi*c=E(X0n(xaP_u%KBTjg!U@Zo&LW6R(*8$}~H~ZQwm_G(f<na3Y%xVDO*@Fqqr` z#)1YE7gu$mEjOTzo90b`^H5(r)W_cG)QSEuB@Fr}VQ-#Mz!81{*`8&b7I{uf0juCp z)E9&5C>`Bo976fD<u1U`d~ATwh2%aMsTsQpp+cTi4@YVVQ{ppSqj|=d$w)4WH1$q1 zmWyo57h!^(UV+lo6)cxyDm3KJB@s{bLt}dI@k*A9cZN}wocy1}^jL0;j)31_dc18+ zTLxv?UTRdupiJBIlfYnj>Ka{OZRI`@sU3a9XqSLIZ4*ahq{>+yrC7#qc7sy+1WZjk zGjTYW0x$#Lw7tam?lzS%Gs13?acv!&Dw%nO`<KXfpsn^GSC*Zg-~&_vGgF=V2|hTL zF@r;Uf*l0epZbUO7&``vz^FrdA_vW=0Po)Jc(JpQE$=fhEo?r_QjH?qQQ^y1xGzE3 zwwU27T=uEmqhbSvdl|rw6zC#bpm297Fr;ubn9V7*!ZksESXtp(xU0igmBPIiRW(s) zpm15Yw^CrBa9Ou&FqlEC+fA^lsxB&jmBPIVRh6(*SmCb1%qeFkP`IC~nZgRUzsej^ zxF)D)imz~yHBh)C%yx@nn}&LCQ>ZkY74CY}9|Bq7vf?*EnYr8^6ATQ13F`KEYyf7f z%49{d!ev7c0;OGZ(XNM7(m>(vK)XVqR=6e@=sOeC`p(3HW}S>_v`y7D1QS3MZg&He zX~qh7FB+gz3aAyX2?h-?LEQio3mU)*cc*GVNa1QQq;O48DO@ffihGfK1qzonwgv-* z%NpARwZi=dtFlm)5GdT=0ghE*pm4ik)fV!kVuj00iO+P6F2b1IuaXA}cK|$Jixe0r z+@gvqFjy`llRyzq^fOG4=T-hHh5Ib3TBp!J;r@cr34yF|w_@6wpiJ92sLBLo+TNK2 z2E+3brtMZ$S)g#QLAyerC|nO>Drb2F3ik^zfx-n-rEr-E6fQHq!hHl<I{QoHVugDj zm;z>4;qu+LGG<ue@*TeHy-MNooxLJ3TH*eVVW|Kw3U?H;<$VQ4E8J|HxA?jjQ`qWv z1(fXuR=6u7a(k_dij5+L`%)y^<E4150%cg=g>mDh7y|WDG{Imcn4n$>CKiaAm*OH- z*D!9td)WK%Qq-WVI=vJ_pk9h57&O2HbpuQ+XaKLICshMFa0B$-M}wFPReK*3G?wBA zssKFE!v$o^=1GIuW&tLsmZHe}6dZ^75_xaHj-KTm0=2wNFzBuc>h7AD?rzk>t&DS2 zU9yf)SF{em0tIHH5$?uF&4d^zo<$#M1I0{Wp!OLC>NS-&WS~q?SMM7rWOX+yL$Fz8 z#gtP!Z#GbS70NPkw<`k`0=0oML0Rc+piD3@P$sC`BL?bgRhiiK4^_KDpcts3r{dA7 zBmGh8%<ZbcC_PhA1vX{yRonr3Gzpa2qCY@?v{w10x3BW~hfD3QP@ZY-E>)@qMFhH3 z6Raw=r^?UbM*}<(EnUcB{zR*6pYc`pRVuyga6ZS{X61UF0%cNs0g#nz2-M2e1V!Ym zTum@gt|l0WoRw>ls!VLmXV}fMat(nZ@=*}ZOqEnj$v#Ylb*N2)(pVPGt4W|Q9IFW& zq$)q$$i8qAqOw^Y-{?K^*I=~D&IiLPJN6qM%qn4KxQ#`bU@cwF3AL7{Z@_3RUBHai z(q&-y9#)LCbarJ}OBaC;v~&eCzLu6|<$VjjQZ=iP8QrXMFx;#tH|wgS{AtL#k((#` z`JC^-X!BCQOqF>l1{*ZIoEhElobSQth8Keg8eR#;G%xu-ASLhT*}Rl8qs<FiA(wAn z8qSQ<%^)@}<~@zTyqHI8QFm-!%%in{THWcw84T2&32Jp`V!>oHkJf>C`JXykcR&*Z z^P-y@GA|~m%!_%n4$O;rw9ZDRgO1h=YV&fCyxF|`XXG7iVcaPX%u9{|a>K;Du)`_i zM=)$&*x{7Nj5aTYU;=fHEON1a3)H#7h(SHvVqQwP9Bp27s@e$njvdqC6qpy&;Ur+P z!-+v@kLhq?P}*ZUoEX&Y2|1hs^I|%jsvKc#2=vt%fxx_IFl1g#(ARZrUi2ls74tID zC^axIpI7LFm?Q{_(b|>-`lZ%@2Gti!+BYxkf~jCJvw2}A<0oOlE||c)9ONuv^YY(t zmY`+ivUxF`B?5|hDK>-?m=}AO?l1Yzbg+5(u_6rm!f9v-r^>vr3nq`{q0LJnGg^<A zfeFk@#?QX~R$iApuz}a5kQwcDDQ8A|U2=Xgye`FHw3cSCOC|Wg>yrN~7-e3#S*6Tt z^HRZ#ZdTrYzgc2lbYDZ}rG!&x^HR=CmAi=FPY4>G$Bb@x2{XFk^t;jU0x)L7%fJT> z&;A39GB57vCJt=|xj(p84c)eHFmbJZyI^O|xEr?Sh)Cj(!?3U5eBC2n$nc~ikLyGl zg+NhG5jH%=Bsh;#rsDv@kKpQypBxDu!8Jjd1o8;3MrGaUM{rG$jp~2pk*UVqSb1d1 z)cVqe8j<vn))z3@$})J6m1Qv5$}%Pb!2f7JL%}xy;G(Y3eUb=+88ADn_4OqwYXW5L zuP*_)RdU-wp$r~m4H!Jg8ZfAvC7XLy0@X#pO`uukZ3qEH6_^j09mh#)VHV^Yvq0tx zKZyN5_JEnVO_ColW6)PdfBAq}^hRT3M8(yH2+Z3`vN-Bu5KOx$Rn-G%+C>4A?IME* z*+m8qvWpA`BV*o(5y{p;vrM}vpp49NV|~g7sv+j_Bx7V)CCK``J_(fCy!i$yrLqX8 zCxN~Qk2CbSSP5B3tT^@cGS}58k}j_GGFCQPfzqG80+nM!9y9*2fxYR4U<377!i-jr zbO4N2j|E_4_s!n)GBBok%qHAP)!y_XW_<N{@STX(I3xXsjO)R7SX!Yn^Y(=3pO!d7 zn-*6<8B9}_r7X*~a5V63iVE(LmSr|>QU^A&fSD>;7K06BS;mZ(Wj1aW2eK>z6Uedx zj48`J2Pw5IOPEonhTJEcJCxQ!*_txkOXthCHE+Vs<lf`knxS2}@yN)whHqMIRY?O| z!{Db1lxe4J%@KIqfv=FQ(V*yL{kn$<`g56I_c&SQ57`<M3~Y@Fa`)x&Tocp>1b*G) zVpXi1()4Q)Cg?8_e%<35m9)y%u*2{!g-RFL*02LB1ZrDjf`P3uL2YYHOsa?2qPIf^ zC8{nl7Hn(y7ST!t2DXMBSg)8V+1Bu#mJq0IjR^*}#smXfV}iO_Vr#al%0jj#1j-`d z9Y>`~8rT}%acEHHi=G80STzfNQ~8@gB*9BRCK${D6AWg737WH@5uU%{i<PxJ%*-$S zm|)c`=%A9O_(}1!!fcF8Cxr&KhVQ7Ir@+A0u#4{!vnsYVd=DxFY8Rgg1|wsF!N{0k zXk@Nam5F58*6=PM1j@*~fsrXvNdsH+JVc<uz}7sG1o|Vh0q8WdDqcu$B!RvN`(Pp6 zr;=9L8g@-RsnC~Mu-ew-v9i(nu?S3{AIq4ja#2-sLhYi;j(}nP$Tt#-n9-h|3NWG{ z*+rF?Ql%gHMnVaA(U0uup;R!+*07&&Djv_`OGL@GhW&&gQ2Pl@P{wUeML4^R+nq_E z9yhtUbdRcxoj)$y8g?EoP+(wd*m)QNWiVNmFRP>>TT{S2(y}Z86UefHnJQUk;BDhT zmU+x*S(Y%PWl5eP%K|Xk*03zgzz4F-P6HFzn%S-JRtSjCHSY359BSSM%yAK`Mk(GG z;p;M-z^s0=V02RNh2iP#->+G(V�@H&Q?GaSzN;F8X}9QZ|7pW9Gz&Cx@GUc=3d< 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%0DQP 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�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%0Dpu~D_sc~ydv<C-<pF>#KeNM%Yh^!E- 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 (U!@7ioPAh+$oGvUA`cn(q{KmDs$l0Fd5_JgF}3 zC=amP^q=rh+d*w!*wRfNI6=KQb^W?JYq+8btrb!^$`w5v+^JCiB~J5rHJkMRx&Gmb zIq0$=x**AcWNn~=@fr=Yb!bD&OgaYOFL&3%4)e4j9DBr9ZX)aZKk84WHYbL7tP5L+ z2|^*+nfsGH-O)r}T;a3jEZcMcFSF!Ip?E^_`EnqZ7p)=9GvUCaBqfKRN|Np@GrgBI zq6~yoWlx2{qLp$~?75bU){~T*(9OsiU4$q%Hbpst;|)^-0776a0NqkXli|wN?QFBk zj&{&_XCGHp1~fZBST#tMPyf!N$0Z~Ogfc-e0;>dqTy6<#)~q=;jhh`&*@9n=T!<;! z&2TIe5mD(Qqb6<6nO2K!)NH1DtBt8MMM)tVs!J0JMxaBbn7`|)#LWhpU>e}|gbS?! ziv(XTG{YmN0dYtf&O;4)l|nVaRy;bPBnVUS4uTs%ZX_Q%w)iQ=uyWrYeOFiaWWA?x zpC=H=NCB=Z>&A6BMV|S}*%6Co*enY!d;{{ZQ~~EkF-!<yg9qOYCXfJGryW_4a6B}X zU}6mD$-k02*>U0jYYFJ*&0KLcAmUXW)VoRF5TyYUc%}jAi5$b?ocG6wXit^V@dcv~ zK_}S@LyL4`aGZPsH^X}GKKnl`9Nmhq4H!48G;I+`+5r-{){?$z?GjMBusxA$yTb!! z#=fUsljw6>Q;ad*h=&EZdzK=6CW4Ke7IjRv?c8Z%q^v$tFWJ*NXJ-8@sKdq|&fd4O zo|1!i6S$YhRB-(Z!L`=4VWh`k7sWl2pHHpb@5=S8y~y@gdfNU4EboUMTQ|W#hU)q) z*~X`*&PXGNJ(UFjUTFkx49FLNU#rAW&tbKED)cU1Igs9m-uIUsR-canC>~p+`@i5Z zuwC9VywRpnm&OnsQpOXtaHAYQs^mlV2Fy2Aw7`wDVS#7L3jWVRUudybW$XG`{H&@S zSJlQHyygfPS!_WwB;PxSv9B+ZO4J>X#nzLXL$b37^g){$3`zgE3|_zO!PMa^<cZwp zH4wo3L2!D1e@jwb-pVi9FL6<U9s}wCyo5LlsT#t8;hrlk_?LSAagM^zoAUPd`gSk` zeC6_pw?St(D^Jndo(z)#5o*_6?xj2oa`UK7iU^|PB#Ls}L;fSW_RtD<s|QGBCf4Q^ z)zs=&JLOM2;JZ4ZM=*sX32Y=3eG~K-u8>FT(Yyx9)Q)mk{h=Jacc48l%MkpL08WZr z(BZ6SP$%&|yx~6UDCMUDk%D5%yz$*!-=L^b2dd|Kc+nj0tb`3?cYoIxyAcG9H4eh8 z%fNmBqo5(|Mdjeaa|fEuhjKtL<<z04QJ7qSc?PbGYV?B4P3fm88njOxXfjp36nKf< z`-}EY(p!2!aAGKEVs>HQOD^~18F|4w*uO_)EIrjH)E&ZCkb?>sQ#@Y->c!-Gb%(0n za1`w_!3J))0LEHXRPL!r9k?Rk!06h(jxtUTSy)6<=8uh&AUGHkf{~#JI*bIV?M9$5 zAOVs!1KJm^rcelRHN~U9zm5%>a<=a6&7IIpf{Gz&*Lg*mYLJKrn5IhI6A|QRXX*^w zviWb`++Y2)KadQn4VJ?$0~<!j%c|)C3}j`itdzri(lAPLfg9By*&u|il7wnx(sv_8 zxH5cdrIeFgwP|mJ#s22<;%-N|?EO^(mc~!8HZfy3`*X0Fa$@{#B)y(LW{R>;8_)1M zUIGj+FbHv236d2XX?%&(^plo)+C?e=TLjs#Z(xcpvIs}H)bD)t-)eXMzh5LSs2wqg z2cS<u=a;vn#{du&5Vhb927T(I-(eu9N;Y>5pA+%4CP)RaNyu@QT0c-@F~<PSOH%S1 zqIF<-f;NTfHo=)%dc!C-;LUVoB7_!KcNbUp3Y*fFXA_diYwC=tG$s*2FeMLvMV(!@ zUeG(cFVPww>EtGmi{LJZq0%PwpW^VgC-)?nk!&oMZ$Yn3Lk=z%dngE^W)DoI?kQW$ zEI;~7nzlf$#{p+atU%k@la?D8`4~hJ>i8%zjzfGTljWXv73*q5W()%j?j;~$BCZg6 zK~D93O{Hg3u;<5*rF$mrbU^|iSw$~1mGJ49b_yJR48&6?fVD6uvzHY1rU~?A-nO~J z>7*t3H{8Mt+-a+?3CMTD0bF-siu=~39`|6?M*jC4^0wQHPT@OsAW%UK4auBB>7W8g zf2I)L2Q^cuV5D>B=c;qgmCTF}fPUi}QfWo*y1c94&dY<A@Onk$dfW&reH(!Qp{;;S z9o|yXkSln?ov)$?0G&@6?(J2W{PF$uU#btUD68bcxD6A?lwnoA-0kmsIIQUd_#+g} zMDP>9O3<XvW)#V=){ud)BFmn*WfTzNM3QyRmk;~bEjf_D=fWJA0(}{CPxAfaIcfL8 zE^B;wGV^ArsPoE49Sf6BO$M6a+BE?G-z^aF3<vJe7{kPGhRG_RLP`*?HLQ-nqH^T? zM>e$^MPTG~w|m8G?Jq_{02mbJv?6sFBoo?Sest4&ru{!^B>+YPZbC{Nmdbys-oJbC z>h9KVofm&XQ&-y7_><CY3%9b8Epv8;fxiE6b~b!r;kfFvyg@4~_Ry+Bt0XcC!6Y{v z=?wtmg&8`x{cxC%HOtKd7Y0QOmT5pLDC0_j^>l1D!Py_r@5g9m8K@(nWDZ0@11h(Z zjG=B^HAi7E&XGnAWt7Mp_`tG+&OxWyX%G#aQo-y_vFZ4gWcgCwb9pTV)MBI5FpIR6 zk}#-*;upb^Na3{*3A6CrFniLoQ(ka%M-@FF(JfGOz|3`Zj0MA0@}yd#2aZxE5h)d5 zN9C|S^>V2#0)mJX8S`2eCTQ7JK#97OMmI}TdU@5rrFQX76*a1>Sk-gR&=0IibSi!n zc{)-;l%qe^r~)%%<q7elKv*h*tO*FrK+!J6i5fp@%u-=Cd?4^)HjKG29<sF~n`uW1 zC!(YH7amD8{si>9T<@ZTt|ODzRB<_mMborx4m(SYIK^A<-Q99tEcS*%)AX*EaZ?PH zzkr1<?}no%G;-TGdU61_1D6)2n1E76uGjH?Pwp<>cEz{%M9>5RC^UxP4ikd83PDi; zy00tKpl_i(8^5<Y&u}kyjmX!Uq}e{IiZoB#1_J_hM}1_91LVEu=k~>F0W&u=D4&C1 zXgW5psZuATy1lr20}F23%4skPv9R<MVUz*uC%C_?lU0b<2CLx!0n6?I&&;bb1M{oW z`qP8^^y<D=ebQ}1%h<rhlEqYF#ku639_y2Kg_J<5Md)N<0NrYD^eGRd@sxS`{k=ll zHVCAud-^q`#I^-KiVT1)uo|5+u{LEIof2kXP+T*dD*$j3heGStj)Wbb%Mc&jRYAcN zq&y9ls=8`k$)ZLr2&o`If-CGmfvs&x@3zj#;-;raa43KZ;gq)vAwWtw?mOX|3WNW; zzWOUa{3%O}a$0~Q7Bx|y^pylMoE2OIdCd~(GbsILJ}xe=Uz5j*mR<>CSJ(xBTXn!X zjZ>x{LHOP6)WcrSz;-vkj!{`@r^R0(h3a*k^f^>Z#|M%PeZXl8JqUaVH4LV`xFp<3 z7+)2Jm)(B9yL(ez?ZEDN(^2CL;<QXard=7%=R+IMgV0C9Y*NQ1&T>YQ3t!dITVtS) z_{|sPcw>l~BA{=|y^7`|&SvF(b-iL83Uq=Kxl1ZSt`P<j#+aabipKrokGCHLtML2F z>+0@R*X&h3$1or22u0!ILt)q=$Zsz+l?g(#s*4=6fb3(uMkdARNmU%{2*ZO!J}q$U zfPx8hw{e91N^W6tCY|{@#YZu^KyW!{31#CMEFxJTrLM*W@{w;aLLaJ`7Gpz*Qvhs} zv`=w@&D%c7CsLJN4D$@+FHr>n2Ipkr6Y<&)gF|&$%B9eroqZ#2iB@ErMhTl~aGQ-8 z4rGxvXeDh1`alYmfOc<tx=cCZ8w`XcneGeUFM)x>VNy_D+hg}TDamWXbkw6T1gI*; zQ`F#h0g2w)Jt~X;uG;_f;>YU!U#g$F+du!YsxP}2ySEa>xxCozF95#WiG8hqckBOd zzu$MU`a}gNr~$sYC|*?Wevagqup8}a)eOI;9r*x}UcZ+Q`N97Xx%Q-|$1@O!BErVP zcERgkfX?F?2ytYULGBrR3J@HQJiW1a8Supe%>MfB&4NleemIB~xpp$$O!2#m*KzbS z5SPLD;8CTpM35uXsIaCEBWYNCd+Ei@v?*a;z7@f-(dhh0z=Bp9w9767hTFeMrq<s8 zeeT|hkz8hFRX`;lpfmEn3KPJ4!t2dSqp93((iRF+ohRs7MF<>+!L`x)^x_R41K~b} zV$Z4q*EbyBoGmcpU02#l8^h~CVJ9+(BcM!zy6YV6bM;6KDsu%@Uq^Hf6{9cl3aQzA z!or*|8ES8K0^H2(MG&jwi|0(o0Zw^m<jMzU3UW-zmmFcGnQKR`FS(8*TAf;-<Dn^% z^Mu0_8WG`(FG?MReoicDwnrNQqD0ULlAYdFqPQVX!n+-B$q0I`8r@XDJ~1~r2sTg< zNB$Lj(hJNb*+DJ<+7Y*W5B1_U^esy-5O;Z%Bi({3hSP(N3B3RZdhFFE|CZWCa`V7k z6$+3Hx;Shp$V%Bgx<PCb?1$IX_j(6^F6_n!OZm~_C6{Shp*?}wT5x+eY>nYlX^<W6 zcv|$PwaGVUXB`Jz@<}m1zq3C+(ruk&8H7;apH<x3tvEVVtkHO%1@6mw{$JX;P_vur z{)+URX$y4m>`dPR0$h4|`G=dmvOJ=me@H;xnDTWE6ANy@22V2qX<qI=Fi!Ntv^%7g zVrj(1Sc|99xd%>Z&?<9%M_NIHo2DxZau&wcPEy~5bf5r)1iuoPa}oPsqP}_C_t<?Z z*AyTmDFGHN<v8qP*9*%!O!sGwpLxf9%opo|_;1>^c|-&dlrzP0C!dY;-n_lh0B5Eq zZ6aIw`0Pwr)-I~cKin$)QS`ar$y%#j;li7#lBwvm<Twe`FE7S=EoyF7EzgZrt^nP? z=1)m|10l_W)i;hr_1;&qH_gkx`<t8w{a)Ukc7MCC6r3E<o;oSeCLoU_?0~yRK9LiR z0Wp^oF)bI1b)D`|_1jcOf2TV-8?Qjpm_hJa)csAQOA$(<1d~pB68vG(8NVmbc~i8w ze&UuY$_mm1{D;&}b$f&xT3himnyzK&tZr|s52ns^vi!>1r3_rEpvAZAi=<)k*YSDO zmzkOdJnal|Ck0)V@?xK2H^-y6cg{<y#*^vsWLk8~D&%1Rk5P@sBgfFy$M{Lr@mNC} z5?}37ZUAWG2;fVUmfx!iR4r>ctfL05`tG{yNgom)(1I3jS88qOLOm*9J+69_%@e@S zhyFkTtN6`m`blTTGgQiuKnnLkTef&3Tjpmel5u#JMnmHP6LpfEf=`nCVYu1>I?FmS ztE`=(C~Ib_eK~w=U3ZXV!uUZX6t6v@tMNLKg^cv=Ivh9yo({deN{QN8yCTT@9G6qx z698zq$hWjISOpm91+=_PO!fff<*u?w7p&WH?D^azL0@BA!><8!J7}G(nY$b3Eex+F zvk5kb5U3XNAFGs$-+u8~`6$yc!zNOGPu!0}kfh{}AYnQua~A1we0Ey)d_q1-60FK3 z1NAVe0lsDp52<fdFYC&^RrRj;RP2*f<>%zEM8v<Si=XVImE(X@?e_MA<Y=16Pz&Z0 z476q4XH6kF^24rDnuFH!XJlmye1;7%zc31sL~WFj$27L2PUl2LxDPX>-o}G>)+CKq zF}8l!K-!S=Q>I1gARCU33PqV43uz3Y7`$vb@etr2PwtDJ90Evq_VI~zl>3td<u_yW zMDNm6_RAh$vh*S*2o(UI5Tg7Nm6^=Q($~X46n%a1dZtiB(jiC;VH*O~$yKO(qG_WL zbTh3FVYJPhAh8ze2oeveh7CYK{m6!i?d)#5w+vn~48TMrXh`NR(3{8S&fdCw8EQd- zYkV!K`xvZ+<6m}fA{yXA<ccZT+CtG#Y<c^r<@ZR~lGqHXo<w(~*o8BZxd|=a^eV;U z>`ZG-^QBN~u&DZIwW2K3y9j85xChV?GaSrj{Q|@3q+Kv4zrZmmcn@S{+QiuD7ZNWn z3u^uWSm5^Z5+UV*VEneWHYlTj)CR6P%)vm><h<@oyqBKMbS^#gMZc)g%JdVC(#dO| z!c58u?qMcD9RhYq?s6}>sb^v2I<>;`+v|HA+uxy&w_>qN5o#&mP`8qIChG+@DOe>b z>m_a-cGK{wnH41~eXCy>64tA|wd)?JLJ1=bMN%^rOkJsCE9zR6<l5Wo%N;2x?@2Dy z{~~5(St2(*#QdM1vnye1yn1a{&ike6{!qpv?v=+xYunVxO%HjU{)myt2uW{-nM7(1 zhaYUon61IrYJi>&>ur*P*mnXg`fdd=(XRG4Drj_Q&j^CTm@u<Aw&P2|*T~I2FbEwC zw3D@|!THvFhM9QsS5W#sVpeS0ZkrxjTsQBR`gAFQ7=|wWqb!D7O0T!h$?-;4z>$74 z7jSYNc|s0<X2g|CqBjZAp;Uuy6mqheMiF&<GfA@+68Jb)>!$hM^pH3IcJF(?+$Qp5 zgr5b4zU<_xbRj#{bbbPn`7DCM?wL)yZPP>E?z7E%zjWlpbGSNPh#N=}bEu%hCN9wd z1B@tratC-=ebmQG@Pu3Lv&5L!AFSvOpH++M28k<~!;h(C{cn&M%5CBrK68ZJ8A3l+ zdq)(I1D|C%#Rm4&YY6}6*rV>s%+ZrR-@faB*}vr5*WQks?$u2XdH1Ys-utC<`K}+O zFmksf-U6UsK~{*`ysxr?Go(`@tj74<CuqE$pG<tt59vz;wpI<9&(Egl`4+o>v_t(p zI5^}F3-V0QH2W{1Fu6&DW+kTFOeNu|Mfl&h^M0v5i;Y{tc$@PW#&xpLG5`{iLTV1# zD!+)$@TuJ=14XQyx~`_?j`GgD%ws~eI;yDBG0j}B_=rtu>2p|jwnm_@$*ahEQu(p) z(#qBdxQf?!ZJc1$jsE>bS>@l9Ao3_*>(L|&VdW#krK*V|CA9$FSO<f^<1KgkQSZ9X z{#c2CkN4Bm?tjF|<}DkAn{T*mLsKV-jw(j-eE|eX6Un`Bchb1bo7Bfm4|!Ml0UgtR zq^EYSP`N7R0l)s|!|;q@nkS!ZiB0&YVL%zRr9X+1&O`k0s4N8wDg_**q7aIl2B}({ zo`BJlziESSdg!rE!Dv=|jv@T`IoSBG=n)(bv}or#1tQU@B}3+-2$r)mK8E&|yb-s& zMkh5I#lFk(wy0p=2_fsO-8A+^^=n||l&>F^6cm>PHIP(fsDwo&_1UhZcyih2Ux=eN z`k1<gFI!hh#EfOVSzis?K8Ki%EY}eKkL0<!Gxs_4u9y(KyKOBGJJz5JWI2L>6jo(W zkn$KiwQK^2HG-FscG!W$v7-?DzPa1=7aiF<{B?D)7jRCPs-jL(%E)Po;vCQR`s2ga zIR1ucd;@XwvH~@$k&@cD0xDzv2K)Hh8#Ln2?(Y8PvYQQogk|6_1=g7S=O7ziu<-QQ zJ{em!tvHNqPWArc?_F#FlqmfTDgg`wueHx62m};&DcIJ#TL5xf1rA1mD0Wy4Rs=wZ zK-N)$<UR5g$(@dz<NZsG#63kuAZd`hS_Tqlm^LD{CK_uc%CdiW<5_4A!uA+2%7F4` z^4wz5x~J`B4zi}~xR5mJtKHT0-R>I90Li9elTZ>D$CMhC0pw1U0OKr~JoFW~4Yp$> zcj}I5%pX3P=l`K0k<Xz4PJRz?hok}OELGk^jveS;f=viNm&!9tHK^%gQ*@f*Fy{Kz z-R+OE82`~--hh@!lZ6^B^*M~8P7+darT7!vLynHlp4`~QuRRPF>Y#%n3Xo?7MK1#F zNGjz2&)(aGT9##dUST&r+}pH>3bzFxQcbh#-dp$7`u^A^7qcQG`UW?vD#?hf#J*e( z>oa1L=j?sz>~k_R3hKc(?HBvO2L&4x?FR+H2SE@7k=B0mqeWY>9~yj6uu-93d=dPO zIp<nyuCKk<UU4ETqiz;d?ugiH&pFqeV~#oI82|AfD~H&T(&*QRE~tp$bpbRCTvx~x z8|d*|hOO)Dzr2)U(wg_VBqb<t9e}1qRwI)nS+-xxDm7;a)3(`E!b-i_fOI@m&vti; z+M)MAUtGqnLs@nu)o=Xz8e9zNM?^&?2e#HMB(3f2*GCDsen~-az|xRXvdnMo_1#}7 zsqZ%R+zN$i2%>DM8eTxU?y$Wf7slzRzA^3^wIVys(X!bzI%&a*sS%L>VI_X*VhtA; zpQ*y$l27&G{m1V=l}$0T8RhbzuGo4r@xyINiktjYn_lB4jY+22MI?2r2I9R1G)h-b zR9Dg+{|BEfx{wxBo6H2s9tjCAu_Tli@X;H^)I9N~Gt!gcDIsrkl^4Y)l_;DWWO*eC z+@UEsI&8`Qu0XSUFyS=|CbSLBo)wMS9y6}>gh}2Zg9|6LpJEVU8dcUIeo~hFEQZt! zl?>6M=LlciX<1@u3ucDFzgxmoK&`;B5hP?>lZ(Xh)DyR(!n9;c7R*_5BqzUWPUqO| z{^%(gGnE17c9U#Sy=z8^3+lAAHt37n*Rrjm9CrRfthkgcOo+;B$RSeP>=+;Vs}Hxo znd*bunE1XutSt&z1VYcUc*UPBn2`kwZuT;*O>g#wV~YpOUiYEKg@QP&xjV92R(|!# zy`ECdIxU0RD_rP$>gG&8CfG|}Q=J=cQ7TLL2~uc1D=y6`6=yrCT(axl!BfqRs2h)w znUWm>(R^cWFFDnoEt!%t<dWv51+zJYq(dW_@FOMESc+1(@hNCy<;<OwOw!O}FAY-c zniQ_?B^J%1H*L@7IQSK1Lf|HbeiF-~WAlG>y}gB_@)imvlWeI<m9#G%9A58=2)xDh zws2kj3H4m2$^dvp1Ur=E#rP0bFly`j54RlVAF1Cx>*mmIE@{3EOnanN(HLB`c_1Yj zIDi@h!2a2A6x47fTb8_eQu4@!V^{Y^A=gFIksD1mn6_Ux17RH#m~^>0W@N=lGX9c* z_|yV|z^p(bpa7RVI(s1M-l}{0{P;llx*Z5MJm(Q?-E4!{!KJ=rAPyJ4$b)Vs^obmM zsC9cFTe<t1SGGu;>?v+$gqWyVn#A$aJfIST&uu=l8H?=S4VQ+?Vhzb=N;o))nUZD0 z$GnFqiW@RqzEFH%lJ$l!H)Jz>>(sD^(F~t!n;Cu`Q;w!glh7?F&uOPt+rJwQpDMu) ze4nXLv0!dN=B_J-$FW}_k3LMwj-+8b6dCSby6^9CjW-700GR(*l~AMO3r$>thmn`V z0U?@CJ9*k?+Vz*V#4HXqAL_ur%a<f(h{LMq;oXX7Mob?0HQl+f!*xE&QsJ<QBg<}{ z9_sxK9sx5{NC{&~v_twT)yREbQxCO$W;9fvL57<CZgRL=iil*dj}ADbnoJbtz)i^E zEIeyPn)#4UV&3kOE493#m!zB}Ir^%o0>R6f??$5wwGU%zWS__i{SkZ`wzqsZmkt_` z>}32INr)mJEW7dvd4HwakrP)a_lg=Mgq<=-aW*6*jg#Swl0|XIAo<Q%Cj4!)QP<kf zWdRrod0euT-JQ94{UdMD{PyTuBpKv9xMkeLFZ0^fD!50`%3v-o7z}LdW-zM39xqJy zjQz$Uc%jNa7D=xt{SHw!lm+Be<_mQ_rBTv?QcYQqIFyI6^dYIss0wv;Z<mmNQrBj9 zdJmU3x7)8^Y*Nz=Jv#11N`JGh<sxc*Z^;F`r^5yfW9zU%_$niu$WR@Us4g7(jh2>W z3Gx1Acb=y{E-9n+Qlx-_2x`ADp4^og2n(PCB-{%H%Jicj@;++C%_7U|jqW&V>ecTr zF4W{_S5No1*V&!SL=a?G*Z?Kjr$X3Xl~M=mzPdcT+TUN5lx?am;h7_8lsYVmum?^g zxNO0A1#!iOXO+%rU}_qI_T3CIDjDf&-!l<u5LR5r3;b<$NjWBKA_fn)Q=yahyIH1w zACoP!Y`uuUW3M5uCfOF9nsAl|QfdX~k=4Wa`Pok9ml9`k>>{F^7I@DxlCRtG^j7^t zUa_~7Q_kIoT}rG=q6S=@s3;8!lXVtbLV9#{s7!-Ho|v830-0#3X0Au8W8Ut})#1SO z3mEi67^8DYG^`$`R%h7BQ5_4dauo+z8dBfDFNN=o>7CTEKi=-BWFVQcTD|HMYl;ZL z_Pz@jwH&OPfI9YT2L^b`rNH6l3yGfbY<QvelPzoXv+7zks#y;bFHf`5k0=BOd!1m_ zP&2(MIZ9%bZq_d`qaM@~vznR6L{;GiNvX;K<GxKyLHkE1SrX)n7~&wdmZK`W%uVvo zio5Kponu31rd>MSOQ?rdy#qIW=-C7K2q3l~bl2C&$KSyz!#H>2oB(+43ZixH9U8Ns zeT`P!k9H8}SfCt#6-+-|7DV08NMduqp4mYGhrH}{PmEV8Mb3B7in?5qw1i?3_M%Qu zsf^B;dAY~Gl6wW36-j^r+k|usHQ`iK-C}>Nj{(9bBJv>`{60ZrQ=0?;0*F%9gYvL8 zTStp=m^LaE#=($JKoMu#ZrsJB6U_q$gt<y3Ov1IsBTjjStPo^!IM{t?STH1nC1-9a z8+q>qFM0T=q!f8t73eJZ(J0y`M4xlbTcUVY4@BUQmDEr1h5;#%XzOWNJgWz|(5aqR z3RQVf2af3UnI2kUY<K`oP;tu2nU_E$o;bEotuc<e(CqwU<d_V{*t0Vdm~h{PGo}Q6 zP3bAQ=(N_|8%UrwO|=BN9-FnIVh^<?@MGAFLX7UHhzRf=wl5e`Ati#1cz${t32bIp zlx=fsaOZ9&ym%pCZWlQZxO>evZ%N=;JwVToQ;O?cSqaNHhuWNcSlaNc9so2r@b3z{ zkyJClhMnu7l|Zp98g;0H4#C0*_rMIGj6{VaBcRp@ba48_ZiI2x<WtA<j4*~J6+R&M z;l=@tg6)UtAYbRJLw&8$!pOC`_TgYFBZ_e=4%k-QPYR=yDNEVtfX4{U9yxd#VLZ!( zqoNM=;=l^T`2F(`MLoBWmN1^zLxls9(uNgb0&a(F#JL_UVKhC2`mQKJ%<+jyGsl$- z&N@6(J|)7U3Y%qMogY^LFl*&P`V{(pL<DPo(5-wkM$2{3X|YKc$kB6@mu(MHO1V)U zAj+VDb10f^-XT(V^66=rSL2Bj`gns$b)@{=h%5LkUh9rH8(v2IK+sw;Pca2uElqwd z8@C}LmixX~4cOzU6qZyix{iKlZO*E9R6ccJ1ljK80~hCV1!&c|^Rbw~iGeRlYIbnl zva|R3tVd&d3a&sP3J+H_Y&<T&PkEG4IyjG_(y@c|Cy${JCUD*;DAOuPC@(WF;*DbI zOZX|p<>TByL4)>j!IVgK+_`;kX%^LmJ|$vvNGv*2rIe!+356YH%rRExJF}F`<ohUx z>cB;1-J#48(zATGYQM^aBPlrs87}%P!D8n|Z`;;p#*TQGo0*tz-uDQI;pOwPBCVow z;9VA-cBJ{{-RGNErLL(NM%l8sq9S^8$BqFH438`|Q%5}IQ?6%yM=(>BNljL2-*B@9 z3Mj6rVHXBB)H)xng_xeIUi)!OhzD+jx~5n>hU;1FPtR4aeS(y5ualXVQS<^*&vE-} zrbrvHW{U8td5)XMUPM{;rVLr{N__Sd_1gDSDM~;mIM}G$G4Qe~aT-*Qx0YafihAt} zqM)Y83G|TEKQPRUz45P^B5hikDJsY_l+p-LqPhu0!{b#rdy0DPb6W&t<@%uF@+6Wn zqi0Cz^c3~lcf~D786nub2vQ}6KXsld6fH7o_C#{KSMeFj&T@i!a@gaUw9EO*l*yv5 zP;w@bK`S}x(^I~tCbE{fIhf9gIhj`slRLN9JnQJ>6tI;|Rf8fwtNF<(?=?^9HA)=d z3#XEuPo=_f^DBhXxIdbG>y?ytrm|OE16`;&T+a}i=?Uto9_pbbn1fE70Yy#)RCPxC z(=*g-KOtD`Q1i8hLeoi8-F|b)Vuz31SEr>i55d_}z=1;3fm6i2Fq0*f^KvtF^n#yO z&Ri{)1<~JtuxVVoc>?YCS+g=d>%I25Ph>^q5RIgw=cG^Jh^m>M^<MkLxS1Gk?Na4D z?bQsnH}08J)YCS8PJN}sgIFK~g**(TpHTSIQ`Bo8{uCT16)xBe)!!=uWnSUzDeAQ! z;;pBAG<cS@PUFHjL-mYkLwkj2y4b*QyQ6b*;XbzFragsuUYNZ#`;AJVh!00N<;j?p z8fNGT;helGs+~10JOktbHdN#hu_d1ZCxZYTPzueaWqYrfnE-zXb)P|;kjCRB8W`9# z$-=B?68sCKywG#wWpkWRtHxCq{a8*sjCibWe7Py?cO@GqcRBVT!P4J7I&5!b8X`Tn z+Io4F9VlMQHy0Prw>N*p->O@0?qxLML&8v6$zZEuXn-3EJuob;mcYnn1htyiZObk2 zx#+2x`5JbS)j^o>KY}LIpp{~jbZu}8()eb>*f$%-?ggJo(D|S|4-Y#CXuLTDVjOK$ zG6w}dKM2>i2GNV1X$&0ob0}mAYVG6fF4K7b<#Qo{IjN(bK}n7q$=CvV!|TF|(=s@m zQ;vFJ7?*0YpmW9JEOT1E-n}O>(WaZIG!r$O$+2Qp6rjGi_(^snZ}SXr^i1}G+PlM% zWEgu0YZX*Z2n<yRILzvj3D=NPKfk%!-o2=9uL+$(+NtVY!*8WWtDgI0yQ>Z#?OrpE zw>x4glcNGs52RX{;V`g8!5Z;ns&F5ABb0x6awxK!N=<@LUvGE!8e)^^HDm?UuFyL( z+r7TH;Fb8N+~jsNGW5LK>D1aWDrPvtT#h3W`f4hykbv)MtreUvGhB%>G!)@xZh9ml z>i7OZCo~LqvthXJ{k~ZjJy^CTgVm*5qr^&m*{gE1l8$n>m)v*}A5}AIp<*a-)R4iK z6h8Jh!B~4CMm5m2POzm|9-+Egw;&6<4Faxj+)=o~Va}RcVr;*d&|TOh$ThGRDT{Vc zp1GNVtCPC};2c3tFQnLeNL_60c{RI3df9Bc++ud&W`p#PH_viW)U(ugE=omqQn}S) zovW{aC&XzE>V_~Tp6A}~9*)1h%I@x}-DdNYKb(G#(F!lxYw874E&O_ujTTD}gZ0wG zXq4LLXDT*oC}LKU_5h0+wti1K=hQ_1o$BoV>TdR})VJz&-jeJ=p(*%SKTpJGRO;BU z5iY%Tp-whi*ZgyT{9r>#Ipp8AJ25&EZ81*Ix_SzlaCunkfyY)=xzkFHOF}^nD?#tY zRL|x<)fov#1r3Qi`<<FKIoj}BmEhKC)TNJ04R1*wSIN{EfrQ*Mf}Rut7EUh-99Z8g zBha?e6uZ~Oh29L$j52<4hLwhMq5?(`Qs*zBsF&qlJW?#txu!5P)tIU4$B01!I%!7e zE#xv5rj{pSzKJ9|w7;huNljoYf+Q{@0Z`v5LR&G{_4eZ8=h-LQ!`-u{XzXd(DrnFp zTLb`Yk`Vi_ZxUj3Q9DW<9RxRq<qId3x}di+$ppj~SOs-YsWZaOrW>K!-*3(KilHNL zGOrBDVGctf$vCoUwpZ%Bd8$5}GsdnKs!TMih?Y`v&ki3QitYA`S4h_327f`{X#4SN z{`uMAr~A7n*Ee^s`(J*(J7jgG9(l2Ues`-T!-SsS|M90-M7zWBng4VT#93#UoBK)y zhJjLi<nAXG0kz(ZS=v0cmg5!!Y9&+9Hln~1UW(L6oi;R<v^X@^DArO#YDcMehYV@S zn3D^etvg%0=??JTnKn}j#tEppUxnZW63@7@Y)xR@*Ph=2XI?1O><hdpv`yI>?0Mt3 z)tgTh&SZB?R`{IUBIF8|ILMO<!iY4I(p5?_vDlOltgv1IHFDPm702ZmZDVBpPvpe< zQ`P2Mt$Wx|7m~L_IyD!52sUuaY4K~7d6M66uc&ErNR?2Cnu-BR-)^e|>am6m0cdSr z)>VpI3D>^)?!yn{Et*4V%+n~}T2x&AIi+x|&^8{0BJ%+i;!eb~VtH)NX|M@v2gJKb zJHl&D^~uQcf6nXriK=bX*CG%>Nk0IAnPUq6Mh|DdQc2belQ2i3!?3RO<_^|Mbx>6} zNzf92KwM5qJ%#7r#40cGzyk`okyqu36@<~X6pia+Dp07kjhs`bi?te+iKv2RCy#+r zeH9LNYvI|H$7R+LY(?bY=?e$|<hIc8Tb;LH9B9i%YZ5NZ(CV@Xih{_3n+lv(H~-em zVM@%TMGAC><Vz`GtW=V6mkbTTbyu;^ciUoLR(h)@wh(Kxthwr4T-53i=8B>|n;Xif zXP9dhbwr6ZqYTN#Ap_Qa8|!wW&veVn^6W5olv}5`I<f5WHz(G*OJpp#x*BU%$Z>F2 z=@Zc|XeS!3xyqYaJm>84(t?cb$n^t~@^jnp6kVB2@|&^vQ~7WA%4Sh#X3a(BQ`kH{ z`&4^6FWTk#tWpSMBg7HKn8EkJZA^hSUxE-KSVCm@d&<J0I+3<~>^D~3e{}njD)GC! z!@@IK>LgZCh9jt;GGuCY<N5l>6+Wx5fR{N3wK_0hC6lZjm>PJ`>BEHL8oAoO+{wss zZ#92h_zs-jDM+0ZuHq^R#T$I;YH9om`a;ijPj8pyKGzs}DQLIw{=&OT2CltT7T<%L z(^({Sv$32`YKD4lVlB)pJ+w|t&|`j~{IGvarP_s)#Bo*R75q#Ic}`GEjdzSffGWNf z<$pW314*7Htd1o~;7|FF#Yla)Ee~EObg6XAeh<7<YLCjE_@MJOs-ZKHLW`t@?BP0> z>lpxwl3XNAdV>X<@NhKxS|l*EO=uKobCp(J>4mEXky*iZ@}au%3pnugsy*C$mDFwa zNNYsn6BJI5U-xWh+!`N=mTUX+JvzizdqqK`<9MfNxuE?psqG#4Fh}vnm3FT^v}lnD z;dxXrm34@@iW<4r2P`5!RGkLCw(Pb$x=B`fNp3#;Rg!UQj<udLR)TsXZr58}yy^=6 zQ&K_Tg<9sxNC+X3=2{muf5<%(j*_>Lvu%xe*9&ihp=BL>2gFw$WTqVI18SMdNlMI9 zG6L~h;ShM}4Tta4Npjpr0AIMN^fp}oAh4Xd_D%n8drjZ~5+Om)K9yX^=T&hyS6SC+ zF{r1gC=DbuG3BHmavDM87eyRXB%1VO3E`m-dq-LmwR(fdCzXal-V{KsU~N&H2kJz? zU-RAvX8VZithoGYzb)0aH6b<mveCw!1zqfKwpGdLsy@#(383PH)*tl)l2S0xwgMX8 zzlD8XSt)kZy}$KfR=nG)ll~XatL(NQ1TSNH+?tH1y_Do5a-Ak2l;nksBp;(%EDy&6 zE;()_NDqnVK#B$^UEhm)s^uo*Hgj=twJ$OqK>Eb|X`yP#fYKA*D^rj;6<9+hR4e>G z0ZwpmN^V_%=7kh)ES$;|BEOiNYs@XR%g)_lMB_QQoh%{A4RUgQMSkcVP(~^m2s}6; z$5=Q3+8tnRfPwG$0oPm=R0}Bgibkf)y}mv4P!@OD;meDQukq<iBEr{S@Q2%<zYsQ{ zg^TV)U{^gHT%e}Xurltk^Dijmxky=fcx@cSRCwZLs`M<$AU7KsBqfh~gVcw;9UIi9 zxVF}fwYTt1@Jm53OVMqxN0}dL@$Io(D6vE2NIhkr@E@-Jn2jH+KP)x$K@<zaH7P}; z=TSLn?JjZ1s0q1+l3W!A_>{)G<N;K8P4*GqKG;&S)b)Msd;V5pu~ID~!s{DWc%m|? zSl`Km<?Rp!+(I_&1KO;8bBR+wQQBI82kd*mxAHnA`Ls1&Y=<N$@ao26pv8O1>nKBU z=4I4(J!ncaw<C;^yl_YOLIo6(nBwOZNs@YR_jF|cNPO}2{)_B&dm1h?NC`dQ1qKV5 z;t=FErT2q2sgB~KOnOEKY=fB=pOcS^ERP{KW{yp|rbi}D^G7Jp<lbxFau&O~ROt&0 z5UHsy$9$;%0Y5)kASIq+Hgy6`weTOSZ;bjH-fw!SiPaaiquxe#!j|g+0)H|#Kl@Su zkTZ->5=-HO$^sVVt-e$v+(&2Ytw!i0+gqn3Ti<^z*Uxz4%ub(A#0Lju1s<BKN^Q>G zhn2e;_bLY#z}y(ek$CkMFVWkb$%lPSkOe?;BwdVy&KFpV{hEs%dfKA5@nm{^yDP>b z)Yt5a19*ow0bah4Ky?vnXHaT8gGT+?z$G-nV<}K}*8~SXpT0`W_K)v?3}ryQWJ9@` z@EEO{re-7Br>Qz(^!%OkK1VKTvu^?1k%U~7IIB&pOq*d3tglNSW^6K~NwoySDsfqR zrlw!~$eG$O>h*4XvoA=x9d%lRye<knOTyeb=ZJlF94#>018hl=6LPSEeUEFY2O_t7 zTkxABuK|O}Le1bfXL}({HKn*24C6vRB!rUm@-2#c1{Wk$uz0e96maig5oN1AG}Q9= z&PZ)H(9xZa?(O#YEcSYK;vuPvp`?-B&h1zb3F^@X;L{<nIsT`O<MXUZ1$H=I;HO_3 z4~r-#E=EQ@{+75ba>-;8ifsbem%=tX9;$W5HnVJ*#f|Y6{%W(~8ZauA(ELQx=yOR_ z%={`KXYSeZBOQ5ATCAUqKU^#nz*6f;|5TUH(=IE)x)Y#5{Nzuf!V~@Kl!lQ!{Ll%Z zU!_O}<nj_2ZN7Y4#$q!!GE#d(^sLagWexn0NN9fm<4S|gRBbl4h~O8b;K696RTe?h z;*#ZVo;^dFT1eZH_FGOEPZwq}p=S|0GIYAAk|p3{Bl27+!XqpKL|`?7{Vi#C*HvlB zyk79%-1*j|d8>?ebO>&n{sr=6eX;`NQ<lXpdC5r`O9+ee?rhz-tZrx$6Vt(Mm_efL zk>cL3=p_b9BiBo0w0ZWNJ<z_K4=+ek-|q_X3G4E4hSq)n|55xQ&4YMlcRvAS+p{ZL z{E~&hRf$Iw4Zpg&Brt%61o;dt7^KpatML?HQ1j)7KTyhqmwyL!iaK^QZ17v2(3Iq} z3N(bn|H;(H-khA!4<s(5Ps?{lb9A$M+&;07V7Squ5(@RS!WWlFYWv^_9@+o;6jKxQ zPR>%Z|Ci_rZ63Mj-0~LPTF*M-Ana9%MJIJK_c);Wu&E}*_A()dwJRTLX`We5{pFG= z`Qdx-<f;$$MqA0Zo!scDp5=-4bA4H_w#qMRIpjtOmY5QH0i5Q7{_Q<stk=c9m_{Uz zE{@hije7>uzd^W|`#{QdpxL|jw_Jw~_qWhi@4o5^wjb^3H(3mtsb2Dq--+EX*QAJh zJvF;ruDYoscl&0YA6U@d$(?=viuTCov?^}470~2?7xIYLPXBcIb(hc~a4$D>ohpt( zQ~v-uH7lifG@2zCv-uyXBr&W`ow7T;eb-=ip@Hzz96X8;YONQm;l;L@Pg@a*h5XOE zF=|Q%+^SRik+-F*Y)fu_Xy0p4JPdl3AYo@+CY(zY4qmb0Y;Wtlv_9xotHE1kc~RnG zO6=;M%S~f(O}kXrg07XkP+@)^?2nm4^v{SEeOIhvFNRi_%roHFd89n!Z^bIMRm{8K zW_nnI7)KD)HUSmEQm+I#G;I*e*0;T`*AKw>&}gHX&1f&ncSrNvqk1QVrJ3b-$!w++ zWK>b)A}y-2CV)E9-@j&Yd>0me#kxOm;7^+i%Z==q;!PN~QsRK33dQ)cWchs`zi~+L z&q7EC$NsPHk^;3}TINDsM%k3O7++G}&L;l;KJ(HR?ImizQ5AYY-Ua3MZd_&jG=Ls6 zpxRVQMdsLG%Ef|MewB&SM5>_R-w)gz?Ct0%94p279iXf>{$t(X8;iPiGFmaYqlVcz zf~CeND%*-4H$dOM@XZ@~-+Lbn@S{Ir@5XLj<9V>L-`bRDgyZ4@8D2vBc&-JK`$1ZO zISc%d8nsf->9pTKUkJv#(E9gT$)De;!w|vu(*F)if3stks7xKXaCG4dks*V=nUSF} z24@6c5Z|28L5Madtxu6c;7=ArmjZD}m;%BhpG;kHXH%F^HSaQTdCR?xfGZsSlnP%k z2!o-R8HbIVsH4h-^q?k*3aX-9!!bK}N*n(3(E+Y!A7&?`tcerxnjTyiG1Si?Zo%gC zQ{lDmPreph*huWqL?5c9Z`<##mFl}>r#_&wt_^sTm2e;DP`mIS6L;ayrTjzrKHHh{ zQV_RRR0t&lAHuJJoTF4gB_i!THjp>FG&D!E9TL*<i0?&2VrR#qGA%?+-3nR-*Dm*R zd_((_QxXC%Lja|+>r);HvKCMfJx%zVEg|n@l*eMxTYh;YTphX<yh~Cr1CA-3qVcdv zO^{5$!;@2L0(Wg7RM<9(zprLGu8D6kzoI6eh#IyzjL5zu0QUztJmD}XR#92&S8LAA z+1IvBDt$X?H0J=n@RK*ot-xmhYj;5&X;P(dr}tla?zS>9?B<O|SNLu%dx`kUPSkJK zT=vzIV;fP4$y6399z)8DOYx*Ai>eSm@EU+J=b%gCRRW7r1oI(PfYEaLI(I60Lk+n1 z;#x|Y2zxRUVQ+r2*v_9YYg-k*T<i0u<mpKfx1vlFh$}LH^fKbs%`=me@z!MBwk7n` zHB$bd_JLWa?iRgd;+sX%<N6M{Pv)d*jj!|99N|YIQ=trrb4Xh=3YaAA-XpccHsU+E z_!fonU0C!+OqYnXK|4P1*&-X{;zG~Wl9aFrup=z!5Tr%$^a|(Kz<Ksyr_NZt{6?;5 zGDGZl;#@s<-Rg|mgsuyXc<uU>#<JF})2#1~wmg61{MulgP-Rjjf$G*y6~vSgv}XS8 z=*Z!EcG`F7*m+Zb^8*~s^MiW>m%;;#>s`<_YitJRTZej9o}W>$Jal}&h@o0sYUtZp zPzkm@0UNihb4RfDqdhb}b>?@0vO)MyYd9az+nu~Fb*(Qsx*KgZeZ6YF)!KJ{Lwvtm z72sJX#`h=f-Po<~NPLu{?$ld#Ary_nD3J|2F!3gLgg(p0`_TIL#}+nVq@ur<ev{97 zjzW2N47L?#mG+y6u*KKa-K%|h@HARLLJrE)B;QGd6Bm#o%DXHztui-LI9@{7s57q? z>cUbNCr(EMsUwjbd$87oT0QDH!6rg-19`huZhE&}vTT%oq*ZN*1-&niu@-QPM|Fjd z(9hg5*2Fp!&ZreJRw!Ug*M-ml!d$Ni2_^R;3oJ{cpJj=<2-IlTpCjzwpPpKmKH!wT zOZubZE=e>i;<}6TDmD#@%EQ&~LK9A;1s>$3Hf*11Xc?PEO<_l9CBV|c7#;~}_}tz) zd-Le!KIP!<g4y3Tn+8)0iDv{EJEb3Lq1Bxvf3UC3?}X*IFtlOccp#At{TTLLNL=8^ zgTG~o5hmA??{eUC*8ANY7fVFiI6~hM(ubNL9atnnHgS<w^#Yj28y%AGkVfzCif;uG z5yx%-r8OlP>Jr|bAvSCR5%B<vF@K}~-o<6InP>Ha21I;|I09&$De&t@U>vCNDjWbd z&_VC6Zb8?Dvl>3{M(NoGUGtr6j&F^lF##{>QrOmusSQ-gwy<A%?oK~3?B<OIrn>!7 z$8iMa$?-kt2#x^qbt=TTe&GdPFi|O@p%4ApsS4w>eG~~C`z2L}DMW$?pX;1GKNIuN znNY`JJbn96zzjv`k_uTTe&QsM1vSV1aWI3KwchOaY(3xo&Vd=?B8TED2KoU@9r-hF z6U@-aUo$}yD>jZccDsBSHd(E<+jUy!KK`zq?Xyy~!r6oRv2f_}rd07Ovm5?!7=Wgh zQcvqf^aWu_Xxl5OIOvBIFQyh>E*Q6g$*t$V8P#U<*0ldv7{5E$ocTp>cGnp;{I40z z;1yKu3G31&At-gSaVF4%9esZmR@C?veCk(Vyd1|h%%1b-ZrX~<NNx~NR3_nMt~i?8 zP1`A1y>Wjt_t38m*C2(abEgag=nTU|(uvxcw;ePOr!I%<*|j`8px-P~`XHzD{NTQ~ z9`vPe{vcUnK79MQhNOaFvaHg=^<2M-hbe54RyT?09^qC`o;81Hwh87wrDrn;uz)rA z<YyH4dYdl|esX*O&F_LYz%{&~$WLGQ8hb!%-}w#k{ce2+a1F<H>pOyL@X9m*MHCU1 zC6tqJ;~Z?Z$!np7U(ka5n22Uu#BEOU=XdG%XVsB%7k!oSE*NYp&Z=W5gju_I4GN)5 zlA6lAX#@^}lD1rL#Hn}$g|NK$<tPLSX@?ng`N$9`C?z>8M9{kZSD+B6Oei1(hto4H ze4iAexk%~c&hGZ;k{fFynsYmT+UEU!xBrIicIDY!>BC+HJs`c$rJy??+Nz=+kM?hO zD4tm}v+r7720e)2rgw^%r1CrlYzty&ZbO~DWAxeCxCrLl(VgG?TZbMLZtBDd2!zBZ zO+r#BO_h&#ppeHA<E$TKos||Fdf?^6AIdxk3qSIM;yC`ZcXRj-Ll5Sss8Q@oMEc!= z9s~)@x|v6Cg(|O=RFUs(=TWq~x0d=mTQVul1nMpRP8e<dUD4VgE7Ee?pPV9Na7fd4 z2(P9EW$^GCd@GAFf9d|-3w7EH)k;ZxzuQXrbk{R~xGb|fuxf`dw>OuED!VOS;mmQO zJf}vdUw~kXs73zdk@fwDq5s48+#m|OBQ88#ZHvm&Fvb?s{QiBIzyE^&!t^50<|yCp zGO7{kZZ7lJ5+$zS^q^iLoP&Xzy2#S-p%3qUui2NXn}#{wArL%#`0~r@^*9GcwO}=4 zUVXE%=U}t3-f`SU`_dM%#iG{+137qY8Kij3Ky$lw4Q+s=z$Z-d)Pwr<A8hcZ9yf-8 z3T=csY(?{9oPxTi<y$JYJ%4p2q+DB`VjboG{^8XXuMh@ll(>mg7KIZem4J|xEc&jF zoP_#@CgsG}c9HqO2dRNWd0M|J<>qHC(>Y>&l5LBUtx1>za*Hb>`UOrE`;2MVzwPr4 zR{!K!Vu+;44<pkx7O(06m9C`W;Y6ZgtC-OZc!ot|TwYbXmv^EaD6tIRU>H*T)y?yW zJ==RiCMeeF3HOKXFRQU+sclRgdskN9AYGz6p2?pT^IKnOC}De9Nr5^lO(k_4Qua22 zo+xC$@b9uc&eTJ`X^voNUF2C-QzC^V@V2=hzNd!WwHj&IjT;VNH|m~Geug*$sxk@5 z3G}$UKY4`v`a{(QO?AraY^~$|s#CSyXl7O^HfwNmTh-fdE)VzDOqpLN@W=oXEVJ4p zyx6W(_f#v+Gws?Z!%4AC{4yme+s8(u{<=qh?H00M=23Qa^D4`$yKQk!_q<T%yCoHz zYrm>X`XI_+X@d{_@Q3du@q?U8vCDZD`{azJ@+zpEp>qC?oJ-9+KiIJZY%6uhK7x-Y z&w-JQ-(1eG2RWA7v7aLaCxx)YRaiKli%*S8gF`*u^x1a#Hr04Zq3(?NECZ3Hl#qVA zADmykr71k2t&$)sf{MzN6hlwE64r}{(^k#go>W$6DU~!tt;8N1JBhi)+mnb=Y5K&; zai}i0FL(RfEWfJS<z1lG<VYhq!GpRwq-bZz;oH|M9tNoIK8RlN(z5g**LG9CDD$b^ z^&QbG%{xDsUWsv?lR)T%NmZwQ3c2`Dqdu5kX~%w!6r9v6Fjf%&pqy*zK=UQgS$i`# zeYRb`O}&!Ky*tRFf<qSY3a67jl!q`6o7d^K@(I0CXClvKnEGCoCmuWK;q=OQFbj6| z$@L_WC5v+>@iJV*wFFVyNkp$SeYWelpi2~q?CFFW;j!c9A;m%Zip2fldk>;Tijtc4 zb(Z^CmN=Chal^gz9nm7{g&$0X<aLUP4L_ojXRaqWt>J4wm<rJYKXdUNHz`sMd{Gom zQlsK})+uh2*o(UzwMauudQCznPkan|?m?OFi=923i0{by`{tb=OawTb6DQ9zxfT=P zK?x7v{J}(^9s4;_a8m0y_%dRrNGY)qrM^QDtkpW0giW7qmy2X%+QoEoC?tSXVMrbs z%mRMm4^qe;;uL9Kr<3^;rwB6b<x%4MbrBVwk89!KPLc6o7O3=-lUTTL$OUi{6gBC1 z9&UtoJ;ge0_WaA+?B-Q<O>N|F0R5Nk`pyi&$M1Hi?mCYwjtVcxD?AqPK-4*6(|h7W z*Au5~^uzZ&hckwIu;+G@KGTV9g^RNwC^@xUypbs$C#n9@(_SfUKFr<P=Vo0*sV6qD zo6EsF+{51$?PcEi!L(NrCXrL%#Y`O%;w36QeDjCXUd`A~iJC11C#4-|r&rZZm0;*q zeu0d%(k|L-m5i*_UIZr~-K{weu!bbV-X6+>Xs^)}p3q)ICMj|pVFIRU5(f{fy+(ss zu&Yn5CoWvCcAzK-VV3cnfek!b&zUYq+A77p;0A6|xkVBLkuuaQeTKF|Ly5L>;~%~k zpt(HDEDi+Xbc!b@*&Z&lL$TeWxLn^&)2hJX!)b;EM*f}ovX%Ws$LOS~mE=KE;tQ;@ zBynpYrXFtD4}Ty7{^5InA|L<ad;XuoT%beFGalb!zx#?@u<d?#AcAG0Vak1RC$5W8 z?CB35S-)ssX=W{4>sdD$x6XXQBSat_E+4<nW3t3}rO_bTZv30O+mtpBcbELh_f=|J z7vlRdbz0<0<>Y@M-uh@?*Bo7HU8qTf$HpmYilm5rp}!hWSa(#N-JPGwUFcOUkxC~j zQVB&B@=pBwOh*qIoNy(aaCyHgURA}Hl?(*}b4b8B+;Bir5E?Dedtzo#3J0}JOvgQD z5<HFT5TCkR)lBq>9!DV#zqq~$WmONsAc!lHd~w0o7Z*RfE!8sD`&;!X@~+}De9L>& zwI6aYxG}72zKdyoBCvEyR8MNJ)D8UD4VmY}^^+JiQ{Ug+-*(PFADmkHbbouD-I223 z0o}~+UtZqb-&|Ff^|rby4}9#l2Z?GCUF7l}r?nLE&O;odvrn5Sr|X2jYW^7d-5=BT zk8#}oG3g#ix(Cv>1<xTOtD~o$)BX$_sr^@QKg|Pv_dw9L>jmAjVb^Zd{VeVtNV*5o z?tzqci<|pxXP@@KYthr)&vpff55be|`4iKYQT)8b`QsD`uMjpwH}b7X{7@+YpFe;0 zSD#$|<fG62_{nD@1xHHZ2PR%-;jYy0+Qs|bzK(Dmue{ygTyA%lH&<Cvsn8)|W-YFQ z-?5W!i~Y^EDq$&8pYp7Jt_eh{$Di?E`RYCqp>F=qE7mZCr7;I(=t(|1x~13khaYHd zuR%i{PDOXR+2~H2EEoxPZZ`T^>G8w+ghKc2R`F}!^K>z-R>|^DGMaeD-Qn_Hwi+tN zEz6p!P+8;_QYgTDx1^m^JzMU--qDhi7Z9J-W#)N-Ux_W=e!HZt_-=nG7ZE56?k*YU zC4a~Cl1a<+xGWuV6sn*Me6~~Xi6xDv_3i$;Yo2zcd3vGwqOJ-KF$Z#~#B~MPNAuki zR`XFXn$IX0%x4wj(}h%;`t5MQNo$Sj^6S~(_vVo}PaLCvv&eBmcI~1T`m+}WYWAXl z*K_ep!kG|<ykm)C*R$6?v1oXM+0#Gfb!eVsEnq!ii0iQ8wuiG;X0LssYkqfsErDgP zzPgKw{q^;Jm;883prw3zlm4>0-Cy49zn10jC|9AX-gDyRKu@1MYQLRqOd8!@XIJsZ z`ZK)U-|yt`gon?;fy{9pLNg@lq+JPXEW@9>&Q(=&TYj~z6;c33_b{WS%uOq@p%*sd z-fmyM>RO4pZM#w7X1*84fwW?Me{@)`e?wwT1&5=0NnQ(d6V7J*Juqi`ex*x<g!-tJ z?S1b#?`H>ns;UE*m%X?!GcTk8`wSe;XW7?J<xe8LiCSLPjMicEsDzfutIEJ}JeXdX zv^Q$q^_%AP{sZbmp^l`GT|%vMC6T=+-n_>UQF5KjIulDXQ$P~{<CzaWqpmy&yRZue z&)B`Pso!iCsp1U~E_cx<_;XyH-qFnBs@BJ|n0lU*#pswgsFFHh<5?@Uu8)a%i;_65 zg2JI<mXjp8?nN1xzO{*>tLl1tTgmUMTO~#0pacb>Nr*OmGq$;3!IinczPZ1vE^lu4 z<vr>nyWvmY&<+_g0R5q$2qQd<8Ar<Wqw?yb=0mk}Tu*NxMw_d#L5!1@g!H{4DHB|6 zNP^m7`hg=Yd9Hqt|K4r0E9`~(a+mGgK>xG+6=1L^jWCm%$EXZM&T~sNc>fXUB(_-| z`djo<8IRhXiq&~6i&H5RbnBOr(-g#{L?p1BT1iFrTBSENuEXn_I{^-2W>=-3fjaWI z`PNKu`|adRxUPJ^-F=l^ZAHgMoX5hA<b<qI5~GZ)@1=z(R=2!)#l&&op`4V40vd*` zg&yC-6MLnnKopdlT#IqGKU@-$zrLjNd$AXNhr-ZqiEALNaf6{%$B)@#nB5d_FowwS zaBv0yzy$MG49^GCazcJoc2~W89hJA)%l$6BzQ2<5PEsykkzSHf?$h-M=*RH$@*2&z z{WX|rjJH?U63(ps?VXlDcz%<Ja{?j=EKQr5Q;EV{OP*<|`X(zxkgJSBr1-{iprsH= z*`|o>{$VrW%iHbY9y#id=MvBxjRg*IHcF+1bsqSR$VzY5&NLR;Luy;fsp}PG2rbY- zDYvq&r2vsSZ1bzvmyOL(dqJEAg`Weg2)!7aq5sHaM{ZnhUt+n6&4nmmve>+?<2w+h z6-nV&Dc&SboY7M!TdTeSNv&FgizNUf4=q$u=Y>>q>sm8U^;(nbYJeiS3%|bQhQN4; zfl#R~4039tammM*U{6}_dRw+X@=J%PgyWPkP!kHt^?wvrx3~LSH+*sX`YHDHv)!Fi zSgwD`JRFMKt>P9_OP_~fln1e}c5?WuW@5X_wbFp9xr>WIbBpy~jO#Y%@`xcHqmKq> zl^LwBv}-fe;7gFB3^0OF6i{dofzK-d9_RtuRUzyF_L^8cyc|SlUBp=(0oJZk1cC*K zSN371O3k-Yk#2v+Q{1r$F_9#L1f~j5?9$ol89&us<%2KIu#v;i&9ZVJCy74m+FPi; zG56XOdyAc}CR2ZX{7jTnVeraM?BcU39lweQhz9n}i?%St<O;}cy1dQGtymWl`6m8P z>=dcYg$=#`h}@@pn`EL5w;=8W#2Yx7!x==UgEqEqbg~f;$SJ2NFq}Fr6Di~|Y(&7% zC!2w=khmW1lf1xFDkU$6&Da2EIS3|R2!8eo2Wv%^TSOUn6wR=a)02{CWm?3ZhkGZ7 zvzgsAXk&nio*7CFM=V9P@(@TJ8VHRwXlCnr_F%57Yd7Se-5sv)aer^Gws)_ij}G9M z5l^+v!Tfr7;PWU?LvbjpU7-!fBR`Jw`#UTTIl}-+QD7LGBaDfh3JThM*U3ri{tPvD z+d%4-`%@G%CghV}D0y$>p1-)tS>#o}psyq=Y7$z~DvJq7`1&fQ2ix_b)yGsHLl<k? zx;SWQ-b1Iy1P)=r4~x>*DYV?%JC~Mr|8rS<wySZ|aZpYG@aO3v!LZ}4&*d)9T}5l- z^V{!fiHThwXAZV@oug0z^}9x^+UfkJh3EVGTbz5Ni=Ft-PStt~#FNFG6-8P|78BS# zm%L+b?S*#z1ZA2(kz;Y()2Ua%^e8xQaY16f7sl%y**d$ZuC6XFe!QpsuUB@0iRlCZ zxy(ou2fA5y`xWd?U^H0S50@<V2q9i>fduKfX2}6$(;14-pKySRU?F6W`KvkkS9Xcd zxFUp0N=YP?>3YNT?pcE_)j2NxuI#WZxo_bg5~4gdl6gm4_Ud}eE6S;Jaq*P%=f|%x z(7)K;z540>)yhse*~5Y~3^$A^?pkVFs<*FHwiRmdCDE48<m2i6l`aj^^9$))q=YfV zfDi)^39kb=3`^h{5`U?TA*8*?`dl8hE(+sW`HeI(mifs}l9)WNIuhoYu)w-hvf*pl zz-c~oU}d}47Z)GxUP}-0-Rm1Jp!)9VQHe*cC2Yq!(U%hfDN2KtuXm~;J?6HBdylg5 z$}4uA-F_(>|2YsEo*e!2>s>J($>iHef>%*-XUOolgZZ`&75a@nuC6(J{9W}m)0?Jo zMb$g<v0`rMQpSK?VKV2eq3Yi(>|gwWVHpWG0XIF#FQLsI8AEn^n=yrEcc~<)mBQzR zm6N0%7ca8gi1VwyTt|m;%?m8<tlj#uGmalSB3t}l*>Fr_l;Y~(`Ui~*XIP}o&BRt> zDxiOH@c{KAQ?b1+Uu}14d-!ol1{BD$JY%Qm1K=%n99-eQl$Xs2N>K756Dn3>(|Uc+ ze_1WO+XF!^wUx|{Pr;cuZtW%HouR}`^Su=naKy>EoZK5F1uHzT`e}_DFw2Y)VBdM{ z(`H5}CtDVNn;L5Cni6_MiOsOjJS=CXgkmEu0o=5r;W`%^Say^>CHAQ2&&bJvN9072 z@{UC(3_wP9BYQc|X?(Ptq_d?pK4+llPN=Gd$hq4y>-y*JsY7sPj&iW+xHrKlV|EcX zS9A1c=le`gWbLMyz?l=1vgt{l3vZ<CU<L2tzM`_wQMB^;`5loKB}i^^zq`qBOP8cD zVllnM1IKpq$>plBeWQrQb%mjD{FwA$pdDJNX~RMHWIU8sPjiZTv^Z&9l{nI?IOj@^ z1*RvhxAtmrmUmQ%smb0{7AG2VcqvXYb~k<(@{v3T2ap!!u{dZ&`MJ*MU;I9GNo0$| zCkZ3Bip<iO+rB+<51@wqor>ecewI{WnfvHNC$G5^^6#=-Z>QHr2YcWYag;k*0cjXC zFvq9yV_k4<@ic-w3|&enm1&L_q0shF-|$yr(M+S5Y$GdaX7^N1Ac`OabP!O+LGPZV zrzch0FZQ2E@J6s><F?PaBY9+1a7`jFFe79WnIrNobl5wX5%My|i38`Z5EbbKN_FtT zmc%n&v)tcv<GsW_6uigB>TgfvFM_oY@=~!#bmTtIiZA7)CLAIehMp8GsD$gHr>WfV zF|+#<qFdYDOKHRyg=Br_l#WXzC!JhM?U|ie{-a}`S$@EVK@E}-<1|m|LJ!FVWqR|X zUARXsLo*%35l4U&1`%ir7E1TdK9`?R-F-ZF^6uk$7**Bnc7J=hyB7`!)T5gf0&5O~ zG8ffsKhRF*>4p=$HPYrK%@Y$s@ymsQYZHX#QB5kX8xhw)cZ?oWn%}OWHhF{le0R6K zn!m!$Ocm8Ds<_5P$4iM{OmA}&71nEEclP-C-GmQ8H$Awt#dV5e0tN2mp!WnLi`<zT zfDmRZZQK-!lmku|UPQpbN2otDe}JP)cm=uYkd==aqq>RT@VYxQSMW1&MU1I1QhUUo z>`PTER)I{B1}_M*luI_e5|=7)RpNZY4hqR`%EC0l7219~Ax6^;-HP$;`DISrB7-TS zg#Vyx==N@|Ap(NpY0l-U51JE6G2+cY2rjrljnV{)6P9V}!MSD$t98wOjSIoFN^mBv z!T4k$=Wr@jCnuhpYZM3TxKRs&>L^6+rT7<_3?I)Cmpu-Ac;ySBnd!cs>med2#@zGk zIt0e*;yukg^rdIioNZN~7XN|w6#3M?(hTzkcWIuuDaqHFcI<|>`d`?#cui^5_(<hI z$%>R{KIu3l;46s-*<d+IPq(WaCWfG-<tEWva^y>SYHq^HK`sMn{vWCaL?F|MsCSfj zgsi9?uFvzH2f>W!tNm7EY)?CV#1!>;!z#@J@^0r==I7Zb+r!<nrp|1yUG*k{Wkh-K zUm12Fe`Um}#OH<Hi;Y}4xei4owkJ@V7Y*DIjMDZB#f`^IeJcOb`;XuMRL#YV-80aL zK2cZHeaV>z^^N#h&@)rG$>%pj2?+EwID15Ovw3#-NUpqJykcO78~m{?m$Uj>Iq{wy ze!9PVA}|USmr3-U_We&jegFN>`2T2_`W-b7oOnI2uBrmB=M$B~C9l~2)T}zpXzDxA zv2twzOC(-&m{3aMY(C1j`?}qGO;U+ZNSNk9Ky9zo(dU7jm;5Nsp8{5PZfm_K+6KVP za0N)N_C<C_QbF>G`Ge=ElXwU0MQ!<8U^+y8F?mWR8ed_QI;ocw+MTQ}XSylZQ7sBs zW}kj4jT21R$2Zw)&}VWe11iFS<wCSU{s8P%o&9jMf$QpU$X=?rHgFdJN)DCD;L?=> zHI31Atbz6w8A9dzWfJ(1!Ele^56fDBV>jEOD!<kdWbmoL<p}qa0~3R(MK`uz%ZOrI z(WyDPxag+l;-a0KvFOYkk?^15d5(!3Vl(BEaMQeasv0J={Zjwwk`{PR3?EYcWucsy zu%{LM>VDuRdQb>DA+PrBlBkYBEaT|JFe3^AE<)B)g;SfyCb~B(z{vqgYryixq^TxA zqK=GJ9~PAdq6QdkSaQV#Icaq`(T|`cWjLk2ar3U^4G_>TBY?={Gm5R%d*Z_n=%x#( zj^95Q5b5DkrDD*WAEkMc0_(yvE_l$UIs37xap?(QCObjNiBsb`foeS>U?JzV9$EX$ zWIOtx)lcfxgm;bWq9n1iu~jYa!823s_}Sr5-CBwvBOX*mSrp=sCLYMb_MT|Dr}_bC zYraM;N`dVd<WVZ2(xB4&v3EOHZz0kNu3is^qzY!53<{;MWHU&Th4$e0jv2ib2FgBg z0)h!tDvC=tN&IQKPJ8c#KH4cXAkdsNfc~j2aZuvZ9=yMPuARw9Gk>~18-py|PQL~v zDX$5PGM*14SAbHzC!~SirRzX=fw#ZgUvK&RNPYfzzh4@qA+$!a1O%oD1R07ULptbL z;@2E5`Th0^NFAlZKF!LHbltES_40+Fgyeut6<)}gY?6iH1qJc<oN%#h`$olx^EheR zcioR=NuJ-yu@I_k7}+!Ut*ab72FF8^3(3j!j~(^n7m`WS{?_I27GPlpSf~mj%jehc zSpW8!EM{2k?rsIsNJd%-;5#E$LH13hJ(D_aZVx)qW3KMn9|j<4vjAi@X8|!b>m2BH z+Ws(V6Mg~@$VG~K9xJLM3N-Vo`j<EW+Ae)BPc!tmOO9h1WR_l>=#n4$n(q-zPaeh4 z;AAC7j_8odsqOk}Ad^7G(cT_OPHyD&N_J28*S#XPb&!QH8WuqW%gNvsLj^16HX)dD zgM$-LKGuRD{Yh2VfI=d|DM_u+nQ(n59oFXPFFph}+G%MS;?j=5fnoAs*TTyeQH<$i zM^P}<kx#n9^cz`VOMzd<lzYmE>p>_X7@!kB`Vf55>h9_a{;xEFxB}vi#1-52WOvik z2sc9WOUyy+OfIYAHOtZBF=%}_z~kD>I7(0cYWDpWbqM1c#m>3c;-~kBzbxu-<_)7` zW3|>0C5ID>SO$az5>Y<hXY<3^_gvg<1-nZblq6lm5R9{{mW+42Ei{7aMgiF+`37r! zk1E8_;}E6?sdiBa<got;Y4&|Fly*XGsSYqj`s6hc4Y}PksHJ;ASaNX4?xagVdDP5B z#Sj_rpeO08rWNfA$jfe@BO%X)I3TDUKoH~h69#fAqhd6WYk|#6NJJpDtrY#*d?^|; zG?zA9WFW@W$@s-t=OetOcq=i#{9JhX@H)4rr=79boRgbPcMhw0Uo!yL(S1lriZ{$8 z`wF+5iyh-di9SKrv}+E2vx)!_Ll06Mfaw{BcYl^$=cC(~pz3yaKd01)@*pXPg)Bdn zYsnUg63}Zvq;$ZyJ$zeSaRKC!;2TMI!oU;^&i5|QR<burk>(246LCS|Kp^!tA~m?i zi7UB)_Q^N<Lr>4yjbb#V8E9cRte}X&8i#!xPqY2NOq*OX<i=V?@TL$d2NhpNUNAod ztmN`i!`E>@lZkXob|WCNv~r4qYN{9uWMANInRsqy2%f9QIc_zC#wsTx2)2l@4(3P2 z0h+y3!*EEN04kLPMd^`bGdGg~-WZvA3>6HqDD(-%VtmXlSx9QgOUVcI1JD_@pFrk@ zO7#X7L$_4n*V|H)0q5{o=VZx6l@sPYAPrL4{UBu-i>;6z$ZRH#=i_q4jSvIAk(+7r z?aUmy&Vd155*N6ac>oVbFrGp@DXKUXNK5ziObgtE#oiSoS<;o1!RvSF-&vh=U9P#` zNj9@2!p=W_Mh`*P1C>uOa6y~}4p&?uZ5#K{Jbp$GVb?<dMRtTU5cviaFA%M956$Ce z^k5~)XGoGqwd>3YggOdMG47#xe6ELa7QWZL0{BLzC!h==>p|jQ)4^Srv)??uynSn# z2`>b2C#rN7vO1^QZ=PP>ezR%_rep*;PzGaIVz3tork)^c{LRzL+i%v4_JJ;P<;d`k zL?zZFI&jo}^Yl#nsaY{a(E-o^z;=+~VdMyqvcc`Q$A1nj7o));<yRo$KoNLYn_Ox1 z&-qq<z8GYSroaU~LS9r3SqT(obxFT);?g+FbX1xnAKdlGW2;*l_!>~zoVO725a0!M zXq1|^BTxqmTL}u6{MQ1$w2Ht|qv;IFl5>4wGZ_+Ca5FE6E0$SdY$4-lJkrc)c3_gN ziInAe9k|@>^jo=}j-Ob_JOw}gtg0XL2l;2k(sF9B`155=G-|mjKNXIJS9@_xocd*B zQi5gTSWBr;2yVwD=V%|ZVqJ*9?ia6a-9Ud{ssl*5z1^ZDp$9pSu|+|Nl3J%8Z60X_ zQ?sR*h9C^Org()|SDcXnByun{L^xV~>!PiH5h|Rauh+k|m{qk3xF6bb70%u5_PQk* z;wlwEYmy2MG{p{*l8epPGNJ~<s$)ckSfU4LRN;y7?Db;|=i?V@K?=ci?cv3uww89? z^)i&s7|hH@q+Prg1r9<F`i}<9XuGb??qje;af$`-9rzGzq(u7lTUg?vLup>5`r!=6 zEW^U2W`L9>P%b@L_%a|)i{VnhIT7Wo(fs2BDKhP+^FO#$q2-kNxLl}fkp5L!*GIeH z7t_52x)(qy<98q^68e?nsw8`k*ybI^4^Oup&$X?`U*UlYq5Fz(XA@Ooa~*kpx(84H zLeKvG7M0M<KOBWANuF+o12Ip##)pqix2rd&nUSttJ?>g4tN0(5lf&Hx`IsKX+?@Na ze%_XxJuF<@+`n#y59kV{7|^&VaVVX}*?QtP)9+zqs9Ug6Kb*Fa>yzRK%f2T*R^89c zFQ$8u*xsJ3I5GvS&_6L0Ndd#DO$3G@lkmGwJviB>YqiO4f?_5}axw%NV&Mz>Lf6vt z?<4hqei=0~S|J1ltb<Go67KM_>M(T=+Nz$X8i<M>tI)1KrOpc;$8}k|(9pyH>wR+D zmDAvKjCk-Or%D)wkovs7RF`KpY&RD5bG<#NU`QiKK}w(>6AkBuPX!m&VDwbmua5ze z5ClRN?+zN+aeqhI4zyW@->!}!`hlz^%WOZs{hNklf*)Pt5aEZ^`Vb8mLR=RBtYEL` z+rD|C*EKH$+66!M9<MKdB6x;Bibmk>;T>RtfE^a}6?&-uh_n*fcmT$9abb|H;CT~` zZk;jEM#c=-?Xn^o8^rLq#g2ACtZDxgwl<`26&P`x2omlxsZ_C@D`UTi!dXj<=e)Ne zdABG^G68)~Gt6{#O<&!~saGP`JH|ADXR#!`(a?SLAZqHB^ac~KpeC9*9i#KXFW@GJ z6C)z3TWD`X4=!#stak1*!3F|2kR5yu^ux_P%KB2+2l6%2J<&B-A`SFIqdP2MhsfSr z83yU4l*I^fhmzC>pQKv19?ai*;U~Kmx<0n*Chs9374vvMppvANqgyTS4egqWmY!&Y z<`f*9P-1*?wt7T!#CIqs$Mmx@Ly3)~QsahJN0vvY?R^TyehXrxdakOzY3{S9XTWvv zz)-m@$XGXOT9mdgirzqrsLovX`Q2^PMT4D9NHVRe45lb9`aQ1{zYMP+czB(P4tf0Q ze)nbA@RkT19u#8@O_@ue$o5T5{4DMWPZBURK6gMetqF;wM!9JF-`MM-yi~t}qdWrD z9-6JBQ$#L08tk+WF-?C(^_#d(`zi-B0W}~1ym%DZ^9mQMSN&|fUS>eu&&P7szdgv` z1msNiulbX#XOjpUa6;mWMR0JO0Y03O?ghP0N;lcBxLC>P1&x!061_tRwHKM?agFJ& zlv#67awRXw>2~wf!3`>z*}b1MmXzd4sGn$@C>$a#aJmXeRe~$JvtjM$PPL@0d11)_ zz+Dj!D3VAHYGa9YEm=0aY|J5-9RDO!4E2`M2AB7e$s%SC1R^!WBxMZrD-m<VexNtF z`6drVM&6`ysn8_R%DBcm@8mwfJYkNvCu^>iplVua5Wz`>;}wo|2+1PoLF{19kr!;* zF`TyYia_>b754K3xM8#-qlag>+g_8+`tdz7iQjiDyb6Dq0b+P{aq&@Eegv<}%bl7| z96u#jZ}~etxq;*@0YM50FcP%af@@zt&*|y;eQx)3xX-(u9GCRO0>l$EU<r_zZjJ-# zBAJY`*{|`Fdv*3{tuh!Da-!y-4Z>+&M<3=OUNVPR4XPL1dr6kMCM_qnQSF1~MyAzZ z9OflCiQz?5dR+w75uT!UW>ZjFr2CPKCm1-1%yeIic&+aL<Ly^7{g>OXy8gk6ixq|w zUqVE}2GxBn{rAwor`~^3E0IQ1L02AwO>?k|^@_e}vo2j(?0!&~U~iKSLRb&$;o<u@ z$%IQJr65{^0T|{)GV};~%rScMOg8aTK@dEzio<zkEr)K-VINWH0JM!wa@mkk6XoF! zC_G?cgTliKmfFqi+k$eZ!Zq2bt?`dYE;&FbXPRJBpz%C1xa5?C97|%g_5*E8!CiLv zGWa_CvT_4R62IUNw?BU&!!QRffwmA5Z(t=Z2Zq#-W)Qt>9ckg>LYlxl+GECkqhrgb zt>g%6EW_MS1&|#X?{Z{Y7k1lfY-3e8DZ7%QhhZ#u7=Q+n5FuOAzN^6Su?LGra`65h zckL(Y^Snic?i2`Z!Sy+Ug-0R^!>KWyd?bCH*>;+9i6me|v`=8D-P%Jbep_8ixnchs zNY4(33ewceYq);kEV(=gen2HK1lOz!f&jU+)XBw{?1MbEdC2Blx}9t(Vu>K#ae;4f z545A?{g%Q5gQDu23`#ktZ!fExZPE<LsktHJvJ5dO1Gh$VHe%gxCdj_}M!y=w2bZ~e zJ=)>@nwCl+&;Vvr!I*NmTkh(9O9?H7#EZXH6UCn<Tcey6l=Y;^hAw`rN{`Dx3+~-$ zEP0BuDd(US#!(@i_}R@tn>00l!KJ`)p(xgID*y(DrN|Gd7h_l^-k@dC^tZ78h^GV3 z8`QZV!E3+;wi(E%C>t$<gLw9(?|nlaj@Sk`Ty%gNydp>n?!KgcLuaLU-}Sfcf(U+P z*hnJp1(_cqS%Tya?5S+98g7nCLKV%Ii<&^;b9mP<{?u5rTx&e3{A8L4k2axCV@(Q2 zD*|T?(RU>w5ZvLmg*WjE5ZE;nm?jR_8Uk@d1R*Tbi{3NE_&v~4v&zj(j)h?^RR>EJ z@CF3)0+!_VqLqZ5QnRpwNj(P*Bey^@1Yy@8%iglOtfdP{>$p2aj6M0rHvpDK3Q`;t z5<N)K4KN~1Ph777n?5(pVe2Q=7DNKJNMc`Hx@qtI+7ul?<8#)+NQOyGkzL!8p7~)< zcHw``$vh2+R1v>3>Rn%$W`1r<ZHUH(2P&u`$c4b$(yeoo*8Exo7ArI1`bqL9*jaRI zr@rQXJ(N{^l2{uq*bl4@6LvZ}c(TZ}z_y!Le2ci+iO9o22h-%~L0B>mGa+boGH<yJ z=8=@hmc!9b*yxF*k{$w@N_>_JKCu!u7XJFmFDVqQov^(l_^e*8z-wY($cO0IP!Vyl z98j3M=s*y104o6M=>26I|L1fwxygvFR-B@AL}##A%*+=o2Ez6&*-ioi=3*vURnHek z$#G5vNd!|b2_V=m`c^nzmQgnit@wCpCf|nBq9jukjZv3e+9o`#YQoxX_!~^Z7Z*QO zp9?z?$QZU4I}|K!-Go-{toVK>%3G{#>!W7Uz=s4f8y*I5bpWD>v}i$&Y%5RqvL)~! zb~~r^&B7Omh=&#dge8Ol*dki9#kOBiHEmd2EjnMZ13p&N9Oc5UD9p_T3;aIY5!*<M z*Z3{kuAXxiEo~YdfqOW?Lk!)n$(ib1;q+SwV1XrAYPS=__Xv=LUJki*WiBSYz`1I+ z5?@fu!-RwToV5kLT1!~NrF10$(Fq@k-G`E&Gkbva%PE00qC$a{73O3fX^!1~Cye}T zfc@^T@`ukQH)!Gf3$1P)k+lT+3q*&V6T;|Y({yTDeujq|-mEStNpy>hOS~uOIp{Lr zu`BUD6$0#GKAJCkc2d)(>okqxRGV)V+5wV%36^>AN(+<BiN+xEnQshoDsYV89ayr2 zKb&d|2LAcRfQ(2Ea!55$>Pkyxp5~Sy$87tWZu^>2$!2!;fcC;c1}Q$M7+_pxJKI4x zB~4~Qy0r$>GNfn2)7SAQN&>TJcupj37x68N1<ZvrDUzH8e0>s1mJ@cQJx1M4-7=Q+ zNAM>~$^ES|Y&fn%OZ%IupRlCAz{haF>hk~`6{-O6viF;!Bwx~>kC|J=fcmA{CjM*v zezqHPdiexPziI(pAUlX2UT6qOsfwjLJSi{FR(4kw;IlDhIWv<SAJM|~d$v|yNc{)` zs;QO~ek<VNUE1Gjc`3jK<3Zx8?&2HPw~W*K;n`|=$$`0792?}Bkm_&t-${9Swpv~w zrxYq1c)O_G143I(Xlv7Z1Hjx?Wq3@m5xWF(sn>z!M5rC|M1wzIi)a?-o(>$wEudaj z-iI;svkxQ(i@yL1K@_mZF2cSUwWEFB6T>5RLahZChJg$QT_LQob@HekR!{uq<M9wL zg25$EC~ySa(9S>?-R@~Kv4s~l88H(Lxdka``2ACdat>5s91LhM?YcbGL^A{~Jd%d+ zAUJ>#hg|W)_Yz;w^m~E87Q7$%xdf`AgB}b=8>a1hnb^X_c%WT|+tP)Jg*5}ma-yBt zc}_{UfPN(QxwWK};u*9vm}ki$nt8F5y4-Lj<~h-7+;&>L!_j_vdh?j5_{;t6>#^3I zyo-R=p@IhvcuK9LvC%{AwlP4AcEYTHb3-iAoWG*vo8XY%UG{Mdb7v$m5)v*_6zuS} zJP?zm-Doke`>82u0kve#R3$~+i_Rn0#<6|&>*(!h_mfgkliVCgB#@3W*XpgEwzd6e zF|zx?Iz}DQ6O{4fH4nCzxuTr?K1R&!j^Hj5&Y6lVD)GJ!I$9|Qdb``*0Bl985&)+j z2Sw%w`(fq08FgUy6Z)YK>RU+MDXuZ{%B_<(qb_>=z&6kI#iQy@D5SXk{k`^m#&VFS zD!>Z(9wP<E!JwakUR$_-8g*m85OD!CumYf$A*{1qM}aWXdhY%17W$7@5}%sBCgDf+ zC~=R$2)i8BTDuk$Mw0;9VOt!0$~Q%yRaCr`Ai3m^IYf*CKqWqV>&YYiReQP(e;WLi zy~;Nw+g@-RK}AX;<u1Um$QR1ix1A8+>(!0HCh8aOkTCTxRFt^4q`nrEYBi<G3^~4G z+}HE1{Lj!iK`^(QrAr+6Pe^)#R2YgYlEDZQ>UHfAH<&9tfyJ-T>_UxiP--KqdQ!hb zrUp+9^{$~OC&+5f4cm-19n7)SPq$i=a|3HPS41JK)t9**C3wSj{pqU=tnc-wLVvN; z9aEC+2E{93CG;LK6D2`CzokM8Xk@mb9e*Zxdc{4ya6O$6(<LIMGvhiBu|+4QQa03e zt=3(qYyHR#m#PCqKB$#L4MjZq`i$!lWhqwh7x0NcTRIgE)irYD4c?VJtW6NICm+kH zwkKB-=Saql4xS!B6fi*PxwhSe0;;uG^Oc`RfSBjFlJJ~_-2d6$KqVZ*%G?7|4|<Uf zj&t)*z6}=}aP}3Ti2?zYP?p?^ZNIwi2iGdhy#kkOVUXv%4j86Ds-&w+LT!RBy;afO zH1w$oz4ZK!{ku>&$!bFnl1e1u`G#}NoF+!us8v}&&^b^zgc)6UoQVBYl>1DycAjkc z^P8JFcGl^+ms&<K<+jMCqXzMWPSBGwpd?*5BM?AhFK|0|lN4jpD9SOBu@M@PpL14J z@&zblhk=SCfQyJ099vD=w0mOnE-0)pIZcHS22rLESUM@;4LO}QNc7U4?CFouO-rXu zfTLtlOZK`?R-1k=+YL6^+akKrfn*6INkkD2Dv<fGq-)czr~Xt|n$vIL@KaKxsZm7o z1(==4KvYvZbgMC>7L(tVKz9lKJk@`AjQ^IRqX5aC!RYt7+^!b(O-c5c86)48M08l? zZCJPTy4f_nZZ_nMZZ@#x*r;#)j0obP$MvT~Q{fs7>1oULC;MZw=_w6G+VCyCFa-@k zX~IS#rJ^CtQL^$a^-YnsDs)1QeL}(jhTg_xgNzn%6j}Hky<&gLdE(ogaAKv@y-ENs zm8t71o|`st;9(@p(5p{MSo7V;SXOLlXL1D&bpc0A!gW8wgGQ>iz83ZDLyM9PGo1XP zGn5*k*%Yt}h4%nnLpP%YwV&zGV>>(3CdVH}bcY)ZWUPc~wIVyxye3nday(BS09BM@ zng~*+P9qMpQ=`|-e?H;Yo@}1VR5)~~v{b>?0PavXZ=YmSRB)4i?CJLL=n~%miVu)Q z5!_&6^^=`?lW&GU<tLwPU&6@P<5bzIfVCTfvXkvUoAQfKwojRJFZC$dlmiF_k+y7p zK408Ew^vY1xG>3V$JJ{fi6`fuEB~?!T};H3>aFNWH}}b1Svda1?Mnq|Q2I3lhfx+A zJa7+=H7P%5gk-}oqlOh>0iiR1<xjtX?aG|$;hdnaWRy|akUW)uvd}igYscso4t%f1 z_Oi(wY?r3g6UKHh1OYf02~JUBy^#O++?fcSri?qnYNZMvJo!c=AsVM?zX$lvp#_9z zfqdQoz6CW&+QGP_2W7k;@4-naWEAAM%M&o*HY#=fBx%Q$nWPGS4(MV5=}Un~n}XHq zU@|E|ZQSWe>h(Yp5~Mc(n5io5fyRH3N$T~GxY#3UMA6Lzw42Gk3N%6iFZcA8RgqA` z2!gvt<R%aR1CB1A%#{KkI9vgcCmF=UiuPii6{}KhsVWZX05Eg(g5w%2-T6ZdNy)yK z2B`)Jvm~?}_|KENG@g<38x$gTT(h)D)GDRQU`h2X%2i0|B>k0g@2zYYXBpYToDzUL zFw?Q16tRVb!&bHk7(&2o;HwED0`jPcM;So#`7Ork4HYFE+43msG>C}-!4zR!aK;5a zdoCUkBDr08aPa21(uLk$iM;_cO9*nYR9aF5A9V?PagjiwnpGyXcukwF7`d?%0mnlR zL-s<7^y*P6Ia15bOj15Rq@J_~jc~0o0c!@SnpEo@;nu}>42+^ckC+6AHBDLz?ohIV z<ag4JRrpW))S5PD4T&QQj#Du%uvyqk6)IH=<(dYq1@{Vvm{LV7n&NuoGWM3|oI$n= zUO-oq66FRO48dKfkxXkw*(nY{&G>>blJV5icz^4hGssSc;1sX$tifObcVT2QJy(xX z$q;3Spq&e-l*d7hpL6w8+A<_8<iJr-n<T!PM8{^Bv&P&J87hE@V^&l4M@TJ<L9wPm zONQ_)#mHnvXn_i~CaZHzo2?Atkp!nAz;eKniv9tGzNW=ahBy;Rx{W9|Nct%$?7h`F zXC^xtB5Q^!M1hl#M4CnhC%k%;N`_FsV7W+TVj^qu(pQhtk|FZi0pTQ&QDH*DVyfFT zvBF89jWWEB2oX32vP<C?z;dUikWm_ITC}C8@Tfx!QySqykP_ygSkq`HMh=HrMtT5s z2MBDNHDA+YCr3n)Q-GQ=?nt(JY<BtTHr0U!F%{k)sQe&(!O{5!^Qp$EB#Ar_0N=p= z3BTrL{s!Z;L@CWko|4+#K&xO-)F-bow1jtT2+^Dqq;5JXh$T)&j$A4f0<TrVxwb_$ znFI~VL?N>zOM$F5*eGqfoij%3wW;(OQw<e-I41?gFYH|@sDty~TaVJ=HUa5G#;K7) zbiKMsYnW6-gA16|Ck?HJthU$YIme{krVHz;L#jR(D<K%@wRw)(wA#b~&i#sPxtg>k znpJJKms&xdHA=K8`D5M6e@t0518Zuo%o=B8uA3!fFGS_=tKo3Oe>ZNtxfo0|{<Go^ z;ul%Y$+in{ngyu=L^jx|>EJf525uC=MB7sXM|L`ILc|3#BdZ0LI*JGglY`u1<kjWX zPE5<h$a{@*0<g#2n%FDa%VcQu8$WO8$Wu4;8bl+$So}~iyriCuw_7#zUgI)cn76qu zLq0=7=)}C7H}u}sUMNqXa48+q=E6{Dd){o;dyU6HQosR_-xWbk+T&Jf=4IahG$}AW zPI9=M14^ir0tyJgY)y=PerBd5rq?>v;;_By91_dSg=lu7bsd5m0MC@tS8kg>s=n!O zCWAO@wrW&UOhjY{3J+kyXLX=lTPHdo`X7=1KxHwUu_RZHJ2;{XIu4ylU4ZJwKBEv4 zl-e=gr*Ydyl-NYuz1<oD2CrhOZD6@D^An23XVPPeCtSk1Fa8Q(w@?|80b1kp6i=l2 zZY0g}!y``5Nq1XM!PXJAeIdO8d&~{5VWPFw)S50dM$iZbw8^lh;v*r+1u`DvdKz_c zrqj^CvP~c0Xi2x>n1BG7NWg^fsn<BO4}(E8eE^996o@VFQ6q80jV>B}O&{Byb_B*j zhJRfF#j3<tH<rUSeHe_Rc@NNO5amE%1GI@k$Pcw1JynU{DFhBmwMlaDU<-Vp_vrOO z;*lp==3r<es0AkW><Q7G^r!cB2TVzj4(5~q3psG>nVoxN15S3)+a2(`Q%Vg?9ElvT z?M$49Csus2i~jB?ITiyf5vt};{?D%QCL*ywawq%f?+#E+0aW8$`yl*-`10%(pX{T* zJJ{Kj<qX&&Swta{^LP1VAA{Y2i<p!l;IKZvG*iX0XIiaVkDlb>IK~FTcmrIOrNS3B zv{Kge!P#LMaa_8qigXEJ-++IojFm(kDjedRIG#sn88;GjF1ZPo%xv@JXlMrgGixS1 z8HB)^Jd;NIgj7R~L4}lLxi(qyz4<-2g9h<zItcMo!rDRZLj<Q`F`*WYbTBC(gEzo$ z%YJ2Q!EXcdow70KEvd;425*p3zan?B1D(o`umzQP^wNu!QTCBk$dK|WGdEUkmUL!) zAU=Ek<CEG$QonJ@*f>hn>^TU#u<|6ahfoy+)NNoz8^KaC`o+SbIiW}WVSG@)v+_{t zG%^$$cV)O6H=E}jcjGgzWxDRriVkr}Qssoixx`B#SF<~Ol^tGfHis?fujkvFKjLrI zt!D~tt?7xVU<KDd>}_Hj&-A3bF|XVoffszH%1Hj<>X)U$M^t7`OkgSZ5(KuJU8}1j zLvZ~!9Rk2q^fs<0T;L>x*+bB%a;h3>RQbo*T{bxnZ#)PWbHVj+OhMO;o7ZTD^Ouw$ z7_yTgr<4}Nd!W_#ns#J8DhiZEQtc7XNw+TKCT=zs+HmdK17^VY46d2HCTe)~)_yr0 zO;PE-sBWotBW#`@3c{|%pQ)jKvfWjOk9M!YORknvSAw%-276&aMx1XvN$1b2=W=#a z6N8HDu<%HhvCQiSKPX@C-jizwAkW?F&4$sw_xt7_8X0^J<@xWfoojM2q5@--+f=}x zjq$!>{9G?wXyKeBAoONDf5D1&h_R6;1)Uc)dvW*K@-<xh`u@PYJmtS;?+qVVi-xrU znyV!PRvqDl!vze+i+l|GP5Nlh4wb)l71<<^`I15bix-A0Hh;G(bzcLp`|6H-ygg)9 zdE^6vdFXBbJ^U2=-DdMM^*OU7)Zh|WG|R>xP6L(u6UDmBBA6d!%>aXuaYi1F!_9z5 zm_3g};d-MtQA<AiF6!IWf(OdOCm{-m2goYl>DdXRml$rLW)Xo4?VkZIH_JF$hd*3D zyfAU9B&K39UJuf6j?FRMZjqJ8^07pqkSz1q^7m*~VKg=0ZApc`n<9LKFi_jI6oZr< zzfD$e?6OQqGr)OA$}(I^YwZJ{5>aG$z?lKZog<}P<eGT?IUtx-7-Zm#3ThnKM|a{t z&5ssxd!@1@o~lnHABv*7u~w9+aJtMzBPq&wP-!>M4nN)BJ%O0#b>Fi1e0P9QPCfEs z|D1a3YnLT}6g?(=nCl^q{Dk9KmihN6QDKY#Qdu^e;_|Egwp`r@cQy)OQI9nR&?F@? zy2GR0Mt9Zqyee3`#s#8VM^cq66bz`{v1Q|{e6_VNCpB$BTmVG}?npt8welDiLUWbJ z&}&MaHul>(xrQjVgeEJ7qY(x<ab%7syLW)LEAZA7a#;B(d{6LG#TfJkM6zPbMnI0z zk`k5_7AWzd>Q`&)Sf8&0BE;Uyxo5+=2WQh!9q^WH!6r9l^#+do6mKj=8X~gUF_G={ zUZ$wJOO;kr`Zl0+(6fV8&!eZEEXA~T=TKdfXimv-KtPpcwMX6vrIFP8Wc~b*R$PM2 z<eo>qqeSAn{a_m%W+C247vNn4Fast~(3_dKd!?^?rK{hocR%<&DhM6!-uuDtuD(sh zpo(+CUn!v25|GMTEfJHHfZtn6bR>Bq^`5#}xe<X-T*~4{<4V}L)YdLEg^r6<$PHbX zO2X23^UvR|RNp1^04<OZg5hnj2d$UVRA^ELoz9AtWUJNVCVy3`anxLX$ja=w2?%U$ zHkFVLZZ?>*%0Ku<eMy~ZO83ED3esB&7j_FW*bE<ZS9UW1)%)rl0^J$>NQ5FYszs|B zQtM703^KfW6q*6E9bly$c?GRvCbr+|m*5UeE#x4~*c&ma40h*Am1$k5JThzL0Su%s z`HQf<LmeZ0AG2$uUvQ*<ZHs@+Rbu`0kW!py1O*9oQ8lS2%A-*ZuWZ8y2IjCez1*Wt z<^ZpM2Rs5&QUyv`)>^VPW~cuHJ^y@<`ZD#@534(db2^4zm~!y2*pYOoJ8qTvT5*yb ze+RRXeUFFF?Y)n&y4BQ9=HS1Hu7M9Niro}!nlLj96Gk_Ys>e34pl%*Nt*Y{>TK$$p zaB&=wUn5M=Qua(btE1Ji11XC{J(M&PxFTe;_UH$ia(Wm3n#4Dw-XO(1ae;anl*p?u zu9=jKB<Y}lX%}Z`@BIf`5i*x;Q61JU9jcr#5VR?zIzWfnGZH3e+E(aI%KzHVa|j&e z&Om@hXqtM~q0rQBHj`CS-eg~p8%Q7sGsOW<4x#i~<0`K(#>w%gH5ielG;+7U7R;OE z=C7SKENY>mq?8))Sc>-8T{rH0JEZi1T=W}lY2EbK_s>2jnuSXt0;k&xX$_ANiga$P z5?f7uPPt8<iGNUR|JB2Rbby5fj4L=<NrCBBqOa+Ga({KVmE-HlFPbuVAAayBBG7;O zCcOjD&MB4wEjG%}?tM}YhBLHIQ@!z(5)5>NTZ4o)JR5OnpswfJ>u4yPY>^+9#5k3! zPG;Xoo1#V7Y$#Tv%8qR|pO`<bUTa|MaMWcKcS_PyVBFnWOKG3YM#=_lHmbDG+D-@< zLRdsyHtc11MSDxCt^|h4UcwKMz`yaepoFBCELy1g>6MDp`lSFet$qPA0D(6Wl7qIE z3$bpnyHPM_n~efVtnPse3|YiDp}_vDTiUwo1h?DTC0B@~MPLw8JD^+7Syg82KG9^F zen;UUR=*04QR1(V36uTKF}U_Xpai)pol3rO8I;NCgY;n(fm+6v2xhe!t8kE|aah&p zf{OZJdLhg<ws%&)rq|j@hro~Sl8`7P2w6`fa#nZ?rP3$Y*~0TlE+isk%a7WsrpUo& zqdC&J$ZL|c)&7DCW}7O)K~uyO@G$9JYer64sFZ5K9>ghlaaUW4QVs(m^MID5Y{~j| z$XSD?gsR<woHH~QYu-y3#}evYI|=A0!CD>P(Rwr6j{5D*8{>YUBLmczNNQ+8IHIRk zhTHB9BCzHV?)glWd7=2Q+9P_UlfR}Kst+0@frgHp3oOiaI<}^`D9rlg>j&h^HYL5z zKj~{~0jNB1kl=YD6`8x0?b}%|zTSV4y>3h_ts^ur@F+BHREeAvJ<!^el7}Y`43&lh z25VZPpdLBb)OAS!9^gMxbJ-(75(&Jx0Q+`v(PH0Re<6yGVr4}8eQaTBX^>N>o3{am zQ_U}IJfjFI$=E`%K@IRy@9-mIZ_r{3n=b?~6lXxONVx#-eQIi&&AG7olvH<UvWa<d z>Eevh&FeLkz0aJVQ>}i$%vF<859PaCCTM^Bk-BxABsp$fk$s*lAwTGXNSl<D3xrM) z;y#WTwqbAj)eDGPp_~+V33DM|I6t-co8X$q1C23dO5e;?j90PXg$)ZyZh{R6<riGS zCOfgud?XXE$E|`w=U0j+J3s)iWdylZrDrDYF&_<jc+mps&g}~?Rz%rQ5R9-nkq)a@ zK`Sw9q4nD|ki3O6MHVm_KxDu}D_M|9Gb2RSOmzXXg<ZgJ1!ss0sSBl^Nf=dK^cZ6; zAySK>YJHvE5Ba@RafiqNwz^Ca4;~TLhMEyy#KPBraDe*U@Vo(UqQa_K1)G1<dX1)e zg+p4{0X2j0><4ZLkUgXNvtEj$9hhTwVFyr{qyRxEZwayl(7=KYG@5)mH`>r5S=k4i z1gIo-MV7J>g0+wp7-=LeOpB&ybS%o13*RbbQ)|&n=CnE5#feE8by36P=w+0`0P34E zTQk#Se8?P`mDG=Yepf9mhX&w?3@P}>T`0XB->k#v9oh~=u{H+9!lm}eRwGl`r5vQV zV)eytyyyB|T;WSSvmdw~AR#8j&xJEKG1=5(McelCyaVztd=s*%F<hYElllxKf2q~z zm6TT7ZmI{l8ZYdHI(`|{oiUL$cwZVDX>?Lw?GK077Z;!3)yd;m_q#6_whkjGwK*vA z>*6?oo?E|zO%%MMEcW22#+^(m4@@S|%>hw27PA}=O?_+EyWeevB>S=iY!9#b)eYSL z)!nv;uJ-#c?{CNmf~PJ=X5jzj<cv&#Rh6eR(+a6Jhw74)l>M#L5$IYXhJn6MDi2;d zd;-R`Fh8D98Y;WrQzy!)JPAdzHlWzmoE;en6$82-Lq-AOh2#g~@{kRm?A#4s-exzi zs_W{Kg4>|MyQVz6d+2>wrF^P?+cjOMXC%Gaf33;3tu}BM11OCmpRgWmjHlkk-F3e$ zLJU)&3{YYeNnlvrkIX}Q-;jNGZTQ?;5|BlZy+~O^Jcn|dnqLcWRr}pn)$IW^@*#o# zOuZB0L0vmahxrLrLNkxDABz1=eR*z+YLv7X5;MYnEs1(EF%?IKu&v1}NQ*sNu)e3n z1UB<$mDGB8v9v5s4zwGJF_K<ui7RPYi0u1`T^GG^@hsfgcq{>GQDq+2k&6>S&1{by zcd|74!qy=X0t-V%08ks^m=ng?Wb4W)yRZxV;0_xV)C!y%p4llq5_!|bM<>g!4-^s% zAr*|BgeO$A#ux*(N)-WAwb$kDd0k#y+$Z073&-sS1&My7IIt%Rh|0zjKWcruymdH1 zajU_D1^C;G4Dn8HSx2oi_NBb9WV1TZVUQJ7Qu)guDtou8aqDihcxn<(GPDdAD$f39 zw;vxoQ?qpN1lD1uEMPSda(F}daD4E1^A``EqG3M5n1Y=nvXmHS#VM(oqb<_rYnKd( z^$wjx8Tbh>GwSJTsp*v-7|A4qUphCywjrz$1aKV2vB|YOJ~yNxFP<BCj;Unl<Ej9K zM-JMO(MQ2I?!qla4e`(ma3n`iVnKVjY)dVjdi>PXB*P0usTmMd`V2ZgHzGGnr#=9J zji(|Fv0V70akU&>S+dL*PrZv0fX<EMBT6~@Cj3yNExSEq>Rr+#nQ@S=5chM(U$C;E zf)|e-Tol(aC~^c+(byly=bk&(V!^3!)nekpVM?wiWd|0F9&HI(%FMlTc#r@<cLb0Y zgmDfcWJ&W#&Qig|Z7I==3Jab3Vuow%_~gi@T`HJJOXk;E2(=HW0YfHnqIu?i={bn| zFLb%7vSp#+X-=x+a(~9$Q=^jH5q1`=Aw^rg=6Lhx%zXkzEX;6D!xrN;*RJEupE37I zfU?A>gyjzYdBcWqeC}n}E}eTfsz5qH7(q54RYi2h&++DE*DjSDCI;7Zl#q-j<sz5J zz3kehqc3V`m!a(_pdN;xbIGoi=9iAX@VPIM6I)6BYHke+cJ1{Uf(cC?l?y6rD?xti z#uGt}kwU&cLoo5_lEwu?616@-+)e}r#?7CxwAB9NR)Td8)pcA8ifHJn95;W)(t2nb zhj^%0A#bi@PV%GM3WYq&E;zKJpz;VZT=wACBz4X#tz8#kG<sNLmMeUGpxmblcv&Hp ziA-Ik<NHc9@=}HG3Vj}yU`_>JNcxsYCL}A11s}(xpHp#Gt|e6FT4afwG5L5!e9|!B zq)JnGIF?Ml*inm5TPZqENfQVo;fp6dV1a0gA+>b!3;cOhV<wy$=9u|Q_N}PorCJ9J z9E7QHNnLXnj<Y3_FDiNI=qc0znFJZ06ds|5z#=m+`38obWtL9ukriHoWB?jUSq<Y& zIJIvVH%}HH+(15+R4JDN@10)Sqx)7wXR%)JD(Jr;b3iY6K$p#p|7iQ77Z$fq5h4$I zT_36U6VEdT;?ed+G#870<pi+rcoBuqa9dQ`)!eIBGuCV8v`-<11h=ch7Ko{?W;Dam z@r!US9zVdh(5amSJdi_$$t4DZ?5(B3A7jYoa3B$!;sUxzv5DSX+B{Sh1dUK?KnWly zUSv(3(Y%DQ$$@mpl?^ERXioH*$^RyaE-o%Fuc67>F5J6Nofk1o$YdFZH3WM{^`_PS z!sf|%<$ey_G_JWMHgzgb4}WQO!2&Z4%5u_b1GrS1OV)|@y)arjJ<tv!`vh<(8ZH@r zi>8P67fuhjE3A@`3p%t;prMbdwr2Kee(CfC!i--+BLtJOPkeAu`vgLlPLEr`OjOrs zXrjRJiBq>3KkYA^9x_RQ{*a}NS(O3wTsr)v(*r<<>Kmatw5V!jj$J!+ZE4PC_-wBH z)xsC>xPo$lO9SjSkIZlV0w+3PeHV8CA$&!(L>!w5kP$<{*{=iJc?O#|U;!3)0L~d4 z1cZAesHM11)f>de-k`X--{KU1EFTi{xVl?7S)oe?95_}=UE+pp?xi+1MXiSRxgWmX z{_>YsgjK*>6ib(bt0S)cAg}VAOq~XvC#|M!)8RFk^n<DOJm3v%AG)|uPZ0p9va5=> zCH~B(deJ^*uUGwoa8ZEmO9m!o?IortnCT{xHR@R7W8SD^PF{S+re|V+oUf>_7zq?g zt+&}THc{Jigtg;VnTwl^SdgiJprUtg<DE5~q<&|P<QP6}oG7sRGx1Lz{iw)pU+#Z& zTfN*8c7Oe&!)@`Sm)pBn_xVM!zy1U0Bnvoc$azn>L3{p>_{W>=Rdsur-@_e3z4$+H zF5HVGP(Qrd<`=hzAN@<?r!H{H)$mr=e^9)<zrZo~U>!dijp)(grYg3iga5KBFU##$ zm$%imtS#~M;o$x4?#@joo+q@9Hfw&3oPz&NIjM=Nh43y&kp=sKNB8t|q>n(pPcJX; zulMEMmU{26@I+7nlHvtqP75d&>1)0{($4f)Q#F+Qwa`vmL*_n4eldkRq);y;oo2}W z=USl``dDwU#iU&kTi5%VX!^}|_ww@k{z_&8M;R<7M0s6`WHfcnL<y*72K?rR(Uc(c ztE%{tMPWf?3b?LA<^ni_=s_gg!215|Nl4`7`|m~{9AGK+P=FhNpa`VC*Z8pq6UDRk zK;RvD#a3Pr8!a!~@t}jj=O052LoItHFZ$a@|Jb8PkNzD0fAr|H{covH{V(#j|K`uD ze=yIyclfPGfAO!`|MCa_-)}wo)xT%|%YXRq{Pv?i|Bu-J@*n-Xzy0X9|4I8_{?q^D zw;vr|+W+!<|IA-_wEGYAD0J`t=704UAN}jScK-6;?*1kHZ}qc(&wT!$=JTKU@Abd` zCG&Z0K6PK+f1BU`Z1DSk?Z4B%@1E3u`iJJZf7E>cJLdBT=JS>L+?mhe@BeZ0?{mNV zu0P+*Q#0SqJPqgDH}n1T6Z8Mj?fr>apW*oaoEb+W56$?7^WFUZ-!Sbo@Aq%btY`E5 zm*)AuW<JmTeLm>#ug~<?wA;MjzipoTzfL^=H%$A@^MCV!p8uPs-DW)h@rm&?&;MuU zcYk~E`~Ty_@BfRz@0$La-woIEyY{?MWRK=PhvT1nuKD-3{e06;^LcK6&F`AebALa4 z{vZAwt(X5_^Z8Hx5Bl%FV?O^m^ZA#}=kWK<IF^2%`}=dBACBW)`~A7&9X|hGnsxfG z&F9}WpZ}}*{0HXq|1qDxX}=$?|M2g__Z@zJ>hIt7?}z=l|D)cYsrme4^ZDF-{=$5| zHlM@a|2^~Xf8l>J``mo~zWE$J|M!1Gp8vnid;E@h&wt^>`~Gj{`TyN~F8zIK+Wpjg zeqlcU74!M8n$Q2-eEu!-`RMQJ^%&0o+iLG4)9=4*J~Q*#jPI{E;~EU;pEl!k%x7#q zGxPb%eEtpd`R|+0zi&PV%{_Ws?ftW+ztntwWImhm-OP;V)c!y9{qX%xJ%8%^H*N1t ze?J`Gcdfm1$1{BXAN<dH-zEQx{`}Z{{{QTqdAyBP`~Q(CnVu3#GE_oBD4HorQe?=O zC<)0_R8lD_DKsc5MT1i2N<vbIGAEQ2LP(UPOqJiuv)<Rw<NCVnz0ThEK6^X&KhOKO z*8W`6XRZ4_`<(jryAf*rEcU;GKf|2g9r^jy`ajX{ga0OZ{0YpJ9~OXT81u$UU)ach zHv8pZMOZsveHA1BVD^W=q44!|((C6{ul0S_pX+s~cMfP@WF4zNxmUaQ#(&_+uq4#^ z<E1ZV<S)hkIj{n}EMWbGM*bS?*MfCm`+)TgjQn!$7WH{qI@ym^{|$X^gXezl?$d=( z=kLV+hj1p`lur6yp8cd%|EijIxiPQgk5>N_d7gp8pu}tcef61saOar~9uEscoj+ds zJVt)0+lkMY!hd0jHLl+>Q1^Ely6aT@?+J>(fjT$B=1}I*{l-h*hB`XG)a}XVz2HM} z(o3Gv<eLm<8u=e*KU#f7&bbDx1+O#C-_kv8=)Y$FTeuPa9_s&ll`MaLHT>Dj{=YEy zTKBvbf%<-idgo6;!=LBa9|qrqlS2J}uaf1@c*CEm?0*6m!quVvzkXW&tTg<Q@0k|$ z^KR*6KUV#}^m*Jm_gv+G1)<I#FZ~HdewoXn?#I%}{;{Snj&GIVh43=N&vF6lo09(~ z*cNt!+J9etrXStCJQsF_&%n3g1gPu98efsT=fewOBcoot^wo|0`PVx?O2RU*Jk;}_ z7O?(G^4ErS;muI@6EA%uBmb@Jw}+kJ{Q>K{8u{N~e>5BmX9leQz{sCzgS$W3U>;Z) z>hr3={`IgKyu;8x%KiZO3>+D-{&^$++w6~p@58wP>!%y}7qPz#u7X<v*8gDS|Bd}! za6dd@qq`^iKEz9Z!06|E>ehzM;Oj;|$)@j0pFQ9M@KK}x0qhTkL!dQptomUQ^1sFB zW8irB8PxYd>pzU3|D4a~!^Lnb)cIr8uZ)oYxS!lT&k1wG)1dArUiyMY{@Uzc2OGoI zhQ2NP9pIhtfq?YgBIJLX&!2}c!YrGP{66v3OTMw>of;v3vgw!7?+W+>{0Zv&ww3+g z;4WzS8LNIzg#6h!$6PQkENh%^yz~W){MWKyA2xyQ0@k-M^54mRcX%IsDq#J?M*ip6 z9|lLj@d4}KF!E1ke;WJ@eig9(b0hzD_Wy!^!&^2V`F$my=i~EJV5;aV((n23Qg{{A z@1HvC*Mp6qHE*o?rV;YD<MTUUXE*@r{<Xem1pRbApAEl;E1}Lm(^GHdy==>o?^|y6 z{{v5kB?HzMGxC>W{~TBWTK&gMf1%M&4fbonI<S4f`UXaR`MaY<eSa*S?8mC#LZ6j> zcK7RIcnj3|ef58N=1;5sRMmfdqkqXCtv)At^1uR6;<Z1%`mW^b0Uv<<q0V1<t2?J^ z@Df-T2BoiM<Zs0O)9_jNdYtv0qRih6oz@RC`UzS;jk+`8EV#(%CuqIAH!SM=W9eky zS1)lw-}q$H%N#=A{v=MA=y>0HvFZ!_;@)4Uz@qS6sPo55f3}fde7C6kv2?N@tG*6> z)`Jb<tw#Ux(%)p{m$@v)I<J*i_QU+n0r5jK^vBPiUflDCU|;yGasT6`f85Bg&r`26 z`uTo<Z&Tq6_>bYIuU_&kB;TqC`F-_2k#8&fEkgcy>Hnb4|G7Wg+|S?aFc&-p2Bpty z<d?cd`Me}7W9ThiCqqAm{rBKxxHO&gQ>pt2oE4#;c<JXF^KM{&3)}|x2dv*=<S)M6 z-OsaN8Q2c$`{}Efe3y{#nh5!0)n7;c2C#`|y`bXT(1-T31N)s}cQ`0ueJ>;bX!gg! zN$|6P_0x^~pR+$7E{1CY)-N;i?_j^kukN||3@(EDeE&wDna^`Vi4RJj-{_|t`{%*) zVb3_}C0}jwHH(m6>u*AT3%or^;=9p@KCfQvKLq>27XsElY2<JHo4c2{!4B{psQdTT zOTK%_HwZolheE4fvd52z(EnIIp9CkvMNs=2Fa1;_f0Z5Xyf1{8!unA66EFQ$M*gns z_kj1okK&}4eErGyVubu!KMMW3aD0--Pp7|6;T-rq)aM&7{TD`l{rj?B>wfg-dY$U} zSm#Oa_(c1k>38?O$_9^zwV>|DS1<WaBVU;a`L+IB^p#-MB#Ey<AKIU5*uNe&fVTy# zZ*Jt*_gSxX|N3*ij#d9TeXfGv!F5LezWQC{*$Z>*boV<y)cuR@0D93CGxVa%#^<7| zVCeg>|0sL{ei0|V<Qqo5cOvB1`pM|0!B3JregXY0h0EavsLwZE`frW=o7vw6cfg!~ zxO=DjiI;wt(N6{HR)JOF6-GZn>u;j&EwDX&%jicwzn{;a2v|Rm{LjLnp7nx?e~mu$ z{dt%D3Gh9*I7<Dr2>K0tz6EZB`=Rb9UiuwI{u6e&=cpOH1wH|FKluXI7xm1aR(%cX z$h`L$^Gg0`^%cld1zrp#Ui;~*|Au^p{&eS799|7|{-E`%J^M+k{s47k-t&!lC4aQ~ z?d07F_d<!+e){V5_dC7T`Ss^|9qOF}+80@Cf9~O)^oD)l)5iUYmwteee+c_8!dKw< zfc0-1`G03W>tF7DatgcvYCmJu7bR~=c(!M~pyJOn=Dmph%i$HUag_Qx5%kUYycN6! zz5})Y@_9Et9|WI+Lt(1MkBHF!I6i+5eh3#s?U&Y1i=dbHh((>>(#d|PcMgajnz8z` zh4ZYs+r7W4!`q?GzdOnF`#t+ftG<}>r?KIW<d0ULhdd|3Q=r6a|9$mc$u|~$0OvxT z{~`9DgU`d^Fj9P9bWcX9x9Uj0y1!)8>*rCgb^rQvy^dA?FTPjb<DTb6@P7Dz^0Ob5 zKA&g)wCXEUN9OHd%q#h$)t4YoDR?fFc<raJUZ1~S>-_q2y$<!x0qu*dLw`bl4muFt zhoj$vWc5e-vgoEd^uLzQ+CLN-oj*E{Z+xojW1T;}<9+>4?|##}zOP@2)=%R5S&Mz{ z`|lmF3)KBgMn4^X3D>|Ka337C*X5lCgU%;?Y^44m>PjEFe$e_8sDCc34r{{&a68O| z@3{^CPeLd8zSi+-Ksm?0<a-&8Hu86v<r3TtABRuEkKo5}J3Mu^i#rcihL^%_P_>sy z>#s$39lQzN98mlt^e=O6RdeZnQ(b>A^Yw<~;d^i$+z9pjJGnQ1!5sUu{8w@UJPj6y z=fU$~Em#M(fH%Xg@NO8^Kiq-z_J0h|;rH<3Ij+A>Z~;635AQxxCW-%4#n)Hy>x_7b zn@9WtxC%<1Cd9XZ9iZgh%=%aOH`M)ZA@A>S7nHg0CGKI^4~h@@K6e=lz(TM&Yz?1+ zx_&nDNxkP){xelRE4~nM68|=9iNC<8FL7niOWah}5?9-ZmpJKP;=~_`6F+qSQ^-3F z?t$6nI^|Wc4r~iM!l3izp-ws2XP&D#01kqAzR;bxwZs=8{zLSi!o_eo{0;7bI%~Z1 zNk7w6{hdaA>3a^JAAr{UzWV3!X%j4iuh$v=if#w`UGM>;{}Sw%g6G2XU_ICfYX6fZ z{!G<x1EXJ=^Bg{J3U7^*el9=9m%<$|$KURIgZ3}2`uXJD2ahxIuQU1>VCc)SUj<$Q zYa05i*}n#Mf%m49z8-ZO!QRlC*H?cw`7EFG`7THQ;=k_v$H5W@j(i`k_{Z&E4eP-M zQ0Mp6OP<E$YYJN!`F-`H$uka4f|HH>zWS-;`54ZGvyA+{`dpk(K3E8z3bp^fddX9i ze8u4zMt)!YZRBYWJHakSeqVjxOvnA#f|ubbx!n33sQvNPXUpvJRXpBtC)^8jP)FCj z)2J``T98-g)BXN|u1uE0=eohj@2l@}oXdM3ES{A*@L~8E)cwUP{x0fEy?#c$r_n8g zU!z+Gb7gb={|6R_m%w_k3DolhoqscZZiTzx9(VvAM}GxiVOSGh4R!xP=a;^JH~P*_ zUvdu8_i3u{YmNSc&M$q)y^ucSUT8mk^>Qz><4;@WydRE-AHoIj511#ryT3)C?kDK{ z_tA&dukOcJ-;ew+z)?_qna27Pm=zz6H~ffqzL%)`n(E^-*3yTZllCLl_>sKl--7SM znNZie8(;2)XXbGCr!<UJ-<!OB;6}IwN}X~>y;$R=Za?Ztor*?1U%lj=spcw9eyMYZ zQBUHBs`&k^CH_hyUgF+GFL8O%OWch{yu?ZW5-0sjoYnu6<b4{RpVQr+3!%P0zWNu) z`wH9z_d}^u-KZz=FRJ+6D*lpy;-#+iFLkAVscZEwabK&s&!b<7yVvMn;>WA_+$z3- z5ifC{5-)M5qnEhbjChHY{v}TOmpH3`iTjTFqU&wc^VQEM&q}x!%J+5s{aoMYM*Q8X z73>NhGX9>GD1B4a&s|18(&tTIy2&1y@Aw290^fpqeu=xC_`Bf)Fwy$1s*jJQA2r83 zV;<>S;zYOD(CdFcA<|m=k=}Y;Khgco;rGxja4S6J1ir_@#;^$-26ev+iQk~|6+mAE z)`ybsxdi81PJi3rE-3w-Vf3TV%Xh8)@{QN}WXl(8Kfdun>$Tr{?OR{R>vgi_i?tu$ z_*nIGcy71At?-oGyw6}`*aQxPy8c4qH>i9C&=-OAq2zlm!TFZc-!`}lN`Ge<{pkCr z*V+&Lxn3t+pVyshd3XuD0sfzUjuHKdYTh~#=FP_ExnR`s7^u%#*8j)fB-204yzjwJ z;R>kxfAkp9zo6z_9AVxk_<RtIHvRzmy7}C5*cled@77acw*qc`T_MMAa5$U<vle!r z7lQhHN|XOG_%ZpH!C3VZ$ommo4)?%()RFmgJ&F5L#bqV#1enL@H>1b*#<$m@z8~6e zU;RMxz6@W5BcrSrYkVcnT|XDKx&L>=ei5FFhQ{;J-N;||WcOTEBd^qx=Wagxo1i?0 z+VA_w-y8PgxqblVrcOQ>@A#3_83o^iA3|NvS6{B+;XY|!<h^tz{#SrCjPs~Wz6;=R zI0EW^ef5>_`AqWZ`y+i>_oWW;O<^l|A58Cf?T^)OC;HX;$?Q*qpTaK;{XovK-zn}M z42Ew&onQ3N6ZZvNYTO53{ahn&Gov40z2u2@-bCr!EB{|H=9PY0@_B0*ZM=MswW!bA z(#d|R>tzn1o~K0-_gwr5>!0S<%St)!f+wHj);hkeil0q<y<$$^8a{K@;rTk3aqGw6 zd^oVI+usE9P}i#eLX`E-FMjlT?@&+AH(KSNc)H6Y^I7_p#C?E%2h{pG=tTcx1br_2 zECb8ItD(-nn)A4dyq4eA{1Sg$(Zl_Fne(#h?WL~Nv-Fbpc={8az7Hde^SOn-Izfq_ zVDy)4`d;+?0DJ+y2DQII>!pv!R3B4Wi?4D%y1xdTqdX__{Ac6&)B2myKLguxkKZ)z zb6=%@A%gxBK3@yh!+)UervZJof}`McqyNV2H-)3&7(*{Q$uBx9e^>HIAOEl(U(!8~ zAHsUZ`*nur`?TR1F7FfYP539&ezjNn<q`DR&vg0A!%FZvsPo^zeskCsK4a*IvHuDD z3T}cm@JamA_2L!(vZ_~`y1HJZJ}vzmHP;^2S*Vi>7J|iKIamdT`Q3et)*ta*?p0cS zmwTxFpT{{${{8A)^Kfo*t|isER%LDFzqo{(SHC|l<+=T>wEJAXpZUH&t|Wg4*o>dU zl26Yo`j%1ZCGTUr_p+1!VkrH7Wqe;)K%EuvOck&DOE&!)`u-7S#)p%k?muX~^s$wG zq>nP{e8gwn-%xa~K)HW%uF0++N#F83tzf+o%Dt55K+p3Bx_vM=&tX9rFa2LCe?BAs ze))axZ1)~G6?TH(z&%j+*U(chdEZxg^Yb3k`CmpCtzLA}_bKEpVdO8%enZ#|J_dh; za!+-C@rplJ)!V{a*NfDrrEg0<nQIv9*WtTx3Y-ZS!sRf`@1B!r{Sn{gUZvG{xrf^S z+c_7>|1xVi*Kw@nTxYSCbNz<3m46=JFBU=hJ@6-fj_Q6ycN*^%(d|ZGiJ#LojGx!( z9lxA8Pd573^Cn9F4}EDrt$wygslSmq7sFzl%USR)_=s^{^7q58{QajJ=PZ8*(*31X z-yzEU@^{Z@sr!pIE?&Bz>-*+Ub-g~9WSb}1`%5;zg6=0gkHa0-e(3e#>O=osRIQV> zuU_KPO5b{^uGc>K&J%0AZ#`eV?l00h%<mkqd<y-EuRp$i`s(#L`o@QP=YaN6*1rBo zoX|Hu)%7yBFr4Rb2gDbPhpXfN{mD1K?laNxzV&?ddcH{OFu!xa@+qVF6YIRG7Vq0{ zs_XSVPxg6g^Y2HVR?hu%h#TSQ=eqR{cx8FFz6maddOpe5ioBBV0C}~(75iP`<8T=K z7OsIhz7P9WT(axMC-Gl=isb(g{GSrxJc7>OMcp5(|MK)H_ec8I=abfa_Zjz5@;yYK zbKz1b{pRDITmAG@`s{}OX;nw&wfg%=={qw=y!0}s+^>`ATi-7^A3eXsucA*KAFKXH z@=Aa5zOnid{a?i8;Q5#M()ee^XF@M=QcvRaJjtd%gZ|~cdJgCLopB#UUz<45ziQ~^ z^Go^sYS<JGgI0X?2yxoqWYbTi|LJfA{1)o|_i*19R&YNbvsZLn3`d^l)_=e}mE8J4 zXywbR@=YM0*5_rvIIIe5!~Sp()bSPBx8jmrFFuL?;!`C5YvTXy5zZs%{KYuuNd2!- z_ec8I=abfaWsLhM`6|$7ci0<>-!qN-CGn+{{zF4wUDc82#p<uE(x1*8@zTqjaz3Ba zx4vI;KKeW){!#kW@v-U$l2`hZ_l?z$=wBypii-c1duGK?RB=*I;`BVprvIA$<vqQc z^L&iCb^oH@L!9WZH}vxPcJl6qInmdKR{V|#ak{@`)3;{6+u_5oAJqNp-<S0|+4RZY zpRZqfo=EFt%kSHduU`8RYrM{<*I|C=fc8b!$C^J^RCd1))PXHv7pUhAT7MmNZ&ZEs zXPxB&*KdBP`x{uref|u59u9?CFZ;v!Jj?km{sgG?o6+rur=y$ZsXr5aPuL4S4xfSV z!Su?n`;&eq)0g(gSMTeCt|#%;=%*&E3!A|<urriC#pluNhxy(8kJcYw-}OBg-{oFu z|1afS<Xr2qmUC^(TF&(W*76*UVQuAqqN<yBFq{QfLfuc$dg<eJ)yFTaU%tro`wrCo zHK^u3zY#Wvt)bS-erG-(e4&dU2DN@Fy3TywhCaF){fK@IaXaC0#NP(fJKx9j)q#FG zK|Oz@IV}A~HFsh1p8?N-7s48_9&7@`{O*26>yP*@_b#oz%RSZpZ&vrZ2<If{TAsC> zYfaX2uFY9n`Q^Fjk8TXCV?1w`eiCuniOU5G!4mKam|ppHf6~uY^rijx)%*IO>q-0< z__-W@4}XTg!+)XlDLz*-<_Yt==iBnf*LQu-C9m8oeZGr0FFDt>tmRyHsdLT4Im&Z% zF>5Qo{2pmh_hac~KWM$w5e8i^==?H=Mc?{X9@+QJ7qnjbik80pM4MN1VSeX;_@S9> z{v=yJ+OJ4!-~NNv>wbOf>G(+NFu!xa@+qVH6YKnmj`ywStGDinwIAkp4ut+3*@sx~ zhi`n)dh496ecyhpJl1}g-#L&h{;cBn;Vc)s-|H*D-j})c5I6zq^Ba4K(=CNN;c=I` z{Wh>83@UyCb){Z=qu#m*ed_*1|C5@lF!@Wuval+=9M*-6V3^<Ci)j53-{oGV)pxlU z+W#%;J`~}c<Xq2XE$4a#YdO~@tgZZ?@c9pLC(Oa~bQ|n!JYVsO|BSjFsME=)7pYI} zpXfKLxeAm240sN_5Y~Y8U=tYTch5(({)q2#uhQzf+(YgEW_53ia87cr<yp(Q)?_W` z+MKnO{{Ww#e7T#u4jg}lTmKCUUFp`kzgXj!R(E-ShbPr=>oeh_a1hk>;}!ok^`+iZ zM!ihzTYc*OM4yc~nX4M>E8(@U8EgZ)z<Xer-`$UB{Sn{gywd8s+zai0PR>R0U(8z0 z^?KHFu5DS%x%Ogh<^Pe-PvAK$0V~62;mc6>7q9qD^zj09UNq`O>Qnb8`U2#WxoWd+ z0Gq?xVHemN_Jd)5_k2X_kN7V4Dy_cDJ=Fde;#?&EwXEe_Z(=Ry+MTtW>*K7g{MPSr z*1qn~(pmed7Vq1yuio;>+7I(P2SR_2>_e>g!#6%?y>-skzHdKP9&10$?;J=Le_pET zeqPUo7hUDn^<ds>-1=dt&u=Pm)8TBDPwTI&<?`jP?f4+v0WJMo#JvYIq0a-O%{QC) zt?=@zT_25Mq<(%NZY|ub^6CDqbGG(<<Ac^)eagOXeTftL#%ujY+{-`U0r;Of?p(Eg zP8#(aqRjsVx;09l%jl;j`!~Xy;4Ox}e!%*V$Ug&q2ET&Z&v@w<82Jla>(22MSQM6q zx}Tu+a&Il_ek`5rhkECL_@SBX{*31yz7IcyvyA)ctCu`qk#9Zx1Lm*mo{vIM`&FF% z>F^u4#?W_VzX!YzjxhA|*<S)T!Tp9l({--jr{HKf0qXv*V!sZ&9(FbKFS9=qPJs&z z{ZjVtxZd^kI2;6ZKgHQU3zmWP41F*5AA&EyF@}C3`<K^q{j`9$K;6$C^#8!j=*}?o z*R$Ucc7zWZ`abOEsqgwJ11mz^&s_8i;1c*d)cVuNQvz0l*BSZiv%eK)zrppD2kQJI z(7g#q!^KeR_p<*lJej;@jr<ka{~Z1Zw;1~S+3y4U!FLS(a`soj9WYx1H@EITKl{Vs zM{uU0Z_Ivk*b4SB^kdkc2<O4?4gEUyJ2iCu_J@O^?*A<I%fj-ozM;RL{XTFg9Bb$& zvR|c<>!&_!0(C!I&~Jyo!;=mDmF(AsH^aLPeINF7H+KD$h83Xh=X3P);bOQ0YJCy% z6o*w|T_b;e_J4snZghR+g*yL8bfe%qa0%4<ee55A1<8Akm4AWDaPdONCa@LM`FEiI z6Yhn@41FE;>%n&LenYRnpXjyjM}Mx@vFiKKXYNHVQ)yTM>inOhpAQ$q9Z>6wkf%7T z3hNsA>$ATc?tr@ueSh``!e`)QL%)IjE${#=uvmBQ*0*u5UW3z{y8HYk9Ma6K--J3# zyyBmwezf(X)z2dDYS@msx<NgUuYLo0&uQX(`kB0c82Nqm7n8RpyqvtXjQpaz3;iJY z1^gbKA$d60=EnKPJKuw<udj{1WX`(u+0vNz2lmDHQ<$SF>;s=N=3B4gPe*qKEDa^! zqpXuHUpe}U)Zd@zvNw14b!jWd<8F4;&x57kL0q)@Up)0|4gFd4eK~v*-EcVO7B|NN zxE1ES^~m$ZJ70O#pYBKd6)*iP=8QJ~G()fbjO1Uu^qGwFvGVUV`k#dVvtS|a^+oXP zHtrr=1hrq0;-l4{XFN|<{!)g133IH2eb9}BZJDFHF;Ap;J&&ay>e=65L%)qV{(+Ow zErriA$0%c-Nb!0eOFz%EzfTSQ@h#kaIu&j~m!q}Y|B5-X822^W_@50wtoQ?-{q8pO zrI@QJ?A_MQ^&HfGpNsASc)g0(`n&mjCd^0P0!Dsc{dV$}XzBVM%zI{t@xJlZpG4kh z^NX%Aac|JaXrmur{ng}+Hh)X>Q(zVPxZdc;SN{olzlG&^E-r;1an9eu2DiC$>I(IJ ziFdwvsz2S2t{*S`661bb`R5sW?Pnza;-znIoR5{ijiIk|lRNLW@EYz#b13&>5A#1y zo(T!c*HHDR`_cC!Ui#mR^S1JDHuT!hNdCo3KgKv8EB~8@emefIfbF;!_dvN9g@|7c ze@#%nIjTS1kG>!A(&sbgv-0OK^xDrz{>4kb)w7=shW<zVKbhbEKIZ4vXU5MjUwsbp zMw?%BrHJdxJ$(b7%lE+Q#`nQU@%lbl`j@B|t^Qd<Ux_)cgdd<=>#1Mqsh@4=>(NJR z_$#_Rd_V4tuMZpkMvB*dS^BKT_i;=Ak1@}Aytk{v7VX^6!|qV`<Ey{3z021h4(RIE zFT;1cx%CowN>8`026g>-=etMsr~A?M<E8(Md85rg)zE7{Bl#CEeFfuuto)@7{Sf@0 z00%PXt8n*y?mkrQ<*5CNHU3pqU+NV$>cvZ+*E4^1L$CdkzAeAvr7!Q<&)J5)b_aK^ z&7iyoe&hU`b8p%k_a{=kzAu)3lkt36`Zb1rAalG5+x2$yJq&d}siN=g*?$j1zYJeC zz*o@CNOAoKp8bzC^uOWD*&W@zna=xf8PxaZFZ2gsQQ{<C>#yYVXW;yMU7a0J>ldK= z3toSZ(>H;!>LqW9J6zt|$lKA#@2f9O-bY|=@}6bn_tif^-Z$X^-V6D=yLp=N-s=Vb zf+yeaKG*)mJKuAvKi!Y6A1{4Z<9%=CZ*S<epOO5Fmp->~K34v0hQ4wqch0Tg8{E6m z#{KivOWrP0hkN%R)aM&7eGkw4cN+Tp>H8@-2;I1V^>2FSf5p%bqwja%Omu4l*01!; zzu3?hz0=*#YH%C6f1td#Ugr6%$~|vj-1m6rJ6rXq`_cD1UixQ@_mP$V2}7^_jO1Uu z^w$~ZW96@9=x@dUv9J!`Lz=<gh|6w#p9xz3Ieo2!$KU1db7`pWN4)gKJo6Ve^y}&S z4|ox}YvQEO+S&P04BkcFeo&t4>D=GDInTkyeTa9yysAIlk3PS6>EAP+S1bR!hF<#_ z$-j8%2N>sL<?n0g&%yso;M3fTiSQGC@BYpB{X5$Dm7ei$Q(vFIRd0l$@6g5F|6cHW zbbkk||HCu?FNXdx`kn+o<a^_E<NKqpUh>W&e~Y`FU-v`pf4ubFJ@a=o^o!|xEqoH) zho1Uzp8A&z{V(+KH(Y>jYry&+J@bEO=yURS`O5H1?%87FzWM4UZ%y+5O&^7OxO=DX zTfFoqdFDUC(ATH$Hn1MLo}T({p88gX{!aRM5ROGRFJS#F&-~L3{Z{(k4=eC@s5^|m zM_Kwhp8Bgi^_Lm?Ob@twTL`v;cfv~^a-TPZo8T_^R3G>GD5&qh#LYop>|v)b1!L7q zA16_N40&f7`9)V1{dRPjA8~!@eni(!&G|X&JBaUP)RXw?=$k>wr|WI!^S!VRc^et| z7t!}pxDtM6%(I>Sf_>e*jURKo6aJrmJoVkl+XLPYAA&mnWcELTpTJp$zTTs*-v+QL zYzcM#Z`ofBe}q37`aSILhnevuo8eDk_KU!xu!Nz{^tkK)3|I-)fc0TpsORa*{#)=P zILFYR)Zf)R4W0|DLY==2`yJr}@Nq*wiv3Su-6veV&tahfZhaZl^(Gtf^@!Jc*`LJc z9~t$^8uen0Z$!Q3usa+Fb-$K=n5Vv%p}&>=4p94{`-zwSQ==b!E^-dm`L8C=I`|9R zVdT%peqnentZL|Mau42x6X0675uWg*yQleKC8+(o2K`VKpEZKMucyAb((h+&^`rHF z82UEscZ8DH>R;v*|3oK#>3+oDFUT)`o@4lvR{h5+f2j!hwZ534pG{urU-DZ0i%#y7 z=&bwGin;^gk59RKw-stXef9l3^GhE?h?71t4|IL$eqKa31!kx3sz(2ozGMXbTPlB1 zPyNY;ew^xG@>>1OLcb2moVOYIEq#Ls`Xws=b)NcKhJK~$U-DZ0$eePn50LjoI0~*X z>O~trBSQS|^ey#=c<P@r^n1uF^GRNrPv7_QJO^#y)IsjKm;qzeH}cFceLP6qV)zf# z{aE^+Bj`J;{6Bf>e=zht*q8n#uhma~^zXpD_<o7uzojo7LI1qUf2OCtsG%RO`j@;` zKQgDB>#gK{&&Y4-heps(qc6$d%TwRo(0@i=>0k0bXy_ZV-wLjPTMYd!_RkvZp2Hhp zC#dhg=rb#Qdry69L!XoV+)(mb{VYXS?rGP5ZFoKG4>!S1&p2II_~f&0{UX%!O8$SP zFY=Uymj0In>x&ru$ow<;d=V5sbpN7%%TqrnM*a81>wYS+e=(H4_r*ysd5Ur$E`bf8 z?nm_bJoTBB{`v^{wZ1y~tDqGx{imw_1m+WeWlrln<T+kW++Xl)<9YVgcPHPy@L4z- z>iZEd{TrV7UqJs7wBn`zRMkJieEs1kP@jKE<NTwI&+8e#gg*3ru<Ff1KNni@GGD6d zS25oP*cD$NGyIL0{t?go_Zs@)?7s#_!|`#_FD1_knEyHVedHvl@6!$Jw}PGE{X<;b zBX9zIAASK_KJRq5!7gwDTntZo!RflguEX4VFns$(x7PhNrk|#88g*x=`ZrT2-tj#m z_#yK?sOHU-#(BS{UUBBr`SpChddb_0{Bl0~4FB5GkK7A6_j>5>c*&jHRJaSC{qm8| zQ|DVwA8F0E!-)SN%6_h34yhlhe@ma+nD;&I^(rX7)I<LQ{0?3?-1&Apd;#u*V_$Kf z{{Z!U_$0ygf}W=qzKCDq&-M7B=Z}~E3M0Rq*GM@(bZ-Z&A7SL5N*}Y~r|6ajtpCEu zzmz`YKL3m^+WQ-A{2b%{Tk*de{jTA8`4!4@wb{s@pZ7{t*phjlfSX}C>gne=8+qG9 zsZ;pXBfl?COK`oQ=jo&T5`P{r&L>{_u10=2uixoQ&Zm%Z{_)c1HS+&UA35o_BDxv@ z>#G_0OVWqj=jQ05y}!}MAMmVyi=nU1^HLwmb5+uKzJ`!Tey)nHs-f5a{oY7x{qrf3 zUVk2Iyw0cB$(G-@pIG(#IOktKckkaya~=Qu^2qPwQ%1P`rcvtKpzrpEi(4_z@q#ZL z>rkh^Q7_i`vDCk5<l*&yrw{F4vg&Jk_Fp9+{T<}p2gS!+oTv6PS@l19_WxBt`kb%1 zd)W_)kHrl?lU3i@v;VdM>7ONU!PlLy;-kE8^!-d${U6K`ZT~^(<-I-PP3PwrI38+0 z|K>d(t=`go_`a*R;RDAV@aoBK-3U&DYhaBj?(^nw;Ad|AJlq3w%yRp0&2}s?$5DR% zwKRS{SpDwAkF29yo{})y{^!xZ_S4GS>@8R4)wdmQAM3broa2D;j;rD1NpAfk%#FWN zH{Sl`HvHSCd@74i=fby`=N+j1h&8?ibuP!hDRK5M+WWSKdnfnJ^6OLjT?eJ#<3_vl z)c*MDC9n9Q?}N^tR{ak8KN;UE!f5LyTm0!!_TQItdJq0N(Vg4bJcn}rzs^1KdFDV@ z7&bunj;H=XL;uDYS9dI&370^9{<6QG&-3!$DGbv~|8120G{r}GAC`X4%`fjm{qtcN z@GdOn>`$H%Id{%)pE>1Q>4>HNO>E6H0w%KVAa*Nw6t@#QV_;)``&Y1Q9N{wLv3 z&w9xgKP1ZjpMS?aANk*PJfH6qjiA1NzWUMRT>|C%*mUE5|1rV!QIq$m{&}nW@zu-s zs%>w%I+^%>;QKx6JKi($UXky!H_UT+t?!rPsrxyU?{Ocf?{PE8ujhRUT~K=I%koF} z<Et0H^Wl3Tcse`_J_mKZi}?Oq3yKf&Jy?AE%<yjx{spBk%I`4^;XVAG|0dM)So%i| zeMuv~rEh`0KimVa;`foasq?W>?}QKCeXhpuTQ|XapSb-;c#fZjkIr-Z3*cqs6(64C z?|>8Fc4+-QGQI1Umib{@*cIyY^wn1*Pa~DLH|xjYHmK{p!~O)g60VE0ew@nxoss`N z_CJKuht<EYJ~#JI-^csdZ=>#;_A99Pb}`nEHh#}X?)l0&)$y`vjxRwyZ*z2=;oYzg zY=~dtTfF0?&H(DY0E-#@&f@bg;9u}xsQXK+ey+;@w~>D-`^#Y#`p#kW@2ej{o<`H% zIleo?@nfjx?Tzjk_z9d3W7Y4cZZ6*Mg<(-x0#=5)Ub4rRiO~NHKHmiE&UEL|7V3HP zu`jv;{5&fHwSETr@8OG|y8NF)t^bbwOZmHIA1L38bMtr3Lhw(X=Nv|TolnQ>`oF09 z(dx_6XC(c8@@GY#AC`zRz6Nu@3l}o~S8zSt3iW&vKbZItDxcP0&*#4S-cjanj_zjI z4&D=GyuK&n@$nm|=edIY=I~Z1_blG}+sWSvcJr(kRQ&z)q33-M->1Nta4`%@KikN^ zlKs_i1N<vs{VzuTf7w5d@Bb&jQ=#@JUiy4S{*vsU4J*LQ0@hbH@|WSCJC%nQz^kD4 zCtmuCjQrQJ-vBm;cLuD##mL`-{a)}9_)Nh1$Bg_hvi~Z43r-GL|E`h07Wb+iYy!I& z_bp!fn~nT4=yMjF4}UQFkC%R#k$)%qnLl^mqfUosz_a0nP(N?U9$z6s|I_BXxtGDL z3*5RjEV0<F%RoJUTJ<-0=1+C~MV|8prGJ)lw$8m9eU66uykm`jYN5MNW8r&nGSu~a z^<x*g{0reSxB}|@zWS#0*$%cR@6$&9SoL?3w<o;cvtCf~j~erS$$MfMEWN~?$HQ<E zTmkiYNc=+LE266$C;f5cvHH^e<X-CfpZ%@l=E7P3E6IL}WB($KFTzJpck5T+TKFf- zTHJkpCaekT!As9}pSOj>;7FKi{guYQt6>LtH|!6;g?heM*na~~gR|qTe@*3|VdQ^@ z{c&(UwE9nV{d(s632uiMes$#MLEmS6o*6A)vt`bwyI|3;-MS0Bl=n&}sQrpHz9MxR z!RsT`ORK&L`K!a4s$N55K8dTQ;_9%LxTZ$D#9e}3;;v^caW@(95+{92ocJYi*7-ca zxekZFt8;F>+@1F;FeiN!G5UFyzTbo&z}c{%`uU;nORVuyXA$+jhgZ|TuD6@d|AD8V zD-mb?ewDwNk^eaMbHLKD@-eC(#awMyxO=ws8^`@npVw39-hki0O)ysd?JHgVu5d6M z26g_ERyqBt@C;ZEYQ5G~LO1+7m*?gm9jC#<>)m=dJbr^){|DyW<kkh@+Fb7Y*FIR9 z?|BdM{cakpSJdgs^S!PswE8VdpVCh$`WdA9lls3=Kj?ho-~EPv(&r;l`X_$%!ndJt z56p6^^X)Wv18fZMg4*vBqx4(mX@cJ!;Y)BHTmXwP_Zjdt?#(C|>AuLkEsc5g`AL6` zsW0(Y5wG>V&`JN|=N3=>#}V}XsWVX3)BW`0^HkNhrhk1e-e6zP>#LVM<H$D&&VX`H zx*6vYDPH#%Fa1<wetAx|@p(<2lXg&^*Mhtkb$`*uKh1ML31&%9zOR^TE!+TQUOmt1 z6xZwX6TkQ2yPnt5uZ*B?#r?QN-4~s|IiIJh-nzHe^B_NG#8>&g(vzPz5+^_Zv|rK2 zSLXR?1QV674Ch%DUJPYkJx}En*X#3(<ab*2ow*;~q1+ekXGcCyRlWRN>CV0A3FZ5# zp0^91r>b7QUsvJ#^(C+l)bmzkKUMWIS5xL_4Lck2Hex?j_0MoWhd}u~>QQ4}(aG<# zqLbef^?i7gyp!Q>n0vMRy|xOJ_m2Et{15L5`Mo&1`n`D9Plx|re9}(0&cDlXa~Ah| z+)(}=^)+04mfJ5-ir<gnrLX~f10L)1OjPHyKaJ<}CHLj=2>zvaJ-Kg}aPRc_>iHW+ zc|W6_U-I3u&fQbF?>}?j#lNSF`!|q&#=tM(<=?w}dLCbW4)UA|i^DUG{E5=%kFuYR z=<bF0!#Zoz=C{P}`oYDYy2f!E)P9S8FLgy<I?nq3p81nS{{?-23)jF+Q2UuE{Z~=; zlZSgy8TNn^p`3F^<GdyQOcg&u#WxKoUi!O`{FlS4je3dFpBH66)s=4_u>KnA`{S#B zpFZZm`EVK3`4gr8ILdw&@pEJu{0_>`7u|on^lPZ2^UKdg{r&9>zRzj>_>J!UT3vm= zE4tb3$4ftnI#sB15w!A0tDiyMf~x<K{PP=~U-YwxTMzRX{RFMQ5ua~{qv82mod4su zIxd5Ho+{hi=XK$Wd)#_B)cU6AUV;mLbNb4^JIeQYoo9KJ-|w6AJ?a+Y`_!$}y%Ro| z#(q9ba6h~8sml)MQ+KHSwdNbboXMhp)aYjobFPQKK$&0npX&O%ImgG~K=_<-zI{?$ zFLRAzj&X33G4BZWQ&lhTvy%LsqBJ}g>ie8*daLisM*qpCmp(70-)rG*M*r!hzscxl zJo{7NxA5mU=`a4%{XBUNZh^=D<@WXc6n)Qt^)<=g3`)KIQT8YCx1#R=J9*}-jlLoL z3rZi_pJda2!8tC66?VIGy#lu8d)ghw_qBM%FQ&fKyUnQggVE=D`jx-$PUi2s+J7DY zIdR`Wt(X01^Dm|EwQ%m=&d)Va=dZHYeO`E<;|u5{&eH!(T)g!)$Xf?K1f||b5&F~d zvx)x_F7?dU68$}JH1(wq?N74l3;pZPwG@01eg}7EcK_TV6TdI$dEymcT-DnrbydM~ zs?VLQH)e8u%5x?E{6vLkvf?uza6V{#TlOD=ms6(=)Oyj4MSnNCrwzU6mZ2YsZkC~6 z!G5&!ZbN?#es+WZ|6J7o-TrYt^n?$>fl$da#Y_K)k^g1(N5au?O2GQDM*h#(p9>em z9|P8}H1h9ce?L5q=RuxJeO~d>=b(<xKaJmuTW)vvNdE32|9n&Hm!e+*e}LOyQ2HN@ z{JYrS3o|oE0jT?lm;QJo|7q-(fMsB{fc57Z`Kz;k6}%40d24^-rN6=Gry74>xfZsB z@^`s9{9W!bsQU|AKftq}yZAfmy|51)Z2WySUiyAU{-Nv-hi}3u0qe&a`Dd~}2QGxG z1J*A!@^9eZ<EZ(Ed*8`>?)BsN-lQ(v81_GayJ6O>N7hf_^B-UVbXOVr>e*bLaqx!h zZaop+U)-&qgz`P9afu_>zg6XXLgfoO{t2W0^YkJ0&!qqJpfyjt^S!M4lYUM!{Iv9Y zI1hDQGQFbw)^loo?HukL8^GqU`0;MP0$d1N(Pt;4-<`x)>Si!l6*t*ZMAT*8fP~ zo8b%eJ;~@lX#KzRaU%csMVU`<J{5z~*Bqn2^o}n;-$h|H`fdXC`C9rKhF*Lq%jZ*I zhdj=w#qip^Zha#xmCvmQ!QrrENw<IJS&q6tU2mVNw>d&R$=@nM{xfCX+^&yoFc<yj zQ}eW7Jra(BKf$d~&vOEK`$Flj96o4$S#%e`i{Rx@>no?YUgo-vIc|VWjCrqNKUMWI z*KN$v9(Fe7ZNq-5>SeCp%<&ME=Rx1+d-*(7^-t3O1h@pQg8#rAyvNGG%24|ud8QIK z1M0k6+5Z*lI)%w!#Hd@7{i|U^copxdF7SCc6aEDAo#Ec2m%`hj?>xz({|q1JD!+Aq zavrIwmwRd5A3bk+>34DtyVd>H{mK1LRlU3ytmjqFn_l{2ydTbh@*dOu$@?Z%_3~b} z-j9*qcR|N%zpZ-La!&Q2yx(=ay#G^GUz+dX=fMkLb$AEt4g0`>a57v0_rVkR{Ut9v z6%OI&+{bV={1={eru(_r5Uzq*jNeZp^{>w>z4RC1i|!|qzsaKSNB>ViIe*=s+>cb% z%Y9zNoL@n?-+JCJ`8-wik)GE`&tK5-+Hb4giM(G5s`rhKm-kVs>NoTAXeTVf{VM_6 zKzXl>VJ-K12W#<Be(&h$`Ch)4_p<g^=a=_*y!7(-v}yc3O8%bqJ$}gF&z|8P=>B4j zzk@o@!sns%aSnAGz{XJe()~#ME94RVO-BE|ddd4H`6X{#Bfqa+^3Eo|<n3$Z@5;Ho z2Ium3;+4kVi$y2rCc2aPJzD$OhrjE}e+O$Q-y7aBzCYZ<Kga3~`@!d+&L1y*e<T0P z?2m+_;q-v@6OH_{+5ZAAg=+)WFE{evUd(+z>;&(IeW5<Dc<Jvo@;}M`({LCZ6R>`y zk^g=6KZ2jaB?0T_82P_pe;wQc{|;Ec&B#BA_fkdvJIu%P-_er)j@nrMdpGjm>3fI& zF5eva?=O?L5VZa~%+2}do4ZQ6`&#g9$4c-bsPAjC_xC0Kt%AAoGauCR`06F^KJphN zZwXitPBiM>!hR?C5_~hx`gSV+t497V?B4~Y537G){WS8<fS<#n|8eJ{@3;JS!sUMI z^GZ~{%yI57t@&o0=zLlVOBZnKF;M$c_9XZD<*+8K4=>=km;a7+yyK-#bLzE&d5nHv z<MX%S*Kjq|{iRhuO66Z=<R8cWB)A@KkCXm=d}w>JJE!@D9KVNp-lx#L2ET<r!dUhB z_&IYjEDGi4kIwI_uSUL0;Z^WD*amilx?U^(yQov)r~JJ79cq0$bVHT?8}vU19RC@0 z=fcJC2dMjvmwuU%e<r?u0hhv!hTrL>UvBjC6LW2aJ7H$yzek*2`o9eSr|~`N5BM+4 zQrbQD`abyTi;(9`SPni0C&C$U53F3q)t^?@@rHAb+)rBbXCuF!FX(&?nXd`#1ta+p zZNI6WKUP2Ta;|5p`%~4pKcXv*{t9%p;-tTjyq(}+I2`Kxx10Tc;R)RTd{FBfu-^=} zgB=Zh=5p>i$_1BIbL*8*=Wl`TU-(sdr|(<g$j{><blc!M^sNlN=yssL8{NHe(w}y& z>vIZy)W68BJ3&2fE%bHZNaDsqt)Gr=8C(OK82bLq^<@>;N9Xe$`{Dl%`1OTue+Yek zX7u|U`G$*M6<u5&sQcZ>{ua0!9x(JR&vW@&!!Gb1sPhk~<n&8mugY$HGV_*at~pT0 z4>a^+<D_3o{u5O{50ZZ%wCcqg|2_40K=GreF`uPxYUpJy@mtTO{g!h&z<FJQFZaP% z_2)2W3pjwh^Njqy`mcF@eu2B-D^=aSTMVz`xsvDUZR2_BcY%wW1XsZ<<k5a;{iZnU z_ux}D=92f;gGT?)Gv^!XJ+g`WBJYu<Mtnuy!%g7(<e3I%K>c%LJ^R`p$yb?twN(B& z#La_CJoD?kR=-vq-LK@kBEtMS-vVR)c;_o}vAdsRVE;?p`X#968JcAJCG=B|etSZh zL-&6<pC^kxGYwkQ{aZR~Ka4-z0m~<A|M2KcnJk^``|2f5=o_EvdYN08>hpyCI|t-E zH52X6x4iH7z)Y9ApKm3h?xz9!?O<ov$Ix54cMbg??C*yAVV28WU%H>5^}3Jj^ikO8 z$5-EvJpJL*aEOuLS3iP0Z^N;0wvpdgukWv3>+{l|>$R^wz2kMinJ#ztv>03lw?nNj z=&6^yrHJbarH;;@x4P@62y74gLai_8sV|Pc6f6s`fI9yI_6yW-eYJ&MVXXS%<hc^w z1f`D7ukVjuhkECL_QhKJ`la(EI^MTlvgy;?zx1x3Z08a7;~dcULe`-_>FbZ2gV6Up zB+g>2`F!Jj^}6p=i;uP6Sm*bxpV9QO`kT??Gx~ke=O1aE(fkVMbq-kfBH8@Wefstn z#vgv(iT2O8p07TmpRcc9q24*5?~Sz%{W`i|p+CpAKh|>*?S6Paj_vyqp6{`JzWO=$ zJ?~iKed}d3edzDuC$9a_>%-OY|M$(p{LTUGyR1WhQp+DXH=*zONt`g%;(hxK_09n~ zZ_Uu3(4T`2$h`>f!_n`9_;jo=+0I-0>f2v>$NTmh>YW4n++^+RkHlH@&F8DP>dJns z`F!I;y>meP*9`p${W<7>+>7u&g!du54~L!tc`hs-QXc)@NPMV2x=*1$@%2aUoiN$_ zmA-_@)?e7q(eI<2o6y%Ui4%tLhdUs?M9agY4}Gso)_C836Rn@i|Gj0UE8YKnXHD1x z>V8DOhd9yS7-#)j&-~HqvtQxnJRVMg)1aO=X#Hu_Z3Pd&Qw%@PN~8XI&-_;@eSV`K z>AN%fPvJcHCHx9%e<Q_fz0~Py)Je4dIeaNt%iXIgFw50$t@{!EH^hm)7IE>?FO4#P z-kPq@|G)uoAk_W%>g$r{5jf~7S8s}tx#t@54=3(+^o`MtgNxw`BYs+p@t?;jeldBZ z|Bgn#QZFdI<jsqp57Ea^qn~8e@50Y$`wvQA0w2rD{e(@SoU`<)pQl*kD;jm>d69FK z=S9~)*5ZBVjko?+&Lca|lf2jEx!3*&t&jG5v8B`fS~}TJHof#EOt$_qdOxN3p7dpH z_r2f;c-b{a{{AHT+lYGz{t2%pzOl;pFKg|0KNT<aBk8{&PV~P;$nUHFEXw?=RR7Y4 z)ql|XZuBGPvYWL&m*)5-edgx83qkAr|5o|ZTc4LXWWGrKq*Y&uI+DMf@q9@BX!XU( zdloDQC0;)-zWO`JHv&$8pFlbH0>(VYTD<SP@z%@F!L(A}hqUIAxLEV0cf8CY^zFx2 zFLi{e7Vq0{sCN#?d25FLg#H|KK<-6&AHw@^EZ>L5d`~P;$Nhd-99D<={)>JDaUZ~W z#`n!+)9bz$(f1~}4eo${!A#1ZQieZP{`D%~KGx!QqVma{Tc|H{?o@MTG3Jx^qD6gQ zES>C!dgp-np_%Ib#5zw#j}Q9%)7xL)`O>@J^sevgSI~Oxhh7I=KiTr@`Sm*4`VISW z4(M}|b?DF0{Slvpp<hS$E7kpxbGGO^pU#tN@xJ|rdgp*XcUcGRkJPc~TVLl%wRqot zgVv|IpRx8Iw7;pIKURNJJwDaXFX;YL{d{BX-`C$*>t*zKU%x}Wb3or4S%>}{-5>Eu z=<Aon34P;3{n5|I*B?0tp>KRf(~D0+-}xm@nCN)ldZFGqAm^p&>yM7tYu|jK{^;iu ztG}rpAKs6n-;dCr`1+%t7rplNTgU5ltoc$c-nU<0eXRca*7MaTdw;(3gnH+IK37?1 zG=F4ni@ttXd1OD<e5n@i+i$At<(!4dHjnfrOt${Qew+hxKAIWbpSSt<)c450uYRrj zzhgKVmWP)>?N@roTYaCS`mSg6ukV9i>v{F(dY#eq8GZhYcHYT0Z+QO>KN0PRULUSL z^na(Rb+Qii&H?d5GxR6)=b!^}FT(o}-iPo$9C`}mxv+RhdGvcD@uB|cK85~-{v325 zt<Q_ZMN8lN7HwY9C0l;qeth*Zw=mV>eftgd&H*`ZO<#XvjrXk=v_95(!uZ4Qm+yIH zbpL$)()zCa-T6`YKK#)5d-QDfH^2pT-QVNaL7iXp3(>DgvG}^o^@y7DPh(zR{SD-~ z1>OO>L-EzBC-Kdr)JvV)RUMg6pI@@+_4BURx_|w-UI(pDbiJVGi8cS%i(Q7AOB~z4 zzEI~E{iUAzmDI^fTn<<bUJP};9mMT{xzUw{(r@Pk#TSdQex!b7F7ZX?vd+U-ukXKJ zYyb7<dY#eqdVan3^+U(&b(qgNpnZwgI#z$f_`@CWJ(t6y5B(j=H;<){HGiVxed}d3 zy>-sApV9otX!FWBTlDoq=Sg(DZ@r-P+7G?<t*_(t+BaXQcMfPDWu5B&$Q(l7c_dEg z8}F-^I>JQ9>v}b>bASKq2=9W=LQCIF=^r)p6WL!5FS*{;s}4uQv9M5m_jwVh>(7jH zzS8wvy@jwnbtf40_oK_i=h>k2t^19aKA+LgTK0Ftf;YH%PK7-ixb*<2`&%Dl{OQ!0 z2?sZJ^;SY%uOfY12y4I_jsD`Lzt+ev&!I)#zonD?SoPU%bpDlxwP16o^CwDQK=soo zLO(hAJU5Isz8m_U@G*F46X#1~*cAQ+_d@MYn9upP0w43>Q!!Wtrq$nH$-5ICP<1M* zI{JKKjn{o|qMqCfT~GAY(ba@<uOh|Ey=zX~U^ooQJ<QzH`L65Vtl~zpo&(cMe;f6s zpHGZ_&SS2Yup@lPm^V@S>Z+f6BlJ^+&#S>`<K;bXQJ<fsll@fJ%N#=Ac_dDlYVp4P zhI;3KoVPE1{fm@8z4Q6j4_dGN@~xNA<9+=K_09o(Z)Bb7{>U5_edp785*?rDdg(oH zto42U3iZwb?Ypdl_DAXned|e_Fwyb8^+LUKK+a1u^e6P^paXI*g1!$@$D(h2ohQ-p ziLRI4^Tt}=*RNRhpYivve_`%s?(deBq0T=$$@KF)`$?<*7v)b0!ym~Xt$r1G*TA2k z#B2Y3_4+>Qwa%|U*XvO49MHbVI`k*>=b!`OeK`6(2>l8D`QPUxybs}h2=9Zt1ONNK z@?2Q_U+t0n({Z8RIiP)!b?8s%&p`*m`*8GokXC;rPUxx}`d`_%ct{yce?jNhbNSXw z^?2WTL%nlApS!F>e?or_IuPE6qu+zjpN!#;oU_nPedvE>KUyA&jLtuuH_`FF^@7%? znjh)iZ&?5E=Pc3pGgkkD?l;-;C%a#<_LtuA$#&kp{lw~@Z@p0O9MHbYI`rq*_D9ZH z=zHE0Crq_?-+n{Ab3o2pGxR6E{>18U7=QSA_}<T0{qwDNtm$j;?>*LqjbU@+--q<o z>+{j;W6e)JpI&FQd1IYF*7#)eJJxw(jZd^6!+DSV1{*ea|33OH@Co=P)cuW!F@6T| zi(sUBv(SAJrG6Q@)lko;=Mf)HR6ab;`fWJL@I&JNqTW83-N<Lvx8kGKXEFLK&VFfF z4%RaCo7lgog}WES;7q9d`PoySgFJ=cn-TKo=JOMy)Srg#EGYd;9o>H$bRFQG@Nua1 z`gzyuQ12YjzQ{VG`6F`+Gur&&yzzY=<Q@q_f8*<KM)Ondkucfjm%fCF?(cWL2mB4Q zw{+i&PK4E4x%F*O_ZKNXT76#XX}$DOUiI;k(T}gbI(4ss50Q76k^e??kHc4Qa{i2m zy8rFyp6B!Va5EHNrEawGYdzz4(8oo@T>+nj&p}<kIQwPb)$l$j^GH8I$9Imgex!b7 zF7YMO`S|KTrT@9`Us%w%Z<aorp&!6G4}#CZp-`XCGlp)sp_lhmwAA$?#RaX8cm1IA z1?@+&<=1{DTYtXzwH?;IB&679cly-<JndC9p6Q{5k#L+Cq?#0h=llT9yk2$QY9 zupj4uoR4PE{=`}@z2klTNwt1`=kwLa>W6Q=jHcKA>b0*Q=^gLeZ>V<;=yQ{`uRjte zOttt}`<1zc>7CEFe$aaHMd({k;)K5Oq24(l{%MB(g#H|KK<<U_eULa|qT_w*1+5n! zgueA8PUssStNt_oIYHr@`R97A9WQ}8{~S;Kdh|PCi3s^OquU;(emA<Ts(-1Y`!9)Z z5xks!?tl-$$DxkzW5l;I^n;U3|D0z(Y1L0r{x&lFk^Ir>N0IkkI0;I;J}+PWI`VCS z+u(6V|MJ{g)csgG+0STtncJeTA39H><8{4Pxi{~?iEs++*2cYWUx2>xvFfFdD%7tB zr7xXd^yhl&r!ns?xEq!x&pA-nTZe87{2QLC>bFc#d_L-=wZ8ak^(%SB7tvYg;j7or zN2IkrkD&F-@i*Ho?zuPxc7(bgOJ5#+iwN;g@%f*(x_a5$Iz9q*y?LJcuRZlYqW>+* zezu}7sPv_b{zbo=IGMMAp%<Ox7oC+qt@?cQA8r1i^jFZw3$QxA+-&%BLz3y6c=nT4 zeQ)JYW5XZGAFaLvc{{_NP~!FT=&P4=T}EEH$Cn!Yr&T{b%KW3yX?;1PpP=<Yzu&|B z?gonw`aa9P#f+|>$a7KrHurP744evm{n0+BT70VY8>`>G^M-oofc9P1zWzv@Fr&r$ z&Kv5T19D$9ef`n#k=Ch}Ki>TwYx#WV3H8na>pAiDN9Rekc;9|Qy>mdHyR4JVAL&cz z+n>Y<6CLkcFVs5+<h(R}{mJO@zJ7)J#NNM8`8&sAn7N(%J4jYo1y+Une0C7G2Of{E z6l@4vCn&y1jP)b+D|3l2GFJ~{K3{zw@+^WY;YK6B=!f$8bU4S*%YL-^ef5%eDfRcl zzu|)R?tU$X`aa2=64wKr#GT&3#lHr1`~;<Mj&4Yt^jU6q^=ndRCEN*hKPRDY4hO;! z@B=sl>iEv=cZUx_$up6)<cW9uJo0}BW!|5Sc||`T{bJAfUFh?Xzc>`XrLN_7ddEw@ zm(h2mekXD-|AE;%y8BfW>hl!+JoLZ7T~O;~Kid4hddZuKek;NAjs9h>3VdGu4mWRK zcz!3hZVB}~$rj%r#{PZdEqxusFJFCI=D8d8R`coe@YP?;xwnL`!uR2ya4)Px{R^P3 zAMboOQa4`xNxtT3oUc7`;?vhEPkww6pC-uKxDS%A2YH@W`L(|VB_I3+o@M0s)z2i) z33s~ZzA&r`bw7)fOux*tpS0@#qK^1;uHld5k5<2tyg$PoP~x@!zWSN;c|vE-7gmKj z|KcRmFZ1jtt@^*HQy5>)HT;qM(dsvn_h+~RO1$>pSFiuRq1QUU{#>s^y>meOBI{)H zNBR=__9t<|j27=ZZ_s)<2Vv0l!u-ww@mn)ie_Hc%<TseJi~BiT0QP_bpspwJor!-R zeh9b1?NG;$Wd9vF9exXSKS9SYim`sAeq}E4C6d3s`ple@^iha)8#oZY3$>r6l1yLL zv!Ar;ucwaq^Sa@W<d0T=33+P3+EC)P|GxTV<U0WKbal^fNvQKDtA2y(zet4sSE64H zqm93Tyf4E^aIsOZb&~1ZdiIl6eShkRKXVO#B!9H}p5(b7J_03P-&bF~{`u&;*7bek zwca;hsCN!%A7!2D{>U6c-+3fXnCN)ldZFGqAm^nS`V;zd&;hv@zV|`mgud~qu9vxm zsXkBGzjHv&Q#14@^yi=haxZ-EgT$pOGuphdo>NBiE1cIk5bM23miS}+JdgGH;(d=2 z?boqhFW%>)^Cj9pU0<)0tsmW=UWffU2edEoTKoDNv|i8UTQAw-bw82TvCbPQzy3U| z=N!<!SnGKE74Ljj->JGE`jfu*Gga?Rw0(#7%kO?^Uqk<n?qBFn=+8k1^mAja!~1gh zeL2?r2<JKce68moz4nvsd}8e<(eb|ZLcMdqy6-{zqwD(COYeB!enY);K%bkeLw`bl z4muFthoj$v(4Wws|9wu9^*%^nLU(G1{#W)b9#Xphm!*?^U%kXxOtyTn_LJy%-+HO8 z*Y_yZ=L!3F4(M~0b?8s%&p`*0^*%^nLDBdA2i1q<4f}Bph##7%?vHQ($)=C@dHBv3 zYkl8($)=BW{)`@<Z0G6QPk4TZJEr~6>%-NDzUOG2tbO$oCyX^-@>q;Df1=}k>-p*} zpJYGQe5n@i+i$3M4#<7c4E+iHIp~1gi=gj=)UoJW-^wHVzWI_(FLPM*?bpg9`@Z=? zy>meP(+vFy{W<7>+>7u&g!du54~L!tc`hs-QXc)@NPMV2x=%s-Bj+IWttWB9M90Tk zPx==6<_lUceF=lE7v^^kh~Jv2?vI{FuYKp!@p|o>&sVSO>9udZQ12YjKFT`uC-mo_ z1L1u*`aKB!3H|xs=Onxj;e812gS!L&`@iyBSo~k@k^HmbWZySFqv^#bVMd!@&%2%f z|0_=F=KlX(c^bYAb9Q(87eF0<JUWRNeaUpv>;9z=tAAg;+?!~r{fahDbcv2nwR+-{ z(6|3k?;H^SG?UGrSo@1LKH2;T`#JjkjrF`^jStV~=;ssq6Z&(|0eQ~C`*8I8AU+9G z-7lF#nCkO{{Rex0<(>$W&2Q;T=-Z#f2~#cJx8G3j9FX(Y4BDSq>%|)HJD;wn*S`6J z)<^2^N&Zf@5$=Pz?s9*3YYmq{-S40n;};VDl~G^U`%cx1)ZZ^g-WJ9@siHs4=>I(S zFMyZAE90bZdAGY4li>om8lKm~ef|d2=XZ0A@vjj7I@I-by)mj@r2alO@|H8^NfrHe z=F<LTVXho7FDzip>#NuAAHCN7=+E^!)H?^XFS1THf21#A*x%s}h%ag7;n@!T9mC3( zY<jCt*-y59!+x9taz2`&KcPPd9guqw-iPo$g!kdlQy|ZU#Y4)Y-y4Y!^+)$9^e6P^ zpaY3|UZjrD_x?$oFwyb8^^#35z6pK%lQ?0b<9+Ledgp+gmu5!yXLwKd_t>{!qkG)C z3)KEBLAMtcM0dHN-{7h5N}fOAntNS8neKC33pc<%z1)63sQc|tp0RPt_YZmI(bv=W zyZWy~U0?K>(BBA~!O8F=sN;*XUk7%D??lj7Q2K`==+9F69&yr_C6Dyei?!8H6+V}F z`>}otYJWs0zKSp6YozmuHNGKzN&WX&OMTsMvgzd>&!_L9JXbG4-M>7CL->3yTn(+~ zvIWmaPxz$qyh#2F$#)+d0Hdw<Jnw^r@LS{kAoa4V{#&A#_sRexUgix-FMSm>=8rUA z3*uVCG0ZU$?w7eZkBeb-<9s@k=Wh53@pE7<;&Q_}ur7>r{;8h7Zg2PV;0D+S4u<-9 z^3_Y;8_Cxiwl(s<%>J1VxV|>Rk`KDI?nm^W61NJjh6RW(2zC4jbRVQ>yv%u`nzJzL zNdEo6+!7y2|Es5dN5J|r%vlLu0I!DSxHlIY_b1l)4%E39N}W1JJzu^4{;${iKI_l* zI#zu<=IRJ<>*Jow4p8U!)i-*`<?8{@Aa64xzpuWzXMSJ(arAj2{P|%w&mO4#@zwVt zZ(sNrd;&_H14g}A<5y8<1I$UC>PEd})Bj4}yWu|g53KNrJFg3%KCf8gufnJ6VP5JK zHR=Vef0sT!g3^chpy&71f5BX9;mLiSzm?#9@IjcnpZok=_#oU1bw84SG5OCi;x`-d zLF=V2nP28R#pq`tJ}iS*KkEFr4z7T!VY|oN=bhmG$K5(le@E?Cs^?#cFRS1U_|OQh zh3jEge7Os1KX$NR9N#*^Q7~5he$V{A`qK1S9-hv*pJkkX(E97>qal=gSitBfXubaa zqu2U;_2+sW>YW4H7g>k?9Ni!BN$BgB#0fK6yzjiB-Z>!mMKkm#^yi=haxcRB5Z;II zJ{)=q<hihTNO|;oBk{g^iL;n&`C{$IH$G^+_C4r&VSeX;_FdMYKcPPd9XM9+!@?)s z-|g;v%CY!B$MR6$f6?cNQZK$))cGx)?5Db3<`DYMBXPn+$NSdHXnHvpi@ttXd1ODm z^ZC{f_09n~Kh2>1iM3vO#|Q0Cs^?Gd^GWaeseXQ8|IPt@k7OPC6Z&(|f$%;Y{T_t= zg#P^Ra}wT%#N3BkgWTUwo`e(OH_&x)=zo(<-^jE7wCe9w{(NruBl)A%w<FITusf9a zL(aSZm#;qiV0XUP!me;A)cKQ5U%<2fwCbxVe;zgbk^Ir>OOfXsSP4qJ_TN`8?@5a~ zzonD?Q12WNKQu#sLVpfAAon7?4;kw|OyT`K3$BD4p}r5ITcmXV7<#!^7Il70XYFUS zc;9(__1b6O_)za0&_2pKXn&-RFz9+g=a)HzLD%!mFMSDp<F&rl)9&}1iEsh@8ftwT z_TTW-cS8RRd=={aqU*18(bkjrE-L;tqh25OrCy}@#iyyniBD^c{Blkf_54>o<IbZt ztP2~#SoOD)C+l;r&gdbIGvGZhxOL{Cj%9~AUJeJp=++~l?x*;(?(?(Y74T}P^;6kj z2NzR+CDi(FJoPfqX!7ZKbpGejMXMK|a^Y76e0kjPr@Hc8e7zcf$HC8G0rHehaK75~ z`6L_)N5GX(_pAMsd4tL~hCUX;NcEFVKPy82mj5zGB>%1WH=;bh^o}pid+BmmAGU=0 zyo1)Cr}}9ap`Uhq-UIf6^4`_`2d%%CbC+`+&RU*p-H*JNdh$Nn%X=v2OYS|d^*fmF zdfuZF_n>;OWij4o@rvI=AJv|Beb$6^VP7ck+3)DjnkT4yP3hx47^!};>AOVe-|}DP zh~&Q&Uq8z8OYiul^!b~dFV96zsLwlS{g0}j<0ABPBA=IlrJy|Dy8oc{rRiVJ^%~al zT<d=1y(2#-*Yn=_-FW|0<9pnt@Cw)f>iqH2*ERAtVZSA81G@#Rzr)CH{T?Ix+8^1s z80wt^$ErViuJF85`@Bakas9s!FIei<H$Z*9?|SN&p|7a&-fQH~!oIJ*kjj6nkze26 zNNYWRKk^QSL*OTAtf%w)_VXFv+jqlLUUuJ)t3aJUQTo~R^95WCbw9HI6`!ww-x~Vg z*pGHzUq3^=J0bBwpO@@g4E2ZmXZd99`}$|)k^N&WpYJ@rdhtz|=y>0HLF>hbXzANe zw0TA6n?KY$2gE<k(4WwsgAT~ONcH<5b6E79&&nhF$67w$c`}+_&fTJ~A66dOPw#xb z^?mg+r^PUzbHMT^(!Q^Mq5kN8hyH~A9CSdQyHvjqGKVned8Cfex1PiaGg`dwyrJGX zAooQx^e6P^paXI*5`7=)edQ|dg}Ilx^{Mbm*b3_YJ|u1?6n#TOFLko=xzwqm>U4+@ z{}1&f{&W?8ixDqzQeWbvzQkGe(>q@7iA8-rmQMCVy>meP@TISRk@BZ^KHvJj`edI! zqxI)|excquVBM2s^GElYZ2g7(q}F{(^m$F=-y`}3zBJtZ`$Zo^-A`Ke^Hu(_Mt;#r zKcchxNvnQ6{Y0BTD1B{w7@&M#V)&C*{moJ4zY(3*&ocT6TA%L~cOOT;>NpKH9pTpc zex8iJ7c7hJT0>tk$@JAd`$?<*cI8hE!ym~Xt-djNo5MCx;`Mp?>Q8#jo%`wV4_Nzk zx8DLj4RyWq*bhp7rOMwmLO)l%;reb4d%=EC_wTE3PoD1ZDLBZ;ufNYkTI>EI>GkKS z7Vq0{sCN$NbC-3{{zx66Z#{_<hVh3xAihM)!=n%VUDk>Z_0ECNAAJ*!?u+=Pqh#M= z(0Z$`?EBW2IE!IE=YZu;r2Wvp#QJxv`F*U-qo0>p=ktyC)yKPEoiE<&Sm%p(KRRF7 zpL0O_674$lFR}jl`W@<zem=4K^VOT~?_Cu~IbH&<f&<`-P}hq!eh2kSsd__<dIi{z zRxdi4Px4yxh)(;^fw~g+s?p#1>`Qzd*7aZ`DEYLXlJ^aCqv3X#=`D9o`Jj&f*i-*G z`Xz9yj#mZpQ+G1_6lQtb^`+#QeDybY<`;b@)z43?bw8un9|J}AbBgFo;`0x1D=hlX zk^Qe`=)WB8^n0Kc|FjW5mAEX_jTApd^_!1)eLfY*cNts?zlMp{x1ero*cJAGz2Jke z4}1dZej~+eeYD?WMCTiy>Ux=5nCkO{{W}NbJT)_#KN)@gSkL>Gciqpq3GlQrZha-x z`MW2X{$9_1(yAY>{5j9?NAgFjA3)y0@C7LG+J9etn{n<u$HB>P8Pxf^CYipcXFqAx zzeFAJXTIT&<d0V0pF9KM5Ge85e_#E><K6i#f-B%osPjLaWcn98`$?;Q8g;~<t%g66 zKU)20@{EHYK#AA>`|9=2H@(*R_2+sW>YW4H7g>k?g#H|KAg%X7;)K5UN#caQ@uA*1 zApU8F{)GM<bU^M!cpt+1aJ2hSe}emd-3p%ao?BOe`u_ZZZZG^7=A7u_wEoW&*IRQI zGUmOA{afID@Hr^Hw!q&h@MFX8#tF`s)_(fXr#^qHe@j1sJm0~Mlia<^V)!HakClEW zak?MTNq*5;`O~UjPCwD+4@&<VeUw)|%5$#$Nvl3rl==UmAFa=6oNv(j%Jf|q-VFyp zc~0Lo`nx<q@pn-FHR#*V{q(8N+v?xa-$@?v=@r&fjQp$LchB!SxEXGTx*uQtzR50s z<_{gS!S+z+f1Uk#a3$OlK|du*ec>stkH_F}I0ou|L|=^0&w$a!i@qmuk?KuH_YK?x z_dwmB=$A&R&oR}_UkUyW^G<X7I{&sAZvQv97asS?k@fPu)}qdD>103A`UNxHT;IZ< z;PB7f{zzD1wp(8b`+k08Kjwew_D`JeSRPh|)nOy3=Z!V~%@r==r*JV`4RyU)?0>0r z>*J)CbB&g|zi8t`7i+xavFMvW+4Xa|hqo<s_w_!QdC`&Yx3B(J^6!IL7P!0@!H)1@ zcpded!%yJ~sQpZ@{DoEj_pnZDzuAw`eBzUww?1Eeo<Zx&;d8Y8RPxjhK>q@id%M-R zzd`Gl(#H;%nLdt(gW$_Xf3e1|SM{@c*59JyBlRnDokSh+-FlxTn_l`pgZ|Hk^4#d> zC20Kt_1<p5dB}TP_hbFsl>MOfQb*`pPvV4$j`yt>>YW2}UYemlsqIe*zK7O_ZDD&j z01krsyc@HBGnBYqDsBYp_uyAh=lhQRHSi}`d9nLmdpW!oMjQVpc}fsh-iQ}nVWo?< zzQpgLp42(dsF$C8sTXNJ{ru^*_CtTJ*P-4ypnZ{b=uha+K?lP7aP)hSQT>s*h0diz z|10~^@=#=Se(Su6j`yt>>W_Y|8O@*czQ1Ap!|$W-{Y!QKeCG{XpWc4@&Zqm;>-5g& zTR++K@%GbqzF6z~)(iE{0qwi2ef^O*i|L)uw|=7a@ACJVRj|-f_jjl=Q1_Eo{cO+t z(dxI7cL%(3iR-@=)cuS8SEaw&&<|sODqIYIj-dZQ>DL;1>)y(~?qBvT`s#I_REziR zH`(;b?tg`^-1AfgJ_cWgvHH1^JpWnd>YNELfY-v7P}hq!z9@Nh-HTP-Hb(vK?7t2_ zh6~^ya6i=jA8YZx^Tu1RpC`T6{_D>pt;6`k9f-GIhi5<ZcWJ9ms_XS!zVn3f&N1=9 z*FRsq)Dil|hkECL_@^2A6Z&(|0l639eK@x7gPgNP-}ATf$i8pBRM*Sg7JcW_c@iD( zTQAl1>FsxV*H8BIEAX}ZyTu*wZ&+x#+t>Y<^3+#MqrMVxRpF&j_j9vnetjSGTIbiF z>vgDi4rpIw9r_dcbI^hCJ{<iXWK@4-ZlQDO(ErN5#Y4)_--8ZlpF)44yBFe{uU`@; zOtpC5enY);K+an;^e4IeX~XX^!{I3Sf${r|=m$lq*XQrM4*I@C>c_W!yz}|iPd2^w z!?!;juh+i$eD%7XUZ;0H-}=d>kL2eAE8O2%9)(ZAAyCg#{u`(N5T5<5TUUeq;RvYX zt+*bBUiYupI=}v0uaixm?ENL1Um2~RSno%A$7i(j3g>kW=zAyYWb;S*68iQhaYEnt zQ12WN|1?8?GL}EH_#QY9?t)oY9r>RJF5&a#@MLsX#7X}>d4GhGw~LYASN|$`X2Cgd zoss{2_NOZSazkJ3JLlWOa5$U|_45_9zJ_N%Y1QAR=AC5BEBT|<HzZF}cr%oE?WeE) zw$<*u9)y2<@7CFVIP(2}3f(9ux<ZD29J)N@6<yId>vMYM4_d#IxuczTLqK}{^G&by z{n4N6b*Og^XkTO<t3S{4T)YGetZ~m_8L0CItsg}nW8efh9nOT`L*1XHTaSJd%*A}? z!Rp4m;&Zgr{X~jOw7xZS4uB(Ik4^5}cl_d5e4FF>us&P}_rRLlovtm^^E^!czVL1M z4%B+-N9$Sy)ZZ5RIBTt&qdYtxegNk|ng2WH*Zn7Zz7ot~&8z3})n{Ahe9Q&&!qcJ7 zA1{4jBY#Qu&xU2;B?0TJ82M|kUkhFfTLr9dXyo6>{>4AKbCc(P5AT8e+;e#!=<}2K za%qg;L;Z{%Uo=Ml(kou>&13Yh?~T4MqQ56f{gvoaUEkhw-k|iW=;JT=FD%c`SN-$; zXZ7=5pQn{Ca~ks<x8A*nw!uB{xD9S!*O&b?*CTIQ<If|0+(y^mCivh_NACAR^sQhQ zI2h(6J}=bsO5E)#ZYb*!@GUqVPKGn!9JmmE4OheUa4Y;B?uD6Bv_J7pd`~am<ec^S zhW)wcCepo2RsVYP+&l?ihw}c=_d(uExp<$R0_A<J_40e&P=2qG-|Ob{eeQcG-}B^q zoqq4n;k}=e-|NnYUEq7h?|V{jM1tx)iXVxtS7)=kr}BI8^TzLk(%)A4Y>n>jIP1Uh z%pa{@`aWLGD|6`kmu&ix^gSD{`PrS@U0WUX^Y9+$BKKeJ``z64cO%??UGGZjNIjij z`?sC`{(!o_MC)&&k1v#OLz!zI%*yjF?~6jl`yt->deGM!s=q<>rTuEN#hv>W_zk+v zP`?k4)%Zom{Qr-=Gmo=+ZvX$OXi*p{6~$OWwkEo>Ybd0`AY0TuQnDmNvXp9Cs1yw) zmDJoVgfKT*vNgA4O^p<7YNTX0qR^t>IdeU)hwog!c{}Gb=bV{yn$P^<>3w}(*ZO{c zKIhELscgT!&_$|WX674ip1KeFv46S`n;rYNtLS$!r%3zts{h`^|IRT_oqH?he=5}b z)SicA*X!%RH@qJFkGbe`!1fz&{YTVM0GC6p?}IS)#mj#kb%e`*2G9LA@Iv@+Xy@tc z<@M)E$9#HX?*;q8`+a@!QF6^^m}5SF@;;>IPcru-;nC2Z&oi;NgBQZfVW*!Z&K1!5 z*F$#zJQ-@-Cs;oRt^e#IiQnWG;c;*bwEFkZ*Nag9CHh~X#=pxE{||IKU{!RQ&(;$w zeH}+VH*S)-42AE)&!DX*-ui(a>q)fV2mAHNiP1UO^P_ebeSOLKx#pyHJFi;5%Kd!U zW??$)w?)=2eY4->`eW#SfmWYE{4TH;To1$PKMbSq&-Dl3Bk(0?<7?dusbA}^?dbP1 zbn({bntG~-sV81~jjR1?9j^JP?f`Rsx;f56S@p}A&kwMs$=5zizC`ig5oP^)f4cfz zPyCH=KjzZNF&~|y>NKuv|GesNAnyct73Vq=-UeOI8+~p?N_)RY>ZiJ7^Y>b>ua^nv zep}l4%;S6>_Pe~^Wy0Qnl>YkYRd4g#wXMfqw`*VTZGQ){k2B%Z@Lk9Lj>kUP=wEZ_ zmtwE>r<|9X@Gxli>o@dUq3Rnt^mkw%15>t1o<pFGze?k572Q^-elGnl_^H0CBmOAj zEr5@sdo#xR7fk#Y9r354n*nD-^|$?c)o&s1G23OHqu_LC<L^M<$mkz)=xboF15=>- z+xTAfi-~v04ype{cq+UB_J=m#GW`F5$*TX(WBu{c+vj<>wcU?!dVAfgzps}G*g5Lj zpU<v6AKhoA*Zo#MrSD&I0y>wnvShUX|L+U5aeci^z|KY2{(SuTgeH)v=RxaIdOfe| zrz~%OulW*9uX9s+txx@w$>#61USBU0(EScauk*6;y!!k4f8L*DpN~BscI~x4>u=Xy z<HcJaZGFDK?2yhO-uvapFF9|WyV9S}u00>!XQjX2{(grhpyweRll{Ed{=D{6(f(fR zt?c^qcFOPJ*1+v>ufXnhG{x(yxPE(tdV3!1+9t8r?b_;_P-jQj8Fq2he^eRu?IMhS zGrA%0XV|Jr>GRCMektq?2Rihfv0n?Hh6`e(*Sxcc_c2`Wh~K4}^fef+-c8oOL%Uz9 zyC1#kQg$zWKB^yP^jjVAHSR;`C&2m8)}!_hx&8^<;n2?^?-JOAx=(i0ueufJRoB*| z{xpaFuVr-fnQ&iN588gc>i<Wa`EUtb>WJ@Ef6(Vr;lc2D*b>_Mz3MgY;U@0Mj`%lY zzY|V}vmE*z*muHxmrKR<psnAlUgPdYyauqbBffoJ+O@66UbpLH*Y9fm*!_5w=fdmo zvFh?1odT_XHM&i3KDyr=`kFN)-hFUsO<7-2OE|KQ@cTW5zru_6mi36b!r9Q)qx#MG zUB8#;Z-Q3eko^BMb&RH-Dez@jV-JZ}588Oo66X~YuX}|4I)_O01Bp8n+Inq$+UEz< zr+tpYU;BKEwf5QA(eH5V@55#ATR4q<dm7q$qV=C(@_*$qzxq$cPyIKtw)N(leBt`* zSX<7^C9oUp4sHDRnA0No1zhWxU;lk1{t);O91CsyohhQP#`W58ABVmQ_DJ>V=-a^z zcnP%iyvlRnefTSL*_Y?Q0k9Q(m^tX&BaOFPg#N0lZSpr|ZS$#4>s6iBYxM{4Ts#V% z46krJFRlJ;bnW2<3GP3L`i8;LP+wQ<d}5`~A&-rJcRe}(!{CeXHE8v!d&21Eh0zZ; z`Zpc=&#|wA4eCpM2SQtq>Z%*vp<(nJh_7)EcIZ#Seh%yd2RQVqyUyr_gwda8^w|#m z<Jg~obsNZh8bdpu?EU2WNcbpx3|jqD*k6G2;UBOWd5(AFbNPQ7p}*=@qW=p12yMMC zoz`phL#cZN91X|9M`0eE0~f##;0hQn{*&l5p4Hp@HlNjNeHu4hJ<S`+{@(^4hcls# zulkd@ehs|Yp;z4%Mi*&5^*_z{XF2j^VAp)%`mx`i*tPB7UbpLH*Ozxc(dLWRKiT)o zuU{r$&w;MJ&PV-}Uj2Q2Z1=;?v(HMgEP#_&$@)EL^#jn|XY{W)^s3YNs&mCx{Z!)n z`jR`4X!Ftg+QpL9hyT5^ua^n<^DKQ1iGDuLY9#Of-+&9?;Qht!wSIdJy!t1*-u7?T z$=;t|zf8dHtFHa|B-ea&-;{~Ae_EG|@vhgESMBl6U)kd8TwRR!JY0Fz9`F2qe3^jG z+tQzpKcCP9^j!GoA-T`PpM0M+w~2hewHU62c7Ib25Z!n1!p5?`+o6Bjqy8(0{wng= zdb(r39^MFVap*^59|I@BsSf=y^wk`m0^2(J)%(IlTfa-EcB?<-K$&+Nm;q<OdGIs% zJq#Qqem34juKy=adhMgEwDpFI6Ro~Jb2<&ShgZOPa2d4uV(srWUpT$?b(ZPte%7nt zCP#m&8^iUn@KN|I)H>{ZD%!tks@w-14&}LZm~a%d^&W>VQS?olO1&2xCA<uFg$Eud z_B8k~oCs}y`A3$F=heS4d9|Lh`v1#OzpYpE*uDqiAFW>JcrEd6g0A?n()V%HpND<v zF|to1juk!t>#(nO?rpJO1c$>J@EK_5rTOX|EqQGGaQ-W)H(LK+iDUEIdheyqsZh^- zOGkf?c+}Tt?wL^I+WB7L$fy3tIs9!unr9;VtB8B8BmO{ik?LRK+`I<o!_T0tCsz88 z9P!s+{|at|TjQ+%*%7~Kb2;}5VY4(@pAPMO+Le?3G4ebK^G$s%!qit${;s?_U#;6U zU)AkPf6uj${rDK#{YW(ZO7<zz`pc@{Ngkcge8+q=ex&*zi2Dot6RN+RzgNBP`#koy zE_EO3s9*K3MW}xc-HQ?G-$C~&)H<%Gp3(3bM}51he+x&yYL9e2Wz}D5=Kr5C^+c*~ zL!5T-La6@se0$aJBwnrK<+*hzY!3ei7ebq_8g`d|wEDWl*Sbz-ZR`31`$qUDwE4ru z3+La4xHBTmS62Pi9^)s9zR3x4jt+<C!VYjKd;r@0X^q|G7peYEkMU!r&m`})uqV9H zQIF2y)O49!i(7?{-zF@ApZ1aUZ?HyxSwDA=Fl~Tv1#CJ{)+6C7(9Z7>>Y4<nzz<+J z{cB<L8fOW*-hHI50no;exBhqP7;uu*asA1{1J4k;=5OncbU(t)|KOI)BSGr9jC#Ik zRdPOkPmy)TslqC!3*$Af2OZ~C_siCE9d)_tX=Kh_r2A*jr{-^B=Arqc)n{=YBaL5P z`n##?P53d?^Wf^=<){7GdBsY90Q(az{wMVDJGA=2*tPGn>VI&=*Euw!-WKp;NBu5+ zx<jvVuHyPlQ12hx@5#LWw1(%xp3v&mZeOobVsyXVOy03jUpMsr-N5T#4PN(befLsF zqUay>SWj8?uaigTvz0m7`Dpw|^-mG^IrtJ(e;ePc{u%c9B;NPj*H>O=MnW53^}pd4 zss0s@`sX6lccyN=AN2j%%Z~Y1Hhs$NvY%JNf5V>8?ys+xdAa7}n&TeaFZ;t2;Hj_; zY<8!_Zw^1WTh@!A-H-ClcL(QU1oT>OqWIqzW&QV*(SIR+k)8*;-<928=hh(1ePmyE zmZG=wblr!s@{cs%g^v2F+#&aWC)gQwgEqdemwCD7<C^1cJa6}c`$0S3X#MB1Z;|Fp zcD<|5Bbcwg&VB2cceMU%?vnGc5$gNCHIDax-=Uku>+N&!WykBUSN&DQi8Ow)>s@`m z#~k#1%}xDepZdcmpuPWM9q(B3M4CU@_4@N`{dquj&U+JR=bfnf&3s?C18P66`lHp? z;QMMD|4Yu#cW@Kb-v`7?znwfb{^PCWKAHxfhx+s5c<J9DkBz?;`-BsvF8w+6{`|b! z>QBdh7HkiP$4Ia7x)Se(F!8OvH~K#Ct_1NPLLGLVW3Z2dli~Am*3WRn*WdGuI!Vrh z{+{P^e&1v3pW9k=HTiv9Q>ee6tIO{t^!IDl|0n#nL-jv_I99*Y<WrsIv-%n*OMO?u zEd!|6@%xf?<b4l*3U9ng{PK97{RH*rr0aP8=yOGXj&&;eX2Ue{-U8>rHE;`jW{~8w z{kZC@cc$nU@O#ds(E4|D^cSiBW%y5rPr%oq&F5AB7IAd`;rdB5eN*<~Z20DRvM(RN zh485MVz=kV&QIf|g^AZ-7m4SZSET*L%YPaBX7@+!k=D1CIEkYF-D5rR)}LtZADxrl zFLwU+K0A&3pw$&}e`UgnH^|yPzmMfPX`eIp`Q4A__p~t2^Kj2^SH06NmHO&Zr`G!k zuQO|5CiUJ0UvSjF75nLYAKeA^fe*q+`|03#J#zJPUy}B7xp~g&dHSJKa_&#pU96vV z^s@mT*hcoH8O&}c>rt=|&$oflK0j={!%e&qCSLz?j@Rfc>F03R47Px_AD8~v80lSg zoa%_L_K&%~5A)T1YsvaK_&eOUt@LgCdzLu!p!K(U)y+p=jkq-&@xAK5B<^>xIdM;S z#QzbU&Y?ZJehz)#vt<tFpCh!d54PV84*h6eSEAMLK^>=<db$z67j)%|)_*_pHZ}P> zJNk3!PjcwBFP*pT%g#@AThC>GcwY2_kHKZo`ag%?Pf+!F4*gqk)_+T0eQw(K2e$r| z=DzLOQRXlfTKz-k$#s37-m8PG)o(n0uUsN_ukU}tz2DLIXAOBj(+0ZU-y~bTPnr3S zVZIZf-4CyN-LF9=?sV33VLiwGui*Mx_!q1hWBnH<epN^Ob?Ck}b-3#Hs&7GFd%j=C zZr_jF{fU?V)F|^u>i_fwav$fzcVGd$(0qSl`;XRN^Q<J_M%e2@smtcu8+(1&8lD?t zeO(j(Y)AY9upb03fLF#y|0i+gWXL?O<hgq-wDVbm?pJukMdH^IMynrB-pOzV)Yk(W z->ZHj@!IqKoc^42Bi}D~=I5{a^I4lu{nPMo4PEi9|8L}vm%q)o8}-$K_2J>r)^Gj$ zp<4rWPWtl&{dxAknA^GVLg<P&pLm~!iEsUfqmP%r&G#tzCc{~9F0}Pq|F--*>O6Q6 z><;6lztR!^ZtVBMiSU~w(dSX;OYlwjzN7w+u`hw2Ls!4i>Q{w{|13Wjdj&3sXJ1zO z>ycOezL!g!`tT6g6dnzahxYtM>wh0VZ+!?(f>k?9T^GS$ua~v{JoYVqzNtTtZO8LC z2Tq6j+zIzS-}Up`3wXcp`u&>LJMGGn_2&BZ79SP;xpB1f-N?Dv4g<{Fo=4q}NcD}0 zGt%teVOPn1+W1FdKLMT$+rZASC$#>nuzv@)!fIESp07LhK5!@;?a;69B5}6E+W(gI z(a_e@sH<F8-COAH?J0Jz_gj;D#LsoV>HU<&eKj4r?yp3zuLbjK2YbVQ(9YYdUgLH( zaVN2!33dN$zIj}K4}J;1hq2PnH}N+(;(x^XIwDifNf*wGeqU?rDXYGk$M})ze<1D- zSoa#~qan2Qd)0R#&b9CsxWW<N>idS#Z@NzE-3IsIK2L$Rey{rD$bTkW*-i2_xK`Md zJSREw{fS>~{OZ9}*xWo{Y`xL?Yo4RX*9y*qHeWC7x5EeF#2D+dO#DY3@eg9o>*4F{ z^8#q=uhU)j<zRRzyaq<ApGTa<a5elAZh+rFn=e}b8#rgZ;T=$4-)z2E>H9g(_e|`2 z@%~WXA5Gz0_u%sa`uPD{pZfnwoNB~z#k2me;1@4{o9{jHEriSAx6sya{g0zReLt;p zvhOF;ncKy%GjzopNZbd)#JB!!(8tT)=DU!5o#0il7qs<T{}Xt<Jqf163t_zUZ5{Ei z!k!7QhyCNM&vL|nlK1`3!KF~Y|D4I3_4`jduRN~51mA=oL918$3a)<vUGYEW_l|qr zB+u!VupQLTj~?7#t`FeckAe2{qPCtb#NP?q+$eFzz->_TTmPwCe;=-eKS8Tc>m~6| zyhS(&J_D`((3?ef1Wbc1VYGUUd#s7u#u0x$_SNva-csLYXzTIyi7}rA5$;!Sba%pb z?CY(L{mssj{-(o2`FjlX@5!;}!K=PXw#5H#u<+0!!Xj98sH`s?CL96J7%l6IVP|OT ziFf>?9rdT1`s-4619*t(=MYEzuK3MO{Lh(_&c_vRrKwlvyPxrIIYQ>!c9d`yTn1M| zJ8zBu5c_H4N2^~){gK8mFa7t_brgM{9%273Kkd)XD^~h3)E6%PS?I2F=zleRmsNk2 zBfiezajwsV3q0yycIe;7{s}CE`aH7pd7S(9&@$d1>OYG(+wPP5>o4fa7jOL&9_z`C zQ2#%4yWd;#dD7YO{P6WMr&!PD8}>n;=i%bVOMejO;50aZbN?Rf$GMp3I3Gh2OrPVi zp0euanE8xx%tzx#s-H&OC*gBY{q6I}tA08AoJQQ`P@j8x4tqQLQU8PS^YtZnMCY@& z$N9udulwZM?~>IA0;)TQ`t@~i*l>9cMyo%OIH$pLpez2as_*KUr>kF={&Mz7pWE|@ z`=KL#W!2xtoWjj#9PcCFh0S;l>g)8ItUq)-A7_q~`{Zf(0$c#?{SzzwYmWH(eW`x` z`xD<+y1xIl^=0sV?WM2_91o+_YrHJt-5n;r)ek^F1P)IS|A(l<&Swht>F^o&R-E-O zI^w&2uG5G2r?&n?)Bi?a`g4sdsk<w@7P|T=FaMhz^Sp<jGd&6a2MZlPfBG7G#|Pv& z^94NU!O~x!x1z6M^!qvVnb>cDx5K*}`gPbh!0+MDG16<Ct;E{_8;&Wx-zTwOkt5e< zJtX`I+ViaXJp5jV^BnR2=P~{v)X@|k4Vyz-k5|3MIfZzqL+#(jAH{W@%Qoh6_QNu# z8e@fNa98txjQ(fBr{HX8`}L~-h&bz^&a;tYo{6Tvk2+5rC+DCWyaT=m7ehO*X#FQd znLkndpP-M=;g8VkJfCsI(fzUWkCpykj{UXqf1$nu9Qx-?{bkkf?TD{)Xv6g@#>=_A z725f@^xYi#d$Es#55w^eeI9kZ4VykH^_&T9Jzn*C-wl04;+{ku9US$PRsRX~{{fps zm~T1yHO5ctwf#q{KbX4O!f^4+s&DOxuYHZ-`egW$NBt8H{jb=!!JV+0W52)UoNa?U zVciLGUhI69V4pcruJ1QV*ce*<W$12#x4^qR`u9ju{SfLN0ms8h(9SE~`u~#mM_7%0 zOL6R9y!F43cPG5yF*#2+Lpz^6u(ySS;bSoCaq+(o#>@YBkNG0iYhUe&KLsv@wx5d9 zKkcy|m%fNNH7Coy?FILTw%;SMp9;@_7drG~vCn{i!TlWPBcJP^!WHm4XzN)+oZ3^Q z{sC|_{A;S%cgq#}{v{`nX!G;BU$NHr;N0|t<KTEW16JW&m7HcEP+9!nV-98QKT-X) zuFvT2w=nzNigPdortzF<?Reg#6R!&#i{Avtc~W~3*Q*ovP)Gb^*UzEPNc%0Tez}?F z0gicU{7Cih689sx1ggKiU%cv57gsF~aq}m_EZ84bA%QX*`zV+LA9Lu{FILPY&#&c_ zFIIJHoWK&9b33T^NST4(j57M?;kUryUx5A0Po>UC>q-_~27P6gu|M_eQ%3)2=afy} zhD&3!KdHp&6Qg+1_7~1Sn>t69vECf~rbp<Xhi-0!dRu=!es!0XZNF0SJNh&6PlGi+ zmvsu<2yK45E<)FQdFl0}VZX(3Jq!Euj_Wp`UFYHV2F!;G9PtXUuXbE7#D3X|()+Rb zGtu>kP;dRS@Vgae!-rumym+P5lL@Co8!r$0+pqxMzDoSF;TUNBbFhzdT+hY+7R-kQ zhFw=vFZ>!7!DegZdKzrDmNonq+WLyHHz*Xny`GA_HB5(-U@lw-i{SHLO1wOnZ@7ka zAuKZ7$vUu3;#7wzusKYFtzbILG`xqk?Jpbq6qpP14L7q6d?ocXf~oK(m<9J-FS-=? z8w_j^dlQ%n(+mf(&W0_&7Qb}(DJ+EJHp=x}_yn~5=3&468_{ROc`zR?f!4ned$(`J zKMRh8Iq>N3<hu1w!+t)@fYV?eTm%c??%$UlF9rK?j_YaIPjXyO$KKs>Jq!C-$Msz7 zYknxbzC!HVVc<v6?G97m1egm84S)Yh`~p7<4}__(9n65A!$SBoEP^$PBu)z452nIn zU>dv#X2P$b-QObY5BwtWbKpzR>hrM|8h*{X2sYm&@zP*xm=3d`jc?bg+xJ(AmkQg! z47eOx|3d8BVc<83GZN;&i7*$=f%)*<&EjX{+jR!IZZHex8NSE5050EBdi+A{J%5+$ zS@2zG^A}+6|3~TZtlqA(@td`^bpQ0X<r~;L=L_@DP2N_z-o}sjI-9yiFOd3j;Q8;% zI+r?c-lJNvAp`r059N9m_UX{pTZr!1k3^paAA))K&2{+Ocy^tS-=x}7pS>P#or~YI z4*xvtZ^C>ysgC5!h3jAuJbus8>q*Bx#Btr$n}cpignH}mbzMlFZ(tF;Xs^=y2^T*T zzw2QZTm}o_B@HEhCcGVH!|9Dm&!30A{?VmhPsP6IIJsT`2OeL#J{x<JR&qTRzI;mQ zdfR_Ky64XjeI9JkrgZ;Q>@&|R{dykuQ`*b*ba*e!fzQD__!|s#5Wf!4)|-Jn(=dy* z@*dXNFbCRrYH!d{@}|OVFmS%u7s3Mg%mrf4gM%)Vbv8UdL)IDasEcHs26w+$)+ul` zEQGT!k?VQz_D-_Sh8-`Jbp|~8GFj*Hoa(<&o?o`#Z0sFBmg^a?-XflN#F>Ak#4CXP zt|LDT43M?*f+4cbfaC6ybuQcj1H;AM6K278U;#Yie$l1F6GyRz)gO>`3jFawSr@^( z#>hGw&W8o?w6Vm47fq3MCcGWm`Bn5fo4OXl0=W4DsXy?c@RCLJ19Okqt$2f#tB;m- zAzX0^YdGmNSx4J%E^!t*;uT<j^K{9V4~q;Nogvp#;Xs%T=R;d>0rsyP*R9^Ji}2f0 zM*l!-se3!L@dN2{eF{wFKD-H9eJ;A0Fb|GDQ{q^?UFV{k9iiU(?`rEj=FqoI>GR9R zUiIA4ug7~HDdaulyo$*mZGY+1-LZXg)*o&EzJKZOLw41<WN^-V!z_3g%!VUiv~$QI z&NUtU`zv(PqMhfi?w`dusegX?oR=)##|&K@pXWd-eH<R6e$t3D1LnbZGh|)`u;|jV z%}@P0Unc&Uu*wy(PJwk{DjWo};ZV4%pVw&n%VAC@Tv@jLiZ=hQ?w`(FuZ_`svxt*z zm=mM;8t2{4avloc(yQWgJ_?EZeAoEIPqy=w#~g-dmTew6_&sw?Wd3>RZtN!dEI6cl zWd1qm=Jtq8pXmFMPal1+lYX+{e{PU<9=y7jtTSP!n_0t7y=5J)-%NC`+#>pXcu1D4 z)8Hx?E}nlqKJTOax%zVrO~5|~{yFf^fqx(P&w*X@IZ(*^tX8*0_WsR32fOAuD6f4@ z=bYVkhkxGu*VT%DUCrhk4o#Btm_wbn+!>$yCyTh#`j;L*5Br#V<a!QlKd^MYeXeAn zJ9~)eGhp)(vQC4YM@1IT#!s|$CVe!1Ffsc{rLNCmA$)X9V%D2z`|GuyT;^Im$DeO9 zy#A%IPj$;_zf#Gw#*wcOd&;EJ&rc4&SDhHA->=&9u65LP)MND(z0PGWcNNI{_*CjX z6sExwV$@GIdFDf}{ijn$`v~jFK=&rhhb<o~{k(*$Cmp|WW%Lgh-@jh5-%l2BF7I1X zwmNd~JN(ng{L|27EsacX&xiW8T2{J$F6Z?7$#UL{V7IBV&Vn;x9$b?v*9&2d>9S6N z$H6rC#0<G^>nrbd9(C;f1ogtIPqKzbJSFQiSOm+v-f;P}t~Sp|y%}%<%!N<DJlJM7 zdbj`<z;(~c^&(jHd0B_6Ck0*I7e${6d%YByzm1>Hx$O)y;bfRa-1V>s)_6torNC!k z9{d9aUKL$!m;#FoTf7lj{pslHy(#)sIQ6a4{d2M3Gq3dP+1Q6JDE+#fS7l%4FsJ?> z`11-q@$GrYW-eEM7}<O>(T$8yZ}aVH>s+2Y8)2;b%VEybBAj=g>OPKaKVw~QMaN5_ z?^_p@t^aKNhL+Jk*8S&DNBe@v`pH1|@+YP1^RaJRQu_5+*KgwmK9#%;mI_m08))_Z zy7c$yk<KN9xn7kd^Ub8rIc2OjAHS{3<a`A_6Yl-FFw(iXbScD{x;!@VTzOpfT=EWG zA^CIQI#>kfuaxTru*(;v*PDsG%bL=!yXq*bJ(D~y{3!YI;gBL(=fE+)u!b8ql}~-) z`YNK1ep@1|CmUVwKO)nI%b!J@k6;08_NT;8gD1dr*al|6)!Rg02w&VT>wMUMN7?Gl z#&2YV{yFFl-%0&&uYmmh*5T%ng058+(Wk@pun6|8D%Z2&NSFiX!hCq^?vdpWSD(FJ zr0*9$ljnL7+~adur@+C>OMmX?V83=n>DO((aO-UPys)11n*p~pC|m!5hT``E441#6 zujf<eHxbsG#oP;5#b*9R<UO>J%q<NL-oI?~ujqM}cm5palxH}Xbv|4O3*c&42-h|# zecpxG_d8Ior^3KNrR&wciR*z>(e2q>m;%?ekaZFK^LSYYP7ppbNEmLOdFVRx@9bs5 zi}`ntGNJzaKN<XcEcGWy{8ZRtlC0C=>o6bA<liO8gXi-1OWXS7uK4@Em!lgBAB4}s zzm@WTH(>7#?||wbt^Rf56~b*W<v-HDjqg?eG4Ynbl~D89_+Is0sdEGz4`(>)--i8! zY0}@BFcaE(RG(t>mpJqp^r!oo$NCWRronW>j;u4F)}P1vHu7b|#~u0Y`Lk==pS>P# z?bYAc%LH6=jdnhbXYibYBVi7VHomKFwfphoyT3YT7ybGB^AAlx&qut^gXU4jJD(q4 zCZO}SjQ4zOKCf%9^(9(-TTin0lW6sOttZj+_I%j2*Ltmgyw|&0eO~*iZ2EBL$?H7I zJ6^baUa!ZxU$6PY>AlvMX!>yd+3Q~GxBlVQ@s1xZf4J+rT76#oiMQU)Khg6=TW_@f zUgr~SzG(d`x?WqqU3;ysvgxCpSEBjHx}Ip``RA$R1nfM+txJ0U{d2c)etJFG{k4xs z8EwCj=22a=`F#J96VSOv%97rd@BT>k{_Q?T+mDSGZXNG@l`X#4e&ekVxBvFK*Ltjf zyw|&0eO~*iY<jQf$?JT)#*bFNtJUYVA73vMi1r+*zt?%HU!;t8{7CCiT}9X9=Px+{ z-4_>2s>6SO5^ue&v%K@!{NdJK>kAhz-1YL#7p@+AeOIf`Yd`VU+j&R3_F8Yae6fya z^LdT$Rd4gzb+qx4&EIRi@z&e@2)FiHPq=uozP_u~=e3{8ruTY&yw1mK{Al&NT76#o z@%1tR*E#Y!9~&oH|7hcR&F@v8==FK+C(-nFzOi0=?bqh7Xn$KzxV6`Mz3MAEe?`}8 z`;WFBul|Xqk9Hnj`-wK6_4n7Z1O6OhGl$ga^5>h2`18#ETw^m=e~$hfLlcPgIgqLT zpZ~rm_iqDu1Y8W)!}<$F_kTR)f4Oe`AHcr#Bk}X<-#SYFf8lTIRePlI<E_^@*?F&J zZnpli>K|erx}Td^U+}){&*kthSmgt;_k>x{*7F{5wEpd^s}slS>tR0%?n~S&9r3;D z+Yskmcz&4pT8GX->(IU*`B3Jt0saAZK-*tM#hVmiee=-00~f*-(DpNseOd>9fm>id z=35AVhQGnxiF*_52M2}8_o#_K*2Ft7PW~gvn*)cDcQo9aybT=rW92{E<R4-3*A0`u zto}N8*M93hxb|E3CDQ%g)$>hZAM@d4_VF!v1p9cNV?WjZHRJ!P@oy8x|3Aims_{R{ z;r|qVv*DBYJq?e??_Umo^?L<>^?M0_^-Fj7Yu`FQ?OW%keY@tTetMqOPtULV>3Ox! zKlNWt{p!Dx`qjUOqki?DZ~Xsf{5v}QKf-Sj`~bg&uoHflJN(se1^(*yIsWR`&Ec<o z>-@BDouBsYnxDRps7Ai+P+u49yuIo#|CskF@J@I)wDBile;U3D^Bwvk?3-b|MUt-p zJOmyAZN96qcZYr905}OwgVw*=V#&7$+zajpt$rx>sc;&c9Y#Nj>to;qhkgzAGYh1y z$?#M7Ijr-ETu*_`;IZ%o*cOh5li+jk1^5PR_Nm0Z0owk*p}z0oZ0dO)MyoF*&IY&% zZgIr-s=r`~^mhsD0dIx2{u{_U39e*Lg)mn7dn1gmc{h-M6YSuq->bekaazLD;5m-? zk8(~PhcCeoVIlkuKC)Ei|1`Aoi*-D$qk#Ma$*XnP{PEUrrH&@lkp@qOufZ>15!?=K zy;ZSmyti4azttb|xy=6*cs9He)+&_ijbVBFyYjU(^<Ki->Ro+xK|g@L9&+>-Z+~0w zB<gx<xy)VbdfZXpbo6h)SnKB#w-)vEfOo)gQ0uk*MC-qq{C~ooum*W;zDC$>oew9O zzA^Ql3eSL7!LCsE;cnJ;9^YWEwnEO6o}(un=gF(SHE}P8`>mBc`@@^abGsv7y#4Jw z+EV95j(T1Cc5%|{+<Fkd-WM{zE1<2%tNtwFw1XGG%N+3^q>g9do9x?1j{WnhpG(|h zS4y85@M>uLRed9_H-*h&q_0k#T5xaJz!CpO?4#kutJp7?1^d9CxevBO+h0Y;bJa7L z{%k*1uYEpDzx7wkJPwCfa&GiFP~QGFpYGc;^jDL*>p*=@>HC86_IKr*?5NkJ9~US6 zR!7`pnBVL0e{dP+Uhjh=I1jBH&y#q^*L{w(UOV4#{#LJZ*up$A=v(iLX!ROb@4GJC zcfFyFpJ@8Qybeu<Q{j_P&xy{>_7iV^oA1#u^;-Q4=wF3v;kWSkHN1YnSo<$@<UQPx z&#Qi4;_L?-!^0f$dtmPk`@^9Qy}pk;j^~KJ4_V@Pet6YyS|;<~26y{R*7aaIYy)qG z&q2Fiv5q%^JX7EdINOo`2<*o~t@}LI1@JRy>yMTHQ6~R6CjY07{1;-^IbXuQUj^@g zqoA!n-u|w9*HE|Cd!?g3JvXnRw|&|8tI=(S<B2=d5#Ou6I^R$41M9>6q2|%oaa&)V zFXetYex2}Ac<=^Up9|Z=PvGHS%XJ&Ck;iy{go)Rbc*nuhU>j)jC%e8qef5K*;k)n% z_DA>2?vI^EyyA5!V?8h6_cD9~z5{Ljb`DF>=^P@}*Jf_f>X#5_HT)8O=ZIf(J@*j| zciweh&m*4Rhi94l@Ilto;LFhV7wdR!x$nopS@1>pF<c34JvU+>1=asqhyFqAnoo6+ z=8M*UD*0!?AK-RaYoqM%`Ox+oFaKZ2Z}Xi<9jC%GVFyQjwvR68UI?S#Nq*I5qQ3*) z4IhHzpsn}xZ)AR#!ftQ`90w=E^76kU!u;LQ-EQ=cI_fRLz8#+Zt@Pg!+Ws!Yei6J1 z{@bC?!afJ)!{fe_JZbPGX!GTupJn_HcIY+!V)XUVHFoF^!+to_dRjU3?Xb6p=fjH} z`X$(x!L@K*jPx3JwTZi)^*8VbN4|T$mwk8)=D|0h-H-c!5dDL25}XIE{xj@ZKZ@UY z_y%<8SK_zE;Xloz|DR#%v-!Sq==UXWQ>gts?x?5!Pty1P@HBW1><N2AJCFOYr~WK) z&Vjw4OMgFp4?6rW_UQjqnEGtKu@3#)*q1@==X^&!3$T9(e}G$HgCd#BfzZz5MC^;; zW_Z9a;^)$zimtW8zluly&cul{Ut5R%HtfTo_Osog&!o;Ca5#Jj&VjE(Ti<1yWKMnI zboeTaR^R?Ni9Z}>ZI<;1a0{%xrS$#k5utxohri|<Z1U}3ZTtI@eCy#4a5Icne<O9y zf`z|J-);X8{sOE2S^7NgjnIDwacsSsZ!>u{-yaTr09`d$8`gt1zE^!VaXy9Lm^s+^ zWz~=K7(Y?;w=j>-U^~vm#g6k)R()UMFM>;<oqrDY88BQuiKfqFZnwji;H&U;_!hMN z=VE^r?tq_cmHTxK+_0_m`?nU?^Njuv);6D4{V^WnXQ1z9>e=9^=WhBM2&cknj(&Ac zI%hj4+wVKfb2$ubmpRsgiLOtf&V%3}c(0@WbnF@MAvhsP^m)`d5AMH1_A3?I{VGIP z1dl;?LXzk+sPo_O4fwXB{%q_ya2Z^iB>E!i+zGGwOZK-XwELTiJq`AQ!;(bbai{b* z9DZ7*dU1=#R25FGCY%dx|IzyQj55F0`z>{Ay-zsm9focsd>Xz8ZGT5pm;TR$S@08R z^?H3E*B8Kr4t@I?62BW<TvOIRK^y<(I&wV=-U081(dsqs?Iv!2NBk|=>+LCZO@lMx zb9;&Xzp(1wvff>}kF0A#TmLP@84I(Bqj96vYuw4iKZ-iecGRPN<)PQU=24fe=XcY0 zW{ULtH2g1I2V?E;%Cp0f?*jJaWw-(U0BwD$@5J@z;2eiO3wt&U7eCSTZ&3H=un2C3 zc0Q}HYoDsC@0h<!zts`{aL(7!up_(-+IsHgTu+7j?kneUExfX>tY3wZ`cK3^QvE=O zUh6rG>%C!LhrSDSc7wy<1Mt7l)sObw$>`o;ZTnIEx72eEI`y~u0N3k97(dbUzfpIy zdU7td!#(QD+V-pZK!o~Rh;uu91Ws|p-@k$6Jrq9KP}U2ettSoL$*@x+(ccEG{&IAg z@L6;pIrP_~yA{^nU*aDFZTx$v^Imu|y2~B<xd%wR58x+oDYWtDd(_|BMB;w|&puGr z=RzC*rE=0Qim;w82T8r3z`tN1RqVF@XUj?dc7*kGrp{O3UI$CvDTkC^{{(b1jDCOo zM!*^H`!Mky4-;>k$9P)5))Ov&y!Gc&e|OWzE3EDL@TxzIeR}Os*{{v8T2on{aIElU zX!D&NrT<|3?<TM2>qx$SaIho)2>eIE58y(06LEV(TYt3vMdaBGtCFX>BcE5j-H)zj zF5_80<CxEO>evap947mj3GF<*>hp=S5^6nD9reUpUqBs8O+6DG^~`53MeqR5{lTy+ zycXJd#mawu8S`tMhnqT&I9&GG)*CDRAo7id?>gq=$``GFUq`+du)hr7fbTf;wvNxx zx#s6pulv%OxINgHn;iR7R(+cY<JUo_=Un?dhkAO$HAl$#>2{QG?$N?E+(+Lz?k89L zV@>=Kj{Ym!U+YY#zWd==N4@dZpGe+F>xs9%Hs@kL816iH)sG|YL^u^b3GMSNhx0iW zegOC2yhf|vOuVfyK-`*+_^q+Gg`MHQW2`^R#P8yWf4R|V9nZ!{Kb|;`!T-Q#9P#zJ zGVVxuo~(tJGT$%pJKz|(uJ1eboc+ObC+#@7ZufT+=VS}4L;QWAua~(+Iv<_eLCjD0 z;~mHI->d!%;&y-<x4;qKtNyBH((m=~e)u4?=ixW(yKx>5hezrCZyb)ruIINF=T^_J zkq64EKaV`&;{U+?^Cvun`^0s>c-3D-f4Q&_ehv3w-}ZOxU$p+C$&&-e!zs|tdp34g zozd#2Hkb1?4SoWbLK|Q0pK<+XxL;c7&$GaL^7~Ew`+idw%DNBChGU`q`;Bw4Z-Rl3 zi3d~R!7vS;1vB7am;>L31@O#85;p^;Eta+NHrClt|NgW**82C4W%2hV4Ou4sIq)0) zJgDuj2)q7yvo!wP!KeIr0;?~?K8w%S=fNI)K3zW_e+r+^PKS@cT-fsmsV@ua=dJTu z>*t5F_*|`i9yXQFh3e-!^ZA_TA-^&&crc$|OoJEjIl>Hh1)sOk&qwL!ZS?ajv-rG* ze%_-Ep9j#-L;TEIKQAzj-}mRjt-Es`s|)w8AxweI>c~0`>hBvf_`Qt&{-J=MzkkNh z!wX>>em<H3Tk!M7bf`Z+RO<6fIfUn04x9+>e&=G>`^#Prw@&50{FmeY4CkMY-@`B$ zz5=bkeO}n>{#qvF&%vKVXafE@@XvvN4*dJTe-8N1fr@wz$khM-Z@6>#w^IJE<u&p? z`efJ%UJkp#p3wSx&F57=oxHQ)Z1{?!9<TcO#Cabsgr7U&d)0gG*VoGl(>cWZylEb# z&6o0pSRRB=!~a67Z-@PScoDqCp?@6vG&mP7a_9>=mtDKbecKNXhPIxD*qgwEVQYu} zX6(1Yk#LGb{~Gpr@NHNSBfZA?oOs{C9kBkjGKYhp?O*rRMPDxy@aJPs!avVN=ViUr z?qX%r+c|jczoPwj^?JSb=j&wx_FU@P>wMHtnQZ>Mdc9uz^Yt<TJ<pb2=Tp)CUhDPs zvEBc8&okQd74Q0@ji23JzCRk$LpT<G0&V=U=qEzeKj+Y^ZV`Iby%S^oJ09als$WOk zy{WemZ04xH2>Yh%WS-S}3eSXgp4HIRGWr7@dexnQUUe;FtZ(Ttex&+~i8~06gcG5i zkG=ow+Skhj>|Ath=QEje()4;cmp8#a(50V>-}D&y?;y^B<kfm?{#ocE)xU;*9-I#g zp^aaM{8~r2dFWgtrOg-4&)3TYTyyg0<Ig8F0X-kdejc<BrPqGcPnqog+J}qD)}PmU zeZ5Q|R{QVIvts9I_tEQq#M-~I#q&CEUth8Ji$DK=o`0<GU$677==@&m_4WUJp6q;T z-ylC1X$^0K!{8A&$@S(ioPV<EQ*V_1PKEEnU!d(b(e(EIv};?xy>8dOUM67YqHBLX z{(M3cNYwM7bt%1`SM^htx4+kXzFsDv`(^3R$J>0m^FHTRcqe=hE`_V1ov-TWd(^*C z$@EWp>^EL|d%uKR+x-rwx7WS;N2|Z9m%P7y5zd33KpTHp8THd6j6VY16r=x;wXMg_ z&#ryFOu)`X*U`==BU8@LbeIRL@#iiyPozx2Z*Up?!{x~#?n5vaz6$f<au_aNMPJuH zZ=-+yMgP2u{`r$!{@lk={CSTw*dG?~=Vn$w+fO#Sk<eZbx6Z+DBFu$zU_M+5!^QJ@ zy^y%;VG+EF&oOz8mx*5=sGk@6iqARe=bbL$^A$FJCiWpPN6F_dtlnS$^Ybg&=aa*} zpTql|WbY^1`ZJh=zJD%cy(vcX3GhDR7MKOM!f^E$@|^6nrhLw2;AVM!?Eu5o=k<ED zum9old5v%5C7XY;)tl_|j<)_}+b^&6`g)mwJtw;M=i|>OGy(rS{PQ^|>wMHtDOvvh zui9PwTNzn>Hcol_d(9VbeYEqa?Dcu=-_ASSI@a+kI-b}3UiEgK7408wJzneg^)dlF zcU>p@e6$Z`viFl{_3K=fyIOtPm(pv0>ZeRLf3Nj=)$3f8mCfI4zrJ23py$Oh+2>>X zv1_mWS%15(=y+c9`+Avx-A7#~+I+Mw7roZ&ilg?5j^{PMua^nv{#hp4d~AJo?X_O( zZ`Tza&ue~PFB7o)sOv<VkJja)*Lq!X)Lzl?yyo|+*FKeA{e8VmK<8%}@A*WVFV_Ci z#*6p7DqH+$_oK4=$NRk4`G#A2t;fczZ2n&R_4P6Vdv0{?&nLF?(YY%9`Nnp>@t&vd zo6>7O^;3HFkGEdyQhLp&e#&V5HICA2JYO#p(D_;V^YP~snt+~*WIqquhl^hObH!16 zMaT1+-`C3obpI?9Z9cX>yY^bI^|$Maj^{PMua^nfebjZL%}48U(QCb~IBKuxcwY1S zdYORkpJk%W$JS@pUhB2~c3si&yyo|+kG5a0`Mm0*tuI=Cul2@TzpM2V?|J$0Wdiox z=sMZwqkSm7_M?8vWb^l0Z)MZ#zPec1=Hd4%6L6h}aCWcr3m4B`Pqg@6>+$t60lTld z_UGemJ}dcqc?w~z-tzbL)PZ}$rf>#)3fg&Ff7L(f&=-;SS2zdVYYzQx*lixI^Lego z99y5}*-1Xl^R^@3zp$SQuZ7pa8{i=L9oz(Me(SILB8Pq?_R+BFEwVo~p^YDJeP`;h zedrwi;Q9_|>#J!04C=ZR7QzjVdiA+dR@(l<#Yr^1tvBBF*?e{#@BEc5zMZdKd!2{% zx9f_I=QY1qeYE|0%@=RI-;YdK=Me9C`|(T8TjyR@#(SQ&u6XD3<9j<Fm2F;?{XACo z{wv#g_u8+2K1xo^&cm)ts{j66rPb*=(e-Qjxyc4tJxhL`auA#WpN6&{)z>omCms6V z$g>5`LHDvluez#6m+#QGz<wgU3igGo;2O9Qeg~V}D*ZQwwqK3c6}^pT^@Gt3g+IYx zV0r61kyraz##;NZ^~76$FZsv7U*TWS)}!}Tr1a{aX!=O|R9&Lg@7E&}(EYLWI-h9$ zz2=Lz-tVX6`H1(t{rDy4ZO@<AwLi~)o@cVpC){~RwEk?p@vg7D^ToR#ukkB;|6b?i z>tzD=+(f!g_W9X9<K2(VXV>x0AMg0KAG<E^{PE6L+2Y&%v}>>Pu>N*k(ea|q@73Se z%LME>h;;3Be&OO)bUd&5eZ5Q|+`j5{uk%trWwQBut=Fqw=b}tDf3NlWdYORkcdS|2 z<{Rz&?7T8=liwfS0|&s7@P0TJj)VV&FTj;>6<iNDz@OmH@DKPW+yQNU<(<##d~Lnq z{L5Q^U?17v*6<?uZ&=>-B-(sZ@09r*3D3Su))zoKpG4DNOx>5lyWvo1>-VbHI8%t1 z2VZx@AHm%2htI->{ba7To;<F<2w#D3!D#iD-7R^qgk9lmXybd;A5UK=!BgQ|j(*o+ zUk^9JhW$&QPfP5r;8pOZdrH?Y=lU0L9XumO`sxEDZ%ue8tTnLodJgA$Gk7d)4(<HC z>IV{MFuV`0aK!hj_xij#j5!<*Pk?7T=HoSfto1gY-4A=+t}C0~_HWn8J`dZET_;+9 zwm!Q~w0aY*9y>3)PPBTx)?@pzYp?Nqy-dK)QP;^nAML}%WbZH0>UYgq?TJ>e*Lt)M z7rn+SZ~c|LZ_R>t!D;YmxE5}NhYl+J`+<1HyN0~|;1H<wy};VeZy0qx1)qVd;1{rA zw)C?<yc*hgqtQ=?8gH42x37tJSvkiWM?KHNmrQ*dSlj+C8Z2|@1=|mi^~LZ~m<eO; z|3C6BhAZG|X!BL2juf~*Y~rY|JNEwY1^6<Y3-h7P7p?z%;=TtL!6k4xTn%mhX#LL{ z%6`Io;UsADb;5op{MRt?zYylbLfGwIxjySYVZ7sYH}!d~$M=_g(*2Fs{O;jg+{C#U z2p@qH;dJOaKO>1V9X<=^!;j(ja5HQ|+;&jw$YJfO!=7KwKb5$y{9l>;wN3u6tX=sZ z=eo@wZ@u=V^VL3dp4x}bQ~S_)YTdezw*I%dU%!J}cy64)ysW<4a5<m7;1HMtW2L__ z!uT~tNIkXT-mosT^?22%6X$%`4Zh)sullw|pBE$jB;rhgGvITM__asMeD;R*;UUn@ z=X&gS!iQnaQ4+`3%N*={K4VTF-7nYIz|HVaSdBTl=J_pgs-fQ#9tw|z9pI&K0GtK2 zjw05sI_!RG{+-m}%HM{#n*Sz~|1H+8{5!aA^T%7Sed&C)51ps>q4U%}be>wb?xU@L zPxkj{cnzEet-cWZcW@`HKDzY#t*rWQB8>0)zFF<IeziwRul~MXCJ?Xr+PGfly{q}# ze!Q-uouAiyR_`^xua^nfIqEvm=X3r8@;Y%L>;&(HiC(|X*~MM0{?r`VuROTVSXmzi zZNI9Yg8pga-=LiQn~^tMzWdQV2*<(6(DwHk_U~Z*hh!f6!((AvX#HzqSHC8#kAm00 zCGaff)zdNWM2UBSqdu*BB-h`7E90zx%Mt&qak5`+;bb@su7ZETA082X!|_79pS{s( zoM%m(-S9sVo(ucJd*O@lEvR`9ByUI96+Q^(!3K{eXMJ~3_aHb1j)%{~m!X~i%@d^W zHSlLxZDQ&3@T#9fy!;5`$6N1u-BG)pkJ??V?D`KmCyU{pljPhS0_}Xf>RoeJyN$1Q z7k#}<AXf8n#ZkN0d8?m`(Z(xpf3Nu}o8Gn0YWF%1^>Z=N;ze7JSN}xQ+kHy3`l78T zgV(_waIeSY^>H6~^W(C<4GxF*Lz`dY&5tl%y!=Nx^4ok9(P_Q5U#pLFPIob%M_`>P zGRG$HI%wm&=I+OfY<>rEZl^+>cPq!dz3Pu4ZgY4lYz@1^8)0ww0GtdXt<UCj#qZ;Y zZ_ihG#k)SjdhGnP51m)I{fpLrCUxq4e}0(z)2seDkMYZ@pG%&aJa6j5On3vd=V2v& z)r{W-#xK(OXuKmP%l)c#XgpW`c<Ill4((6p5NSW^pGh3+Z~IZ5<_mY8%Bt@{J)_}6 z@KyLGTn5*|0Q>5-zF6gR%`0K!n}T(}%3QCBr*Up&e{>%oXRZ6V$n4_=-OnV8cQbWs zzY|$&zYADL+ONL9+Jon|zRv4?XT}ros-MCAG7G*4Ux7>EN>~X0gf*xu()w&ZSN!#k z__p8jinlz%dhGnP51m)I{fpM$em`f|c7FD{T_?K!ylL_}d@<ZUUDm^A3T^$qUgpwu z26JOhH^9E|Za4(G=6Ne|X2MtCpKveyFNRsrmB;Rv#ve|+QSd)d^L@<v6Sxs-{+8rD z30@GUo_n}%>(O}oRgk}H4my9=9CSZibI|?KzIESi|5tLK%~5i{EruK5w{R2G`_jhy zggCpSYXGl=S#S<4gswcU_#4UdJ*+|;&37#87VuoC`Ny-K1oNP)o*%ew>(O|3Rgk}H z4my9=9CSZibI|?KzIESi|N0!s;r^KhXTg`@8}LI|0N23va1;CkR)0dCYjvQ_|0ue6 z=WXmU|BKY6eZR+A`(DLb`~I1=_Fc{N-N4Upx4w9-bJlaFbJlaFbJlaFbJlaFbJlaF zb9U|bi|oUza2@;_Hh)si>nYF{eLD8munnA{`dQ-N0G<F(gcra|ppE}JalVH?!(XAs z>EQ4mN*|-)!*Ck3`ErQ!7@P%<cv||XEc%V~z5XfbdmF6J92&txpld!=@cS1$7mkFv zQ1he^&y~l{U*k6*&H=Cm)O=l7Ujy%in*UwaAHqWDs;4n^+IlqJtP1jX%|YkynuG3# zYYw_U+PChz?caWXX4k%6CSd2H>qMW=)tvjDumI*iC(nuc&kOrQ+mFlt%x6k}zN)?l zdA^3<LRb7q^=rtx5uQff?Hu*TTmK_<>^@uOp><s6sK=}R5aPCi8=jRs>Fl4KXRP#F z$a4UB4uXfm<KRiqRZk7B?+xq12GGWBiCyE`{+_0;7opBM%Q5eG>*rF(D%g$s_5QN; z$4cLuJfq+kI2Pu@SD~w(JGnjx4u!*^jXMXs#<l%5%9Hc?IPCIYS@(g>UX=A|(B(f0 z|3^){YfZf76%_9f>hfC8o%r>KgW*VM=kYG~WpFq8uLV=#i7?jwznZ*t$kPPg4cEYb zvmaUTqdBtQUqf48qQ|%OYF`i0-@WwpgrmP$=|?%@Pp6K2csaTr4*d%+%YM8BUxlwj z+poUQaWPu`?ypEabzoh%KRg&732nY;{hJf_EcnH%QqNlW6Wj)E{&@S_d>74?`YwT; zVIB;pzaHJqa1a~@$HEElNjMwY_+7AH1GC`mP~(nZt#K!_j(5Bl$ul2*0zY-+SNn3V z{|tYJyT2y$Zv$=p(fS`l+!pXec%~y?q;+2J@ORzUYPbEV-Nkt8ZC;zN`|GklV_`n5 z@rKx~exOIa&2QH>zP)bO(dz5b*IDou__CwlCfHNqA+TwT^v4n>(t7MX!mYi|%f|ES zpX~Zwt^a8IiPqoic_{CEUhDJqG6B0!WnFunXIb;O{E{ud*LuC`U2}5Ty~g+TGJ$x_ zGoSYpAHucpD`@Bc1NLff%KN=H;MXu(eQV;hg&FV)I2w+HHlNGCQ-uE4q3a9#!GX}` zbM1@TeZ5RT=V9s3$DdDV0(vg|^YG8-LFeS6*ZH~PsJ)`&dCgzh^tw+<ul=i^GFpF) zqx2fj*UJQSewLMOKDK{<{m<vapHFo2@p^yx^Nw!b{`|bn&p)5u=H;KS@|~C0^XcoO z+aIs<3wJ+wjpysV?Vs0q+5PhBA8&oM^;NWgyyuhb@%{ag9n?7_`+j<@U;9>8Hh-`E z`g)mwo)^n_&nMb^vG$KPUZT${-u3zMWdimb>Dr%<KcCP9{PXb7=O9t%qjf2zi@*P? zb{GFvCTIWguHVkhYd-65*U`rF>R;LPcHVaFbspB=t}8m8*Zh@DAM5?{IzOA=uD!<d z^)dlFN7p*p=jG~4?Oyv+Kc!dy%BI&jx#)Est~hG1=y+c9C%azfuJqcE`necwJg@#< z^{%>I_C$*xZ9V1fA8kInFJ9v%n%?$f*Iw(5)<4>OHoslRI)0+Xi?*K1=I^!N%BHvX zPq?+$`GkvSuX~N3XnNa^UB|oLX!GrA{uSMi*Zr>OdZW$nwO_CLXzNRMf3NfM^)dmw z@4Alnd^C^JYd-Z;M(eL}lwRY-Td#E~<DJisFB8ytTl(|y=M$QMJr}z6dOp-oS>FC$ z^Cg;I=ce>ppZY1w+uv)x^49M;PyQa2>tHYV02~XSg0{X+*vsnQ-T2?iI@0`J^?D8> zrR_ITKh=5l_o~-CO0WKju3w?&E?>@R4LBA~f>Yst;9U4Nd=J`wyJEiv_JX%SjrSC5 z>;IYB|0nfTf%Ra0_yBwaJ_aYlSKvIj0NQ+4Vebli!W*H+o59-pe~NwB+fwfc_%O73 zJy(%3+5ElM>s4>(mTdmXR&TWP_WP9y*g3k^$u_TKtJlumYyG}nCSd32T6>+BD~{T| z#`CJzJj!JE*FKcV-jCP%eZ5RT_un$n=X2wHd0+hrTmgTCw*LOu2f$%)xI_O8_E%uI z`0>_nrH*Ufk-l$$1EB4<HugPXJ=nmZKNb7AFkJk2>+N~8Yum5AZr8qECSd2HYkxle zd_oiO&%-~TgILXHB+uDj;WoJU0(rhm6@UNtW3I1A5Pc)+912IlsgC-)V80<j^tz8O z{yq8fIS;Nn)V{0L^EBsRzjx)l9|(_!w%;Q3+hIlP+f(Pu@GZE+QGX8h$qAy@a}_D= zenjf0I^VzK1avNuvZVLluha4J_nObw%LH8e;m^mPPiO*qJ`(LbXkE%gtIuma+K1As ze`V9_oRpQVf4^UufbPF#wDZ}j?~mV;_xt~OU-&h&@vEX+5~1GKYu7fuy>8d>)<>H! zTK{<W7w`Dd_Mhzj@t&_AUnXGBiLMiEK3bR3YklgcOg8^yt5@f&Ebscg=1Vla&Q0mH zKJ`;3o4?n3eZ5RT_uJB+&#pb6X!kqW{k@*=X#0&eU$prvyMIN`Kid42&EIRkzFsC^ z?{i)I^GUAx=)NiAy?>fV={2AFDU;3LYrVc+CZPLmnP~H|_1Sg2>y0*Fvirw-zFy-; zJ5R6qe7#J-&fT^4Ixib1+5D5O-e~9T_bU^ybJVrh`BXN&&PnODfAv$Aw|{x((>|5u zoxi;EX`jmS&R^d7v`=Mu=P&Pk+NZL-^Lx$bRj++1z52&nuXQQC=2JhVSASnG6VUlt zdYw<S{$BINTfeLI6YqKX@nr(`+~~Tp%}4uICR+bmmom}n^Xrib=>AwH+I(z%cI~xZ z>u=YI7SC%vUiG$ryN)(qW%KviudkO0*mLJvd!3h!Q{Mhw^Z9z2fZaD;`}6VV6PkeQ zJmfBxKd<#BoClXfdw#yezPdpCzJo`6B5SL!%k|S>YuE`!tDj7q|G>|o)@S3FRX^3l zU&-3W*EvT@ul|)?--2^C96kV7z*TUsC8eLoaQjl(=Ns?&WZW$K(hX+8TVc5T{&hK_ z{v7-{geKshgMU5;**sTnzeS!qUgwpK-=tg1=I=G%uCC8zjtAW)^Gt<D!(F}qH2OTR zlJuKFpMO=7e&c<91AXMasSa(v6ztDBuIFKY+i~5-i}gBljXbZfhc<ozb!FTxeJZbD zoe6uuEZ7%j!+T*4{Hd?R%OdYgm<NwtD|My8L9htFJ?{|z6nHJnM)w;G6iS@>(Dvtb zol2bVzm&K|u<trqXHmxtm<MmXi+*9lezH!5i(mn4(x2<_rhD**U&A6;YoJ_Dfd@j{ zUn=&q9oMaXS6^o^hoc9{{L<hpFbm!dvtie4(PzSG(9SCl`|FPD`PetZz+j16dno$} zbB4=W`2*`B*l@I5xB2Zl6<wO)^%45pc+sx2$lK46KO6h~Fb7V8xo|PG^%P(q_dsOx zvHo_QOPtlP5RQLP;^)FXV`7spn>a5;7%v}PL4<nSpIvL5m1Cu!LbwSA#)-Y{qrwb$ z_yk#}!D<s_ZR6W@3c5okm99_2evae1jTdg6L7eNRl%6k}=lTeJzN1?YbFfc<McBJf zm3X<>XQ@B-^)Ot0(O%CZ?_po@dPUyq(@O6*1^bv;ay<v0@pS3>XzTOppGF^dLhGMS zo&BGedb8mOm;)!mT=?}I(HFtrVc;dP*Muo>>C2_hBb&NLI_fLL@9Nh}_qY9oTW1od z#v7%_OTqrK<9fLG6@5LQy1#x?`YVDv-zvS|imunsFV7i&4*ncM6G*gk5SS;=jpt#a z)mPc-$zva0N|61?r;f$20Dh1!=cWL@%fCBY0LSz1%_jT)<<dtN{vE7j@5is-e;rE1 z*CGF0`sXqk&SfUA1N!eh7O~cU4>8{7INSVtT`By#MEdVvh0C9dUjMzLbp89$VL1Op zzg|cmH9si*`{5MqQytfHv5)>x{Bz*DAMt(%{<^UA_<@hbe(0jouP6HalD)n(=6;?( z|Kb;vWZ%zSz5Wc&=~w=FEk3VB%whM%$?^P5q0ZDKskglEC!I?x=93ODftm0TSl;#d z`I7tlj$F=-{&|o>*81l?!tHOG`8<9&eYDq8mdJCh8H_fb@1NY~*WW*X|3VXp)j5!9 z{{3Hh+5`gqF%5yQ{Vgf+e_r*~@V*V+4IhBxU_P{n*5Ae}xeiTrx4<tuOIibg2E~Sy z!0PTbOI&IeTvZL!4&)vv`%#ChmtoJto`QWS_7v<o-2&`IO(f1i=tIj;`~vK|W8YXT zO9}jD>iH9U#~vl?tW#Cu6cR_W1Ogp`_CO#d(B0^}2JNNI;dbI=9VZd?rk>xir(kc7 z{p{d&h3e15uBYYc;%!U`6kb=d&NtBKA1m?CCC;Dd59?V{UwgNZASG~&u{R0YORN8Q zhrNB!9;!1fU-H%_Zw~f!><40BgFO@bG1!|2Hz*V*2fNO>H}+iY2cX}GJs<nk*n0#A zRa*V`1nr^txgVFD|4!^_*e@c^`8B8qyPbdPZ6)XV0{Xm#5`O@3cB-8?dd`n2b`PE( z6G!it+l^iKYlN|%5sXt>zn44g8vm}oCF{=$E<^JPR4G2#fg7p+`C4Mn!hS6F#>E?* z5*TLUG{-*K*v|^uORMv`puPC~JScgkzCfUQa8Mz8(F0;nCvOh+4D@zi=JYSwm(KYQ zW8WN%Q(8T>_LRISZ%JM~hwXy)()8WY=e#TWeW+9O&KOX#o-ZA7s_a#I{DXt`;yJu0 z@#_<RF!q%9#jf|)X6$L$TcPhAeBgxQWMSV%WBPmu3@lmai$Q&rK%>A()q)2g_@!5W zFMe>P1R5KCt>A;YwD~j++CzC$7fYSz3j(vS7ycp!yN~H6e%;_;i|hYH^u@<4Sl5-< zvyFW!_8ep1fIS!cCB@wZ0>|zv@dHaFemm@av1efKg#AtIdDwMdcCRaO3b5ab{(S5i zpGy2-`^8_6V9&%JTo!+Qfjw<{@PQfpx`X{ntw;RO3rFzlnd1Kj0#mSO6K4YUud$~t z75ydHj|&zYnrAk4+2vp!>^a!Ao_y?iM!&~?5+~op?}<HindGfa{gbd~d@O~$Lp{G? zPy0;tpJP8F_&^BNnU*DU(0(7op7MD~{UYp{y+waHdCzJnaf;BlCVn66Y0D*!+Gk+T zGWKQI^RVmlJgpIPz^?B%Mq$sJD)sPk9@vPzz{ELge~D9w{SNAU9DB|$QfE`_)r(&c zQvz3;`(^*2Jv6t>6{6RA`eHB4m3oel%YmP<XQ5|ofjb*ZoNVmDV=rG##Gco__zgy& zE#_0P=c0cB`vUBlD<xqY>=y?gT*dcw2Z^Ke9E3dsyWTIevF8y->p3;}#xE2nhkEpR zcn9_Z^fSo2dn$dcl6v(0*m&$Y*kww==flCG&&96s-@~4dUF+<2i0BJ8OZ=J)bd}oC zKS(|O4kiBgqCW%uQtVk@iT!c(&mJcFl=Wg?k9}nDV1(w7x<Tw(&wYo71Sx^*%{iGA zv=^U~)uO+TI42(=`rD2E{GdIgFG7DZb^eGwo%x?loFk7UzS+l1vFCp&d3B!q2EQ>V zj*ngUr2u;>bLc?)nMX;T*{069L3=1p+8T-fC;BUo7JI>Qa^9X31YW|PwpR3W(O-HD z^<Xa^OYqtj?5TyK4<57PugS-XJ{@~!>}`$<{ZC3D*VK7=&>pHY7yVi2cWW;C*+$<m zXfK`*`g!OVp?}rr*P+j2o_Zc8r%9YbWAEHT?16RCm%c7HI$rE4*tOr)*wc)D+6kgh z$DT@^H?|aeCidXtrTFXke~CRCyPk)?u;-dMAGH#FKK7uj_-o3EVh?amf{)qauiH)v zAtkWT%;&zKJv7e%_e=0GRs415$zo5#ej)ZpP7!-H_Bq%;JXP%JU(4LaVy|+#*bA|% z{;V^^p1ZN+oQGr2!~PC&7Gux;M)a+*?;rf1Q2qJX^?BF>dw}~+@0VQch3JP6=f~oJ zDS_o?K2_2se%7~=SLd05JqP<^#F>gcvzI(Mf5W~Ad;V_{XE^q=&Xo9R--%u4KNfoi z_KVT4$DW5>&q=GZBu)W#Jr5(Wr|?`={VMEf*!BHw^EMJE9eeOGTl_T)dlvRXv9H3O zdUUm7i#|_IY%6gJe~`ZPoKM0Y_)+Zoy1WB>3ic7izb5z~Eq*>=PshFhdm;7)JcpZ| zBl@%=iGMKqhp?w$*ZcYp>_ylg*SzP3{wF1{-kgWNL3{E2^0UO(d9K8siaq#vFaB!X zPV^brb>C-VFT}n#`r7A-z6g8p?OgHKZP-((Q{N}7z@CZyKJ;e=e~?mqU+{h@75i-L zMc9jveeha?;0+Ser)`qHw4Nc@)3FC1o5f#0V$Z@p4SVN~5-0UniKFM_ee4<7b$?Gf zU-X68^_)C~J;41klKA^y5c;3sQ+!ZOEP~^L_E7yf=xcFx8unc5^|0?({6I?y)G=|6 z3fe<)GI-yj&y!s2S=iHw(;!3idDwNo9>iX_MdqOUUhATeV@jZ*$=f7o59Q6``<ly$ zKMDO|M*p1ZJM31hoXPqB3w!n-lJ`hK;LP9yBosgWZ3%oL`bV+nZ581U<lQ~^jZ#RT zJzor=p96-zPRE|JK-O<!AAmh~n;1UcORhhQJ>z{@k3_#FXb;VyrRi%E`m8<Vd2)id z1&;3|^%Q<6hT!oi{<<D}+DEd!2KyB3dBoB4@DuiY>?_fqbE(A7tu1-?)Hv9)8;bo< zoip}4qrWV;aiO{8W7qi4Vb852an2(CZkLO`$k;n$Pv5hoJ`a12u~)x>`C!+(<7(_h z*mXWHV9(r3;;X*ql@ccldk^aDioFnf9|oF_J(Ky=L*Fp?#xFF7yh|khJJ@@uy^+{^ z>?0T62--vEp`AGo1=!~p`+Dq4jr|YeXCE)|9~T6=UM2OUwi3g5xorXqu;-s5_Mg$W zxSIOU5JOM&|G}QxM(p?ULh^GLssA@qPqnVZIZyQWOS^&dg7#3qjk9&~a-j?Q><*$2 zKIw|T?#G^kU7sg!Vo&WT`c>%n__yQ@oG<o;*e}OkfL--7u;*PM`o-vf!Jd7g*gwX8 zMyABi$PoKV?4z)!T_pBp*q38ZxmfI4Pt)Lm44sogW4{f1cBhj1dDt^96}#47r<=sd z<vF1C>#%2&Q1j+vPrFRwj1>fS2JNAJNi+LW_gaZxaHR;Jt|N_g#GZYf*t7Q&`@PuH zM~VI2Dq?>Jd&&c1{{nl>?h?P~L9vezdEhMU>GzBMckJ2N0|Uf<!R~TlF7}KeVsE>f z*tcQNy-)1=`f_pb1`o|YFkI|Ci9Zv27WUv{v-s;z?AcR9-w}JC>zEJv-c{woT<qCn zMBfJex7ahsO5tD1<v^=o0ik*d(D%YV9D6z&wNJ3*(AOgDnbf1tpChj)4)&%;i~fe7 zy-HxuKz`F2#fFo`9JmF2;6q7x33JOsUv!Y@8=-$WXb+u}j^><vh`sUPnkWTpg7#2f znTsTTdhod!`f7AT=)Wm}wnl$!&>qs~9wCLCMm^oJ7oH-9*El~D)qb?t|K#;|W6&P@ zIre_L)e0pF{=a-3eWTdx8++fNJ(M?li^TZ}hc|-u>VbU&ui~%WrQF1vDey<GUmdiE z^x3Q%!l~$sPM7%2u&>6Rk39|hk-a2-$`hjBg#G5AJv6r;hG->nVKDZZLrdBpAx`Qd z(RC0676<L2`4pL-^VhgJBuEJyX5t(Ww1?)C^0Cx&4fDAWd)873{4VixgZ5DTJQII4 z`obo1{#&7M)|>gyllaxD%Y~uXbKesCYV`Ai_E4Sarq0iU_E6rM>~9_PHE$7prqMSJ z+CzP%eJa9q`nnnYETbQcK4+2Cqvx<7Xb<HLkXLtM_bjphVdij3&>qU0UsdMtU!EJi zu&0fX_($;^crR!V^_y?%S%p4pk<?$8`di#8@pG<_IMd~FpnK3Bic@If+=ac!*hgcp zIZQi}K)J*(x>Vu^Z<FG$2DeGx%*(|7AL^NaJ%xH`E6}))=u@!=Uv`VX9>tz*^n2Yd z`n($?{%q!UZqOd;E7jC_RnQ*Vmkj2gUK~C6*e6bQff(9g|0HM+-M=rgru@KBeM5%e z@6Ap8Gq9%{`^DHZjQzTxJycH)_2~2AG4%Hs{qxv!jeS0G+7U<V+=+gU(bv60=9bk> z=C&_$yApfm&0_zJzDES@p?=>naVBFgH1<5=<oA#`FA--g_U!A#elQ!~@J@-p-NZQt zd%b&0p0{-DX~y0Odq-oxK4>q#ziyGd-Kb|Z`tC+wgg(8B+>bNRUv`(oNePJka0dNo z&>ou4?IzAM=rcnfcnE%7ymv7IJFw^fDE7CRe}}szenvfs{{-{-G-wZ<lUe4uQKO&e z^ZHAiwGuvXHuju*#IDb!2e4;<Aa;FzZVcK(^-nPMZ^J&@*!S))d9!zyIv4LHi66mU zv_j(Z7!7<Fw1?v7n>cH*ce=0S{{BjwtQ8VBi}|G8BY6wBPhV#KgM;=^{Oe7e@#u4w zNSyJ4z(({VjD9=zTw~v7faJ}6O#13T-t&U?P~KOKzAN_kjlB<XviLpVzo=(1_M#Rt z&sxOaXQ0GiZ{i$|{SRY5HE1t>UFP@22NHjz+FzCW3$d>wPMzT;=l^@q9y)KYn)B9b zkkr%I=sN`Mq37fr;!=L#@nZWvSObA0`M>Xj_E4Qg4W-``u%DhC`k&zU9VY(8*xMR= z&!9aNC+#WeD?jKR`g$iDdn1W|5e3y59J-nk$TV>d4%$Qg=9_-o1?|Ok68{q73?t6% zCeB3cqmBJJ?30ase$XC@pZcQI-;r}(e~8pM+vtx9+N%T_2GRm0-^Y$b|Bca4!Jayz z<o>>hy`{0gkG-w2e}Vl9W8W0C7uWx$)IX?7sO~`El%ZnJT_)>u1%Y8fd#L_))UQ>& zAGC+|CC9}7f;gE=C4ML3)Eg%8^Rb^o-VQ-~@%?DxWTMYqE^)ph&N%c-js7Y0IXuTM zM!ydIH%9-v>Wg+OR_;W9^1Y$|NeOH>`U|kP9H|o!hikEC8v9*AduYx%zes%jJi|xm z54*o)oI>pB#=bdd51sRR=KGzC?~{FLVb0aepgmOo6(-JW*hd@t;-EcLXWE}qXEkXn zaN2OO7j6@~zAg+7+C%YYnK<LIFE#dOg7(n)Imw)#CFs8~`i;f<Mu7&V-y=szoOILg zTS0rM{s7OV7pT9+NU1Y0s^pv-W537PTVS7H?B@jSq54zFn?n4lL3=1~{{FicTlD*s zt=J2U{nGoTp4le;jo9BY_CY~=abE{X{7vLtgnpsXf2I0V(eKIomS&?Q?|P#@BWMrB zPYHd1Gx)WnYB2%>(6=02a&8X??V)qnkbOxLdEjT_<UKBN9wkn@(bRu}*q`Yr4zsXl zju!i->SF&Dd+G$S??aq3A7IXt#Llm813B3928msNuGR2C(Pum=_65}0D`*eZ-_D$? zB|&@WJYQ}4-H1K!!IE>>j=kNOlJ<SZNZxenEPk65jGP&?hvMI3^nJ0<GWPp}_R>C& zH=X!JGo-KLV-Sq|8TRa%Vt*%;F8Fn5j?`1QO4e#05VV&T|6%k+Pe~lMC9nf~0Q)5p zE^zik5<e3=kMqC^>{-}T&<}lB^x4MVVyxJ6upf$k1onLFhhhI2d*ErQvoZD?#z~yK z)ndrRJ{5Z^`r^k<@Y)j9V_%H^phu|l8Hv9Td#|89w2yUiO78n0>~|Ua!`O!z`^=!d zwE4dlw1@7;j7*ul&beyv4RFYwXYB2<r(7fY;J5R|Uk_u?!LIvKfISy`L-b7^mH7F_ z-Wz+$7b1KM{rlK+yGdR>hug3h5=ZszCWIVQ0yE4UuEPF~vG)$zL;Ys;Dj9zc`t?Tt z9`@ZHD!DKE`MQ?IzViQ(_a)$!6jj@ezy~5r09h3bI4B5&?!Mi30hA0g12Zzr#97!x zZ~FE!6DN~|EX)j`1Y}cD;)aM@J_Q8?jLIe=1O(-CBZ>-c7!eWo_=$?hr~g}h-nzNB zZuiVE!1w>p^WW!zWZu+0b?Q{rsZ*y;okIC6`Tvpi>eo$nV|x$zF!@<4{AhW8k+^=H z;7R`BF^%_2`F*L!_PA2$=<NA0r_;|_#C28%eeU@q;ySzjOIZFD9}zk_tMz`wyNK)C zqq`HolDNJ_>JxvAcsp+c?nzw7lPomk*6~rPS7*=G<1^AY>FD`>J#n3FdLPQ?3F117 z@=sXr%RVObbvET=h%Y9tvns!s_$P_$?8=W2f10??vV1J@u8#|SoelYP;vXVDz$~o8 z#D7j)XJ^&;L7xyh1D}xo)p!qaoqbaK89q*2-(rXQN<WVi*SER%Al@;q)~TJWa<E;B zTtNIn;&%{dIIQ(u;92AOao}nmO+Ia<pMxp?SNx~o(_0Ck<#QMDfforrSH5Olml}kK zC#f~hukt5_&dfih-~*yAt@je|BAs1GN8jIhY1mBXw=6$Ne)KrJ;8W_0ZC002{&L`| zT{h{zl=Oc`yqh@LvHn5+uQ2GmWE-J>n}K&<l`YQ^;HuvCtwlZ;vfe)cSA1?CHMdLO zOWNDOt*fQ{!3MrN@v?#I`x*-k{Dc<?odE;a_c%rk{8gksX5ba#;|9JMc-FY8vHXNl zek7;-yMQaXb-!BVrpLn%iMMlL&QZ<5=a^4R`AJS7sEhRT<<AIivHbqT-;SS({s8Hp zPkiTV1fOB~8;M^;e4O;PKDqu{DL-+L@Tteu8?F<)i*z*q_Yxm7%Io<u5I2v9rJof# zlMKYTPpYx5BR*m9b6EQIHfzS9qvyq8Ni+SOZV>u5>8xgZ_4qFv<^O>4YTV8@@P8AJ z3|x=T0Rz|L^Be=$<LwFq-whp+HLeZ@uKIEEFcHj-<X_9-UW3lc96FDWv%iW$huvna zA^o;a!H*^V9X==JXNb=wuKTfbRkNJ6ew$)>Jsz}Pnjo&n&-tX^P5gM$KX^jw9c4h1 zBkI0>?{d_rSL?TF(%F`Dv|gRFx|vVi@AD1(Jl1QGj!46@cKW>V(>Yg=ACrDey#3f_ zxqX@V0C8RWA^4u^$5G<CA5S7aMqJwoyQUlVHtT+a&pE)e#>o`vOwJd6UO_%9D6i_B zA+Gg<*4u3hr2K^}{}Gm-B+f80OW%`v*x=`1EZ=sL&^bbWSbDz980Gc4(B7jZBNe~t zi^AvRDMH|W@}t*_#YTC(Ui2FHeWcTVS~DFzPtP&R>v{T71Mj$r{q;tnqy1EReYxH! zuh*BK8u+E8GyNu^^Dx_`^}vi#UavcCZ)uj#Z%AjXDs=86o#Ss-zu;WkD1RF9`3Alg zxEc?3AauS>I^SmbQ;hP{#Cr|=FQhY7Yo^n6i|{jQln;r2z`)N0uKW+(Tgi&kO@2ND zT=6-c2z_nmKLk8${QsWiJI|2v4CAibU1RG7*LvxYTZR72h~TeG?S|R=-QP0!)cSK~ zjg;5=Q|q?@(%1S;>!oqxre4~9O>_Th`?H<pwI0^?=LGS&l#gET4mRkV&vv!<3!l5Q zU0Uy*Zj{&d-X#WpFX`CBLg!BTQP%_CGRkj#TXw(f4P5o(^adet82KLtUkdL$TX5Yk zDqJ@0_p=0lJ<F@>>I%1soAP|d;79A9Ilawt*7LV);CenTG;lqSA_LdsdA))6<j6s< zn;$UBAC|I*^F#yJ{qj=-*LwK(2L3kGtMtHA20ljlPhKeU)b^y-!`rNFmXFrAZ3eF8 z@Nxs!dSkJHYrS!ffouJ6y@6|a-eKU|d`a5%Qv=_N_%jCn8sabSYi`$TfoJKBWx&<A zvOXa4fjN|ZK6ty}6U5(2T-#$~AC&TX9oPNUY1I2D>DVlP8tLeM>@v#h@p-y|>-FU- z1MmKFcDuA4-gdq4sr6Fb9wxq;{EUE(lEdVU&Fwmj<MZHwW_jxNdItW<9Delp?=s43 z`n?9O_1ma{Yd!V>1J~n!!oam2xZl9_IG-`_TXXpTdJg_b4*s_sT<2BjzE$L`$Cb{j zFil*KD=nXG&S;jup1&_OaNVwJ41DK1vd77*a`4yX;45?R-W>exIk+AVHyM0t`)AU? zwf>nl@GEoZe;&9R&(mKMIcvLj>#uOWf4v#k<9WuQe=^Ev>5V?p>AGL&XnR}J*~Z9g zaaRtVALigQIrt8DX7lq(;HtfCKNNnnp4ax_9R@#I-%c6$SvmCIujxN5^f^qeBkq!V zXMQTUUdQ#gebS)+7|TyGQ2JczpJON4FT~dn-}-LByB`tyD~Ml6ypy<i9WCph#3x8c z&l<fSeCd!zgwTq6g#Hxy-;eb5IyG#Rf12gHSg&sHy05A)wpo`L<=;ts+`#p@$@K>Q zF_c&RI5sWq)%&u&?#=FZ8+fX>e<|gw<o}z*r=Ad8>k~ciZZqoD{n-APl-KQgigaw^ z=ac>dY(UcaMf!T*s^xsIL4T0tCrRgU(z%y-`>&*4-S2vwj1kx4M9;4&gZ}<s6MhEB zkLF+ZSGR%d_4f&b&ZkJH?eS)Q^!j2AH;<qH_`1|P%JRD2UgBd0{$t|f#6K+6SXyuI zXwcX8z(NDp`f!DTYrE@G1J`!Zlz}g~KYLuQ0<QXZ;AvrSTlSZp*V`ERaJ2t(j)6Y{ zI%-~&4gAkJ_3rRr99P?7BY@8->HiT2MZAj}8a<x({DzbtW8mjpmj5L2Y2qgnzxta} zzMFI&C4R`a1n(rS`%#a#dky~QW8<vkGsOe>)cgi5Jr28GD*S6YS`QDLxjk!?A6m~` zVc?%gH|A~D^#=Y0;92X@H_1=u9#XHi_qKh2?Io_~>3MJ%rTuH*+8=VSQLnbcy>-p} zYdgHlz_<EdHlKQ*)oYZ08Oo>foFn|7Kq(#hpy2HX3I1~8dYrE}=yZQy%6GE-UpT*R zAl}UcA+IEzm;FG>j}xCm{DZ`&i0gjTa=5^#cds9^UY36a>F9It+l=z7QC`i9hYehx zkGHLFmh;&xztF(n13YUyXuUmogvjlD@^cOO93`&DiPrz)#C3aL_mH$}g1BC1wf}9{ z;77}$%a(ez9JKx)AbuG6(fWU!xT*i!9HFE2zupIp8ujXVH_7svf35!~3|x=HD-1eX zpN|>kwLTvwuJzA_kdNxe34_iR#9zLlxgS3ZJgdL%qnyW&llDGJ`Rw<w$bam3!S(#z zEB!n2l^OJ3&+?t~rM%YL+OEFFD6i+yHfJ^SdHs)a_yn%zskKb#>-n-T9ODYNiJwpY zKS+FXrIgol)AqvzaosMxzRWTBxku9>eH{<5?N6lMnH54G+phF;Eb)m`1+Q}8zFn6O z1%J`jQvM<0<ALBI^~NDT75Z%~KSKH!5g#L7CH^RJn}Oas9^U_%&>0vJ`fnrsi-}u9 zg2(d1`o6|j32>OWN3BC1AwS)MpGP|S+{!lOrtOOP2CnDtfPrg2`6ULf?T~Q;KMVY1 zjpq;N;5U<hYn|{vmvZa=xwNZ`__4&bA7Ij`SNj2eZ{W^!Ha{ok;Hz`+x98xW0iLc? z=Lr9Le!0I8e44m!*PX=ew@Ud(E&1$;Ulg6OQNdS{&|=`qAKuRR?QK|I+n?=5-aqZ% z=r-_+K_{zUwA{vw@}JEquj}3BoM!#-Ku-C;<luY#lJdFiMQMxly7Pv|1aBJ?oav3M zTZzxSPw-E1p6>rEDL;O>;MWs>C-JT;1y}h!)#qvAV;>iMSLy+6Kerq0((C&|17G;- zY<czqSN%ABjnIFKRBL_q3BkLr75s4GT5m@N{k?yiP5-qycr6FN2zaW8C!}7z4u0r& zf_D<<aI<v(UTW~8{Yy_6_&<K1&8ODe+Z*{I_56LQfou9@1K;rv+4S3Ua1VGoADOsf zE6RB!r~D;3_(yVZy`MeB;PZ1i<+VJ|G0NYQQ~n3Q75}66Nq=en_x_{kfrE{E97m@3 z-mo}iLC~|ZN_=kvzW{ia9{2?CwBD~vy)osc`|Bx#|DWd2d4_bRza?}oCY>YxlwGeL zC$^D?XK7CPFb6*uxZ=NSTt@PnSntEcJO5K~ZEtA5$CMFQyzPw8nIN4((pg8`CLPm0 z`KdwYDwJ38Y4196yOe_N#~+i<=qH7r{YYQy;U^3_dcV2NnC@Bm!hwIzmS;H!Uy_6O z0#|agzApUiAwR4qiQC^6U^nu4@PAABDdJ}kUr&7WTT*^^;*-SNi7zL<{a=L6IPqn~ zmudW8LgzFQpY>ki7VF)E<$p@Now$~B-;+YWi@3w`JN;GgG2&(7Hxlpqj?_C%{6GFC z<!uJ;9ZURl;-kb5BmM>A6U4v7_2_`V3!Q-nDNmUm))mC<#|8fs8}M`D)4vw{e$wCn zDWNm*gy1)8euxkJM(}SC{}}Pk-wM8x_>YK>6Q}#z+Vvmg^Y>DIDa)Tse3Ceig{%+j z@_&@_8vhCL={;nD4cU(`ds^tX&q(=?u)S|0-nN~T=k+%0qr@lwEae$qVEvA`{TIP8 zT+>hGpF-b$Qt<sL=QB0FqtMsm{6XSff0Odtv%lJ&5js=5OZopGofX8p{~_hMoLe6v z-u8^(SCF3{6Q3ade&YN6kI=XNL+I~9IfTT!{zvG1g5^I=e1`Z{#DAm9(~wc;=<0Ly zzl46*enS5jq<<dq&Q}ON#q!?<p0zGKo`Y}oZ=v7j2%U3;UF)^P$BKe$`)xh(fr{YU zvEEyOXVv?y9Q=<t__oltS#;WS@S}3@lXCDga_~!Y@T+t1yK?ZK<lukL!FSs#yS<0! z;0tr`C<i|`2fs20zc~k=%E5n`ga0iD-{D2s?cFa2S8>l-<6&M79_HZda_}p2a5eX` z>b(Qy)jB(Hiz;DRC&~}&zkw?|;lU?lUQqp5g{`Ih)Kju?IhEx<M!frAnb6w4I&>Q; zKe0e?ZJ(S$yzNS%qv>BqeDY!`e=O<mv#rqS`l{gXA^t(&iqA{_A$$_H9%A|FyJSLh zn+3H-I`f+OTuyxE2ZHZTLNDKr<;mw-;wKWH*j38!DL<?)67PPO)OZK=$rHrKJA}_O zS$@IxLf^VY0J=}C3yIse3xV@l@9&6rM?y#Qc_=Qhr*`r;g$|cB>wUz#J}(4#&C+^+ zc-tL9=hLKr=nmwE`xL5AtEzE2isW0C^>gB*<R@giPJM~cX}?l{KkO<Myp#Cona%ya z<Bn2(jQ1|v$xn&6^?=Ah@5gT=-bO!$wsQ{LN$AX6FXbO4oiXB_96y@>9}%Ap1<~VV z<<3H<ZBqExa{dHy{VMLeN&jEOr*4+=T5daG0ag7nWea`=|FD$!*fmnGwofi2K6#9k zKZf)tH9jiked7DH3H|AJ3(je5Rf&%sE_4oM`TK}ZJR-nbiCY-Q>G=7%0K>$OBHneV z&{-)ztow*h4~WE0B7WFzG9TafVi|$D-nA*dhh=|G_6vKH{^x+JdfOfnI+u~o?}>L^ zB7pASlaOFXm7m~#=N{7O0lt;BhgF_vrhgsFo8#@6mkJ%5=SsVf&Rg~nynR~g?I(UU zaHVIQ--w)FPW<r{-v{?uWaf4ee;pKp;?u_8)n^Xzj}tffDeWcYN7>#rl*8G?C$^ID zd<W@F16TZf<4?lR%ZMMix6skAAit0J`NXG&r2HuH$B9qeCAc299s3BKHqQ4$SbkjN z-xCJOruCwIMg9j<{#ws30IuXve>Iq2xQ6)569RNe^Q`ulk^e~nj%2;BCq8|;l!qCg ze!fq<&EV&-mkXUv27qY2aRc#*!-S5W?|rWj{<k;A=LB%YfA_zn{5x6i&h3JCO$miW z{%jpZyzOiObiLOSZ?{FxduTcb2%V|B1^*iHGl{o-Qt)%-hjjz-?w?7$FtgLo-+-&} z@UlmxAjN5w4x}9TYP22?A0|FYeoi2rM~RQ!C-i^Eh52=_6guOFNV~MZ;zHt<u`b+B zd};&xkqm7;N926ljWSPd);k}#lJhkCy^r{9#LfBg`h%pslllTW%U=py(HXl}Dx}z~ z-x8l5lXlr$XkYazmgg(jMfT%6h<D#CKs)L0`D)4mwW!ZhU0f8L`!o^;M9K1s#Q zZJu>6@hRh+?j?|~;(z?J!l&kcAL7$LlM1zd4v9~mFBLvXe%?pC>w2LxLi}otUoPcu zB;NKK=@<Jp>6dom%YZ9>CQcMOdvZKXvHZmCQohXcyJMYD<<0)OTH~DWdb};bJXGbU z=ZZXE&v9}E@y>gMPpRFqzDa!Y+k*dHepm~z&M7+fzojIXH|tX3W0Bx!e){<m@iy8y z%gO&%9c=H`Qc#b>qltG;2>uh6zfj{w{*7M|pE*s+YkT#gBPgGF!VlABS~n7(;dod; zMZC35`MgBvtdJkpJBUxxZqa(?LWlGX`|3X8WAxu@dwVxm%InuUD{R*s;^SE7)kn|w zw-BHDri@HX^Yrs=;`Vy!!1ofLR}lK0+Y6xi|1aWQgF;7-!=pVZZ_bOi1GlW5t=m>< z%U0^WoaL<_iacQ^rJtvWPp=XBy9sQ)+ZX!Xj|p%n$J-+*zM~cK)lwF>9%K3TwL<tw z(mw`@LXEd^PB?vDa~|>TFH60jA)%iES9wUbH~ijDrT8A!_BS`%Ek~Aw{@6F9U7G)k ziBEIf>UH@i8h?>6xIgPXsVsCRJ}>x1x?vT{!PrMEB5q$P{O`%~<G_`D)p=7hpT8hJ zMm^BZ@~=En=yy?%EhK&f@d@J`;Vj~#*te<A3d-3!O6W{~PXKM7yq0+PcccR^C;hhr zS9}hTPrbg}o8tRePZ;MEFF9K1cb+Wt*R$Ra0atYPHrn+gmTw!CdWTr=zOSV`?-Bw# z5#K<3dQZW35V2aHB5pk>__tYp*VhT18TFtZJ|X!zpZMrM1UQ4`zoGG4g&*zrTa5jK z8lN+F3(n=vx{!G19Wt)IPda0|{G&quTf~1xe2n{6O=piz(*LHE?`HXVz?Ix?Gvt2( z%bV-M-gAYHiQhnciu+$}PyU7Y0OMx$zTmKVs@}b<nLo?;Bs<ozz|(oUv+$|M)&0b~ zJ|uGfA-}Nee75Tc0>Is!eyYUB9*}=)IlP0o{j|{6`-qzskk0Ew&g^#U7r>Q#rf+GU zN3T4N<)>wY7dg<+Bi??A(ARSKI`OWz3H`rPp%-Czr2T%Dl;4m1e}?$jYT@J-85Y)K zz*Qc(36|6ALTRDUv5pb?a2Kbas>Ye$L+_8S0<Pi#?&th!XZZ(Me&!tEN82Y`FB1A~ zw8wP4cMu=AUIcJ7>HL%U`1L|Z+YiOp3!RBh;q!5pkBFP&>be~Km=h?sF9`ih<cD=5 z@qsf%ZXW6HvRKO7x3N6&qlu3)udE&?XArlz&-xt8KL}jO%{KJXwkMMQSB1Xr_Y;VZ z!oE-+Z7+R*_`v;wi!`w90<Ol}{dYHyx1E;={n2}+U6+xcKHzE}@!KZ_*X#ZS%MY9? zlr=vuUMh6V{nRaQAbrCQS+Y#<DcYsG3A<J|@fq&3w7v9A;+-7NE6L|=%Srz-;nOGn zC*qy#K+UI*iLd5GJJ-Q?vHaVJkI~N8<?kat^WW0mcXEJkvr_0xaK7vFtd+o(oVWi< zvz$M~^5!@^>?HDkqX<Cnb608HklQoFO+R4;>z3-TRrE_xoYvXEReQT=|6I!UK0|!! zG-=m1{KA_~k@7a}{9%@VH*iJ&wqJ;x_aXir;_qO++D>jeRmwj=zp);N%YZ9>%yF{o z>4LX^PZ-hj;xyu8?-E6&`(>Q?%&P_0<MVOi19u6Xx#V-NHwpbQ_7|IL)re2B-?d$F z2JtEKqwyPvkN=m*;rFE9_GW4CYw3s4exWx2SM438eXjMu`-o4SC3H?Cohjnu+>h@? ze5b0=Uqk=4mgiF7ivECl2pAu|>WvZ~|D4c2jt%%R@yQ270>2}Dx0~|E{8pbI6Tg(W zId0nn#m^piFSvP}hrks--NRC^mfKatZO%vCU%w?j$@N|1c1`HC-7IwOWruy5xXI5E zp_CtI|GtF$pGDjvuH}CZ@zI-vu*UsJ=uCCWxS|<tT|#{HmqJ*V|1xkjFZTbX@Tu+X zf2H^y*1?8+I%A=4Un=GGe)(g>CmDC~Ci35wNcqlJ2%m%O_zLj>Zg92UdkgV)t`}OK z6Tnq}O&I$B&n(}@IQEaS-Wyg)`6p<<wG;nSitl7Cd`kGYi94%>&k6b!^*$vcKF0C+ zU6#L`_!Q%Cv^=-(5jx|P&k-y?7r5g83WNU(SibFT!q3hue<$%N+STo}bB=tA&>1)O zFJ}W+<92LUk@GI3v)vlOrw#q^GU9D)@5fmFbd7&iDip3PYm#{97li)xEPp|-(C>Pe z;9w*D+z(uht7o>AeQr0)zj&>bpP^pT?X3_u=f!u3x7{l<@dDD>p^tL-a`XIM3|z@! z>c=wB-c7lEka*`0g+aYfxrey99&Oi8xxGi|+{$`A;$6%itLJHrxan8C7PzuYb-aQ; zFL;{eO+Ejn0jYQLF5$DpdOt|q^oReI_{=+`Jk(?QshlD5fB6m~f9>Bp3%HVx>Bs&# z%m179Qp9=>927d;f0L1**RKe;qSM8FnfAwiin!U2M-55&PVRH{`f@+<c0<m8Bi=?o zhF-5v9hQDCb3c0u`TPj*v|S8TUqbvb;@#)UK)8zd{v+gv{@&w=pGJI)=P8G?gV&uY z<=biJ-^ucyCO&bMj1w*Yp95F(ef%dfKDFH1)(PHb=+$Mw75}4L@ANwO4&u`nNyqAS z?P=ns9dhkiLTCI~DSsXL-0y6`Cwcy>?V|S+Z~L6^zqS0Zz7AZ?-|y01(t2|Hb0~*t zA^c5_xB0~F@5(r#TDLCIxUp`2hxjxdR|V2}>071VgMTY@4krI60Z;q)7AdIp?Kg<G ze_e2Wp0e}XC<p3|*OSgd;-mLVdF_Q8C2pQy{FZnZ?E&2{hn`FN?-4#9B>gjp54=dm z+W_tDpAqjg&M#g&N;-_ge+TJY1YGHjZvMNSKYz;dlM99aWi(KZK2PXObV|K?{d$mi zCl_8Fr+xJKQr;Sq^3n>+x?AHLgub>1c6qz>%l5Pr_8>oR0IvGQ-2Z-!`1n0S`712{ z>I<a2eMPg}-blQYcH=UZ|4-sGw+cUcJ$+i^H^_k9P5x}{exb~-Yv`9~C!G~3zLVAc zAJXG*Bz`&Yblw^Jlphgq<9K^B%g@I=ROM~j!zU1bEAeUiz4d&*m-smM_1d0%l6c$O zMGm8!cZXk0`j~&}!)93@BR)e1&%Ug8nt1!!Lgxg2;pLcbiqA>zD>Xl76CdUJz7xw| zOMJjs_YcClqUdzLN5;uZS?~IH3U2E8onQy3@?+fBXglNs#HZgV4P_XF^;hDiJ^7kT zWxRde*nh17uINwQFN}Xi*s`u7-g%WUsMnW=bosjluaW=ucgr}rjs9vapAdN3UizyK zVfnj>x6@8Li1;(4GiLa~Ui%)QGjOxCSL@rQ#3yN(YkA&DeCDH4evs`dT_$u!>3^HY zdf!RhW}L%P;<o}<>&_{LefSj1x8Es*zsP=HHYW7jxnGu1WLeh%SN@z%!=LjzmLKEz z*LwKB-%CCp6-Kn4EWM9%;Qd^!mp(~+jQEx0|JTH4sJBlep9j95e7;TiFA+bLxHT;V zv|f5I@$NmO;7z1|C-KpL3(h}VM}0u(cl})OfaT95K46@$-AUZOSIWOseprWpQ0R2t zD8P}Vvl{qT*6!BW4I&vWpU<$o^&u(W&h_Fk;xml<x|(!$xm@Vm_egoYe!Z6XB>i%F z-d#o9obTTQuFi3~c#cEz)*~$6-7WOLs`&?h>Abr}0DVp6JH#gf8Mn8y{B~DJ`R?Bc z;L(m+M0~1C$}>&8^(l?7l>Yr8<?w6b6P%B4kUv`oeOTzX8~W-B;sd)1|61RkeWjFd z`;64P7wOytT-iDMab1&dS=QfKe)?`f4q&_7k5CSiGE@FW{7T|xoX<8N75e)#o<Y-p ztSEG*87KB{@^jzCO6RLxf}UAY!2-}p<&Sk$eeMz1I`U)0+3(u^`6TgC<KEnBKQ84* zVUMWKC&<v3h);1L<+V@i6)2$UHT|pSYTQ^i?;$>Yi^zx12w6`NpL#?p)cUY6F7z#~ zj~{2dBI46`O8K`D{}6F=zdWVO8*!3b|0n6+B6PG=&n4cqR0OZjo3{F-l%HU~=<+)d zAOD%qk^fuPSsJH4)cSn=r-aTJ$B*8R{8r<usA);)h^wT$P5Yd~-})$VbDb?-E#*5; z7dmY+tgRm6)&~TiPeK#K2R<V+0?StV`6=;s`YZH0SoyRXw|Livc>;BNgB0J%`orIa zzP6)21ze4j0mjp6eCy8$K1F+GUlKYBxSDrQaD89I{ym4~$B&nOd64Zo=o+D8#w%U` zT&;Ic8Ge=fSiXyX8*Rt_IR`)BTGHpcT^Ev{Q;AQ0R~R{p{9guK@qgSuMGmL2{C8P? z{A(iT*AU<1I?CY=0dC-YKTYF56I_qC_W@V*x1!$ImvkOv`Oe=7BNVr_?`Ng_Hw}B~ zbl|FAtc#>VK0{?)PJFCe+VwKF>+i%T8DM)b>s@=j&>4MN3hMEB3-Qh$NI}i#GsL?X zPjV^STev~!Ow&Hp<81@+P9y&0N5p3?7C9fx@vuGCSJkeGn}r{(=l38!MSDrdyUr&* z%J&vE|DV@5?c1#=hkZXM^gDMFU<L7U;%yHR;E#uZr{{)@pVWSd-6n*NIlqo4KK2a} z%u$rjdx&?I1X#lXaq#Dbj=9hJ5b^2#g^|<QUweE(%A4(d8*nwQ{zgBK9&dNEyhVSt zwojhcbSP)tUvs}G^v52S3ibZ?!^BO0+SWI*JpCKG-lK`n{9O3A$^Sayrrz5He5ih( zY!~@JJ*J-l=y#<D78-GnUjVMkk1vpd+MoOs@zKRX=YGontXrl0DEIq%T-`<7x=jWk z%^B;++eDt*8*##K1+MDt((xx8x4$4h^A#D-yO96=za-_y9+&oLe$F7?ZmbK}67QxR zcs}K}%k4tP^b6g7hv4>iq+ab$+vzKUPd+0IewlO@0axSXD{NPl_&ZsC9QLXD+(`T{ z#7(<v4c2c(r;GlaE|$Lmcq*U!gwE-d!>@>Uvb{U7{BCzi`L_Fn|I3IE5}%k70x+M_ z&z;0a?~;EnB>inCh0erP(&3}*_W<j(;>Vm{4-%h&K2x9hLeAP5a#!W2c)woT+m){h zZfz~)^*;1w;wJxlVE>@#jM84!bT$wl<N5m`toLE!GdGDGwEe#e<f!O$(%w6q<rfkk zHO{-QCO*b-{$|Q&$FB*U>G=Za@qZEV?ni{M)(>9-uKM@aPYXYKocvSM;kg*qgmv`S zDIcCY$hR!(Y~YH{ikC=>I9;r-5Pv`8V|BgO{X(bhRw?-rws$>oQ*Z3_Us7J_3HA97 z%fAP>s`snLy7>UhPs|ni9H!PYEPwEJ!sh{`bIdn{&MD+y+k58$Py6M&Qt!Pi{~h9O zTu=8S{-bXSo$vD8<WS=KeoNu7a|}Pj>A)5JnG1!!wnP4smfy+xHtn=_((%77<)_D_ zyk6Iah<DL{J|us(t|#6(Bfx9eF@GW6&U27glKyMHBlO!I65tHdIg9ud)?4*?m;Bkf zn|K%V=TIG6pTK-p>**-h)A=mF1LUaMtKP>@pZ9SgKc4u2p|{^b+|-|cCO$>~*bZ!0 z>3c$dl5u@^OEp#kT#b{jZ!P`KW?9#;yy-V<e^B~s)UZoK;EMmLNg@0s>EA$n`~sn@ z_4)4Km-1sjkePT27oPRR2i6JW+OK;9aK)!NU;f1M)Bhp#SFiyiKM?xnxza-#52au? z^<?#jQr?_jzaT!weT3HA`@v39?KSo481czRgud2$9S=+S0qQYrr+uHe$!GCLq<@ys z(fhAa;A*~f8s{wcu>2&}VfERI3g|Dy?O#fV94|jC@5e%ahWooU#Lpx?`cI+rJ<8{Y z#JhN}X9dgu4!G(Ub3Pva6ViXH(9!nE5O6jAPtkF<@@H$?pR&Cl7RGlYehl&P2Lvy( z-gAhX_Q0!QZ>fG6f3Xno$o~z%6`!a6N$BYK%s;Zcc|Rqbmh$>sfYn-816TAXFBSTq z<sV-43&Cy9cir!AcvNs~IMb5s7VBNW6+Z>T4*5=s?_sswDl5X?q~G>Sp)-y3R(<rj z&$+~{n&4k&`JEn<@>7QiPIJK;BHqq@#G6_EYs9-QlJXZ5fAg<|&cHds`I*E&LVSwz z;$Gs95+60@%l?m34(AD-m#|+J5bwHC08F>^^Ilz^8|A%--%ot}3sPS1qX&L1^e5jg z1zFsB^%H`R!@gD@ZRhs^SMvWd&rP&_KEd*xPfPhZ>9;KFfZqt6F2+6TefLV@?Vl1o zMsv-27jQ+t%zdub8{cO60q&2q9ktJIh5i8SGWF5^-gf~{?f*NP$HRA6-W<2b{*HWN zT&quz{@=3RN_>=l18r}7PUAcm*5lLrJ>_<^=;6ai=W^oR*cYnLPl*4Fc-N;z4tvO- zt&{&CbZoBUdR#q5eCiPC$89+t4*8>$H}4(aM11lPA^dLA-{(){^PNKAQS$Rn;-)@- z1=f2te@(q{|9=yIv$Pj#JpCN<m+bQ2`>XWJ_PkHm&U*Lw8~I_pkRB)J6Q4Ot2y46O z_r%9wAE{4w`hUwh=<h<urXTo7;%^{6!MGsp2e6-#@wS@reh0ApAaK>*G1~LT5PyjH zz>`vM8x7*Vf3W=jh#W4LKU>!jpMJlL5PjY;L%e;16ugP_)%;QQ+8obE5m#}U3LhnX zy<gr7>y5(48BeI=X5T`*n|_$1N#~=)ExsFg0`aFc9on~g-FeM3LVxB=87F!^ew_FO z?d^r6v;Y5)Ps0y<3-QU<Nqe>Yt$#^*(;m2xxOqPQE8^oEuzEhe>fh3j7UK!^zM}`Y zlF!tSq~3o@Gpw%>AK--e2>WXrlveuZkAIc^(t7@Q;EIlUkN#D-zpC(d+7HtEmUS}m zwgZJuI|X_Pahvyp^uGI7#K$ia3JK-8H{u2q{kBVlLEYYqiFe&2IESJ2CF17%U9z>% z>H3zG?<W0oi4Uw7KChu1?f|aj&`)`4`u}2i(~s1*4duXbtK~33eBx_D_yE@XN+>SX zuF<2U-aFdm4*~H`?oVII^6w@-@mZn#e&Qb?ZoN(DpF#d#j07^N+_>&bEzsx0+hH%L z&%LDc4d80Mc-UAkcHE9~J74PkIR$YU@rkd=fO>#*p48=;=S}ZlzWZX4=Q#ZyEN<<- zgU~m}`H05fCwzX1?fN2c)h|c$d}>J7%knnwv*>t<*T7&%<-l>G_3Ar`x8E;>=a9~K ziFbchB=&CN_Ks5TI~f0S1o1O~EBfuQ<J3p5Q+E=d7!^9)rdWU1cp~LJ%JaybME>1| zzwR91ivHyOQvPME_pih|>A==@_0pZC{0!_e_0jE`1g_#|4(9i@Jv?U@Y1bt8`+9#7 z15ev^xb*KS)EjpaH~pE1wh8|a-y<_r+n;NJD>~+U`5Ez<Pl$Z>B>i1?mGV<OFX$k@ zONm?82=Fc9*Ak!L{z%(D`|j4<E*7`mnBwpo+||tIM}aFo+qfS;fM0lsxT#OhMV@X| z-aH?_o%r~@(jXpVSbrzpd7ZTPDE7O9^L|CAo9F)WSIc^Uc-!$Z?>Z=-zY}lYM*3Ip zTi*&hEal(ui*5tKDtv}^tkz?%AU^h}G*qNvSvBI;QlY=icJlXoi4S~A{;lP|KMs!7 zd_0l%gWkVXQylljjCj=l1g`io$HPnZCZE3$`WMO%>vhE2&l7$=CO@pT#K$;)bzJDR z#0SQOz+Wl1$AK$8@1S4qP|`nmAE|fp%|iG-;uFLtD4${Cd+sac2fi(YwH!i?8~c|l zh@1Yy-CjmH@Ss)4#l4OA*gZmj1MB^>E^pWs7rk8QOy3~o1D3xVxYFlc#{JW+_mlE7 z^xMzngg=J(1otT??IncHCEmvS5totvFNk+8lJU7C`(<Y&KvVrYaG>z>0pk6yV0#Vz zw`nKNeUsKdONh5!CIq-_TbB}_ex2ZSt66supXC1K0P^`X@$Oxvyw<~=2W0c}F!342 zDe3*=O0-9fpF5wF8G0D$e+am0Z|4m{|G$WTkN5=dm)$OZwvK$IlpmwMV)`8G`@j|b zr|4(U>)M{M*A;#9KJ~@KO}p_K;^VNV)MrQXbL>GvXPo(Dv^{(l@ot{KAIS1|5}$dw zF#coWPY@rwN$`7#_q~ekI#uxZ5Z~$5<bPZMy>IO#-oB@lzn$gZ0$j=Ay?+!r>++w~ z<@Xm2HqG*T!#}Ia|A6-w^t^r}@%^}umRc<9qrjCstu{fl{yY%-$yCl<cjl7*yNS=x ze$f0p4P4EyDMP;<{TeL?nHNP?{9)oIot+Mq^3(IApxzgsM!XYtnfjc^f%{S7QwK?T zZRekUn9ynG{i7Sn|8>MWpOEsJ{|eUit*kw*nLlaGFJCwoxRS%<m!;kU`M-(y1ozR} zAM#J)=K6TiQHl<BY2##sKR$qkOwk{|Pw11p^)rprkbIcs_c}t#cbzRI-%9*u;-;PU zQd`PT&>o9e{&eE@XQbY%Sn*dJDL+QN^mCSf5_o!k&3KR1#4mGS1S_ibb9D}Wdk+4M z9DMKBX4C&E%4?Z7*8X@7{*OHRg>3qV0?(p<WKQ|69K0_Fe@6~}T@Kz?e37MfV`F>o z$SMDm9NhA<+qDbutbRNo2QTE{%X08I2Y*`*{@xt?I^gY%0^sjo0-n`h-_N1*>m2;w zIrt%dwtSAv!B5P=-<*S=13ZiWv7GYP<lwjG;E&|s|H{GJFy6Ap!<-zv3_Oef6LQM; z0?!)H=L65`-;d|ezafYIWDfpB4*sH2HvhW=&y+(>`C?A_MZmM#^?^z@{Sf63%oyhv z=hS<7PQ5qh;E(3e|DPQC+m*BV+&2fGpM$?C2R}Opzbps88hDm`ZqF(I{T%%FIrz5d zm#p!;XHI{;ItM>82k*+klN|h<9Q^$`_@{I5TXXP-bMW8i;9DJ;Js$P}o+Y=#bIKo| zgTE;UKR*ZmU=Dt54*nJ3S$t0Al>b`}{$kj5S^D9i9DFYDta`h0%CF7A-=5+yg6TK= z5Ou|+Ipwbco>lKHIpx2fga0}Qe<}yx<>+kr9GHX8&B0gX;H!XVwd<Um@|We{*XQ7O z<={Wd!Jo;&56Q7(U!Q}&F$W*Y!7l)wC5QLr;8*9+`BF~#ujSz1&!O|{9Q+?S`2MfU z=Kl!bS$e(`c-Fi-IS230!OzRV-=BkDn}gq;gHHj^;@?`;8xOASD3*#*t?YV-hpR?9 z9LG9--n?qOK8y#3tHVL9H+HS+X-oW|x3@o(|Cek1>#NCN96P1eL9tdW*-^P%DaN7e zMGH1oxaKB>Fm$3q=oXw>R7wkbVgF!U7#JS(+-R_WpxV<{9q0|hc+TP#bB2baj*g!G zj*fV6uz#?lV}bfH=lB(KP_t92mHlGiM^5bdZl%0QVrdIHI);V^d-_&&bSzJQl31l& ztl3T+m1|L42|TBnm{Tmau%_4(`E~U63=PM9b4FZyPB4`I7#tZIhHN`J`g)R%jwL;b zs-~l3+1!(>$E{p4FU70LNMG2|v2HLJ7*Iv$jFf6~(*K3M{X-*zF@BE}5aF9r#YPLU zB?ZS#qDmY&CEF{P6L&#Ne->I0C+*^TN4VwI)-F2^ouNf<dr=fdZs-(zuN)Np);gSG z=HT+w=&09IX_cz(qYX+la|c5u<vGW8%~?A#+$h-U(1xLo4oX@5qZ$nKsNvBISuf~2 zQ^|tzh~3DJYC+j8lq&_>PMUkxE3`DV-gj}|nH?QV*Y(8_DPqvo9Jg33x?$1ryr@|A znyF<BlXL_t2E+cfYy0~;I{N#<xT7N(8IIR?bj<5tJJ1^s_w@H2KN1W^WVw`-YDuve zx}~C93o3D|cx@%e0%#Y9R}aQP<YR6Iy<QRw4LgM>Mo;x`sGb@0j;JYGj_ssSies-5 zIhCY<v2D(9zXi$cKG)K+skm_=jB1Xk3_s<jSXG_1qH!9incdM5^ld<2_H9tDD-CZL zh^svqovVG@EycCS^((P$mt8v*rD~I7&&sP(3&J(SgHQ)<v07EtSL42@I<&ffaJX9k z8>l5g(MC^)C8t&_xMk4>idtnL=<5mBV9GmAEncOxivrwobt4lF1jAY(_KJQ~DaT%+ zTrxDmCZ|ZHR0;yuu9c#4l6VCfb`>X;Q935-Y;|-ru+`DgrMT+~HuUxfkrL?KbSyXM z77=Rt^^T5X``4csuN+Wi3ajE_)!R`iC_$6e{6fV^DwR~MFKET(;b2W%#hReH0Wx!n zUa63{aZ;$E_RJwu`QO(Ab|ndmH7~Yneo{`NV)M*>wtAoxf=bPe%9Svw6m3k=M#c6# z>4BtxIg%t{s49wz(v@}XnXz1IS!XSmQ4;$FER&UDu@n^|8IXCadNB;6pyqmoz$;b? zQN|+TSm9v*5Y{~y5MCT4Zl&g?+Q7^EL#atbZn;(St`3G)*9QC7K}!yW{R8nTr4zAG ztKUUGs?}g|*PM}|p0naP^XAOKs-#zjhA$5W>#)`a>sBc1C0#-Aot}b=Zw&RU>I-_S ztNZ)cR0p9Apedo8miP7#&so-$E*a_1d2^mGavdF5&HG}QOZ{uBJ<#@>T*J8tz^W<2 z7%5g9j5G|-<`IUTY+1M(Sk4!pXpgn=+K!I3LEi}0+YMDksiWgW{&PP5rG(Z%?zst6 zt;Oi8=aXcMI!uL(^;F4P36NsnTwy1bg75kTXwG67VI;RMkxuIx>6EO@;pEv#5Er93 zoessOQSZP)Zn1GQhve#@H>qM(U(?aC5Wg<QZ%TsFef<N<WPov!{#1A-BOP6XaorT+ zu=0X}U8#9RyHK;kI5G?v2W#ka;xC(z<!KY=2g8Blf}8}{HY6oC@JeOB92N|P{5+}9 za>0+Cxa_+HuNK=OI(99#6OL1;B;~l#e5tF|oRwXv5Acp9uILwQzT>&&xP-k=0hY!< zFsSScbk}f4u@GY;5hh|8rFL4Kbj5BFZeD*jkc8!^tf&U0qhm#C^%(;7+^}N%o?Wz) zxBx}p#F$VCJy?JkgDH1@BjXu=Z&uhvr-k_jma>>!2z4$hSOkX^IQIS6P28YT!Um;T zqm^6fb2D&ejJ?1~ak>}SM3u*mglppAhCx>Hi%vNyB&8%NmIKdNr^~q;5Lh!YmL8Z_ zYIbd+)~1GXltf8bD!4IBZ?{wkO0wKKMU#@_G$55ap+aB0PFYia0<Bc3`Q<3UrdjsO zn;_yiOIDs(U9oW4g1PgTgGR-!L{a1y3zZT!YqeUdYJ(cXHoF|UK~RVb>Ci~Wtz*MR zM(f!PVSjIL94f_wtygUr+kdr$VBuH<BS4iq0b2f~RQ4_Exd%l$I$+254CBk{U%{~2 z&#SMh-_*CfzIeSdVA1GO;0JM74obDKW^`GpRY7fxKef&c#;HGnrgh^+%Xj>!7Q2<O zgnfhWi+l^ub|a%)8HKXzCzZeti=m9`XHBJ6tHnVHyVP1K3|x=fp=ZlW>=a9$7bbqq zEqZ<u$Q*OiepJ>{#`Y{(JKWJRKdz0eQoT^XKhX(JIrQQp2qkJ1ds|G$b6hmYE!%c2 z^dpZ-{@L^6yH4a{Z<iDbMHjZ?mbS|e;kXEErCOmBRZ3glt|C-Q*$ZlsSMnW4FQd=C zUFFzMJUei_uvn^;)cU0M5zn4Z1si+Uwu>dK0g>%<4CZd89lw8Mcwl6>n)LL>eZkt) zO;Eyau~78mB#LaTkj?73(yE?iT^fvsMtU)VmZd*aTSPhS27=+$YQ_z(K6WHghIgJP zkNPr+%0<uhOPEM7cq6!!woDK;Y+d}YY?u6UB`Am7Gd+8Oh9w9iw6R?(RBYGTVmfgd z`agmjAr76mR)qRh?eaD~A$x|PwNjr6r=(Z$ia`{6c36(xu*9LVC6r(fd7<Z*usFI& z>^Al^W`Ch?WUX(f466M~>d%p`ZqO7;!za+&>L*PjvT2uts08KX!3PN~)TqAkegEV^ zXn)6Er+!q!)xjW?O{w5GmC!Dg@rf#lsA1Wfmaz4x!T@k8*w4`hSb^b`dPPbYd-33z zF?2&ec5~_P)d23H)%ahp8q<;QM3qWdPMjK+zNT$@E;Hae3LUTPRJ=+Oh#oGBJnDlu zZH4mPs#c_8nHvQITnATVuYqZ?^o#2675OgqpK8e~m%<{(z7s_FNhi9Pjd^TV+*-kP zJs;L{oRn-CS1&M|@MKluV!<h6U2vf(8Z<<mO|}dFM!SlB4QrWeJAM$_fo%*l84FEc zfY33t?Sd24k}{T#P1X<=Diz1Iy;5AncE)RTk@OD?m6eNKSuDll`j*1)in#-0p{iW4 zv(CRW(?gDqq18QWXFcv<-nOwdv7@+9DtWe7Yh?bpk}k!Lm-u1e!wjzZ71@O4yFMMe zI)F0^XzR7ZoAg_HQCxyUH3$+Mj+9G{8@%Vrb^ym-T&%g^8`}uw+^ajio-66lNy_kX z`9Zl5)X;zi(l{AHH?-_ZWs#w4x5<af=@0X=$(JgdkfL1+Y-|S|J1$4*^fsO0FngcB zcEL&L;cO{^4-FfycvDX9&F|?=jstWM^hq2hMc>A7XzVOV)UjJd+UQN&JWZFeK^rNj z+7H6!!d{7!N;xPf1G$j+730j$v0Lp5QXOhM14{W31P(uSbaJBl(Xc(iB2nKZHZws+ zl9~raS#YCbfY}i@IzT-|*>QQ^l<IGBuMPF~r~5FhX9YVcx<OLGO5UgnQdzd{N%Hpf zYzH<$BYiz+#lT>H7!To}`~~}HIVPI7JUyPAJ2)st02|>19?sp|z$pZwgHzAudE(f9 z%S6eu(kSI5!MRyj#X1D<nbe8pHRF#<MtbX~uVe<kNgF341#Dbu5&YmOGkGrMf)|&9 zIL5&dx*({?P9U$a?G($AgJza1ei55jvzeuqW@Zf<X*zwK8)|VCGVkkwt$JdBf2~aa zQ8!rSAPrm6zCLVcIexX&?V5uP49=@cUhLD0AiQsC=!9VfcDYk3)WXn%M}4zf(m0-# z&pRDCX>aupNp~$Bs`uAM{;1vBqW)^I7qAW%LUnvu@@YgWL8%jX2fhMR(TWg<dVAEd z<q(eDFi!dhHZ1L%kCJui)sNz;gBZ+18`jqPd*P$+=vdXWwihET?!`HHS1>pfN6R;? z)#Ak}TZkerEJH8ghz}>1rh32zJ)5C0?u9FTS)4!*C@zG}49BQiCuYwR;e<$CXNWRL z5LO_5v_<$`v&0@Rcz)TzmI~*l#kf*7<>a)UkaGZ<-NyFoX`Sw~Reej7WC)(Bd2_M~ z%pDB+R>eas)7*oJ9R~&MltOIJeSK_NcQL|{ZV^}zMT2f{Pak@tH#iH&9gFe*d63_% z+*&tr4PRP}uMW*}s?M7mA~Ce!RA0i0UanOTmf^?6z>&qS&RT}EO*-v4R<0_p6x<@t zYs>I_`USlkua9cC^{A<#dCTG<sDgA5u`i^BIA`t&`l=lH3(|irSJOa=O%Ll7?HN`= z?HNYMhZNH?;b5vo2(T&HIGK(Tc#MtZ!*3npO?(8k8r=9eK~I171gQs(lq*pXW3v^6 zK@`}{=C7L089vp#dD2v+43<TG7_}-qAyy-xYp{RSV6e8K@z0N#=J7PIS>s}`REo8- zjV&*NShyvu4<+nCT1NS1j3vDr=;%0(`+}k8y*a8G^+}yERWMqE1isuPf}gGe8{IZk zp6g^RZqIQB|G&_1j#%s<3chbgE(~zr385oe>~FWh{#K(nWBTTG_9o4%9<{ndd#&#o zUOpTQk0`yCekm)+j4Z>14-q=x1~JUWLIg9XmF4DuhOA@0W{op{T`-uuAcIfVc@;I_ z!zbtkPFPBOF*`QTVsS!Dy1@55->E2jZKGD5U4-3-ZE~SpgtyG0pSZ4hp^VMto9iU~ zI_Ww6NpX6%(=4GEQYY(<E!Z`j;}t`APy(E&8@3r7F*(dPZB3dqXQcWS?(`S3d&#|D zD;ItE0c$mA6Kn<y?n|v|Bv1FVOPbHTntS5~Z;)0GF#_Hyw&w(4sp#2RbFI*PsG2#~ zRIDntHF+mi$F9KX)rrBZ`ML#mHP<WXa}^6$E5|s@#^x-F#1$uV&2bud@Y6%H0?y1_ ze^K9XzdHO<DnQQ7=+kuUXoEUS=3!XHO&r8hdGHTLWhXW_LK)!%?97IGjnle@nm4j- zpjylp%xv3BaT!jOT2irV<pc}1F$mpO+ooY$9S3_N)>3GiM$ez^6<~J258^lpf|m>2 zcFr0Sg;qC66C?i{^BF@Z0Uth$*J7~}!k81^L<5((PLk$18*Pv%WIfTb6>C`fQx~Wj zaB4eQ4|f`IYjc*She4?`f6hoj1s%h!-&9Igl}g$61Gr_&eq3=1PMEP07Mi059GtV6 zN;FHrFNn4`OiLx_ViF=c(kVIR8kz#rt7R!K7}kfE8za!T)oU2lFYtbXiW2rdR1IPS z61!4?vm~n}hEW2m%j}A5&7ZG5`}!m7A{QgxZwY==W9d1n5Vj^MyV${0YKUJccu8Ue zyE*wQar5}!i0%{4p?2dz1OPt2+y^+_b`gIZ!ncf2jTY`(mEh*usY=52L%2<TNjn+l z!H0+wFeO_!7W;>K)>nrH0u@%-rT(#8{T>Y0qxn4q$9r)(L~wkV1dKeGRX%=(M?pqN z-3$_+8F<Z_+Ap~2fO+l2ehn_RLg;&N(zTeO#a0LHCWXnJ!VA{}$KmLGuEf)D79hqK zUV^BIW8M<NxDEda!m9J;Z;mFK)%}b5)RsQd+g{bErmlLP)?3{U8<FRBsTkm9k?RDe z^KA3l(ZruPB$UJ!^dVyRdFS6)DcFumEw06d8p5w|EbY22?btjgAfj#>R)_yveS(8b zzks$>@Y61t2W(C;cak@bt)@O1NnPo4p+|aZIEy(+-8T7O>KKH>CoUqC+?tK0&oj-X zQoh2ipRWwYJV#m<#~4yU-*9@MR1Y&36RPfI*6z|&Z75$sZ6rzJK@}sY#%6k$55IzP zl%+@fsbOC)j9=7umJde=yFnm>8efh7L4%d-xQ0;G(2ZS0=sM;(0j}t6*4jO1#IOC| z8*U>$Y{%KnffvBxi3q78;#C6NzRIvs{N@{BZpHzY8dI5eO0%`wbVE=XwbFxY5u2+# zKFguvVAi(4IQUCBZV6co`}@v})oI6Zh}>`B0Vid~^+EN07}_YNx>)_Seo%&vt>OBa zT}DWfk9{KU#We4b+zg{k8Qx7ZO&Q1a^MVFlvPItfSq1cht_B<Pf$F^nq=QJCa>YU1 zOQle%c#O8G+a4-(DreX?s-^#L1g1tBgjNZP1;ndXa1?}aDN|Rt8S1ZTILTtFRMoQn zb<e*C+~|3!?SKC)!C2BEwt}1Zamh~L2Z-&m3f!-UufWahmRnbiOtq7$*#AF<oT1Ns zgpuI1){78U6t>u>g;w)4T>uk!A(Z9D!COlr7dMAPzmy<spbQ^EV=rX53sNHKUEGs! ze!O&ubV?=HMnFvkYfI#MHG_`Vy4OwV)Z;DYt?ubfcSsl*ZsZpN1R4|_+>fh;#{Mmj zlnxk>Gh}iV+PK;Z)?(!$@q=gMcgMJNOCjRr%3+9TIm4fuaoaC#P}aExn&iZ#N)0z+ z5i=dzrL3rbn0!r=M?gS}s+~P{Qrcp9e8xzuLgz#al~IF@VUXZPbR3$VwG478zglW( zXjWq^el5hoZ2+fs#j~*yl9L1#6X*8yXG97XA>srF4v5fAJnUVYhf(gqXX{yW-OaV> zgP<55*fNe;14LNk^0%=c*gQwkY-kdC31^%Lr9|i=LVF_wRyH>xgJ8YO@e3`=p1$;M znDhzu??D;2f8ayMt>dyehFX1b)Nol*KteI_;gM0ZtQ6robIY~aR*D%c!Zd5(5#$mi zZ150F<sody=s7QUQ`N|0V=xlr=({zyoP>6vqV9>Cw|sE#-5l8|lZXn@VOR<5c%`G} z$3v+(sQRXaB^GvD(Z=Pp8gc+M&6W(at-e?wM+NSm&g);NtVWoNYQAvJ;3iTf#A%IP z#+iM=H;J~oDVi4UdL)3}b7@@|V-JKVJA@~d60hV*fWh;00^#CTi|-}4zTx^Y4y~Kz zuz7p=2AfscvddI-OM_G*PsK1}hkzg;zgRI25i_btyRSLqC=HOsg)N;fAU#_+Zf$xO z487@v2;almii05YxM&`h;hMiWLfD&)W+tKR4FKxE#x1>0l;8?REhrf0`Wba(G@~_g zYH?3(Fo4U06TB29h>63MB}8!6cw?z<FK=lbI0_rUwuN=zrkGPM7YbN8aL>^(+mSPy zn!BU59ccvE(%M^ag^cx-N}-J|FP3rSSHSHCV`Q}|g3Xc_T%YPPGyczN>;O^a0aglV z8y6v<&DG?E7H_IKL&Lb;sP=pK!HN*k?F2=2eFj_kM6F;ghYOYFL@OJ)<f=7O-C!{T zMCT5!O7He!;He;ZY%^V_=p!7{HkOf%R8sebY(`R&3L>);#I5@ghBsQ-EJoxM*qj-Z zZ&2vY!tDY?9Uxf=V!050x5-*eO`a>S<!Z%bEdjPj>eg0>3uU-tZ|nr%QZn1357b(& zU90FqZPLsdf~>|xWLD9}QIn62M;sX@YDP7iYz&>!T@p3SYRa`@G4T;z7W;^0C>e`N z#sJUPZH;TJjs~7xy>KI{6u};Fah0}+{0+^WQ))e=WP4ODpTTuFlE-ECW$TnFunaMT zbyr*60-LP~;Utb%z_B_E%m9JoMoq2j<R&FoKO0eYe^<`{A{s@b781Kwad1%=>jJKJ z8(Jviy6Lm4YI(!3!(DgWMv4Pm3&!eS=3Ou~wp8%#bEzt=rLk3UgbRvx<kcM9dv*%u zeTr6FfAd=<F0OiDI`mJeR>TF*k{98BaON063K{N*yy?V&x$#kmKnPfS9;UACBIL+W zL>XZ(q}qH`D2`H|V>P?<j9o8o?;#f0g$d}DJwGt46CBi-$|7TWHJNeZ5vd<$9M?a% zHb~b*tv0Y1z_|B9WFoVJ&>SYM6^b}pw>COWO4_$s8%14V9N-dC8ClNM&MQR!nG2We zG@puR?61@;ZmMuoE2uU)7~YI=RIJsYlmjQOL@v@78B;N%PD;A<9Fn71DW0_hYtv95 zocykbH&>1-XEhCWoCWN^YM7UvU#Vcn)Y5j>X)^sY64&U-Q(sSINnnsU;=DJRhXk!h zj0$2Rad4J8SxhT9BjQy_JgqsMFI#jg0M%j+Rgg>udHiDB1}z)YDWlr@Xu>aQP@#EM z-X;!l2NH?vHm9|Pl3PK3v&2CzIX5zO1`gcJSyit#JzvSYdzmr!W_R2i?qvk2BgiHW zk-rT&24F6=c6qaJBqMQ0ot@c(ApEA!fpF(}_8917RWA+*dPjy<S5XMNl#!&-^#Sh{ zrd<ukB=FrPaYk5;TSyH@x<kq!k{&))@QYOGltI&|vQn=R-R$9L85eL0WnYDcCXKsp zY-l{(V;ywe<paGv!#YMn?OwYS>pC$5?#?5YDs&Tgws4oFaioAm2{*n~aD`JC>RB6M zCiD#lJ$*x)zNd!N7Peo*AjC~bsMy)1-VfB}r()$<Tt!Z`I&vHoR3=5lFf9QfM^gF{ zHGD=6u3Z*FBm*gw8^qwJf&QMl;o^9RxDVDKQC!-hA&AdL_5yW_$1fMu`rWXJX!xG% zBALf<5AsW);W#_O#nWm^52`Jysr`8k&OyZG`VH%G!}oEYIUK<i8Po^sw^XY@%(xs= zL;PQZRA%`sua1KOR)C#{TPhWxLY4bb^>53d_Gbepi?UeYR(1W>{t84wFHqfG9O+Xz zDV1s{BL{~cskwrDL4Jd<8j|W2f+5w`Y7)SIg8lXCS}i~_K6Ntz$vfaWnPq)r-wJV$ z8M$i;*l}VP>oJH@u3a}KfZW^!7TAnoNkcj(TLl&|?IW+XH(qo+IUOfV+bIhvZrOHp zq;n}%7|nOpoj8o5f=b$ei%UMY4$lMK3iKg1C5a24po_IXm73p_fW>e;w47LOly4j> zCrG}U;D%0wov=*a=Yj7U+}02@(k_&+ZY45Mp9i|Q$b+zZ7kRlV@CY%6WJ~Ba-7iP# zkWv9Rr=V()=!>q6=S;PLX=1~Is=)fK6rL|$y~GLCF<;R^SR8`uWkhgBG$g*;<Opt( zKu}9?@fr8Vkl_XKIkJa)4idni#GLnWnI$M-;yb>BOTMDSpF36LAjD#WOF+1`3m?vN zm4NV?IO_NcIme)&5D2s7BbIU{RUdamu+u^omZ(so(eC^8JRd04s%ZeGnNrlcnI=n7 zzobgX?@<|J(<L;Hu$(}~xR3!aFLJaXOAsP(DdT6aA<R@iI4h_j6>9-gB7**vrA?g2 z8_mAqs6|Aj->4!HNOb_l4VVn!BZzGrq!r<6!zqb$S!$K##=<v7<2S{^7iAe$ZI2w} z!A0~0?mi;mKf|>KYqE94t9Th$nyoh1Iqs=IQMYnz&>QrH@QKbtCt%~CjG=mdE61;m z^sd1r+!#xJZ=9%97eU1>*vMQ}aBE=+IlDIA@Xe~F*ig%0&#Kj`8sv0{0}p<<80qV< z+CTSdTxV@OxGJuyB)e%AJJ>LYh(cYM$xuPar{f^ryHJ#E{c{qW>l<~2${SOSqgBf0 z@f<Jqkh>bU!eThNIWhCb4o2VFe&l}f4f~KgfUNru5(B(2O%Br#(UV_Pg$d(|@n)6P zfkx^+^1S+;j!kl-zoufU)y&6tH~Tv$NVYY6%ke}S7>z+vU2`U+iG3A<FKy)Oh@y(; zz~VFw!h)R!UrCP^aMIxvPm0r<SjrYmGwe8+g2VkPw=c9%YIuS&4#lwGhe)TOuB0ea zt(9_`_EIRz{~L40m(+$EJ8m$BY*T8_jSv7SR@XRAf~)%2FRj91nraP(JJtdZl_Hgf z(>U(yU&%@ll&Pc~-0rTq$P0v<MsPJZ&edm649-v-+`~$aJP)aL8%OOH5G#4EgUrcr zvLY)sPg@PiY<4pd9f`C%xPk|bS*$P0>F9d)oE4BSrG$W^8j>mD;GOpA783J4XiHqz zPMjFwOY}KxX)}H01PpC;TP#B8gq(hCDY24Y!q!FIM(~2zrr&f+i3LbAQ-TXmWuCHe zt1@exZ+34YXEX9HVdGj+IY?^Ht(lR^Wl<@@?TvVWV$gVCywRbt>5N;*3x%|JNUnzr zB?+9So7?71Q!Yg@EVl{{&dYFBR%j2Wo>gc+beQt1I=<mo^|73#J8I<P#0iB8fyR}( zn#x7hqO}U54_ip4B&zDhL>lP~b%eBHIDW-0w-Ut2?n7Iw;fpFb+L5}OzKEkU+<L~* z29i7b+Ar_Vei5r0a=Z-|)d5M2tIz76RdsxhBr&MBfW(-%KJ6os9L_UsDx2J|L#X(= zN|qf}`_qIIpyA;33#++{om*rVU25Mv8s(J4ND=42tC7huD#v9HG0M;Z0gb!7Z#qu; z)q1_Su9V=eYJgorErhc|M#k*7J(1banx27Kk*P+jq_Hr2+>(dQ6*5m{f3aMTL|4o8 zGPRca`UM2_ZRDWDEk#EqT9d$?2C1i27u-69dMx|0IrHW)@>Z>~&PaqD#`T9492mQ9 zF-9mG^o65$Jw}T*O}0Ezu9NiPp2M(k5CT>#mznYP*>hSMaf)@CFi8;;65@iPnm(~~ zcttjnDYGg?s><o1Iskbl^f=FvLhClhOup@>0D2Bb(lF&<uEsH@oeBU~3;nEs{PcRI z<JGSSrQL>bV6dQa+`#?@6{O8@Z6ug4DMA={CY921NlWXgClk`~qPBK8kMfEL3gUQ4 zv#a4X4ZbFUG&PlajDm1fK!ie30u)L^LJ`DD$O{!=h4*owhI6}?!B+|-S4+W`q%8{} zNx9bBJa+1O2wjWk2VhYn+bi-f(vq2#NqMkum3r-E$hDXCty+xV^bOfmINBMjvOuX| zG$clK;g%J?iqfexAVq*WCcU-WQh(9>mOPVKv|QZU2~_L{QYXt~snkPw9O$Nc!W8zG zC`hG$)qJhs7FM|gD-DAVuh3u#Q2X3;+qH2r*mpp7X--m*K`<n4Lt)lJUx(?zgd)?r zqbn3!pDaR>ST)odsw;u(=3!Rvkr2*ZB*XL&^@6luS$ED0#X>W=dSXGxR@qbWCJAmO zDV~!WvdX!E4G|)sPpqU_F6v*aq~B7*9AEN~?HAW-@o+}0?1bDeIi<#keG$DUqEGix z5Fe<i`{Kx_gyc>I<k@bBqbwlaO)0wdZfWI`MW<AkFFL+!QP+a%+!ZU9RhM@yn78P- zMGNMGLK)d{6C}Y$vfXk4N4pC;Qpd5HL3J9AhX9yxO%*$^!30Ut3b>`{6qYPlFuyu? z@rvau=FU3-l#oFcaXpBlLxyC#U>7%=lDk$tDI#e+m5AUSt-%dg#P;8Yr%l!l#ZZGw z8JV<^4G><F5w&|=yma2&#nrC4OBT(m&Re>2$%<07iU(49h6^XnU92d=*Nhoday<um zS#hd6+sKSJb=(u;^wL?H8qV?1+3?BqC|5t$R!~D&M7bENG?efzLFuF_il;R`*zD<d zyrnBwbgf)boj12@#mZ$1G&_E^dcuNJLBjPtL?Po2kc#d{%H=wV40c+d_^H4<gjWY_ zT+l`kv&>mlf5w+L)fODa`6`g8i2SX^3Nx20T8;1WI8MV6C$blh3@WEVRY0@`^T-W7 z<gqTnuOBE!Ym2p2E@fcpxmyF{WeKWT6se5pm3aN?08ap=#|*eK@4CJVD;6o3qspwv z+2p2gmeL`xU>P{W6G1o%!#NJTtAV5J=oZc@>1<bA)W^G<40+13EaEAWzADt(YMdY; zV=ZFk66BM{;ZD83)OU&!Zh~2|7RtDq=GVhw=6Zu8ebse6!>g+ylvy=Z)JW)*E^}%< zfN=tY5@QK-w@$E8?z8V9VYLg_co^ntqSZXaXhyjC>bSm->`1fUZC>)~>tCf8rflE3 zp1#Oej-R-k{=b?i4N`N}z7b+V7gl`kG|~akM9fb^E}hb`dQH_Km#!n(N>z#%X={J) z$XZ1iL5s*CihS4b701}i<gr;_nTyNQOmZGmRO2)!ae^97NRTBO!Bwq&=Q$aD*FRKV zu;ipFWrfozb%2R2BMbzberFMp7p*t|wxl!hv<BjdVqA8B?;0Vw8I`yhoF+r5y^WQ0 z%_a{{;XpwSUOaDrRBMG=A{)Y{LF)yBtA><j_U0}-{v^mB`HP@rDhU!dVrfUV@mZx; zAL&hBnujl8a~*idnt(%74-t-;N*vRpqLd;Qg<<s!6dWt)=pr)c;ffNDv(k<(N)~QN zHFbI;dJ-4a2k>A^->|%z*K`UOu0<GUmz<|AI76B9ZhQtv!v&6)iIB<ziErQu&zQf6 zEmy0x5(VxKZ02FP<E01bYD!`W=~Z?lvQi^+n+;uv^Hli8>!VfONC0stbyt?CDprsv z!B>h%T?>7uaz)kr$c3qDDi>T(&%j!r<U{_YhDP`*3BXWEl6^NP1W+Lua#*Pj1a(es znt*WXH6}%+S1;WgrOj2XEW2)ufGXq?!s21erjD|E{;Snu24i^kAywqQi)8IJ*iBLB zBdA%nCodcWC7i5CS2ywyBzU+%9gL}`%luj0tGfDmmpu=T&_|HJ%21Bc0$*f+3)<ZA zy<pAv)0hxci{msr5Lv3ZNV4kH8Z3tTbsMKVJ0luIh3s{h6Ue7tE|*mJcE%7dr2$jA z4e3lNE?+Sp1`sNCafE>=f25i~uwXe72azh9W>T%FNaXb0Bd4S?cB^1fwVxNm%Wg8d zT!b3p5l}=VBP7t~&00mNalwQOB)#a3gqck?ipm9x>r7PyUOJ~}V@%tI*ihlJ3l5xu z1i8O69Na~?&dr%!v|FEuD&jfSSyd!TqX-UhBc{A)3C!dr^A<oR5w5~GFiTu0OT6Nf zq0_M9wN}^^6hw_wX*M&fE0?D>J#zhf*pyT}<h;g;<S5PG(ttvJ*{f@~0@reN2#^LH zReO>u!@Q~^$mR;};Yh;ES;&%y0J<_ljGFXhs+yWkpkst@D)$#&$btoxWJ$MB%wVo= z8rDZ>(>(IvWI*6Z$#akhzGBbXWA)-W0~#@CxH45jfR2rr73Fhp5e#mrw_+K+?Pu`q zr+mM_nfY=3E<|84LRE24m#E<U7Jjiy=181f>W6#Q#(o-8?#VfF^U~6AK}wZGx?KE! zXdq6nNEQ0hgBe&K5%O5#JrykVjmBbgEoJ>x#~m7}RTVi!NR6Iixl+Mmj>ym0O;7zy z*0FtTVZFpSf5&US7g1vF8yq%EEF!k%>NE_#4CKwlMM%8Cfq2i^(NSk}QxwaHa~#3z z#QmU#tnN5{#kCa}-M9xkYZ<gsD`@^wF&E`MpIkAsa7H@t*_1vdJa!SU7un%O9Xx7) zXDyK&roi`<l?H@w1AAe|TfT7V%Ej~bo)erSd9{lhym(j%8QGn3++YF1l`y>8v1e^E z2SX$59f|Nx$H-tc>QNi<nynJpsw7%2ViFm)nQCwI+b+G|Dv=#5DjIs}o2{UOnT8>Y zS0>@V!joV$5SyMyRqw~tnQ8T2<=Kbu;UIkm;<bwju1cvOdviQt>z{#bWQ;xkedwq8 zn9}}mVJ$|u@QVY)AjmS}2XI-zR}Nb29`S#C3E6evVp4AvBK>AmgUQy?#7d<F!^NPw z3T<2=J+<We>4U_cT5@6Qr-n%Zeh54ggZ&nsFhB~Nx>{F*d`tF3cxEdqAeR>|f8zn= ztPn*9>0BD8`j*s!a27Xx0ocYHzt|kL3de!HnIWB0rgUaE+<L#e8g>Cp`${>f!9D=3 ztQyL#K1t-tuLtoq%73<o&42v?g8;#Yc&!od%OPhPZeh#eVru;~?b1yzH|(LI{@ydw z7*kAPT;7i03c-<-x~pyuBe2}M@&T;d3EAz~#8b_<VNiyti{T5ar^t5z73U4kJfvQ# zKh>=LfScSA+Xx}96|e}QQP|+a3zpHKG(TY~r-o;y=`*UV#q-dqW3zDLq9qWra#$od zHZ0>z7-5-}EVBto^V4VtlV-Dv%#j!Qs*9E!w^W;(J`BJW%Kk%CLk;g7;0<~>%@eFA zv-|Q!32&Mr4OkV9iRcQ~E)<nZNKQ<iJ%2cHg_o*dIkrQrH}EXs?z@Lez_rXVUukvd zK{oXX-PDp2-G^{uA%-f#UeLu^r+SYU2LS4yh$rstRqm>aa+xV4J^w5xP?UI5BnXfz zEuP)1HW6oUs%->_uZcHQa7}Z#CxjEXfPbMm2@<E^&;-u5S_vJC)05Vb0u@SwNzVVh zg-e&FPVEXTSoL@oY^^fPpSoU@Vo1pf_V6T{c=xJlUZV8DVbqKL5>!VKLH-U52z7?t zQZGc70XiA;5P|HP!-kpT>gv@S$D5oo*x$hVQg1y+xOd{ii`vSN-2E{o=(DNDId0Li z<txM)4<Q6@5yql}#O`>*1g@pbI<th}wwl)%-5I0KL5|?ob`<JMJYL<52Z#ER2okCL z<q*=1SG#t4V2u<P2>Xhv1O147!Wlfg`(;FL;3ggR6(yWPXD!m}a9_YF&+moj@?`v~ zwyeh~H;dD}WyPTb#tgj1xPcNQCsuvz)D1_DUB|1dqV)XUpTBtdsV9OL7Y~Xc^(XG? zAnd@#t5hAW{v-$cD?Kvmgx&rj94z;piHFh<6M(6)2Goj(T*h7==PEXm3;VOam*%hG zK(ZF%8MeV8Txr19Ac_c<K^Z6C7|}`A8tYc-(yr6;lqpjQ`fx2m{RToRaWxW%V-t@w z9<T{Bh63WWTH2BlD$fNWb?4EqyRs0;0xuFC#_(L|h^&Eyao0jE&+_;Bhp-pNd6=tm z8{<BF4aX}ujm%&YXA!LfPQ}-?j6$rno6Uf~TuzR#`IbOQtdZ&d!!P+2c*^kV16~G4 zn)WP?oGgwqyyG6uuOsCoc5R%Gsej<1@}viD(AtLKc*u2*U$A1?+$Hmuo>*PEWbR3G z7cHK9>|(WOA=U~OT?MWSL>D5|tYOib?Qu=KQm5?}j$gK9KGwnI3+CY*tlCJ@!z*A3 zGS<g9Nb{mv>S}J4AROlzV7dku#X|}?rH{VoOZ2JS)Iqp%yfkhl(t@)dR5f8U{ew2% z<->}B91@9|F|+4u^_Ftp7UjGueZSY`8V7>{cZx7;d|X=fp!I8bN~joSc+L<$o?)5d z$y2L3h;uJ&`&59q9IB`@f&g*5)oL`<PZKFaE?(>GX?E5-$_T+}FijD-fz>fIR03=t z9EfN2YJI{y{~IH<xrGmVjbksIySzGY@zNy=3J@JmIPfwqatgu46vD;+EVwFl$z^$O z9UdPBDR{vUp&sIWL6z3i%Q%@tTy?9n4PeHSRKOu7jf5r(Wb@4%fBuT4%a(&L4<;+p zSwZGFL&j^>^`)U{u_~-WgrkSpSVT>)t_ErP*iA0-IOawkd8Ml1yhR3-=aY1VJz}KZ zN=0lD@@i*jBG~w?;}W4Ib-`_PzXG==GHgH-;{WCJR3pIqp%52R17Q8Zy#V!WY^DlC zDDCFe0jE(K<j+^P14P%Auqq<_1h0~YS^FZ-o!!c9lzmU7BLTaJ>r$8L;3z{_5`uiQ z<TQIA2=9eHRLuxf^5+HNYS{JZ+3Kp^{#wxMcqh*7>RPnqc+8o(^A;-g9F}og1Pdaj zvq~y98#1wR;;xOgeyAGZ4kL68WL+It9S!2HkXYj&jAw$&c<l|sPw;55x~-~bz(%>& z8_!LSR$R=%^KW<<Cs5hY8V(3H&Ui!kRz0!@5t`7s@OtA38B80AwMzFv8)dbD6iyG- z4TT=%cJYyW2Ulm|u0;L|tiPMta7E4W)m{X`Y#>*}rTc=94SY!@)#KC8o5`G<q&B+| z8;4BR6KwjvJr=nNf+?!VQZu5$>ktu%>^q1Lgn5V|GwZ(JY<c6#ZyXGUtE;en@t7)T zLO{6ASW{aZ?9#khyK>Vs@%)iuOkKWRjRj9d!a1e+3yxiRJT?$37FHLWvS|4Vr7#n` z>k#6NOT1W(o6X2|mT{!vKsRJ4pNzv4l&r6mo57?X#mc9t!g8x;Va9-;5HEtmC5lZU zo=I>s%|s7&d5h@+3(l%X*LAo_L2V4Y!^2f0;sr3G&y9-_c*76=4jVDoDm=<%Om3<u zHyX*Ec`>4boT3O^^F8E~@$hhAI>L?mvjW!D+}`*@%m}i=&_ckpx*X-IB}gJq@hD_5 zLh^yx=GK#0W#mIio0apfON{KhgE8LBR__$HWEX_536EnU^aGn63>r~dTky_$fF%ET z6&lJZ#ulCqh&s#Ijke@1P?wE2#<$8=)p!FAq1JPZ6sq;SZw)WNsm*1&!Ng>P{f$c$ zQG&P_+!~i5Fw0X$UQY7UoDpRsOv=Tn#%CX%C70y1gk2tD)DooJi9;B4>G*2kv^DF) zmT{_67^wSOYAe2F+^VdgcCCcBt5s?s_1Xy*x;nRhYgab~Q`b99hg0i>L+Yv}l0m`a zg8bMCZ%EY1W@Lp*GplUosF+Qrf*`VrdUqafE(GqF@Bbn`*G#ZMQRAq;9x}4=1}(<{ zUQg14bq!vDrtyeX5~md^n>lh9h$Wjgu)$5$nl>OtxOU{@_8&x!ce=B5kD>bzG=e;r zE^-Xu&G|ru0-=L8LtSO+zOsvxJiI-P3)eVFZpz&H>=h}Jc!Ws-M}&Bs1>xBl?oz*X zi-D73b8*0-t#nHT8A5P&7c}Teu>q8N+1#86F7jzPxByU$5LykdpA6_{PX|6Mgu|<+ zh!NJ0L_J$drv}##Qbr|C1*xi#ol)rMd|1dhY7SA=SV`xC^%iL<;l5RoZ*ZsDjl)c3 z)5^$~%K;9THUci|Ve#pne|3Uj1Uz4b2uz%w<E`FiRx&cNX3Un^L^H|)!ZjDXpod#N zs&SitEpRiIQp8O72pB>XA8c?cQDf8_69osgWh4i|#acvq;_NnUo$-~dbv<*UlnOyP zf{}w~N^Au9X87#9*0C*a2&wW}Tr~}CBprow5_igw;ZR+7HfM<6>gK|kRhr1d3*cTv zuxP`aNyk>kTlIK#3l1-J5UK`Nj6^hv3V~H=5_r+RuAp(~mN_mZcZk|Fb#y=*4d54~ zmks*|dekEkcrqD3)mkLw(z~=B9a3Ch@R%JyTrc5f#oWN&-N%Vm0%y$Z3e-2U7JdM{ zIiT*zR0o5oN5x&@6*lM`gv#Td8`51isNO>M7m5YtcEy1y9NV}ID;8f#&f$eqNDGFQ z%Gj#jYE+3^(TGLS`c&a(=O8gN43yzOj}kc0VCv$Pp~iWRJ1B}X-`LPd)p9{a?FLex zosMmkEMu6r%;|&Yh7r1mmLO{&Hoe@JNu))FY7F}DTJPMxG^1*1c*8&}yE|Mm@{8rr zMYdoc&LO!_W2{=TekqAV)-bjmhzu`OBk&s0gVH(TfZV87Zn<%TOftCCiQN}o2@dhL z^OjReis*bK<51z8F0Kl0Ii&)QP;t)^9!cELZOX;gxQNS@i%41onc!YEj&*VK1*x*} zb~bzZ*{?7#TyRW=Y?iRUu)a4MiWn5KDaZVB>~yH5Io*7H2M22|?xmM-Cp*SQjze0e zFTN|O#GU4(J|*0{C}Q(tC%B=Au4tHN^{+I=uq8-Hf>?bY$D6pa!y)(F^PPC;KRhMr z7HSdRu@ZO1mQXdC2Qw3QJ#kGMIcjiSoqNRRnn}h<aO=gj;RC|ucf|BH3$1con${3n z&_Px#mBM5=#{1E|jw?~6*g7Yv%0i-H7e*XbN*ga(H>SOl%vcCQisJQdCDoYfa2~m) zQV6*Y`qHdZ)zrI=`Gf4&E)JA%aRou*v+Oj{DG43iG|QwC7jdxbU^J+UXJIT|kPe<E zD)J9f=pRgPts(!FaFSpIdiY=(AonouPoy+T2s%}Vi<R_(L{RIEeR%THlQ@`*2o}YD z1D+rx-jJ}^E!d#K2Z4my@F1()&G5~N7@qwMtl?@Do~%JSVHZ;|q$W{%SvSIQ*_x`l z6zllt-GSAyx(tU?iat2Z5PY_5MRn<M$1Pv5qPlG566Lfh;991Gwbex?&A8IIf8I>8 zC84Ki;rt7y0m`$AeFH*@;8W<02iJDs)v*YZsKJGzylQE9v8S>@`s;AHY|uYh{lD1P zKire3kO1UMg>@Wak-{})Oz+w8qs&R9P-t28)59alJ&Cho94D*y_0-P=$N)e40F;#A zYg5gSOf^uDG?gi5i04<V=^Yhq0jx0<AO0D?7-FGv8&x9s!+YtbvD`=;?{lq3Qf&33 zo_4qK?`e+AtjZx6m6#ppRXCcc;1z6K2h{%FS&5cZsv>l|cBFgCHN8nkFXC<s>h=^a zW4ShRk2Xs@<ITqwj#;fTuhRM{stRJ-5l)R$ZMb@HmeoucS6^CWrA-|(zca1;W=Ba2 z8|u0)oH*)CT^UDaK4aaHkR=jS6mUTlr^(2dh1juHdp13|m(>d0n(@p)OYQ8o1?j_h z+|49-M+1hS9YK>pjWr7ZJ6&_EH11}iLF8@36V~d7YR)Drq|_61V+lz_Yh?$w{?s$b z8PhR6k*PN?|H++3FGTA9aEkDX;Z{5TPiBpM96cXo23NaEAufZ#D8vc13T!Yp4mgKz zfie!3{||d-)+NQ2Wb67ddd}tZ@Q46au}T6hK&tNh63eH6xJoj!a{yGo{(fd>@Z(cN zkVvY&RjO`50x`HBKZDt}ZF{c(w#)1WV&&SsE=edf|E#@Gi%EV|zQ}N<p=l>gksM=d zzz=T*{;i0ApP1^iQ5{jnUi4wHDQ07*!Knz&SJ@w#&x=W=6UWrRMe>w7isVMhe5LzB z4?bu%GR360&DK3isq2eY|HahT--v}NTjWy~8&;OO?PJ6Td(0Rh+fFk7xmO2NS6?1f zVTm;6$v<}A{q*wb#RY%A6GJqSlf?r;F5#PpQp7{~1r>uk)NJ`#9Fh4&y#C}Xj=o4H z;PDs8MUMu|$6ssKb0!}3=-Wv1BuCxsAwSA8C511JQ$bzR_TKSWXIsRkA;yN*vU|)w zQnwsbEiJsqU<V|dNKmh-z~Q3?8I<YwCfMiB_a^@k-FN(3PY(0IQ#w)*N`cUtWT*)m zz{YP7R5TZ(bZS}Sb4b>EtMXpqjvhn?vXsJu;O9YKJw+vgM~Tf)g_`XE=L-4aejbr5 z9k|@ay|@<lWKYf>B2q?$1P>lO&hE32A&!=IfnPi>?pp4EZUnh`Bfmc*!gY5pzjKr) zrN|t@djK~C?GA&C6@V!N(Y6TFxWRm+Sb8~J+`T`17&jUDXbOOE?#l{7NJTr-bd99( z^68(q)e-?VzqZ_rD2!nD@*lVJ^5pE(1B!yL(lia__dJ?M(`YzsEHGmT`_t7OUMS8J zc58~6zo#?`8JI)ID=qt-(T6hA_;TuN>fx#t^HT9Nwf7YM&J-H<El}^i8fqG)L6(;B z&q@>%tp+FBrf!g1^J^&Ohg=1j78)OvM2lKN?X~zudCI}|wOppbmh@ZYQvV!oX^o!f z{o9A1rZldybU~<Un7Bc1E1}FvP#Rp_d3oH*ck@uF2o!M&(HaTj2>Frex`wp8G3l;v z=6OkYL7KanFMLWn`qgkL3)@dJ=7$u<yN@RW4LdqCt`|eSN4SHsCozX!<urqST)u|} zAr)%M@F>|0g_TGhX9a?l^P^v2R0dqpU%h2d)!fqmw*%vi-T1S-=Z#^0j_V)y6?!9j zxCcZcB%*qgzX8-1?=i1H-HF_;2N^a<;$uE{0ylEj;Uk3VVobpp+~m<$Yd_Th*n7Ij zXljY}EkI1V*3&_Q@yc@64Z%ORV!4=Cf`~DQ6NKjCEx)=Qi-m!eXM^w}!v>w7k<<IL zy^=P#mv_*=@xygb$(hJMs633H4Vcf9f35_6#ZL-D=I1Nm<;Z>yB1VrjqVQ%2O`+q< z@`uW$50%Rv`1lA%Lt2@z{G^Gyv`jNA$7Mf$xRTSJQq8B`2jL~G-9ebAtbPx*WCVs0 zm%u6$r5_U*7L(fmjsFe4h$<5Lp=~xqL^miehf~hpkb;<xyA3+$XsqJkh!G>HoQ<7P z^0l8Xs)djHaENCjp<1JuS+{5juUvYEPVV{~I{5^M%rPjVz*aRC)ebiCIgF4j^M1ob zwN);AgQ8x%yT5+iJ$7j!DqXnOpc;Vt(#lmV3!{c$noWiowCB^~E`gnVpVCo{XfwRX zf=y{L5KHg`I-YPebO?0)h@wON^2K+%=P%#B79FgT91v>`^a9cAq+Q!Qz3ChDomTCS zGli~!9<mPWn|k<a1mfFaM$FQn!1WuF5rtbvBp8kohO$T&?x}BN0l{^A^WzRc{5kPx z!|8(RERKX@Ti*D=^Q(%Zhbz|?$KViUp#qPq98F%B6`83$J)7sBfS{0RtK;ptK-?&v z!HFgFmy)HKixb3rt*ML$;oC7!;=0m#O&Kd;8Fn<cvPZ3a%aRkW^h<xNthhaOx7T;l zAISM}cmFGi)5VW4ITUQLCr*34<-O`+8?+o@?_wR6LGuu;nZ=x4Uf4>983fXmd(vJ2 ze+O7iECQPGsCqALSQZUiO~l^nEB=25x=se1%t*{6sn#MOB2X<0Ust;y!W9yaA3^P_ z<gnLT3xORU2F^R6j+==U33%uX)2f&Lgnrr}Zw^Fx{aK#GqtY+F9ibQiQd+T5LxK8C zgt0P3wCiCjnSwOdp{pPcK`4ofy6?&-)PMO%wWRr<cmKTmeEYusXZsg7Bz1y1bl=9x zcZoOtI@<XAt=A_TuTR(ie&glY`m6Kxzb@AQdb+%_<?6DJbHhGR9ucf<sQW?}ge;QH zCdi6U^hzY_*(Y{Op&dHLHKV705)yjFZnye8^udo4ds(hq`>HC4k-2ILW#ZEZ4+;a2 zjqi#6GH#Rb1(D5d6Eh)TMfnYM`Y-v`zf9{AD~#9i6EB935HKX)W{0M+_PPAg4iRl+ z)Vz>{!`rpQr2F~S_i1K9=}wCRcZYX;j&@EPqEtf@_{D{^Ie>ex`SU9%)*F4<ovd87 zuL^^iQy=l9@6FrwLUD=`v26KP=1LAtnLZ$-Sz+@dm^a;-#0Phtt=cE(5pubtQ&+IO ziH&y*pXte@JyXZPT=c7}OC>P{lLX#rL~_m18|QQq*y_IkQG#r+CC;yT<J<foTeA$a zzamgjVqadP-bf}oVVCjg*s6W;$D12@He4QPE>?xr50b85iDTkJPcBEMIy4;kKcQRu zMt`Q}vvJWUhKOg1Tn?T4q)(WdBY!qq|M+jshiCps4VrYub9J{w-`ag>bzX~-1mf{2 zih(I@;L};PVlBCO1*ZopKsz$R9TfJWl*&ufgtS1J7E9petPf{Eqbx;a1?nB%UnrN) zK6nk$vH*=bbDpj}Y(cBR44|J~;@ewDeaxm83qX{sqy-MaPe=?2N*<Iir-Qy??l>Rx zb5`=!6BpTg`k-q1E+IP$4}TtVrpvN33Pq$zwV~|<H~ZL)(2Qfir(|we_9V->6=j|} zYY<=*^Ve}xpBxi25O<{tvGug<aBiU7{!ns9$ldkBtu*oI5%Na=;I=q>pg;?3;EaIb z(VT(Qwm#6UsEURlh}~J*$i@|mcU0KMu@YkH6qRjgCBzh#xOmg%w8}M!Wmar`bBE;~ zG7s>i#XYf@;mj)mj4nHSkm_%OX30V7dPi_38NkO1lwC5!e`a;Te7S)Ib7!ZY{xRBB zx>7jh?p|E&oh3S2vZRy=p=XVUl~u6z@d_QEr?$p0bPm3Cb;iD-B~p|dR2<MfTNY|u zLRLZ9B|;4mC)8Pa4_@2+BF3pYpFD8WU_9w9BO*(8nw>fo<RH}E!L?}MYUUg8ijDos zSN!VXWy`(MuTd1ieoIV=JH^5tZ9xG4JS+~f;jTGiFIU0%Eu8!V?V5Mp?cqkxe^H`- z#-HuCp`(fTAF4;OIDcAS4*%?qXVP}IxiuFIn;f~5Xl`7JJSy-tXo~a_&`gJ48cT2- zsL8gWx(wsRET5s>9hC7i=N^rp>7MW8ih`*lyH`!U3$0#IUh(^!Z?g#MjvqI<M2*e= zH-w$1p%q-P2*9GO#?}kfw%J~GGyn?^%FAmPn<I1D5bBB*R!w*Foc6d<lnEAh@R9GE z%e|_~ST*92W;llN!OP$1--cy%<`gXp_!`4vqE!?jtXVXHTG?X#pK~z(CLwkJ)(7{$ zy17k~3h4!LNyRyM2-$zq?@5vnRiHg^wgc8H4_Ks5CJuJ*QA%LvlfKfw@gr^DGD?Ru znMTgx!?4rAZYK?NUqE>RmkLo-3;p{QjHLhKF|5T)|6Y&A4h@MQ%cO**4K=5;-Uw!B zzLxX>V2Y9-iB}u#`*ObmP2%6Yv4M@o&XVTQUcGoiQVtF#Zt(D*sD=n}vu7hr64)sk zrp-V?m@@_G@01{FO3mMWBO*~waR+|M!{^=Q;TPgK{rTeJ-PHrxdy!pSe6EU}{LTd( zh(LDteD^nwzbQ0_R}c3$w(N_Sx3KS!Hun|n4I;$KUxV%I5ixef(rlRTbL@mL7p8<V zE5Wa^7*~T=`<Ih-*OH!cx65AX|J-r68K_-62=B5P;z5o7Gz~7MitYCm!llKmecaf) z5W#hS|2h5!z9G1!C8eX6lK6pEhs}`9NR;^}gS^hxlL=|ss}JkM_CZI2oD+U&%Y@n7 z08Dy$luxypy6LBy4{(mFZ-hN{WYe&dm$-x;ddP-(0%`<mGe<erIIDInq}H!P^t$=< z^Pp_Xf8SBc5b1&h278@&5@nlNY`SbZ(1+y}uaSEGfcTt?K`1DbVw1W<5ddGBe%M+9 z1;%-Cv1Cfw@!qHj*lz>srCl3O!gP<2hSk#b^M9p|_eDs@HxGHsF_!Q<N7-~wjH(7F z-4=QevNwG@OB7cS$*pg;xSG#Q{kYm6M1uQ+v?#q1MwGh>CO4w%MS%!4>HnS@+#DYH z@<Ih5n|N*Fg^h4xlM}_yGqGYxkSI2jGjt3?ye5v98Dy}*uSVoH12__qo`#O;bccOU znG#`n^eSh065X<MXhJc8o9oL<=?c5Nv@=bN=lLY4%UEe5o46dDbV<xi>#e}g=sEhC z3bSs08Nt{DLEoE6`o%1W3(ys$0g`4P_k-m;Y~fmn=3=}91c&T&i(cS#ai%N%RdyAw z#Y>u~gaSD0SNxw4rj930mkv0a(VNlJ*^c+!_E9}q94qZ&{=C^@MrhtmTX3JDjf%Dd z7F*NjxyglIKZ$7<pi!&Rc%D*?q^E0Gs$CBNWk^_H=hcw=<efP*w&oq+0OV9kno%tT zmJlDH0Fa58LXy0>LDbiUfU@L&l&^BOnKUtV^oAif%Q8mSXS`LMcZH}O*CSE;Eq9_d z#gs`ZaX<~Nljb%&=c)AeCV8lRPL?Z{<`qGW3LV|@ppV$S9b}au^j(&4V(_9s{>|L& zi4RCh{|UkyRQ982TC<^Jhzt;iDK3}9RDlY%w~W(MpJ}}rxGM2>xI=FH=K2mlLsj=h zj;n!Pgxe`_A`?-^=)@<c#dwumTzlQzqELASAGxC?7-zu!W%CXpxAz?k#+WYq0_2e1 zc~by8_2I$gLOLXX`xQ9!;{m52vCvdgX8CMrRV8Ze_zR`Ah##GE;Yo1e;z)v}V>r44 z@=pUs&3y^qFE0!~<;3MW=L;F#7IQrsqC`%*fxE;-mW)7}pioS?4COy_;-C7&XdK<! z&mZrZ2zc-CVNHaC5~a*k8s9-B&bs4j{ICa}kx{!2W)!k112$#!*mN)`h0!3jsN>T- z$^6_Th}-=l0;T#jv<trP3)B}WzabfokZwgCB;4cWpriwXey6yy)Ro|$FF4b1kSkL2 zPgA4=;>Gg7GuprN0;9(x?S>d;E}Jpc7Ie8<WkjBdY7~f>(Cf-L*jfaXVQW2hsgG=W z_<e51?#)Qu6&cxjfyfevI!kr?xg^{FR&4)M9sbi8o@5baGboPw$fs=cwHB}7s>aW_ z2mtBVL(}``zy9hslYqz$02*ev19a$ti7{(7tKY?cC^n91X3;U-G4bBx^f|kh#|M6U zXrOfmWfNWieyHZ`PolL^V!OHOX|-iVC(u|i*`lKZLM7_xx<#zND~|vA{i|>B;(hV* z#arG=(2J2alEFZ6$S;Eet$o+UWDaC!yrw$iHRsH?=??QJmfGB+MM2uQf~7VsaSV^L z!Wy)9UiG>qVJJh+V@%ZVaz#cn0Y;Ph+vbv(0N$39Y#>7WJ8{;}y5{os;qn(mUItF# z%V95i-Q>sOLqxwP)!H&OL7#~bANwsu@GZB8ckktE_VkCKXpdYl-q%=*>Wu!XuSwz$ z!z}{skhVI`Ls7I9k7T~967zQYE6^Efds3<2;JfnKcNxEcp?@b)0xefHCVhAppuSo~ zCSTjUHv(a4O(4is8lD#!wr5T7V1e^P%-eFsc%Ua=D$wlfVK3qN$=5o(PO!qKcCPqZ z#rD;>w~1=0%q`w~_E-H~XQR%@%!~%JvDxo_5i7Y8uqKCKM|g~dTFhvk-oU1^7s(3G zOR9G5?e!-R8tpuO_do>AvXky(e|8B@YWSy8Fd2K}f;R&>icZ_7x6%XTu+@{rKUaK_ z-=BW-TYVgb$xG~gcPdjS^XOy+REOLIjA+tzn24ZODYhUX1cYAHB9sa)d3*RQ{wqqs zK#dPf2l5C26X}aKe|*NDWYB_-`?>)&6Yn?u$e<K$Zb%0i4ICM389+Pi=MHw8A`nX~ z6LmeYo-`MpF`uJzUUbf}Jw^BE$Xz^IyK4Xas**e^wiA>s3uM=Ow1zPlSyUwd1k)5r zTB*~VUA{@t&4T?2@w^AR5yxUlIU!~VU&wV!EdMH6dD(Qft~6|`Lanwg+NVoc9RqmK zu`%E}zxLhv@_Xv#Us01=Tw?Z@%j<U+dm%y=b*<Ubw9O!07G2~5<v##3yV(xV+<{AQ z<BBj{h)v{^^2y$wP8xF%4+K@g@X6&K@`~d7SAYHM^ViH`l#{6<WJ8@J*BH~<ZXN7S zyeR$)L6HVWP*5(AjT8yCz21p$L$l60>Y#85>+<d%IK~*$?LIb_4-(;^)LNGa#WK#K z`~|T)_*{@OYD1_&)pVTp`r+CSXd)ml?mW}Xg}fZsnOJNhorq-jsgErFqWlL~9Jqz$ zW?Ge828w^E9en~2xxhFPS<1vbscD|E!oi-rl@5MFV$M(qp`W`!1p(~y!?e9b=(30U zHsHz?My}=#L%jyvF%fc#k=W)r(#SeJS;3>`^#i;6PPw~hU7EeTY)^p{9}=*>9_>k! zDw+#hULGQR_zV_w&eJ^yNkA`81SH2%q@U4@MDg^=%O~10I&`!|L+U_V4MMu@OW1f9 zP@*{FmV+C`o%8}<JqW%_(W)KLkWKnF>a#uHe%=0Gl9-DKJ++P!q0Sxlh2cZ@{`LZ; zQ|U1_pq1&X>cAxlEoj@iAWQGjfsE{X2w(sVG@>@Awvqldyi2Nf8YAtA{=P%g*YIl8 zK#mG^^o^CX3g1Xpak%Gw@-e0<L{x<3CmDAKchgaiTVvYCNIDd7x`M~e29S5x4<sby zYW#-97)Z4&Wu*8J$Jpbnv&SpJW(!NT&=qOjRf0LDS2>G<wJD$IN}OM=NZCU<Wg+gF zw@fB$cKis1Ow5(aE`kRP41rCFtzJDwx3{A<&F+qyK?!_mH3i~K`oG4BkbI1=pgKrf zR2*r`yjq(u&_h9=G0rPwWigVyww#gc9Px~Z#p7QcW6H;PXAf-PX_q2=8$4&h9)Vrw z>pDyyrWY*i@P7{9A3iX(`tLs6KQUs~no9&Zhnb9eHD2mfrk-8)@~HcmPCE=f5~_s3 z6*2P)Gkv+RX^v?=)QMw@@GDny3DEySewItH=aw!DCkSocwGgU)do6F6^y?WhS;ijC zdHPk#l7c}&`8^!4@bb(o^(pXgdU>+Yw=a;X&Qq(Zq|17!u%;~k7$K3F7BFOV77|R~ zj;axhT%XHhK6fHef@pC^H%8jz8GxcCP<+Lw@(g4rqMtXSVqW8%OtIOV29=pI_EFpe zP2m*8;!<kE?He^Bn(BkBzSO-g*en}{nI0+Ryx=duV$q?gLM?PIEBHFpb{_S8aipH; zADa7)j)(U|OaKWOgQ3`qUcEtf<K-@bCEoD)<)J07zl$>(o=kyd_rTsFy9tGrglbTP zY!3=FW=5}kO!1?(L&Wj>;q&gwejK$;HY2`$PapwJ%zB(2c{{$Q2s&fdTO@or9nZq3 zkI|uo8_*lt@{xC^B2x09J%Dm>V(|fclx-TE#mbxlZDnNvw?Cl1YCa6;0IFVp*_1hj z>ljX<&}R*tw*B7x&>I-8<$$KJL1CuiwzqHDZ{OwJFNd2Oh4N%W=LfEw&7b`P`Rat} zN~5dJnw4+&pMq&3Z{A6ZB^ua#0v*W+extGr<GZTu0r^FrfbBIj0jefdg|3xd)W<#{ zHrIfDF444T*$qRKBH&dKBtyIU@_Xo^6r$#mV)n=TZR`E9E3ikQ=<jm@7}Q`>GhhqO zc8vD<sSBWLtAqGI57$y#r4^<@tj~uqwCmE{jZ<~sq%{4Rs_l`hp<=5acX`+k_Xi}b z4Pqr{4i`sRy+sgf;PHxTl;N!&`Lr4n@m3_tWn#k{5*gkqW_2L`Wuo&VZ+0<)49v-P z5Nf7e5k^16y{P@49Ja}owQ1AfEYT1I!N|2PF2}CS4ic13!L-#(GsmYjZ$zU%f$L>0 zl8${wW(N9hxPct5a}O~`b{;$h>w%-miqn7DM^L3!c~n{~u^X~JGGF!)2u5QW04*HJ z7h1zkKI0e<R9VIE24rZ-@S0oQ3utc_cR*p8;Ei+oQ<lTgw0MJenaU`acsHF|3GwnH zSWqw_ur47^E^$CS^$}?hmhL`?LgWt6`O4j!<OJkzIQ-%aNBbl4R-0#(-{kE2)D6a+ zP$}KF2$#dAjqp{j4X@zHV@m8!X+Go*n-iEl<T%ou-$z41LV>vsW@3XRDI;VnyD|DM zoy*pc82ab#`ZL@91raIkdPy53WidwE?%zw=5iV)iRze+%<#5kTr%zDMCt^h`z&WDP zJG23Iy!qaW1#)$_*Bzk64t_`ob)hU(NHUtovH4a^0B&vord@b|UJq0!j>dtJhXM5* zvp~^GmfWR_%G}<HxDnD7c&iSR98Gr@xIOI?-k~o*fNE8i!pnHz-FSB)%Md39^O;_= zWBE^Bpkw(@USDMSPyP~?|Fo$<vCVv(AkZ_GNE)KkvwzFC|Lw@z%I$Z>NB(JofKM;v z2xH>NyCzlc=?AXhmDLh6TzM5F(gm~#nl*<OljUEfCtx<-B0WLu>v&#tMu&tZrsGqU z34iJ($f&!5Q0PX}+|lO?)eI+&L3l@0rHdN$qut{wmkCc*yyq{3x=;|K^ziU-sKaol zC1iz3m0_9_b@fGkae4Xi!$pRZ2DBH9kysR%)8Y0bU;7()jAzCJ1r8F?uU;xz9U`Mf z1WxZCfsk$zp4Yq9!mE7ubqeO0+{*#~1$Hw`hxV`stK_-4ZNe1X!q~7d>clvg+pdnP z7E#AeF{P%lCrOFHOZzbi;>h&8V+w%acP1aGoxmbiHc}+{1BUh%-@DeXFP@t)LwG03 zH7RCB;-t#3e?>M4NWrIyuLp|f9r#{4?5Voj+l>%`6^kQ`wm|4$7^u!rohmZnHq8r( z$AH_6)x-CME*@@MAT)AFA!UCSK-cA5j8Rj8fh%TeIz>yMcJ$qff>w%z&7Tp>GwkF@ z5Xev4=%TO}4^IzG_=uu@%BANKO7SvSDGNFi@_8oQb1MOND>f$(?S`zugGC#D3!DEd z%DaVxvxqv**apW+jKy+4aN?9x7B%Gu!hTHZYa{OGXKlP<WFQ_HyXNLV1=gy6i0pn( zZ9i}(39x&y9z!qFy!LhTNnc2b+OrW+X)wY=z{1qaUxe~Q!uv9f{}z;Dn&PHbAp4vQ zxKz12A!(@~xIy;H0sV#C>y5)RNe9Xoq)E-yeK}k<H+Q;Tc^;&D)Tk>&jXE34SRKv@ zFzP3e&@71-ceh}ze5TqFydLf!5KEFuy_AbmBFbwhZ1R`-Ehs#cISw9l9o3M&%tBDP zKXFISe&m-p6+5!S&CVMtCGbJT6ceBEhWfdAQ!!5G5t_v0!=lwol-a<H3#&2|)?sO5 zP{nNQ8An~3rM<~q7fC_x14FldIehw7f2x|hokDs{KN59dPm20LI(@rP;9AzJHVNc> zSc8@Wb*EYgs~tj3c15#NAf`n)9%fa7Nf!%VHxQlVg^U)7dn)kTPxpjlA|MwFoN>Kt zf4v7=p`4U7GM({ANb!@iLs%N%$v;rLBLHB)CwRiI;ULamwW>+m6h+H*qeTt<4n;B@ zOnJO<L^NhQb~14#%=fYavRC|=iI6<ki2r7Rg3ul&I^~?yMAL-<EDhpirrEOxssdur zy4a@_Fl}zJ>H%bZXk`kfcMoD^O~n*Z2WB@uY-wpbHDymR6nFcpDwE{**T`}49wum) zHsl*PUhVl1y&0=uqhPak0hqO_OP1YKKjCh9Wz!wha(r}gU;AyBt0h9`p~;K+e#AP_ zTaH^?o=Gn(YuTcATJ+Q|tjaWD1!G|gTq_M?qC*9lMr>}G%P-)sm{lq?@truR3ogtz zQ&6bU{*$@V(mrM$qgxZ{aP_fzg;`1e{OV)M;+Ho>2(7SFLuix0elk=#-}j7-Xncet zqyI2Y3p*OfeTPm{yw50j_)lP%^s3DSKgjF30vs7z=x$iXh?s3@u0Up<Ey>CB-CbXQ z;HART+($hX9PE5i-7(MANVGks<Gaz`@$k;fY@M@Ma{UV~fT{*gsvtR3)X<qVp;2k< z9qph9*?WUQ{Z{UN`E6!<Q)@|?_9jB0nv+5}%7AP*bnO%>4GnHgFXcp<Qmmv;<jMN? z=o*vaix?`wE#k|xe@zCK^t?wU6=%<e`C~GDH*HGmN0Y|yhI?SzJ;#En74Br;!Fi6{ zRCoq_5ER@5{ae7$5*6*rKuk7%v9o)PCPx)>-7!5_9Ols+y9o||Ow%GP?<%y<t$ycY zifK6R<t-tPG@tAv8}yl2f~RxBB=jfo?g1Xx2kpv2#<;{jTly`K7Gi)Z4pUmqnZ_K& z%yKCw6P0Mx#B>^^cr($|kBdN4U*}SG2l0ea&!}yoCEg;)f<AUKD{z_8DsrII2-wJ_ zzN%0WrR%QI){PQ2f`px2hY~Ga1G=vK{TiFfNsR^FHp(^x<3c0>W7RiUlBRi1I;o%B zzI%|4o0V<VO!~!{4*y#`&SBL7nxHE+y^_($G0DNS9^UQlA8ybiLWTXZkNNHDa3^I9 z39La~V!GBE#ID9zWre?ypyV#4FC9=*%a938?~R$!;Lr^R&mOivp)G|U8|}v6M?gD7 z$1%D!BnQ>l9S|gfG`I*~KoFxVhF-WATwqlY^wWuwQBe~So$)r8Z*6&7&k1bJ83_ik z8gF<`v<QQN>01GG7UlfL8~<usqt#w{!T#_S#eBe|Uw8X!Mw|GF@gS(<l*4$ZOH7rg zG{K#2hS&ZGP!UB07lgb`)ICth?I)V&!K9fx_VNsglFNOCEhR7#Q$o`cC~EX%<C-DF zZ%$jP7HAp5soG2PPP)H{%!5K59RVNomD8HaP%LI_<^zU|jB}`3urR3q4XmPpb%aos ztb10|MedR^bjZj(Bbx3xBS|7t&B`X(V{uJfiS^jG52$QuC}3kd0+=DiVS@z*<EQLx z`}ps2X0#b;0QLXAqf-+)2vfuCD`X5{5jqpiy(2<c5Rqa{DkoZtdU_5hh#eM2TnLvJ z7qPi_r~vRKNS(<<MMMmheA%2_tz4h770BdN`KiA#Pd7Z{?6K%V$c<RR2AEcEbNrz7 zkb&Y3g7b)`p!l9AR#o5UdjE;UO%?)YHyd(U;H@6HO$uvt*d?UmAVyIC5TaJt$V66p zyu^t$;?n)kaIWqyuRrN7I;3%en=X7VHdBWO4B%4)`3;izeFH~{rdj$&_c4`|Cd=ad zB5~_x9nA3QvI*Uj_{Gb&&tJc!E9d#o2=DJ+KY#K}d3+c%&=pHvsf?1Q%N&@qks(`) z4jW|5)YrdVkBBx7p(4hEB%zOqG$NxGY_{0gL=xkizwemyZ@U{oV5Ic&wX;6_sP%c@ zv*|%$A(_M!HmXf@<-#;bk<+xEN2pCwE@YFAVrs-3+}OCm2NQp8>keY`NjrF9KjP!! zNz7UI5zeCOflQOL-Lq?yuE99FzJVHtKRg9V#yN`#>M;Un6Ns>8?vR>S0(i19BbN#8 z76%kX7lN6SW=4q7NBaHsr<D+_$Yd5cqxM3C*@uo+9<pl7m$JiP4kO(zLD{Z5%~>xl zzPCSx&pAA|7QqZOfCm4aD2LAu^~fY+W}CuiJ~3<#fBmA$!S%(N7JMaOxNUm1rAEA> zhfB(4mvj(?3{F;=+ZVLl!A>rfmArI$k<&z0{v><{_G9~#<^#e8VUl#9j{`syLJYaM zdXDjl^pCC(<AZSsRq$Couqc=cG}LF!Ft~jw0wYXu+QD>}9g9hjB=%577C7TD0{`S+ zc}DnOP*Eo0DPeDQ989U*T{e(mAGJ!9o-(-B=)@0maHY@e6O$yv2kMhq!ZFiv;1eOx z#~oQN0E%G}F#3JWkN-C8w@72~%xKh#?V0&O1|QWG{Y%ClBsJxbg~5!2fGbZ<fz*_& zpI729jyDcILVMAZowA*bV*iC!hr{{c0iojtGcNBtUivqcc$qT^{BkPr{106L+r2p+ z%FAX7K|)Mk#Jdr)gS=Q#^`MXl6X4iPAp&umo`v~LuvHqqqJPx>J}o@vfUod*+bz$0 z0MV%;a`H3^Z`XvpLersth%|8<Q(KrW2C+e%6B^ANGYf7Oh7*fx{46s_2S5q>PXpW8 z(UdAMXO$nlx$GCaDy`ehj^>ZR8&h{#l7#Rcw(AFwg%NDP+#1|Yz(BdmaoEFKSvgzQ zUdYI^p47FSdN)b&(CcE;64UC4+Qi0OucK?Sr<t8i-aOJS|L9@lZe%W<Y=8Rt7qEo- zB%&xn2p_}x2hg@lXf1}<4C-V8<O8|&1js~@lg8JY&;i={|2#l4_<87_$xreGd=wEE zV#f~d0AKEK|0~#$>|sUHh{32Z--f-Vd`;4;WPg{D#K_S^MTC}BqRs)TBEq24)wrTM zV-pY+VF<nDpC2<RH;2qd)wMJyx6ID4fZ?gi&p*F!%*<Wv`zGR?VSOZFoVPih11a4T zbqIQJh*{@0zpL4aF7!{gE~S3J&ZT?&>>#ULG{MldH4>^|iXC{X)S-i+WB;=Z{H(vW zAdw^CLrp9wQqfYA><c*j`nJjAfq-<~4R=sMrwU)C6;ewLB`NE$l4%Fp8L&HS#9B}1 zp+rZJ$E0nBR2~fx=sg4g5%>+Hu%f)kTtX40MZuZKj80P$SnDAs10qqK;&QVizzmj- z`Z_MB+b>JhhJ~o>VVsljwS9wsp5-fT6J*L~gHQ+nL=moeCA=PcE;m$BV8Jn7ROE6S zU)qw0&Pa{hq~1g6L4Nx?$WVAl2Uk8vL@-&~Q?%kj=^h|C(+6T!qs7c=k%2d;Y#~@u z`1ioxhE?0a-*E@)M*K8ZRtghN7N#(wibl*K^2j~n3_OUgK##*fYjGU3X;v<@EUj}# zVVbeysi#TVWbm&bS=M`??ucCGyva}=oeZ|fqEWH1h-?YMz}0(-vPL-kyU9?8F|>K5 zd!20Fp=lYQWG-_Q0wyT4n;wxhi7{#~{!4w`BiIENXoxJ`(aB@}30!cfuP&DZR>ND^ zI8F5g(F2P1HN=6T$iaQ=FtV4TXu<f(AXft>PM{(bh_e{7eOL4sv4zJVY$iDwJed~w z4r|<iTRv_}m(h*hgTFbsB(@faA~^6t7$c>EDQ{;P?Nh`@AaDQ^#QF#_Do84uhubsq zr|%EIiNz;aoI5=nJof^L%LGy>9RlbD#8!~&YXf}gKOfh7#9l(5q4*Z|FzU>7_BRjS zI}hz_7$Zyo&N{8VaL~yaXCLkMIipXH*uJbXq#bo8!3y#@5wdqN&5eZoK+Or@ayoUn z0DauLnrTPe|KB>NOr|F45ivynLW~J1O}Rh@=?Lr+iVCCT0@Q%nDqy5Ot&&osijXDt zhh2|NdYr$zZEoJ9`n5A5WpR0Z{fqY3CBzN|lq(dlx)@@S?xArU&^>C;_NW}$qgKj@ zgU47;)LAikqw<m`wkt;G$8r~5$i>-RY?U*!yX`NDqV%Iiwm`~!iwis1-V&i}na?U@ z#Oa)H#$Eu>!p!FAZosnqshv<dSF?*rMP~r?jxl0{T)rO)?Yz~?(2Lkf`Dy6oT9&}| z2MwxT58WWfNhaE3fi2InBc;1MrTwg<4Ne$5g|sH?VL(e74H$JvU5bB<Iq#Sm(2&Yb z42$aAvE$-3Jb{aqeMW9q%~LF3GK-^vfGkW4bukA=^zCp1o%L`}*!qk3^S$QJ!8Ve@ zj!7w__pubMWUx(yU2;q!TScdGlP4IaF~DimL=+yd^NPW{T!@W$QBfhs$=%l^{yDd& zK>ODmEiYgseBsezNDTI9Dd^A2BhgBu>AEdu`s6h4ZtRVd0xy%+Bm@^1OkJN4EWs15 zc52q<woCZ@SP@Fh!FEv9E`EU=S4(MJ6dMboW`xdU#MXtMYOlZ**E;vTjETbD`JHed z*?B;Gg?$+%uy%TQ*1BjM){t?5AF{XnA}k`uv*&zE5I>~X2f<qDHkYfgVTey~bpqNz zFI*V@1vBXOEJjw#fs6M}4Gz!QE55sS%6m>@T;8j5r<h?-?d_$%DRmyK=8uBg)CrwZ zB#&4VanSmYk(I+bI9!)IW;;_u2B@X&o-R1Hy%<c>&WSH?poMZ(4m}T);53dbk-}`7 z$M-p|Hy>gNtck;_n2^O^?^rI!5|=8suuH;i>8Z@9@^+xdTC3jV5yVCr5|cpbeQ%C{ zlZ;xTlkf@pjl%l}<@?JAtwMu)x18b)B{XKK1;l=Hf9&&6IxO;LR@^*Hu8pXV0x3O) zJ-s`AB!wtcexx^VcP$h&A~2{Z=wI&{@PR^%OtiTOV__oaOgKN1L?r1?>!v+6K|;)v z@{u@<HpRfcXFjx2Xw?Q;>>avmtez?1Ym^0L!eX8}!8@!d4XpW-gCAbV)0h8h|3Vo8 zYQAhD5qzGOo->p0(Wa%BA#b%`b1cG|E$-GrXHN9#l(u`29hjVt9up2yTnFVAf@@e} zlyW<!U7vea<Wf_~aDE<1BO6u^PNA?Z&^7C0bMKnhQ_@YTZpCp>lCq4@0~(!lsYr(r zT8tSOHI{qmNF+|F+>|ARv48RM`sVxVcQj^(7o`8fU+ZEtKJ?0npvVC-A?mSg>ng2g zYS$nNEeac)yE5yxvfPDT?a?gpYjX%&s<D_s2Nxxy;T4VuD29lP%L#Cvap=^kZ!r~) zgiHgw3xwYo)IX;@W}aUCN3S1f1K|EpSdtc=d}At-Rj4f?C=w^1c15~k$KpN>u<PI~ z2OzB1rZ|ES`-Uc8W~7$(2-=z#@b+U#dMS=)SmnendRULU|N8Q$-SfZgzI*-Thv&P$ zJ$o$=vM@uc`+R^X7`_L~P80#c`5i8}MMaRNLi%D^b@&qCXk-YC=Gq+@*a~yZ!qhL= z6J&552pDdXgkQ3mn2L+6J}oq|jw#gEy>O*aV`<TY_s76^pk~@2x!|862z5Z>jCiqw z0SFguP}L6L9E$b;PSQXEtjh-qHA_ZQwwLi^=l<}h4EWFE!bn@tJkFwm01&j#QRFLJ z7PGR*p<GE&omcfpkr!pIOfr&<EB1^zS~-M%6_*hTBUY*U(Tru-OfsM;3@0vI#PqpF zl=(6;f}G;_vwxtOv%ipNZ#TT(!4JH<#`6#W+~x@<DHXOZ9<Miu=%&r&)WbIeY`v4p zXPiHI{nwvW>vZ?z_3J199VbfFv~*6n(k5f+5>(UnLI07dY~^P4Dk!FeYDf;ktKORA zGcX%`2^rQHARc`cBx`jxc|@gHvg%bxFfK@FAM{r{XJ@C~Xq%L`<$#I@a{ufC&=}m3 zM(Qb|=OmATnrQP8duo|+{;OlUs^%GsUDYFIV*|&Fi>D@nlohjhk!idM$e3Osg-IY2 zLH^VEn?wyZS~dK5(0x~si8qiQ8~(!n&Xq72*Af7*Z2v*Y<mJPqp6#>lfP%&-@ISgh zX@9|4b{y?oOJR9)*BuV&Oxnb_fLQ*yTx(*w)_3}9uAG3C7LS^`XU+@}$lv6%r{?LA zX?k8lY}?&vd|AndM?gX!?3Y9uJ}B?=f&>C#f(D*2O-edofB3Np|BfOInoUDW|CbeN z7$fS6xRoG_?&7tuoo*6ztkn3LRvgj7W}4f{L&&_uh~h%?dW~Uy_e+xryFlXqVW95j zXq6|~UA`Ez%I=b#D4?){rwRL2S5;hD@#P<%ynOL=_w?0IFW)lND5%4~#G;h$5mG{1 z%rF7CB{0Z(o9;h8Z~iS942Ai8u0@<!DMiAjK*k<p1~=_b!8nd7x;ksOFo`(&>*aOZ zTs{M+glr%McrF2|9)^ebZM0Zm=8cIEY*Om)n)K}A!ZmU%_vIr|Bhnm1{Iqr=(j@l1 zI(McIErsICg>bCW`;(;=7&Xbh!4GW%LKs%eZBpMlWb%uyE7{XH$VJiiSVy#|>vfeQ zuE1#!exAL6uV|FXfNZtgyzdiX7wQ*2Lcxm$NMs(+A0O%j<lao*+VpAItDN9rR;5@e z*`d>n(Vc!w?}lg{B1Ootm$t28{hFpr!>^o{@v6h!ZuoF>FHg9FC%_i4r@<-$OlJqs z0L9RR{g&c8F>6q88$<eM90Nbo=ll^0zW8<++yh^t21`TWDcYwq+bI~&M1(5W?pH`h zo{?BW2utBS0ic0}%p9<j-Vl8<>2OP~f8pv$c?L0X*aKj|%W;tL$^FaM4_Egurk|$% zdgj|=Ho<_DsNMjDO@bgB7o1==yAtFL9@F&Z(ey2D(>_X=_CjIFvImAQ_YtfwC;>VI z6Sj4bf=D^jR|kWX>Wu3WX1=@~jb}l#bt|DJ>Oz;<MPY}7U}+1ji=D%oscj`(uuIF7 zgBAG`B=YDCF^Tv_AEXb?z{nQCnF|C7=^41&&STjcl#PBEq41zBIpcFhHUdoXMqhS! z<Q>QCw!%R@@qMHK=DTDNzsPCV28)n01jK-0*3lG#ow`LZU>}w>d_bN6IR&LJ8sP0g z`s%yy-aLQ1d;8?u@1O4^2>8R}7y%(-LXJq4POaKyW&$%w{KGx_Xkv^40@8&|+wPHQ zL^4Jv{v@pt&DCG-U>`{Lsp-PbwF5iO<X?y}KzzwSH3Ne<PE!iz^tG7jji2U=&J6@{ z!LxC`=`fu}Y6r0=*L*n6$`z*Td{)ZTI#F?zmzWgcf3q>I$yu<XUF{^;2yNsM*`})c zSLwo{%SmXd9Ev>1j`}DB;#4FTHU2+M0JpS+4FY%&2!+h6j}cIjD5;%2-!O7yjj=1C zKv?dr)%ez)Myh~Nfv654;(@50Tbk?1xD^G|U07P<C71kggC6>7AKaH9UnnTSf<~4& z8wN4hGBJy+D`91?_^#Nwx<XbMQ6L@`9aB_QIdo84?Rt8E&DOKQelw$F;i}?|X<^S5 zRDYm{om$h~orV`^7q<904rL36+-eERe3|1vaf$Dj*ir0kwd&C4&wl#hhyN~jG%DU7 z?(^O5@6Z2RRx4#A(td~<c(3K{So*P3Fq85<ucJ9Qi#kqHs@f38O_Xb{TfaO_np=E7 zV9@L?n_sEuX!xQ6&h{_(5CU<OcQJgTpNv?+grw6@Is4nISAXZF01ilDK%g1+eT@FG zJ{a?TsZZz2r)I2d{UgIwkIEOYfY=?1z%Ls(IwxcJ5gheC5^?-Gy?9{N&xiXr@FE}X zHh_PR8&Y0X2~rmv_^`w<_vl$RKNw<B_{lCR$Rvs6W)bqPP!Go}kIn#kea+3jJAAl2 zU{KKr3f$ffALI0i{(jKziM!lIoe14Zt9OC|cHh#&7>t!Zn<EWLlqoUtq$?=tD5KYg zaS`l5#apd*+5x8FAf=rY1yB(f31H1o(SX+?IvkccZ1<jaDRQ?hIXd?0G5yR*55LJg zCaV=YA53k9JEH|oa2+4b%s*rj*7=A`*OxwZE{dWVvK2@oWGI~@b*dNTPpvQD!2YAb zP{#%!9VUQS5dy4JtfbS=?Q$DvRbdJo=2SO^2ojthBv#YkzrDV`+}e+4m?2W(INN2E zAP3=rnk34V-K7|rB3R&|TZ|!4DklCHVxwI+G7HACHy}30J5w1PMNkwTBT}%aZ}g3j z1sFUXF$?XRTYzZ`@!SwHe-v3#R?Nnt3OFM?A6o@VsGZ|!&7!WMVRsfqr`nZ7KRo%b z9qRPE?`d%Re)rvr@9B5rn#6qyfDNx(?O_d9g4sJlv2@ygTChzxVCaIkktf)ZFs(F7 zO}E*N?(rGg4x<X=EeNIitR`=pY5)Z3S0;})WI)hziyLL5-8!sFha{bB(6yaBYYn<= zg=RWCTCdp_XGIZx4(q*M6Oy0sg*tk0OAL<D#)h<T9vE5K5PT!{$phM_P=%O+^4pvH z{(O!AG6Q72Nd<BZ<ISENekGIHFR~&tTTR&TJM@;EiM9RNQSwid!%sR&ez(E1$H3RO ziJbfd_9Y?X#f_+?i9l8C!riq#5(!yQebV%L#$BG_9bqbMU+H_kB{uoO<4|G|&w++Y zM}s{$7MDxqLXHo^9ni%y!?V7uUnP5o4;EumA?FhT+0zLKN=xg)@vXtHU@-uh7oB9Z zY-A2xe{u132&%l_NxFDen~f>Py4EK-=!xpI=jEyUdV3WHhjwwE%m6|>h~<?Sh{C=+ zkr4QudX(qjXi<3%SrB|43Ik#%gq0nht4<HeoN>#OZbQTGNa=G-D9$5(QH-ln5-GG4 zE83xL*;5B&c{!9A2^@$XDBFvQseAGpVbLTI$xvRUvMzc(()TBSg1V2rt+1+~GADws z<K#=Lt&L->vLI#pxz)xZlK;s)Fc+AMQcy#;G+_cFU9t@Hn4<ts9{>`2+-pYBi*g=_ z4f-LF^J8KtPohnzB}EltYVyC7Dr%zoeP0bfE~DL3@Z%)dr8A5Wo_1J3(Y~~`GV`2H zB@EEou)-i|M@K#{Y}7ZoAD>t`h<EMiCJ{StubS<7K6sz(R&@0OiqjNL_&PuX(NNR{ zyA#>EVyRgdbt2N$=8VaJGm5WJoh-~AhrOr3A#gm<siTw~nTqmcgWYT<y1>V{DJs7^ zx(Ve@NYV8BCdgA`1Y<&R%eYfFC=lr{jHfJ>oh8h|5>Iw=L`2wF<;Vx<7s$HwRPbB_ z`%Hw>cs<<aJ^GN;{$M-PmSoq>$+k3K>|VB|nfUV5LrE;ywYIhCC!AD=b$SUKP>nx^ z3OLI1W9WAdBn`EXJrBuDbSc7F<m;GW_4dz*axJ3#{YUW+4J|or#p9V?4!{O}w1??N zXgLxhOeu3r@bf*2g!C2Mb;ymvYA^2TB?fx~`b#4=7y3+*qCt8hBu6aIcB~FXf`n5- zjysMP6V*{`LCl@MN4%cQ3~H+q%*^}OK4k!oL>Ct>EL5_>eoDgL##u_c7uv;i6d=VT z5TD!W1=bkF7_FGYK<9Qs=@i~n?P~72h)oNN*|(&K@sUnb?iLCO$08b+I0#`8=e~N2 zJ|q0Ips#2g-;r>V&t@E7g6;v*TUfg#lu~H^)cw>4eUH`IhzmIsEO-J151s)Hz<aoe zc!!)@F0dK;MztV(U~y%|a5T)@DbQ1a5$O-yWYhE=O@_7jHxTR_fXLru)jm)G7ItH- z&A1@B58Zv?1?RB3%7`y&6k5`b=3E^jjr-I`H)R)$<L~(DLwgX~U+u4guZD>sYFu!A z5QU=)%ig>+BC}kGc!YLOZw3fU8qrovw={aPF}CDpx^7G~J@NKj@hc1zUa3ppodUFS zw>5$xA{CYbS7k8MWM<k%bBpLnf4M^WqRflbUbumqm#o5IP(RZmrX>X%44^5~Ad(vn zt>5=`(8)#wZ9DUGafW4)0^HZIei;(IVvE37n$YV(o4JF?*?-|o0ECG*%6ovH4HaEP zN!5v@oQcQ2iU+U^cta?Eg9k8)d8PXkQVF8M7{@dsaHjD<L2n$^iU==4_RHy8>{ARZ zsD=#tn*OM4RL6l9NN-Dm3cA>-V9J<|>V(#IFf!aMY$mSjABCp%f}cvPjP4qB>h7p{ zWgVS$bQr_SH^_Imq(XRdlYhU;ve^0*l1=HDk$MP_UGDPE4f24c*e~a+NGU&k|8Vuo zitgl>)Z4g>cz`sX*MoSDn6m`jdBi&;k-0ovJzx#zGl?G${j|N@T%gb2T+pmJ`teN2 zh0HWMVO*KwE7^b*m*zs2=YmmVl~a(zAdV1bqg$t~apQ7H>jskf2;NhN>mkBif)>kn znCh6>FQpc_#4WcVi8s(Y!ZHMAo5h|6drF-#J-%)ZY>{TauHR4EzREo<TF860rt8%q z&txxgp&VLsMyQp8?ABS=;lLTwbC0i0!D(oM{gc8~uGMo*c;UR&?P-SVi`(vo!RGwk z^)1#d6hSsNS>LlZX$8iDj1HUusiQr5mDZ@!)=G}4S6hQpv4<stlV1_E-Ak`*)4v|n z_&%=nuT|T8*W6=9dw)>bYFK}`p5d@3mTfj_lLO2Nw&Jh$Nu*-nX)rH@o{T#N9b{uH zGO|w1Pdkn$SqVKY&9oHJSWN#%VNT|){YTm$+8$L6&M<-j7Z0w57y86bmN@J)KU(5o zxo|@p=^6Aol?mf)<9Ermmz}f0;W7)01Af?3Lt_tGn$78J!+%DqMLd*=g)R#!FOWcv zgt2DEpGt3IN9JDPN$4lwdx_#p+yTkLU8FXH&`eFc`hW)=UDD-+(|X&Gv9#ft<I87K zU@yRhW$E(d+5R~9`WTNTDH-cjSqqACwV2`^#QhZT2-xWbjM(1v9ky*e5C#AX!owM> z$I&hN!c?Ax%DY@@N9ec_{)Sxvd!JrZ>V~GG?W4{BPo>3J<c_&B;!e5Ln(kTjY}vjl zC@gHh=WQXx2<j&zhANu@f&}G0;;l9M`yL>d)WA@K%YoRGb}BeqqWozhrZL)$V~M-E zoxa@m)cDF>pk1yU*uQ~|S_LmhfqnChqroycCm+U*Hwk_@sN2$$N|TYaTc0->ok_{c zT=d08R^qnehbeJGL-fTC!&ZT6D4GDeHaGe}Xj8)82Swh7$=If@c1zJ>sb^#g7bZOz zRTtJ~Is^*fH{%mwgj22_WG`jv!g`BP1kZbbUlS=?WlL@9v4XvXE=;GPq3kW4x~v_3 zUe4atD4%2m3=h&XHrl8)hAE+JXDgyHdPf%*(>~foOmJ5FO>=wO{3@i}1_qBR&aI8R zWS5Kv*j~#tp_(<66}EaV654?8U3Pw^m}*V#9nm@kAB)sjtk`rm?i0*s;Q&B}Md}KP zqcW%7P!tfGQIs57CoN5%D;9LIcvaG|1RRew8nbaFFV7^k;dW5a5+PsIV}P_H=g%3^ zQG6VFE~5SQ*-DxdtkZhMHSPP#k?EF<pd@4jS(XkXNcRT@!^jw6*WuRl$)mwVQyWKv z?DHNja;(oyc`}2(pwP;3(H0Fgz7&p$ZvW%6Fc_4}pe3rN^Hsb;rH$R-1#b3CQ2fz+ zCQjhG;~(UEaE6RF45-pbkJAQYOB-_O5ZSD!P61)RKgfB8HaW|!Knz79NZIn4DwF$6 zuAy1o-d+hytHEFjQF^rEA*Rsjps(JFd$zK-wNTZ5>7?cc&*t+zVsH9;CL&Jd(^sfE z|JU0Eg>R30Mu9sCJ$#}<Y)<9Eq*Oj#KhfV}by5YGP{CAL>VbG_2`dQZDY6duO2ci` zTX&Df$tC3K98im+h5p2lkx=7n&?AG@vRzvv5`P%0y4)AiP!1C@S$u);L5#5_M%AjY z571rLnHvt>cxjD0f_QtTY$tZZIT?uBWB+I%%1-aWJktZ}PwgP5c(x{*J5$j^RsxbH zijD{?qlfPhEi{l%$l<t>%37YPJ1gRkF#{k9Q8a-!a`;FDMJb7VY~QC&^`D5kLQqG~ zSK8wfygpSPW=q~KPA9sQ%mzMDbc=C&>4-P>W};5W4re9*_J|t`h)1{EGq`^p_BR-y z@x<{1q<K(hx0$69zr>3~!k)ZJHL(3VLFl>`%zpcz0nL~il$44w6M`wdFVK*4l4Z!n zNc$;`-Yhw^<*{dSd(yapm26;=mdFA_MlwTRDn@&YL)k>Tg=x4kGt6GAA?2dDt>oM< zfeDK|A}8m<==Ya$xC;+Y%{&(#u1&o46WO0Gam^jNG8aLwSf~jGgY|0+I?_NN$WgI2 zC&W5jk^Kl^7DD<xee^Q*s8;V&G8cHBHJoCz(-XT1TQz;??}U6!uog#S;KqRKDUkuY zHmLtK6)`%T?qJ`aFkf<QM9Z!y&7mG)6dHq4?pn{9yjDa#`a!b!k;Jn7S|@=*p9V3# zi|_42KK-`uv2mBZo%f#op6C5LV_-+mt2%Jr4zSDbjABU%cnZ8v&pW-+$iA3?Wr?~7 z!H5xNqD9Dazz?n9Q6SodQqT~*JY*2N?g#pHNzX_Hc;i09D`t;NFHC(ZI+kr}@R4-5 z+{elD@4wr<eD(JE4#^4L04tGx#8x3b`aWF=`Xt`#66B-V9Fv9SnY+7RYY&X(aNQ3w zNokWuOO=xZw{>pUQejNHxL`d*E1DAgV<R!}2vQt<!o6)!+jBlQ#_SLNJ&Tb%6$v^Q zcArSUz`Ymym)RM9H^SqGYq}TV#;=tP{;W@{JAkb94GrzzZ}jZxbCR(5^)Fz$%KD)& z3LgatBA7XLx^C2^!ww$-)N~PCT$lx*`SKIvy(9yt0(0T)3Sue0dMy6RO66ii>;xSa zLZ^cK5wkuyRI5OS#+WHuBhckXE8b+i6h)atKtn~WW+sewgso~xGhpkAyV1ao$5)T( z#R#lY-8KRD?maS^a-|$8;Ds<FsT83OZBN^i%o&%wtpOkwe-FO3o=97I)+b3d&Zo%E z_LyU~w&tpV(7G6C{UF9{;&?WyfTr~SVLjL*l-Wo(PH<Y9Tq&$^Z7C_Q?`dP==!@%P z$gn2sfTSHZJqbNdxyT!FXqbo>)?1omma#|hCU2=yq$L&$P!?*$varK&BqAgbGZEtA z%o5T9GKQ)jYbUGEt!yc@RXbFUbLWh@F^?#E3x@wpev@OINmJ|JNg~S>fY?B%6#);Z zJ(oUBww6gv{PM6jPP0fLskuC#fovlDO6q>JwP5LL-Q<?|LG<JvW?D-F=$%CmBK%|s z5^$rdK~f4~{*DZbdCx)#G)yf-j3hD7VS#~^WhpLv6J=phTsOJ{v+Re(c|vjBWkI3l zdJe2z%MisS<}FoFCp%h(y=i{Eyaq0WorXImI&FmC$lb%M)m!vg=?D?8IN~LvBOZc@ zI3Qz<JnY+I*xP|JMkWCyOBhSNrup<%eSmfMa#(C|KAPQR(<C!(SWZBLd5mca13bOr z6M6KyO8X>_&TF_Dz-DOwfUMc+a$JHuPA5WZcJ^TYo8f>|ChQ;)I+}W+f~ZU)<xIvW z1+0$a*Gk}(hC7vc&*(~gvp_hKj3ff(jsaK<Ca&32tmm<1D!gSDVmqkH>fySZFH&b% z!lE1b3Ikj|R!W8K3z@Jg^$H8$oDVD2q3eg+j<{WP8F9Ln^J+twF}#xP&(VuED(bQs z7zr=tDNH2t73|{aR)>Rc&@=1EqDio%%jO~!fHo=2Bd}+biNNRfkg8xmC}PN(_X#i$ zb53+Tk~?hrj&f(*6Z<KS%bX7&4cyw^MX?*<woaYEE*Z&$?iWPuC{z}<BY_U}-Q9a> zPV@i9_cS@?fDM#;+$6Eua~)K}shYAYux;RUWe_t2MZy_NIat{KISCG-dx5lOupbz0 z2<vRfKNzkZClD|<psC<IL=C!rCVhbxs(*X?tH2(rmG>ptJWcsR`k{i0`C~ls`6JAV zOMG^v#ZOATJ}f}67`KC3irB)hHiyYroLW$^=stF4BxC}&d*gkFuwvAv=+33+dviqS ztvRgD94sORj;QX<f#X>jA^yDZ%UE$tS{G%Zq`Z(vO_EoEEbXbACD6TOJ2xdC1XKnz zCJ-v`1|@5m<NsvGyhZjlYt$!mNEeKqIjIGMsJ%g>GrM%{vIr;Pd(A<I?thAHh#5D7 zCi-ESg&>CI9_~K#SBl97L5B<@D2eL4vuH}f&W@@9^%JZ>LWJ9E)~r5TVMHY$(DZiG zMGKlGLBkd_-r)d@r$IrqfLd7LwCHiY<wQlZ2qQDLJE?wXvxIB`j<cXGO@&}>>T`|z z0d%YsU3(zK#3J7-2YH;_z?_hYjd;Bj^q?T2Fp3&CeeZ~^h7kaW-->XGE@M}n)LBYT zE*k20woBY>ZixTnOvD-=ZPe8>cV`<^@=2j#Q;P%S<QL_o_V55HybW}>=7i}w#Qt7= zZ8?s#xcpX3e4+G;i7(Ir5g_FkXdY3;`D_`yVYjiSSZ8xvX2?WBgK?I|RY%<ooW>v? z0t@@-To5(~r(tM@-~b>Tt)l`41vkRj^DyRzjo(6pqfV>{c$T)%DkK5<lgwuGbP>L# z^BK4LCa0sr7U-#Qr+_jzQBxv9`vtCq%u|2R0dOzAT<V~K6ASd4chv1~DV9D_r}G#6 z2&GNx+5Z*-CZj}T$-|<5tw$^X^)lbTwoz`KGz4jEa&MhI-z;k4`gp^Bpj9~EcMIvK zz3p!72l2%9sZT9j&<&$l*U*j@<JuK+nnczED0@D~R)Vw9>Smh)Wab-=n$Q_RKiM>) zP&kg$28r0pmFsOUdUC#J*AKUC|Ef8zK?KH3Pa#G_RVfGJDVohqMa6FlV<s~pqYZ2X z&@lI~c}iedS4ukB8Dp8@8@t)`B+o>+z_hjRg;K$i;d0UCz$Ap`Y*GZFkLl8vZ7_f) z;+7S5Wt^3HOI1;E1o)(61fU>s94j`~BLDyzWt4j@w@hqC;-Uk~2RW5A<6iPEK8TzY z(Hv|SaJEKY$(1q0*X<}4;Qb^vz<^NQUP{cS$Logj!~XF3OCmEQ*XZ}BOuDC4A{NfN z-<#N-{RTghheobEM1O3zsRg2>)3nm}s5r;TK*wU;Yk`i$3p?{DjK%tRHF82OU3}~^ z-sq1t3xz2MATLa?HplJW6}{+0T-BMaO$VF(<gwo8<NS+@ow_IhrkE1yw=O#f*HC~C zx=JgTW7{OiLExI~(Wz>PhX=EQf{>#?jQIw@{f+!4=M0tNf$8-@#B~5Rh%~RRWG0&6 zK)O&9yqu|%Q>>uDnPYc+kmEGBNChhxd*=)g0);meLPQf%AKgjKJy)h!N6Kv9fu^P! z&m;Gao|8oO{IoSVGYJv+nkZYMLXqJMgSD^ThwVG?`x4{`@3(g5=MttvG;Nu&2|;Fe z){?IO_T<gqRFzHk1p0B&{H6t!u44>=^}-<LYswH*(WcC(>47}E?*EMr1CvXX1q2{y zy0Z?~LfoZRO;`uAStOjd+M{oS87owb{oU|6v5ad9X{z7CU+pf3E62SC!2(M|akCq; z9*b!mOPg>`DpWxbw5ksHh9aEEF#3ZkP9$<AV8VY;HO$dj=|s~LgYzL$5pOoQ5!0PD zq!|=M$py+~w*V83<A|wn+%bRfFtaTbM}f`EifH2EPK1Z`Y?sphEF$83|3>xr4F`+; zMpW$J5}{{@F1lo4`Zhgd$K@QG^^8&*{OeDQJC6tHRn$On;mnFCre3Y@bEl+BXdDR} z=^@A!Sr6?EyC~b^Q=24j4QzpWu;u~umS9vptd>jh2xS(@a{6LOD@0lh)nL6+lf9j4 z2k&7S)6Gw)1Ie83J~KF@$m~kjy`~zb|7qNYJ1P&r48q|79kR!~8!XHHB8Fh2wUqoN zGB9gM5)1|aKnH?%YNG4?huQ6s7Q^rzo?Hu*^aXcZLM%jsp931J7ouT(>m-#sq888L zP$1aAynyG6<g`PLZFW9sV2o9rX$L;K>+si+_z4fIf_epvkqD+@Z)UJ8k?iLB@-q8T zevzMeDea(urD!zOm_6mT9nB4BCYZh2F4;MbbZ>{*1f-N2ggFo6NY1$2@JalTn*)_W zJptZVGUy?4&;C-Q8wO^Ma1cPV8N01Sk)9=*Fk8A8h3Ts>{qF4#Pj}B>KHI4_r&V^a z2(S)PIPX2=5!Rfm*H8Yj`|hWgPb>a*w|}_m9DVJCC%1bBq7)A4mBc5{s6d$0YYK)X zpxP^Ve+<#lDEr<H5}ERpFf^b9ruhSHpr|RBOcmqqHCsNJW!^z5uI?b(p{;NO`w_hD z-iTc%SR{0?{Q=*zddSU!lsAs-!Yv;MXdNH9CQ0Ej5CRZZLWc$04S(T_j{SvIhhUnb zCPTV})hVsYvH@=&0Khz$N}+eoZ##8P<?7&Sl0U$OLpzRG-k=AQ<%dc^^&RY}XB?JL z-8p{XB0wUNJsJ7ZuBG=3KfD&-1dFJf>8-(%W|x2!r-<A-5U$fqVcjQp9@M3}s_Z50 zo+g^l_f-n}h+_*&JH2TSIl!4-<f0P6e3?x9dZWKJr8rv6mtH$jf<O8q3#)K^O6w2f z2s9^bSqrPImz?F9gruH0HW4x~+#X;EjX;9mTw-PNF{XZsTcQhoPl5E#X_Za5sHoUV z>jg+)6|0o5Lmp3^UBJ<FN3x7D!jmd+@MNT7IWu@TchfU6Y2mI%<9msQ9h4o+NXb6+ zdzPk;An#b1(EFgjo6PY9*<pT)7CA~F5G+x0WJfQ-Z#9`XNgi-iz4a$KPF4bx1#qG? zh-FWe4O*rlxZjbtz4`E_=g=52wdn^;WBBGuV7RMa+4NWAcljXuACs*^5fpGHs>NcI z)Wc8T)qYxY(_b+UVr|Bs%mZ)+5zXsM0okogC&oLb_jO$idrL|?tT3JN&O4k>MV0*d zXRs{FXXrb~$mGtX5vaI9R#p6A5gWBFeJ)xs;g?}|Tc36x3iu~#qc2xh2%|57P@nKb zzvaKD-&ja-EIM>uM87D}FI5g9H|z4SAlW2*^xw5Td$h*Rjag^4+ksONId+~tq&$FM zm>iIjaIG=lVjeO9>4^&ZsvzRj^_X7zfd;OO*nmP=Y(ulz9;k&Lk6q3SJ!q<?c)~MH z3u>{_`QiZ}Vy(EIch2rqZW}^i1ZjJKnosy_;q>!@cd?S95GURO$j{oUzwFyKJCU-< z?JqmwI1y*a@rkc>OAtp5m)mug685=Fg4f)IOElsj^Tn<Q8jtv|;cfbH_ox=$1vKNm z8ODw{#&W<=g+PYZhTJNO`B=AlZE<*_pi3yexNvfuM3}~v1;`=@AO74rfEGmZljmfm z%xv^dc<I|~0FF;`B+ngwWC0cCW%At}W>3Jeh@|v&Wob`;sA<IjO8_@t3StE<8Y&#W zyM4F2zWy-IqpvA$#duKl^l|e1Q(8^@{<)^6PhS0R2gjJabrICkV;wW)5c;JENf={J zcRSr|SsRe@!{Ht;=Tph++V&|HUNY5ul@{QXz-Ius0V#;2zl(jstoWrgc3kfifEU1k zWas@LX3NaihRaRk65(6mSWstk*?|s&DP|cbYU!H1xcEQ(x?x*(qJ0QHVTT?~o8TcJ zqJR2jL~Wz$Ls<WD6&`7j9S{@`b2>IBLi0d8Znao6VZ~VSXogURF`gERSheVQq~IUo z*V4JM>@SDg@`?PKa%>nDs&2oGT!IxHX<J3#QG(jG4d@M2eaxU?hORcmX*e7skpn%H zoLk2P8diUsAb&A{E!|^lXY6037ZQ&{G9Nk}VON?b{`mUsgd2+_hhSSswcz|rDS!_T zJ7yJyq>^$aqaj3_2OJ5E0H_9+C))~L1JXuYVOT%m!MaDsgO=jhn|r{+<qYr?VR@vv zJ|CV81bL)_sO)k_Lu3POJ!>-Ix|1!ECadBQ1zaiz*HXWiy_>cI)R`MZnQD?}4&L)H zct;am$KY#21zbb#9_d)LK@Uvz?{{|(`mwUM@n5QPlpiRu!yfVV?+rCde;R8Pv`W;} zy>FFAcu<hX7E@r$qVYhbjs{dJ2LxF<kSAN|Ea_^al};j(WPg`QQeR#h)g|sS6WLhA z9+|&g(Ly7UZP31UqR?b9E?T@exHz7vXHaJ|<Q93oXDP&VJW6b7)k%IaI4+zxyjYO} zf=L|jgYWV0<Kp6^lUqGNUou_AoRUx#!RXLq?1cVqhT^1hs1qdFcvks{bOYmD4dwUz z@)|weN}0bq`MX`ye{8NeB*gk`kDH7bfk}hE-*_dgv(?jDsAuqwhtC!G1$5-$a~wZh zL2>zoo?2%-BJvSb{b}3jix3_*r_P!X7++3mPBIFA8mNVX$qm8DY}A*wR(koDcoCo) zq~2O<TL{xDm-01#HQYKVG=>&k(6tM!9#Qdjv+`uU+o22_1@HCBK^#3?IXig9fWC6N z#@OcLhWUWss!Y;t1^|2A7cv0)p+?>=&0yDM=l~jOk8?_%AC}k53S6q>Az!G4$|YVP z*H=d4I7lf?2z;bs07V__JELkUc0l&n)O{pW)uV^~0R&GrX3WrYTB3PUc-S~z)Vijg zS;RqYW#V`!y^j)(=;Y)ax)&Ig4G%m|9A&teG#wi){1UYp&CJe%K67g39O#s!s7#w< zRX1!ivBOq{4c6Kg$-|Ux*j+SSdCaNiJns?k!4(A5vZbA@uuYGC&mK7*DI7P(g8V%Z zMLUc=M0rKfrr<btd!!wY@>?UqXSYZu6KZJqr_|J}&~DWMDc8lwHA>qs<~R!&r4eV( zxr_e@s#J6w1fxG8i<`DeVT&8Jlr(zPbq_ZOx_DH2o7Bv;L2BtMPN>dH2b$AXL4Kgc z*j7w_sL9*tX)4c4bbN8~^PoZ`i|!(Og6nJUZiu5bpf=reZ}_u@pu`oDB)$dVcp*WF z{Abie<b^yJ<UI(qQ5(!V{91Z5+2-JPoGM<eC41wtL0FQaq$`em{GTm1Y-~NTH8Fek z<n0r_5wa*;3zTK(!YNXl4zEm{Ni>)?&~1RMY4(@4X!BG~@ol2F>JlUL2s@K7lEyBq zr(H2+VOrgve;K2`l6X(g2~MS)a^)VN0Ij92w|1S@7IVH__k^Pobu2QF$pq)<*(P+0 z4kg-G$d=SB%iQEyA+be6X*rEiav7OVB7s9R@uTTkk(sqo*44LPTzq@|`G?`B8<}<0 zy_DU-O_>6qi^xCGw$za6RhCX(278m-;g8~sdw0h{FcJ6D!5BLXX0LqySsRx!5hCV` z_#Uzu@T9Z@<V=~}CWJoKB<{}Gt)sw9SKu$xZcBT%7a}Cv1~THiF_WSMU1S^pNsq*S zu#qgc@rq7vg1?l~Pyz1c-Rn2RYbNob<>)4QfbMQTNsv^${v;=MV#p4fiQMim?v&YP zXb&j$qn$17XV~X;*0jq$gD*v;%#j@Qk7@qH7Y&pm-|y+SL)MT$hw5J=O6DPeIB!@k z4_B^bx#B2Kp-e&qpw?Q4^zBnc6j7)ljm?LQk!OnQcTO}N!fag+4bOC6EUWOPUzylf z)R<wB)A)@nIy~cGQmmXV)m8KH@D9o#Qkm1ngCpsiY2N>x`~08%%GSW4;*PkJ*W&~N zzNXV(W)=E*6b+c-n2kYiyF!j;0wBe7&>@N-og_^|0ne>?Fi4nP5Q?y%rqquP4??>c zhzWHC>}4-}tqK1GN_K3<_(ze)p<N@>)vVa%y4~m$MTey3nB(oJJpul*-O8u@p}=dA zL5}X}TYyAS;hQopyJP)`boe$`BU^~mC`!P`$Q5DT)dnJ~gV1aJoN&O5vQ8&Q#v+_w zo)jrkJ!~6j^N@L$WeI8wzz@$)_wJKjE~!IyHriaQK$<O_ULGX(XzsehfjZP3jD_Ke z{2|-~%uBa`R(g`@Qe*>%t5z35+ox+zu9Xa`eBXpLVf+)PKCBHIC=$><WM8E+$}Ex1 z{Uj|SiTVQ^P;}9{dv^710LE218+>?}a}Av=kchNXd-0L^16rJSrLa=3_j?-}(OwJH zPFxWn)1x>uP8Z>(ueb{6K`e-uLUB&xnI+1zgGwh%4YEv_X+niGHTgA0FIQ(yQ@*80 zmOXuD@P9W^2z?si!}e!iNY7bkGJNw;w$xwv1*l70-TAqfzu=drwiDl6IJM2gJu!{^ zNvfQXUj0w7!FEH_!O#Y!QIR`;3A~0@lDGWI=h-bb%n8<B$OGV!d=`h?9U78g)qyU+ z>M&YS#>s*(FO-XvAa6qw;`bUmZb7#CljM)De*sf9ulGqs4lDB%onzPexgiK)T|0vv z;rSOxo1^|IJScJZqt`SuQOP8hn*svLrMhZ9NGL0QuzOm&p}{p6MY9v12V&aYa0A2) zgYK}j@`mZ-Qb&0li*5S|3ey8C!SVo5t0c#>l?WL!*-45sIQrwa&-ES|2x-s5{FzFs za2|ohxA{IgLZ@3P><4UgQmpX};^>29GfqzqPi%;f4SlG1Ck*0H@Ah0NQkPc0BQ=J} zWmlxoTIu>A45TMD*l16e{MW(mi3cKbsT3S4JT}W3%?>mCCUWuJlCkkK*jdjrM3N9B z8X$lusO;82feL?tBRTzP_+#*+(V1AL-SwyI+n%PE?w9Hx{3Mx&^vrswRxEdLR7I*3 zHb7+Af98@_qTa#)C4Ariu9#OuF&-K5zPfcluxxDOW`0^3>+e77J9t-ISpeymk8JFm z-Ne6g)N*#v{TxGFge4;lM9jUg8$YOCoehp1#SR+!8!&H&9fQClw0ZqT^E6MTWeD2U z<&d$HfxkNy4}bg<YcGgg_SF0L>tU29O0@_jqKr1Ol>AnV^W0{(5xe@KTIokUKR%Ed zB_~P};k*EJi%J=)ey%@otL@2r_anEchshR&=z0f7y&q^`AXA&inj0sC>vJ}!p1lb$ zXh1<Y{+#0(g>N^2>zqL=Ke_<afWsX(cX`yAz<*XJ?-7(KW3lyXz;JCBk{O~^Sja}% zm^wi4FIqI<i23d2JW(`Z<NQP?%*O%FJbf#!&$=Oz>}f%7!HgkCnPqNy8$J@}2V0$9 zGq;;mr!Bh5q+uptO<SNg3UfTi7SPt?EWmC;9h;@;Z%UQ5NT4{0Y>n80lagZQj`#}e zzM(W488X^9rI)e4eNLu%?+z^dwM}%C_ym8?(e~_QXhHcR07a@=2rjga3cQhx>o*ss za*MLXXE1Z@;TwQeDOiZw5k|}ulOVQ0the#j$x5j!6K+&WC;jK1C6*7;A5qb)q@*!B zS-`phAh9KHkb!nhfOZ*9r0@-$li;dm?nxJwQt%Qaj$1$gw9fh%CV{;JygVQ!Bc()a zKs_FsKeLe%B!Xa6l=I%pOs(~$n}`acC|VtG-jNevaG`h6tP07jYtodayo=cRDdQ<a z3XfV;%5q01B1u%6wGL?eI;9ps^9UgP7y{0VFx1Y=0B5%70gx{hZiF?(=qa^qq-Fp2 zLw|!XO@FgdF*=F-P5Zyc50X<}cG)SdhtQqHOPPhif&^hs&S`upf}b4h_5lAPLaRF} zr=E^n#mLdhnxvr0K(`x)E3vS9^nsqNIa^Q3jgqrwFeso9%RSuQN(ZXZvCh%~Ewhpm za{{c8yKg&*;P~F=wNp?p_~aaR7|_}rCO(>l!!;a(p9foJv#n||VW??~kp$f{o^Xmo z_?#2FA&@l*oZrDn?iTTj>{Rx_9OH~nFq946_{v}7s3X&CxdSgeh&CsOyr1Gb-SDPG z{OX;_X!&b)K^(rC64@2Vn?p(%?~d0s^;~^2Ck64Xip`orgMPrt?r=9dPJv1Fra<zs z2XQ8OpP`{WReam%_9ggeN%~wKx+L!Fjh&wM_5;>tJ#%&}%Hn<e;RDRKxH1$#`$u~6 z?hbNccq*ZAFVg5O98g=^^HLH^kwRxVK=`zmk{r1#^|HZaj^o#cviPgS7F)_JGo-)~ z%7OeqbI~wn!=Cn#YpIIOQ79ift0Y6445Ao7_8AFAX48rZIC7-W6)WF{-I!i-kPA7$ zQHFx4L-~j7ND6>sQZC6vCKOU{BAt(j!&6xh<t-;M`jLDLG$lwvH54lvjGD~cjbHNO z<u~s=36}g?eg|Vfd)}`dy5?#q8>Q40q-EU+d~CP?5dKe+gYnp?-Q*T7=cuiKNwH9o zBBzw#`WfSm7;T*L%e9hJZ=b*Z;l;}*-|v2S_3ZiX$JZ}jz1~Upru>olLJJKla2?u1 z_=G~Nu-n20AxGwS*p8M77s@P;>=i#|f(gr~iY0an^#LV~6nW4QG&)wysZ5<r+wupp zqzXnBMBSX0ZnL;;EhLDuSwYbB0H~juAC^bU2~u^GlaWO&LRw__I4zqibphXmGaI0& z^Omu!i@OM50}75<N1OXiFRwv7c2Yt4C^{<5%>mF!KoHt4b0}OHxnPENDhZ`KONxZ1 z=n4WBPKx-hv~;_nVM>?m5bX!&&H{dilq3I4!44CHvZnh)U=+X1^Lnw$b<9Q{f<i0A zZgZC%bBuC3l;QT`H;TzDuBUdZUkgvpJ1kO{XKb7nXMuEcN+nI_5D`mp)S#8y7To<H zd|?d;7C$phWo@!t49vIBM?tI%Q(X!cA|b%>Mz1Mtpu@YSqn+-V{hQ@<+$hU+Ek=%{ zwN=^08MMH0_g8XW^z{0}&Gi+r>Rm}&tR?J~K%lUpASfdMmz1vL2+G9)a>SoCwbkQ| zMgE7Ax<sx{sMh$+CVNCW$K660(aNWu2^j`UalNa|Dc)L2bwpf<GapI?6)C+lg*1Sz zZ4&OG@P?1e7pua;+GG3P>G;HGmn<F0M!cA@E=5*2vZr%xdl!Y}xXG0|nc6vWr2hn# z@=8tzFhgnsf==5ml#`&$E<-i)AY(%e+C7Li_3k}<X11*!bOD+GUcV6vM5cB;ZNc@O z2NT1PAP@HY(0NLpJtBw603|bmBth4CFf{}}SSroA#DSQJu2y4;=K5W~SbRmtkNXx( zg<h}-6uG2c;kJhLo~?grFKV3M@x+jEz1x|)<+0JPi=1SSoiG9rwKQh<v*MA<%NJPf z^2#wKiow<)GUuFtM&l?m1UWHlm^7dUYj-Img+5+Z!qB820kT)a^gQo;aeSDK<Hdm% zlkUnC(J6)pDK$`+3YltDL29cHY)%ml$imdZ6C$5mkVMh_acZni{3oILizFn;(BcFD zJ3*3CXA@$m8|=1KCYDP8TTY-{Q)xxSD(fv;s#AHT;53qWlj`RN{>%OIRSK^)8j)K> zz`d!73h>*ak|!IiVKW<mRJu&B9&XG~pX@|({W=?+NCvAgzlO~39IaeTb~3sMFw-2I zlfec?W6xK+H;W7&JIm{z-n{+(`Rm=2x37M96YkY!N*$y1#XIppF&^jH_fP)Me={mI z)(QkrG^7k^jWnKJ)*GdCoe@S7sz9B&dw&~e=Jy@lD(_5xbWDB?O%zQne3AP+*sdJA zCQi`b)b<z=-$ciE)ch}6ROVw`wGk1g;boS({R_w@=V`(GNjCYX8v9Ttl~meJ+23pI z?5Y0sT#}QYzzU(elG-Vj4X8(w37l9Ve|X$j(2WGIB58VR0+a*BG^zs1>G~#1!G`GG z1Ib6%6Gu#Pt~R-_jdG_DInK-lR>EQCktujfABo7VBB1M<vM~e1{e9M9_=loEg_)v@ z8P-Y+dc>X7RCh<*hFXhdIR;l}aW?1w62fkTMqgtDLjVY0HQqPWN@|qZf{22s>_4$C zPRN4f1j0Eb?Z1#$ZSuH**tl@SiDns9kQqxybpA-h5wge%>YZnoBhq8K={nVLwJzd} z3=yA8d=Vm^WCY+qlVgi8MN?h4azsW$K1>bJbTA31%Fv6Iu3_Z+eTHPkAVdQRYdn4x zs8H2Wg1~?NYS*OChBg*_aABm!T^P?5#w(W9nVbB`Zmj1TJ3Tg4EA1Ds{ec5ic#k37 ziLVXbeLBqr0<*L?0eG8BWFqeF;{@9b+5WZfDbA!-=5U2tf$L<Y&`A1(&?G$`1RNe- zpkF>Au|Up?v=Di53*`jgvZ9@OxH_SoDg{y&W*Lczzz`;Rk~M8qu6@DX?HGzx1RI6s zZUH}sKim2}^&r{z?B0jOHMTe0F*QT52)`QEJG@P(&3AbjlTdwql;=gCK4BUH*Rz=? zUAXB?GFP11g#2JF$#I%Ny*)6TVJ<Vh5~_({J=B$hy=(F@E&+z$;1l2mahMqTG^tJ} zm6YjweFr^4`YD|xc<2sf2AScD1mbo;>PhvtBmUy0xW5`3BZ5L$4x$*-p!wFC)JkT@ zW_3ax0tdtqDT+`%h4;ihtylW5>!ruZ5he+3A#5leJBr;OH&~t?!XuSlJ%Sk;4gVi; z*oEGKI-g|*j}uvlD8WQVKS=DDTC7i)buMQ?XPDKDSp(#dSk`WFwCRGD$s7?=x_5Ch z6Wd>VIIJ~GotN#}qNE76Rb*9&)rfTjoW*p8122a!7_uYL3yts~FGxnlRgJ!pdtO`p zWu~9LkO<@Ys(u40gf_SreP+499ReRna)6zP><0UR93nP}vcILDfhX?n=p3@S6?`wi zXX<<Vf$}xoU%(b7PCC^Z;|?#>AJ<xAmPoUTBf3uhIQ|a5(ziyeiFHVG3F0NtcvIBQ zsc!%hqwH0!aUrB};yi&GXP+d;qf=LP0ySP;RoG26&lF&rp6|#pdQRr&v6~$m3A$fh zDDAAqx2i>F7>ts59|TC#-@m=SzO-9BV}fu*Q&RAOoI!uIL(A70H0RMR%RRmKNYtYq z(zjSh={%9WPNX5?S2x4eE2CTCcUt66rTR;~A1ZUVx4@IY0qRh&oc<ObTrG4CPzr8` zn@iN?EM3gB^s^r@0dO{_DG=}^>Df^SFWj^-%0*yt<d}dOE-;vZ<4F)8g}B&^y_aSK z$|@8Gcw|v$@iiHkvG3-b+AzGL8U#o@aOfy?E!?J(;U#m3;Iv!q`U+FAcLSDO8qO`@ z7SnUF-6|q8C6k6X1`lC+_Q?iq7;t`|!r<T}AX)K-HiNMgMDzsvr{DP9dqPGTH*bzW zn&{xwmHP}5%$R|#Zr;a=s4*?`(hud$l;w_E9Ciry_t+$$_-$q$2SX^vG$8_hw0nx7 zt1O=Tf&rtq=XxA0nee0My6E5v3r1#UNxhK5K4oLH?;;bGgr!n9|9*spJ>2^!b@@nF zYWJ#D$(Nuz2Q>}GbHlE*Z%k+1xRtE<&8*h<-{{{;i@V)OWXacETkI=BY!VT>krWX8 zaMggbTGHJ}5weKo(3mjdtn?7I-}i^h{>{3^(b;vAnfaKTM^i=|#!&=-FxSOmf=F^Y zk15_Rc2qNw&02v?r^-pV-3h6JUv~TJOYL`(u*9J1Prn&6rLdnWnE3(BbXL{sPlRp_ zq5GYN&Q6?@@Y>hEfK@5&#c{^}Fc62Z>axlW2-_;=$XxTACqD!^T(B+qSNuclvt_kT z>~ClZ>cxc|8iM-Z{L5E@R(yl&_p2zZ-~PE0)>gvrG<1LHO2E#Yh!n3%<jF{sT|m0F z63&BLW0yy4;H@^mlf^XAG!3TUb^Cuwg(RqKDDBIyFx~Jhe$7v>hrOPFMyjU$73<(# zBcT#qQ90H5NRYWWwVf0Gpv{(;v<+#)M%xFKld~r*#wIk%fygw-@<A=KC+t??&8{1x zxv2(JaUvrBhWM^jMN08QkLw@u1W*+N0|nzYl7~(s=>Ru{7zv5U94m#eeUQkHqVeLy zBuf58xKbRDMq-Obw&Al0#R1p?)it#OHL`0As?}Yi3}en*(<yOrVR8mJGcOM<xs36@ zL*nfL3zx$$!rGCaFD~9)Jz&KkGA`G5GIs7i9t!P=9k$+p0Hl8KbnF<e5opZpLWrO( z#oB^;9-1*UPeLui8L2`Y1h1l?<zO`$4dA~o0U1dR_Ru>-I&fbDHQ399VMgmIu8>s$ zHyTy*LfaZ(j%l>ImJ>0XzR($Enhw|mOSH0u;X1~gjB8=qy%|<6a}b3?5quyqSg|2+ zNb9?Y<`#(*!`J7XED`BJqi90RNSB^DejJfzleV|$@k#LFL+cET4Q#I+Oh6~2AF><+ zyWGka&W*^>(lED%T}?+4IB&-XI_)n*H1a2s!^@pbt4X;oe?0VINIrl0Dq!B$$O)2z z$9)NU9~m@rLx;(w0k$D6*r?osp~f!D5&jy#%Jg^9Khh*s%LFPbloAkn)8Ss%&jRPX z+-q}fTx;mySFS?iUM#(&b*o0u3H}}%p0y8`ksmedQc(2Lk`s95ZCAq4Mgj_56m+)D zR$_%u?Hu0k*)}?Xeld`LxZKFK6xW_pIC03shMav0QXPh<2H*+Sp%uN$I}2*zeu=^e z<If{U4Bx!IvR-RJ?xThnAERAGzk>et-Mk4+Utz(xJ8OzP`dHIOE97WZKTArKH}_44 z3K9%q+mQ1+%bSEkSY$njld_u?eTFcNN#iFnMZz$(+o?~_nAhJ;X10cwVPYozyJ|`+ z`-J;fw^L7;WOiGQqXTcD!h*1|>?7;~SR#tKIhbf^351W~AN4>KeFwx}iHiT;K=*NE zAFD9*{B1q|e7G0K^#^NSyI4;?rI*|Dcee6=chF>VQ``<3GDxM0+E0fVR49ex`H(Yx zC9{BaUjHP7y}u2gbt`e;;$h-bAEQkOoRt?a%DGd+t=14@VtJMrseDU%x<z2YF`lSJ zuqVP|l->*B@|;N>iX97h12mg-mR542NEMM(8{FcmPfCj(440xFqvf{O9QV&<{OV5! zQF^8Yl>tOHwqR2v>Oeyt_+7WF5#c$}kOIQW6mJV`_4fNgM6b-5eoBQcalq?Zw~?pZ z{ozs167e_jD6?|7b*u#mNfFSn%S(Qj4VNMSR>#0F4SA-o+R#LT+X0n0M52Z8Mgyx> zh3$bQ9J>^6@d~1Hw`*>N@ZO8OMkEb8u-aj*>jQ~1dB;ef##6%ZsCfhCBG{$#27X8o z&(JqmRWUQ!yW#Ru6#K+jfC%wRwtAu<`mI5*(_C$o^}}VWFYV$ip<7GGQeljtWJZah zH-TKH2EGX1$sJqgtgxgsG5ZTv<vfYzgp#}DsDbf}ofo&d?_JWeQD1VbflOl5>@B}& zolrU%q3WdZ9&y#SfkG%wduD`V*T}%erIi0KFc6kqYq2R$8%VtghnqOFeK~{8o$TA9 zPb*ZTGIL_P+XylYBX`SPz~!fM4U|F3KnK&TI6D@IV?Dj!AQ;r$dw*^Y0Sqzeq7rrd zR_y3>-JYbwXExJYi{^RC8wBSWUKs5DdVo!|EuU<-TG7Rh)iFL0U5Q|sjUlGvBf=!j zB^z5`2`(=|Vz{sXL|c@&BKqv(8kq`x?9)#$<dR~hNIs7)*Gf_za%4Lwd|e9tp`j&2 ziZQ*UL&UD-_ycr@f9|e7A0UZiPIXDgiykSw3_0)*H(>dq5>LYdGl7;37C2mZ6G_V2 z^OkJ16!)w<c`c_PKrmg}C?55sGeTSKFGUqnB=vODF`;#s1B2@wFo1d{znQ$_QErZu zcm_lur6;36ZB_@?r{OEqu=#+thpR>m&R>0k8v3pN!ELMbGXYdI=+_i5@qLyC(yc@r zjO^&|L4+^TO-Ap{OW~Z|`-_H6MU^^c2dyA0FnGEeP6`6JLu`Y(R0nnw(uQ)O3fQJK zCCpyT-ZxDOd8|@J(T+zRkpAhpv_HPEC%p_%ts04P<TC@Jj>9IxD!t_}C@qa42+F@C zIfh$=n-{KY9g$0mkh&>Z(({J&AifnDwx-m@D00ZK`$zp}%cKkF6(1oByttrPzmwl- zF%TcRod^wiZ42r9ex-(rIv>7yNYR&*?a^;1E1ltj5v=^RYZyP-GKuJ;bobOW5oPQ* z4xm{hnCLP%sj}rF)eV&`Gd&2nPjn}(N8_{ZBuZZpg%F*snCMu_>t1tqxJsL7rBYsX zn~Q6N3&ydx0g8Y-fr$t8LAVqg7BrWo?4&S*oNmS%LdyJ~2WN32l(ry3>k3R}t06%g zokPHCQ`-n_+zZDFR&YR$|NQICK*H$Gp2;!Op*jKPKp!at9PVOrvY`TuVzRI^=;092 zvLrIzDm#HHg?NXVr*@)(h*d>hw6s99B#EJji+g&rlQD?e)_coBuMVunq@126B;}Zn zxlHJ!JA-SYSl9iT={?Nk&*+S8nd3;kR0LLoo9ifKAZ}75*a&l<QWZ+-aVO(u<LJrl zy9cpc|CyN}#p9ip9NA|v`a&QA_qYlT7X+_#uw|be2?lv{d)xdP7f%`Jt3iby70^+C zT|R;dOn(U-%T+;8En$JlnoiMmtX4<7LD%_RMZT^0%8*Fc5mf_H?jE5Ny?g6isllAg zFrj(VLULu8XN?j0HgiSG<_%>sPQy13t(;;hJ~A>WA{qq&of%B$)kJoQJTPB^-^*le zlBU@RVvC*y6OBv)1~ToGOoBR#4bWQzpg9rzt?`5Pl&3;-X9ExJq%9?m-~R3O^C!=C zqJd8bGjznmeZJfM{kinb6c9LopcpT_Z8M2E^+}&pWw8YIjl#pY-z~e?<4FB^5!!x` z^d52$TmhQ4vFpQ_B|Cz~OZ;w7?)j$U;<J~-CmWpwJ5=yoRTf-2dMVw=@Y5H`Ph3Tw z_VlRbB!!@&qfO6AtrthnUTdbFr5op?X=kMy_}9Q8LjDLzADZ351|#y(%Hmab#&F>Q ziFodkl1GD<a@_ZIfd-QS+C%>w$|?6Kvk{Pg+T9uE-wv5xV@=D~#9cvbRZw|qq(hlI zob7IF5iNoiDrS?!{Wamf5w;NzZ?ntGb;bJ_<?I|gL>fDK1Nl`}>3M`-Lk-(ATtI`p ze~u4lT~}iCD7<008MestX1$H4*Jizbz&;^mr?XX{aEcoEc_aNl6a`+C=sygtllop$ zpz(vL+jN}ReplU>jRb%-A1ZN$Cqd+yb7Iiu==b;J`Yu<z)<GZ6PtHp@nIZ95rU=S= zEOUE)vQRYUa{#1nqi&L3OG;!jBamTUn^`JT9*aqvwi}_m7MrZ=Jo4Z^ANKnKK?UxQ zWYMIh6ZtYzoh%h;-}jR$rFc?N%}kLDM^T^&iQTM>l0-+avN#5Dc!P;N27tF#^o%2; zqlks~=YS|1E@9)5%MO1=gYq0=QPNmY_>{rc3W4a(P}b1ms*IWYkHvsGKavs^&aa%d zS>))t0Cz~3Vb_`^h^P?{q$=w!=emG&<qqYH-L+)pFn#f@CyZmYH?1WY{^9*x5mxnO zgf~{x?sM3`I+l2!taIw#-u{Zdo~6Vs_U`owdlsJ#5h)1;>Yhq`pT;s70`DJdYi2g0 zTmQ5t$a!W>X4$X|dM+Y&BGt!G1Aye|5V06by6bYYaao~9+u|b7-VfK9K0TNIGF?YD z-k2X^>yb0q3Jv<;7A>t<se$)@lTEk8bSH`EDd0@t3?wEuG2W?ax3gng;mzv@oa8h+ zP-3HQ5Rx5({uD2T5X_FrMuaE>blfd)F545GbGQ>yiyz3ivPEj`;qpFCAFjk5eiUIu zkC<!-O_zkw2>&O2ivzb50-oqtLR!WPK8>nYXsU_Xm8amH5->8MU)zXXnIbZccm{MW z6Y$f92iL%VRam&*l;^<#fC9+?G}}eJkU8}+oWzD)=(2$gWfMV-vsgus?b7lZU|Cm? zY&8vT8EoMJU~Cp-VlK&_W=hq0%dcP(?4goJ-u!B;sH`)oELDtrJ~a2;d$(q@I>8SN zQOF)OBaxmxGmKdk<%?-3%af8`_`SHe+G3>~vr`3*y1A4?2OO2hT@J)J&_}95wsa~5 ze&b0wW>#1<I?vs9_u;e_DS;G00%F%FAY=nZ(FPsc&?2>%_<MSoTIw&rt-6%p;Jj7y zaL%l^U_u)bVH*ydSnu#G@%KvTn;nQXO?|mCH4HriwTAJ~gBfrv&$Ww!RepX+9VKzB zo<Rm!t_T{NH8`Oe2OG*ULF(VKo?UVjca+xlG%(XK6^6~HB0W%Ly0+<65<Mzrie1_# z@h-o#YvP2Y#^Svc-ZiLHE>lf5v5}aOL~;-rO4v@5$M@IQg4d#m$9B>n%S4DwgPmC@ zquZu<$lVSf<MfICe!vw6zpPQH0_6mNJVd{M@h}GtD$}m=owAg3Q;zqGI*i&a!$;<V zi#-h+&PtWgOVZMw2sx)gU8@)!<|QH;6+ws3y6VLDD4|Fb4+R>);d5Bg<@nS7NCVX8 z{X3(F!2Wv5{s>hXD2{+wB+z9elB>+M$?EfTiE~N*t7S{aC7BiNY!p4KT6Q(@Q_{es z!zzb}XWVN;Th78zb(r*2a^OINxDXs6+2&LdwwmQepyLD&Ax$7x;3plob&EfZnSCC3 z&NZHhqfbK5-ic*4mjdB%Kj2jilc`SktzCawK{~Z@R80l~7*Tu0&ohlo>XjPzWe!Z% z(**PK!lR5~DTKD&K~yXuIOeEwR#nPMN94{v&`AgnEkGLuZAp48A_re$kFW8il6THi zC5{0@<_z~`|4bF&bPS=g##$J2HED52G{P+V-&5B)q)ovifvJeF8U2q*Av8x5HlHGt zIB0Z(PjX&f3}IDp8@hv#!KQgkpNJ(d2ODQ=EKC{FADiCwd<PFCc<DNqf#V8&pAPO6 z)U?um&%aa)E4#c_FV{hIhaz~dRZ7!a=c3({DhLjv-%vrQOx?f?jI2Lr$YqeD#n?@2 zq4FmoH;vXxii6mGxxS!c(MeE(<w_EpbFd6r3b&D$;Cq+3j%<zuX$EwO;{$)xrZxz} z6ai4jgY}eSB)e~lIE-@5RGY{-0XbxdLR1*)vgCa=6&RnSwxIM34#Phis<Gd-0)aW? z5Ts4tnbOp0-4w*2C|j2F9GjiPd@nStL$0jO@+k<67>O7Od0{C(T!F^G50g9K`s=LE zF>n;M1(A?ngf1y%EM7^ZS+t04iCG+!?3qFWl+<}=tnQ%~7ks0)xLt(U7NId}Ty7td zaqW7%5NeqH1T~o(Drs6}%^)(7gK;FtK%^RK*}{Xx0%o0u;YRGifUv{mu?f{`k7G$= z;~sh|E<u<eSV(OW3F4A7+O0CKfSB;k@i&L&5rN)rKLIuglo)Ag%}7EiB-l;yq@K17 zR5!$XN|W#DqY(~)IM2|xDG9@`AKGiNm8V9dKfc7MDjd#Whg<5>VFij&9n$=WhQU$d zU_B4GaO&T5a@6oK@(AK35G&%ob!0x`WU0`DC+kM;W>Z+1o{9p8HyFO=@ea&;7*-YK zGKvDI4_I=l)&JK(-}SqgP+xk-S+XsN=EN7*jP^0fHmR_n1w*@V-m;!)641#s5;K+} zx8WWBJg7jvmnzhBp8$n4I?c<Th#vkTnl2{KU7JqlJz@8F)*djs&+(o+cuwIH(rN2u zSmcUx=U+~jLe2jVh|1CH*M)U#0Du)fk{t{3@||v4Z2KESk`?Gu!0ASPMtm0B{<JnE z+|U_7;wtQsAq69{&`5D1!)0$^y@f!mqYUR=L@XOslVESr78(k)a!CBY_O2&H(xZx( ziI@aYS93@t;tIy-CGB+2WOkMa#+}GyU{{9O-Giqu-Cuv*(`;{d)BVkE4`@z;5F$jq zL?JN8Rq&>gg9p)z-X!3`lLkEGAUa;ugSh^FuimS#s=5aglA|AV*Y{P`d-ba7)vJH6 zUU5f1We40;yCSqbllj#;9=qbI9oN%?CQ8sNc^_=-D}&+g-$5TINuXN_Th7}-r}La+ zWT9tVuiS`z31~Acj*7{2QdG;MF6P}(enx4)cp<ECK@lGoI<OKLFC&2=u%LKO54MIO z-od7`W)3@5=-W5jxDp6g12vXV*KRyN|MjnZ<=Xx(`(WLelVzD`J!PR6$iR{sFO-2~ zR*$$*#FAp|;gkXIGic-Pne9tZ66^U@BhRL*<Cb1$fNNu*6<5M)3huMl_K$0<u{8>7 z+AyhteG;7D+1c@P(de4*M1z)gt|}Zqh)LBE!T*@GtW19bDjPGTht6T*0_vd{#KNLK zOb+;Nc*{?zU{4$;U8b|E)8R0sMMB`sn)8;(p;Ubt8rZNbxeaO3r9~AT9yMAXn36&* zd|5*ST3p@b!t?>B);hR00`v7}wtW!?NxWv4>%5ld{ln%Aj>14rji42X)xt2Isdz_a zbVI8$A8docoZb%Wxh$~`t5vsdXBGJh4NEk%-ldLDvSieTd2MPA_A$M|*v5|)--#G( ziwwpBE_Q*?V%u^O5(ZwOe$}BhAr`;K^Z(T(jL>>m(#7b^UkGj&aKD??B(gW|8{6oE zMPV(h+2z(t2QJgBRx>JG)F)#~(j9Ce;20OBN1Mi1rCxL(8F*69>|x3VD>3i4AzGf> z#2yX?+n^n)x@t^k-Ndslp;>|L==pPdSNE^%7M)h7^^Ajh^|XfaMdHcDu1@f|?8+nD za}>S_R#96HLU`ccaNBcrdsd&|SnQ&9#m&iG>|PdoRegx=csjvhr#VvC-7Pj-8xD4w zK*=gPxoMQUDgnXus@^*ca5L320x(a~6_Z)OvAN}D)5U060JqrG4Iv~J>Zeph0&%?( zLz?*lBqb4et8tb1L|LH8k;7_y1-GQEkiz05YB^-eZL5F;6iFFLrj9XPcB5%ok3%@= z>h@r6JMoFK$Z_^)Fe*bhFnSAD!G}0NIu1R91ZtXvkoF}vT7bBd;3JjBuCjmuKnRu) zu-Ss9S22Y7E!sJr*F_N#E>mp3$t6mB4y)Vcou=HSbgOz+al0u>pZ>l=7PIbM>_nlM zP;D5K>7^PWdBy}m{lo)xh-@WZxcU1|;$cOFtPA>>8#+D<dbdsC6}H?0)BS#NLaTlW zCX9|oSv3eRHKg||Y#L3|!ZZ$f9s`fM`s%W*#KKfy5mgomDP3|HzM%UW1RrJ{g)$qC zQhFM`q0GP)i4$j;m7K1n2D<TgM)QoXi~Sqdpm}R!;v3g?$I!QzjW%CGQqBY=A;%dV zmczZOz6yg*$K7FdU73<?BIMMF%NZ+f0a^tE$mt~iUXHM0j-lTVq2f@|$Z--$vavQ3 zMNuxhg~|nRH7c^;=1u@_@A!<0QDw=f<?66If||riwMASD1CXG}Pa+m5#x*=3$zz-? zwmL(itXLJ0lRmk7%<~Q*cr$JqX(H4=4)KVlDC+S-gcr?hg&?5NOy8<bR$BCyuo~(% z#1~YJRNg-bm51gthkD%fb`uw=YSb&X4x-UFos70M!FB+-9LQmp5WGV<h!Dh?Kpg2q z-ZQ$Uu+Fx<l>&J|6^Tnqsd7L(n1v*9!#pqbg;Ye-f<eB-djJtvM~UIYMz6e`$}=lj zX=^ARfRwia7B7XN$CV<c2!l3U6OVZ(Fz8s3jKUkE2_-y66>`8Q6ks3Xtc-YN%he_D zkeEONaVJz#w35oa2SV9^H4`{=Av9B)_}%T|LV>LD3ynya=kfh1vY2b7Y(#d=r^jjW z0S59U!EfxeSJnFmJi{*Rw1x4<hQpyOzo1<ev!jT^1MiRq>4wl2Fub2kg(B|$CTWlj z`hAd;_?k|COnXCaTbrquf>}kdVf96}2aKqDP*dJb#q|OwP(l<TTez2n8obHA0L>+= zRU(4U>+Un=<k^I*XOx=4k+lWRN0~Ttw~r?<5*E@YSw*p&iEUe%Boz%iZML?Y>;<N^ zX2eNduL`C{n%uywZ)Jeg^q{GPLnZZ(XPtzyNan6j4EynE%R+6-cr&l>{uqn30k@68 z$U-s%YnU3t)Pm=LMLMr7Q4DEiFe@<Zx2&7YyK5=BkfyZFCiB)%aH?^*NFoVd72=#C zpyTV-%O(mI5wwW8`oyu74xh>C<4h_sRSphk%^0P<<p$*>5}}NP@*1+mrljD+a>go} z@^v=YkZ@E@D|IR}gm^@b6C{o+=XJLSx1M|V$lfNHbcop;**$!E)OYelwIJ8Rtvi79 zZaw!QI&4oq3WQ;d*Cl|y&BnEBky#z=@htJrMKFX-c{stfDkx^nId_1lX}*B8EVc0z zAaq;-+5^<R#lj=Rd32m&@d)jmaYzC13$<OCJO#2T()Hj1%{^;qW5Q3it-9!MhZV5; z&)IR09Ypx%u{aC!3*q*K{sn}2D3qhU0)b31?OV~i_xwBo3=iS=fMS~Ii@8r`DSR;d zZsGeM_wP>){xy9u*We#ixQ8?N9ejTnKZF0JzL<OP5f8w0KY*XXKkmKVb8v~<;4fV8 z0p@<g0KB*0&{uI@!2kV-{#O*Sxu0U9c#M8a$K0C;`%eUa?~@YUnLAT>(oY;2Ij#>s zh8e!cSs{4LJ^iNtw)73&@;^Z^;jj2;?v2;{i@6)>Px#01%i)*sBZ(ivPoC4%RdUqR zrxiZ%vcNBf|IDcmHP_PjzRqd&1ox#3{y^c){X{2FCMXQv@O>+T@4xBeo2%?&(WR`y z2VP!Qcq@PRCrwY?pM5)y-Oz8o-^<|N7_v1vXYQ9iC!gVubrnCS_+a^2`u}>x!<+k; z-^a0=`ZM1jXYhaS`5HEN%mx}gdHTOV7}I}H1CD;;;g4ST?iV6hzIxxr^VjNU@UJTT zs|v5|7yxqk-y-Cr_!)oa@Ogb3ytyo%k45mOn*OP#Z}AXC9{V=;E%-|QHT<5!-&6P( ztYK-m!Re>_D_+PkM*rF0e2lX{YD}$ID|dspeEk!!ar$R}SNONQdx3=$JqB;?zY!M0 zJNJl>edc2vM6i4{IP-o0!1Ocv4;21D;qwNQ!#@OgroUkb)iwBBelRW{b1x{o_ig@f zY5KqWQRBxqgEQZY=fFSvLthSWe?Fx+hyUU^@SpwF$0doM|0b0nIsCKd!2jXpivs@` znKOEF`2BO>&wk+HU;ln8|8n@73ZIw%cb<MqQvL1|k4C9C<!5+aJSY86?_+F-=cfsD z18?5!-wc=e(S1|lPcJGzYG59h-zNJsia5)WZ+LH0K;d~3ze9*dt4-_wh~0RX@$7l= asa^m2<rI6KK5Ka`Jhs31yp#cCpYFd1Pu;}; diff --git a/test-community-packages-javascript/build/packages/glerm/priv/windows/libglerm.dll b/test-community-packages-javascript/build/packages/glerm/priv/windows/libglerm.dll deleted file mode 100644 index 2e8fd10cffc798d1a6145a9733ba4505af1454a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 352768 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 z�ddqNH3uAJ>ZfJL%`UnBq3+XIK8&RmT{#a?nOnyH5SH@eTW}mEHSKA3M9(&-^n? z`uUsuvs=2R5B*#|%tU=Z+s6xA_ftRF9EBU(mIim5g?;-icn6I|e9sY>Y?(eoa2n=y z5SiCAV+yPh^Aif<tT3zPYh$}Gk0Bb^z$a|5pw`B}c=<yo#<$hr`Z4bM!5K8Veyu6j zFN7v5&G=SQE2g`CT&1V#_0_1)pqb|HHE!kl+{!lKhW9$m{@#JMw~3pPp-k=V_?Pg( z(B3|9Bmrve?Iq;FcHZ9pbq#$!fcEynE&C~d<wLAyn02SnfvJeWnyLhLvd<aMGwH$6 z%3c>nC7Q1g8BJ4#>j*Qc3O^GX_w}I)#|olC6<qw`cTk17t2?N|6udI4g1JA{wLUEW zOw)(gaq~Os!w)whSDEzT>(}wYpbrbsr%CFA=WRT6t`C2yr_TqV53Wx$=|gHlq~m@Z z7^`YwmsWGdXojIizpv8fRVUkN)qnk0IUei(<VY19GepWMfmXhrrSy9#{3|TP)H3x9 z{N`m%EkkrQ{;B$w-G%TOsMArH4k}Z2x|McTH4#mgdA;Z!RzN92p^iszBzqP(^pGz{ z#$y0&5Bqj9UW6JPc<H}esSj=Ife=yZO`?+XcwnmR<>*bi+Y|keY4phrO=zG^Hz|Es zaWqYjcCcgc>Lsg)x<w&?-YQ2b?eYBN{2WsDB;MBcYEZ}XA-Qi6#;?uSeu{9d_-4qq znOzv>#gOh_;~$^Qr<WFxCDtW#%Et_xqOtEhrwc&UWc+rpS$Ktf`iql!#1a!H=M3^k z@l_&kh_BM~=A^tKzKZ0C&@39(NX1uSfP)PL02X~{aXZOPM>>vQn3bkT><2=ePBXNV zHuH+r#-`wgDwcVd5Q+yA<5S65Iljq<w!cUVd;a50Xa}C34WI`{rj31&k+44Ad!YVy zVmenD2XwFd@uqtYCt%IXuHbHTr~b@>Re;?;FS~nxrWd^3?#7$kr<y#D-{j9c^QSK9 z!=L%)6chFR^k?ROl*xYap&hfo&7KZ&lhw+O{TzHlKM_V}0K4)kVj>@fGI}yg2v}>r zTG%gq+LD0Kd|e^vU@#GO@DBdaN%Qqv2C-JWnpT<ju&3}Uz4;2m{!oT#JxOx>DzksS z`$MkQjP1ishW6_~_4%~xkb(UjKV8kYdeHQ_`c1*>PI`^Y5T^CJ>2oQ(<L>l1@CTE| z{U&|>cxadOq0a-%)b~@LUwnUm_4%VJO`peZ1>bai-hs9=gFbI2;G{mk#wT($eZEW3 z5&HaJ{_s2Ka}4TbYMl145Ao_C^!X%khW9szXe|1j`kPlwMYi@=pLg~lU`?N2A^(#5 zWEtlJzFtnBf2Z-->kvlPojyN#(t+!9udeAspGTRg@25U*+ql2_oQp*SXd_7v+t{}> z)gt<v1K7k#g3oDPjGly`>2w<_*rEf$M!$-X8qgA5j4k}36P<4T4ZY3$WgT=n3$N03 z+KHq)*yoP@&5OYq=yNNZq_OCC(&xJ{MY!Mke0*;L*7W%+czRvvbN^T9^Y5h351-b( zK7UYn;QCzJHGSyw95eO()aSnM?yo-oX|6$^k8A<&bbWs8BEjc0eLjN_lKMQs=ySy9 z81%UhC;U6;vl{~tX*T+F8j~=Mo}}h$P5wqleZF&prq2s;WA-;N&Rrxc>t!|X^ex$# zrkjkpR`zR8EJewpersdSNn5imn2EK>E3)vfox3=B$KoZzdj{}Jeme$iWhK8ao*Hu` z{0q&+=ln&8*}(f=0t%d^ryh8s0EE6dR(ju<(-Rl^1Hx8>m;l6rH;p;_kRSeD$w}ar z*07*Il8Sr~GtS6+$+}p7^v}g}+Ir0i`oJy^f56rShy#?Bx4e-+i#Kvk0_k}pgPKsj zcz>_L<a*`^wVxnW|Ad6a{!qm6@Mn0$w7#rtrd9Ho;h6n1gs%BYr(&sPYZ-0M*TZvl zcGzoeO|-g#RrVA7Yhuq49r{bnZ_>mxEwf&TPgG?GH%WKULUh@RUEdnwcVRfW9V_nS z`j`WY+87&?on<-u1hHL1{0b13P6$l!VB0|IFk{hq0y|{o0+LU~n#P}zuXcYPO_&1A z!geCI&7e|9gKfpD*pV1Lcb9w@@8MH^B_5>rCMiSc{xU3NdyorsCp&3~un=WbgpTW{ zMgKBX)vhm`z7_!wnR=65;%A!pef=%2$nES+++?C?p-tDe;#ZH~nfPHoIDOSF6$W!D ztzf!EvS&&5(RRsxkwY3>fyMY(yiEJ-Me=_prH1Q<=<KCz{9?>sVHN=W66%O!M*nDH zh2&lxpNJh9&@~^gY}7_JymEw34z$TCpBz9hTbmr{e7s=%3ntmnB-;6S1=3heNmJx0 z{SoaKueOovD=CMJqI)<q0I9Wa$?tqTC9Rh~cRlA~8@nAhI-;mPh@YaNw_>U`#i{wd zcV)E~tt2ayRoZH;iYptf<#yS$d4K<OG3VbaK3-Pm*n;Qw2%Lwp;UXH?SH~9<izKw? zMcS~-l;`<-ZB#=YTY!;`9wJD9dHA<Eww1#nAU$w^7U>mZ)HilAzEYm)VNHkeV;WsS zwva0)&lwLFs9Be8^|Zp`Qqi%rDmHFw?=cGtVAd8BL)YVp#(x66AyH5rVNclOhotUl zfP$6@>YQj4obX@~9SFq!f|btc@<XBy44P=Ul_|R%ooDysCM~<E@^uOSObVXIzlF9B z*Tts=eXZxSS2S}~egMk30#?jmIA}^Yw01Z|QHu{G3fyCIDopiBvj<xI2`^yBQKt4r zP5%<ON!P!Q@_^xo_VL9=P8-cSm=&+Drg(zey|p|+a)$XbGyjO)_?2U56u~6dYngEH z2oi2D()g$LCH1}ZpqS`?wi6~^h7Tzw?ic^+8Z`dBftxh`87fW80@BI&z*-VcDkh8X ziiAyU_`=UDD143-z8fIeK}V`a6+`^NOz`MZI~K%5u`&sJLhMNVxj<fV!2<(|U%6}g zXlj12>4Q}LH~}jG?1135;TB8oM;4Q`T#~&feq*uMfPFk!*H&0p+U_I@qXm+Cfn;I5 zx#v34*3i>p$U0<fVXh@;mZt$27H2Q(@iHkFkd=xiBEar}fs_@F86SZ!izWLAo79(# zH?8p5fu@?hz5*l$A^TJe8@q|4)U%VIBm$K-zO=DiifZNVb1e#>h30APzi8jm<LM}W zccXbB?mILDgTCpjSW(HB1VK`+OR}xh-Ol&ava!1nzPi8oRN!rhel@~#Beq}iJp>yK zK&&;$i9xKj;0x9|bt2Zs2pCL*SaFvWYjX#&qQUeng;;CBN{}S6+SxF2R)uiPVnuyh z44F)omW{B5_T&Wm7Fr=IWi?5w(upq^aQE?z0n`!Lb!D_2l8uq|g;ZNLsWSB5vDb?- z(Z*HiVHjA73%wBfqDvLd&FOnG2vwVJ>>wWs%&kx3@BYgZ3L0ap+s)$XQhz9Bu`jgl z|2ui|I(@+Mobsa1+q7zGXMcYR(wI}Gj<BgCdSjWn!`mxLl7-|b_J;)f^mzaoM}npB zK{(k{758>Dq<tXV@1^A<`r~<*LBP4_x*G&s2RlXru7u_o1bpG{3<B2t(T?@i&bIxA z`ev@LT)v-c%eeIF-mQE~pnw_VYnVEjza4!~qg5`4Nx@zgZWNOOwPiKu(Pngg)FAD6 z+TgyxnrN=ZMj;eDO(v3i9g4e1vRh&J3cTtNbOxx#paH`V@u$E6eP1(}YiGp|04-G2 zZ1JB3>=w96t&m9+a7|cdBC8V+4exU%-ji39ynaz2u>R%iVBiBs!|@#scqeOy*^FN& zs}ozWv0ZEIXmp$CJt5TJdh9!oHvOxf5c-3#llx%Q!n%jE#pq_lONb2m5U-YUznZyL z^g`L$bI_hp70Z#TFBIh32#!_bwZ71D;&Ao=uiEwKfU)WLLM1~xP=M->PEr;68x*I% znZ58|{;d|@7Lzq%GoImOaPOe+cZu%|-(gP>KROoQL1ZZi*3sl;A0i&9SgNmnsb|}H z${$k@+kB4A*UX{RSU75PB@Ty2j5s|J`zktHoK@9NP)>NWQ=rMf&RV(tuHny^82#sy zm=Pp-sd>vbWWzGw-3qzV*AmP(qT+n)N^BCqJ6JXbfEFQsnG{AWuG3B!000`XytSCb z0e9V)D_S|282eH?4m$wT(Ml_B2R8p<u+etn6tiLZ8&J*!EKpVx%E^RMc{FwF()z2J z`**xm<9VZ&X%wmke@LG&)cx}g^N*rc)L17RI4IcGRh`jE>;Gh?7p%HK^f)c-tJg%` zGtXa=zi&jHzrBc*F6k9j*MbdH1vRfooofe!R)Do~BtosHiw}a3J2Ld&(A!n?4yrpO zmm1b57vTx;8;$T7PJtrqW!XmfGQi8~V;cNZMtIb74*xzBC`tcPPX84R{x6x}|80b? z<nXIB__0QKeBt!{M)(CB{y!T0AS1k<|1u-|qkxyyYJ!JyEk>DlQ9PB-qaIosb|cR7 zCY+_fdDDoar}OE*4CRiRaO!~bfDuPeXR#4ylL;pZoGC^eJsrOh=Sve#6L8MRgyS^g z>@wjr11Hyr(^KO?ZzGP)X5<@2pmIK@NHLvndfr<8Y2d+;CY)B_EHUEf`tolh&M77w z8oBw45l2s_(ui}e38xJ>V~jX@I%gYk%1t=!z&Xl@lcn*%X2iM5ghTZuhWWZA52#U~ z`tp9Qfd_sQjtw}kXTqs9;w&)XP(8lah;xXR&J9MKhfFvHz`4$dgReYq!;LsgOgIkU zoMXh%`Ic?OdCi1V1e`o0jxL|(e;9bM!Gu!`oGpJe@a<47Z;u*rT1_~^f%A$HN9Xl4 zBhF3}juSY4HR9-e8*0SK2BnlekbyJVh@<DtV#Mih!YK#NpNu%Yweq};?q$*r7MXA+ z07o+7=ymQPBhHy7oXNo1hWWIlzUlJ0#)#uJ;Y<V0i$)y1JjF(w%YZ`%fGCsDE18Y{ z<~+D3GaP7u7sF>Q!WCWydd4bw8YAIQxudu`ac#m?#<dyOa$H+*oq%gAu9I<vyE1Yb zu5Gwh;)(`+<Xl{#iwlCpCTd2N1vTQ<j$3Y+`O2mR4~e%9ysZ_tMYvroZi{idRNM~7 zZJoGv;x;O7W!yH2+j87Ci`xmf<&LZBo{Za8@pc++8NbyUh6Qc(#Jknh%$mFwXbaDo zQXK@4WaoWTI4G4ETD_$h^3fI$pND%aAa1~bGX`QSS2_UAYy+?sRI_oNQu(8S${x%( zflAOsWp#g0`C3@<PN{qcOg%3z2`XorsN6<WYP+HGw1LWvg33<_*h!V>45C7<d{=zA z(m>@TLFIW9m9~6PIlLPxM;WMW<3-7vW}>o$sBA!8>MAcE08{77BZA8DCMwqum6~p- z+-0CrA*g(MijgnJ5|t6%Q1KY3NP@}(CMqq5gUT<ks$G?+hk?pEUX;9Y6P0_2%Cc^# ztOBOamyn=xh>41qs8n`CWsZT$IfBaClZ|}oNmTyO4V4lDmEAlOdGkzEqKARXm#~0c z@g)vSy+khxD#J}w{z6n9?}o~g1}f79m7NH}N!5U%M1^{}UFGEp1C>F7%5x?v-}eKR ze%(+x!a!v!FG}826P3k8<!yMEUFGFHVCsB%SWt18s9Z%<7IZ@;VxaP8L1pt`BVUdt zDp+vPWnM-ZsN@MM_nD}C*cVjx!XN9ZL{<ZpMqZS>u_h{uh|0^|P<a)YI$!1sDmD|9 z(L`lNH&jIYm)K0;EJ0;;k&!RiM5U-3DyJFp@;{!5yxUAvUblk^wrlN@FEL>1C3-<n zIm1L{E>U^38!As2s9Yzgv>|LKRRc~ZD&xDMGSNWg1VLqqiOO~fRP5bQ8DOCD881rS zH6|)g5ta35YrE2yjlk6T@}Qt{tcl8Gq7v?gifW*8p`g-&1^y|%90@9MS63O44J7&q z68D=(eAK7A`D!s95%E>B_!pT*4lvk91p!047!SeVN+o;tAn~UkB>u?<i67Tj$(j7M z-%$R8#GihU_$MDEetg?O%KsqorynH#$p?ua*H@t(sQeESfBHe<pL~$`aczm2dF1dn z=>I|DPd`ZflMfO<zU3hG{~+<FA0+<C2Z<lomXsZ^{0|a;`a$BKe31BYebw24*8hXV zpPmsv8L*Q!e$PAZ$?<z}eyR_f1B&T0S_X3H(`dB$I&LgEo4AxB|IG1t6|I=0Vl?~H zb_5OM-`Iq6gPMV|)Dk$sSN&aJ91s25%j%!fC<WGQM{35NB#$6cRp(K&3n^%5W+ndd zpNeP-|5U`}AwJJrh~c0qIJlv#5F;}b%HXyjeCR|>$kfrKd3<bFaD0?UOfGrVDcJW$ zkLZ(e%nfrWG<1?nXE_x5u-ls*VSN0kjlLt1=nRZM&2u29a0cPFP;fAD%PiJKUHUUL z#-xSG@C48McShS_;%8U>Q98XJo;Wyq5%AECEV|pIzPMnYECnZyq)$R6b%$<fUkU_x zsTV>L^|3zpW@&MwI*_a!VhS<M7!O1znENk5Je5?vikOQtK(Gn?LM%A4NYx*4cJE-T z??@z;S{E#!eX?+nMEDK<9-HMLxbN$$5Di58S-I+hoB-k*L`;?U&J;ZYkgD+lDJ&3h z3mu?l=J#rB6hP--JwOnFALMFrs7G%(vXHjOVn?29u~0r}pDn~Mo`sd4?eJ9FS>Nk1 zEqjWV`94^^85wJ5UZ4;(jV1y*FA06vlvJFOF`kvn+Ys-C6#`AzCV(csX}hED_%|Qv z==`Id#iZ&-=?!@F-;kMqyd!}vhv?f=S9Zp~-V0LnXqp@mZ-DRrCle3OPL?X~I`H6B zEdyh18WTn#3mKWv=NbbO4Dlgp<)39JKg~DlTiPS2vYg^+_9bYF@!dpzPmFrV>afI8 zn&j_^;0e+!sk#)5XmtOATwn*RQ8qe;gzxu=z)NY_6_w#nr0Oq-OHlj<XC<`R=^%}) zKow}iHvR>2B-`nY3~hA10S;K=ha2S;YAo=U?)DFs)eCUwJsl)=i#-rST&EqYL5pyl zuAMzpOd;*{Y|#f+OB_K67<rD!cIL_zNg}y&N)CaZJUKZnIXWOHHD9|Q=@n_|IgIH! z*+z`}1*?8RF{^m&rOuzgwP3(~2+YLER;w@!kXixDcgJQ&{FH_BMsPHa#=G!Z@Ebv^ ztvC;-29_Q(4VdWGd#=-urOsyFef*-IIP#Q*I*jbyAG1&i0*e|(;VcMoo^{Gz3ZWwQ z;QDf61fA6(J#MgPJTnISYJ{h#-K!o;2PPY2+OM6Dx2IY+S?J9MgfFy|VXqx_6Ly*v zr-M@fRupYZGqgRC{{n^*yy~#U&u1eVPiGrWl!i7mx}8u7sMScWR<rR6l>yTcn0kQf zg<ViR6bCPE;c}HDM>m?!PiriY6Ag0dRw<khSg(4!-KSpbVE6VgoS!xz=`T09M<KwA z&QRNQ31Try*ZNmsV=!@s+68t*UQj?WlnH03jlvmf7jO+EB-U?;6~Pc3oArDTXJe~X z!#(Ql<#Oq6X~FZzw?`d?EFL}^CssA%C>#ncbja%E%?NTh9PRh&0(tj`vUQ(a|8);< zBzrbH=|co@C*Jiapn*d*FGW*{utb_xnMhR$jfcBASmm@x;RiJ)B=RR>@B!bNId3jR zq76=~wE>$MqABC&e&oTFQZ_B@9y=X?7ki8228IXcRa*Qf5<NPUEhU64^qqv11=2Xy z?h*bRXhY0Q4f23!b8-=IZNU|d6oTm{WKn%=FdX#V9~8jStrrt5S}Z7q^LV=YVc&F+ zM+I~qf$rk4Z(IvV@D1*f6!VBe?`5z$I8BEP4?pgkY={*89zawwsrpL+j=cCB>}3f{ z1vcRgyYvUJkrq;b+nms9b}c6atUe-klw;gM7`22^(<UmUQ`5TeUw@?vnJRNm|07Zr za`TbALiWH;_80_e6QL>jzh+rtF%UDbGJFZ@13MYS$v}Fkk|Wxv!D+L`&Z93c;_%|M zjJ}S6RAmiilpk5-V4wA&y5Md<JIkL>JK3ShJC3BuB{VsY8<+WOsU8ZyiC5}W9{lfd z(LW8Az)m#qGh?FcA^s>;=OY*ND%P8Bpvss?yquR5fpL4;&ASny16!RJ#e5b%4KC0F zalS$94y`CGBk?BJSETJP9;_N^!L|Vu#x&<)VM>fUjHCTEK4uudN~6bxc4`JnFy{t) z-f4cw2ujN;+Bru8m?!3ZH0NUKqRz`h%ETfMaZbTwH|2hR(hpXRviK3A?;EaGI9V8k z$Okd=z}W>qdHU~Qr>b<c{VhLLlkYO%>#ilg!XNrSa~|I!OxuzlQ1cG1@B+BO<LB`` zg(-0DJiamG$=T`dJif0U&>A~hw9!$YH2+B-g>7Zk26!|7%<)^9`hQ;4DlK!_8eF!l z8h7s5I6G(q&6Fu0;;cS6IhPd3s>jjbKEyheBG#=aRhG2yO@JU0uo;Gz`e-n|fmV-N z?(m#dZb!cjOS0TefxaH{gJLIBvxk^T`m8!pgZbfl&9p!W>fMC%YUyk}rvuQ=2DfBo zbVfw5Di<xwd9c!W1$O$H68Q;R4@>e$ya3K9g??)1;ax>gY~Jzkzz`{WRI)wQzmMSG z&-Evdn(K%2<`9X7CJHCcNufd1R#8Iwd3EPwX`*;h&vFYv_7!wktx~uL%`M@CCFH1G zsy<#rOXN>S-emQhYn~$4G<ob^m?kKA(l33R#m^=V{$xeV+>VXug`?^LfJdE!#$;ES zGUX@#AJI$`i~a{23M<#~{Jo(z|CQ#m_u{aL&tcvRHgO^xWYGe=2VX39I~p2U&3X4p z%9MVFmlR&Y?JM|oEHXun!NYg~jcwwM!QbeC4$eCq*v5nNmX200?|5*YWdpehI5>~W z@QD<@3C=oP1@f?(;VQI3Uk>H1M=Se>jXcz!AXn-xaqfbPiTsmtd*FR9yy=C0gj9Vd zc+9^>^4^ETigMkE;)!zoyc6Ym8UQ$M*T~55a%3C9t<7aMQ(EA&o&XHpXI&1iz-Mjc z7yUrho&N)&NhD2!xTYcVTwK{P!I_Jx>j7tnb7nLi(vBvim5)L(z7=;uF~Z+alTH4C zh*1Tvcb;jr;F#lOKHJi)Fplr7fa)keOD}AV9DZJ6by?(WoE`J76{T`1pW&bdWeeQa z_PC2`zo9+hnY$AwVxji5kBDSnmEa_CO1jJ1;IjTN)R0wX`Pmh0<Z1i><q9QoXRU*K zv&n`1XmJ?!%;Wgt%XU-|w3p`7oPS&t66c{e<of?5EnCCSx;CXR&UcPir-U~%hb#W{ zC(Md()fIo`H<=ZmIA>J+GrLgyRC_kI6#9Qk2K|S32t9ccp1h|2@N;6fBNJSekHk&) zsyys1qbmCsccR8EuzjS){_9d)xF$QL!czD(l&vHh52Wj8ZzzyKM;pmo)*^Qf<BFbl zHoxdPI+iLi_7XAZs9)tOaLw03KmTIX&l~ZuG%M4<6)ePGF{uX*-J9gli*UQ(HQ_(J z?v2;9+h}h%f$=fCT#>ws1<G(_Q!sTNP~xWo{4<{Oo$Ryk@Zx9<{Lccsl)#ISX?6im z!K6P1f2P8vc~s~V@|H}H!Ol{1?h>_-#zcP8_!}J+{1dC|488OHn9S+#UU*RH4?n>4 zu~ylF5hOHq@C$R<4&;Il3z=C!>`c{%Zum)kmu7aYC=b?Yrt$Obx5<-m1ovhIX!)iC zXWu1{Ui|w%jE#or;Kw;utatw$hljw4*AITwybc;HMECSi?)&7#XjPPXe6Zts#Zalm zUrNi>RV)F;qS;g7Pqbms1j|Oj3*4oaiuMzs@A^{F3$%eFzIZW=q)<_~zinQ>n6_T@ z8I7-e0V6Lz&bx%4P{8wy6UE0Cuwg_hv@hWwh?f}WD&PujTwLpz6l<O-#;w4%q|arb zXD3D+)j*YZe1X28*RCz-y$`tN1d5SlS^_t9OrVqTL0Vi0UkjdB8+!)Bae{G1QLuj8 zQeZ4IG_Sw{CaYu7Uh^f&Ba8Unl<nXF;x75N<oeQ#u@3g_&00<!f)z)sOwTE;ZCwi} zQdU~q+EG6>f0fp^B7-f|Hqz)bjt^#WJa8@Ni()nT8Q@VcRdzrfc-Hs|RQ9(NN{Zj( zQ5^H4>0&+SNg)pJ$m2t`jB7$n(HmKm)Q2KAh<qZGKBO}N`Vg(`s1LLhH?$|=9{^$= zTflBu7#v#!_>|@d6_V@pr9tA0KK@QRTyBp=ZcQ72Po1ZF2N=2LZCNb7#oBR?O{iLI zurZkw{C_z-m6w8}`}T(YkKn9!*9sA?yMtXhlg0yfu#d0I;-W1kH6MSm;an+<tnt%x z=<K5iKLu$Idt@He1)ZQDiTQMn6!tp|&@EpR6q$`%a*N*L6>Kk#Ag!l6EUb-q3!Q8t zVXFg(zzE#(U9r7|4q8rh&n@(cLY!#vZS{RXla^mzh{l5u3pwJ&G)uv3X_ym?n1M;s z@*8xl@2iOB#i%#+Y!mK{>5ZVQhHfi#Sp1VI-QltlE(}tt_OikvX>eI#B?5~JBupN~ z2g{8k;oG8<H&9yc1$A{?VX>^B+T-RAxakK_+f-#NR{a|0m&gmIBZ4rdl##yFm!BJk zL$9VHOnRy^;}A-F96=*X-oj}}yf<Y+R#2H6G5(7j{5xrj=!VwoBS=^r!mb@)S-~3I zyRGcX`6wVACxPiaI)T0~BCTm%J$i2VPQzH}-Bm1Q*Od^He9ejcIX^=q5OA$m3``f& z8Ekk(UcN0rgL|!n%PO?Bnw6san%-V%_PH`xwOilw;_4bvsbQ5n+7BHb^jlaj&0-Mb zB9pyGLACVr0mBP{M$K^g3(nKU{w<AVg@web`Fn%-ca~H$uCP$6D}TicrFs5dI-X_L zQQ}}nKnFiRFStGkxItp2TYL&Yu+7V?B5^V!K$K?vWX7_>K}q-%U3KVTSmMKQFk@jZ zj%L&##nFs_G@_lDL_5h<hrSm?fSj>QFpt13Bv}OHf10d7#Y{VK;7D6(FscD*WidA6 zm`9ya)C(+?zzf!Rji|xX*1RpON=ijCwI^s5CSn_hgId4;^7KyD?>~YMdP9-)$I|UR zRLXFCMf(EYUbL|UZuGW7D}qek1F9M3Cx!L*Xf15)bR@J!KkuhwCD?$8rB*odr~-7X zD0DyKZiVhgp+ikv@Bi5!ou{hSoB;M3<%<joFbUm6^<A%OH{nAYHv)EdtM&mM4b+jU zW?J@1!{#uqbL{cH`go#;c6Lp?<v+rs?_cUk?q3?D2}bN+iUs>9OFzTrr7)sb<0H*V zht^h-Kge54^xri9FSUO6`bx?(Uozjy#%jy@92$zyf3!)B&_iVO|4J1YkJ=!r0M+0B zd--2r%>OjB!Cll|^as(V<-dv!rJ)LEYmG3fu<4K6gZ-g*mYLqmlanUFOi%3<Yk|qq zUxL@M7K~Kr&-(Q2{Ov)gkJu0ccJU-Rf~GjU$)C%PoB=J)VNcvh%E`+@4I;+x`{IqZ zMwy&}y=*dE1UkpCm`>drP86Jkfq%x4L*b<+bT2!E+F`t&Os}WW>&dL)22P4Q6?+-u z{snK3$KhB$Kvc4S1A=Im6Y2!=LaxHpH5t_M)MDlHkX3vl@8W%p29m_l;5>0Q88oQf z#$FpD9)ya_Ym(~<T@0D{0SXQoaT9#uJ}TN&)aJ9Pc*nC}IY~Oj61jvS-^+f6nKE%@ zG~6}Hc@c4?IEFP~=(gVm+zUJ4z5!hLSU8u{OQqP$&IPVkV1C%Bw{QacJ5PZ7SJ(q$ zFFR6$flSCrK|YGuY`{=*G9iOyd)UxvpagEoDQ=PcG;TeGhy^<Q5_yF9sA%wxxC;Y+ zkdvg8$~hD{he)ZMUdybvD6S^CAsPe(l+5q9Fmyz=k|@rlyez&}<fSr|muk)nF1aH$ z8piTG#f@dxk`o%u+dnAV4aj$+9%+C%d>rq+?Z0St(1nAQ?@tE#n&g&Mm!h3uG~zA) z_N}WPxhB0~WHoq&$+T9qCZO7r{9}IFlMEwIjKTi6-0X?tov1%#ZXa82*V@Oe{07aK ziXFQY8+G?VLa(~~+C_Q)Nz)g<dwHL|x<h#%!mEQRFPo>8_XmE{O?fZI1kzGeqSUhW z<N<5R&01WED0Xmn7baFuRVonJ<3>$!*J2d;KaarU<wvjiuv@!tDemiJZ2CriLZiDG zWI;D)RDwgb;uRxz4<T-~wCfk1F*8YH*(YHjCckbUz;MV9rfHk0V^w?^p4AGBqWGti zy}<F<)iiPliWQi@<ypWn<cPAvJ<dFj<jmNNlEXj8?a78TDUD=yDC7s}k{^O}K`g(9 zKxrIk;3qWVhh5U3%^f#jvt#=hP{*ka`UY&cGj1(!Pi-y#!Id4Px*D%Qdj48sb|>er z@L{%K)k*rc1M{%60=4UWzfdVPf2;4$$l*~fkdZW<|ME7j19le24KJrg#iZ?gf3Nx5 z7ZZO{aUl+L=21}W2Le9f6ZkZc<kJjcfluwOx+1(}8-JlBD%v5QS-N=Ea!NU`|H8%7 z0s^gr_$wZMz#x~mTDXYXa9bmUSO=)6CL+oS(x7?{DMEvUn6OWLB!3%$;{+=<_v5a_ zgn<AqCWuShCl7Z<G1*dL8Zx<qn2y3LE+)zftOJcEb{J38?2RU_fkIsEi0?`H-{$it zgniP*g$$*MYuK$^TsC$#ZoqEztc7i&{qs7jpB3N|B0yo5=}+StG4`A9Igi^#O(ZF3 ze9ie_7Z(g?Ik6Tsu?=;{z-nF-hfqhB?`cV^jS(MrF`hHm#C>}>MP8>)BZ^8@3$pO# zhdc|dxcw&)BfF3;W+h-u7YXL?<LN@g_v5VR-=`*ynbbkV!|}>g6FbURJ1-=?K7POB zK<neUTeyJj>@wVRSsyQ^bID0w8ERxZc-V$d;AaK>h`mcrr$>rIqrMg_XQR88gFp`u zxrSFu@v2Tpdtxi59LY2{X%&m=wUb1Mb39;oYssIe!_*t3O~EU$yB`|u?s;Sa=vX#b z@?xHkiOtBvF50l0Z|I!!lF$d9rdFv%cF01f(j{rzv4Rj4x|Tit0hjhJVRz|dEKDT_ z^o=inONE|zc?W5a#;cNDFp{WK!+Bp=jNoDjP}WDAPXvr`VTti@VQII&Aa3zi?C-3d zOJT0@ZS1ojxL7UhzBaAubL8~#oMfzC=N90Pb2ud%I}<m$1>nR?790Lar`nNjug~D^ zDcNfqO2UrYO(|rw*Ix;<K$fC)FqK+_i;=xP>OC%6GAk_zFoKjjR^-g~x<oV=i&@iq zT~+4aBHnqIb`bA$ygE>OJrH(MA1^V>yE}Vb9nhrpH{9sbB46^i$Y&w7lDs|T@|jQD zC}oyUyQs*S<Z~<SElv|ck(}WM<Gvs5>D>fQ?P<}b-%CDQCUlU`TX=P#^0|Hcfy(Er zS(<#d<K{r+Q-|qUA)g|uKikl{cOswpn1|-}5A~<eTz@`!Hz}WogcSF;{_G%dl21+Z z?<Jpe5#VW<VWFn|WV||1`E336K;`3}smaHSo8K%SS$cgnX6zZb?p3qvahpfHQV*{O zDYR%<j4*U(r@}gYM@m>nnuRrFLsD3A#L@f)V^>BRK*IV2;Xa*vF2BXt-CfZ^So848 zB&<cI{;#=pYG>yePH6sZ_U*|^O+L@z#wedmBgt%BYMxG;U&Ddfn1oIqR3Cd&2N5ly zLsn<ny`>GaFA)2u!&SG9i5%{v&}*;iZN_#tW3Y)fVzB%6(4((CyPG}MHcx$Pj|(E% zPWB9Kp`E}C+Z?;hBlc+wca0aPYbiT@N)x;KZIVO!{%j9%c|TVeq-&#C-$e(ZD;vD( zXgdVh3Ma_MzQzvESh3ZLNUQ;Hl(gOMmcog^d0&{FLjX0@&1ca9U|P8WMpWMlqPvn? z^EH142*FZRJLc~I+A0+xq_wY%fIdpRDVs7OJhm2c$7J<<l*JvD>^%@1w)9nc=Z)OR zu*MA8s=`{cDYp2j>HU!wEc3`oQTOIjykM@Jz|aV7tmunkxtUkl>r+~pq!-IS5!<f1 zEl8zSE0ceWR-RhCOqNG3o!At3RLuQ=IZd?b;pV5ocnsjj!`d)E&FxW<akb-OiNmwv z^8t_`%?BVHJmX?91GAo5Pr^!_KVS^XqycSh*IS5(-Kx!Qr3Jp|^9Q0nbb)`?LE$&C zqYy;IeFmtTD|tj((nm9`Ck$<uO(SPs^-QmNl?@x?`v!mIssFBrSNYjH_zNlgEZF9T zlL|$yXXi@yA>?oyaTLoAt)IAR8a!BYz=H?>%ilulKlUOR>52;p2EpHSLWC6lCq8<W z!Lo9*O^zTagn}Mur`tvsmy3+06*xH0R<g;|->G08mA0LfSlbmCY7MQmVN4f@*me^g z%*1M-*nOqH1U`U*w2`*NkDx>vT|(%Tkd{EnCRstMP3XJIChm9@xc0lG>MQuT0?+!( zO(b#l-Klgj<tG`RZj67TgWEA?2k(e2!S>{o6?V5ahicY@q$I?RZg2PkP9H|^F7#qR zICP60izz(Xtk^LgwU<X}@u2H-YB@NHgE<Du$~^F4k{ye=5F0q0kLzw`-(SE#`?t}s zH$brBDc+ZZYPv7FSs0_lXbagRk|@YE$6wI$#Yb)?fUQ#aDNUA$2#WMZ7~V!%8nsal z?ag_E8wTn8z4D6j75p#94Xa=Ju1mTn3fNzPh{on{4;e#{_aBE~6<Aw5z%ugLPZ}F8 zmNAPpoN8vg7rzx~m<ILoLG5ikW&>dfsLmLA_B&`YzFg)-0BBGyU5yh0t2YJm*~n8! zOqfMSq0dFxCZK3+M+3b~<9Dj&Ar69{1%kn1Ueje&(H0w;$5ZxVy`ikMCzl+;Rt92T zbr}Ksl--`{eSyQU_7H=w7WOzMB)#hE^vSE9=-K^|=ePu0VMpNT8kh2>TYBNU$SFr9 z-i-H8#y7KD|7Woz*0`+Sh2G5Kft|T!N-VUkU26|v7JbTEuet!U)u74OLwXYHpvosd zP(V32ZrcTFc9Rc7{Z?P;>cBuxqTYMfLL_OK+2A?ueQ%Ga2rRx_r&s!oe`M(A+*u1S zw|S>4QjrMl&7FB{GCv*SN$cAKao4UlbEWWj)Q&|Wel$jrv?w_&0SyFE41{iL%){0D z*S^sTuQrU|wzG(&uka!}zm!@Vb_?Fg>cSvo4n7cXJ=IPA{!6Wy0wrBa1Dc^)G)w4l zR5iPm-QarS{K(N~B-X@-u)Lqd0VS#RdV;Vk(V)?GS+|DPWFdvX<F3%Yo+~LR!zGRQ zP<mmLC(-0C+2j?B_Z)|H(+f!|W5~rTtq%<KM4VRntOdk-Df9$oH*z5sgEi5j!v`q) zQuQ<VH+B~~Kgsr>#{!a%H{!B-OJP>G6WH^xV?AZ@h4!51tJEkrby{v3sNr@&29ePT zn&!_9?a7^aMCkK&$jAI&Xf@<V(1!sU^Yxnia`;mjSb5xfZx60Xri_N;$W(_E-$jiy zrg#!k<js9*Ji(kg;*s_A?*(ou{c8S%^pQrc6uJhFZfYWK#EmO5ipMz*E>qe=ts;S> zygJYq@y?CV&l2Erlw5<o*2<fYZ|cPM`9E9M|NSg~A@*}_V>`~rBD>PInOIy_UlR3} z?vSdNpz$r;EQS7sE0(c0V~(f=>(yIv{tBPv6HC$%17M@`b7)DL_c-x^SiA_b^Qq^0 zL?Dk3c6l0tg_%cNl7?#mATU}jK`Zva=V2Rq0bA|q<LlA*<V`;wh|`;g(qfbKQ$NPS zuDQKw)dLRSOsfM@_!#6f_9Mo**~@iVG!2OggBF+1tIY)M_yG1uhYy$FLz@Rn!k(gS z+-bZ!{^*zpbeN`061eylk5PKp%kvv5p#;<idk_YHX;$oSG@#DMn^IQPIPOH`KD|1V z`;pR*?(iQy2z(xYi}+8h5Ua>Y25o_Men4n@Ie9+iaC5bwDy&YP_91zW!>;sG;B0CI zV?AWn=!W4y&D0isti?SBlF{Iga!><D&M6+mN@Q9>>Uy09IO2!E6T|w^(yhkz$2X_1 zKP~`mieR%ptgS!BxE9vk)UPK;0*QofM+{qDNp!&|CxxvC2BJ+5-9Fp`>#M)QIxs!M zfk~tQp|$1Y;!K(-CkEAE_>%p&Tr5ibNna&=HcS8whO6$MYT!{va`qr3o!Vsw`m3uD z^p6!6U-OH*MMRGW*K(ie8Bjvt@WXtS@V#mEUz4vE&r+<d7G@OIz3ob&8hnWwAHhWZ z&je3FVnfq_^=90#UN~Kb<T#0aFqDmn{72rW&iAnUW}4RoZ-H27jfO7CZ}5y&wvZyc zC~XA;_g^|J-3bE{ix5hWwn3PQdJlqMJ<2AZb$uYN_biCWn3AXqQgMgB3`~q)0H;V= z@Fw9!dfP^;<81Ih$J<As>u5vAV|3(jO!BTS@C|PAgrbOp_&X%PSL{-L0<U;9DeDA# zr&eMHuBMOyP0E+MXq_e`{WwN4S+8Zu1si%X!$&~authCpHB(5`Cw`R@^(Ndy)Ial! zF6#SNV_m>W?Dbc;sPA)eSx0Dr6InFGo4))dQP|5KUBw;bq<uEj@6>urzG9r~z-Lz& zbU<V~)A~4WUrhL<6OIhX27M4AErwYMUbC?@&KX9-`VhBe8xr|<U^G!ykGZvyYI%?3 z9t0}BmqevyV{Np!XAz!o?+mZ==Mgq-)*o}?AI1F>8U@t#kyP=e@IJ`aSovuif(+}& zu?2w?-UQg>`td(QD}osB?;|Io@xzk-7qvy3*aJsFE3tOG-ne%B<&0~`+2$XF_1JVD ztr-uXw}f3#Xw5iU4X8GPOSLuQUbTz{F5Io!;_+sE<RWd|_zw?)L8OKA9O$;wGIJVO zXeD2aY@L*h9*wevo5)1b+z#wjUw%vvcoUijdzD?XE)M0MM`o%XHf8~s8Konobe0Du zqiIRx$1!+F>nVd^j_8z$T@B8EiR_gok8ma0Z}7dj1|9cE&h4L*@(D|I7?v?Web43> zecjE6*a#wi983I{tM7w+o$}q#+OM|}B43UC#Y$4#MH%%~n+5T4mHorS3@Y2Tz6*Ss zvA^;1j>x(x<JV++G@06?$$EPvPVVz4(AQ1xBG2kEZ{29t*CpT=OpUIvFW?b^=_xJz z8h3n>6Jx!꽼&zLkZx0*={q<nq6I%Mo>==WD#x&DcNXW-^g|F>wK~I)>Xl*BL zwu8l;BOQT$9!;1oA<BaIAtmdyd!tw{q3wf0YbPh0pI#^c^S?;q)UzADklUj`i)eWo zvB*xB=lKv3<aq<X=;o*=np5<~PXiGs(c>;I&<APhQ^)pWGOA-UwKq3kX5fA2?F|?Y z+p_l3bYNlcGtnpb_tW5Yp_1j|G4`SD6R<4BtKNb$L9h(B5tR|LARqS%++s}66M2LB zjNDt>iS9ky0cXym-Wdd(N0mH1?xK!?M}3fbJo4^M@^P!t2dB*y1W5Ir^ueEJSkO4e z?owyi=Ko4gZeW&($DlDg^zi$z<I&Xd5j@o4opPdy7QxPP>cL(frH$3Lqmm(F9#uBH zo^mUq+RG4}tcT1ydF4NZu*%sYj7HN?(*)lCL$zJwQ_qMWPaZ+Cen1(NZ#_zsy@VZI z$jP~tC9@&XELDPCH=Hl(C0Bf7Ajef2o4MXpCMnDpaYhi55ZaR^-QfWe6)6lq<*Ls} zTXG)9MJ!o+6z(pxB9iykr~J#OTVM(L;Q3YYd^tg$jKZ;*0uo~Y?BYXV?Zrp|#oL>! zBK+Z29&dl)Wym>AWYfB5bwmN~u@48%;2O+>j?pTjv)cP%WR5)09s~{3$QhQW1>`gK z+&hA2lQW&yHkrrM(+aXytgW#z=@J2q5cp(&k^A4sqyw%MsV-wH`cj`_H-%(SNIm~c z@?Yq$4xh|M&S6FzU3qa8@f;3#uc?NVx1BJ+F!ea1%9_+=G=J4xO^Vqt%yP;~buB$& zmO+l(Pq%E|BgBmezu$@dP-L~5?m17eVUzgq@Y@8miasE2d$Fsoo$fH$b;I2-3)*@M zbh-2o+<ceg8#No0Q<@Hkgy#!g*qM~@A~-^s&v!A$Cu#Y(8KaP-&RQ^&vHoX-uLs|g z@Hz{V=aWsQTAPens%}A<I19Ol+ED#Io@pj%F%5mN@n1jz?YWZu0y|C@YlTKNqa~OO z7}B9SXxcO=MHDgVsJ2y$!5v?ve-1haOZnNV_X)UZfNRGme4c1);2U#U8md3UM{7g% z2XsM#cJR2J-H(OupoSxq0uE1TpMBN@U-d5kbtO?6e8pc<e}ZQpX7OK)@jy@Mhk>0K z)Qw*tD1)StGW+9bs^5*sW+mmR`UdC=T!8Tn)o)YEbi~hQAB@Z+UR20KOEzI-GN%qa zf=z^f^$sZ<Klz+*rjLPnFrqq$&jKH;jL;K%yMUUC`i!MxThaDG3!?ypidm$Ett14+ z4NL5vj1Sa7mmB#`{J5jrATB%;jeJLbx?NF>f5aTgKh6XYd3m(iF*fZdXvrQSGLrrN zTDtTtcjz-FihHg|^?E=f)$)ew4FEyW*|J<>4xgOyA0mLTl@ZGJ9sqD5&k$n*^(?{x zc|u6o@8C7%$TT>O74;Zs<_=mBX^hVSt+At^6OhnwT%if>VqD8{bwbv2Wpxaif^|62 z6`Ni)RKG)Mva`1$uXKKuQoR%}K+ld@AO~I*>-8C%%;0u0eH|>yE+n&JI9>@x%`Vj# zbthiQYJ^B(Z@OZsNbsyk;1#9wOyq(r`1_klu6*F4G(^n$h)nziFc?uz>s&FSJqi6M znyjJPB^-=3<OLXH_VZFKxn2hxL-xL*cdy_b*eUihn9F8yZ&lY7TL4Vn2nYzHnJ&<` zC@yUKn=nqwsvv)r)1T*3IG+DPlph?GxA4jv;l*5u1t-`q2z{nF1_U4s<$jK*aNUv> zaR8F?%0q%!iGkSv1hGj5Vy6+YJP^w?|B&imb6+#KiYl4Ke{9BjLA9Pefnz^2e+`LE zW4MO|#`F1&H2Qk&dmNh$cSpo*KQhykmOb_sXM$kzZpgw!)>88r*((_1)L?<p9_w4o zVSIs?zoGhFfWy2ABXJVibN!W(L>Xyirt%>_+~JA%=CZ#dGc}J9Jwx(_{#hn`J>eNP zN|<Vv3E5yzGp8S1#c})yU52QNI2AGtFtTJCjKqX3$nXJK?5cc3C%B5+8-L%L$H+1n z%7=7u9wkPXJAC2dOtlA{<)7$T0{t4QiH~WN%h^cOBJqjVu%~3|>_i^HRm6WzkMtys z-UQaLmgv!^{i6r@l0HexUZFNCxauSPYw-_~RUg{bic0n&IPR=@g$zK=V^seQx$NwH zSNw)PL_vie%kycnE5_n?B`?ZFa1}@O!&;NS0Hfra%$8(hr^-)^@0!`yn0L})j0tqc zUmaGfFUui#{gn~D)BFWj@%&(w8clRgL+a!R>2lS5A-clz9L|qxEW=_G)njjf@kBk% z_hL+v_dPIk$VOd`Ss%^+rU}sw5rq8oUU)VbP^d3za35}Ma36+WKm7Wl-Gmcd*b4Tb z#l-1@>0j&F9PA?kgKR@Yr6cV-_6vmrfF`n*uxX*WEpS9S4ESElE~+O7*lnYwwsyow zXoveYxCbB?{qf7UvUw|!3mOkmZHD(2c48R{SmchPX~lSoI6f8taN9W|3AUEaNBkBK z1Vuh46w9GovCQ9vM%zJ+Hk#lnWE0E(m5G=gI-f837kAo{f2_!8hewDWq1a?$jD!79 zg6uS&PyI;X&T`1gtwn+lPPFdYqThTiBgjlXWu%o&c!Rnf^Vd?7k46^GwMJUtYI&2Y zC&R^y|09#VH^-B*KRrjSn87}oze9;2mJ~PGwf`h%fIJvP5l3>WsOv$~jFgv*_Q*_+ zH9p&Add9Tiob9PKr6w6uTO{nAnZC4aV!pI2&_7r;z=FALIuUXT{8wj9;P9G>he0jD zN<`4;IqvLzr~HtXRrLk^en{u=U={pts%DIBgjk%r8m)ojoVyyVfgvyg)K#Q9QOv%? zN2-H@NnB77*})!z2npK1i6GhQ(1h?Ofpzis&HYJp`5<nn7*?cf`$_Ok8~!*3LTDT* zbcuVH7y+fAWgPZpWN0!E!U|A-5fw|{PsH~cZE|4vOZ)!as<iLaA4e;H14RqyQ#DQ0 z4@I3g1v-L^c7I6vH$yZ7rLV`*`orWNg8=HA;e7PbnA;{!igo81(m(M1POeDh!_0qk ze$w_kS%CqMWQJ&5Aa?OniG;?(4Edvw8r4<AO&Jt~LT}|FcEYRNd=bB3P@?|BOy3=B z79^tq+t{ur>4DQJ=5T#T$-tE2iLo<5h_b^sZGrg7A2Q{i^llLPx>}wy*@qN7nvcP# za5}73-;Ce6dgnkdG#G>O;Fhn4!+KAlAfk({_C2Vj?<-D8k84C}X^)gze4tFw9w}z| z>FfJQp<sm57SFVg65M17+z<i7s=mzfV{gjTkdOeZoc}n{oOnOO$onAbb_f0wKT*k( zyrLxwN63hILVfA01<ENKv0^s1>14jX9;|i}`<$uzg=En~<jv|apoM%eb2ViP>Zn8& zfcpy?snfBdi8oS%F)YR#CZT~^!{pa@{c)fW&WW*0kTB)X*<t?&Cnd$!{hXBbRI@(N zcgkA<oAOHvh7>G0USZNlz*GH}9Z-5Sd~`gs)6T9NnZ$*EqA@rp)^8=>e+9Lhb}aI$ zE}K`vz@FrGVV-Xz58Pahz|GkDVa6?7FkVLfN*#$JIojhc7DGK7kXM-Jc{Yo5{~BEF z7N>N7BO5-5<c39YN(EKLzz|vOL-IMo>G+vAuWUx+OBAWWi|vIgOs%p0Vhyul7sSQZ zKrVYDOnwu_4dnV5;;UFujr$bESA-_>KZq_x5<HZfxBjUmR(s##pZL-yu0au6Lj~t3 zl5+u#3ej29k(^Tm0S2vTL)!*7!rh`lBgP6!-slzsClN}oqJ@QSfl6QmV>)VT>?%}g zqko*%zC?Tl?1a5qUEr;HvQqPrHaI(U95|-#XzbeG3#)DX12C(0H5|uhDKm&k_~UHs z?>N$q)`fQdRY!r(=OLH5lu3UXE%~LGGgzl03OGaSq3zp(xHwdaeB!qqRjXHk4`vs$ zHOrBIj55;r0;)I#kWI!!Sp1b_*7ywtx&gm$@JtJZmn|ECIgPTYONq*e;Aya0%W7O! zV*^(K<ycBtPANx`P!1m^=D>$r3-J+3&<i3az=>;E(M(OgTkq%~-$Dh0GuXdP2r-j< zH+3%Gn;c2`UM`^aN4`i8@_ho!en`G5^4LMX!d@>4;u{<NFLJ(gt_jJb0=lq;R@Co= zSP^<{muZqxy}~Y+e(WFQCFw<adpwcDn{d6%6Y1SV(SlxzqrUQ1<e6rstSz!K$`08$ zpfO1nXR`kg?ZNMVa$+Zqz$5rT)=M-3P(^D0y0QO=)FR8p61X8;qx}~Ql64cT4HCbF zO<if1elHYjaGSj1*(Ksn-n|Xd|6v`;v4^aj57*^Zho`hn3a<w5VW-eNX!q2|vN=zc zHt*mlq11nyjnK=BJdx}uDlemuSudtFyvn=s?yY>XB~BrL)ZYs=6mTmW$(ArPP4Pgy z_MtU^CGE)@qfe;*-TN|}|BV<|M0<BW$yN%_M;7=Xql&JEIuF9#L&8OkO9}UOlW@bg zkZ^%+g|9!-9v`96!hUip;^t|<vUEoW1(|K4;Y`wK(-cG&9feH(HILJ6XH$PQ8lR5s zN77yqe4rJjY?DiWq+lFaj!5=pC{QEYcrL_>F!s_P5dorm-pTpga*}Ad-l$?Gmv2(1 zMVfkGt-jtThrZb-m+q6Q|4ob|gS3)ts<s^NbQlItghvyS%xK2eBf=m5AL`BoJgVw! z{F#tIqQDIb7!@UI)TE+KT#2Y;APF-#gSennMfr-RxKt5l02efI66Ai<X;G`SwY9c( zv8!m6&8i6?35XD|)wl=T?sQxN`bj{`{D1E`_s-mz1jPD1|L6I94EN4G`+LrL&$}Of zb}NAYKmi<GL9{{Wa=xP-p9S1-nsw&&I5{3&=cAtAE=J*=-&*FEVY=q`Z%@elvRc>X ziZwwKitMD>y|d%da~N&(P<Kxk9V2bOns|xh7D_?T84&9T9p;NhRlk(w@6c*{VBeAK zv4~cFN`c5|-FX>QD9G=My$$A2>5r_>?EVvREUW*YKCaiN)1we3<WW^|MsJw7$t)KP zrQ)qe>z!@?hQyQokRdMw6^bp3ut#{Rsuj`cS`p8km9ZiOQAwbm4EXm|A4E@05pAKk z_BFODOX563cgCqBliqaXpI_0RZ~y20k@)w5s+{&6e6Hvn(QVtS+s0RP9E1hsukeIf z%UY_gU_FXEO6XG7g?!*7PA$-$)B-)Wuk~qVtxuU>R*GwV9=yb!U*<xuxNukK5Dxt^ zZD^iaZvQHg<yHqxA+#VjPusmB44djzb)UT&>G&h*_4d{Mi9EKK{#0l6=ThCD$##FH zXZL67|4x5C{cCoArYZQGJ2k66>qiQF#?RFK89(3EpYgN$?8`B|@yS=iXGT_kWUkJg zmDQJXq%U&)M6_V#Vvw807%ao7g3{w7NtV^(ZeO3j5aD9XuXiUW(lo30?mVh0V|Ut; zlHTPxsFw~@{peyvkG5_;P;Z6(kv}Qyu$T6KHG03>Kb`g!p`cH)|7^UK``ca@OvhyF zAcVl_HZ$=}`aGPh2$}l<iNeB>)|u9K4saLz&*!J{jQxhs@a!qc;{P)GtCo}1FQbTq z&cxn9mQG*zjF__b7syEjy$?5`Z2fT=>}MZi_lzJZwlH;eNjRbCLZ3dm6yCc)W0;2O z%;PML`VND?-Cz82%%8INGx&}Z_J^wWj5E#JiTNO1o2=Uf>n)t_>egj;x2Eo`TmRAi zj{I>i{Zq|k_U{tizlL=G#NN_DJWl@>{jc`#oj+vv4}2&TifSgaf6ERN_(dK_^)K>h zX8$4&@2zjgXRrVLo!{|U{ZoBY&1ClNaOs<kA{*e$?Hkn`6!|65hW<nR=s9)2_uu`n z*=iNV7Re&BF3!Lm|6%)$r|ft8!)ZT_tNz3GhU{;9T@YonWSHOX=Wf<TA7<bi&X2jk zL*d89R#`;W>9&R}b%g8-Ux^y0uk-7_PTp_$eExOX)A;ezj3Qr&AHj9rB4@{bM`IL( z=)zoT4kV4`N;Bq1?+0Yk8T^OPci<@(eRm2nZpB~Hl5!#xdck%gOwo3O50Q-u|0pzF zbi5FlmQb8i`2i`KqBgA*wYiu5`PKb-1d+J(M;a1(Gc=O^lw{H`DMDo~mLRe|71`1U z{hzU3)O`2BU*1%)fAh_`13%s`4^Rkjd2a(RWNZ%?|JR$|5o>mbzjbpn+rPbk?PEEx zFk@q+77s6dpRd~cx0^}tWF5&&sRQ$Tz{`hfna{3X>u7}Xzt-#LtLe>8AL)hfI~C1Y zoH=LK`k`tK$=YEBjvwuG2L51tMV}q{kIu&#S^ZJ#ry{d2&WeejPM^Ns`myQVE*Cdi zdD4E)U$?bZj<YC}fqLCCA-pqJ&;HY&?)D!)alhNIqy2P~eXJi}mV7M8E>!qO$qWSl z@Im1pXWgVFAbsJVuU<cY`;}fl(vnhPvfmNgWE{rKmy$Kb7apYhuYT=wzgOGRgFfb~ zanydmi}LI@F*NHNUUp|emf4++Zykcd$Hi8~JNU3NO+&<6<abVrrid@$H~Sazc)Eap zy66II*)=QWmV%tnBwv*Ka%LC#q9{xNzo^0$KN%&MRwS7p9*mZ#T~JaD!m>mGop0w$ zhuY^RTMbpG$%Rw63y5wXJHQ$Y-YRi#wjxmxBWr|!Xh(8J5dp}Bw{1BbuQ`cz>39sP zlO<viZM~q%A<S$d53Ab7cUnSy?Q{jc0gbsNfMU!kEQI`@Aljk}%I-Hizjf=r>%)Fv z1t4_QhPF0Uo3^L!1AZ;I`WsCT(Loi0_hnxcC7B3HaV@w;QFyW$cjbr207j3oa3MMC zqYJvYiULU2iRz%!s&;2Q$XGU|3!~|$1Ke@MS&sh;7yWf{6Uhgy+lp$8Wwq~l3p?=0 zFNsds8Yo<)E`e^{R#0OsZTA<-!Peq4kvIGJt9H-GrBB*3vfV@-GMqW`@kI%ZSF&w$ ztXKK2W~xO^ub!z6_e?$B`}}d{!#e!GrS!h%>ykSZgjq-|oml?eE(rIUuNPEr_F5nF zRhU`Zcvo%Am)o_q@k5INx>Pq)?d8t`X5CN37HAyNOk^R+K~_QE{*22Ji=m9YQX$ac zS<C|y(POJf!l`&PpQ`1PQvdt_heTiO>|aP)Y(a4#cG@k_wr+SW=v|kq61)H{pQ<Cc z#5(U(Y}}UNt`+I&Z!}%Xq3oZLw=m%8PIl3?$Irxr$gK7GqWQlY!>e4~eF~A(e0(H< zy@g6LmVXdVHjXpS?c}T65;S`-blv?I+<1<-oy6#%->Is0SR0WN`o!(>pA<YlU4Pv^ z>VE=bT&MmcUG@J=>VIZ|s{doV{u@;Nn5moJFQI#7EPx6ph_D2Wv4X>Ft;cqhRCp}4 zSkV&nQ)`(gz>CM6cPQlu^y1CKJQ_&n|EWqr;Za{S|6yrGpl~Wsc$9oT8yW(J16|#m zM@9z>pJK~o4cFaVrs~>ZwGB>z!Hml-O!o^-VeX^f_o)m5`YDs?D9;_%R<^U!;H1X# zoDzp&14U%nrXA=k*kHIps9kq3BBJ<P@{Mt#td{FZIjERJ6-#=Dwc}g36Ny47RoyJA zi~mVgQ~QJ~=c3B&oOP13QB|IQ%V-5KSvEJyc=xhwUjJ))S|^atf!FFk0k8L!5^vCr zs;V8<PX@_IpO?T!vHZi*^&9)B|5jK1A5g@pe}>e*P}l#QUH=)>&ys<RoYwcU8IJo) zCTuP`k`ez1tAc3l6KNR!5E3{u-zdrVJ@SDtmjgp*$;i^mSu3-yH0l3Vz3q(#^fpr{ zKw$^b0LNdaSd`mqoxqY4_cJW@f^H{LtYPILgv*GWw#(XHDD^^6!>kNPiN|H%C{Db~ z#XHP;av0|^Dv{KO3;)gs!eVjOVuE1jx?*86$yKohrCgl&BZac^uRC2W2Wrlreuljq zPSwL&!uDAL0A%}YV4FC*d^Gt$AS?bLIIgys!~JEYvm120s%wXJmxvQ3c)=?y=1yyV zqXI8S$gBdNIloAJM+#7n3o;g!N-C-mPCo}fES2Ur^Uw}p58i2?M&M{zN_`sj$Z4eY zoKM1y_M&IqNMFg3l`5MGeAZ<yQA4`rtn+2B<z-?EtmBVKs~gjGxa0?Ym$#B?EMKR; z)2$Qc3*cd8xP6d$_*5{VR!*i{-p}z{cYM9}Ia~iSFQfHv->vUw`)V;9cywQ|+fVol zSCD0lbshD|%CKhlS#c*mkOl@wPhg(%9)Ih1C6gYuyTg-+J%?x}TttDR0<#oNCuAqo zK_EI#sJRv_t*kOZ_K^iGIiVA1naknu8(cc&6-|}}|LHB<9G$WmdaTpmx)tr!wt_(6 z`b3EePF57`bnJzx?P2TtV{GcKa!Z<Uv)qJR;~MFnqNNx8(WczafI?Linw7mLY+9Pl zrAsZ=^pvK~v^~cys&FPf?MkP{0&8hFW7_YrNvdh9`>5|*`>u~gG&8fdnpAB{o<Q3m z-3)^@?5xxsbYk&?8ok2y&@WO#CFuMl3`%WR+D=-5AylZW!Cnx#iH_KUX%7q?d<eP8 zGNn85iQRw4zN6Z@9^w&lHCuj1r^;YIs)0t1^=L>zgK5D+E|!ntOKm~X1ox_M#J=kT z8kc6)CPvq?p{dQq|D@a3<CLMvTwAw|l;zHF+E^8`4Bf^j0#8apfoM|&&E1KU=MX5T z0^8AZt+yzbp>%*%I7_yKhRT6rC`%9tw$f=WV!jpZCM(bZXxJ+B>gn;)NQo%ttP`Oh z`|xLS(&=)Kb<G?FzAoCd03Uh<#ZS4%>*TlIgb>?DeSq)q%-Swb)uwl}GToW!u(x(B zn4o6QekcG-ZRJkc%E1!(Btohw3=_#2cbO544Je2M^?7iTdZp2Gu@Z<Z=*%Hn2vk_( z)*M<kmTr+~V&ckaLaTA<5tf-I?%|O&GiBWggiUHTsaYVqr&`K%EEj$bXUY~%x_5qO zZ|d*fW^d{i>Z2CLATvp62Kf)Y?q`~A{aKaT+xneORXLV*lbQhPRP5GIHOOSeWv}1q z*5&)Ij|uo$W^I^}JL^|wpfCHaZ+LapE`XIm3Q0HuvES_?VX=PyTK2o6N656Yna1)W z6$mKw@=^DZDePlln|R4@1aR$=W3_ekWn#RiBok%I_UC42LlFfaRKB7}x>>+K)@c5b zJvG8-RzU9*P}3l(iE6|Q@zqPEB3J%mj(EqyF8*|}Cv~|GeTt7cH1qelS-(#}6=?Te z9!fsji_e{|_}pIJ-dm-k(b2x>5&!e8yqx5{#7JbkYgY(|tA`>t*fJEOsY9~1<tQSz zt-3%xO-z%7)l^>3|FRk(!r3kS`HGVFc1T_PQh0@Z5w{wD$l@=mebgulE;ov%v>Qd! zI1D8!Xb|t4Dfqiit03LtTQw!2@oKTR!hu$~vEpw-wlcDnk!{EX;_aNrWq+5H8AGld zjW13$-+UCCjM3QCG;zr$j17A35k*v1FbO(VK%IiPYn=DZl_^N?FUS5s(~We#hF++p zqBZ#0=S8plp_kHRPHJ(<{DA5z1U+HF>i9p1rUdIiHhMJw`f?^>u?C*{uHa{zi;s=z zN|mX;TOMZP&kD7wcWu$Rl*0qd*IC+XmB`6gg3+eGaaWQd&CSDadnE0CRwir!X3=63 zom>pF%+I<4g{geRmsD1?+{x*R&y#Iv9xz`BYNDU&BfAP_U+0fqJitdxIar|pR*zMk z^QQV%G}!<7n+J#M164cJLh~6lL|DGC$5+)c=WsVY?{6O1KYXSy(o#Uu?Cty<9zMa> z_=W2H#hg-R|M*KRk;)cGNG8cwwK~-0Z8)nx%d*;YGvegeLl@UpvWQ<de%fLzdV##& zMQtje>2B+XP=YM)aFz3$vsnnM{P&I*a1hf?B6;)%N1RQUqxg1M(k>P%=dr#hA>jEG zlVU_aU5UfxJckTqc5AJ=MWyQ9pKKvyPq)A7Egh4C2r9#&{I(HaYW~6g<l6Xy%!-Si zt}(kJT_bA=3*+%dwsIx;mv7IVAYoT>y{%jO^QES6UBm9~*^|gp-;c<Ftz8F^;ElXH z)?2v2Te!yC_+?Jc5bn$*%3U5m6yU1jkJAiaa$CFl*A%vUP06Q{j*Q>0llrxG4J>T+ znj7pC<E{lH1jf{M8O?|y2tNgQR$14fppFmcx4*GRRX~hVSuk>-63g?11n5Oh&-{Ci zQy}dPOgn3cFup;{mWJd*vg<WhtvN&$M92vMY}dUh@rE^`Q;=!)`KS0VJKmHKD&Q0N zVESQQ51%aiSlPkZ0jt!;u>WBvX6zTXiw~k@irOAE?AmDlALJdWi3C5&uTekN_&_s~ zN)V&b@-|xDswsFDjI6^q&mu2;bKx%q8<7m-{EKTzj^^)?<p!<FeX+Vdz5aB2RqpoQ zb#m^dy$w|Ew3nmX`{_gJ_D<C8J>=Blv=^2SbXmr?P9@soyUoeDm-a4qwYQkOjIZ3) z-ZR&z@ty9}vO(ziVmVV$yx7)YBGXzGKN!Xg$TR-YgpnP^QWL;TE0rqwEg@tpl9OkN z+=GQ8J)Ln;=_r6UdbOfeN9$>$OgUw+psf}Zmh5s*F7L83w6=D#zATRdJ;&%q%GmMA z$rW;P6I%;M19fYxid}o(AjUx`ow6K4)VArnWhEZ3!T|{kA}<%v$*p;~FO-96=1*l; zgZNZf$m3x`C72_a=3x6%=`6uCUUA?<w6&dJ8h*3Kni!DTyB(4JT#nY;i}hAgxK~@T z5|hU&|EDZ@dtB;1Vo3Yw`4ni4{~H-`#)wn)%PhuB9t-XkOk{<E8fj0Ajd)&wuF<ji zsx^D3ee}zr&kP0VMr&6d(Wa9A<?MI)&md~5pRF)&nD|kcyAn6?R5ip!!vV6ZF<T>B z`*~NumE{DC+I7M5c5%IF-J0j~><Yv#DXFbo=f?NM2_M(RKNGu+;jKIm;O~MWWBB@U z1g?^Q0_%$i)tBdwtf~%HwTCzPJZ<jsa*`tNnrP;&qIE3R!yhrj!;hBb4V0&JCl{-Q zA(2f$ORzr&r)|L0@%i7M3+iF&cCfe<_JKM~LFM`zWZrt=8+%PTxCVSj6qq6et|?q& zlbCY;f+kQ9<u@Khr-<{*vfB>WoQ_Ge>S|{-kM?=}vat*nE`O2~A<Ej~3Uxk9R`+G+ zlu-4Hmw~y_*+zlrpy8BL+lV#dP2OEXX;yiWv5cKn?;P`qT-S1QdH_5{3Tj8LM*UZ) zF?4(ew};4njpnZ?p;O7}KGoko?E{RZ9ylEdOppGeA>e62e-Zsofx3;J3g$}%U;*2{ z!k2tlgcrC=umf)fSm7>-&B=Zurmm<#ZB20?`ki7iHi!;7g9-xCyE|C?0sJKbaucEo zCnu<7hc`)_aAW{5@4cqG$9nKHLJvSKuy0fTbS#wJ)}18iNdMaELvhg2K`)Gywi>%= zOZsdQuUwmj_>)~(^dl$1wUcE{(RPoOD@U5RWB&nST$aUXMM_fUGd^G)ll(VNIZ53c znB`I?IP-8NwuXgsNVE<Krq@C>Wg7pLY5b??GeK~@eC|tx2Otg|w^RD?6Nw(-VI*i- zx<Nn53rDja=0T`{MI;JVZ8uc9Q06UA<4Xb(m?#=t9<17f?kH%CL$tfw`o#p!6(&a_ zNCvBR&KC2?4vIsi*Dirtr>Il`{X-+NYVTbn)5^X|xuUB$mqMW*`!hwMpTlD%#)LW6 zKYWT3i{+p4Q$dMRNxr3CYf9N=gD&Eov*twgsO?^f@n(+o*o|s)X5a&*FHU3qGAFjb z$WX@AcFhry#}ex_d#j2;m+q8fFTS_(G5E*x2!r7;1-cab0W*f^`NeuR<bHNBN7ZMI zT>HRsH;>3ZZjO`#jm0j0ZCora2Me*!IVS5$AkPOm2aZi}+QhgV2&*?Z_tCQ}CKtr_ ze3`)vvXIo(c}{0C@dJ2a&xll41TXa1ctLk(pLoGpqYi!&yjyjCL1<_on*S)ZDr~#T zn_O&VVk)_~&s?AGknF1TuRi%B!RS5x=17ct7#~XWOC*6pe@$fE<BF0+i38H_ddJB$ z=!>`7wD1hXAr-{`*o`k^7XQW+3F@w31$V=UQK^XAZ2!{2fi@aX%S-l||J4Ii`58}o z>CKlDcovL;5->Z|#{o-n!Hr&^<exEcQNYuh+^S^Fi2Lm;LfG`Xt)?BxWMn~mzR^5M zj$?LO{0|CA0s+ws00puoC$nhe{#ka*uUTenoEBExPI(1tq0`XlwD7T=C)L(=k?&{s z$p+KAYNJ}3gTD7;*<7_<5U5{X$!qlNFbV#uJz_VVzwR)pn9xqIIkU?(D3~&s7&%7s z|0Jm~k$LUXnqB8yt1DnFpVimc9^J0T7CuYHl{iREW!9kT3WyI68ePQd-)y}ss!T-| z%};Gu%62j&5Eqw#l&hgVcYk_lr|=HK7^oh#T`ST15zp>AOdw!TdX;?2Rq}3Katm-0 zpsYkionzHd5;|b9manHL8T@kXELLETb#fmlr5eDgcta^FROgptA@^(M-vaNNiG1D# z!?#n*Z{*3}rvfE)KYa%hU{=}N^xQvV=;DB9RdO3h^p}h*{@=2U#IG5*S|rEv4{uXR zepoSK-0#eL4OtV%^__3NE8mA|H7N&OxFA+FQX|$DPgaFgOWoD-$tRR=f@_!u{fZ)q z0ldu5C@bl%vV$&QQKn1l3f0BVt=20adz5fy=IX`5nV!zy75w2*lw84|gRA5TJjz(5 z`NgtIDV|*1EeML!4-6ukKn_&;@}!#W{IePM%A;w_8b3}Ze1pS1l<A1BJ`>N*)0Q2Q zm*Y*|KNTXEsFsmk{pOscDo3ioXS;!L3Dr*1)xOU|SNkD5-#8G)prjHv%vagNkb-`5 zJLS6QSbBn`Q*FBRWa-q2(y70y((dtP*}JF{H|?rytF}0WFn5_>#F7|6U7UcHcLnwb zz?b`|KbGBSfoVQt3IfrqyUF&8R5s`ymF?4yoNNaO0I@hF+s&zLd{fyrq_PRoNq9oZ zc2O#u2*Rb&-=?yiuCgtVY$vC(^|!O#p2`NJL~Y-fY(rAnoZ2o)W&1AK*xubBhDXVo z0DyY5!jDM9qf%KB{Ww{dkabNeE1Gzf)sxD)Fr9TdSszJdbvp3!hYoNakbauq2MeoC zw3GejRCcEmzfWaHQ0WZo;$GPrQrVW;9SE4m3Be%jVgPm#ywd{VP{Q+3o-Fj>5}p-2 zm-7VCiDF?=b-=vA2XVnh?}iqWH6mCvt%lda*DhNa+rc5xtTvxMB>v}Kg-K`MqwrzJ z$`Z<3r`Cf?F45iU0ov}uK3C!8y6|Zkg?AEeCw^Gpg%5NUzEv0QAyz1u*lu~H6n;}5 zirFo1q=0j_oudmsol$s!6n?nx!gsq0dvxL3GYVHr;Te4wzQ|R0jT-DAZ${yMQuw&O z3m@Vte3veqmr;1_RTPfPy6inwuTj7m^F&>^ZLu3*rWF2j--UnSDm+LR{_l*!0SYH( z_tESOSIL)DX9rErD0z^Sl(RN_lFD5rf2vCk&nVeBL!Gr>X<xz4?y#PQFHK?1)RNvm z`vNI{>o+Vv<{Os(0=Dy;^#AE^SpL>;SboemEdRx)-*Eiju>7sxu>6=l%cqWLZGT;z zC5#ghfeMk}Qc3N22kH&F#NSKp2Iq?E4aJZ_lo8Qm9zTbyiggi-YPgsDV-2CvMNwLf zAvO|~POz)1^50%2TgoM`usND)cQp}hLY?Znya=DCHC3wy(?s&&4k~u#(EMOD|2L#2 z7xz{uj<82{Xs=PBOr*gpR=awcyi|JWs@*NWt#Iy9JlPk$g-AeWSJI>ixk}V^V@l47 z?B|l1A~GJKi90y#GM`C=9Za)R(pxM_MbYC;{$w&^k=#Swf-sxGQ1n+!@Mym8htOX~ z$*Fe|6mDh*UGyPJCVkQ4X+If6&qVTeKX^@A2pyyuD84vt8V={LRBjovI4zXWT(Z(X z>-*g95)>{H1swI=_qi25Ct7G9_qicbmRl@at+BF@4%HEK6bM9q4iP?@^QZ6I+JrW$ zz%W~c-qjp4UvXjEeF(BqoMm3vR{fo9=xF-e!UWF&8|$vmc#>cKKqxi(3OQ`;EKEtf z75y&OL86~eN+w4?f9Dv<v_Ja!2fFmma_Q%vlA0j>ML%DqDst)P=TA+K186IaY<_$d z)Z6L}@xuYOYlX(2&irl5M>bj)iuI;qSu-TIeb`G_JweIJJ?O%es3H=aMg@zMu&(PS zNwR1Ya1P=)Rs9i5%O2|_`jlXg+8;%>)ngsXM}jRq<vKs5SHgK#s0?NBNb1O;mA?A3 z=={F>v)y`VE07dtFKMT;uYPS(N%zAwB-Uj0tC5fN>o17wvgI+E{aXYt>-5i9S{Uzf zfjHCNNAovIWNmGk?DX1bYLyLvmBz(pclxsTI_Wwhi%H<lx&eT<TiKO?imL~>Y|9** z+`-nYx01<BLlkQopArNw<Qj+%q>b3H6QZ(kgYDksLfu<$#3W2@Z5Nj_7)^Kc1u;xG zge0RK%-vDF6xr5-&b;seja65LzyDpri7~GjhfADCEoirPzexZtYGKZ|TPMoW)c{9^ zgH-tktQF)!IU!^xVc2{<^G5Sv=2U_Ha4=3>Y?V}-2*5?n+F{rI5Op&JCr77j_<U7f zcxYrjafO)5{%Qp(h1H*(Iyq}3NfhXGyL#big+n+1w4u}9=5M+xGLs_C{Mr5;_WGMn z<-j}3r1JsHw&<i~{gM}_puNXj@-&}wh}!Zrk!)jvz_vJ1srp5Upp|gSwcyup2<Y0_ zHes-@`t-|-WMe-kNKl^vV)V7PLXZjuTP9I=2+-;}kFJy|sGl>0(+9&Ij$zJ&u0^>y z!n%tpKs?5jC^)|A#~CN?DXJ~&daRcF&>v;UgQ|g=Wv#l-MF=VNw}3za4ven_c7f6o zYqui@QU^pDKON1eR&S_maZ6VzzkKAL0f)T*$lt2$^MndZ#GHvsWUNol1rU)vNfkGD zQbD*_@pg`yR;Y=RE8^F_uKT6Yn6d2qqw6C#m*mv9c}s}Y_ARsH*qol6oU?N}S@_N9 zj__bvb$0S~Y)#J8s}3z<QJ}B|jf}V0cK!gSA-TfDB&ryLtMV3vZ>rov!OXmBqR9Jx zX5P@tftb$|FbmOVd5gRpw2iGfbf(r=w$9tQD+dFJITuL(JUR8I_h?tOnQg=-1J@zO zvWvV$8KY=AlkH=d;y7~pWGriM+?E81HExxEQ6nCPUbDzoxY@UyVT;-{$LHaS$y5nF zf1{11`5U1K&hmr_3!A@+*QOTZz81hcdNuKszs-5hzcR((=RuDM@emty3PJ~=ZYmJU zzVdBYsWoax7|T3NK`yG_CkDwuRJm@6r`uREC`75SM~Iedd8^zKKW2;ya|pg{{O|$k zSz0Po1b$^}Y<%2P*&<~}OW8Yok+aX?B_}M)@lk6IE|Kh3wnhGQJ|i2*G~^m`M3sCV zGVEye7<8a|<bO6$1Z~4U;=xWC&LF6*+iE^S3?Ow^*O3;k#Lua_9zUn>Shjvo;zD}9 zgaq4h;n-8;d_Maxe8~wv7Qa?uw?RMRC*bg%$u_o&hgywg!O!c>N&Tb29p)s&T)`gt zO2_JoggmL&woHv{1P1C<b;WyA)?U^M*KxBr17GR%pSsdF#G{CZ)J*7q;^*S~;QFo3 zr%X&`EthSk&i8P=AoZ!Q3Ha41YAK|?Y=R(lD<^~*O}IO8NOa1FVnrqB_j;0g9sVUM zsS-qxNK*tFU60_ST=d*6xG8(Q*u_YlWoY^xG}~8y3$ptA=&M=%9neRA*CWxT?!VXV zwZ9l~_3rQWeEh2Z&PPL^?ypj?&6KlXx}#fREnAP&&@i}S7#H*v)JwET4TPB>Xd$M= zn*y64IYS?<#pFtEUngF_TH$qe0f&xyUJYe4?gNRHEVTFQ&Dsso+HEF^2C-KhQoE51 z?N&E%GTR{fopO2#eoDDyTXJ>1d3$cXc|{(b;YhwgaLPzJrPiMsL>Uy>bk)@TE+K;3 zdeGJ<d2Q1sGP~{=!&J-q%lOpN0)b$$EG`SEU#&HOgE8W>Kv35(#7Awnq8p`)-PY$A z-)Qhm*OEYW-Z0d)4E2p@?J5kJ8EQL2eTxE}*3}G^D@<(%pARN7@YVHR`{!tZ!&*$$ z^5+FHRa?VWz7J&Rn~~QDK1_Bgf8bN32IIL+HO6zRYmCQQ!P;zvnB-Hmt<gLc2&t@{ z(0lQn>{s<`H;wf!c#*5%NT=X0rQowtumvlVnyOEYpSRW+fo{*H8m_V0Z9PU+#&a*! z8qc+*yKn$C#Z9NRALuOfQe~mxjb2Z?H`${5`zHAkS5~g0vhR{p2BQ<!kl+mDM<5K9 z#h^clO5OG;lD+)XbcuUhC8kkAXM1Bnx}FJq&6>Egu`H_mJYG$TZU30kFFA{(#9me1 zR<$jfaNE9xDESxu-skUd;8x2Y(u9=G#6@qR64Gu3ir%U<H`bV|p}00#Guc0KQzv%9 z%@IZ+KCDgu)HniDj1m~lvJx2`WQ}Y%ugU-0tsy`_uw3|<`WiEY#RgfkvRq+j2_1?F z0)(Q?*BnK*9?J{bN}!O;V0K3F5p&M~20Yp>L+j=HkpF4T{Ai#vSygv58dkw7VwPbm z^TFfwk*d5fL<y$-ns)Z%OUDW!W-4a3tF!%!A$l0*pGzC$*;YFls4|f$yVzivb?yrS zpzy=yv`4}DOUx<DeX$7xdF|i{MOoX)UDp-SX^(nWh-069!|^yYClAxjCDzj~%Ff#& zx2qijX~ENI-UE$KcK-8Ly*5W~G8S{PmRdBW19y9v8v@#5H-ancZtLmdoScRQ6)+{! zDzO>;tj4JM)M#EKH8kwWHJYzuaDH=VO*H(dw{eej!D!yeH?R3d;?VlV0dtQekt3D* zHmNn{JGy?|Yio+#3iS8YmB!Lf399><(R>B1RMSdmh25Fk1F{6@O!Ih2lEC&4MHZZz z6MDeT@S;y=z>F5rakx5Q)DT}2QYI%FJhfq0KjSWiN0)9!M-k_%5ACK;w40c=wV;)5 z2WB9_DJ|lTWj%(K2uQFSXX-PUm^hR^b0HqK3!s5(i-CR@&k~-NbO1Fr<vOfoj0Th5 z5wfr!WU((o;l0cH6>r`}YvuKK^6|=nHH+pAS~OuWm=Z(wV6|iaVmG;l#Sni6V7d8S zdz@jgp$5d60&4(aG|eTy0K;gyo;N$=-_=oDfs&|pG<%}jZ`AC>9+yH6K*o{TPylJ? zYX(3#5i$Yt(BUb794NgTse9+*$C+<t9`&AHeP^?JvEw%GYpto;Vcg3NhMmTp=b>jV z*laXS;Hj(<1g5mLPngai)DJhi1JkY61P-Taf#g;zz^el4R_lEAb>3G%^+Fm=T#FT9 z{BYhN_e8}|Chjx!Z8-yS&~M3})Ti1sy{{z$K@kcPZ^|3l`sXBGX^j^pk<hi&W5}Hk zpAg&uR;v9hVN|y4Y!zCb+nG5GyNSFor5hS^2hY!#h0pmA+=I!JP{(D)km@4J71f(Q z&icuDG}E8ozQJ)ps;To{>;=4291P95uP95_YK0Yr08+$FMwb_RnI6H@|3x*o@K?fM z{rsKJyHLXp$=MhE=JPUXn%<l*^rp2*<7V1Z_}H3ow#LLZy;&X&e&}m!q1I%#&v<-L zS5H5XTCiv313=RH*I80qmiVbe(yhlZ<mg3#{)~@qicZ8mdy^Mbt7;xV&*`G?;7}{% z=t+4@So5l#0fmq`c7wDlG*P$R8mPvG=vCwj!;X`lV{z1Kl@OmNHthbJxk`CCyhqOC z$6JqoB4Ajn<mf9BhtqVoH7H|n3xq~8!ar9@Td*5S+|4Ar38!cH$oV@DP`S_FRQwV; zPOWVTJs=g4#F;7mwCyE1hV%f{*=oLGzVLXi^|0!Uk^^!;$S~z>65@5cRk|@Xhdt(N zoT%1pM%8OxWV`oRhe+3-q3c>!sL9e?)%C>h`kapxJt_l09%K)oOttSGf#@@OdC(TH zP?PoM6j}PUdG*a(=8vf{*VflUAS`-{Zkn%HSG_3xZ?#6rR7MM0-^UpBmBJm?s)KSd zO*NY2(u2yD_;4QBDq-|f`!Fc}hFp=&5ZfV^Z~H~JaLNjvlhbwy56S&7SvvULslMw) zzQj8EkLuDO(LS~)vK_-lmux4po(?$_jO+WY*nKD(l8W=}ZhYWLb>mCzAie+Hc<>MV z?8cYtR5u8$4&y4$f11M(=K1Eixhz}6OxE}A6oH!d@s$N(_0RX@SRVdCHc{e>wC5(e zTtir{tVH@+pAOntVqNqd*Anf$KP6~TNg7Qpu}a<fT??Ww|0cMNuXn%80DvF}K$-gq zf23P??DGnc(DG-S=Ut20lVn!zPRQd4G2-e^O8zc4rO7P<P;roRI2N~V%TI-)MXYr% zw=b${(y{2J8cijZC_M{aLc6U5VwP0Y9s;QlkiBZv-0%9LM~cySd56Conyh6mPNJ{+ z%6A2-T4!V3c`?m>kni)nLcE@QQT@<ewo?4k5iF$g)hbjF{lP9vinVU#4IBBcd<lS3 zA$d$LO4MaC#d*q~A$^Wu5iJf+bHoaji1VC^^aU>+zcFsJpGP^dU)Bc8Uk=93I?QLj z6)68aXiVtA%DR9Y+k@q=gzExTpUyqS7ilX>4ASx0+Dd%MjiHkI$Q|8zFqF|tdIW|a zaFe+$ME(vp5hh-tdx9OXB9V)OrSk$|01}9mj`l~^*!A&N;!kc0Jy7pOvqX&_`|+|+ zRle(w4lK3n%$GV}0{%9Boau173O@>eKj%!LQ#*vkpIT$K*kXOZFS%Z<{Qbz3p+b86 z$nup`pFz5$`tC>@az9{(RDYLs7oRGVi6A;V>uJ`7n2&=}APt};`1cL2SF3$1$E6~w zrG#LQCZWPb%4`<b<0dJ&t1+xvTRoVs#L$WzacfAXb6Wd~oIJ<LvOpIOU140(qM{GA z)pnGqdTKje*|uVBEW`DI5;~wSyNn@|h*kt{<n9IYiZaZED|9h}W4F~+Qv)q^Gchw2 z+ICg-yR#7>mbgCLCm#&gfSUM_wr|wCpiFU+oFcs>_V0HoiG8>A5ihcf^g)rLciiR0 z$YSZcdb8<leb57`^JhBePlt87BjZ*B`KtUa)?616)tCIlCcPRz>=78H`L$VcaMhZd zg60}*<O9(Qii526(|l2k1IHDKB)6(PV2p2N*Za+N{_@tK*?~vPyh6Wcl`vyC1XQ($ zhQ-^F@QBPomoS=_^IM`xG(X0RFE+b`>PnbPpHahA53QV2$|`@sWNXwj!jfE#-;D4s z(>i3`nNvF97^nMVbrt-a8i<7pQv7TndJ<PN6lk`~+n5xFEyU%juUhv!CrlfRVwcS* zb{Wkg3(<^XZPo5Mhd^-Gm}rR=r?@SV<`mJ6{404$2?C%3M6#hvBRvC*CgDt2dIc=K zVpyAQF|v&=Xt&#(05{UIw)RFu=&xGCX**EWW88}i&wVXbyN!EWY6@CP+M$&fbTzev zj!lfU?d#c1UHx-X)r416w%D1%BR~<!{^4PmAhy(y0|H%m`*rcld2%PhbZ&`(2bx#y zYnxEbz<}F!!JR&Er(7+FCjwwAh7c%`RLGyHd@G|=F_cHZv)#D!x_tRQl3PoRg%VCi zA??;c)%H2Jz->;4(Bin2TaKq3BD;2{FM7Hz4sLG+6>^=$`gt?rw@cC3u=ZI(T^>bS zP?s0JCwOB*!P)_y__J(v)Ne)R%aQl{LA%V8RWM`V5_+24%AGSsjArs#$AlKd#e)*W ztVgG+Hx{C{V0m=<L8UCasupA6dn(s<U-_%Ps#fDpxdYQK!8!8|0C-8^U-MNtKRzD@ z0RzUO-YJY|Gj|J>SWgWVDrCWAdNuv5V~pmzNUxX6b|QN`p_Ags?#Zs`=19*mk}*6} zCC5KS)6sB?p}$?EzNva+;}|W@*U^bg%{Yy7r)S{Y@Z_{6^|;n7oV(pRm{0NhM2})# zqJU=d9w=X{2Zm%sP7^sFojI1H)H;~K`OJA7b`!Y!nkb3q6-|ug>4UE$XpCPUz~3x- zHRd7T2gq_iHW8$vQ{WG$ObwV@eC4a~K=zq?jEL|yO7*&wmtfU<0rPF6=|w;v^lT0? z**iA}JnIx#A+P+A=W$&79Q=lkDcHqA-Gxj6sw^jng*Yy2)w%ow@iruQ4%?(600mHA zYX)-nuz}9;8bfMw2g5Q}@Rpa$ax<EqKoo)dFOJUK-~Bv)EhWLKuJFV0-;zLgjHVd1 zdua`~-RC)tclDPZHcOlIBrc}iJo%<F-$<$DCAvf)ze}<kP2x&FF*dZ!7g>dQ=D1wE z>|8xW=<PKFIi%<w=5*UVtjXDC_l$xifvRocKgJE}*UiO`qE-hkd{XR0n!f`KwcGdy zbYa6nsG)iX6e&muAXLvc=}zlmDsUv%O83K01<OA)n*K(zzxBg>fKZe$>K7|uB{vvN zKOlj5SO7_p@Z%^TM9MZl;V*28;&0DFQEV1aU8uk?uq;ru)o7}d87}|OUygM`aH>Sv zRJE7C==VJDkG$74F?MP>VR)r2Z9frN3;nV|=%L#+J#?`{4-K|k@=HrdLz71Hb~=?9 zFVGX@gNxZ1AJLQp(dk8js(0iD6X;mAVG$^CtB=B6Vzi^E#Mi9TV21pjFU86iY!v7> z7fIFJVvQE@QeQAx?Z3o#nW!!tuE5CpDpFsxzrSiNezGu%Vvor0Ky+@gB6|rqDKwI& z0|Oy;Q(Y0glUij8Q}qnV^WbUeQFuw(0IB!DZ^&t>X*^q!!l@;b)_k{!UKntb$n4cv z)5A2Hhw(9fs-(mQy@3NVyiDzNm{1L&I_poTDMBMN9?@RpBT=r)eemft>5w*APMwEo z|BBx76?Hnr2ygTXf^hXCMYG!Dsb9RW@{l4ATZy<Ti#F1scb&2>`<lM{FFL0FA>(rn zNv;4DpO1&A%psRtgXzV8^<5u;2E}F>Ph9qjBE=?K-{qxu-S?pBsX-z21<!BswEcq{ zKWtz!T$GR<IY+K-b2w{FoeHPB9Kx2&(>i+ZcMip3*?L$rPQW&z8jnp3PR=X9R~Ns* zjsBglPKxCfs3-^%)Iv1LFH3LPP)~hicmMElat52bZ8>rfRbRt`j-1f%8EmK6?V&wG zTz4EtCqW=VVSYhjZ-Hbx>doOS;0`pse6D><YkbAPU4|yh7Ealj-(L5jBU#^!ph^H% zVdqs`q|4s!Co<?h?CtWO<Fr)vc0%sK+_lEf^dc=}6mn>>nN_^=BQ)13{9lF%p1=|l zBC*Ef4Y1-MqbwM$CD*WJ_Rs!q*iZVfziX+Kt)+&M`X^<ds78WX<)#7%lGA6(G0H9% zPx6~f0_C3~fM`vCWx;&I-1IhI;0Ip_9R(H=1o(+RsuAG({-}cheJenKcsO6dN_ahV z8YCKsggCcVJGfm}?uOGxd74}k>PAlUTD<K2p0@%V=+5@a<i-_0h%lg9*g@z%CxXhx z=fEyWvGox0_Ym(jEf&;6jk(Tu&92B>hmZHQesZ#>%^Euj_`*RIicWZKe^26S;T745 z-PUhTBq<6IuyBY?v4j}pfJ1Mx%Q`J57ptv1?l2-f$<R5N5Bb;Dc|3`O&Tb%2Xu#RI z<PD$3H~gn@Ps<b#{`?K*P%&X*h`ZXl{8QR-gfv4T8lT2-!n^!rs)A@d@^#5AzHaG? zLdz1*rq5GHUu;W600f=?-Ya_L_9b7;L>==5a4sK2<txaVj@<&iylZ6<-LMJ)g;!YE zT`K`%j<pM@5g<f<!^-AZartd5-Q;c91eLS&m8KS>W^-&@9=aZjFeWIJ{smQZ4uAEz z)`(*nuhI>MzHj!}Tsi?UCkVL+BY7Uj#e@Oy#vO`H@5mq-7xXwJqhWozG>c^1Wp(jM zp#u$I<qDXx_*dpzsH&MwY`W+L*q7j4P=6A2SqpKEW_FmE$#q+wy~Y`J8Nc9p-a^j* z_h{{F+_woLfz7UcmORU?3Ryk?CUb^YQqmi(%R_SqH0lQWB0YJb(;^u8P7;Yg^QF>+ zxuAzCI<09Zz(Xw^0}C{<x+xikn*oK=rJnd70j<h%Em=sv*e}eQ2nkSo$A93Yj?$@@ z_@0(j(Mu$_y^fmuk)Vsn(q&GXALL0RMw4ikiMdHDi3uw2A*vFi={eY4T?RggED1P# zs_Oifbg~o5q+I=efZt4Rw?DEm*WdbniD2l~Pb$3SUur|A9HH8eY7Z24L!WLC8z_Ha zo4;@q;CPYwK?INdoiGFaYm^1Vq=NXlG_0zgrkc9d<5Sv884g1)RK0%3$x}t1rj~Fq zUkTR0DAJkZAw7ScR;jA!vRpe2@|21SnqD`W9+Y};c$bmwDVG`C)zl)@7|qW?wveUy zBx;F2!H>P3|Kigr_iAJvwjXa&hi#AbKfLrlY*X@&%uNWCsZUnjUtj9${7)fkUeYC} zh)@3mKuCEGD_?SRv)-|nFf5bsyRYgE>*FWJ8S-0g*wOs1W-h85Ud-kBPuGU+s%=7n zRkIDA`_}%<@pS`v8&A-UWi2q@2N}&6G3L}ZePlF8c~KJlrbgZf>(RJX?EFBvovfB- z7=CuxSd^8!cr%urmuoEBtjJTZ+3s!ZlDyu=9-Vm`SsHhXO`vhtZr;z%fj>3w{6s!0 zTe@SlLETmi>bfwfYxk`rNmd62b*tjP=jn}|cRy^w=d*`lXOcJDs4=%TZ0#o+;pRsr z*;uwI(%KW*b)0e6!IZ1qf(hNbY^LChp=QvtzH*&6xsBLLrJjKY5HLM1PSp%)drs#k zNg`tn_#|m8oG47NM%7T#O{L17bkT20AE5rVO{G8O!IANUQrTYKCAo27B^WVAhBfAd zT!Qfu5LEv34ofCS=J=0#+1@ckWD*Mf0ENEdM^jQ}OQGNYKAx_CeeKD-Req|uRdabg zKbgZ#)gWJ<DdbBmh-#*(W)+*%pjN1Cb8g<Ex`Fj=b%U^0koj35=sZ!cVzDHy1cHkr zyNZp7U=nX^!rjKQjunF?N8Jjc%oAs?P^8J}E7(jqiEpbTF;TXnP<|b?Vt_mj(~;>9 zUO^K%iGeGSYvd&Il`CoG7M6{WL4q+_w-sPN34)Nh{0dOk=Cr7FqXq%iK<P56f6b!0 z!Gh(n+XGgYO;dtqMR;R&6zM53B4U(bEW55isMPYN(gyj-Q||eZ=XCoi*Bi<2YWpcc z-Q{<Q{VcMdIrg)g5lMQN{p_%xE%tMX{e0MdF6Id-SCf-dlw)~%kg}Mqm?-`m6AFaM zU-D3PonjIrsGVntfHx4+>q`i~ni_ML`7i5b@^XIs@Kx{<?ia|og+`o8<{WvMF2$fE zXG(pu>iIIC1d30!X8uEk8%nm<i`Ds^4^V->_2UvT*kIimO?UA@=RAj;DpT_u`Q|La z0UVcl%{9=7)l<rv8~wcIvAwanUq*TkGa~;Z9f|$Cv`L=kt2IPC|27`Of!J-OK5QZg z4`7Xbkl#>HZ9ns{$5q>+*F&04KYi8`KF9B(cs4d^dII@v_ICUy8CRg(VK0N+;t$bb z`tqFWi|RvWUsmtP?91P1O!_h=-Irxl=Jci1`7HJ@DM(F2?##g0#l@=Wc$u`?xTk@V zvl;Ss>$Yx>I&61v$|TyHq-Q1R{Ovkv2B%Bn&+xvv(-iN!j)x9I_}uZi5a^^>m#dVv zRLXCil#M#&>QqY9NqJJI%t)o&q*6F@?xNRaK=3%8&fmqZ_dk*5{5k1+dwN~v+<AO_ z7wBBY-_87;$KOc)iut>aKX+bvpUqzbe_8(N#jN5q*V(+7)d3)r{^y3>Ht~)XH=ps4 z&x}pwW59T9S0H-q6`lQZykbI=<H!sA(GjJ>Wn5}39ba6zt_+F%9{)=p`=S>X_^Vz9 zxe09&Jq0Axe`4&c(=l+KWIR6V^zf<vXkMuV3p^`r>Cj5B!k)a@e~xtJhJO#4U>OIa z75Rl#Fhsbc)rp_Wx6AlpmkmP`Khr>OCdEda?vJc4m=wM3bd7+TWrYM{f047o7mLX+ z;SHPT%UF=nnR|lG$?!$->-jAbvvfR?XtSV@K=eK-iWr_X>o>nZ_8f>lGo9S$aqsga zv$SQB8EPq*XkOj|7oDr?Gn$SdgFjkV6pZ2wKBie9r-e`fb8N6`PC;n0zpbu>ipfQs znaG%&&}BY4?$-g6y?>_wZ8tYajz~}8>>0l7{sgO58O>tvkeH$LgHbgmzd4>tGOG^% zR;nhN!Ci!I>G3S5P6+|lU0eCCtBE<k2;w*qQ==xfi&n|1Mh>EpfT;$Jgchi+ZT=Dc z^Q@Fk`msA)B6F*bB|bDDiZ_~`VfDm2$>5LOj<D=0fwv8uW<^kHvld@8Ci8}MOREHz z$(vm)bAGVhfSqa;$-GCOX^?(LpIXF&`4(puU-T)NBwzFwYJSaM%#x3>`yQ5$SloJ- zFX7F)Z4cN!l0?+gtTV(^VPkwdvbQhnXv|citJHbSX%C~ccogfYB``?KVI1Zw!CC_q zVuH5B7x|(P4b&b#8d|^krGMue%V|3&!DU*Kg;{GWMp5KBH#YE8b=mhWPiU;fo-=D_ z`J)q1j9$_cL{JVFJd}~=V)ATm_9ibVNIb9QSIBOj_D2tZ_k}r834f-|f_VjrqvR=q z!gtVN481Jn7Gh2P1FOLcBXe#nZ!Q<XJ->vR^LZ?hd+vN&34~MYdtz+h8C-<p2@PSG zvy@zUbS|Mfi^K16xC=VS5HKPtJQFWML<QEkV-&I^rsPr1JjDjp;>Sv!i+N~q;`K+1 zBGbvhk^3~~D~e19Uwox}?>c~}i}x1s?VX-ih7=9Y$ok9)4YYT>B}7+muE0&+Z@_(# zXkwjY3`ETi9x7J1zv#T!P`@v-yI}4~lVU?R`;)Eyot?7Z&WnvG@JGJzglYojBFQgF zku!6Hu?vdB+Y*wygV=aTb)`i8;#B^jedVWx!r3YS9y5A@p3%7ZdllJDcT?PP1QEyu zR8X^svSQ9{eevn;jP|IO<Sz6)T7c(C{2-)@;;(cw_e$l*LkEdBQWigh?<Zm?3>6fm zNz^)pb8x<^WAC=2V)H9p&nVg5n~lhNfsdzSPJxK=TjU4fR(!@Y>vnGTwP7*9s(a}Z zVW?Ty7&PqhCELOUelr;tF2;w4llSjJ(guXKc|o;>6dlWo=nci9@vZu|ao1?s$?VxV zm#g&4P^3!{O6Pqf&p<4%T1cCRcMBzVlCrW1m|eb|Ta5-~th55bs{D5cnqVW+kLsL_ zA|7JasNb<y^8Hm`h7SvxA7iGB=P|Ob(HSHyLr@iq)P3hxzu7kHW#0-cy;Z&bs!j9S zq;qpl^*$?oQ?Ut!v}yS*0AOSP!Ovh^{T1B;UH)j7Cnqt6x|Owq>h!i*<LTzSb96=S zjs~f3G4)ARV%Km1Z3`@9fd|a`BA<B!TGVsmVn<5{<0ngcY|wjz0AWAw;jyxWtkxSx zs$C0>ihV*&X$9YaWqz0pLb#StX2r!)X3#eEAfKj<-Z@GNVt?cKD<MQOHxdJIv<z{e z$X5<y6|7P94HM!}v>hLzaamh8nhV}U*AitZokx`J33>_%qjx;==?cLCQ;nht*jAla zf}W$)hZ?Gsr6`?*q^=;E7zApWWx&?37%8BsbEBxgQH0G!(ZwZ3`HxE*Xw)bVl+H5B zp~uC;d@91b3LQNSlD)zxqFSR!H86>m#09Cpa*{@>J2MCGUYeP1O@*qpnHy@9sBY>1 z<bH}SzNU#JZB&kh58V<w5Ra097oAU+rnICqKy6+%=Cxk1Yh=NrIZEO1u=NoPo>-1a zl}ICh$eMoC6CPmI!WxMGHdaS*<g-@UqS}BN^f6P9FfBBs0vyZaBXkvPC6oAoPU_*4 zeBqOdqlGPF{y(AoDOJtu(K?sX!wb(sZhJ>z((S%kORi0dal6Vja;$^7x8KTH{$18p z27RRb8(h|C)*p|Mg_4QiUFo9Mv))IMMpp*PB8`ZpSk`&q%5Pn|@A`;<|A4OTSrIJh z+FbNoul^mN>T_n4me9Z2{_B@a5!kkitb4V!>PwjdrEkDSp;C;p91<ZbzI^AeXqZjl z@?Re$HBpWDuivaHa@q1MKU8fc)rAcDJNusObWE#Q7&nBoucTHkI%{X%xhT%GM2?3& z0Fj}XM_V5%uFr4sQ>6JSh%LdZtl<f!Fgm4EG(jh#d+(|-Eo8q$|7;3)x{?IwUQl#Q zXtjz$lSv;iU0uYxG@5=WO9hU<yxq7{L@hqgCahZ%KSE*;&Wwu{196osD}g{A3x+1K zuSTfRu)sJbJk=koRq|!@ze#_zb^tkhJ9pEsp3oo(4k&73>z;=*1kAKy-NC2$VN_gO z`B9=@(EPW+Afm#3rnPm_A?!^o(B94qWj?t-%w9q@G6W~yTZTRopOeUf9@&-R=RAO0 zeR|Ug`_d;;9w~G$dE^yO+w#b(dFiXhoP{jfxA|-3?@a!by?CZpKnBAm?E>i7`)DhH zq6-AQbbww!F||w3TU;h%MTbcsrX|+rsGpecE@ZAn%sE@_Hc2*WS0$#w_pk~sHa8Oo z7{V_c@M&8SdXKG$4)fQSjb1o)8`fa!^M^9#Mlk(5e4^^en)#?zviF}8KR~3cU6uuN zu7E*KTYsXqp^DVkhc#RAO52)kBri@udjm_s{fS@k;|l~lcKnJn+GK018l*huV5tDN zad!j%&M_8URBGEjs$hI(N8|1sP~@D$Tdn>BTNaVKVcXb-^$p}Z*1KGAXyR(JAflR6 z)@ltL*d<xa4sw@{9oWE+V^jH$^DYOQ<|IyQwGJvBFtFRnInc@JE_Ph1*zr1gfdsKD zwXR|ND=5ghME{XEF|Lf2aZ%}HIS8xeAgo|<JbS)9dgZZfy@LCn)G$-UHwU{F{vQKD zJuuWDP~(qs=DPMp=I9j_fnINN1_=J~;}i(&m82iQA}+_F^RW;A4W+5|7g$~hYC-!q z+GfmGrMA?i>VTFw$zOkKJ@{a+t+j|x7@Ty0Vk{w8p#PM2dSCv-eOZHcF17d1+v=s3 ziohr)@&@-!EB5%o4F>YH{@&%)fFVARw%zoPD_*>vMNHU;7yr)BR7S_XTTIMtCp}!C z3)3}PE6M1K4p!u-P2qBAUlIQ`-!uGaGu;@B^01I9wjBfkRrCCW*}=Yeox^af;$VQ` z_?It9;D?@ETX<rO-)4R9UP1hL0tcJl4GG09#CEGyg*4n~22~=G_`u)#L4O>bL@<RY zh=}tl2$A*WPt_!ci{o?2r(lv8D52Md2$xuM7>9N;-Cd&52zMHne6GA5ukJ`xsq?}g zo8a*#(NS`Y0#&2@)FIH_LyCYcUAk>Zv3dEBk{Vvvg~UHku7Y?62@}BigE=L>F;hCj z&)^N$Eev;MK1Ilc{alB*UnU+w8!9)pEWwhF`JC25>JneoYjdk<Zn-okk~pm7-^SYA zo-IFogpV<a2m;mliBkDWnQ4)wjYPl_Z{`Qyjmr~5yw6I4UI<n{3au#Nw_<OscOOu2 z35^wy9^f~g0TXQ>i>^V6tQ^Zf<?90ym1AmwMCC9i7aL_vp!Si_A_e8stc5EgWLePd zs{XzrA(5<&VKJkyr=n4PQ{+kZ`J%LPwi7n^PI3Q6c}V%MF0tD4K=)<x%Qhyl@0n2Y zvNS!=XL*U-7@hL4^)9l~zUpw%6MdJ5Di~ASF=r4{(n(ES*2=xqr1u|=0_LjLZG$RT zdCd-Qt2M-1*@3D7YmA!87Smhg-iuNqi++UGclj+n&H7YAwIga@5XY;HUL9K{$xYCu zmuY&2I9-w^#$vxDcOZHrwn6V1k>B$p*!)rGq(Jlxf9rew6NX;Tk+s#>__c(FBf1S5 zkDn9zNY>^*zkrv0N8~Zl{H^P$ud2;x`n9TWUO^Cg`6s^USlL^N5n1$Qq>cL4vYBSf z?oD~Q*|Og*kpmKlb(eMUzi9#gSsG$1JKenVJ5nl|AC@*{OO9vA&b1^MZYUe6I!u!4 zO4im@P_mmfpgf9Qh6!TdWJSK9BD~bFTrH@4U5vw3&>xIgF@@<L^mO>2c4Xj*gVXCz z-+QnsgfQ<?T#{c8eO$Tj1Ya>1!33fe;uDj#UIWovF?v0>C}=$Pg8!wsziRWG+x=V+ zb6)hS!9_tP4-5Bq&x>6(xFBfMzUMbbl%8u|KDfx&Hoh2Wf^EJKLG_BnUB2j*?5zCI zItCscix9BC&+`TP@+!<^6A+TX46l)D7euvW^(}$ut7~hM9;-zrZ6mKDA{a9f-ojjG zU56<tJMT#%m&gA`Jz4#Ct#`M-<h2zI3z9i1BvH53vup2KbR75wEpP9qWKXhwqxmN> zbyxeM1CO1`_<Yg4R$r_^PGG&#_nW@+yXd=1Fxt22yZ_8ytSW6U)?cQdr4@4Q#Sj=k zZi#RL2T0@z)%3M*d$ES`OvC=!i@k?HTKIkZpv-evqEm%&Tzp`fPZU_me<F_Lh{o>1 zk6a*iOkaJkeN0Q@0AKRh4-vC!`ViihxHFPHdF;!4)%7_4x{l#^36%)E)BLai)!~Pq zKsK>|{BZj{)RV;zOHDREe2uEe#ScG9#A188gr4<@rMnVS)(NPq5lJmn9YKO4Bz(1= z0AODt`fbSDOGrjyHI;`WGi$YW*c6^z1vKnxl_aOG$W$V0eDQ-xR`4W#*(>QN{qYkx zEF9qQRP^6e!K#x*tipy!!ivdW<fp|W2mfS2v$7US<Tngh*9x93%J{>p^dZ)7Uj=Q6 zz1nFo&8~Cq7k6t=aY(P~BLd^v>SAI5C5Bp0Z9p|j^rdZ_Ve501ia}P1VxS0#B@OFy z`SL=6Wg0(a@>i2Ng?gUwSoQQ+(a%)i8mz!W<{ud|F(s|fJ4NFi8lc!ZBq9}b!m*W; z$&{i(?=c}8m6{(22pCSHH|%6${rHMh+->U#T@%3}NEIVzql~;_8OrE}S+Bg{s#t7F z8K4~)h=7?H@;7(?W@hzovAY^q|DZxrm#?_GHOe|sS8yP`8iip4eHpIeL8JyrU+4;; zXVc5c;oQQKhMBz|iIL9+^K8-VVEpADIaIUsw`ohL(3-;{1DN>=a4hL}>SWF4Up@iJ z>~NZ}?m-+33Lt-ji0B7GHCyLo75b|#bbPANG*u|woxbjSG?s!=2c01YqZ9FE1xDye z>u741MQJoeWx_HRW*#FD0`X!rU+(qwC6+99h<bJBBeE^ElH~r!S+K$@Fc3~!?JxJe z-2eK+uUhV?Wm)cP*Y&mBov4eh<^FxT!*bu-dglZV_F(QIp&Oj_o<)Bs`p=P1IQi?` z`4?~D*C>W1cJn3txxnrCLuN^AV#9u3E9X&|u!C}ziGXCsQ@{lAhX|yGAHcULG40qb zN(9fdjC{)eL<9sBSjhv;rTjwkXWjKrienuiNF?Bbz-2KF(%E7OnSCMT)FQzkLUziz zFeJ4=r9UTA5MZBVeWx8@x4|NSTQ;$2`^ub8X0;Q<h#DCW6uii8rn#5K);v8I0^pQ> z(Z)Z@e-PpnJ3Ebmgr1fe5n8Mdd66r>NQ~~!$h|-CFRgLlKR|=in*C%N{`WH}UlaZV z{?Rx5UyuHW@PC4W3jVLI{c89(lliOQ|6l#S2K=vr+}(fp56{T$hQHEBwxrn-MCowV z=|hF9rb^v6_<im<4B<s)dR~i_>wJlNTCI`J4;qsCe(B2JJS3y|20Pwfs)Vu3JD31` zMfE3m52!!k{DG+iyVKxlVz{n1mWjP&4pY~<wZzx@uOeULHubZx1CuycA?nMx4~O4* z)ZgF9l69SDU-*|J!tAguttbBn5+T#fmI%qd5qwL6nnQL_roP36&-#$3wsRo~+pyc( z#EXL#Q}FRXq8Eho<0oTSxLV&|Cg=Oon$npyxQ0&$RgGdxv43#FCHfNP#aMTCcngX7 zBR2qoP)p2JwPuI)T8BFFGLF{|S5s0OapsC;efIGxJ(u&^;3~AQ+up1`+Pm#5+SB~A zV%-}*Tq47=y^oPMLCn+^3&p4Co6q^Oq^-6^#%@dFQ^dp+Zm0-$+5TpqY*NGiE|$Af zmUv?mxq!ql?%K%t8=dxK4Oc>#ovl{U4um($pU8s*c%EZ3IAg@3pl7vl2__!z7-fT+ z$Fi3%YUh$vBKw%_#zpxv_(C!6r8i$N%DUqqjU4NtRhiI~uzCpXy7;I0b#e8rY<Z%e zy2AAFqwt9=m^auzV;$u1+-j;{I&g?lcG`ierEXdn!rK!bqpUsged}0QIPE52H2;a( z#34YDc(q*s<zv1u|K~y7A<+0ILlbuSaXuoKdY^HJKQ@+4>keWM)B0hFAKP@+lmtf? z-|^QV+H1?-uPOh6&gC*<<Kpd$F3!WEG#^9Vx&5&)HkQ3qxC)mL<KVdi7fl+93qTi! zr^ATbyKPb3A=)+yf((gL2@)llHJ3z*u6CjD5O_Hn?Fr{7{$Q4R)OKlw_CcV_M3r?} zs~dz2FP2~JDmqXXJuRc?D}+6P>ZmcN3`fU09I-(M#ePN1ZC*QhokVsKCIG7*nGv2{ zJXl=hlq;IsYL(`msdz-P${F`-tdoQVOzEd=c~W(jJgdW+>XIN;yGGu(JS)3=mo*h^ z?#QzKlk&xTDeuD=^XL41!k$@gKjmHi&aj`(@9bxc{DOj<{h!7%DK=u1_27oy2<1VH zdiI4-Y`o??6#wApd+#_~rpea#Zh32e`CBWZk9?QD_cW;qmP6QfQ&r^RZ`+Zxr1)Em z9uAQ<30kOBN4EI<H`FO-N|rni4gB>myf){_&bqb;qyLYH9dF|1+%^u5HV{2IK)`*h z_~IB1=%1G&!~4`|TFCEU>{deYl5Q;R#~&U+A4%Eys=$k6P^#dOWXrX)UC7PG+s1ku z{{8mctN7f{{(LSs93yW)vQ=BS+1t?5J^Lb3iKwOOzOJ9X>zLz!Jnxa`MQ`Er-o}56 znQ{0OM{|xD1lW%C@1^HpDvU~U)Ro5_Uh{c|kT{21j=hDgwdRYIO(vO=g%^T>y)nen zNf6)xgT!UQ+xVV%BzPNN6i)><;<ZJ!=7&^)WIj+%sKJ(g$oH|d=*fGQeBun)?ORSg z^50l)pRQU9ax|KjvN@}{ecFSq%!t!5kK{~J(!l&X)fD5cLJl7u&ow3@9|=O8-qgX^ z4gIt{H8#z{D^JNs$yhocJ16ll@|vG9S?`7p#{z210xSHEnxIVngNquCCcy>F%>e#z z0C{&l)?#gTnaAQ{WQ8|HWUJgdeO~(3X$j?diN1Au8@EocS5tB!dA`>#vUNb~)`Qe+ z$+gq}kejFVwbMq^ZhM0NGF0`HZ8BylRAa+x}AuO@7%Zrf=7wj>2f>esq;AT5~x zkh`Z<sdAFMu^*r}Wme(`G_KRr@~)ni4Kgh?=KItoBR87gWBV)k1WhYgjzhJTE7!ql zU@!j{h!gdBT>PJS!3|B=Brk?NwU#jiH%Qr{K8@*Y?_TR~(=@tN(^U_a6`PZ4wsQ)9 zX2>V2sndeD>9%gMc?pSilC~Of<A?pxCtp=1Xxr8&fADBp-Uxyz!Ca)__TronLVu!o z-`u9K)~K(H<o)m+nw}$)Hw^o#)0Kc=%o&b=;HG#QjX2#^@)`{F<bLGIeshbzeEn=3 zJJ-)U2m~Vm6+{eTeSk1mjuv80uD8~!A5I0n<*m0K`Qp#pf8DAnTHo@@XD<kc*FSlU z^ZQxP$8WB?{~ntLkLKV0WN&%xd={0?AI-m_kM!xObR}CVP>%M|>f+w_LEH8=M91R- z7UE^Tfn6|G3`0bmtt|6EvGGIxDktrBYZHk&fh>ql1pmf=Mxr8WdA|YMWM`!M>D<pr z{7_<aAKA3;^mEMYbkPq_y*B+d-CtbV=<le$`g{DJb$>_p)!#po==ArBW$BuAf91U5 zEc{=vPmp~(@BfE=Lg6$=InNOO5B9(6|9Jm@dZ`QkI?_{xLr&QyE`u>$83nn@349m- zq%2$xb1Ym&rA$vwd{z$Z#0>lcWdR-U7`TjbTdJIx%6^hMZxg4c?ORkv$G+u6cd3(7 zrM@i@c{l?wu@f87D~o*PojxM!9;@s{J+CUxQZ9p70k7fneCji=EK*Wwi4A}p3fw?| z-EQml4@jnXqRrX$tiPE`U$74g5$t15v9Y<fk6AW5WgN19<^P&le%{wDzcI7?8DF=2 zR{wY2l<I%{+&eS%8FKw`ranW|E%0$cr1jXC;xk;7qoSU{%HV<OEkXL&aC0$~QLrb# zjqzd%+8=5RStLhw!~Ei02->KanaNcqz5<&IerY}~W1ZmSsh9PZ?@1@b>sIL_Ebji) z7?7Mo|8ssKvqZbbnqXC+J)W#XqsfA`uBBqpE?um2yZteOR-`1)V)4#Ks8GVYmZqZe z<v(05Plac%8!bQRkv?B@_4#@)@gy}v*ouFcaiFWEA{09g-R`U>eabn%Hf(^gEksyy zH6nbKWdHuH^V^qnOTWN}(EkV8nJS!2>FPG@HD03%pjurZUiraptc}?z`a0zy`a0!8 z2F7j5m*WZ~rwO4NwSHgGLkg&=`;_hD*N)eC3%!sMI$mSaKU&m<wz)DY!#^R_b@h)g zce}sX`VVH_Z_j-E)wz!HgL0gg_Gq6NCLmJ!Gz7seD}`?=AG?P3G6Dw5#V8^ln@oa? zO!Nj{M?N-_o+|m+9lWTcnF?$e*w*h{3sS0t^=e7Q@{ff|6KTVIUt3dY10Q9nigbS_ zPYA{QK!s#zDqW<$Yx8xTL>?*0cF6zs4MHcN65#!vQ+16#sb#WenrfVoB$AzcQzdP> zY6?=cM6l#&>$US~kUc6+%*reH#d6mo*89uc*t8|gO3KgwBjy9GUD)ThsPIIx4z6I1 zpF+Z6mAogkSJ+yMn?Yim20-8XuJ`f#*APnjOZ56FR-=ow7E#;xsLh67{7rn??00#% z_rv0Y9V#-NK`@Wt7p3)fud+G1$@pbkGVq%(nQ0><yo0Fb*mmg56_z?sW2ktg)X>*@ zB=0n2#NSA0`w#4&`&^VylaOAN%#`peGAn`)D>V0m6OA1mQ}(viiLZ`YkDu_8y&gf8 zAj88D2Rin4gV}TT5GT=?vvM^|?ag?s?f$cY**P@nnvuTXp@DztH-g6+%zOHT$Dc^} zn(%1H9bUoXZC<kAVbkMG;mHzWTW0@)B9Ua4Z<>9)b5_W;=~!BL+R?fb-piV{R`%WP zMXY|2;2@K2R@=4J`o$+%M}RD(zT`LW-lQSj7yNoJ!I>#dT;c*&<u`)twY1zPWX~tT zfozt4#lF|uOb%3y|9HuQuZ{n(%P4K!)xaK~GjP!X%Elr78-5XfqJVEB%yvyl<~D2{ z+pw--(L|4mS`e2K<N-a-87;`GOr$e7Pvsg5MOY=p#C|$gl~*>=<2+6kxjJ3~(lE*i zy-2yd*%wGwZA-06X-adP$5lhB6a7@E1!4ftD?o1i09C+f=Wjj%Mq3s_i}lx!WV!<y z1=~oL!z%wc#lY2wEeZn{dJ@6hpzeoc+1R(VqqI=hsf*_k{x;N^aULis6dkwE12B2^ zX`ph%hP@yqX=SE$x0SW_6uuPu8042>WD7zAoG**kx0={n1-7wwzUN%sHs`^hzl>6n z@0ZnsgGEz1hkTf-S@_xcccc-3LPY;t_Tc~DSkB)C?S+bdT<ll=m+aa9zx99Zr2pIf zAD#_=>ms6~*mgtd!<;vJeyppu+wLODiYT3h^qG+V`{33ztu*Yq<Mci$(=1!w)hU)I zU72og|LQw8v%V*<`iAvgcWg%guKK3+ots(T&~I8_G_$@n*s=?%pP5N6Y)HkYQ@&^~ zscVr3NCde+c{j1lHHS{@UYh|w6oI(kgMIxx&7UhFtK!h{s}&CY4Q!62xWl0f{;~XN z5>9^0eQeGo_G%x_kc%Fp`{;w*eY?*-Om+1^+M7Dj)n4i*5Eb8PG(>cLjd91HRX`ef z`%P(){q5(aLgmZ1AD4D>mdM)=O1td0rqT|1Gw%3%X^Vb&vUCYA0aIeU`OOVTY3Ga! zV3Tbu%_|MYCMErmJ-OlYkP;6u?i4nG5JL6F4g5`S*<s9Tp{`loIphwMdbAyP{J&`5 zXucJNs&*-s$jHCIMZ3AB+W2u>{3;S~OTZB@63;^gvN>qB`?;A>A~Qr5&_d8`3vypk zB$tfi(FdOuBo5r@*3fJI*u{pA3uPAmi(LMy&yBl=lLc{oz}zN{j8=^pP2bArYjQOK z=^g$mQ1yAWac`S(=LeFMDlmWoIwOq6>+$s@225q2uk1NRcoQ_YTF)Yn6^q&F&>xb3 zy@AhYl8b45(Vwe8PfF0OU3;<EMx8-gfHVQvq}ae>e{vl*)kdUVnvczbkp6pV18IS1 zsB~t4`sU+c5rF8fAi93QysdO}(EK0&&Nt(YuvmRU9P_#CY3RYrpI9T8(?bS9be*e8 zCkHtGE94)X9qYy-yfPwJGCe4X?(oM(jr2vHuc*Xt@m;0<N!v$#I?lK;@0d^Pj2o{y zrbr$a9aAEYnqw;JjnG<24jkJdU#>s4OCFaW+bxg4v8;#Crh4P`cGlf1t=#1izJa&U z`|{5x^|i+9AM(#D&r6K3@GSZGvi$S5q`W36t5r%!KBC@|x=3l4lvb58|J+#KC_na> zYAix5nLVXkgESG%kGhYoy5R$E#$=jU6cU&5@y(u`>Vmd7TzAqBD_WGwAgTA-sbc0Y zsU;byVLMfBkCN1ijMPhXs=GsX-bl_wJ^-yu^8Gkeeg@5W8@95%yXVZTZCV$efn&kQ ziLp^*0-{9K`Z*ik3akRbwY{KtxK!t=>Ih&^M0KGxiGy%LWw2t7w+34ivn}zG?}U)B z>v>$!(9-=W^L9!%muuZPa6n&m8_gb8nG7x7&Wqo(y7F}v?U8E5KFOClHX-3e9@#YK z9e>qZe)CnXgV;z2i9-YCi?)An)$?<X=emd!{8g_QkxE(pu>~Hqe%#D`X6d&A=D$O4 z1U-qM=ZnN6L38`!K-CLIB*H>e8>7{TTu2duSsd!G+G0d5;0GIjRKd72M-2(R6zF$3 zgNa^VI@;;gopP5^9Dn7UhTBSS0oe@ZRcwLg%SN23+$1id_5e|67S{4IuHh_Ci$R=O zM9T}v8({z0dvmn2H`kNsi%m@iqED*5=}Ya+fcfLnM`gFh>XU)ks7kMnEmOWj@7UPT z3V#x}BE%eiPj{l&?`aE~U(naXE0aO<Z3V^~sa%0EXgsoU&YR3tz$9^%9gl_3K!g2N ztLGdah>bYMU-gm^Axe{A)o=Nes{*krJp}6To_YP*pr^M(TN00)7aPb;&Y%gw9TgJa zdbcNZy1#0T5rJR;H-c-B)JQzWk<{QzZt};jN!Fb?qR?-~Lz@Hr{;mcTzX&*1FZ0CZ zP#}JFHw((R5AH*uza3T>xwgp#6>rDiLhEfbk7E@6s*Z3GWtwnO6OZfoJ^aJaM#yx( zKm|94Y6;L2**0>Vu{7lIMBYbfzpHEZx#S6Wa&fj1Wxcm>ySL$s?%7_xUhe5f_5tYe z57K)2chJ+nP+Ry?t@&yKh~y7HQdpr~oYmHhH-$$~D*wVAwdUr86dQ=@U-c+_pagdn z)&3QgNwdc&(}$Z;rcb*XqfDQFyyzp57kx_dq7P19^jXS_K3?I;<h;!Yy|J7R==l|^ zIr~UuF(EA%5bvu<b-|OPF820CI@wPxp|PyQxuex8TyP4E*!5T#2qRYFM>#jPOU4xR zyb!2*EnrM|jS-)9gpBxAEA)mWg<k~dM$-vQ7BI~d(3?l{<E*auAw2w^oq?*|l-y0p zTvc+Hb*3uGheGvXUE)aIhpG3?))6Yvzf+oub8(E^NMWwB`a5MlQs35D|MR-dktzM8 z&Df!!T=2a#Yo<sdM}7zAS7M9YCzaVE_vu_lmZ@YGiFe8Z8R`x<%Q0jULQh{84L!aq z89D^1kiQ^Yw6Y?VKYlRzpas+Ic@dtqgbrUTXYs{E5?11VLb#|IvfiDZ-FCVzRJFS8 z=g8!0TLvWc<i~$Uf+jpw%thVh_+q}gBpdMte%tyi6?`PJ`;K|so=O1qF~h^$$hF;? z#7<NnqICt;i_Sv!xQfuiMe$XP3+7wdEt);tkiq(yb3{tn1x6lA0LO;vMYoln_#AcQ zB(7;>zR`DmE3NP9A;0aWeWJU>NzZ{ra}sAbVhC|2Aa7db<tliRyWqEVpz0_wiV1on z8n2$&T;w2<DM#bgW3~MalE_2AF?HjRt?$z0c8~SL4J1-HvCg5FHGE1$;$?0GJ%`R0 zf-`b+QBLSMzwMBFgg**)>J(Sdv#(Ujl<-KzUj@=e;zSA6f^b4qYSx}Bw62ACHFYH4 z4pE;#6;D=M>!K!Ke3DsES`|l(iI#9j;xW5JN**_rc`%xO1eE9$6gTH(p|6UF_Y*pZ zc$5{dn;_l);!1`ew-DKAY|zsp61PJYR3NUD*jxKuscGsnPPh07@2B6@_s7V-%ksM_ z#(TjLnY;Qgno`w&sGfm%IBur@n<Zk?bF3yYG2-Ty9{<h`j9bRaR_UwLg3bDL784i5 z>izHcQ)l+k@9DS*IQ>qo2N>$f1RgV*#Aq{`-*S(#-Wck5+pY3N8yckhv7roUJwsX# zO32sxSY!Nl6+)dWKH_7vOPs`B%)=#4g-|~wI%t;E7qGqexG;*a#^xfaueFOnp`w&f z{5qSjLZGC_E~tSP1DvY-Q)0<Ql`>(YS<D=Wp~Dp6?^BD5oDJOQ6+V$AHu;Lx(fmDk zXOF;Kq*^qWG)T278)$_nIzOrsfLK0E_Z_%o;n!)|_*FcKFTMocPvl4<K;}Z^Ww#Xh z+qe@7f)gFWgaT~5&SFWUcfOL_?V+{hY6)D-={<XQ%wYH;=GhnXV!4D1>e3+)2fJ&D z{A~V^Of?dAdt@Ny#on&2Ks2n_baiobC*Pj?oj}Zwz1<}Fd^5IPT^!*ba7MQ^?Cv)1 zl+wP~`M?#^*rooI#oY(}Ip=E%cNKDF^Cs>b62vw4xWr9j4~6ct2(T9`BfA#Dh-dL1 zl^-c}`<RhN^HCHGa5KdTbwo64>Bsc|c*9${^^t#j{BpWRTF?P2v~UR)O>v2^sf_iA zvZ<T=n>WTDaa-wqpv}QH*;abD7uA^mmQd!R;g=@=N*#$PQ&y%9eYvU3S-AF-d6>%S z<hflOr>3sPmj`AYDC8e_m_FE*7+J_orEV+ZDXDJ`)u~#0raulVkRmL&GVAo0oE4$= z_k29G^45Bb#Pq#TB&#<O@qJ-k*;z?^DI;s<i;Y2KEpo;DVLwuS#&~C`GmR8Xn0(Pe zS2y#WqcrRn>2w9~fb-11Qohn)h4SUmA^egZ;Kws%orA_&B%`|1vy`k-Yg=+yr5G^) z=xF}&Qr_I*6pYUzH`{5HFDC!+CbH>o-7DFZY&!oWblURnQVh}^pB}%GIYYEd4`(TW z#fF_N1?ZvAI%bOkiJbQp5G$V*O9C9acg2AMQV!RfE|Z3~TR%Nli;9#poM>3uyjt1E zs^GuO8AQLd`CS(cv(Ni2tdD0(QxciLXcEzbm|S-6nN$|4)$l(e78Cft9=gyMJA24! zxp+qD3vN>WMw%Rv*^xUd1iZ<YmUy@&cFF1CcTj3rYKrr%(w#zzG_Gl&6)^-v!^<>2 z6tSnVPAs;iFthMe`G|#f_9WI*U6*?fr<2j1!|$Uy)pK|qA2B#h&tmn$bDVw{O{gG~ zcF^=e#{qI6e<zQXSI{l11RgVSK9}BNHvXAU8=0SVw^Xc*%)LrOO!NmX0MYBe_Wu$0 zCV){@*W>?8U?42v1!XiY=xAe2+(=vrf@UBCGdcrtLD7QJswl1qGk^;^A&F!<j?%?% zt<{QtYinCu(<&ILOF}RSxCOL|Vr#^zZycAP77|eA_c`~z*^*GT?f3sjC-1$x-*eAB z_uO;OId>J=Xsc2(ZzfzkMe*%CPm;=QDU&F20DHNVl+9)7nw!pd*oB}_NnJ{x(z>4` z6;D~Fc^Cjv+?)kJHDi_jvM?bvA3dz<exx`o&vuWCxt@%??u)!+4!vB4Ru8i@onbDN zVK(Z1C|^u9f7JP4bPx^*HV5ZDDR)PR%Z;7y=n-9T3bSMW27Qr4{CLjs79KHwL*--x zX;<mX#$C8C9SL75!^c^V-<aHjlR}R%r2|O3b-dUJE3ibiyOW#Cn{OKuA0xF!$F4%q zgip<6C_r=bB|D@43ki$`^81XwQGbBSGzV5FJ&VU)MB<>KTzI^ZbYAhUxH#Ue?hV)N zNAefJ6DRHhUjrn~_evENJx%36$bUfhLf9_RUA{z#>^8|bccFD-(wgo|H4uAvNOQW> zH3~EC#ZK01+|umbiKb2RK40zM%PoidvT7QWJIKC@PP`u$B*aE#l~TDCijwRE5#dq} zsthOXA$+trT1b?RX5XCb1WyaC`SQi*dcMe@s_}MT%#4W@T<=s!`yvmGv{!LQmmuxI zpdkwK$}(cb9ciS!y&O#Bo^|^4bx8YwBo(A>ph%E5OP@ur(v}v{@4~dnyyWkKu`4tB zznT-~R9(eWP@#F<-!#T*skHRq1y<>zY>H*kCt;cp8dcNGw8t4y@Wh8lWM)^JXQ%y1 z7qx1e>kgPPOfwnWJ`s;f1TcodY%%|Q4ug#iHz<9Pw_PqN0R<*&GmyxQoKY|2LMX@W z4TEy-BPS=^TktToNL)u`2=)ClTy2v}s1ojZeRYa@MP{1jX<S{1w^f>_M6aKjf#<(& zzAGIp)2!Mm*C_22_DL9dp@-S<&dmQStHaB7YWIa(%v;{>O9F(u$A<~qQw`P}dxn~i zmU3>Jvas^D*LO3sg)Dd@u`XT->5#pY0!@7<ufpULikoTm&)p;;N($hO)C*lG-zrko zk9{>gB3fHimKd9>UvJdDNzPRCXl^)v_!%h!(RTt5D7HYU=`a1%U(vp(*c*#U?f7^$ z7juMwBVhUTMpZ+s>J(AIO||=JTAhTnB>a&-Nb7L2<BvWhE%HY`2}C|+`Z#TWx5Mor zP1%-oeu+2*H|ebXqms@?`Cy5w{|!y^Ao<2wN<G+th4Ed))b`xS#gs$^>`7Ihuc93n z!#x3Z7rL9q@)JoMuaqWW$*^2>`f2^cs`hQBc>*%J!g~2M3S(kHjDuu>Z|Z_l7SJNE zeXC`F5{*f-WxIFiSuzyj)nCR*&>-z4CF$IS%pz@QqswFC*ESW+!1}GB#zY&`;0?rs zEMY%84r)+Bqs(iN^(CBeDfbd2K4j$-sM(zQlAz_k(AU><HmU~18@)?V!K`71%X%}g z;=aW%o+m`XE88^1=zUBh;HBY?+~J<QkZNv%J@&cmBozyW6mz@>?ePP=5$w2N-*HYr zp9X1rfA9C;{FuPo<dD(rkBzkZBF`uG#kV+@<88!4%PRq#N>ywOwgh6B%@}JAs@r<Q zN8#OF3*QRw{y21qME#m5Ngce;9lpta|B{o)jqk!Y6YJB(RK4jb-yEoT9*ezo0sEUG zuKSG#Co~ls327xHaknR$?}=6ps)|fKxGFNePit-Q0H}~ze^agvYd#X$Sk`<i<5SN! z-~(md0|s*S%EQY2&k|YCBC87}OH`H(sB|PIQ<R6oqR7+D>PyX1rezOb@{d<hy|gB4 zKCkjGce1(&<v=)6FRB}`ZCR7{=)^&3{S<_?M(u^PBsFD6F=bb&DT^Q@F^~BgDE%Z* z(S`?bDM?LRX@^YPXV=Q%;%fP1+DenCPb#*iQJbE&>}>G#`v+;K*b7BeLCjuB$?Ww< z5;A)yziG#-IrBj#usgCP>8vCq(ypiQM{npUyq%_U+q=J_)u@;Gm~?I?MonQMNOXsZ zmZBQS2#~sLNzY>0amA0~4~8kL(n>(*X&Ye$DD9K+E@@fn8c)@slztei2_De}5Sg2q zE&v&_#AbBBoJx?))cDafSCNccWUyl~nOJnsTs@9wbhUg!Ikw27w0@O5*4!u5AzB~j zZ=}A6nxgd|srQ3aqwbQ*Wl?jcb(*}<m^9ez^mE6+?!3@K$d6!^w4f@|txcizRhgWX z0b$iuUz8)z=u~`zu9n=Q=-R)l_hol=gn2DB<aG57^Lqp(jxtJA>#d4$G?E|HZI4N- zBU2BEOvl69$qihI7QIWMI6cVrkI-xGLqVDt$|UMT3_s=w8FDUnsmLu%kFl3$5L2)) z>bsd`ahr^6tYAGZS%j}IO%cUe&sjuq1wk32SiV88)v|!4_cIxOCN-&*rl7^ssA*|l z@!CLyu`j<gK>ief`{)~9@u6U3Oh9ek%zJ;L`wiO{jp?a)mraUl*)m{Jx$E`6?C)OM z+Z4~V_XXbjx7S)6c;xUSeKp}ZmG{Q3FDl1j>N4(0Kk3sEGIEpVGLd2Zx)Ve2uf<iS zK2FGR_Wy>jbdzygfe--HfydedtR<`;#M?V%@5dp^acIHduCH4qfVYyH6UG1TmbCxf z6@GgU{&z8LF66@DIdN=9bNN5HW>L1o>xhub<-(<#KrGAWu6YxSKRLgn)bBDrfrI<R zMIt2y8*-uWZG7lTYkTZQ{YjKyIpyuja>{GUti#D<_TB7rx>BTNgoy|DzVj_XkaSVn z7T*Ti3oY2!Tk*=mr9K1=2%l(o=_{er#AokW9JVVJSJqUITr>~c`--=;b>ZA}+TgK1 z7Ur~a<`%P=O%6-04%`U&H2+A5EFT=eW3gbu63oh(o=mpqhR8O9vz9l_H<@kd^u-*1 zQeiFT1{GkP2kr&mgew*}^qCpcKM+jASo<<w`lDH9zns=0vGyq1(g7HCn-~6dpsafk zfu0Za%K3@+nH0vx#WhdrL+}^&rZQy|thOc%m;<mU@#7O*IjPrslB#Jk63y^=VlEKj z>f=IBmoXY8jAr0fIj1!%Z3#*{x%(?BaiNY(Mf7$4%eukJKwzfc+utptYI#avk5ovD z0Zh3f?vOle+B43E0R5nmvXxub?N;|w$%<6$W2xo_09eEA%rX&LQKR#1-Ys9ZBzpE_ zSk72Mk4hl2<e2jxD#1{xKGGttt$!hD*j^1n)*HV~RyD3xiiGm1Rnp>vr^~H$PepX~ zN3Rs<cwH5!Yi!}2jWNax&?rjUZu(S-ZBZ_!J%n@D29H4&e^!<WI*XCXvY(Y@X1?@N z`ZuPA!eWkCR<=^!-A%gb+vV`3>m=QD?|AqM#7|s(S-;t+Yn683CC55h`=N)WM79H7 zSu1PX47ShR6upg8c>x<6Rla#aCDqYp1&Uzs=eSjq@G?<SDG{k(B}y?cYjj-oHRkvc z$#I-EpOo$<G<-<UoLOfs22P2I0?EpTP#2)QOUjCc7{C;i&QSyCI8jC5G6=wRpQ8IS zo}q}eV*I0ZY?+(=>@SpmpIMo`dAIr4iyF&hDswOF^UQ~RK`QZyUB@#u1^yNOiP5Nb zwF1(NprL7hSISq(*<3v#dmF)BsU$vk2JN*jNQdOPpx9Z_BG_&D&=r|EGBu`^w+euk zbpqSfLI{)?&V$g_(?!sO%cS=ZjhLgI6`xln<bYKI<epVLfM7;4#|+_n<|+Z)Z#+2& zFoHZ;2oS-IV0@>{D4Ij*Zi&8R<Vtm0J>UO>Nxkwm5Whtd#T-EiKsDYLzeWd~B>`ys z+v40&B`M0%S<ch}Mmk`E4oD2e&ll{8q<)ciot;x{33yZj3Zy*dwFIn`fKd{#Tk(~S zD<uHy8C(2A9T1QJRzq7H_E@r%OMr-$<07OaU_?606FT5M=(R56*E&Fmy1w@7E*<b| z2~gFdHzs8)Cm_B^zgJ7-cclW(cqDSD1dNw}^K`)990VL70l;5Utd@ZNCE!FIaJK}g zR)0qa+#&%u#<9is(E*o8z;Fq$>ww7;Agf-yn?DqKpaiHw-_`-$*iY$dU(x}aBtUiJ zX&vyG1St4Eq66-bfHAx)UoI3Hl7M^(_@PeWlYoPGPuxuOvGOG)Ca&enkS}RcVlH0^ z{GL3C&6f?+gP5a3zGR>hReU`vUot3(llh9KQzAukERZj0RN_Fs&QGUgdN@v&FRXV2 z>pPW{Ok=vxso&w3ncyB?pTG_%H7|fx_Pl_Cd77Cgf($@S&x<=zgXv316ua1$|LiC0 z>ozahkXdG-CwuT&B6p#k#BV*n4t{U&`;gymej}kbWBHZxo51f(ezW;q!|xV;ck)}s z?@#>J@q2~e+x)uu*`ZPU@cRzG6Zv`goyYHTeoOg9_}#<r_xzsX_aeWo{Nns}@^e7n zgx1M+P+Trd;&&!Lp?Mierwd)tfLt8KRiiKCc?hQ;DB-g6>{xh$H+p8i-!6JPqGS70 zPJ~2NC2~`tH-f1H7sjihLAGoO_c&)$0zyu#yG<X)4Y;K(Ogw4Tr*{geGtid;a{a?Y zln{u#thHCsM)S73hrh(~WOU>pxe21SxzJnjTxh$Go9;y+qqGybwy}Jr<U*g|YFUC@ z+=5nEz9Vs5_Wp)lpKkewfk>D6=8x@2y*>yiTbwqE{AZA(fU8f)uZk9*K-sFlU5iiw z+wPC-k{q}Ho*a~$SR-0wu0)=kwTOO#tY#ovw-Oj--%m+ivH3YiGRnd2_kncc`PBN- zm}{=tPybm!&mHR5?@j-i4*W~q<F|e%z|QDDmp5lipT*zk`7mFs=~=>Ozet{65>C|x zL$+nDa^Cn@4c(I~l+llso{HPPCRuFgPSSf=r&lpOYE7@`2z@^bC}}|hhiH>!YQpEL zn;+oeC+nLZc&o$?TN#)lA2L%r0K@!pVxJvAuNfyOF;w{?A8q-`tkz3@m5hM0Z<9`y zX@g&wmA-8CPK3`ac&0h(Ej?+=B)=Mxf$XVJ2w8-EUUqjoa=Uw8x{qgAeWX(QNdIJm zrgk}a8OiEn_U#r$efzlGbP&Y0P)XdyoHQ-3vie8&ppkpA-z(DH>o&*nqIM0b-lgmz z98gzAvu6-$Ofg5(b@CyOJB|ZM3HVJaz)G+5Dv)ow%wrjFRbmQ@R6{cHb0DWV@d}=B ziYUZFZM85^TU(<t6)kvxcHoRTr5-YJqc;}0Nze-%DvVAYpJXTcTfQSx$0u;)x;^Rq z2^2f(n6LBYIB{0_P;qGI{wFD-_Lf4>A=Djm!^uLKz&n%^6uQQy7nwikmUW^{?N>13 z#1J_&DrJY9bQV*MC6fhsz@!y%qqS=&Siw7N?A)EQr||UXdwY+EjX<?0R<MEP4;FSf z>+o9P2h5H?_ucQL?BOaE7J6B+Qp1!xz7pSUZpn&Q{HWZU21LtJ5Vh{@5xBDdngU#X zjNsnjIx;#1xCR$QrYM+laCkZ=>F65hJOjXVN`Ctk4O2XD;)RoCRyKKxn*TyLG6lw- zJ|KKYSvhutS=#9)p!p-~HlX>GhX&0b{-i*&*Y#B}JkVpl){?!rrf8=;g?`n16qfPM zY!A~%XabS(qCyibIOW>CL!>Y|O<~$d@Fp@%L8Uk8ET#QXNAen#Zvd!F%Wt1%L1kHY z&edR9_i(Ab5+ap$PbY1pk<J?hk#I~0=BzTGE(6V?Gdt54=bZFzk`Tl585ig55Ya}4 zwD>L3(q)lP$f!j=a|I}&v;bw4`84;l<p?ado4+H7qCu=a<5iBFLJJ@ToI(*9u`iJ- zGh&nAr1XgGe$+zdI_VD?()8Aq*<N*;#q0Hmxul$a@<p}iq|*;1`8XFDBW>(5ud;-V zx}cQ<)hBc0@n^H@%R&$>f6KVG({xB7h(B84tGyNH6ZO@MyPiW_pP?v)uYH=L6n`3S zzUgI&ja`feYIE>3F{MeiDGL?h;RDgjOXNa|OTE!S{?aagMfc)`zUT~>-~JBMLo8R8 zqG1rQe-VgWUXr*n5M4rYF3b`>h1)n??(oe+lEXO-M<aN1f*#8$o$%n2QkB__b-|K_ zitF~pW|Uc_?qCNXLWt?OO-vl54$)O@d;XUp<iG&_=MA$)7Z|$O4{uhwgZhf3SbwQ1 z^AMd&7_ts>B`P>0N!Pd-l}+h|XthX+KSvas5r`})K_io!xZkiMVp5@ax=P~he|@DE zi>Zq?Aej%dIZKhub9skk9{ZUhncbRXCe`c*%Rb>)11y^cL0$VDx^F)8N5QgO`Bvt> z3j{^7dKW&e$6S<DIXP6-elvPd6fHRN%6~}@T(a_vR`kG?80U@6C`>ww)(JuQWd2?W zLQ(rP7g^}^w;>2W{}M2z2*M-B2tcz5!e)Wue~lnKaza0X@N<Gv1i=;BC#_zEFNLJ@ zU{3h^5rq%FQo~iUhv8By-23ni+2^ad^IN=dj%m)CpZ^9usM>7NgYWSoi{;nQgMV1K zp^|0O0~nUd6g#5ViTVwp5yl$F@8%7%L58c_9QX5P$5+J_IT$jSTYj3njIL5f2v_rx z7{lJv#5(7Fj<c9|f|c6sLj=Kmr_6{ss1PPTx7<N^Otf3_@k=V$`(P(MiaD-gMx-Xm zE;S7byf^`1b?9C@l{(Bft*MYrZ!PXtPlE&2TGK#S*uChJ(7%nBN&hTe(a6hD#}SwJ zMdYmhHLCtOQFqv2=1cD^^{G#2k~extYQKZS*t$0e^2Zh-8izgmLTNHM#sWgi&j&Z| zY%%IvN!0H7g1;Q`O(}wj==8?UbU{YU4G0c|xSkhjNna5sS}1t_LGMU-ceQ1x)LVtz zwQgB@tuxF`WqnY)*L;Sc@Ukyx@iJ^%yirFzKuGx?nanV7$~r-{7@Bt4W4N~15Hyqq z(l9d*F*Mt|t;(rTO6$eEd6nIEq8%N%xEyJi*YJtUlGSa~itLF;GxRE3e`P?)evs0s zzsroKq}@Wq)LJPLhrZ`=x#b16L}z|sKESwBM5k#!VND6Eh%9s$|2H)sZ2{_8>`^r` zfaKmT4vjgk-ys-@00n+s_H(%@%eVuOy8u0fkgP&e+^Ew30HFQzC9;cPOTiY%ahZHX zJo!e6XO&SBXf#TMCz_d+*~1JGwZag;nXI|oH?@QQuy~C|C@L)m80LMyWNCVolx!hr zkyb?PXe6N$f)Xsa5p&FxBSbByzVV-``7WAY0&glppF$oqCnOB>coi0NE|O%@g?oOZ zX;=3AviS4gg(V;NlA5b65SP%XZ18IMKCF^GQmm3&nukgy#BsE4Oa~Qr_J<{h-hpml z*+m^)ru$0;%hT!3wLehc+mg#wW+ex55zoUwkDnHX4-yZ`KyNtEllIV1k`w{94xQBT zqem5t8VO?lakqHPafqB`iXbfJnDT`JTQ@E3vB1_vF#<LLA@W)Qg>#}Llh$5>kTk9T z)(2iiX8jtClKtSN^nC*nBr457$cJ)226HjTeIHQTq3qv%D6WjDijK_pviu+k3Vwp& zUw%(w5DJ3A`?<iBwO`28JN$ZSoNO<$Z^`(V=dH?ousF@^aS1ecsC9ATI+b2=(dnH; zB}#MVUl#K$H-cVsj6fL<PR>omA{Qx{ZjabvfW)^iAiQ>2mo0b%=dNb@+||1G)H-)P zC;kBWl|B+n0aVAR`;{uNTithhpS<h)PJe8js0Lk$>r+RtJ-4VM*ing#Gv}|NbFxlb zF9bf;X)71Lr>{WmFNdIs-9}vz$<x=MMlnW<4<UpT&w&m*xdk=x0VB3mty`a&TOSrY z=p&y{_oL<bL#<ZFuzdwF*KP!y!oJt@BCC3?t`+q3C1{nM){NwL2)}=CeCH{)^BatB z?5KgpR|H_z_&##&|NZzDE&D$l-`|&hv+>>CE%e|sbGMr3|K|AK(P546L%e*W@y%e4 zk_XRHQ+9c3$|4VL7E2%WiOV-AdNH|nVxA2t7T4V)6UIXX`l=P%jTKjs#asH4Q8!gy zTHYD#wQo#}!JZcV#d<N6SF^ZOULt>0(qeDR`$(8A1^@K=8}&O7u)d@P&TS#YdU%4k zRSUu~k=evdE#I0rIs>2Rj4b)`jW;X#vOjWbA<mwWFaKTcx4U{Q^5sj%!j%lQ1k8{& zgy~Aad^BfGQbS_3>Yv&!-X*ncF5f`6qg76u-`>nlbIBMw?X6vhW=ONQ;<eCwi6P7v z0gwo$y%jGlywZpN1)$}NjVV#ENHUpxrESqXfx-$YwW_o`k~iHRbl|aUhgKs>;BHDc zrrZ4GPjzGBLL!uV6}&5E)HFpdHUeff@je9M2cKw!+4w6V2*mtI1&9@h90dbu){!cG z?F_NMe@BwbDKde=Y|83#Em;y1h@HvSLShHbd)+{JFO)1w3A5vVX@Op*bLd6QM-8f; z^h&MdkqX7wgJ}_foOW1PCLph!xUWVpfiyORp-&WgF*!7Pt(O;tUaTcYyw)Y_h%70` zKE{HX_|D3l^`qB3_Pb1o$eVJgBCE)4<n~2&au+D5XRUwj!Gl=;1_{Qc*1thLi2_T1 zgk_Lp2yXJstUPAXm9#;vIpy4kz?y@>7k6z})q^RfQudjKvX4>MM(5-EQDruNDZ&@g z_i+-gaco02|5+6syl=qX;j3s~GTOqo0E!S5uY+%Bm3Dw<#`0|x?2ByRUctd<#Kw#O z*FvM1ibmZS&?f#@V*RDfT;EaAVXWB0S7}RR_!;)95iIholmH`iTwD&PSnH;tJ;YkK z2&-_p;@cd#)S`vo_hYM|?;j7%WQS~~MDAP|LDn3x``#{<mRn4Xy7?s6%bj7~S4;zE z5uk2S?SXd^4AJrg%kwwv!I2+<mJF)nmW0Of_aCru{0}Ms1}b%u*zReh01(l!@$ZtB z<H>f9aI=Emcal1B5^;-_WMsf>Kk1(>EU9CGM)Ok?k;IxNd;FCAEkiZ4Z4?Gva(Bz| zs4Thrv<^g)<(zRD@Mz#CXNXFEzf?BN3+RZY%&Sa9x};M%ev@+U2R}g|1Ea`Bw$Xg; zAU-%TN{cxiUvf_G{jc2*{@USvwtm~qR)Q48S}L2WG(FFiuP;!n>{1wGwKyrBS;;fi zvBuu+2X8_etw8v4N-Uk(75w|~5`d)O_3H!s!s~_je-mE6KCB<SenQYUgqQb^-ws|4 z$bJ;O?ze<MS-XOiC0I$y-;;95ymyCBC84i5@Jz&H$x0u14s`y+*(NSJ%}t-vEaVQ? z{a5ePKGW3?wBrf-Pwvz9K5N16V)epyQ8o>TnBbQ)m}jkbvcY1roPFMA^>@4Zf6?FX z9onzIUV{FU{?2;F>hE>x<?H)9OZr=#rccUIAuHl|MEe*VK!snzw{wzz(Bp1z%$sli z6?bqVKrh&)s}lM3UQvO)HjJM>y9V~^?E0G=zEmF44>ZRT1ZZF*Wd|?!ymBuH<2Xx5 zPt0-0KbYmPJuYP8hx3lad^bh_nM1}G@6jv3Ug#OSEGT==LwlQ_vJ0c-eY8x?rxXyn z%%pme19P!E8yLTGmzrG2qpg7>2>2-^cb&nbjGs3f4Q%YiBBq-&199_m@L1|XOtDYu z8+O+i(L^FTK8IQv?RI_9X&V=va!ty`vNR(m60`SEsnX`iUjJIQ70P{TYW?1BPQtWN z5(bAxx)b|~JWlQ>KAqx?CorvU&x^=CY(4VXiCY&I=Fro4n%|1&jWb9ZJi~axP{}sd zth2c!+2)#EwlDGiGTwM%(-C4`Ub9X9vI{v7*93*$Ve7n2G~T9qfUfj)pc#!x82rIV zD=~DQI8TebG%w=W1%2OTZX9B_(KV!@6e~4!SdL9cG<d$$m&hlkYL_#M4ve(4#D|18 zG&cmkRIWfgU%8(WNlc<Rva#jEk>QP94Ku%#B--t1;47VKkNYXw$dc>XB2oxHMrRdW zi*P4}8jDhVd9FdI<Tc;|E3`e15a~<UN^|3NvR`@6AGyZVUIy0efj?^Ek5acNgzQ8; zoyKU?dr|G}s|Rh~DS-V({0aKWXqK4A{c0c{BwN5H<gC&gb=1umM1?(rj1|A6V;on+ z3jQQLOx-XFcUAM2te|KqxSNnD+syAjkMI{K4|$<6N>Qb9O<rPV<r;h9e0jqUu1J$m z^DYthZe?<JPjDap+CxR*iZUG9wN=`7Bu3R#%nMz8wR|EBRwuHSKWFp%2PTuTsdk*W zc_WU0Odn)Z!l+6txMBsBTV&QchP=xONr^P(Rdl2P&B|Gz$6Nfu{Ob8-rW5;J?5Ctp z(Q>(&07nglwLL?Ehhf{ux!+HV?<5YttD}uV-(g1S?ZsjFF2%OqSTlcuvF5Dt;@hD@ z_Oc|W-wo`#<lfr_;uA?F9*t3%G1^~zmN$C4Do#9R%&ly=y7<b5bGiPG9P`7w@{IbA zC|cQQJq}t=9JFYDdVgCkyMwIx7oIq3HvTi%iB`NE!p>KAvLZ#_FD~OWZ>7GESR`Ea zF#`M*FB{7*8_bLSC4cG5nDH&mEw69+^l9WMu96!UJc7TogNIsGeUPpyw12{t;qTJ* z$^9(7_RvA$(~b-6=eKX5ea3QSdBbj=n*T?pX9`qetY_3WGG~x_g?HJx1<!N9$JG6v zJO9OrLj<d;-Oq{`*>8Ay<#Vq48JGUtUWX2~NbK0XJckE|d^yAA6wk(uR@T=|Oj*fP zW<E_7AdKJMB{$aJb{e04ydEs@$8Ihz6M3MTqPxu1fGDgznGHAU_a~V*vfF#~YzA}r z>FR4X&P>qhzB*H2<ZTQ^mpl{yh}z1Ns!Mgpf@1M41WX)a)W2^vGSe`;$Y(WkQM#G? zWlEK1{)~uBGjqn@YOf=wy_ZWt>Gs~KzO42N^|AnvYA*sDjciB~va3=1VXORyXix?o zXzpf}KQ2{1<Tmtj{I>#nW6g`8_Av-UVg*MK@4uwD#%F&)_57G@{KX5*F}C0V<r~VI z*NTANom3tZGwZ7wHZ*yq)sc8AjW4=C0)fGaYF+}-ApyKxvg`$nst&&$hc@f-6DKoe zs^pY^!1%nxemZ_FCFktN?VZM&4X9cRzTS2SeG$ZApMp0y^L`R%pkSBCG?cX{3n&8x z>8AFtBD!+e?0#U}_6qf6jbYk<rqXOQJvk+7rYVJQFOyS5-BPl@;@u@LXdPe{Su9jj zxLdwe_s1Hqf6}&8OGDoiHv>ltAzB_*Wr<uT(jIyxQHAWRlIAVOF;A)_tAxk0OThkA zw`QRyyCttCu$#qI70kt(Y~6);=7^`BqzpRk*kA3bcbVgUEJPU7dBP4-VWP)imZ;!) zE01QK6Mfn`e)4`UzaYQt^++~`<;~$6Ccs-hK<S9sAQN0m8t!!%%Y{VyqWoW-?+z~= zZwqp|kytE}$?^@P7~(goT7tN|T$BH#Ae%qt6luYXOGf@MVBh3UzT=Y{%xhZ)Cnm{T zAX@3l!K@9$<tGl?Yg}H!p|mh@thCUF!>CZ|Ds_yw{IS9LT!DtaIUFmsKvna@y~pA8 zs>+3Mr!%;Puh1*Z8{5Qj#7~?}RDOr-Fa%h4u(X=nR|@ptspNR!QhpEclXqFm?&T+N z%J?#R-B@$w`0}ll;jbX4>lBZ4Kr^g(J_z0s#tYnF4&JMcH5X5SXv%w)*s<ITyqRg0 zbsvXL^~TNzZsA)Chj@*uO~GRUbe;vbg4-F|87%(DrrhEY=L`+EVdauF_#EqyT?Xcr zGjPq}jh>$`K4_PVww6E2-GhTi@Es~3!3;RZ&2bDZgh`!I=(l%@E^)H?jMzk0wU>!x z+y*TwNzIq=>9d0;i&0Y&C1iMoPZLvf=pk+yYj=+e?pwQic5qZyx(^bEh|>(_wJepi zMf`jC?9XeDlK~EyOE(6OXdH%ruRNA~ygr7Gc8A9w7doQ6Sz2KHq&YUYvbK3>Voc-k z1n5T8aB$2nV|d~)pB=xu`-y`m@jurvwMa%z<^pCufF^pj%O9J}7H2aUxXw>2K&1E^ zz<RIIdGWPGD|CuC@&*>HVk=@M?hq{C>v!_?H}wTh+(MF{g9AU}Deq0Zzs@g*zhUlR z&kmq}Fy0;ha*$Cc_l&S(Amqjh98wV?mRz3kUm7cLwgV@0s27DSW6gEoLG4!np#}MT z?N>vpV(0pX8f%tJU^(ta*eaJmY5K!;hDO~AU<)d*SEh%*<D+fb_`J$G1l()E0Qcj0 zQr7aH@m~9t!>FSVys$tTsyV$LaT@ihKk`p^1kci(@l{1$GY5Ssr?W;qCrLE<4R_=- zKW3Rk?eIlD!OfJ19I<0hq9JiNNmBR%`VTScjv$0tKjh4`P!`K$Ft&Mc+(A?pKc#S0 ztg^}p2bsfP4O(<iR(yEkpxME3f>`({`z)~^6M2wuM+XaYw7(Vpp|D|{vduEwV9S|` z4)Ph??iLK|$;17CAn)<vQ;(xr>)gu3#AA3`5{D8LIuOSJ$BF+nces0)pm&D90)z2v z=_}n}ESKe4JO@S$e`E&qu4j1gjQGz4t?3(j_AY#fiAIG?UL4}k+x*0VdyT`ZLvv_8 z17&wVF5W~0L4qf6L@U^E+Yz8t;t0{?B$-hs2SVOthw_Pbs5de#-`zH)a7bbp*$2t% zaKF;p&|bbQpAz^>Imj28lJ9AlQkZyKDiT;Ldcw||gAUvDOGbu$_7+8lr)zq0wJx|Z zUGv1gH7hKTR6`R#Omz;gYSMA$+6L$k`)H{4;d_tFknK&zil+deGL2*Jzdw~_h@2E4 zC?ku*R2GM+xr+nD8UV96>?Mv`lp_;7()mi87hdMIv)jh{9gs$+l>wPDqi`CViy4Qp zM>tddOc|{}c4of2;i|&;Zy5rn{qEP8_V1(BsEB~$b-PVr7mm_4r2<_9ny;k3j^ay1 zEq_i0#3><_=ROq({pe<Ty@2d_0kz1xX}vGz`w#p+;wSGL`F+6ebADg(n*fcG_XBu} zMvl@vLn}l)=?UlLvJ@4^_=STL$%^>Z6=%YgYUm+79W28KC`cd7GW-gs_&$7jCEpbW z5BtQ#vEsuV?#>5y=e6U3k<mP$Usz@kIemOWW&!1tvJCb5A{*r(rwEEPJlxB|x-Q%+ zYi$0eiH=42iBaVnCOQ`8<3E}+pu`Q?jlTHIf7$3TwPbjQf4jL$MzT3jQYf#!j3)f5 zjM!(UEh3{lZ>87_iTF%56Y?&nIwkxj^ZOycpYUt8-hadMFZ`b4C;UJT{l^~<aP~)@ zS9V3IA!4_xluWNbLwYM}?J_ztPSvR)dXCAk8PYoAk}<6K7-jFop4FY)Ces1jN*wEr zogu3mq-LY6v1*9=g{6kbAKBxt=rvYcM2VbLsUh0Hd0cP|Lu41$r)A<e$lr5p{zUNv zmxW^X8mTLO7Kj^#RmJ5-p`WcZn{eUZjMBQ|RXo)ePuWCmF@MD!1K^ej7IJ$-Pl~g9 zvIVc%|8`Hj6>k_T9%j`NFCV4sJwV+JO8&MhxKCDR6f=kXq8Xn){>bCS!U%aI_o`D_ z=?_!ikFa2LT`|hexb3;Uc$TC<I6}8?FTR40hPvW~JmzuV*aDumJa6o&;&*s)Kaq!5 zbm8A|qW;y8;EB2GMN~sgq?$9tOS1q<1QHr>QY#`1PylTBsk*`dA)+5pZy{Y}!z0CA zJOzX^AoGWcIHSxcQEi=p3~Fc<DTdRWs)k<`=d0&a#lv{AiSWjBdFBl}VRIk_S4fET z+`OC+<y0K;P~~u=?nl%yk*AVSNKS+y=7W_sr7tOC?u}Y)qc_qpV~uW@QHUK94Y3d) zg%A)_RwdnWkicr1u|~Iz5Z!1_JC8%;a!hpEQ9!3eu?qFiGr{5?^Jn7l&@^uvdUeI) zXnB7C-mWf+kOmYI51dLU$|apUhN6qv3FaxfGS?Dzu#FRW4}u|`Lx#d7C1=TobX_uH zbE_II6}iyO#q+B~N<{fCg0GVDiz)v)h4SVpABz|dFHRJcvjJnhIH6M$lgH|;CF5`v z@TU2o3OEf~KaF3IpS*vM-*x;V{66CMPkx897RdWBo?<h33O}JO@~^*t0>sDN3=y*t z3kPQqxf_fREHHxcTW4wOB(!pq&U@JPA;oohYdi2Ws<a4=Eb;rhtxEiUuX=b)eUZ`h zT164F`5|@w%C4}?@?T(@kvp|elPeKLA6Hy6SgPx6<MlbJQar9grB?YT^hOKDo{D&r zJ<xHvt$&6#3cn+Y=+Xmkq~P-jDy32PE`1akb8T;)+xT(27m@MCdrn<4qDda*n|E%P z`Cb)UWjpz@^^&N{n9@}h>1r{DdFMCRo;jG#n@8f&etxrLaF?$4q1Icmd+`uYba8%S zg!~OvyDN4qJaeri@Rsggl$W@efJKIQ#QegWeBNEtrt|K=%}#E?UVE#t{C{X-s`$35 z$Y%*w<6f~D-Qq!2?)qbaFfOQvhJIO9v2DrE(KW{64ab7(7i1~)Bfx1ufDR_Pw;@aw z^J#O%Eiw#A=j$tThOikv?nDx$PEcIy)DXVWA`efq9>Qpi<R#^Bf*E&pJ`Z?B$+4LS zc;hgrF#99|;qr-+Iu>X)ufpt}MKQ(S>+|I7K^8<{ph+5zS%{F;oxPk#qI9Y24)i3Q z&2$T#tzg7^%;#syo^@0e=5m6i5u7&Q3{x)Fet>CEzJcQjMn_m|WDCH~%Slqw`ShJM zHy62&e@8l{&z6SJ8y2Exn-yd%<i0*^A$JbHukCw8?2$(Bhi|u}_Ht;2PaF1=3n#k~ zVAS*`H{5gT;*soegXQj;7D2r#xfm@Q<yfB=9+$!j9JF;*VOq&if{4vO!Sf;`edJ3i zv3cw!YqVyoA=#Tk&_z${zU3$r)kqfTeu?>nDn-!?+KcRoK>Ec<@xoPXo=Asz4g{t@ zG{@&^`-*%+fg<u!)bZXaee~yzHDL%0^SC)UlI>OS#Pa62EOSxE+T5fQTfDJ5y$aWy z96j00lV`9;T_Ks_Vs_x#D!N}<!+vuR2K~HzX7lE#<NEA^{L#TJzGy==*?ci&kl?d4 z_<ikRDPGXp7g;F@f=5AKf=5{1HNU$mnT$G$vkUW5m{*s=XvnpM3SOuLkk1HL*xDG0 zH9k8`aHJzzV4j>~95HfZTg_6bv7zP$9vP^Kzh1cyvvxcaj2QY^S(pbsrqtBEw0Ga1 z^2V?1`9y^!SL38gohvGh>VjIf*hy!MJ-avRSi=Ws4$#<{-$CKlJi^@J5{ZgV^ES+3 z@ed&D=j<w0@HA<7WeyeG19jk4sb*XAze(CB(~EF1+3Ql_v6)R`dD@8yM0i<`P1zAl z%2XU;VibIQqO|H$bPu#j@=~Te>g&@NXlsF<_?7U(=IMN*E&p<xV?F8ZiMDwwEqxT_ zpG0ODl%rr3k$5*Un_;e3%3!F%)NthbldAcsWT-Uwk>ap4yuE%EQbkw?dW-a}ys}~S z{RGgVPV*m+2+K3a6#r<~i-A!_eM+Py`gFU#L6WNj?z>j1S8ZTeuRpTPmsd;5l$G`< z^E@;QvozgAn|}&H#v0Xt1Sf19>qhFkI3?g9u@hf!oxDap@ksqr3W|C@il}R)Xz^UW z@unv6B&$@dP#MWz%~!*Hvm}Sk7rTk~Nc{!!H#VEU5bpyw${^@tWNTbI=^;@kox-+L zo#m&=?Mz0s*ZdhXMPxe%4WiOD^$KYC9;6AtRQc&4e?xtT1jJ&hO_A8c>Z{-{8>Gxw zBVQD8SN(m`iuU?49`diP{+IIRjajAEn<|@%r$^oTOJ$1G_vkOlL7YupDOIoPiPY!w zm2`f^mW(KYzBz2FdRJo;o73rT5||-5VJklBY>9fq{K&&jJc4^pp-KCMpH^)#>bd>f z7XJj`pn8{d{+2TR(Mca3FaD1~ou|jE`tMu7BXp!UT5vZpEP*SKm?xc4cI-+9bDr9E zv~%{^NW4Gxkc$?oJF@GG$Z3qO&)1J02_Ic=>c<xS=+KWQ{dibE?$(b6{aC6WSLnwq z{qX9?c>O4mM`?W_4`5zGeTCAiXnlvk9AAt?wAUZQUq+U2&lRkx3y7#z5wlYfkyxb) z@TUS|llGlMhS=D*X0!ap{t%{UZ)~*;o<Fu)>P!3cx>*i0<Q^mCf`s)IeO4j9w1{nN z>ZL?pp1kxnX~kVKeEz7KRop`6PQEU}IJ|Vnq`h=RYLkB))}!)k9#aL#qbii9tIo=) z&1dGL^h)q{iA?!uOa{#Sc#0&}V;DQhv&L?-hCNgnep)cw77BV}j=FZikO5|isJir- z9!tNHYJ!u(Ps`NH3m!rj)Fi+>c^~Ta66$V}xn>4-?@2b=*$N0@(rk~VM)?gg7m^tf z2+PpZ|3Bdpuov*kKVFM?RTSjEfKOu&+$yZiNl#r!(Xo^2d01%0%+YA|v{a2Fa^E=R zh&+Vb*n+XVbGVgsj#*(%yPwiFA8wr^j>CwPOYJ~E_TFjq`$lM|#3!3UJ1p~HBln7W ze{%OlJ#PL(Q{6lfzzFL3LA^M~jV!VSt|t`t_5cS1n%90Ci2=NFe||C}6_UjsB_eHU zrKdzc{Uq<*s)aIZ%-Oulnm8*5xw7Qb1L(u1%h$BqEUFu@40T?c#m}ehSJL^dDfV#f zK>79hjOsZ1d$$Yq1i4DwZ+H;Ji;uJTWN3%AAJjhW6pc!+-JVKo;TAS0Y7dXMVag@< zd(>83y5y`j&*>-)od$YvYjpIYB7bzT%Nq-vt{4@ju|Kj5_QrD>Q@R^HDug^(ZAF%e zSGviv9>!*Fk%jJ}3pkctcAA_^HYY9(FFV~9I?EkC-4;BPIj=|*8If3>U&yz3Wn~(8 znj!RZn^74LdAj6D<t1#Yw&2RH*}VJ+md8Pm*D`OilJ>DxN!r4v+7LTI3Z$PhTFO2< z17Gb!$(tVgK$-dIat&B-I(hc~x#puTRdI^j@rd5GusRxIZSc-${sB0nu2vEv2v;AV zqkNP|R|prf2TwYcZq6$7M^C}nBA?#mLr{^9nZF+axN4W>+q9yU5}Bu*?_;MZM>8WS z&>!^_NiH+-qLhv`qg*OoFZLiROZ)?=DS9ZXsH$`(vA6>Wq)S)VK82>hib<it3F!jw z$to}i4G2^+$ig<^QW49`LNTJ8iPd1B3(LVy@%<n5NS_etz*&_LTtf6{l8q+$Xb*O| z%h)>3@iMg4zS?A-QMXOnCXK&E>JkBi!bRm$UNB5h!l>U)s<>WH|8*N^BMk`bwE;8^ z=!R&(vTASbtu9+|6h{puv~7#lck@Rs>%==jbjHDIXQtOsg>JO688icr18{0@nqM6* zP@V2-V5}KM!M2+9T{Kja1C3%)`Wg*YlUMQx*k3~?$e?!8tM?SSL(@=9m$&di(ymme zxm+_=a6>cn>tM=6PJwXNyZ|<w<qxavsYM`JB1W3)CC!1EG$*MvoIFyXyKSgFei^8# z?E5nGDC2~}qIQ7}^XXeP##d&wUlS7Ruk1F>od>~hXoHqM_AC$6gbe?$@4N^^UQ!z- zjFu+Yf~9x~$@fPm7kVRc$dGv|{xqOa*A&%l4Wb7IYDDK0#wV#cVkJ~?TW3CiKve+^ zcHtMYmo}<AThvJ*Z&+qW1nmO(Z63TV>jFcM%3<|ad7LKrqc=atNa^Bzk+=Lt)d%XP zzis9P?<bRD*7Vbs6YcpOMtuu?;4~{g5S<RLVtTaAY!i2ff|n0T|76a6A}?5l+c)`; z_aEV_ZNZ4C1CQt}vb<#IzcNngFzTL>Lb(x%<IT~Yy3IFy;12KVTG+wgk3-)jCpWq3 z6jF@7E6g3f0e9&qQ?wYiBvz;EsOo?V^HprXIeN3`8*n+&!k<Cl$w^QPL5YTR#}S&- zaii*OP)}TE{2oRq(kf8lcs4pydJ`O_xh0{<2Xn0vGB0hjtC7HBn1F9H&Z9bj{<LR+ ze#EniSHE4oJ`AxZ*3(GPlZ%83Dtq2NN)DpAI-%N-JZtYmW?35G>{NJ6Ha^?UUw+OM zzX((vNS>8m|4LFc8Uxt3Zq^7Zd(w=z{tU{d{SV9)S?64-P*LgV*f)=Wl|gXG+VFh* zV8OSTbD^{sMNms)^HDTPu#oMZ2#xwsnjghFJi3hO=`opsqeLaKUd-0wFUa5tg2?9e zjM!k@Z0*7kO6|HlZ$*pO@NCS;=Qa`&d`=F7z|!F!uCYv@P|>w;Gk-r09VW5AAyzU5 ze;K~fe!sEecB#8|9m++U63?Uyt=hz~I`@v=C0I!2?u8E`u&ij23t;S<5_hq)WRaz{ zN|=mb0XFGAI!d)67MwX8$nOY_P7l4DupQF9C+Vr%5p?{;W^)0FDV%&e{>1r^mV?d} zAd8TVjDO3?_}-^`k_kFVLa|p#Sy8x<Aj}njny)U^<K(i6NR5z^KaQ8NDPwGuupsI< zh@rt-RK~{<k}RPt@Q1;ZM6@F3nNi0VG%PFGi7@JS+%2GrIXwul%mowK@7^XE?NLX2 zZeoN>wM~-P7Fry2{H|YQdsrgDM0nBgDqflXp~G-KvGpEARRuTb3|W4{A~li<d6w;# z8PS3Z`o$+}q(G5@!!3#nHD=1`f04<<@&W~KMYR<X=)J#}N6LrSwO0wls{T8)j_fo; z!Pl~Hzp^aq`1CtDKoFr>gVba$Uu?|`>PkUd&L?U<YL;>`jNW*e5K+gkbwQ~v4PKW8 z^m8GsB?9={m?v$XQ-J4^z0?cvI|5Yy`2-oFv-+lLQv=Cr87QI5qNrnB-)ht2a$eN2 zPrt~laj9)uMMrF**-^)bhv!KDaE%gakVvmiF3BKi%{+iRT><u6mFz{sej3Vsz~1#c z1^X@98PI3*m8h50ZJuHTc`kATHpe!Vk@FeOb%2J@v@KTD<-bwHP<g7*LCP;eKDo|) zkCYKlA+N(8QK_29s90H^f}@nJd{ATrfUy9GG4o+FA6K5Du~5w%dJ^(&d$E)ggQ%wj zY}4LbO3ZVkq=`BHpvu<0n#eo7`r&V_UQH#Zd9dnLW_{B5#H!AQO|bz{$9;$G1*6J> z8lyN!>O-Hi@-y3u%poDUP3IJd)_O^twI24XFTCs&abN>Jm~$-}p$@7nl+|2$87wuN z{xJfknq6W3E*jNvZt*d20T5rIxsgr|9`Xr4Fnz0Oc-!gWjbV~mSDIdeVMP+diX$^u zns#PgX_`)M-Di4Y_I;)#%-m<1mFu{4u5Wai>8{fl`n_Fd+HyXTIhUCNgY1)>5<kqf z986={TRd9)R7`q^Ev^^<*X;u&xWjS;*NdT0lQ`1HZH3ra_zX|8cK>b3hXQuuG1u<W zT(^&#s$oeAwVJvxCVy9q32YOL$uTP3TEI&>DbA?-10SO1cmEO}RSa@JDVs7jnTcOp zHNsdmbFNQXm@Ye&O9I8B)WNk-hHxz^g8ip0el@fQju>SDWBG#wC|72pA}7qqbqU$j zhnBgOy#yh$)4xy$Ug4{4<EqH*lHs;qNElno`;jimNjodqtMl~i-L4cWo)_^xe#v?@ z6J*J-wU4g&FbYICNiKXU<VKx_gCN95TI8*hi~8yQs-DlxJ5?nF49Qe{l?qD}T-LXN zt-QmN8kAOheKVbH!}ca6<Wi>rvTNojFy?rqSP_dYygooBgf>Di)RvCtD)I{5fO&%b zO4<Cz0zJ@;Rc7aUXaa)Pf5(wgw$r|Rv!68mpXfZv33~(e%UYJ(=$+q5H~RL~-?Y)r zpG#7?mFMocN=%a_|FG6OYo9WJ$=K@KWTD0l%nQ7zGYV_f)AYk-DPTnlPCQt+KDkl1 zcF*WV$CYo^V=in7S2e!BNJPpee+6z6g~5+F?2?7l3pac1JLOQAEJ^2ItV9QRW7F|B z+ah?zv5@_97WA?n*7>cPXOfb$)?dz_e6>BJ7Y@ezDjrx1eua!*N<@M8h@})M^WADQ z{*F-^lhlh2Bjt@&N^$D~MruaNeKGl}$!B>+juxClGCCM?CY>&;iF0&6Du|gL8+<Z{ z^yQnm&kA9f^m4LKcfeN)WoQrBcb*{~@K$`z{du2@*}K+;I(-6jD>_Zu+<l<5IqB@6 z1kp$0E{+`6%4y{1Md5#w!qP{I!}4tRlnKMp<~atGFCm0McR1jFz+tr}T8pZ+COY<6 zrJ~fbs8i!;h#fq+l7Ew#s}|MAf2C5XRoU8USgW#HRMnEK3Pw&O(kJt=mc367mlFAj zw<28RinH7hA^OX53Y<A=O8leW<k&(`dYx9=!M^KlHa?p-T&$S9L&K_f+5BA!-)To5 z6UpZg`GM~)^DRsEmomKlhVXvz&wGXUgTLG>yzhJ~4ezS|{g&{af=1rnh|#x!_f7Bi zgZC8#eG7OGyXf1)dnS@V1@EgZkzfYi>aNd$FdUvG>ZmTtVWvj5$a3;zBSURp;xPZ% zj%Nc8SJ`eiAA1?t$_{b~=nGP_0BkpJkw97WTastv@H5GECQr89bjXYMc07pIeg~fW zB73+JBR^3gsjF3Llz1eya@!9xZv2UXV!t-l*Hr$@*`d(J$LEVzno-^uUczhJKyJhU zc$*WiU3dY!`ZEMZP2%C7J;~dRlDAo02v#ep;Bfp@6!}ne77;QoW0n6ik!l6l_=^Z8 z(8QCb2by`(uRw>frl8A-r$5BbxL>RLn3CHZFA~BY;)MNkfTQ+gUYP|jg!<?|fug-x z^tM7Bqi(S<IZ-x>l16%^4c+KUA!~cmIrKW(8+DYiuv(|^?0<WV`rV{%_l%KD#u{u9 zBFyL5c`g?2InqOMWic2wCA@5mEi{G#KBal-WBeDTDl}h`&Q;f9DeD-m+rETKvNoTY zwnHuQgR@iZzr4+JFm)G6-EE$6cF3Q+@_ro5xg++dt{;+AWQJwr$t}Y*3f_JcuMF!A zx5|=cnG?w|J|J=YU4cYW8+8%N^F|Sz&2)JqjMIkT)8rl&dcu6^7Sz-m&GW1EvHzI3 zs3@CWKIN<g-!CAw$JJI@WRHu&GDH5+eX?6{+(o<enaS@jP>fW}akiqvdTa5{{gSF+ zoJ#B|TC27eEwfn;PL~4H`x2Mwrv+`EV*#>bbXEbYbOE2-E9ImL2vdMQp6N#~Q~C&s zBGUiWms`s`tLuRNd~^Md1bU(~$Cx&h9%xI7pOZ^jm|famaCZ9evSV#x<_eYo{sXCs zkt1bDMlF+D1=3p(J2#^Len+q9EIg|H=sg@q>EPnBabQ-yxpRIpSy`7173^rW>oI?5 z-nZ*tzWEqsWRx@d?9X!RSA=X4HK>6ZK%YaB*L-xhpjAdpPzdU<(px(aj)asRP4pb5 zp5j#3T?_&VK@cyQB63oyVUFi@FdV64=^sFLi-8s9e;@`{b_;>%0<SQzK;NBwZEuSP z_|BpzLSJi<)^FAVjcc8Jy-53_hB@_bIg5rEs-8d)zR8QQFyp8MOP}K*E@FyuCe_08 zAZs$}SJN7Iqutyg9_)oU7mz6B7SyO`H%W&q*Pwmc6Bqu4+m#)Y^R=JT&61d_pfnJ= z=)9>IlC((FQSvhdA0-tfF{zbQRKq}P1!wB6l>~dKJ26g<>D{`~!P%)yp|kgvfk~^t znBs2s5r0IA6h%jw!`?!+2frH1@1s)F%_SZ}m;_OjSWj*g9+2P3aJ8v9plj^I)qHxR z5F{qVkef2dtk3B(@>3;WOmoTqvb_6K<*nf*H97u+@@AyUoA=)-FL{I2-~IZPm*Sz7 ze&2Xl3G>ISdf;G)+h+=<-mR$g+X$>Qm3Ew~sI<(^?dGhkln3jS_oY*AJx8Y$Le4pT ziJ0ai`|)#`g6n<6-IkxSRQ*amJ1f_p3Hy@T8}e<TDSl3%z~e5)UnX-3pS#s}OjN8O z2Qg>!Pt+o}#k`m~z`(;FOy%&<(`9g92B)GV>lV+VrE*Zfp}G_{RkY{jSt#FGm$hAm zm7tJ>u^<Ws;rXFN3SzQ2O(b3HjKp_IR)#aqk`CwMPfC7TEnJH^{s$IzkTF-js^g2Y z;uSogPN=NYV@tWM4?Ik1GO^v({O(cTF(HZc5F6VcD|mF7GdP|F9z7O3Oo2ztd6;xV z`EC&1*#YNMs{NI;-!zwgKhu6oA5^<+P?sL*`|wWOqQQo1_cCu}X+HJ5@vs7ys8(hr zJP76>3kgJDGUogvN%bbyy6>SsM#y?lEgO{*F&0H-w0?8wV%dmZ2+^BPkFh)!-UN5N zVpMD`9|92APHz-u6r%jg^#DY!f?Ety^qP<IiB`Xh76hfS43-#{fZ`!QDwfmAE3k%l z^dgGj{!>*1htN{Q8|KxSB8H`lP@Ykbw~EMF|F6^|-j*71#a^W5f;`oEr(PeMWRx@O zquSMSUF=GNmGTi+mbW;5HA1%I_?;2=6Kv<Bj?+f=VI2L@CfN`8lI{M8ev?D-6=9X( zHFR_ef5dE;!<?AoZ(72v&UE|;T^hLmB35uHl_Z^KUBbw%aU3W$)=rWK$Tihv)c+7X zRJ<oVa;KV;aQiAiPG%<Hb}If;l6aqFftP=`dJpRm^?}7Vwt3!ydEG)w=&7SxS3b}t z{hF16vz&mZS2Gk=MRx7~v$b-5Ng1hy$f*BBb<SEjUDir&ZMWn1>FN&9WlFc-|FtSU zyW4H>^X--=W%NF%T$&hLCs0<xf#F%Lg|U_iDN8cZG7qz*?1ieO5B^EDbU<lYpB5_C zaBl*EH($-+HH09y6O`Vd_8SRrwBXudj9JuioqAMq;J`)!AqArqE0|0mb|c8dP?oSS zadJ*RngsL%(adM&FBmyv1cB9Up20vwx+swNg$7x_!2*%eqoj)wZ#xg0|BDlA{oP`I za53A4>AB^N_?G3JlU3f&C@<ZAMbI+-EcAKdK<jybsmIF;)q3eN-{<Aqt>@uo<IoQV zoSzRJWHX1%{kHib)BW3Xda6C=^=nUxW>`LS%u7!L{i}*k<fdHYUR5c#qlCx-APb7) zL3m4fhXOf9JtXgS#ll&6v2a_(lW|t>4Ls$aHzxT=Bv>tpgovm_vASYOB!!Kqus1g9 z_e$PlkP->MLbUQ0=xI?^Jd4z-JQ$6t;-ykpm=IkUCJADIHp{HR%^nP-xnWM$XsYuG zbuzE~1@(}P>$;TVt(W}K!~D_tQ01Q%cM~ov!WegWnadU`@Fmy#Bj3dy;nJZ{zG$F` zTT6_(!>Ex)u2Ql*6uhL7<8{AT1t>yd^KRE&sFYZ*1d6SnOY~1K#;J&GYzrt<DuRPQ zmp%rf%ZeEJ3n<onYJ(I~aICN-SP}~CM1FscY;80M1*A<<70qszC)K!8kSa^HMmI~+ z*<6wcxK%Q?-a(SQT7sqcusngL42R?t^~eR1VyP;JfszJDjVrB`ck@)00rCa1Pl>`a z(Wkm7IpQb69pOlumCee@C50n3s>tZ)HkAMsGJY^GJ~10qP4&a@^=)d*q2+mc+*2*q z?YLSPMP(*tHQOJ1T*D2+&Fp6DF41iBb@&<?hk8eP97I9FCv%9Fo4hjy2OvT;kLi&2 z+ckn%147(oOi%%!>eV+Nkb(QQ@<9!vu+(dfhU!~xxB7G^Jqq6F?W)P9&Fa=40Vr3~ z=xyUDx{WX8e5_kJuEoWZQJ0XFS3FF8CKZAiXvqyS3eSY+J%`utp$P{85XV>JjnU^8 zdyUbvi)XPHtyD8pW`oRapk7zJMS;pOb(|DbSKOs~ke<1ExKu-xRe(#PNhYJxrl|+` zsL2OGGJ8%`i>ig;L^Ttv2aZxDuR=&71oAq<Y6WqOl>%UAI_{?`z4<<pM-*bF$A3cC zbq5@i9}uYTZ5B^#(6N<*vtG)hari$o?^Puk^=G6Da=yld*UBd5MON%F#MVAlJeLMC z#~<A-T63rPYWJY0^B^Bssa`=8Ef)A$l;9;^ebG5W3GQD7=Kc9Osk7iacS=Ljl;F$h z|KCsoYlH>p-<TW-KYKIXkg0VPqizAZ7g^d~0X_DW+az|jY*%sseS%fcI{*p~gZUID z6O`vnCMiSV2M0NEW{W6R#b9h%vf3q8BO0`-PGN@hA~xxrAyU)L#Y<sXmx+9jyaSMM zaV-XAg9xb>QJ6LK4<Kok@@Ejl;4a`{4}FiZ6k=&%rtWfzY$}wM3inde0F_L%DiL)q z3x4mY1CN0bbpXKaf|SwBx{6--=Kqz}|3@=i&9|82(xasyYXxGRR*PINIaZKj5EoD< zAWH!uckNJ#WbH7|w%WM{LqcT&(L=TzYiPBf(V{{4ge(m#Z*=Szd-9-RTZ3>IZ>*I~ zfk>1p_F;shj-sT*HHQvn`rM0P!8}sJBMzGm*UAXtNlg@C3s#jU;|8r_m2E&=jAOIS z=2xRhFXFUq3Vf~Q&Fq!_G&W3z;GJ@_PlQVVj}mo=$melHK?sEkey<v|0V{-<^8_k| z6G=MnIL|8RDOHf1)<Ohq$xW0IbxL`{bcoH+rScwg4kc&Od44LJ9zHQ%IG6a^mj+{3 zx7iy#X}Zd}L*+b5=iJJ!Jn0;p%DF;SNJ|}u6VE+E2w=p6UkeVJnq&}?ueCYWe3gfO z?wDugJ5eCh_w7QvO?`?BGMt2=3Z}N0q9YG9uVu0VsMisTYq`#`laZ-Uuwtuq>;vgo zLt+oMVvpCcSEXaOyJaUou>2q;PrtGZF-ng)5B?{`PiJe3ao=VH_gI|9I2X}>e{}Fh z#Qu!{(Raz1h`5%Ew8S^SQl;44v^}aQ!HXZVn0uG8hPwqP+woGiYp~y#(rm0bzpyHH z#xC?uHU(lA+EEUX@GXG~?qzBKRBmy7c~YbJI0@Y(&ZZWJ#%~H?+wZthpnl2725fed z?;w40`A?nZ68G!p!<<hqN}xYKHJ`A2?$}i4TIL-GDU0==HYe~!Z>7g?k4|qcP_dyg zM3s@POiUckFQKTC#B)kfPlO{J8I7JWZFFKScJ#?-`Qfc0nf;#bJTI2~C04K)WKTN( ziL?z&4`K+>1`ux{P$BMLt?=*4=^oMz70z{4Pg~&}$W3}+Hz*r%JSY!@^jeL8@~!)m zEIWg`;v oa~J)fsMnko7VbXxY@{^;K;08Iw7)^9yyh_)@4%m;`VtejEe&i5m~y zFY`mr;P@#=5jH8Yl4LZcw|p~H07c`Zb2aUpB=v+2AY9dvbgn#``{>B0B7&#XH!m#^ zPZ@I&Z{=g(ae&O&I_Y3b7o3uKIhdNS=86~3!}^XTItdqjuI!MiRi*5UKxm<if*Hch ztmH|>s;f(_G@sn6)7)*PSta58lWr`PZd?KKY<gNcq1Gx#eVxwGB#A6G2x_I?g(Ay8 z$$W*>+#w$%%CJ4+hXm&xlG3~qC1J+Y{Bw2IwkVAfsAsfP+cWbcB|mEFC?xMM88dI` z`ivB*zLH=$Xi=jZxoaYyauH%|PLsRI#s@?M0{RSN?ta#`kIl9dS+A`ycnrkD4xqS? z7ICLw-2T2uTg^_1j65x+kR1B}QP<cZ?0`$gwTx)J8O_IKiKth7=8p8ZpS1CbJc*Jh z=n8kFd6JzFqZV=oRAO5UdCY7w4+Q|;+NZntwi$I@^0%;FVzGf#jg8iuk`^ODX}VB+ z*>ifMv3$P$v60*)?RfB0?yR5Ah$fvsW9i2RRTW<^jV5Q4`f^l#rM{ZgS4<^|#5#20 zojS=TL?NlFFqR`bTp|Ofn!+1x)}>*GDP?1z$wQ5Ls!w-GtIdW7iA^<KB-N@<@lKgm zu~fTsD;<v@*P_xM-Gm|inxKl$X@YKhb`umf$6~stx(N>51l>W^1c{9YNDA59JY~n= zLN*#h`0PX9F$*y2FzSK(+DOW?Q0LyfbhtluMpE)6zK`<vg?rrL-ObAm#mU`QmEk0B zM1M*6m$mN>ZFzS{?FXk1dpj|jz&-BTcMnx>U)6qKw0tmx@6+AGcDqUCM)OgM^bC8` zjq0UsG#Ky`fb5A~xYJ#`8|RbPgU0UKT`r@J6VxP$!bC5e>507JZb{^m=FnRY@rc#S zQ7Yl?{X!LzXg|Rvah;VoiZrgElfPx5L!^>2i8@fCj1&~GaT-Pd-U_)4W#J)W%^=sJ zEUpMo9No;~wQO*r3`%ZcU{oWb96yvOv=E6q7GaEf`T#4qnYnZy1cilozc33iwc5;I zq5h=Ybi8smK{7%7TssnJHg7_ulT|kNd?9n*1!MI)={M6x;noX2z0%6EuTP@Vq(Z%j z_LsV8$i?axJjPgad}VmgxMycmgi*B<WiWfF3@4D~AA8ETLW!BpXrv|MapL<2m+y#o zO2##l?Re4j^pHI-<m{U+{)kF*VP1ImIQKJBliR5JJ81`n_RUQjU#?3VG;v%Njt)sO zI8>08Bykz&b;e+p>~ZeDNI@Q>>UmN*Lc>$35|e3-L*?H>%#hGf6_Yp`@0>&MI5f_^ z)@s3rL=O!)h)#?m&rp@8lN;K`6OrG<2-sNDnnh5(a8aePCh2YYAfM+B@31{JduCHg zXm+Hn_We<6TX?7H)|wqH@8igN_pqJD6FY1697iIf?pS6^&7RXG!_^c$$hhreW^H)F zxZr-6UyKVDhHuOp7aShGanLxU9s_plc&hg#W|1_{SpGKUl4^oc|5x5{2pU-z-u8BQ z-Lv6c2N)|_2#ZzUAKrDK@#A&P+Z<)<+U$;ov+VKT6F~uX<F+fPD-c=dt6jH8AMxV) zAkSCZyob?6KVhn|X7=zrrU32W@9f}kU$P~D>d*U$%VD09fzs!L7opWRoGhrr;>7wj zAePaez;CEH-nzMBP;GKt&{><D9V{elKVOpTLz8<#ZwIhQLu2H?05iwgX2*S*8{;@% zp+Dj-@<+~cB?h(GhsY^VEh>j{*V09;8c2HMxDLxrs{S%~I8&fX`4}5XbMXK<TKUHw zfeT13>j`0O)!b&sg5@maf$qY@AC&auHdH=swOx2885~^3*gXepQ05=j$?SfGkuKpW zxA?dM!#4SbwP?roGpA3P?W<@B1!%@l<F*JT0J8jmc+o9*Z;6P>TYHSURX|v@6?VQY z2(}}9^YQt!E&Hw5!Ka9)#$=nfc6U$cy*OeWDPl0bZNK!@;$3wVMGp=NG7Jgso0tMp zpAG5TH7+QBXXB>wM#qE@bF<JL!D?q4{*Bi?3m1F9lA_q;`zJEi&COkovd%VpUW3~n zf0p%JKvcdtJh5;#7V61$c(}z`<_I;1Hz&@;gJqknT^jQ7J0wGF=}s2N<1zXg<}KYB z%BL5;$ma<hmVO>6ZRLwW-)A!SH4mE|e1Ar4@V<;F4c-y@fD||kY_ns#BL!Z-Q2L7E zay;cl{&N@34na9!vrfp@BNY~18zd1TDYPQ~Hx-fBC*npG0dahiLnD<#%=j)%C4WUi zWpY~OoT(zxL@veuz{SEm0QN_U!}7$wLf9U54T6p1kRhYd8rhU|p5WE|%#mVQTHBKh z9h-DsH;pihiHy$!0hF7EA?nqubfe`IIqoN>-DC1fJu^+DsY&MxWQDNK_eSpv6VBbQ zgB4#Q9}@=~wXc$g`7$c9F}#fpOW3G?jhKd!gCymi=7uSQjWu{{a!v#)#+r$vQ7~(+ z9N%NqimFKF*jnnh#U-ooSuXjKqgr*RS~te-n4Wf+W!xLdF}NK2DuUpxNy-|b89l!- znVo^?*nMXH=4G-gb5XU#qUeRWC`O3CP{lfWXp7?2<t{EM-F$z7ToB0V5mwl8OvLy| z5yU)ohQu_3afx%<rVQpvFtEFMqQj^?ke*A0Y)j3PNiDIe(%=PxHw>%r>m1ONPONEU z_|l6Q7IEC{Ac{XYg4kuUOSUDp0!PlX3r3Sw{5y-&uZ0(TD|#1S*f5CF?YP>OYe$qX z79_(JXzKkj11RZ-7OpNcVaGh(p`$prYXaapspj>yo`9_IL*l|_(A3CJbW>AXi}(y3 z-pe60CG>!6)&?Sl8;(CNQc?6Sb)x9pDyijkefaU#4Dr#AwR(oAmA~d>718eLq0w*) z1(gCL41^Q=QcfyxiVkc71B*~~GtITdlI?5xg(%jzce?vA3l?Y5G}i@Fa`9j)EafES zW$uAz>iBAU?I6&?6P{Ig6jnQiXKyWjHfexX;U;-Jd#h8N@i*<^y}8o34@Yh7U-2%x zow*8&K-dz=|70AVTWJrtW#(MS(kC3ei0Ay5^h}bPjM^1^rFIfosD5toTt7M`Y$ms} zeMmY_s?wQdw}PAEGJnNxqwaM+j9RQOxOAjy_FSyJ<gIzqKJe{}xOH#LY-}CpLaO^! zkS<$|ankwP6e&J5B<VbtHz|Atpkc?cHMq!Y-^%Tb$;4=FPhfu?C!H8qwg$gvJmDWa zcP;5`^J;r<UHp$K<B1mK|K45GBOKns%{48$O$e=OdZk&$Pq3}r3<XcD!A=12ONtC- z&5cBX2!c>(uyk2!*3WgNr;3=5bSXr9Lng{sWfpSXuENC6D4m7m(fD+)IS;&^n%KHl zOW-Ub87}91g`oi1ynLLLLdn+>v{uGWPLAF=!3u52)c2waOH*Uy70Pr=EDaF(>WgeI z*d=thn+2bXY!!gB>=)9eoos-wmiB0STBR4rRfUu@vr7z4vouPcT&+}3jJkVhH@i}A zq)2I?(3KMD3Qw18>1qESKCw<fSNJo`s*}!71j0BMVQkO#MMrUV&Hb@c^OZ_|H_8p@ z+*PA4yE&tdKby*w{hnKKh;sVwBPi)S6=@hHwQO^FYd7YlWpK6Ys}&JLWeBiobT{{h zC6p-&Kcn@5QZ^Z7*t61cbcW8Iq^D+?mAlV;wrn_bdUe0js8n-Bwa#>$D=^+}7Vs3o zTdEkbm+0$l45(u9W2=@y4>Tp6H&iNQ$KT-Pyw&zBmFun%7==)y0U{Bse^97OiZTwW zRu+H?v_>DYz6p=#LMRH2`z~Qh-X)jQK|)VcBs5D&LK?t7qH0lsru;38e3uS#R!eG{ zX1;xlz)g0fea`n&`brDT+mBO8_7<ONa=Nu|oeiL*iSP2FM3l5J8-K<B-7Hz_@Y)B( zDKYQ4pLTMMMu{!R4NL21AyN|Gy~@WjyD@yVnnOpDgj-3yqG^4SH_BOrc_vEYNF#pr zcM-ZFNdC-?_5~XEPkHSq#0$s7c!>%1u0Nv=`D<O!C<t`oo~-7i<bTTFbJTIRnb${2 zJle2QiaNC+%p-KDIeVtq-X67=bWum4j>%Z%dZQ~Fqy)L+Gcs{FI();iU=OQO(^A4r ziv;qnsAIzi{TiaPzzcbE#w*zoE%=2_ovQRi#Jsnu3Znm`>+V7wbYx!g+&m_rj$wwb zk2-$PznYcOQJJEpQOA`2(G9x5ZG-iEHShh?9^i3czl7~!DM$Wc(<^!M^{X^X{>k=4 z?5uM9Q79*oSBtDmYwFeR8pL%tn~nO#5Lkb7(zy5Y#Ko9V_kF%`8qB#z9ou<-^rU(o ziIMET0?}LZNfIn`N0$@@qT>Sf9~*T)Bzf{B&I-6SwK@0}GTg{^<o@U?ix=p>;xInZ z?%uH;2~EDPsO>$gBH;?CNEV|y)$ReyKk6Ho|1gEnk$I`|@BT*RqY(0q+8^{&_HbQx zuu|GREY;p)GVloAl7U6nK(KgTU=bQ?F8E5^DL8I8ObfJya$3Id=d@DM1OLdgB?hM| z*rY2s62*|<*u7WqYT_kW%#*KC%f|;ON$7Kvf0k$p&ZJH03%j%ZM_lPL^MJB3Ldolw zHrj8qbL)rDi={#@SjVD{QraWqJ5naTitx(K9tAhNDedn~hJ0#?hPi}7ITlH%usmx4 zZnGsP?_^p`5VzHwgJS=LD|ybj3dWOEN^MU%JrjkR_LBcp$sggyD)MefcE&||#)^+% zSN`w@?Q)!Eg6X_h@;;f)%KI#7#au8(aSUFbv_p~;r`3E^T+DfvWT1s!^OPf{>xxJW ztj`J|Jm_6P*=Cq-i<gDMV*~RPaxmcnAD|kzcN{x8wr^7@gG*o<{KJ~%QrsYiUEOS0 zcXmTd6T{@)y|Wv#I)9z=-5Xiw=bpNj4_(2bDpkUv5_sotP|<iyN8liCTGyU);V)K= zYpSw&cWy(PN7#t@osy<>lk(Ck8nTT4j?2~fzkMU)uRQYp^SjbR;LGka!=kYqa-P8K z71+4QcgK~IuV9*bc)B(2^p<Me2`f-4{7J1}z#X^E<4?{kMUD2F-YeM@+<IJ1FGtHZ z<4!pltZms-(<?hdL!1->b?001;9ea(b0ps>Z*HyWJ@`nQ?Uuu1KYDjdGFiLpL}LZM zPe@ttLrU{rGUi8I5T4xDIEIwY{VD(2n%<X*G4A{a$!dD9lJ~k0rPlN=R_|A<ca^4o zKJSeVvI?_)>lHP<A4ps7_*i8HhsZiqCC}rpQ72TXrgwzA*Rwv`8b^^ea44U5{!B&f zM+=NPk(1Q)UV4zcKd0Wq>itRH<2zKqHsO(#6ONkRcjaBVwW;YHtC}dpx~BL0>b*`f zweTla^BOn*iWDzc)BEvB92s97|E)?W{v(5z)$|$;Dd<iW_BijsGvf{FV>(R?o>tR) zxQpk>HNEj8cpjIyw(+~IjYX}EBk2WN4z^%%O|Qu5LNgl=B8cM{TX0%U@7XNsp~;Q= zwKk4uZ5-U%cvx%Wp{<RhTN{g88xLr0ENpE&xV5pMwK2c7aae2P@Ycp5t&M|P8;7<w z=Cw8+(%R^1Z9K5G(P(WfX`Q$7Sa?kNp?#9v#!sH|!{u`NJr&kBT<#{2Fz%!uFl~0e zZ}YzLzg*t8sr#Fz{mH**<M|dmziC<DG~H8Kb$%U;xU(@SdeKt$x~zPAtLvq2kfv|m zP5(xozGZyf_pAR#9Wpk<S+l?MHNRV_{Oi*6jZdPL(l_kuzVm2@gI_+swN{-Ycpt?t zm3MU3`#aPzChJ?$d_Y)+J5KS7mMgTmvZtM!+0()Zh#o^AvR-WfP+AR6;Kaqxh4(Gy zX?PPf>Mw?v%!o}ab~m&I>^l@Q$rfAo-y*ns=GWHN_h=P%Sr<Delk&TvM%od`oDKw9 zo%58EJ&Q{hVxkUn2|_yA^dRVC0mY{t()V5Y3(t|4Nas9vEjPJc&SNQj#KrO)Yzv+* z&mp$p40+~5;N&^n7Cc>^BW=M`<T=X5T}`#k90WBNB1|2+<T0;Z_>Ihd&0o<$(kZnQ z^Eu}5<%K?F#q_Gv^&ukNRPE;CbYbXEM-rlUM&|nuu_qemJ#}VRXteagbWF?iU|##+ zv*;}c4q_3=bzmvepW5|vH4muV<oOXfz**G)m053r@6NHZ5}O^%q5pEkRz)!xe$E;+ zm*r!s%bZ)L*JW2$snuz{b3N*oeumngvDl8Sl{51h$HNl9={Z@b#}J}aG>+GSp`k#4 zGf4s+D>{Wo6SaHzK@>8CA7qd5<Wi!O&e7#|3_mJuVTnxbQB#tGk}A$-*e7tEk1(vQ z%cb7e$&sq}2|`r8YjvQi_Yht0{?v;kO&qxOxD_+1+?`4Na^FNQ+S1(nRattE4&uQW zdOCR6h+2P<RFj2-G3Nu4I)=E>rNFHYl>6+@WfLi2HeWm>%{gj#ru)a)lXi=)JGiYz zI=BPzR;q(%r#kqC4pbdHR(J5UmsJPZUb~fjk3difR_I~&Y-PR<)Za&`j7}+;M4$e? zI;UTM-;vbP-?D?HGyk%`e^VgIYQo<7`&n4}J0z>WKUR%Gh!saV2N1IRd)`a`QGcJM zvc2^8AG7=Q_pnrdE75lPn*M&QK$6wptn(V-xw6h{wC$T^$F;()Y<mzsabHF+hw{RW zLTNbDd{1Qyne3|12NH<`1mJ1>!gYuun$METAH^;$IzDaQ&&Iq-;m5LWob=n-q)jWC zm<%~lS1s{I9g)|Vjm+Bpn3Bk9Fb7mt?|(48l}KfN%}(v*7f2yHwaLr?ZktydwT%)O z+1_`Xc9kNy?U`NLk4c9g0(>RPzWxm=yj$hmmD-}EYBcIkq2xpZXCeY3g|}h}%QXKb zvkkGP!3gNR#T-sqj1dvfmpJYDQVn6uG5<|Kr7Qy-*Dh0|*F<xhEku5pA^|(dony4* ztd*p(z{BR12S}0R5Lgl9ya4QAQ?p!<1OqP)9UeA4BPCJV-aVtAfTowFpTNduMya*2 zN%!G}sN;^mD$!9&7&LgDcHx$%%)dFSOWm5V`82sTLFgf%s()3D4SnCe268T5sFIz1 zNU_2)NpH3TKWjg#^5b1X3x%aW$fbd}`2<@SCI3rNR*j^4O}~QlqJ8GdrpA5l|5A5v zyjEM07rK!fu8{_UarX-lqZd?aqmtO9DPVFAz9Iw^I&ALqI0=z6x@^I7{n1NNla{-} zI8D2{xO^>JAK?MS;pQ$jGdQuDTDjvnd$1~C|A_l#7tZk8-}RS%z<txl>(yj@wq|bp zw#Cv2vAhw<rIhlxDkV6$(VlW4n4LjR70%#{0B6`DqI_LVbOoSnd011&Xbz2zLiM?i z&Kbchy7=L0^F?08y_os_D@+wxj4RoK2@_O%Q$EkTT%-)*A>&NWl(&f^+ZTzC8<Hrx zs4)5qsE6R(Q|_iOI8s7U&4~#_yC=VMs63ix2~?t!ie6FDFr{7l!e$U9=4`)3$mg?& zWTe`<FMyw%_eLBa5$}&YR7S=A$m$XvNoNBabUa<weq#3;Q(i-ltC7m&A5}Mrj-v}7 z<`Sj^xpx(jiDf12+1{v^i`F9djVC<n8H~NTH;E(74*VT;_+!_Ml*8oG`c;K69i{av z^&_kw3-n{IepKs6rGAv@hf6;S^~0tgqVq*zqA16sQ$IwPjW5;E*uep0(y)XHPJaPn z`3~GF%|kkUs9K&f^wM~u{xsU1IN<+L_wMmgRae9ROcEgB;u(}EBA2L9h$4`Rl_+Wk z5;!9>2na%{3TmZzsnTQyP!R(&5l+XcJXTv<+ehANA8oZyZB;-jl7L*j1+5CA<>Kue zM-;q32*UinYwvSrCaA5?^L~DRynL9PbM}3&z4qE`ueJ8tu0OX>)jLMw0&)b6<+YeT ztShjZ7wq!2QuOi`u3*~A9`~eY4rkbSw`I2be6ugC+`n3|Q|-NHEI}a>5N|HcPGG^o z2EvW_ulcL=BhGJmJF0%_iw>o(Nvf`(#U(q<zA~}&S-xq;b66!(=U1rjdc&t$_eoP# zZRyJ@xtH`E{eH2reDi4;8nIxP{6#*~3vqV9^ejB+4UlNgYtuq;6Q}q;uJi$y<_uHr zsw?*k%2phieUUiny$U<BkpHWYUmVH-JEQRxu-bWxKRNiV23LVD#Q>5yO}atPgcfA{ z)M~`9mA`8IpU@-M!~+a#;UWLPHQomB7EYcv1-1<Fq{8DOVGUEIrSk-j4<KJtcsz>Y zLe}%(@j&7;r7t6v+R(VuEzC@%q%^@;$Z$%6750jSX0w@8h+C6v6g-7T4`%)$)?cHO zjk-;;8)cWUN{rXS$=}J;Fq0{nDEaH_jQG6C(y|Hu*cU;i%wv$ipYG7q_PJ2sb9L=~ zf{tP9K50zYT4k$8YA=r(tQ>h*jbHKCw4TP|kH@NF^|&t}kCe(5%v@SVON3U~pY9T> zjfEW_nk#p`2}7_#BCQi-7iHzp6JQO#$C7yiX8%NfERmdvfL<L(OiyCQ>zG%wF#%$} znV*sMEhq0qa;n!jw^4J;^)jby@UjwUy`JQ9PP%l({nCZD_vo1@*->1w8+<`dt36Ds zvox*}u^QIFdkIr?E>XUeS552A=>eyQb7_SmJ6}>b^7t)+Bd?w2;>fR<0!k~|!6rUa z`loUtC~qm9mw#dIHC(Emcd3FEQNxRPD}0GqkTsqub4Z!=a^7Wtx_lv-DF2u?Bso{d zBcHrIT>b?i3dIxUOXRg8Q4Xh|p0nKNboV*VeO9~AA?~xxeFog8&wcKtnNr?P_u1k; zo80FU?sF;6aB5&Uv|ydICP(u23(4!9kH40k?wkJ|sruMR^pQ-)@}lxk{P}-J?*@7F z?*CBfH_*HK+cm9gAX@Z2RUb#sqU;{3>~E)UrPk}3c0_~-eXQTf_dg?Sb@8L<nH-$0 zI3)C}&Hj(mgr4#L2u=?aJ;TXz#%cRb^z4YHXW)_^Y|P%(NYhKth@Mx`z0cCr?1H)% z)T%6cQ4WO&Cdqx$3UT`r1#$CXT$d^Bb*hWF|0KU&q|YTjQ@ZbDh#QIrDOV1U4HGMk zSsGp4J7vxXF&l_BH@MX6u5w|S^Y|<1)%YyEdWP1!NB`0tHQOCd-dnzv;Be}<<x7c` z`>=<}`LF6Qk^!>@S~?El{zN&&Fh!{8bdeZf{y$MPA_p^<l_`%kLXO0k(YuQoin9`7 zx=W7s*?%}zG1aMVZ%<I<=n6E3njAfFjKpYS!C%>rqUDG4g9F#D#Sx8EveW)k6a9d- z<g|(F$9}_zVp^>BEGL+j9}7#g^<r3w!&`gg6T$;S=GuTV%^5k@tFc1Wn7!Xe^jTC| z#(sQ=eSy)gHJsOhrxjmuscvUT{lW~1vIDXJBT1{Ua+T6!cO1^tR5UH>uym6^yTj|O zr|SED^<CPigV%e(�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 AN&o-= diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src b/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src deleted file mode 100644 index e3f22c0f0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src +++ /dev/null @@ -1,11 +0,0 @@ -{application, glerm, [ - {vsn, "0.1.0"}, - {applications, [gleam_community_ansi, - gleam_erlang, - gleam_otp, - gleam_stdlib, - gleeunit]}, - {description, "A terminal wrapper for Gleam"}, - {modules, [glerm]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.erl b/test-community-packages-javascript/build/packages/glerm/src/glerm.erl deleted file mode 100644 index 09ab08df23d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm.erl +++ /dev/null @@ -1,397 +0,0 @@ --module(glerm). --compile([no_auto_import, nowarn_unused_vars]). - --export([selector/0, clear/0, draw/1, start_listener_spec/1, start_listener/2, print/1, size/0, move_to/2, enable_raw_mode/0, disable_raw_mode/0, enter_alternate_screen/0, leave_alternate_screen/0, enable_mouse_capture/0, disable_mouse_capture/0]). --export_type([modifier/0, key_code/0, mouse_button/0, mouse_event/0, focus_event/0, event/0, listener_message/1, listener_spec/2]). - --type modifier() :: shift | alt | control. - --type key_code() :: {character, binary()} | - enter | - backspace | - left | - right | - down | - up | - unsupported. - --type mouse_button() :: mouse_left | mouse_right | mouse_middle. - --type mouse_event() :: {mouse_down, - mouse_button(), - gleam@option:option(modifier())} | - {mouse_up, mouse_button(), gleam@option:option(modifier())} | - {drag, mouse_button(), gleam@option:option(modifier())} | - moved | - scroll_down | - scroll_up. - --type focus_event() :: lost | gained. - --type event() :: {focus, focus_event()} | - {key, key_code(), gleam@option:option(modifier())} | - {mouse, mouse_event()} | - {resize, integer(), integer()} | - {unknown, binary(), gleam@dynamic:dynamic()}. - --type listener_message(GUP) :: {term, event()} | {user, GUP}. - --type listener_spec(GUQ, GUR) :: {listener_spec, - fun(() -> {GUQ, gleam@option:option(gleam@erlang@process:selector(GUR))}), - fun((listener_message(GUR), GUQ) -> gleam@otp@actor:next(GUQ))}. - --spec decode_atom(binary(), GUW) -> fun((gleam@dynamic:dynamic()) -> {ok, GUW} | - {error, list(gleam@dynamic:decode_error())}). -decode_atom(Val, Actual) -> - Real_atom = erlang:binary_to_atom(Val), - Decode = gleam@function:compose( - fun gleam@erlang@atom:from_dynamic/1, - fun(Maybe_atom) -> _pipe = Maybe_atom, - gleam@result:then( - _pipe, - fun(Decoded) -> case Decoded =:= Real_atom of - true -> - {ok, Real_atom}; - - false -> - {error, - [{decode_error, - Val, - erlang:atom_to_binary(Decoded), - []}]} - end end - ) end - ), - fun(Msg) -> _pipe@1 = Decode(Msg), - gleam@result:replace(_pipe@1, Actual) end. - --spec modifier_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, - gleam@option:option(modifier())} | - {error, list(gleam@dynamic:decode_error())}). -modifier_decoder() -> - Decode_some = decode_atom( - <<"some"/utf8>>, - fun(Field@0) -> {some, Field@0} end - ), - gleam@dynamic:any( - [decode_atom(<<"none"/utf8>>, none), - gleam@function:compose( - gleam@dynamic:tuple2( - Decode_some, - decode_atom(<<"shift"/utf8>>, shift) - ), - fun(_capture) -> - gleam@result:replace(_capture, {some, shift}) - end - ), - gleam@function:compose( - gleam@dynamic:tuple2( - Decode_some, - decode_atom(<<"alt"/utf8>>, alt) - ), - fun(_capture@1) -> - gleam@result:replace(_capture@1, {some, alt}) - end - ), - gleam@function:compose( - gleam@dynamic:tuple2( - Decode_some, - decode_atom(<<"control"/utf8>>, control) - ), - fun(_capture@2) -> - gleam@result:replace(_capture@2, {some, control}) - end - )] - ). - --spec keycode_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, key_code()} | - {error, list(gleam@dynamic:decode_error())}). -keycode_decoder() -> - gleam@dynamic:any( - [begin - _pipe = gleam@dynamic:tuple2( - decode_atom( - <<"character"/utf8>>, - fun(Field@0) -> {character, Field@0} end - ), - fun gleam@dynamic:string/1 - ), - gleam@function:compose( - _pipe, - fun(Maybe_pair) -> case Maybe_pair of - {ok, {_, Value}} -> - {ok, {character, Value}}; - - {error, Err} -> - {error, Err} - end end - ) - end, - decode_atom(<<"enter"/utf8>>, enter), - decode_atom(<<"backspace"/utf8>>, backspace), - decode_atom(<<"left"/utf8>>, left), - decode_atom(<<"right"/utf8>>, right), - decode_atom(<<"down"/utf8>>, down), - decode_atom(<<"up"/utf8>>, up), - decode_atom(<<"unsupported"/utf8>>, unsupported)] - ). - --spec mouse_button_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, - mouse_button()} | - {error, list(gleam@dynamic:decode_error())}). -mouse_button_decoder() -> - gleam@dynamic:any( - [decode_atom(<<"mouse_left"/utf8>>, mouse_left), - decode_atom(<<"mouse_right"/utf8>>, mouse_right), - decode_atom(<<"mouse_middle"/utf8>>, mouse_middle)] - ). - --spec mouse_event_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, - mouse_event()} | - {error, list(gleam@dynamic:decode_error())}). -mouse_event_decoder() -> - gleam@dynamic:any( - [begin - _pipe = gleam@dynamic:tuple3( - decode_atom( - <<"mouse_down"/utf8>>, - fun(Field@0, Field@1) -> {mouse_down, Field@0, Field@1} end - ), - mouse_button_decoder(), - modifier_decoder() - ), - gleam@function:compose( - _pipe, - fun(Maybe_triple) -> case Maybe_triple of - {ok, {_, Button, Modifier}} -> - {ok, {mouse_down, Button, Modifier}}; - - {error, Err} -> - {error, Err} - end end - ) - end, - begin - _pipe@1 = gleam@dynamic:tuple3( - decode_atom( - <<"mouse_up"/utf8>>, - fun(Field@0, Field@1) -> {mouse_up, Field@0, Field@1} end - ), - mouse_button_decoder(), - modifier_decoder() - ), - gleam@function:compose( - _pipe@1, - fun(Maybe_triple@1) -> case Maybe_triple@1 of - {ok, {_, Button@1, Modifier@1}} -> - {ok, {mouse_up, Button@1, Modifier@1}}; - - {error, Err@1} -> - {error, Err@1} - end end - ) - end, - begin - _pipe@2 = gleam@dynamic:tuple3( - decode_atom( - <<"drag"/utf8>>, - fun(Field@0, Field@1) -> {drag, Field@0, Field@1} end - ), - mouse_button_decoder(), - modifier_decoder() - ), - gleam@function:compose( - _pipe@2, - fun(Maybe_triple@2) -> case Maybe_triple@2 of - {ok, {_, Button@2, Modifier@2}} -> - {ok, {drag, Button@2, Modifier@2}}; - - {error, Err@2} -> - {error, Err@2} - end end - ) - end, - decode_atom(<<"moved"/utf8>>, moved), - decode_atom(<<"scroll_down"/utf8>>, scroll_down), - decode_atom(<<"scroll_up"/utf8>>, scroll_up)] - ). - --spec selector() -> gleam@erlang@process:selector(event()). -selector() -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@4 = gleam@erlang@process:selecting_record2( - _pipe, - erlang:binary_to_atom(<<"focus"/utf8>>), - fun(Inner) -> _pipe@1 = Inner, - _pipe@2 = (gleam@dynamic:any( - [decode_atom(<<"gained"/utf8>>, gained), - decode_atom(<<"lost"/utf8>>, lost)] - ))(_pipe@1), - _pipe@3 = gleam@result:map( - _pipe@2, - fun(Field@0) -> {focus, Field@0} end - ), - gleam@result:unwrap(_pipe@3, {unknown, <<"focus"/utf8>>, Inner}) end - ), - _pipe@5 = gleam@erlang@process:selecting_record3( - _pipe@4, - erlang:binary_to_atom(<<"key"/utf8>>), - fun(First, Second) -> - Key_code = (keycode_decoder())(First), - Modifier = (modifier_decoder())(Second), - case {Key_code, Modifier} of - {{ok, Code}, {ok, Mod}} -> - {key, Code, Mod}; - - {_, _} -> - {unknown, - <<"key"/utf8>>, - gleam@dynamic:from([First, Second])} - end - end - ), - _pipe@9 = gleam@erlang@process:selecting_record2( - _pipe@5, - erlang:binary_to_atom(<<"mouse"/utf8>>), - fun(Inner@1) -> _pipe@6 = Inner@1, - _pipe@7 = (mouse_event_decoder())(_pipe@6), - _pipe@8 = gleam@result:map( - _pipe@7, - fun(Field@0) -> {mouse, Field@0} end - ), - gleam@result:lazy_unwrap( - _pipe@8, - fun() -> {unknown, <<"mouse"/utf8>>, Inner@1} end - ) end - ), - gleam@erlang@process:selecting_record3( - _pipe@9, - erlang:binary_to_atom(<<"resize"/utf8>>), - fun(First@1, Second@1) -> - Columns = gleam@dynamic:int(First@1), - Rows = gleam@dynamic:int(Second@1), - case {Columns, Rows} of - {{ok, Col}, {ok, Rows@1}} -> - {resize, Col, Rows@1}; - - {_, _} -> - {unknown, - <<"resize"/utf8>>, - gleam@dynamic:from([First@1, Second@1])} - end - end - ). - --spec clear() -> nil. -clear() -> - glerm_ffi:clear(). - --spec draw(list({integer(), integer(), binary()})) -> {ok, nil} | {error, nil}. -draw(Field@0) -> - glerm_ffi:draw(Field@0). - --spec start_listener_spec(listener_spec(any(), GVF)) -> {ok, - gleam@erlang@process:subject(listener_message(GVF))} | - {error, gleam@otp@actor:start_error()}. -start_listener_spec(Spec) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Pid = erlang:self(), - _assert_subject = (erlang:element(2, Spec))(), - {State, User_selector} = case _assert_subject of - {_, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glerm"/utf8>>, - function => <<"start_listener_spec"/utf8>>, - line => 314}) - end, - Term_selector = begin - _pipe = selector(), - gleam_erlang_ffi:map_selector( - _pipe, - fun(Field@0) -> {term, Field@0} end - ) - end, - Selector = begin - _pipe@1 = User_selector, - _pipe@4 = gleam@option:map( - _pipe@1, - fun(User) -> _pipe@2 = User, - _pipe@3 = gleam_erlang_ffi:map_selector( - _pipe@2, - fun(Field@0) -> {user, Field@0} end - ), - gleam_erlang_ffi:merge_selector( - Term_selector, - _pipe@3 - ) end - ), - gleam@option:unwrap(_pipe@4, Term_selector) - end, - gleam@erlang@process:start( - fun() -> glerm_ffi:listen(Pid) end, - true - ), - {ready, State, Selector} - end, - 500, - erlang:element(3, Spec)} - ). - --spec start_listener(GVL, fun((event(), GVL) -> gleam@otp@actor:next(GVL))) -> {ok, - gleam@erlang@process:subject(event())} | - {error, gleam@otp@actor:start_error()}. -start_listener(Initial_state, Loop) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Pid = erlang:self(), - gleam@erlang@process:start( - fun() -> glerm_ffi:listen(Pid) end, - true - ), - {ready, Initial_state, selector()} - end, - 500, - Loop} - ). - --spec print(bitstring()) -> {ok, nil} | {error, nil}. -print(Field@0) -> - glerm_ffi:print(Field@0). - --spec size() -> {ok, {integer(), integer()}} | {error, nil}. -size() -> - glerm_ffi:size(). - --spec move_to(integer(), integer()) -> nil. -move_to(Field@0, Field@1) -> - glerm_ffi:move_to(Field@0, Field@1). - --spec enable_raw_mode() -> {ok, nil} | {error, nil}. -enable_raw_mode() -> - glerm_ffi:enable_raw_mode(). - --spec disable_raw_mode() -> {ok, nil} | {error, nil}. -disable_raw_mode() -> - glerm_ffi:disable_raw_mode(). - --spec enter_alternate_screen() -> {ok, nil} | {error, nil}. -enter_alternate_screen() -> - glerm_ffi:enter_alternate_screen(). - --spec leave_alternate_screen() -> {ok, nil} | {error, nil}. -leave_alternate_screen() -> - glerm_ffi:leave_alternate_screen(). - --spec enable_mouse_capture() -> {ok, nil} | {error, nil}. -enable_mouse_capture() -> - glerm_ffi:enable_mouse_capture(). - --spec disable_mouse_capture() -> {ok, nil} | {error, nil}. -disable_mouse_capture() -> - glerm_ffi:disable_mouse_capture(). diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam b/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam deleted file mode 100644 index dc0f1394352..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam +++ /dev/null @@ -1,354 +0,0 @@ -import gleam/dynamic.{DecodeError, Decoder, Dynamic} -import gleam/function -import gleam/option.{None, Option, Some} -import gleam/result -import gleam/erlang/atom -import gleam/erlang/process.{Pid, Selector, Subject} -import gleam/otp/actor - -/// These represent the noted keys being held down when another action is taken, -/// like pressing another key or mouse button. For certain keys, things like -/// `Shift` will not be set, but instead return something like `A`. -pub type Modifier { - Shift - Alt - Control -} - -/// A particular keyboard key that was pressed. Either a character with its -/// value, or a special key. The `Unsupported` is for things like `PageUp`, etc -/// that I'm just not handling yet. -pub type KeyCode { - Character(String) - Enter - Backspace - Left - Right - Down - Up - Unsupported -} - -/// Which mouse button was pressed. These are prefixed with `Mouse` in order to -/// avoid conflicting with the arrow keys defined in `KeyCode`. -pub type MouseButton { - MouseLeft - MouseRight - MouseMiddle -} - -/// The possible types of mouse events. I think most of these will also -/// have the mouse cursor position attached. That is not supported at the moment. -pub type MouseEvent { - MouseDown(button: MouseButton, modifier: Option(Modifier)) - MouseUp(button: MouseButton, modifier: Option(Modifier)) - Drag(button: MouseButton, modifier: Option(Modifier)) - Moved - ScrollDown - ScrollUp -} - -/// When the terminal window is focused or un-focused. -pub type FocusEvent { - Lost - Gained -} - -/// The possible events coming back from the terminal. `Unknown` should -/// realistically never happen, since this library controls both ends of the -/// message passing. -pub type Event { - Focus(event: FocusEvent) - Key(key: KeyCode, modifier: Option(Modifier)) - Mouse(event: MouseEvent) - Resize(Int, Int) - Unknown(tag: String, message: Dynamic) -} - -fn decode_atom(val: String, actual: a) -> Decoder(a) { - let real_atom = atom.create_from_string(val) - let decode = - function.compose( - atom.from_dynamic, - fn(maybe_atom) { - maybe_atom - |> result.then(fn(decoded) { - case decoded == real_atom { - True -> Ok(real_atom) - False -> Error([DecodeError(val, atom.to_string(decoded), [])]) - } - }) - }, - ) - fn(msg) { - decode(msg) - |> result.replace(actual) - } -} - -fn modifier_decoder() -> Decoder(Option(Modifier)) { - let decode_some = decode_atom("some", Some) - dynamic.any([ - decode_atom("none", None), - function.compose( - dynamic.tuple2(decode_some, decode_atom("shift", Shift)), - result.replace(_, Some(Shift)), - ), - function.compose( - dynamic.tuple2(decode_some, decode_atom("alt", Alt)), - result.replace(_, Some(Alt)), - ), - function.compose( - dynamic.tuple2(decode_some, decode_atom("control", Control)), - result.replace(_, Some(Control)), - ), - ]) -} - -fn keycode_decoder() -> Decoder(KeyCode) { - dynamic.any([ - dynamic.tuple2(decode_atom("character", Character), dynamic.string) - |> function.compose(fn(maybe_pair) { - case maybe_pair { - Ok(#(_character, value)) -> Ok(Character(value)) - Error(err) -> Error(err) - } - }), - decode_atom("enter", Enter), - decode_atom("backspace", Backspace), - decode_atom("left", Left), - decode_atom("right", Right), - decode_atom("down", Down), - decode_atom("up", Up), - decode_atom("unsupported", Unsupported), - ]) -} - -fn mouse_button_decoder() -> Decoder(MouseButton) { - dynamic.any([ - decode_atom("mouse_left", MouseLeft), - decode_atom("mouse_right", MouseRight), - decode_atom("mouse_middle", MouseMiddle), - ]) -} - -fn mouse_event_decoder() -> Decoder(MouseEvent) { - dynamic.any([ - dynamic.tuple3( - decode_atom("mouse_down", MouseDown), - mouse_button_decoder(), - modifier_decoder(), - ) - |> function.compose(fn(maybe_triple) { - case maybe_triple { - Ok(#(_mouse_down, button, modifier)) -> Ok(MouseDown(button, modifier)) - Error(err) -> Error(err) - } - }), - dynamic.tuple3( - decode_atom("mouse_up", MouseUp), - mouse_button_decoder(), - modifier_decoder(), - ) - |> function.compose(fn(maybe_triple) { - case maybe_triple { - Ok(#(_mouse_up, button, modifier)) -> Ok(MouseUp(button, modifier)) - Error(err) -> Error(err) - } - }), - dynamic.tuple3( - decode_atom("drag", Drag), - mouse_button_decoder(), - modifier_decoder(), - ) - |> function.compose(fn(maybe_triple) { - case maybe_triple { - Ok(#(_drag, button, modifier)) -> Ok(Drag(button, modifier)) - Error(err) -> Error(err) - } - }), - decode_atom("moved", Moved), - decode_atom("scroll_down", ScrollDown), - decode_atom("scroll_up", ScrollUp), - ]) -} - -/// The events from the NIF are sent as messages to the calling process. These -/// do not go through a `process.Subject`, so they need to be explicitly -/// extracted from the mailbox. This selector will grab the given `Event`s for -/// each message that comes in. -pub fn selector() -> Selector(Event) { - process.new_selector() - |> process.selecting_record2( - atom.create_from_string("focus"), - fn(inner) { - inner - |> dynamic.any([decode_atom("gained", Gained), decode_atom("lost", Lost)]) - |> result.map(Focus) - |> result.unwrap(Unknown("focus", inner)) - }, - ) - |> process.selecting_record3( - atom.create_from_string("key"), - fn(first, second) { - let key_code = keycode_decoder()(first) - let modifier = modifier_decoder()(second) - case key_code, modifier { - Ok(code), Ok(mod) -> Key(code, mod) - _, _ -> Unknown("key", dynamic.from([first, second])) - } - }, - ) - |> process.selecting_record2( - atom.create_from_string("mouse"), - fn(inner) { - inner - |> mouse_event_decoder() - |> result.map(Mouse) - |> result.lazy_unwrap(fn() { Unknown("mouse", inner) }) - }, - ) - |> process.selecting_record3( - atom.create_from_string("resize"), - fn(first, second) { - let columns = dynamic.int(first) - let rows = dynamic.int(second) - case columns, rows { - Ok(col), Ok(rows) -> Resize(col, rows) - _, _ -> Unknown("resize", dynamic.from([first, second])) - } - }, - ) -} - -/// Fully clears the terminal window -pub external fn clear() -> Nil = - "glerm_ffi" "clear" - -/// Write some string to the screen at the given #(column, row) coordinate -pub external fn draw(commands: List(#(Int, Int, String))) -> Result(Nil, Nil) = - "glerm_ffi" "draw" - -/// This is the "meat" of the library. This will fire up the NIF, which spawns -/// a thread to read for terminal events. The `Pid` provided here is where the -/// messages will be sent. -external fn listen(pid: Pid) -> Result(Nil, Nil) = - "glerm_ffi" "listen" - -/// Writes the given text wherever the cursor is -pub external fn print(data: BitString) -> Result(Nil, Nil) = - "glerm_ffi" "print" - -/// Gives back the #(column, row) count of the current terminal. This can be -/// called to get the initial size, and then updated when `Resize` events -/// come in. -pub external fn size() -> Result(#(Int, Int), Nil) = - "glerm_ffi" "size" - -/// Moves the cursor to the given location -pub external fn move_to(column: Int, row: Int) -> Nil = - "glerm_ffi" "move_to" - -/// Enables "raw mode" for the terminal. This will do a better job than I can -/// at explaining what all that entails: -/// -/// https://docs.rs/crossterm/latest/crossterm/terminal/index.html#raw-mode -/// -/// If you want to control the entire screen, capture all input events, and -/// place the cursor anywhere, this is what you want. -pub external fn enable_raw_mode() -> Result(Nil, Nil) = - "glerm_ffi" "enable_raw_mode" - -/// Turns off raw mode. This will disable the features described in -/// `enable_raw_mode`. -pub external fn disable_raw_mode() -> Result(Nil, Nil) = - "glerm_ffi" "disable_raw_mode" - -/// This will create a new terminal "window" that you can interact with. This -/// will preserve the user's existing terminal when exiting the program, or -/// calling `leave_alternate_screen`. -pub external fn enter_alternate_screen() -> Result(Nil, Nil) = - "glerm_ffi" "enter_alternate_screen" - -/// See: `enter_alternate_screen` -pub external fn leave_alternate_screen() -> Result(Nil, Nil) = - "glerm_ffi" "leave_alternate_screen" - -/// This enables the capturing of mouse events. Without this, those event types -/// will not be emitted by the NIF. -pub external fn enable_mouse_capture() -> Result(Nil, Nil) = - "glerm_ffi" "enable_mouse_capture" - -/// This will stop the capture of mouse events in the terminal. -pub external fn disable_mouse_capture() -> Result(Nil, Nil) = - "glerm_ffi" "disable_mouse_capture" - -pub type ListenerMessage(user_message) { - Term(Event) - User(user_message) -} - -pub type ListenerSubject(user_message) = - Subject(ListenerMessage(user_message)) - -pub type EventSubject = - Subject(Event) - -pub type ListenerSpec(state, user_message) { - ListenerSpec( - init: fn() -> #(state, Option(Selector(user_message))), - loop: fn(ListenerMessage(user_message), state) -> actor.Next(state), - ) -} - -/// This will start the NIF listener and set up the `Event` selector. The spec -/// argument allows for behavior during the initialization of the actor. That -/// function returns the initial state, and an optional user selector. This -/// allows this actor to also receive any user-defined messages. -pub fn start_listener_spec( - spec: ListenerSpec(state, user_message), -) -> Result(ListenerSubject(user_message), actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let pid = process.self() - let assert #(state, user_selector) = spec.init() - let term_selector = - selector() - |> process.map_selector(Term) - let selector = - user_selector - |> option.map(fn(user) { - user - |> process.map_selector(User) - |> process.merge_selector(term_selector, _) - }) - |> option.unwrap(term_selector) - process.start(fn() { listen(pid) }, True) - actor.Ready(state, selector) - }, - init_timeout: 500, - loop: spec.loop, - )) -} - -/// If you are not planning on sending custom messages to the terminal listener, -/// this method is the simplest. Give an initial state for the actor, and the -/// loop will receive only `Event`s and your provided state. To allow this -/// actor to receive additional user-defined messages, see `start_listener_spec` -pub fn start_listener( - initial_state: state, - loop: fn(Event, state) -> actor.Next(state), -) -> Result(EventSubject, actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let pid = process.self() - process.start(fn() { listen(pid) }, True) - actor.Ready(initial_state, selector()) - }, - init_timeout: 500, - loop: loop, - )) -} -// TODO: -// - test? -// - docs diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl b/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl deleted file mode 100644 index 021fbde4915..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(glerm_ffi). - --export([listen/1, print/1, size/0, clear/0, move_to/2, draw/1, enable_raw_mode/0, - disable_raw_mode/0, enter_alternate_screen/0, leave_alternate_screen/0, enable_mouse_capture/0, disable_mouse_capture/0]). - --nifs([{listen, 1}, - {print, 1}, - {size, 0}, - {clear, 0}, - {move_to, 2}, - {draw, 1}, - {enable_raw_mode, 0}, - {disable_raw_mode, 0}, - {enter_alternate_screen, 0}, - {leave_alternate_screen, 0}, - {enable_mouse_capture, 0}, - {disable_mouse_capture, 0}]). - --on_load init/0. - -init() -> - Arch = erlang:system_info(system_architecture), - Priv = code:priv_dir(glerm), - ArchPath = - case Arch of - "x86_64-pc-linux" ++ _ -> - filename:join(Priv, "linux"); - "win32" -> - filename:join(Priv, "windows"); - "x86_64-apple-drawin" ++ _ -> - filename:join(Priv, "macos") - end, - Path = filename:join(ArchPath, libglerm), - erlang:load_nif(Path, 0). - -listen(_Pid) -> - exit(nif_library_not_loaded). - -print(_Data) -> - exit(nif_library_not_loaded). - -size() -> - exit(nif_library_not_loaded). - -clear() -> - exit(nif_library_not_loaded). - -move_to(_Column, _Row) -> - exit(nif_library_not_loaded). - -draw(_Commands) -> - exit(nif_library_not_loaded). - -enable_raw_mode() -> - exit(nif_library_not_loaded). - -disable_raw_mode() -> - exit(nif_library_not_loaded). - -enter_alternate_screen() -> - exit(nif_library_not_loaded). -leave_alternate_screen() -> - exit(nif_library_not_loaded). -enable_mouse_capture() -> - exit(nif_library_not_loaded). -disable_mouse_capture() -> - exit(nif_library_not_loaded). diff --git a/test-community-packages-javascript/build/packages/gliew/README.md b/test-community-packages-javascript/build/packages/gliew/README.md deleted file mode 100644 index 4120dfe33af..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/README.md +++ /dev/null @@ -1,393 +0,0 @@ -# gliew - -[![Package Version](https://img.shields.io/hexpm/v/gliew)](https://hex.pm/packages/gliew) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gliew/) - -An **experimental** web framework with server-side rendering and optional live updating UI (à la Phoenix's LiveView) for gleam. - -## Quick start - -Usage is similar to [mist](https://hexdocs.pm/mist/) except the handler function should return a [nakai](https://hexdocs.pm/nakai/) node tree. - -```gleam -import gleam/erlang/process -import gleam/http.{Get} -import gleam/http/request -import nakai/html -import gliew - -pub fn main() { - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - Get, ["hello"] -> - html.div_text([], "Hello gleam!") - |> gliew.view(200) - _, _ -> - html.div_text([], "Hello world!") - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} -``` - -### Live mounts - -In order to have some elements of the HTML live updating you will need to use live mounts. - -They can be either used by calling the `gliew.live_mount` function directly: - -```gleam -import gleam/int -import gleam/option.{Option} -import gleam/erlang/process.{Subject} -import gleam/http/request -import nakai/html -import gliew - -pub fn main() { - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - _, _ -> - html.div( - [], - [ - html.div_text([], "counter is at:"), - gliew.live_mount( - mount: mount_counter, - with: Nil, - render: render_counter, - ), - ], - ) - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} - -// The render function is called with `None` on -// initial render but `Some(a)` every time there -// is a new value on the subject returned by the -// mount function. -fn render_counter(assign: Option(Int)) { - html.div_text( - [], - assign - |> option.unwrap(0) - |> int.to_string, - ) -} - -// This is the mount function. -fn mount_counter(_ctx) { - let subject = process.new_subject() - - let _ = process.start(fn() { loop(subject, 0) }, True) - - subject -} - -// Counter loop for demonstration purposes. -fn loop(subject: Subject(Int), current: Int) { - process.send(subject, current) - process.sleep(1000) - loop(subject, current + 1) -} -``` - -But a nicer way (IMO) is to use the `use` syntax to turn a function into a live mount by default. - -```gleam -import gleam/int -import gleam/option -import gleam/erlang/process.{Subject} -import gleam/http/request -import nakai/html -import gliew - -pub fn main() { - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - _, _ -> - html.div([], [html.div_text([], "counter is at:"), counter()]) - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} - -// This becomes the render function. -fn counter() { - // Here we use the `use` syntax as kind of a decorator - // to turn this function into a live mount. - use assign <- gliew.live_mount(mount_counter, with: Nil) - - html.div_text( - [], - assign - |> option.unwrap(0) - |> int.to_string, - ) -} - -// This is still the mount function. -fn mount_counter(_ctx) { - let subject = process.new_subject() - - let _ = process.start(fn() { loop(subject, 0) }, True) - - subject -} - -// Counter loop for demonstartion purposes. -fn loop(subject: Subject(Int), current: Int) { - process.send(subject, current) - process.sleep(1000) - loop(subject, current + 1) -} -``` - -## Example - -The following example has a random string generator and a global counter so that every browser session remains in sync when navigating to `http://localhost:8080/mounts`. - -```gleam -import gleam/int -import gleam/string -import gleam/base -import gleam/option.{None, Some} -import gleam/http.{Get, Post} -import gleam/http/request -import gleam/erlang/process.{Subject} -import gleam/crypto.{strong_random_bytes} -import nakai/html -import nakai/html/attrs -import gliew -// This is only here for this example. -// It implements an actor that keeps an -// incrementing counter and can be -// subscribed to. -import gliew/integration/counter.{ - CounterMessage, reset, start_counter, subscribe, -} - -pub fn main() { - // Start anything that will be needed by the handlers. - // In this case we start an actor that simply increments - // a counter (starting at 0). - // You can subscribe to the counter to be notified every - // time it increments. - let assert Ok(count_actor) = start_counter() - - // Start the gliew server. - // This is a thin wrapper around mist which handles - // rendering your views and starting workers for - // live connections. - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - Get, ["mounts"] -> - mounts_page(count_actor) - |> gliew.view(200) - Post, ["counter", "reset"] -> reset_counter(count_actor) - _, _ -> - home_page() - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} - -// You can just return a simple nakai node tree for -// a static page. -fn home_page() { - html.div_text([], "Hello gleam!") -} - -fn reset_counter(count_actor: Subject(CounterMessage)) { - reset(count_actor) - - gliew.response(204) -} - -fn mounts_page(count_actor: Subject(CounterMessage)) { - // Return the HTML for the page. - html.div( - [ - attrs.style( - [ - "display: flex", "flex-direction: column", "justify-content: center", - "align-items: center", "row-gap: 1em", "height: 100vh", - ] - |> string.join(";"), - ), - ], - [ - // Random text - html.div_text([attrs.style("font-size: x-large")], "Random text for you"), - random_text(), - // Counter - html.div_text([attrs.style("font-size: x-large")], "Counter is at"), - counter(count_actor), - html.div( - [], - [ - html.button_text([], "Reset") - |> gliew.on_click(do: Post, to: "/counter/reset"), - ], - ), - // Explanation text - html.div( - [ - attrs.style( - [ - "background-color: #d0ebf4", "padding: 1em", "color: #222", - "border-radius: 1em", "width: 21em", "margin-top: 0.5em", - ] - |> string.join(";"), - ), - ], - [ - html.div_text( - [attrs.style("font-size: x-large; margin-bottom: 0.5em;")], - "This page is live rendered.", - ), - html.div_text( - [attrs.style("font-size: large")], - "Once the browser has made a connection to the server a new random text is generated every 5 seconds and the counter above should auto-increment.", - ), - ], - ), - ], - ) -} - -// // -// Global counter live mount // -// // - -// A live mount that shows a live updating counter. -fn counter(count_actor: Subject(CounterMessage)) { - // Makes the function a live mount. - // The second parameter passed to `gliew.live_mount` will - // be passed to the mount function (first parameter) - // when the mount is mounted (i.e. the client connects - // back to the server to get live updates). - // - // The returned value is of type `Option(a)` where - // `a` is the type in the Subject returned by mount. - use assign <- gliew.live_mount(counter_mount, with: count_actor) - - let text = case assign { - // View has been mounted and we want to use the - // "live" value that was setup in the mount function. - Some(counter) -> - counter - |> int.to_string - // View is being rendered on the server before - // the client has made a connection back to the server. - // Here we contact the count_actor to get the current - // value. - None -> "Loading.." - } - - // Return the HTML of the view. - html.div_text([attrs.style("font-size: xx-large")], text) -} - -// A mount function that runs once the client connects through -// a websocket. -// This should be used to subscribe to whatever data that should -// be returned to the render function and return the subject. -fn counter_mount(count_actor: Subject(CounterMessage)) { - // Create a new subject. - let subject = process.new_subject() - - // Subscribe to counter. - subscribe(count_actor, subject) - - // Return the subject. - subject -} - -// // -// Random text live mount // -// // - -// A live mount that renders random text on an interval. -fn random_text() { - use assign <- gliew.live_mount(text_mount, with: Nil) - - html.div_text( - [attrs.style("font-size: xx-large")], - assign - |> option.unwrap(random_string()), - ) -} - -// The mount function used for the random_text mount. -// It will generate random text on an interval and -// send it on the returned subject. -fn text_mount(_) { - let subject = process.new_subject() - - let _ = process.start(fn() { loop(subject) }, True) - - subject -} - -// Random text loop. -fn loop(subject: Subject(String)) { - process.send(subject, random_string()) - process.sleep(5000) - loop(subject) -} - -// Helper function to generate random string. -fn random_string() { - strong_random_bytes(10) - |> base.encode64(False) -} -```` - -The above example implementation can be found in `test/integration/live_mounts.gleam` and quickly run with: - -```sh -gleam run -m gliew/integration/live_mounts -``` - -And then navigate to `http://localhost:8080/mounts` to see in action. - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gliew -``` - -and its documentation can be found at <https://hexdocs.pm/gliew>. diff --git a/test-community-packages-javascript/build/packages/gliew/gleam.toml b/test-community-packages-javascript/build/packages/gliew/gleam.toml deleted file mode 100644 index 391330c4572..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gliew" -version = "0.3.0" -description = "A gleam server-side rendered web framework with live updating UI" -repository = { type = "github", user = "arnarg", repo = "gliew" } -licences = ["MIT"] - -[dependencies] -gleam_stdlib = "~> 0.29" -nakai = "~> 0.8" -mist = "~> 0.11" -gleam_erlang = "~> 0.19" -gleam_otp = "~> 0.5" -gleam_crypto = "~> 0.3" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl deleted file mode 100644 index b4e74b38aa5..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(live_mount, { - selecting :: fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl deleted file mode 100644 index 8d99ff6efa5..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(get_worker, { - from :: gleam@erlang@process:subject({ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}), - id :: binary(), - csrf :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl deleted file mode 100644 index 8589100c87b..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(process_tree, { - from :: gleam@erlang@process:subject(nakai@html:node_(gliew@internal@event:event())), - request :: gleam@http@request:request(mist@internal@http:body()), - tree :: nakai@html:node_(gliew@internal@event:event()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl deleted file mode 100644 index 89ac76e9dd3..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(connect_socket, { - socket :: gleam@erlang@process:subject(glisten@handler:handler_message()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl deleted file mode 100644 index a89d582fa33..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(disconnect_socket, { - socket :: gleam@erlang@process:subject(glisten@handler:handler_message()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl deleted file mode 100644 index 2e4eb60f892..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl +++ /dev/null @@ -1 +0,0 @@ --record(live_update, {markup :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl deleted file mode 100644 index be1a4225b8f..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(response, { - status :: integer(), - headers :: list({binary(), binary()}), - body :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl deleted file mode 100644 index 5a9075101ce..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(server, { - port :: integer(), - layout :: fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), - handler :: fun((gleam@http@request:request(mist@internal@http:body())) -> gliew:response()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl deleted file mode 100644 index 96a8047b829..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(view, { - status :: integer(), - headers :: list({binary(), binary()}), - node :: nakai@html:node_(gliew@internal@event:event()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src b/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src deleted file mode 100644 index 91aa7179e93..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src +++ /dev/null @@ -1,17 +0,0 @@ -{application, gliew, [ - {vsn, "0.3.0"}, - {applications, [gleam_crypto, - gleam_erlang, - gleam_otp, - gleam_stdlib, - gleeunit, - mist, - nakai]}, - {description, "A gleam server-side rendered web framework with live updating UI"}, - {modules, [gliew, - gliew@internal@event, - gliew@internal@manager, - gliew@internal@util, - gliew@internal@worker]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew.erl deleted file mode 100644 index 1cf3336b7ff..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew.erl +++ /dev/null @@ -1,495 +0,0 @@ --module(gliew). --compile([no_auto_import, nowarn_unused_vars]). - --export([view/2, response/1, with_header/3, with_body/2, morph/0, append/0, on_click/3, live_mount/3, script/0, new/2, serve/1]). --export_type([response/0, server/0]). - --opaque response() :: {view, - integer(), - list({binary(), binary()}), - nakai@html:node_(gliew@internal@event:event())} | - {response, - integer(), - list({binary(), binary()}), - gleam@option:option(binary())}. - --type server() :: {server, - integer(), - fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), - fun((gleam@http@request:request(mist@internal@http:body())) -> response())}. - --spec view(nakai@html:node_(gliew@internal@event:event()), integer()) -> response(). -view(Node, Status) -> - {view, Status, [], Node}. - --spec response(integer()) -> response(). -response(Status) -> - {response, Status, [], none}. - --spec with_header(response(), binary(), binary()) -> response(). -with_header(Response, Key, Value) -> - case Response of - {view, Status, Headers, Node} -> - _pipe = Headers, - _pipe@1 = gleam@list:prepend(_pipe, {Key, Value}), - {view, Status, _pipe@1, Node}; - - {response, Status@1, Headers@1, Body} -> - _pipe@2 = Headers@1, - _pipe@3 = gleam@list:prepend(_pipe@2, {Key, Value}), - {response, Status@1, _pipe@3, Body} - end. - --spec with_body(response(), binary()) -> response(). -with_body(Response, Body) -> - case Response of - {response, Status, Headers, _} -> - {response, Status, Headers, {some, Body}}; - - _ -> - Response - end. - --spec morph() -> nakai@html@attrs:attr(gliew@internal@event:event()). -morph() -> - {event, <<"gliew-event"/utf8>>, morph}. - --spec append() -> nakai@html@attrs:attr(gliew@internal@event:event()). -append() -> - {event, <<"gliew-event"/utf8>>, append}. - --spec add_attr( - nakai@html:node_(gliew@internal@event:event()), - nakai@html@attrs:attr(gliew@internal@event:event()) -) -> nakai@html:node_(gliew@internal@event:event()). -add_attr(Node, Attr) -> - case Node of - {element, Tag, Attrs, Children} -> - _pipe = Attrs, - _pipe@1 = gleam@list:prepend(_pipe, Attr), - {element, Tag, _pipe@1, Children}; - - {leaf_element, Tag@1, Attrs@1} -> - _pipe@2 = Attrs@1, - _pipe@3 = gleam@list:prepend(_pipe@2, Attr), - {leaf_element, Tag@1, _pipe@3}; - - {html, Attrs@2, Children@1} -> - _pipe@4 = Attrs@2, - _pipe@5 = gleam@list:prepend(_pipe@4, Attr), - {html, _pipe@5, Children@1}; - - {body, Attrs@3, Children@2} -> - _pipe@6 = Attrs@3, - _pipe@7 = gleam@list:prepend(_pipe@6, Attr), - {body, _pipe@7, Children@2}; - - Other -> - Other - end. - --spec on_click( - nakai@html:node_(gliew@internal@event:event()), - gleam@http:method(), - binary() -) -> nakai@html:node_(gliew@internal@event:event()). -on_click(Node, Method, Path) -> - case Method of - get -> - _pipe = Node, - _pipe@1 = add_attr(_pipe, {attr, <<"hx-get"/utf8>>, Path}), - add_attr(_pipe@1, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - post -> - _pipe@2 = Node, - _pipe@3 = add_attr(_pipe@2, {attr, <<"hx-post"/utf8>>, Path}), - add_attr(_pipe@3, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - put -> - _pipe@4 = Node, - _pipe@5 = add_attr(_pipe@4, {attr, <<"hx-put"/utf8>>, Path}), - add_attr(_pipe@5, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - patch -> - _pipe@6 = Node, - _pipe@7 = add_attr(_pipe@6, {attr, <<"hx-patch"/utf8>>, Path}), - add_attr(_pipe@7, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - delete -> - _pipe@8 = Node, - _pipe@9 = add_attr(_pipe@8, {attr, <<"hx-delete"/utf8>>, Path}), - add_attr(_pipe@9, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - _ -> - Node - end. - --spec insert_event( - gliew@internal@event:event(), - nakai@html:node_(gliew@internal@event:event()) -) -> nakai@html:node_(gliew@internal@event:event()). -insert_event(Event, Node) -> - _pipe = Node, - add_attr(_pipe, {event, <<"gliew-event"/utf8>>, Event}). - --spec map_events( - list(nakai@html@attrs:attr(gliew@internal@event:event())), - boolean() -) -> list(nakai@html@attrs:attr(gliew@internal@event:event())). -map_events(Attrs, Render_events) -> - case Render_events of - true -> - gleam@list:map(Attrs, fun(Attr) -> case Attr of - {event, <<"gliew-event"/utf8>>, morph} -> - {attr, <<"hx-swap-oob"/utf8>>, <<"morph"/utf8>>}; - - {event, <<"gliew-event"/utf8>>, append} -> - {attr, <<"hx-swap-oob"/utf8>>, <<"beforeend"/utf8>>}; - - Other -> - Other - end end); - - false -> - Attrs - end. - --spec find_id(list(nakai@html@attrs:attr(gliew@internal@event:event()))) -> {ok, - binary()} | - {error, nil}. -find_id(Attrs) -> - _pipe = Attrs, - gleam@list:find_map(_pipe, fun(Attr) -> case Attr of - {attr, <<"id"/utf8>>, Id} -> - {ok, Id}; - - _ -> - {error, nil} - end end). - --spec random_id() -> binary(). -random_id() -> - <<"g-"/utf8, (gliew@internal@util:random_hex_string(3))/binary>>. - --spec extract_id(nakai@html:node_(gliew@internal@event:event())) -> binary(). -extract_id(Node) -> - _pipe = case Node of - {element, _, Attrs, _} -> - find_id(Attrs); - - {leaf_element, _, Attrs@1} -> - find_id(Attrs@1); - - _ -> - {error, nil} - end, - gleam@result:unwrap(_pipe, random_id()). - --spec has_id(list(nakai@html@attrs:attr(any()))) -> boolean(). -has_id(Attrs) -> - _pipe = Attrs, - gleam@list:any(_pipe, fun(A) -> case A of - {attr, <<"id"/utf8>>, _} -> - true; - - _ -> - false - end end). - --spec ensure_id( - list(nakai@html@attrs:attr(gliew@internal@event:event())), - gleam@option:option(binary()) -) -> list(nakai@html@attrs:attr(gliew@internal@event:event())). -ensure_id(Attrs, Id) -> - case has_id(Attrs) of - true -> - case Id of - {some, Id@1} -> - gleam@list:map(Attrs, fun(Attr) -> case Attr of - {attr, <<"id"/utf8>>, _} -> - nakai@html@attrs:id(Id@1); - - Other -> - Other - end end); - - none -> - Attrs - end; - - false -> - _pipe = Attrs, - gleam@list:prepend( - _pipe, - nakai@html@attrs:id( - begin - _pipe@1 = Id, - gleam@option:unwrap(_pipe@1, random_id()) - end - ) - ) - end. - --spec process_tree( - nakai@html:node_(gliew@internal@event:event()), - gleam@option:option(binary()), - boolean() -) -> nakai@html:node_(gliew@internal@event:event()). -process_tree(Node, Id, Render_events) -> - case Node of - {element, Tag, Attrs, Children} -> - _pipe = Attrs, - _pipe@1 = ensure_id(_pipe, Id), - _pipe@2 = map_events(_pipe@1, Render_events), - {element, Tag, _pipe@2, Children}; - - {leaf_element, Tag@1, Attrs@1} -> - _pipe@3 = Attrs@1, - _pipe@4 = ensure_id(_pipe@3, Id), - _pipe@5 = map_events(_pipe@4, Render_events), - {leaf_element, Tag@1, _pipe@5}; - - Other -> - Other - end. - --spec live_mount( - fun((MEC) -> gleam@erlang@process:subject(MED)), - MEC, - fun((gleam@option:option(MED)) -> nakai@html:node_(gliew@internal@event:event())) -) -> nakai@html:node_(gliew@internal@event:event()). -live_mount(Mount, Context, Render) -> - Tree = begin - _pipe = Render(none), - process_tree(_pipe, none, false) - end, - Id = extract_id(Tree), - _pipe@5 = fun(Selector) -> - Subject = Mount(Context), - _pipe@1 = Selector, - gleam@erlang@process:selecting( - _pipe@1, - Subject, - fun(Val) -> _pipe@2 = Render({some, Val}), - _pipe@3 = process_tree(_pipe@2, {some, Id}, true), - _pipe@4 = nakai:to_inline_string(_pipe@3), - {live_update, _pipe@4} end - ) - end, - _pipe@6 = {live_mount, _pipe@5}, - insert_event(_pipe@6, Tree). - --spec script() -> nakai@html:node_(any()). -script() -> - {fragment, - [{element, - <<"script"/utf8>>, - [nakai@html@attrs:src( - <<"https://unpkg.com/htmx.org@1.9.2/dist/htmx.min.js"/utf8>> - )], - []}, - {element, - <<"script"/utf8>>, - [nakai@html@attrs:src( - <<"https://unpkg.com/htmx.org@1.9.2/dist/ext/ws.js"/utf8>> - )], - []}, - {element, - <<"script"/utf8>>, - [nakai@html@attrs:src( - <<"https://unpkg.com/idiomorph@0.0.8/dist/idiomorph-ext.min.js"/utf8>> - )], - []}]}. - --spec default_layout(nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event()). -default_layout(Content) -> - {html, [], [{head, [script()]}, {body, [], [Content]}]}. - --spec new( - integer(), - fun((gleam@http@request:request(mist@internal@http:body())) -> response()) -) -> server(). -new(Port, Handler) -> - {server, Port, fun default_layout/1, Handler}. - --spec add_headers(gleam@http@response:response(MFW), list({binary(), binary()})) -> gleam@http@response:response(MFW). -add_headers(Response, Headers) -> - _pipe = Headers, - gleam@list:fold(_pipe, Response, fun(Res, Pair) -> _pipe@1 = Res, - gleam@http@response:prepend_header( - _pipe@1, - erlang:element(1, Pair), - erlang:element(2, Pair) - ) end). - --spec to_mist_response( - gleam@http@response:response(any()), - gleam@option:option(binary()) -) -> mist@internal@handler:handler_response(). -to_mist_response(Response, Body) -> - case Body of - {some, Body@1} -> - _pipe = Response, - mist:bit_builder_response( - _pipe, - gleam@bit_builder:from_string(Body@1) - ); - - none -> - _pipe@1 = Response, - mist:empty_response(_pipe@1) - end. - --spec upgrade_connection( - gleam@erlang@process:subject(gliew@internal@manager:message()), - binary(), - binary() -) -> mist@internal@handler:handler_response(). -upgrade_connection(Manager, Session, Csrf) -> - case gliew@internal@manager:get_worker(Manager, Session, Csrf) of - {ok, Worker} -> - _pipe = fun(_, _) -> {ok, nil} end, - _pipe@1 = mist@websocket:with_handler(_pipe), - _pipe@2 = mist@websocket:on_init( - _pipe@1, - fun(Socket) -> gliew@internal@worker:connect(Worker, Socket) end - ), - _pipe@3 = mist@websocket:on_close( - _pipe@2, - fun(Socket@1) -> - gliew@internal@worker:disconnect(Worker, Socket@1) - end - ), - mist:upgrade(_pipe@3); - - {error, nil} -> - _pipe@4 = gleam@http@response:new(401), - mist:empty_response(_pipe@4) - end. - --spec get_params(list({binary(), binary()})) -> {ok, {binary(), binary()}} | - {error, nil}. -get_params(Params) -> - Pmap = gleam@map:from_list(Params), - gleam@result:then( - gleam@map:get(Pmap, <<"session"/utf8>>), - fun(Session) -> - gleam@result:then( - gleam@map:get(Pmap, <<"csrf"/utf8>>), - fun(Csrf) -> {ok, {Session, Csrf}} end - ) - end - ). - --spec parse_params(gleam@http@request:request(mist@internal@http:body())) -> {ok, - {binary(), binary()}} | - {error, nil}. -parse_params(Req) -> - case erlang:element(9, Req) of - {some, Params} -> - case gleam@uri:parse_query(Params) of - {ok, Params@1} -> - _pipe@1 = gleam@list:map( - Params@1, - fun(P) -> - {erlang:element(1, P), - begin - _pipe = erlang:element(2, P), - gleam@string:replace( - _pipe, - <<" "/utf8>>, - <<"+"/utf8>> - ) - end} - end - ), - get_params(_pipe@1); - - {error, nil} -> - {error, nil} - end; - - none -> - {error, nil} - end. - --spec handle_ws_connect( - gleam@erlang@process:subject(gliew@internal@manager:message()), - gleam@http@request:request(mist@internal@http:body()) -) -> mist@internal@handler:handler_response(). -handle_ws_connect(Manager, Req) -> - case parse_params(Req) of - {ok, {Id, Csrf}} -> - upgrade_connection(Manager, Id, Csrf); - - {error, nil} -> - _pipe = gleam@http@response:new(401), - mist:empty_response(_pipe) - end. - --spec handler_func( - gleam@erlang@process:subject(gliew@internal@manager:message()), - fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), - fun((gleam@http@request:request(mist@internal@http:body())) -> response()) -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))). -handler_func(Manager, Layout, Handler) -> - _pipe@7 = fun(Req) -> - case {erlang:element(2, Req), erlang:element(8, Req)} of - {get, <<"/connect"/utf8>>} -> - handle_ws_connect(Manager, Req); - - {_, _} -> - case Handler(Req) of - {response, Status, Headers, Body} -> - _pipe = gleam@http@response:new(Status), - _pipe@1 = add_headers(_pipe, Headers), - to_mist_response(_pipe@1, Body); - - {view, Status@1, Headers@1, Node} -> - _pipe@2 = gleam@http@response:new(Status@1), - _pipe@3 = add_headers(_pipe@2, Headers@1), - mist:bit_builder_response( - _pipe@3, - begin - _pipe@4 = gliew@internal@manager:process_tree( - Manager, - Req, - Node - ), - _pipe@5 = Layout(_pipe@4), - _pipe@6 = nakai:to_string_builder(_pipe@5), - gleam@bit_builder:from_string_builder(_pipe@6) - end - ) - end - end - end, - mist:handler_func(_pipe@7). - --spec serve(server()) -> {ok, nil} | {error, glisten:start_error()}. -serve(Server) -> - gleam@result:'try'( - begin - _pipe = gliew@internal@manager:start_manager(), - gleam@result:map_error(_pipe, fun(Err) -> case Err of - init_timeout -> - acceptor_timeout; - - {init_failed, Reason} -> - {acceptor_failed, Reason}; - - {init_crashed, Any} -> - {acceptor_crashed, Any} - end end) - end, - fun(Manager) -> - mist:serve( - erlang:element(2, Server), - handler_func( - Manager, - erlang:element(3, Server), - erlang:element(4, Server) - ) - ) - end - ). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam deleted file mode 100644 index 884bdbf69ac..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam +++ /dev/null @@ -1,477 +0,0 @@ -import gleam/string -import gleam/list -import gleam/map -import gleam/result -import gleam/option.{None, Option, Some} -import gleam/uri -import gleam/bit_builder -import gleam/otp/actor -import gleam/erlang/process.{Selector, Subject} -import gleam/http.{Get} -import gleam/http/request.{Request} -import gleam/http/response.{Response as HttpResponse} -import mist.{Body} -import mist/websocket -import glisten -import glisten/handler.{HandlerMessage} -import nakai -import nakai/html -import nakai/html/attrs -import gliew/internal/event.{Event, LiveMount} -import gliew/internal/worker.{LiveUpdate, WorkerMessage} -import gliew/internal/manager.{Message as ManagerMessage} -import gliew/internal/util.{random_hex_string} - -const elem_id_prefix = "g-" - -// Response is the final response that should be returned from a -// handler. -// -pub opaque type Response { - View(status: Int, headers: List(#(String, String)), node: html.Node(Event)) - Response(status: Int, headers: List(#(String, String)), body: Option(String)) -} - -/// Creates a view response. -/// -pub fn view(node: html.Node(Event), status: Int) { - View(status, [], node) -} - -/// Creates an empty response without a body. -/// -pub fn response(status: Int) { - Response(status, [], None) -} - -/// Adds a header to a response. -/// -pub fn with_header(response: Response, key key: String, value value: String) { - case response { - View(status, headers, node) -> - headers - |> list.prepend(#(key, value)) - |> View(status, _, node) - Response(status, headers, body) -> - headers - |> list.prepend(#(key, value)) - |> Response(status, _, body) - } -} - -/// Sets body of a response. -/// -pub fn with_body(response: Response, body: String) { - case response { - Response(status, headers, _) -> Response(status, headers, Some(body)) - _ -> response - } -} - -/// Creates a HTML node tree that will be `mounted` -/// and receive live updates with data on `Subject(a)` -/// returned by the mount function. -/// -pub fn live_mount( - mount mount: fn(b) -> Subject(a), - with context: b, - render render: fn(Option(a)) -> html.Node(Event), -) { - // Render initial node tree - let tree = - render(None) - |> process_tree(None, False) - - // Get id from root element - let id = extract_id(tree) - - // Add mount event to root of tree - fn(selector: Selector(WorkerMessage)) { - // Mount component to get subject - let subject = mount(context) - - // Select and map subject - selector - |> process.selecting( - subject, - fn(val) { - render(Some(val)) - |> process_tree(Some(id), True) - |> nakai.to_inline_string - |> LiveUpdate - }, - ) - } - |> LiveMount - |> insert_event(tree) -} - -/// Attaches an on-click handler to a node by specifying -/// the HTTP method and path to make a request to when -/// clicked. -/// -pub fn on_click(node: html.Node(Event), do method: http.Method, to path: String) { - case method { - http.Get -> - node - |> add_attr(attrs.Attr("hx-get", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Post -> - node - |> add_attr(attrs.Attr("hx-post", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Put -> - node - |> add_attr(attrs.Attr("hx-put", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Patch -> - node - |> add_attr(attrs.Attr("hx-patch", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Delete -> - node - |> add_attr(attrs.Attr("hx-delete", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - _ -> node - } -} - -/// Makes the live mount morph the diff of the innerHTML -/// instead of replacing the whole thing. -/// -pub fn morph() { - attrs.Event("gliew-event", event.Morph) -} - -/// Append the innerHTML of the live mount instead of -/// replacing it. -/// -pub fn append() { - attrs.Event("gliew-event", event.Append) -} - -// Add an attribute to the provided node. -// -fn add_attr(node: html.Node(Event), attr: attrs.Attr(Event)) { - case node { - html.Element(tag, attrs, children) -> - attrs - |> list.prepend(attr) - |> html.Element(tag, _, children) - html.LeafElement(tag, attrs) -> - attrs - |> list.prepend(attr) - |> html.LeafElement(tag, _) - html.Html(attrs, children) -> - attrs - |> list.prepend(attr) - |> html.Html(children) - html.Body(attrs, children) -> - attrs - |> list.prepend(attr) - |> html.Body(children) - // Other nodes don't accept attributes - // we return them unchanged - other -> other - } -} - -// Insert the event to the node. -// -fn insert_event(event: Event, node: html.Node(Event)) { - node - |> add_attr(attrs.Event("gliew-event", event)) -} - -// Adds the id attribute to the node if provided, otherwise -// generates it. -// -fn process_tree(node: html.Node(Event), id: Option(String), render_events: Bool) { - case node { - html.Element(tag, attrs, children) -> - attrs - |> ensure_id(id) - |> map_events(render_events) - |> html.Element(tag, _, children) - html.LeafElement(tag, attrs) -> - attrs - |> ensure_id(id) - |> map_events(render_events) - |> html.LeafElement(tag, _) - other -> other - } -} - -// Transforms event attributes into actual htmx attributes. -// -fn map_events(attrs: List(attrs.Attr(Event)), render_events: Bool) { - case render_events { - True -> - list.map( - attrs, - fn(attr) { - case attr { - attrs.Event("gliew-event", event.Morph) -> - attrs.Attr("hx-swap-oob", "morph") - attrs.Event("gliew-event", event.Append) -> - attrs.Attr("hx-swap-oob", "beforeend") - other -> other - } - }, - ) - False -> attrs - } -} - -// Make sure there is an id attribute in the list of attributes. -// If id is `None` it will generate one if there isn't one. -// If id is `Some(id)` it will replace any id if there is one or -// otherwise add it. -// -fn ensure_id(attrs: List(attrs.Attr(Event)), id: Option(String)) { - case has_id(attrs) { - True -> - case id { - Some(id) -> - list.map( - attrs, - fn(attr) { - case attr { - attrs.Attr("id", _) -> attrs.id(id) - other -> other - } - }, - ) - None -> attrs - } - False -> - attrs - |> list.prepend(attrs.id( - id - |> option.unwrap(random_id()), - )) - } -} - -// Extract the ID value from a HTML node. -// -fn extract_id(node: html.Node(Event)) { - case node { - html.Element(_, attrs, _) -> find_id(attrs) - html.LeafElement(_, attrs) -> find_id(attrs) - _ -> Error(Nil) - } - |> result.unwrap(random_id()) -} - -// Find id attribute in a list of attrs. -// -fn find_id(attrs: List(attrs.Attr(Event))) { - attrs - |> list.find_map(fn(attr) { - case attr { - attrs.Attr("id", id) -> Ok(id) - _ -> Error(Nil) - } - }) -} - -// Generates a random ID for a HTML id attribute. -// -fn random_id() { - elem_id_prefix <> random_hex_string(3) -} - -// Check if list of attrs has id. -// -fn has_id(attrs: List(attrs.Attr(a))) { - attrs - |> list.any(fn(a) { - case a { - attrs.Attr("id", _) -> True - _ -> False - } - }) -} - -// Server ------------------------------------------------ - -/// Returns script tags to put into your own layout in order -/// for live mounts to work. -/// -pub fn script() { - html.Fragment([ - html.Element( - tag: "script", - attrs: [attrs.src("https://unpkg.com/htmx.org@1.9.2/dist/htmx.min.js")], - children: [], - ), - html.Element( - tag: "script", - attrs: [attrs.src("https://unpkg.com/htmx.org@1.9.2/dist/ext/ws.js")], - children: [], - ), - html.Element( - tag: "script", - attrs: [ - attrs.src("https://unpkg.com/idiomorph@0.0.8/dist/idiomorph-ext.min.js"), - ], - children: [], - ), - ]) -} - -fn default_layout(content: html.Node(Event)) { - html.Html( - [], - [html.Head([script()]), html.Body(attrs: [], children: [content])], - ) -} - -/// Configuration for a server. -/// -pub type Server { - Server( - port: Int, - layout: fn(html.Node(Event)) -> html.Node(Event), - handler: fn(Request(Body)) -> Response, - ) -} - -/// Creates a configuration for a server with default -/// layout. -/// -pub fn new(port: Int, handler: fn(Request(Body)) -> Response) { - Server(port, default_layout, handler) -} - -/// Start server. -/// -pub fn serve(server: Server) { - use manager <- result.try( - manager.start_manager() - |> result.map_error(fn(err) { - case err { - actor.InitTimeout -> glisten.AcceptorTimeout - actor.InitFailed(reason) -> glisten.AcceptorFailed(reason) - actor.InitCrashed(any) -> glisten.AcceptorCrashed(any) - } - }), - ) - - mist.serve(server.port, handler_func(manager, server.layout, server.handler)) -} - -fn handler_func( - manager: Subject(ManagerMessage), - layout: fn(html.Node(Event)) -> html.Node(Event), - handler: fn(Request(Body)) -> Response, -) { - // Return actual handler func - fn(req: Request(Body)) { - case req.method, req.path { - Get, "/connect" -> handle_ws_connect(manager, req) - _, _ -> - case handler(req) { - Response(status, headers, body) -> - response.new(status) - |> add_headers(headers) - |> to_mist_response(body) - View(status, headers, node) -> - response.new(status) - |> add_headers(headers) - |> mist.bit_builder_response( - manager.process_tree(manager, req, node) - |> layout - |> nakai.to_string_builder - |> bit_builder.from_string_builder, - ) - } - } - } - |> mist.handler_func -} - -fn add_headers(response: HttpResponse(a), headers: List(#(String, String))) { - headers - |> list.fold( - response, - fn(res, pair) { - res - |> response.prepend_header(pair.0, pair.1) - }, - ) -} - -fn to_mist_response(response, body: Option(String)) { - case body { - Some(body) -> - response - |> mist.bit_builder_response(bit_builder.from_string(body)) - None -> - response - |> mist.empty_response - } -} - -fn handle_ws_connect(manager: Subject(ManagerMessage), req: Request(Body)) { - case parse_params(req) { - Ok(#(id, csrf)) -> upgrade_connection(manager, id, csrf) - Error(Nil) -> - response.new(401) - |> mist.empty_response - } -} - -fn upgrade_connection( - manager: Subject(ManagerMessage), - session: String, - csrf: String, -) { - case manager.get_worker(manager, session, csrf) { - Ok(worker) -> - fn(_msg, _subject: Subject(HandlerMessage)) { Ok(Nil) } - |> websocket.with_handler - |> websocket.on_init(fn(socket: Subject(HandlerMessage)) { - worker.connect(worker, socket) - }) - |> websocket.on_close(fn(socket: Subject(HandlerMessage)) { - worker.disconnect(worker, socket) - }) - |> mist.upgrade - Error(Nil) -> - response.new(401) - |> mist.empty_response - } -} - -fn parse_params(req: Request(Body)) { - case req.query { - Some(params) -> - case uri.parse_query(params) { - Ok(params) -> - list.map( - params, - fn(p) { - #( - p.0, - p.1 - |> string.replace(" ", "+"), - ) - }, - ) - |> get_params - Error(Nil) -> Error(Nil) - } - None -> Error(Nil) - } -} - -fn get_params(params: List(#(String, String))) { - let pmap = map.from_list(params) - - use session <- result.then(map.get(pmap, "session")) - use csrf <- result.then(map.get(pmap, "csrf")) - - Ok(#(session, csrf)) -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam deleted file mode 100644 index 87e56938353..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam +++ /dev/null @@ -1,20 +0,0 @@ -import gleam/erlang/process.{Selector} -import gliew/internal/worker.{WorkerMessage} - -// Event is a special type that can be added to attributes -// in HTML tree elements. -// That way we can just return a HTML tree of `html.Node(Event)` -// and later walk the tree to extract various data from it. -// -pub type Event { - // Instructs that the HTML node is the root of a mount - // and contains the selector function for the worker - // to know how to process updates. - LiveMount(selecting: fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)) - // Instructs us to add a `hx-swap-oob="morph"` to the - // mount. - Morph - // Instruct us to add `hx-swap-oob="beforeend"` to the - // mount. - Append -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam deleted file mode 100644 index 44f711a7286..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam +++ /dev/null @@ -1,222 +0,0 @@ -import gleam/map.{Map} -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/result -import gleam/otp/actor -import gleam/erlang/process.{Selector, Subject} -import gleam/http/request.{Request} -import nakai -import nakai/html -import nakai/html/attrs -import mist.{Body} -import gliew/internal/event.{Event, LiveMount} -import gliew/internal/worker.{WorkerMessage} -import gliew/internal/util.{random_hex_string} - -const sess_id_prefix = "gliew-" - -const csrf_prefix = "g-" - -type LoopState { - LoopState(sessions: Map(String, Session)) -} - -type Session { - Session( - id: String, - csrf: String, - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), - tree: html.Node(Event), - worker: Option(Subject(WorkerMessage)), - ) -} - -pub type Message { - ProcessTree( - from: Subject(html.Node(Event)), - request: Request(Body), - tree: html.Node(Event), - ) - GetWorker( - from: Subject(Result(Subject(WorkerMessage), Nil)), - id: String, - csrf: String, - ) -} - -pub fn start_manager() { - actor.start(LoopState(sessions: map.new()), loop) -} - -fn loop(message: Message, state: LoopState) -> actor.Next(LoopState) { - case message { - // Process tree - ProcessTree(from, _, tree) -> - case extract_selects([], tree) { - // Regular static view - [] -> { - process.send(from, tree) - - actor.Continue(state) - } - selects -> { - // Create a session ID - let sess_id = sess_id_prefix <> random_hex_string(10) - // Create a CSRF token - let csrf = csrf_prefix <> random_hex_string(24) - - process.send( - from, - tree - |> wrap_live_view(sess_id, csrf), - ) - - actor.Continue(LoopState( - sessions: state.sessions - |> map.insert(sess_id, Session(sess_id, csrf, selects, tree, None)), - )) - } - } - - // Get worker for session - GetWorker(from, id, csrf) -> { - case - state.sessions - |> map.get(id) - { - // Found session - Ok(sess) -> - case - sess - |> validate_session(csrf, _) - |> result.map(get_worker_from_sess) - |> result.flatten - { - // We got a worker - Ok(worker) -> { - process.send(from, Ok(worker)) - - state.sessions - |> map.insert(id, Session(..sess, worker: Some(worker))) - |> LoopState - |> actor.Continue - } - - // We failed to get a worker - Error(Nil) -> { - process.send(from, Error(Nil)) - actor.Continue(state) - } - } - - // Sessions does not exist - Error(Nil) -> { - process.send(from, Error(Nil)) - actor.Continue(state) - } - } - } - } -} - -// Validates that the provided csrf token matches -// the session's csrf. -// -fn validate_session(csrf: String, sess: Session) { - case sess { - Session(csrf: token, ..) if csrf == token -> Ok(sess) - _ -> Error(Nil) - } -} - -// Get a worker by either extracting it from the -// session or starting a new one. -// -fn get_worker_from_sess(sess: Session) { - case sess.worker { - // There's already a running worker we can - // return. - Some(worker) -> Ok(worker) - // There isn't a runnig worker so we need - // to start one. - None -> - case worker.start_worker(sess.selects) { - // Worker started successfully - Ok(worker) -> Ok(worker) - // Worker failed starting - Error(_) -> Error(Nil) - } - } -} - -// Walks the node tree until it finds a `LiveMount` event and adds -// its select function to the list of of all select functions -// in the tree. -// -fn extract_selects( - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), - node: html.Node(Event), -) { - case node { - html.Element(_, attrs, children) -> - case extract_event(attrs) { - Ok(LiveMount(selector)) -> - selects - |> list.prepend(selector) - Error(Nil) -> - children - |> list.fold(selects, extract_selects) - } - html.LeafElement(_, attrs) -> - case extract_event(attrs) { - Ok(LiveMount(selector)) -> - selects - |> list.prepend(selector) - Error(Nil) -> selects - } - _ -> selects - } -} - -// Extract a single gliew event attribute. -// -fn extract_event(attrs: List(attrs.Attr(Event))) { - attrs - |> list.find_map(fn(attr) { - case attr { - attrs.Event("gliew-event", event) -> Ok(event) - _ -> Error(Nil) - } - }) -} - -// Wrap a container around a node tree containing any -// live mounts inside. -// This instructs htmx to make a websocket connection back -// to the server. -// -fn wrap_live_view(markup: html.Node(Event), session_id: String, csrf: String) { - html.div( - [ - attrs.Attr("hx-ext", "ws"), - attrs.Attr( - "ws-connect", - "/connect?session=" <> session_id <> "&csrf=" <> csrf, - ), - attrs.Attr("hx-ext", "morph"), - ], - [markup], - ) -} - -pub fn process_tree( - subject: Subject(Message), - request: Request(Body), - tree: html.Node(Event), -) { - process.call(subject, ProcessTree(_, request, tree), 1000) -} - -pub fn get_worker(manager: Subject(Message), id: String, csrf: String) { - process.call(manager, GetWorker(_, id, csrf), 1000) -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam deleted file mode 100644 index 3eb23e4a052..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam +++ /dev/null @@ -1,18 +0,0 @@ -import gleam/int -import gleam/string -import gleam/crypto - -pub fn random_hex_string(len: Int) { - crypto.strong_random_bytes(len) - |> to_hex_string -} - -fn to_hex_string(bstr: BitString) { - case bstr { - <<>> -> "" - <<a:8, rest:bit_string>> -> { - int.to_base16(a) - |> string.lowercase <> to_hex_string(rest) - } - } -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam deleted file mode 100644 index 36b0f78e703..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam +++ /dev/null @@ -1,128 +0,0 @@ -import gleam/io -import gleam/string -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/function -import gleam/otp/actor -import gleam/erlang/process.{Selector, Subject, Timer} -import glisten/handler.{HandlerMessage} -import mist/websocket -import mist/internal/websocket.{TextMessage} as iws - -// inactivity timeout of 10 minutes -const timeout = 600_000 - -type State { - State( - self: Subject(WorkerMessage), - socket: Option(Subject(HandlerMessage)), - timer: Option(Timer), - ) -} - -pub type WorkerMessage { - LiveUpdate(markup: String) - ConnectSocket(socket: Subject(HandlerMessage)) - DisconnectSocket(socket: Subject(HandlerMessage)) - Shutdown -} - -pub fn start_worker( - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), -) { - actor.start_spec(actor.Spec( - init: fn() { - let subject = process.new_subject() - - // Apply selectors from live mounts. - let selector = - process.new_selector() - |> process.selecting(subject, function.identity) - |> apply_selects(selects) - - // Send ourselves a shutdown timer that we will wait - // for a socket for. - let timer = process.send_after(subject, timeout, Shutdown) - - actor.Ready(State(subject, None, Some(timer)), selector) - }, - init_timeout: 1000, - loop: worker_loop, - )) -} - -fn worker_loop(msg: WorkerMessage, state: State) { - case msg { - // We got a new live mount update. - LiveUpdate(markup) -> - case state.socket { - // We have a socket to send data to. - Some(sock) -> { - // Send updated markup to websocket. - websocket.send(sock, TextMessage(markup)) - - actor.Continue(state) - } - // No socket is connected to the worker. - None -> actor.Continue(state) - } - // We got a socket to join. - ConnectSocket(sock) -> { - // Cancel timer - case state.timer { - Some(timer) -> { - process.cancel_timer(timer) - Nil - } - None -> Nil - } - - // Update state - actor.Continue(State(..state, socket: Some(sock), timer: None)) - } - // We should disconnect from socket. - DisconnectSocket(sock) -> - case state.socket { - // We have a socket and the socket matches - // the one we should disconnect from. - Some(socket) if sock == socket -> - // Send ourselves a Shutdown message after timeout. - process.send_after(state.self, timeout, Shutdown) - |> Some - |> State(state.self, None, _) - |> actor.Continue - // Either we don't have a socket or the - // one provided doesn't match so we - // ignore the message. - _ -> actor.Continue(state) - } - // We got a shutdown message. - Shutdown -> { - io.println( - "shutting down worker " <> string.inspect(process.subject_owner( - state.self, - )), - ) - actor.Stop(process.Normal) - } - } -} - -fn apply_selects( - selector: Selector(WorkerMessage), - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), -) { - selector - |> list.fold(selects, _, fn(selector, selecting) { selecting(selector) }) -} - -pub fn connect(worker: Subject(WorkerMessage), socket: Subject(HandlerMessage)) { - process.send(worker, ConnectSocket(socket)) -} - -pub fn disconnect( - worker: Subject(WorkerMessage), - socket: Subject(HandlerMessage), -) { - process.send(worker, DisconnectSocket(socket)) -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl deleted file mode 100644 index 24d4dcdf4fa..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl +++ /dev/null @@ -1,11 +0,0 @@ --module(gliew@internal@event). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([event/0]). - --type event() :: {live_mount, - fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))} | - morph | - append. - - diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl deleted file mode 100644 index 4686ce82cde..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl +++ /dev/null @@ -1,216 +0,0 @@ --module(gliew@internal@manager). --compile([no_auto_import, nowarn_unused_vars]). - --export([process_tree/3, get_worker/3, start_manager/0]). --export_type([loop_state/0, session/0, message/0]). - --type loop_state() :: {loop_state, gleam@map:map_(binary(), session())}. - --type session() :: {session, - binary(), - binary(), - list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))), - nakai@html:node_(gliew@internal@event:event()), - gleam@option:option(gleam@erlang@process:subject(gliew@internal@worker:worker_message()))}. - --type message() :: {process_tree, - gleam@erlang@process:subject(nakai@html:node_(gliew@internal@event:event())), - gleam@http@request:request(mist@internal@http:body()), - nakai@html:node_(gliew@internal@event:event())} | - {get_worker, - gleam@erlang@process:subject({ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}), - binary(), - binary()}. - --spec validate_session(binary(), session()) -> {ok, session()} | {error, nil}. -validate_session(Csrf, Sess) -> - case Sess of - {session, _, Token, _, _, _} when Csrf =:= Token -> - {ok, Sess}; - - _ -> - {error, nil} - end. - --spec get_worker_from_sess(session()) -> {ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}. -get_worker_from_sess(Sess) -> - case erlang:element(6, Sess) of - {some, Worker} -> - {ok, Worker}; - - none -> - case gliew@internal@worker:start_worker(erlang:element(4, Sess)) of - {ok, Worker@1} -> - {ok, Worker@1}; - - {error, _} -> - {error, nil} - end - end. - --spec extract_event(list(nakai@html@attrs:attr(gliew@internal@event:event()))) -> {ok, - gliew@internal@event:event()} | - {error, nil}. -extract_event(Attrs) -> - _pipe = Attrs, - gleam@list:find_map(_pipe, fun(Attr) -> case Attr of - {event, <<"gliew-event"/utf8>>, Event} -> - {ok, Event}; - - _ -> - {error, nil} - end end). - --spec wrap_live_view( - nakai@html:node_(gliew@internal@event:event()), - binary(), - binary() -) -> nakai@html:node_(gliew@internal@event:event()). -wrap_live_view(Markup, Session_id, Csrf) -> - nakai@html:'div'( - [{attr, <<"hx-ext"/utf8>>, <<"ws"/utf8>>}, - {attr, - <<"ws-connect"/utf8>>, - <<<<<<"/connect?session="/utf8, Session_id/binary>>/binary, - "&csrf="/utf8>>/binary, - Csrf/binary>>}, - {attr, <<"hx-ext"/utf8>>, <<"morph"/utf8>>}], - [Markup] - ). - --spec process_tree( - gleam@erlang@process:subject(message()), - gleam@http@request:request(mist@internal@http:body()), - nakai@html:node_(gliew@internal@event:event()) -) -> nakai@html:node_(gliew@internal@event:event()). -process_tree(Subject, Request, Tree) -> - gleam@erlang@process:call( - Subject, - fun(_capture) -> {process_tree, _capture, Request, Tree} end, - 1000 - ). - --spec get_worker(gleam@erlang@process:subject(message()), binary(), binary()) -> {ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}. -get_worker(Manager, Id, Csrf) -> - gleam@erlang@process:call( - Manager, - fun(_capture) -> {get_worker, _capture, Id, Csrf} end, - 1000 - ). - --spec extract_selects( - list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))), - nakai@html:node_(gliew@internal@event:event()) -) -> list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))). -extract_selects(Selects, Node) -> - case Node of - {element, _, Attrs, Children} -> - case extract_event(Attrs) of - {ok, {live_mount, Selector}} -> - _pipe = Selects, - gleam@list:prepend(_pipe, Selector); - - {error, nil} -> - _pipe@1 = Children, - gleam@list:fold(_pipe@1, Selects, fun extract_selects/2) - end; - - {leaf_element, _, Attrs@1} -> - case extract_event(Attrs@1) of - {ok, {live_mount, Selector@1}} -> - _pipe@2 = Selects, - gleam@list:prepend(_pipe@2, Selector@1); - - {error, nil} -> - Selects - end; - - _ -> - Selects - end. - --spec loop(message(), loop_state()) -> gleam@otp@actor:next(loop_state()). -loop(Message, State) -> - case Message of - {process_tree, From, _, Tree} -> - case extract_selects([], Tree) of - [] -> - gleam@erlang@process:send(From, Tree), - {continue, State}; - - Selects -> - Sess_id = <<"gliew-"/utf8, - (gliew@internal@util:random_hex_string(10))/binary>>, - Csrf = <<"g-"/utf8, - (gliew@internal@util:random_hex_string(24))/binary>>, - gleam@erlang@process:send( - From, - begin - _pipe = Tree, - wrap_live_view(_pipe, Sess_id, Csrf) - end - ), - {continue, - {loop_state, - begin - _pipe@1 = erlang:element(2, State), - gleam@map:insert( - _pipe@1, - Sess_id, - {session, - Sess_id, - Csrf, - Selects, - Tree, - none} - ) - end}} - end; - - {get_worker, From@1, Id, Csrf@1} -> - case begin - _pipe@2 = erlang:element(2, State), - gleam@map:get(_pipe@2, Id) - end of - {ok, Sess} -> - case begin - _pipe@3 = Sess, - _pipe@4 = validate_session(Csrf@1, _pipe@3), - _pipe@5 = gleam@result:map( - _pipe@4, - fun get_worker_from_sess/1 - ), - gleam@result:flatten(_pipe@5) - end of - {ok, Worker} -> - gleam@erlang@process:send(From@1, {ok, Worker}), - _pipe@6 = erlang:element(2, State), - _pipe@7 = gleam@map:insert( - _pipe@6, - Id, - erlang:setelement(6, Sess, {some, Worker}) - ), - _pipe@8 = {loop_state, _pipe@7}, - {continue, _pipe@8}; - - {error, nil} -> - gleam@erlang@process:send(From@1, {error, nil}), - {continue, State} - end; - - {error, nil} -> - gleam@erlang@process:send(From@1, {error, nil}), - {continue, State} - end - end. - --spec start_manager() -> {ok, gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start_manager() -> - gleam@otp@actor:start({loop_state, gleam@map:new()}, fun loop/2). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl deleted file mode 100644 index d5e9e805dbb..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl +++ /dev/null @@ -1,23 +0,0 @@ --module(gliew@internal@util). --compile([no_auto_import, nowarn_unused_vars]). - --export([random_hex_string/1]). - --spec to_hex_string(bitstring()) -> binary(). -to_hex_string(Bstr) -> - case Bstr of - <<>> -> - <<""/utf8>>; - - <<A:8, Rest/bitstring>> -> - <<(begin - _pipe = gleam@int:to_base16(A), - gleam@string:lowercase(_pipe) - end)/binary, - (to_hex_string(Rest))/binary>> - end. - --spec random_hex_string(integer()) -> binary(). -random_hex_string(Len) -> - _pipe = crypto:strong_rand_bytes(Len), - to_hex_string(_pipe). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl deleted file mode 100644 index 090e6b398c1..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl +++ /dev/null @@ -1,129 +0,0 @@ --module(gliew@internal@worker). --compile([no_auto_import, nowarn_unused_vars]). - --export([start_worker/1, connect/2, disconnect/2]). --export_type([state/0, worker_message/0]). - --type state() :: {state, - gleam@erlang@process:subject(worker_message()), - gleam@option:option(gleam@erlang@process:subject(glisten@handler:handler_message())), - gleam@option:option(gleam@erlang@process:timer())}. - --type worker_message() :: {live_update, binary()} | - {connect_socket, - gleam@erlang@process:subject(glisten@handler:handler_message())} | - {disconnect_socket, - gleam@erlang@process:subject(glisten@handler:handler_message())} | - shutdown. - --spec worker_loop(worker_message(), state()) -> gleam@otp@actor:next(state()). -worker_loop(Msg, State) -> - case Msg of - {live_update, Markup} -> - case erlang:element(3, State) of - {some, Sock} -> - mist@websocket:send(Sock, {text_message, Markup}), - {continue, State}; - - none -> - {continue, State} - end; - - {connect_socket, Sock@1} -> - case erlang:element(4, State) of - {some, Timer} -> - gleam@erlang@process:cancel_timer(Timer), - nil; - - none -> - nil - end, - {continue, - erlang:setelement( - 4, - erlang:setelement(3, State, {some, Sock@1}), - none - )}; - - {disconnect_socket, Sock@2} -> - case erlang:element(3, State) of - {some, Socket} when Sock@2 =:= Socket -> - _pipe = gleam@erlang@process:send_after( - erlang:element(2, State), - 600000, - shutdown - ), - _pipe@1 = {some, _pipe}, - _pipe@2 = {state, erlang:element(2, State), none, _pipe@1}, - {continue, _pipe@2}; - - _ -> - {continue, State} - end; - - shutdown -> - gleam@io:println( - <<"shutting down worker "/utf8, - (gleam@string:inspect( - gleam@erlang@process:subject_owner( - erlang:element(2, State) - ) - ))/binary>> - ), - {stop, normal} - end. - --spec apply_selects( - gleam@erlang@process:selector(worker_message()), - list(fun((gleam@erlang@process:selector(worker_message())) -> gleam@erlang@process:selector(worker_message()))) -) -> gleam@erlang@process:selector(worker_message()). -apply_selects(Selector, Selects) -> - _pipe = Selector, - gleam@list:fold( - Selects, - _pipe, - fun(Selector@1, Selecting) -> Selecting(Selector@1) end - ). - --spec start_worker( - list(fun((gleam@erlang@process:selector(worker_message())) -> gleam@erlang@process:selector(worker_message()))) -) -> {ok, gleam@erlang@process:subject(worker_message())} | - {error, gleam@otp@actor:start_error()}. -start_worker(Selects) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun gleam@function:identity/1 - ), - apply_selects(_pipe@1, Selects) - end, - Timer = gleam@erlang@process:send_after( - Subject, - 600000, - shutdown - ), - {ready, {state, Subject, none, {some, Timer}}, Selector} - end, - 1000, - fun worker_loop/2} - ). - --spec connect( - gleam@erlang@process:subject(worker_message()), - gleam@erlang@process:subject(glisten@handler:handler_message()) -) -> nil. -connect(Worker, Socket) -> - gleam@erlang@process:send(Worker, {connect_socket, Socket}). - --spec disconnect( - gleam@erlang@process:subject(worker_message()), - gleam@erlang@process:subject(glisten@handler:handler_message()) -) -> nil. -disconnect(Worker, Socket) -> - gleam@erlang@process:send(Worker, {disconnect_socket, Socket}). diff --git a/test-community-packages-javascript/build/packages/glisten/README.md b/test-community-packages-javascript/build/packages/glisten/README.md deleted file mode 100644 index 2a9db26bb3a..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/README.md +++ /dev/null @@ -1,132 +0,0 @@ -# glisten - -See the docs [here](https://hexdocs.pm/glisten/). - -It uses the `gleam_otp` library to handle the supervisor and child processes. - -`glisten` provides a supervisor which manages a pool of acceptors. Each acceptor -will block on `accept` until a connection is opened. The acceptor will then -spawn a handler process and then block again on `accept`. - -The most obvious entrypoint is `glisten.{serve}` which listens for TCP -connections on a given port. It also takes a handler function wrapper -`handler.{func}` which you can provide functionality to, and the state which -each TCP connection process will hold. This takes the shape of: - -```gleam -type HandlerFunc(data) = - fn(BitString, LoopState(data)) -> actor.Next(LoopState(data)) -``` - -SSL is also handled using the `glisten.{serve_ssl}` method. This requires a -certificate and key file path. The rest of the handler flow remains unchanged. - -`glisten` doesn't provide a public API for connected clients. In order to hook -into the socket lifecyle, you can establish some functions which are called -for the opening and closing of the socket. An example is provided below. - -## Examples - -Here is a basic echo server: - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/otp/actor -import gleam/result -import glisten/acceptor -import glisten/handler -import glisten/tcp -import glisten - -pub fn main() { - handler.func(fn(msg, state) { - assert Ok(_) = tcp.send(state.socket, bit_builder.from_bit_string(msg)) - actor.Continue(state) - }) - |> acceptor.new_pool - |> glisten.serve(8080, _) - |> result.map(fn(_) { process.sleep_forever() }) -} -``` - -To serve over SSL: - -```gleam -// ... -import glisten/ssl - -pub fn main() { - handler.func(fn(msg, state) { - assert Ok(_) = ssl.send(state.socket, bit_builder.from_bit_string(msg)) - actor.Continue(state) - }) - |> acceptor.new_pool - |> glisten.serve_ssl( - // Passing labeled arguments for clarity - port: 8080, - certfile: "/path/to/server.crt", - keyfile: "/path/to/server.key", - with_pool: _, - ) - |> result.map(fn(_) { process.sleep_forever() }) -} -``` - -Managing connected clients can be handled similarly to this simple example. -The `with_init` callback will be called after the SSL handshake, if the -underlying socket is set up to use it. - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import glisten/handler -import glisten/tcp -import glisten - -pub fn main() { - // This function is omitted for brevity. It simply manages a - // `gleam/set.{Set}` of `Sender(HandlerMessage)`s that "broadcast" the - // connect/disconnect events to all clients. - assert Ok(connections) = start_connection_actor() - - handler.func(fn(msg, state) { - assert Ok(_) = tcp.send(state.socket, bit_builder.from_bit_string(msg)) - actor.Continue(state) - }) - |> acceptor.new_pool - |> acceptor.with_init(fn(sender) { - process.send(connections, Connected(sender)) - - Nil - }) - |> acceptor.with_close(fn(sender) { - process.send(connections, Disconnected(sender)) - - Nil - }) - |> glisten.serve(8080, _) - |> result.map(fn(_) { process.sleep_forever() }) -} -``` - -But you can also drop down to the lower level listen/accept flow if you'd prefer -to manage connections yourself, or only handle a small number at a time. - -```gleam -import gleam/io -import glisten/socket/options.{ActiveMode, Passive} -import glisten/tcp - -pub fn main() { - try listener = tcp.listen(8000, [ActiveMode(Passive)]) - try socket = tcp.accept(listener) - try msg = tcp.receive(socket, 0) - io.debug(#("got a msg", msg)) - - Ok(Nil) -} -``` - -See [mist](https://github.com/rawhat/mist) for HTTP support built on top of -this library. diff --git a/test-community-packages-javascript/build/packages/glisten/gleam.toml b/test-community-packages-javascript/build/packages/glisten/gleam.toml deleted file mode 100644 index f6cdc2792bf..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "glisten" -version = "0.7.0" -description = "a shiny Gleam TCP/SSL server" -licences = ["Apache-2.0"] -repository = { type = "github", user = "rawhat", repo = "glisten" } - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_otp = "~> 0.5" -gleam_erlang = "~> 0.18" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl deleted file mode 100644 index 0dd99accb49..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(acceptor_state, { - sender :: gleam@erlang@process:subject(glisten@acceptor:acceptor_message()), - socket :: gleam@option:option(glisten@socket:socket()), - transport :: glisten@socket@transport:transport() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl deleted file mode 100644 index 71796ee3ea4..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(pool, { - listener_socket :: glisten@socket:listen_socket(), - handler :: fun((glisten@handler:handler_message(), glisten@handler:loop_state(any())) -> gleam@otp@actor:next(glisten@handler:loop_state(any()))), - initial_data :: any(), - pool_count :: integer(), - on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - transport :: glisten@socket@transport:transport() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl deleted file mode 100644 index 4f553b84c48..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl +++ /dev/null @@ -1,8 +0,0 @@ --record(handler, { - socket :: glisten@socket:socket(), - initial_data :: any(), - loop :: fun((glisten@handler:handler_message(), glisten@handler:loop_state(any())) -> gleam@otp@actor:next(glisten@handler:loop_state(any()))), - on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - transport :: glisten@socket@transport:transport() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl deleted file mode 100644 index 8ba0b7f5452..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(loop_state, { - socket :: glisten@socket:socket(), - sender :: gleam@erlang@process:subject(glisten@handler:handler_message()), - transport :: glisten@socket@transport:transport(), - data :: any() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl deleted file mode 100644 index 858335aa80c..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ssl, {socket :: gleam@otp@port:port_(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl deleted file mode 100644 index 2c0ad76b188..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl +++ /dev/null @@ -1 +0,0 @@ --record(tcp, {socket :: gleam@otp@port:port_(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl deleted file mode 100644 index c97154c6447..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl +++ /dev/null @@ -1,34 +0,0 @@ --record(ssl, { - accept :: fun((glisten@socket:listen_socket()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - accept_timeout :: fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - close :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - controlling_process :: fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}), - handshake :: fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - listen :: fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - negotiated_protocol :: fun((glisten@socket:socket()) -> {ok, binary()} | - {error, binary()}), - 'receive' :: fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - receive_timeout :: fun((glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}), - send :: fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - set_opts :: fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - shutdown :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - socket_info :: fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic())) -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl deleted file mode 100644 index 3d655dfb48f..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl +++ /dev/null @@ -1,34 +0,0 @@ --record(tcp, { - accept :: fun((glisten@socket:listen_socket()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - accept_timeout :: fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - close :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - controlling_process :: fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}), - handshake :: fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - listen :: fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - negotiated_protocol :: fun((glisten@socket:socket()) -> {ok, binary()} | - {error, binary()}), - 'receive' :: fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - receive_timeout :: fun((glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}), - send :: fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - set_opts :: fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - shutdown :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - socket_info :: fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic())) -}). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src b/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src deleted file mode 100644 index c89d29a854d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src +++ /dev/null @@ -1,18 +0,0 @@ -{application, glisten, [ - {vsn, "0.7.0"}, - {applications, [gleam_erlang, - gleam_otp, - gleam_stdlib, - gleeunit]}, - {description, "a shiny Gleam TCP/SSL server"}, - {modules, [glisten, - glisten@acceptor, - glisten@handler, - glisten@logger, - glisten@socket, - glisten@socket@options, - glisten@socket@transport, - glisten@ssl, - glisten@tcp]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten.erl deleted file mode 100644 index b29f20f1fff..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(glisten). --compile([no_auto_import, nowarn_unused_vars]). - --export([serve/2, serve_ssl/4]). --export_type([start_error/0]). - --type start_error() :: listener_closed | - listener_timeout | - acceptor_timeout | - {acceptor_failed, gleam@erlang@process:exit_reason()} | - {acceptor_crashed, gleam@dynamic:dynamic()} | - {system_error, glisten@socket:socket_reason()}. - --spec serve( - integer(), - fun((glisten@socket:listen_socket()) -> glisten@acceptor:pool(any())) -) -> {ok, nil} | {error, start_error()}. -serve(Port, With_pool) -> - _pipe = Port, - _pipe@1 = glisten@tcp:listen(_pipe, []), - _pipe@2 = gleam@result:map_error(_pipe@1, fun(Err) -> case Err of - closed -> - listener_closed; - - timeout -> - listener_timeout; - - Err@1 -> - {system_error, Err@1} - end end), - _pipe@6 = gleam@result:then( - _pipe@2, - fun(Socket) -> - _pipe@3 = Socket, - _pipe@4 = With_pool(_pipe@3), - _pipe@5 = glisten@acceptor:start_pool(_pipe@4), - gleam@result:map_error(_pipe@5, fun(Err@2) -> case Err@2 of - init_timeout -> - acceptor_timeout; - - {init_failed, Reason} -> - {acceptor_failed, Reason}; - - {init_crashed, Reason@1} -> - {acceptor_crashed, Reason@1} - end end) - end - ), - gleam@result:replace(_pipe@6, nil). - --spec serve_ssl( - integer(), - binary(), - binary(), - fun((glisten@socket:listen_socket()) -> glisten@acceptor:pool(any())) -) -> {ok, nil} | {error, start_error()}. -serve_ssl(Port, Certfile, Keyfile, With_pool) -> - _assert_subject = ssl_ffi:start_ssl(), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten"/utf8>>, - function => <<"serve_ssl"/utf8>>, - line => 62}) - end, - _pipe = Port, - _pipe@1 = glisten@ssl:listen( - _pipe, - [{certfile, Certfile}, {keyfile, Keyfile}] - ), - _pipe@2 = gleam@result:map_error(_pipe@1, fun(Err) -> case Err of - closed -> - listener_closed; - - timeout -> - listener_timeout; - - Err@1 -> - {system_error, Err@1} - end end), - _pipe@6 = gleam@result:then( - _pipe@2, - fun(Socket) -> - _pipe@3 = Socket, - _pipe@4 = (glisten@acceptor:over_ssl(With_pool))(_pipe@3), - _pipe@5 = glisten@acceptor:start_pool(_pipe@4), - gleam@result:map_error(_pipe@5, fun(Err@2) -> case Err@2 of - init_timeout -> - acceptor_timeout; - - {init_failed, Reason} -> - {acceptor_failed, Reason}; - - {init_crashed, Reason@1} -> - {acceptor_crashed, Reason@1} - end end) - end - ), - gleam@result:replace(_pipe@6, nil). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam deleted file mode 100644 index 74a51ee3e9c..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam +++ /dev/null @@ -1,85 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/erlang/process -import gleam/result -import glisten/acceptor.{Pool, over_ssl} -import glisten/socket.{Closed, ListenSocket, SocketReason, Timeout} -import glisten/tcp -import glisten/ssl -import gleam/otp/actor -import glisten/socket/options.{Certfile, Keyfile} - -/// Reasons that `serve` might fail -pub type StartError { - ListenerClosed - ListenerTimeout - AcceptorTimeout - AcceptorFailed(process.ExitReason) - AcceptorCrashed(Dynamic) - SystemError(SocketReason) -} - -/// Sets up a TCP listener with the given acceptor pool. The second argument -/// can be obtained from the `glisten/acceptor.{acceptor_pool}` function. -pub fn serve( - port: Int, - with_pool: fn(ListenSocket) -> Pool(data), -) -> Result(Nil, StartError) { - port - |> tcp.listen([]) - |> result.map_error(fn(err) { - case err { - Closed -> ListenerClosed - Timeout -> ListenerTimeout - err -> SystemError(err) - } - }) - |> result.then(fn(socket) { - socket - |> with_pool - |> acceptor.start_pool - |> result.map_error(fn(err) { - case err { - actor.InitTimeout -> AcceptorTimeout - actor.InitFailed(reason) -> AcceptorFailed(reason) - actor.InitCrashed(reason) -> AcceptorCrashed(reason) - } - }) - }) - |> result.replace(Nil) -} - -external fn start_ssl() -> Result(Nil, Dynamic) = - "ssl_ffi" "start_ssl" - -/// Sets up a SSL listener with the given acceptor pool. The second argument -/// can be obtained from the `glisten/acceptor.{acceptor_pool}` function. -pub fn serve_ssl( - port port: Int, - certfile certfile: String, - keyfile keyfile: String, - with_pool with_pool: fn(ListenSocket) -> Pool(data), -) -> Result(Nil, StartError) { - let assert Ok(_nil) = start_ssl() - port - |> ssl.listen([Certfile(certfile), Keyfile(keyfile)]) - |> result.map_error(fn(err) { - case err { - Closed -> ListenerClosed - Timeout -> ListenerTimeout - err -> SystemError(err) - } - }) - |> result.then(fn(socket) { - socket - |> over_ssl(with_pool) - |> acceptor.start_pool - |> result.map_error(fn(err) { - case err { - actor.InitTimeout -> AcceptorTimeout - actor.InitFailed(reason) -> AcceptorFailed(reason) - actor.InitCrashed(reason) -> AcceptorCrashed(reason) - } - }) - }) - |> result.replace(Nil) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam deleted file mode 100644 index 3237bf0c82d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam +++ /dev/null @@ -1,204 +0,0 @@ -import gleam/erlang/process.{Abnormal, Subject} -import gleam/function -import gleam/iterator -import gleam/option.{None, Option, Some} -import gleam/otp/actor -import gleam/otp/supervisor -import gleam/result -import glisten/handler.{Handler, HandlerMessage, LoopFn, Ready} -import glisten/logger -import glisten/socket.{ListenSocket, Socket} -import glisten/socket/transport.{Transport} - -pub type AcceptorMessage { - AcceptConnection(ListenSocket) -} - -pub type AcceptorError { - AcceptError - HandlerError - ControlError -} - -pub type AcceptorState { - AcceptorState( - sender: Subject(AcceptorMessage), - socket: Option(Socket), - transport: Transport, - ) -} - -/// Worker process that handles `accept`ing connections and starts a new process -/// which receives the messages from the socket -pub fn start( - pool: Pool(data), -) -> Result(Subject(AcceptorMessage), actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let subject = process.new_subject() - let selector = - process.new_selector() - |> process.selecting(subject, function.identity) - - process.send(subject, AcceptConnection(pool.listener_socket)) - - actor.Ready(AcceptorState(subject, None, pool.transport), selector) - }, - // TODO: rethink this value, probably... - init_timeout: 1000, - loop: fn(msg, state) { - let AcceptorState(sender, ..) = state - case msg { - AcceptConnection(listener) -> { - let res = { - use sock <- result.then( - state.transport.accept(listener) - |> result.replace_error(AcceptError), - ) - use start <- result.then( - Handler( - sock, - pool.initial_data, - pool.handler, - pool.on_init, - pool.on_close, - pool.transport, - ) - |> handler.start - |> result.replace_error(HandlerError), - ) - sock - |> state.transport.controlling_process(process.subject_owner(start)) - |> result.replace_error(ControlError) - |> result.map(fn(_) { process.send(start, Ready) }) - } - case res { - Error(reason) -> { - logger.error(#("Failed to accept/start handler", reason)) - actor.Stop(Abnormal("Failed to accept/start handler")) - } - _val -> { - actor.send(sender, AcceptConnection(listener)) - actor.Continue(state) - } - } - } - msg -> { - logger.error(#("Unknown message type", msg)) - actor.Stop(process.Abnormal("Unknown message type")) - } - } - }, - )) -} - -pub type Pool(data) { - Pool( - listener_socket: ListenSocket, - handler: LoopFn(data), - initial_data: data, - pool_count: Int, - on_init: Option(fn(Subject(HandlerMessage)) -> Nil), - on_close: Option(fn(Subject(HandlerMessage)) -> Nil), - transport: Transport, - ) -} - -/// Initialize acceptor pool where each handler has no state -pub fn new_pool(handler: LoopFn(Nil)) -> fn(ListenSocket) -> Pool(Nil) { - fn(listener_socket) { - Pool( - listener_socket: listener_socket, - handler: handler, - initial_data: Nil, - pool_count: 10, - on_init: None, - on_close: None, - transport: transport.tcp(), - ) - } -} - -/// Initialize an acceptor pool where each handler holds some state -pub fn new_pool_with_data( - handler: LoopFn(data), - initial_data: data, -) -> fn(ListenSocket) -> Pool(data) { - fn(listener_socket) { - Pool( - listener_socket: listener_socket, - handler: handler, - initial_data: initial_data, - pool_count: 10, - on_init: None, - on_close: None, - transport: transport.tcp(), - ) - } -} - -/// Add an `on_init` handler to the acceptor pool -pub fn with_init( - make_pool: fn(ListenSocket) -> Pool(data), - func: fn(Subject(HandlerMessage)) -> Nil, -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, on_init: Some(func)) - } -} - -/// Add an `on_close` handler to the acceptor pool -pub fn with_close( - make_pool: fn(ListenSocket) -> Pool(data), - func: fn(Subject(HandlerMessage)) -> Nil, -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, on_close: Some(func)) - } -} - -/// Adjust the number of TCP acceptors in the pool -pub fn with_pool_size( - make_pool: fn(ListenSocket) -> Pool(data), - pool_count: Int, -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, pool_count: pool_count) - } -} - -/// Use SSL for the underlying socket. -pub fn over_ssl( - make_pool: fn(ListenSocket) -> Pool(data), -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, transport: transport.ssl()) - } -} - -/// Starts a pool of acceptors of size `pool_count`. -/// -/// Runs `loop_fn` on ever message received -pub fn start_pool( - pool: Pool(data), -) -> Result(Subject(supervisor.Message), actor.StartError) { - supervisor.start_spec(supervisor.Spec( - argument: Nil, - // TODO: i think these might need some tweaking - max_frequency: 100, - frequency_period: 1, - init: fn(children) { - iterator.range(from: 0, to: pool.pool_count) - |> iterator.fold( - children, - fn(children, _index) { - supervisor.add(children, supervisor.worker(fn(_arg) { start(pool) })) - }, - ) - }, - )) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam deleted file mode 100644 index d5e8d9348e5..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam +++ /dev/null @@ -1,160 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic -import gleam/erlang/process.{Subject} -import gleam/function -import gleam/option.{Option, Some} -import gleam/otp/actor -import gleam/otp/port.{Port} -import gleam/result -import gleam/string -import glisten/logger -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} -import glisten/socket/options - -/// All message types that the handler will receive, or that you can -/// send to the handler process -pub type HandlerMessage { - Close - Ready - ReceiveMessage(BitString) - SendMessage(BitBuilder) - Ssl(socket: Port, data: BitString) - SslClosed(Nil) - Tcp(socket: Port, data: BitString) - TcpClosed(Nil) -} - -pub type LoopState(data) { - LoopState( - socket: Socket, - sender: Subject(HandlerMessage), - transport: Transport, - data: data, - ) -} - -pub type LoopFn(data) = - fn(HandlerMessage, LoopState(data)) -> actor.Next(LoopState(data)) - -pub type Handler(data) { - Handler( - socket: Socket, - initial_data: data, - loop: LoopFn(data), - on_init: Option(fn(Subject(HandlerMessage)) -> Nil), - on_close: Option(fn(Subject(HandlerMessage)) -> Nil), - transport: Transport, - ) -} - -/// Starts an actor for the TCP connection -pub fn start( - handler: Handler(data), -) -> Result(Subject(HandlerMessage), actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let subject = process.new_subject() - let selector = - process.new_selector() - |> process.selecting(subject, function.identity) - |> process.selecting_anything(fn(msg) { - case dynamic.unsafe_coerce(msg) { - Tcp(_sock, data) | Ssl(_sock, data) -> ReceiveMessage(data) - msg -> msg - } - }) - actor.Ready( - LoopState( - handler.socket, - subject, - handler.transport, - data: handler.initial_data, - ), - selector, - ) - }, - init_timeout: 1000, - loop: fn(msg, state) { - case msg { - TcpClosed(_) | SslClosed(_) | Close -> - case state.transport.close(state.socket) { - Ok(Nil) -> { - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - actor.Stop(process.Normal) - } - Error(err) -> actor.Stop(process.Abnormal(string.inspect(err))) - } - Ready -> - state.socket - |> state.transport.handshake - |> result.replace_error("Failed to handshake socket") - |> result.map(fn(_ok) { - let _ = case handler.on_init { - Some(func) -> func(state.sender) - _ -> Nil - } - }) - |> result.then(fn(_ok) { - state.transport.set_opts( - state.socket, - [options.ActiveMode(options.Once)], - ) - |> result.replace_error("Failed to set socket active") - }) - |> result.replace(actor.Continue(state)) - |> result.map_error(fn(reason) { - actor.Stop(process.Abnormal(reason)) - }) - |> result.unwrap_both - msg -> - case handler.loop(msg, state) { - actor.Continue(next_state) -> { - let assert Ok(Nil) = - state.transport.set_opts( - state.socket, - [options.ActiveMode(options.Once)], - ) - actor.Continue(next_state) - } - msg -> msg - } - } - }, - )) -} - -pub type HandlerFunc(data) = - fn(BitString, LoopState(data)) -> actor.Next(LoopState(data)) - -/// This helper will generate a TCP handler that will call your handler function -/// with the BitString data in the packet as well as the LoopState, with any -/// associated state data you are maintaining -pub fn func(handler func: HandlerFunc(data)) -> LoopFn(data) { - fn(msg, state: LoopState(data)) { - case msg { - Tcp(_, _) | Ready -> { - logger.error(#("Received an unexpected TCP message", msg)) - actor.Continue(state) - } - ReceiveMessage(data) -> func(data, state) - SendMessage(data) -> - case state.transport.send(state.socket, data) { - Ok(_nil) -> actor.Continue(state) - Error(reason) -> { - logger.error(#("Failed to send data", reason)) - actor.Stop(process.Abnormal("Failed to send data")) - } - } - // NOTE: this should never happen. This function is only called _after_ - // the other message types are handled - msg -> { - logger.error(#("Unhandled TCP message", msg)) - actor.Stop(process.Abnormal("Unhandled TCP message")) - } - } - } -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam deleted file mode 100644 index 14a31a6ce54..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam +++ /dev/null @@ -1,8 +0,0 @@ -import gleam/erlang/charlist.{Charlist} - -external fn log_error(format: Charlist, data: any) -> Nil = - "logger" "error" - -pub fn error(data: any) -> Nil { - log_error(charlist.from_string("~tp"), [data]) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam deleted file mode 100644 index 95aca833ceb..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam +++ /dev/null @@ -1,93 +0,0 @@ -pub type SocketReason { - Closed - Timeout - Badarg - Terminated - - // inet:posix() errors. - Eaddrinuse - Eaddrnotavail - Eafnosupport - Ealready - Econnaborted - Econnrefused - Econnreset - Edestaddrreq - Ehostdown - Ehostunreach - Einprogress - Eisconn - Emsgsize - Enetdown - Enetunreach - Enopkg - Enoprotoopt - Enotconn - Enotty - Enotsock - Eproto - Eprotonosupport - Eprototype - Esocktnosupport - Etimedout - Ewouldblock - Exbadport - Exbadseq - - // file:posix() errors. - Eacces - Eagain - Ebadf - Ebadmsg - Ebusy - Edeadlk - Edeadlock - Edquot - Eexist - Efault - Efbig - Eftype - Eintr - Einval - Eio - Eisdir - Eloop - Emfile - Emlink - Emultihop - Enametoolong - Enfile - Enobufs - Enodev - Enolck - Enolink - Enoent - Enomem - Enospc - Enosr - Enostr - Enosys - Enotblk - Enotdir - Enotsup - Enxio - Eopnotsupp - Eoverflow - Eperm - Epipe - Erange - Erofs - Espipe - Esrch - Estale - Etxtbsy - Exdev -} - -pub opaque type ListenSocket { - ListenSocket -} - -pub opaque type Socket { - Socket -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam deleted file mode 100644 index 86766c2296a..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam +++ /dev/null @@ -1,83 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom -import gleam/list -import gleam/map.{Map} -import gleam/pair - -/// Mode for the socket. Currently `list` is not supported -pub type SocketMode { - Binary -} - -/// Mapping to the {active, _} option -pub type ActiveState { - Once - Passive - Count(Int) - // This is dumb and annoying. I'd much prefer `True` or `Active`, but both - // of those make this a lot more annoying to work with - Active -} - -/// Options for the TCP socket -pub type TcpOption { - Backlog(Int) - Nodelay(Bool) - Linger(#(Bool, Int)) - SendTimeout(Int) - SendTimeoutClose(Bool) - Reuseaddr(Bool) - ActiveMode(ActiveState) - Mode(SocketMode) - // TODO: Probably should adjust the type here to only allow this for SSL - Certfile(String) - Keyfile(String) - AlpnPreferredProtocols(List(String)) -} - -pub fn to_map(options: List(TcpOption)) -> Map(atom.Atom, Dynamic) { - let opt_decoder = dynamic.tuple2(dynamic.dynamic, dynamic.dynamic) - - options - |> list.map(fn(opt) { - case opt { - ActiveMode(Passive) -> - dynamic.from(#(atom.create_from_string("active"), False)) - ActiveMode(Active) -> - dynamic.from(#(atom.create_from_string("active"), True)) - ActiveMode(Count(n)) -> - dynamic.from(#(atom.create_from_string("active"), n)) - ActiveMode(Once) -> - dynamic.from(#( - atom.create_from_string("active"), - atom.create_from_string("once"), - )) - other -> dynamic.from(other) - } - }) - |> list.filter_map(opt_decoder) - |> list.map(pair.map_first(_, dynamic.unsafe_coerce)) - |> map.from_list -} - -const default_options = [ - Backlog(1024), - Nodelay(True), - Linger(#(True, 30)), - SendTimeout(30_000), - SendTimeoutClose(True), - Reuseaddr(True), - Mode(Binary), - ActiveMode(Passive), -] - -pub fn merge_with_defaults(options: List(TcpOption)) -> List(TcpOption) { - let overrides = to_map(options) - - default_options - |> to_map - |> map.merge(overrides) - |> map.to_list - |> list.map(dynamic.from) - |> list.map(dynamic.unsafe_coerce) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam deleted file mode 100644 index 4e64c806241..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam +++ /dev/null @@ -1,122 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} -import gleam/map.{Map} -import glisten/socket/options -import glisten/socket.{ListenSocket, Socket, SocketReason} -import glisten/ssl -import glisten/tcp - -type ControllingProcess = - fn(Socket, Pid) -> Result(Nil, Atom) - -type Listen = - fn(Int, List(options.TcpOption)) -> Result(ListenSocket, SocketReason) - -type AcceptTimeout = - fn(ListenSocket, Int) -> Result(Socket, SocketReason) - -type Accept = - fn(ListenSocket) -> Result(Socket, SocketReason) - -type ReceiveTimeout = - fn(Socket, Int, Int) -> Result(BitString, SocketReason) - -type Receive = - fn(Socket, Int) -> Result(BitString, SocketReason) - -type Send = - fn(Socket, BitBuilder) -> Result(Nil, SocketReason) - -type SocketInfo = - fn(Socket) -> Map(Atom, Dynamic) - -type Close = - fn(Socket) -> Result(Nil, SocketReason) - -type Shutdown = - fn(Socket) -> Result(Nil, SocketReason) - -type SetOpts = - fn(Socket, List(options.TcpOption)) -> Result(Nil, Nil) - -type Handshake = - fn(Socket) -> Result(Socket, Nil) - -type NegotiatedProtocol = - fn(Socket) -> Result(String, String) - -pub type Transport { - Ssl( - accept: Accept, - accept_timeout: AcceptTimeout, - close: Close, - controlling_process: ControllingProcess, - handshake: Handshake, - listen: Listen, - negotiated_protocol: NegotiatedProtocol, - receive: Receive, - receive_timeout: ReceiveTimeout, - send: Send, - set_opts: SetOpts, - shutdown: Shutdown, - socket_info: SocketInfo, - ) - Tcp( - accept: Accept, - accept_timeout: AcceptTimeout, - close: Close, - controlling_process: ControllingProcess, - handshake: Handshake, - listen: Listen, - negotiated_protocol: NegotiatedProtocol, - receive: Receive, - receive_timeout: ReceiveTimeout, - send: Send, - set_opts: SetOpts, - shutdown: Shutdown, - socket_info: SocketInfo, - ) -} - -pub fn tcp() -> Transport { - Tcp( - accept: tcp.accept, - accept_timeout: tcp.accept_timeout, - close: tcp.close, - controlling_process: tcp.controlling_process, - handshake: tcp.handshake, - listen: tcp.listen, - negotiated_protocol: fn(_socket) { - Error("Can't negotiate protocol on tcp") - }, - receive: tcp.receive, - receive_timeout: tcp.receive_timeout, - send: tcp.send, - set_opts: tcp.set_opts, - shutdown: tcp.shutdown, - socket_info: socket_info, - ) -} - -pub fn ssl() -> Transport { - Ssl( - accept: ssl.accept, - accept_timeout: ssl.accept_timeout, - close: ssl.close, - controlling_process: ssl.controlling_process, - handshake: ssl.handshake, - listen: ssl.listen, - negotiated_protocol: ssl.negotiated_protocol, - receive: ssl.receive, - receive_timeout: ssl.receive_timeout, - send: ssl.send, - set_opts: ssl.set_opts, - shutdown: ssl.shutdown, - socket_info: socket_info, - ) -} - -pub external fn socket_info(socket: Socket) -> Map(a, b) = - "socket" "info" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam deleted file mode 100644 index a3cd828f3df..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam +++ /dev/null @@ -1,93 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} -import gleam/list -import gleam/map -import glisten/socket.{ListenSocket, Socket, SocketReason} -import glisten/socket/options - -pub external fn controlling_process( - socket: Socket, - pid: Pid, -) -> Result(Nil, Atom) = - "ssl_ffi" "controlling_process" - -external fn do_listen( - port: Int, - options: List(options.TcpOption), -) -> Result(ListenSocket, SocketReason) = - "ssl" "listen" - -pub external fn accept_timeout( - socket: ListenSocket, - timeout: Int, -) -> Result(Socket, SocketReason) = - "ssl" "transport_accept" - -pub external fn accept(socket: ListenSocket) -> Result(Socket, SocketReason) = - "ssl" "transport_accept" - -pub external fn receive_timeout( - socket: Socket, - length: Int, - timeout: Int, -) -> Result(BitString, SocketReason) = - "ssl" "recv" - -pub external fn receive( - socket: Socket, - length: Int, -) -> Result(BitString, SocketReason) = - "ssl" "recv" - -pub external fn send( - socket: Socket, - packet: BitBuilder, -) -> Result(Nil, SocketReason) = - "ssl_ffi" "send" - -pub external fn close(socket: Socket) -> Result(Nil, SocketReason) = - "ssl_ffi" "close" - -pub external fn do_shutdown( - socket: Socket, - write: Atom, -) -> Result(Nil, SocketReason) = - "ssl_ffi" "shutdown" - -pub fn shutdown(socket: Socket) -> Result(Nil, SocketReason) { - let assert Ok(write) = atom.from_string("write") - do_shutdown(socket, write) -} - -external fn do_set_opts(socket: Socket, opts: List(Dynamic)) -> Result(Nil, Nil) = - "ssl_ffi" "set_opts" - -/// Update the optons for a socket (mutates the socket) -pub fn set_opts( - socket: Socket, - opts: List(options.TcpOption), -) -> Result(Nil, Nil) { - opts - |> options.to_map - |> map.to_list - |> list.map(dynamic.from) - |> do_set_opts(socket, _) -} - -pub external fn handshake(socket: Socket) -> Result(Socket, Nil) = - "ssl" "handshake" - -/// Start listening over SSL on a port with the given options -pub fn listen( - port: Int, - options: List(options.TcpOption), -) -> Result(ListenSocket, SocketReason) { - options - |> options.merge_with_defaults - |> do_listen(port, _) -} - -pub external fn negotiated_protocol(socket: Socket) -> Result(String, String) = - "ssl_ffi" "negotiated_protocol" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam deleted file mode 100644 index 55c15372879..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam +++ /dev/null @@ -1,94 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} -import gleam/list -import gleam/map.{Map} -import glisten/socket.{ListenSocket, Socket, SocketReason} -import glisten/socket/options.{TcpOption} - -pub external fn controlling_process( - socket: Socket, - pid: Pid, -) -> Result(Nil, Atom) = - "tcp_ffi" "controlling_process" - -external fn do_listen_tcp( - port: Int, - options: List(TcpOption), -) -> Result(ListenSocket, SocketReason) = - "gen_tcp" "listen" - -pub external fn accept_timeout( - socket: ListenSocket, - timeout: Int, -) -> Result(Socket, SocketReason) = - "gen_tcp" "accept" - -pub external fn accept(socket: ListenSocket) -> Result(Socket, SocketReason) = - "gen_tcp" "accept" - -pub external fn receive_timeout( - socket: Socket, - length: Int, - timeout: Int, -) -> Result(BitString, SocketReason) = - "gen_tcp" "recv" - -pub external fn receive( - socket: Socket, - length: Int, -) -> Result(BitString, SocketReason) = - "gen_tcp" "recv" - -pub external fn send( - socket: Socket, - packet: BitBuilder, -) -> Result(Nil, SocketReason) = - "tcp_ffi" "send" - -pub external fn socket_info(socket: Socket) -> Map(a, b) = - "socket" "info" - -pub external fn close(socket: a) -> Result(Nil, SocketReason) = - "tcp_ffi" "close" - -pub external fn do_shutdown( - socket: Socket, - write: Atom, -) -> Result(Nil, SocketReason) = - "tcp_ffi" "shutdown" - -pub fn shutdown(socket: Socket) -> Result(Nil, SocketReason) { - let assert Ok(write) = atom.from_string("write") - do_shutdown(socket, write) -} - -external fn do_set_opts(socket: Socket, opts: List(Dynamic)) -> Result(Nil, Nil) = - "tcp_ffi" "set_opts" - -/// Update the optons for a socket (mutates the socket) -pub fn set_opts(socket: Socket, opts: List(TcpOption)) -> Result(Nil, Nil) { - opts - |> options.to_map - |> map.to_list - |> list.map(dynamic.from) - |> do_set_opts(socket, _) -} - -/// Start listening over TCP on a port with the given options -pub fn listen( - port: Int, - options: List(TcpOption), -) -> Result(ListenSocket, SocketReason) { - options - |> options.merge_with_defaults - |> do_listen_tcp(port, _) -} - -pub fn handshake(socket: Socket) -> Result(Socket, Nil) { - Ok(socket) -} - -pub external fn negotiated_protocol(socket: Socket) -> a = - "tcp" "negotiated_protocol" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl deleted file mode 100644 index 1b5c360d729..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl +++ /dev/null @@ -1,232 +0,0 @@ --module(glisten@acceptor). --compile([no_auto_import, nowarn_unused_vars]). - --export([start/1, new_pool/1, new_pool_with_data/2, with_init/2, with_close/2, with_pool_size/2, over_ssl/1, start_pool/1]). --export_type([acceptor_message/0, acceptor_error/0, acceptor_state/0, pool/1]). - --type acceptor_message() :: {accept_connection, glisten@socket:listen_socket()}. - --type acceptor_error() :: accept_error | handler_error | control_error. - --type acceptor_state() :: {acceptor_state, - gleam@erlang@process:subject(acceptor_message()), - gleam@option:option(glisten@socket:socket()), - glisten@socket@transport:transport()}. - --type pool(GRD) :: {pool, - glisten@socket:listen_socket(), - fun((glisten@handler:handler_message(), glisten@handler:loop_state(GRD)) -> gleam@otp@actor:next(glisten@handler:loop_state(GRD))), - GRD, - integer(), - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - glisten@socket@transport:transport()}. - --spec start(pool(any())) -> {ok, - gleam@erlang@process:subject(acceptor_message())} | - {error, gleam@otp@actor:start_error()}. -start(Pool) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - gleam@erlang@process:selecting( - _pipe, - Subject, - fun gleam@function:identity/1 - ) - end, - gleam@erlang@process:send( - Subject, - {accept_connection, erlang:element(2, Pool)} - ), - {ready, - {acceptor_state, Subject, none, erlang:element(8, Pool)}, - Selector} - end, - 1000, - fun(Msg, State) -> - {acceptor_state, Sender, _, _} = State, - case Msg of - {accept_connection, Listener} -> - Res = begin - gleam@result:then( - begin - _pipe@1 = (erlang:element( - 2, - erlang:element(4, State) - ))(Listener), - gleam@result:replace_error( - _pipe@1, - accept_error - ) - end, - fun(Sock) -> - gleam@result:then( - begin - _pipe@2 = {handler, - Sock, - erlang:element(4, Pool), - erlang:element(3, Pool), - erlang:element(6, Pool), - erlang:element(7, Pool), - erlang:element(8, Pool)}, - _pipe@3 = glisten@handler:start( - _pipe@2 - ), - gleam@result:replace_error( - _pipe@3, - handler_error - ) - end, - fun(Start) -> - _pipe@4 = Sock, - _pipe@5 = (erlang:element( - 5, - erlang:element(4, State) - ))( - _pipe@4, - gleam@erlang@process:subject_owner( - Start - ) - ), - _pipe@6 = gleam@result:replace_error( - _pipe@5, - control_error - ), - gleam@result:map( - _pipe@6, - fun(_) -> - gleam@erlang@process:send( - Start, - ready - ) - end - ) - end - ) - end - ) - end, - case Res of - {error, Reason} -> - glisten@logger:error( - {<<"Failed to accept/start handler"/utf8>>, - Reason} - ), - {stop, - {abnormal, - <<"Failed to accept/start handler"/utf8>>}}; - - _ -> - gleam@otp@actor:send( - Sender, - {accept_connection, Listener} - ), - {continue, State} - end; - - Msg@1 -> - glisten@logger:error( - {<<"Unknown message type"/utf8>>, Msg@1} - ), - {stop, {abnormal, <<"Unknown message type"/utf8>>}} - end - end} - ). - --spec new_pool( - fun((glisten@handler:handler_message(), glisten@handler:loop_state(nil)) -> gleam@otp@actor:next(glisten@handler:loop_state(nil))) -) -> fun((glisten@socket:listen_socket()) -> pool(nil)). -new_pool(Handler) -> - fun(Listener_socket) -> - {pool, - Listener_socket, - Handler, - nil, - 10, - none, - none, - glisten@socket@transport:tcp()} - end. - --spec new_pool_with_data( - fun((glisten@handler:handler_message(), glisten@handler:loop_state(GRL)) -> gleam@otp@actor:next(glisten@handler:loop_state(GRL))), - GRL -) -> fun((glisten@socket:listen_socket()) -> pool(GRL)). -new_pool_with_data(Handler, Initial_data) -> - fun(Listener_socket) -> - {pool, - Listener_socket, - Handler, - Initial_data, - 10, - none, - none, - glisten@socket@transport:tcp()} - end. - --spec with_init( - fun((glisten@socket:listen_socket()) -> pool(GRO)), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> fun((glisten@socket:listen_socket()) -> pool(GRO)). -with_init(Make_pool, Func) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(6, Pool, {some, Func}) - end. - --spec with_close( - fun((glisten@socket:listen_socket()) -> pool(GRS)), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> fun((glisten@socket:listen_socket()) -> pool(GRS)). -with_close(Make_pool, Func) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(7, Pool, {some, Func}) - end. - --spec with_pool_size( - fun((glisten@socket:listen_socket()) -> pool(GRW)), - integer() -) -> fun((glisten@socket:listen_socket()) -> pool(GRW)). -with_pool_size(Make_pool, Pool_count) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(5, Pool, Pool_count) - end. - --spec over_ssl(fun((glisten@socket:listen_socket()) -> pool(GRZ))) -> fun((glisten@socket:listen_socket()) -> pool(GRZ)). -over_ssl(Make_pool) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(8, Pool, glisten@socket@transport:ssl()) - end. - --spec start_pool(pool(any())) -> {ok, - gleam@erlang@process:subject(gleam@otp@supervisor:message())} | - {error, gleam@otp@actor:start_error()}. -start_pool(Pool) -> - gleam@otp@supervisor:start_spec( - {spec, - nil, - 100, - 1, - fun(Children) -> - _pipe = gleam@iterator:range(0, erlang:element(5, Pool)), - gleam@iterator:fold( - _pipe, - Children, - fun(Children@1, _) -> - gleam@otp@supervisor:add( - Children@1, - gleam@otp@supervisor:worker( - fun(_) -> start(Pool) end - ) - ) - end - ) - end} - ). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl deleted file mode 100644 index d4bd37df499..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl +++ /dev/null @@ -1,234 +0,0 @@ --module(glisten@handler). --compile([no_auto_import, nowarn_unused_vars]). - --export([start/1, func/1]). --export_type([handler_message/0, loop_state/1, handler/1]). - --type handler_message() :: close | - ready | - {receive_message, bitstring()} | - {send_message, gleam@bit_builder:bit_builder()} | - {ssl, gleam@otp@port:port_(), bitstring()} | - {ssl_closed, nil} | - {tcp, gleam@otp@port:port_(), bitstring()} | - {tcp_closed, nil}. - --type loop_state(GMF) :: {loop_state, - glisten@socket:socket(), - gleam@erlang@process:subject(handler_message()), - glisten@socket@transport:transport(), - GMF}. - --type handler(GMG) :: {handler, - glisten@socket:socket(), - GMG, - fun((handler_message(), loop_state(GMG)) -> gleam@otp@actor:next(loop_state(GMG))), - gleam@option:option(fun((gleam@erlang@process:subject(handler_message())) -> nil)), - gleam@option:option(fun((gleam@erlang@process:subject(handler_message())) -> nil)), - glisten@socket@transport:transport()}. - --spec start(handler(any())) -> {ok, - gleam@erlang@process:subject(handler_message())} | - {error, gleam@otp@actor:start_error()}. -start(Handler) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun gleam@function:identity/1 - ), - gleam@erlang@process:selecting_anything( - _pipe@1, - fun(Msg) -> case gleam@dynamic:unsafe_coerce(Msg) of - {tcp, _, Data} -> - {receive_message, Data}; - - {ssl, _, Data} -> - {receive_message, Data}; - - Msg@1 -> - Msg@1 - end end - ) - end, - {ready, - {loop_state, - erlang:element(2, Handler), - Subject, - erlang:element(7, Handler), - erlang:element(3, Handler)}, - Selector} - end, - 1000, - fun(Msg@2, State) -> case Msg@2 of - {tcp_closed, _} -> - case (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ) of - {ok, nil} -> - _ = case erlang:element(6, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {error, Err} -> - {stop, {abnormal, gleam@string:inspect(Err)}} - end; - - {ssl_closed, _} -> - case (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ) of - {ok, nil} -> - _ = case erlang:element(6, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {error, Err} -> - {stop, {abnormal, gleam@string:inspect(Err)}} - end; - - close -> - case (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ) of - {ok, nil} -> - _ = case erlang:element(6, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {error, Err} -> - {stop, {abnormal, gleam@string:inspect(Err)}} - end; - - ready -> - _pipe@2 = erlang:element(2, State), - _pipe@3 = (erlang:element(6, erlang:element(4, State)))( - _pipe@2 - ), - _pipe@4 = gleam@result:replace_error( - _pipe@3, - <<"Failed to handshake socket"/utf8>> - ), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(_) -> _ = case erlang:element(5, Handler) of - {some, Func@1} -> - Func@1(erlang:element(3, State)); - - _ -> - nil - end end - ), - _pipe@7 = gleam@result:then( - _pipe@5, - fun(_) -> - _pipe@6 = (erlang:element( - 12, - erlang:element(4, State) - ))( - erlang:element(2, State), - [{active_mode, once}] - ), - gleam@result:replace_error( - _pipe@6, - <<"Failed to set socket active"/utf8>> - ) - end - ), - _pipe@8 = gleam@result:replace( - _pipe@7, - {continue, State} - ), - _pipe@9 = gleam@result:map_error( - _pipe@8, - fun(Reason) -> {stop, {abnormal, Reason}} end - ), - gleam@result:unwrap_both(_pipe@9); - - Msg@3 -> - case (erlang:element(4, Handler))(Msg@3, State) of - {continue, Next_state} -> - _assert_subject = (erlang:element( - 12, - erlang:element(4, State) - ))( - erlang:element(2, State), - [{active_mode, once}] - ), - {ok, nil} = case _assert_subject of - {ok, nil} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten/handler"/utf8>>, - function => <<"start"/utf8>>, - line => 116}) - end, - {continue, Next_state}; - - Msg@4 -> - Msg@4 - end - end end} - ). - --spec func( - fun((bitstring(), loop_state(GMU)) -> gleam@otp@actor:next(loop_state(GMU))) -) -> fun((handler_message(), loop_state(GMU)) -> gleam@otp@actor:next(loop_state(GMU))). -func(Func) -> - fun(Msg, State) -> case Msg of - {tcp, _, _} -> - glisten@logger:error( - {<<"Received an unexpected TCP message"/utf8>>, Msg} - ), - {continue, State}; - - ready -> - glisten@logger:error( - {<<"Received an unexpected TCP message"/utf8>>, Msg} - ), - {continue, State}; - - {receive_message, Data} -> - Func(Data, State); - - {send_message, Data@1} -> - case (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - Data@1 - ) of - {ok, _} -> - {continue, State}; - - {error, Reason} -> - glisten@logger:error( - {<<"Failed to send data"/utf8>>, Reason} - ), - {stop, {abnormal, <<"Failed to send data"/utf8>>}} - end; - - Msg@1 -> - glisten@logger:error({<<"Unhandled TCP message"/utf8>>, Msg@1}), - {stop, {abnormal, <<"Unhandled TCP message"/utf8>>}} - end end. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl deleted file mode 100644 index f2c2a3d103d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(glisten@logger). --compile([no_auto_import, nowarn_unused_vars]). - --export([error/1]). - --spec error(any()) -> nil. -error(Data) -> - logger:error(unicode:characters_to_list(<<"~tp"/utf8>>), [Data]). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl deleted file mode 100644 index bf277dbeb4d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(glisten@socket). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([socket_reason/0, listen_socket/0, socket/0]). - --type socket_reason() :: closed | - timeout | - badarg | - terminated | - eaddrinuse | - eaddrnotavail | - eafnosupport | - ealready | - econnaborted | - econnrefused | - econnreset | - edestaddrreq | - ehostdown | - ehostunreach | - einprogress | - eisconn | - emsgsize | - enetdown | - enetunreach | - enopkg | - enoprotoopt | - enotconn | - enotty | - enotsock | - eproto | - eprotonosupport | - eprototype | - esocktnosupport | - etimedout | - ewouldblock | - exbadport | - exbadseq | - eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev. - --opaque listen_socket() :: listen_socket. - --opaque socket() :: socket. - - diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl deleted file mode 100644 index ba8da56d523..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(glisten@socket@options). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_map/1, merge_with_defaults/1]). --export_type([socket_mode/0, active_state/0, tcp_option/0]). - --type socket_mode() :: binary. - --type active_state() :: once | passive | {count, integer()} | active. - --type tcp_option() :: {backlog, integer()} | - {nodelay, boolean()} | - {linger, {boolean(), integer()}} | - {send_timeout, integer()} | - {send_timeout_close, boolean()} | - {reuseaddr, boolean()} | - {active_mode, active_state()} | - {mode, socket_mode()} | - {certfile, binary()} | - {keyfile, binary()} | - {alpn_preferred_protocols, list(binary())}. - --spec to_map(list(tcp_option())) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()). -to_map(Options) -> - Opt_decoder = gleam@dynamic:tuple2( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ), - _pipe = Options, - _pipe@1 = gleam@list:map(_pipe, fun(Opt) -> case Opt of - {active_mode, passive} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), false} - ); - - {active_mode, active} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), true} - ); - - {active_mode, {count, N}} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), N} - ); - - {active_mode, once} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), - erlang:binary_to_atom(<<"once"/utf8>>)} - ); - - Other -> - gleam@dynamic:from(Other) - end end), - _pipe@2 = gleam@list:filter_map(_pipe@1, Opt_decoder), - _pipe@3 = gleam@list:map( - _pipe@2, - fun(_capture) -> - gleam@pair:map_first(_capture, fun gleam@dynamic:unsafe_coerce/1) - end - ), - gleam@map:from_list(_pipe@3). - --spec merge_with_defaults(list(tcp_option())) -> list(tcp_option()). -merge_with_defaults(Options) -> - Overrides = to_map(Options), - _pipe = [{backlog, 1024}, - {nodelay, true}, - {linger, {true, 30}}, - {send_timeout, 30000}, - {send_timeout_close, true}, - {reuseaddr, true}, - {mode, binary}, - {active_mode, passive}], - _pipe@1 = to_map(_pipe), - _pipe@2 = gleam@map:merge(_pipe@1, Overrides), - _pipe@3 = gleam@map:to_list(_pipe@2), - _pipe@4 = gleam@list:map(_pipe@3, fun gleam@dynamic:from/1), - gleam@list:map(_pipe@4, fun gleam@dynamic:unsafe_coerce/1). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl deleted file mode 100644 index 10ebf6c34c4..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(glisten@socket@transport). --compile([no_auto_import, nowarn_unused_vars]). - --export([socket_info/1, tcp/0, ssl/0]). --export_type([transport/0]). - --type transport() :: {ssl, - fun((glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, nil} | - {error, gleam@erlang@atom:atom_()}), - fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, binary()} | {error, binary()}), - fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), integer(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()))} | - {tcp, - fun((glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, nil} | - {error, gleam@erlang@atom:atom_()}), - fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, binary()} | {error, binary()}), - fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), integer(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()))}. - --spec socket_info(glisten@socket:socket()) -> gleam@map:map_(any(), any()). -socket_info(Field@0) -> - socket:info(Field@0). - --spec tcp() -> transport(). -tcp() -> - {tcp, - fun glisten@tcp:accept/1, - fun glisten@tcp:accept_timeout/2, - fun glisten@tcp:close/1, - fun glisten@tcp:controlling_process/2, - fun glisten@tcp:handshake/1, - fun glisten@tcp:listen/2, - fun(_) -> {error, <<"Can't negotiate protocol on tcp"/utf8>>} end, - fun glisten@tcp:'receive'/2, - fun glisten@tcp:receive_timeout/3, - fun glisten@tcp:send/2, - fun glisten@tcp:set_opts/2, - fun glisten@tcp:shutdown/1, - fun socket:info/1}. - --spec ssl() -> transport(). -ssl() -> - {ssl, - fun glisten@ssl:accept/1, - fun glisten@ssl:accept_timeout/2, - fun glisten@ssl:close/1, - fun glisten@ssl:controlling_process/2, - fun glisten@ssl:handshake/1, - fun glisten@ssl:listen/2, - fun glisten@ssl:negotiated_protocol/1, - fun glisten@ssl:'receive'/2, - fun glisten@ssl:receive_timeout/3, - fun glisten@ssl:send/2, - fun glisten@ssl:set_opts/2, - fun glisten@ssl:shutdown/1, - fun socket:info/1}. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl deleted file mode 100644 index 28d69867a46..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl +++ /dev/null @@ -1,94 +0,0 @@ --module(glisten@ssl). --compile([no_auto_import, nowarn_unused_vars]). - --export([controlling_process/2, listen/2, accept_timeout/2, accept/1, receive_timeout/3, 'receive'/2, send/2, close/1, do_shutdown/2, shutdown/1, set_opts/2, handshake/1, negotiated_protocol/1]). - --spec controlling_process(glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}. -controlling_process(Field@0, Field@1) -> - ssl_ffi:controlling_process(Field@0, Field@1). - --spec listen(integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}. -listen(Port, Options) -> - _pipe = Options, - _pipe@1 = glisten@socket@options:merge_with_defaults(_pipe), - ssl:listen(Port, _pipe@1). - --spec accept_timeout(glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept_timeout(Field@0, Field@1) -> - ssl:transport_accept(Field@0, Field@1). - --spec accept(glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept(Field@0) -> - ssl:transport_accept(Field@0). - --spec receive_timeout(glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}. -receive_timeout(Field@0, Field@1, Field@2) -> - ssl:recv(Field@0, Field@1, Field@2). - --spec 'receive'(glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}. -'receive'(Field@0, Field@1) -> - ssl:recv(Field@0, Field@1). - --spec send(glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -send(Field@0, Field@1) -> - ssl_ffi:send(Field@0, Field@1). - --spec close(glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}. -close(Field@0) -> - ssl_ffi:close(Field@0). - --spec do_shutdown(glisten@socket:socket(), gleam@erlang@atom:atom_()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -do_shutdown(Field@0, Field@1) -> - ssl_ffi:shutdown(Field@0, Field@1). - --spec shutdown(glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}. -shutdown(Socket) -> - _assert_subject = gleam_erlang_ffi:atom_from_string(<<"write"/utf8>>), - {ok, Write} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten/ssl"/utf8>>, - function => <<"shutdown"/utf8>>, - line => 60}) - end, - ssl_ffi:shutdown(Socket, Write). - --spec set_opts( - glisten@socket:socket(), - list(glisten@socket@options:tcp_option()) -) -> {ok, nil} | {error, nil}. -set_opts(Socket, Opts) -> - _pipe = Opts, - _pipe@1 = glisten@socket@options:to_map(_pipe), - _pipe@2 = gleam@map:to_list(_pipe@1), - _pipe@3 = gleam@list:map(_pipe@2, fun gleam@dynamic:from/1), - ssl_ffi:set_opts(Socket, _pipe@3). - --spec handshake(glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}. -handshake(Field@0) -> - ssl:handshake(Field@0). - --spec negotiated_protocol(glisten@socket:socket()) -> {ok, binary()} | - {error, binary()}. -negotiated_protocol(Field@0) -> - ssl_ffi:negotiated_protocol(Field@0). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl deleted file mode 100644 index 09d0bfe4e49..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl +++ /dev/null @@ -1,96 +0,0 @@ --module(glisten@tcp). --compile([no_auto_import, nowarn_unused_vars]). - --export([handshake/1, controlling_process/2, listen/2, accept_timeout/2, accept/1, receive_timeout/3, 'receive'/2, send/2, socket_info/1, close/1, do_shutdown/2, shutdown/1, set_opts/2, negotiated_protocol/1]). - --spec handshake(glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}. -handshake(Socket) -> - {ok, Socket}. - --spec controlling_process(glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}. -controlling_process(Field@0, Field@1) -> - tcp_ffi:controlling_process(Field@0, Field@1). - --spec listen(integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}. -listen(Port, Options) -> - _pipe = Options, - _pipe@1 = glisten@socket@options:merge_with_defaults(_pipe), - gen_tcp:listen(Port, _pipe@1). - --spec accept_timeout(glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept_timeout(Field@0, Field@1) -> - gen_tcp:accept(Field@0, Field@1). - --spec accept(glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept(Field@0) -> - gen_tcp:accept(Field@0). - --spec receive_timeout(glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}. -receive_timeout(Field@0, Field@1, Field@2) -> - gen_tcp:recv(Field@0, Field@1, Field@2). - --spec 'receive'(glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}. -'receive'(Field@0, Field@1) -> - gen_tcp:recv(Field@0, Field@1). - --spec send(glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -send(Field@0, Field@1) -> - tcp_ffi:send(Field@0, Field@1). - --spec socket_info(glisten@socket:socket()) -> gleam@map:map_(any(), any()). -socket_info(Field@0) -> - socket:info(Field@0). - --spec close(any()) -> {ok, nil} | {error, glisten@socket:socket_reason()}. -close(Field@0) -> - tcp_ffi:close(Field@0). - --spec do_shutdown(glisten@socket:socket(), gleam@erlang@atom:atom_()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -do_shutdown(Field@0, Field@1) -> - tcp_ffi:shutdown(Field@0, Field@1). - --spec shutdown(glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}. -shutdown(Socket) -> - _assert_subject = gleam_erlang_ffi:atom_from_string(<<"write"/utf8>>), - {ok, Write} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten/tcp"/utf8>>, - function => <<"shutdown"/utf8>>, - line => 63}) - end, - tcp_ffi:shutdown(Socket, Write). - --spec set_opts( - glisten@socket:socket(), - list(glisten@socket@options:tcp_option()) -) -> {ok, nil} | {error, nil}. -set_opts(Socket, Opts) -> - _pipe = Opts, - _pipe@1 = glisten@socket@options:to_map(_pipe), - _pipe@2 = gleam@map:to_list(_pipe@1), - _pipe@3 = gleam@list:map(_pipe@2, fun gleam@dynamic:from/1), - tcp_ffi:set_opts(Socket, _pipe@3). - --spec negotiated_protocol(glisten@socket:socket()) -> any(). -negotiated_protocol(Field@0) -> - tcp:negotiated_protocol(Field@0). diff --git a/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl b/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl deleted file mode 100644 index fd05f369c20..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl +++ /dev/null @@ -1,60 +0,0 @@ --module(ssl_ffi). - --export([controlling_process/2, send/2, set_opts/2, start_ssl/0, shutdown/2, close/1, - negotiated_protocol/1]). - -send(Socket, Packet) -> - case ssl:send(Socket, Packet) of - ok -> - {ok, nil}; - Res -> - Res - end. - -set_opts(Socket, Options) -> - case ssl:setopts(Socket, Options) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -controlling_process(Socket, Pid) -> - case ssl:controlling_process(Socket, Pid) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -start_ssl() -> - case application:ensure_all_started(ssl) of - {ok, _} -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -shutdown(Socket, How) -> - case ssl:shutdown(Socket, How) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -close(Socket) -> - case ssl:close(Socket) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -negotiated_protocol(Socket) -> - case ssl:negotiated_protocol(Socket) of - {error, _} -> - {error, "Socket not negotiated"}; - Protocol -> - Protocol - end. diff --git a/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl b/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl deleted file mode 100644 index 955b881d4c7..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl +++ /dev/null @@ -1,32 +0,0 @@ --module(tcp_ffi). --export([controlling_process/2, send/2, set_opts/2, shutdown/2, close/1]). - -send(Socket, Packet) -> - case gen_tcp:send(Socket, Packet) of - ok -> {ok, nil}; - Res -> Res - end. - -set_opts(Socket, Options) -> - case inet:setopts(Socket, Options) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. - -controlling_process(Socket, Pid) -> - case gen_tcp:controlling_process(Socket, Pid) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. - -shutdown(Socket, How) -> - case gen_tcp:shutdown(Socket, How) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. - -close(Socket) -> - case gen_tcp:close(Socket) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. diff --git a/test-community-packages-javascript/build/packages/globe/LICENSE b/test-community-packages-javascript/build/packages/globe/LICENSE deleted file mode 100644 index 37eec8b87f9..00000000000 --- a/test-community-packages-javascript/build/packages/globe/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Willyboar - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/globe/README.md b/test-community-packages-javascript/build/packages/globe/README.md deleted file mode 100644 index 3b7011fd631..00000000000 --- a/test-community-packages-javascript/build/packages/globe/README.md +++ /dev/null @@ -1,26 +0,0 @@ -![Globe](https://github.com/Willyboar/globe/assets/22755228/54162ccb-8f4e-4e6f-a732-e1e21453b213) - -[![Package Version](https://img.shields.io/hexpm/v/globe)](https://hex.pm/packages/globe) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/globe/) - -## WIP: Not Usable - -Globe is a lightweight and efficient compiler backend developed in the Gleam programming language. It provides an Intermediate Language (IL) and Intermediate Representation (IR) to facilitate code transformation and optimization. Globe is designed to generate C99 code, making it compatible with a wide range of platforms and toolchains. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add globe -``` - -and its documentation can be found at <https://hexdocs.pm/globe>. diff --git a/test-community-packages-javascript/build/packages/globe/gleam.toml b/test-community-packages-javascript/build/packages/globe/gleam.toml deleted file mode 100644 index d37f3ad1638..00000000000 --- a/test-community-packages-javascript/build/packages/globe/gleam.toml +++ /dev/null @@ -1,12 +0,0 @@ -name = "globe" -version = "0.1.0" -description = "Gleam Compiler Backend" - -licences = ["MIT"] -repository = { type = "github", user = "Willyboar", repo = "globe" } - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.app.src b/test-community-packages-javascript/build/packages/globe/src/globe.app.src deleted file mode 100644 index 7c9133d1a43..00000000000 --- a/test-community-packages-javascript/build/packages/globe/src/globe.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, globe, [ - {vsn, "0.1.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Gleam Compiler Backend"}, - {modules, [globe]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.erl b/test-community-packages-javascript/build/packages/globe/src/globe.erl deleted file mode 100644 index 2bf599597f2..00000000000 --- a/test-community-packages-javascript/build/packages/globe/src/globe.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(globe). --compile([no_auto_import, nowarn_unused_vars]). - --export([main/0]). - --spec main() -> nil. -main() -> - gleam@io:println(<<"Hello from globe!"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.gleam b/test-community-packages-javascript/build/packages/globe/src/globe.gleam deleted file mode 100644 index c19cb826afa..00000000000 --- a/test-community-packages-javascript/build/packages/globe/src/globe.gleam +++ /dev/null @@ -1,5 +0,0 @@ -import gleam/io - -pub fn main() { - io.println("Hello from globe!") -} diff --git a/test-community-packages-javascript/build/packages/gloml/README.md b/test-community-packages-javascript/build/packages/gloml/README.md deleted file mode 100644 index 16757b25e97..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# gloml - -[![Package Version](https://img.shields.io/hexpm/v/gloml)](https://hex.pm/packages/gloml) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gloml/) - -A toml parsing library for gleam ✨ All gleam targets and runtimes are supported by gloml. - -*Timestamps are not currently supported.* - -```gleam -import gleam/io - -pub fn main() { - decode( - " -[my-project] -version = \"1.2.3\" -", - d.field("my-project", d.field("version", d.string)), - ) - |> io.println() -} -``` - -## Quick start - -```sh -cd priv; npm install; cd .. # install dependencies for js -gleam test # Run the tests -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gloml -``` - -and its documentation can be found at <https://hexdocs.pm/gloml>. diff --git a/test-community-packages-javascript/build/packages/gloml/gleam.toml b/test-community-packages-javascript/build/packages/gloml/gleam.toml deleted file mode 100644 index c7f482deb7b..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gloml" -version = "0.1.2" -description = "A gleam library for parsing toml." -licences = ["MIT"] -repository = { type = "github", user = "lunarmagpie", repo = "gloml" } -links = [{ title = "Website", href = "https://github.com/lunarmagpie.gloml" }] - -[dependencies] -gleam_stdlib = "~> 0.27" -toml = "~> 0.7" - -[dev-dependencies] -gleeunit = "~> 0.10" - -[javascript.deno] -allow_read = ["gleam.toml", "test"] diff --git a/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json b/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json deleted file mode 100644 index ec78ad53f3c..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "priv", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@ltd/j-toml": "^1.38.0" - } - }, - "node_modules/@ltd/j-toml": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@ltd/j-toml/-/j-toml-1.38.0.tgz", - "integrity": "sha512-lYtBcmvHustHQtg4X7TXUu1Xa/tbLC3p2wLvgQI+fWVySguVZJF60Snxijw5EiohumxZbR10kWYFFebh1zotiw==" - } - } -} diff --git a/test-community-packages-javascript/build/packages/gloml/priv/package.json b/test-community-packages-javascript/build/packages/gloml/priv/package.json deleted file mode 100644 index 8f6b7a45402..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/priv/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@ltd/j-toml": "^1.38.0" - } -} diff --git a/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex b/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex deleted file mode 100644 index e021469b55e..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex +++ /dev/null @@ -1,5 +0,0 @@ -defmodule TomlFFI do - def get_reason({:invalid_toml, reason}) do - reason - end -end diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src b/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src deleted file mode 100644 index f654c6d7087..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gloml, [ - {vsn, "0.1.2"}, - {applications, [gleam_stdlib, - gleeunit, - toml]}, - {description, "A gleam library for parsing toml."}, - {modules, [gloml]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.erl b/test-community-packages-javascript/build/packages/gloml/src/gloml.erl deleted file mode 100644 index 0f25cc2bd74..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/gloml.erl +++ /dev/null @@ -1,44 +0,0 @@ --module(gloml). --compile([no_auto_import, nowarn_unused_vars]). - --export([decode/2, decode_dynamic/1]). --export_type([decode_error/0, elx_invalid_toml_error/0]). - --type decode_error() :: {invalid_toml_error, binary()} | - {unexpected_format, list(gleam@dynamic:decode_error())}. - --type elx_invalid_toml_error() :: any(). - --spec decode_inner(binary()) -> {ok, gleam@dynamic:dynamic()} | - {error, decode_error()}. -decode_inner(Toml_string) -> - case 'Elixir.Toml':decode(Toml_string) of - {ok, Value} -> - {ok, Value}; - - {error, Err} -> - {error, {invalid_toml_error, 'Elixir.TomlFFI':get_reason(Err)}} - end. - --spec decode( - binary(), - fun((gleam@dynamic:dynamic()) -> {ok, EUG} | - {error, list(gleam@dynamic:decode_error())}) -) -> {ok, EUG} | {error, decode_error()}. -decode(Toml_string, Decoder) -> - gleam@result:then( - decode_inner(Toml_string), - fun(Dyn) -> - _pipe = Dyn, - _pipe@1 = Decoder(_pipe), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {unexpected_format, Field@0} end - ) - end - ). - --spec decode_dynamic(binary()) -> {ok, gleam@dynamic:dynamic()} | - {error, decode_error()}. -decode_dynamic(Toml_string) -> - decode_inner(Toml_string). diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam b/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam deleted file mode 100644 index 073a087bc63..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam +++ /dev/null @@ -1,77 +0,0 @@ -import gleam/dynamic as dyn -import gleam/result - -pub type DecodeError { - InvalidTomlError(String) - UnexpectedFormat(List(dyn.DecodeError)) -} - -/// Parse a toml file with a decoder. -/// -/// ```gleam -/// pub fn decode_toml() { -/// let version = -/// gloml.decode(" -/// [my-project] -/// version = \"1.2.3\" -/// ", -/// d.field("my-project", d.field("version", d.string)), -/// ) -/// should.equal(version, Ok("1.2.3")) -/// } -/// ``` -/// -pub fn decode( - from toml_string: String, - using decoder: dyn.Decoder(t), -) -> Result(t, DecodeError) { - use dyn <- result.then(decode_inner(toml_string)) - dyn - |> decoder - |> result.map_error(UnexpectedFormat) -} - -/// Parse a toml file into a `gleam/dynamic.Dynamic`. -/// -/// ```gleam -/// pub fn decode_toml() { -/// let dynamic = -/// gloml.decode(" -/// [my-project] -/// version = \"1.2.3\" -/// ") -/// } -/// ``` -/// -pub fn decode_dynamic(toml_string: String) { - decode_inner(toml_string) -} - -if erlang { - external type ElxInvalidTomlError - - external fn decode_ex( - toml_string: String, - ) -> Result(dyn.Dynamic, ElxInvalidTomlError) = - "Elixir.Toml" "decode" - - external fn get_reason(err: ElxInvalidTomlError) -> String = - "Elixir.TomlFFI" "get_reason" - - fn decode_inner(toml_string: String) -> Result(dyn.Dynamic, DecodeError) { - case decode_ex(toml_string) { - Ok(value) -> Ok(value) - Error(err) -> Error(InvalidTomlError(get_reason(err))) - } - } -} - -if javascript { - external fn decode_js(toml_string: String) -> Result(dyn.Dynamic, String) = - "./toml_ffi.mjs" "parse_toml" - - fn decode_inner(toml_string: String) -> Result(dyn.Dynamic, DecodeError) { - decode_js(toml_string) - |> result.map_error(InvalidTomlError) - } -} diff --git a/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs b/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs deleted file mode 100644 index 0623dcb1ad6..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import * as TOML from "./priv/node_modules/@ltd/j-toml/index.mjs"; - -import { - Error, - Ok, -} from "./gleam.mjs"; - -export function parse_toml(string) { - try { - return new Ok(TOML.parse(string)); - } catch (e) { - return new Error(e.message) - } -} diff --git a/test-community-packages-javascript/build/packages/glove/LICENSE b/test-community-packages-javascript/build/packages/glove/LICENSE deleted file mode 100644 index 37eec8b87f9..00000000000 --- a/test-community-packages-javascript/build/packages/glove/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Willyboar - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glove/README.md b/test-community-packages-javascript/build/packages/glove/README.md deleted file mode 100644 index f7bdb08e6de..00000000000 --- a/test-community-packages-javascript/build/packages/glove/README.md +++ /dev/null @@ -1,40 +0,0 @@ - -<img src="https://github.com/Willyboar/glove/assets/22755228/bfd9673f-a105-4083-82d8-84bf4b0ff071"> - - -[![Package Version](https://img.shields.io/hexpm/v/glove)](https://hex.pm/packages/glove) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glove/) - - -## About -Glove is a library for working with QBE intermediate representation (IR) in Gleam. Provides utilities and functions to generate QBE code using the Gleam programming language. - -## Requirements - -To use Glove, you need to have the following dependencies installed: - -Gleam programming language - Install instructions can be found [here](https://gleam.run/getting-started/installing/) - -QBE Backend can be found [here](https://c9x.me/compile/) - - -## Quick start - -You can find a working example [here](https://github.com/Willyboar/glove_example) - -QBE IL Documentation can be found [here](https://c9x.me/compile/doc/il.html) - -## Run the tests -```sh -gleam test # Run the tests -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add glove -``` - -and its documentation can be found at <https://hexdocs.pm/glove>. diff --git a/test-community-packages-javascript/build/packages/glove/gleam.toml b/test-community-packages-javascript/build/packages/glove/gleam.toml deleted file mode 100644 index a66d650c5f5..00000000000 --- a/test-community-packages-javascript/build/packages/glove/gleam.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "glove" -version = "0.2.0" -description = "Gleam QBE IR Generator" -licences = ["MIT"] -repository = { type = "github", user = "Willyboar", repo = "glove" } - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl deleted file mode 100644 index 517a9ced453..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl +++ /dev/null @@ -1 +0,0 @@ --record(block, {label :: binary(), statements :: list(glove:statement())}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl deleted file mode 100644 index 706288b1ee8..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl +++ /dev/null @@ -1 +0,0 @@ --record(const, {value :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl deleted file mode 100644 index acaeff560d1..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(data_def, { - linkage :: glove:linkage(), - name :: binary(), - align :: gleam@option:option(integer()), - items :: list({glove:type(), glove:data_item()}) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl deleted file mode 100644 index 1ff1cdff09b..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(function, { - linkage :: glove:linkage(), - name :: binary(), - arguments :: list({glove:type(), glove:value()}), - return_ty :: gleam@option:option(glove:type()), - blocks :: list(glove:block()) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl deleted file mode 100644 index 9b6ea546aa5..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl +++ /dev/null @@ -1 +0,0 @@ --record(global, {name :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl deleted file mode 100644 index 6e1b0685acd..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(linkage, { - exported :: boolean(), - section :: gleam@option:option(binary()), - secflags :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl deleted file mode 100644 index b97efd9675c..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(module, { - functions :: list(glove:function_()), - types :: list(glove:type_def()), - data :: list(glove:data_def()) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl deleted file mode 100644 index add43ebc8d9..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl +++ /dev/null @@ -1 +0,0 @@ --record(temporary, {name :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl deleted file mode 100644 index c83a3e1e7e8..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(type_def, { - name :: binary(), - align :: gleam@option:option(integer()), - items :: list({glove:type(), integer()}) -}). diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.app.src b/test-community-packages-javascript/build/packages/glove/src/glove.app.src deleted file mode 100644 index d7cc4ba9821..00000000000 --- a/test-community-packages-javascript/build/packages/glove/src/glove.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, glove, [ - {vsn, "0.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Gleam QBE IR Generator"}, - {modules, [glove]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.erl b/test-community-packages-javascript/build/packages/glove/src/glove.erl deleted file mode 100644 index cde846d73e2..00000000000 --- a/test-community-packages-javascript/build/packages/glove/src/glove.erl +++ /dev/null @@ -1,640 +0,0 @@ --module(glove). --compile([no_auto_import, nowarn_unused_vars]). - --export([display_value/1, into_abi/1, into_base/1, size/1, display_data_item/1, add_inst/2, assign_inst/4, jumps/1, add_block/1, last_block/1, display_linkage/1, private/0, new_datadef/0, new_function/0, private_with_section/1, public/0, public_with_section/1, new_module/0, add_function/2, add_type/2, add_data/2, display_type_def/1, display_type/1, display_inst/1, display_data_def/1, display_statement/1, display_block/1, display_arguments/1, display_blocks/1, display_function/1, display_module/1]). --export_type([comp/0, inst/0, value/0, type/0, data_def/0, type_def/0, data_item/0, statement/0, block/0, function_/0, linkage/0, module_/0]). - --type comp() :: slt | sle | sgt | sge | eq | ne. - --type inst() :: {add, value(), value()} | - {sub, value(), value()} | - {mul, value(), value()} | - {'div', value(), value()} | - {'rem', value(), value()} | - {comp, type(), comp(), value(), value()} | - {'and', value(), value()} | - {'or', value(), value()} | - {copy, value()} | - {ret, gleam@option:option(value())} | - {jnz, value(), binary(), binary()} | - {jmp, binary()} | - {call, value(), list({type(), value()})} | - {alloc4, integer()} | - {alloc8, integer()} | - {alloc16, integer()} | - {store, type(), value(), value()} | - {load, type(), value()} | - {blit, value(), value(), integer()}. - --type value() :: {temporary, binary()} | {global, binary()} | {const, integer()}. - --type type() :: word | - long | - single | - double | - byte | - halfword | - {aggregate, type_def()}. - --type data_def() :: {data_def, - linkage(), - binary(), - gleam@option:option(integer()), - list({type(), data_item()})}. - --type type_def() :: {type_def, - binary(), - gleam@option:option(integer()), - list({type(), integer()})}. - --type data_item() :: {symbol, binary(), gleam@option:option(integer())} | - {str, binary()} | - {constant, integer()}. - --type statement() :: {assign, value(), type(), inst()} | {volatile, inst()}. - --type block() :: {block, binary(), list(statement())}. - --type function_() :: {function, - linkage(), - binary(), - list({type(), value()}), - gleam@option:option(type()), - list(block())}. - --type linkage() :: {linkage, - boolean(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --type module_() :: {module, - list(function_()), - list(type_def()), - list(data_def())}. - --spec display_value(value()) -> binary(). -display_value(Value) -> - case Value of - {temporary, Name} -> - <<"%"/utf8, Name/binary>>; - - {global, Name@1} -> - <<"$"/utf8, Name@1/binary>>; - - {const, Value@1} -> - gleam@int:to_string(Value@1) - end. - --spec into_abi(type()) -> type(). -into_abi(Self) -> - case Self of - byte -> - word; - - halfword -> - word; - - Other -> - Other - end. - --spec into_base(type()) -> type(). -into_base(Self) -> - case Self of - byte -> - word; - - halfword -> - word; - - {aggregate, _} -> - long; - - Other -> - Other - end. - --spec size(type()) -> integer(). -size(Self) -> - case Self of - byte -> - 1; - - halfword -> - 2; - - word -> - 4; - - single -> - 4; - - long -> - 8; - - double -> - 8; - - {aggregate, Td} -> - case erlang:element(4, Td) of - [] -> - 0 - end - end. - --spec display_data_item(data_item()) -> binary(). -display_data_item(Item) -> - case Item of - {symbol, Name, Offset} -> - case Offset of - {some, Off} -> - <<<<<<"$"/utf8, Name/binary>>/binary, " +"/utf8>>/binary, - (gleam@int:to_string(Off))/binary>>; - - none -> - <<"$"/utf8, Name/binary>> - end; - - {str, String} -> - <<<<"\""/utf8, String/binary>>/binary, "\""/utf8>>; - - {constant, Val} -> - gleam@int:to_string(Val) - end. - --spec add_inst(block(), inst()) -> block(). -add_inst(Block, Inst) -> - {block, - erlang:element(2, Block), - gleam@list:append(erlang:element(3, Block), [{volatile, Inst}])}. - --spec assign_inst(block(), value(), type(), inst()) -> block(). -assign_inst(Block, Val, Typ, Inst) -> - {block, - erlang:element(2, Block), - gleam@list:append(erlang:element(3, Block), [{assign, Val, Typ, Inst}])}. - --spec jumps(block()) -> boolean(). -jumps(Block) -> - case gleam@list:last(erlang:element(3, Block)) of - {ok, Statement} -> - case Statement of - {volatile, Instr} -> - case Instr of - {ret, _} -> - true; - - {jmp, _} -> - true; - - {jnz, _, _, _} -> - true; - - _ -> - false - end; - - _ -> - false - end; - - {error, _} -> - false - end. - --spec add_block(binary()) -> block(). -add_block(Label) -> - {block, Label, []}. - --spec last_block(list(block())) -> gleam@option:option(block()). -last_block(Blocks) -> - case gleam@list:last(Blocks) of - {ok, Block} -> - {some, Block}; - - {error, _} -> - none - end. - --spec display_linkage(linkage()) -> binary(). -display_linkage(Linkage) -> - Exported_str = case erlang:element(2, Linkage) of - true -> - <<"export "/utf8>>; - - false -> - <<""/utf8>> - end, - Section_str = case erlang:element(3, Linkage) of - {some, Section} -> - <<<<<<<<"section \""/utf8, Section/binary>>/binary, "\""/utf8>>/binary, - (case erlang:element(4, Linkage) of - {some, Secflags} -> - <<<<" \""/utf8, Secflags/binary>>/binary, - "\""/utf8>>; - - none -> - <<""/utf8>> - end)/binary>>/binary, - " "/utf8>>; - - none -> - <<""/utf8>> - end, - <<Exported_str/binary, Section_str/binary>>. - --spec private() -> linkage(). -private() -> - {linkage, false, none, none}. - --spec new_datadef() -> data_def(). -new_datadef() -> - {data_def, private(), <<""/utf8>>, none, []}. - --spec new_function() -> function_(). -new_function() -> - {function, private(), <<""/utf8>>, [], none, []}. - --spec private_with_section(binary()) -> linkage(). -private_with_section(Section) -> - {linkage, false, {some, Section}, none}. - --spec public() -> linkage(). -public() -> - {linkage, true, none, none}. - --spec public_with_section(binary()) -> linkage(). -public_with_section(Section) -> - {linkage, true, {some, Section}, none}. - --spec new_module() -> module_(). -new_module() -> - {module, [], [], []}. - --spec add_function(module_(), function_()) -> module_(). -add_function(Module, Function) -> - {module, - gleam@list:append(erlang:element(2, Module), [Function]), - erlang:element(3, Module), - erlang:element(4, Module)}. - --spec add_type(module_(), type_def()) -> module_(). -add_type(Module, Type_def) -> - {module, - erlang:element(2, Module), - gleam@list:append(erlang:element(3, Module), [Type_def]), - erlang:element(4, Module)}. - --spec add_data(module_(), data_def()) -> module_(). -add_data(Module, Data_def) -> - {module, - erlang:element(2, Module), - erlang:element(3, Module), - gleam@list:append(erlang:element(4, Module), [Data_def])}. - --spec display_type_def(type_def()) -> binary(). -display_type_def(Def) -> - Align_str = case erlang:element(3, Def) of - {some, Align} -> - <<<<"align "/utf8, (gleam@int:to_string(Align))/binary>>/binary, - " "/utf8>>; - - none -> - <<""/utf8>> - end, - Items_str = begin - _pipe = erlang:element(4, Def), - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Item) -> case Item of - {Ty, Count} -> - case Count > 1 of - false -> - display_type(Ty); - - true -> - <<<<(display_type(Ty))/binary, " "/utf8>>/binary, - (gleam@int:to_string(Count))/binary>> - end - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end, - <<<<<<<<<<<<"type :"/utf8, (erlang:element(2, Def))/binary>>/binary, - " = "/utf8>>/binary, - Align_str/binary>>/binary, - "{ "/utf8>>/binary, - Items_str/binary>>/binary, - " }"/utf8>>. - --spec display_type(type()) -> binary(). -display_type(Ty) -> - case Ty of - byte -> - <<"b"/utf8>>; - - halfword -> - <<"h"/utf8>>; - - word -> - <<"w"/utf8>>; - - long -> - <<"l"/utf8>>; - - single -> - <<"s"/utf8>>; - - double -> - <<"d"/utf8>>; - - {aggregate, Ty@1} -> - display_type_def(Ty@1) - end. - --spec display_inst(inst()) -> binary(). -display_inst(Inst) -> - case Inst of - {add, A, B} -> - <<<<<<"add "/utf8, (display_value(A))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B))/binary>>; - - {sub, A@1, B@1} -> - <<<<<<"sub "/utf8, (display_value(A@1))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@1))/binary>>; - - {mul, A@2, B@2} -> - <<<<<<"mul "/utf8, (display_value(A@2))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@2))/binary>>; - - {'div', A@3, B@3} -> - <<<<<<"div "/utf8, (display_value(A@3))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@3))/binary>>; - - {'rem', A@4, B@4} -> - <<<<<<"rem "/utf8, (display_value(A@4))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@4))/binary>>; - - {comp, Ty, Cmp, A@5, B@5} -> - case Ty of - {aggregate, _} -> - <<"Cannot Compare aggregate types"/utf8>>; - - _ -> - case Cmp of - slt -> - <<<<<<<<<<<<<<"c"/utf8, "slt"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - sle -> - <<<<<<<<<<<<<<"c"/utf8, "sle"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - sgt -> - <<<<<<<<<<<<<<"c"/utf8, "sgt"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - sge -> - <<<<<<<<<<<<<<"c"/utf8, "sge"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - eq -> - <<<<<<<<<<<<<<"c"/utf8, "eq"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - ne -> - <<<<<<<<<<<<<<"c"/utf8, "ne"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>> - end - end; - - {'and', A@6, B@6} -> - <<<<<<"and "/utf8, (display_value(A@6))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@6))/binary>>; - - {'or', A@7, B@7} -> - <<<<<<"or "/utf8, (display_value(A@7))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@7))/binary>>; - - {copy, Val} -> - <<"copy "/utf8, (display_value(Val))/binary>>; - - {ret, Val@1} -> - case Val@1 of - {some, Val@2} -> - <<<<"ret "/utf8, (display_value(Val@2))/binary>>/binary, - "\n"/utf8>>; - - none -> - <<"ret\n"/utf8>> - end; - - {jnz, Val@3, If_nonzero, If_zero} -> - <<<<<<<<<<"jnz "/utf8, (display_value(Val@3))/binary>>/binary, - ", @"/utf8>>/binary, - If_nonzero/binary>>/binary, - ", @"/utf8>>/binary, - If_zero/binary>>; - - {jmp, Str} -> - <<"jmp @"/utf8, Str/binary>>; - - {call, Name, Args} -> - Arg_str = begin - _pipe = Args, - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Arg) -> case Arg of - {Ty@1, Val@4} -> - <<<<(display_type(Ty@1))/binary, " "/utf8>>/binary, - (display_value(Val@4))/binary>> - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end, - <<<<<<<<"call "/utf8, (display_value(Name))/binary>>/binary, - "("/utf8>>/binary, - Arg_str/binary>>/binary, - ")"/utf8>>; - - {alloc4, Int} -> - <<"alloc4 "/utf8, (gleam@int:to_string(Int))/binary>>; - - {alloc8, Int@1} -> - <<"alloc8 "/utf8, (gleam@int:to_string(Int@1))/binary>>; - - {alloc16, Int@2} -> - <<"alloc16 "/utf8, (gleam@int:to_string(Int@2))/binary>>; - - {store, Typ, Value, Dest} -> - case Typ of - {aggregate, _} -> - <<"Store to an aggregate type"/utf8>>; - - _ -> - <<<<<<<<<<"store"/utf8, (display_type(Typ))/binary>>/binary, - " "/utf8>>/binary, - (display_value(Value))/binary>>/binary, - " "/utf8>>/binary, - (display_value(Dest))/binary>> - end; - - {load, Typ@1, Val@5} -> - case Typ@1 of - {aggregate, _} -> - <<"Load aggregate type"/utf8>>; - - _ -> - <<<<<<"load"/utf8, (display_type(Typ@1))/binary>>/binary, - " "/utf8>>/binary, - (display_value(Val@5))/binary>> - end; - - {blit, Src, Dest@1, N} -> - <<<<<<<<<<"blit "/utf8, (display_value(Src))/binary>>/binary, - ", "/utf8>>/binary, - (display_value(Dest@1))/binary>>/binary, - ", "/utf8>>/binary, - (gleam@int:to_string(N))/binary>> - end. - --spec display_data_def(data_def()) -> binary(). -display_data_def(Def) -> - Linkage_str = display_linkage(erlang:element(2, Def)), - Align_str = case erlang:element(4, Def) of - {some, Align} -> - <<" align "/utf8, (gleam@int:to_string(Align))/binary>>; - - none -> - <<""/utf8>> - end, - Items_str = begin - _pipe = erlang:element(5, Def), - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Item) -> case Item of - {Ty, Di} -> - <<<<(display_type(Ty))/binary, " "/utf8>>/binary, - (display_data_item(Di))/binary>> - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end, - <<<<<<<<<<<<<<Linkage_str/binary, "data $"/utf8>>/binary, - (erlang:element(3, Def))/binary>>/binary, - " ="/utf8>>/binary, - Align_str/binary>>/binary, - " { "/utf8>>/binary, - Items_str/binary>>/binary, - " }"/utf8>>. - --spec display_statement(statement()) -> binary(). -display_statement(Stmt) -> - case Stmt of - {assign, Val, Typ, Inst} -> - <<<<<<<<(display_value(Val))/binary, " ="/utf8>>/binary, - (display_type(Typ))/binary>>/binary, - " "/utf8>>/binary, - (display_inst(Inst))/binary>>; - - {volatile, Inst@1} -> - display_inst(Inst@1) - end. - --spec display_block(block()) -> binary(). -display_block(Block) -> - Label = erlang:element(2, Block), - Statements = begin - _pipe = erlang:element(3, Block), - _pipe@1 = gleam@list:map(_pipe, fun display_statement/1), - gleam@string:join(_pipe@1, <<"\n"/utf8>>) - end, - <<<<Label/binary, "\n"/utf8>>/binary, Statements/binary>>. - --spec display_arguments(list({type(), value()})) -> binary(). -display_arguments(Arguments) -> - case Arguments of - [] -> - <<""/utf8>>; - - _ -> - _pipe = Arguments, - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Arg) -> case Arg of - {Ty, Val} -> - <<<<(display_type(Ty))/binary, " "/utf8>>/binary, - (display_value(Val))/binary>> - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end. - --spec display_blocks(list(block())) -> binary(). -display_blocks(Blocks) -> - _pipe = Blocks, - _pipe@1 = gleam@list:map(_pipe, fun(Block) -> display_block(Block) end), - gleam@string:join(_pipe@1, <<"\n"/utf8>>). - --spec display_function(function_()) -> binary(). -display_function(Func) -> - Linkage_str = display_linkage(erlang:element(2, Func)), - Name_str = erlang:element(3, Func), - Return_str = case erlang:element(5, Func) of - {some, Ty} -> - <<" "/utf8, (display_type(Ty))/binary>>; - - none -> - <<""/utf8>> - end, - Args_str = display_arguments(erlang:element(4, Func)), - Blocks_str = display_blocks(erlang:element(6, Func)), - <<<<<<<<<<<<<<<<<<<<<<Linkage_str/binary, "function"/utf8>>/binary, - Return_str/binary>>/binary, - " "/utf8>>/binary, - "$"/utf8>>/binary, - Name_str/binary>>/binary, - "("/utf8>>/binary, - Args_str/binary>>/binary, - ")"/utf8>>/binary, - " {\n"/utf8>>/binary, - Blocks_str/binary>>/binary, - "}"/utf8>>. - --spec display_module(module_()) -> binary(). -display_module(Module) -> - Functions_str = begin - _pipe = erlang:element(2, Module), - _pipe@1 = gleam@list:map(_pipe, fun display_function/1), - gleam@string:join(_pipe@1, <<"\n"/utf8>>) - end, - Types_str = begin - _pipe@2 = erlang:element(3, Module), - _pipe@3 = gleam@list:map(_pipe@2, fun display_type_def/1), - gleam@string:join(_pipe@3, <<"\n"/utf8>>) - end, - Data_str = begin - _pipe@4 = erlang:element(4, Module), - _pipe@5 = gleam@list:map(_pipe@4, fun display_data_def/1), - gleam@string:join(_pipe@5, <<"\n"/utf8>>) - end, - <<<<<<Functions_str/binary, Types_str/binary>>/binary, "\n"/utf8>>/binary, - Data_str/binary>>. diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.gleam b/test-community-packages-javascript/build/packages/glove/src/glove.gleam deleted file mode 100644 index 3dd73dfa7b3..00000000000 --- a/test-community-packages-javascript/build/packages/glove/src/glove.gleam +++ /dev/null @@ -1,563 +0,0 @@ -import gleam/int -import gleam/string -import gleam/option.{None, Option, Some} -import gleam/list - -/// QBE Comparison Operators -pub type Comp { - /// Less Than - Slt - /// Less or Equal - Sle - /// Greater than - Sgt - /// Greater or equal - Sge - /// Equal - Eq - /// Not equal - Ne -} - -/// QBE instruction -pub type Inst { - /// Adds values - Add(Value, Value) - /// Substracts value(b) from value(a) - Sub(Value, Value) - /// Multiplies values - Mul(Value, Value) - /// Divides value(a) by value(b) - Div(Value, Value) - /// Returns a remaider from division - Rem(Value, Value) - /// Perform a Comparison - Comp(Type, Comp, Value, Value) - /// Bitwise AND - And(Value, Value) - /// Bitwise OR - Or(Value, Value) - /// Copies either temporary or literal value - Copy(Value) - /// Return from a function, optionally with a value - Ret(Option(Value)) - /// Jumps to first label if a value is nonzero or to the second one otherwise - Jnz(Value, String, String) - /// Unconditionally jumps to a label - Jmp(String) - /// Calls a function - Call(Value, List(#(Type, Value))) - /// Allocates a 4-byte aligned area on the stack - Alloc4(Int) - /// Allocates a 8-byte aligned area on the stack - Alloc8(Int) - /// Allocates a 16-byte aligned area on the stack - Alloc16(Int) - /// Stores a value into memory pointed to by destination. - /// (type, destination, value) - Store(Type, Value, Value) - /// Loads a value from memory pointed to by source - /// (type, source) - Load(Type, Value) - /// (source, destination, n) - /// - /// Copy `n` bytes from the source address to the destination address. - /// - /// n must be a constant value. - /// - /// Minimum supported QBE version 1.1 - Blit(Value, Value, Int) -} - -/// Display function for Instructions -pub fn display_inst(inst: Inst) -> String { - case inst { - Add(a, b) -> "add " <> display_value(a) <> ", " <> display_value(b) - Sub(a, b) -> "sub " <> display_value(a) <> ", " <> display_value(b) - Mul(a, b) -> "mul " <> display_value(a) <> ", " <> display_value(b) - Div(a, b) -> "div " <> display_value(a) <> ", " <> display_value(b) - Rem(a, b) -> "rem " <> display_value(a) <> ", " <> display_value(b) - Comp(ty, cmp, a, b) -> { - case ty { - Aggregate(_) -> "Cannot Compare aggregate types" - _ -> - case cmp { - Slt -> - "c" <> "slt" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Sle -> - "c" <> "sle" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Sgt -> - "c" <> "sgt" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Sge -> - "c" <> "sge" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Eq -> - "c" <> "eq" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Ne -> - "c" <> "ne" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - } - } - } - And(a, b) -> "and " <> display_value(a) <> ", " <> display_value(b) - Or(a, b) -> "or " <> display_value(a) <> ", " <> display_value(b) - Copy(val) -> "copy " <> display_value(val) - Ret(val) -> { - case val { - Some(val) -> "ret " <> display_value(val) <> "\n" - None -> "ret\n" - } - } - Jnz(val, if_nonzero, if_zero) -> - "jnz " <> display_value(val) <> ", @" <> if_nonzero <> ", @" <> if_zero - Jmp(str) -> "jmp @" <> str - Call(name, args) -> { - let arg_str = - args - |> list.index_map(fn(_, arg) { - case arg { - #(ty, val) -> display_type(ty) <> " " <> display_value(val) - } - }) - |> string.join(", ") - - "call " <> display_value(name) <> "(" <> arg_str <> ")" - } - - Alloc4(int) -> "alloc4 " <> int.to_string(int) - Alloc8(int) -> "alloc8 " <> int.to_string(int) - Alloc16(int) -> "alloc16 " <> int.to_string(int) - Store(typ, value, dest) -> - case typ { - Aggregate(_) -> "Store to an aggregate type" - _ -> - "store" <> display_type(typ) <> " " <> display_value(value) <> " " <> display_value( - dest, - ) - } - - Load(typ, val) -> - case typ { - Aggregate(_) -> "Load aggregate type" - _ -> "load" <> display_type(typ) <> " " <> display_value(val) - } - Blit(src, dest, n) -> - "blit " <> display_value(src) <> ", " <> display_value(dest) <> ", " <> int.to_string( - n, - ) - } -} - -/// QBE Value for instructions -pub type Value { - /// `%`-temporary - Temporary(name: String) - /// `$`-global - Global(name: String) - /// Constant - Const(value: Int) -} - -/// Display Value function -pub fn display_value(value: Value) -> String { - case value { - Temporary(name) -> "%" <> name - Global(name) -> "$" <> name - Const(value) -> int.to_string(value) - } -} - -/// QBE Types -pub type Type { - /// Base Types - Word - Long - Single - Double - /// Extended Types - Byte - Halfword - Aggregate(TypeDef) -} - -/// Display Type function -pub fn display_type(ty: Type) -> String { - case ty { - Byte -> "b" - Halfword -> "h" - Word -> "w" - Long -> "l" - Single -> "s" - Double -> "d" - Aggregate(ty) -> display_type_def(ty) - } -} - -/// Aggregate type with a specified name -/// Returns a C ABI type. Extended types are converted to closest base -/// types -pub fn into_abi(self) -> Type { - case self { - Byte | Halfword -> Word - other -> other - } -} - -/// Returns the closest base type -pub fn into_base(self) -> Type { - case self { - Byte | Halfword -> Word - Aggregate(_) -> Long - other -> other - } -} - -/// Returns byte size for values of the type -pub fn size(self) -> Int { - case self { - Byte -> 1 - Halfword -> 2 - Word | Single -> 4 - Long | Double -> 8 - // This not working - Aggregate(td) -> - case td.items { - [] -> 0 - } - } -} - -/// QBE data definition -pub type DataDef { - DataDef( - linkage: Linkage, - name: String, - align: Option(Int), - items: List(#(Type, DataItem)), - ) -} - -pub fn new_datadef() -> DataDef { - DataDef(linkage: private(), name: "", align: None, items: []) -} - -/// Display function for Datadef -pub fn display_data_def(def: DataDef) -> String { - let linkage_str = display_linkage(def.linkage) - let align_str = case def.align { - Some(align) -> " align " <> int.to_string(align) - None -> "" - } - - let items_str = - def.items - |> list.index_map(fn(_, item) { - case item { - #(ty, di) -> display_type(ty) <> " " <> display_data_item(di) - } - }) - |> string.join(", ") - - linkage_str <> "data $" <> def.name <> " =" <> align_str <> " { " <> items_str <> " }" -} - -/// QBE aggregate type definition -pub type TypeDef { - TypeDef(name: String, align: Option(Int), items: List(#(Type, Int))) -} - -/// Display function for TypeDef -pub fn display_type_def(def: TypeDef) -> String { - let align_str = case def.align { - Some(align) -> "align " <> int.to_string(align) <> " " - None -> "" - } - - let items_str = - def.items - |> list.index_map(fn(_, item) { - case item { - #(ty, count) -> - case count > 1 { - False -> display_type(ty) - True -> display_type(ty) <> " " <> int.to_string(count) - } - } - }) - |> string.join(", ") - - "type :" <> def.name <> " = " <> align_str <> "{ " <> items_str <> " }" -} - -/// QBE Data definition item -pub type DataItem { - /// Symbol and offset - Symbol(String, Option(Int)) - /// String - Str(String) - /// Integer - Constant(Int) -} - -/// Display function for DataItem -pub fn display_data_item(item: DataItem) -> String { - case item { - Symbol(name, offset) -> { - case offset { - Some(off) -> "$" <> name <> " +" <> int.to_string(off) - None -> "$" <> name - } - } - Str(string) -> "\"" <> string <> "\"" - Constant(val) -> int.to_string(val) - } -} - -/// IR Statement -pub type Statement { - Assign(Value, Type, Inst) - Volatile(Inst) -} - -/// Display function for Statement -pub fn display_statement(stmt: Statement) -> String { - case stmt { - Assign(val, typ, inst) -> - display_value(val) <> " =" <> display_type(typ) <> " " <> display_inst( - inst, - ) - Volatile(inst) -> display_inst(inst) - } -} - -/// Function block with a label -pub type Block { - Block(label: String, statements: List(Statement)) -} - -/// Display function for block -pub fn display_block(block: Block) -> String { - let label = block.label - let statements = - block.statements - |> list.map(display_statement) - |> string.join("\n") - - label <> "\n" <> statements -} - -/// Adds a new instruction to the block -pub fn add_inst(block: Block, inst: Inst) -> Block { - Block( - label: block.label, - statements: list.append(block.statements, [Volatile(inst)]), - ) -} - -/// Adds a new instruction assigned to a temporary -pub fn assign_inst(block: Block, val: Value, typ: Type, inst: Inst) -> Block { - Block( - label: block.label, - statements: list.append(block.statements, [Assign(val, typ, inst)]), - ) -} - -/// Returns true if the block's last instruction is a jump -pub fn jumps(block: Block) -> Bool { - case list.last(block.statements) { - Ok(statement) -> - case statement { - Volatile(instr) -> - case instr { - Ret(_) -> True - Jmp(_) -> True - Jnz(_, _, _) -> True - _ -> False - } - _ -> False - } - Error(_) -> False - } -} - -/// QBE Function -pub type Function { - Function( - linkage: Linkage, - name: String, - arguments: List(#(Type, Value)), - return_ty: Option(Type), - blocks: List(Block), - ) -} - -/// Display function for functions -pub fn display_function(func: Function) -> String { - let linkage_str = display_linkage(func.linkage) - let name_str = func.name - let return_str = case func.return_ty { - Some(ty) -> " " <> display_type(ty) - None -> "" - } - let args_str = display_arguments(func.arguments) - let blocks_str = display_blocks(func.blocks) - - linkage_str <> "function" <> return_str <> " " <> "$" <> name_str <> "(" <> args_str <> ")" <> " {\n" <> blocks_str <> "}" -} - -/// Display functions Arguments -pub fn display_arguments(arguments: List(#(Type, Value))) -> String { - case arguments { - [] -> "" - _ -> - arguments - |> list.index_map(fn(_, arg) { - case arg { - #(ty, val) -> display_type(ty) <> " " <> display_value(val) - } - }) - |> string.join(", ") - } -} - -/// Display blocks -pub fn display_blocks(blocks: List(Block)) -> String { - blocks - |> list.map(fn(block) { display_block(block) }) - |> string.join("\n") -} - -/// Instantiates an empty function and returns it -pub fn new_function() -> Function { - Function( - linkage: private(), - name: "", - arguments: [], - return_ty: None, - blocks: [], - ) -} - -/// Adds a new empty block with a specified label and returns -/// a reference to it -pub fn add_block(label: String) -> Block { - Block(label: label, statements: []) -} - -/// Returns a reference to the last block -pub fn last_block(blocks: List(Block)) -> Option(Block) { - case list.last(blocks) { - Ok(block) -> Some(block) - Error(_) -> None - } -} - -/// Linkage of a function or data defintion (e.g. section and -/// private/public status) -pub type Linkage { - Linkage(exported: Bool, section: Option(String), secflags: Option(String)) -} - -/// Display function for Linkage -pub fn display_linkage(linkage: Linkage) -> String { - let exported_str = case linkage.exported { - True -> "export " - False -> "" - } - let section_str = case linkage.section { - Some(section) -> - "section \"" <> section <> "\"" <> case linkage.secflags { - Some(secflags) -> " \"" <> secflags <> "\"" - None -> "" - } <> " " - None -> "" - } - exported_str <> section_str -} - -/// Returns the default configuration for private linkage -pub fn private() -> Linkage { - Linkage(exported: False, section: None, secflags: None) -} - -/// Returns the configuration for private linkage with a provided section -pub fn private_with_section(section: String) -> Linkage { - Linkage(exported: False, section: Some(section), secflags: None) -} - -/// Returns the default configuration for public linkage -pub fn public() -> Linkage { - Linkage(exported: True, section: None, secflags: None) -} - -/// Returns the configuration for public linkage with a provided section -pub fn public_with_section(section: String) -> Linkage { - Linkage(exported: True, section: Some(section), secflags: None) -} - -/// A complete IL file -pub type Module { - Module(functions: List(Function), types: List(TypeDef), data: List(DataDef)) -} - -/// Creates a new module -pub fn new_module() -> Module { - Module(functions: [], types: [], data: []) -} - -/// Display function for Module -pub fn display_module(module: Module) -> String { - let functions_str = - module.functions - |> list.map(display_function) - |> string.join("\n") - - let types_str = - module.types - |> list.map(display_type_def) - |> string.join("\n") - - let data_str = - module.data - |> list.map(display_data_def) - |> string.join("\n") - - functions_str <> types_str <> "\n" <> data_str -} - -/// Add function to module -pub fn add_function(module: Module, function: Function) -> Module { - Module( - functions: list.append(module.functions, [function]), - types: module.types, - data: module.data, - ) -} - -/// Add type to module -pub fn add_type(module: Module, type_def: TypeDef) -> Module { - Module( - functions: module.functions, - types: list.append(module.types, [type_def]), - data: module.data, - ) -} - -/// Add Data to module -pub fn add_data(module: Module, data_def: DataDef) -> Module { - Module( - functions: module.functions, - types: module.types, - data: list.append(module.data, [data_def]), - ) -} diff --git a/test-community-packages-javascript/build/packages/glx/LICENSE b/test-community-packages-javascript/build/packages/glx/LICENSE deleted file mode 100644 index b96ba24ed35..00000000000 --- a/test-community-packages-javascript/build/packages/glx/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Marshall Bowers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glx/README.md b/test-community-packages-javascript/build/packages/glx/README.md deleted file mode 100644 index 5b21e3f0858..00000000000 --- a/test-community-packages-javascript/build/packages/glx/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# glx - -[![Package Version](https://img.shields.io/hexpm/v/glx)](https://hex.pm/packages/glx) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glx/) - -⚒️ Extensions to the Gleam standard library. - -## Installation - -```sh -gleam add glx -``` diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache deleted file mode 100644 index fcd403038e374849ea1940a32415eb039772e52f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1223 zcmc(f&r0h+6vpRF8m1LWdngnllt!Ucis-e93pd(=3PtWURuJ5@>CK?2v4Q+q_&zRt z5Ff;ik09J#?nzQ@te0}#=w@<e&g5i%-+U)Ons6XcyTpdT#&P8^ClJS#POe$G%Zcd9 zk>>5@$YhEy)5*XOSjlqi(E;z2Io5iH4oal~z5W_dP~_u&nN#pW!5<1DOa68(xx2#{ z12ERPVmyMn1*<$drQ*KSLqWrEMB(nvAl*IG?TH>-)AIBHb}%qK&%7Jzx2_dBlJb5a zg=uX7FouOqV~s0}895pO3wu~-V?pfq1J9mZ)srHp+0@1Une;;^NK-~W$<=ze(#91* z6|_~<+Ng=BYX_b9!*u$$GUBK0yiHU9#8?D+T%u0nQWiPND#-YD6NV7U$-E@@3nWQ* ze_E0Y<0O&fBU@_$TdC{1Gq?p>s=z;RXSn9L@#a1XJ!cT_Ap6iwPrZ<UcV}M6XT0$G zf+hbGp6oy#i~aBw@Z<NF{(9OJZ;pTa32Ho1AU60r1(I%9pund(Vy3`1cf>!$nUT+n z^T3}u{Z8^6i!CfxQQJeUnm7^F7OL&ixfja%k?Hty+PA1K)4KBOrhe#ou2+V?5~wsM diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta deleted file mode 100644 index d03bd4e27eedf3cf7c1040715866556930eeee16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache deleted file mode 100644 index fa977bc7ae1a82bbfd8e047c1690b7bb21d879b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4959 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 bp_k3NM}4~D*e+O)yn12i1h<>;6@BP0`pL`( diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta deleted file mode 100644 index 09e2f8acc9336bce7885613638b9b2af3ff95002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd;&v`S@w0Y)f;2TG^sq$cL-7nc-e=B0~Ie!%wp&?033h=d8> diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache deleted file mode 100644 index 978ec12631881a81b9ff3202568af472548a6143..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 zcmd^?-)kdP6vywG$z(FwPP2!Sl`JkvOG|&CMpFd|NZLRJmx`Ir$}S?Lna#9LOp`J* z!EIlZvJd(oNFEpVB~P*-Ea<}u`s|DT0luhj{tNpyp81vS#Ei6Yd|4q3hnr;XJ)isi zo_p@A5BV(-3qxFg0l)ln;l{j(`OZRNesw{a7oEed-a0C42G~t)V07C$nEqJPvRSU( zHMH#%hr$O+22xJlu<P!R7_XZE%8MM2J0c20l(W-b#5j~XD335NI`tD<x9HC-M{@*I zl(iF}QEy_AMjISYpY1m}JgO>P;1^nOrnZ3sovW&Cj)M33Q}qr{!MiC_ZKNpJ5gw?! z0tIiS&(y6n1+sXmUKQPujHYg7D3Bymos%f|RT`;(xWV_?y80wb!8cd-)W=sSIGI~g z@67>UYaJi!J(^Wn=6K~h5MF~v;4}!6rI!W*J?xM4(tg0r%_;zA?w5}G?Lk*B89mF+ z>8<uF0F0q@Te-vWj42s<0^aE0;t1D83KwtUN(EOg49DfaZJMnU##qr?0O6wdTo$qb z9AZ@|0iZm@5+G)Stf%kd<{O;JImf2%f@y-U6O#pqen<q-ehi`xu8i>IOCY+K&Ss@{ zrYsXR9O5!yK09W@hfG2{J#!P|Hh<?<`P$un?{3Qum_1H_Sy{Q|F-!Rx*g&a*QaQJ4 zShg<?CHUr&7MuwUF_{pQpKpwyeiQQPF+5hYY}4o+CdlS?z~=9ktKwn>7cZ=*n(8g> zU%Tyex^BYMV=x`3zD+rPJ!)F4_}o)6qm(8xkAbu%bOgs&TT=tWrh|*r#2;FLp1w}R zYr7Zo+D()zD3iRBs?=nx2g(}Nocs{i01Mfvsm7rBEd68JIWYT2P0g^u2Xh$K?ave8 z^3r)O|3&r_6*tU=53`wCaqnlIWJ2R;tmZW~ZpY#t>Hn+qYFu|3-gy-`YK&y6Zb%>v z0O}E7bvwhMd>!YgQK-_BxBHAr*5Kg4xCgNLkblbi@*>MI@mUGKpNO>9&P%K69dBYH z^_V=RMJtV`sxXPEP`J&q*c2VR?^<cH7$;+;*U#rW!=e38?i1XuWum-J<Pwwis`Q~W z-ejOX9=Gd(pT0_Dvm?oyC_i#94gTR<AF!f(GYM}EmJM#Z;I6~FOw8H@6OmE0w1zT> zq#48I7g5f98uY{giRbsSP>);|!n9+^d;vd!qfsB;w2V^*dO#<cq7c!^3?^Cf>xlSH zFX)m<J)SxCq7~uX`eV}kS$ZmoJ^hm)y><dN5WPDhn@!NJ!<Qoa<gPAe@i|zBEzT?N z8z^7HLKO?wa`k?{i^2v9mE0|Jpcmh6buGQNr(1)rjly*r=imFdxMP}q^D6uWa)-J` diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta deleted file mode 100644 index b59a80e2912f11ad19fd2dd2d30e22bb976c9293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmX^5A|sUn2AH4>VJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache deleted file mode 100644 index 31e6666ca904e587ffb1f6607631444d4299af50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1934 zcmchY%}x_h6vywG>2M37sVAi*C6bng253ZND$&fQw23BERHkFXMpLHk6bFV5&P<~i z6XLc{!NON?=gKFLr5mG5pQ7IRD7G>*!5SC6J$F9O|98&$&z+yJNio&M6^bjb6OSpy z<UwMKE+yVm+S@lY^=PfGgHy8|OK<NJ;vZvM5^oxMeUmHQ<Zwfh?*gAlLRpys7Mz2m zd~t&xoTz-~SnwiJRrVq*P=%_}6j+d(s4L48z!w{4yP-M&@*>B}XCSOY7kWGF&9;{5 z2yAg)YMH%$Do#zcEcIkBb7VF<hL+LWwxg-d+k^lRf|G0VHpdepN7xEDna4?y9gJ`5 zwv+ar(LYncn20gjE9*|leIg;mzhK9|bJTeO08x@N>@U{E4BJcvGD48?g@edh<W#q7 z9jA3a(D`nBowo*cj>`5o2O2M%rg0(DlTjX$(N8l}$0Pm~UsR8ewRSU*@nKvUyRwU$ z$Wagad<7RoT%auDR0ZcnoDZ+hUlxrUDB8AHG+#`JSOC~zKMrB36y-1`;WVrD99xTa zr`6Kmu<mwDLJFTD%B5{XZ)iS}DvXQdR5m;$(;kxb3T}wF;UZbh;;M+NZkWqrPQ+X| z9lF&HdY!Qy+PIw{c@wc)tZH`0=+DGu{8>zin7ZNxPxQei;t|Du6Fqma`aG_t$|Kw> zO>>yc;|%oIITptq^-u#Y-m=UiLU`8|3dh`6uIHG(0TI{_I`7lCnAhZM4bUiTlHaO~ zZZeBW5tFp2cy@U)X>^zvgH)9lT@&fzBD-s9P+$l*zHrV*Bfa{Gqt$HvErFof<o|6W zS+9BMP*Zs>@`s#(Ohe@qp#eR&%5GT+WnY$m=ZnkU^aTFzm+ewL+(8&+nVzQlaEXS} z4O4|5zp>Au>lS&8&0<Qz)U0Q?DCAKP<Ik*)mVT%jwiXN@3Ull@|MW2Zz_Lv12K)jj C<lXoH diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta deleted file mode 100644 index e7f013d77b779ab53ac19ad95a796aa2567c499e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache deleted file mode 100644 index 2d192fdbf5deb01503da4f3f8a8348295bc64521..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7081 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 F{{TP;oZSEb diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta deleted file mode 100644 index e616ec00377dd7ef4a8bfede2ea0cd223bda2c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmaz!7?a8X1B_4xH<V7#Nlnbv&o4?zEix6=4Ak0}oeTh-hX}R+ diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache deleted file mode 100644 index 03665a3d2a03e0ca4e37561ce9071b154ed67fa4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6045 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta deleted file mode 100644 index 701db1ffe1dd588340d9500aba145a8b33520324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmd<{vr1)v0cI#e1WKppq$cL-7nc-e=B39cm1gFoq!w|Z$mL`fm++&ABxRPwCl(bY ORz`h4w=v2;suuuDoEL!r diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache deleted file mode 100644 index 5e054b65c30aa33414ac81f462ef08ee174352d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12276 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 U4xYmE#4C5s@DW8RlE=jV0UN+j7ytkO diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta deleted file mode 100644 index fd97a7e9416a1be0edb048f21be7ab89f3389b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ocmX@|G$oY*1{k3X9w?ojlbV>TpI=atnV)y~=BAkQ+a_%U0Mz0PzyJUM diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache deleted file mode 100644 index 5215251bb4c69636ebbdb2b0b05ccb7dfdaf9912..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49265 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%0DhsW4Z=7xvoKFad3NDx_6!A&WzAH<bjhhMPD0$&U z$+N-36y;I$2!$zkOsomAj_quX5-QFI0>fXO`>%7W+2Ztap_G|dwCTB`rq5|$I6;NI zfa`((dx=6!5Z`CN2e9b~1Rqs8c-K7cWF@&QL{YB15(oq;8OfH85zIhzgYoKte%>h_ zg{0<Fl+-`8mivxz?mLCX7>}~?1RIZ4nfohiIcn<+1e@iu)u$ZBTURzucH0x%&=!Kt zroP|Wwh)qtrU;v(Y;%Hbj`b$dE&BOrMdxVt<)f)D3c&Ot7}iUjyw6o~tdB2fb5}}g zAJ|h#)6}aA8Xp7|a7oRTfT5`04uMr<!3u~;mB5WMf|;nf`EE5=#&xxM5>-(#ocYN1 zVguspcw*QZ!WTToFg2j}*d>nC&k>hv@J2Csdx<q+`2N35_ieTf5jln5XAY6{X}9$C zQ}Kmy$oihg<nzl>_T>coaxAq0vRz?ElkBL@j!|!!NU{l?9i`pzBpcV+1nrI{*{IIO zKhSArvpux>@HASya(MpTf#5-=oHw}FVjz@RvcAjK7Je5rFd@hDY$x%qOq693EEDT} zAU9VwhEy&Pnk%=P&gHyQHi)UqG;g@d=G~PU&oJfq>RdikD&^)$f>_Kj>lZWZJS-*{ z{RW?tLhLM<71P;SCC+|7WT(MsU{kfPPIBI(_GBbV0c6VN<}zghGT>fZf~&=OzMmEP zd~42UpXC{EDq+dPT0URo$i$cg36=zrtqlK%+yCx%rbK)3q_Wv8=_i~Di>dTAO9?@G z@xEB<h^eFaMlAKZ9jVu!W}vgxn*6Wx2Y&me9O?3hp7#lhYBiQ~08d2OM1oCt3}C>k zbsT|oHHkoij73vF64Qn?G;R2s+j#e>?9oyR@0C(GH(#l*5CWKbUv2s7!2EPMp>Td% zLAyFINE!^T5W!!<@e=2A#RXSVSeI7C)*Qgcc{P={*TmN+GfUp0+51_MNb?U990yN# z!T4@P!uTLl?wME@WIfy2dMKHw43+i*nxw-*n6iYc>(+?fq@0%n+k=cA4jtE(c! zOI8YrmpA{I!y`Vs!Q>{;&!;ygM@*e<PEcU*bq9jdU_byCGU1Dm2{$`eU5~6BMQ3Qn zrRDop)VWNlOn6nQ`~>$GlW@#)RcoS0W9jq)ur0ycf~u9~GE15YOp6)$yqIhYaZ*|- zm9<3ycNa4&G+kdVY4gi@g3JZ=s-9U|g8b=L3y?#PYnW>0GZ04;j~*-SRgV!YRx!B6 zU0F3l#6irK)kQ5+TGlm8^Ybe^LCmpvb)~qB7bvKi$BVfvo+88=Dwtm`%$0M+!jPIR z;##P|hcB)9gEb_T@=&0e-ymI~Ao>eK?6iQj;)~tZ?tEXW{05_JFu?}hDnI@PO;0wX z>1U*h=<CGmkKe&RN@XvVy#AAo&A8~p5|+t;cj@Ka+;To6R1|y~*6o~!@rxlm%xTzZ zprI19)R?ek^h?X6rIvDp8z^<NOHpUeQV$gnkwYh`)-K`k-TVitelLcLriusQ40^4+ z1&S+BN!l!-4JVzKc^B``vs$;%WR*%7H?|wAba5J&awuerDl{|Dl$9221k#fT>s5Uk zUWT8XDJ|f-;?-%Qcc$BVTWIOZS|(dtl5$aZA(DaIh|E$k2R$}PQ;1HgkgLmt{KU^t zW>sG6q29khc7-8zxJGqClzPo`O@U@8?HyXGNEC!p-5!sZN;i)esr}>=cyXH;HwiH% ztNC2A(s`)JmUq6nlPQy{v$^tgM%Oa|WyNG(sn?qmAoWn-akeud&EZkDEy1?MR+G8% z1gM}1ProrMX?AWqnfj&>Uav!VUGK8LswYd>)fh`at6?;Q-fEhd9Pl1LNyE|P1Kx%% z;}fj7=0NKBxN4r;OG81biU%TcngqcKeQdQ(X5M!znj85IY<<hor+J4yEPAx7U)i-c z|Gjf?9aC-^P_3vek-*I4X(n6Ud0;B_GcFvR-V$6+Zi}T3(YYFycHgE>>-`a-^?E-P zu$S3RGJoxfvONj5CwBN0Zz9<#i%WrCYBAwCrL1p$22@?iQw;Rm9&2~|D1GcJA7jec z;WBy744Z6$e5dTrGdI%r2Kje0T?1mN)AR%Xa^H)IuSy5uloCsq#k5?S$eNyb_xSU* zeCs{8w;4UX{?OA3w2Cgm`ffnOdMwJ0CD^eTIi3Ik_V6kH?Y!)5vfIO5VT?dH`74Cs zwh-@`+$KA;C-cur=1(Zf?W-U#+wdL<c3>aG*ccKh43iYW?}75lnOuQSLQ1gh=jNdk zBbY@7t*i-@8o)fl?*aIP6z&`)h`~4jD<*ew5Pl9E^Ej^cz#G;5DC~7|FNq<k&J$p& z;wF#EE3lNkUV~tJmGZs3s*?&17&ggN3GWZGadN9Ad_YXVW`9T%#EX}#+RW}+B`mAq zhjE&E1<e(P&5v!9rsmm%{j3Sw$iu^gZX{+o5Teg7UOrN-EBH-gC7QHRW$0=`OgS*I zK1e3BO|YGf@sjrY=W{x_ksKB?9!2RdFXZ&B5*&W-=*ojkN!}2Xn^9A!gg16T^CKNH z<6Zv-&at5&V8Vbf&Bp(%sHB&;<lus28G__l>#!pjOAl}%#LxaA4!><3?heJ$4~Gni z6#f<te`FmVT@y<$kTl}*D*Ofx-!%`}TkyJtXO}pa3<kr`1&OR(oKbDyEQ;}RBQL|e z+{DYxyxhXeJ9xR3m)m^wf!p8@clS;Du{NV;W1G<vZZmo|wHZB|KLmP$LAEi-B49sb z(glJk2{HR*%9L0Hp=|MoFs8&BA8YVDs5OZIQo5rpsoLrfRe1eYpw6JO%_sWE>!%y; zu<0L5e2KsDp2!YExK#p7;VYpQNBwe$h4u;#u_*RYF+#<DDh^O_kcv^ayX@!yK?zkg zoo2<M1hl5-tn*jXeO9`m8COGfCe?1P6T@C7_IaHc@j9{J>%;-C69=6q1mrZ{SGfE( z+HfA&^zH%6D;SMT4PCLBSW;r0e~#^5A1VvglA%0x!%m+)o;%^<4O7i)pZ`x^ut4Ym z6NILpU2D^9#Je6+(yw$7GEAuwhW=r{l2$F;xf?L_Ve9Z)IQ)@ycoZ;n!GfW0;P74R zPy-Bo%7UT4#Nk#GcZQz?4E-8EOzq%Ub34b5ck*%vFZ+0T7ccvHsq%8CkN9%CKdiEG znO8^P-PvaJ>}WH3`r3@1yV{JN{x+jW^@pC;;G~`Y5Z9rsBarm01WEWC?|JVI36c(Y zf}~F!Xemf?N#_F}ap`<(7>8c|eIT2EdTrKD_(Yo2fKUGYjo*EOylc5?bGih7*6W&S zHA^knFbb{qzn3Ev!U}LvY&fm}T^!-d`a3&;!NhzQQ!eT6qms$gSRh==UDu|I^V5NT zPLUY0c1zL6?t9=qrd(ew8aBSe)AKnkpS6(HD^8c-snicS)nbKc1h|D<G<{$7c(*?s ztOdlO`TK6s0(f_mrV#i*UMH7%a^wm>0WQq0hbz8VB|DZ*GAHU9Mc{-8*O2l8j3$QB zL*>0-FLxjz7ZJK7Tf{<8awA#Dz&VS4l~=<u!Y>~(J!#;1H3Mgk-^9YJ!5KKQa8D6Z ztJ8WbSXb^7?ql#r(J=kA)<GDny<~;LB}}a6nn@QIH7t{wscn3z<GM+cV_JVoE}$Sw z)60e}9uvW-qMpy1N_x`S%gg!O4IroqU+O7r_gF`Um0ofV&CNKRK%<hXe7Z5>Zu!By znLXtKE&6c0hjczLr`pDvE-y!!nog&%cQ`x>Twb6F@&YZ+!;ZjP4{JkKhc4_Pg`HRj zXYrZOe5hXFyZqrdzD<{Q`$JFb_#eCh>n%as#V579n`eGw>0J_n!WSyu^PLT{^LVnn ziN>6OL>DBs)R1SOyxi^+M1FiT#Va#>IoFIvtHiM{y#(Q(3a3<|L&EY^a)spw!WR`c zo)R}=<Z?747uA!mAm^@fr6|1kyj_pDVG*2`FU{nvP24q5yfQ|<x>!d~L^&CialHqS z6woSyMP`eZ3bKJ}-S>G^Z{tVxDit+)@uf+=?h@KNLkA@^Ql>f9lQj`j5)SJ9ymiP& z{R&vq`W>YmOt~!4o2CbNq$3l*rLq3N?mjb>`l<niBq)%B;;}LISOQT_s;$fXm_GyC zy#R<nVf97pbf(c*PaO)N#$~bINoOkXMz^am+(QmAW=`JsbwEgSMHw(}f!wHtr&y~U z`y+fYtbGBf0~0svfmnU*7k|Y{EPb8*0kf@oECF=Wy6_LIEyTiLdt11BNwdu%{m_iA zAz0hA@uF4w#^2n=)|-xKBbKoL(Hh4{`a$|DT%VfSBrQkhVyVy2*y8f*f5i~>$v6tH zKvnxC>#z&D*&$0e`$stZQ-0{1D89#^5$hX018qjnV4KksZ8Lg)!ykHD0Og2Dv%Vj| zkMFT4msl}A0E5as9Jvkfa*&r%Uj9atSgwP7`rymQefk~_0?TdeJIpl`BW~ugs><nW zsqXZ3<OBEV8&Y8m9Wj+^;tiaheV#sk*1aD1$l<hSU2XXgj)*5Y9LK6ZPKI5wD)D%v z;r}NtbUNtCr*SOlD1_otPz!&+`VZk)HEy^9y1W9VgWx{nG>>Lbm6B@jO#u<?^w?kA zh<M`h?$z7}>$b22rj0lfj@VrV4WxS7a5MD7k+4x}AK>ei1nIWORVFP}DRtX*twk}0 zFCifD6psy?V7nByTa;t2efSm5mlu>ZhC89<UuZZSqG@zo5gJ}i{rM!JaEUJF1HDoq zDG+6Pog0Po#o?}~0dTPy3IuB`Iv`l=6%r2TY$`r8%8I9xKh;&=9lj~>W#Mu|wd-u2 zN;LZR-VHI!RBl@Yu;5$-@O=7NftNN&>~-{pEhONRvDDX0=(QQp>!1a_{w)q);fK=w zdk+^9dwCh-<-I;ywD<TUM}5O#d)thjm_PKi0%ru3d;KA<15u|LMVlrBv5}NPH*c5r z$l*!^AsC)II_#G{vT78=VKXM76|~ShilKFl<$)z6m($J3dX%T!vK*I8BqErCFBH`m zaYEf<h%~pL@Yw-~{C{9z+n;|a&y+|fkcc^({D|uqBK8<l-|3`RtL(}W3^x{HsvtCf z6(OcjvslrHAX9ZBOyN?;!b4ISayvq0Z!|BJb_ME;vh#=mSb;c>)r^(d;3~!MZus9D zX#Fb(-_w^69L}b7a)w}=O2Iq|^dOffV(}hA;FF%DPpXer>jraoXqD<=2V1mgxjeQ8 z5NQ?`Ogh68*_xvg6O_mPXw1R{`^^!Q{(gr|9~19_uiURK7dA5R{?@Nj?;1FO{bS7T zO7{i8fEO)P&<7375lbQS4II919gf3UZpQMRdku&02-Ob)L<6+NIc!Mqa+sI<csat$ z{k%NjBdCb`BbR&w6^S;ZXSmJi+1F<DjI<d&`~9J(H6ZYSKg4w?o#dAG8L3CYU-<5C zkuXrkNVjD%F@jl7?e_}?R&_ylVX*xl4Y#yv(9`qvDrG-c>3F%+e`H&v&7iOJeSdG| zyVuE<B3w>P+1+aN+j^_gSn5lBKF7X|ft*+;U(gc+_cvzT7tK^9yoWf^XsA_jwJWd( zclR;iZZ*dn`&|tMT}>MS<BjQ*z{qx6cKxuc-|G(EMlse5*v<1LSsmpS8^&W@H&Rb= zP>hxPz_al&7EiD^f#Sh29^i>~cSd=jmzdj*=svE3VTEq3B2Xnk=SHp3n}G-!6QR|z zG~p+6wBy~}eS{2#6fVbH-h7;GMaq^0FQX_|4ZSC>?B`9bD81CkSm69u%38jXkRxat zHvXy|8?&xorOygzOn{Z3@nS6XjK9#>H#B+BAA#!|J)><#&sdw$b6=a$bEwVe8TW^t zR-jvMN~MfPPe$332?o8nn9v^NQ`S*lj`8w7ULNA*c#{UzwPa9T4<Bp_l5&j<s)>GK zP_2T4r4H%Sbq%WfKO}?dkh<T*jDib$*;K0qPZ0)4S%)W71-Lb`(Kv3f%&YrrnpZ2H zY&SJxB`kjfkEc7$thm-`-;@uAKFzY`T6=c$rfF`i^SoQPxJonZgPD9ub46;Y(Jo|u z9pZuQ?Nr)ZhK#U7s;Cy%cr;KoTWpQT8ZCti>qGX_hRJpR`!LADNu9ox2iXX(D;=!u zy|$X2x{_i8&%jA@zyK#mAXJ-L6D@k;!?jGgG_f_v_KdM1#3>VHg73Ra(-eEyFu|I} z+EVTspizfmv^9dm46mO3+jFFa$EpAUFX6Y9eu_JAKeu`Yfg@+&V6T*==YJ@Z6&&{i zj_iHEKhnZC^mEuBdRid8fXZ#5`RhjZzMspk!%fOAn6x9Q9b)G9Fa%gPbtf-G?^;&i z3NAf1^RH(ty|(3N7!Iz(R6xci0(1{Qy_W0%CUXCQh$YWk^o<yc;w0^dqYBbjl6Mq8 zx*0^`N(14C-wYuY<{IN%q63LDJE&4}T?{Hmc+*VqGRe!2^YQ^+9<^((ks5b<$S@3$ z-zbk3Wht(h(h0K#SuSe0D)2}8lD*F704EdvbatPqO133cA8$*l9`J`Mbl?_nEcE-M zKG8?PV1T2O=}$_9GX6rLyh$pQt9T{~nXR50X_Z3RM8R3^vNh6Hx@2G-Sc9G33T~A# zy?_T;s-`V&_xG)jE`_?zP~N%mna{ouQX%};<!j5PbNxP3&zD~Bbgq9s{Xbm}Ua{1I zA<ozvG0U(U)?mtg$};8t5{FyGy>gLqeJ{5<!s<bP2CZ+H?4dTJ=ixS^=a@hAv_b*^ zbcr-y7o+TAf+3Uf1`fd<<WTD&UOvprV@)De_?(R)i?YzNY$YvA^iH8=+2;mrrrY|J zx>}ZfABL92<g|RIy040UMX-0fTX#)n?$oDLt-f+1Y=4HOC8+Tno94u+Gimw_E;Obi zsrpnOUaXqNL%vhh+UrXqQ**Gd)q0Lr(&?6<JbN-%!SqtLXJO_+)|Q7RHU!C8dk1E) z30q0O*!3AasI8&LFf|^-Uw`Dp2~&h7ED>7%P#2>g_lN2FCL|y6hn|)RfhnlnN1|*b z!A4>->gRFJ_#bJK@k2#1mj0Y%{D?&!?|EU1VEhSB#(%CZ<4=6BjNi$V6DG^IGvOMn zS8ynV@W%C)l3Z59d6c~(ah(VB=Um*$NpG2)D*U=?jkiXbDeh{%<t;E@$GRS4T41tf zM{sddhkHv(X4eOhq}9_VS0$^G*SZ<4seKbG=f|*q-p~bGy!7oOk4#YNOEZ*^E%jv@ ziCpYU=VPfBXVW^-wk(Tut+yCI=tPrj3|<t+(|KZJh#&M6*cf|tll?P!^0LXgysUsE zRGC?X%zs?dOUQZR4yJ*mSIC^;^uo!gb44AYAC{0(i(+BSh=o<K7BrM?hXXdt`G)f( zqtD4yjDjPHcsy1@QV*`=V^x`QanYIQhuX&qqEVI1+R=NeRGIU;#^pj*o6i+A#6B{Z z{QIEP7T2Tl?%Mpx<Uj_e6zUX{Gje`JxX*C#K?-<x%J_e|`?cM+=nFCfGOc@)>jv+2 zvmoDdPE$sdl_*<Duoa#W1w%caWO1F1kTcbuB-^7)7po*2)Y%^Y6HQlf#A?*rs#^Fs zp?;h;+EVZdd-%9J4jeqdl%K9<%F}ryVJruyja$gtI<4uQuxpy1AoUZ65SU7xAT^Y+ zEW;McBgr=FY@0K@ona|)GpqUrl9T?(0v;UYr>Oz3(QP^#K-pdUz1@@|R>~g_|9Y5b zK`l=6yvc!1<cPM~r^N}PpH3l;65D*4*5+>RHuFO((=x$xAW->*_1@3-(rR2I3t+&R zCNuSp<CDfxJ`O69lt>sZ^G=RN*=T}|y7NxrqE@fHh1k4|_vF%ZJxR}GkE=P{U)t0H z?UMo&`Arco4_St)XC<Och)x+<M*38lA(Dh5U$DiqMv^!+BSe{r8!6BfMdq7Z(B`ga zJSXEZkp%U9rF`V69?eXTcz7eJ9*rKt(>ih??at*W#Iiu}NC{~y^+#ezb9YYU2dWg+ zj@sj>skTIMrC9WoCpFUG{g*oiwpI!hGA>Jja;@b8g+g<DFUr1`U`WOW12a1Nxg<NM zvx_89&Lr6xot>lIRFb81c7}FOCfP}yrD*q9k{#38N&m%64PIR1R7-`EG}GCI(>D*k zagg%*QeVVZQxsaJUXfcFLE7;>Vc&pB@i$3Q)VFbPQ5j7EP>@sdy-*9>RQOY>@PT3h z$hh1=nUPo2hae;u)oiAmp%t1%8#AEa5ZDs<X87yDzr=hi(a&eF7Tw=(Eu#gO#eeEG zo1>H#YICgr!F(}eg_mvi>m^c%A5HD`O|;jmo#OSXG#GKPl6qHTjFY!f70$_jZ`8$~ zUo1TQDJY5HQnXjqhDnX$SQ=ZK5%ET>8KX|+%&r32+B0(g=Z#y!mVb-Q)VI%R>ia=D z>x!fGycNEIeIsVMyM)JK+ncdWeXrs09qaHSR&73ESq+2ADXvd@l$R-9PVzEs_h{+T zSx+rygU;m{a|5IAls`DlH?`-ZZAMS3&FGo*hn`lbg@a1kAL3~32V6rANgXi$!Zl>0 zbPcIu{Syi}^`U(&a1Ajh=VFev@5As45zNuk`GZKT#BLl6y8S-d<ZUGPt`W)U!*J~w zTKe-P&hU%V61@n_SrfgSrY_$gdO7Zl8j#B(t9`Ca*}E&JfQLh$fET5a`7v%nlJx6N z06aCx1qipm(88!b8R4D}a9C!}+K|>6E<HZsqx3lA&wy_YH~NG>#Bmiwl4nJiK<YbP zk{87*p_JrByW@WGA}b~hSGo!|6gOSLtk5<x{EeGgG{_xXoT2su{2ISdF<NOH{>A)X z&pShq5$ZE%eyv_|+j1-}L;O~T5~J6wWB^|Ye;4r6jL23F^pbYZYK|Yac4}ga*CN$H z_2acPJ6oyVLh{WkTj=?bmq#cV&C+sdVH#@dfU;mU&*vP?GnIP4uJxQ1!Ds+~rvky+ zt6Qa}vvGwk%-1qHj1jTdMxUEsKs&kN(8GtA^7N`0*weF0t~|~2VslHLlt8aL-o|%@ z-*LX;nC79|WbB;PWUf4+>lqSG{oF?$4bklPb*VzDym946KGAihivnF^nF2K1dNB~v zOXgQjKj9LFskiN)S*)U;;?m`@Sn63iS1mmFS$_nDF$Ze2uh7iwR<8AmoQQ7h(;IM6 zC&O<Wz1QCGRl4t8xBV+De>ZT-L3|pa@=0eqZGAT0g@n{!T+2VsF5#OV{}bd3v}FT4 ziOH}nW%YkkVv~F>OkXd&h^g^2*5N<mP_+UYeE|WDUbGJTkPPq$`Ob=!B;UZ{>(=3T z2j<{bn!=!Rj-#UUyu856PxA62FF(c0X<p9oGUFqDI_GcCtB*tLXaml-89f);jGj-n z89f)<jGj-m89mc&M$e2t^t5Kal<|kS4yB8<H-9R%H~0(f&2~9sI_MT5t45@#O9%a$ zF}c^pAjy<H%d=~ybMV8^=%|L9@Bm_(mv|VOL3pB3qG=;nbkhl*-4j7tgWo{YG^j~( zr*Qsf)T(~XepT7^MSZq)=x+0c>8T@qb0YDG<(fSs7bgARC*S%V4#ZZF^eZ=K0<lz! z=MEoS+)elbBvYRk_N>o?sYE+(NFNF>rc%07tu+3VZm;rZN^p02A%~1n%Z0fzIn`0- zy}~_ZwWMi_<Y~8}E|;|V<-7_f0Ukdc!55Yh+Z7G~$h<eJ!NCq@$3hNDy>1o02L*Md zxU3d5WYU9O?NScu`!YsiD(fj!1zndd(z7yi<>gF1zk({^TyPcs2=L`Yx~p<=kC-h9 z9;xPfDU>YimWj2GBkI8U)mh9MiH{%;5aqrB2FH5q)Q<^*zqk4*xe00Na*%=q(3O0C z3D>{F!o{Ek;siLe?*p1un)8)I=pfyWmT>orn)bfO*ZtW#YD%<!<xDg6Guv#2GH-s4 z&t+&@QQN*Y>yJ>Sr}&X-3Qc6Tm&)7A{<;<I6&(Kg@9lYp)KE*y<!NG3f!?{YMwv>b zX5tw~ySRe>N<9m81{u+=uCm1)<&0ju(MfW(Oj=I5tGwXe9=(TK{+$_Ezv|X3{E&Ze zL^H;8dkzypQnve^fi>$-Z)t1d_*Y7#{(&>{uuAao<sNvpBLS}a^O!DO`=w_BoRupX zI+%8b=Sr=bPSxS4Ah_w{nf$UQ68>>sjwd_Zpt&5ln#<?8dsk_BZjP8ZL_!8xQ{hI< zUA?^112&d$v?bY4jYO!P20@#@u*k0}9kERmTF=MpWM-)m#|q)%WiDZ$&>^g+GB4?W z90(2)Xpx}T1TE<o-NWxE#_%I%BE435H{Tpf9i(%PVBv-;u4#pc*3JXcC*q`m>t|v> zZlD4A+<N1acn-;U-66?WyQ+C)=G0WJP+Y#WKtPD+F~({HIA~>Z1#)xDYS$ctlp`MJ z808l^#;Eu3lZJ0vBWq4dj7gQWk?~*({5qb(({svGwGO0^fFBuVS03{KvT9=*2U$sy z(jHcdyi3VpTeUAm5|<l3_~vRQ`=TLniQ$-!d7`S)Y*9Mshm4h(uF=NB^}s3;;HiLz zH^$G#nR3s>x*+RGPOJ~I(b<VZX0jd{Fd{sE1IFwlE}IFzdGNrkh-xBWb0W0~xi2T8 zsU!IFh2yDbl%NqGlvlYkK~;JLH5FINIHLUWi6~v}jgmYn;#JsVl!|8`ukmc#)d3?B z(`7cemhB#6ySK3TEE~C<jVIaoT1Fn!TU@3yX@g)L+gV2<bm~e!?@3N*R1s3v@bT<T YBJLaOh~m~>3h>s?<GUel(FW!J19^uaasU7T diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta deleted file mode 100644 index e0ebbdac5a8ca12ffada134deb381bda9ca0a76d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmX@|G$oY*2H2qtPAHw8lbV>TpP5&}g(8rXS&Sx<l9^n>gQ6zCpd>Rt4^^xvwYW5= rL<B`$aY<2TUV3~|X=YAJY7sw*TvBF9d}2{iV&%$Nhtz({EiVE9yu2zO diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache deleted file mode 100644 index e6515db0ce1b9bb9bd46523539c10ecd31e3f400..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11362 zcmeHNO>7&-73PqlDbteaH61%PoM=oZHZ9APL`sTHI924tPAxczX}XPJ*ASQFiduWQ zOYbf%$qkUg$fa(O0y!1Ev?$U7ZBd|gQXoiBAm}MD5)>$kqNg6x9EubHf}$wUpso77 znO*)#qWq&MmqJ`|NY2i@dGo#ZzV~MLv7XR(!cRq%-9_c`$mrv{g7J3_Gex-)zjK(y zr-#^5#n9C1@T?JtSgI>O%{Xo#RyOqFQ^BcMg7GlBk?&<J6#o~S&i|VlzYbo^za2y) z7n;tW525jCsF?qZ8sF}@n18hgjcPcZH^ONAYSWecTbt1MT4XwZA%e!S-kbU3y=dss z8+jv&#<jjgzSf6^+MmrA`l+$?T)w;&jVEK-{P7qX?*v)=4lcWg#c$&JQG~^B<FcbH zehb&<eJmdB#}#Ao1g^htWAUJZzHt_R9oO_jEPfGJdKZhI!xi0)ez=NzFb1yTUcBQP ze3Zpc;7aU6UtGU`jKx2~b^8E|{}$J+B<4=CCAH{SM%~o{lQY*<qpmTQ>kEc*1r}CV zG!S4c5KuM`=aRutAdu_9f2M3si&tdelmTTA2-TnM_Dh&yuWsaO^j1`AY*a~vmrdNU zh5Vf6)@{>?b9YYTzLZ?Z$gNrNt!~!pE>|6{@`8}1kcvk6{{8&qf?BN^nuAY;LO}=^ z<zH!xB3GI`GMY|}ABu8%6CJyEA00`hsW;xJccc)F23Y3LyEZ+%RJLYn*1TpzUqXA| zYSZ3}xvvWC^$Hz5l2+&yfg&GDi&v*2??JCYMM>lyhF<#zm4~r2(Fo*-RaJK`5X}5? z@9*}KXeCWI^gzh0U<bdLy&Y_mAx0DWLLA?o-%diz8kW`2&-$Y)-6p|+n9UbqKK^Q) zL~!l8Sqel{fc=3Kk&y6@oHm=_7ZCS^$jYr45c5rHwxL4x!OUkndv^(>*jBk72$ft< ziXV1>Wv&%0g90qW0Lyq<ydtqPy5r5;-5&1^Mi+BjnkR>mM%(0Uw@j?$AADrrK*@lO zdETOZ2`}g55`Z<xJ(?CT!uz4Lcu{j-TD;bP{yi)qq$ug!1+s*q@(LU6|0E<OY!`kB zZpCqJy|mSB@fy6Sx$~N4!jBka##}Yayk4uJRkZ46xw}^pib#&8(nGwen^``Z8beE6 zpw<LAjMNzXMXUgS!Pr@b$fK}>Q@uf@KcVzNUiu$Fe-@13e#SDjP48|Jc(p_bv-JnH z+^hubWF9LwD-DM&Fnd$(`xQm*I}As4XIv|Ysl~*?dE$eJq}cnn!XJj01hR!4AwWEc zPg&KJrV)Wev?w52Z0~8EaruslKoJumLB<CP2_`SVKnp|M6BaAys$uZ5R?@2~-t~&^ zI^DO{UuQC%8q0{kqhn8Gj-q)K8!N&<A&M}`GM9FKbLSFVoTC|wGpuA)YpSjJ%6X&B z!oO(qC@TGtffwwuW_y}~-;LlCLNthsqTI|M1qcy|<8utky{$Cl4*GKYY)X(R{<K`p zNr$`hmLF*yKCioTI@yeC8Jew{C2fe?B4`U$L;pgELKf&h;}-a=Wqao3&Z*`QFPyw4 zztpbPRl^zL_`UF~*Rf)2z?Y3ZRZZHX^K-hxXW_qH-NKv(?9|~R=5r~u?%@0RIo;4W zZUOBxD^Y$)^dNE0TDs}-)76@d?RPN7<>Z{})|~9{ux6&_^{aYKE9+{?vMa;%Y1qH> zNR95CQEjZYs=0b;|5T||x7E_(OwG26hE{bBk$}%z_)W|5Q?v?ka{>ASb!lja&s*j} z7rusT3u?(FwT!1S{0JXUjTAVRXIifO$ynrtkyK_4Hshns+q5Kx84{b4#fTZ;UTlkt z)o1yLAUY?n5pjVZ;-_c%qE+YfDwN_{yfmkku5!!7#I#FdLv(jh^r@<gyzXdFX2G9P zZdl=Ra)0|bhq!J!t~Q{O$L#QR7nN<m+#voh`GOH8VZj*T2wv}dTmHGFfyBV1oMYqT z%b@g?u@jbMw0KI`&5isH&u*R}ySW%!CT*u@dYaVg@Z)VdCGNV08AUtnh-499_`ek_ z<MizaybB{ZZ`T24X$JV;NDjIUG}>uRqj3MH;I!mOp=D?v6p@`U@4>qR^qC)TWic7< zMflv<gaIUkXwq5Gq?;j<Vi|Cy$M0|V_^s}pJez|s3eWFnV?cHHXo`stNa3W?sSJhB z)QGnaNSiW$jQuAzi6~OGs-Dqrq)xJeZa^oX8~rzXJV83u@~mbe(7B36+)>KPXNfR1 z2qdYcqF)D<#A5Yoy(*|A$em~lazd1&Taqfr1)qeX;L?SnCdMW*<KxHD6Gx9tjHHjY zsO@;-N&?uDY%Rbl4@Sqj5yf+YT_b<L0O$9!Q0t_fdh$~Dei8p9kAz1<=yf#HRYe5% zGI)g0>v~x$`ysPCfc$k<03$+B0&fW@LvU+gC=@;zo-FG$A`p%u%MH9y6$8{q7Bbc$ z6_+}CaT19{-S88!<*9vQ#ne9Xyxxo|XIVJRkilnjh<|?G@==esf>o5d9mMszU@*Sj zi7E&XDH0kf)f&t}swg=^5ChJj$rr8?;Lup^7ro8`kGKPUPTIC*C$SRIpXwko)}u_d zYpN%xg!d>YofQ`m)ZcvU)5jE+oiw!y=-gR`ZFrD$VdcV;$YZj(Gg66XV8Po%-i)g# zaf?8v5DLcXD^lhTJ|w$CQ7*_++7T#6s!rqrS026fsKQRX>=Co(s$Xf#1J(hH&_`Fc z4{)8xy)X6hG4ygL>I>DW7?0x*uI}+Ep;|{mzj~F<=d&%L;*9Gf^SmYLJ@HYWqJOdE zKHAEHTS%}cW-AN!zVc|WV8K*DrJTQE8-uV7pYmG0Kj>9hBBGYdO^|G4*h}Qzmf(0B z;P_-S3DOCSsdAYxaln$14sENVA<WriAE(`e_yRGnk(q(E>#!sEdEcrEhf@V^p_Zb$ z7H;au<dF6txtOgRNFDf`Uctb~1CgyZhIA+|tRX#HBUgv)GH3!fa7-EBBn5IBEKjf2 zEZgNW!8K4xqq;D?r)DjqoV+C5oIoB1xIBc!2|f}-W5kJ-M?^pV5^BqsUe1i5jXC|8 z^os+3IH0iNl7l4I)@G23TbA40?e@yqUDw&yF9-?eS!}J%?+LdH+lh#_!n|A-x3MUH z!|$~!?`sA_B**+{BvrXQ8nt#lGKwu(7LN*G<KO~6dE`%zkQ0VGFV{;g8gI9+VXrpt zoovYLZ}_fjtf*wJavCD^dcv<rf;08s3HicwYV<h}3B6`))djI6G?FeGRRpR=%EF2? zHg8Go0SeX#Z8dQ2^+{gB*~Soz0maF&RQfU*MkY1kc~g}0UgAIH3Y!-7Ue$I`84m!Q zD^{jEz_|)nB#o>)Iyt<Q;+H5<S#va;C#-bThZUXb`9_bz(gUK~T^icPttFjXkREpd zi1<7#rR>DRl<R8Mn!A&nEf?!RzTxrc*3+)mgsjkHWhf@ia@|FB$BBxfQq6K49i^&v z#B`pHiHVYeQv)Vogpy=0w?VJt)QP7P?bbI*5ERz;TIfAgxj}*G=*g@!x1rERfjS_y zGQC^V#?DKPo`*(nhx{o!b$X5p`3~==XeEgrbW0yhZNZh12WB@vhoTub>(wG6P^+rD ztIk`dr!f(F27FcgT=_tuAn(+xO*L$!6H4SzucGwg8B$P?1nE>xzFwv5VRNVJX<v1R zi@`XJcnSBCNoB~rOwd_sWAS|h;{ytNo!pDaYgu)sZtAFqF;a%-W}a%pL?lPa6s2sd zZ#=n!6FHZbHK@33bo1xom*u$C7|lb+JmOGbCsx&#sC&Io=q$s{+IkU3-(}(+O<bUV z1@sb;pFeq=U*N|nNAiw@%E)4*6LyfuYW|Jzwk6GRFs7(atM(#@PF_Pf__$wXo}Zsj z$)i9~V=h~z;i_s5lW?gyw`%N{l1)~RjC@6y(1-i~vfuN}Het8TGvB8ft$N(jadIgp zY@S@cx#RsE1Yy)MR)g^RBr|XTohO1KLr&ycN>(>evQig1A?zhEeb}9r>T0Wpq#ZU? zyK*lTD|LZLU9)19i8g)QZ?=8BjRFlSK$hLq%YAOm%Dzvqh;**S!+k#_C+u8*cmGDm zn)mPC#0ov<26YJbAX(PmwnyUx(yC-IixQ+?LIH1Dq`9b0y^reDt!S%2otpC4)*)hB zgcVW2qfmQ~dClO)<Tbu(B@iV+KDtsWvQ}y%fQ;BgOpsC=k?Q!P!*i$cwMPsojyI^J zm*Dt4Ne<!X{m$TA3&}T<f^*U7dD9f$Yjf=D;3C$OSfVzP&V3*w<6jXOw{IB`&+v4@ z#fv0|MT9^J6G%r&Djz^9s*Z-*FC8%2s_r0?c%(v%<n@Z;P_Jg0NQse2iXxpTT&z)} z6C=nyr}7ds4n`)A@dUGI+oG1va(B>IB4xF{KoB8-9)BXHmrhNjpBNjRICkubV-v^5 z)AXRz@>?+^rMhx9Yc@+Id^v!Zi7mfH_N5h2E=|)ld8(X(tyn#@W>G!-@9wER1S=7a zny|W058Ea9(X$3#@&8JXoNgHmB!Ar2<OvP_h`fF!-|9Vp(9WScNw-*<?^;*Vx!-|Q zmq7==uJGKBD~QS2NiZwPELY6gUi2Qt@#@nX_B2s8w^yokFBBW~gltzS+{V`jUIROv zUUKS17bog?Ac~UDFC}_>3~>=XP$X5R`&tER7kY{3rK}_51WXjZ#PQFpZP7`O1#sMb zUF^ul#1CJ&N#XjXD}mjvgtfIIh_GVZOJrX}5K$fTCjdaZM-abba)t;Mc@7M?k{n*d zY4jIU&Y*v@&>jVRzB~Btpu!?gp|&cYry5lHcPhKH%I=-w_+AMQD&cgD4txj1VXb#& TLkAS$bm)bv1Hu<!h;8hD2FO3Z diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta deleted file mode 100644 index 8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache deleted file mode 100644 index 01022dfbb3f019f439694598af80efcd06e9154b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5793 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 MuDY({!WOgaKaT{dbN~PV diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta deleted file mode 100644 index 8bfae6dc9ba127cf7714d1689d480cfcf6ebdc98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2Wbbd7QGhmnF;_hmjz=0 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache deleted file mode 100644 index d87d203823b36c987b8d2307e3e1777db89ebcfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18155 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta deleted file mode 100644 index 7c99d5d905225ba7c564dd44324b01b038d7953b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache deleted file mode 100644 index 61485ce0044715aa244f337e1bb695ca69369d15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2856 zcmcImL2ukd6!zHbc-Lx_i~>PHmG&u7#U`Xl*FgwH(QX^5B}9V8I1+-W%6i#J;>2rP z_LwA1D$Z2B<iH=Ogg|iR#6Ljdgv1T*Md|@0PF%v9ne3*UECob2Qf8mWGw;3m=6m1s zjU)Z0MJHD2HH%*Ra_sYxMd|L?N$It*?@QL{cF6qpd=P7zrtHm(Ya^{NXx`LsRdo99 zLwB7RW0W+#mxwU*Wp7kR<99vv{t(75hU5KgpmE*&$h%>p@vFJ&Jr%|mL-)O}hR|S^ z<Fza_J}f@;8bxB9w&Kks4I)m$Xp^OBoNC0qq8o05n3UL>Mu?`-(!5*I4NY?kI1*Y~ zq$P)zth&c>>vmb@zNTJHs#n%~LD-!)386G~LHz8}B^>Qj85Cn`Wf}FtnMK?+f`62} za;u<IbCDKEJ(J-yZDD)pWJr0yoHYxxCIia4=^l%$SLrdS(jU#<pepIJOM?&6fU^w7 zeNcG<kJ0j@mY=pj9&*mM;hilwjC0ucBQA^-;+!Wr7mJ$=Br2>0aRdR+Al{E43?c>@ zW6<b8CVe%8v#BY#ec-o~kl{n4(XgQgK|CiHs@tqgt^|<8$>g*R^Yd`M2I|=cydbp) zZ<#Ed=-=s|o&^{bmdi*gLWfsrgH(s_7dqkkqBz<YMTONY_({T|7E%v<h}gb_2m$0f z3~;_5GLoXt!V^Xkns(mqfd-!yG<AumfM%+&Qc(APPS-&}l)5{LZaYY~$CtwPg^Kot zN|NLSA@v+8b@4*DtcES{`r7=-EVo!Q-#$ZW<${!4?MMmHHADPMeQ?|-iXBgo9e-X? z9(oVFCWI;j$A?e+FlUzw3@RCK;mN1rFkqo1$lF3!Av=t?e;|mljvP_DgA7u}^EASG z^S3xlu>b|7WEJ3C7Gn*<$9^OVGtY1)h#(0PCg_$umt^wvm-)4{B&tzRu2!?5W2-8Z zW0$4M!QH(|b-G))NAcb)R3F$Nr~B;++DV*pRE&%Zs&7<h!MP`_<C>hDYx_xME2<n! z!x0?7>rjOU=w7~;5&wSe3^;PF(vS^j78cO+#v8Nn<~{qoRvs0<Ep}UqW`q&;jDd8M zW%sIJ%PxHjN4r-_x}EbMy2uZO-wNl+4yx}tJ(-pzyA-YeZJwWzZ^(I`byban0=C(w zO?R5?e@pw05gF>ZgHlV!<w`O*O2%XJS!^#f<(K<vq-rOklK+2K?%R*M_1tO7mo-5N zLbn|&4Xr*MkvFbXbn~n)4~n5L^2@AQdQ`#>)}l^_XXx-aomiw3<0H#)98z<Jn$F02 enzQm9Kg?MDeU{}Rr{=3TZ`|E0-xi;rqvS8qHNxTm diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta deleted file mode 100644 index 48ca73e0ee43502e40d1b8b70f34ddf19d858229..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache deleted file mode 100644 index d650561ceec9c2756d443e974284f903aa79cf5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37897 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta deleted file mode 100644 index fb52d575e15e87bdb03fca9fb3c0bcfa695274fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache deleted file mode 100644 index 3df3b89f7a0e8991141a83ee6ea85df10fc246c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46265 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%0A# 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 F{vRyk5itM& diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta deleted file mode 100644 index 6587875a9ea9dec90101364c1e7d76d5ef2dffcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmdo0G9#4%23VmCPAHw8lbV>TpP5&}jUteilb?ttlwXvRTEvB-svt2FO(Z2Vxn%E! Lc~|2ZcNPEuC=VMA diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache deleted file mode 100644 index 44187b1f3e10bfbd421efb27189f53ea669cc799..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4750 zcmc&%O>Y}j6rKCV&SV_BlZ%_SNfY8a6p&RE#a0FK#<i6okP6LsD!F)*xb-BN#_?G8 zxP_`x5CW-eSs^xb!Ga&qT{j>W-5`WmwNfjwtk@xS#irc%=EEP@uInIJ%$qkeZ$|H& zd+xb+&Ok{16D}w?U&ON~*Pfh&_#ejr@p}BPV-UZk!SmgkSvgoes7TOo=UXjD(yBG< zYCgm;oYX@QQa-3O0Q7TA#&!wA#Wl6u`{E{jq-7@BAsU=LGqLS{wQ5~+wi5?-wOun4 zR=wqza-}K(swq^<7%OS(w7}az)sp0Ejy}y~U=kew66?LnuQU82rGE}`yaHKc8)&j5 zXN^UfCSQh9#+?vNa4KocPSNDNQZ(LCX!6l?%D6I3lONTB@q<c}Cy|u#I6{++Xx3Pd z(&SOBU_6Y0j0M0l#6OcE{uLeRDTo*7NKez5j^Yf&uhLPB(K!ZM%erL}F$pH?cOkq6 zM9a%iK^P@eSM|$GmLxqy<BPc=b{MfEOCeN~sHRa>l=th-vS56Z$zh=Iru0QR#frE{ zV?=DTJJ1rtC(m;2Mz!L2+c(x>;{6}$Ka2fG#s1e)xK_sVCE8<%cFGavSM`tiiecdv z3mJqd;2sBARIg)fHFv4uSa#jpy4{d8e#sZn*J-&JiH8@+sq_6XMHsU_IafG29t}P8 zNC2Ba@<Mn!A7wbVfX4ynvSLipC|h+&3i#7*TFxG@Om^n>Opa7;HXTnB&yK+9?ZKQ* z3Dk<jhLY*87=ssoDI3I#i)17($$$};9c9OE0%%s<v56m#3YPgs{zcYy>{`{O#h5*c z)_xt#OT^dOp)QykO3$<)P$jLAUP(awMFzp$;11mvtOThf)FNPv<b>-3=Q^Xd)3gtW z6jvmgeZy=@Qs&Xjn^9%g^o8<tVxg4uJwXWhCYi@l3YW@wh9}?52#L@$S`p<ILYYPu zQpy$0R=ei8h-<s<bKhb<v}(&8i(!aKKZ}ILa4bEvu*`9JU4G8NZ`G`p1U}T?Cx*J} zLGAb??R-_cXtn%(b7LT%Av_XzAYuaQF%I=bF5xewxRZqz^@KQKf-WN6K>Be01W!S$ zHf>%ZsSp$=7k5d&Ga!}})_e-{X|mCwqSge;Sqga{8w|8@pa<`VfkGQd{ykAWIJO?l zo;@;zH}caAV=0W%LOyyt2+fnqzl%JK96B}^z`qgxmnxGeD0#(0KZa8L7u@g{dgSec z=%ImSHoykWsqA}2^nVF`T;M!DDD?4hLLa<8DD)g#59a>R7lP0q?we-As_&B3@ua8d zN7V~zZpW%QCKUyq8pgS!<i@=Lx#6}Ko(B%ijyXZm39@|AU4nn@dIImDw1RDS{B4{r z%>M?dg)$~+DMZG2pvNF?f#~ZHC)$e4*UE3o;a;V+wQqjn^%3_b_ROK>;pB+&K+mW= zoa&@bA3p+e0T%!nU>YzS@%KyK3&n2S)J91#3z;0dN_J6xeo$#_-Kf;sl5Dm%LH2Y( zPCIGyT++XvSQqmG=R%;1;F{2%9w&F)7f$m|fkaUDE5=1pF}k64QzG@}5Ep@KpF#j` zrvRC^LR%q(Y_4k7Oven!(kCyVL&dN-LJahb=vW$u4u9#uoN!@`B*LvDSzbq63-Pc6 zWL}S4j3A^m%88C{^vUz$CI7iz6(lToGU6X?2LoC&=--R)xCb@M+z&mX$flPM%;s(< zu*RvQWWn75S>SaJW!xD0rws{#?92!O_$$Wfp!}t-0MdR56{hH-?O~!n5xV*auW5Gw zBr@Ns4^*BC+&Q{@<G+i4Qn0i#GX5)G{DWE`8e?zIJ-AtBMcGggl1kmY*-7kACpJNa z7dA<vzyEPc*J}dISsKZw`r3HfP~TSXvj^nd%7w0OFLnawvp9c3R80)0Fr3ydH{0g& byOmnY^nN8Uyg>KmOZ&?k&8FR?Pt3yK*o5XT diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta deleted file mode 100644 index 0b52486cfc5f05044b9b56a9fe4cd784dca2c15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache deleted file mode 100644 index 537182b25f7b45440690c47eab0d251232bcc2d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7259 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta deleted file mode 100644 index 8b36f47ca8f554f7005ebbf3285be4ae7326420d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache deleted file mode 100644 index e1808b4e0d35fa0566e4b02f6c7b4b1e562911be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2704 zcmd5;U2hvj6y4bmZ@p?{Mpl}}5Hd|$DTy{|;t*9>g*2v%RVh-lbtE22Rj=)-y|CVm zXUB<)ic;~2KuEmsh~T+M@K*Q-{1bTKH?((W)`7K%tyTzCvRAV+cV_NA=iak-qpRLD z@q80sox_j5EB<+I4&zUXm-5$(pXbfzoq&41YY|h-Hf8edLClpxJMf#kx{8gmt0R5! z4ufTc+>5G)-!-w(#Ca>bS5a}kjPp%AV@m7n^1iCUZ}*CdohA1c(uxi$)o&pf{DhY3 zPsKnj)t{;`Gp|+a7d05Xr&sDXbQr7|)w*rK;Fnyb{&NlnznZ1`GZSfM&kw<`^Qz{4 zg$#@=ML|eWaQ-6~?o$-^96S+TDC31DzGT91zMO!uaF&;6I1d}Agl8ZX<0bb1Aw1K> z2WWHVTj5<6hv(!j<pUPRGlX|3iF;lU(3q3xA>qdni4vS+((#XI2nHS}jT$HK6Q>W4 zJ>FQiEOPlWafV*+5ca`aqtOr?T3`TJEIWN03|B08h(!w^L0hxA8#&GCr%2fnsi}-% zU>ld*w;&_}@dLM2I3yd;3HUbf0=NW!|AX1{hOa9dUjiH6Fzfsn8-d3<{~a0L@NY7l zz9hp^)U7v-s-f-iSL1>J7gr<~O*mvcoIM)HYrLzNUYIcQ^*1N2sCVcw`WmrPbw8Fh zGK3l_=_3!vL-{~DUWi3uG=u^*$dMNeC`>`Agp_z;1XaXra>%0gpyh`h;*pRZlhk~2 zxunntmX3Yit;oWu$->br3!#04psdlHkiu20qe5bc(3YuR*LQgIzz;`6wlnf`&9#O6 z=t6#`NJk<rOF~~v^LEG=ML~mn8GsY6xPgQ#0Jv6-^wM#(_5}d67$*P>dX)Js!ssER zF%7xL{U{U?1Ck>oW->4`u4N%3Yny52W|StiaQYxL8xss_i4r9z6dDaH5h6>owG&2< zK;=d``NtS=!3emKkZ*_y5OSm{$={eJ#jm_k0A6(;OTZr|`I#GeJC6A65Q5<G93-K{ zG|9e)gRqr=ZId`6AkaxM!g`ZJu0h&%81*=1a?%UinF;IE>~!N~ngT!O>v6>R^1V%) zY}@3W`!;DlssQl<-(^V7^)$&>fQNgDiA^@|3&J43fsdB?qq!5(4!D&{M0bpim(1hI zJwTe#Pb9!k0N^ij>GfyeJAaDr|AMK6LZ*Hy1Y;lB)Iy~GsjO#;<6qB!zGUln^cT`< zBf)sdukb&V|1&sb9Il#7EoCQZ8-(~j`%N}*@RUuB3u1(?COyy;J-Vsxo>%c~8PC3r zS61=L1-xCs+ZW_1IA4-K`20XO0In3OQ50Zf6`IAu0UOZ854|9!J9lY32sk!MFt6SD LbkSifVsD@q4wtD{ diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta deleted file mode 100644 index 2395015401100f34736675fe98225d853098d534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache deleted file mode 100644 index 3a2037f8bfbede0d447b1c3e951f8488d545e9de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1879 zcmcJQPiqrF6u@_8v)y)0h-0AGg5=Rsn#9_gL@$B<6Dma%yNOT;NVDxulhw^8WH)U@ zz4r?U6+HCf!LQ**@F)nLMLl^Eq`sL=V$+6F5f3|g^CvI!e)-KT&=s9cl-Z2VW~zyI zy3W{>#9Mtf@k!T@t1h?d3r$N=omSY{@&hGqyUz9sUA;=#jVW`EsEG%pT-qQQe50At zSBk+ewOEYc=W8ujI@B;|j}%J52vK#9?-OE1scIe&jS)jp2vHO^wrSp^s-l>qR3%iw z2Zu3}oKnc(utq3jQ)Y({7Avz3$;LitBJtpcp~!=F%k#&<0-S`V<+Nbm32G43I8>cI z?g4jsoqK^l507e&4?C6zmg_fQn}gl(IJAAotIG8@x1Aj;;I;w&GcT|@;COz(ExP~} z%$~~5K`sr8i!dFAm3adUn4W%rwAQieO_%$kU#V0iR0Ed8p2DTLtQX+C0SJZUZS6oi zu3OD5pYJpj)w8?QKA)m?(5EI?UE4&Qg6Hi8bG<)9ktjY$lbR91S47xG&JgY{#0kl` zY&MZGE3-Ew%Z$PO42PW<3R~3R**)4&v-Skmnq@;p{2>*vnoZZ?HUtd=oM7G%<e(33 zkXsiPyjX%BAJ0zhdMPgr&%uKX<ltqx3-uNT0;=>39Yu4<?CL0Gu}Kz1eKOdpja@~F zi;WPHPevX`;{Lvcg-c7126*?V3W|en5=|l<Ig3;bQ8BFvmKhUwA++5<ZSSe_r-q}9 z4n^5B7Q`N#+&-U`Sd{7llSp!NknJO(`R^n~rDeNL%U4M7Pm<}f(9ynRVSnr_5ivvw zE|iiLO*fS65GDH=Ik}zTV6F@WBPs~~k76?QP{R;sE^RD_iV-p(m{2R!tm~HaEdPUM z)uhbWg&kbfFhgRyBwLK7PC0Wu)M*`c`bfjX!?79i9vj5u;C&}A#`84_0sQeOD-V^5 zr;4!ltL5-`|7|%@SxBtc%5n-P%lSgPna``|)YWpqg2Hc|I2k#tC@${_lD|&w6MVmk zOCrN!<7}e9CdT7;8V#3e8K&jpk6LY>yo)aizFg#f+YOjDiR0?Sr^&TetI@hlegl8` BnTh}a diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta deleted file mode 100644 index a2089a5966a154b5dd61585b9e0a71668b274981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2a#5L@9-R#`vm|lvIQ^z diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache deleted file mode 100644 index 4af2a984fabae78b73642b949e602a8ebffc5152..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7006 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta deleted file mode 100644 index 6ec02d279a3395e477453db0c144ac488b739524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache deleted file mode 100644 index e32b59e08b9e8e8e66bccc8e832b8b974625ca48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6599 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 Ph37G(<Rv^t>Phrp01=-8 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta deleted file mode 100644 index d6129ae46ca64f4056698206dc7d3f0de91184f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd<{vr1)v0Y)f;2TG^sq$cL-=NFV@=I0$1IkMi{#QhNfhQkTV diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache deleted file mode 100644 index c9328b3e01d12cd9f0c43099a54e78e9b65c0fb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10381 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta deleted file mode 100644 index f4e887486561f8be3945fd8b61344d52d6d64401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmZ4IWtGYR1B_4x7nDxVNlnbv&&ez<xplPfLd0zE)c}_f3VHwl diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache deleted file mode 100644 index f8b70c2b5b9f3ebd1291629fef5f1c30e9ae5735..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6395 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 C4H$L+ diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta deleted file mode 100644 index e4e832bc82346f74985f18beddf6b6e9edaf3e83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache deleted file mode 100644 index c54e05a7b73d4c922761a7bd63b2e2e860e6c593..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21839 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 A#{d8T diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta deleted file mode 100644 index 7c72b25579dddf57ca0f1d52e021b5c2d8247d4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache deleted file mode 100644 index 46563080f8b9fb45648765a455f9a47a30df605a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10571 zcmdT~U1%HG6`nh?GPYtxzLA|cKd!HpKgZ+;%Sqda%{q3HZDInAq=ao#w)V)njwdV6 zC^MrZb_)qh3uWok(q+>?AuLT>^so<wLRcs)fkOMzhkYotTUsbBY|Fkh(3f_p`rSJ- z`g6vK9j8ek*SV5r?wot>Ip6utIWt5$BAMt3jc%*b{rg7$xlc{zh6(Mvl6*K!k`MNi z+T{}07Y;ivu?_R`bfID-N=0saUr#%(k|>sp!bGP^<GE}P>7cruEs~DfDZ}Qou3;&} zRFv#aH9}8oG+L$cSjdWsO1pA2UZs6n^UWbwpI0OJSIfIXs>zBnXb7nYdD17@{*&4k zSn+8S-&2!ulFRoH5=s7@T*`kYCu%1Dsfus<Ituyz4or?lujIcR#pG|%T>euriE2~% zP7RY^cINUQbz*X_E0_OS7bZW9W%9RUn7q3&o&Ui`On%i}$p5+<ldJK`d^t`c)F$+8 zk{nS<GJ}zhkmMA`haDvOF-AtiXN*`ENv1HW8*y+Lcj6@ZbBscQB$qH!6xU*mBuR1- z<NaQ&f$`23+=H>XAHQLIyp1IPfl=5&k~YR421xQD#=i&g42J86a6LwPH`c*;uou_t zCAFe8J!_e>x<Xu>c()qK-X>8>Vv0hDqR_6x*$Zj}zjWX)p<N@iD~&G`=M2Xkltvc( zvg)%D%dPsRC?S+iWtsTz3T5~ks~JUZx`w-`D2itZbpuz_vAwaWnAoJv%Ozcj%yNI1 z_gi*(GwaG-V*e0p)TT$P^tguU(F{GBrbor}V1^z{(}P;O`G#BHxM!!Ho?!UxpRwp# zG!UWmQg*k{K$Y%>*SGF3L>#E%;@10H$MtfVn?<<X@}qv;Kk81YgaMll0bRt-hca|1 zO^2Rh=WE=lN@*s020I17xMY-8RbT#)P1e|i+@90LbT;E@e}-A6YcY48Gi;n$bIh?8 zc<}3FMMBWbp;(ONDyG8>lffSxS2tbe8Vd=IUkEu*2vI57ClPZy?S@1d{EfJlqKrG0 zxjEwoA!EPk*cPpEyCjWG(e%2p{k6r|eww{2jjc!O`Ls>XR%uq~`D})sP1CbtI+39h zX*waM$8z*|6*#<pcK2jRy~Z=^pmZ|ZFU~AO`(fa*o6_}W`M4utABMQ6-|ZJZ=~~iL zMKJKavecre!`UNJQ9kyp8Z5*PG7_+~cGr_QQk6K;H|gWZ?7VL4vo0sLBSb402~)Qh zZ&plW)+%yE-Sy}0xIA8`TrwJX*?PD)v$v$oD<Vmbj#lZhr#R6kKf!ebY{W!L(=BH^ zC{*D#PWE@b@xGejO!KQ1y#zcC!I>GUqUAVa(>>KyA?%a;gs=rq7g}P{vPyMOj>54K zQ9k$Z^m8)WcPHMwg;1zDX)Tm>n;&(Ud);E7Sc1#ogT;#6<@SPMa%Rj4;8|qz`ZX>g z$kBm4F2CVIKLTi6gf4+S-ePbBxtL)UbysH<M}7h1nmK+PI9BGi?piim&=;A_-HL6p znb-7^!)F-3#?9bqv9`zgk6}856T*nwr9cIao21|Z_KL>b9Je74yRI)f2LO|?x&(&9 z<|?LOhIont5QW^VY;)XT^P<?mu3hZ(4Sk_p;toE|%*;q~5M!^hIon!*p9?Q{hQE>0 zQwLb8ka}Z3JAS<Rx8amtNbQd?xgohi+d6?+4TmjwVEJ-b?}A<7a=Az>rjW7Nj?+5? z_Q*J>kfIMfKW+h@*R#*bLRSrO(t7PSJ|wMYT2}^TF!T&qBCR0(z~Ap`ztCzDd~qlW zx$JxC{}+67NH`>gDZ=GOI-2DPb-4>Ld57r<*u59rgYXUeh2J$|K1}Dre4Ei4!Z;UT z-@M37-8HW9(jqG?O1Hdb*wP~x^x1jgw>p>tZl5<U&zBZs@H|if!{G^G>M)|A?tJ&S zq|NRl5$;7K&6(^ek4T*Ykt(RZ_@SzvvJ9c>PF4cb7p$ocaK5SqHkEkrwSa&}@h7f% z8k_IB*X0EZUtz8M`x#Tubq#_D7wPOPo-V%zU8<_Lu~1d!MT~TqrU%LbBZaMAh6Msd zbr-<`sOlMTySAnF0{XdiqC=(8?G)*%WrA;Ny%&20mI-8BP_(j0fh4bAe@_kxop9i( z>`vjw8M+gc56PI2MM?r<91y+_27Wsb(7;EY|I3ztO=eGc25<%jkWquZg_=N4WS_HK zgGZH0IBSt#%yJP(VF-Z<TsPeLx?Om>V@{>uAh#W_xQ#?4LRB*M{+8aYlzeHTTcv&5 zX)n^ik^0{VP+duIU>P9^v8u>ja<#&u%cmV<Ng@0^i99pVPkD@6J8SwC0%X3DZs(-e zAZdLCh+iem@~ogZL35m_N1lu&E>tFRx#a->Snl$K<KfL~@k*SMlr~W+VXwYh9Pxtu zYD-p7H>D{VW07umRZ(*g>xRgT_<E=JN4=C>^2!d^xUEDSp>bb|8!c30J#w5ium<dC zS(XM#ou({}Z~o3^N~W4U`dOOIN(ggTAWW6sh28u`YZfTv3~KDG>6B5)`~n=Vj=Js4 z+;ByVN2+36(@TQ)3JPH|317_fKM~fRh}jOOtT$8p*|%TCk{$rAz+{^U>~O06t~y_B zqrXizfkuNqw>&GjOPi4dWn|#%1C&exm*k-~&h5o9J|93&06@130F{D<p65x+#09PZ z(B|{hnaQu$zmNbbz`@UW9Arsy+2SFO{C`3>!=&G;A#)K`uxa9x8l|D2mpT!6D|^oK zlp6wJ)%rdo!9IhwfJnv~T>*C9(?^%{$l6$=fQGPTOERdN7W8Zj_jnZRdy=Y|$R1_Y z?1O0E1`(c0)^%>r>P|~|dQt2(7ijhzH2b#NEbQZK7Fu1&W}!x}G*CC%dTt(Lflg$O zjmYxN#Cr)!3IXZ6s%WSqG(yYmmeBItve*zPm&CcbGB_y9L=Bqw;f~LCh}{KHr)V(K zhHJL7+TrHnU`U;BjYUj^n}Vcxh&n*1zK5h$sK=f8265&-h4Y!c?}8yNGq@o59a77m z#C{*6<Vxdl2~js`DB=4pM|?PYrdbK$dCt14=ZZ`xp&q1@eHpb)-pA=j;&_njczP10 zcbUVlsHkxxP}KI$i=9GI$bTfURT7}KO*E_BTAsd?97=2pZ7Gl?b~f$6e3$q*`T;uX z+v?cA;#)QeoU5QJ^U~m4ldz9F)2G3?;4uNt-Rt>N4<$?Da3vT7xnu+C+K>0yg28G! zj?){zwNa3aKz8EWw;&mQ3h<&h@oKj9N#}n9f0I#3Ng!4?`P+*Vsaxt1K?DV>Xat)6 zo?|et$(ue8Y@lm<0QGv`%NrHXu^~Fy+z@@B273tgPM_PwL_}KN60I}3)ig!DP!&|A zyr!sVhtjxcjgAM*PIgDf{unvZA<{^=gKQR|E7Wj=`z_JzC948XEo;ID8w@!N1c5L1 z-Rcu{38XCzt2@`C1uZM=O+nRUP2@!+0I4h*)}m>C9@$kYBAyl^QjMLox$bhdv7Y(1 zRaOqMiw>Wwl>GJ)SWS=vu(DA`t~IY4CO8V(N+wF>e)JZ7u*+QJ2z~+hMC6T#Ky>f@ zgXw}Y?lsIBT6n25ucaVA5SiCI>auNys=xli!lN9pk$L&AE<7ghf@6~Qw-uTkGk8(K zbIf-){0Dj0Na6}A{f$#-_ek%(7#{&g=s=nd9EM#6?<cIsi$LwY`8AonY=n&jJ&qaJ z{gNuT7OHu#!{K(KUf`AD>!#}y(dN>E!_n)7pA=cW$l%@NxZ@(3ZhA??tJ064O7GQP z$(Xb0BQQTnRVC4RNkV5p%34C_G`&SB@%Curb(r=Jym%c9E&Mf|;R%$fzcSII(t#Wu z+C=wc=$<X|WvmT!bcBv>X@2X$FYb=#xKk;)qAL<jN51;z;Az{o>~^7K$Dc+=a7{u~ N$_8bVnG&ss{0~7TdsYAd diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta deleted file mode 100644 index b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache deleted file mode 100644 index 00887a7dc8161207703959ccd973b9e5454d4c13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7769 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta deleted file mode 100644 index 2ae412bccfd7739434a236925520c9652e93ff84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<<f}##0 V7N1m_nUj)Q<er!*%^>nW832Uh9(Di# diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache deleted file mode 100644 index e2a24f1b35167bc143baa6286b81cdb86116470b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3252 zcmbVOPi)g>6!&K*aTB$Kr>=-1x*7z7S<?y$NNXe%(yfd}Td8pwQnku;;xDbiu`AmF z1r7B!P0=oscG!VUTy~tqapS%llQvD$;L2^MUADtc+50{_ByN*ZkfQh{{=WBq@4esq zbFM61mSMUIr*BUFNB*3g9+v^ClT+h&C!dYW-A#wmmTQNCAPmZtH$*u7SbK-0pk32G z!^h7Z?FmUuP7_r>N>ErQReb}6?uW4kvf_K2J`IBMwe8UMTtU!|iV{?0NLL}78_+I6 z_Az3BDS71Ofz!f@DB-8O$Y7#sLGCNRG*o#FCaM5(^2QL2*Xg$BhaY>yYB_Y-Y*K;j z1Gy7J-g_$%xd?5(5_-)z0`o&bs*tV1gv<{P!M5nuJ<E1Cg&5OtPf<hU>5J1tuv9LH zKnt2hB>1hPJtfklM%MIIf&vvwx+M~+*p`kF{R@e`OI_DjQz)#bRsGX63jd}T^naM} zZAR4}WKj4)ey;y0qhO9L=o@1w{DQ(0CM;!D{c4s-v&-IU*v1Hqi;{MZq=DoF5wZtK z4IpcvpdBX!6vCsFi?j`dNh+?(wITGuXfcBqUKl)h)<7fx9qkmFJ&O|3Gq;zXi7Jtb z&oX~yx((a4jE3z95)ER9A4c{CLIeS_H?^yxgm1?1o4`y7W(qJPqc~N9sREWkSr2{8 z^(+>n*+c^E{*6bo$d>|S=kg!fK^Ps>Qe0oQ#NX^uk|rX+nx>#Xa0^!OJC}gkk7nLz zG;AaqSs?^3ku#Ms5hjkoIAQcUOeEVSq}w#Z`c}lq;)C?>>2g#EvBysn9?xmtaE}oo zLC-M+n3&l84xFyS+syqFDx4_5iMj5}OKOPQuh>FZ3=hJ-DJ%zoQi6W5tNn-xQjyBv z$z98IH>vNnq`+w#b<e#+{m=+_GL6tP%uwQ8fKl?xM1XE;nC79BsIp!?vnQL~enZ$@ z;xRi$bra5md)yx=!EwxKu3NKR({CH0P-Y;#W|{g9x*~|ht<3kCuHSMEHWdVdbAcDs zue;EHJ&0cAgq}kj^D4|2V15`&_vv>-l6#O$F~1ie>th$)`JnBZO}oxAWH#rlwlK?o zW01M~s)jQQCJJyA@8t3!#Ttsno>=@t&Wz=^OsD7SM#9xO?QD<9%-+eU*5oBOE<%>Z zf&Z6nCn`>E8EY=KT#79-JN;mPm3o-kdEaw9pIULCo&BswJwVPccwXNOGyjUUfE-6? z3ki<*a3n}RBdc=0X|np~G`O5VC-ahK^LbPVm>E@j#A08CN96p(y)0KZU_|IDSFnL9 zrhCd#ka&veI0{RU(rCGLwnzj@!}FDJiz@Y&?^8Eawtepwt%pi0z<#7Ga_*i9l*Jpk zA>`uAKF;&Io`3t@Tu!OD?f8^}ns8w;n=iC0w##*IFq<2SW&5bv^V`Z@JKR!C1$jgj zYS|$(WxF|L!-!7Wfr1qu*cQd?;lTuEbjLys=t_+;uNaD@29sQ-$8(jcdB@c2zP%mt zo5A4ep6z-oz~YQF<JGcDeN-fn;uW$+BCcbb5sj#Nji$#I8N-#?DihW1zGNOTI9M`A zyh^i#KG)9T1G^NC$!WgVnaxo!1`;h5e@gwG+WCa~H81GldyUOt7j0vG2}8QPChu6D z!I&Ed;&qrCSwiOWrrA@NuoQ@&i}@R2<Gt8S-=CMSW_;mL6Gg~XB@CR*yp_2uR*s8s zQH6^cIR6;t55XlBE**iT4rqs9y$a?bpf#}Hg!?79e<WHdN3G>R7J8-5`v{~}NEh;} zev8gtF`a-8o5nyoLwBKpp#(&Y&?okE-l1`CDfRLmZF2EI#YfO`LP#G&2-3CNvx~m( H`G?8>b;>hi diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta deleted file mode 100644 index 35823f819643250ce036eb3ade6a8b4cfeac4a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0<IM LSG~Z5x<GpX@`M<b diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache deleted file mode 100644 index 5759b2b763316da81f66679300bffb7f8bb46279..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1132 zcmb`G!D<sx6o${acP7&W!+3~RB7tcoK^YgVQ8(Qf19lNmdpkmL<CxNkO*>{V$)JKF zWa-8y@DT*{E!_Ghg1A!Rxs#b`A~hRb<mSvBlK=bv``=9;TNYI()Uc@WywWf&qE2Pq zyj*!`TGJ<C5X6K2SZs_Aqc}W(Yy+SrZr23eY^ob5>03vAM_KuVZSN!Ua98YlJA#K_ z!u5XY;iYVPFC-7^M#rlgD4qSlkB$-586njxGzm)phyYaFP&+~bD1%p|;uaN~RNT9@ z8;s&`>@Y(2sag>d1@MP|BJ^Y;5*?|v<crq$p){RA`}<&Pt=tXRey`UDas8aQCZ^00 z42RJWwEVx&Fa?vK%+`cxaypU7M6*CMq}SrTc*98JVH~75kN*hg%6vF(5{_lJqbQt3 zqqF1GF3nz8_xdOM2~k_sIHU4}YP^;*tvnpej+*m%SNL3*4x+IiJd3-4VG4A(0JNtz z6QJZo&`8`HVEm0h5WQ7(COCgYbzbvR8el3E0^~ILQGLKKX!pAPjG?u_VCg;pEU~U@ z;Vw8&{w)`pw|&97YB}0+CbrD5nHV;g8a}<20oYn2N65Wy<0I6y>~+IYa8k?v+=I@n znUnOc%<1Js^Pzk#{3!69UlCMxsk}<nEvl|2wIkCdvuQuz#yZ;?IlZZ5UgUjw|Jb>s I@7G!U4Me2lCjbBd diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta deleted file mode 100644 index 401fd74cd1e9eb44559765e4eac26450d3f34537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache deleted file mode 100644 index f005a617477a85e6a547a334a7ebb0b84cbae461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 552 zcmah`!A`<J5bd-ymBt1pBpAG~mV-!)M7((rG|_`G(W*BwX^~B7EL+@Nl%t>G#jF40 z*XXo8c`zJy-^{$(w{J3aIdZTy!5s&8wi++sAo`6t>^45Z`H9n2Uul^bj)+$dWh3*n zVxm0=DqywKL~sQVY?@Z^4mN^o7yyQW)qc=5EyD;ZbOTn8u{yx2GrS`y5x3)%NAsJK z>J?PKc9key5^EmW0EmO&gTR~M2ON5r8>N%KZhzP<*GnlBV|vC};gvmQLPz9!$`VnO z<K&eKmX9dn1J`AD%f%v-TCqu{XDl3xkVRrjfy~2PgmE#YW|en$I_!KE%@-+Gl!akf zOy;ta^1H5|2|gD3EgK7hndFrDdoFv(34fpYL=})z{$nBWzYtl-r3ms<%2BXZ&@hj_ z;2UUl8zy?k=rys`!&Y;6%hfW~Xm8U(t?TFZxs;i#on={yc8_Ycd%5K8izrpR4!`T% BlYjsK diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache_meta deleted file mode 100644 index e09e4b1bdc7ab6767e4a4ab5ad8829ce2691f3eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmYc{FH2#70Tw8O3reTwq$cL-C*|kopo-*V7MF0Ns3}TKPp#lV5h^Yz%FIh&s=wyB IUERhi0Bl7T<NyEw diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index a978a7ff425..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_stdlib" -version = "0.33.1" -gleam = ">= 0.32.0" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 6e1e2261268..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs deleted file mode 100644 index a8309e0cdbd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of Dict size and clean up the API - * @template K,V - */ -export default class Dict { - /** - * @template V - * @param {Record<string,V>} o - * @returns {Dict<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type Dict<string,V> */ - let m = Dict.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {Dict<K,V>} - */ - static fromMap(o) { - /** @type Dict<K,V> */ - let m = Dict.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new Dict(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {Dict<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {Dict<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return Dict.new(); - } - return new Dict(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof Dict) || this.size !== o.size) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index eab2f0b3fec..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam deleted file mode 100644 index 79860e964ef..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam +++ /dev/null @@ -1,157 +0,0 @@ -//// BitArrays are a sequence of binary data of any length. - -import gleam/string - -/// Converts a UTF-8 `String` type into a `BitArray`. -/// -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") -pub fn from_string(x: String) -> BitArray - -/// Returns an integer which is the number of bytes in the bit array. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -pub fn byte_size(x: BitArray) -> Int - -/// Creates a new bit array by joining two bit arrays. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - concat([first, second]) -} - -/// Extracts a sub-section of a bit array. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit array. -/// -/// This function runs in constant time. -/// -@external(erlang, "gleam_stdlib", "bit_array_slice") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) - -/// Tests to see whether a bit array is valid UTF-8. -/// -pub fn is_utf8(bits: BitArray) -> Bool { - do_is_utf8(bits) -} - -@target(erlang) -fn do_is_utf8(bits: BitArray) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:bytes>> -> do_is_utf8(rest) - _ -> False - } -} - -@target(javascript) -fn do_is_utf8(bits: BitArray) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } -} - -/// Converts a bit array to a string. -/// -/// Returns an error if the bit array is invalid UTF-8 data. -/// -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - do_to_string(bits) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "identity") -fn unsafe_to_string(a: BitArray) -> String - -@target(erlang) -fn do_to_string(bits: BitArray) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") -fn do_to_string(a: BitArray) -> Result(String, Nil) - -/// Creates a new bit array by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -@external(erlang, "gleam_stdlib", "bit_array_concat") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") -pub fn concat(bit_arrays: List(BitArray)) -> BitArray - -/// Encodes a BitArray into a base 64 encoded string. -/// -pub fn base64_encode(input: BitArray, padding: Bool) -> String { - let encoded = encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -@external(erlang, "base64", "encode") -@external(javascript, "../gleam_stdlib.mjs", "encode64") -fn encode64(a: BitArray) -> String - -/// Decodes a base 64 encoded string into a `BitArray`. -/// -pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { - let padded = case byte_size(from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - decode64(padded) -} - -@external(erlang, "gleam_stdlib", "base_decode64") -@external(javascript, "../gleam_stdlib.mjs", "decode64") -fn decode64(a: String) -> Result(BitArray, Nil) - -/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { - base64_encode(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. -/// -pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> base64_decode() -} - -@external(erlang, "binary", "encode_hex") -@external(javascript, "../gleam_stdlib.mjs", "base16_encode") -pub fn base16_encode(input: BitArray) -> String - -@external(erlang, "gleam_stdlib", "base16_decode") -@external(javascript, "../gleam_stdlib.mjs", "base16_decode") -pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52ec1b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0930d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 91bd6b76129..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,428 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{type Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} - -/// Runs a callback function if the given bool is `True`, otherwise runs an -/// alternative callback function. -/// -/// Useful when further computation should be delayed regardless of the given -/// bool's value. -/// -/// See [`guard`](#guard) for more info. -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "Kamaka" -/// > let inquiry = fn() { "How may we address you?" } -/// > use <- lazy_guard(when: name == "", return: inquiry) -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -/// ```gleam -/// > import gleam/int -/// > let name = "" -/// > let greeting = fn() { "Hello, " <> name } -/// > use <- lazy_guard(when: name == "", otherwise: greeting) -/// > let number = int.random(1, 99) -/// > let name = "User " <> int.to_string(number) -/// > "Welcome, " <> name -/// "Welcome, User 54" -/// ``` -/// -pub fn lazy_guard( - when requirement: Bool, - return consequence: fn() -> a, - otherwise alternative: fn() -> a, -) -> a { - case requirement { - True -> consequence() - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam deleted file mode 100644 index 20c145d93aa..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam +++ /dev/null @@ -1,197 +0,0 @@ -//// BytesBuilder is a type used for efficiently concatenating bytes together -//// without copying. -//// -//// If we append one bit array to another the bit arrays must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit arrays together. -//// -//// BytesBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit array using the `to_bit_array` function. -//// -//// Byte builders are always byte aligned, so that a number of bits that is not -//// divisible by 8 will be padded with 0s. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -// TODO: pad bit arrays to byte boundaries when adding to a builder. -import gleam/string_builder.{type StringBuilder} -import gleam/list -import gleam/bit_array - -pub opaque type BytesBuilder { - Bytes(BitArray) - Text(StringBuilder) - Many(List(BytesBuilder)) -} - -/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> BytesBuilder { - concat([]) -} - -/// Prepends a bit array to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { - append_builder(from_bit_array(first), second) -} - -/// Appends a bit array to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { - append_builder(first, from_bit_array(second)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to second: BytesBuilder, - prefix first: BytesBuilder, -) -> BytesBuilder { - append_builder(first, second) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "iodata_append") -pub fn append_builder( - to first: BytesBuilder, - suffix second: BytesBuilder, -) -> BytesBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string( - to second: BytesBuilder, - prefix first: String, -) -> BytesBuilder { - append_builder(from_string(first), second) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string( - to first: BytesBuilder, - suffix second: String, -) -> BytesBuilder { - append_builder(first, from_string(second)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { - Many(builders) -} - -/// Joins a list of bit arrays into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { - bits - |> list.map(fn(b) { from_bit_array(b) }) - |> concat() -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string(string: String) -> BytesBuilder { - Text(string_builder.from_string(string)) -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { - Text(builder) -} - -/// Creates a new builder from a bit array. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_bit_array(bits: BitArray) -> BytesBuilder { - Bytes(bits) -} - -/// Turns an builder into a bit array. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -@external(erlang, "erlang", "list_to_bitstring") -pub fn to_bit_array(builder: BytesBuilder) -> BitArray { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_array.concat -} - -fn to_list( - stack: List(List(BytesBuilder)), - acc: List(BitArray), -) -> List(BitArray) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bytes(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_array.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -@external(erlang, "erlang", "iolist_size") -pub fn byte_size(builder: BytesBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam deleted file mode 100644 index 280bf9d1d98..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam +++ /dev/null @@ -1,544 +0,0 @@ -import gleam/option.{type Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a dict, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a dict once. -/// -/// Dicts are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub type Dict(key, value) - -/// Determines the number of key-value pairs in the dict. -/// This function runs in constant time and does not need to iterate the dict. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(dict: Dict(k, v)) -> Int { - do_size(dict) -} - -@external(erlang, "maps", "size") -@external(javascript, "../gleam_stdlib.mjs", "map_size") -fn do_size(a: Dict(k, v)) -> Int - -/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the dict. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { - do_to_list(dict) -} - -@external(erlang, "maps", "to_list") -@external(javascript, "../gleam_stdlib.mjs", "map_to_list") -fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) - -/// Converts a list of 2-element tuples `#(key, value)` to a dict. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the dict. -/// -pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { - do_from_list(list) -} - -@target(erlang) -@external(erlang, "maps", "from_list") -fn do_from_list(a: List(#(key, value))) -> Dict(key, value) - -@target(javascript) -fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Dict(k, v), -) -> Dict(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } -} - -@target(javascript) -fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { - fold_list_of_pair(list, new()) -} - -/// Determines whether or not a value present in the dict for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(dict: Dict(k, v), key: k) -> Bool { - do_has_key(key, dict) -} - -@target(erlang) -@external(erlang, "maps", "is_key") -fn do_has_key(a: key, b: Dict(key, v)) -> Bool - -@target(javascript) -fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { - get(dict, key) != Error(Nil) -} - -/// Creates a fresh dict that contains no values. -/// -pub fn new() -> Dict(key, value) { - do_new() -} - -@external(erlang, "maps", "new") -@external(javascript, "../gleam_stdlib.mjs", "new_map") -fn do_new() -> Dict(key, value) - -/// Fetches a value from a dict for a given key. -/// -/// The dict may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -@external(erlang, "gleam_stdlib", "map_get") -@external(javascript, "../gleam_stdlib.mjs", "map_get") -fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) - -/// Inserts a value into the dict with the given key. -/// -/// If the dict already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { - do_insert(key, value, dict) -} - -@external(erlang, "maps", "put") -@external(javascript, "../gleam_stdlib.mjs", "map_insert") -fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) - -/// Updates all values in a given dict by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { - do_map_values(fun, dict) -} - -@target(erlang) -@external(erlang, "maps", "map") -fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) - -@target(javascript) -fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { - let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } - dict - |> fold(from: new(), with: f) -} - -/// Gets a list of all keys in a given dict. -/// -/// Dicts are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(dict: Dict(keys, v)) -> List(keys) { - do_keys(dict) -} - -@target(erlang) -@external(erlang, "maps", "keys") -fn do_keys(a: Dict(keys, v)) -> List(keys) - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(dict: Dict(k, v)) -> List(k) { - let list_of_pairs = to_list(dict) - do_keys_acc(list_of_pairs, []) -} - -/// Gets a list of all values in a given dict. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(dict: Dict(k, values)) -> List(values) { - do_values(dict) -} - -@target(erlang) -@external(erlang, "maps", "values") -fn do_values(a: Dict(k, values)) -> List(values) - -@target(javascript) -fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } -} - -@target(javascript) -fn do_values(dict: Dict(k, v)) -> List(v) { - let list_of_pairs = to_list(dict) - do_values_acc(list_of_pairs, []) -} - -/// Creates a new dict from a given dict, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter( - in dict: Dict(k, v), - keeping predicate: fn(k, v) -> Bool, -) -> Dict(k, v) { - do_filter(predicate, dict) -} - -@target(erlang) -@external(erlang, "maps", "filter") -fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) - -@target(javascript) -fn do_filter( - f: fn(key, value) -> Bool, - dict: Dict(key, value), -) -> Dict(key, value) { - let insert = fn(dict, k, v) { - case f(k, v) { - True -> insert(dict, k, v) - _ -> dict - } - } - dict - |> fold(from: new(), with: insert) -} - -/// Creates a new dict from a given dict, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { - do_take(desired_keys, dict) -} - -@target(erlang) -@external(erlang, "maps", "with") -fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_taken( - dict: Dict(k, v), - desired_keys: List(k), - acc: Dict(k, v), -) -> Dict(k, v) { - let insert = fn(taken, key) { - case get(dict, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) - } -} - -@target(javascript) -fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { - insert_taken(dict, desired_keys, new()) -} - -/// Creates a new dict from a pair of given dicts by combining their entries. -/// -/// If there are entries with the same keys in both dicts the entry from the -/// second dict takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { - do_merge(dict, new_entries) -} - -@target(erlang) -@external(erlang, "maps", "merge") -fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { - insert(dict, pair.0, pair.1) -} - -@target(javascript) -fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { - case new_entries { - [] -> dict - [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) - } -} - -@target(javascript) -fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { - new_entries - |> to_list - |> fold_inserts(dict) -} - -/// Creates a new dict from a given dict with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { - do_delete(key, dict) -} - -@external(erlang, "maps", "remove") -@external(javascript, "../gleam_stdlib.mjs", "map_remove") -fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) - -/// Creates a new dict from a given dict with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { - case disallowed_keys { - [] -> dict - [x, ..xs] -> drop(delete(dict, x), xs) - } -} - -/// Creates a new dict with one entry updated using a given function. -/// -/// If there was not an entry in the dict for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let dict = from_list([#("a", 0)]) -/// > -/// > update(dict, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(dict, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in dict: Dict(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Dict(k, v) { - dict - |> get(key) - |> option.from_result - |> fun - |> insert(dict, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over dict: Dict(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - dict - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index c71c6f342ad..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1508 +0,0 @@ -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option} -import gleam/result -import gleam/string_builder -@target(erlang) -import gleam/bit_array - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from(a: anything) -> Dynamic - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_unsafe_coerce(a: Dynamic) -> a - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit -/// array if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_array(from("Hello")) == bit_array.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_array(from(123)) -/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - decode_bit_array(data) -} - -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - -@external(erlang, "gleam_stdlib", "decode_bit_array") -@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") -fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -@target(erlang) -fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_array(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_array.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitArray", path: [])]) - } - }) -} - -@target(erlang) -fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "decode_string") -fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -@external(erlang, "gleam_stdlib", "classify_dynamic") -@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") -fn do_classify(a: Dynamic) -> String - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -@external(erlang, "gleam_stdlib", "decode_int") -@external(javascript, "../gleam_stdlib.mjs", "decode_int") -fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -@external(erlang, "gleam_stdlib", "decode_float") -@external(javascript, "../gleam_stdlib.mjs", "decode_float") -fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -@external(erlang, "gleam_stdlib", "decode_bool") -@external(javascript, "../gleam_stdlib.mjs", "decode_bool") -fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -@external(erlang, "gleam_stdlib", "decode_list") -@external(javascript, "../gleam_stdlib.mjs", "decode_list") -fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_result") -@external(javascript, "../gleam_stdlib.mjs", "decode_result") -fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -@external(erlang, "gleam_stdlib", "decode_option") -@external(javascript, "../gleam_stdlib.mjs", "decode_option") -fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -@external(erlang, "gleam_stdlib", "decode_field") -@external(javascript, "../gleam_stdlib.mjs", "decode_field") -fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -type UnknownTuple - -@external(erlang, "gleam_stdlib", "decode_tuple") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") -fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple2") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") -fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple3") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") -fn decode_tuple3( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple4") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") -fn decode_tuple4( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple5") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") -fn decode_tuple5( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple6") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") -fn decode_tuple6( - a: Dynamic, -) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, -) - -@external(erlang, "gleam_stdlib", "tuple_get") -@external(javascript, "../gleam_stdlib.mjs", "tuple_get") -fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) - -@external(erlang, "gleam_stdlib", "size_of_tuple") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn tuple_size(a: UnknownTuple) -> Int - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a dict. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() |> from |> map(string, int) -/// Ok(dict.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn dict( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> dict.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(dict.from_list(pairs)) - } -} - -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - -@external(erlang, "gleam_stdlib", "decode_map") -@external(javascript, "../gleam_stdlib.mjs", "decode_map") -fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.concat([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 5d62419fd0d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,546 +0,0 @@ -//// Functions for working with floats. -//// -//// ## Division by zero -//// -//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE -//// 754 standard for floating point arithmetic and does not have an `Infinity` -//// value. In Erlang division by zero results in a crash, however Gleam does -//// not have partial functions and operators in core so instead division by zero -//// returns zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/order.{type Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_float") -@external(javascript, "../gleam_stdlib.mjs", "parse_float") -fn do_parse(a: String) -> Result(Float, Nil) - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -@external(erlang, "gleam_stdlib", "float_to_string") -@external(javascript, "../gleam_stdlib.mjs", "float_to_string") -fn do_to_string(a: Float) -> String - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -@external(erlang, "math", "ceil") -@external(javascript, "../gleam_stdlib.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -@external(erlang, "math", "floor") -@external(javascript, "../gleam_stdlib.mjs", "floor") -fn do_floor(a: Float) -> Float - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -@target(erlang) -@external(erlang, "erlang", "round") -fn do_round(a: Float) -> Int - -@target(javascript) -fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "round") -fn js_round(a: Float) -> Int - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../gleam_stdlib.mjs", "truncate") -fn do_truncate(a: Float) -> Int - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../gleam_stdlib.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Generates a random float between the given minimum and maximum values. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(min: Float, max: Float) -> Float { - do_random_uniform() *. { max -. min } +. min -} - -/// Returns a random float uniformly distributed in the value range -/// 0.0 =< X < 1.0 and updates the state in the process dictionary. -/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> -/// -@external(erlang, "rand", "uniform") -@external(javascript, "../gleam_stdlib.mjs", "random_uniform") -fn do_random_uniform() -> Float - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index d93c16afaf6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,874 +0,0 @@ -//// Functions for working with integers. -//// -//// ## Division by zero -//// -//// In Erlang division by zero results in a crash, however Gleam does not have -//// partial functions and operators in core so instead division by zero returns -//// zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/float -import gleam/order.{type Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_int") -@external(javascript, "../gleam_stdlib.mjs", "parse_int") -fn do_parse(a: String) -> Result(Int, Nil) - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -@external(erlang, "gleam_stdlib", "int_from_base_string") -@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") -fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "to_string") -fn do_to_string(a: Int) -> String - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") -fn do_to_base_string(a: Int, b: Int) -> String - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -@external(erlang, "erlang", "float") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_float(a: Int) -> Float - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Generates a random int between the given minimum and maximum values. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(min: Int, max: Int) -> Int { - float.random(to_float(min), to_float(max)) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} - -/// Calculates the bitwise AND of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "band") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") -pub fn bitwise_and(x: Int, y: Int) -> Int - -/// Calculates the bitwise NOT of its argument. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bnot") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") -pub fn bitwise_not(x: Int) -> Int - -/// Calculates the bitwise OR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") -pub fn bitwise_or(x: Int, y: Int) -> Int - -/// Calculates the bitwise XOR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bxor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") -pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic left bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsl") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") -pub fn bitwise_shift_left(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic right bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsr") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") -pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index 0c0a3eeffe0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,117 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -@external(erlang, "gleam_stdlib", "print") -@external(javascript, "../gleam_stdlib.mjs", "print") -fn do_print(string string: String) -> Nil - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -@external(erlang, "gleam_stdlib", "print_error") -@external(javascript, "../gleam_stdlib.mjs", "print_error") -fn do_print_error(string string: String) -> Nil - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -@external(erlang, "gleam_stdlib", "println") -@external(javascript, "../gleam_stdlib.mjs", "console_log") -fn do_println(string string: String) -> Nil - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "console_error") -fn do_println_error(string string: String) -> Nil - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "print_debug") -fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index c57e7fd9473..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1530 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option, None, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_map2( - continuation1: fn() -> Action(a), - continuation2: fn() -> Action(b), - with fun: fn(a, b) -> c, -) -> fn() -> Action(c) { - fn() { - case continuation1() { - Stop -> Stop - Continue(a, next_a) -> - case continuation2() { - Stop -> Stop - Continue(b, next_b) -> - Continue(fun(a, b), do_map2(next_a, next_b, fun)) - } - } - } -} - -/// Combines two interators into a single one using the given function. -/// -/// If an iterator is longer than the other the extra elements are dropped. -/// -/// This function does not evaluate the elements of the two iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// let first = from_list([1, 2, 3]) -/// let second = from_list([4, 5, 6]) -/// map2(first, second, fn(x, y) { x + y }) |> to_list -/// // -> [5, 7, 9] -/// ``` -/// -/// ```gleam -/// let first = from_list([1, 2]) -/// let second = from_list(["a", "b", "c"]) -/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list -/// // -> [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2( - iterator1: Iterator(a), - iterator2: Iterator(b), - with fun: fn(a, b) -> c, -) -> Iterator(c) { - do_map2(iterator1.continuation, iterator2.continuation, fun) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Joins a list of iterators into a single iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [[1, 2], [3, 4]] -/// > |> map(from_list) -/// > |> concat -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { - flatten(from_list(iterators)) -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - keeping predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - groups - |> dict.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Dict(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Dict(key, List(element)) { - iterator - |> fold(dict.new(), group_updater(key)) - |> dict.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} - -/// Add a new element to the start of an iterator. -/// -/// This function is for use with `use` expressions, to replicate the behaviour -/// of the `yield` keyword found in other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > use <- iterator.yield(1) -/// > use <- iterator.yield(2) -/// > use <- iterator.yield(3) -/// > iterator.empty() -/// iterator.from_list([1, 2, 3]) -/// ``` -/// -pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { - Iterator(fn() { Continue(element, next().continuation) }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index a5cffa9b951..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2154 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{type Order} -import gleam/pair -import gleam/dict.{type Dict} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -@target(erlang) -@external(erlang, "erlang", "length") -fn do_length(a: List(a)) -> Int - -@target(javascript) -fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) -} - -@target(javascript) -fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -@target(erlang) -@external(erlang, "lists", "reverse") -fn do_reverse(a: List(a)) -> List(a) - -@target(javascript) -fn do_reverse(list) { - do_reverse_acc(list, []) -} - -@target(javascript) -fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - case dict.get(groups, f(elem)) { - Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> dict.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> dict.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) -/// |> dict.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { - fold(list, dict.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Combines two lists into a single list using the given function. -/// -/// If a list is longer than the other the extra elements are dropped. -/// -/// ## Examples -/// -/// ```gleam -/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) -/// [5, 7, 9] -/// ``` -/// -/// ```gleam -/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) -/// [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { - do_map2(list1, list2, fun, []) -} - -fn do_map2( - list1: List(a), - list2: List(b), - fun: fn(a, b) -> c, - acc: List(c), -) -> List(c) { - case list1, list2 { - [], _ | _, [] -> reverse(acc) - [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) - } -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -@target(erlang) -@external(erlang, "lists", "append") -fn do_append(a: List(a), b: List(a)) -> List(a) - -@target(javascript) -fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) -} - -@target(javascript) -fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Joins a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn concat(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// This is the same as `concat`: it joins a list of lists into a single -/// list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// Maps the list with the given function into a list of lists, and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> concat -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> [stop, ..acc] - order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) - order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, finds all tuples that have a given -/// key as the first element and returns the second element. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") -/// [0, 2] -/// ``` -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1)], "c") -/// [] -/// ``` -/// -pub fn key_filter( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> List(v) { - filter_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> concat - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> concat -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> concat -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> concat - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [elem_pair, ..enumerable] -> - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calculate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 1f8b228eb90..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,127 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(map) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@target(javascript) -fn do_filter(f: fn(key, value) -> Bool, map) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 12ce01136ca..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,133 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > negate(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -pub fn negate(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} - -/// Inverts an ordering function, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > list.sort([1, 5, 4], by: reverse(int.compare)) -/// [5, 4, 1] -/// ``` -/// -pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { - fn(a, b) { orderer(b, a) } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index 9ffda789f6a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,214 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{type Option} - -pub type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -@external(erlang, "gleam_stdlib", "compile_regex") -@external(javascript, "../gleam_stdlib.mjs", "compile_regex") -fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -@external(erlang, "gleam_stdlib", "regex_check") -@external(javascript, "../gleam_stdlib.mjs", "regex_check") -fn do_check(a: Regex, b: String) -> Bool - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "regex_split") -fn do_split(a: Regex, b: String) -> List(String) - -@target(javascript) -fn do_split(regex, string) -> List(String) { - js_split(string, regex) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn js_split(a: String, b: Regex) -> List(String) - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -@external(erlang, "gleam_stdlib", "regex_scan") -@external(javascript, "../gleam_stdlib.mjs", "regex_scan") -fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index fb6dddb3110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,482 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// "Updates" an `Ok` result by passing its value to a function that yields a result, -/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) -/// -/// If the input is an `Error` rather than an `Ok`, the function is not called and -/// the original `Error` is returned. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), Error("a"), Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index df8d500e804..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/dict.{type Dict} -import gleam/result - -// A list is used as the map value as an empty list has the smallest -// representation in Erlang's binary format -@target(erlang) -type Token = - List(Nil) - -@target(erlang) -const token = [] - -@target(javascript) -type Token = - Nil - -@target(javascript) -const token = Nil - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Dict(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(dict.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - dict.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: dict.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> dict.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: dict.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - dict.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: dict.new(), - with: fn(m, k) { dict.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - keeping predicate: fn(member) -> Bool, -) -> Set(member) { - Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(dict.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case dict.size(first.map) > dict.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index 7254fd9fd1c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,913 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{type Iterator} -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/order -import gleam/string_builder.{type StringBuilder} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -@external(erlang, "string", "length") -@external(javascript, "../gleam_stdlib.mjs", "string_length") -fn do_length(a: String) -> Int - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -@target(erlang) -fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string -} - -@target(javascript) -fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: String) -> String - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: String) -> String - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -@external(erlang, "gleam_stdlib", "less_than") -@external(javascript, "../gleam_stdlib.mjs", "less_than") -fn less_than(a: String, b: String) -> Bool - -/// Takes a substring given a start grapheme index and a length. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -@target(erlang) -@external(erlang, "string", "slice") -fn do_slice(a: String, b: Int, c: Int) -> String - -@target(javascript) -fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -@external(erlang, "gleam_stdlib", "crop_string") -@external(javascript, "../gleam_stdlib.mjs", "crop_string") -pub fn crop(from string: String, before substring: String) -> String - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -@external(erlang, "gleam_stdlib", "contains_string") -@external(javascript, "../gleam_stdlib.mjs", "contains_string") -pub fn contains(does haystack: String, contain needle: String) -> Bool - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -@external(erlang, "gleam_stdlib", "string_starts_with") -@external(javascript, "../gleam_stdlib.mjs", "starts_with") -fn do_starts_with(a: String, b: String) -> Bool - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -@external(erlang, "gleam_stdlib", "string_ends_with") -@external(javascript, "../gleam_stdlib.mjs", "ends_with") -fn do_ends_with(a: String, b: String) -> Bool - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: String, b: String) -> List(String) - -@target(erlang) -fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split_once") -fn do_split_once( - x x: String, - substring substring: String, -) -> Result(#(String, String), Nil) - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - do_join(strings, separator) -} - -@target(erlang) -fn do_join(strings: List(String), separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "join") -fn do_join(strings strings: List(String), string string: String) -> String - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -@target(erlang) -fn do_trim(string: String) -> String { - erl_trim(string, Both) -} - -@target(erlang) -type Direction { - Leading - Trailing - Both -} - -@target(erlang) -@external(erlang, "string", "trim") -fn erl_trim(a: String, b: Direction) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim") -fn do_trim(string string: String) -> String - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -@target(erlang) -fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_left") -fn do_trim_left(string string: String) -> String - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -@target(erlang) -fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_right") -fn do_trim_right(string string: String) -> String - -/// Splits a non-empty `String` into its first element (head) and rest (tail). -/// This lets you pattern match on `String`s exactly as you would with lists. -/// -/// Note on JavaScript using the function to iterate over a string will likely -/// be slower than using `to_graphemes` due to string slicing being more -/// expensive on JavaScript than Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -@external(erlang, "gleam_stdlib", "string_pop_grapheme") -@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") -fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "codepoint") -fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -@target(erlang) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(<<string:utf8>>, []) - |> list.reverse -} - -@target(erlang) -fn do_to_utf_codepoints_impl( - bit_array: BitArray, - acc: List(UtfCodepoint), -) -> List(UtfCodepoint) { - case bit_array { - <<first:utf8_codepoint, rest:bytes>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - _ -> acc - } -} - -@target(javascript) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") -fn string_to_codepoint_integer_list(a: String) -> List(Int) - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") -/// > utf_codepoint_to_int(utf_codepoint) -/// 128156 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") -fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -@external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam_stdlib.mjs", "inspect") -fn do_inspect(term term: anything) -> StringBuilder - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -/// ## Examples -/// -/// ```gleam -/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") -/// 58 -/// ``` -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "byte_size") -pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 5792ca8699d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,298 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -@external(erlang, "gleam_stdlib", "iodata_append") -@external(javascript, "../gleam_stdlib.mjs", "add") -fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_from_strings(a: List(String)) -> StringBuilder - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_concat(a: List(StringBuilder)) -> StringBuilder - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from_string(a: String) -> StringBuilder - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -@external(erlang, "unicode", "characters_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_string(a: StringBuilder) -> String - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -@external(erlang, "erlang", "iolist_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn do_byte_size(a: StringBuilder) -> Int - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -@target(erlang) -@external(erlang, "string", "reverse") -fn do_reverse(a: StringBuilder) -> StringBuilder - -@target(javascript) -fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -fn do_to_graphemes(string string: String) -> List(String) - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -@target(erlang) -type Direction { - All -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) - -@target(erlang) -fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn do_split( - builder builder: StringBuilder, - pattern pattern: String, -) -> List(StringBuilder) - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -@target(erlang) -fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, -) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) -} - -@target(erlang) -@external(erlang, "string", "replace") -fn erl_replace( - a: StringBuilder, - b: String, - c: String, - d: Direction, -) -> StringBuilder - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_replace") -fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -@external(erlang, "string", "equal") -@external(javascript, "../gleam_stdlib.mjs", "equal") -fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -@target(erlang) -@external(erlang, "string", "is_empty") -fn do_is_empty(a: StringBuilder) -> Bool - -@target(javascript) -fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 11f6ea68cd2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,462 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/string -import gleam/string_builder.{type StringBuilder} -@target(javascript) -import gleam/pair -@target(javascript) -import gleam/regex -@target(javascript) -import gleam/result - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "uri_parse") -fn do_parse(a: String) -> Result(Uri, Nil) - -@target(javascript) -fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) -} - -@target(javascript) -fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) -} - -@target(javascript) -fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } -} - -@target(javascript) -fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } -} - -// Split an authority into its userinfo, host and port parts. -@target(javascript) -fn split_authority( - authority: Option(String), -) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } -} - -@target(javascript) -fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) -} - -@target(javascript) -fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -@external(erlang, "gleam_stdlib", "parse_query") -@external(javascript, "../gleam_stdlib.mjs", "parse_query") -fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -@external(erlang, "gleam_stdlib", "percent_encode") -@external(javascript, "../gleam_stdlib.mjs", "percent_encode") -fn do_percent_encode(a: String) -> String - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -@external(erlang, "gleam_stdlib", "percent_decode") -@external(javascript, "../gleam_stdlib.mjs", "percent_decode") -fn do_percent_decode(a: String) -> Result(String, Nil) - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - _, _, _ -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - _ -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65bc3f63e4d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - gleam@bit_array:base64_encode(Input, Padding). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - gleam@bit_array:base64_decode(Encoded). - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - gleam@bit_array:base64_url_encode(Input, Padding). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl deleted file mode 100644 index ba18dfaabdd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(gleam@bit_array). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_arrays) -> - gleam_stdlib:bit_array_concat(Bit_arrays). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam_stdlib:bit_array_concat([First, Second]). - --spec base64_encode(bitstring(), boolean()) -> binary(). -base64_encode(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_decode(Encoded) -> - Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec base64_url_encode(bitstring(), boolean()) -> binary(). -base64_url_encode(Input, Padding) -> - _pipe = base64_encode(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_url_decode(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - base64_decode(_pipe@2). - --spec base16_encode(bitstring()) -> binary(). -base16_encode(Input) -> - binary:encode_hex(Input). - --spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base16_decode(Input) -> - gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 284c6d46cc3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,66 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). - --spec new() -> gleam@bytes_builder:bytes_builder(). -new() -> - gleam@bytes_builder:new(). - --spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -prepend(To, Prefix) -> - gleam@bytes_builder:prepend(To, Prefix). - --spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -append(To, Suffix) -> - gleam@bytes_builder:append(To, Suffix). - --spec prepend_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -prepend_builder(To, Prefix) -> - gleam@bytes_builder:prepend_builder(To, Prefix). - --spec append_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -prepend_string(To, Prefix) -> - gleam@bytes_builder:prepend_string(To, Prefix). - --spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -append_string(To, Suffix) -> - gleam@bytes_builder:append_string(To, Suffix). - --spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 7dabaa3bbc1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam@bit_array:append(First, Second). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - gleam@bit_array:is_utf8(Bits). - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - gleam@bit_array:to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 5f95f4d8314..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,162 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. - --spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. -lazy_guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence(); - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl deleted file mode 100644 index 2f6dd93a9f3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl +++ /dev/null @@ -1,87 +0,0 @@ --module(gleam@bytes_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). --export_type([bytes_builder/0]). - --opaque bytes_builder() :: {bytes, bitstring()} | - {text, gleam@string_builder:string_builder()} | - {many, list(bytes_builder())}. - --spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -prepend_builder(Second, First) -> - gleam_stdlib:iodata_append(First, Second). - --spec concat(list(bytes_builder())) -> bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec new() -> bytes_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_string(binary()) -> bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). -prepend_string(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append_string(bytes_builder(), binary()) -> bytes_builder(). -append_string(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_array(bitstring()) -> bytes_builder(). -from_bit_array(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). -prepend(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append(bytes_builder(), bitstring()) -> bytes_builder(). -append(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). -concat_bit_arrays(Bits) -> - gleam_stdlib:identity(Bits). - --spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). -to_list(Stack, Acc) -> - case Stack of - [] -> - Acc; - - [[] | Remaining_stack] -> - to_list(Remaining_stack, Acc); - - [[{bytes, Bits} | Rest] | Remaining_stack@1] -> - to_list([Rest | Remaining_stack@1], [Bits | Acc]); - - [[{text, Builder} | Rest@1] | Remaining_stack@2] -> - Bits@1 = gleam_stdlib:identity( - gleam@string_builder:to_string(Builder) - ), - to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); - - [[{many, Builders} | Rest@2] | Remaining_stack@3] -> - to_list([Builders, Rest@2 | Remaining_stack@3], Acc) - end. - --spec to_bit_array(bytes_builder()) -> bitstring(). -to_bit_array(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl deleted file mode 100644 index 99c231e18cc..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@dict). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). --export_type([dict/2]). - --type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. - --spec size(dict(any(), any())) -> integer(). -size(Dict) -> - maps:size(Dict). - --spec to_list(dict(NZ, OA)) -> list({NZ, OA}). -to_list(Dict) -> - maps:to_list(Dict). - --spec from_list(list({OJ, OK})) -> dict(OJ, OK). -from_list(List) -> - maps:from_list(List). - --spec has_key(dict(OT, any()), OT) -> boolean(). -has_key(Dict, Key) -> - maps:is_key(Key, Dict). - --spec new() -> dict(any(), any()). -new() -> - maps:new(). - --spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). -insert(Dict, Key, Value) -> - maps:put(Key, Value, Dict). - --spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). -map_values(Dict, Fun) -> - maps:map(Fun, Dict). - --spec keys(dict(QV, any())) -> list(QV). -keys(Dict) -> - maps:keys(Dict). - --spec values(dict(any(), RG)) -> list(RG). -values(Dict) -> - maps:values(Dict). - --spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). -filter(Dict, Predicate) -> - maps:filter(Predicate, Dict). - --spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). -take(Dict, Desired_keys) -> - maps:with(Desired_keys, Dict). - --spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). -merge(Dict, New_entries) -> - maps:merge(Dict, New_entries). - --spec delete(dict(TF, TG), TF) -> dict(TF, TG). -delete(Dict, Key) -> - maps:remove(Key, Dict). - --spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). -drop(Dict, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Dict; - - [X | Xs] -> - drop(delete(Dict, X), Xs) - end. - --spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). -update(Dict, Key, Fun) -> - _pipe = Dict, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Dict, Key, _pipe@3). - --spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. -fold(Dict, Initial, Fun) -> - _pipe = Dict, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 2c6016f4222..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,808 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). - --type dynamic_() :: any(). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type unknown_tuple() :: any(). - --spec from(any()) -> dynamic_(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic_()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_array(Data) -> - gleam_stdlib:decode_bit_array(Data). - --spec bit_string(dynamic_()) -> {ok, bitstring()} | - {error, list(decode_error())}. -bit_string(Data) -> - bit_array(Data). - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec classify(dynamic_()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - gleam@option:option(DGM)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, - DKT} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((DKX) -> DKY), - fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec result( - fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - list(DGH)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec map_errors( - {ok, DEV} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, DEV} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec decode_string(dynamic_()) -> {ok, binary()} | - {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_array(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_array:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitArray"/utf8>>, - []}]} - end end - ). - --spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec field( - any(), - fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec dict( - fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | - {error, list(decode_error())}). -dict(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@dict:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end - ) - end - ) - end. - --spec map( - fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - dict(Key_type, Value_type). - --spec decode2( - fun((DLB, DLC) -> DLD), - fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((DLH, DLI, DLJ) -> DLK), - fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((DLP, DLQ, DLR, DLS) -> DLT), - fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((DLZ, DMA, DMB, DMC, DMD) -> DME), - fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), - fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), - fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), - fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), - fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index 33b3d4a3e3f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,181 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= +0.0 of - true -> - X; - - _ -> - +0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > +0.0, - case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent - < +0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, +0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. - --spec random(float(), float()) -> float(). -random(Min, Max) -> - (rand:uniform() * (Max - Min)) + Min. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - +0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - +0.0 -> +0.0; - -0.0 -> -0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index c58c0fe151b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(AS) -> AS. -identity(X) -> - X. - --spec constant(AT) -> fun((any()) -> AT). -constant(Value) -> - fun(_) -> Value end. - --spec tap(AV, fun((AV) -> any())) -> AV. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((AX) -> AY), AX) -> AY. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 2a5dd2c8a1d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,332 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. - --spec random(integer(), integer()) -> integer(). -random(Min, Max) -> - _pipe = gleam@float:random(to_float(Min), to_float(Max)), - _pipe@1 = gleam@float:floor(_pipe), - gleam@float:round(_pipe@1). - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec bitwise_and(integer(), integer()) -> integer(). -bitwise_and(X, Y) -> - erlang:'band'(X, Y). - --spec bitwise_not(integer()) -> integer(). -bitwise_not(X) -> - erlang:'bnot'(X). - --spec bitwise_or(integer(), integer()) -> integer(). -bitwise_or(X, Y) -> - erlang:'bor'(X, Y). - --spec bitwise_exclusive_or(integer(), integer()) -> integer(). -bitwise_exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec bitwise_shift_left(integer(), integer()) -> integer(). -bitwise_shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec bitwise_shift_right(integer(), integer()) -> integer(). -bitwise_shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 82865bbafa6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ENH) -> ENH. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index a667ae1ac4b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,744 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. - --opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. - --type step(BSE, BSF) :: {next, BSE, BSF} | done. - --type chunk(BSG, BSH) :: {another_by, - list(BSG), - BSH, - BSG, - fun(() -> action(BSG))} | - {last_by, list(BSG)}. - --type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | - {last, list(BSI)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BSV)) -> iterator(BSV). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BSX) -> iterator(BSX). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BSZ)) -> iterator(BSZ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec do_transform( - fun(() -> action(BTC)), - BTE, - fun((BTE, BTC) -> step(BTF, BTE)) -) -> fun(() -> action(BTF)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BTY)) -> list(BTY). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BUJ), integer()) -> iterator(BUJ). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BUP), integer()) -> iterator(BUP). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec do_map2( - fun(() -> action(BVA)), - fun(() -> action(BVC)), - fun((BVA, BVC) -> BVE) -) -> fun(() -> action(BVE)). -do_map2(Continuation1, Continuation2, Fun) -> - fun() -> case Continuation1() of - stop -> - stop; - - {continue, A, Next_a} -> - case Continuation2() of - stop -> - stop; - - {continue, B, Next_b} -> - {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} - end - end end. - --spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). -map2(Iterator1, Iterator2, Fun) -> - _pipe = do_map2( - erlang:element(2, Iterator1), - erlang:element(2, Iterator2), - Fun - ), - {iterator, _pipe}. - --spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BVY))) -> iterator(BVY). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec concat(list(iterator(BWC))) -> iterator(BWC). -concat(Iterators) -> - flatten(from_list(Iterators)). - --spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec cycle(iterator(BWR)) -> iterator(BWR). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), - BXD})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BXG)) -> iterator({integer(), BXG}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, - BYH})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BZU), BZU) -> iterator(BZU). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), - gleam@dict:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> CBH)) -> iterator(CBH). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec single(CBJ) -> iterator(CBJ). -single(Elem) -> - once(fun() -> Elem end). - --spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(CBT)), - fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), - CBV -) -> CBV. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(CBX), - CBZ, - fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) -) -> CBZ. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(CCB)), - fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), - CCD -) -> {ok, CCD} | {error, CCE}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, - CCL} | - {error, CCM}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). - --spec each(iterator(CDD), fun((CDD) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). -yield(Element, Next) -> - {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index cb6c9e44af2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1136 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(XF)) -> list(XF). -reverse(Xs) -> - lists:reverse(Xs). - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec contains(list(XN), XN) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec first(list(XP)) -> {ok, XP} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@dict:insert(Groups, F(Elem), [Elem]) - end end. - --spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). -map(List, Fun) -> - do_map(List, Fun, []). - --spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). -do_map2(List1, List2, Fun, Acc) -> - case {List1, List2} of - {[], _} -> - reverse(Acc); - - {_, []} -> - reverse(Acc); - - {[A | As_], [B | Bs]} -> - do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) - end. - --spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). -map2(List1, List2, Fun) -> - do_map2(List1, List2, Fun, []). - --spec do_index_map( - list(ABJ), - fun((integer(), ABJ) -> ABL), - integer(), - list(ABL) -) -> list(ABL). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, - list(ABU)} | - {error, ABV}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, - list(ACE)} | - {error, ACF}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(ACL), integer()) -> list(ACL). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(ACS), integer()) -> list(ACS). -take(List, N) -> - do_take(List, N, []). - --spec new() -> list(any()). -new() -> - []. - --spec append(list(ACX), list(ACX)) -> list(ACX). -append(First, Second) -> - lists:append(First, Second). - --spec prepend(list(ADF), ADF) -> list(ADF). -prepend(List, Item) -> - [Item | List]. - --spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). -do_concat(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_concat(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec concat(list(list(ADR))) -> list(ADR). -concat(Lists) -> - do_concat(Lists, []). - --spec flatten(list(list(ADV))) -> list(ADV). -flatten(Lists) -> - do_concat(Lists, []). - --spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - concat(_pipe). - --spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). -group(List, Key) -> - fold(List, gleam@dict:new(), update_group(Key)). - --spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, - list(ABH)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold( - list(AEK), - AEM, - fun((AEM, AEK, integer()) -> AEM), - integer() -) -> AEM. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, - AES} | - {error, AET}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(AGX), AGX) -> list(AGX). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec unique(list(AHE)) -> list(AHE). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(AHH), - list(AHH), - list(AHH), - fun((AHH, AHH) -> gleam@order:order()) -) -> list(AHH). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_down( - integer(), - integer(), - list(AHM), - list(AHM), - list(AHM), - fun((AHM, AHM) -> gleam@order:order()) -) -> list(AHM). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_sort( - list(AHR), - integer(), - fun((AHR, AHR) -> gleam@order:order()), - boolean() -) -> list(AHR). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - [Stop | Acc]; - - gt -> - tail_recursive_range(Start, Stop + 1, [Stop | Acc]); - - lt -> - tail_recursive_range(Start, Stop - 1, [Stop | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(AID, integer()) -> list(AID). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), - list(AIO)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). -key_filter(Keyword_list, Desired_key) -> - filter_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, - {AZQ, list(AZQ)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, - {BAR, list(BAE)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, - {AJV, list(AJT)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AKM), fun((AKM) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | - {error, AKS}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), - list(BBY)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(ALG)) -> list(list(ALG)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - concat(_pipe@5) - end. - --spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(ALQ), integer()) -> list(list(ALQ)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec window_by_2(list(ALU)) -> list({ALU, ALU}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AMU), - integer(), - integer(), - list(AMU), - list(list(AMU)) -) -> list(list(AMU)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec last(list(ANS)) -> {ok, ANS} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec combinations(list(ANW), integer()) -> list(list(ANW)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AOE)) -> list({AOE, AOE}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - concat(_pipe). - --spec transpose(list(list(AOL))) -> list(list(AOL)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - concat(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AOH))) -> list(AOH). -interleave(List) -> - _pipe = transpose(List), - concat(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - [Elem_pair | Enumerable] -> - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec shuffle(list(AOX)) -> list(AOX). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index 9f45b107384..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). - --spec size(gleam@dict:dict(any(), any())) -> integer(). -size(Map) -> - gleam@dict:size(Map). - --spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). -to_list(Map) -> - gleam@dict:to_list(Map). - --spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). -from_list(List) -> - gleam@dict:from_list(List). - --spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). -has_key(Map, Key) -> - gleam@dict:has_key(Map, Key). - --spec new() -> gleam@dict:dict(any(), any()). -new() -> - gleam@dict:new(). - --spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. -get(From, Get) -> - gleam@dict:get(From, Get). - --spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). -insert(Map, Key, Value) -> - gleam@dict:insert(Map, Key, Value). - --spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). -map_values(Map, Fun) -> - gleam@dict:map_values(Map, Fun). - --spec keys(gleam@dict:dict(FED, any())) -> list(FED). -keys(Map) -> - gleam@dict:keys(Map). - --spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). -values(Map) -> - gleam@dict:values(Map). - --spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). -filter(Map, Predicate) -> - gleam@dict:filter(Map, Predicate). - --spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). -take(Map, Desired_keys) -> - gleam@dict:take(Map, Desired_keys). - --spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). -merge(Map, New_entries) -> - gleam@dict:merge(Map, New_entries). - --spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). -delete(Map, Key) -> - gleam@dict:delete(Map, Key). - --spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). -drop(Map, Disallowed_keys) -> - gleam@dict:drop(Map, Disallowed_keys). - --spec update( - gleam@dict:dict(FFB, FFC), - FFB, - fun((gleam@option:option(FFC)) -> FFC) -) -> gleam@dict:dict(FFB, FFC). -update(Map, Key, Fun) -> - gleam@dict:update(Map, Key, Fun). - --spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. -fold(Map, Initial, Fun) -> - gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 812aa1fe854..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). --export_type([option/1]). - --type option(IY) :: {some, IY} | none. - --spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(JF))) -> option(list(JF)). -all(List) -> - do_all(List, []). - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, JU} | {error, any()}) -> option(JU). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(JZ), JZ) -> JZ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(KD), fun((KD) -> KF)) -> option(KF). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(KH))) -> option(KH). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(KQ), option(KQ)) -> option(KQ). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_values(list(option(KY)), list(KY)) -> list(KY). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(LD))) -> list(LD). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index a9eed8f39c1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec negate(order()) -> order(). -negate(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. - --spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). -reverse(Orderer) -> - fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2452a9817e1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({IJ, any()}) -> IJ. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), IM}) -> IM. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({IN, IO}) -> {IO, IN}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(IV, IW) -> {IV, IW}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index faec6923a14..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(EYN)) -> queue(EYN). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(EYQ)) -> list(EYQ). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EYX), EYX) -> queue(EYX). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EZA), EZA) -> queue(EZA). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec reverse(queue(EZN)) -> queue(EZN). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec check_equal( - list(EZQ), - list(EZQ), - list(EZQ), - list(EZQ), - fun((EZQ, EZQ) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EZY), queue(EZY)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index 2d1c5fc870e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([regex/0, match/0, compile_error/0, options/0]). - --type regex() :: any(). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index c80a7048303..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | - {error, BIK}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | - {error, BIU}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | - {error, BIY}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, - BJJ} | - {error, BJG}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, - BJS} | - {error, BJP}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | - {error, BKT}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, - BLA} | - {error, BLB}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), - list(BLY)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. -partition(Results) -> - do_partition(Results, [], []). - --spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BMT} | {error, any()})) -> list(BMT). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BMZ} | {error, BNA}, - fun((BNA) -> {ok, BMZ} | {error, BND}) -) -> {ok, BMZ} | {error, BND}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index 3374ebc293f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@dict:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@dict:size(erlang:element(2, Set)). - --spec insert(set(EOQ), EOQ) -> set(EOQ). -insert(Set, Member) -> - {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOT), EOT) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@dict:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EOV), EOV) -> set(EOV). -delete(Set, Member) -> - {set, gleam@dict:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOY)) -> list(EOY). -to_list(Set) -> - gleam@dict:keys(erlang:element(2, Set)). - --spec from_list(list(EPB)) -> set(EPB). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@dict:new(), - fun(M, K) -> gleam@dict:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. -fold(Set, Initial, Reducer) -> - gleam@dict:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). -filter(Set, Predicate) -> - {set, - gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. - --spec drop(set(EPK), list(EPK)) -> set(EPK). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPO), list(EPO)) -> set(EPO). -take(Set, Desired) -> - {set, gleam@dict:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. -order(First, Second) -> - case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPX), set(EPX)) -> set(EPX). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EQB), set(EQB)) -> set(EQB). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 6cba31d1895..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,352 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - gleam_stdlib:crop_string(String, Substring). - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - gleam_stdlib:contains_string(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_join(list(binary()), binary()) -> binary(). -do_join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - do_join(Strings, Separator). - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_array, Acc) -> - case Bit_array of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - _ -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 693e840f370..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([string_builder/0, direction/0]). - --type string_builder() :: any(). - --type direction() :: all. - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index a36df375281..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,252 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {_, _, _} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(ETW)) -> list(ETW). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - _ -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index 76aa1ea673c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,31 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.33.1"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_array, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@bytes_builder, - gleam@dict, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index c6ea1257110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,529 +0,0 @@ --module(gleam_stdlib). - --export([ - map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, - parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, - wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, - bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, - println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, - int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1 -]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - --define(is_lowercase_char(X), (X > 96 andalso X < 123)). --define(is_underscore_char(X), (X == 95)). --define(is_digit_char(X), (X > 47 andalso X < 58)). - -uppercase(X) -> X - 32. - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_array_concat(BitArrays) -> - list_to_bitstring(BitArrays). - -bit_array_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_array_int_to_u32(_) -> - {error, nil}. - -bit_array_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_array_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:_ -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(nil) -> - "Nil"; -inspect(Data) when is_map(Data) -> - Fields = [ - [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] - || {Key, Value} <- maps:to_list(Data) - ], - ["dict.from_list([", lists:join(", ", Fields), "])"]; -inspect(Atom) when is_atom(Atom) -> - Binary = erlang:atom_to_binary(Atom), - case inspect_maybe_gleam_atom(Binary, none, <<>>) of - {ok, Inspected} -> Inspected; - {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] - end; -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(Bits) when is_bitstring(Bits) -> - inspect_bit_array(Bits); -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - - -inspect_maybe_gleam_atom(<<>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc) - when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, $_, Acc); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); -inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> - {ok, Acc}; -inspect_maybe_gleam_atom(A, B, C) -> - erlang:display({A, B, C}), - throw({gleam_error, A, B, C}). - -inspect_list([]) -> - {proper, []}; -inspect_list([First]) -> - {proper, [inspect(First)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_bit_array(Bits) -> - Text = inspect_bit_array(Bits, <<"<<">>), - <<Text/binary, ">>">>. - -inspect_bit_array(<<>>, Acc) -> - Acc; -inspect_bit_array(<<X, Rest/bitstring>>, Acc) -> - inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); -inspect_bit_array(Rest, Acc) -> - Size = bit_size(Rest), - <<X:Size>> = Rest, - X1 = erlang:integer_to_binary(X), - Size1 = erlang:integer_to_binary(Size), - Segment = <<X1/binary, ":size(", Size1/binary, ")">>, - inspect_bit_array(<<>>, append_segment(Acc, Segment)). - -append_segment(<<"<<">>, Segment) -> - <<"<<", Segment/binary>>; -append_segment(Acc, Segment) -> - <<Acc/binary, ", ", Segment/binary>>. - - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<First/utf8, Rest/binary>> -> - Escaped = case First of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). - -utf_codepoint_list_to_string(List) -> - case unicode:characters_to_binary(List) of - {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); - Binary -> Binary - end. - -crop_string(String, Prefix) -> - case string:find(String, Prefix) of - nomatch -> String; - New -> New - end. - -contains_string(String, Substring) -> - is_bitstring(string:find(String, Substring)). - -base16_decode(String) -> - try - {ok, binary:decode_hex(String)} - catch - _:_ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 45c28cfc87b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,878 +0,0 @@ -import { - BitArray, - Error, - List, - Ok, - Result, - UtfCodepoint, - stringBits, - toBitArray, - NonEmpty, - CustomType, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import Dict from "./dict.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - const iterator = graphemes_iterator(string); - if (iterator) { - return List.fromArray(Array.from(iterator).map((item) => item.segment)); - } else { - return List.fromArray(string.match(/./gsu)); - } -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs, separator) { - const iterator = xs[Symbol.iterator](); - let result = iterator.next().value || ""; - let current = iterator.next(); - while (!current.done) { - result = result + separator + current.value; - current = iterator.next(); - } - return result; -} - -export function concat(xs) { - let result = ""; - for (const x of xs) { - result = result + x; - } - return result; -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function contains_string(haystack, needle) { - return haystack.indexOf(needle) >= 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_array_from_string(string) { - return toBitArray([stringBits(string)]); -} - -export function bit_array_concat(bit_arrays) { - return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_array_to_string(bit_array) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_array.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_array_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitArray(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return Dict.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_array) { - const aBytes = bit_array.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitArray(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (data instanceof Result) { - return "Result"; - } else if (data instanceof List) { - return "List"; - } else if (data instanceof BitArray) { - return "BitArray"; - } else if (data instanceof Dict) { - return "Map"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_array(data) { - if (data instanceof BitArray) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitArray(data)); - } - return decoder_error("BitArray", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - const list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!(data instanceof List)) return; - - const elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (!(current instanceof NonEmpty)) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && !(current instanceof NonEmpty)) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return data instanceof List ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return data instanceof Result ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof Dict) { - return new Ok(Dict.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(Dict.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof Dict || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} - -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function bitwise_and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function bitwise_not(x) { - return Number(~BigInt(x)); -} - -export function bitwise_or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function bitwise_exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function bitwise_shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function bitwise_shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} - -export function inspect(v) { - const t = typeof v; - if (v === true) return "True"; - if (v === false) return "False"; - if (v === null) return "//js(null)"; - if (v === undefined) return "Nil"; - if (t === "string") return JSON.stringify(v); - if (t === "bigint" || t === "number") return v.toString(); - if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; - if (v instanceof List) return inspectList(v); - if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); - if (v instanceof BitArray) return inspectBitArray(v); - if (v instanceof CustomType) return inspectCustomType(v); - if (v instanceof Dict) return inspectDict(v); - if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; - if (v instanceof RegExp) return `//js(${v})`; - if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; - if (v instanceof Function) { - const args = []; - for (const i of Array(v.length).keys()) - args.push(String.fromCharCode(i + 97)); - return `//fn(${args.join(", ")}) { ... }`; - } - return inspectObject(v); -} - -function inspectDict(map) { - let body = "dict.from_list(["; - let first = true; - map.forEach((value, key) => { - if (!first) body = body + ", "; - body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; - first = false; - }); - return body + "])"; -} - -function inspectObject(v) { - const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; - const props = []; - for (const k of Object.keys(v)) { - props.push(`${inspect(k)}: ${inspect(v[k])}`); - } - const body = props.length ? " " + props.join(", ") + " " : ""; - const head = name === "Object" ? "" : name + " "; - return `//js(${head}{${body}})`; -} - -function inspectCustomType(record) { - const props = Object.keys(record) - .map((label) => { - const value = inspect(record[label]); - return isNaN(parseInt(label)) ? `${label}: ${value}` : value; - }) - .join(", "); - return props - ? `${record.constructor.name}(${props})` - : record.constructor.name; -} - -export function inspectList(list) { - return `[${list.toArray().map(inspect).join(", ")}]`; -} - -export function inspectBitArray(bits) { - return `<<${Array.from(bits.buffer).join(", ")}>>`; -} - -export function inspectUtfCodepoint(codepoint) { - return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; -} - -export function base16_encode(bit_array) { - let result = ""; - for (const byte of bit_array.buffer) { - result += byte.toString(16).padStart(2, "0").toUpperCase(); - } - return result; -} - -export function base16_decode(string) { - const bytes = new Uint8Array(string.length / 2); - for (let i = 0; i < string.length; i += 2) { - const a = parseInt(string[i], 16); - const b = parseInt(string[i + 1], 16); - if (isNaN(a) || isNaN(b)) return new Error(Nil); - bytes[i / 2] = a * 16 + b; - } - return new Ok(new BitArray(bytes)); -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE deleted file mode 100644 index c7967c32d6f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2021, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md deleted file mode 100644 index 3ca1c63e98d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# gleeunit - -Gleam bindings to the Erlang EUnit test framework. - -A custom test runner is included for when compiled to JavaScript running on -either NodeJS or Deno. - -Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). - -## Usage - -Add this package to your Gleam project. - -```sh -gleam add gleeunit --dev -``` - -And then call the `gleeunit.main` function from your test main function. - -```gleam -// In test/yourapp_test.gleam -import gleeunit - -pub fn main() { - gleeunit.main() -} -``` - -Now any public function with a name ending in `_test` in the `test` directory -will be found and run as a test. - -```gleam -pub fn the_universe_test() { - let assert 1 = 1 -} -``` - -Run the tests by entering `gleam test` in the command line. - -### Deno - -If using the Deno JavaScript runtime, you will need to add the following to your -`gleam.toml`. - -```toml -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] -``` diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache deleted file mode 100644 index 586f1012e4134ddac35bb64f7e3e8fb5b2db969d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1223 zcmc(f-%8^^6vpSwG)%it+Cy0}3(_b^m$Il^ix=K#3+{p}uCapPO`DoQQ_}|W=fd~# z!Uyp|_GX_Wdy-UBgO>GX_hvXVb8<M}Z@!bA792{{FL6`i=J&=?Ng_@fy;7@jSCa9y ztE}nv*kU43*=87otY*8;_>lMN9M_Ib14KiE<3SlHsPf66&MEjPCWBQ0B3832&sKX~ z#u$M4g$wf@w6Czi<5MagC?k@zjK&o1b%$B@$Z%#xctgkY2Aptc`Mz~GGNzs#xr*+C zP)W<)0$>a)7v>Kx7&FVX0yTx}9bA_b>TT3JsLQzTguSE!wb4wAo^ny^d!GBeqwLB) zRytUb2ZPXeX4lVG8gRr!DIi{=LF<P_T^X4<CdTphKDJd+_2UxNS@yeCZ=0V})umMR zTg~UXE)LFA5V>Kd>lIiVOJK<pCugN4Bnm(lBo~0}wqOKt<h#QphwMWyJ@-ONrJsAD zyx@hW4{Y_9WXKNWvBVGmnat#+Ri1=o%8PIw_-~%VNxc68PC6({;Jj;Cayb8DSY9EJ z%PSK21#6ssCuNS+Hda?q-$#8V9ZuBRsC8=Rex#b;EH_Yd2c!0h&c)B$=8^AvejWY* DT17G` diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta deleted file mode 100644 index d03bd4e27eedf3cf7c1040715866556930eeee16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache deleted file mode 100644 index 9c2b842a84992053ebb351c077d0fcde43d77669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4962 zcmd5=L2nyH6yDj5S!Zk48PZfuX_cu<)HG_^#z{+MD%=EuAc`Oxx2jr%?6p0PH+6Qc z-EmX*K&7Y$gg`=74;(-O#D$6<07Xa~$`J_(Dj_ahxx$SDGH+&f*Ky*cEu~Tqb;q;W z-8b)j-}k=fL#PjZc}~Z}>v&Y396f>t@AM&zR|fC)p}}knwU_JET0K#+RaUS(&uS@R zqu{etrEZtbsWY#s_=9=#L!=E(pj-KA1dF5Ud-;<pEbgoG`Cs|sJI%{~uff9VE9EPF zus9U+^3TU$(f>>~AAbfGqxwpIOov4>KATU(VevyelfTCopBR_(pBk{3+m+3~vI`a; zB)t5G3BE|)%HK}H;>+Dj`LA}vB8?z&_@`=UaKDDy)G50adU{$>keN_5vw~t68So7$ z3hqB)9#b_%G5g>X;r@A?%;2Qnp0(MGIIg0Mh!Zc$>sj2N!TowJ&pg{%jxNOzBrR+1 zga49Qybm5^<m7vECCle8SEs(+_4BT_{8nfpuU-&;fGCn--RuhMqPZZ#ii_7CoX3YU z_>c|}4v*vE3?A+sVQSWO>rqhrJln>rVtmV7gm{P6@gkZW`c3T>TU7o;Sbj1m(&-b6 z6vHGHiR~~KcKGSY>1iU5ULn575?QlZja*n-AeK`hRl80dYn2k;s#0Rr8#Sv$*>TM< z6g2gB^2Oclro%547;*t-Jk3wKaPubN^;^LNK8?0rp$@ZIOHmYgeh5PmaEB^>q<^iq zE3_L@Uv$;(ggGW^7eH#85_GC_F}FnhW}V5xnOjSq-l63B8+NDS0)}4qX?RTv5U?^L zSg`d(wd6ZVQTxf$1*(jQ@&=fEVpO?o9uSPd2Y@g}K+!@?(de~Y$#yKS1*wh?OboQE zp1aCnpy&XEZNhrkbnirNk-B;Fj0D0NG>Pw^9gxr_FT2iF>aiGS!iDp%PMje{DGEix zS`8XfA|gquc$`B#gASrF+ZAO*04X@u(~cs*M;P%|6x|v4aUfTAowCJ(<Gj0x6jIOv zQj7~7J&{_l{SfyLslX2`;(I1UfQMEv16iAmwM(|tF4QW>__oj*is?~{QGXBA(xGbv zZXu%Eky4ASxV8h>Bdb7ByHTfb6#!~eAL>aCA0~6xtX0_d;ajm-6wSgQFA@2!vA041 z!z0Ghr6yz4OCLQ(y0)wJR{H4MM~&`X`N!g#cr?HVB=V$j$!J&H0^{naq=Y^yqOonp z&wpray`?CN4`%Q|-hGDBcqoI1w)DTPDzqY1Xg$!>?tmqHz*V5ItpMGB(T(^G+b=X( z6<GNAty)4%@9v3$=CdZ)6r5bg(`YjJISOAIMWu&Pk@M7NK7romQ%crql+~!m`&@(% z+b378x?PbHpbLsm&Bd<7M*O;64tx6_T~xSX)<u6vh~7Rqk56UrDW2VlG@i)d3BDXn z<IxOQvYtjnf87a41Fod&%ads;8piA9ZK;eufihm!BT}iYf;ecmEo=iRm}iyQ0j`dI zvozt;GP7NWxYdp6;|w}q11rFD1va5x2g_i2Kt4v6?W@!w4cE8Djodl_rI_tBDQPxD zO&YXpS8ZA`2v~|`Ry%Hx8Q|}-#o*pxkCZKkl;9ShR`^X+1_s0izVr7$Nx`pFdPWA- ztu`GQxd*lcM4bl#F*<Ogy-K-lK?rOV(lB~qCZXb?{df=XWIX!RxFDvOb%i1|#aXW? zQ=j$y*~d97(5`6JGhjdg4UcC{x5xYCEnJLV9ASPV6K}`9iRG+D1JV)@@%=6UUo^QJ zR(d#<d8rgVQQLEq19oRc2cw!b8<MXd17EL)p+%wZjp!Q4I6!P$6=!R1hrSPxaG8QJ z=4N{dGgooHS*_aFHeD8qy_1;dc%uk`qhfSqCa&_iApxSaA3k&Pu>dOO0$T2=h8CLh zumJ~k*(~`F>x85y?XC73W{pQRp29t?WA2{rN|$qbdXr}W(eKFXE5iP8jo4;#2<D2w zMCGiOG*MH}B`zhxl!#eMIPz$gdaBa0)0h>69YMJ>W<4-94>442@u0<E%=%|{F4YzW z0_=l=0$+`n(Blrqy%CkgD#Fhq;CdS248pT0n4dAqj0nSokq(lAQJNcxO}mRICc5^L zxxib{I$i*HsoKW)qx>a1QXuWQz*f|)#gHmzO5S>wC~JD4>d+ym=eZuStD+rrwRhXu z(BMhMVis@mV8r5jPRGa#VHl21i%1K|d2^F!E^H&3|KCLK$@xVx5ayTQ*M=~(C`}y( zcBc8+;1`b&G(8!aT9yvyGvjvyqop?Qq6Oc+t{~bucctsxkN5*iTK>S&<!XZRpXKGx z;<L~M#^KkB&Z~3Ot6R=;J1nTqD+<y<m%**A)$DSOKqu#o-f6CuU=Lh~?Elcu`F2?F zR7)Q3KKcu&pr4Dhc^oJA;^8bF-Ye`Rj*a73CUxFx(verKx=(`%9>?~>zV_yokvWbh Ic*Fqu7vZABoB#j- diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta deleted file mode 100644 index 09e2f8acc9336bce7885613638b9b2af3ff95002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd;&v`S@w0Y)f;2TG^sq$cL-7nc-e=B0~Ie!%wp&?033h=d8> diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache deleted file mode 100644 index 6c81f153248d383a02df47ba397294ba9f23d5dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 zcmd^CO=}xh6n%F_qtPfHs~6)Gg#^jQ#vim*E4NTYi(-Kb35I$+E-s}YYof6`sw}B* zMzr>(#bnVg3PsC6HiAM36jGW+7wx*6_Aj&)0{IKsP49d;mLdgPnN<T~bb0!icg{Wc zoOy5F6|c*f?cvI+`2FLVYtu5$HfFNZOEcQE>>f1D+F`-4z^NKtt64XJ2WwT^VVQc< zGS(9UN}p&cNVpZtsd!&vqR9cYtAdCdGD<yE)1&@~38*ws?c=QMR*oFgrXRBm-6On3 z!8ih1^=~ZG>XsnVYyDjT4@+7T#F-jY^gW>BBcY`42vlr{cl1q>iuV)q`g;i~{!MWG zkyrdI9qSJzZzZ{{KT1;ZlYFc{kg51FW$5=(RD7Xu-BGBp(tW*?rsBq>6Mgd%71^m1 z{pu8m<yxm>w(10LK@hcvAiV|m!QCR7Y%|}L=;C~4=J!J0JX9fZd@q04u6LVe-fG!S z#;n!f0ALK2UF~B*WK2uZ74TXE=lZxJQ#p4N7mK)fZgM>S*Ez2pF~)NK28b^DpNo<# zfq+=j@&KszFb|075cTLTuDv60;p+}JUkYL>1H?qI$1w99`~l@#?bfZD6DsCG42mge zJHBEPL3>wGDWX!yY+AMx^j!--x!`n7q!p6KkX8b`V;K2cnoYXFH>w6$4*3YTTH=8n z@^dd1em2j?&rMW|sM3JNH8@1Z9c`HgXSRpSfZ6m&sAH)4Ci#0(Zkb<(Ow?mwLiSyS zP38jx1Lp_S?(J^O<}<JYuG6j>UQ1cdYwAG=<l7j46tuU`wsZnvKd;x42bF6J-dhhB zsD0^SEMs6VDW58C5D8U-mHmkHvd;^L-(tYMtL^!?pAClwF81;D3xvb@5_TdFpu9Ma z*xT~i8>VC=eGFg=fYJt*)>8tiC7hzjxkA^n-QC}}zM^b*+KjE;6`zQ%K>(_@b<DsF z3BDZz!7nbXdEb6z`9>>rUz#>wP}>nDfuPRpe<T~i+Mmi3#SL?`%F4boMne=wZtRA+ z@vN9iI9J5EbBn30`}3W9(T9vv(F6<)Lmxv^C-F<d-RJE?FFTn0)M(<-!}3|9DFw}q z1u&V5F(`=v5M$65<f<Gw%#gAEFEue_!=aHx$j6YhEH$K4NdPJ0^w1Dm#SigY1xNM1 zcXSD6q0(hJ?|c-UU2F%u2=w;hA896wVBbgjgHIHZXa-=8;pHz`O$EGAE<^CFbwIZ3 z=Tkhn{My-Zd0xm)lq@teCnIKt(1;P5=!p9Cgvx}q+o@kur&bEV(UnKQU#egpqA&7T zG2&z-eg6nc;&s6f<yBNKW446Z%b7~M-9%{>rDA4>cg@@fwWe*Bw@tg-bWplN>*9x> L=QcQR^H<<MKB2tC diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta deleted file mode 100644 index b59a80e2912f11ad19fd2dd2d30e22bb976c9293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmX^5A|sUn2AH4>VJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache deleted file mode 100644 index 3657f591620fbb1984bcdfb66fd54bb8557a179c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1934 zcmb`IUvJV-7>Cb$N>f-y@C~wr#f6SQ=7<wlTr|C55N9%+x`N4WOjv<3yLEK7B|2lW zc+02Qg<rutulxpHdgGnR_9^i64+~^<b72>pye&EHd4A`4PamDbx`62cE(^H)A^B1e zFtwlD6qb@-1Yx*mXzF3HrGwM79ZT=+5#rxtmn6|K^wv79+@rWAE02LoZh+i)2CT@_ zR^vWp#W|H4XKtZIs*O&B6^nemk>gqMhZSe6D62<DTCW43<S3_n1%4F<Fx+Nuwl%TO zv%z_%iMykvI8D{E)Z<<8(CqXLP1Jj~qp6*Tga8nNu^nZba)c;RHUcixa8bfVftBeR zE=af_46C|RaUVel$#_p?6GCsYNwFHnC5(qp;(;Q{iU@%50d4`}OaK!S8~|*yA4OQI zL@CDSah6S!*~mF2A!WPY?dl%^N<Sb<%WbpQR-GV|(`hp)DqCJA5igTi0b>%ziis`V zcKigC;Ge5#uTO&oaFK@SrQu_Qq`{T;Bd3vJ*D?=Xvxval3TQu1PkVoyR`zIxa>En& zV#ogrr={fB=HdWzfT@|u<%Ut=x8E7t(A%2NQio|-P87pqne}#VwT5dFuDLd^WN}5p z6}QZ1F)v|0+)-h(7wj>!eB#0lz|Ur<T-WTrF>>K@=VUQ0Vfr60c%>T`p|W;Hltvx# z)^)(oBP6V#AvlC5m060Z0^VgI`{O*T6RsSDBpmfX1IoGGP&%T&=!tGO`%d@i?dkGh zT$k%wz;7NQQ8mqRZiZSNaf>eZXqh48T<Hb(o*TA~9j$5Wp9loHD7T>gjaagNYfNat zyTaEey&qd?C{7vLFmz1+8$n>y$=|27zo^^@=PH|J|L|whr?QxmFm>rb5GF;woWdAj zXbL~MXoP(Z-NU_r@i|P(n4a@ILB4>zlz3zHwajzXu(hD!ke_Gwxz`7o4a+jEJMb4j C2;Lw7 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta deleted file mode 100644 index e7f013d77b779ab53ac19ad95a796aa2567c499e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache deleted file mode 100644 index 5ae07b5b49a7571a716a53505f89508a787320ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7078 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 E4S%Gc*8l(j diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta deleted file mode 100644 index e616ec00377dd7ef4a8bfede2ea0cd223bda2c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmaz!7?a8X1B_4xH<V7#Nlnbv&o4?zEix6=4Ak0}oeTh-hX}R+ diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache deleted file mode 100644 index c8419964e1483f0ea86901e93565d41bd7fe4fcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6050 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta deleted file mode 100644 index 701db1ffe1dd588340d9500aba145a8b33520324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmd<{vr1)v0cI#e1WKppq$cL-7nc-e=B39cm1gFoq!w|Z$mL`fm++&ABxRPwCl(bY ORz`h4w=v2;suuuDoEL!r diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache deleted file mode 100644 index 1cff4b455788b7653d5f4a93ecb7c07c9ab1a00e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12268 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 RPu)7n6=Po95~(BNe*q9&PX7P^ diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta deleted file mode 100644 index fd97a7e9416a1be0edb048f21be7ab89f3389b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ocmX@|G$oY*1{k3X9w?ojlbV>TpI=atnV)y~=BAkQ+a_%U0Mz0PzyJUM diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache deleted file mode 100644 index b0e4f1fe8d576f972851f3c8c264f7658c3c7d3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49216 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 B8~FeL diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta deleted file mode 100644 index e0ebbdac5a8ca12ffada134deb381bda9ca0a76d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmX@|G$oY*2H2qtPAHw8lbV>TpP5&}g(8rXS&Sx<l9^n>gQ6zCpd>Rt4^^xvwYW5= rL<B`$aY<2TUV3~|X=YAJY7sw*TvBF9d}2{iV&%$Nhtz({EiVE9yu2zO diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache deleted file mode 100644 index 0be48509bfa9c8884cb6f5099e056a343fab22be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11377 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta deleted file mode 100644 index 8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache deleted file mode 100644 index 62d17d5507a4009f069cda23c024a55a73932d0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5806 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta deleted file mode 100644 index 8bfae6dc9ba127cf7714d1689d480cfcf6ebdc98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2Wbbd7QGhmnF;_hmjz=0 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache deleted file mode 100644 index 2eb1d05be650276fe78373129226fd3527494c45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18138 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta deleted file mode 100644 index 7c99d5d905225ba7c564dd44324b01b038d7953b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache deleted file mode 100644 index a9d1867658d08f494777bb0f35f85d4e32891791..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2856 zcmcIm&ube;6yDh%mbAn;gQ<&4Ko6Tx*;VXlRZ41%lo*n_rft04K%pi`tL|7{d$qgl zu4+5BNv{pL_|RK(357y??WzAkp{GKRg&uS0q32$lH?u3nN)?lUB+%;V&CHuO-}k<G zd;LhhnWM8C^lFY?{c-xcLXOhi>C?iy)4vsRXKjz!on<$WBq_BUaUxAQp4+-9-zv%U zQ^Wj(DAP~Kn)N+F<3!%DzLC-RP%*3<3L4kc$hxkgF{?eYKttm%?Sb_-H=ay9vVNFA z!_KuVC&!KamzI+!O3`7hZkrJElB}5PM59EPBtj&K7M9H`vLZ>QDl0^m#8)GPQp0?P zKa(5u8L3SEcPWi9kUwljuAjtU*zmRObr~c9#EI=YcH{tyq9B4&oH%GLz@f`L$MxIr z5eER`LqD+(mUJEN?XYaM8$-mBZsaou?Cpd_&|-W=$ag_s9Dtj^SGJFS=*H-AeF)u< zd9Kf59&3IcZXej4&|~<g*=!21b*O<jeQ9ppg-*9Kx1huFGF+>{>T1tbtLf0Q#nPbx z?(UT;3;oqc!Co0ECprlCuvKm+459=)H%@pKTa_{x_qlak6V9cM9hSEJ(!l~8!2!Gn z6*$50VqB#B>bZ+xh`H%Owu~}VG4j^?W%%H}Ugw9`b%|6T=YPpR6aadD#(wi9_DenX zB|-};v|!Leu5Kj=db=n9+{6huG?xzLK6AakUlhuk*-Q(iiG}h&?QJ($Dqloy!eY2= zV}<b01GN%#ldzkV!45;_iz>0fXZxI2J}<!%LH~seyTMX+%>UDz(yjw$eh!*>bzMDk zf`(XzVi3|8IXH%Sg@dz8Z{Sleip^4F`oiZz+$8v+<n3FkOtlrNl6nf0Bvrp9Ka+Ib zxCk`NBqcCG0-tK<lgw@^$mo0P0{S>TA8*59(1m^5Pq-05$}A@lH7gE}vJHF`aty(~ zk19ZlW5%GFvDbVpmM`WQt3M~ozw*x%Im-e!q@uWz#sy+z?jVSCgYJ+DeX72^?NBw) zp>T>cM<j-Z2qxePgYd=8cU}^GxT-&Ce`;J3X|rf#$c;-HkqI2JUAl@-eK=sRE0R{> zap8rS>*=wvsquC<a!t2}B#t{uIqZ0ErtLe5uk_O<o}cACrn_jAfVU@3CsN9KCm)xv zTIO*otYZ|`AKKuiLuEDdYFUlul1gbBdR6g`-Rni^w4vfdF{b@UbZUGVBh^#+SGivc zlH&Q}D&Mt%mh>=F`I{B)@9MuQzOd$HI=M(EXXxw-ot>Fl3j&X7i&QhF?nPZzykmPY YtAEbou9r~l9rP=A_lmdqo8e{h9N?G1z5oCK diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta deleted file mode 100644 index 48ca73e0ee43502e40d1b8b70f34ddf19d858229..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache deleted file mode 100644 index 15bdf1d6fc3e94574986445cf04af8d55763504a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37904 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%0D{^F9^Fo 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta deleted file mode 100644 index fb52d575e15e87bdb03fca9fb3c0bcfa695274fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache deleted file mode 100644 index 3b60c9cc8ecef600ef12d93823c7681a0177ed00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46259 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta deleted file mode 100644 index 6587875a9ea9dec90101364c1e7d76d5ef2dffcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmdo0G9#4%23VmCPAHw8lbV>TpP5&}jUteilb?ttlwXvRTEvB-svt2FO(Z2Vxn%E! Lc~|2ZcNPEuC=VMA diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache deleted file mode 100644 index cc21458a0295aa759f1cded53fa46236b5d63ded..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4737 zcmb_fPi)&%829(=;5tp>y}8}ive7hSfUKdYjSx~US*jKR8mx{d1?AFZi`#ll<0x@9 zm?o72NL-Pa1W1S-IE*XWfj>tMlhA|^64G{<#BmZJfwbeM@%j1LsnaB+DTls3$Dg0x z@Atm%_j}(wNa7!GMy4|*dg|!HgQK8*p8`rRYd@txdsBs{8+EI?o!zbq(DdhPZC6lh zb^BsbA~cpUB#`8{s!agnG!bd1Ok<@5r4s#c6&Gn+>5hbhyJ@8__^a0JOYVjAwo~iW zt+d@}yOvn32|yK{DixY6tIHU`cTlqh@sevy5D|!ge*glBJ{6Y<{ZKbP08vYlB{M;A z@`UK-V{h`8m@)qpaq_j4H*ZNe`6re!|Bm5gT3$4#WSrcX(9KUKaPmaSn~xQod^fpd zemjYi-x3w`UIHgpN;hjMoP3eWYu5;9pQUu|Vhpq!_^ivIeT@HS70^lv&@LxHU3cm= z<R(o-^AJF60g#&g(1ADws_YoQ5K$0}1dc!#bh=QXuauDmN${8uXmQ85?nMlu3`rvx zE+T2T2LBL$34RTK!3B{NN_FEn08N(YJ2=J}jNQ2)2mq@97zwWy6NFCdbP9Hl>UzuB z22h<VRtvXv)pj?5<nB+tl-Sv<w%4|-_k322+hdbbHZ~b4m=j3K37wv((0PxPm_P>d zfbTHk89`!Mwn!COU2>fI9Lva6BF2DFx)gvv?tu?B9Kla=1#*$7h@*XAAX(!)10pdX z|CRk9GYAu12wC;4-FAHl1}=gCF(!uR*F8ptgl)G6#t+hcNp4tIIg0nkJ`UL{M?pXi zM<`)X7>GEIxXVn0Z*Mofn<RHgp=Q-B*W&y9ee8V>Oq<CeX@l>O)dc5!m^eWYiU)wH zln<c2?xhmP5JAT)iBNd4I6-JqrwI(r<H%}A5JKR&7vg8*@`mMd4j%sh93+QufbWol zl*d7yDp)$@Ldj}(>Otl)ZT8=1*n3%i+wQ5Xo|8r_5iUq>N?aD_wyo9%KWOvV_^Mep zZnC<H3It|nQK!WUT^VRFpfae3hL90N_&PE)A%ajpAr>PE;X{pZ&_5r%tOzvKZn%yh z<i1qyC~B?cc;1WtQaT7x9}OmIkruN9<&-j_4kJ-}B#4euEaCU8SVGfb#lo<SN{!D0 zubA9d@q6(?r&+58dSNb)&(4l<m$9?Qd^H5m%r|Si>qQJ?$qOVfh33m89_!~aO=b({ zny&3MI7X)_sNN%&a13W3jgVpC`pmjR$zj&bY3RpeXx_8Tyz`-ji*^HLC*UtI@BHNT z$sN~OtE1T*ScUiLdDD!HBSSn7`A0<(z`qni@PTiGJ%-LfL^vV26>#9`cD1>7rCRR@ zqQ#BfOpl*BW#d+#!t#@b`_RCoIm#d(!=&+rHGIabm>H$E{10Zln*bV7#XuaCmgrd= z;}M(@9(v_xmf4XfKP)T!WPseu(wd~Y)h#a5+BX2>-EHv>eb^(UfDM4va@Dqd%_?{& zV6_YDcHOmF6w2&s(Y@nw2_LFVvy8rH`zaH?8u6AAF0u--ehTFgFqFNekiDHP%WB$< z4ZIV3S7X%ggmOk%1(BE1qp{7LU;Xzs2gex&Cx*CK5HW(r1fiHs*dFv~jDL3hm<Tnd zt1fgpgG$5C8;I)LnY`|_0CJy;KZ{*bZjMdLKK11}M%A2GR>9rnjRwEiu&!Y5UD`|3 z2x3AXJnC+J{Jv(NTTipC&kvDC0`t5b2#<}m1H8<lAaW<=6*+`qo<4~9-5y)~G7Qwo zQ2c^tKT-F#ZKJdt!5Y3EhE(_$b6;vARP<LuucDa}b_+W9sr;)<q4d-%Y|kDAa6<-- z@jI0)Z*aSPAp+mi?DZJm^NhJuqZmXG>U(4<Fo-lWh+SABtdQJ~@DM1-XLfZg$s=?o rPiKy>UYf>q8e3G)w>s9`Yt?$&;%x$r&EoIkxvjaCR?9(Imk+_eGLq}A diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta deleted file mode 100644 index 0b52486cfc5f05044b9b56a9fe4cd784dca2c15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache deleted file mode 100644 index c6e2cffcfb0cfe07a04e05fe48d595584a3bab4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7261 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 NB%?)ubC!OM{SS_5Wpn@l diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta deleted file mode 100644 index 8b36f47ca8f554f7005ebbf3285be4ae7326420d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache deleted file mode 100644 index 35d8d06fca9acd52e4037705e4606d9f169c2f46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2704 zcmd6p-*4Mg6vuu2BVMdk;VSC721;+cP3kJQYm=dE5u$5Yh$dB9y;S01OpBA;B?iY% zu5a274RzuXfslCN5y4-95c~m1@E^cCJnU~6$M-q~TdYB4nkFUI_4T>;9)Hd`-{XzG zdeg-7ZG34CKl-}(=b1T-KP)cguN6PZo6mYabq7~MrkGvI<lTdaD}}D_wYPN@8)ZjF z`r;i1j}dats~WyxVxx`oR(h?X;(QtB+jz#5*6GK)ss_L9iz==!JGYQltfN}<7J`AN zR-1hl1|zN19BMH5U8^>KiwD2zrRFa>3~m_9&Fe-y$km$Hb1?YHEH!^Lk!B9uL-6aY zsyUw{10zdO5K<JJf8T-g6va6MSA-YJc%hA#Oc>6WV;Bq1^YS^)!@?=AXCM{hWoHi| zJk!Q|XmjQ>;a!@;Gjf;mF$<y@!uyo?F6+^Vlkg$o2O$Y#%n|8%`!s;(E+?%9C-0E@ z2rfIkwQgDD!Ua-4bO%G9MsU|^wL}OlFaQ)Q^^pyRmn~Q#9$J>7R$e!1#!)963|&TF zAy_r%0}1O8V3qWVhgo3nO2-S4K-3bc*dqI`Kc+AR&;m-_AOxJuCPNl>#~m-|5tjt? zfF$N8gG<l|cn2QuS0%y*7YH@WLTDEuh%cHGHL;3yREP}`s+jsUeJh|nmrv04Q+asB zu|*#0A`hqJ(0|D?gmKk*BEdZYaG&Oq<Fnju2m6%qXdd9m#Ii{g5=fh94N@y0Z3^!V z2z!iz^Gr^<K{qvF9h)65Jej3Lu_AIX0hmeC#G*d>XO^ZC`Cs>d!mj*`o+53BCpm0O z&{Ks6gJ|KBLx9;uC}WVQHf)l`wIjhOrW;rghcCX|;^6}?m>kyqe^Ff)@?n~{1HLE< z7SzcAhai@|jHM5;Ts4wIv(D{`w5G)<PV4c2GOt4z9WolxfV<oaA;cgdpeRB@P7aZL zFBzh>%|s?r0Z1%Fh&E0zXv9hr?@(y9Kxt6L(ris@OqiWMKp(><Sq2T6r^;5Wj3P$g z|6mTh;1yD|l>C1M^6v%Nw@Ar<G;n>Ws~4sJUhud6??~~opd+HnZ0_yc5u>07(L|;G z$mFv>QK?D$+z=DcK9Q=#e`8t$JoQ3R2Q}xhtb@mKGdT7(i!Twixnog_rT*bK=)^Vf zQUuQTBEBAljIZ3=w8>jGxq9Cw?MGFpN5OXmG-EyKD3_r;?!_iH*}Ok#CJ>K~`JJiN zN2k-VH-Hn7I#z>C(u9tn@sC|UR<Lirl^<|$l^-<@^dNjG{sx-ThHk3cXH`7Aif7N^ zr7B)Jhu6w@?ae|h41H{@!bf3YkB#Z#d#)eRt-CZD`y3l3nAh%nv{+{>Wb#CuFUcS1 LEw~Cr{TliUU~H-r diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta deleted file mode 100644 index 2395015401100f34736675fe98225d853098d534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache deleted file mode 100644 index a4cfdb824fecc15d2d2a334101ddf6014065c30a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1880 zcmb`I&ubGw6vy|?X1jH5h-0AGg7nc+nntZA(M!R$3Q7^dZc`8fV%F}oUEOX%c4I5* zz5jsV!9y<|{5L!)=*63&;91m@ColEQ>?TdxMO3^@=I5JvpZ&gXkS&;eq{b&rKDnNM zVVa!Z%|AD%@}Ep|Z`~Kp=GmsB>0T=y+zulx=lb5A1$OBK<7aC2IneWOVZ8bVsPm1L zt6v#)UhBo`E1f#;Gt1SF8S1nLW~<Qv=zE(^^L8j!8=4-t0QL~m?ayFvurv)o)A*5_ z_72lE%^qYFfF@4fqy@Qh;jF#bU16FIjHa2Lp?#`HEz{_B6+{CSAl^pP1~ATRb`yYp z_%kSR%jkPcf3~<RqIN3?^XOn8wy^1VE!^^=4U9Gf%J&B@3SVrBAi@pjz89?1kBfD= zr;bju>3hP(s9~WO%~%#rOyHGmXS3;xkVf@-UBR_*4krqw(^#IyM|0R=6S#%7pb$*s zLkzHpWqdqM5#+w})S<(cqP0X^7>B7#gN$d3d<b}Ul-itp1AUIhnx<98GPg1&WssoW zIe_}yK2QQj03mY-;r@bxIBstf#B7akLn-^tkipa04X3hO_wI|JgD#xGl?^Y%RVP5l z4;y$#pxX!pwnIr&vUY{*tvZo#Eesz7k+Y3n5JtjrXR%IKC-5#_>~O5lSSWG7-0kwF zaWC-hsf1}cVTz<dsJO<CF}CKl!YDx&^&#tMP^zw9X<#UR1FEIIA*EKf7h_n91nUEf z1E=G%RJ!Ws4jxLC7)tH^UP9_nArTT~Q&I`*q!QrmC%JITA>FG|+x^pIOqIsqVKK-l z2DGg5E7~MNDTXD=@0zZzN>6VnRSiiAg(%<H6z=cyl$(0eoG6q}W2svatnwYQOck{R zqCw{i{*%AJ5tXRbb(na3^e_=Q#Yj7`$1K~v{O~pYlsx8VruRANV2-DP>DR%3b(mN! zX$C_$sTk&ChXLsG7wIgq%P3<>Os4XKmGt@85C67ah7`AKr&W5I?X8zDEQy>BE-sh@ zUi^m@6QAnQQkhC7r;HUUr{Fr!A6)FJ*<n61%SVQDmm3YA8%1uEb1SX37`sY_CFYk! W*!ClCjMBV*<KEbnR;$rE2EPEr$(yAB diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta deleted file mode 100644 index a2089a5966a154b5dd61585b9e0a71668b274981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2a#5L@9-R#`vm|lvIQ^z diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache deleted file mode 100644 index 60ddb1de5c626c4ccff9d271c0dfc4241b6a110f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7006 zcmd^EO>7&-72eq;MRE1#F{31QVrVQkC`B-qNTx_&)UoB%O(LX;D5g+l!;qHLNZe?- zOYJT#tBqlxw*ox`0Rpr+C56!hy)-Ct3Q(Yj9)jjjAjckx7Dy4GK!FxWZvoWzW_HP4 zE-BMcFGUZchO;xXGw*%#z3)AqCn@bKay3KG)ag@?(f7a1{b`y|`bO^W(<Jxy3_04h zxY1hN?<g7G;qu$2=PNVYmRVm;sWe@#rbue8+JVP}R3BG0`n^S(uG6d@pR1@eTc+7M zom!Nm<BzK;RU@jRh5whIQ)#PQwTPB`hpg3pMxgNzb*1)C6&efaYqfkD8h6L8)!rO~ z#=kT3wXZVJcz=AQc7Gfif6dlwUu2>2&IC-Kz%f(r*1n#C#%Yb@3h?)fF_QZP{{A+7 zDOb;uoIXi%^OHnwPf@Cqs#g6SNmHUL3L%O@v+LEis=<?S_$2gPfu1YVbBoYiDA0v6 zU09rX#q|6+VYKih$*%NBmY7vl@I<-#Bq8(_A}ps5vK;Phl@Ov*^3COOl}??dlY~yq z!>4B2ijr|UJ|UIAsFT`JyW=%C>qbK%d*CcQ-~GPxy&gRu9Ij5!FA^0_uMT>*JR>|! zjc_DfBn{i7Yt?Ny6Rp#?NQvG^MRyek#SvSD4Rep3GHk{z-r}~;9NTx8-{cI=vB#Vp z(cVY=UDS1UfnC32wAvQ;;LFz5mT-m6o@X~pMOMDW-h7_zxK3-+0zcuG&?0;J$^w4( z9q~w)<BP0vODv=5dY_dG!pitL<2Ox@kQv;VqEtT6ztoS~P8;pKr=WL)p}&q9da-&{ z7#dIy=y~wPfU5x}z9dGjUs>Z`#|mKvSR{Z+dTw3O=*B$VDASD$A{5*vW<BuM!7w%R zs%c5wuBuuZ-LtX=paL)D0DvVrKOH?&znfm<z6XAImNUx$yN0epOZVJUWG?qRu5H@8 z*r|7i8TK|an9UEEa3eb~{U(4G1{vM8(6_IHo!L&uZuq8SGykw{HVn%;WNydym}#?y zV|%^<5b@0xFS0r;abQ{&a~ci9gDK%)7^^eOw7KDmp~vC|wv}H%0L8$vl<X>Xy8_?i zwAc3X7xI8S0W&a%?dQdUMYgoC0M7xTeK<|LPtNMSuz&TXBAPBg%5ssZ*In0f^Wb!` zi45#Q;+s(NnBesSO_3RNAVB*2(?6fS7u<{h&ObdFoHc}VLBKi5nE+=X3c%jA>WA=e zs!l&7rKvxRhg;}J-wTd?o4fwJ2Pl#V0#*nxh`<28Fu>mc%z!OCqs5~G1V*t_XO6qg z-HQM<jywTa3b73MLei1z*LlNf0WV?Cj_F1q9}L5{B_SIE^`WpA2VP0ARFAdF16WH^ zmaZ#mWpQj{?4HZPJRXK;Wc;^I=DE~pT%YQ?@Kfo+Pr-$s>)~D!E_Au!bFUEN0Yo2k z?3%Z^9T*<2xNn#tg|L_-<&DR?jc#$;ZO1cxXb6uc=p*z+j5Guj3=bj6@DZ3c9yvn$ z_r;$PXP1Ud9~iy{zQ0^#;UXYiNabITJUN>IjtBtogBSors8AGO{m}wZS^+gc>3sDW z>DOn#uWu7veuz)g;KCi3d(FUwg4F{*ddzm%ZNutt@1idD`l7a}9hu%HZ?*lyUi7>Z z+w((5&#@leWM-~8PJgHa8HAyZ-iJt6ACJDj|4`rIK6hItP_D-gnjDbk0>a=J7_LHk zfG{QYKb!$hhPu!`5E9)EkXAB^+$<&0)|>TR!}5kq8;G(2GcjTSwEmnK8$W6^d1G&r z?<<*(VM*OwYm=DA{#bjC2*LA+z}ZGY$P`r0yg+%Ga%}Dw=zf{*WAko--YwI+i$Zq) zWWD+kPEIIkl2OzXb_PNT76Q4H8444;8!}ua@RJ7MRGGvN0~G0Td&B_*l>E}{Z)b&; z!uX;P(B}UQeK?L=e`tLuW<6LRjt|m@Yqf6#0`V#e#2=oD9x8t7BNhn6tNr0pP<;2| z{BJ5mnR`Tao9u~bzOFV*Jn8DX;0Z`Hp*y<b5#(KD66O?n`CYsan0|=xiwp|XYyUE% zzgoO%uv{Jbn!#H0isY(ev}X47tEZ8GEoawk5R~k|EFI0T<UOG)pisN{_&usZUXJ$% zE@-JtOLh7!q>tq?U9QvXl0K^I)jLQZ$0V@XW7AuB8qfr^fF`m-Y2u2-?Onea1k-_p zu}acVxuEpj+T(bAX6w0^;QGw|cxK?C`|r^UNVOij9EKkMz>)CqSkt%-qIMrBIMl2n zDZ<MoWRlQ9MGRUl$5;jV7Y;W4LzKlmx$LoR8RKle&FY6;0oENY=pK`}FcnLNIS7Cq zkMDFWW=N3?BAmOBfI$k_1}y-2ydjdfmT}1HoNb#sJFqQ~+dGa6`mJ{=%mqbcjY&Ps z_TmSFO}DwdjoX6Uu<0D&^Fy5-;Aus)bvq58Zx@*-s|VfVIBo74KE&{?%a^wpZb+u7 z%<H&q*YsdX9l9{%29eUAg@!URBI#KRhMH~5l=j1YVnWJ%V-IvJSX3H6C}(u{G03bz zX-A8fc2?*qqWKOXGSa{XQ7EaE^)sKHp=3qK7j!N3t`aSXFCWF?ad0KVLRL`dft&Mm znLb^orDJMzaQlv{1?fXChp7FmR52d_sr3cKjNj<dy$-?p!Z56N0no#4KPr;``aeeI zTnj5?-7=O;^Up$>FR)bk(G$OZf|9i(49Qpn18LGjPk*}qZ6s8z{sCl$=kXJWg$K)v zi6B>8tG*|(@g88KJRaRi0vj^rpTm?t%<LmD5E;J+O%Iv!56k6&q#_yr(853xZy`S< z1^=;yN-R8LQW-i!)GB3g(OE@jb3*ci0RJHMd8+586Q)U%=&yO<vP|Y>JE$;*1;I<z zkHI}qjrkZ-zF%d7SeNun$A)6yQ+PY=POFajQ8c{R-GCycLxNG87&3sPU5IB;wGccn zT?xJ2&?LH(>lbz8chm3I1S7nR&bcr&xtGSxcMYDuc?%WK(xB`rIkqGQmqr|nNfs_% zhVe640R%_>GW%JUk{hxZ4!ck^J97U<EYnXNOU+ZGT}N0%Q1y*ynf{HSOdss5-|MT# z)ahXgmhDF_)Pv$(N`gP8rsMS%sIQ7Sp*6b{Cw~u#RO(?PP@)eC_LbjHq$erKT!mjw zo?V_)>1=_{K1$DDqURqKad29c3TV0jzjDoBradPT=b-#f(`TVydu?w{)KaCoq@)}+ IGN;IY0K=$vTL1t6 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta deleted file mode 100644 index 6ec02d279a3395e477453db0c144ac488b739524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache deleted file mode 100644 index 343c2a25e00043bb30d972f6b9f5560a0ea10a7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6607 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta deleted file mode 100644 index d6129ae46ca64f4056698206dc7d3f0de91184f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd<{vr1)v0Y)f;2TG^sq$cL-=NFV@=I0$1IkMi{#QhNfhQkTV diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache deleted file mode 100644 index fc865bb561816657dfeba17ced130ae43f4dfbef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10388 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 bqwF-rc}MTY8H1Dff8gS^DV`itjEnyQt>}2n diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta deleted file mode 100644 index f4e887486561f8be3945fd8b61344d52d6d64401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmZ4IWtGYR1B_4x7nDxVNlnbv&&ez<xplPfLd0zE)c}_f3VHwl diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache deleted file mode 100644 index ac3aab69cfd99c5e7fc4f4cfec259c9525d7469b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6402 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 M;-{F>vE~f>KiVD_EdT%j diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta deleted file mode 100644 index e4e832bc82346f74985f18beddf6b6e9edaf3e83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache deleted file mode 100644 index 56a8556be6c6c82cc50b9ad602ee216107ebe941..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21832 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta deleted file mode 100644 index 7c72b25579dddf57ca0f1d52e021b5c2d8247d4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache deleted file mode 100644 index 75483550b0448e42f84a11e245d390d4d392040f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10562 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 VZ@w{j!88rCUh;6IMM{(|@_!|WeGLEr diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta deleted file mode 100644 index b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache deleted file mode 100644 index 8a0b42a87ebe04e602200039906fd11ffcdc4611..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7759 zcmd5>TZkLi8J?rd%98iu6Lq~8d%MT8*;>1?CGV^^$qH|`PGVCpCblF88wax*t!A|& zOB!Wn<gFJ9j%mU4shAY}5JT!Zkd#oGhk|YBg}k-6w4u#IDTUIvK>Of_LQ_)I|37C& z8fmq+cv}LxoVlDc|M_p<_y2Q<1pI^kZ-nSjnvM@lU4MZ@*PbDi7Nf(1B>I=WP`yyn z)N-O`N<<gqMa!1@@+CcYGT@^@ITav*&}*hnNNUjMr?Vj%Ow(}0J5Tb_uuQ{g+7rS% zy_e4W{O~z>)<=JEJM}j4N54%TWxhjT@V+mZdCv!f*?^fj5rDye0_k)R{(l|3m-#&o ze%7^?dC&!eyP=zzcS11uY)?A#`5qXABT8mZ1O^}Py`1^uUKl*=Rx%H|VKCd9%be(i z!Dqd4^xuR;|Jl11y%{3WkHRGSH~1=hNpu0ezv+Qv_<nC6iQd~s>Um?as+mg~so0Bo zZOO<JO_EaGK7Z;R5~L&|NrXre4JT4DpC7IS;Fr*Fl7<x;4$Wt5Q?C?8xjtdf%}W>O z)0$N)+2T@a55G2&q$3I)3BhgsGVNDr|GE`Iuj-}7azO%CTT3zgD^do(kvf+agq7yG zxSCLW!+w%)diKDj1Gq0!D;w8{wwO2UMN6A6l(mX&Ih*@y%jPboZt=}IQciLy6CmZx zB%M*{Orr0sZn<08Tm##`6LmGo)wqM@gTzPaqtvsYk^VG&7JefeZdGVTcsZ!$jRPMa zm^VzlpjW`H(Zcszl#oar;Yx7!x3O=d;KKg9XXIq+F>I+PO&^n~p2@wAoZcPO*=fyQ zTG6cMn7yJgu@Po0GnKuTJ`;~bSX#4dX2n`}xn}B2wOC$T)+<_`>6Hk3J$?FR_Wbdg z<5yxUwq3Q7iG*z!B`dCL_Hx`X3yBrGTuPYBOL)@+EPer=Y1OJ#!?a-ycp|evn6hRu z)znxPSIIK9k{3fO8;`(EXDzm>+bc%R1}Vk;aH3RVCKr`uPno7+!o3kTHpWhUOD$JR zngvJMY?g;qgngZrG?;B!nrX9hS7Wf52{y;7s%dF486OL>Yhq@6$tWkPs=YG5Y#3uX z)s!c20ih~BGlENWn1wfH`?A?cL?Y9<@$Zk<i-ul-s3}OJ-mtmR<}u&&dd!ZUx#>vj z(g2TqQ$&8+iTpN^yv_mcJrFw+tLIIlx>!;ziP%n{-)fWi#MTlMpA_6EG~t?`%a(4H z&GX<kx!ynghr@NAiXamao{At7g_^0TJ<mS9PIqhwzN34sS*4@MZF?(@ygTAa$XW&P zLvxZ#woUOduj03akIoLUmdYa(q-mZ^(aV8#kM@dJXQ#M0);^3q4pR{NwgE>DgfJm* z9-^^oY8Ie_YU@U2^JsM8N6d}MQ^$^tvx2FqHpUP?RA$DNW8xH#WIvCpzYh)%)!(RT z=JiF}Ab?j0oB*yo6F+EE)(x++I-8UD5tc7Xqyx4lJ7ep{Xx&-eH&Zu+x^IBGhr1fm z`&{W=8U-xM)%F1Bw*+8`nfa=Aon2E)H4W00ZbGJn4^N$34USPz-I!br$gP%c<3KaH zA((ElEaba5Pj-uZ(iXYW)vqI9?Desjtjb5gF7m_?1_wDjP~?d#Xe@PZ>T9_<MfO<f z@&4|Cx^0O05-B+L$+y{O$4J>(!Rgd3q2ODf;E%ez5ANv7!=S$`kj<>4)`mibH*Hsy zTPP6$2QhPw!J}dsqwD|;s_<2#q8(x4oCkIAQam2#aN}yP;2=&XxZxUyumH5N*&Q~@ zE$ryJot5k?adf66G95|NL&!UaWICkKp-!BAJ@r&F0m5lX6#l1rZubg7TWxb5q1a-x zDg*efmUOjZ3x43qImlRq;VxXSYQPQ7EOVOT<|T_&4CDw9ExN-l#B7*Y0b0Q{BnlW1 zf;njUZP>bDh%M~x;SxxMJZ4Q!DbvRjY9cq!18dGUYuebdsd6ff`3~4bgfZ?X_|F`Y zlXN_Ub1U!-ajga%Mz1UzN#RA}<ceY0?(Lo@HzpzBa;~E=?pnxll1xU~WM_FUqPtX6 z-o{F<-0m&zG46vg_<;}bt_ajTWO}gctefwus^r&AhfcIRXVy*ByOfSi+Vf+mis~6| z{+DXfs9wrzrsHvzO%OE}b2YsWPeaAUq5E<x84+1f$nEu2U`h7}{yYGT&Mdev{kSEw zT})vSC%KT)8a8RD+&YxH9Zofg-R^}W)ICb-Egp^ZEeytx*oSw6b*KR>qjXIhaghe; zH^hup)s}1q;E#b=(62#I<y1?<ICTTbJ!a(^pjS@As8e&WS`9D>`98#-y#f)qT&pZ0 zPiSHCZiqr?BbceB0<dm-rOcLL8tNO&hDp`J7|v_flBwsswaE1Bi_dRai{MRT7VHF` zesm_TOvHt=u1<V7QFlR73IW9ssg&L(yI#RJYvT!-PAGID)K>BGK=2WXw4_t+BrbPy zOZR;s-bL5fJgtFk(wFlj$h|+8x+75Z4x(tNRTHi5;pFPCg1KsD$>o1MUfMX~1{?<L z>z0|W$+?O3ib&mjNwBr+RhzIH5v4my(t-m4rE!Rh$iSPD9L#7OXMgvV!T$5aFFYgj zIq}5(RCttRenoiXAB0~*-%Qdsi}btL0=b){cZ>9gIDD9-4~z8YIQ%3@KPl2b;qXb4 zK2his1lLcK^wT2!2b_%tNfN%rXqY7C&sEW59ZMKhsSgjg=p=nvCP5nn8(pC@6{r6L z39_9>|NmqK9dFWf?DvJBI+9ZdAsp_*ozR<%v}b4R=bZ;q6QX4G<Ut>uNz&uc=USjI z5<0s;PY^mcx$akiGxMT<AxU)?$0b~=?!qV@b@d@!6Mr9~I`Q=(N|V4S_jD4Re%Vg~ z4Hx_p^%pOR^l=H&$0NU|sPr}%on|q61$(5L)dOU$y^L&<@Qs@}ZVD7ji}F#Kd9G1F zVtb~gq@3rR1Sv^z_}yVjZnt!7dAcDQDAnO7|C_3tp@P;oU`75EaSaudXrKeh_{q?3 zhbUR&k|H^l=0)Oaiuo^3_Svo8aub=#GA%2#+!2|cu3~P%GzWZIm4o|*-EtIOubCh9 z|FWMF6Clc7@pRXkLDAk|+ivmGxkrHMVuMx-7v4;LAYA_gaD896U948@%s_2pTWky| z6w1#WCerA^iuQ_bAGV+ps#vye*Py2Yw~5X>LSh<Q@=z>k<*I$XafSCyfutdG19oKC zN8LHtGC=O8FY7K_a-RzPr%9MrS67>@Tj<(i=N8#g9NV}plnJH99Y6yZ1==K19TV~P zXG~6D*0U1OM}Y3J%nxLC1o{eBJhkjIqpyrove0yVNox9hd+D%U({9#kZzbs4u4|p< zr5n+}OBazoN~FWvl=r%R(M8FCcrOOO2q=i%bbNJlG~(zonK}+{EYt;P-1&e%q#h6- zP=bX_H-UjlluQ-}ACk$;PjNtelWAWAIQU}@O>W}F9AR1kiBCGU;7lsgo-f8fyo)xV zPpqAM+O?haTA_2d<o4jP3%p`!<!Qwh%Q@IC)^u(2h1JYgb6CSpm+VB%_)?U-aI)J+ z`zLAtetIZL5ACN%WqP!??<IK0LxYnvsPtWcR>tUQwFEB)p=N{^l{7dE=l$odj`Ei> K=;oBj`1fDVAGuZl diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta deleted file mode 100644 index 2ae412bccfd7739434a236925520c9652e93ff84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<<f}##0 V7N1m_nUj)Q<er!*%^>nW832Uh9(Di# diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache deleted file mode 100644 index b7d93046a52ede28e212fe16157739a5771ad13c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3254 zcmbVO!Ef7S6!&K*aUHeGo=T@}YN<DEY*>PhWJqfylqJx?BDU4@O0|l~b&@ZwH^(lY zolTiQy&;IWAaUS;&^U18unPyK{SinA!LGY;;<8EX6y9e$ZQP_KL#pDJ)bD-2_rBlz zy?3r8U6kQi6;7{CzaW21ADff`s?#%*_okmr%DoMT(za^{f*=gq<yS;FUDMB!6nvuT zTlo07t3M{GX@yjcNrJ`-d1QQyMsJC`U)u@<+4fvP(2t4|ydy)p3QBe$qy$P0rm6sP z(qrHiVOf;$FINt{Rvc(?WFQTcDon}Yi^KlC>vYRw!4;1*+77*HwWvTsROOMux>ydF zkw<tXDiUGqExC2CVY?eb9CLK0h%U->=j~Ck-j8cfmYKJ~sPC7sjJrh~4fjzDcR%Oh zdX&$LKsCKVr0F*48lMt0o|B^Sj2nuyW=u+G%%v*EYzmDpQ=0JwH=d{R#xrhMY0X$q zqwykLG5+Dk51FUNPZ=T=R^;QvXvp}}8xz-!a}#JRDiz~`LZn>FvRy*-Nm0@-k~EMk z){F=OD6&2wN&>%afq-%nlsx_>U$vciWTVx>-w6TG^oRJsIzA+CP2E?*aD&P9)JwM8 zP%ZaVLuGAOwH!wcs2`}!wp-_A^wp-v)L@gU^)_SF4b&~>-KO<GZTonG>JoD-cjJt& zF0CMgv#~QnzTETJoj0>twd{7{w^WRT6}MVD(N)_GW3Tfw*VTs2FtW!w>ODKyR4vuT zI4W(}0YA!iv+BATy=nVu9l_ZR$|%B5V#ahD7y(nMQJxh?ak<GYm&fs3wQAk9j5@Qo zg3!|+e7k>kz3pQQMUm09<Wh!#1X8#})<|!NIY?!GN#~<W5<wZiB|yZR>guQPrp}^; zjg%b`e~|oA;YsGNOeyM7>~encp9y*_=-+aB=qcm@K0#SUfSfS|=DKjY3a`s(p3vY# z9!@Nb(YLt|Z9j;(#e;Ivy<``0mvPi<MkEqIQJ=+nsOW<_kd0FvpsrM)^7nGDiS#v_ zwj)T?j|=f2QHWLjgRl^B?nRi(!yM0jrU)~6)U1*bFr>v!+wA?$VWU=Jdo7HpK{0B) zy-sN&0<7sO@4?%!jGx&A)ZIjKX0vJYrd}oloyeK;gvcBAF!~(F&tA(4>YE4<-;uZ$ z6uwLUmfrq|vYO}9IOTIYtQ)7mfWrkUiTd{A?cx%of+4TTxs{-KVd#|qmgbPtTH=f_ zRN{b>nb$J&SG^lSXXu2n^T;R8h@vG9xh2=++@|H=bPoGuJwcBJ{cOKa_(k`1^s*as z{Q!MU^UKxrqxhIA!cp|jhUb)MsELAD_&W6<wf(N=cqmfw>CQo?M>Laj70=t1aSrPx zI}JMsq3yZh7)PQubFvn0FILM8JkgARn=OyeeAAWr)E}d0`}6<@zR$nH(mln^i14Kf zMekU+<?Ih5f%=!!->F^$#|~v)Tk@TbiL>A?Wr693t&F*tRv?A@4_C&o5;b4d`JD=V zF&q$tDhD$+BnSiR%Af}KNACf9RHy>?LxMsPW|1e^Ud?tb)-eO2#6fzkUAAmye$4c6 z(wKag6iA=1zwSZ*%^-R$l(Pja^`Zugc~~5!Q3oI#p=jfD9>3ZOC=B<<?e{u3rR_Su zA*;2}=m_)ScPw(4e%v7WxIy^%o{yGgvGBW`nb>Z4CSP)5qWzyGCn7p(W?12VzyxJ{ z@pJK_Se_N(?HVk;3Rg6^as+N_a5DodkKooJu&O{0fn5aq2(-KK*`efy9p;NOpx9T+ zNNM7^6m~46HAv@kH&~m_U$PvZMyvJErVuZvKq`H07-Sd_Efh+O?6;i&(#J8VbnVXk R5@Q}4HK>7fN39Eo$-gpIGF1Qo diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta deleted file mode 100644 index 35823f819643250ce036eb3ade6a8b4cfeac4a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0<IM LSG~Z5x<GpX@`M<b diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache deleted file mode 100644 index f19571aa4e63b4c2d3a0fccb0e0d9224a015daeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1134 zcmb`GO=}Zj5XWbpXE)mf!#YGOk;qnQsH}(9h#<X~2JImS_2~-5i!sHGO}b_=$>K#3 za`YmCS3y637r%v9KZAY)^&02dw<c0^(L*M)&%VrW{_~%$4mK^SPN{BD{duKsT14&2 zMRTL_z_eyh0^g5@{fXEdABIuz7_tL^rr4<oy53edP}0wq`hl|Y7Wce&$jOdqd$$B9 z-$ldwrjw7-^*%^WE*K53W}uuM_#J;V3P%8ds7?u~UZ6=>(w6{K+*J331W*P?q~bOe z8&urCx#y3gVB#=H_o-SD5(V&&UlB<(5s9X1P5%vOjbmw+z;_NrRx)eD?(}+n5Z7Lc z_u>@;O-7NQ!aVu|=JGs@8^c(3D-44KMYA&HrR0Wnr+<7N6SY*0iON%|aV%xEa)B`u zm|@-&J{M-gaMJOgMP0xk1v*>++E-gKP^<uJpt~1f{Ea{my;kc?aCSiJ9CJ;Em=+2E zavI2V`Gj9k531J<#{Ti3{<AjiWLnd7T66VsqIrG37Jd~RekeTpH{YO)RWstqc|51V z$<6^=*UNEofzF7l!tQnZ*^rtGL$b6%0hV|}yVPB<M*OwB(0t$LtSgqIJ&_e#<_I(H z%3SJ*lY8~S)-`g3yw_cPh`jYHg32zHSE;&9)zx?f$aKkU*!OvRoLy~|bW6!R&*$>) Lk#k#b`f2<P?Pucd diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta deleted file mode 100644 index 401fd74cd1e9eb44559765e4eac26450d3f34537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index a978a7ff425..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_stdlib" -version = "0.33.1" -gleam = ">= 0.32.0" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 6e1e2261268..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs deleted file mode 100644 index a8309e0cdbd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of Dict size and clean up the API - * @template K,V - */ -export default class Dict { - /** - * @template V - * @param {Record<string,V>} o - * @returns {Dict<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type Dict<string,V> */ - let m = Dict.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {Dict<K,V>} - */ - static fromMap(o) { - /** @type Dict<K,V> */ - let m = Dict.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new Dict(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {Dict<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {Dict<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return Dict.new(); - } - return new Dict(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof Dict) || this.size !== o.size) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index eab2f0b3fec..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam deleted file mode 100644 index 79860e964ef..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam +++ /dev/null @@ -1,157 +0,0 @@ -//// BitArrays are a sequence of binary data of any length. - -import gleam/string - -/// Converts a UTF-8 `String` type into a `BitArray`. -/// -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") -pub fn from_string(x: String) -> BitArray - -/// Returns an integer which is the number of bytes in the bit array. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -pub fn byte_size(x: BitArray) -> Int - -/// Creates a new bit array by joining two bit arrays. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - concat([first, second]) -} - -/// Extracts a sub-section of a bit array. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit array. -/// -/// This function runs in constant time. -/// -@external(erlang, "gleam_stdlib", "bit_array_slice") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) - -/// Tests to see whether a bit array is valid UTF-8. -/// -pub fn is_utf8(bits: BitArray) -> Bool { - do_is_utf8(bits) -} - -@target(erlang) -fn do_is_utf8(bits: BitArray) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:bytes>> -> do_is_utf8(rest) - _ -> False - } -} - -@target(javascript) -fn do_is_utf8(bits: BitArray) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } -} - -/// Converts a bit array to a string. -/// -/// Returns an error if the bit array is invalid UTF-8 data. -/// -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - do_to_string(bits) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "identity") -fn unsafe_to_string(a: BitArray) -> String - -@target(erlang) -fn do_to_string(bits: BitArray) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") -fn do_to_string(a: BitArray) -> Result(String, Nil) - -/// Creates a new bit array by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -@external(erlang, "gleam_stdlib", "bit_array_concat") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") -pub fn concat(bit_arrays: List(BitArray)) -> BitArray - -/// Encodes a BitArray into a base 64 encoded string. -/// -pub fn base64_encode(input: BitArray, padding: Bool) -> String { - let encoded = encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -@external(erlang, "base64", "encode") -@external(javascript, "../gleam_stdlib.mjs", "encode64") -fn encode64(a: BitArray) -> String - -/// Decodes a base 64 encoded string into a `BitArray`. -/// -pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { - let padded = case byte_size(from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - decode64(padded) -} - -@external(erlang, "gleam_stdlib", "base_decode64") -@external(javascript, "../gleam_stdlib.mjs", "decode64") -fn decode64(a: String) -> Result(BitArray, Nil) - -/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { - base64_encode(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. -/// -pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> base64_decode() -} - -@external(erlang, "binary", "encode_hex") -@external(javascript, "../gleam_stdlib.mjs", "base16_encode") -pub fn base16_encode(input: BitArray) -> String - -@external(erlang, "gleam_stdlib", "base16_decode") -@external(javascript, "../gleam_stdlib.mjs", "base16_decode") -pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52ec1b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0930d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 91bd6b76129..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,428 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{type Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} - -/// Runs a callback function if the given bool is `True`, otherwise runs an -/// alternative callback function. -/// -/// Useful when further computation should be delayed regardless of the given -/// bool's value. -/// -/// See [`guard`](#guard) for more info. -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "Kamaka" -/// > let inquiry = fn() { "How may we address you?" } -/// > use <- lazy_guard(when: name == "", return: inquiry) -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -/// ```gleam -/// > import gleam/int -/// > let name = "" -/// > let greeting = fn() { "Hello, " <> name } -/// > use <- lazy_guard(when: name == "", otherwise: greeting) -/// > let number = int.random(1, 99) -/// > let name = "User " <> int.to_string(number) -/// > "Welcome, " <> name -/// "Welcome, User 54" -/// ``` -/// -pub fn lazy_guard( - when requirement: Bool, - return consequence: fn() -> a, - otherwise alternative: fn() -> a, -) -> a { - case requirement { - True -> consequence() - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam deleted file mode 100644 index 20c145d93aa..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam +++ /dev/null @@ -1,197 +0,0 @@ -//// BytesBuilder is a type used for efficiently concatenating bytes together -//// without copying. -//// -//// If we append one bit array to another the bit arrays must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit arrays together. -//// -//// BytesBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit array using the `to_bit_array` function. -//// -//// Byte builders are always byte aligned, so that a number of bits that is not -//// divisible by 8 will be padded with 0s. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -// TODO: pad bit arrays to byte boundaries when adding to a builder. -import gleam/string_builder.{type StringBuilder} -import gleam/list -import gleam/bit_array - -pub opaque type BytesBuilder { - Bytes(BitArray) - Text(StringBuilder) - Many(List(BytesBuilder)) -} - -/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> BytesBuilder { - concat([]) -} - -/// Prepends a bit array to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { - append_builder(from_bit_array(first), second) -} - -/// Appends a bit array to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { - append_builder(first, from_bit_array(second)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to second: BytesBuilder, - prefix first: BytesBuilder, -) -> BytesBuilder { - append_builder(first, second) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "iodata_append") -pub fn append_builder( - to first: BytesBuilder, - suffix second: BytesBuilder, -) -> BytesBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string( - to second: BytesBuilder, - prefix first: String, -) -> BytesBuilder { - append_builder(from_string(first), second) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string( - to first: BytesBuilder, - suffix second: String, -) -> BytesBuilder { - append_builder(first, from_string(second)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { - Many(builders) -} - -/// Joins a list of bit arrays into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { - bits - |> list.map(fn(b) { from_bit_array(b) }) - |> concat() -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string(string: String) -> BytesBuilder { - Text(string_builder.from_string(string)) -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { - Text(builder) -} - -/// Creates a new builder from a bit array. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_bit_array(bits: BitArray) -> BytesBuilder { - Bytes(bits) -} - -/// Turns an builder into a bit array. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -@external(erlang, "erlang", "list_to_bitstring") -pub fn to_bit_array(builder: BytesBuilder) -> BitArray { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_array.concat -} - -fn to_list( - stack: List(List(BytesBuilder)), - acc: List(BitArray), -) -> List(BitArray) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bytes(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_array.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -@external(erlang, "erlang", "iolist_size") -pub fn byte_size(builder: BytesBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam deleted file mode 100644 index 280bf9d1d98..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam +++ /dev/null @@ -1,544 +0,0 @@ -import gleam/option.{type Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a dict, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a dict once. -/// -/// Dicts are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub type Dict(key, value) - -/// Determines the number of key-value pairs in the dict. -/// This function runs in constant time and does not need to iterate the dict. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(dict: Dict(k, v)) -> Int { - do_size(dict) -} - -@external(erlang, "maps", "size") -@external(javascript, "../gleam_stdlib.mjs", "map_size") -fn do_size(a: Dict(k, v)) -> Int - -/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the dict. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { - do_to_list(dict) -} - -@external(erlang, "maps", "to_list") -@external(javascript, "../gleam_stdlib.mjs", "map_to_list") -fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) - -/// Converts a list of 2-element tuples `#(key, value)` to a dict. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the dict. -/// -pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { - do_from_list(list) -} - -@target(erlang) -@external(erlang, "maps", "from_list") -fn do_from_list(a: List(#(key, value))) -> Dict(key, value) - -@target(javascript) -fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Dict(k, v), -) -> Dict(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } -} - -@target(javascript) -fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { - fold_list_of_pair(list, new()) -} - -/// Determines whether or not a value present in the dict for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(dict: Dict(k, v), key: k) -> Bool { - do_has_key(key, dict) -} - -@target(erlang) -@external(erlang, "maps", "is_key") -fn do_has_key(a: key, b: Dict(key, v)) -> Bool - -@target(javascript) -fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { - get(dict, key) != Error(Nil) -} - -/// Creates a fresh dict that contains no values. -/// -pub fn new() -> Dict(key, value) { - do_new() -} - -@external(erlang, "maps", "new") -@external(javascript, "../gleam_stdlib.mjs", "new_map") -fn do_new() -> Dict(key, value) - -/// Fetches a value from a dict for a given key. -/// -/// The dict may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -@external(erlang, "gleam_stdlib", "map_get") -@external(javascript, "../gleam_stdlib.mjs", "map_get") -fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) - -/// Inserts a value into the dict with the given key. -/// -/// If the dict already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { - do_insert(key, value, dict) -} - -@external(erlang, "maps", "put") -@external(javascript, "../gleam_stdlib.mjs", "map_insert") -fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) - -/// Updates all values in a given dict by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { - do_map_values(fun, dict) -} - -@target(erlang) -@external(erlang, "maps", "map") -fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) - -@target(javascript) -fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { - let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } - dict - |> fold(from: new(), with: f) -} - -/// Gets a list of all keys in a given dict. -/// -/// Dicts are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(dict: Dict(keys, v)) -> List(keys) { - do_keys(dict) -} - -@target(erlang) -@external(erlang, "maps", "keys") -fn do_keys(a: Dict(keys, v)) -> List(keys) - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(dict: Dict(k, v)) -> List(k) { - let list_of_pairs = to_list(dict) - do_keys_acc(list_of_pairs, []) -} - -/// Gets a list of all values in a given dict. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(dict: Dict(k, values)) -> List(values) { - do_values(dict) -} - -@target(erlang) -@external(erlang, "maps", "values") -fn do_values(a: Dict(k, values)) -> List(values) - -@target(javascript) -fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } -} - -@target(javascript) -fn do_values(dict: Dict(k, v)) -> List(v) { - let list_of_pairs = to_list(dict) - do_values_acc(list_of_pairs, []) -} - -/// Creates a new dict from a given dict, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter( - in dict: Dict(k, v), - keeping predicate: fn(k, v) -> Bool, -) -> Dict(k, v) { - do_filter(predicate, dict) -} - -@target(erlang) -@external(erlang, "maps", "filter") -fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) - -@target(javascript) -fn do_filter( - f: fn(key, value) -> Bool, - dict: Dict(key, value), -) -> Dict(key, value) { - let insert = fn(dict, k, v) { - case f(k, v) { - True -> insert(dict, k, v) - _ -> dict - } - } - dict - |> fold(from: new(), with: insert) -} - -/// Creates a new dict from a given dict, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { - do_take(desired_keys, dict) -} - -@target(erlang) -@external(erlang, "maps", "with") -fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_taken( - dict: Dict(k, v), - desired_keys: List(k), - acc: Dict(k, v), -) -> Dict(k, v) { - let insert = fn(taken, key) { - case get(dict, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) - } -} - -@target(javascript) -fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { - insert_taken(dict, desired_keys, new()) -} - -/// Creates a new dict from a pair of given dicts by combining their entries. -/// -/// If there are entries with the same keys in both dicts the entry from the -/// second dict takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { - do_merge(dict, new_entries) -} - -@target(erlang) -@external(erlang, "maps", "merge") -fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { - insert(dict, pair.0, pair.1) -} - -@target(javascript) -fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { - case new_entries { - [] -> dict - [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) - } -} - -@target(javascript) -fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { - new_entries - |> to_list - |> fold_inserts(dict) -} - -/// Creates a new dict from a given dict with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { - do_delete(key, dict) -} - -@external(erlang, "maps", "remove") -@external(javascript, "../gleam_stdlib.mjs", "map_remove") -fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) - -/// Creates a new dict from a given dict with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { - case disallowed_keys { - [] -> dict - [x, ..xs] -> drop(delete(dict, x), xs) - } -} - -/// Creates a new dict with one entry updated using a given function. -/// -/// If there was not an entry in the dict for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let dict = from_list([#("a", 0)]) -/// > -/// > update(dict, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(dict, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in dict: Dict(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Dict(k, v) { - dict - |> get(key) - |> option.from_result - |> fun - |> insert(dict, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over dict: Dict(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - dict - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index c71c6f342ad..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1508 +0,0 @@ -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option} -import gleam/result -import gleam/string_builder -@target(erlang) -import gleam/bit_array - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from(a: anything) -> Dynamic - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_unsafe_coerce(a: Dynamic) -> a - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit -/// array if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_array(from("Hello")) == bit_array.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_array(from(123)) -/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - decode_bit_array(data) -} - -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - -@external(erlang, "gleam_stdlib", "decode_bit_array") -@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") -fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -@target(erlang) -fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_array(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_array.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitArray", path: [])]) - } - }) -} - -@target(erlang) -fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "decode_string") -fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -@external(erlang, "gleam_stdlib", "classify_dynamic") -@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") -fn do_classify(a: Dynamic) -> String - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -@external(erlang, "gleam_stdlib", "decode_int") -@external(javascript, "../gleam_stdlib.mjs", "decode_int") -fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -@external(erlang, "gleam_stdlib", "decode_float") -@external(javascript, "../gleam_stdlib.mjs", "decode_float") -fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -@external(erlang, "gleam_stdlib", "decode_bool") -@external(javascript, "../gleam_stdlib.mjs", "decode_bool") -fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -@external(erlang, "gleam_stdlib", "decode_list") -@external(javascript, "../gleam_stdlib.mjs", "decode_list") -fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_result") -@external(javascript, "../gleam_stdlib.mjs", "decode_result") -fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -@external(erlang, "gleam_stdlib", "decode_option") -@external(javascript, "../gleam_stdlib.mjs", "decode_option") -fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -@external(erlang, "gleam_stdlib", "decode_field") -@external(javascript, "../gleam_stdlib.mjs", "decode_field") -fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -type UnknownTuple - -@external(erlang, "gleam_stdlib", "decode_tuple") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") -fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple2") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") -fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple3") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") -fn decode_tuple3( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple4") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") -fn decode_tuple4( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple5") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") -fn decode_tuple5( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple6") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") -fn decode_tuple6( - a: Dynamic, -) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, -) - -@external(erlang, "gleam_stdlib", "tuple_get") -@external(javascript, "../gleam_stdlib.mjs", "tuple_get") -fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) - -@external(erlang, "gleam_stdlib", "size_of_tuple") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn tuple_size(a: UnknownTuple) -> Int - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a dict. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() |> from |> map(string, int) -/// Ok(dict.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn dict( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> dict.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(dict.from_list(pairs)) - } -} - -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - -@external(erlang, "gleam_stdlib", "decode_map") -@external(javascript, "../gleam_stdlib.mjs", "decode_map") -fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.concat([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 5d62419fd0d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,546 +0,0 @@ -//// Functions for working with floats. -//// -//// ## Division by zero -//// -//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE -//// 754 standard for floating point arithmetic and does not have an `Infinity` -//// value. In Erlang division by zero results in a crash, however Gleam does -//// not have partial functions and operators in core so instead division by zero -//// returns zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/order.{type Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_float") -@external(javascript, "../gleam_stdlib.mjs", "parse_float") -fn do_parse(a: String) -> Result(Float, Nil) - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -@external(erlang, "gleam_stdlib", "float_to_string") -@external(javascript, "../gleam_stdlib.mjs", "float_to_string") -fn do_to_string(a: Float) -> String - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -@external(erlang, "math", "ceil") -@external(javascript, "../gleam_stdlib.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -@external(erlang, "math", "floor") -@external(javascript, "../gleam_stdlib.mjs", "floor") -fn do_floor(a: Float) -> Float - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -@target(erlang) -@external(erlang, "erlang", "round") -fn do_round(a: Float) -> Int - -@target(javascript) -fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "round") -fn js_round(a: Float) -> Int - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../gleam_stdlib.mjs", "truncate") -fn do_truncate(a: Float) -> Int - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../gleam_stdlib.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Generates a random float between the given minimum and maximum values. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(min: Float, max: Float) -> Float { - do_random_uniform() *. { max -. min } +. min -} - -/// Returns a random float uniformly distributed in the value range -/// 0.0 =< X < 1.0 and updates the state in the process dictionary. -/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> -/// -@external(erlang, "rand", "uniform") -@external(javascript, "../gleam_stdlib.mjs", "random_uniform") -fn do_random_uniform() -> Float - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index d93c16afaf6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,874 +0,0 @@ -//// Functions for working with integers. -//// -//// ## Division by zero -//// -//// In Erlang division by zero results in a crash, however Gleam does not have -//// partial functions and operators in core so instead division by zero returns -//// zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/float -import gleam/order.{type Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_int") -@external(javascript, "../gleam_stdlib.mjs", "parse_int") -fn do_parse(a: String) -> Result(Int, Nil) - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -@external(erlang, "gleam_stdlib", "int_from_base_string") -@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") -fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "to_string") -fn do_to_string(a: Int) -> String - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") -fn do_to_base_string(a: Int, b: Int) -> String - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -@external(erlang, "erlang", "float") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_float(a: Int) -> Float - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Generates a random int between the given minimum and maximum values. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(min: Int, max: Int) -> Int { - float.random(to_float(min), to_float(max)) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} - -/// Calculates the bitwise AND of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "band") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") -pub fn bitwise_and(x: Int, y: Int) -> Int - -/// Calculates the bitwise NOT of its argument. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bnot") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") -pub fn bitwise_not(x: Int) -> Int - -/// Calculates the bitwise OR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") -pub fn bitwise_or(x: Int, y: Int) -> Int - -/// Calculates the bitwise XOR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bxor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") -pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic left bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsl") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") -pub fn bitwise_shift_left(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic right bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsr") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") -pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index 0c0a3eeffe0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,117 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -@external(erlang, "gleam_stdlib", "print") -@external(javascript, "../gleam_stdlib.mjs", "print") -fn do_print(string string: String) -> Nil - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -@external(erlang, "gleam_stdlib", "print_error") -@external(javascript, "../gleam_stdlib.mjs", "print_error") -fn do_print_error(string string: String) -> Nil - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -@external(erlang, "gleam_stdlib", "println") -@external(javascript, "../gleam_stdlib.mjs", "console_log") -fn do_println(string string: String) -> Nil - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "console_error") -fn do_println_error(string string: String) -> Nil - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "print_debug") -fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index c57e7fd9473..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1530 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option, None, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_map2( - continuation1: fn() -> Action(a), - continuation2: fn() -> Action(b), - with fun: fn(a, b) -> c, -) -> fn() -> Action(c) { - fn() { - case continuation1() { - Stop -> Stop - Continue(a, next_a) -> - case continuation2() { - Stop -> Stop - Continue(b, next_b) -> - Continue(fun(a, b), do_map2(next_a, next_b, fun)) - } - } - } -} - -/// Combines two interators into a single one using the given function. -/// -/// If an iterator is longer than the other the extra elements are dropped. -/// -/// This function does not evaluate the elements of the two iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// let first = from_list([1, 2, 3]) -/// let second = from_list([4, 5, 6]) -/// map2(first, second, fn(x, y) { x + y }) |> to_list -/// // -> [5, 7, 9] -/// ``` -/// -/// ```gleam -/// let first = from_list([1, 2]) -/// let second = from_list(["a", "b", "c"]) -/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list -/// // -> [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2( - iterator1: Iterator(a), - iterator2: Iterator(b), - with fun: fn(a, b) -> c, -) -> Iterator(c) { - do_map2(iterator1.continuation, iterator2.continuation, fun) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Joins a list of iterators into a single iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [[1, 2], [3, 4]] -/// > |> map(from_list) -/// > |> concat -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { - flatten(from_list(iterators)) -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - keeping predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - groups - |> dict.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Dict(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Dict(key, List(element)) { - iterator - |> fold(dict.new(), group_updater(key)) - |> dict.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} - -/// Add a new element to the start of an iterator. -/// -/// This function is for use with `use` expressions, to replicate the behaviour -/// of the `yield` keyword found in other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > use <- iterator.yield(1) -/// > use <- iterator.yield(2) -/// > use <- iterator.yield(3) -/// > iterator.empty() -/// iterator.from_list([1, 2, 3]) -/// ``` -/// -pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { - Iterator(fn() { Continue(element, next().continuation) }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index a5cffa9b951..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2154 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{type Order} -import gleam/pair -import gleam/dict.{type Dict} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -@target(erlang) -@external(erlang, "erlang", "length") -fn do_length(a: List(a)) -> Int - -@target(javascript) -fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) -} - -@target(javascript) -fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -@target(erlang) -@external(erlang, "lists", "reverse") -fn do_reverse(a: List(a)) -> List(a) - -@target(javascript) -fn do_reverse(list) { - do_reverse_acc(list, []) -} - -@target(javascript) -fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - case dict.get(groups, f(elem)) { - Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> dict.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> dict.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) -/// |> dict.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { - fold(list, dict.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Combines two lists into a single list using the given function. -/// -/// If a list is longer than the other the extra elements are dropped. -/// -/// ## Examples -/// -/// ```gleam -/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) -/// [5, 7, 9] -/// ``` -/// -/// ```gleam -/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) -/// [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { - do_map2(list1, list2, fun, []) -} - -fn do_map2( - list1: List(a), - list2: List(b), - fun: fn(a, b) -> c, - acc: List(c), -) -> List(c) { - case list1, list2 { - [], _ | _, [] -> reverse(acc) - [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) - } -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -@target(erlang) -@external(erlang, "lists", "append") -fn do_append(a: List(a), b: List(a)) -> List(a) - -@target(javascript) -fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) -} - -@target(javascript) -fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Joins a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn concat(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// This is the same as `concat`: it joins a list of lists into a single -/// list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// Maps the list with the given function into a list of lists, and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> concat -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> [stop, ..acc] - order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) - order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, finds all tuples that have a given -/// key as the first element and returns the second element. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") -/// [0, 2] -/// ``` -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1)], "c") -/// [] -/// ``` -/// -pub fn key_filter( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> List(v) { - filter_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> concat - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> concat -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> concat -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> concat - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [elem_pair, ..enumerable] -> - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calculate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 1f8b228eb90..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,127 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(map) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@target(javascript) -fn do_filter(f: fn(key, value) -> Bool, map) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 12ce01136ca..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,133 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > negate(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -pub fn negate(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} - -/// Inverts an ordering function, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > list.sort([1, 5, 4], by: reverse(int.compare)) -/// [5, 4, 1] -/// ``` -/// -pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { - fn(a, b) { orderer(b, a) } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index 9ffda789f6a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,214 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{type Option} - -pub type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -@external(erlang, "gleam_stdlib", "compile_regex") -@external(javascript, "../gleam_stdlib.mjs", "compile_regex") -fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -@external(erlang, "gleam_stdlib", "regex_check") -@external(javascript, "../gleam_stdlib.mjs", "regex_check") -fn do_check(a: Regex, b: String) -> Bool - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "regex_split") -fn do_split(a: Regex, b: String) -> List(String) - -@target(javascript) -fn do_split(regex, string) -> List(String) { - js_split(string, regex) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn js_split(a: String, b: Regex) -> List(String) - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -@external(erlang, "gleam_stdlib", "regex_scan") -@external(javascript, "../gleam_stdlib.mjs", "regex_scan") -fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index fb6dddb3110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,482 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// "Updates" an `Ok` result by passing its value to a function that yields a result, -/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) -/// -/// If the input is an `Error` rather than an `Ok`, the function is not called and -/// the original `Error` is returned. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), Error("a"), Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index df8d500e804..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/dict.{type Dict} -import gleam/result - -// A list is used as the map value as an empty list has the smallest -// representation in Erlang's binary format -@target(erlang) -type Token = - List(Nil) - -@target(erlang) -const token = [] - -@target(javascript) -type Token = - Nil - -@target(javascript) -const token = Nil - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Dict(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(dict.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - dict.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: dict.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> dict.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: dict.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - dict.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: dict.new(), - with: fn(m, k) { dict.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - keeping predicate: fn(member) -> Bool, -) -> Set(member) { - Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(dict.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case dict.size(first.map) > dict.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index 7254fd9fd1c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,913 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{type Iterator} -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/order -import gleam/string_builder.{type StringBuilder} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -@external(erlang, "string", "length") -@external(javascript, "../gleam_stdlib.mjs", "string_length") -fn do_length(a: String) -> Int - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -@target(erlang) -fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string -} - -@target(javascript) -fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: String) -> String - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: String) -> String - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -@external(erlang, "gleam_stdlib", "less_than") -@external(javascript, "../gleam_stdlib.mjs", "less_than") -fn less_than(a: String, b: String) -> Bool - -/// Takes a substring given a start grapheme index and a length. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -@target(erlang) -@external(erlang, "string", "slice") -fn do_slice(a: String, b: Int, c: Int) -> String - -@target(javascript) -fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -@external(erlang, "gleam_stdlib", "crop_string") -@external(javascript, "../gleam_stdlib.mjs", "crop_string") -pub fn crop(from string: String, before substring: String) -> String - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -@external(erlang, "gleam_stdlib", "contains_string") -@external(javascript, "../gleam_stdlib.mjs", "contains_string") -pub fn contains(does haystack: String, contain needle: String) -> Bool - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -@external(erlang, "gleam_stdlib", "string_starts_with") -@external(javascript, "../gleam_stdlib.mjs", "starts_with") -fn do_starts_with(a: String, b: String) -> Bool - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -@external(erlang, "gleam_stdlib", "string_ends_with") -@external(javascript, "../gleam_stdlib.mjs", "ends_with") -fn do_ends_with(a: String, b: String) -> Bool - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: String, b: String) -> List(String) - -@target(erlang) -fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split_once") -fn do_split_once( - x x: String, - substring substring: String, -) -> Result(#(String, String), Nil) - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - do_join(strings, separator) -} - -@target(erlang) -fn do_join(strings: List(String), separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "join") -fn do_join(strings strings: List(String), string string: String) -> String - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -@target(erlang) -fn do_trim(string: String) -> String { - erl_trim(string, Both) -} - -@target(erlang) -type Direction { - Leading - Trailing - Both -} - -@target(erlang) -@external(erlang, "string", "trim") -fn erl_trim(a: String, b: Direction) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim") -fn do_trim(string string: String) -> String - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -@target(erlang) -fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_left") -fn do_trim_left(string string: String) -> String - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -@target(erlang) -fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_right") -fn do_trim_right(string string: String) -> String - -/// Splits a non-empty `String` into its first element (head) and rest (tail). -/// This lets you pattern match on `String`s exactly as you would with lists. -/// -/// Note on JavaScript using the function to iterate over a string will likely -/// be slower than using `to_graphemes` due to string slicing being more -/// expensive on JavaScript than Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -@external(erlang, "gleam_stdlib", "string_pop_grapheme") -@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") -fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "codepoint") -fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -@target(erlang) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(<<string:utf8>>, []) - |> list.reverse -} - -@target(erlang) -fn do_to_utf_codepoints_impl( - bit_array: BitArray, - acc: List(UtfCodepoint), -) -> List(UtfCodepoint) { - case bit_array { - <<first:utf8_codepoint, rest:bytes>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - _ -> acc - } -} - -@target(javascript) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") -fn string_to_codepoint_integer_list(a: String) -> List(Int) - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") -/// > utf_codepoint_to_int(utf_codepoint) -/// 128156 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") -fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -@external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam_stdlib.mjs", "inspect") -fn do_inspect(term term: anything) -> StringBuilder - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -/// ## Examples -/// -/// ```gleam -/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") -/// 58 -/// ``` -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "byte_size") -pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 5792ca8699d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,298 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -@external(erlang, "gleam_stdlib", "iodata_append") -@external(javascript, "../gleam_stdlib.mjs", "add") -fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_from_strings(a: List(String)) -> StringBuilder - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_concat(a: List(StringBuilder)) -> StringBuilder - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from_string(a: String) -> StringBuilder - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -@external(erlang, "unicode", "characters_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_string(a: StringBuilder) -> String - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -@external(erlang, "erlang", "iolist_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn do_byte_size(a: StringBuilder) -> Int - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -@target(erlang) -@external(erlang, "string", "reverse") -fn do_reverse(a: StringBuilder) -> StringBuilder - -@target(javascript) -fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -fn do_to_graphemes(string string: String) -> List(String) - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -@target(erlang) -type Direction { - All -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) - -@target(erlang) -fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn do_split( - builder builder: StringBuilder, - pattern pattern: String, -) -> List(StringBuilder) - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -@target(erlang) -fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, -) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) -} - -@target(erlang) -@external(erlang, "string", "replace") -fn erl_replace( - a: StringBuilder, - b: String, - c: String, - d: Direction, -) -> StringBuilder - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_replace") -fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -@external(erlang, "string", "equal") -@external(javascript, "../gleam_stdlib.mjs", "equal") -fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -@target(erlang) -@external(erlang, "string", "is_empty") -fn do_is_empty(a: StringBuilder) -> Bool - -@target(javascript) -fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 11f6ea68cd2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,462 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/string -import gleam/string_builder.{type StringBuilder} -@target(javascript) -import gleam/pair -@target(javascript) -import gleam/regex -@target(javascript) -import gleam/result - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "uri_parse") -fn do_parse(a: String) -> Result(Uri, Nil) - -@target(javascript) -fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) -} - -@target(javascript) -fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) -} - -@target(javascript) -fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } -} - -@target(javascript) -fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } -} - -// Split an authority into its userinfo, host and port parts. -@target(javascript) -fn split_authority( - authority: Option(String), -) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } -} - -@target(javascript) -fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) -} - -@target(javascript) -fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -@external(erlang, "gleam_stdlib", "parse_query") -@external(javascript, "../gleam_stdlib.mjs", "parse_query") -fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -@external(erlang, "gleam_stdlib", "percent_encode") -@external(javascript, "../gleam_stdlib.mjs", "percent_encode") -fn do_percent_encode(a: String) -> String - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -@external(erlang, "gleam_stdlib", "percent_decode") -@external(javascript, "../gleam_stdlib.mjs", "percent_decode") -fn do_percent_decode(a: String) -> Result(String, Nil) - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - _, _, _ -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - _ -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65bc3f63e4d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - gleam@bit_array:base64_encode(Input, Padding). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - gleam@bit_array:base64_decode(Encoded). - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - gleam@bit_array:base64_url_encode(Input, Padding). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl deleted file mode 100644 index ba18dfaabdd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(gleam@bit_array). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_arrays) -> - gleam_stdlib:bit_array_concat(Bit_arrays). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam_stdlib:bit_array_concat([First, Second]). - --spec base64_encode(bitstring(), boolean()) -> binary(). -base64_encode(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_decode(Encoded) -> - Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec base64_url_encode(bitstring(), boolean()) -> binary(). -base64_url_encode(Input, Padding) -> - _pipe = base64_encode(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_url_decode(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - base64_decode(_pipe@2). - --spec base16_encode(bitstring()) -> binary(). -base16_encode(Input) -> - binary:encode_hex(Input). - --spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base16_decode(Input) -> - gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 284c6d46cc3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,66 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). - --spec new() -> gleam@bytes_builder:bytes_builder(). -new() -> - gleam@bytes_builder:new(). - --spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -prepend(To, Prefix) -> - gleam@bytes_builder:prepend(To, Prefix). - --spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -append(To, Suffix) -> - gleam@bytes_builder:append(To, Suffix). - --spec prepend_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -prepend_builder(To, Prefix) -> - gleam@bytes_builder:prepend_builder(To, Prefix). - --spec append_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -prepend_string(To, Prefix) -> - gleam@bytes_builder:prepend_string(To, Prefix). - --spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -append_string(To, Suffix) -> - gleam@bytes_builder:append_string(To, Suffix). - --spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 7dabaa3bbc1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam@bit_array:append(First, Second). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - gleam@bit_array:is_utf8(Bits). - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - gleam@bit_array:to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 5f95f4d8314..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,162 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. - --spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. -lazy_guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence(); - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl deleted file mode 100644 index 2f6dd93a9f3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl +++ /dev/null @@ -1,87 +0,0 @@ --module(gleam@bytes_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). --export_type([bytes_builder/0]). - --opaque bytes_builder() :: {bytes, bitstring()} | - {text, gleam@string_builder:string_builder()} | - {many, list(bytes_builder())}. - --spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -prepend_builder(Second, First) -> - gleam_stdlib:iodata_append(First, Second). - --spec concat(list(bytes_builder())) -> bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec new() -> bytes_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_string(binary()) -> bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). -prepend_string(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append_string(bytes_builder(), binary()) -> bytes_builder(). -append_string(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_array(bitstring()) -> bytes_builder(). -from_bit_array(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). -prepend(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append(bytes_builder(), bitstring()) -> bytes_builder(). -append(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). -concat_bit_arrays(Bits) -> - gleam_stdlib:identity(Bits). - --spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). -to_list(Stack, Acc) -> - case Stack of - [] -> - Acc; - - [[] | Remaining_stack] -> - to_list(Remaining_stack, Acc); - - [[{bytes, Bits} | Rest] | Remaining_stack@1] -> - to_list([Rest | Remaining_stack@1], [Bits | Acc]); - - [[{text, Builder} | Rest@1] | Remaining_stack@2] -> - Bits@1 = gleam_stdlib:identity( - gleam@string_builder:to_string(Builder) - ), - to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); - - [[{many, Builders} | Rest@2] | Remaining_stack@3] -> - to_list([Builders, Rest@2 | Remaining_stack@3], Acc) - end. - --spec to_bit_array(bytes_builder()) -> bitstring(). -to_bit_array(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl deleted file mode 100644 index 99c231e18cc..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@dict). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). --export_type([dict/2]). - --type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. - --spec size(dict(any(), any())) -> integer(). -size(Dict) -> - maps:size(Dict). - --spec to_list(dict(NZ, OA)) -> list({NZ, OA}). -to_list(Dict) -> - maps:to_list(Dict). - --spec from_list(list({OJ, OK})) -> dict(OJ, OK). -from_list(List) -> - maps:from_list(List). - --spec has_key(dict(OT, any()), OT) -> boolean(). -has_key(Dict, Key) -> - maps:is_key(Key, Dict). - --spec new() -> dict(any(), any()). -new() -> - maps:new(). - --spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). -insert(Dict, Key, Value) -> - maps:put(Key, Value, Dict). - --spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). -map_values(Dict, Fun) -> - maps:map(Fun, Dict). - --spec keys(dict(QV, any())) -> list(QV). -keys(Dict) -> - maps:keys(Dict). - --spec values(dict(any(), RG)) -> list(RG). -values(Dict) -> - maps:values(Dict). - --spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). -filter(Dict, Predicate) -> - maps:filter(Predicate, Dict). - --spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). -take(Dict, Desired_keys) -> - maps:with(Desired_keys, Dict). - --spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). -merge(Dict, New_entries) -> - maps:merge(Dict, New_entries). - --spec delete(dict(TF, TG), TF) -> dict(TF, TG). -delete(Dict, Key) -> - maps:remove(Key, Dict). - --spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). -drop(Dict, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Dict; - - [X | Xs] -> - drop(delete(Dict, X), Xs) - end. - --spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). -update(Dict, Key, Fun) -> - _pipe = Dict, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Dict, Key, _pipe@3). - --spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. -fold(Dict, Initial, Fun) -> - _pipe = Dict, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 2c6016f4222..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,808 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). - --type dynamic_() :: any(). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type unknown_tuple() :: any(). - --spec from(any()) -> dynamic_(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic_()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_array(Data) -> - gleam_stdlib:decode_bit_array(Data). - --spec bit_string(dynamic_()) -> {ok, bitstring()} | - {error, list(decode_error())}. -bit_string(Data) -> - bit_array(Data). - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec classify(dynamic_()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - gleam@option:option(DGM)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, - DKT} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((DKX) -> DKY), - fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec result( - fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - list(DGH)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec map_errors( - {ok, DEV} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, DEV} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec decode_string(dynamic_()) -> {ok, binary()} | - {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_array(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_array:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitArray"/utf8>>, - []}]} - end end - ). - --spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec field( - any(), - fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec dict( - fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | - {error, list(decode_error())}). -dict(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@dict:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end - ) - end - ) - end. - --spec map( - fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - dict(Key_type, Value_type). - --spec decode2( - fun((DLB, DLC) -> DLD), - fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((DLH, DLI, DLJ) -> DLK), - fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((DLP, DLQ, DLR, DLS) -> DLT), - fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((DLZ, DMA, DMB, DMC, DMD) -> DME), - fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), - fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), - fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), - fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), - fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index 33b3d4a3e3f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,181 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= +0.0 of - true -> - X; - - _ -> - +0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > +0.0, - case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent - < +0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, +0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. - --spec random(float(), float()) -> float(). -random(Min, Max) -> - (rand:uniform() * (Max - Min)) + Min. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - +0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - +0.0 -> +0.0; - -0.0 -> -0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index c58c0fe151b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(AS) -> AS. -identity(X) -> - X. - --spec constant(AT) -> fun((any()) -> AT). -constant(Value) -> - fun(_) -> Value end. - --spec tap(AV, fun((AV) -> any())) -> AV. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((AX) -> AY), AX) -> AY. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 2a5dd2c8a1d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,332 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. - --spec random(integer(), integer()) -> integer(). -random(Min, Max) -> - _pipe = gleam@float:random(to_float(Min), to_float(Max)), - _pipe@1 = gleam@float:floor(_pipe), - gleam@float:round(_pipe@1). - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec bitwise_and(integer(), integer()) -> integer(). -bitwise_and(X, Y) -> - erlang:'band'(X, Y). - --spec bitwise_not(integer()) -> integer(). -bitwise_not(X) -> - erlang:'bnot'(X). - --spec bitwise_or(integer(), integer()) -> integer(). -bitwise_or(X, Y) -> - erlang:'bor'(X, Y). - --spec bitwise_exclusive_or(integer(), integer()) -> integer(). -bitwise_exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec bitwise_shift_left(integer(), integer()) -> integer(). -bitwise_shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec bitwise_shift_right(integer(), integer()) -> integer(). -bitwise_shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 82865bbafa6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ENH) -> ENH. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index a667ae1ac4b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,744 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. - --opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. - --type step(BSE, BSF) :: {next, BSE, BSF} | done. - --type chunk(BSG, BSH) :: {another_by, - list(BSG), - BSH, - BSG, - fun(() -> action(BSG))} | - {last_by, list(BSG)}. - --type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | - {last, list(BSI)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BSV)) -> iterator(BSV). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BSX) -> iterator(BSX). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BSZ)) -> iterator(BSZ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec do_transform( - fun(() -> action(BTC)), - BTE, - fun((BTE, BTC) -> step(BTF, BTE)) -) -> fun(() -> action(BTF)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BTY)) -> list(BTY). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BUJ), integer()) -> iterator(BUJ). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BUP), integer()) -> iterator(BUP). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec do_map2( - fun(() -> action(BVA)), - fun(() -> action(BVC)), - fun((BVA, BVC) -> BVE) -) -> fun(() -> action(BVE)). -do_map2(Continuation1, Continuation2, Fun) -> - fun() -> case Continuation1() of - stop -> - stop; - - {continue, A, Next_a} -> - case Continuation2() of - stop -> - stop; - - {continue, B, Next_b} -> - {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} - end - end end. - --spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). -map2(Iterator1, Iterator2, Fun) -> - _pipe = do_map2( - erlang:element(2, Iterator1), - erlang:element(2, Iterator2), - Fun - ), - {iterator, _pipe}. - --spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BVY))) -> iterator(BVY). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec concat(list(iterator(BWC))) -> iterator(BWC). -concat(Iterators) -> - flatten(from_list(Iterators)). - --spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec cycle(iterator(BWR)) -> iterator(BWR). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), - BXD})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BXG)) -> iterator({integer(), BXG}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, - BYH})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BZU), BZU) -> iterator(BZU). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), - gleam@dict:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> CBH)) -> iterator(CBH). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec single(CBJ) -> iterator(CBJ). -single(Elem) -> - once(fun() -> Elem end). - --spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(CBT)), - fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), - CBV -) -> CBV. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(CBX), - CBZ, - fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) -) -> CBZ. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(CCB)), - fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), - CCD -) -> {ok, CCD} | {error, CCE}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, - CCL} | - {error, CCM}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). - --spec each(iterator(CDD), fun((CDD) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). -yield(Element, Next) -> - {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index cb6c9e44af2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1136 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(XF)) -> list(XF). -reverse(Xs) -> - lists:reverse(Xs). - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec contains(list(XN), XN) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec first(list(XP)) -> {ok, XP} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@dict:insert(Groups, F(Elem), [Elem]) - end end. - --spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). -map(List, Fun) -> - do_map(List, Fun, []). - --spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). -do_map2(List1, List2, Fun, Acc) -> - case {List1, List2} of - {[], _} -> - reverse(Acc); - - {_, []} -> - reverse(Acc); - - {[A | As_], [B | Bs]} -> - do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) - end. - --spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). -map2(List1, List2, Fun) -> - do_map2(List1, List2, Fun, []). - --spec do_index_map( - list(ABJ), - fun((integer(), ABJ) -> ABL), - integer(), - list(ABL) -) -> list(ABL). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, - list(ABU)} | - {error, ABV}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, - list(ACE)} | - {error, ACF}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(ACL), integer()) -> list(ACL). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(ACS), integer()) -> list(ACS). -take(List, N) -> - do_take(List, N, []). - --spec new() -> list(any()). -new() -> - []. - --spec append(list(ACX), list(ACX)) -> list(ACX). -append(First, Second) -> - lists:append(First, Second). - --spec prepend(list(ADF), ADF) -> list(ADF). -prepend(List, Item) -> - [Item | List]. - --spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). -do_concat(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_concat(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec concat(list(list(ADR))) -> list(ADR). -concat(Lists) -> - do_concat(Lists, []). - --spec flatten(list(list(ADV))) -> list(ADV). -flatten(Lists) -> - do_concat(Lists, []). - --spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - concat(_pipe). - --spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). -group(List, Key) -> - fold(List, gleam@dict:new(), update_group(Key)). - --spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, - list(ABH)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold( - list(AEK), - AEM, - fun((AEM, AEK, integer()) -> AEM), - integer() -) -> AEM. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, - AES} | - {error, AET}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(AGX), AGX) -> list(AGX). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec unique(list(AHE)) -> list(AHE). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(AHH), - list(AHH), - list(AHH), - fun((AHH, AHH) -> gleam@order:order()) -) -> list(AHH). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_down( - integer(), - integer(), - list(AHM), - list(AHM), - list(AHM), - fun((AHM, AHM) -> gleam@order:order()) -) -> list(AHM). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_sort( - list(AHR), - integer(), - fun((AHR, AHR) -> gleam@order:order()), - boolean() -) -> list(AHR). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - [Stop | Acc]; - - gt -> - tail_recursive_range(Start, Stop + 1, [Stop | Acc]); - - lt -> - tail_recursive_range(Start, Stop - 1, [Stop | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(AID, integer()) -> list(AID). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), - list(AIO)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). -key_filter(Keyword_list, Desired_key) -> - filter_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, - {AZQ, list(AZQ)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, - {BAR, list(BAE)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, - {AJV, list(AJT)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AKM), fun((AKM) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | - {error, AKS}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), - list(BBY)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(ALG)) -> list(list(ALG)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - concat(_pipe@5) - end. - --spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(ALQ), integer()) -> list(list(ALQ)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec window_by_2(list(ALU)) -> list({ALU, ALU}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AMU), - integer(), - integer(), - list(AMU), - list(list(AMU)) -) -> list(list(AMU)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec last(list(ANS)) -> {ok, ANS} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec combinations(list(ANW), integer()) -> list(list(ANW)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AOE)) -> list({AOE, AOE}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - concat(_pipe). - --spec transpose(list(list(AOL))) -> list(list(AOL)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - concat(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AOH))) -> list(AOH). -interleave(List) -> - _pipe = transpose(List), - concat(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - [Elem_pair | Enumerable] -> - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec shuffle(list(AOX)) -> list(AOX). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index 9f45b107384..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). - --spec size(gleam@dict:dict(any(), any())) -> integer(). -size(Map) -> - gleam@dict:size(Map). - --spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). -to_list(Map) -> - gleam@dict:to_list(Map). - --spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). -from_list(List) -> - gleam@dict:from_list(List). - --spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). -has_key(Map, Key) -> - gleam@dict:has_key(Map, Key). - --spec new() -> gleam@dict:dict(any(), any()). -new() -> - gleam@dict:new(). - --spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. -get(From, Get) -> - gleam@dict:get(From, Get). - --spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). -insert(Map, Key, Value) -> - gleam@dict:insert(Map, Key, Value). - --spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). -map_values(Map, Fun) -> - gleam@dict:map_values(Map, Fun). - --spec keys(gleam@dict:dict(FED, any())) -> list(FED). -keys(Map) -> - gleam@dict:keys(Map). - --spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). -values(Map) -> - gleam@dict:values(Map). - --spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). -filter(Map, Predicate) -> - gleam@dict:filter(Map, Predicate). - --spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). -take(Map, Desired_keys) -> - gleam@dict:take(Map, Desired_keys). - --spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). -merge(Map, New_entries) -> - gleam@dict:merge(Map, New_entries). - --spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). -delete(Map, Key) -> - gleam@dict:delete(Map, Key). - --spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). -drop(Map, Disallowed_keys) -> - gleam@dict:drop(Map, Disallowed_keys). - --spec update( - gleam@dict:dict(FFB, FFC), - FFB, - fun((gleam@option:option(FFC)) -> FFC) -) -> gleam@dict:dict(FFB, FFC). -update(Map, Key, Fun) -> - gleam@dict:update(Map, Key, Fun). - --spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. -fold(Map, Initial, Fun) -> - gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 812aa1fe854..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). --export_type([option/1]). - --type option(IY) :: {some, IY} | none. - --spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(JF))) -> option(list(JF)). -all(List) -> - do_all(List, []). - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, JU} | {error, any()}) -> option(JU). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(JZ), JZ) -> JZ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(KD), fun((KD) -> KF)) -> option(KF). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(KH))) -> option(KH). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(KQ), option(KQ)) -> option(KQ). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_values(list(option(KY)), list(KY)) -> list(KY). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(LD))) -> list(LD). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index a9eed8f39c1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec negate(order()) -> order(). -negate(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. - --spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). -reverse(Orderer) -> - fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2452a9817e1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({IJ, any()}) -> IJ. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), IM}) -> IM. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({IN, IO}) -> {IO, IN}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(IV, IW) -> {IV, IW}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index faec6923a14..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(EYN)) -> queue(EYN). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(EYQ)) -> list(EYQ). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EYX), EYX) -> queue(EYX). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EZA), EZA) -> queue(EZA). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec reverse(queue(EZN)) -> queue(EZN). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec check_equal( - list(EZQ), - list(EZQ), - list(EZQ), - list(EZQ), - fun((EZQ, EZQ) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EZY), queue(EZY)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index 2d1c5fc870e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([regex/0, match/0, compile_error/0, options/0]). - --type regex() :: any(). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index c80a7048303..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | - {error, BIK}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | - {error, BIU}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | - {error, BIY}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, - BJJ} | - {error, BJG}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, - BJS} | - {error, BJP}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | - {error, BKT}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, - BLA} | - {error, BLB}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), - list(BLY)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. -partition(Results) -> - do_partition(Results, [], []). - --spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BMT} | {error, any()})) -> list(BMT). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BMZ} | {error, BNA}, - fun((BNA) -> {ok, BMZ} | {error, BND}) -) -> {ok, BMZ} | {error, BND}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index 3374ebc293f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@dict:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@dict:size(erlang:element(2, Set)). - --spec insert(set(EOQ), EOQ) -> set(EOQ). -insert(Set, Member) -> - {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOT), EOT) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@dict:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EOV), EOV) -> set(EOV). -delete(Set, Member) -> - {set, gleam@dict:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOY)) -> list(EOY). -to_list(Set) -> - gleam@dict:keys(erlang:element(2, Set)). - --spec from_list(list(EPB)) -> set(EPB). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@dict:new(), - fun(M, K) -> gleam@dict:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. -fold(Set, Initial, Reducer) -> - gleam@dict:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). -filter(Set, Predicate) -> - {set, - gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. - --spec drop(set(EPK), list(EPK)) -> set(EPK). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPO), list(EPO)) -> set(EPO). -take(Set, Desired) -> - {set, gleam@dict:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. -order(First, Second) -> - case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPX), set(EPX)) -> set(EPX). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EQB), set(EQB)) -> set(EQB). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 6cba31d1895..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,352 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - gleam_stdlib:crop_string(String, Substring). - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - gleam_stdlib:contains_string(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_join(list(binary()), binary()) -> binary(). -do_join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - do_join(Strings, Separator). - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_array, Acc) -> - case Bit_array of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - _ -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 693e840f370..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([string_builder/0, direction/0]). - --type string_builder() :: any(). - --type direction() :: all. - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index a36df375281..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,252 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {_, _, _} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(ETW)) -> list(ETW). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - _ -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index 76aa1ea673c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,31 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.33.1"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_array, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@bytes_builder, - gleam@dict, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index c6ea1257110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,529 +0,0 @@ --module(gleam_stdlib). - --export([ - map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, - parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, - wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, - bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, - println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, - int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1 -]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - --define(is_lowercase_char(X), (X > 96 andalso X < 123)). --define(is_underscore_char(X), (X == 95)). --define(is_digit_char(X), (X > 47 andalso X < 58)). - -uppercase(X) -> X - 32. - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_array_concat(BitArrays) -> - list_to_bitstring(BitArrays). - -bit_array_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_array_int_to_u32(_) -> - {error, nil}. - -bit_array_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_array_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:_ -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(nil) -> - "Nil"; -inspect(Data) when is_map(Data) -> - Fields = [ - [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] - || {Key, Value} <- maps:to_list(Data) - ], - ["dict.from_list([", lists:join(", ", Fields), "])"]; -inspect(Atom) when is_atom(Atom) -> - Binary = erlang:atom_to_binary(Atom), - case inspect_maybe_gleam_atom(Binary, none, <<>>) of - {ok, Inspected} -> Inspected; - {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] - end; -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(Bits) when is_bitstring(Bits) -> - inspect_bit_array(Bits); -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - - -inspect_maybe_gleam_atom(<<>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc) - when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, $_, Acc); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); -inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> - {ok, Acc}; -inspect_maybe_gleam_atom(A, B, C) -> - erlang:display({A, B, C}), - throw({gleam_error, A, B, C}). - -inspect_list([]) -> - {proper, []}; -inspect_list([First]) -> - {proper, [inspect(First)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_bit_array(Bits) -> - Text = inspect_bit_array(Bits, <<"<<">>), - <<Text/binary, ">>">>. - -inspect_bit_array(<<>>, Acc) -> - Acc; -inspect_bit_array(<<X, Rest/bitstring>>, Acc) -> - inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); -inspect_bit_array(Rest, Acc) -> - Size = bit_size(Rest), - <<X:Size>> = Rest, - X1 = erlang:integer_to_binary(X), - Size1 = erlang:integer_to_binary(Size), - Segment = <<X1/binary, ":size(", Size1/binary, ")">>, - inspect_bit_array(<<>>, append_segment(Acc, Segment)). - -append_segment(<<"<<">>, Segment) -> - <<"<<", Segment/binary>>; -append_segment(Acc, Segment) -> - <<Acc/binary, ", ", Segment/binary>>. - - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<First/utf8, Rest/binary>> -> - Escaped = case First of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). - -utf_codepoint_list_to_string(List) -> - case unicode:characters_to_binary(List) of - {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); - Binary -> Binary - end. - -crop_string(String, Prefix) -> - case string:find(String, Prefix) of - nomatch -> String; - New -> New - end. - -contains_string(String, Substring) -> - is_bitstring(string:find(String, Substring)). - -base16_decode(String) -> - try - {ok, binary:decode_hex(String)} - catch - _:_ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 45c28cfc87b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,878 +0,0 @@ -import { - BitArray, - Error, - List, - Ok, - Result, - UtfCodepoint, - stringBits, - toBitArray, - NonEmpty, - CustomType, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import Dict from "./dict.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - const iterator = graphemes_iterator(string); - if (iterator) { - return List.fromArray(Array.from(iterator).map((item) => item.segment)); - } else { - return List.fromArray(string.match(/./gsu)); - } -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs, separator) { - const iterator = xs[Symbol.iterator](); - let result = iterator.next().value || ""; - let current = iterator.next(); - while (!current.done) { - result = result + separator + current.value; - current = iterator.next(); - } - return result; -} - -export function concat(xs) { - let result = ""; - for (const x of xs) { - result = result + x; - } - return result; -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function contains_string(haystack, needle) { - return haystack.indexOf(needle) >= 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_array_from_string(string) { - return toBitArray([stringBits(string)]); -} - -export function bit_array_concat(bit_arrays) { - return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_array_to_string(bit_array) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_array.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_array_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitArray(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return Dict.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_array) { - const aBytes = bit_array.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitArray(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (data instanceof Result) { - return "Result"; - } else if (data instanceof List) { - return "List"; - } else if (data instanceof BitArray) { - return "BitArray"; - } else if (data instanceof Dict) { - return "Map"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_array(data) { - if (data instanceof BitArray) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitArray(data)); - } - return decoder_error("BitArray", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - const list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!(data instanceof List)) return; - - const elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (!(current instanceof NonEmpty)) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && !(current instanceof NonEmpty)) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return data instanceof List ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return data instanceof Result ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof Dict) { - return new Ok(Dict.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(Dict.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof Dict || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} - -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function bitwise_and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function bitwise_not(x) { - return Number(~BigInt(x)); -} - -export function bitwise_or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function bitwise_exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function bitwise_shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function bitwise_shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} - -export function inspect(v) { - const t = typeof v; - if (v === true) return "True"; - if (v === false) return "False"; - if (v === null) return "//js(null)"; - if (v === undefined) return "Nil"; - if (t === "string") return JSON.stringify(v); - if (t === "bigint" || t === "number") return v.toString(); - if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; - if (v instanceof List) return inspectList(v); - if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); - if (v instanceof BitArray) return inspectBitArray(v); - if (v instanceof CustomType) return inspectCustomType(v); - if (v instanceof Dict) return inspectDict(v); - if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; - if (v instanceof RegExp) return `//js(${v})`; - if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; - if (v instanceof Function) { - const args = []; - for (const i of Array(v.length).keys()) - args.push(String.fromCharCode(i + 97)); - return `//fn(${args.join(", ")}) { ... }`; - } - return inspectObject(v); -} - -function inspectDict(map) { - let body = "dict.from_list(["; - let first = true; - map.forEach((value, key) => { - if (!first) body = body + ", "; - body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; - first = false; - }); - return body + "])"; -} - -function inspectObject(v) { - const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; - const props = []; - for (const k of Object.keys(v)) { - props.push(`${inspect(k)}: ${inspect(v[k])}`); - } - const body = props.length ? " " + props.join(", ") + " " : ""; - const head = name === "Object" ? "" : name + " "; - return `//js(${head}{${body}})`; -} - -function inspectCustomType(record) { - const props = Object.keys(record) - .map((label) => { - const value = inspect(record[label]); - return isNaN(parseInt(label)) ? `${label}: ${value}` : value; - }) - .join(", "); - return props - ? `${record.constructor.name}(${props})` - : record.constructor.name; -} - -export function inspectList(list) { - return `[${list.toArray().map(inspect).join(", ")}]`; -} - -export function inspectBitArray(bits) { - return `<<${Array.from(bits.buffer).join(", ")}>>`; -} - -export function inspectUtfCodepoint(codepoint) { - return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; -} - -export function base16_encode(bit_array) { - let result = ""; - for (const byte of bit_array.buffer) { - result += byte.toString(16).padStart(2, "0").toUpperCase(); - } - return result; -} - -export function base16_decode(string) { - const bytes = new Uint8Array(string.length / 2); - for (let i = 0; i < string.length; i += 2) { - const a = parseInt(string[i], 16); - const b = parseInt(string[i + 1], 16); - if (isNaN(a) || isNaN(b)) return new Error(Nil); - bytes[i / 2] = a * 16 + b; - } - return new Ok(new BitArray(bytes)); -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml deleted file mode 100644 index 08c866301c6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml +++ /dev/null @@ -1,2 +0,0 @@ -[packages] -gleam_stdlib = "0.33.1" diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml deleted file mode 100644 index 74b7e202e47..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleeunit" -version = "0.11.0" -licences = ["Apache-2.0"] -description = "Gleam bindings to Erlang's EUnit test framework" - -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] - -[dependencies] -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml deleted file mode 100644 index 913de938d95..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml +++ /dev/null @@ -1,9 +0,0 @@ -# This file was generated by Gleam -# You typically do not need to edit this file - -packages = [ - { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, -] - -[requirements] -gleam_stdlib = { version = "~> 0.27" } diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src deleted file mode 100644 index 2f98842c95e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleeunit, [ - {vsn, "0.11.0"}, - {applications, [gleam_stdlib]}, - {description, "Gleam bindings to Erlang's EUnit test framework"}, - {modules, [gleeunit, - gleeunit@should]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl deleted file mode 100644 index 32e1a833d01..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gleeunit). --compile([no_auto_import, nowarn_unused_vars]). - --export([main/0]). --export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). - --type atom_() :: any(). - --type encoding() :: utf8. - --type report_module_name() :: gleeunit_progress. - --type gleeunit_progress_option() :: {colored, boolean()}. - --type eunit_option() :: verbose | - no_tty | - {report, {report_module_name(), list(gleeunit_progress_option())}}. - --spec gleam_to_erlang_module_name(binary()) -> binary(). -gleam_to_erlang_module_name(Path) -> - _pipe = Path, - _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), - gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). - --spec do_main() -> nil. -do_main() -> - Options = [verbose, - no_tty, - {report, {gleeunit_progress, [{colored, true}]}}], - Result = begin - _pipe = gleeunit_ffi:find_files( - <<"**/*.{erl,gleam}"/utf8>>, - <<"test"/utf8>> - ), - _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end - ), - _pipe@3 = eunit:test(_pipe@2, Options), - _pipe@4 = (gleam@dynamic:result( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ))(_pipe@3), - gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) - end, - Code = case Result of - {ok, _} -> - 0; - - {error, _} -> - 1 - end, - erlang:halt(Code). - --spec main() -> nil. -main() -> - do_main(). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam deleted file mode 100644 index e5d4b460cad..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam +++ /dev/null @@ -1,92 +0,0 @@ -/// Find and run all test functions for the current project using Erlang's EUnit -/// test framework. -/// -/// Any Erlang or Gleam function in the `test` directory with a name editing in -/// `_test` is considered a test function and will be run. -/// -/// If running on JavaScript tests will be run with a custom test runner. -/// -pub fn main() -> Nil { - do_main() -} - -@target(javascript) -@external(javascript, "./gleeunit_ffi.mjs", "main") -fn do_main() -> Nil - -@target(erlang) -import gleam/list -@target(erlang) -import gleam/result -@target(erlang) -import gleam/string -@target(erlang) -import gleam/dynamic.{Dynamic} - -@target(erlang) -fn do_main() -> Nil { - let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] - - let result = - find_files(matching: "**/*.{erl,gleam}", in: "test") - |> list.map(gleam_to_erlang_module_name) - |> list.map(dangerously_convert_string_to_atom(_, Utf8)) - |> run_eunit(options) - |> dynamic.result(dynamic.dynamic, dynamic.dynamic) - |> result.unwrap(Error(dynamic.from(Nil))) - - let code = case result { - Ok(_) -> 0 - Error(_) -> 1 - } - halt(code) -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil - -@target(erlang) -fn gleam_to_erlang_module_name(path: String) -> String { - path - |> string.replace(".gleam", "") - |> string.replace(".erl", "") - |> string.replace("/", "@") -} - -@target(erlang) -@external(erlang, "gleeunit_ffi", "find_files") -fn find_files(matching matching: String, in in: String) -> List(String) - -@target(erlang) -type Atom - -@target(erlang) -type Encoding { - Utf8 -} - -@target(erlang) -@external(erlang, "erlang", "binary_to_atom") -fn dangerously_convert_string_to_atom(a: String, b: Encoding) -> Atom - -@target(erlang) -type ReportModuleName { - GleeunitProgress -} - -@target(erlang) -type GleeunitProgressOption { - Colored(Bool) -} - -@target(erlang) -type EunitOption { - Verbose - NoTty - Report(#(ReportModuleName, List(GleeunitProgressOption))) -} - -@target(erlang) -@external(erlang, "eunit", "test") -fn run_eunit(a: List(Atom), b: List(EunitOption)) -> Dynamic diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam deleted file mode 100644 index c393c232724..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam +++ /dev/null @@ -1,90 +0,0 @@ -//// A module for testing your Gleam code. The functions found here are -//// compatible with the Erlang eunit test framework. -//// -//// More information on running eunit can be found in [the rebar3 -//// documentation](https://rebar3.org/docs/testing/eunit/). - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_equal") -pub fn equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_not_equal") -pub fn not_equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_ok") -pub fn be_ok(a: Result(a, b)) -> a - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_error") -pub fn be_error(a: Result(a, b)) -> b - -@target(javascript) -import gleam/string - -@target(javascript) -@external(javascript, "../gleam.mjs", "inspect") -fn stringify(a: anything) -> String - -@target(javascript) -@external(javascript, "../gleeunit_ffi.mjs", "crash") -fn crash(a: String) -> anything - -@target(javascript) -pub fn equal(a, b) { - case a == b { - True -> Nil - _ -> - crash(string.concat([ - "\n\t", - stringify(a), - "\n\tshould equal \n\t", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn not_equal(a, b) { - case a != b { - True -> Nil - _ -> - crash(string.concat([ - "\n", - stringify(a), - "\nshould not equal \n", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn be_ok(a) { - case a { - Ok(value) -> value - _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) - } -} - -@target(javascript) -pub fn be_error(a) { - case a { - Error(error) -> error - _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) - } -} - -pub fn be_true(actual: Bool) -> Nil { - actual - |> equal(True) -} - -pub fn be_false(actual: Bool) -> Nil { - actual - |> equal(False) -} - -pub fn fail() -> Nil { - be_true(False) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl deleted file mode 100644 index acf032e1e7d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(gleeunit@should). --compile([no_auto_import, nowarn_unused_vars]). - --export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). - --spec equal(EYG, EYG) -> nil. -equal(A, B) -> - gleeunit_ffi:should_equal(A, B). - --spec not_equal(EYH, EYH) -> nil. -not_equal(A, B) -> - gleeunit_ffi:should_not_equal(A, B). - --spec be_ok({ok, EYI} | {error, any()}) -> EYI. -be_ok(A) -> - gleeunit_ffi:should_be_ok(A). - --spec be_error({ok, any()} | {error, EYN}) -> EYN. -be_error(A) -> - gleeunit_ffi:should_be_error(A). - --spec be_true(boolean()) -> nil. -be_true(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, true). - --spec be_false(boolean()) -> nil. -be_false(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, false). - --spec fail() -> nil. -fail() -> - be_true(false). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl deleted file mode 100644 index 31f9ef9e2c9..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(gleeunit_ffi). - --export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, - should_be_error/1]). - --include_lib("eunit/include/eunit.hrl"). - -find_files(Pattern, In) -> - Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), - lists:map(fun list_to_binary/1, Results). - - -should_equal(Actual, Expected) -> - ?assertEqual(Expected, Actual), - nil. -should_not_equal(Actual, Expected) -> - ?assertNotEqual(Expected, Actual), - nil. -should_be_ok(A) -> - ?assertMatch({ok, _}, A), - element(2, A). -should_be_error(A) -> - ?assertMatch({error, _}, A), - element(2, A). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs deleted file mode 100644 index 339a843e5c5..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs +++ /dev/null @@ -1,101 +0,0 @@ -async function* gleamFiles(directory) { - for (let entry of await read_dir(directory)) { - let path = join_path(directory, entry); - if (path.endsWith(".gleam")) { - yield path; - } else { - try { - yield* gleamFiles(path); - } catch (error) { - // Could not read directory, assume it's a file - } - } - } -} - -async function readRootPackageName() { - let toml = await read_file("gleam.toml", "utf-8"); - for (let line of toml.split("\n")) { - let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() - if (matches) return matches[1]; - } - throw new Error("Could not determine package name from gleam.toml"); -} - -export async function main() { - let passes = 0; - let failures = 0; - - let packageName = await readRootPackageName(); - let dist = `../${packageName}/`; - - for await (let path of await gleamFiles("test")) { - let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); - let module = await import(join_path(dist, js_path)); - for (let fnName of Object.keys(module)) { - if (!fnName.endsWith("_test")) continue; - try { - await module[fnName](); - write(`\u001b[32m.\u001b[0m`); - passes++; - } catch (error) { - let moduleName = "\n" + js_path.slice(0, -4); - let line = error.line ? `:${error.line}` : ""; - write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); - failures++; - } - } - } - - console.log(` -${passes + failures} tests, ${failures} failures`); - exit(failures ? 1 : 0); -} - -export function crash(message) { - throw new Error(message); -} - -function write(message) { - if (globalThis.Deno) { - Deno.stdout.writeSync(new TextEncoder().encode(message)); - } else { - process.stdout.write(message); - } -} - -function exit(code) { - if (globalThis.Deno) { - Deno.exit(code); - } else { - process.exit(code); - } -} - -async function read_dir(path) { - if (globalThis.Deno) { - let items = []; - for await (let item of Deno.readDir(path, { withFileTypes: true })) { - items.push(item.name); - } - return items; - } else { - let { readdir } = await import("fs/promises"); - return readdir(path); - } -} - -function join_path(a, b) { - if (a.endsWith("/")) return a + b; - return a + "/" + b; -} - -async function read_file(path) { - if (globalThis.Deno) { - return Deno.readTextFile(path); - } else { - let { readFile } = await import("fs/promises"); - let contents = await readFile(path); - return contents.toString(); - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl deleted file mode 100644 index 1f68eb95e58..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl +++ /dev/null @@ -1,607 +0,0 @@ -%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters - -%% @doc A listener/reporter for eunit that prints '.' for each -%% success, 'F' for each failure, and 'E' for each error. It can also -%% optionally summarize the failures at the end. --compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). --module(gleeunit_progress). --behaviour(eunit_listener). --define(NOTEST, true). --include_lib("eunit/include/eunit.hrl"). - --define(RED, "\e[0;31m"). --define(GREEN, "\e[0;32m"). --define(YELLOW, "\e[0;33m"). --define(WHITE, "\e[0;37m"). --define(CYAN, "\e[0;36m"). --define(RESET, "\e[0m"). - --record(node,{ - rank = 0 :: non_neg_integer(), - key :: term(), - value :: term(), - children = new() :: binomial_heap() - }). - --export_type([binomial_heap/0, heap_node/0]). --type binomial_heap() :: [ heap_node() ]. --type heap_node() :: #node{}. - -%% eunit_listener callbacks --export([ - init/1, - handle_begin/3, - handle_end/3, - handle_cancel/3, - terminate/2, - start/0, - start/1 - ]). - -%% -- binomial_heap.erl content start -- - --record(state, { - status = dict:new() :: euf_dict(), - failures = [] :: [[pos_integer()]], - skips = [] :: [[pos_integer()]], - timings = new() :: binomial_heap(), - colored = true :: boolean(), - profile = false :: boolean() - }). - --type euf_dict() :: dict:dict(). - --spec new() -> binomial_heap(). -new() -> - []. - -% Inserts a new pair into the heap (or creates a new heap) --spec insert(term(), term()) -> binomial_heap(). -insert(Key,Value) -> - insert(Key,Value,[]). - --spec insert(term(), term(), binomial_heap()) -> binomial_heap(). -insert(Key,Value,Forest) -> - insTree(#node{key=Key,value=Value},Forest). - -% Merges two heaps --spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). -merge(TS1,[]) when is_list(TS1) -> TS1; -merge([],TS2) when is_list(TS2) -> TS2; -merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> - if - R1 < R2 -> - [T1 | merge(TS1,F2)]; - R2 < R1 -> - [T2 | merge(F1, TS2)]; - true -> - insTree(link(T1,T2),merge(TS1,TS2)) - end. - -% Deletes the top entry from the heap and returns it --spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. -delete(TS) -> - {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), - {{Key,Value},merge(lists:reverse(TS1),TS2)}. - -% Turns the heap into list in heap order --spec to_list(binomial_heap()) -> [{term(), term()}]. -to_list([]) -> []; -to_list(List) when is_list(List) -> - to_list([],List). -to_list(Acc, []) -> - lists:reverse(Acc); -to_list(Acc,Forest) -> - {Next, Trees} = delete(Forest), - to_list([Next|Acc], Trees). - -% Take N elements from the top of the heap --spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. -take(N,Trees) when is_integer(N), is_list(Trees) -> - take(N,Trees,[]). -take(0,_Trees,Acc) -> - lists:reverse(Acc); -take(_N,[],Acc)-> - lists:reverse(Acc); -take(N,Trees,Acc) -> - {Top,T2} = delete(Trees), - take(N-1,T2,[Top|Acc]). - -% Get an estimate of the size based on the binomial property --spec size(binomial_heap()) -> non_neg_integer(). -size(Forest) -> - erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). - -%% Private API --spec link(heap_node(), heap_node()) -> heap_node(). -link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> - case X1 < X2 of - true -> - T1#node{rank=R+1,children=[T2|C1]}; - _ -> - T2#node{rank=R+1,children=[T1|C2]} - end. - -insTree(Tree, []) -> - [Tree]; -insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> - case R1 < R2 of - true -> - [T1|TS]; - _ -> - insTree(link(T1,T2),Rest) - end. - -getMin([T]) -> - {T,[]}; -getMin([#node{key=K} = T|TS]) -> - {#node{key=K1} = T1,TS1} = getMin(TS), - case K < K1 of - true -> {T,TS}; - _ -> {T1,[T|TS1]} - end. - -%% -- binomial_heap.erl content end -- - -%% Startup -start() -> - start([]). - -start(Options) -> - eunit_listener:start(?MODULE, Options). - -%%------------------------------------------ -%% eunit_listener callbacks -%%------------------------------------------ -init(Options) -> - #state{colored=proplists:get_bool(colored, Options), - profile=proplists:get_bool(profile, Options)}. - -handle_begin(group, Data, St) -> - GID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; -handle_begin(test, Data, St) -> - TID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. - -handle_end(group, Data, St) -> - St#state{status=merge_on_end(Data, St#state.status)}; -handle_end(test, Data, St) -> - NewStatus = merge_on_end(Data, St#state.status), - St1 = print_progress(Data, St), - St2 = record_timing(Data, St1), - St2#state{status=NewStatus}. - -handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> - Status1 = merge_on_end(Data, Status), - ID = proplists:get_value(id, Data), - St#state{status=Status1, skips=[ID|Skips]}. - -terminate({ok, Data}, St) -> - print_failures(St), - print_pending(St), - print_profile(St), - print_timing(St), - print_results(Data, St); -terminate({error, Reason}, St) -> - io:nl(), io:nl(), - print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), - sync_end(error). - -sync_end(Result) -> - receive - {stop, Reference, ReplyTo} -> - ReplyTo ! {result, Reference, Result}, - ok - end. - -%%------------------------------------------ -%% Print and collect information during run -%%------------------------------------------ -print_progress(Data, St) -> - TID = proplists:get_value(id, Data), - case proplists:get_value(status, Data) of - ok -> - print_progress_success(St), - St; - {skipped, _Reason} -> - print_progress_skipped(St), - St#state{skips=[TID|St#state.skips]}; - {error, Exception} -> - print_progress_failed(Exception, St), - St#state{failures=[TID|St#state.failures]} - end. - -record_timing(Data, State=#state{timings=T, profile=true}) -> - TID = proplists:get_value(id, Data), - case lists:keyfind(time, 1, Data) of - {time, Int} -> - %% It's a min-heap, so we insert negative numbers instead - %% of the actuals and normalize when we report on them. - T1 = insert(-Int, TID, T), - State#state{timings=T1}; - false -> - State - end; -record_timing(_Data, State) -> - State. - -print_progress_success(St) -> - print_colored(".", ?GREEN, St). - -print_progress_skipped(St) -> - print_colored("*", ?YELLOW, St). - -print_progress_failed(_Exc, St) -> - print_colored("F", ?RED, St). - -merge_on_end(Data, Dict) -> - ID = proplists:get_value(id, Data), - dict:update(ID, - fun(Old) -> - orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) - end, Dict). - -merge_data(_K, undefined, X) -> X; -merge_data(_K, X, undefined) -> X; -merge_data(_K, _, X) -> X. - -%%------------------------------------------ -%% Print information at end of run -%%------------------------------------------ -print_failures(#state{failures=[]}) -> - ok; -print_failures(#state{failures=Fails}=State) -> - io:nl(), - io:fwrite("Failures:~n",[]), - lists:foldr(print_failure_fun(State), 1, Fails), - ok. - -print_failure_fun(#state{status=Status}=State) -> - fun(Key, Count) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:fwrite("~n ~p) ~ts~n", [Count, TestId]), - print_failure_reason(proplists:get_value(status, TestData), - proplists:get_value(output, TestData), - State), - io:nl(), - Count + 1 - end. - -print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> - X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), - print_colored(X, ?CYAN, State); -print_gleam_location(_, _) -> - ok. - -inspect(X) -> - gleam@string:inspect(X). - -print_gleam_failure_reason( - #{gleam_error := assert, message := Message, value := Value}, - State -) -> - print_colored(indent(5, "~s~n", [Message]), ?RED, State), - print_colored(indent(5, " value: ", []), ?RED, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); -print_gleam_failure_reason( - #{gleam_error := todo, message := Message}, - State -) -> - print_colored(indent(5, "todo expression run~n", []), ?RED, State), - print_colored(indent(5, " message: ", []), ?RED, State), - print_colored(indent(0, "~s~n", [Message]), ?RESET, State); -print_gleam_failure_reason(Error, State) -> - print_colored(indent(5, "~p~n", [Error]), ?RED, State). - -% New Gleeunit specific formatters -print_failure_reason( - {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State -) when is_list(Stack) -> - print_gleam_failure_reason(Error, State), - print_gleam_location(Error, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "No case clause matched~n", []), ?RED, State), - print_colored(indent(5, "Value: ", []), ?CYAN, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -% From the original Erlang version -print_failure_reason({skipped, Reason}, _Output, State) -> - print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), - ?RED, State); -print_failure_reason({error, {_Class, Term, _}}, Output, State) when - is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> - print_assertion_failure(Term, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, Reason}, Output, State) -> - print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), - print_failure_output(5, Output, State). - -gleam_format_module_name(Module) -> - string:replace(atom_to_list(Module), "@", "/", all). - -print_stack(Stack, State) -> - print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), - print_stackframes(Stack, State). -print_stackframes([{eunit_test, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> - GleamModule = gleam_format_module_name(Module), - print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), - print_stackframes(Stack, State); -print_stackframes([], _State) -> - ok. - - -print_failure_output(_, <<>>, _) -> ok; -print_failure_output(_, undefined, _) -> ok; -print_failure_output(Indent, Output, State) -> - print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). - -print_assertion_failure({Type, Props}, State) -> - FailureDesc = format_assertion_failure(Type, Props, 5), - print_colored(FailureDesc, ?RED, State), - io:nl(). - -print_pending(#state{skips=[]}) -> - ok; -print_pending(#state{status=Status, skips=Skips}=State) -> - io:nl(), - io:fwrite("Pending:~n", []), - lists:foreach(fun(ID) -> - Info = dict:fetch(ID, Status), - case proplists:get_value(reason, Info) of - undefined -> - ok; - Reason -> - print_pending_reason(Reason, Info, State) - end - end, lists:reverse(Skips)), - io:nl(). - -print_pending_reason(Reason0, Data, State) -> - Text = case proplists:get_value(type, Data) of - group -> - io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); - test -> - io_lib:format(" ~ts~n", [format_test_identifier(Data)]) - end, - Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), - print_colored(Text, ?YELLOW, State), - print_colored(Reason, ?CYAN, State). - -print_profile(#state{timings=T, status=Status, profile=true}=State) -> - TopN = take(10, T), - TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), - TLG = dict:fetch([], Status), - TotalTime = proplists:get_value(time, TLG), - if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> - TopNPct = (TopNTime / TotalTime) * 100, - io:nl(), io:nl(), - io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), - lists:foreach(print_timing_fun(State), TopN), - io:nl(); - true -> ok - end; -print_profile(#state{profile=false}) -> - ok. - -print_timing(#state{status=Status}) -> - TLG = dict:fetch([], Status), - Time = proplists:get_value(time, TLG), - io:nl(), - io:fwrite("Finished in ~ts~n", [format_time(Time)]), - ok. - -print_results(Data, State) -> - Pass = proplists:get_value(pass, Data, 0), - Fail = proplists:get_value(fail, Data, 0), - Skip = proplists:get_value(skip, Data, 0), - Cancel = proplists:get_value(cancel, Data, 0), - Total = Pass + Fail + Skip + Cancel, - {Color, Result} = if Fail > 0 -> {?RED, error}; - Skip > 0; Cancel > 0 -> {?YELLOW, error}; - Pass =:= 0 -> {?YELLOW, ok}; - true -> {?GREEN, ok} - end, - print_results(Color, Total, Fail, Skip, Cancel, State), - sync_end(Result). - -print_results(Color, 0, _, _, _, State) -> - print_colored(Color, "0 tests\n", State); -print_results(Color, Total, Fail, Skip, Cancel, State) -> - SkipText = format_optional_result(Skip, "skipped"), - CancelText = format_optional_result(Cancel, "cancelled"), - Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), - print_colored(Text, Color, State). - -print_timing_fun(#state{status=Status}=State) -> - fun({Time, Key}) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:nl(), - io:fwrite(" ~ts~n", [TestId]), - print_colored([" "|format_time(abs(Time))], ?CYAN, State) - end. - -%%------------------------------------------ -%% Print to the console with the given color -%% if enabled. -%%------------------------------------------ -print_colored(Text, Color, #state{colored=true}) -> - io:fwrite("~s~ts~s", [Color, Text, ?RESET]); -print_colored(Text, _Color, #state{colored=false}) -> - io:fwrite("~ts", [Text]). - -%%------------------------------------------ -%% Generic data formatters -%%------------------------------------------ -format_function_name(M, F) -> - M1 = gleam_format_module_name(M), - io_lib:format("~ts.~ts", [M1, F]). - -format_optional_result(0, _) -> - []; -format_optional_result(Count, Text) -> - io_lib:format(", ~p ~ts", [Count, Text]). - -format_test_identifier(Data) -> - {Mod, Fun, _} = proplists:get_value(source, Data), - Line = case proplists:get_value(line, Data) of - 0 -> ""; - L -> io_lib:format(":~p", [L]) - end, - Desc = case proplists:get_value(desc, Data) of - undefined -> ""; - DescText -> io_lib:format(": ~ts", [DescText]) - end, - io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). - -format_time(undefined) -> - "? seconds"; -format_time(Time) -> - io_lib:format("~.3f seconds", [Time / 1000]). - -format_pending_reason({module_not_found, M}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Module '~ts' missing", [M1]); -format_pending_reason({no_such_function, {M,F,_}}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); -format_pending_reason({exit, Reason}) -> - io_lib:format("Related process exited with reason: ~p", [Reason]); -format_pending_reason(Reason) -> - io_lib:format("Unknown error: ~p", [Reason]). - -%% @doc Formats all the known eunit assertions, you're on your own if -%% you make an assertion yourself. -format_assertion_failure(Type, Props, I) when Type =:= assertion_failed - ; Type =:= assert -> - Keys = proplists:get_keys(Props), - HasEUnitProps = ([expression, value] -- Keys) =:= [], - HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], - if - HasEUnitProps -> - [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), - indent(I, " expected: true~n", []), - case proplists:get_value(value, Props) of - false -> - indent(I, " got: false", []); - {not_a_boolean, V} -> - indent(I, " got: ~p", [V]) - end]; - HasHamcrestProps -> - [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), - indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), - indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; - true -> - [indent(I, "Failure: unknown assert: ~p", [Props])] - end; - -format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed - ; Type =:= assertMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed - ; Type =:= assertNotMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected not: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed - ; Type =:= assertEqual -> - Expected = inspect(proplists:get_value(expected, Props)), - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were not equal~n", []), - indent(I, "expected: ~ts~n", [Expected]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed - ; Type =:= assertNotEqual -> - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were equal~n", []), - indent(I, "expected: not ~ts~n,", [Value]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertException_failed - ; Type =:= assertException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA - [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - case proplists:is_defined(unexpected_success, Props) of - true -> - [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), - indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; - false -> - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, " expected: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])] - end]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed - ; Type =:= assertNotException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - indent(I, " expected not: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])]; - -format_assertion_failure(Type, Props, I) when Type =:= command_failed - ; Type =:= command -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed - ; Type =:= assertCmd -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed - ; Type =:= assertCmdOutput -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_output, Props), - Output = proplists:get_value(output, Props), - [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: ~p~n", [Expected]), - indent(I, " got: ~p", [Output])]; - -format_assertion_failure(Type, Props, I) -> - indent(I, "~p", [{Type, Props}]). - -indent(I, Fmt, Args) -> - io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). - -extract_exception_pattern(Str) -> - ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), - {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml deleted file mode 100644 index 44f92f58c1d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml +++ /dev/null @@ -1,3 +0,0 @@ -[packages] -gleam_stdlib = "0.33.1" -gleeunit = "0.11.0" diff --git a/test-community-packages-javascript/build/packages/glx/gleam.toml b/test-community-packages-javascript/build/packages/glx/gleam.toml deleted file mode 100644 index bbbca2306be..00000000000 --- a/test-community-packages-javascript/build/packages/glx/gleam.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "glx" -version = "0.2.0" -description = "Extensions to the Gleam standard library." -licences = ["MIT"] -repository = { type = "github", user = "maxdeviant", repo = "glx" } - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glx/manifest.toml b/test-community-packages-javascript/build/packages/glx/manifest.toml deleted file mode 100644 index b605eaf19d3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/manifest.toml +++ /dev/null @@ -1,11 +0,0 @@ -# This file was generated by Gleam -# You typically do not need to edit this file - -packages = [ - { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, - { name = "gleeunit", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "1397E5C4AC4108769EE979939AC39BF7870659C5AFB714630DEEEE16B8272AD5" }, -] - -[requirements] -gleam_stdlib = { version = "~> 0.29" } -gleeunit = { version = "~> 0.10" } diff --git a/test-community-packages-javascript/build/packages/glx/src/glx.app.src b/test-community-packages-javascript/build/packages/glx/src/glx.app.src deleted file mode 100644 index c6fc08eca4b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/src/glx.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, glx, [ - {vsn, "0.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Extensions to the Gleam standard library."}, - {modules, [glx@stringx]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam b/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam deleted file mode 100644 index ba8bfd24805..00000000000 --- a/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam +++ /dev/null @@ -1,31 +0,0 @@ -//// Extensions to `gleam/string`. - -import gleam/bool.{negate} -import gleam/list -import gleam/regex -import gleam/string - -/// Returns the lines contained in the given string. -/// -/// Supports both `\n` and `\r\n` line endings. -/// -/// ## Examples -/// -/// ```gleam -/// > lines("one\ntwo\n\nthree\n") -/// ["one", "two", "three"] -/// ``` -/// -/// ```gleam -/// > lines("one\r\ntwo\r\n\r\nthree\r\n") -/// ["one", "two", "three"] -/// ``` -pub fn lines(value: String) -> List(String) { - let assert Ok(newline_regex) = regex.from_string("\r?\n") - - let is_not_empty = fn(line) { negate(string.is_empty(line)) } - - value - |> regex.split(with: newline_regex) - |> list.filter(is_not_empty) -} diff --git a/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl b/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl deleted file mode 100644 index 442e47bcd68..00000000000 --- a/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(glx@stringx). --compile([no_auto_import, nowarn_unused_vars]). - --export([lines/1]). - --spec lines(binary()) -> list(binary()). -lines(Value) -> - _assert_subject = gleam@regex:from_string(<<"\r?\n"/utf8>>), - {ok, Newline_regex} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glx/stringx"/utf8>>, - function => <<"lines"/utf8>>, - line => 24}) - end, - Is_not_empty = fun(Line) -> - gleam@bool:negate(gleam@string:is_empty(Line)) - end, - _pipe = Value, - _pipe@1 = gleam@regex:split(Newline_regex, _pipe), - gleam@list:filter(_pipe@1, Is_not_empty). diff --git a/test-community-packages-javascript/build/packages/gsv/README.md b/test-community-packages-javascript/build/packages/gsv/README.md deleted file mode 100644 index f9e1f0e4d20..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# gsv - -[![Package Version](https://img.shields.io/hexpm/v/csv)](https://hex.pm/packages/csv) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/csv/) - -This is a simple csv parser and writer for gleam. It will get more performant in the future, -but if you're looking for high performance now, I'd recommend doing ffi to an existing parser -in your target runtime. - -We are using the grammar from [rfc 4180](https://datatracker.ietf.org/doc/html/rfc4180#section-2) - -#### Example - -```gleam -import gsv.{Unix, Windows} - -pub fn main() { - let csv_str = "Hello, World\nGoodbye, Mars" - - // Parse a CSV string to a List(List(String)) - let assert Ok(records) = gsv.to_lists(csv_str) - - // Write a List(List(String)) to a CSV string - let csv_str = records - |> gsv.from_lists(separator: ",", line_ending: Windows) -} -``` - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add csv -``` - -and its documentation can be found at <https://hexdocs.pm/csv>. diff --git a/test-community-packages-javascript/build/packages/gsv/gleam.toml b/test-community-packages-javascript/build/packages/gsv/gleam.toml deleted file mode 100644 index 5531f8f1ada..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/gleam.toml +++ /dev/null @@ -1,20 +0,0 @@ -name = "gsv" -version = "0.1.0" -description = "A simple csv parser and generator written in gleam " - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -licences = ["Apache-2.0"] -repository = { type = "github", user = "bcpeinhardt", repo = "gsv" } - -internal_modules = [ - "gsv/internal", - "gsv/internal/*", -] - -[dependencies] -gleam_stdlib = "~> 0.28" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl b/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl deleted file mode 100644 index 6f89ba03f95..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl +++ /dev/null @@ -1 +0,0 @@ --record(textdata, {inner :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src b/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src deleted file mode 100644 index 357abfbd8a2..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, gsv, [ - {vsn, "0.1.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A simple csv parser and generator written in gleam "}, - {modules, [gsv, - gsv@internal@ast, - gsv@internal@token]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv.erl deleted file mode 100644 index a5751d0d9a4..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv.erl +++ /dev/null @@ -1,58 +0,0 @@ --module(gsv). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_lists/1, from_lists/3]). --export_type([line_ending/0]). - --type line_ending() :: windows | unix. - --spec to_lists(binary()) -> {ok, list(list(binary()))} | {error, nil}. -to_lists(Input) -> - _pipe = Input, - _pipe@1 = gsv@internal@token:scan(_pipe), - gsv@internal@ast:parse(_pipe@1). - --spec le_to_string(line_ending()) -> binary(). -le_to_string(Le) -> - case Le of - windows -> - <<"\r\n"/utf8>>; - - unix -> - <<"\n"/utf8>> - end. - --spec from_lists(list(list(binary())), binary(), line_ending()) -> binary(). -from_lists(Input, Separator, Line_ending) -> - _pipe = Input, - _pipe@1 = gleam@list:map( - _pipe, - fun(Row) -> - gleam@list:map( - Row, - fun(Entry) -> - Entry@1 = gleam@string:replace( - Entry, - <<"\""/utf8>>, - <<"\"\""/utf8>> - ), - case (gleam@string:contains(Entry@1, Separator) orelse gleam@string:contains( - Entry@1, - <<"\n"/utf8>> - )) - orelse gleam@string:contains(Entry@1, <<"\""/utf8>>) of - true -> - <<<<"\""/utf8, Entry@1/binary>>/binary, "\""/utf8>>; - - false -> - Entry@1 - end - end - ) - end - ), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(Row@1) -> gleam@string:join(Row@1, Separator) end - ), - gleam@string:join(_pipe@2, le_to_string(Line_ending)). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam deleted file mode 100644 index 3feff3f6228..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam +++ /dev/null @@ -1,62 +0,0 @@ -import gsv/internal/ast -import gsv/internal/token -import gleam/list -import gleam/string - -/// Parses a csv string to a list of lists of strings. -/// Automatically handles Windows and Unix line endings. -pub fn to_lists(input: String) -> Result(List(List(String)), Nil) { - input - |> token.scan - |> ast.parse -} - -/// Option for using "\n = LF = Unix" or "\r\n = CRLF = Windows" -/// line endings. Use with the `from_lists` function when -/// writing to a csv string. -pub type LineEnding { - Windows - Unix -} - -fn le_to_string(le: LineEnding) -> String { - case le { - Windows -> "\r\n" - Unix -> "\n" - } -} - -/// Takes a list of lists of strings and writes it to a csv string. -/// Will automatically escape strings that contain double quotes or -/// line endings with double quotes (in csv, double quotes get escaped by doing -/// a double doublequote) -/// The string `he"llo\n` becomes `"he""llo\n"` -pub fn from_lists( - input: List(List(String)), - separator separator: String, - line_ending line_ending: LineEnding, -) -> String { - input - |> list.map(fn(row) { - list.map( - row, - fn(entry) { - // Double quotes need to be escaped with an extra doublequote - let entry = string.replace(entry, "\"", "\"\"") - - // If the string contains a , \n \r\n or " it needs to be escaped by wrapping in double quotes - case - string.contains(entry, separator) || string.contains(entry, "\n") || string.contains( - entry, - "\"", - ) - { - True -> "\"" <> entry <> "\"" - False -> entry - } - }, - ) - }) - |> list.map(fn(row) { string.join(row, separator) }) - |> string.join(le_to_string(line_ending)) -} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam deleted file mode 100644 index f991b826f7d..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam +++ /dev/null @@ -1,140 +0,0 @@ -//// We are using the following grammar for CSV from rfc4180 -//// -//// file = [header CRLF] record *(CRLF record) [CRLF] -//// header = name *(COMMA name) -//// record = field *(COMMA field) -//// name = field -//// field = (escaped / non-escaped) -//// escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE -//// non-escaped = *TEXTDATA - -import gleam/list -import gleam/result -import gsv/internal/token.{CR, Comma, CsvToken, Doublequote, LF, Textdata} - -type ParseState { - Beginning - JustParsedField - JustParsedComma - JustParsedNewline - JustParsedCR - InsideEscapedString -} - -pub fn parse(input: List(CsvToken)) -> Result(List(List(String)), Nil) { - let inner_rev = { - use llf <- result.try(parse_p(input, Beginning, [])) - use lf <- list.try_map(llf) - Ok(list.reverse(lf)) - } - use ir <- result.try(inner_rev) - Ok(list.reverse(ir)) -} - -fn parse_p( - input: List(CsvToken), - parse_state: ParseState, - llf: List(List(String)), -) -> Result(List(List(String)), Nil) { - case input, parse_state, llf { - // Error Case: An empty list should produce an Error - [], Beginning, _ -> Error(Nil) - - // BASE CASE: We are done parsing tokens - [], _, llf -> Ok(llf) - - // File should begin with either Escaped or Nonescaped string - [Textdata(str), ..remaining_tokens], Beginning, [] -> - parse_p(remaining_tokens, JustParsedField, [[str]]) - - [Doublequote, ..remaining_tokens], Beginning, [] -> - parse_p(remaining_tokens, InsideEscapedString, [[""]]) - - _, Beginning, _ -> Error(Nil) - - // If we just parsed a field, we're expecting either a comma or a CRLF - [Comma, ..remaining_tokens], JustParsedField, llf -> - parse_p(remaining_tokens, JustParsedComma, llf) - - [LF, ..remaining_tokens], JustParsedField, llf -> - parse_p(remaining_tokens, JustParsedNewline, llf) - - [CR, ..remaining_tokens], JustParsedField, llf -> - parse_p(remaining_tokens, JustParsedCR, llf) - - _, JustParsedField, _ -> Error(Nil) - - // If we just parsed a CR, we're expecting an LF - [LF, ..remaining_tokens], JustParsedCR, llf -> - parse_p(remaining_tokens, JustParsedNewline, llf) - - _, JustParsedCR, _ -> Error(Nil) - - // If we just parsed a comma, we're expecting an Escaped or Non-Escaped string - [Textdata(str), ..remaining_tokens], JustParsedComma, [ - curr_line, - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - JustParsedField, - [[str, ..curr_line], ..previously_parsed_lines], - ) - - [Doublequote, ..remaining_tokens], JustParsedComma, [ - curr_line, - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [["", ..curr_line], ..previously_parsed_lines], - ) - - _, JustParsedComma, _ -> Error(Nil) - - // If we just parsed a new line, we're expecting an escaped or non-escaped string - [Textdata(str), ..remaining_tokens], JustParsedNewline, llf -> - parse_p(remaining_tokens, JustParsedField, [[str], ..llf]) - - [Doublequote, ..remaining_tokens], JustParsedNewline, [ - curr_line, - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [["", ..curr_line], ..previously_parsed_lines], - ) - - _, JustParsedNewline, _ -> Error(Nil) - - // If we're inside an escaped string, we can take anything until we get a double quote, - // but a double double quote "" escapes the double quote and we keep parsing - [Doublequote, Doublequote, ..remaining_tokens], InsideEscapedString, [ - [str, ..rest_curr_line], - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [[str <> "\"", ..rest_curr_line], ..previously_parsed_lines], - ) - - [Doublequote, ..remaining_tokens], InsideEscapedString, llf -> - parse_p(remaining_tokens, JustParsedField, llf) - - [other_token, ..remaining_tokens], InsideEscapedString, [ - [str, ..rest_curr_line], - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [ - [str <> token.to_lexeme(other_token), ..rest_curr_line], - ..previously_parsed_lines - ], - ) - } -} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam deleted file mode 100644 index ff70536f4f1..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam +++ /dev/null @@ -1,54 +0,0 @@ -//// We are using the following grammar for CSV from rfc4180 -//// -//// file = [header CRLF] record *(CRLF record) [CRLF] -//// header = name *(COMMA name) -//// record = field *(COMMA field) -//// name = field -//// field = (escaped / non-escaped) -//// escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE -//// non-escaped = *TEXTDATA - -import gleam/string -import gleam/list - -pub type CsvToken { - Comma - LF - CR - Doublequote - Textdata(inner: String) -} - -pub fn to_lexeme(token: CsvToken) -> String { - case token { - Comma -> "," - LF -> "\n" - CR -> "\r" - Doublequote -> "\"" - Textdata(str) -> str - } -} - -pub fn scan(input: String) -> List(CsvToken) { - input - |> string.to_utf_codepoints - |> list.fold( - [], - fn(acc, x) { - case string.utf_codepoint_to_int(x) { - 0x2c -> [Comma, ..acc] - 0x22 -> [Doublequote, ..acc] - 0x0a -> [LF, ..acc] - 0x0D -> [CR, ..acc] - _ -> { - let cp = string.from_utf_codepoints([x]) - case acc { - [Textdata(str), ..rest] -> [Textdata(str <> cp), ..rest] - _ -> [Textdata(cp), ..acc] - } - } - } - }, - ) - |> list.reverse -} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl deleted file mode 100644 index ac107202ac0..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl +++ /dev/null @@ -1,125 +0,0 @@ --module(gsv@internal@ast). --compile([no_auto_import, nowarn_unused_vars]). - --export([parse/1]). --export_type([parse_state/0]). - --type parse_state() :: beginning | - just_parsed_field | - just_parsed_comma | - just_parsed_newline | - just_parsed_cr | - inside_escaped_string. - --spec parse_p( - list(gsv@internal@token:csv_token()), - parse_state(), - list(list(binary())) -) -> {ok, list(list(binary()))} | {error, nil}. -parse_p(Input, Parse_state, Llf) -> - case {Input, Parse_state, Llf} of - {[], beginning, _} -> - {error, nil}; - - {[], _, Llf@1} -> - {ok, Llf@1}; - - {[{textdata, Str} | Remaining_tokens], beginning, []} -> - parse_p(Remaining_tokens, just_parsed_field, [[Str]]); - - {[doublequote | Remaining_tokens@1], beginning, []} -> - parse_p(Remaining_tokens@1, inside_escaped_string, [[<<""/utf8>>]]); - - {_, beginning, _} -> - {error, nil}; - - {[comma | Remaining_tokens@2], just_parsed_field, Llf@2} -> - parse_p(Remaining_tokens@2, just_parsed_comma, Llf@2); - - {[lf | Remaining_tokens@3], just_parsed_field, Llf@3} -> - parse_p(Remaining_tokens@3, just_parsed_newline, Llf@3); - - {[cr | Remaining_tokens@4], just_parsed_field, Llf@4} -> - parse_p(Remaining_tokens@4, just_parsed_cr, Llf@4); - - {_, just_parsed_field, _} -> - {error, nil}; - - {[lf | Remaining_tokens@5], just_parsed_cr, Llf@5} -> - parse_p(Remaining_tokens@5, just_parsed_newline, Llf@5); - - {_, just_parsed_cr, _} -> - {error, nil}; - - {[{textdata, Str@1} | Remaining_tokens@6], - just_parsed_comma, - [Curr_line | Previously_parsed_lines]} -> - parse_p( - Remaining_tokens@6, - just_parsed_field, - [[Str@1 | Curr_line] | Previously_parsed_lines] - ); - - {[doublequote | Remaining_tokens@7], - just_parsed_comma, - [Curr_line@1 | Previously_parsed_lines@1]} -> - parse_p( - Remaining_tokens@7, - inside_escaped_string, - [[<<""/utf8>> | Curr_line@1] | Previously_parsed_lines@1] - ); - - {_, just_parsed_comma, _} -> - {error, nil}; - - {[{textdata, Str@2} | Remaining_tokens@8], just_parsed_newline, Llf@6} -> - parse_p(Remaining_tokens@8, just_parsed_field, [[Str@2] | Llf@6]); - - {[doublequote | Remaining_tokens@9], - just_parsed_newline, - [Curr_line@2 | Previously_parsed_lines@2]} -> - parse_p( - Remaining_tokens@9, - inside_escaped_string, - [[<<""/utf8>> | Curr_line@2] | Previously_parsed_lines@2] - ); - - {_, just_parsed_newline, _} -> - {error, nil}; - - {[doublequote, doublequote | Remaining_tokens@10], - inside_escaped_string, - [[Str@3 | Rest_curr_line] | Previously_parsed_lines@3]} -> - parse_p( - Remaining_tokens@10, - inside_escaped_string, - [[<<Str@3/binary, "\""/utf8>> | Rest_curr_line] | - Previously_parsed_lines@3] - ); - - {[doublequote | Remaining_tokens@11], inside_escaped_string, Llf@7} -> - parse_p(Remaining_tokens@11, just_parsed_field, Llf@7); - - {[Other_token | Remaining_tokens@12], - inside_escaped_string, - [[Str@4 | Rest_curr_line@1] | Previously_parsed_lines@4]} -> - parse_p( - Remaining_tokens@12, - inside_escaped_string, - [[<<Str@4/binary, - (gsv@internal@token:to_lexeme(Other_token))/binary>> | - Rest_curr_line@1] | - Previously_parsed_lines@4] - ) - end. - --spec parse(list(gsv@internal@token:csv_token())) -> {ok, list(list(binary()))} | - {error, nil}. -parse(Input) -> - Inner_rev = (gleam@result:'try'( - parse_p(Input, beginning, []), - fun(Llf) -> - gleam@list:try_map(Llf, fun(Lf) -> {ok, gleam@list:reverse(Lf)} end) - end - )), - gleam@result:'try'(Inner_rev, fun(Ir) -> {ok, gleam@list:reverse(Ir)} end). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl deleted file mode 100644 index 63647f465f1..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gsv@internal@token). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_lexeme/1, scan/1]). --export_type([csv_token/0]). - --type csv_token() :: comma | lf | cr | doublequote | {textdata, binary()}. - --spec to_lexeme(csv_token()) -> binary(). -to_lexeme(Token) -> - case Token of - comma -> - <<","/utf8>>; - - lf -> - <<"\n"/utf8>>; - - cr -> - <<"\r"/utf8>>; - - doublequote -> - <<"\""/utf8>>; - - {textdata, Str} -> - Str - end. - --spec scan(binary()) -> list(csv_token()). -scan(Input) -> - _pipe = Input, - _pipe@1 = gleam@string:to_utf_codepoints(_pipe), - _pipe@2 = gleam@list:fold( - _pipe@1, - [], - fun(Acc, X) -> case gleam@string:utf_codepoint_to_int(X) of - 16#2c -> - [comma | Acc]; - - 16#22 -> - [doublequote | Acc]; - - 16#0a -> - [lf | Acc]; - - 16#0D -> - [cr | Acc]; - - _ -> - Cp = gleam@string:from_utf_codepoints([X]), - case Acc of - [{textdata, Str} | Rest] -> - [{textdata, <<Str/binary, Cp/binary>>} | Rest]; - - _ -> - [{textdata, Cp} | Acc] - end - end end - ), - gleam@list:reverse(_pipe@2). diff --git a/test-community-packages-javascript/build/packages/hug/README.md b/test-community-packages-javascript/build/packages/hug/README.md deleted file mode 100644 index a55808a6eb5..00000000000 --- a/test-community-packages-javascript/build/packages/hug/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# hug - -A package for creating helpful, and pretty CLI messages. - -[![Package Version](https://img.shields.io/hexpm/v/hug)](https://hex.pm/packages/hug) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/hug/) - -✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! - ---- - -## Quick start - -```gleam -import gleam/io -import hug - -pub fn main() { - let source = "let six = 5 + 1.0" - - source - |> hug.error( - in: "example.gleam", - from: #(1, 10), - to: #(1, 17), - message: "invalid type", - hint: "can not add an `Int` to a `Float`" - ) - |> io.println() - ) -} -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add hug -``` - -and its documentation can be found at <https://hexdocs.pm/hug>. - - -## Why `hug`? - -The name `hug` is inspired by Mark Rendle's talk [The Worst Programming Language Ever](https://youtu.be/vcFBwt1nu2U?t=2229) where he refers error messages in Rust as "a hug from the compiler". diff --git a/test-community-packages-javascript/build/packages/hug/gleam.toml b/test-community-packages-javascript/build/packages/hug/gleam.toml deleted file mode 100644 index 3aedf38c6fa..00000000000 --- a/test-community-packages-javascript/build/packages/hug/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "hug" -version = "0.1.0" -licences = ["Apache-2.0"] -description = "Helpful and pretty CLI messages" -repository = { type = "github", user = "brettkolodny", repo = "gleam-hug" } - -[javascript.deno] -allow_read = ["./gleam.toml", "./test/"] - -[dependencies] -gleam_stdlib = "~> 0.26" -gleam_community_ansi = "~> 1.0" - -[dev-dependencies] -gleeunit = "~> 0.9" -gleam_erlang = "~> 0.17" diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.app.src b/test-community-packages-javascript/build/packages/hug/src/hug.app.src deleted file mode 100644 index dfed29a1cf7..00000000000 --- a/test-community-packages-javascript/build/packages/hug/src/hug.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, hug, [ - {vsn, "0.1.0"}, - {applications, [gleam_community_ansi, - gleam_erlang, - gleam_stdlib, - gleeunit]}, - {description, "Helpful and pretty CLI messages"}, - {modules, [hug]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.erl b/test-community-packages-javascript/build/packages/hug/src/hug.erl deleted file mode 100644 index 21d3a159505..00000000000 --- a/test-community-packages-javascript/build/packages/hug/src/hug.erl +++ /dev/null @@ -1,303 +0,0 @@ --module(hug). --compile(no_auto_import). - --export([error/6, warning/6, info/6]). --export_type([location/0, output/0]). - --type location() :: {location, integer(), integer()}. - --type output() :: error | warning | info. - --spec error( - binary(), - binary(), - {integer(), integer()}, - {integer(), integer()}, - binary(), - binary() -) -> binary(). -error(File_name, Source, Start, End, Msg, Hint) -> - output( - File_name, - Source, - {location, erlang:element(1, Start), erlang:element(2, Start)}, - {location, erlang:element(1, End), erlang:element(2, End)}, - Msg, - Hint, - error - ). - --spec warning( - binary(), - binary(), - {integer(), integer()}, - {integer(), integer()}, - binary(), - binary() -) -> binary(). -warning(File_name, Source, Start, End, Msg, Hint) -> - output( - File_name, - Source, - {location, erlang:element(1, Start), erlang:element(2, Start)}, - {location, erlang:element(1, End), erlang:element(2, End)}, - Msg, - Hint, - warning - ). - --spec info( - binary(), - binary(), - {integer(), integer()}, - {integer(), integer()}, - binary(), - binary() -) -> binary(). -info(File_name, Source, Start, End, Msg, Hint) -> - output( - File_name, - Source, - {location, erlang:element(1, Start), erlang:element(2, Start)}, - {location, erlang:element(1, End), erlang:element(2, End)}, - Msg, - Hint, - info - ). - --spec output( - binary(), - binary(), - location(), - location(), - binary(), - binary(), - output() -) -> binary(). -output(File_name, Source, Start, End, Err, Hint, Output) -> - Header = construct_header(Err, Output), - Body = construct_body(File_name, Source, Start, End, Output), - gleam@string:join([Header, Body, <<""/utf8>>, Hint], <<"\n"/utf8>>). - --spec get_relevant_lines(list(binary()), location(), location()) -> list(binary()). -get_relevant_lines(Source_lines, Start, End) -> - gleam@list:index_fold( - Source_lines, - [], - fun(Lines, Line, Index) -> - case ((Index - + 1) - >= erlang:element(2, Start)) - andalso ((Index - + 1) - =< erlang:element(2, End)) of - true -> - gleam@list:append(Lines, [Line]); - - false -> - Lines - end - end - ). - --spec underline_source(list(binary()), location(), location(), output()) -> list(binary()). -underline_source(Source_lines, Start, End, Output) -> - Colour = case Output of - error -> - fun gleam_community@ansi:red/1; - - warning -> - fun gleam_community@ansi:yellow/1; - - info -> - fun gleam_community@ansi:blue/1 - end, - gleam@list:index_map( - Source_lines, - fun(Index, Line) -> - case gleam@string:trim(Line) of - <<""/utf8>> -> - <<""/utf8>>; - - _@1 -> - case Index =:= 0 of - true -> - White_space = gleam@string:repeat( - <<" "/utf8>>, - erlang:element(3, Start) - - 1 - ), - Underline_end = case erlang:element(2, End) - =:= erlang:element(2, Start) of - true -> - erlang:element(3, End) - erlang:element( - 3, - Start - ); - - false -> - gleam@string:length(Line) - gleam@string:length( - White_space - ) - end, - <<White_space/binary, - (Colour( - gleam@string:repeat( - <<"~"/utf8>>, - Underline_end - ) - ))/binary>>; - - false -> - Line_length = gleam@string:length(Line), - Line_length_post_trim = gleam@string:length( - gleam@string:trim_left(Line) - ), - Num_white_space = Line_length - - Line_length_post_trim, - White_space@1 = gleam@string:repeat( - <<" "/utf8>>, - Num_white_space - ), - <<White_space@1/binary, - (Colour( - gleam@string:repeat( - <<"~"/utf8>>, - Line_length_post_trim - ) - ))/binary>> - end - end - end - ). - --spec construct_header(binary(), output()) -> binary(). -construct_header(Message, Output) -> - case Output of - error -> - <<(gleam_community@ansi:red(<<"error: "/utf8>>))/binary, - Message/binary>>; - - warning -> - <<(gleam_community@ansi:yellow(<<"warning: "/utf8>>))/binary, - Message/binary>>; - - info -> - <<(gleam_community@ansi:blue(<<"info: "/utf8>>))/binary, - Message/binary>> - end. - --spec construct_body(binary(), binary(), location(), location(), output()) -> binary(). -construct_body(File_name, Source, Start, End, Output) -> - Left_padding = gleam@int:max( - gleam@string:length(gleam@int:to_string(erlang:element(2, Start))), - gleam@string:length(gleam@int:to_string(erlang:element(2, End))) - ) - - 1, - Body_start = <<<<<<<<<<<<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, - " ┌─ "/utf8>>/binary, - File_name/binary>>/binary, - ":"/utf8>>/binary, - (gleam@int:to_string(erlang:element(2, Start)))/binary>>/binary, - ":"/utf8>>/binary, - (gleam@int:to_string(erlang:element(3, Start)))/binary>>, - Relevant_lines = get_relevant_lines( - gleam@string:split(Source, <<"\n"/utf8>>), - Start, - End - ), - Underlines = underline_source(Relevant_lines, Start, End, Output), - Trim_left_amount = get_trim_left_amount(Relevant_lines), - Body = begin - _pipe = gleam@list:zip(Relevant_lines, Underlines), - _pipe@1 = gleam@list:index_map( - _pipe, - fun(Index, Input) -> - construct_output_line( - Input, - Index - + erlang:element(2, Start), - Trim_left_amount, - Left_padding - ) - end - ), - gleam@string:join(_pipe@1, <<"\n"/utf8>>) - end, - gleam@string:join( - [Body_start, - <<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, - " │"/utf8>>, - Body, - <<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, - " │"/utf8>>], - <<"\n"/utf8>> - ). - --spec construct_output_line( - {binary(), binary()}, - integer(), - integer(), - integer() -) -> binary(). -construct_output_line(Input, Row, Trim_left_amount, Left_padding) -> - {Source_line, Underline} = Input, - Line_number_padding = (Left_padding - - gleam@string:length(gleam@int:to_string(Row))) - + 1, - Source_line@1 = <<<<<<(gleam_community@ansi:green(gleam@int:to_string(Row)))/binary, - (gleam@string:repeat(<<" "/utf8>>, Line_number_padding))/binary>>/binary, - " │ "/utf8>>/binary, - (trim_left(Source_line, Trim_left_amount))/binary>>, - case gleam@string:length(Underline) of - 0 -> - Source_line@1; - - _@1 -> - Underline_line = <<<<(gleam@string:repeat( - <<" "/utf8>>, - Left_padding - ))/binary, - " │ "/utf8>>/binary, - (trim_left(Underline, Trim_left_amount))/binary>>, - gleam@string:join([Source_line@1, Underline_line], <<"\n"/utf8>>) - end. - --spec get_trim_left_amount(list(binary())) -> integer(). -get_trim_left_amount(Lines) -> - Get_left_white_space = fun(Line) -> - gleam@string:length(Line) - - begin - _pipe = Line, - _pipe@1 = gleam@string:trim_left(_pipe), - gleam@string:length(_pipe@1) - end - end, - First_line = begin - _pipe@2 = gleam@list:first(Lines), - gleam@result:unwrap(_pipe@2, <<""/utf8>>) - end, - gleam@list:fold( - Lines, - Get_left_white_space(First_line), - fun(Min_white_space, Line@1) -> - case gleam@string:trim(Line@1) of - <<""/utf8>> -> - Min_white_space; - - _@1 -> - White_space = gleam@string:length(Line@1) - - begin - _pipe@3 = Line@1, - _pipe@4 = gleam@string:trim_left(_pipe@3), - gleam@string:length(_pipe@4) - end, - gleam@int:min(Min_white_space, White_space) - end - end - ). - --spec trim_left(binary(), integer()) -> binary(). -trim_left(Str, Num_white_space) -> - String_length = gleam@string:length(Str), - gleam@string:slice(Str, Num_white_space, String_length). diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.gleam b/test-community-packages-javascript/build/packages/hug/src/hug.gleam deleted file mode 100644 index 5c81514446d..00000000000 --- a/test-community-packages-javascript/build/packages/hug/src/hug.gleam +++ /dev/null @@ -1,405 +0,0 @@ -//// -//// - **Outputs** -//// - [`error`](#error) -//// - [`warning`](#error) -//// - [`info`](#info) -//// -//// --- -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/list -import gleam/result -import gleam/string -import gleam_community/ansi - -// TYPES ---------------------------------------------------------------------- - -type Location { - Location(row: Int, col: Int) -} - -type Output { - Error - Warning - Info -} - -// OUTPUTS -------------------------------------------------------------------- - -/// Returns a `String` displaying the provided error and relevant code. -/// -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// let source = "let five = 4 + 1.0" -/// -/// source -/// |> hug.error( -/// in: "example.gleam", -/// from: #(1, 11), -/// to: #(1, 18), -/// message: "invalid type", -/// hint: "can not add an `Int` to a `Float`" -/// ) -/// |> io.println() -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/brettkolodny/hug/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn error( - in file_name: String, - containing source: String, - from start: #(Int, Int), - to end: #(Int, Int), - message msg: String, - hint hint: String, -) -> String { - output( - file_name, - source, - Location(row: start.0, col: start.1), - Location(row: end.0, col: end.1), - msg, - hint, - Error, - ) -} - -/// Returns a `String` displaying the provided warning and relevant code. -/// -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// let source = "let five = 4 + 1.0" -/// -/// source -/// |> hug.warning( -/// in: "example.gleam", -/// from: #(1, 5), -/// to: #(1, 9), -/// message: "unused variable", -/// hint: "the variable `five` is declared but never used" -/// ) -/// |> io.println() -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/brettkolodny/hug/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn warning( - in file_name: String, - containing source: String, - from start: #(Int, Int), - to end: #(Int, Int), - message msg: String, - hint hint: String, -) -> String { - output( - file_name, - source, - Location(row: start.0, col: start.1), - Location(row: end.0, col: end.1), - msg, - hint, - Warning, - ) -} - -/// Returns a `String` displaying the provided info and relevant code. -/// -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// let source = "try five = int.parse("4") |> result.then(fn(v) { v + 1})" -/// -/// source -/// |> hug.info( -/// in: "example.gleam", -/// from: #(1, 1), -/// to: #(1, 4), -/// message: "use of deprecated code", -/// hint: "`try` is marked as deprecated, check out `use`!" -/// ) -/// |> io.println() -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/brettkolodny/hug/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn info( - in file_name: String, - containing source: String, - from start: #(Int, Int), - to end: #(Int, Int), - message msg: String, - hint hint: String, -) -> String { - output( - file_name, - source, - Location(row: start.0, col: start.1), - Location(row: end.0, col: end.1), - msg, - hint, - Info, - ) -} - -// ---------------------------------------------------------------------------- - -fn output( - file_name: String, - source: String, - start: Location, - end: Location, - err: String, - hint: String, - output: Output, -) { - let header = construct_header(err, output) - - let body = construct_body(file_name, source, start, end, output) - - string.join([header, body, "", hint], "\n") -} - -// -fn get_relevant_lines( - source_lines: List(String), - start: Location, - end: Location, -) -> List(String) { - use lines, line, index <- list.index_fold(source_lines, []) - - case index + 1 >= start.row && index + 1 <= end.row { - True -> list.append(lines, [line]) - False -> lines - } -} - -// -fn underline_source( - source_lines: List(String), - start: Location, - end: Location, - output: Output, -) -> List(String) { - let colour = case output { - Error -> ansi.red - Warning -> ansi.yellow - Info -> ansi.blue - } - - use index, line <- list.index_map(source_lines) - - case string.trim(line) { - "" -> "" - _ -> - case index == 0 { - True -> { - let white_space = string.repeat(" ", start.col - 1) - - let underline_end = case end.row == start.row { - True -> end.col - start.col - False -> string.length(line) - string.length(white_space) - } - - white_space <> colour(string.repeat("~", underline_end)) - } - - False -> { - let line_length = string.length(line) - let line_length_post_trim = string.length(string.trim_left(line)) - - let num_white_space = line_length - line_length_post_trim - - let white_space = string.repeat(" ", num_white_space) - - white_space <> colour(string.repeat("~", line_length_post_trim)) - } - } - } -} - -fn construct_header(message: String, output: Output) -> String { - case output { - Error -> ansi.red("error: ") <> message - Warning -> ansi.yellow("warning: ") <> message - Info -> ansi.blue("info: ") <> message - } -} - -// -fn construct_body( - file_name: String, - source: String, - start: Location, - end: Location, - output: Output, -) -> String { - let left_padding = - int.max( - string.length(int.to_string(start.row)), - string.length(int.to_string(end.row)), - ) - 1 - - let body_start = - string.repeat(" ", left_padding) <> " ┌─ " <> file_name <> ":" <> int.to_string( - start.row, - ) <> ":" <> int.to_string(start.col) - - let relevant_lines = - get_relevant_lines(string.split(source, on: "\n"), start, end) - - let underlines = underline_source(relevant_lines, start, end, output) - - let trim_left_amount = get_trim_left_amount(relevant_lines) - - let body = - list.zip(relevant_lines, underlines) - |> list.index_map(fn(index, input) { - construct_output_line( - input, - index + start.row, - trim_left_amount, - left_padding, - ) - }) - |> string.join("\n") - - string.join( - [ - body_start, - string.repeat(" ", left_padding) <> " │", - body, - string.repeat(" ", left_padding) <> " │", - ], - "\n", - ) -} - -// -fn construct_output_line( - input: #(String, String), - row: Int, - trim_left_amount: Int, - left_padding: Int, -) -> String { - let #(source_line, underline) = input - - let line_number_padding = left_padding - string.length(int.to_string(row)) + 1 - - let source_line = - ansi.green(int.to_string(row)) <> string.repeat(" ", line_number_padding) <> " │ " <> trim_left( - source_line, - by: trim_left_amount, - ) - - case string.length(underline) { - 0 -> source_line - _ -> { - let underline_line = - string.repeat(" ", left_padding) <> " │ " <> trim_left( - underline, - by: trim_left_amount, - ) - - string.join([source_line, underline_line], "\n") - } - } -} - -// -fn get_trim_left_amount(lines: List(String)) -> Int { - let get_left_white_space = fn(line) { - string.length(line) - { - line - |> string.trim_left() - |> string.length() - } - } - - let first_line = - list.first(lines) - |> result.unwrap("") - - use min_white_space, line <- list.fold( - lines, - get_left_white_space(first_line), - ) - - case string.trim(line) { - "" -> min_white_space - _ -> { - let white_space = - string.length(line) - { - line - |> string.trim_left() - |> string.length() - } - - int.min(min_white_space, white_space) - } - } -} - -// -fn trim_left(str: String, by num_white_space: Int) -> String { - let string_length = string.length(str) - - string.slice(from: str, at_index: num_white_space, length: string_length) -} diff --git a/test-community-packages-javascript/build/packages/mist/README.md b/test-community-packages-javascript/build/packages/mist/README.md deleted file mode 100644 index fedef427160..00000000000 --- a/test-community-packages-javascript/build/packages/mist/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# mist - -A glistening Gleam web server. - -## Installation - -This package can be added to your Gleam project: - -```sh -gleam add mist -``` - -and its documentation can be found at <https://hexdocs.pm/mist>. - -## Usage - -Right now there are a few options. Let's say you want a "simple" HTTP server -that you can customize to your heart's content. In that case, you want: - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http/response -import mist - -pub fn main() { - let assert Ok(_) = - mist.run_service( - 8080, - fn(_req) { - response.new(200) - |> response.set_body(bit_builder.from_string("hello, world!")) - }, - max_body_limit: 4_000_000 - ) - process.sleep_forever() -} -``` - -Maybe you also want to work with websockets. Maybe those should only be -upgradable at a certain endpoint. For that, you can use `mist.handler_func`. -The websocket methods help you build a handler with connect/disconnect handlers. -You can use these to track connected clients, for example. - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http.{Get, Post} -import gleam/http/request.{Request} -import gleam/http/response -import gleam/result -import mist -import mist/websocket - -pub fn main() { - let assert Ok(_) = - mist.serve( - 8080, - mist.handler_func(fn(req) { - case req.method, request.path_segments(req) { - Get, ["echo", "test"] -> websocket_echo() - Post, ["echo", "body"] -> echo_body(req) - Get, ["home"] -> - response.new(200) - |> mist.bit_builder_response( - bit_builder.from_string("sup home boy") - ) - _, _ -> - response.new(200) - |> mist.bit_builder_response( - bit_builder.from_string("Hello, world!") - ) - } - }), - ) - process.sleep_forever() -} - -fn websocket_echo() { - websocket.echo_handler - |> websocket.with_handler - // Here you can gain access to the `Subject` to send message to - // with: - // |> websocket.on_init(fn(subj) { ... }) - // |> websocket.on_close(fn(subj) { ... }) - |> mist.upgrade -} - -fn echo_body(req: Request(mist.Body)) { - req - |> mist.read_body - |> result.map(fn(req) { - response.new(200) - |> response.prepend_header( - "content-type", - request.get_header(req, "content-type") - |> result.unwrap("application/octet-stream"), - ) - |> mist.bit_builder_response(bit_builder.from_bit_string(req.body)) - }) - |> result.unwrap( - response.new(400) - |> mist.empty_response, - ) -} -``` - -You might also want to use SSL. You can do that with the following options. - -With `run_service_ssl`: - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http/response -import mist - -pub fn main() { - let assert Ok(_) = - mist.run_service_ssl( - port: 8080, - certfile: "/path/to/server.crt", - keyfile: "/path/to/server.key", - handler: fn(_req) { - response.new(200) - |> response.set_body(bit_builder.from_bit_string(<< - "hello, world!":utf8, - >>)) - }, - max_body_limit: 4_000_000 - ) - process.sleep_forever() -} -``` - -With `serve_ssl`: - -```gleam -pub fn main() { - let assert Ok(_) = - mist.serve_ssl( - port: 8080, - certfile: "...", - keyfile: "...", - mist.handler_func(fn(req) { - todo - } - ) - // ... -} -``` - -There is support for sending files as well. This uses the `file:sendfile` erlang -method under the hood. - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http/request.{Request} -import gleam/http/response -import gleam/string -import mist - -pub fn main() { - let asset_root = "..." - let assert Ok(_) = - mist.serve( - 8080, - mist.handler_func(fn(req: Request(Body)) { - let not_found = - response.new(404) - |> mist.empty_response - case request.path_segments(req) { - ["static", ..path] -> { - // verify, validate, etc - let file_path = - path - |> string.join("/") - |> string.append("/", _) - response.new(200) - |> mist.file_response(asset_root <> file_path) - |> result.unwrap(not_found) - } - _ -> not_found - } - }), - ) - process.sleep_forever() -} -``` - -You can return chunked responses using the `mist.{chunked_response}` method. -This takes an `Iterator(BitBuilder)` and handles sending the initial -response, and subsequent chunks in the proper format as they are emitted from -the iterator. The iterator must be finite. - -If you need something a little more complex or custom, you can always use the -helpers exported by the various `glisten`/`mist` modules. - -## Benchmarks - -These are currently located [here](https://github.com/rawhat/http-benchmarks) diff --git a/test-community-packages-javascript/build/packages/mist/gleam.toml b/test-community-packages-javascript/build/packages/mist/gleam.toml deleted file mode 100644 index 91c326f0ca4..00000000000 --- a/test-community-packages-javascript/build/packages/mist/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "mist" -version = "0.11.0" - -licences = ["Apache-2.0"] -description = "a misty Gleam web server" -repository = { type = "github", user = "rawhat", repo = "mist" } - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_erlang = "~> 0.18" -gleam_http = "~> 3.2" -gleam_otp = "~> 0.5" -glisten = "~> 0.7" - -[dev-dependencies] -gleeunit = "~> 0.10" -gleam_hackney = "~> 1.0" diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl deleted file mode 100644 index c49d5eace0b..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(response, { - response :: gleam@http@response:response(mist@internal@http:http_response_body()) -}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl deleted file mode 100644 index 4dc61ad70a9..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(state, { - idle_timer :: gleam@option:option(gleam@erlang@process:timer()), - upgraded_handler :: gleam@option:option(mist@internal@websocket:websocket_handler()) -}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl deleted file mode 100644 index 95dd5e515b9..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl +++ /dev/null @@ -1 +0,0 @@ --record(buffer, {remaining :: integer(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl deleted file mode 100644 index ce21939a44f..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(file_body, { - file_descriptor :: mist@internal@file:file_descriptor(), - content_type :: binary(), - offset :: integer(), - length :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl deleted file mode 100644 index b58f506cc3a..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl +++ /dev/null @@ -1 +0,0 @@ --record(read, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl deleted file mode 100644 index 204cebd84f7..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unread, {rest :: bitstring(), socket :: glisten@socket:socket()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl deleted file mode 100644 index 4d0a2f59f4a..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(binary_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl deleted file mode 100644 index f44c5b4e905..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl +++ /dev/null @@ -1 +0,0 @@ --record(binary_message, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl deleted file mode 100644 index ec07ce26727..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(close_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl deleted file mode 100644 index eb73aeab1f8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ping_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl deleted file mode 100644 index c55a2aa1fc9..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(pong_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl deleted file mode 100644 index 25def5fbb71..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(text_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl deleted file mode 100644 index c4cf5176528..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl +++ /dev/null @@ -1 +0,0 @@ --record(text_message, {data :: binary()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl deleted file mode 100644 index 00dd595dba4..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(websocket_handler, { - on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - handler :: fun((mist@internal@websocket:message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, - nil} | - {error, nil}) -}). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.app.src b/test-community-packages-javascript/build/packages/mist/src/mist.app.src deleted file mode 100644 index 9cd4bf452a0..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist.app.src +++ /dev/null @@ -1,20 +0,0 @@ -{application, mist, [ - {vsn, "0.11.0"}, - {applications, [gleam_erlang, - gleam_hackney, - gleam_http, - gleam_otp, - gleam_stdlib, - gleeunit, - glisten]}, - {description, "a misty Gleam web server"}, - {modules, [mist, - mist@internal@encoder, - mist@internal@file, - mist@internal@handler, - mist@internal@http, - mist@internal@logger, - mist@internal@websocket, - mist@websocket]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.erl b/test-community-packages-javascript/build/packages/mist/src/mist.erl deleted file mode 100644 index c5e34db8e56..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist.erl +++ /dev/null @@ -1,116 +0,0 @@ --module(mist). --compile([no_auto_import, nowarn_unused_vars]). - --export([run_service/3, run_service_ssl/5, serve/2, serve_ssl/4, handler_func/1, read_body/1, upgrade/1, empty_response/1, bit_builder_response/2, file_response/3, chunked_response/2]). - --spec run_service( - integer(), - fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - integer() -) -> {ok, nil} | {error, glisten:start_error()}. -run_service(Port, Handler, Max_body_limit) -> - _pipe = Handler, - _pipe@1 = mist@internal@handler:with(_pipe, Max_body_limit), - _pipe@2 = glisten@acceptor:new_pool_with_data( - _pipe@1, - mist@internal@handler:new_state() - ), - glisten:serve(Port, _pipe@2). - --spec run_service_ssl( - integer(), - binary(), - binary(), - fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - integer() -) -> {ok, nil} | {error, glisten:start_error()}. -run_service_ssl(Port, Certfile, Keyfile, Handler, Max_body_limit) -> - _pipe = Handler, - _pipe@1 = mist@internal@handler:with(_pipe, Max_body_limit), - _pipe@2 = glisten@acceptor:new_pool_with_data( - _pipe@1, - mist@internal@handler:new_state() - ), - glisten:serve_ssl(Port, Certfile, Keyfile, _pipe@2). - --spec serve( - integer(), - fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))) -) -> {ok, nil} | {error, glisten:start_error()}. -serve(Port, Handler) -> - _pipe = Handler, - _pipe@1 = glisten@acceptor:new_pool_with_data( - _pipe, - mist@internal@handler:new_state() - ), - glisten:serve(Port, _pipe@1). - --spec serve_ssl( - integer(), - binary(), - binary(), - fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))) -) -> {ok, nil} | {error, glisten:start_error()}. -serve_ssl(Port, Certfile, Keyfile, Handler) -> - _pipe = Handler, - _pipe@1 = glisten@acceptor:new_pool_with_data( - _pipe, - mist@internal@handler:new_state() - ), - glisten:serve_ssl(Port, Certfile, Keyfile, _pipe@1). - --spec handler_func( - fun((gleam@http@request:request(mist@internal@http:body())) -> mist@internal@handler:handler_response()) -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))). -handler_func(Handler) -> - mist@internal@handler:with_func(Handler). - --spec read_body(gleam@http@request:request(mist@internal@http:body())) -> {ok, - gleam@http@request:request(bitstring())} | - {error, mist@internal@http:decode_error()}. -read_body(Req) -> - mist@internal@http:read_body(Req). - --spec upgrade(mist@internal@websocket:websocket_handler()) -> mist@internal@handler:handler_response(). -upgrade(Websocket_handler) -> - {upgrade, Websocket_handler}. - --spec empty_response(gleam@http@response:response(any())) -> mist@internal@handler:handler_response(). -empty_response(Resp) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body( - _pipe, - {bit_builder_body, gleam@bit_builder:new()} - ), - {response, _pipe@1}. - --spec bit_builder_response( - gleam@http@response:response(any()), - gleam@bit_builder:bit_builder() -) -> mist@internal@handler:handler_response(). -bit_builder_response(Resp, Data) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body(_pipe, {bit_builder_body, Data}), - {response, _pipe@1}. - --spec file_response(gleam@http@response:response(any()), binary(), binary()) -> {ok, - mist@internal@handler:handler_response()} | - {error, mist@internal@file:file_error()}. -file_response(Resp, Path, Content_type) -> - File_path = gleam@bit_string:from_string(Path), - Size = filelib:file_size(File_path), - gleam@result:map(mist_ffi:file_open(File_path), fun(Fd) -> _pipe = Resp, - _pipe@1 = gleam@http@response:set_body( - _pipe, - {file_body, Fd, Content_type, 0, Size} - ), - {response, _pipe@1} end). - --spec chunked_response( - gleam@http@response:response(any()), - gleam@iterator:iterator(gleam@bit_builder:bit_builder()) -) -> mist@internal@handler:handler_response(). -chunked_response(Resp, Iter) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body(_pipe, {chunked, Iter}), - {response, _pipe@1}. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.gleam b/test-community-packages-javascript/build/packages/mist/src/mist.gleam deleted file mode 100644 index 62dd7e18ec8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist.gleam +++ /dev/null @@ -1,165 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/http/request.{Request} -import gleam/http/response.{Response as HttpResponse} -import gleam/iterator.{Iterator} -import gleam/result -import glisten -import glisten/acceptor -import glisten/handler.{LoopFn} as glisten_handler -import mist/internal/handler.{ - HandlerResponse, Response as MistResponse, State, Upgrade, -} -import mist/internal/http.{BitBuilderBody, Body as HTTPBody, Chunked, FileBody} -import mist/internal/file.{FileError} -import mist/internal/websocket.{WebsocketHandler} - -/// This type reflects whether the body has been read from the socket yet. -pub type Body = - HTTPBody - -/// Mist supports `BitBuilder`, `FileBody`, and `Chunked` response types. The -/// helper methods provided can generate these from a `gleam/http/response` -/// Response. This type is re-exported for pulling specific handlers out into -/// separate functions. -pub type Response = - HandlerResponse - -/// Runs an HTTP Request->Response server at the given port, with your defined -/// handler. This will automatically read the full body contents up to the -/// specified `max_body_limit` in bytes. If you'd prefer to have finer-grain -/// control over this behavior, consider using `mist.serve`. -pub fn run_service( - port: Int, - handler: handler.Handler, - max_body_limit max_body_limit: Int, -) -> Result(Nil, glisten.StartError) { - handler - |> handler.with(max_body_limit) - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve(port, _) -} - -/// Similar setup and behavior to `run_service`, but instead takes in the SSL -/// certificate/key and serves over HTTPS. -pub fn run_service_ssl( - port port: Int, - certfile certfile: String, - keyfile keyfile: String, - handler handler: handler.Handler, - max_body_limit max_body_limit: Int, -) -> Result(Nil, glisten.StartError) { - handler - |> handler.with(max_body_limit) - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve_ssl( - port: port, - certfile: certfile, - keyfile: keyfile, - with_pool: _, - ) -} - -/// Slightly more flexible alternative to `run_service`. This allows hooking -/// into the `mist.handler_func` method. Note that the request body -/// will not be automatically read. You will need to call `mist.read_body`. -/// Ensure that this is only called _once_ per request. -pub fn serve( - port port: Int, - handler handler: LoopFn(State), -) -> Result(Nil, glisten.StartError) { - handler - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve(port, _) -} - -/// Similar to the `run_service` method, `serve` also has a similar SSL method. -pub fn serve_ssl( - port port: Int, - certfile certfile: String, - keyfile keyfile: String, - handler handler: LoopFn(State), -) -> Result(Nil, glisten.StartError) { - handler - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve_ssl( - port: port, - certfile: certfile, - keyfile: keyfile, - with_pool: _, - ) -} - -/// Handles converting the mist `Response` type into a gleam HTTP Response. Use -/// this when calling `mist.serve` to start your application. -pub fn handler_func( - handler: handler.HandlerFunc, -) -> glisten_handler.LoopFn(handler.State) { - handler.with_func(handler) -} - -/// When using `mist.serve`, the body is not automatically read. You can -/// inspect content headers to determine whether to read the body or not. -/// This function will pull the content from the sender. It gives back a -/// `Request(BitString)` containing the body. This return value should be -/// treated as replacing the initial request. Do not attempt to call this -/// method multiple times on the same request. -pub fn read_body( - req: Request(Body), -) -> Result(Request(BitString), http.DecodeError) { - http.read_body(req) -} - -/// A websocket handler is created using the `websocket.with_handler` -/// method. This function enables the mist HTTP layer to build the properly -/// formatted websocket upgrade response. -pub fn upgrade(websocket_handler: WebsocketHandler) -> Response { - Upgrade(websocket_handler) -} - -/// `mist.serve` expects the mist Response type, rather than the `gleam/http` -/// Response. When returning a response with no body, this will convert the -/// type. Note that any previously set response body will be removed before -/// sending. -pub fn empty_response(resp: HttpResponse(a)) -> Response { - resp - |> response.set_body(BitBuilderBody(bit_builder.new())) - |> MistResponse -} - -/// The mist runtime only supports sending BitBuilder types, or files (see -/// below). This method will erase any pre-existing response body. -pub fn bit_builder_response(resp: HttpResponse(a), data: BitBuilder) -> Response { - resp - |> response.set_body(BitBuilderBody(data)) - |> MistResponse -} - -/// This is a more generally optimized method for returning files to a client. -/// It's a light wrapper around Erlang's `file:sendfile/5` method. The error -/// can be matched on with `mist/file.{FileError}` if custom behavior is desired -/// for various cases. The size of the file will be added to the -/// `content-length` header field. -pub fn file_response( - resp: HttpResponse(a), - path: String, - content_type: String, -) -> Result(Response, FileError) { - let file_path = bit_string.from_string(path) - let size = file.size(file_path) - use fd <- result.map(file.open(file_path)) - resp - |> response.set_body(FileBody(fd, content_type, 0, size)) - |> MistResponse -} - -/// You can send chunks of responses from an iterator. The iterator must -/// complete. -pub fn chunked_response( - resp: HttpResponse(a), - iter: Iterator(BitBuilder), -) -> Response { - resp - |> response.set_body(Chunked(iter)) - |> MistResponse -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam deleted file mode 100644 index 95e529ee6fc..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam +++ /dev/null @@ -1,104 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/http.{Header} -import gleam/http/response.{Response} -import gleam/int -import gleam/list - -/// Turns an HTTP response into a TCP message -pub fn to_bit_builder(resp: Response(BitBuilder)) -> BitBuilder { - resp.status - |> response_builder(resp.headers) - |> bit_builder.append_builder(resp.body) -} - -pub fn response_builder(status: Int, headers: List(Header)) -> BitBuilder { - let status_string = - status - |> int.to_string - |> bit_builder.from_string - |> bit_builder.append(<<" ":utf8>>) - |> bit_builder.append(status_to_bit_string(status)) - - bit_builder.new() - |> bit_builder.append(<<"HTTP/1.1 ":utf8>>) - |> bit_builder.append_builder(status_string) - |> bit_builder.append(<<"\r\n":utf8>>) - |> bit_builder.append_builder(encode_headers(headers)) - |> bit_builder.append(<<"\r\n":utf8>>) -} - -pub fn status_to_bit_string(status: Int) -> BitString { - // Obviously nowhere near exhaustive... - case status { - 100 -> <<"Continue":utf8>> - 101 -> <<"Switching Protocols":utf8>> - 103 -> <<"Early Hints":utf8>> - 200 -> <<"OK":utf8>> - 201 -> <<"Created":utf8>> - 202 -> <<"Accepted":utf8>> - 203 -> <<"Non-Authoritative Information":utf8>> - 204 -> <<"No Content":utf8>> - 205 -> <<"Reset Content":utf8>> - 206 -> <<"Partial Content":utf8>> - 300 -> <<"Multiple Choices":utf8>> - 301 -> <<"Moved Permanently":utf8>> - 302 -> <<"Found":utf8>> - 303 -> <<"See Other":utf8>> - 304 -> <<"Not Modified":utf8>> - 307 -> <<"Temporary Redirect":utf8>> - 308 -> <<"Permanent Redirect":utf8>> - 400 -> <<"Bad Request":utf8>> - 401 -> <<"Unauthorized":utf8>> - 402 -> <<"Payment Required":utf8>> - 403 -> <<"Forbidden":utf8>> - 404 -> <<"Not Found":utf8>> - 405 -> <<"Method Not Allowed":utf8>> - 406 -> <<"Not Acceptable":utf8>> - 407 -> <<"Proxy Authentication Required":utf8>> - 408 -> <<"Request Timeout":utf8>> - 409 -> <<"Conflict":utf8>> - 410 -> <<"Gone":utf8>> - 411 -> <<"Length Required":utf8>> - 412 -> <<"Precondition Failed":utf8>> - 413 -> <<"Payload Too Large":utf8>> - 414 -> <<"URI Too Long":utf8>> - 415 -> <<"Unsupported Media Type":utf8>> - 416 -> <<"Range Not Satisfiable":utf8>> - 417 -> <<"Expectation Failed":utf8>> - 418 -> <<"I'm a teapot":utf8>> - 422 -> <<"Unprocessable Entity":utf8>> - 425 -> <<"Too Early":utf8>> - 426 -> <<"Upgrade Required":utf8>> - 428 -> <<"Precondition Required":utf8>> - 429 -> <<"Too Many Requests":utf8>> - 431 -> <<"Request Header Fields Too Large":utf8>> - 451 -> <<"Unavailable For Legal Reasons":utf8>> - 500 -> <<"Internal Server Error":utf8>> - 501 -> <<"Not Implemented":utf8>> - 502 -> <<"Bad Gateway":utf8>> - 503 -> <<"Service Unavailable":utf8>> - 504 -> <<"Gateway Timeout":utf8>> - 505 -> <<"HTTP Version Not Supported":utf8>> - 506 -> <<"Variant Also Negotiates":utf8>> - 507 -> <<"Insufficient Storage":utf8>> - 508 -> <<"Loop Detected":utf8>> - 510 -> <<"Not Extended":utf8>> - 511 -> <<"Network Authentication Required":utf8>> - } -} - -pub fn encode_headers(headers: List(Header)) -> BitBuilder { - list.fold( - headers, - bit_builder.new(), - fn(builder, tup) { - let #(header, value) = tup - - builder - |> bit_builder.append_string(header) - |> bit_builder.append(<<": ":utf8>>) - |> bit_builder.append_string(value) - |> bit_builder.append(<<"\r\n":utf8>>) - }, - ) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam deleted file mode 100644 index 9783db1b2d0..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam +++ /dev/null @@ -1,26 +0,0 @@ -import gleam/erlang/atom.{Atom} -import glisten/socket.{Socket} - -pub external type FileDescriptor - -pub external fn size(path: BitString) -> Int = - "filelib" "file_size" - -pub external fn sendfile( - file_descriptor: FileDescriptor, - socket: Socket, - offset: Int, - bytes: Int, - options: List(a), -) -> Result(Int, Atom) = - "file" "sendfile" - -pub type FileError { - IsDir - NoAccess - NoEntry - UnknownFileError -} - -pub external fn open(file: BitString) -> Result(FileDescriptor, FileError) = - "mist_ffi" "file_open" diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam deleted file mode 100644 index 1f5ea1bbc78..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam +++ /dev/null @@ -1,350 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/dynamic -import gleam/erlang.{Errored, Exited, Thrown, rescue} -import gleam/erlang/process -import gleam/http/request.{Request} -import gleam/http/response -import gleam/int -import gleam/iterator.{Iterator} -import gleam/option.{None, Option, Some} -import gleam/otp/actor -import gleam/result -import glisten/handler.{Close, LoopFn, LoopState} -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} -import mist/internal/encoder -import mist/internal/file -import mist/internal/http.{ - BitBuilderBody, Body, Chunked, DecodeError, DiscardPacket, FileBody, - HttpResponseBody, -} -import mist/internal/logger -import mist/internal/websocket - -pub type Handler = - fn(request.Request(BitString)) -> response.Response(BitBuilder) - -pub type HandlerResponse { - Response(response: response.Response(HttpResponseBody)) - Upgrade(websocket.WebsocketHandler) -} - -pub type HandlerFunc = - fn(Request(Body)) -> HandlerResponse - -pub type HandlerError { - InvalidRequest(DecodeError) - NotFound -} - -const stop_normal = actor.Stop(process.Normal) - -pub type State { - State( - idle_timer: Option(process.Timer), - upgraded_handler: Option(websocket.WebsocketHandler), - ) -} - -pub fn new_state() -> State { - State(None, None) -} - -/// This is a more flexible handler. It will allow you to upgrade a connection -/// to a websocket connection, or deal with a regular HTTP req->resp workflow. -pub fn with_func(handler: HandlerFunc) -> LoopFn(State) { - handler.func(fn(msg, socket_state: LoopState(State)) { - let LoopState(socket, transport: transport, data: state, ..) = socket_state - case state.upgraded_handler { - Some(ws_handler) -> - handle_websocket_message(socket_state, ws_handler, msg) - None -> - { - let _ = case state.idle_timer { - Some(t) -> process.cancel_timer(t) - _ -> process.TimerNotFound - } - msg - |> http.parse_request(socket, transport) - |> result.map_error(fn(err) { - case err { - DiscardPacket -> Nil - _ -> { - logger.error(err) - let _ = transport.close(socket) - Nil - } - } - }) - |> result.replace_error(stop_normal) - |> result.then(fn(req) { - rescue(fn() { handler(req) }) - |> result.map(fn(resp) { #(req, resp) }) - |> result.map_error(log_and_error( - _, - socket_state.socket, - socket_state.transport, - )) - }) - |> result.map(fn(req_resp) { - let #(req, response) = req_resp - case response { - Response( - response: response.Response(body: BitBuilderBody(body), ..) as resp, - ) -> handle_bit_builder_body(resp, body, socket_state) - Response( - response: response.Response(body: Chunked(body), ..) as resp, - ) -> handle_chunked_body(resp, body, socket_state) - Response( - response: response.Response(body: FileBody(..), ..) as resp, - ) -> handle_file_body(resp, socket_state) - Upgrade(with_handler) -> - handle_upgrade(req, with_handler, socket_state) - } - }) - } - |> result.unwrap_both - } - }) -} - -fn handle_websocket_message( - state: LoopState(State), - handler: websocket.WebsocketHandler, - msg: BitString, -) -> actor.Next(LoopState(State)) { - case websocket.frame_from_message(state.socket, state.transport, msg) { - Ok(websocket.PingFrame(_, _)) -> { - let assert Ok(_) = - state.transport.send( - state.socket, - websocket.frame_to_bit_builder(websocket.PongFrame(0, <<>>)), - ) - actor.Continue(state) - } - Ok(websocket.CloseFrame(..) as frame) -> { - let assert Ok(_) = - state.transport.send( - state.socket, - websocket.frame_to_bit_builder(frame), - ) - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - actor.Stop(process.Normal) - } - Ok(websocket.PongFrame(..)) -> stop_normal - Ok(frame) -> - case frame { - websocket.TextFrame(_length, payload) -> { - let assert Ok(msg) = bit_string.to_string(payload) - websocket.TextMessage(msg) - } - // NOTE: this doesn't need to be exhaustive since we already - // cover the cases above - _frame -> websocket.BinaryMessage(frame.payload) - } - |> fn(ws_msg) { rescue(fn() { handler.handler(ws_msg, state.sender) }) } - |> result.replace(actor.Continue(state)) - |> result.map_error(fn(err) { - logger.error(err) - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - err - }) - |> result.replace_error(stop_normal) - |> result.unwrap_both - Error(_) -> { - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - // TODO: not normal - stop_normal - } - } -} - -fn log_and_error( - error: erlang.Crash, - socket: Socket, - transport: Transport, -) -> actor.Next(LoopState(State)) { - case error { - Exited(msg) | Thrown(msg) | Errored(msg) -> { - logger.error(error) - response.new(500) - |> response.set_body(bit_builder.from_bit_string(<< - "Internal Server Error":utf8, - >>)) - |> response.prepend_header("content-length", "21") - |> http.add_default_headers - |> encoder.to_bit_builder - |> transport.send(socket, _) - let _ = transport.close(socket) - actor.Stop(process.Abnormal(dynamic.unsafe_coerce(msg))) - } - } -} - -fn handle_bit_builder_body( - resp: response.Response(HttpResponseBody), - body: BitBuilder, - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - resp - |> response.set_body(body) - |> http.add_default_headers - |> encoder.to_bit_builder - |> state.transport.send(state.socket, _) - |> result.map(fn(_sent) { - // If the handler explicitly says to close the connection, we should - // probably listen to them - case response.get_header(resp, "connection") { - Ok("close") -> { - let _ = state.transport.close(state.socket) - stop_normal - } - _ -> { - // TODO: this should be a configuration - let timer = process.send_after(state.sender, 10_000, Close) - actor.Continue( - LoopState(..state, data: State(..state.data, idle_timer: Some(timer))), - ) - } - } - }) - |> result.replace_error(stop_normal) - |> result.unwrap_both -} - -external fn integer_to_list(int: Int, base: Int) -> String = - "erlang" "integer_to_list" - -fn int_to_hex(int: Int) -> String { - integer_to_list(int, 16) -} - -fn handle_chunked_body( - resp: response.Response(HttpResponseBody), - body: Iterator(BitBuilder), - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - let headers = [#("transfer-encoding", "chunked"), ..resp.headers] - let initial_payload = encoder.response_builder(resp.status, headers) - - state.transport.send(state.socket, initial_payload) - |> result.then(fn(_ok) { - body - |> iterator.append(iterator.from_list([bit_builder.new()])) - |> iterator.try_fold( - Nil, - fn(_prev, chunk) { - let size = bit_builder.byte_size(chunk) - let encoded = - size - |> int_to_hex - |> bit_builder.from_string - |> bit_builder.append_string("\r\n") - |> bit_builder.append_builder(chunk) - |> bit_builder.append_string("\r\n") - - state.transport.send(state.socket, encoded) - }, - ) - }) - |> result.replace(actor.Continue(state)) - |> result.unwrap(stop_normal) -} - -fn handle_file_body( - resp: response.Response(HttpResponseBody), - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - let assert FileBody(file_descriptor, content_type, offset, length) = resp.body - resp - |> response.prepend_header("content-length", int.to_string(length - offset)) - |> response.prepend_header("content-type", content_type) - |> response.set_body(bit_builder.new()) - |> fn(r: response.Response(BitBuilder)) { - encoder.response_builder(resp.status, r.headers) - } - |> state.transport.send(state.socket, _) - |> result.map(fn(_) { - file.sendfile(file_descriptor, state.socket, offset, length, []) - }) - |> result.replace(actor.Continue(state)) - // TODO: not normal - |> result.replace_error(stop_normal) - |> result.unwrap_both -} - -fn handle_upgrade( - req: Request(Body), - handler: websocket.WebsocketHandler, - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - req - |> http.upgrade(state.socket, state.transport, _) - |> result.map(fn(_nil) { - let _ = case handler.on_init { - Some(func) -> func(state.sender) - _ -> Nil - } - }) - |> result.replace(actor.Continue( - LoopState( - ..state, - data: State(..state.data, upgraded_handler: Some(handler)), - ), - )) - // TODO: not normal - |> result.replace_error(stop_normal) - |> result.unwrap_both -} - -/// Creates a standard HTTP handler service to pass to `mist.serve` -pub fn with(handler: Handler, max_body_limit: Int) -> LoopFn(State) { - let bad_request = - response.new(400) - |> response.set_body(bit_builder.new()) - with_func(fn(req) { - case - request.get_header(req, "content-length"), - request.get_header(req, "transfer-encoding") - { - Ok("0"), _ | Error(Nil), Error(Nil) -> - req - |> request.set_body(<<>>) - |> handler - _, Ok("chunked") -> - req - |> http.read_body - |> result.map(handler) - |> result.unwrap(bad_request) - Ok(size), _ -> - size - |> int.parse - |> result.map(fn(size) { - case size > max_body_limit { - True -> - response.new(413) - |> response.set_body(bit_builder.new()) - |> response.prepend_header("connection", "close") - False -> - req - |> http.read_body - |> result.map(handler) - |> result.unwrap(bad_request) - } - }) - |> result.unwrap(bad_request) - } - |> response.map(BitBuilderBody) - |> Response - }) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam deleted file mode 100644 index c845487a3a8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam +++ /dev/null @@ -1,393 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/charlist.{Charlist} -import gleam/http/request.{Request} -import gleam/http/response.{Response} -import gleam/http -import gleam/int -import gleam/iterator.{Iterator} -import gleam/list -import gleam/map.{Map} -import gleam/option.{Option} -import gleam/pair -import gleam/result -import gleam/string -import gleam/uri -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} -import mist/internal/encoder -import mist/internal/file -import mist/internal/websocket - -pub type PacketType { - Http - HttphBin - HttpBin -} - -pub type HttpUri { - AbsPath(BitString) -} - -pub type HttpPacket { - HttpRequest(Dynamic, HttpUri, #(Int, Int)) - HttpHeader(Int, Atom, BitString, BitString) -} - -pub type DecodedPacket { - BinaryData(HttpPacket, BitString) - EndOfHeaders(BitString) - MoreData(Option(Int)) -} - -pub type DecodeError { - MalformedRequest - InvalidMethod - InvalidPath - UnknownHeader - UnknownMethod - // TODO: better name? - InvalidBody - DiscardPacket -} - -external fn decode_packet( - packet_type: PacketType, - packet: BitString, - options: List(a), -) -> Result(DecodedPacket, DecodeError) = - "mist_ffi" "decode_packet" - -pub fn from_header(value: BitString) -> String { - let assert Ok(value) = bit_string.to_string(value) - - string.lowercase(value) -} - -pub type Buffer { - Buffer(remaining: Int, data: BitString) -} - -pub fn parse_headers( - bs: BitString, - socket: Socket, - transport: Transport, - headers: Map(String, String), -) -> Result(#(Map(String, String), BitString), DecodeError) { - case decode_packet(HttphBin, bs, []) { - Ok(BinaryData(HttpHeader(_, _field, field, value), rest)) -> { - let field = from_header(field) - let assert Ok(value) = bit_string.to_string(value) - headers - |> map.insert(field, value) - |> parse_headers(rest, socket, transport, _) - } - Ok(EndOfHeaders(rest)) -> Ok(#(headers, rest)) - Ok(MoreData(size)) -> { - let amount_to_read = option.unwrap(size, 0) - use next <- result.then(read_data( - socket, - transport, - Buffer(amount_to_read, bs), - UnknownHeader, - )) - parse_headers(next, socket, transport, headers) - } - _other -> Error(UnknownHeader) - } -} - -pub fn read_data( - socket: Socket, - transport: Transport, - buffer: Buffer, - error: DecodeError, -) -> Result(BitString, DecodeError) { - // TODO: don't hard-code these, probably - let to_read = int.min(buffer.remaining, 1_000_000) - let timeout = 15_000 - use data <- result.then( - socket - |> transport.receive_timeout(to_read, timeout) - |> result.replace_error(error), - ) - let next_buffer = - Buffer( - remaining: buffer.remaining - to_read, - data: <<buffer.data:bit_string, data:bit_string>>, - ) - - case next_buffer.remaining > 0 { - True -> read_data(socket, transport, next_buffer, error) - False -> Ok(next_buffer.data) - } -} - -external fn binary_match( - source: BitString, - pattern: BitString, -) -> Result(#(Int, Int), Nil) = - "mist_ffi" "binary_match" - -external fn string_to_int(string: Charlist, base: Int) -> Result(Int, Nil) = - "mist_ffi" "string_to_int" - -const crnl = <<13:int, 10:int>> - -fn read_chunk( - socket: Socket, - transport: Transport, - buffer: Buffer, - body: BitBuilder, -) -> Result(BitBuilder, DecodeError) { - case buffer.data, binary_match(buffer.data, crnl) { - _, Ok(#(offset, _)) -> { - let assert << - chunk:binary-size(offset), - _return:int, - _newline:int, - rest:binary, - >> = buffer.data - use chunk_size <- result.then( - chunk - |> bit_string.to_string - |> result.map(charlist.from_string) - |> result.replace_error(InvalidBody), - ) - use size <- result.then( - string_to_int(chunk_size, 16) - |> result.replace_error(InvalidBody), - ) - case size { - 0 -> Ok(body) - size -> - case rest { - <<next_chunk:binary-size(size), 13:int, 10:int, rest:binary>> -> - read_chunk( - socket, - transport, - Buffer(0, rest), - bit_builder.append(body, next_chunk), - ) - _ -> { - use next <- result.then(read_data( - socket, - transport, - Buffer(0, buffer.data), - InvalidBody, - )) - read_chunk(socket, transport, Buffer(0, next), body) - } - } - } - } - <<>>, _ -> { - use next <- result.then(read_data( - socket, - transport, - Buffer(0, buffer.data), - InvalidBody, - )) - read_chunk(socket, transport, Buffer(0, next), body) - } - _, Error(Nil) -> Error(InvalidBody) - } -} - -/// Turns the TCP message into an HTTP request -pub fn parse_request( - bs: BitString, - socket: Socket, - transport: Transport, -) -> Result(request.Request(Body), DecodeError) { - case decode_packet(HttpBin, bs, []) { - Ok(BinaryData(HttpRequest(http_method, AbsPath(path), _version), rest)) -> { - use method <- result.then( - http_method - |> atom.from_dynamic - |> result.map(atom.to_string) - |> result.or(dynamic.string(http_method)) - |> result.nil_error - |> result.then(http.parse_method) - |> result.replace_error(UnknownMethod), - ) - use #(headers, rest) <- result.then(parse_headers( - rest, - socket, - transport, - map.new(), - )) - use path <- result.then( - path - |> bit_string.to_string - |> result.replace_error(InvalidPath), - ) - let #(path, query) = case string.split(path, "?") { - [path] -> #(path, []) - [path, query_string] -> { - let query = - query_string - |> uri.parse_query - |> result.unwrap([]) - #(path, query) - } - } - let req = - request.new() - |> request.set_scheme(case transport { - transport.Ssl(..) -> http.Https - transport.Tcp(..) -> http.Http - }) - |> request.set_body(Unread(rest, socket)) - |> request.set_method(method) - |> request.set_path(path) - |> request.set_query(query) - Ok(request.Request(..req, headers: map.to_list(headers))) - } - _ -> Error(DiscardPacket) - } -} - -pub opaque type Body { - Unread(rest: BitString, socket: Socket) - Read(data: BitString) -} - -pub fn read_body(req: Request(Body)) -> Result(Request(BitString), DecodeError) { - let transport = case req.scheme { - http.Https -> transport.ssl() - http.Http -> transport.tcp() - } - case request.get_header(req, "transfer-encoding"), req.body { - Ok("chunked"), Unread(rest, socket) -> { - use chunk <- result.then(read_chunk( - socket, - transport, - Buffer(remaining: 0, data: rest), - bit_builder.new(), - )) - Ok(request.set_body(req, bit_builder.to_bit_string(chunk))) - } - _, Unread(rest, socket) -> { - let _continue = case is_continue(req) { - True -> { - let assert Ok(Nil) = - response.new(100) - |> response.set_body(bit_builder.new()) - |> encoder.to_bit_builder - |> transport.send(socket, _) - Nil - } - False -> Nil - } - let body_size = - req.headers - |> list.find(fn(tup) { pair.first(tup) == "content-length" }) - |> result.map(pair.second) - |> result.then(int.parse) - |> result.unwrap(0) - let remaining = body_size - bit_string.byte_size(rest) - case body_size, remaining { - 0, 0 -> Ok(<<>>) - 0, _n -> Ok(rest) - // is this pipelining? check for GET? - _n, 0 -> Ok(rest) - _size, _rem -> - read_data(socket, transport, Buffer(remaining, rest), InvalidBody) - } - |> result.map(request.set_body(req, _)) - |> result.replace_error(InvalidBody) - } - _, Read(_data) -> Error(InvalidBody) - } -} - -pub type HttpResponseBody { - BitBuilderBody(BitBuilder) - Chunked(Iterator(BitBuilder)) - FileBody( - file_descriptor: file.FileDescriptor, - content_type: String, - offset: Int, - length: Int, - ) -} - -pub fn upgrade_socket( - req: Request(Body), -) -> Result(Response(BitBuilder), Request(Body)) { - use _upgrade <- result.then( - request.get_header(req, "upgrade") - |> result.replace_error(req), - ) - use key <- result.then( - request.get_header(req, "sec-websocket-key") - |> result.replace_error(req), - ) - use _version <- result.then( - request.get_header(req, "sec-websocket-version") - |> result.replace_error(req), - ) - - let accept_key = websocket.parse_key(key) - - response.new(101) - |> response.set_body(bit_builder.new()) - |> response.prepend_header("Upgrade", "websocket") - |> response.prepend_header("Connection", "Upgrade") - |> response.prepend_header("Sec-WebSocket-Accept", accept_key) - |> Ok -} - -// TODO: improve this error type -pub fn upgrade( - socket: Socket, - transport: Transport, - req: Request(Body), -) -> Result(Nil, Nil) { - use resp <- result.then( - upgrade_socket(req) - |> result.nil_error, - ) - - use _sent <- result.then( - resp - |> add_default_headers - |> encoder.to_bit_builder - |> transport.send(socket, _) - |> result.nil_error, - ) - - Ok(Nil) -} - -pub fn add_default_headers(resp: Response(BitBuilder)) -> Response(BitBuilder) { - let body_size = bit_builder.byte_size(resp.body) - - let headers = - map.from_list([ - #("content-length", int.to_string(body_size)), - #("connection", "keep-alive"), - ]) - |> list.fold( - resp.headers, - _, - fn(defaults, tup) { - let #(key, value) = tup - map.insert(defaults, key, value) - }, - ) - |> map.to_list - - Response(..resp, headers: headers) -} - -fn is_continue(req: Request(Body)) -> Bool { - req.headers - |> list.find(fn(tup) { - pair.first(tup) == "expect" && pair.second(tup) == "100-continue" - }) - |> result.is_ok -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam deleted file mode 100644 index 14a31a6ce54..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam +++ /dev/null @@ -1,8 +0,0 @@ -import gleam/erlang/charlist.{Charlist} - -external fn log_error(format: Charlist, data: any) -> Nil = - "logger" "error" - -pub fn error(data: any) -> Nil { - log_error(charlist.from_string("~tp"), [data]) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam deleted file mode 100644 index 50318f2c6fe..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam +++ /dev/null @@ -1,167 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/erlang/process.{Subject} -import gleam/list -import gleam/option.{Option} -import gleam/string -import glisten/handler.{HandlerMessage} -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} - -pub type Message { - BinaryMessage(data: BitString) - TextMessage(data: String) -} - -pub type Handler = - fn(Message, Subject(HandlerMessage)) -> Result(Nil, Nil) - -// TODO: there are other message types, AND ALSO will need to buffer across -// multiple frames, potentially -pub type Frame { - // TODO: should this include data? - CloseFrame(payload_length: Int, payload: BitString) - TextFrame(payload_length: Int, payload: BitString) - BinaryFrame(payload_length: Int, payload: BitString) - // We don't care about basicaly everything else for now - PingFrame(payload_length: Int, payload: BitString) - PongFrame(payload_length: Int, payload: BitString) -} - -external fn crypto_exor(a: BitString, b: BitString) -> BitString = - "crypto" "exor" - -fn unmask_data( - data: BitString, - masks: List(BitString), - index: Int, - resp: BitString, -) -> BitString { - case data { - <<>> -> resp - <<masked:bit_string-size(8), rest:bit_string>> -> { - let assert Ok(mask_value) = list.at(masks, index % 4) - let unmasked = crypto_exor(mask_value, masked) - unmask_data( - rest, - masks, - index + 1, - <<resp:bit_string, unmasked:bit_string>>, - ) - } - } -} - -pub fn frame_from_message( - socket: Socket, - transport: Transport, - message: BitString, -) -> Result(Frame, Nil) { - let assert <<_fin:1, rest:bit_string>> = message - let assert <<_reserved:3, rest:bit_string>> = rest - let assert <<opcode:int-size(4), rest:bit_string>> = rest - case opcode { - 1 | 2 -> { - // mask - let assert <<1:1, rest:bit_string>> = rest - let assert <<payload_length:int-size(7), rest:bit_string>> = rest - let #(payload_length, rest) = case payload_length { - 126 -> { - let assert <<length:int-size(16), rest:bit_string>> = rest - #(length, rest) - } - 127 -> { - let assert <<length:int-size(64), rest:bit_string>> = rest - #(length, rest) - } - _ -> #(payload_length, rest) - } - let assert << - mask1:bit_string-size(8), - mask2:bit_string-size(8), - mask3:bit_string-size(8), - mask4:bit_string-size(8), - rest:bit_string, - >> = rest - let data = case payload_length - bit_string.byte_size(rest) { - 0 -> unmask_data(rest, [mask1, mask2, mask3, mask4], 0, <<>>) - need -> { - let assert Ok(needed) = transport.receive(socket, need) - rest - |> bit_string.append(needed) - |> unmask_data([mask1, mask2, mask3, mask4], 0, <<>>) - } - } - case opcode { - 1 -> TextFrame(payload_length, data) - 2 -> BinaryFrame(payload_length, data) - } - |> Ok - } - 8 -> Ok(CloseFrame(payload_length: 0, payload: <<>>)) - } -} - -pub fn frame_to_bit_builder(frame: Frame) -> BitBuilder { - case frame { - TextFrame(payload_length, payload) -> make_frame(1, payload_length, payload) - CloseFrame(payload_length, payload) -> - make_frame(8, payload_length, payload) - BinaryFrame(payload_length, payload) -> - make_frame(2, payload_length, payload) - PongFrame(payload_length, payload) -> - make_frame(10, payload_length, payload) - PingFrame(..) -> bit_builder.from_bit_string(<<>>) - } -} - -fn make_frame(opcode: Int, length: Int, payload: BitString) -> BitBuilder { - let length_section = case length { - length if length > 65_535 -> <<127:7, length:int-size(64)>> - length if length >= 126 -> <<126:7, length:int-size(16)>> - _length -> <<length:7>> - } - - <<1:1, 0:3, opcode:4, 0:1, length_section:bit_string, payload:bit_string>> - |> bit_builder.from_bit_string -} - -pub fn to_text_frame(data: BitString) -> BitBuilder { - let size = bit_string.byte_size(data) - frame_to_bit_builder(TextFrame(size, data)) -} - -pub fn to_binary_frame(data: BitString) -> BitBuilder { - let size = bit_string.byte_size(data) - frame_to_bit_builder(BinaryFrame(size, data)) -} - -const websocket_key = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - -pub type ShaHash { - Sha -} - -pub external fn crypto_hash(hash: ShaHash, data: String) -> String = - "crypto" "hash" - -pub external fn base64_encode(data: String) -> String = - "base64" "encode" - -pub fn parse_key(key: String) -> String { - key - |> string.append(websocket_key) - |> crypto_hash(Sha, _) - |> base64_encode -} - -pub type EventHandler = - fn(Subject(HandlerMessage)) -> Nil - -pub type WebsocketHandler { - WebsocketHandler( - on_close: Option(EventHandler), - on_init: Option(EventHandler), - handler: Handler, - ) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam deleted file mode 100644 index 4205bfe793d..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam +++ /dev/null @@ -1,51 +0,0 @@ -import gleam/bit_string -import gleam/erlang/process.{Subject} -import gleam/option.{None, Some} -import glisten/handler.{HandlerMessage, SendMessage} -import mist/internal/websocket.{ - BinaryMessage, EventHandler, Handler, Message, TextMessage, WebsocketHandler, - to_binary_frame, to_text_frame, -} - -/// Helper to encapsulate the logic to send a provided message over the -/// WebSocket -pub fn send(sender: Subject(HandlerMessage), message: Message) -> Nil { - case message { - TextMessage(data) -> - data - |> bit_string.from_string - |> to_text_frame - BinaryMessage(data) -> to_binary_frame(data) - } - |> SendMessage - |> process.send(sender, _) - - Nil -} - -pub fn echo_handler( - message: Message, - sender: Subject(HandlerMessage), -) -> Result(Nil, Nil) { - let _ = send(sender, message) - - Ok(Nil) -} - -pub fn with_handler(func: Handler) -> WebsocketHandler { - WebsocketHandler(on_close: None, on_init: None, handler: func) -} - -pub fn on_init( - handler: WebsocketHandler, - func: EventHandler, -) -> WebsocketHandler { - WebsocketHandler(..handler, on_init: Some(func)) -} - -pub fn on_close( - handler: WebsocketHandler, - func: EventHandler, -) -> WebsocketHandler { - WebsocketHandler(..handler, on_close: Some(func)) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl deleted file mode 100644 index 78d65345b19..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl +++ /dev/null @@ -1,209 +0,0 @@ --module(mist@internal@encoder). --compile([no_auto_import, nowarn_unused_vars]). - --export([status_to_bit_string/1, encode_headers/1, response_builder/2, to_bit_builder/1]). - --spec status_to_bit_string(integer()) -> bitstring(). -status_to_bit_string(Status) -> - case Status of - 100 -> - <<"Continue"/utf8>>; - - 101 -> - <<"Switching Protocols"/utf8>>; - - 103 -> - <<"Early Hints"/utf8>>; - - 200 -> - <<"OK"/utf8>>; - - 201 -> - <<"Created"/utf8>>; - - 202 -> - <<"Accepted"/utf8>>; - - 203 -> - <<"Non-Authoritative Information"/utf8>>; - - 204 -> - <<"No Content"/utf8>>; - - 205 -> - <<"Reset Content"/utf8>>; - - 206 -> - <<"Partial Content"/utf8>>; - - 300 -> - <<"Multiple Choices"/utf8>>; - - 301 -> - <<"Moved Permanently"/utf8>>; - - 302 -> - <<"Found"/utf8>>; - - 303 -> - <<"See Other"/utf8>>; - - 304 -> - <<"Not Modified"/utf8>>; - - 307 -> - <<"Temporary Redirect"/utf8>>; - - 308 -> - <<"Permanent Redirect"/utf8>>; - - 400 -> - <<"Bad Request"/utf8>>; - - 401 -> - <<"Unauthorized"/utf8>>; - - 402 -> - <<"Payment Required"/utf8>>; - - 403 -> - <<"Forbidden"/utf8>>; - - 404 -> - <<"Not Found"/utf8>>; - - 405 -> - <<"Method Not Allowed"/utf8>>; - - 406 -> - <<"Not Acceptable"/utf8>>; - - 407 -> - <<"Proxy Authentication Required"/utf8>>; - - 408 -> - <<"Request Timeout"/utf8>>; - - 409 -> - <<"Conflict"/utf8>>; - - 410 -> - <<"Gone"/utf8>>; - - 411 -> - <<"Length Required"/utf8>>; - - 412 -> - <<"Precondition Failed"/utf8>>; - - 413 -> - <<"Payload Too Large"/utf8>>; - - 414 -> - <<"URI Too Long"/utf8>>; - - 415 -> - <<"Unsupported Media Type"/utf8>>; - - 416 -> - <<"Range Not Satisfiable"/utf8>>; - - 417 -> - <<"Expectation Failed"/utf8>>; - - 418 -> - <<"I'm a teapot"/utf8>>; - - 422 -> - <<"Unprocessable Entity"/utf8>>; - - 425 -> - <<"Too Early"/utf8>>; - - 426 -> - <<"Upgrade Required"/utf8>>; - - 428 -> - <<"Precondition Required"/utf8>>; - - 429 -> - <<"Too Many Requests"/utf8>>; - - 431 -> - <<"Request Header Fields Too Large"/utf8>>; - - 451 -> - <<"Unavailable For Legal Reasons"/utf8>>; - - 500 -> - <<"Internal Server Error"/utf8>>; - - 501 -> - <<"Not Implemented"/utf8>>; - - 502 -> - <<"Bad Gateway"/utf8>>; - - 503 -> - <<"Service Unavailable"/utf8>>; - - 504 -> - <<"Gateway Timeout"/utf8>>; - - 505 -> - <<"HTTP Version Not Supported"/utf8>>; - - 506 -> - <<"Variant Also Negotiates"/utf8>>; - - 507 -> - <<"Insufficient Storage"/utf8>>; - - 508 -> - <<"Loop Detected"/utf8>>; - - 510 -> - <<"Not Extended"/utf8>>; - - 511 -> - <<"Network Authentication Required"/utf8>> - end. - --spec encode_headers(list({binary(), binary()})) -> gleam@bit_builder:bit_builder(). -encode_headers(Headers) -> - gleam@list:fold( - Headers, - gleam@bit_builder:new(), - fun(Builder, Tup) -> - {Header, Value} = Tup, - _pipe = Builder, - _pipe@1 = gleam@bit_builder:append_string(_pipe, Header), - _pipe@2 = gleam@bit_builder:append(_pipe@1, <<": "/utf8>>), - _pipe@3 = gleam@bit_builder:append_string(_pipe@2, Value), - gleam@bit_builder:append(_pipe@3, <<"\r\n"/utf8>>) - end - ). - --spec response_builder(integer(), list({binary(), binary()})) -> gleam@bit_builder:bit_builder(). -response_builder(Status, Headers) -> - Status_string = begin - _pipe = Status, - _pipe@1 = gleam@int:to_string(_pipe), - _pipe@2 = gleam@bit_builder:from_string(_pipe@1), - _pipe@3 = gleam@bit_builder:append(_pipe@2, <<" "/utf8>>), - gleam@bit_builder:append(_pipe@3, status_to_bit_string(Status)) - end, - _pipe@4 = gleam@bit_builder:new(), - _pipe@5 = gleam@bit_builder:append(_pipe@4, <<"HTTP/1.1 "/utf8>>), - _pipe@6 = gleam@bit_builder:append_builder(_pipe@5, Status_string), - _pipe@7 = gleam@bit_builder:append(_pipe@6, <<"\r\n"/utf8>>), - _pipe@8 = gleam@bit_builder:append_builder(_pipe@7, encode_headers(Headers)), - gleam@bit_builder:append(_pipe@8, <<"\r\n"/utf8>>). - --spec to_bit_builder( - gleam@http@response:response(gleam@bit_builder:bit_builder()) -) -> gleam@bit_builder:bit_builder(). -to_bit_builder(Resp) -> - _pipe = erlang:element(2, Resp), - _pipe@1 = response_builder(_pipe, erlang:element(3, Resp)), - gleam@bit_builder:append_builder(_pipe@1, erlang:element(4, Resp)). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl deleted file mode 100644 index 51bd02b0819..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(mist@internal@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([size/1, sendfile/5, open/1]). --export_type([file_error/0, file_descriptor/0]). - --type file_error() :: is_dir | no_access | no_entry | unknown_file_error. - --type file_descriptor() :: any(). - --spec size(bitstring()) -> integer(). -size(Field@0) -> - filelib:file_size(Field@0). - --spec sendfile( - file_descriptor(), - glisten@socket:socket(), - integer(), - integer(), - list(any()) -) -> {ok, integer()} | {error, gleam@erlang@atom:atom_()}. -sendfile(Field@0, Field@1, Field@2, Field@3, Field@4) -> - file:sendfile(Field@0, Field@1, Field@2, Field@3, Field@4). - --spec open(bitstring()) -> {ok, file_descriptor()} | {error, file_error()}. -open(Field@0) -> - mist_ffi:file_open(Field@0). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl deleted file mode 100644 index 7b0afe0b615..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl +++ /dev/null @@ -1,577 +0,0 @@ --module(mist@internal@handler). --compile([no_auto_import, nowarn_unused_vars]). - --export([new_state/0, with_func/1, with/2]). --export_type([handler_response/0, handler_error/0, state/0]). - --type handler_response() :: {response, - gleam@http@response:response(mist@internal@http:http_response_body())} | - {upgrade, mist@internal@websocket:websocket_handler()}. - --type handler_error() :: {invalid_request, mist@internal@http:decode_error()} | - not_found. - --type state() :: {state, - gleam@option:option(gleam@erlang@process:timer()), - gleam@option:option(mist@internal@websocket:websocket_handler())}. - --spec new_state() -> state(). -new_state() -> - {state, none, none}. - --spec handle_websocket_message( - glisten@handler:loop_state(state()), - mist@internal@websocket:websocket_handler(), - bitstring() -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_websocket_message(State, Handler, Msg) -> - case mist@internal@websocket:frame_from_message( - erlang:element(2, State), - erlang:element(4, State), - Msg - ) of - {ok, {ping_frame, _, _}} -> - _assert_subject = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - mist@internal@websocket:frame_to_bit_builder( - {pong_frame, 0, <<>>} - ) - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_websocket_message"/utf8>>, - line => 119}) - end, - {continue, State}; - - {ok, {close_frame, _, _} = Frame} -> - _assert_subject@1 = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - mist@internal@websocket:frame_to_bit_builder(Frame) - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_websocket_message"/utf8>>, - line => 127}) - end, - _ = case erlang:element(2, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {ok, {pong_frame, _, _}} -> - {stop, normal}; - - {ok, Frame@1} -> - _pipe = case Frame@1 of - {text_frame, _, Payload} -> - _assert_subject@2 = gleam@bit_string:to_string(Payload), - {ok, Msg@1} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_websocket_message"/utf8>>, - line => 142}) - end, - {text_message, Msg@1}; - - _ -> - {binary_message, erlang:element(3, Frame@1)} - end, - _pipe@1 = (fun(Ws_msg) -> - gleam_erlang_ffi:rescue( - fun() -> - (erlang:element(4, Handler))( - Ws_msg, - erlang:element(3, State) - ) - end - ) - end)(_pipe), - _pipe@2 = gleam@result:replace(_pipe@1, {continue, State}), - _pipe@3 = gleam@result:map_error( - _pipe@2, - fun(Err) -> - mist@internal@logger:error(Err), - _ = case erlang:element(2, Handler) of - {some, Func@1} -> - Func@1(erlang:element(3, State)); - - _ -> - nil - end, - Err - end - ), - _pipe@4 = gleam@result:replace_error(_pipe@3, {stop, normal}), - gleam@result:unwrap_both(_pipe@4); - - {error, _} -> - _ = case erlang:element(2, Handler) of - {some, Func@2} -> - Func@2(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal} - end. - --spec log_and_error( - gleam@erlang:crash(), - glisten@socket:socket(), - glisten@socket@transport:transport() -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -log_and_error(Error, Socket, Transport) -> - case Error of - {exited, Msg} -> - mist@internal@logger:error(Error), - _pipe = gleam@http@response:new(500), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:from_bit_string( - <<"Internal Server Error"/utf8>> - ) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-length"/utf8>>, - <<"21"/utf8>> - ), - _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), - _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), - (erlang:element(11, Transport))(Socket, _pipe@4), - _ = (erlang:element(4, Transport))(Socket), - {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}}; - - {thrown, Msg} -> - mist@internal@logger:error(Error), - _pipe = gleam@http@response:new(500), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:from_bit_string( - <<"Internal Server Error"/utf8>> - ) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-length"/utf8>>, - <<"21"/utf8>> - ), - _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), - _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), - (erlang:element(11, Transport))(Socket, _pipe@4), - _ = (erlang:element(4, Transport))(Socket), - {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}}; - - {errored, Msg} -> - mist@internal@logger:error(Error), - _pipe = gleam@http@response:new(500), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:from_bit_string( - <<"Internal Server Error"/utf8>> - ) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-length"/utf8>>, - <<"21"/utf8>> - ), - _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), - _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), - (erlang:element(11, Transport))(Socket, _pipe@4), - _ = (erlang:element(4, Transport))(Socket), - {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}} - end. - --spec handle_bit_builder_body( - gleam@http@response:response(mist@internal@http:http_response_body()), - gleam@bit_builder:bit_builder(), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_bit_builder_body(Resp, Body, State) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body(_pipe, Body), - _pipe@2 = mist@internal@http:add_default_headers(_pipe@1), - _pipe@3 = mist@internal@encoder:to_bit_builder(_pipe@2), - _pipe@4 = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - _pipe@3 - ), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(_) -> - case gleam@http@response:get_header(Resp, <<"connection"/utf8>>) of - {ok, <<"close"/utf8>>} -> - _ = (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ), - {stop, normal}; - - _ -> - Timer = gleam@erlang@process:send_after( - erlang:element(3, State), - 10000, - close - ), - {continue, - erlang:setelement( - 5, - State, - erlang:setelement( - 2, - erlang:element(5, State), - {some, Timer} - ) - )} - end - end - ), - _pipe@6 = gleam@result:replace_error(_pipe@5, {stop, normal}), - gleam@result:unwrap_both(_pipe@6). - --spec handle_file_body( - gleam@http@response:response(mist@internal@http:http_response_body()), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_file_body(Resp, State) -> - _assert_subject = erlang:element(4, Resp), - {file_body, File_descriptor, Content_type, Offset, Length} = case _assert_subject of - {file_body, _, _, _, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_file_body"/utf8>>, - line => 268}) - end, - _pipe = Resp, - _pipe@1 = gleam@http@response:prepend_header( - _pipe, - <<"content-length"/utf8>>, - gleam@int:to_string(Length - Offset) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-type"/utf8>>, - Content_type - ), - _pipe@3 = gleam@http@response:set_body(_pipe@2, gleam@bit_builder:new()), - _pipe@4 = (fun(R) -> - mist@internal@encoder:response_builder( - erlang:element(2, Resp), - erlang:element(3, R) - ) - end)(_pipe@3), - _pipe@5 = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - _pipe@4 - ), - _pipe@6 = gleam@result:map( - _pipe@5, - fun(_) -> - file:sendfile( - File_descriptor, - erlang:element(2, State), - Offset, - Length, - [] - ) - end - ), - _pipe@7 = gleam@result:replace(_pipe@6, {continue, State}), - _pipe@8 = gleam@result:replace_error(_pipe@7, {stop, normal}), - gleam@result:unwrap_both(_pipe@8). - --spec handle_upgrade( - gleam@http@request:request(mist@internal@http:body()), - mist@internal@websocket:websocket_handler(), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_upgrade(Req, Handler, State) -> - _pipe = Req, - _pipe@1 = mist@internal@http:upgrade( - erlang:element(2, State), - erlang:element(4, State), - _pipe - ), - _pipe@2 = gleam@result:map( - _pipe@1, - fun(_) -> _ = case erlang:element(3, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end end - ), - _pipe@3 = gleam@result:replace( - _pipe@2, - {continue, - erlang:setelement( - 5, - State, - erlang:setelement(3, erlang:element(5, State), {some, Handler}) - )} - ), - _pipe@4 = gleam@result:replace_error(_pipe@3, {stop, normal}), - gleam@result:unwrap_both(_pipe@4). - --spec int_to_hex(integer()) -> binary(). -int_to_hex(Int) -> - erlang:integer_to_list(Int, 16). - --spec handle_chunked_body( - gleam@http@response:response(mist@internal@http:http_response_body()), - gleam@iterator:iterator(gleam@bit_builder:bit_builder()), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_chunked_body(Resp, Body, State) -> - Headers = [{<<"transfer-encoding"/utf8>>, <<"chunked"/utf8>>} | - erlang:element(3, Resp)], - Initial_payload = mist@internal@encoder:response_builder( - erlang:element(2, Resp), - Headers - ), - _pipe = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - Initial_payload - ), - _pipe@8 = gleam@result:then(_pipe, fun(_) -> _pipe@1 = Body, - _pipe@2 = gleam@iterator:append( - _pipe@1, - gleam@iterator:from_list([gleam@bit_builder:new()]) - ), - gleam@iterator:try_fold( - _pipe@2, - nil, - fun(_, Chunk) -> - Size = gleam@bit_builder:byte_size(Chunk), - Encoded = begin - _pipe@3 = Size, - _pipe@4 = int_to_hex(_pipe@3), - _pipe@5 = gleam@bit_builder:from_string(_pipe@4), - _pipe@6 = gleam@bit_builder:append_string( - _pipe@5, - <<"\r\n"/utf8>> - ), - _pipe@7 = gleam@bit_builder:append_builder( - _pipe@6, - Chunk - ), - gleam@bit_builder:append_string( - _pipe@7, - <<"\r\n"/utf8>> - ) - end, - (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - Encoded - ) - end - ) end), - _pipe@9 = gleam@result:replace(_pipe@8, {continue, State}), - gleam@result:unwrap(_pipe@9, {stop, normal}). - --spec with_func( - fun((gleam@http@request:request(mist@internal@http:body())) -> handler_response()) -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(state())) -> gleam@otp@actor:next(glisten@handler:loop_state(state()))). -with_func(Handler) -> - glisten@handler:func( - fun(Msg, Socket_state) -> - {loop_state, Socket, _, Transport, State} = Socket_state, - case erlang:element(3, State) of - {some, Ws_handler} -> - handle_websocket_message(Socket_state, Ws_handler, Msg); - - none -> - _pipe@7 = begin - _ = case erlang:element(2, State) of - {some, T} -> - gleam@erlang@process:cancel_timer(T); - - _ -> - timer_not_found - end, - _pipe = Msg, - _pipe@1 = mist@internal@http:parse_request( - _pipe, - Socket, - Transport - ), - _pipe@2 = gleam@result:map_error( - _pipe@1, - fun(Err) -> case Err of - discard_packet -> - nil; - - _ -> - mist@internal@logger:error(Err), - _ = (erlang:element(4, Transport))( - Socket - ), - nil - end end - ), - _pipe@3 = gleam@result:replace_error( - _pipe@2, - {stop, normal} - ), - _pipe@6 = gleam@result:then( - _pipe@3, - fun(Req) -> - _pipe@4 = gleam_erlang_ffi:rescue( - fun() -> Handler(Req) end - ), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(Resp) -> {Req, Resp} end - ), - gleam@result:map_error( - _pipe@5, - fun(_capture) -> - log_and_error( - _capture, - erlang:element(2, Socket_state), - erlang:element(4, Socket_state) - ) - end - ) - end - ), - gleam@result:map( - _pipe@6, - fun(Req_resp) -> - {Req@1, Response} = Req_resp, - case Response of - {response, - {response, - _, - _, - {bit_builder_body, Body}} = Resp@1} -> - handle_bit_builder_body( - Resp@1, - Body, - Socket_state - ); - - {response, - {response, _, _, {chunked, Body@1}} = Resp@2} -> - handle_chunked_body( - Resp@2, - Body@1, - Socket_state - ); - - {response, - {response, - _, - _, - {file_body, _, _, _, _}} = Resp@3} -> - handle_file_body(Resp@3, Socket_state); - - {upgrade, With_handler} -> - handle_upgrade( - Req@1, - With_handler, - Socket_state - ) - end - end - ) - end, - gleam@result:unwrap_both(_pipe@7) - end - end - ). - --spec with( - fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - integer() -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(state())) -> gleam@otp@actor:next(glisten@handler:loop_state(state()))). -with(Handler, Max_body_limit) -> - Bad_request = begin - _pipe = gleam@http@response:new(400), - gleam@http@response:set_body(_pipe, gleam@bit_builder:new()) - end, - with_func( - fun(Req) -> - _pipe@14 = case {gleam@http@request:get_header( - Req, - <<"content-length"/utf8>> - ), - gleam@http@request:get_header(Req, <<"transfer-encoding"/utf8>>)} of - {{ok, <<"0"/utf8>>}, _} -> - _pipe@1 = Req, - _pipe@2 = gleam@http@request:set_body(_pipe@1, <<>>), - Handler(_pipe@2); - - {{error, nil}, {error, nil}} -> - _pipe@1 = Req, - _pipe@2 = gleam@http@request:set_body(_pipe@1, <<>>), - Handler(_pipe@2); - - {_, {ok, <<"chunked"/utf8>>}} -> - _pipe@3 = Req, - _pipe@4 = mist@internal@http:read_body(_pipe@3), - _pipe@5 = gleam@result:map(_pipe@4, Handler), - gleam@result:unwrap(_pipe@5, Bad_request); - - {{ok, Size}, _} -> - _pipe@6 = Size, - _pipe@7 = gleam@int:parse(_pipe@6), - _pipe@13 = gleam@result:map( - _pipe@7, - fun(Size@1) -> case Size@1 > Max_body_limit of - true -> - _pipe@8 = gleam@http@response:new(413), - _pipe@9 = gleam@http@response:set_body( - _pipe@8, - gleam@bit_builder:new() - ), - gleam@http@response:prepend_header( - _pipe@9, - <<"connection"/utf8>>, - <<"close"/utf8>> - ); - - false -> - _pipe@10 = Req, - _pipe@11 = mist@internal@http:read_body( - _pipe@10 - ), - _pipe@12 = gleam@result:map( - _pipe@11, - Handler - ), - gleam@result:unwrap(_pipe@12, Bad_request) - end end - ), - gleam@result:unwrap(_pipe@13, Bad_request) - end, - _pipe@15 = gleam@http@response:map( - _pipe@14, - fun(Field@0) -> {bit_builder_body, Field@0} end - ), - {response, _pipe@15} - end - ). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl deleted file mode 100644 index aad9e7db5c8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl +++ /dev/null @@ -1,591 +0,0 @@ --module(mist@internal@http). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_header/1, upgrade_socket/1, add_default_headers/1, upgrade/3, parse_headers/4, parse_request/3, read_data/4, read_body/1]). --export_type([packet_type/0, http_uri/0, http_packet/0, decoded_packet/0, decode_error/0, buffer/0, body/0, http_response_body/0]). - --type packet_type() :: http | httph_bin | http_bin. - --type http_uri() :: {abs_path, bitstring()}. - --type http_packet() :: {http_request, - gleam@dynamic:dynamic(), - http_uri(), - {integer(), integer()}} | - {http_header, - integer(), - gleam@erlang@atom:atom_(), - bitstring(), - bitstring()}. - --type decoded_packet() :: {binary_data, http_packet(), bitstring()} | - {end_of_headers, bitstring()} | - {more_data, gleam@option:option(integer())}. - --type decode_error() :: malformed_request | - invalid_method | - invalid_path | - unknown_header | - unknown_method | - invalid_body | - discard_packet. - --type buffer() :: {buffer, integer(), bitstring()}. - --opaque body() :: {unread, bitstring(), glisten@socket:socket()} | - {read, bitstring()}. - --type http_response_body() :: {bit_builder_body, - gleam@bit_builder:bit_builder()} | - {chunked, gleam@iterator:iterator(gleam@bit_builder:bit_builder())} | - {file_body, - mist@internal@file:file_descriptor(), - binary(), - integer(), - integer()}. - --spec from_header(bitstring()) -> binary(). -from_header(Value) -> - _assert_subject = gleam@bit_string:to_string(Value), - {ok, Value@1} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"from_header"/utf8>>, - line => 64}) - end, - gleam@string:lowercase(Value@1). - --spec upgrade_socket(gleam@http@request:request(body())) -> {ok, - gleam@http@response:response(gleam@bit_builder:bit_builder())} | - {error, gleam@http@request:request(body())}. -upgrade_socket(Req) -> - gleam@result:then( - begin - _pipe = gleam@http@request:get_header(Req, <<"upgrade"/utf8>>), - gleam@result:replace_error(_pipe, Req) - end, - fun(_) -> - gleam@result:then( - begin - _pipe@1 = gleam@http@request:get_header( - Req, - <<"sec-websocket-key"/utf8>> - ), - gleam@result:replace_error(_pipe@1, Req) - end, - fun(Key) -> - gleam@result:then( - begin - _pipe@2 = gleam@http@request:get_header( - Req, - <<"sec-websocket-version"/utf8>> - ), - gleam@result:replace_error(_pipe@2, Req) - end, - fun(_) -> - Accept_key = mist@internal@websocket:parse_key(Key), - _pipe@3 = gleam@http@response:new(101), - _pipe@4 = gleam@http@response:set_body( - _pipe@3, - gleam@bit_builder:new() - ), - _pipe@5 = gleam@http@response:prepend_header( - _pipe@4, - <<"Upgrade"/utf8>>, - <<"websocket"/utf8>> - ), - _pipe@6 = gleam@http@response:prepend_header( - _pipe@5, - <<"Connection"/utf8>>, - <<"Upgrade"/utf8>> - ), - _pipe@7 = gleam@http@response:prepend_header( - _pipe@6, - <<"Sec-WebSocket-Accept"/utf8>>, - Accept_key - ), - {ok, _pipe@7} - end - ) - end - ) - end - ). - --spec add_default_headers( - gleam@http@response:response(gleam@bit_builder:bit_builder()) -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -add_default_headers(Resp) -> - Body_size = gleam@bit_builder:byte_size(erlang:element(4, Resp)), - Headers = begin - _pipe = gleam@map:from_list( - [{<<"content-length"/utf8>>, gleam@int:to_string(Body_size)}, - {<<"connection"/utf8>>, <<"keep-alive"/utf8>>}] - ), - _pipe@1 = gleam@list:fold( - erlang:element(3, Resp), - _pipe, - fun(Defaults, Tup) -> - {Key, Value} = Tup, - gleam@map:insert(Defaults, Key, Value) - end - ), - gleam@map:to_list(_pipe@1) - end, - erlang:setelement(3, Resp, Headers). - --spec upgrade( - glisten@socket:socket(), - glisten@socket@transport:transport(), - gleam@http@request:request(body()) -) -> {ok, nil} | {error, nil}. -upgrade(Socket, Transport, Req) -> - gleam@result:then( - begin - _pipe = upgrade_socket(Req), - gleam@result:nil_error(_pipe) - end, - fun(Resp) -> - gleam@result:then( - begin - _pipe@1 = Resp, - _pipe@2 = add_default_headers(_pipe@1), - _pipe@3 = mist@internal@encoder:to_bit_builder(_pipe@2), - _pipe@4 = (erlang:element(11, Transport))(Socket, _pipe@3), - gleam@result:nil_error(_pipe@4) - end, - fun(_) -> {ok, nil} end - ) - end - ). - --spec is_continue(gleam@http@request:request(body())) -> boolean(). -is_continue(Req) -> - _pipe = erlang:element(3, Req), - _pipe@1 = gleam@list:find( - _pipe, - fun(Tup) -> - (gleam@pair:first(Tup) =:= <<"expect"/utf8>>) andalso (gleam@pair:second( - Tup - ) - =:= <<"100-continue"/utf8>>) - end - ), - gleam@result:is_ok(_pipe@1). - --spec parse_headers( - bitstring(), - glisten@socket:socket(), - glisten@socket@transport:transport(), - gleam@map:map_(binary(), binary()) -) -> {ok, {gleam@map:map_(binary(), binary()), bitstring()}} | - {error, decode_error()}. -parse_headers(Bs, Socket, Transport, Headers) -> - case mist_ffi:decode_packet(httph_bin, Bs, []) of - {ok, {binary_data, {http_header, _, _, Field, Value}, Rest}} -> - Field@1 = from_header(Field), - _assert_subject = gleam@bit_string:to_string(Value), - {ok, Value@1} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"parse_headers"/utf8>>, - line => 82}) - end, - _pipe = Headers, - _pipe@1 = gleam@map:insert(_pipe, Field@1, Value@1), - parse_headers(Rest, Socket, Transport, _pipe@1); - - {ok, {end_of_headers, Rest@1}} -> - {ok, {Headers, Rest@1}}; - - {ok, {more_data, Size}} -> - Amount_to_read = gleam@option:unwrap(Size, 0), - gleam@result:then( - read_data( - Socket, - Transport, - {buffer, Amount_to_read, Bs}, - unknown_header - ), - fun(Next) -> parse_headers(Next, Socket, Transport, Headers) end - ); - - _ -> - {error, unknown_header} - end. - --spec parse_request( - bitstring(), - glisten@socket:socket(), - glisten@socket@transport:transport() -) -> {ok, gleam@http@request:request(body())} | {error, decode_error()}. -parse_request(Bs, Socket, Transport) -> - case mist_ffi:decode_packet(http_bin, Bs, []) of - {ok, - {binary_data, - {http_request, Http_method, {abs_path, Path}, _}, - Rest}} -> - gleam@result:then( - begin - _pipe = Http_method, - _pipe@1 = gleam_erlang_ffi:atom_from_dynamic(_pipe), - _pipe@2 = gleam@result:map( - _pipe@1, - fun gleam@erlang@atom:to_string/1 - ), - _pipe@3 = gleam@result:'or'( - _pipe@2, - gleam@dynamic:string(Http_method) - ), - _pipe@4 = gleam@result:nil_error(_pipe@3), - _pipe@5 = gleam@result:then( - _pipe@4, - fun gleam@http:parse_method/1 - ), - gleam@result:replace_error(_pipe@5, unknown_method) - end, - fun(Method) -> - gleam@result:then( - parse_headers(Rest, Socket, Transport, gleam@map:new()), - fun(_use0) -> - {Headers, Rest@1} = _use0, - gleam@result:then( - begin - _pipe@6 = Path, - _pipe@7 = gleam@bit_string:to_string( - _pipe@6 - ), - gleam@result:replace_error( - _pipe@7, - invalid_path - ) - end, - fun(Path@1) -> - {Path@4, Query@1} = case gleam@string:split( - Path@1, - <<"?"/utf8>> - ) of - [Path@2] -> - {Path@2, []}; - - [Path@3, Query_string] -> - Query = begin - _pipe@8 = Query_string, - _pipe@9 = gleam@uri:parse_query( - _pipe@8 - ), - gleam@result:unwrap(_pipe@9, []) - end, - {Path@3, Query} - end, - Req = begin - _pipe@10 = gleam@http@request:new(), - _pipe@11 = gleam@http@request:set_scheme( - _pipe@10, - case Transport of - {ssl, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _} -> - https; - - {tcp, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _} -> - http - end - ), - _pipe@12 = gleam@http@request:set_body( - _pipe@11, - {unread, Rest@1, Socket} - ), - _pipe@13 = gleam@http@request:set_method( - _pipe@12, - Method - ), - _pipe@14 = gleam@http@request:set_path( - _pipe@13, - Path@4 - ), - gleam@http@request:set_query( - _pipe@14, - Query@1 - ) - end, - {ok, - erlang:setelement( - 3, - Req, - gleam@map:to_list(Headers) - )} - end - ) - end - ) - end - ); - - _ -> - {error, discard_packet} - end. - --spec read_data( - glisten@socket:socket(), - glisten@socket@transport:transport(), - buffer(), - decode_error() -) -> {ok, bitstring()} | {error, decode_error()}. -read_data(Socket, Transport, Buffer, Error) -> - To_read = gleam@int:min(erlang:element(2, Buffer), 1000000), - Timeout = 15000, - gleam@result:then( - begin - _pipe = Socket, - _pipe@1 = (erlang:element(10, Transport))(_pipe, To_read, Timeout), - gleam@result:replace_error(_pipe@1, Error) - end, - fun(Data) -> - Next_buffer = {buffer, - erlang:element(2, Buffer) - To_read, - <<(erlang:element(3, Buffer))/bitstring, Data/bitstring>>}, - case erlang:element(2, Next_buffer) > 0 of - true -> - read_data(Socket, Transport, Next_buffer, Error); - - false -> - {ok, erlang:element(3, Next_buffer)} - end - end - ). - --spec read_chunk( - glisten@socket:socket(), - glisten@socket@transport:transport(), - buffer(), - gleam@bit_builder:bit_builder() -) -> {ok, gleam@bit_builder:bit_builder()} | {error, decode_error()}. -read_chunk(Socket, Transport, Buffer, Body) -> - case {erlang:element(3, Buffer), - mist_ffi:binary_match( - erlang:element(3, Buffer), - <<13/integer, 10/integer>> - )} of - {_, {ok, {Offset, _}}} -> - _assert_subject = erlang:element(3, Buffer), - <<Chunk:Offset/binary, _/integer, _/integer, Rest/binary>> = case _assert_subject of - <<_:Offset/binary, _/integer, _/integer, _/binary>> -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"read_chunk"/utf8>>, - line => 147}) - end, - gleam@result:then( - begin - _pipe = Chunk, - _pipe@1 = gleam@bit_string:to_string(_pipe), - _pipe@2 = gleam@result:map( - _pipe@1, - fun gleam@erlang@charlist:from_string/1 - ), - gleam@result:replace_error(_pipe@2, invalid_body) - end, - fun(Chunk_size) -> - gleam@result:then( - begin - _pipe@3 = mist_ffi:string_to_int(Chunk_size, 16), - gleam@result:replace_error(_pipe@3, invalid_body) - end, - fun(Size) -> case Size of - 0 -> - {ok, Body}; - - Size@1 -> - case Rest of - <<Next_chunk:Size@1/binary, - 13/integer, - 10/integer, - Rest@1/binary>> -> - read_chunk( - Socket, - Transport, - {buffer, 0, Rest@1}, - gleam@bit_builder:append( - Body, - Next_chunk - ) - ); - - _ -> - gleam@result:then( - read_data( - Socket, - Transport, - {buffer, - 0, - erlang:element( - 3, - Buffer - )}, - invalid_body - ), - fun(Next) -> - read_chunk( - Socket, - Transport, - {buffer, 0, Next}, - Body - ) - end - ) - end - end end - ) - end - ); - - {<<>>, _} -> - gleam@result:then( - read_data( - Socket, - Transport, - {buffer, 0, erlang:element(3, Buffer)}, - invalid_body - ), - fun(Next@1) -> - read_chunk(Socket, Transport, {buffer, 0, Next@1}, Body) - end - ); - - {_, {error, nil}} -> - {error, invalid_body} - end. - --spec read_body(gleam@http@request:request(body())) -> {ok, - gleam@http@request:request(bitstring())} | - {error, decode_error()}. -read_body(Req) -> - Transport = case erlang:element(5, Req) of - https -> - glisten@socket@transport:ssl(); - - http -> - glisten@socket@transport:tcp() - end, - case {gleam@http@request:get_header(Req, <<"transfer-encoding"/utf8>>), - erlang:element(4, Req)} of - {{ok, <<"chunked"/utf8>>}, {unread, Rest, Socket}} -> - gleam@result:then( - read_chunk( - Socket, - Transport, - {buffer, 0, Rest}, - gleam@bit_builder:new() - ), - fun(Chunk) -> - {ok, - gleam@http@request:set_body( - Req, - gleam@bit_builder:to_bit_string(Chunk) - )} - end - ); - - {_, {unread, Rest@1, Socket@1}} -> - _ = case is_continue(Req) of - true -> - _assert_subject = begin - _pipe = gleam@http@response:new(100), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:new() - ), - _pipe@2 = mist@internal@encoder:to_bit_builder(_pipe@1), - (erlang:element(11, Transport))(Socket@1, _pipe@2) - end, - {ok, nil} = case _assert_subject of - {ok, nil} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"read_body"/utf8>>, - line => 276}) - end, - nil; - - false -> - nil - end, - Body_size = begin - _pipe@3 = erlang:element(3, Req), - _pipe@4 = gleam@list:find( - _pipe@3, - fun(Tup) -> - gleam@pair:first(Tup) =:= <<"content-length"/utf8>> - end - ), - _pipe@5 = gleam@result:map(_pipe@4, fun gleam@pair:second/1), - _pipe@6 = gleam@result:then(_pipe@5, fun gleam@int:parse/1), - gleam@result:unwrap(_pipe@6, 0) - end, - Remaining = Body_size - gleam@bit_string:byte_size(Rest@1), - _pipe@7 = case {Body_size, Remaining} of - {0, 0} -> - {ok, <<>>}; - - {0, _} -> - {ok, Rest@1}; - - {_, 0} -> - {ok, Rest@1}; - - {_, _} -> - read_data( - Socket@1, - Transport, - {buffer, Remaining, Rest@1}, - invalid_body - ) - end, - _pipe@8 = gleam@result:map( - _pipe@7, - fun(_capture) -> gleam@http@request:set_body(Req, _capture) end - ), - gleam@result:replace_error(_pipe@8, invalid_body); - - {_, {read, _}} -> - {error, invalid_body} - end. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl deleted file mode 100644 index 214e0870e63..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(mist@internal@logger). --compile([no_auto_import, nowarn_unused_vars]). - --export([error/1]). - --spec error(any()) -> nil. -error(Data) -> - logger:error(unicode:characters_to_list(<<"~tp"/utf8>>), [Data]). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl deleted file mode 100644 index c361892ff13..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl +++ /dev/null @@ -1,359 +0,0 @@ --module(mist@internal@websocket). --compile([no_auto_import, nowarn_unused_vars]). - --export([frame_to_bit_builder/1, to_text_frame/1, to_binary_frame/1, crypto_hash/2, base64_encode/1, parse_key/1, frame_from_message/3]). --export_type([message/0, frame/0, sha_hash/0, websocket_handler/0]). - --type message() :: {binary_message, bitstring()} | {text_message, binary()}. - --type frame() :: {close_frame, integer(), bitstring()} | - {text_frame, integer(), bitstring()} | - {binary_frame, integer(), bitstring()} | - {ping_frame, integer(), bitstring()} | - {pong_frame, integer(), bitstring()}. - --type sha_hash() :: sha. - --type websocket_handler() :: {websocket_handler, - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - fun((message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, - nil} | - {error, nil})}. - --spec make_frame(integer(), integer(), bitstring()) -> gleam@bit_builder:bit_builder(). -make_frame(Opcode, Length, Payload) -> - Length_section = case Length of - Length@1 when Length@1 > 65535 -> - <<127:7, Length@1:64/integer>>; - - Length@2 when Length@2 >= 126 -> - <<126:7, Length@2:16/integer>>; - - _ -> - <<Length:7>> - end, - _pipe = <<1:1, - 0:3, - Opcode:4, - 0:1, - Length_section/bitstring, - Payload/bitstring>>, - gleam@bit_builder:from_bit_string(_pipe). - --spec frame_to_bit_builder(frame()) -> gleam@bit_builder:bit_builder(). -frame_to_bit_builder(Frame) -> - case Frame of - {text_frame, Payload_length, Payload} -> - make_frame(1, Payload_length, Payload); - - {close_frame, Payload_length@1, Payload@1} -> - make_frame(8, Payload_length@1, Payload@1); - - {binary_frame, Payload_length@2, Payload@2} -> - make_frame(2, Payload_length@2, Payload@2); - - {pong_frame, Payload_length@3, Payload@3} -> - make_frame(10, Payload_length@3, Payload@3); - - {ping_frame, _, _} -> - gleam@bit_builder:from_bit_string(<<>>) - end. - --spec to_text_frame(bitstring()) -> gleam@bit_builder:bit_builder(). -to_text_frame(Data) -> - Size = gleam@bit_string:byte_size(Data), - frame_to_bit_builder({text_frame, Size, Data}). - --spec to_binary_frame(bitstring()) -> gleam@bit_builder:bit_builder(). -to_binary_frame(Data) -> - Size = gleam@bit_string:byte_size(Data), - frame_to_bit_builder({binary_frame, Size, Data}). - --spec crypto_hash(sha_hash(), binary()) -> binary(). -crypto_hash(Field@0, Field@1) -> - crypto:hash(Field@0, Field@1). - --spec base64_encode(binary()) -> binary(). -base64_encode(Field@0) -> - base64:encode(Field@0). - --spec parse_key(binary()) -> binary(). -parse_key(Key) -> - _pipe = Key, - _pipe@1 = gleam@string:append( - _pipe, - <<"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"/utf8>> - ), - _pipe@2 = crypto:hash(sha, _pipe@1), - base64:encode(_pipe@2). - --spec unmask_data(bitstring(), list(bitstring()), integer(), bitstring()) -> bitstring(). -unmask_data(Data, Masks, Index, Resp) -> - case Data of - <<>> -> - Resp; - - <<Masked:8/bitstring, Rest/bitstring>> -> - _assert_subject = gleam@list:at(Masks, Index rem 4), - {ok, Mask_value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"unmask_data"/utf8>>, - line => 43}) - end, - Unmasked = crypto:exor(Mask_value, Masked), - unmask_data( - Rest, - Masks, - Index + 1, - <<Resp/bitstring, Unmasked/bitstring>> - ) - end. - --spec frame_from_message( - glisten@socket:socket(), - glisten@socket@transport:transport(), - bitstring() -) -> {ok, frame()} | {error, nil}. -frame_from_message(Socket, Transport, Message) -> - <<_:1, Rest/bitstring>> = case Message of - <<_:1, _/bitstring>> -> Message; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 60}) - end, - <<_:3, Rest@1/bitstring>> = case Rest of - <<_:3, _/bitstring>> -> Rest; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 61}) - end, - <<Opcode:4/integer, Rest@2/bitstring>> = case Rest@1 of - <<_:4/integer, _/bitstring>> -> Rest@1; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 62}) - end, - case Opcode of - 1 -> - <<1:1, Rest@3/bitstring>> = case Rest@2 of - <<1:1, _/bitstring>> -> Rest@2; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 66}) - end, - <<Payload_length:7/integer, Rest@4/bitstring>> = case Rest@3 of - <<_:7/integer, _/bitstring>> -> Rest@3; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 67}) - end, - {Payload_length@1, Rest@7} = case Payload_length of - 126 -> - <<Length:16/integer, Rest@5/bitstring>> = case Rest@4 of - <<_:16/integer, _/bitstring>> -> Rest@4; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 70}) - end, - {Length, Rest@5}; - - 127 -> - <<Length@1:64/integer, Rest@6/bitstring>> = case Rest@4 of - <<_:64/integer, _/bitstring>> -> Rest@4; - _assert_fail@6 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@6, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 74}) - end, - {Length@1, Rest@6}; - - _ -> - {Payload_length, Rest@4} - end, - <<Mask1:8/bitstring, - Mask2:8/bitstring, - Mask3:8/bitstring, - Mask4:8/bitstring, - Rest@8/bitstring>> = case Rest@7 of - <<_:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _/bitstring>> -> Rest@7; - _assert_fail@7 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@7, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 79}) - end, - Data = case Payload_length@1 - gleam@bit_string:byte_size(Rest@8) of - 0 -> - unmask_data(Rest@8, [Mask1, Mask2, Mask3, Mask4], 0, <<>>); - - Need -> - _assert_subject = (erlang:element(9, Transport))( - Socket, - Need - ), - {ok, Needed} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail@8 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@8, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 89}) - end, - _pipe = Rest@8, - _pipe@1 = gleam@bit_string:append(_pipe, Needed), - unmask_data(_pipe@1, [Mask1, Mask2, Mask3, Mask4], 0, <<>>) - end, - _pipe@2 = case Opcode of - 1 -> - {text_frame, Payload_length@1, Data}; - - 2 -> - {binary_frame, Payload_length@1, Data} - end, - {ok, _pipe@2}; - - 2 -> - <<1:1, Rest@3/bitstring>> = case Rest@2 of - <<1:1, _/bitstring>> -> Rest@2; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 66}) - end, - <<Payload_length:7/integer, Rest@4/bitstring>> = case Rest@3 of - <<_:7/integer, _/bitstring>> -> Rest@3; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 67}) - end, - {Payload_length@1, Rest@7} = case Payload_length of - 126 -> - <<Length:16/integer, Rest@5/bitstring>> = case Rest@4 of - <<_:16/integer, _/bitstring>> -> Rest@4; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 70}) - end, - {Length, Rest@5}; - - 127 -> - <<Length@1:64/integer, Rest@6/bitstring>> = case Rest@4 of - <<_:64/integer, _/bitstring>> -> Rest@4; - _assert_fail@6 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@6, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 74}) - end, - {Length@1, Rest@6}; - - _ -> - {Payload_length, Rest@4} - end, - <<Mask1:8/bitstring, - Mask2:8/bitstring, - Mask3:8/bitstring, - Mask4:8/bitstring, - Rest@8/bitstring>> = case Rest@7 of - <<_:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _/bitstring>> -> Rest@7; - _assert_fail@7 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@7, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 79}) - end, - Data = case Payload_length@1 - gleam@bit_string:byte_size(Rest@8) of - 0 -> - unmask_data(Rest@8, [Mask1, Mask2, Mask3, Mask4], 0, <<>>); - - Need -> - _assert_subject = (erlang:element(9, Transport))( - Socket, - Need - ), - {ok, Needed} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail@8 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@8, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 89}) - end, - _pipe = Rest@8, - _pipe@1 = gleam@bit_string:append(_pipe, Needed), - unmask_data(_pipe@1, [Mask1, Mask2, Mask3, Mask4], 0, <<>>) - end, - _pipe@2 = case Opcode of - 1 -> - {text_frame, Payload_length@1, Data}; - - 2 -> - {binary_frame, Payload_length@1, Data} - end, - {ok, _pipe@2}; - - 8 -> - {ok, {close_frame, 0, <<>>}} - end. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl b/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl deleted file mode 100644 index 8e5110f7274..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl +++ /dev/null @@ -1,52 +0,0 @@ --module(mist@websocket). --compile([no_auto_import, nowarn_unused_vars]). - --export([send/2, echo_handler/2, with_handler/1, on_init/2, on_close/2]). - --spec send( - gleam@erlang@process:subject(glisten@handler:handler_message()), - mist@internal@websocket:message() -) -> nil. -send(Sender, Message) -> - _pipe@2 = case Message of - {text_message, Data} -> - _pipe = Data, - _pipe@1 = gleam@bit_string:from_string(_pipe), - mist@internal@websocket:to_text_frame(_pipe@1); - - {binary_message, Data@1} -> - mist@internal@websocket:to_binary_frame(Data@1) - end, - _pipe@3 = {send_message, _pipe@2}, - gleam@erlang@process:send(Sender, _pipe@3), - nil. - --spec echo_handler( - mist@internal@websocket:message(), - gleam@erlang@process:subject(glisten@handler:handler_message()) -) -> {ok, nil} | {error, nil}. -echo_handler(Message, Sender) -> - _ = send(Sender, Message), - {ok, nil}. - --spec with_handler( - fun((mist@internal@websocket:message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, - nil} | - {error, nil}) -) -> mist@internal@websocket:websocket_handler(). -with_handler(Func) -> - {websocket_handler, none, none, Func}. - --spec on_init( - mist@internal@websocket:websocket_handler(), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> mist@internal@websocket:websocket_handler(). -on_init(Handler, Func) -> - erlang:setelement(3, Handler, {some, Func}). - --spec on_close( - mist@internal@websocket:websocket_handler(), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> mist@internal@websocket:websocket_handler(). -on_close(Handler, Func) -> - erlang:setelement(2, Handler, {some, Func}). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl b/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl deleted file mode 100644 index f83e08f5c27..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl +++ /dev/null @@ -1,47 +0,0 @@ --module(mist_ffi). - --export([binary_match/2, decode_packet/3, file_open/1, string_to_int/2]). - -decode_packet(Type, Packet, Opts) -> - case erlang:decode_packet(Type, Packet, Opts) of - {ok, http_eoh, Rest} -> - {ok, {end_of_headers, Rest}}; - {ok, Binary, Rest} -> - {ok, {binary_data, Binary, Rest}}; - {more, Length} when Length =:= undefined -> - {ok, {more_data, none}}; - {more, Length} -> - {ok, {more_data, {some, Length}}}; - {error, Reason} -> - {error, Reason} - end. - -binary_match(Source, Pattern) -> - case binary:match(Source, Pattern) of - {Before, After} -> - {ok, {Before, After}}; - nomatch -> - {error, nil} - end. - -string_to_int(String, Base) -> - try - {ok, erlang:list_to_integer(String, Base)} - catch - badarg -> - {error, nil} - end. - -file_open(Path) -> - case file:open(Path, [raw]) of - {ok, fd} -> - {ok, fd}; - {error, enoent} -> - {error, no_entry}; - {error, eacces} -> - {error, no_access}; - {error, eisdir} -> - {error, is_dir}; - _ -> - {error, unknown_file_error} - end. diff --git a/test-community-packages-javascript/build/packages/nakai/LICENSE b/test-community-packages-javascript/build/packages/nakai/LICENSE deleted file mode 100644 index 2f3b8c6484c..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2022 McKayla Washburn -Copyright (c) 2022 Nakai Contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/nakai/README.md b/test-community-packages-javascript/build/packages/nakai/README.md deleted file mode 100644 index 49bcf2f50cb..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/README.md +++ /dev/null @@ -1,46 +0,0 @@ -![Nakai](https://cdn.mckayla.cloud/-/2d8051c1ce2f4fbd91eaf07df5661e25/Nakai-Banner.svg) - -[![Documentation](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/nakai/) - -## Getting started - -```sh -gleam add nakai -``` - -```gleam -import nakai -import nakai/html.{Node} -import nakai/html/attrs.{Attr} - -const header_style = " - color: #331f26; - font-family: 'Neuton', serif; - font-size: 128px; - font-weight: 400; -" - -pub fn header(attrs: List(Attr(a)), text: String) -> Node(a) { - let attrs = [attrs.style(header_style), ..attrs] - html.h1_text(attrs, text) -} - -pub fn app() -> String { - html.div( - [], - [ - html.Head([html.title("Hello!")]), - header([], "Hello, from Nakai!") - ], - ) - |> nakai.to_string() -} -``` - -## Development - -While Nakai itself is pure Gleam, the benchmarks require having [Elixir] installed, -and some of its dependencies require [Rebar3] to compile. - -[elixir]: https://elixir-lang.org/ -[rebar3]: https://rebar3.org/ diff --git a/test-community-packages-javascript/build/packages/nakai/gleam.toml b/test-community-packages-javascript/build/packages/nakai/gleam.toml deleted file mode 100644 index 6a59fb50e38..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/gleam.toml +++ /dev/null @@ -1,20 +0,0 @@ -name = "nakai" -version = "0.8.0" -licences = ["MIT"] -description = "HTML generation for Gleam, on the server or anywhere else" -repository = { type = "github", user = "nakaixo", repo = "nakai" } -links = [ - { title = "Website", href = "https://nakaixo.github.io" }, - { title = "Sponsor", href = "https://github.com/sponsors/aslilac" }, -] - -internal_modules = ["nakai/internal/*", "nakai/experimental/*"] - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleam_erlang = "~> 0.19" -gleam_json = "~> 0.5" -gleeunit = "~> 0.10" -glychee = "~> 0.2" diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl deleted file mode 100644 index a1e6394f178..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl +++ /dev/null @@ -1 +0,0 @@ --record(attr, {name :: binary(), value :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl deleted file mode 100644 index ff64a0a76cc..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl +++ /dev/null @@ -1 +0,0 @@ --record(event, {name :: binary(), action :: any()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl deleted file mode 100644 index 1536616600a..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(body, { - attrs :: list(nakai@html@attrs:attr(any())), - children :: list(nakai@html:node_(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl deleted file mode 100644 index 7ca4cf0259f..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl +++ /dev/null @@ -1 +0,0 @@ --record(comment, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl deleted file mode 100644 index d1e743c6e74..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl +++ /dev/null @@ -1 +0,0 @@ --record(doctype, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl deleted file mode 100644 index 498ade5cb56..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(element, { - tag :: binary(), - attrs :: list(nakai@html@attrs:attr(any())), - children :: list(nakai@html:node_(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl deleted file mode 100644 index 1753ea5e619..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl +++ /dev/null @@ -1 +0,0 @@ --record(fragment, {children :: list(nakai@html:node_(any()))}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl deleted file mode 100644 index db9f893f8ce..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl +++ /dev/null @@ -1 +0,0 @@ --record(head, {children :: list(nakai@html:node_(any()))}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl deleted file mode 100644 index 474196a71bb..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(html, { - attrs :: list(nakai@html@attrs:attr(any())), - children :: list(nakai@html:node_(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl deleted file mode 100644 index bd76321701c..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(leaf_element, { - tag :: binary(), - attrs :: list(nakai@html@attrs:attr(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl deleted file mode 100644 index e95a602c375..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl +++ /dev/null @@ -1 +0,0 @@ --record(script, {script :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl deleted file mode 100644 index 174e44494d9..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl +++ /dev/null @@ -1 +0,0 @@ --record(text, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl deleted file mode 100644 index 05a9922f2a5..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unsafe_text, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl deleted file mode 100644 index 67f0288ec89..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl +++ /dev/null @@ -1,8 +0,0 @@ --record(document, { - doctype :: gleam@option:option(binary()), - html_attrs :: gleam@string_builder:string_builder(), - body_attrs :: gleam@string_builder:string_builder(), - head :: gleam@string_builder:string_builder(), - body :: gleam@string_builder:string_builder(), - scripts :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src b/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src deleted file mode 100644 index 3c3ace613f4..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src +++ /dev/null @@ -1,18 +0,0 @@ -{application, nakai, [ - {vsn, "0.8.0"}, - {applications, [gleam_erlang, - gleam_json, - gleam_stdlib, - gleeunit, - glychee]}, - {description, "HTML generation for Gleam, on the server or anywhere else"}, - {modules, [nakai, - nakai@experimental@head, - nakai@experimental@on, - nakai@experimental@web_components, - nakai@html, - nakai@html@attrs, - nakai@internal@document, - nakai@internal@render]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai.erl deleted file mode 100644 index ce38b1f6f17..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai.erl +++ /dev/null @@ -1,22 +0,0 @@ --module(nakai). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_string_builder/1, to_string/1, to_inline_string_builder/1, to_inline_string/1]). - --spec to_string_builder(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -to_string_builder(Tree) -> - nakai@internal@render:render_document(Tree). - --spec to_string(nakai@html:node_(any())) -> binary(). -to_string(Tree) -> - _pipe = nakai@internal@render:render_document(Tree), - gleam@string_builder:to_string(_pipe). - --spec to_inline_string_builder(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -to_inline_string_builder(Tree) -> - nakai@internal@render:render_inline(Tree). - --spec to_inline_string(nakai@html:node_(any())) -> binary(). -to_inline_string(Tree) -> - _pipe = nakai@internal@render:render_inline(Tree), - gleam@string_builder:to_string(_pipe). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam deleted file mode 100644 index 18c83efcade..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam +++ /dev/null @@ -1,60 +0,0 @@ -//// Nakai has several "builders" that can be used. -//// - A `document` builder (the recommend one) that renders a full HTML document, -//// does a little magic to dedepulicate `<head>` elements, and some other things -//// that generally fit the theme of "rendering a full, valid, HTML document" -//// - An `inline` builder that should mostly be used for snippets, and partial bits of -//// HTML that will be inlined into a full document; hence the name. It renders things -//// much more literally. If you tell it to give you a `<head>` element inside a -//// `<p>`, it will, as an example. -//// - A future experimental DOM renderer (meant for use in the browser) that isn't -//// actually done yet. - -import gleam/string_builder.{StringBuilder} -import nakai/html.{Node} -import nakai/internal/render - -/// Renders a full HTML document from the given tree, into a `StringBuilder`. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_string_builder() -/// ``` -pub fn to_string_builder(tree: Node(a)) -> StringBuilder { - render.render_document(tree) -} - -/// Renders a full HTML document from the given tree, into a `String`. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_string() -/// ``` -pub fn to_string(tree: Node(a)) -> String { - render.render_document(tree) - |> string_builder.to_string() -} - -/// Renders only the provided HTML, exactly as provided (disables `<head>` -/// deduplication, etc.), into a `StringBuilder`. Useful for generating snippets -/// instead of whole pages. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_inline_string_builder() -/// ``` -pub fn to_inline_string_builder(tree: Node(a)) -> StringBuilder { - render.render_inline(tree) -} - -/// Renders only the provided HTML, exactly as provided (disables `<head>` -/// deduplication, etc.), into a `String`. Useful for generating snippets instead -/// of whole pages. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_inline_string() -/// ``` -pub fn to_inline_string(tree: Node(a)) -> String { - render.render_inline(tree) - |> string_builder.to_string() -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam deleted file mode 100644 index 466c0c259aa..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam +++ /dev/null @@ -1,22 +0,0 @@ -import nakai/html -import nakai/html/attrs - -pub fn title(title: String) { - html.Head([html.title(title)]) -} - -pub fn link(rel rel: String, href href: String) { - html.Head([html.link([attrs.rel(rel), attrs.href(href)])]) -} - -pub fn meta(name name: String, content content: String) { - html.Head([html.meta([attrs.name(name), attrs.content(content)])]) -} - -pub fn http_equiv(header: String, content content: String) { - html.Head([html.meta([attrs.http_equiv(header), attrs.content(content)])]) -} - -pub fn charset(charset: String) { - html.Head([html.meta([attrs.charset(charset)])]) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam deleted file mode 100644 index 07f43f0a398..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam +++ /dev/null @@ -1,5 +0,0 @@ -import nakai/html/attrs.{Attr} - -pub fn click(script: String) -> Attr(a) { - Attr(name: "onclick", value: script) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam deleted file mode 100644 index 9041dd78bdc..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam +++ /dev/null @@ -1,10 +0,0 @@ -import nakai/html.{Element, LeafElement, Node} -import nakai/html/attrs.{Attr} - -pub fn slot(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "slot", attrs: attrs) -} - -pub fn template(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "template", attrs: attrs, children: children) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam deleted file mode 100644 index d1b07418fe7..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam +++ /dev/null @@ -1,1164 +0,0 @@ - - - - - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// * THIS FILE IS GENERATED. DO NOT EDIT IT. * -// * You're probably looking for ./codegen/html_prelude.gleam, or ./codegen/html.json. * -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - - - - -import nakai/html/attrs.{Attr} - -pub type Node(a) { - /// Can be used anywhere in the document, and will set the doctype of the document - /// being rendered. Usually not necessary, as documents have a default of `<!DOCTYPE html>`. - /// ## Example - /// ```gleam - /// html.Doctype("html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"") - /// ``` - Doctype(content: String) - /// Used for setting attributes on the root `<html>` element of the document. Children - /// will be rendered in-place, equivalent to using `html.Fragment(children)`. - /// ## Example - /// ```gleam - /// html.Html([attrs.lang("en-US")], [ - /// ... - /// ]) - /// ``` - Html(attrs: List(Attr(a)), children: List(Node(a))) - /// Used for placing content in the `<head>` of the document. Useful for elements like - /// `<meta>`, `<title>`, `<link>`, etc. - /// ## Example - /// ```gleam - /// html.Fragment([ - /// html.Head([ - /// html.title("List of puppies") - /// ]), - /// html.div([], [ - /// ... - /// ]) - /// ]) - /// ``` - Head(children: List(Node(a))) - /// Used for setting attributes on the `<body>` element of the document. Children - /// will be rendered in-place, equivalent to using `html.Fragment(children)`. - /// ## Example - /// ```gleam - /// html.Body([attrs.class("dark-mode")], [ - /// ... - /// ]) - /// ``` - Body(attrs: List(Attr(a)), children: List(Node(a))) - /// An "transparent" container that will render it's children, but does not add anything - /// itself to the document. If you've ever used `React.Fragment` or `<>` and `</>` in - /// JSX/React, this is that. - /// ## Example - /// ```gleam - /// html.ul([], [ - /// // some puppies are hard-coded - /// html.li_text([], "August"), - /// // some are loaded from a server - /// html.Fragment(puppies_fetched_from_api |> list.map(html.li_text([], _))) - /// ]) - /// // <ul> - /// // <li>August</li> - /// // <li>Dot</li> - /// // <li>Mody</li> - /// // <li>Spot</li> - /// // <li>Toby</li> - /// // </ul> - /// ``` - Fragment(children: List(Node(a))) - /// An HTML element. You shouldn't need to reach for this very often, but it can be a - /// handy escape hatch if there isn't a shorthand function for the element type you need. - /// ## Example - /// ```gleam - /// // bad example, pls use `html.div` - /// html.Element("div", [], [html.Text("hello, lucy!")]) - /// ``` - Element(tag: String, attrs: List(Attr(a)), children: List(Node(a))) - /// An HTML element, but that does not have any children, and should be self closing. - /// Similarly to `Element`, you shouldn't really need this, except as an escape hatch - /// if there isn't a shorthand function for the element type you need. - /// ## Example - /// ```gleam - /// // bad example, pls use `html.link` - /// html.LeafElement("link", [attrs.rel("stylesheet"), attrs.href(...)]) - /// ``` - LeafElement(tag: String, attrs: List(Attr(a))) - /// An HTML comment, which will be included in the document. - /// ## Example - /// ```gleam - /// html.Comment("You've uncovered my secrets!") - /// // <!-- You've uncovered my secrets! --> - /// ``` - Comment(content: String) - /// Some plain text to include in the document. The provided text will be escaped, to - /// make it safe to include in the document. - /// ## Example - /// ```gleam - /// html.Text("hello, lucy!") - /// // hello, lucy! - /// ``` - /// ```gleam - /// // Time to trust some unvalidated user input! :^) - /// html.div_text([], "<script>alert('pwned');</script>") - /// // <div><script>alert('pwned');</script></div> - /// ``` - Text(content: String) - /// The dangerous cousin of `Text`. This will render the provided text as-is, without - /// any santization. Good for things like including some HTML you just generated from - /// a Markdown file. Bad for things like `$_GET['search']`. - /// ## Example - /// ```gleam - /// html.Text("hello, lucy!") - /// // hello, lucy! - /// ``` - /// ```gleam - /// // Time to trust some unvalidated user input! :^) - /// html.div([], [html.UnsafeText("<script>alert('pwned');</script>")]) - /// // <div><script>alert('pwned');</script></div> - /// // Oh no, we just got got! D: - /// ``` - UnsafeText(content: String) - /// Add some JavaScript to your page! Scripts will always be inserted at the end of the - /// page, regardless of where in the document the `Script` node is, so that your content - /// loads first. - /// ## Example - /// ```gleam - /// html.Script("alert('hello, lucy!')") - /// ``` - Script(script: String) - /// Renders absolutely nothing. For when you may or may not have something to render, - /// and need a way to say "I've got nothing." - /// ## Example - /// ```gleam - /// html.div([], [ - /// case my_cool_feature { - /// Enabled -> super_cool_stuff() - /// Disabled -> html.Nothing - /// } - /// ]) - Nothing -} - -/// The HTML [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title) element -pub fn title(text: String) -> Node(a) { - Element("title", [], [Text(text)]) -} - -/// The [HTML `<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) -pub fn a(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "a", attrs: attrs, children: children) -} - -/// Shorthand for `html.a(attrs, children: [html.Text(text)])` -pub fn a_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "a", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<abbr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr) -pub fn abbr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "abbr", attrs: attrs, children: children) -} - -/// Shorthand for `html.abbr(attrs, children: [html.Text(text)])` -pub fn abbr_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "abbr", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<address>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address) -pub fn address(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "address", attrs: attrs, children: children) -} - -/// Shorthand for `html.address(attrs, children: [html.Text(text)])` -pub fn address_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "address", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<area />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area) -pub fn area(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "area", attrs: attrs) -} - -/// The [HTML `<article>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article) -pub fn article(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "article", attrs: attrs, children: children) -} - -/// Shorthand for `html.article(attrs, children: [html.Text(text)])` -pub fn article_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "article", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<aside>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside) -pub fn aside(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "aside", attrs: attrs, children: children) -} - -/// Shorthand for `html.aside(attrs, children: [html.Text(text)])` -pub fn aside_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "aside", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<audio>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio) -pub fn audio(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "audio", attrs: attrs, children: children) -} - -/// Shorthand for `html.audio(attrs, children: [html.Text(text)])` -pub fn audio_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "audio", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<b>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b) -pub fn b(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "b", attrs: attrs, children: children) -} - -/// Shorthand for `html.b(attrs, children: [html.Text(text)])` -pub fn b_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "b", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<base />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) -pub fn base(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "base", attrs: attrs) -} - -/// The [HTML `<bdi>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi) -pub fn bdi(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "bdi", attrs: attrs, children: children) -} - -/// Shorthand for `html.bdi(attrs, children: [html.Text(text)])` -pub fn bdi_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "bdi", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<bdo>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo) -pub fn bdo(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "bdo", attrs: attrs, children: children) -} - -/// Shorthand for `html.bdo(attrs, children: [html.Text(text)])` -pub fn bdo_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "bdo", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<blockquote>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote) -pub fn blockquote(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "blockquote", attrs: attrs, children: children) -} - -/// Shorthand for `html.blockquote(attrs, children: [html.Text(text)])` -pub fn blockquote_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "blockquote", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<br />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br) -pub fn br(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "br", attrs: attrs) -} - -/// The [HTML `<button>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) -pub fn button(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "button", attrs: attrs, children: children) -} - -/// Shorthand for `html.button(attrs, children: [html.Text(text)])` -pub fn button_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "button", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<canvas>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) -pub fn canvas(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "canvas", attrs: attrs, children: children) -} - -/// Shorthand for `html.canvas(attrs, children: [html.Text(text)])` -pub fn canvas_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "canvas", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<caption>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption) -pub fn caption(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "caption", attrs: attrs, children: children) -} - -/// Shorthand for `html.caption(attrs, children: [html.Text(text)])` -pub fn caption_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "caption", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<cite>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite) -pub fn cite(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "cite", attrs: attrs, children: children) -} - -/// Shorthand for `html.cite(attrs, children: [html.Text(text)])` -pub fn cite_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "cite", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<code>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code) -pub fn code(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "code", attrs: attrs, children: children) -} - -/// Shorthand for `html.code(attrs, children: [html.Text(text)])` -pub fn code_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "code", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<col>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col) -pub fn col(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "col", attrs: attrs, children: children) -} - -/// Shorthand for `html.col(attrs, children: [html.Text(text)])` -pub fn col_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "col", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<colgroup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup) -pub fn colgroup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "colgroup", attrs: attrs, children: children) -} - -/// Shorthand for `html.colgroup(attrs, children: [html.Text(text)])` -pub fn colgroup_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "colgroup", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<data>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data) -pub fn data(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "data", attrs: attrs, children: children) -} - -/// Shorthand for `html.data(attrs, children: [html.Text(text)])` -pub fn data_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "data", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<datalist>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) -pub fn datalist(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "datalist", attrs: attrs, children: children) -} - -/// Shorthand for `html.datalist(attrs, children: [html.Text(text)])` -pub fn datalist_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "datalist", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dd>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd) -pub fn dd(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dd", attrs: attrs, children: children) -} - -/// Shorthand for `html.dd(attrs, children: [html.Text(text)])` -pub fn dd_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dd", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<del>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del) -pub fn del(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "del", attrs: attrs, children: children) -} - -/// Shorthand for `html.del(attrs, children: [html.Text(text)])` -pub fn del_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "del", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<details>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details) -pub fn details(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "details", attrs: attrs, children: children) -} - -/// Shorthand for `html.details(attrs, children: [html.Text(text)])` -pub fn details_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "details", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dfn>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dfn) -pub fn dfn(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dfn", attrs: attrs, children: children) -} - -/// Shorthand for `html.dfn(attrs, children: [html.Text(text)])` -pub fn dfn_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dfn", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dialog>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) -pub fn dialog(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dialog", attrs: attrs, children: children) -} - -/// Shorthand for `html.dialog(attrs, children: [html.Text(text)])` -pub fn dialog_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dialog", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<div>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) -pub fn div(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "div", attrs: attrs, children: children) -} - -/// Shorthand for `html.div(attrs, children: [html.Text(text)])` -pub fn div_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "div", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dl>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl) -pub fn dl(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dl", attrs: attrs, children: children) -} - -/// Shorthand for `html.dl(attrs, children: [html.Text(text)])` -pub fn dl_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dl", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dt>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt) -pub fn dt(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dt", attrs: attrs, children: children) -} - -/// Shorthand for `html.dt(attrs, children: [html.Text(text)])` -pub fn dt_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dt", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<em>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em) -pub fn em(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "em", attrs: attrs, children: children) -} - -/// Shorthand for `html.em(attrs, children: [html.Text(text)])` -pub fn em_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "em", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<embed>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed) -pub fn embed(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "embed", attrs: attrs, children: children) -} - -/// Shorthand for `html.embed(attrs, children: [html.Text(text)])` -pub fn embed_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "embed", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<fieldset>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset) -pub fn fieldset(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "fieldset", attrs: attrs, children: children) -} - -/// Shorthand for `html.fieldset(attrs, children: [html.Text(text)])` -pub fn fieldset_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "fieldset", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<figcaption>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption) -pub fn figcaption(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "figcaption", attrs: attrs, children: children) -} - -/// Shorthand for `html.figcaption(attrs, children: [html.Text(text)])` -pub fn figcaption_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "figcaption", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<figure>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure) -pub fn figure(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "figure", attrs: attrs, children: children) -} - -/// Shorthand for `html.figure(attrs, children: [html.Text(text)])` -pub fn figure_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "figure", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<footer>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer) -pub fn footer(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "footer", attrs: attrs, children: children) -} - -/// Shorthand for `html.footer(attrs, children: [html.Text(text)])` -pub fn footer_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "footer", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<form>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) -pub fn form(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "form", attrs: attrs, children: children) -} - -/// Shorthand for `html.form(attrs, children: [html.Text(text)])` -pub fn form_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "form", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h1>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1) -pub fn h1(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h1", attrs: attrs, children: children) -} - -/// Shorthand for `html.h1(attrs, children: [html.Text(text)])` -pub fn h1_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h1", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h2>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2) -pub fn h2(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h2", attrs: attrs, children: children) -} - -/// Shorthand for `html.h2(attrs, children: [html.Text(text)])` -pub fn h2_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h2", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h3>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3) -pub fn h3(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h3", attrs: attrs, children: children) -} - -/// Shorthand for `html.h3(attrs, children: [html.Text(text)])` -pub fn h3_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h3", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h4>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4) -pub fn h4(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h4", attrs: attrs, children: children) -} - -/// Shorthand for `html.h4(attrs, children: [html.Text(text)])` -pub fn h4_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h4", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h5>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5) -pub fn h5(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h5", attrs: attrs, children: children) -} - -/// Shorthand for `html.h5(attrs, children: [html.Text(text)])` -pub fn h5_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h5", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h6>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6) -pub fn h6(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h6", attrs: attrs, children: children) -} - -/// Shorthand for `html.h6(attrs, children: [html.Text(text)])` -pub fn h6_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h6", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<header>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header) -pub fn header(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "header", attrs: attrs, children: children) -} - -/// Shorthand for `html.header(attrs, children: [html.Text(text)])` -pub fn header_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "header", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<hr />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr) -pub fn hr(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "hr", attrs: attrs) -} - -/// The [HTML `<i>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i) -pub fn i(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "i", attrs: attrs, children: children) -} - -/// Shorthand for `html.i(attrs, children: [html.Text(text)])` -pub fn i_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "i", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<iframe>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) -pub fn iframe(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "iframe", attrs: attrs, children: children) -} - -/// Shorthand for `html.iframe(attrs, children: [html.Text(text)])` -pub fn iframe_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "iframe", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<img />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) -pub fn img(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "img", attrs: attrs) -} - -/// The [HTML `<input />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) -pub fn input(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "input", attrs: attrs) -} - -/// The [HTML `<ins>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins) -pub fn ins(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ins", attrs: attrs, children: children) -} - -/// Shorthand for `html.ins(attrs, children: [html.Text(text)])` -pub fn ins_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ins", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<kbd>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd) -pub fn kbd(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "kbd", attrs: attrs, children: children) -} - -/// Shorthand for `html.kbd(attrs, children: [html.Text(text)])` -pub fn kbd_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "kbd", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<label>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) -pub fn label(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "label", attrs: attrs, children: children) -} - -/// Shorthand for `html.label(attrs, children: [html.Text(text)])` -pub fn label_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "label", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<legend>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend) -pub fn legend(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "legend", attrs: attrs, children: children) -} - -/// Shorthand for `html.legend(attrs, children: [html.Text(text)])` -pub fn legend_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "legend", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<li>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li) -pub fn li(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "li", attrs: attrs, children: children) -} - -/// Shorthand for `html.li(attrs, children: [html.Text(text)])` -pub fn li_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "li", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<link />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) -pub fn link(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "link", attrs: attrs) -} - -/// The [HTML `<main>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main) -pub fn main(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "main", attrs: attrs, children: children) -} - -/// Shorthand for `html.main(attrs, children: [html.Text(text)])` -pub fn main_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "main", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<map>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map) -pub fn map(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "map", attrs: attrs, children: children) -} - -/// Shorthand for `html.map(attrs, children: [html.Text(text)])` -pub fn map_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "map", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<mark>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark) -pub fn mark(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "mark", attrs: attrs, children: children) -} - -/// Shorthand for `html.mark(attrs, children: [html.Text(text)])` -pub fn mark_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "mark", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<math>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/math) -pub fn math(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "math", attrs: attrs, children: children) -} - -/// Shorthand for `html.math(attrs, children: [html.Text(text)])` -pub fn math_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "math", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<menu>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu) -pub fn menu(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "menu", attrs: attrs, children: children) -} - -/// Shorthand for `html.menu(attrs, children: [html.Text(text)])` -pub fn menu_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "menu", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<menuitem>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menuitem) -pub fn menuitem(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "menuitem", attrs: attrs, children: children) -} - -/// Shorthand for `html.menuitem(attrs, children: [html.Text(text)])` -pub fn menuitem_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "menuitem", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<meta />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) -pub fn meta(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "meta", attrs: attrs) -} - -/// The [HTML `<meter>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter) -pub fn meter(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "meter", attrs: attrs, children: children) -} - -/// Shorthand for `html.meter(attrs, children: [html.Text(text)])` -pub fn meter_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "meter", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<nav>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav) -pub fn nav(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "nav", attrs: attrs, children: children) -} - -/// Shorthand for `html.nav(attrs, children: [html.Text(text)])` -pub fn nav_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "nav", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<noscript>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript) -pub fn noscript(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "noscript", attrs: attrs, children: children) -} - -/// Shorthand for `html.noscript(attrs, children: [html.Text(text)])` -pub fn noscript_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "noscript", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<object>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object) -pub fn object(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "object", attrs: attrs, children: children) -} - -/// Shorthand for `html.object(attrs, children: [html.Text(text)])` -pub fn object_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "object", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<ol>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol) -pub fn ol(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ol", attrs: attrs, children: children) -} - -/// Shorthand for `html.ol(attrs, children: [html.Text(text)])` -pub fn ol_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ol", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<optgroup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup) -pub fn optgroup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "optgroup", attrs: attrs, children: children) -} - -/// Shorthand for `html.optgroup(attrs, children: [html.Text(text)])` -pub fn optgroup_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "optgroup", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<option>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) -pub fn option(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "option", attrs: attrs, children: children) -} - -/// Shorthand for `html.option(attrs, children: [html.Text(text)])` -pub fn option_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "option", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<output>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output) -pub fn output(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "output", attrs: attrs, children: children) -} - -/// Shorthand for `html.output(attrs, children: [html.Text(text)])` -pub fn output_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "output", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<p>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p) -pub fn p(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "p", attrs: attrs, children: children) -} - -/// Shorthand for `html.p(attrs, children: [html.Text(text)])` -pub fn p_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "p", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<param>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param) -pub fn param(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "param", attrs: attrs, children: children) -} - -/// Shorthand for `html.param(attrs, children: [html.Text(text)])` -pub fn param_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "param", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<picture>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) -pub fn picture(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "picture", attrs: attrs, children: children) -} - -/// Shorthand for `html.picture(attrs, children: [html.Text(text)])` -pub fn picture_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "picture", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<pre>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre) -pub fn pre(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "pre", attrs: attrs, children: children) -} - -/// Shorthand for `html.pre(attrs, children: [html.Text(text)])` -pub fn pre_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "pre", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<progress>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) -pub fn progress(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "progress", attrs: attrs, children: children) -} - -/// Shorthand for `html.progress(attrs, children: [html.Text(text)])` -pub fn progress_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "progress", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<q>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q) -pub fn q(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "q", attrs: attrs, children: children) -} - -/// Shorthand for `html.q(attrs, children: [html.Text(text)])` -pub fn q_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "q", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<rp>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp) -pub fn rp(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "rp", attrs: attrs, children: children) -} - -/// Shorthand for `html.rp(attrs, children: [html.Text(text)])` -pub fn rp_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "rp", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<rt>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rt) -pub fn rt(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "rt", attrs: attrs, children: children) -} - -/// Shorthand for `html.rt(attrs, children: [html.Text(text)])` -pub fn rt_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "rt", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<ruby>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby) -pub fn ruby(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ruby", attrs: attrs, children: children) -} - -/// Shorthand for `html.ruby(attrs, children: [html.Text(text)])` -pub fn ruby_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ruby", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<s>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s) -pub fn s(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "s", attrs: attrs, children: children) -} - -/// Shorthand for `html.s(attrs, children: [html.Text(text)])` -pub fn s_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "s", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<samp>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/samp) -pub fn samp(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "samp", attrs: attrs, children: children) -} - -/// Shorthand for `html.samp(attrs, children: [html.Text(text)])` -pub fn samp_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "samp", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<section>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section) -pub fn section(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "section", attrs: attrs, children: children) -} - -/// Shorthand for `html.section(attrs, children: [html.Text(text)])` -pub fn section_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "section", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<select>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) -pub fn select(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "select", attrs: attrs, children: children) -} - -/// Shorthand for `html.select(attrs, children: [html.Text(text)])` -pub fn select_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "select", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<small>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small) -pub fn small(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "small", attrs: attrs, children: children) -} - -/// Shorthand for `html.small(attrs, children: [html.Text(text)])` -pub fn small_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "small", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<source />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source) -pub fn source(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "source", attrs: attrs) -} - -/// The [HTML `<span>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span) -pub fn span(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "span", attrs: attrs, children: children) -} - -/// Shorthand for `html.span(attrs, children: [html.Text(text)])` -pub fn span_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "span", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<strong>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong) -pub fn strong(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "strong", attrs: attrs, children: children) -} - -/// Shorthand for `html.strong(attrs, children: [html.Text(text)])` -pub fn strong_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "strong", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<sub>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub) -pub fn sub(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "sub", attrs: attrs, children: children) -} - -/// Shorthand for `html.sub(attrs, children: [html.Text(text)])` -pub fn sub_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "sub", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<summary>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary) -pub fn summary(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "summary", attrs: attrs, children: children) -} - -/// Shorthand for `html.summary(attrs, children: [html.Text(text)])` -pub fn summary_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "summary", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<sup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup) -pub fn sup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "sup", attrs: attrs, children: children) -} - -/// Shorthand for `html.sup(attrs, children: [html.Text(text)])` -pub fn sup_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "sup", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<svg>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/svg) -pub fn svg(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "svg", attrs: attrs, children: children) -} - -/// Shorthand for `html.svg(attrs, children: [html.Text(text)])` -pub fn svg_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "svg", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<table>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table) -pub fn table(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "table", attrs: attrs, children: children) -} - -/// Shorthand for `html.table(attrs, children: [html.Text(text)])` -pub fn table_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "table", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<tbody>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody) -pub fn tbody(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "tbody", attrs: attrs, children: children) -} - -/// Shorthand for `html.tbody(attrs, children: [html.Text(text)])` -pub fn tbody_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "tbody", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<td>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) -pub fn td(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "td", attrs: attrs, children: children) -} - -/// Shorthand for `html.td(attrs, children: [html.Text(text)])` -pub fn td_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "td", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<textarea>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) -pub fn textarea(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "textarea", attrs: attrs, children: children) -} - -/// Shorthand for `html.textarea(attrs, children: [html.Text(text)])` -pub fn textarea_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "textarea", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<tfoot>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot) -pub fn tfoot(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "tfoot", attrs: attrs, children: children) -} - -/// Shorthand for `html.tfoot(attrs, children: [html.Text(text)])` -pub fn tfoot_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "tfoot", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<th>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th) -pub fn th(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "th", attrs: attrs, children: children) -} - -/// Shorthand for `html.th(attrs, children: [html.Text(text)])` -pub fn th_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "th", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<thead>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead) -pub fn thead(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "thead", attrs: attrs, children: children) -} - -/// Shorthand for `html.thead(attrs, children: [html.Text(text)])` -pub fn thead_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "thead", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<time>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time) -pub fn time(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "time", attrs: attrs, children: children) -} - -/// Shorthand for `html.time(attrs, children: [html.Text(text)])` -pub fn time_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "time", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<tr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr) -pub fn tr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "tr", attrs: attrs, children: children) -} - -/// Shorthand for `html.tr(attrs, children: [html.Text(text)])` -pub fn tr_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "tr", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<track />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track) -pub fn track(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "track", attrs: attrs) -} - -/// The [HTML `<u>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u) -pub fn u(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "u", attrs: attrs, children: children) -} - -/// Shorthand for `html.u(attrs, children: [html.Text(text)])` -pub fn u_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "u", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<ul>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul) -pub fn ul(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ul", attrs: attrs, children: children) -} - -/// Shorthand for `html.ul(attrs, children: [html.Text(text)])` -pub fn ul_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ul", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<var>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var) -pub fn var(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "var", attrs: attrs, children: children) -} - -/// Shorthand for `html.var(attrs, children: [html.Text(text)])` -pub fn var_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "var", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<video>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) -pub fn video(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "video", attrs: attrs, children: children) -} - -/// Shorthand for `html.video(attrs, children: [html.Text(text)])` -pub fn video_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "video", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<wbr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr) -pub fn wbr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "wbr", attrs: attrs, children: children) -} - -/// Shorthand for `html.wbr(attrs, children: [html.Text(text)])` -pub fn wbr_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "wbr", attrs: attrs, children: [Text(text)]) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam deleted file mode 100644 index a8fda0fb25a..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// * THIS FILE IS GENERATED. DO NOT EDIT IT. * -// * You're probably looking for ./codegen/attrs_prelude.gleam, or ./codegen/attrs.json. * -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - - - - -pub type Attr(a) { - Attr(name: String, value: String) - Event(name: String, action: a) -} - -pub fn data(name: String, value: String) -> Attr(a) { - Attr(name: "data-" <> name, value: value) -} - -pub fn accept(value: String) -> Attr(a) { - Attr(name: "accept", value: value) -} - -pub fn accept_charset(value: String) -> Attr(a) { - Attr(name: "accept-charset", value: value) -} - -pub fn action(value: String) -> Attr(a) { - Attr(name: "action", value: value) -} - -pub fn alt(value: String) -> Attr(a) { - Attr(name: "alt", value: value) -} - -pub fn async() -> Attr(a) { - Attr(name: "async", value: "true") -} - -pub fn autocapitalize(value: String) -> Attr(a) { - Attr(name: "autocapitalize", value: value) -} - -pub fn autocomplete(value: String) -> Attr(a) { - Attr(name: "autocomplete", value: value) -} - -pub fn autofocus() -> Attr(a) { - Attr(name: "autofocus", value: "true") -} - -pub fn autoplay() -> Attr(a) { - Attr(name: "autoplay", value: "true") -} - -pub fn capture(value: String) -> Attr(a) { - Attr(name: "capture", value: value) -} - -pub fn charset(value: String) -> Attr(a) { - Attr(name: "charset", value: value) -} - -pub fn checked() -> Attr(a) { - Attr(name: "checked", value: "true") -} - -pub fn cite(value: String) -> Attr(a) { - Attr(name: "cite", value: value) -} - -pub fn class(value: String) -> Attr(a) { - Attr(name: "class", value: value) -} - -pub fn content(value: String) -> Attr(a) { - Attr(name: "content", value: value) -} - -pub fn contenteditable() -> Attr(a) { - Attr(name: "contenteditable", value: "true") -} - -pub fn crossorigin() -> Attr(a) { - Attr(name: "crossorigin", value: "true") -} - -pub fn defer() -> Attr(a) { - Attr(name: "defer", value: "true") -} - -pub fn disabled() -> Attr(a) { - Attr(name: "disabled", value: "true") -} - -pub fn draggable() -> Attr(a) { - Attr(name: "draggable", value: "true") -} - -pub fn for(value: String) -> Attr(a) { - Attr(name: "for", value: value) -} - -pub fn formaction(value: String) -> Attr(a) { - Attr(name: "formaction", value: value) -} - -pub fn height(value: String) -> Attr(a) { - Attr(name: "height", value: value) -} - -pub fn href(value: String) -> Attr(a) { - Attr(name: "href", value: value) -} - -pub fn http_equiv(value: String) -> Attr(a) { - Attr(name: "http-equiv", value: value) -} - -pub fn id(value: String) -> Attr(a) { - Attr(name: "id", value: value) -} - -pub fn integrity(value: String) -> Attr(a) { - Attr(name: "integrity", value: value) -} - -pub fn lang(value: String) -> Attr(a) { - Attr(name: "lang", value: value) -} - -pub fn loop() -> Attr(a) { - Attr(name: "loop", value: "true") -} - -pub fn method(value: String) -> Attr(a) { - Attr(name: "method", value: value) -} - -pub fn name(value: String) -> Attr(a) { - Attr(name: "name", value: value) -} - -pub fn placeholder(value: String) -> Attr(a) { - Attr(name: "placeholder", value: value) -} - -pub fn preload() -> Attr(a) { - Attr(name: "preload", value: "true") -} - -pub fn property(value: String) -> Attr(a) { - Attr(name: "property", value: value) -} - -pub fn readonly() -> Attr(a) { - Attr(name: "readonly", value: "true") -} - -pub fn rel(value: String) -> Attr(a) { - Attr(name: "rel", value: value) -} - -pub fn selected() -> Attr(a) { - Attr(name: "selected", value: "true") -} - -pub fn src(value: String) -> Attr(a) { - Attr(name: "src", value: value) -} - -pub fn style(value: String) -> Attr(a) { - Attr(name: "style", value: value) -} - -pub fn tabindex(value: String) -> Attr(a) { - Attr(name: "tabindex", value: value) -} - -pub fn target(value: String) -> Attr(a) { - Attr(name: "target", value: value) -} - -pub fn title(value: String) -> Attr(a) { - Attr(name: "title", value: value) -} - -pub fn type_(value: String) -> Attr(a) { - Attr(name: "type", value: value) -} - -pub fn value(value: String) -> Attr(a) { - Attr(name: "value", value: value) -} - -pub fn width(value: String) -> Attr(a) { - Attr(name: "width", value: value) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam deleted file mode 100644 index 8fe56a47f23..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam +++ /dev/null @@ -1,97 +0,0 @@ -import gleam/option.{Option} -import gleam/list -import gleam/string_builder.{StringBuilder} - -pub const encoding = " -<meta charset=\"utf-8\" /> -<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /> -" - -pub type Document { - Document( - doctype: Option(String), - html_attrs: StringBuilder, - body_attrs: StringBuilder, - head: StringBuilder, - body: StringBuilder, - scripts: List(String), - ) -} - -pub fn new() { - Document( - doctype: option.None, - html_attrs: string_builder.new(), - body_attrs: string_builder.new(), - head: string_builder.new(), - body: string_builder.new(), - scripts: [], - ) -} - -pub fn merge(self: Document, new: Document) -> Document { - Document( - // Overwrite the doctype with a newer one, unless the newer one is `None` - doctype: option.or(new.doctype, self.doctype), - html_attrs: string_builder.append_builder(self.html_attrs, new.html_attrs), - body_attrs: string_builder.append_builder(self.body_attrs, new.body_attrs), - head: string_builder.append_builder(self.head, new.head), - body: string_builder.append_builder(self.body, new.body), - scripts: list.append(self.scripts, new.scripts), - ) -} - -pub fn concat(docs: List(Document)) -> Document { - docs - |> list.fold(new(), merge) -} - -pub fn from_doctype(doctype: String) -> Document { - Document(..new(), doctype: option.Some(doctype)) -} - -pub fn append_html_attrs(self: Document, html_attrs: StringBuilder) -> Document { - Document( - ..self, - html_attrs: string_builder.append_builder(self.html_attrs, html_attrs), - ) -} - -pub fn append_body_attrs(self: Document, body_attrs: StringBuilder) -> Document { - Document( - ..self, - body_attrs: string_builder.append_builder(self.body_attrs, body_attrs), - ) -} - -pub fn from_head(head: StringBuilder) -> Document { - Document(..new(), head: head) -} - -pub fn append_head(self: Document, head: StringBuilder) -> Document { - Document(..self, head: string_builder.append_builder(self.head, head)) -} - -pub fn from_body(body: StringBuilder) -> Document { - Document(..new(), body: body) -} - -pub fn append_body(self: Document, body: StringBuilder) -> Document { - Document(..self, body: string_builder.append_builder(self.body, body)) -} - -pub fn replace_body(self: Document, body: StringBuilder) -> Document { - Document(..self, body: body) -} - -pub fn from_script(script: String) -> Document { - Document(..new(), scripts: [script]) -} - -pub fn into_head(state: Document) -> Document { - Document( - ..state, - head: string_builder.append_builder(state.head, state.body), - body: string_builder.new(), - ) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam deleted file mode 100644 index 780a9715f79..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam +++ /dev/null @@ -1,211 +0,0 @@ -import gleam/list -import gleam/option -import gleam/string_builder.{StringBuilder} -import gleam/string -import nakai/html.{Node} -import nakai/html/attrs.{Attr, Event} -import nakai/internal/document.{Document} - -type Builder(a, output) { - Builder(map: fn(Node(a)) -> output, fold: fn(List(output)) -> output) -} - -const document_builder = Builder( - map: render_document_node, - fold: document.concat, -) - -const inline_builder = Builder( - map: render_inline_node, - fold: string_builder.concat, -) - -fn render_doctype(doctype: String) -> StringBuilder { - string_builder.from_strings(["<!DOCTYPE ", doctype, ">\n"]) -} - -fn render_children( - children: List(Node(a)), - builder: Builder(a, output), -) -> output { - children - |> list.map(builder.map) - |> builder.fold() -} - -fn render_attrs(attrs: List(Attr(a))) -> StringBuilder { - attrs - |> list.map(render_attr) - |> list.fold(string_builder.new(), string_builder.append_builder) -} - -fn render_attr(attr: Attr(a)) -> StringBuilder { - case attr { - Attr(name, value) -> { - let sanitized_value = - value - |> string.replace("\"", """) - |> string.replace(">", ">") - string_builder.from_strings([" ", name, "=\"", sanitized_value, "\""]) - } - Event(_name, _action) -> { - string_builder.new() - } - } -} - -fn render_document_node(tree: Node(a)) -> Document { - case tree { - html.Doctype(doctype) -> document.from_doctype(doctype) - - html.Html(attrs, children) -> - render_children(children, document_builder) - |> document.append_html_attrs(render_attrs(attrs)) - - html.Head(children) -> - render_children(children, document_builder) - |> document.into_head() - - html.Body(attrs, children) -> - render_children(children, document_builder) - |> document.append_body_attrs(render_attrs(attrs)) - - html.Fragment(children) -> render_children(children, document_builder) - - html.Element(tag, attrs, children) -> { - let child_document = render_children(children, document_builder) - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(">"), - child_document.body, - string_builder.from_strings(["</", tag, ">"]), - ]) - |> document.replace_body(child_document, _) - } - - html.LeafElement(tag, attrs) -> - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(" />"), - ]) - |> document.from_body() - - html.Comment(content) -> { - let content = - content - |> string.replace("-->", "") - string_builder.from_strings(["<!-- ", content, " -->"]) - |> document.from_body() - } - - html.Text(content) -> - string_builder.from_string(content) - |> string_builder.replace("&", "&") - |> string_builder.replace("<", "<") - |> string_builder.replace(">", ">") - |> document.from_body() - - html.UnsafeText(content) -> - string_builder.from_string(content) - |> document.from_body() - - html.Script(script) -> document.from_script(script) - - html.Nothing -> document.new() - } -} - -fn render_inline_node(tree: Node(a)) -> StringBuilder { - case tree { - html.Doctype(doctype) -> render_doctype(doctype) - - html.Html(attrs, children) -> - render_inline_node(html.Element("html", attrs, children)) - - html.Head(children) -> - render_inline_node(html.Element("head", [], children)) - - html.Body(attrs, children) -> - render_inline_node(html.Element("body", attrs, children)) - - html.Fragment(children) -> render_children(children, inline_builder) - - html.Element(tag, attrs, children) -> { - let child_document = render_children(children, inline_builder) - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(">"), - child_document, - string_builder.from_strings(["</", tag, ">"]), - ]) - } - - html.LeafElement(tag, attrs) -> - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(" />"), - ]) - - html.Comment(content) -> { - let content = - content - |> string.replace("-->", "") - string_builder.from_strings(["<!-- ", content, " -->"]) - } - - html.Text(content) -> - string_builder.from_string(content) - |> string_builder.replace("&", "&") - |> string_builder.replace("<", "<") - |> string_builder.replace(">", ">") - - html.UnsafeText(content) -> string_builder.from_string(content) - - html.Script(script) -> - render_inline_node(html.Element("script", [], [html.Text(script)])) - - html.Nothing -> string_builder.new() - } -} - -fn render_script(script: String) -> StringBuilder { - string_builder.concat([ - string_builder.from_string("<script>"), - string_builder.from_string(script), - string_builder.from_string("</script>\n"), - ]) -} - -fn render_scripts(scripts: List(String)) -> StringBuilder { - scripts - |> list.map(render_script) - |> string_builder.concat() -} - -pub fn render_document(tree: Node(a)) -> StringBuilder { - let result = render_document_node(tree) - string_builder.concat([ - render_doctype( - result.doctype - |> option.unwrap("html"), - ), - string_builder.from_string("<html"), - result.html_attrs, - string_builder.from_string(">\n<head>" <> document.encoding), - result.head, - string_builder.from_string("</head>\n<body"), - result.body_attrs, - string_builder.from_string(">"), - result.body, - render_scripts(result.scripts), - string_builder.from_string("</body>\n</html>\n"), - ]) -} - -pub fn render_inline(tree: Node(a)) -> StringBuilder { - render_inline_node(tree) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl deleted file mode 100644 index ee2b3a30198..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(nakai@experimental@head). --compile([no_auto_import, nowarn_unused_vars]). - --export([title/1, link/2, meta/2, http_equiv/2, charset/1]). - --spec title(binary()) -> nakai@html:node_(any()). -title(Title) -> - {head, [nakai@html:title(Title)]}. - --spec link(binary(), binary()) -> nakai@html:node_(any()). -link(Rel, Href) -> - {head, - [nakai@html:link( - [nakai@html@attrs:rel(Rel), nakai@html@attrs:href(Href)] - )]}. - --spec meta(binary(), binary()) -> nakai@html:node_(any()). -meta(Name, Content) -> - {head, - [nakai@html:meta( - [nakai@html@attrs:name(Name), nakai@html@attrs:content(Content)] - )]}. - --spec http_equiv(binary(), binary()) -> nakai@html:node_(any()). -http_equiv(Header, Content) -> - {head, - [nakai@html:meta( - [nakai@html@attrs:http_equiv(Header), - nakai@html@attrs:content(Content)] - )]}. - --spec charset(binary()) -> nakai@html:node_(any()). -charset(Charset) -> - {head, [nakai@html:meta([nakai@html@attrs:charset(Charset)])]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl deleted file mode 100644 index 447491b17a6..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(nakai@experimental@on). --compile([no_auto_import, nowarn_unused_vars]). - --export([click/1]). - --spec click(binary()) -> nakai@html@attrs:attr(any()). -click(Script) -> - {attr, <<"onclick"/utf8>>, Script}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl deleted file mode 100644 index d1a7ff36142..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl +++ /dev/null @@ -1,12 +0,0 @@ --module(nakai@experimental@web_components). --compile([no_auto_import, nowarn_unused_vars]). - --export([slot/1, template/2]). - --spec slot(list(nakai@html@attrs:attr(ICF))) -> nakai@html:node_(ICF). -slot(Attrs) -> - {leaf_element, <<"slot"/utf8>>, Attrs}. - --spec template(list(nakai@html@attrs:attr(ICJ)), list(nakai@html:node_(ICJ))) -> nakai@html:node_(ICJ). -template(Attrs, Children) -> - {element, <<"template"/utf8>>, Attrs, Children}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl deleted file mode 100644 index 52c46d513f4..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl +++ /dev/null @@ -1,830 +0,0 @@ --module(nakai@html). --compile([no_auto_import, nowarn_unused_vars]). - --export([title/1, a/2, a_text/2, abbr/2, abbr_text/2, address/2, address_text/2, area/1, article/2, article_text/2, aside/2, aside_text/2, audio/2, audio_text/2, b/2, b_text/2, base/1, bdi/2, bdi_text/2, bdo/2, bdo_text/2, blockquote/2, blockquote_text/2, br/1, button/2, button_text/2, canvas/2, canvas_text/2, caption/2, caption_text/2, cite/2, cite_text/2, code/2, code_text/2, col/2, col_text/2, colgroup/2, colgroup_text/2, data/2, data_text/2, datalist/2, datalist_text/2, dd/2, dd_text/2, del/2, del_text/2, details/2, details_text/2, dfn/2, dfn_text/2, dialog/2, dialog_text/2, 'div'/2, div_text/2, dl/2, dl_text/2, dt/2, dt_text/2, em/2, em_text/2, embed/2, embed_text/2, fieldset/2, fieldset_text/2, figcaption/2, figcaption_text/2, figure/2, figure_text/2, footer/2, footer_text/2, form/2, form_text/2, h1/2, h1_text/2, h2/2, h2_text/2, h3/2, h3_text/2, h4/2, h4_text/2, h5/2, h5_text/2, h6/2, h6_text/2, header/2, header_text/2, hr/1, i/2, i_text/2, iframe/2, iframe_text/2, img/1, input/1, ins/2, ins_text/2, kbd/2, kbd_text/2, label/2, label_text/2, legend/2, legend_text/2, li/2, li_text/2, link/1, main/2, main_text/2, map/2, map_text/2, mark/2, mark_text/2, math/2, math_text/2, menu/2, menu_text/2, menuitem/2, menuitem_text/2, meta/1, meter/2, meter_text/2, nav/2, nav_text/2, noscript/2, noscript_text/2, object/2, object_text/2, ol/2, ol_text/2, optgroup/2, optgroup_text/2, option/2, option_text/2, output/2, output_text/2, p/2, p_text/2, param/2, param_text/2, picture/2, picture_text/2, pre/2, pre_text/2, progress/2, progress_text/2, q/2, q_text/2, rp/2, rp_text/2, rt/2, rt_text/2, ruby/2, ruby_text/2, s/2, s_text/2, samp/2, samp_text/2, section/2, section_text/2, select/2, select_text/2, small/2, small_text/2, source/1, span/2, span_text/2, strong/2, strong_text/2, sub/2, sub_text/2, summary/2, summary_text/2, sup/2, sup_text/2, svg/2, svg_text/2, table/2, table_text/2, tbody/2, tbody_text/2, td/2, td_text/2, textarea/2, textarea_text/2, tfoot/2, tfoot_text/2, th/2, th_text/2, thead/2, thead_text/2, time/2, time_text/2, tr/2, tr_text/2, track/1, u/2, u_text/2, ul/2, ul_text/2, var/2, var_text/2, video/2, video_text/2, wbr/2, wbr_text/2]). --export_type([node_/1]). - --type node_(FSS) :: {doctype, binary()} | - {html, list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | - {head, list(node_(FSS))} | - {body, list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | - {fragment, list(node_(FSS))} | - {element, binary(), list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | - {leaf_element, binary(), list(nakai@html@attrs:attr(FSS))} | - {comment, binary()} | - {text, binary()} | - {unsafe_text, binary()} | - {script, binary()} | - nothing. - --spec title(binary()) -> node_(any()). -title(Text) -> - {element, <<"title"/utf8>>, [], [{text, Text}]}. - --spec a(list(nakai@html@attrs:attr(FSV)), list(node_(FSV))) -> node_(FSV). -a(Attrs, Children) -> - {element, <<"a"/utf8>>, Attrs, Children}. - --spec a_text(list(nakai@html@attrs:attr(FTB)), binary()) -> node_(FTB). -a_text(Attrs, Text) -> - {element, <<"a"/utf8>>, Attrs, [{text, Text}]}. - --spec abbr(list(nakai@html@attrs:attr(FTF)), list(node_(FTF))) -> node_(FTF). -abbr(Attrs, Children) -> - {element, <<"abbr"/utf8>>, Attrs, Children}. - --spec abbr_text(list(nakai@html@attrs:attr(FTL)), binary()) -> node_(FTL). -abbr_text(Attrs, Text) -> - {element, <<"abbr"/utf8>>, Attrs, [{text, Text}]}. - --spec address(list(nakai@html@attrs:attr(FTP)), list(node_(FTP))) -> node_(FTP). -address(Attrs, Children) -> - {element, <<"address"/utf8>>, Attrs, Children}. - --spec address_text(list(nakai@html@attrs:attr(FTV)), binary()) -> node_(FTV). -address_text(Attrs, Text) -> - {element, <<"address"/utf8>>, Attrs, [{text, Text}]}. - --spec area(list(nakai@html@attrs:attr(FTZ))) -> node_(FTZ). -area(Attrs) -> - {leaf_element, <<"area"/utf8>>, Attrs}. - --spec article(list(nakai@html@attrs:attr(FUD)), list(node_(FUD))) -> node_(FUD). -article(Attrs, Children) -> - {element, <<"article"/utf8>>, Attrs, Children}. - --spec article_text(list(nakai@html@attrs:attr(FUJ)), binary()) -> node_(FUJ). -article_text(Attrs, Text) -> - {element, <<"article"/utf8>>, Attrs, [{text, Text}]}. - --spec aside(list(nakai@html@attrs:attr(FUN)), list(node_(FUN))) -> node_(FUN). -aside(Attrs, Children) -> - {element, <<"aside"/utf8>>, Attrs, Children}. - --spec aside_text(list(nakai@html@attrs:attr(FUT)), binary()) -> node_(FUT). -aside_text(Attrs, Text) -> - {element, <<"aside"/utf8>>, Attrs, [{text, Text}]}. - --spec audio(list(nakai@html@attrs:attr(FUX)), list(node_(FUX))) -> node_(FUX). -audio(Attrs, Children) -> - {element, <<"audio"/utf8>>, Attrs, Children}. - --spec audio_text(list(nakai@html@attrs:attr(FVD)), binary()) -> node_(FVD). -audio_text(Attrs, Text) -> - {element, <<"audio"/utf8>>, Attrs, [{text, Text}]}. - --spec b(list(nakai@html@attrs:attr(FVH)), list(node_(FVH))) -> node_(FVH). -b(Attrs, Children) -> - {element, <<"b"/utf8>>, Attrs, Children}. - --spec b_text(list(nakai@html@attrs:attr(FVN)), binary()) -> node_(FVN). -b_text(Attrs, Text) -> - {element, <<"b"/utf8>>, Attrs, [{text, Text}]}. - --spec base(list(nakai@html@attrs:attr(FVR))) -> node_(FVR). -base(Attrs) -> - {leaf_element, <<"base"/utf8>>, Attrs}. - --spec bdi(list(nakai@html@attrs:attr(FVV)), list(node_(FVV))) -> node_(FVV). -bdi(Attrs, Children) -> - {element, <<"bdi"/utf8>>, Attrs, Children}. - --spec bdi_text(list(nakai@html@attrs:attr(FWB)), binary()) -> node_(FWB). -bdi_text(Attrs, Text) -> - {element, <<"bdi"/utf8>>, Attrs, [{text, Text}]}. - --spec bdo(list(nakai@html@attrs:attr(FWF)), list(node_(FWF))) -> node_(FWF). -bdo(Attrs, Children) -> - {element, <<"bdo"/utf8>>, Attrs, Children}. - --spec bdo_text(list(nakai@html@attrs:attr(FWL)), binary()) -> node_(FWL). -bdo_text(Attrs, Text) -> - {element, <<"bdo"/utf8>>, Attrs, [{text, Text}]}. - --spec blockquote(list(nakai@html@attrs:attr(FWP)), list(node_(FWP))) -> node_(FWP). -blockquote(Attrs, Children) -> - {element, <<"blockquote"/utf8>>, Attrs, Children}. - --spec blockquote_text(list(nakai@html@attrs:attr(FWV)), binary()) -> node_(FWV). -blockquote_text(Attrs, Text) -> - {element, <<"blockquote"/utf8>>, Attrs, [{text, Text}]}. - --spec br(list(nakai@html@attrs:attr(FWZ))) -> node_(FWZ). -br(Attrs) -> - {leaf_element, <<"br"/utf8>>, Attrs}. - --spec button(list(nakai@html@attrs:attr(FXD)), list(node_(FXD))) -> node_(FXD). -button(Attrs, Children) -> - {element, <<"button"/utf8>>, Attrs, Children}. - --spec button_text(list(nakai@html@attrs:attr(FXJ)), binary()) -> node_(FXJ). -button_text(Attrs, Text) -> - {element, <<"button"/utf8>>, Attrs, [{text, Text}]}. - --spec canvas(list(nakai@html@attrs:attr(FXN)), list(node_(FXN))) -> node_(FXN). -canvas(Attrs, Children) -> - {element, <<"canvas"/utf8>>, Attrs, Children}. - --spec canvas_text(list(nakai@html@attrs:attr(FXT)), binary()) -> node_(FXT). -canvas_text(Attrs, Text) -> - {element, <<"canvas"/utf8>>, Attrs, [{text, Text}]}. - --spec caption(list(nakai@html@attrs:attr(FXX)), list(node_(FXX))) -> node_(FXX). -caption(Attrs, Children) -> - {element, <<"caption"/utf8>>, Attrs, Children}. - --spec caption_text(list(nakai@html@attrs:attr(FYD)), binary()) -> node_(FYD). -caption_text(Attrs, Text) -> - {element, <<"caption"/utf8>>, Attrs, [{text, Text}]}. - --spec cite(list(nakai@html@attrs:attr(FYH)), list(node_(FYH))) -> node_(FYH). -cite(Attrs, Children) -> - {element, <<"cite"/utf8>>, Attrs, Children}. - --spec cite_text(list(nakai@html@attrs:attr(FYN)), binary()) -> node_(FYN). -cite_text(Attrs, Text) -> - {element, <<"cite"/utf8>>, Attrs, [{text, Text}]}. - --spec code(list(nakai@html@attrs:attr(FYR)), list(node_(FYR))) -> node_(FYR). -code(Attrs, Children) -> - {element, <<"code"/utf8>>, Attrs, Children}. - --spec code_text(list(nakai@html@attrs:attr(FYX)), binary()) -> node_(FYX). -code_text(Attrs, Text) -> - {element, <<"code"/utf8>>, Attrs, [{text, Text}]}. - --spec col(list(nakai@html@attrs:attr(FZB)), list(node_(FZB))) -> node_(FZB). -col(Attrs, Children) -> - {element, <<"col"/utf8>>, Attrs, Children}. - --spec col_text(list(nakai@html@attrs:attr(FZH)), binary()) -> node_(FZH). -col_text(Attrs, Text) -> - {element, <<"col"/utf8>>, Attrs, [{text, Text}]}. - --spec colgroup(list(nakai@html@attrs:attr(FZL)), list(node_(FZL))) -> node_(FZL). -colgroup(Attrs, Children) -> - {element, <<"colgroup"/utf8>>, Attrs, Children}. - --spec colgroup_text(list(nakai@html@attrs:attr(FZR)), binary()) -> node_(FZR). -colgroup_text(Attrs, Text) -> - {element, <<"colgroup"/utf8>>, Attrs, [{text, Text}]}. - --spec data(list(nakai@html@attrs:attr(FZV)), list(node_(FZV))) -> node_(FZV). -data(Attrs, Children) -> - {element, <<"data"/utf8>>, Attrs, Children}. - --spec data_text(list(nakai@html@attrs:attr(GAB)), binary()) -> node_(GAB). -data_text(Attrs, Text) -> - {element, <<"data"/utf8>>, Attrs, [{text, Text}]}. - --spec datalist(list(nakai@html@attrs:attr(GAF)), list(node_(GAF))) -> node_(GAF). -datalist(Attrs, Children) -> - {element, <<"datalist"/utf8>>, Attrs, Children}. - --spec datalist_text(list(nakai@html@attrs:attr(GAL)), binary()) -> node_(GAL). -datalist_text(Attrs, Text) -> - {element, <<"datalist"/utf8>>, Attrs, [{text, Text}]}. - --spec dd(list(nakai@html@attrs:attr(GAP)), list(node_(GAP))) -> node_(GAP). -dd(Attrs, Children) -> - {element, <<"dd"/utf8>>, Attrs, Children}. - --spec dd_text(list(nakai@html@attrs:attr(GAV)), binary()) -> node_(GAV). -dd_text(Attrs, Text) -> - {element, <<"dd"/utf8>>, Attrs, [{text, Text}]}. - --spec del(list(nakai@html@attrs:attr(GAZ)), list(node_(GAZ))) -> node_(GAZ). -del(Attrs, Children) -> - {element, <<"del"/utf8>>, Attrs, Children}. - --spec del_text(list(nakai@html@attrs:attr(GBF)), binary()) -> node_(GBF). -del_text(Attrs, Text) -> - {element, <<"del"/utf8>>, Attrs, [{text, Text}]}. - --spec details(list(nakai@html@attrs:attr(GBJ)), list(node_(GBJ))) -> node_(GBJ). -details(Attrs, Children) -> - {element, <<"details"/utf8>>, Attrs, Children}. - --spec details_text(list(nakai@html@attrs:attr(GBP)), binary()) -> node_(GBP). -details_text(Attrs, Text) -> - {element, <<"details"/utf8>>, Attrs, [{text, Text}]}. - --spec dfn(list(nakai@html@attrs:attr(GBT)), list(node_(GBT))) -> node_(GBT). -dfn(Attrs, Children) -> - {element, <<"dfn"/utf8>>, Attrs, Children}. - --spec dfn_text(list(nakai@html@attrs:attr(GBZ)), binary()) -> node_(GBZ). -dfn_text(Attrs, Text) -> - {element, <<"dfn"/utf8>>, Attrs, [{text, Text}]}. - --spec dialog(list(nakai@html@attrs:attr(GCD)), list(node_(GCD))) -> node_(GCD). -dialog(Attrs, Children) -> - {element, <<"dialog"/utf8>>, Attrs, Children}. - --spec dialog_text(list(nakai@html@attrs:attr(GCJ)), binary()) -> node_(GCJ). -dialog_text(Attrs, Text) -> - {element, <<"dialog"/utf8>>, Attrs, [{text, Text}]}. - --spec 'div'(list(nakai@html@attrs:attr(GCN)), list(node_(GCN))) -> node_(GCN). -'div'(Attrs, Children) -> - {element, <<"div"/utf8>>, Attrs, Children}. - --spec div_text(list(nakai@html@attrs:attr(GCT)), binary()) -> node_(GCT). -div_text(Attrs, Text) -> - {element, <<"div"/utf8>>, Attrs, [{text, Text}]}. - --spec dl(list(nakai@html@attrs:attr(GCX)), list(node_(GCX))) -> node_(GCX). -dl(Attrs, Children) -> - {element, <<"dl"/utf8>>, Attrs, Children}. - --spec dl_text(list(nakai@html@attrs:attr(GDD)), binary()) -> node_(GDD). -dl_text(Attrs, Text) -> - {element, <<"dl"/utf8>>, Attrs, [{text, Text}]}. - --spec dt(list(nakai@html@attrs:attr(GDH)), list(node_(GDH))) -> node_(GDH). -dt(Attrs, Children) -> - {element, <<"dt"/utf8>>, Attrs, Children}. - --spec dt_text(list(nakai@html@attrs:attr(GDN)), binary()) -> node_(GDN). -dt_text(Attrs, Text) -> - {element, <<"dt"/utf8>>, Attrs, [{text, Text}]}. - --spec em(list(nakai@html@attrs:attr(GDR)), list(node_(GDR))) -> node_(GDR). -em(Attrs, Children) -> - {element, <<"em"/utf8>>, Attrs, Children}. - --spec em_text(list(nakai@html@attrs:attr(GDX)), binary()) -> node_(GDX). -em_text(Attrs, Text) -> - {element, <<"em"/utf8>>, Attrs, [{text, Text}]}. - --spec embed(list(nakai@html@attrs:attr(GEB)), list(node_(GEB))) -> node_(GEB). -embed(Attrs, Children) -> - {element, <<"embed"/utf8>>, Attrs, Children}. - --spec embed_text(list(nakai@html@attrs:attr(GEH)), binary()) -> node_(GEH). -embed_text(Attrs, Text) -> - {element, <<"embed"/utf8>>, Attrs, [{text, Text}]}. - --spec fieldset(list(nakai@html@attrs:attr(GEL)), list(node_(GEL))) -> node_(GEL). -fieldset(Attrs, Children) -> - {element, <<"fieldset"/utf8>>, Attrs, Children}. - --spec fieldset_text(list(nakai@html@attrs:attr(GER)), binary()) -> node_(GER). -fieldset_text(Attrs, Text) -> - {element, <<"fieldset"/utf8>>, Attrs, [{text, Text}]}. - --spec figcaption(list(nakai@html@attrs:attr(GEV)), list(node_(GEV))) -> node_(GEV). -figcaption(Attrs, Children) -> - {element, <<"figcaption"/utf8>>, Attrs, Children}. - --spec figcaption_text(list(nakai@html@attrs:attr(GFB)), binary()) -> node_(GFB). -figcaption_text(Attrs, Text) -> - {element, <<"figcaption"/utf8>>, Attrs, [{text, Text}]}. - --spec figure(list(nakai@html@attrs:attr(GFF)), list(node_(GFF))) -> node_(GFF). -figure(Attrs, Children) -> - {element, <<"figure"/utf8>>, Attrs, Children}. - --spec figure_text(list(nakai@html@attrs:attr(GFL)), binary()) -> node_(GFL). -figure_text(Attrs, Text) -> - {element, <<"figure"/utf8>>, Attrs, [{text, Text}]}. - --spec footer(list(nakai@html@attrs:attr(GFP)), list(node_(GFP))) -> node_(GFP). -footer(Attrs, Children) -> - {element, <<"footer"/utf8>>, Attrs, Children}. - --spec footer_text(list(nakai@html@attrs:attr(GFV)), binary()) -> node_(GFV). -footer_text(Attrs, Text) -> - {element, <<"footer"/utf8>>, Attrs, [{text, Text}]}. - --spec form(list(nakai@html@attrs:attr(GFZ)), list(node_(GFZ))) -> node_(GFZ). -form(Attrs, Children) -> - {element, <<"form"/utf8>>, Attrs, Children}. - --spec form_text(list(nakai@html@attrs:attr(GGF)), binary()) -> node_(GGF). -form_text(Attrs, Text) -> - {element, <<"form"/utf8>>, Attrs, [{text, Text}]}. - --spec h1(list(nakai@html@attrs:attr(GGJ)), list(node_(GGJ))) -> node_(GGJ). -h1(Attrs, Children) -> - {element, <<"h1"/utf8>>, Attrs, Children}. - --spec h1_text(list(nakai@html@attrs:attr(GGP)), binary()) -> node_(GGP). -h1_text(Attrs, Text) -> - {element, <<"h1"/utf8>>, Attrs, [{text, Text}]}. - --spec h2(list(nakai@html@attrs:attr(GGT)), list(node_(GGT))) -> node_(GGT). -h2(Attrs, Children) -> - {element, <<"h2"/utf8>>, Attrs, Children}. - --spec h2_text(list(nakai@html@attrs:attr(GGZ)), binary()) -> node_(GGZ). -h2_text(Attrs, Text) -> - {element, <<"h2"/utf8>>, Attrs, [{text, Text}]}. - --spec h3(list(nakai@html@attrs:attr(GHD)), list(node_(GHD))) -> node_(GHD). -h3(Attrs, Children) -> - {element, <<"h3"/utf8>>, Attrs, Children}. - --spec h3_text(list(nakai@html@attrs:attr(GHJ)), binary()) -> node_(GHJ). -h3_text(Attrs, Text) -> - {element, <<"h3"/utf8>>, Attrs, [{text, Text}]}. - --spec h4(list(nakai@html@attrs:attr(GHN)), list(node_(GHN))) -> node_(GHN). -h4(Attrs, Children) -> - {element, <<"h4"/utf8>>, Attrs, Children}. - --spec h4_text(list(nakai@html@attrs:attr(GHT)), binary()) -> node_(GHT). -h4_text(Attrs, Text) -> - {element, <<"h4"/utf8>>, Attrs, [{text, Text}]}. - --spec h5(list(nakai@html@attrs:attr(GHX)), list(node_(GHX))) -> node_(GHX). -h5(Attrs, Children) -> - {element, <<"h5"/utf8>>, Attrs, Children}. - --spec h5_text(list(nakai@html@attrs:attr(GID)), binary()) -> node_(GID). -h5_text(Attrs, Text) -> - {element, <<"h5"/utf8>>, Attrs, [{text, Text}]}. - --spec h6(list(nakai@html@attrs:attr(GIH)), list(node_(GIH))) -> node_(GIH). -h6(Attrs, Children) -> - {element, <<"h6"/utf8>>, Attrs, Children}. - --spec h6_text(list(nakai@html@attrs:attr(GIN)), binary()) -> node_(GIN). -h6_text(Attrs, Text) -> - {element, <<"h6"/utf8>>, Attrs, [{text, Text}]}. - --spec header(list(nakai@html@attrs:attr(GIR)), list(node_(GIR))) -> node_(GIR). -header(Attrs, Children) -> - {element, <<"header"/utf8>>, Attrs, Children}. - --spec header_text(list(nakai@html@attrs:attr(GIX)), binary()) -> node_(GIX). -header_text(Attrs, Text) -> - {element, <<"header"/utf8>>, Attrs, [{text, Text}]}. - --spec hr(list(nakai@html@attrs:attr(GJB))) -> node_(GJB). -hr(Attrs) -> - {leaf_element, <<"hr"/utf8>>, Attrs}. - --spec i(list(nakai@html@attrs:attr(GJF)), list(node_(GJF))) -> node_(GJF). -i(Attrs, Children) -> - {element, <<"i"/utf8>>, Attrs, Children}. - --spec i_text(list(nakai@html@attrs:attr(GJL)), binary()) -> node_(GJL). -i_text(Attrs, Text) -> - {element, <<"i"/utf8>>, Attrs, [{text, Text}]}. - --spec iframe(list(nakai@html@attrs:attr(GJP)), list(node_(GJP))) -> node_(GJP). -iframe(Attrs, Children) -> - {element, <<"iframe"/utf8>>, Attrs, Children}. - --spec iframe_text(list(nakai@html@attrs:attr(GJV)), binary()) -> node_(GJV). -iframe_text(Attrs, Text) -> - {element, <<"iframe"/utf8>>, Attrs, [{text, Text}]}. - --spec img(list(nakai@html@attrs:attr(GJZ))) -> node_(GJZ). -img(Attrs) -> - {leaf_element, <<"img"/utf8>>, Attrs}. - --spec input(list(nakai@html@attrs:attr(GKD))) -> node_(GKD). -input(Attrs) -> - {leaf_element, <<"input"/utf8>>, Attrs}. - --spec ins(list(nakai@html@attrs:attr(GKH)), list(node_(GKH))) -> node_(GKH). -ins(Attrs, Children) -> - {element, <<"ins"/utf8>>, Attrs, Children}. - --spec ins_text(list(nakai@html@attrs:attr(GKN)), binary()) -> node_(GKN). -ins_text(Attrs, Text) -> - {element, <<"ins"/utf8>>, Attrs, [{text, Text}]}. - --spec kbd(list(nakai@html@attrs:attr(GKR)), list(node_(GKR))) -> node_(GKR). -kbd(Attrs, Children) -> - {element, <<"kbd"/utf8>>, Attrs, Children}. - --spec kbd_text(list(nakai@html@attrs:attr(GKX)), binary()) -> node_(GKX). -kbd_text(Attrs, Text) -> - {element, <<"kbd"/utf8>>, Attrs, [{text, Text}]}. - --spec label(list(nakai@html@attrs:attr(GLB)), list(node_(GLB))) -> node_(GLB). -label(Attrs, Children) -> - {element, <<"label"/utf8>>, Attrs, Children}. - --spec label_text(list(nakai@html@attrs:attr(GLH)), binary()) -> node_(GLH). -label_text(Attrs, Text) -> - {element, <<"label"/utf8>>, Attrs, [{text, Text}]}. - --spec legend(list(nakai@html@attrs:attr(GLL)), list(node_(GLL))) -> node_(GLL). -legend(Attrs, Children) -> - {element, <<"legend"/utf8>>, Attrs, Children}. - --spec legend_text(list(nakai@html@attrs:attr(GLR)), binary()) -> node_(GLR). -legend_text(Attrs, Text) -> - {element, <<"legend"/utf8>>, Attrs, [{text, Text}]}. - --spec li(list(nakai@html@attrs:attr(GLV)), list(node_(GLV))) -> node_(GLV). -li(Attrs, Children) -> - {element, <<"li"/utf8>>, Attrs, Children}. - --spec li_text(list(nakai@html@attrs:attr(GMB)), binary()) -> node_(GMB). -li_text(Attrs, Text) -> - {element, <<"li"/utf8>>, Attrs, [{text, Text}]}. - --spec link(list(nakai@html@attrs:attr(GMF))) -> node_(GMF). -link(Attrs) -> - {leaf_element, <<"link"/utf8>>, Attrs}. - --spec main(list(nakai@html@attrs:attr(GMJ)), list(node_(GMJ))) -> node_(GMJ). -main(Attrs, Children) -> - {element, <<"main"/utf8>>, Attrs, Children}. - --spec main_text(list(nakai@html@attrs:attr(GMP)), binary()) -> node_(GMP). -main_text(Attrs, Text) -> - {element, <<"main"/utf8>>, Attrs, [{text, Text}]}. - --spec map(list(nakai@html@attrs:attr(GMT)), list(node_(GMT))) -> node_(GMT). -map(Attrs, Children) -> - {element, <<"map"/utf8>>, Attrs, Children}. - --spec map_text(list(nakai@html@attrs:attr(GMZ)), binary()) -> node_(GMZ). -map_text(Attrs, Text) -> - {element, <<"map"/utf8>>, Attrs, [{text, Text}]}. - --spec mark(list(nakai@html@attrs:attr(GND)), list(node_(GND))) -> node_(GND). -mark(Attrs, Children) -> - {element, <<"mark"/utf8>>, Attrs, Children}. - --spec mark_text(list(nakai@html@attrs:attr(GNJ)), binary()) -> node_(GNJ). -mark_text(Attrs, Text) -> - {element, <<"mark"/utf8>>, Attrs, [{text, Text}]}. - --spec math(list(nakai@html@attrs:attr(GNN)), list(node_(GNN))) -> node_(GNN). -math(Attrs, Children) -> - {element, <<"math"/utf8>>, Attrs, Children}. - --spec math_text(list(nakai@html@attrs:attr(GNT)), binary()) -> node_(GNT). -math_text(Attrs, Text) -> - {element, <<"math"/utf8>>, Attrs, [{text, Text}]}. - --spec menu(list(nakai@html@attrs:attr(GNX)), list(node_(GNX))) -> node_(GNX). -menu(Attrs, Children) -> - {element, <<"menu"/utf8>>, Attrs, Children}. - --spec menu_text(list(nakai@html@attrs:attr(GOD)), binary()) -> node_(GOD). -menu_text(Attrs, Text) -> - {element, <<"menu"/utf8>>, Attrs, [{text, Text}]}. - --spec menuitem(list(nakai@html@attrs:attr(GOH)), list(node_(GOH))) -> node_(GOH). -menuitem(Attrs, Children) -> - {element, <<"menuitem"/utf8>>, Attrs, Children}. - --spec menuitem_text(list(nakai@html@attrs:attr(GON)), binary()) -> node_(GON). -menuitem_text(Attrs, Text) -> - {element, <<"menuitem"/utf8>>, Attrs, [{text, Text}]}. - --spec meta(list(nakai@html@attrs:attr(GOR))) -> node_(GOR). -meta(Attrs) -> - {leaf_element, <<"meta"/utf8>>, Attrs}. - --spec meter(list(nakai@html@attrs:attr(GOV)), list(node_(GOV))) -> node_(GOV). -meter(Attrs, Children) -> - {element, <<"meter"/utf8>>, Attrs, Children}. - --spec meter_text(list(nakai@html@attrs:attr(GPB)), binary()) -> node_(GPB). -meter_text(Attrs, Text) -> - {element, <<"meter"/utf8>>, Attrs, [{text, Text}]}. - --spec nav(list(nakai@html@attrs:attr(GPF)), list(node_(GPF))) -> node_(GPF). -nav(Attrs, Children) -> - {element, <<"nav"/utf8>>, Attrs, Children}. - --spec nav_text(list(nakai@html@attrs:attr(GPL)), binary()) -> node_(GPL). -nav_text(Attrs, Text) -> - {element, <<"nav"/utf8>>, Attrs, [{text, Text}]}. - --spec noscript(list(nakai@html@attrs:attr(GPP)), list(node_(GPP))) -> node_(GPP). -noscript(Attrs, Children) -> - {element, <<"noscript"/utf8>>, Attrs, Children}. - --spec noscript_text(list(nakai@html@attrs:attr(GPV)), binary()) -> node_(GPV). -noscript_text(Attrs, Text) -> - {element, <<"noscript"/utf8>>, Attrs, [{text, Text}]}. - --spec object(list(nakai@html@attrs:attr(GPZ)), list(node_(GPZ))) -> node_(GPZ). -object(Attrs, Children) -> - {element, <<"object"/utf8>>, Attrs, Children}. - --spec object_text(list(nakai@html@attrs:attr(GQF)), binary()) -> node_(GQF). -object_text(Attrs, Text) -> - {element, <<"object"/utf8>>, Attrs, [{text, Text}]}. - --spec ol(list(nakai@html@attrs:attr(GQJ)), list(node_(GQJ))) -> node_(GQJ). -ol(Attrs, Children) -> - {element, <<"ol"/utf8>>, Attrs, Children}. - --spec ol_text(list(nakai@html@attrs:attr(GQP)), binary()) -> node_(GQP). -ol_text(Attrs, Text) -> - {element, <<"ol"/utf8>>, Attrs, [{text, Text}]}. - --spec optgroup(list(nakai@html@attrs:attr(GQT)), list(node_(GQT))) -> node_(GQT). -optgroup(Attrs, Children) -> - {element, <<"optgroup"/utf8>>, Attrs, Children}. - --spec optgroup_text(list(nakai@html@attrs:attr(GQZ)), binary()) -> node_(GQZ). -optgroup_text(Attrs, Text) -> - {element, <<"optgroup"/utf8>>, Attrs, [{text, Text}]}. - --spec option(list(nakai@html@attrs:attr(GRD)), list(node_(GRD))) -> node_(GRD). -option(Attrs, Children) -> - {element, <<"option"/utf8>>, Attrs, Children}. - --spec option_text(list(nakai@html@attrs:attr(GRJ)), binary()) -> node_(GRJ). -option_text(Attrs, Text) -> - {element, <<"option"/utf8>>, Attrs, [{text, Text}]}. - --spec output(list(nakai@html@attrs:attr(GRN)), list(node_(GRN))) -> node_(GRN). -output(Attrs, Children) -> - {element, <<"output"/utf8>>, Attrs, Children}. - --spec output_text(list(nakai@html@attrs:attr(GRT)), binary()) -> node_(GRT). -output_text(Attrs, Text) -> - {element, <<"output"/utf8>>, Attrs, [{text, Text}]}. - --spec p(list(nakai@html@attrs:attr(GRX)), list(node_(GRX))) -> node_(GRX). -p(Attrs, Children) -> - {element, <<"p"/utf8>>, Attrs, Children}. - --spec p_text(list(nakai@html@attrs:attr(GSD)), binary()) -> node_(GSD). -p_text(Attrs, Text) -> - {element, <<"p"/utf8>>, Attrs, [{text, Text}]}. - --spec param(list(nakai@html@attrs:attr(GSH)), list(node_(GSH))) -> node_(GSH). -param(Attrs, Children) -> - {element, <<"param"/utf8>>, Attrs, Children}. - --spec param_text(list(nakai@html@attrs:attr(GSN)), binary()) -> node_(GSN). -param_text(Attrs, Text) -> - {element, <<"param"/utf8>>, Attrs, [{text, Text}]}. - --spec picture(list(nakai@html@attrs:attr(GSR)), list(node_(GSR))) -> node_(GSR). -picture(Attrs, Children) -> - {element, <<"picture"/utf8>>, Attrs, Children}. - --spec picture_text(list(nakai@html@attrs:attr(GSX)), binary()) -> node_(GSX). -picture_text(Attrs, Text) -> - {element, <<"picture"/utf8>>, Attrs, [{text, Text}]}. - --spec pre(list(nakai@html@attrs:attr(GTB)), list(node_(GTB))) -> node_(GTB). -pre(Attrs, Children) -> - {element, <<"pre"/utf8>>, Attrs, Children}. - --spec pre_text(list(nakai@html@attrs:attr(GTH)), binary()) -> node_(GTH). -pre_text(Attrs, Text) -> - {element, <<"pre"/utf8>>, Attrs, [{text, Text}]}. - --spec progress(list(nakai@html@attrs:attr(GTL)), list(node_(GTL))) -> node_(GTL). -progress(Attrs, Children) -> - {element, <<"progress"/utf8>>, Attrs, Children}. - --spec progress_text(list(nakai@html@attrs:attr(GTR)), binary()) -> node_(GTR). -progress_text(Attrs, Text) -> - {element, <<"progress"/utf8>>, Attrs, [{text, Text}]}. - --spec q(list(nakai@html@attrs:attr(GTV)), list(node_(GTV))) -> node_(GTV). -q(Attrs, Children) -> - {element, <<"q"/utf8>>, Attrs, Children}. - --spec q_text(list(nakai@html@attrs:attr(GUB)), binary()) -> node_(GUB). -q_text(Attrs, Text) -> - {element, <<"q"/utf8>>, Attrs, [{text, Text}]}. - --spec rp(list(nakai@html@attrs:attr(GUF)), list(node_(GUF))) -> node_(GUF). -rp(Attrs, Children) -> - {element, <<"rp"/utf8>>, Attrs, Children}. - --spec rp_text(list(nakai@html@attrs:attr(GUL)), binary()) -> node_(GUL). -rp_text(Attrs, Text) -> - {element, <<"rp"/utf8>>, Attrs, [{text, Text}]}. - --spec rt(list(nakai@html@attrs:attr(GUP)), list(node_(GUP))) -> node_(GUP). -rt(Attrs, Children) -> - {element, <<"rt"/utf8>>, Attrs, Children}. - --spec rt_text(list(nakai@html@attrs:attr(GUV)), binary()) -> node_(GUV). -rt_text(Attrs, Text) -> - {element, <<"rt"/utf8>>, Attrs, [{text, Text}]}. - --spec ruby(list(nakai@html@attrs:attr(GUZ)), list(node_(GUZ))) -> node_(GUZ). -ruby(Attrs, Children) -> - {element, <<"ruby"/utf8>>, Attrs, Children}. - --spec ruby_text(list(nakai@html@attrs:attr(GVF)), binary()) -> node_(GVF). -ruby_text(Attrs, Text) -> - {element, <<"ruby"/utf8>>, Attrs, [{text, Text}]}. - --spec s(list(nakai@html@attrs:attr(GVJ)), list(node_(GVJ))) -> node_(GVJ). -s(Attrs, Children) -> - {element, <<"s"/utf8>>, Attrs, Children}. - --spec s_text(list(nakai@html@attrs:attr(GVP)), binary()) -> node_(GVP). -s_text(Attrs, Text) -> - {element, <<"s"/utf8>>, Attrs, [{text, Text}]}. - --spec samp(list(nakai@html@attrs:attr(GVT)), list(node_(GVT))) -> node_(GVT). -samp(Attrs, Children) -> - {element, <<"samp"/utf8>>, Attrs, Children}. - --spec samp_text(list(nakai@html@attrs:attr(GVZ)), binary()) -> node_(GVZ). -samp_text(Attrs, Text) -> - {element, <<"samp"/utf8>>, Attrs, [{text, Text}]}. - --spec section(list(nakai@html@attrs:attr(GWD)), list(node_(GWD))) -> node_(GWD). -section(Attrs, Children) -> - {element, <<"section"/utf8>>, Attrs, Children}. - --spec section_text(list(nakai@html@attrs:attr(GWJ)), binary()) -> node_(GWJ). -section_text(Attrs, Text) -> - {element, <<"section"/utf8>>, Attrs, [{text, Text}]}. - --spec select(list(nakai@html@attrs:attr(GWN)), list(node_(GWN))) -> node_(GWN). -select(Attrs, Children) -> - {element, <<"select"/utf8>>, Attrs, Children}. - --spec select_text(list(nakai@html@attrs:attr(GWT)), binary()) -> node_(GWT). -select_text(Attrs, Text) -> - {element, <<"select"/utf8>>, Attrs, [{text, Text}]}. - --spec small(list(nakai@html@attrs:attr(GWX)), list(node_(GWX))) -> node_(GWX). -small(Attrs, Children) -> - {element, <<"small"/utf8>>, Attrs, Children}. - --spec small_text(list(nakai@html@attrs:attr(GXD)), binary()) -> node_(GXD). -small_text(Attrs, Text) -> - {element, <<"small"/utf8>>, Attrs, [{text, Text}]}. - --spec source(list(nakai@html@attrs:attr(GXH))) -> node_(GXH). -source(Attrs) -> - {leaf_element, <<"source"/utf8>>, Attrs}. - --spec span(list(nakai@html@attrs:attr(GXL)), list(node_(GXL))) -> node_(GXL). -span(Attrs, Children) -> - {element, <<"span"/utf8>>, Attrs, Children}. - --spec span_text(list(nakai@html@attrs:attr(GXR)), binary()) -> node_(GXR). -span_text(Attrs, Text) -> - {element, <<"span"/utf8>>, Attrs, [{text, Text}]}. - --spec strong(list(nakai@html@attrs:attr(GXV)), list(node_(GXV))) -> node_(GXV). -strong(Attrs, Children) -> - {element, <<"strong"/utf8>>, Attrs, Children}. - --spec strong_text(list(nakai@html@attrs:attr(GYB)), binary()) -> node_(GYB). -strong_text(Attrs, Text) -> - {element, <<"strong"/utf8>>, Attrs, [{text, Text}]}. - --spec sub(list(nakai@html@attrs:attr(GYF)), list(node_(GYF))) -> node_(GYF). -sub(Attrs, Children) -> - {element, <<"sub"/utf8>>, Attrs, Children}. - --spec sub_text(list(nakai@html@attrs:attr(GYL)), binary()) -> node_(GYL). -sub_text(Attrs, Text) -> - {element, <<"sub"/utf8>>, Attrs, [{text, Text}]}. - --spec summary(list(nakai@html@attrs:attr(GYP)), list(node_(GYP))) -> node_(GYP). -summary(Attrs, Children) -> - {element, <<"summary"/utf8>>, Attrs, Children}. - --spec summary_text(list(nakai@html@attrs:attr(GYV)), binary()) -> node_(GYV). -summary_text(Attrs, Text) -> - {element, <<"summary"/utf8>>, Attrs, [{text, Text}]}. - --spec sup(list(nakai@html@attrs:attr(GYZ)), list(node_(GYZ))) -> node_(GYZ). -sup(Attrs, Children) -> - {element, <<"sup"/utf8>>, Attrs, Children}. - --spec sup_text(list(nakai@html@attrs:attr(GZF)), binary()) -> node_(GZF). -sup_text(Attrs, Text) -> - {element, <<"sup"/utf8>>, Attrs, [{text, Text}]}. - --spec svg(list(nakai@html@attrs:attr(GZJ)), list(node_(GZJ))) -> node_(GZJ). -svg(Attrs, Children) -> - {element, <<"svg"/utf8>>, Attrs, Children}. - --spec svg_text(list(nakai@html@attrs:attr(GZP)), binary()) -> node_(GZP). -svg_text(Attrs, Text) -> - {element, <<"svg"/utf8>>, Attrs, [{text, Text}]}. - --spec table(list(nakai@html@attrs:attr(GZT)), list(node_(GZT))) -> node_(GZT). -table(Attrs, Children) -> - {element, <<"table"/utf8>>, Attrs, Children}. - --spec table_text(list(nakai@html@attrs:attr(GZZ)), binary()) -> node_(GZZ). -table_text(Attrs, Text) -> - {element, <<"table"/utf8>>, Attrs, [{text, Text}]}. - --spec tbody(list(nakai@html@attrs:attr(HAD)), list(node_(HAD))) -> node_(HAD). -tbody(Attrs, Children) -> - {element, <<"tbody"/utf8>>, Attrs, Children}. - --spec tbody_text(list(nakai@html@attrs:attr(HAJ)), binary()) -> node_(HAJ). -tbody_text(Attrs, Text) -> - {element, <<"tbody"/utf8>>, Attrs, [{text, Text}]}. - --spec td(list(nakai@html@attrs:attr(HAN)), list(node_(HAN))) -> node_(HAN). -td(Attrs, Children) -> - {element, <<"td"/utf8>>, Attrs, Children}. - --spec td_text(list(nakai@html@attrs:attr(HAT)), binary()) -> node_(HAT). -td_text(Attrs, Text) -> - {element, <<"td"/utf8>>, Attrs, [{text, Text}]}. - --spec textarea(list(nakai@html@attrs:attr(HAX)), list(node_(HAX))) -> node_(HAX). -textarea(Attrs, Children) -> - {element, <<"textarea"/utf8>>, Attrs, Children}. - --spec textarea_text(list(nakai@html@attrs:attr(HBD)), binary()) -> node_(HBD). -textarea_text(Attrs, Text) -> - {element, <<"textarea"/utf8>>, Attrs, [{text, Text}]}. - --spec tfoot(list(nakai@html@attrs:attr(HBH)), list(node_(HBH))) -> node_(HBH). -tfoot(Attrs, Children) -> - {element, <<"tfoot"/utf8>>, Attrs, Children}. - --spec tfoot_text(list(nakai@html@attrs:attr(HBN)), binary()) -> node_(HBN). -tfoot_text(Attrs, Text) -> - {element, <<"tfoot"/utf8>>, Attrs, [{text, Text}]}. - --spec th(list(nakai@html@attrs:attr(HBR)), list(node_(HBR))) -> node_(HBR). -th(Attrs, Children) -> - {element, <<"th"/utf8>>, Attrs, Children}. - --spec th_text(list(nakai@html@attrs:attr(HBX)), binary()) -> node_(HBX). -th_text(Attrs, Text) -> - {element, <<"th"/utf8>>, Attrs, [{text, Text}]}. - --spec thead(list(nakai@html@attrs:attr(HCB)), list(node_(HCB))) -> node_(HCB). -thead(Attrs, Children) -> - {element, <<"thead"/utf8>>, Attrs, Children}. - --spec thead_text(list(nakai@html@attrs:attr(HCH)), binary()) -> node_(HCH). -thead_text(Attrs, Text) -> - {element, <<"thead"/utf8>>, Attrs, [{text, Text}]}. - --spec time(list(nakai@html@attrs:attr(HCL)), list(node_(HCL))) -> node_(HCL). -time(Attrs, Children) -> - {element, <<"time"/utf8>>, Attrs, Children}. - --spec time_text(list(nakai@html@attrs:attr(HCR)), binary()) -> node_(HCR). -time_text(Attrs, Text) -> - {element, <<"time"/utf8>>, Attrs, [{text, Text}]}. - --spec tr(list(nakai@html@attrs:attr(HCV)), list(node_(HCV))) -> node_(HCV). -tr(Attrs, Children) -> - {element, <<"tr"/utf8>>, Attrs, Children}. - --spec tr_text(list(nakai@html@attrs:attr(HDB)), binary()) -> node_(HDB). -tr_text(Attrs, Text) -> - {element, <<"tr"/utf8>>, Attrs, [{text, Text}]}. - --spec track(list(nakai@html@attrs:attr(HDF))) -> node_(HDF). -track(Attrs) -> - {leaf_element, <<"track"/utf8>>, Attrs}. - --spec u(list(nakai@html@attrs:attr(HDJ)), list(node_(HDJ))) -> node_(HDJ). -u(Attrs, Children) -> - {element, <<"u"/utf8>>, Attrs, Children}. - --spec u_text(list(nakai@html@attrs:attr(HDP)), binary()) -> node_(HDP). -u_text(Attrs, Text) -> - {element, <<"u"/utf8>>, Attrs, [{text, Text}]}. - --spec ul(list(nakai@html@attrs:attr(HDT)), list(node_(HDT))) -> node_(HDT). -ul(Attrs, Children) -> - {element, <<"ul"/utf8>>, Attrs, Children}. - --spec ul_text(list(nakai@html@attrs:attr(HDZ)), binary()) -> node_(HDZ). -ul_text(Attrs, Text) -> - {element, <<"ul"/utf8>>, Attrs, [{text, Text}]}. - --spec var(list(nakai@html@attrs:attr(HED)), list(node_(HED))) -> node_(HED). -var(Attrs, Children) -> - {element, <<"var"/utf8>>, Attrs, Children}. - --spec var_text(list(nakai@html@attrs:attr(HEJ)), binary()) -> node_(HEJ). -var_text(Attrs, Text) -> - {element, <<"var"/utf8>>, Attrs, [{text, Text}]}. - --spec video(list(nakai@html@attrs:attr(HEN)), list(node_(HEN))) -> node_(HEN). -video(Attrs, Children) -> - {element, <<"video"/utf8>>, Attrs, Children}. - --spec video_text(list(nakai@html@attrs:attr(HET)), binary()) -> node_(HET). -video_text(Attrs, Text) -> - {element, <<"video"/utf8>>, Attrs, [{text, Text}]}. - --spec wbr(list(nakai@html@attrs:attr(HEX)), list(node_(HEX))) -> node_(HEX). -wbr(Attrs, Children) -> - {element, <<"wbr"/utf8>>, Attrs, Children}. - --spec wbr_text(list(nakai@html@attrs:attr(HFD)), binary()) -> node_(HFD). -wbr_text(Attrs, Text) -> - {element, <<"wbr"/utf8>>, Attrs, [{text, Text}]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl deleted file mode 100644 index a75887648d0..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl +++ /dev/null @@ -1,191 +0,0 @@ --module(nakai@html@attrs). --compile([no_auto_import, nowarn_unused_vars]). - --export([data/2, accept/1, accept_charset/1, action/1, alt/1, async/0, autocapitalize/1, autocomplete/1, autofocus/0, autoplay/0, capture/1, charset/1, checked/0, cite/1, class/1, content/1, contenteditable/0, crossorigin/0, defer/0, disabled/0, draggable/0, for/1, formaction/1, height/1, href/1, http_equiv/1, id/1, integrity/1, lang/1, loop/0, method/1, name/1, placeholder/1, preload/0, property/1, readonly/0, rel/1, selected/0, src/1, style/1, tabindex/1, target/1, title/1, type_/1, value/1, width/1]). --export_type([attr/1]). - --type attr(FNI) :: {attr, binary(), binary()} | {event, binary(), FNI}. - --spec data(binary(), binary()) -> attr(any()). -data(Name, Value) -> - {attr, <<"data-"/utf8, Name/binary>>, Value}. - --spec accept(binary()) -> attr(any()). -accept(Value) -> - {attr, <<"accept"/utf8>>, Value}. - --spec accept_charset(binary()) -> attr(any()). -accept_charset(Value) -> - {attr, <<"accept-charset"/utf8>>, Value}. - --spec action(binary()) -> attr(any()). -action(Value) -> - {attr, <<"action"/utf8>>, Value}. - --spec alt(binary()) -> attr(any()). -alt(Value) -> - {attr, <<"alt"/utf8>>, Value}. - --spec async() -> attr(any()). -async() -> - {attr, <<"async"/utf8>>, <<"true"/utf8>>}. - --spec autocapitalize(binary()) -> attr(any()). -autocapitalize(Value) -> - {attr, <<"autocapitalize"/utf8>>, Value}. - --spec autocomplete(binary()) -> attr(any()). -autocomplete(Value) -> - {attr, <<"autocomplete"/utf8>>, Value}. - --spec autofocus() -> attr(any()). -autofocus() -> - {attr, <<"autofocus"/utf8>>, <<"true"/utf8>>}. - --spec autoplay() -> attr(any()). -autoplay() -> - {attr, <<"autoplay"/utf8>>, <<"true"/utf8>>}. - --spec capture(binary()) -> attr(any()). -capture(Value) -> - {attr, <<"capture"/utf8>>, Value}. - --spec charset(binary()) -> attr(any()). -charset(Value) -> - {attr, <<"charset"/utf8>>, Value}. - --spec checked() -> attr(any()). -checked() -> - {attr, <<"checked"/utf8>>, <<"true"/utf8>>}. - --spec cite(binary()) -> attr(any()). -cite(Value) -> - {attr, <<"cite"/utf8>>, Value}. - --spec class(binary()) -> attr(any()). -class(Value) -> - {attr, <<"class"/utf8>>, Value}. - --spec content(binary()) -> attr(any()). -content(Value) -> - {attr, <<"content"/utf8>>, Value}. - --spec contenteditable() -> attr(any()). -contenteditable() -> - {attr, <<"contenteditable"/utf8>>, <<"true"/utf8>>}. - --spec crossorigin() -> attr(any()). -crossorigin() -> - {attr, <<"crossorigin"/utf8>>, <<"true"/utf8>>}. - --spec defer() -> attr(any()). -defer() -> - {attr, <<"defer"/utf8>>, <<"true"/utf8>>}. - --spec disabled() -> attr(any()). -disabled() -> - {attr, <<"disabled"/utf8>>, <<"true"/utf8>>}. - --spec draggable() -> attr(any()). -draggable() -> - {attr, <<"draggable"/utf8>>, <<"true"/utf8>>}. - --spec for(binary()) -> attr(any()). -for(Value) -> - {attr, <<"for"/utf8>>, Value}. - --spec formaction(binary()) -> attr(any()). -formaction(Value) -> - {attr, <<"formaction"/utf8>>, Value}. - --spec height(binary()) -> attr(any()). -height(Value) -> - {attr, <<"height"/utf8>>, Value}. - --spec href(binary()) -> attr(any()). -href(Value) -> - {attr, <<"href"/utf8>>, Value}. - --spec http_equiv(binary()) -> attr(any()). -http_equiv(Value) -> - {attr, <<"http-equiv"/utf8>>, Value}. - --spec id(binary()) -> attr(any()). -id(Value) -> - {attr, <<"id"/utf8>>, Value}. - --spec integrity(binary()) -> attr(any()). -integrity(Value) -> - {attr, <<"integrity"/utf8>>, Value}. - --spec lang(binary()) -> attr(any()). -lang(Value) -> - {attr, <<"lang"/utf8>>, Value}. - --spec loop() -> attr(any()). -loop() -> - {attr, <<"loop"/utf8>>, <<"true"/utf8>>}. - --spec method(binary()) -> attr(any()). -method(Value) -> - {attr, <<"method"/utf8>>, Value}. - --spec name(binary()) -> attr(any()). -name(Value) -> - {attr, <<"name"/utf8>>, Value}. - --spec placeholder(binary()) -> attr(any()). -placeholder(Value) -> - {attr, <<"placeholder"/utf8>>, Value}. - --spec preload() -> attr(any()). -preload() -> - {attr, <<"preload"/utf8>>, <<"true"/utf8>>}. - --spec property(binary()) -> attr(any()). -property(Value) -> - {attr, <<"property"/utf8>>, Value}. - --spec readonly() -> attr(any()). -readonly() -> - {attr, <<"readonly"/utf8>>, <<"true"/utf8>>}. - --spec rel(binary()) -> attr(any()). -rel(Value) -> - {attr, <<"rel"/utf8>>, Value}. - --spec selected() -> attr(any()). -selected() -> - {attr, <<"selected"/utf8>>, <<"true"/utf8>>}. - --spec src(binary()) -> attr(any()). -src(Value) -> - {attr, <<"src"/utf8>>, Value}. - --spec style(binary()) -> attr(any()). -style(Value) -> - {attr, <<"style"/utf8>>, Value}. - --spec tabindex(binary()) -> attr(any()). -tabindex(Value) -> - {attr, <<"tabindex"/utf8>>, Value}. - --spec target(binary()) -> attr(any()). -target(Value) -> - {attr, <<"target"/utf8>>, Value}. - --spec title(binary()) -> attr(any()). -title(Value) -> - {attr, <<"title"/utf8>>, Value}. - --spec type_(binary()) -> attr(any()). -type_(Value) -> - {attr, <<"type"/utf8>>, Value}. - --spec value(binary()) -> attr(any()). -value(Value) -> - {attr, <<"value"/utf8>>, Value}. - --spec width(binary()) -> attr(any()). -width(Value) -> - {attr, <<"width"/utf8>>, Value}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl deleted file mode 100644 index 2b544c8d6f6..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl +++ /dev/null @@ -1,117 +0,0 @@ --module(nakai@internal@document). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/0, merge/2, concat/1, from_doctype/1, append_html_attrs/2, append_body_attrs/2, from_head/1, append_head/2, from_body/1, append_body/2, replace_body/2, from_script/1, into_head/1]). --export_type([document/0]). - --type document() :: {document, - gleam@option:option(binary()), - gleam@string_builder:string_builder(), - gleam@string_builder:string_builder(), - gleam@string_builder:string_builder(), - gleam@string_builder:string_builder(), - list(binary())}. - --spec new() -> document(). -new() -> - {document, - none, - gleam@string_builder:new(), - gleam@string_builder:new(), - gleam@string_builder:new(), - gleam@string_builder:new(), - []}. - --spec merge(document(), document()) -> document(). -merge(Self, New) -> - {document, - gleam@option:'or'(erlang:element(2, New), erlang:element(2, Self)), - gleam@string_builder:append_builder( - erlang:element(3, Self), - erlang:element(3, New) - ), - gleam@string_builder:append_builder( - erlang:element(4, Self), - erlang:element(4, New) - ), - gleam@string_builder:append_builder( - erlang:element(5, Self), - erlang:element(5, New) - ), - gleam@string_builder:append_builder( - erlang:element(6, Self), - erlang:element(6, New) - ), - gleam@list:append(erlang:element(7, Self), erlang:element(7, New))}. - --spec concat(list(document())) -> document(). -concat(Docs) -> - _pipe = Docs, - gleam@list:fold(_pipe, new(), fun merge/2). - --spec from_doctype(binary()) -> document(). -from_doctype(Doctype) -> - erlang:setelement(2, new(), {some, Doctype}). - --spec append_html_attrs(document(), gleam@string_builder:string_builder()) -> document(). -append_html_attrs(Self, Html_attrs) -> - erlang:setelement( - 3, - Self, - gleam@string_builder:append_builder(erlang:element(3, Self), Html_attrs) - ). - --spec append_body_attrs(document(), gleam@string_builder:string_builder()) -> document(). -append_body_attrs(Self, Body_attrs) -> - erlang:setelement( - 4, - Self, - gleam@string_builder:append_builder(erlang:element(4, Self), Body_attrs) - ). - --spec from_head(gleam@string_builder:string_builder()) -> document(). -from_head(Head) -> - erlang:setelement(5, new(), Head). - --spec append_head(document(), gleam@string_builder:string_builder()) -> document(). -append_head(Self, Head) -> - erlang:setelement( - 5, - Self, - gleam@string_builder:append_builder(erlang:element(5, Self), Head) - ). - --spec from_body(gleam@string_builder:string_builder()) -> document(). -from_body(Body) -> - erlang:setelement(6, new(), Body). - --spec append_body(document(), gleam@string_builder:string_builder()) -> document(). -append_body(Self, Body) -> - erlang:setelement( - 6, - Self, - gleam@string_builder:append_builder(erlang:element(6, Self), Body) - ). - --spec replace_body(document(), gleam@string_builder:string_builder()) -> document(). -replace_body(Self, Body) -> - erlang:setelement(6, Self, Body). - --spec from_script(binary()) -> document(). -from_script(Script) -> - erlang:setelement(7, new(), [Script]). - --spec into_head(document()) -> document(). -into_head(State) -> - erlang:setelement( - 6, - erlang:setelement( - 5, - State, - gleam@string_builder:append_builder( - erlang:element(5, State), - erlang:element(6, State) - ) - ), - gleam@string_builder:new() - ). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl deleted file mode 100644 index ad00173bdd4..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl +++ /dev/null @@ -1,297 +0,0 @@ --module(nakai@internal@render). --compile([no_auto_import, nowarn_unused_vars]). - --export([render_document/1, render_inline/1]). --export_type([builder/2]). - --type builder(HVS, HVT) :: {builder, - fun((nakai@html:node_(HVS)) -> HVT), - fun((list(HVT)) -> HVT)}. - --spec render_doctype(binary()) -> gleam@string_builder:string_builder(). -render_doctype(Doctype) -> - gleam@string_builder:from_strings( - [<<"<!DOCTYPE "/utf8>>, Doctype, <<">\n"/utf8>>] - ). - --spec render_children(list(nakai@html:node_(HVU)), builder(HVU, HVX)) -> HVX. -render_children(Children, Builder) -> - _pipe = Children, - _pipe@1 = gleam@list:map(_pipe, erlang:element(2, Builder)), - (erlang:element(3, Builder))(_pipe@1). - --spec render_attr(nakai@html@attrs:attr(any())) -> gleam@string_builder:string_builder(). -render_attr(Attr) -> - case Attr of - {attr, Name, Value} -> - Sanitized_value = begin - _pipe = Value, - _pipe@1 = gleam@string:replace( - _pipe, - <<"\""/utf8>>, - <<"""/utf8>> - ), - gleam@string:replace(_pipe@1, <<">"/utf8>>, <<">"/utf8>>) - end, - gleam@string_builder:from_strings( - [<<" "/utf8>>, - Name, - <<"=\""/utf8>>, - Sanitized_value, - <<"\""/utf8>>] - ); - - {event, _, _} -> - gleam@string_builder:new() - end. - --spec render_attrs(list(nakai@html@attrs:attr(any()))) -> gleam@string_builder:string_builder(). -render_attrs(Attrs) -> - _pipe = Attrs, - _pipe@1 = gleam@list:map(_pipe, fun render_attr/1), - gleam@list:fold( - _pipe@1, - gleam@string_builder:new(), - fun gleam@string_builder:append_builder/2 - ). - --spec render_document_node(nakai@html:node_(any())) -> nakai@internal@document:document(). -render_document_node(Tree) -> - case Tree of - {doctype, Doctype} -> - nakai@internal@document:from_doctype(Doctype); - - {html, Attrs, Children} -> - _pipe = render_children( - Children, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - nakai@internal@document:append_html_attrs( - _pipe, - render_attrs(Attrs) - ); - - {head, Children@1} -> - _pipe@1 = render_children( - Children@1, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - nakai@internal@document:into_head(_pipe@1); - - {body, Attrs@1, Children@2} -> - _pipe@2 = render_children( - Children@2, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - nakai@internal@document:append_body_attrs( - _pipe@2, - render_attrs(Attrs@1) - ); - - {fragment, Children@3} -> - render_children( - Children@3, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ); - - {element, Tag, Attrs@2, Children@4} -> - Child_document = render_children( - Children@4, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - _pipe@3 = gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag]), - render_attrs(Attrs@2), - gleam@string_builder:from_string(<<">"/utf8>>), - erlang:element(6, Child_document), - gleam@string_builder:from_strings( - [<<"</"/utf8>>, Tag, <<">"/utf8>>] - )] - ), - nakai@internal@document:replace_body(Child_document, _pipe@3); - - {leaf_element, Tag@1, Attrs@3} -> - _pipe@4 = gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag@1]), - render_attrs(Attrs@3), - gleam@string_builder:from_string(<<" />"/utf8>>)] - ), - nakai@internal@document:from_body(_pipe@4); - - {comment, Content} -> - Content@1 = begin - _pipe@5 = Content, - gleam@string:replace(_pipe@5, <<"-->"/utf8>>, <<""/utf8>>) - end, - _pipe@6 = gleam@string_builder:from_strings( - [<<"<!-- "/utf8>>, Content@1, <<" -->"/utf8>>] - ), - nakai@internal@document:from_body(_pipe@6); - - {text, Content@2} -> - _pipe@7 = gleam@string_builder:from_string(Content@2), - _pipe@8 = gleam@string_builder:replace( - _pipe@7, - <<"&"/utf8>>, - <<"&"/utf8>> - ), - _pipe@9 = gleam@string_builder:replace( - _pipe@8, - <<"<"/utf8>>, - <<"<"/utf8>> - ), - _pipe@10 = gleam@string_builder:replace( - _pipe@9, - <<">"/utf8>>, - <<">"/utf8>> - ), - nakai@internal@document:from_body(_pipe@10); - - {unsafe_text, Content@3} -> - _pipe@11 = gleam@string_builder:from_string(Content@3), - nakai@internal@document:from_body(_pipe@11); - - {script, Script} -> - nakai@internal@document:from_script(Script); - - nothing -> - nakai@internal@document:new() - end. - --spec render_script(binary()) -> gleam@string_builder:string_builder(). -render_script(Script) -> - gleam@string_builder:concat( - [gleam@string_builder:from_string(<<"<script>"/utf8>>), - gleam@string_builder:from_string(Script), - gleam@string_builder:from_string(<<"</script>\n"/utf8>>)] - ). - --spec render_scripts(list(binary())) -> gleam@string_builder:string_builder(). -render_scripts(Scripts) -> - _pipe = Scripts, - _pipe@1 = gleam@list:map(_pipe, fun render_script/1), - gleam@string_builder:concat(_pipe@1). - --spec render_document(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -render_document(Tree) -> - Result = render_document_node(Tree), - gleam@string_builder:concat( - [render_doctype( - begin - _pipe = erlang:element(2, Result), - gleam@option:unwrap(_pipe, <<"html"/utf8>>) - end - ), - gleam@string_builder:from_string(<<"<html"/utf8>>), - erlang:element(3, Result), - gleam@string_builder:from_string( - <<">\n<head>"/utf8, - (<<" -<meta charset=\"utf-8\" /> -<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /> -"/utf8>>)/binary>> - ), - erlang:element(5, Result), - gleam@string_builder:from_string(<<"</head>\n<body"/utf8>>), - erlang:element(4, Result), - gleam@string_builder:from_string(<<">"/utf8>>), - erlang:element(6, Result), - render_scripts(erlang:element(7, Result)), - gleam@string_builder:from_string(<<"</body>\n</html>\n"/utf8>>)] - ). - --spec render_inline_node(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -render_inline_node(Tree) -> - case Tree of - {doctype, Doctype} -> - render_doctype(Doctype); - - {html, Attrs, Children} -> - render_inline_node({element, <<"html"/utf8>>, Attrs, Children}); - - {head, Children@1} -> - render_inline_node({element, <<"head"/utf8>>, [], Children@1}); - - {body, Attrs@1, Children@2} -> - render_inline_node({element, <<"body"/utf8>>, Attrs@1, Children@2}); - - {fragment, Children@3} -> - render_children( - Children@3, - {builder, - fun render_inline_node/1, - fun gleam@string_builder:concat/1} - ); - - {element, Tag, Attrs@2, Children@4} -> - Child_document = render_children( - Children@4, - {builder, - fun render_inline_node/1, - fun gleam@string_builder:concat/1} - ), - gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag]), - render_attrs(Attrs@2), - gleam@string_builder:from_string(<<">"/utf8>>), - Child_document, - gleam@string_builder:from_strings( - [<<"</"/utf8>>, Tag, <<">"/utf8>>] - )] - ); - - {leaf_element, Tag@1, Attrs@3} -> - gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag@1]), - render_attrs(Attrs@3), - gleam@string_builder:from_string(<<" />"/utf8>>)] - ); - - {comment, Content} -> - Content@1 = begin - _pipe = Content, - gleam@string:replace(_pipe, <<"-->"/utf8>>, <<""/utf8>>) - end, - gleam@string_builder:from_strings( - [<<"<!-- "/utf8>>, Content@1, <<" -->"/utf8>>] - ); - - {text, Content@2} -> - _pipe@1 = gleam@string_builder:from_string(Content@2), - _pipe@2 = gleam@string_builder:replace( - _pipe@1, - <<"&"/utf8>>, - <<"&"/utf8>> - ), - _pipe@3 = gleam@string_builder:replace( - _pipe@2, - <<"<"/utf8>>, - <<"<"/utf8>> - ), - gleam@string_builder:replace(_pipe@3, <<">"/utf8>>, <<">"/utf8>>); - - {unsafe_text, Content@3} -> - gleam@string_builder:from_string(Content@3); - - {script, Script} -> - render_inline_node( - {element, <<"script"/utf8>>, [], [{text, Script}]} - ); - - nothing -> - gleam@string_builder:new() - end. - --spec render_inline(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -render_inline(Tree) -> - render_inline_node(Tree). diff --git a/test-community-packages-javascript/build/packages/nibble/LICENSE b/test-community-packages-javascript/build/packages/nibble/LICENSE deleted file mode 100644 index b8320fd29e4..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright 2022 Hayleigh Thompson - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in the -Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/nibble/README.md b/test-community-packages-javascript/build/packages/nibble/README.md deleted file mode 100644 index b6cba15088f..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# nibble - -[![Package Version](https://img.shields.io/hexpm/v/nibble)](https://hex.pm/packages/nibble) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/nibble/) - -A string parsing library heavily inspired by [`elm/parser`](https://github.com/elm/parser). - -## Quick start - -```gleam -import gleam/function -import nibble.{ Parser } - -type Point { - Point(x: Int, y: Int) -} - -pub fn main () { - let parser = - nibble.succeed(function.curry2(Point)) - |> nibble.drop(nibble.grapheme("(")) - |> nibble.drop(nibble.spaces()) - |> nibble.keep(nibble.int()) - |> nibble.drop(nibble.spaces()) - |> nibble.drop(nibble.grapheme(",")) - |> nibble.drop(nibble.spaces()) - |> nibble.keep(nibble.int()) - |> nibble.drop(nibble.spaces()) - |> nibble.drop(nibble.grapheme(")")) - - assert Ok(point) = nibble.run("(1, 2)", parser) - - point.x //=> 1 - point.y //=> 2 -} -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add nibble -``` - -and its documentation can be found at <https://hexdocs.pm/nibble>. diff --git a/test-community-packages-javascript/build/packages/nibble/gleam.toml b/test-community-packages-javascript/build/packages/nibble/gleam.toml deleted file mode 100644 index 2f6286a1f38..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/gleam.toml +++ /dev/null @@ -1,15 +0,0 @@ -name = "nibble" -version = "0.2.3" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -licences = ["MIT"] -description = "A string parsing library heavily inspired by elm/parser." -repository = { type = "github", user = "hayleigh-dot-dev", repo = "gleam-nibble" } - -[dependencies] -gleam_stdlib = "~> 0.28" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl deleted file mode 100644 index 4980405448d..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(config, { - one_of :: list(fun((nibble@pratt:config(any(), any())) -> nibble:parser(any(), any()))), - and_then_one_of :: list(nibble@pratt:operator(any(), any())), - spaces :: nibble:parser(nil, any()) -}). diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl deleted file mode 100644 index 3e3e338638d..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(dead_end, { - row :: integer(), - col :: integer(), - problem :: nibble:error(), - context :: list(nibble:located(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl deleted file mode 100644 index b987412c2cb..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl +++ /dev/null @@ -1 +0,0 @@ --record(located, {row :: integer(), col :: integer(), context :: any()}). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src b/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src deleted file mode 100644 index f499dc88532..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, nibble, [ - {vsn, "0.2.3"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A string parsing library heavily inspired by elm/parser."}, - {modules, [nibble, - nibble@pratt, - nibble@predicates]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble.erl deleted file mode 100644 index da1bce811f8..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble.erl +++ /dev/null @@ -1,517 +0,0 @@ --module(nibble). --compile([no_auto_import, nowarn_unused_vars]). - --export([succeed/1, lazy/1, backtrackable/1, commit/1, then/2, map/2, replace/2, keep/2, drop/2, fail/1, eof/0, take_if/2, any/0, grapheme/1, one_of/1, in/2, inspect/2, string/1, run/2, int/0, float/0, take_while/1, spaces/0, whitespace/0, take_if_and_while/2, take_until/1, loop/2, many/2]). --export_type([parser/2, state/1, step/2, located/1, backtrackable/0, loop/2, error/0, dead_end/1, bag/1]). - --opaque parser(EVD, EVE) :: {parser, fun((state(EVE)) -> step(EVD, EVE))}. - --type state(EVF) :: {state, - gleam@map:map_(integer(), binary()), - integer(), - list(located(EVF)), - integer(), - integer()}. - --type step(EVG, EVH) :: {cont, backtrackable(), EVG, state(EVH)} | - {fail, backtrackable(), bag(EVH)}. - --type located(EVI) :: {located, integer(), integer(), EVI}. - --type backtrackable() :: commit | backtrack. - --type loop(EVJ, EVK) :: {continue, EVK} | {break, EVJ}. - --type error() :: {bad_parser, binary()} | - {custom, binary()} | - end_of_input | - {expected, binary(), binary()} | - {unexpected, binary()}. - --type dead_end(EVL) :: {dead_end, - integer(), - integer(), - error(), - list(located(EVL))}. - --type bag(EVM) :: empty | - {cons, bag(EVM), dead_end(EVM)} | - {append, bag(EVM), bag(EVM)}. - --spec runwrap(state(EVV), parser(EVX, EVV)) -> step(EVX, EVV). -runwrap(State, Parser) -> - {parser, Parse} = Parser, - Parse(State). - --spec succeed(EWG) -> parser(EWG, any()). -succeed(A) -> - {parser, fun(State) -> {cont, backtrack, A, State} end}. - --spec lazy(fun(() -> parser(EWO, EWP))) -> parser(EWO, EWP). -lazy(Parser) -> - {parser, fun(State) -> runwrap(State, Parser()) end}. - --spec backtrackable(parser(EWU, EWV)) -> parser(EWU, EWV). -backtrackable(Parser) -> - {parser, fun(State) -> case runwrap(State, Parser) of - {cont, _, A, State@1} -> - {cont, backtrack, A, State@1}; - - {fail, _, Bag} -> - {fail, backtrack, Bag} - end end}. - --spec commit(EXA) -> parser(EXA, any()). -commit(A) -> - {parser, fun(State) -> {cont, commit, A, State} end}. - --spec should_commit(backtrackable(), backtrackable()) -> backtrackable(). -should_commit(To_x, To_y) -> - case {To_x, To_y} of - {commit, _} -> - commit; - - {_, commit} -> - commit; - - {_, _} -> - backtrack - end. - --spec then(parser(EXE, EXF), fun((EXE) -> parser(EXI, EXF))) -> parser(EXI, EXF). -then(Parser, F) -> - {parser, fun(State) -> case runwrap(State, Parser) of - {cont, To_a, A, State@1} -> - case runwrap(State@1, F(A)) of - {cont, To_b, B, State@2} -> - {cont, should_commit(To_a, To_b), B, State@2}; - - {fail, To_b@1, Bag} -> - {fail, should_commit(To_a, To_b@1), Bag} - end; - - {fail, Can_backtrack, Bag@1} -> - {fail, Can_backtrack, Bag@1} - end end}. - --spec map(parser(EXN, EXO), fun((EXN) -> EXR)) -> parser(EXR, EXO). -map(Parser, F) -> - then(Parser, fun(A) -> succeed(F(A)) end). - --spec next(state(EWC)) -> {gleam@option:option(binary()), state(EWC)}. -next(State) -> - case gleam@map:get(erlang:element(2, State), erlang:element(3, State)) of - {ok, <<"\n"/utf8>>} -> - {{some, <<"\n"/utf8>>}, - erlang:setelement( - 5, - erlang:setelement( - 6, - erlang:setelement( - 3, - State, - erlang:element(3, State) + 1 - ), - 1 - ), - erlang:element(5, State) + 1 - )}; - - {ok, G} -> - {{some, G}, - erlang:setelement( - 6, - erlang:setelement(3, State, erlang:element(3, State) + 1), - erlang:element(6, State) + 1 - )}; - - {error, _} -> - {none, State} - end. - --spec map2(parser(EXU, EXV), parser(EXY, EXV), fun((EXU, EXY) -> EYB)) -> parser(EYB, EXV). -map2(Parse_a, Parse_b, F) -> - then(Parse_a, fun(A) -> map(Parse_b, fun(B) -> F(A, B) end) end). - --spec replace(parser(any(), EYF), EYI) -> parser(EYI, EYF). -replace(Parser, B) -> - map(Parser, fun(_) -> B end). - --spec keep(parser(fun((EYL) -> EYM), EYN), parser(EYL, EYN)) -> parser(EYM, EYN). -keep(Parse_f, Parse_a) -> - map2(Parse_f, Parse_a, fun(F, A) -> F(A) end). - --spec drop(parser(EYU, EYV), parser(any(), EYV)) -> parser(EYU, EYV). -drop(Parse_a, Parse_x) -> - map2(Parse_a, Parse_x, fun(A, _) -> A end). - --spec bag_from_state(state(FCC), error()) -> bag(FCC). -bag_from_state(State, Problem) -> - {cons, - empty, - {dead_end, - erlang:element(5, State), - erlang:element(6, State), - Problem, - erlang:element(4, State)}}. - --spec fail(binary()) -> parser(any(), any()). -fail(Message) -> - {parser, - fun(State) -> - {fail, backtrack, bag_from_state(State, {custom, Message})} - end}. - --spec eof() -> parser(nil, any()). -eof() -> - {parser, fun(State) -> case next(State) of - {{some, Str}, _} -> - {fail, backtrack, bag_from_state(State, {unexpected, Str})}; - - {none, _} -> - {cont, backtrack, nil, State} - end end}. - --spec take_if(fun((binary()) -> boolean()), binary()) -> parser(binary(), any()). -take_if(Predicate, Expecting) -> - {parser, - fun(State) -> - {Str, Next_state} = next(State), - Should_take = begin - _pipe = Str, - _pipe@1 = gleam@option:map(_pipe, Predicate), - gleam@option:unwrap(_pipe@1, false) - end, - Str@1 = gleam@option:unwrap(Str, <<""/utf8>>), - case Should_take of - true -> - {cont, commit, Str@1, Next_state}; - - false -> - {fail, - backtrack, - bag_from_state(State, {expected, Expecting, Str@1})} - end - end}. - --spec any() -> parser(binary(), any()). -any() -> - take_if(gleam@function:constant(true), <<"a single grapheme"/utf8>>). - --spec grapheme(binary()) -> parser(nil, any()). -grapheme(Str) -> - _pipe = take_if(fun(G) -> G =:= Str end, Str), - map(_pipe, gleam@function:constant(nil)). - --spec add_bag_to_step(step(FCL, FCM), bag(FCM)) -> step(FCL, FCM). -add_bag_to_step(Step, Left) -> - case Step of - {cont, Can_backtrack, A, State} -> - {cont, Can_backtrack, A, State}; - - {fail, Can_backtrack@1, Right} -> - {fail, Can_backtrack@1, {append, Left, Right}} - end. - --spec one_of(list(parser(FAB, FAC))) -> parser(FAB, FAC). -one_of(Parsers) -> - {parser, - fun(State) -> - Init = {fail, backtrack, empty}, - gleam@list:fold_until( - Parsers, - Init, - fun(Result, Next) -> case Result of - {cont, _, _, _} -> - {stop, Result}; - - {fail, commit, _} -> - {stop, Result}; - - {fail, _, Bag} -> - _pipe = runwrap(State, Next), - _pipe@1 = add_bag_to_step(_pipe, Bag), - {continue, _pipe@1} - end end - ) - end}. - --spec push_context(state(FCY), FCY) -> state(FCY). -push_context(State, Context) -> - Located = {located, - erlang:element(5, State), - erlang:element(6, State), - Context}, - erlang:setelement(4, State, [Located | erlang:element(4, State)]). - --spec pop_context(state(FDB)) -> state(FDB). -pop_context(State) -> - case erlang:element(4, State) of - [] -> - State; - - [_ | Context] -> - erlang:setelement(4, State, Context) - end. - --spec in(parser(FCS, FCT), FCT) -> parser(FCS, FCT). -in(Parser, Context) -> - {parser, fun(State) -> case runwrap(push_context(State, Context), Parser) of - {cont, Can_backtrack, A, State@1} -> - {cont, Can_backtrack, A, pop_context(State@1)}; - - {fail, Can_backtrack@1, Bag} -> - {fail, Can_backtrack@1, Bag} - end end}. - --spec inspect(parser(FDE, FDF), binary()) -> parser(FDE, FDF). -inspect(Parser, Message) -> - {parser, - fun(State) -> - gleam@io:print(Message), - gleam@io:println(<<": "/utf8>>), - _pipe = runwrap(State, Parser), - gleam@io:debug(_pipe) - end}. - --spec string(binary()) -> parser(nil, any()). -string(Str) -> - Graphemes = gleam@string:to_graphemes(Str), - {parser, fun(State) -> case Graphemes of - [] -> - {fail, - backtrack, - bag_from_state( - State, - {bad_parser, <<"empty string"/utf8>>} - )}; - - [Head | Tail] -> - Parse_each = gleam@list:fold( - Tail, - grapheme(Head), - fun(Parse, Next) -> _pipe = Parse, - drop(_pipe, grapheme(Next)) end - ), - case runwrap(State, Parse_each) of - {cont, _, _, State@1} -> - {cont, commit, nil, State@1}; - - {fail, _, Bag} -> - {fail, backtrack, Bag} - end - end end}. - --spec to_deadends(bag(FCF), list(dead_end(FCF))) -> list(dead_end(FCF)). -to_deadends(Bag, Acc) -> - case Bag of - empty -> - Acc; - - {cons, empty, Deadend} -> - [Deadend | Acc]; - - {cons, Bag@1, Deadend@1} -> - to_deadends(Bag@1, [Deadend@1 | Acc]); - - {append, Left, Right} -> - to_deadends(Left, to_deadends(Right, Acc)) - end. - --spec run(binary(), parser(EVN, EVO)) -> {ok, EVN} | - {error, list(dead_end(EVO))}. -run(Src, Parser) -> - Graphemes = begin - _pipe = gleam@string:to_graphemes(Src), - _pipe@1 = gleam@list:index_map( - _pipe, - fun(I, Grapheme) -> {I, Grapheme} end - ), - gleam@map:from_list(_pipe@1) - end, - Init = {state, Graphemes, 0, [], 1, 1}, - case runwrap(Init, Parser) of - {cont, _, A, _} -> - {ok, A}; - - {fail, _, Bag} -> - {error, to_deadends(Bag, [])} - end. - --spec int() -> parser(integer(), any()). -int() -> - _pipe = take_if_and_while( - fun nibble@predicates:is_digit/1, - <<"a digit"/utf8>> - ), - map( - _pipe, - fun(Digits) -> - _assert_subject = gleam@int:parse(Digits), - {ok, Int} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"nibble"/utf8>>, - function => <<"int"/utf8>>, - line => 254}) - end, - Int - end - ). - --spec float() -> parser(float(), any()). -float() -> - Make_float_string = gleam@function:curry2( - fun(X, Y) -> gleam@string:concat([X, <<"."/utf8>>, Y]) end - ), - _pipe = succeed(Make_float_string), - _pipe@1 = keep( - _pipe, - take_if_and_while(fun nibble@predicates:is_digit/1, <<"a digit"/utf8>>) - ), - _pipe@2 = drop(_pipe@1, grapheme(<<"."/utf8>>)), - _pipe@3 = keep( - _pipe@2, - take_if_and_while(fun nibble@predicates:is_digit/1, <<"a digit"/utf8>>) - ), - map( - _pipe@3, - fun(Digits) -> - _assert_subject = gleam@float:parse(Digits), - {ok, Float} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"nibble"/utf8>>, - function => <<"float"/utf8>>, - line => 271}) - end, - Float - end - ). - --spec take_while(fun((binary()) -> boolean())) -> parser(binary(), any()). -take_while(Predicate) -> - {parser, - fun(State) -> - {Str, Next_state} = next(State), - Should_take = begin - _pipe = Str, - _pipe@1 = gleam@option:map(_pipe, Predicate), - gleam@option:unwrap(_pipe@1, false) - end, - Str@1 = gleam@option:unwrap(Str, <<""/utf8>>), - case Should_take of - true -> - runwrap( - Next_state, - map( - take_while(Predicate), - fun(_capture) -> - gleam@string:append(Str@1, _capture) - end - ) - ); - - false -> - {cont, backtrack, <<""/utf8>>, State} - end - end}. - --spec spaces() -> parser(nil, any()). -spaces() -> - _pipe = take_while(fun(G) -> G =:= <<" "/utf8>> end), - map(_pipe, gleam@function:constant(nil)). - --spec whitespace() -> parser(nil, any()). -whitespace() -> - _pipe = take_while(fun nibble@predicates:is_whitespace/1), - map(_pipe, gleam@function:constant(nil)). - --spec take_if_and_while(fun((binary()) -> boolean()), binary()) -> parser(binary(), any()). -take_if_and_while(Predicate, Expecting) -> - map2( - take_if(Predicate, Expecting), - take_while(Predicate), - fun gleam@string:append/2 - ). - --spec take_until(fun((binary()) -> boolean())) -> parser(binary(), any()). -take_until(Predicate) -> - take_while(gleam@function:compose(Predicate, fun gleam@bool:negate/1)). - --spec loop_help( - fun((FBC) -> parser(loop(FBD, FBC), FBG)), - backtrackable(), - FBC, - state(FBG) -) -> step(FBD, FBG). -loop_help(F, Commit, Loop_state, State) -> - case runwrap(State, F(Loop_state)) of - {cont, Can_backtrack, {continue, Next_loop_state}, Next_state} -> - loop_help( - F, - should_commit(Commit, Can_backtrack), - Next_loop_state, - Next_state - ); - - {cont, Can_backtrack@1, {break, Result}, Next_state@1} -> - {cont, should_commit(Commit, Can_backtrack@1), Result, Next_state@1}; - - {fail, Can_backtrack@2, Bag} -> - {fail, should_commit(Commit, Can_backtrack@2), Bag} - end. - --spec loop(FBC, fun((FBC) -> parser(loop(FBD, FBC), FBG))) -> parser(FBD, FBG). -loop(Init, Step) -> - {parser, fun(State) -> loop_help(Step, backtrack, Init, State) end}. - --spec more(FAS, parser(FAS, FAT), parser(any(), FAT)) -> parser(list(FAS), FAT). -more(X, Parser, Separator) -> - loop( - [X], - fun(Xs) -> - one_of( - [begin - _pipe = succeed( - fun(_capture) -> - gleam@list:prepend(Xs, _capture) - end - ), - _pipe@1 = drop(_pipe, Separator), - _pipe@2 = keep(_pipe@1, Parser), - map(_pipe@2, fun(Field@0) -> {continue, Field@0} end) - end, - begin - _pipe@3 = succeed(Xs), - _pipe@4 = drop(_pipe@3, eof()), - _pipe@5 = map(_pipe@4, fun gleam@list:reverse/1), - map(_pipe@5, fun(Field@0) -> {break, Field@0} end) - end, - begin - _pipe@6 = succeed(Xs), - _pipe@7 = map(_pipe@6, fun gleam@list:reverse/1), - map(_pipe@7, fun(Field@0) -> {break, Field@0} end) - end] - ) - end - ). - --spec many(parser(FAI, FAJ), parser(any(), FAJ)) -> parser(list(FAI), FAJ). -many(Parser, Separator) -> - one_of( - [begin - _pipe = Parser, - then( - _pipe, - fun(_capture) -> more(_capture, Parser, Separator) end - ) - end, - succeed([])] - ). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam deleted file mode 100644 index 3292d85d810..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam +++ /dev/null @@ -1,519 +0,0 @@ -//// - -// IMPORTS --------------------------------------------------------------------- - -import gleam/bool -import gleam/float -import gleam/function -import gleam/int -import gleam/io -import gleam/list -import gleam/map.{Map} -import gleam/option.{Option} -import gleam/string -import nibble/predicates - -// TYPES ----------------------------------------------------------------------- - -/// -pub opaque type Parser(a, ctx) { - Parser(fn(State(ctx)) -> Step(a, ctx)) -} - -type State(ctx) { - State( - // The Gleam stdlib doesn't seem to have an `Array` type, so we'll just - // use a `Map` instead. We only need something for indexed access, to it's - // not a huge deal. - // - // TODO: Louis says making an `Array` backed by tuples in Erlang will - // be way better for performance. In JavaScript we could just use normal - // arrays - someone should look into this. - src: Map(Int, String), - offset: Int, - context: List(Located(ctx)), - row: Int, - col: Int, - ) -} - -type Step(a, ctx) { - Cont(Backtrackable, a, State(ctx)) - Fail(Backtrackable, Bag(ctx)) -} - -/// -pub type Located(ctx) { - Located(row: Int, col: Int, context: ctx) -} - -type Backtrackable { - Commit - Backtrack -} - -// RUNNING PARSERS ------------------------------------------------------------- - -/// -pub fn run(src: String, parser: Parser(a, ctx)) -> Result(a, List(DeadEnd(ctx))) { - let graphemes = - string.to_graphemes(src) - |> list.index_map(fn(i, grapheme) { #(i, grapheme) }) - |> map.from_list - - let init = State(graphemes, 0, [], 1, 1) - - case runwrap(init, parser) { - Cont(_, a, _) -> Ok(a) - - Fail(_, bag) -> Error(to_deadends(bag, [])) - } -} - -fn runwrap(state: State(ctx), parser: Parser(a, ctx)) -> Step(a, ctx) { - let Parser(parse) = parser - parse(state) -} - -fn next(state: State(ctx)) -> #(Option(String), State(ctx)) { - case map.get(state.src, state.offset) { - Ok("\n") -> #( - option.Some("\n"), - State(..state, offset: state.offset + 1, col: 1, row: state.row + 1), - ) - - Ok(g) -> #( - option.Some(g), - State(..state, offset: state.offset + 1, col: state.col + 1), - ) - - Error(_) -> #(option.None, state) - } -} - -// CONSTRUCTORS ---------------------------------------------------------------- - -/// -pub fn succeed(a: a) -> Parser(a, ctx) { - Parser(fn(state) { Cont(Backtrack, a, state) }) -} - -/// -pub fn fail(message: String) -> Parser(a, ctx) { - Parser(fn(state) { Fail(Backtrack, bag_from_state(state, Custom(message))) }) -} - -/// -pub fn lazy(parser: fn() -> Parser(a, ctx)) -> Parser(a, ctx) { - Parser(fn(state) { runwrap(state, parser()) }) -} - -// BACKTRACKING ---------------------------------------------------------------- - -/// -pub fn backtrackable(parser: Parser(a, ctx)) -> Parser(a, ctx) { - Parser(fn(state) { - case runwrap(state, parser) { - Cont(_, a, state) -> Cont(Backtrack, a, state) - - Fail(_, bag) -> Fail(Backtrack, bag) - } - }) -} - -/// -pub fn commit(to a: a) -> Parser(a, ctx) { - Parser(fn(state) { Cont(Commit, a, state) }) -} - -fn should_commit(to_x: Backtrackable, or to_y: Backtrackable) -> Backtrackable { - case to_x, to_y { - Commit, _ -> Commit - - _, Commit -> Commit - - _, _ -> Backtrack - } -} - -// MANIPULATING PARSERS -------------------------------------------------------- - -/// -pub fn then( - parser: Parser(a, ctx), - f: fn(a) -> Parser(b, ctx), -) -> Parser(b, ctx) { - Parser(fn(state) { - case runwrap(state, parser) { - Cont(to_a, a, state) -> - case runwrap(state, f(a)) { - Cont(to_b, b, state) -> Cont(should_commit(to_a, or: to_b), b, state) - Fail(to_b, bag) -> Fail(should_commit(to_a, or: to_b), bag) - } - - Fail(can_backtrack, bag) -> Fail(can_backtrack, bag) - } - }) -} - -/// -pub fn map(parser: Parser(a, ctx), f: fn(a) -> b) -> Parser(b, ctx) { - then(parser, fn(a) { succeed(f(a)) }) -} - -fn map2( - parse_a: Parser(a, ctx), - parse_b: Parser(b, ctx), - f: fn(a, b) -> c, -) -> Parser(c, ctx) { - then(parse_a, fn(a) { map(parse_b, fn(b) { f(a, b) }) }) -} - -/// -pub fn replace(parser: Parser(a, ctx), with b: b) -> Parser(b, ctx) { - map(parser, fn(_) { b }) -} - -// PIPE-FRIENDLY HELPERS ------------------------------------------------------- - -/// -pub fn keep( - parse_f: Parser(fn(a) -> b, ctx), - parse_a: Parser(a, ctx), -) -> Parser(b, ctx) { - map2(parse_f, parse_a, fn(f, a) { f(a) }) -} - -/// -pub fn drop(parse_a: Parser(a, ctx), parse_x: Parser(x, ctx)) -> Parser(a, ctx) { - map2(parse_a, parse_x, fn(a, _) { a }) -} - -// SIMPLE PARSERS -------------------------------------------------------------- - -/// -pub fn any() -> Parser(String, ctx) { - take_if(function.constant(True), "a single grapheme") -} - -/// -pub fn eof() -> Parser(Nil, ctx) { - Parser(fn(state) { - case next(state) { - #(option.Some(str), _) -> - Fail(Backtrack, bag_from_state(state, Unexpected(str))) - - #(option.None, _) -> Cont(Backtrack, Nil, state) - } - }) -} - -// GRAPHEMES AND STRINGS ------------------------------------------------------- - -/// -pub fn grapheme(str: String) -> Parser(Nil, ctx) { - take_if(fn(g) { g == str }, str) - |> map(function.constant(Nil)) -} - -/// -pub fn string(str: String) -> Parser(Nil, ctx) { - let graphemes = string.to_graphemes(str) - - Parser(fn(state) { - case graphemes { - [] -> Fail(Backtrack, bag_from_state(state, BadParser("empty string"))) - - [head, ..tail] -> { - let parse_each = - list.fold( - tail, - grapheme(head), - fn(parse, next) { - parse - |> drop(grapheme(next)) - }, - ) - case runwrap(state, parse_each) { - Cont(_, _, state) -> Cont(Commit, Nil, state) - Fail(_, bag) -> Fail(Backtrack, bag) - } - } - } - }) -} - -// NUMBERS --------------------------------------------------------------------- - -/// -pub fn int() -> Parser(Int, ctx) { - take_if_and_while(predicates.is_digit, "a digit") - // We can make the following assertion because we know our parser will - // only consume digits, and is guaranteed to have at least one. - |> map(fn(digits) { - let assert Ok(int) = int.parse(digits) - int - }) -} - -/// -pub fn float() -> Parser(Float, ctx) { - let make_float_string = - function.curry2(fn(x, y) { string.concat([x, ".", y]) }) - - succeed(make_float_string) - |> keep(take_if_and_while(predicates.is_digit, "a digit")) - |> drop(grapheme(".")) - |> keep(take_if_and_while(predicates.is_digit, "a digit")) - // We can make the following assertion because we know our parser will - // only consume digits, and is guaranteed to have at least one. - |> map(fn(digits) { - let assert Ok(float) = float.parse(digits) - float - }) -} - -// WHITESPACE ------------------------------------------------------------------ - -/// -pub fn spaces() -> Parser(Nil, ctx) { - take_while(fn(g) { g == " " }) - |> map(function.constant(Nil)) -} - -/// -pub fn whitespace() -> Parser(Nil, ctx) { - take_while(predicates.is_whitespace) - |> map(function.constant(Nil)) -} - -// BRANCHING AND LOOPING ------------------------------------------------------- - -/// -pub fn one_of(parsers: List(Parser(a, ctx))) -> Parser(a, ctx) { - Parser(fn(state) { - let init = Fail(Backtrack, Empty) - - list.fold_until( - parsers, - init, - fn(result, next) { - case result { - Cont(_, _, _) -> list.Stop(result) - - Fail(Commit, _) -> list.Stop(result) - - Fail(_, bag) -> - runwrap(state, next) - |> add_bag_to_step(bag) - |> list.Continue - } - }, - ) - }) -} - -/// -pub fn many( - parser: Parser(a, ctx), - separator: Parser(x, ctx), -) -> Parser(List(a), ctx) { - one_of([ - parser - |> then(more(_, parser, separator)), - succeed([]), - ]) -} - -fn more( - x: a, - parser: Parser(a, ctx), - separator: Parser(x, ctx), -) -> Parser(List(a), ctx) { - loop( - [x], - fn(xs) { - one_of([ - succeed(list.prepend(xs, _)) - |> drop(separator) - |> keep(parser) - |> map(Continue), - succeed(xs) - |> drop(eof()) - |> map(list.reverse) - |> map(Break), - succeed(xs) - |> map(list.reverse) - |> map(Break), - ]) - }, - ) -} - -pub type Loop(a, state) { - Continue(state) - Break(a) -} - -pub fn loop( - init: state, - step: fn(state) -> Parser(Loop(a, state), ctx), -) -> Parser(a, ctx) { - Parser(fn(state) { loop_help(step, Backtrack, init, state) }) -} - -fn loop_help(f, commit, loop_state, state) { - case runwrap(state, f(loop_state)) { - Cont(can_backtrack, Continue(next_loop_state), next_state) -> - loop_help( - f, - should_commit(commit, can_backtrack), - next_loop_state, - next_state, - ) - - Cont(can_backtrack, Break(result), next_state) -> - Cont(should_commit(commit, can_backtrack), result, next_state) - - Fail(can_backtrack, bag) -> Fail(should_commit(commit, can_backtrack), bag) - } -} - -// PREDICATES ------------------------------------------------------------------ - -/// -pub fn take_if( - predicate: fn(String) -> Bool, - expecting: String, -) -> Parser(String, ctx) { - Parser(fn(state) { - let #(str, next_state) = next(state) - let should_take = - str - |> option.map(predicate) - |> option.unwrap(False) - let str = option.unwrap(str, "") - - case should_take { - True -> Cont(Commit, str, next_state) - - False -> - Fail(Backtrack, bag_from_state(state, Expected(expecting, got: str))) - } - }) -} - -/// -pub fn take_while(predicate: fn(String) -> Bool) -> Parser(String, ctx) { - Parser(fn(state) { - let #(str, next_state) = next(state) - let should_take = - str - |> option.map(predicate) - |> option.unwrap(False) - let str = option.unwrap(str, "") - - case should_take { - True -> - runwrap(next_state, map(take_while(predicate), string.append(str, _))) - - False -> Cont(Backtrack, "", state) - } - }) -} - -/// -pub fn take_if_and_while( - predicate: fn(String) -> Bool, - expecting: String, -) -> Parser(String, ctx) { - map2(take_if(predicate, expecting), take_while(predicate), string.append) -} - -/// -pub fn take_until(predicate: fn(String) -> Bool) -> Parser(String, ctx) { - take_while(function.compose(predicate, bool.negate)) -} - -// ERRORS ---------------------------------------------------------------------- - -pub type Error { - BadParser(String) - Custom(String) - EndOfInput - Expected(String, got: String) - Unexpected(String) -} - -/// -pub type DeadEnd(ctx) { - DeadEnd(row: Int, col: Int, problem: Error, context: List(Located(ctx))) -} - -type Bag(ctx) { - Empty - Cons(Bag(ctx), DeadEnd(ctx)) - Append(Bag(ctx), Bag(ctx)) -} - -fn bag_from_state(state: State(ctx), problem: Error) -> Bag(ctx) { - Cons(Empty, DeadEnd(state.row, state.col, problem, state.context)) -} - -fn to_deadends(bag: Bag(ctx), acc: List(DeadEnd(ctx))) -> List(DeadEnd(ctx)) { - case bag { - Empty -> acc - - Cons(Empty, deadend) -> [deadend, ..acc] - - Cons(bag, deadend) -> to_deadends(bag, [deadend, ..acc]) - - Append(left, right) -> to_deadends(left, to_deadends(right, acc)) - } -} - -fn add_bag_to_step(step: Step(a, ctx), left: Bag(ctx)) -> Step(a, ctx) { - case step { - Cont(can_backtrack, a, state) -> Cont(can_backtrack, a, state) - - Fail(can_backtrack, right) -> Fail(can_backtrack, Append(left, right)) - } -} - -// CONTEXT --------------------------------------------------------------------- - -/// -pub fn in(parser: Parser(a, ctx), context: ctx) -> Parser(a, ctx) { - Parser(fn(state) { - case runwrap(push_context(state, context), parser) { - Cont(can_backtrack, a, state) -> - Cont(can_backtrack, a, pop_context(state)) - - Fail(can_backtrack, bag) -> Fail(can_backtrack, bag) - } - }) -} - -fn push_context(state: State(ctx), context: ctx) -> State(ctx) { - let located = Located(state.row, state.col, context) - State(..state, context: [located, ..state.context]) -} - -fn pop_context(state: State(ctx)) -> State(ctx) { - case state.context { - [] -> state - - [_, ..context] -> State(..state, context: context) - } -} - -/// Run the given parser and then inspect it's state. -pub fn inspect(parser: Parser(a, ctx), message: String) -> Parser(a, ctx) { - Parser(fn(state) { - io.print(message) - io.println(": ") - - runwrap(state, parser) - |> io.debug - }) -} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam deleted file mode 100644 index 968e75b128b..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam +++ /dev/null @@ -1,113 +0,0 @@ -// IMPORTS --------------------------------------------------------------------- - -import gleam/list -import gleam/function -import nibble.{ Parser } - -// TYPES ----------------------------------------------------------------------- - -pub opaque type Config(a, ctx) { - Config( - one_of: List(fn (Config(a, ctx)) -> Parser(a, ctx)), - and_then_one_of: List(Operator(a, ctx)), - spaces: Parser(Nil, ctx) - ) -} - -pub opaque type Operator(a, ctx) { - Operator( - fn(Config(a, ctx)) -> #(Int, fn (a) -> Parser(a, ctx)) - ) -} - -// - -pub fn expression( - one_of first: List(fn (Config(a, ctx)) -> Parser(a, ctx)), - and_then_one_of then: List(Operator(a, ctx)), - dropping spaces: Parser(Nil, ctx) -) -> Parser(a, ctx) { - let config = Config(first, then, spaces) - sub_expression(config, 0) -} - -pub fn sub_expression (config: Config(a, ctx), precedence: Int) -> Parser(a, ctx) { - let expr = nibble.lazy(fn () { - config.one_of - |> list.map(fn (p) { p(config) }) - |> nibble.one_of - }) - - let go = fn (expr) { - nibble.succeed(function.identity) - |> nibble.drop(config.spaces) - |> nibble.keep( - nibble.one_of([ - nibble.succeed(expr) - |> nibble.then(operation(_, config, precedence)) - |> nibble.map(nibble.Continue), - nibble.succeed(expr) - |> nibble.map(nibble.Break) - ]) - ) - } - - nibble.succeed(function.identity) - |> nibble.drop(config.spaces) - |> nibble.keep(expr) - |> nibble.then(nibble.loop(_, go)) -} - -fn operation (expr: a, config: Config(a, ctx), current_precedence: Int) -> Parser(a, ctx) { - config.and_then_one_of - |> list.filter_map(fn (operator) { - let Operator(op) = operator - case op(config) { - #(precedence, parser) if precedence > current_precedence -> - Ok(parser(expr)) - - _ -> - Error(Nil) - } - - }) - |> nibble.one_of() -} - -// - -pub fn prefix (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a) -> a) -> fn (Config(a, ctx)) -> Parser(a, ctx) { - fn (config) { - nibble.succeed(apply) - |> nibble.drop(operator) - |> nibble.keep(sub_expression(config, precedence)) - } -} - -pub fn infix_left (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { - make_infix(#(precedence, precedence), operator, apply) -} - -pub fn infix_right (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { - make_infix(#(precedence, precedence - 1), operator, apply) -} - -pub fn postfix (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a) -> a) -> Operator(a, ctx) { - Operator(fn (_) { - #(precedence, fn (lhs) { - nibble.succeed(apply(lhs)) - |> nibble.drop(operator) - }) - }) -} - -fn make_infix(precedence: #(Int, Int), operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { - let #(left_precedence, right_precedence) = precedence - Operator(fn (config) { - #(left_precedence, fn (lhs) { - nibble.succeed(apply(lhs, _)) - |> nibble.drop(operator) - |> nibble.keep(sub_expression(config, right_precedence)) - }) - }) -} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam deleted file mode 100644 index 756ccbd3ba7..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam +++ /dev/null @@ -1,59 +0,0 @@ -/// -pub fn is_digit (grapheme: String) -> Bool { - case grapheme { - "0" | "1" | "2" | "3" | "4" | - "5" | "6" | "7" | "8" | "9" -> - True - - _ -> - False - } -} - -/// -pub fn is_whitespace (grapheme: String) -> Bool { - case grapheme { - " " | "\t" | "\n" | "\r" -> - True - - _ -> - False - } -} - -/// -pub fn is_upper (grapheme: String) -> Bool { - case grapheme { - "A" | "B" | "C" | "D" | "E" | - "F" | "G" | "H" | "I" | "J" | - "K" | "L" | "M" | "N" | "O" | - "P" | "Q" | "R" | "S" | "T" | - "U" | "V" | "W" | "X" | "Y" | - "Z" -> - True - - _ -> - False - } -} - -/// -pub fn is_lower (grapheme: String) -> Bool { - case grapheme { - "a" | "b" | "c" | "d" | "e" | - "f" | "g" | "h" | "i" | "j" | - "k" | "l" | "m" | "n" | "o" | - "p" | "q" | "r" | "s" | "t" | - "u" | "v" | "w" | "x" | "y" | - "z" -> - True - - _ -> - False - } -} - -/// -pub fn is_alphanum (grapheme: String) -> Bool { - is_digit(grapheme) || is_upper(grapheme) || is_lower(grapheme) -} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl deleted file mode 100644 index 36a1260fc3b..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl +++ /dev/null @@ -1,120 +0,0 @@ --module(nibble@pratt). --compile([no_auto_import, nowarn_unused_vars]). - --export([sub_expression/2, expression/3, prefix/3, postfix/3, infix_left/3, infix_right/3]). --export_type([config/2, operator/2]). - --opaque config(FVQ, FVR) :: {config, - list(fun((config(FVQ, FVR)) -> nibble:parser(FVQ, FVR))), - list(operator(FVQ, FVR)), - nibble:parser(nil, FVR)}. - --opaque operator(FVS, FVT) :: {operator, - fun((config(FVS, FVT)) -> {integer(), - fun((FVS) -> nibble:parser(FVS, FVT))})}. - --spec operation(FWO, config(FWO, FWP), integer()) -> nibble:parser(FWO, FWP). -operation(Expr, Config, Current_precedence) -> - _pipe = erlang:element(3, Config), - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Operator) -> - {operator, Op} = Operator, - case Op(Config) of - {Precedence, Parser} when Precedence > Current_precedence -> - {ok, Parser(Expr)}; - - _ -> - {error, nil} - end - end - ), - nibble:one_of(_pipe@1). - --spec sub_expression(config(FWI, FWJ), integer()) -> nibble:parser(FWI, FWJ). -sub_expression(Config, Precedence) -> - Expr = nibble:lazy(fun() -> _pipe = erlang:element(2, Config), - _pipe@1 = gleam@list:map(_pipe, fun(P) -> P(Config) end), - nibble:one_of(_pipe@1) end), - Go = fun(Expr@1) -> _pipe@2 = nibble:succeed(fun gleam@function:identity/1), - _pipe@3 = nibble:drop(_pipe@2, erlang:element(4, Config)), - nibble:keep( - _pipe@3, - nibble:one_of( - [begin - _pipe@4 = nibble:succeed(Expr@1), - _pipe@5 = nibble:then( - _pipe@4, - fun(_capture) -> - operation(_capture, Config, Precedence) - end - ), - nibble:map( - _pipe@5, - fun(Field@0) -> {continue, Field@0} end - ) - end, - begin - _pipe@6 = nibble:succeed(Expr@1), - nibble:map( - _pipe@6, - fun(Field@0) -> {break, Field@0} end - ) - end] - ) - ) end, - _pipe@7 = nibble:succeed(fun gleam@function:identity/1), - _pipe@8 = nibble:drop(_pipe@7, erlang:element(4, Config)), - _pipe@9 = nibble:keep(_pipe@8, Expr), - nibble:then(_pipe@9, fun(_capture@1) -> nibble:loop(_capture@1, Go) end). - --spec expression( - list(fun((config(FVU, FVV)) -> nibble:parser(FVU, FVV))), - list(operator(FVU, FVV)), - nibble:parser(nil, FVV) -) -> nibble:parser(FVU, FVV). -expression(First, Then, Spaces) -> - Config = {config, First, Then, Spaces}, - sub_expression(Config, 0). - --spec prefix(integer(), nibble:parser(nil, FWU), fun((FWX) -> FWX)) -> fun((config(FWX, FWU)) -> nibble:parser(FWX, FWU)). -prefix(Precedence, Operator, Apply) -> - fun(Config) -> _pipe = nibble:succeed(Apply), - _pipe@1 = nibble:drop(_pipe, Operator), - nibble:keep(_pipe@1, sub_expression(Config, Precedence)) end. - --spec postfix(integer(), nibble:parser(nil, FXO), fun((FXR) -> FXR)) -> operator(FXR, FXO). -postfix(Precedence, Operator, Apply) -> - {operator, - fun(_) -> {Precedence, fun(Lhs) -> _pipe = nibble:succeed(Apply(Lhs)), - nibble:drop(_pipe, Operator) end} end}. - --spec make_infix( - {integer(), integer()}, - nibble:parser(nil, FXU), - fun((FXX, FXX) -> FXX) -) -> operator(FXX, FXU). -make_infix(Precedence, Operator, Apply) -> - {Left_precedence, Right_precedence} = Precedence, - {operator, - fun(Config) -> - {Left_precedence, - fun(Lhs) -> - _pipe = nibble:succeed( - fun(_capture) -> Apply(Lhs, _capture) end - ), - _pipe@1 = nibble:drop(_pipe, Operator), - nibble:keep( - _pipe@1, - sub_expression(Config, Right_precedence) - ) - end} - end}. - --spec infix_left(integer(), nibble:parser(nil, FXC), fun((FXF, FXF) -> FXF)) -> operator(FXF, FXC). -infix_left(Precedence, Operator, Apply) -> - make_infix({Precedence, Precedence}, Operator, Apply). - --spec infix_right(integer(), nibble:parser(nil, FXI), fun((FXL, FXL) -> FXL)) -> operator(FXL, FXI). -infix_right(Precedence, Operator, Apply) -> - make_infix({Precedence, Precedence - 1}, Operator, Apply). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl deleted file mode 100644 index 153d6223e49..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl +++ /dev/null @@ -1,234 +0,0 @@ --module(nibble@predicates). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_digit/1, is_whitespace/1, is_upper/1, is_lower/1, is_alphanum/1]). - --spec is_digit(binary()) -> boolean(). -is_digit(Grapheme) -> - case Grapheme of - <<"0"/utf8>> -> - true; - - <<"1"/utf8>> -> - true; - - <<"2"/utf8>> -> - true; - - <<"3"/utf8>> -> - true; - - <<"4"/utf8>> -> - true; - - <<"5"/utf8>> -> - true; - - <<"6"/utf8>> -> - true; - - <<"7"/utf8>> -> - true; - - <<"8"/utf8>> -> - true; - - <<"9"/utf8>> -> - true; - - _ -> - false - end. - --spec is_whitespace(binary()) -> boolean(). -is_whitespace(Grapheme) -> - case Grapheme of - <<" "/utf8>> -> - true; - - <<"\t"/utf8>> -> - true; - - <<"\n"/utf8>> -> - true; - - <<"\r"/utf8>> -> - true; - - _ -> - false - end. - --spec is_upper(binary()) -> boolean(). -is_upper(Grapheme) -> - case Grapheme of - <<"A"/utf8>> -> - true; - - <<"B"/utf8>> -> - true; - - <<"C"/utf8>> -> - true; - - <<"D"/utf8>> -> - true; - - <<"E"/utf8>> -> - true; - - <<"F"/utf8>> -> - true; - - <<"G"/utf8>> -> - true; - - <<"H"/utf8>> -> - true; - - <<"I"/utf8>> -> - true; - - <<"J"/utf8>> -> - true; - - <<"K"/utf8>> -> - true; - - <<"L"/utf8>> -> - true; - - <<"M"/utf8>> -> - true; - - <<"N"/utf8>> -> - true; - - <<"O"/utf8>> -> - true; - - <<"P"/utf8>> -> - true; - - <<"Q"/utf8>> -> - true; - - <<"R"/utf8>> -> - true; - - <<"S"/utf8>> -> - true; - - <<"T"/utf8>> -> - true; - - <<"U"/utf8>> -> - true; - - <<"V"/utf8>> -> - true; - - <<"W"/utf8>> -> - true; - - <<"X"/utf8>> -> - true; - - <<"Y"/utf8>> -> - true; - - <<"Z"/utf8>> -> - true; - - _ -> - false - end. - --spec is_lower(binary()) -> boolean(). -is_lower(Grapheme) -> - case Grapheme of - <<"a"/utf8>> -> - true; - - <<"b"/utf8>> -> - true; - - <<"c"/utf8>> -> - true; - - <<"d"/utf8>> -> - true; - - <<"e"/utf8>> -> - true; - - <<"f"/utf8>> -> - true; - - <<"g"/utf8>> -> - true; - - <<"h"/utf8>> -> - true; - - <<"i"/utf8>> -> - true; - - <<"j"/utf8>> -> - true; - - <<"k"/utf8>> -> - true; - - <<"l"/utf8>> -> - true; - - <<"m"/utf8>> -> - true; - - <<"n"/utf8>> -> - true; - - <<"o"/utf8>> -> - true; - - <<"p"/utf8>> -> - true; - - <<"q"/utf8>> -> - true; - - <<"r"/utf8>> -> - true; - - <<"s"/utf8>> -> - true; - - <<"t"/utf8>> -> - true; - - <<"u"/utf8>> -> - true; - - <<"v"/utf8>> -> - true; - - <<"w"/utf8>> -> - true; - - <<"x"/utf8>> -> - true; - - <<"y"/utf8>> -> - true; - - <<"z"/utf8>> -> - true; - - _ -> - false - end. - --spec is_alphanum(binary()) -> boolean(). -is_alphanum(Grapheme) -> - (is_digit(Grapheme) orelse is_upper(Grapheme)) orelse is_lower(Grapheme). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/LICENSE b/test-community-packages-javascript/build/packages/non_empty_list/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/test-community-packages-javascript/build/packages/non_empty_list/README.md b/test-community-packages-javascript/build/packages/non_empty_list/README.md deleted file mode 100644 index 4502421a799..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# non_empty_list - -[![Package Version](https://img.shields.io/hexpm/v/non_empty_list)](https://hex.pm/packages/non_empty_list) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/non_empty_list/) -![CI](https://github.com/giacomocavalieri/non_empty_list/workflows/CI/badge.svg?branch=main) - -Non-empty lists in Gleam ✨ - -> ⚙️ This package supports both the Erlang and JavaScript target! - -## Installation - -To add this package to your Gleam project: - -```sh -gleam add non_empty_list -``` - -## Usage - -Import the `non_empty_list` module and write some code! - -```gleam -import non_empty_list -import gleam/int -import gleam/io - -pub fn main() { - non_empty_list.new(1, [2, 3, 4]) - |> non_empty_list.reduce(with: fn(n, m) { n + m }) - |> int.to_string - |> io.println -} -``` - -## Contributing - -This package exposes most of the same functions you'd find in the `gleam/list` module but it may be missing some useful functions. - -If you think there's a missing function that would fit here, or if you spot a bug don't be afraid to open PRs, issues or requests of any kind! Any contribution is welcome 💜 diff --git a/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml b/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml deleted file mode 100644 index 4ac8d3b865f..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "non_empty_list" -version = "1.0.0" -description = "Non-empty lists in Gleam" - -licences = ["Apache-2.0"] -repository = { type = "github", user = "giacomocavalieri", repo = "non_empty_list" } -links = [] - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -glacier = "~> 0.8" diff --git a/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl b/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl deleted file mode 100644 index d88aaf5f88b..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl +++ /dev/null @@ -1 +0,0 @@ --record(non_empty_list, {first :: any(), rest :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src deleted file mode 100644 index ec63d53e799..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, non_empty_list, [ - {vsn, "1.0.0"}, - {applications, [glacier, - gleam_stdlib]}, - {description, "Non-empty lists in Gleam"}, - {modules, [non_empty_list]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl deleted file mode 100644 index efb67411150..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl +++ /dev/null @@ -1,304 +0,0 @@ --module(non_empty_list). --compile([no_auto_import, nowarn_unused_vars]). - --export([first/1, last/1, new/2, append_list/2, from_list/1, intersperse/2, map/2, prepend/2, reduce/2, rest/1, single/1, to_list/1, append/2, drop/2, reverse/1, map_fold/3, scan/3, shuffle/1, sort/2, take/2, unique/1, unzip/1, zip/2, strict_zip/2, flatten/1, flat_map/2, index_map/2]). --export_type([non_empty_list/1, list_was_empty/0]). - --type non_empty_list(GJS) :: {non_empty_list, GJS, list(GJS)}. - --type list_was_empty() :: list_was_empty. - --spec first(non_empty_list(GKE)) -> GKE. -first(List) -> - erlang:element(2, List). - --spec last(non_empty_list(GLP)) -> GLP. -last(List) -> - _pipe = gleam@list:last(erlang:element(3, List)), - gleam@result:unwrap(_pipe, erlang:element(2, List)). - --spec new(GMA, list(GMA)) -> non_empty_list(GMA). -new(First, Rest) -> - {non_empty_list, First, Rest}. - --spec append_list(non_empty_list(GJX), list(GJX)) -> non_empty_list(GJX). -append_list(First, Second) -> - new( - erlang:element(2, First), - gleam@list:append(erlang:element(3, First), Second) - ). - --spec from_list(list(GKY)) -> {ok, non_empty_list(GKY)} | - {error, list_was_empty()}. -from_list(List) -> - case List of - [] -> - {error, list_was_empty}; - - [First | Rest] -> - {ok, new(First, Rest)} - end. - --spec intersperse(non_empty_list(GLM), GLM) -> non_empty_list(GLM). -intersperse(List, Elem) -> - new( - erlang:element(2, List), - [Elem | gleam@list:intersperse(erlang:element(3, List), Elem)] - ). - --spec map(non_empty_list(GLR), fun((GLR) -> GLT)) -> non_empty_list(GLT). -map(List, Fun) -> - new( - Fun(erlang:element(2, List)), - gleam@list:map(erlang:element(3, List), Fun) - ). - --spec prepend(non_empty_list(GMD), GMD) -> non_empty_list(GMD). -prepend(List, Item) -> - new(Item, [erlang:element(2, List) | erlang:element(3, List)]). - --spec reduce(non_empty_list(GMG), fun((GMG, GMG) -> GMG)) -> GMG. -reduce(List, Fun) -> - gleam@list:fold(erlang:element(3, List), erlang:element(2, List), Fun). - --spec rest(non_empty_list(GMI)) -> list(GMI). -rest(List) -> - erlang:element(3, List). - --spec single(GMV) -> non_empty_list(GMV). -single(First) -> - new(First, []). - --spec to_list(non_empty_list(GNK)) -> list(GNK). -to_list(Non_empty) -> - [erlang:element(2, Non_empty) | erlang:element(3, Non_empty)]. - --spec append(non_empty_list(GJT), non_empty_list(GJT)) -> non_empty_list(GJT). -append(First, Second) -> - new( - erlang:element(2, First), - gleam@list:append(erlang:element(3, First), to_list(Second)) - ). - --spec drop(non_empty_list(GKB), integer()) -> list(GKB). -drop(List, N) -> - _pipe = List, - _pipe@1 = to_list(_pipe), - gleam@list:drop(_pipe@1, N). - --spec reverse(non_empty_list(GML)) -> non_empty_list(GML). -reverse(List) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:reverse(_pipe@1), - from_list(_pipe@2) - end, - {ok, Reversed} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"reverse"/utf8>>, - line => 378}) - end, - Reversed. - --spec map_fold(non_empty_list(GLV), GLX, fun((GLX, GLV) -> {GLX, GLY})) -> {GLX, - non_empty_list(GLY)}. -map_fold(List, Acc, Fun) -> - {Acc@1, First_elem} = Fun(Acc, erlang:element(2, List)), - _pipe = gleam@list:fold( - erlang:element(3, List), - {Acc@1, single(First_elem)}, - fun(Acc_non_empty, Item) -> - {Acc@2, Non_empty} = Acc_non_empty, - {Acc@3, New_item} = Fun(Acc@2, Item), - {Acc@3, prepend(Non_empty, New_item)} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec scan(non_empty_list(GMO), GMQ, fun((GMQ, GMO) -> GMQ)) -> non_empty_list(GMQ). -scan(List, Initial, Fun) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:scan(_pipe@1, Initial, Fun), - from_list(_pipe@2) - end, - {ok, Scanned} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"scan"/utf8>>, - line => 400}) - end, - Scanned. - --spec shuffle(non_empty_list(GMS)) -> non_empty_list(GMS). -shuffle(List) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:shuffle(_pipe@1), - from_list(_pipe@2) - end, - {ok, Shuffled} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"shuffle"/utf8>>, - line => 423}) - end, - Shuffled. - --spec sort(non_empty_list(GMX), fun((GMX, GMX) -> gleam@order:order())) -> non_empty_list(GMX). -sort(List, Compare) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:sort(_pipe@1, Compare), - from_list(_pipe@2) - end, - {ok, Sorted} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"sort"/utf8>>, - line => 459}) - end, - Sorted. - --spec take(non_empty_list(GNH), integer()) -> list(GNH). -take(List, N) -> - _pipe = List, - _pipe@1 = to_list(_pipe), - gleam@list:take(_pipe@1, N). - --spec unique(non_empty_list(GNN)) -> non_empty_list(GNN). -unique(List) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:unique(_pipe@1), - from_list(_pipe@2) - end, - {ok, Unique} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"unique"/utf8>>, - line => 557}) - end, - Unique. - --spec unzip(non_empty_list({GNQ, GNR})) -> {non_empty_list(GNQ), - non_empty_list(GNR)}. -unzip(List) -> - _pipe = gleam@list:unzip(erlang:element(3, List)), - _pipe@1 = gleam@pair:map_first( - _pipe, - fun(_capture) -> - new(erlang:element(1, erlang:element(2, List)), _capture) - end - ), - gleam@pair:map_second( - _pipe@1, - fun(_capture@1) -> - new(erlang:element(2, erlang:element(2, List)), _capture@1) - end - ). - --spec zip(non_empty_list(GNV), non_empty_list(GNX)) -> non_empty_list({GNV, GNX}). -zip(List, Other) -> - new( - {erlang:element(2, List), erlang:element(2, Other)}, - gleam@list:zip(erlang:element(3, List), erlang:element(3, Other)) - ). - --spec strict_zip(non_empty_list(GNA), non_empty_list(GNC)) -> {ok, - non_empty_list({GNA, GNC})} | - {error, gleam@list:length_mismatch()}. -strict_zip(List, Other) -> - case gleam@list:length(to_list(List)) =:= gleam@list:length(to_list(Other)) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_flatten(list(non_empty_list(GKP)), non_empty_list(GKP)) -> non_empty_list(GKP). -do_flatten(Lists, Accumulator) -> - case Lists of - [] -> - reverse(Accumulator); - - [List | Further_lists] -> - do_flatten(Further_lists, reverse_and_prepend(List, Accumulator)) - end. - --spec flatten(non_empty_list(non_empty_list(GKL))) -> non_empty_list(GKL). -flatten(Lists) -> - do_flatten(erlang:element(3, Lists), reverse(erlang:element(2, Lists))). - --spec flat_map(non_empty_list(GKG), fun((GKG) -> non_empty_list(GKI))) -> non_empty_list(GKI). -flat_map(List, Fun) -> - _pipe = List, - _pipe@1 = map(_pipe, Fun), - flatten(_pipe@1). - --spec reverse_and_prepend(non_empty_list(GKU), non_empty_list(GKU)) -> non_empty_list(GKU). -reverse_and_prepend(Prefix, Suffix) -> - case erlang:element(3, Prefix) of - [] -> - new(erlang:element(2, Prefix), to_list(Suffix)); - - [First | Rest] -> - reverse_and_prepend( - new(First, Rest), - new(erlang:element(2, Prefix), to_list(Suffix)) - ) - end. - --spec do_index_map( - list(GLH), - list(GLJ), - integer(), - fun((integer(), GLH) -> GLJ) -) -> list(GLJ). -do_index_map(List, Accumulator, Index, Fun) -> - case List of - [] -> - gleam@list:reverse(Accumulator); - - [First | Rest] -> - do_index_map( - Rest, - [Fun(Index, First) | Accumulator], - Index + 1, - Fun - ) - end. - --spec index_map(non_empty_list(GLD), fun((integer(), GLD) -> GLF)) -> non_empty_list(GLF). -index_map(List, Fun) -> - new( - Fun(0, erlang:element(2, List)), - do_index_map(erlang:element(3, List), [], 1, Fun) - ). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam deleted file mode 100644 index 9ceb47e143e..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam +++ /dev/null @@ -1,607 +0,0 @@ -import gleam/list -import gleam/result -import gleam/pair -import gleam/order.{Order} - -/// A list that is guaranteed to contain at least one item. -pub type NonEmptyList(a) { - NonEmptyList(first: a, rest: List(a)) -} - -/// An error that occurs when trying to convert an empty list into a -/// non empty list. -/// -pub type ListWasEmpty { - ListWasEmpty -} - -/// Joins a non-empty list onto the end of a non-empty list. -/// -/// This function runs in linear time, and it traverses and copies the first non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> append(new(5, [6, 7])) -/// NonEmptyList(1, [2, 3, 4, 5, 6, 7]) -/// ``` -/// -/// ```gleam -/// > single("a") -/// > |> append(new("b", ["c"]) -/// NonEmptyList("a", ["b", "c"]) -/// ```` -/// -pub fn append( - first: NonEmptyList(a), - second: NonEmptyList(a), -) -> NonEmptyList(a) { - new(first.first, list.append(first.rest, to_list(second))) -} - -/// Joins a list onto the end of a non-empty list. -/// -/// This function runs in linear time, and it traverses and copies the first non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> append_list([5, 6, 7]) -/// NonEmptyList(1, [2, 3, 4, 5, 6, 7]) -/// ``` -/// -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> append_list([]) -/// NonEmptyList("a", ["b", "c"]) -/// ``` -/// -pub fn append_list(first: NonEmptyList(a), second: List(a)) -> NonEmptyList(a) { - new(first.first, list.append(first.rest, second)) -} - -/// Returns a list that is the given non-empty list with up to the given -/// number of elements removed from the front of the list. -/// -/// ## Examples -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> drop(up_to: 2) -/// ["c"] -/// ``` -/// -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> drop(up_to: 3) -/// [] -/// ``` -/// -pub fn drop(from list: NonEmptyList(a), up_to n: Int) -> List(a) { - list - |> to_list - |> list.drop(up_to: n) -} - -/// Gets the first element from the start of the non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> first -/// 1 -/// ``` -/// -pub fn first(list: NonEmptyList(a)) -> a { - list.first -} - -/// Maps the non-empty list with the given function and then flattens it. -/// -/// ## Examples -/// ```gleam -/// > new(1, [3, 5]) -/// > |> flat_map(fn(x) { new(x, [x + 1]) }) -/// NonEmptyList(1, [2, 3, 4, 5, 6]) -/// ``` -/// -pub fn flat_map( - over list: NonEmptyList(a), - with fun: fn(a) -> NonEmptyList(b), -) -> NonEmptyList(b) { - list - |> map(fun) - |> flatten -} - -/// Flattens a non-empty list of non-empty lists into a single non-empty list. -/// -/// This function traverses all elements twice. -/// -/// ### Examples -/// -/// ```gleam -/// > new(new(1, [2, 3]), [new(3, [4, 5])]) -/// > |> flatten -/// NonEmptyList(1, [2, 3, 4, 5]) -/// ``` -/// -pub fn flatten(lists: NonEmptyList(NonEmptyList(a))) -> NonEmptyList(a) { - do_flatten(lists.rest, reverse(lists.first)) -} - -fn do_flatten( - lists: List(NonEmptyList(a)), - accumulator: NonEmptyList(a), -) -> NonEmptyList(a) { - case lists { - [] -> reverse(accumulator) - [list, ..further_lists] -> - do_flatten(further_lists, reverse_and_prepend(list, accumulator)) - } -} - -fn reverse_and_prepend( - list prefix: NonEmptyList(a), - to suffix: NonEmptyList(a), -) -> NonEmptyList(a) { - case prefix.rest { - [] -> new(prefix.first, to_list(suffix)) - [first, ..rest] -> - reverse_and_prepend(new(first, rest), new(prefix.first, to_list(suffix))) - } -} - -/// Attempts to turn a list into a non-empty list, fails if the starting -/// list is empty. -/// -/// ## Examples -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// Ok(NonEmptyList(1, [2, 3, 4])) -/// ``` -/// -/// ```gleam -/// > from_list(["a"]) -/// Ok(NonEmptyList("a", [])) -/// ``` -/// -/// ```gleam -/// > from_list([]) -/// Error(ListWasEmpty) -/// ``` -/// -pub fn from_list(list: List(a)) -> Result(NonEmptyList(a), ListWasEmpty) { - case list { - [] -> Error(ListWasEmpty) - [first, ..rest] -> Ok(new(first, rest)) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so on. -/// -/// ## Examples -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> index_map(fn(index, letter) { #(index, letter) }) -/// NonEmpty(#(0, "a"), [#(1, "b"), #(2, "c")]) -/// ``` -/// -pub fn index_map( - list: NonEmptyList(a), - with fun: fn(Int, a) -> b, -) -> NonEmptyList(b) { - new(fun(0, list.first), do_index_map(list.rest, [], 1, fun)) -} - -fn do_index_map( - list: List(a), - accumulator: List(b), - index: Int, - fun: fn(Int, a) -> b, -) -> List(b) { - case list { - [] -> list.reverse(accumulator) - [first, ..rest] -> - do_index_map(rest, [fun(index, first), ..accumulator], index + 1, fun) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> intersperse(with: 0) -/// NonEmptyList(1, [0, 2, 0, 3, 0, 4]) -/// ``` -/// -/// ```gleam -/// > single("a") -/// > |> intersperse(with: "z") -/// NonEmptyList("a", ["z"]) -/// ``` -/// -pub fn intersperse(list: NonEmptyList(a), with elem: a) -> NonEmptyList(a) { - new(list.first, [elem, ..list.intersperse(list.rest, with: elem)]) -} - -/// Returns the last element in the given list. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// ```gleam -/// > single(1) -/// > |> last -/// 1 -/// ``` -/// -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> last -/// 4 -/// ``` -/// -pub fn last(list: NonEmptyList(a)) -> a { - list.last(list.rest) - |> result.unwrap(list.first) -} - -/// Returns a new non-empty list containing only the elements of the first -/// non-empty list after the function has been applied to each one. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3]) -/// > |> map(fn(x) { x + 1 }) -/// NonEmpty(2, [3, 4]) -/// ``` -/// -pub fn map(over list: NonEmptyList(a), with fun: fn(a) -> b) -> NonEmptyList(b) { - new(fun(list.first), list.map(list.rest, with: fun)) -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3]) -/// > |> map_fold(from: 100, with: fn(memo, n) { #(memo + i, i * 2) }) -/// #(106, NonEmpty(2, [4, 6])) -/// ``` -/// -pub fn map_fold( - over list: NonEmptyList(a), - from acc: b, - with fun: fn(b, a) -> #(b, c), -) -> #(b, NonEmptyList(c)) { - let #(acc, first_elem) = fun(acc, list.first) - list.fold( - over: list.rest, - from: #(acc, single(first_elem)), - with: fn(acc_non_empty, item) { - let #(acc, non_empty) = acc_non_empty - let #(acc, new_item) = fun(acc, item) - #(acc, prepend(to: non_empty, this: new_item)) - }, - ) - |> pair.map_second(reverse) -} - -/// Creates a new non-empty list given its first element and a list -/// for the rest of the elements. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// NonEmptyList(1, [2, 3, 4]) -/// ``` -/// ```gleam -/// > new("a", []) -/// NonEmptyList("a", []) -/// ``` -/// -pub fn new(first: a, rest: List(a)) -> NonEmptyList(a) { - NonEmptyList(first, rest) -} - -/// Prefixes an item to a non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(2, [3, 4]) -/// > |> prepend(1) -/// NonEmptyList(1, [2, 3, 4]) -/// ``` -/// -pub fn prepend(to list: NonEmptyList(a), this item: a) -> NonEmptyList(a) { - new(item, [list.first, ..list.rest]) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the non-empty list and combines it with each -/// subsequent element in turn using the given function. -/// The function is called as `fun(accumulator, current_element)`. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> reduce(fn(acc, x) { acc + x }) -/// 10 -/// ``` -/// -pub fn reduce(over list: NonEmptyList(a), with fun: fn(a, a) -> a) -> a { - list.fold(over: list.rest, from: list.first, with: fun) -} - -/// Returns the list minus the first element. Since the remaining list could -/// be empty this functions returns a normal list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> rest -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > single(1) -/// > |> rest -/// [] -/// ``` -/// -pub fn rest(list: NonEmptyList(a)) -> List(a) { - list.rest -} - -/// Creates a new non-empty list from a given non-empty list containing the same elements -/// but in the opposite order. -/// -/// This function has to traverse the non-empty list to create the new reversed -/// non-empty list, so it runs in linear time. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> reverse -/// NonEmptyList(4, [3, 2, 1]) -/// ``` -/// -pub fn reverse(list: NonEmptyList(a)) -> NonEmptyList(a) { - let assert Ok(reversed) = - list - |> to_list - |> list.reverse - |> from_list - reversed -} - -/// Similar to fold, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> scan(from: 100, with: fn(acc, i) { acc + i }) -/// NonEmptyList(101 [103, 106, 110]) -/// ``` -/// -pub fn scan( - over list: NonEmptyList(a), - from initial: b, - with fun: fn(b, a) -> b, -) -> NonEmptyList(b) { - let assert Ok(scanned) = - list - |> to_list - |> list.scan(from: initial, with: fun) - |> from_list - scanned -} - -/// Takes a non-empty list, randomly sorts all items and returns the shuffled -/// non-empty list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calcuate the index shuffling. -/// -/// ## Examples -/// -/// ```gleam -/// > new("a", ["b", "c", "d"]) -/// > |> shuffle -/// NonEmptyList("c", ["a", "d", "b"]) -/// ``` -/// -pub fn shuffle(list: NonEmptyList(a)) -> NonEmptyList(a) { - let assert Ok(shuffled) = - list - |> to_list - |> list.shuffle - |> from_list - shuffled -} - -/// Creates a non-empty list with a single element. -/// -/// ## Examples -/// ```gleam -/// > single(1) -/// NonEmptyList(1, []) -/// ``` -/// -pub fn single(first: a) -> NonEmptyList(a) { - new(first, []) -} - -/// Sorts a given non-empty list from smallest to largest based upon the -/// ordering specified by a given function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > new(4, [1, 3, 4, 2, 6, 5]) -/// > sort(by: int.compare) -/// NonEmptyList(1, [2, 3, 4, 4, 5, 6]) -/// ``` -/// -pub fn sort( - list: NonEmptyList(a), - by compare: fn(a, a) -> Order, -) -> NonEmptyList(a) { - let assert Ok(sorted) = - list - |> to_list - |> list.sort(by: compare) - |> from_list - sorted -} - -/// Takes two non-empty lists and returns a single non-empty list of 2-element tuples. -/// -/// If one of the non-empty lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip(single(1), new("a", ["b", "c"])) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip(new(1, [2, 3]), single("a")) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip(new(1, [2, 3]), new("a", ["b", "c"])) -/// Ok(NonEmptyList(#(1, "a"), [#(2, "b"), #(3, "c")])) -/// ``` -/// -pub fn strict_zip( - list: NonEmptyList(a), - with other: NonEmptyList(b), -) -> Result(NonEmptyList(#(a, b)), list.LengthMismatch) { - case list.length(to_list(list)) == list.length(to_list(other)) { - True -> Ok(zip(list, with: other)) - False -> Error(list.LengthMismatch) - } -} - -/// Returns a list containing the first given number of elements from the given -/// non-empty list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > take(2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > take(9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: NonEmptyList(a), up_to n: Int) -> List(a) { - list - |> to_list - |> list.take(n) -} - -/// Turns a non-empty list back into a normal list with the same -/// elements. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -/// ```gleam -/// > single("a") -/// > |> to_list -/// ["a"] -/// ``` -/// -pub fn to_list(non_empty: NonEmptyList(a)) -> List(a) { - [non_empty.first, ..non_empty.rest] -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// ```gleam -/// > new(1, [1, 2, 3, 1, 4, 4, 3]) -/// > |> unique -/// NonEmptyList(1, [2, 3, 4]) -/// ``` -/// -pub fn unique(list: NonEmptyList(a)) -> NonEmptyList(a) { - let assert Ok(unique) = - list - |> to_list - |> list.unique - |> from_list - unique -} - -/// Takes a single non-empty list of 2-element tuples and returns two -/// non-empty lists. -/// -/// ## Examples -/// ```gleam -/// > new(#(1, "a"), [#(2, "b"), #(3, "c")]) -/// > |> unzip -/// #(NonEmptyList(1, [2, 3]), NonEmptyList("a", ["b", "c"])) -/// ``` -/// -pub fn unzip(list: NonEmptyList(#(a, b))) -> #(NonEmptyList(a), NonEmptyList(b)) { - list.unzip(list.rest) - |> pair.map_first(new(list.first.0, _)) - |> pair.map_second(new(list.first.1, _)) -} - -/// Takes two non-empty lists and returns a single non-empty list of 2-element tuples. -/// -/// If one of the non-empty lists is longer than the other, the remaining elements from -/// the longer non-empty list are not used. -/// -/// ## Examples -/// ```gleam -/// > zip(new(1, [2, 3]), single("a")) -/// NonEmptyList(#(1, "a"), []) -/// ``` -/// -/// ```gleam -/// > zip(single(1), new("a", ["b", "c"])) -/// NonEmptyList(#(1, "a"), []) -/// ``` -/// -/// ```gleam -/// > zip(new(1, [2, 3]), new("a", ["b", "c"])) -/// NonEmptyList(#(1, "a"), [#(2, "b"), #(3, "c")]) -/// ``` -/// -pub fn zip( - list: NonEmptyList(a), - with other: NonEmptyList(b), -) -> NonEmptyList(#(a, b)) { - new(#(list.first, other.first), list.zip(list.rest, other.rest)) -} diff --git a/test-community-packages-javascript/build/packages/packages.toml b/test-community-packages-javascript/build/packages/packages.toml deleted file mode 100644 index 948d847a082..00000000000 --- a/test-community-packages-javascript/build/packages/packages.toml +++ /dev/null @@ -1,30 +0,0 @@ -[packages] -gliew = "0.3.0" -gleam_community_colour = "1.1.0" -gleam_stdlib = "0.29.2" -simplifile = "0.1.4" -gleam_bitwise = "1.2.0" -nakai = "0.8.0" -gleam_erlang = "0.19.0" -gleeunit = "0.10.1" -gsv = "0.1.0" -gleam_community_ansi = "1.1.0" -trie_again = "1.1.1" -ream = "0.1.0" -gleam_cors = "0.2.0" -gleam_otp = "0.5.3" -glisten = "0.7.0" -nibble = "0.2.3" -gleam_crypto = "0.3.1" -globe = "0.1.0" -glove = "0.2.0" -mist = "0.11.0" -gloml = "0.1.2" -toml = "0.7.0" -gleam_http = "3.2.0" -hug = "0.1.0" -glenvy = "0.4.0" -glx = "0.2.0" -non_empty_list = "1.0.0" -glerm = "0.1.0" -gleamy_structures = "0.3.0" diff --git a/test-community-packages-javascript/build/packages/ream/LICENSE b/test-community-packages-javascript/build/packages/ream/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/test-community-packages-javascript/build/packages/ream/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/test-community-packages-javascript/build/packages/ream/README.md b/test-community-packages-javascript/build/packages/ream/README.md deleted file mode 100644 index f31e5667fb3..00000000000 --- a/test-community-packages-javascript/build/packages/ream/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# ream - -[![Package Version](https://img.shields.io/hexpm/v/ream)](https://hex.pm/packages/ream) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/ream/) - -REAM is an event-sourcing system. - -The REAM server is a simple TCP server that's receiving events from aggregators which are -sending the event and a status update. The idea is: - -- The Aggregator receives a command. -- The aggregator validates the command and generates: - 1. One or more events are generated by the aggregator and published into REAM. - 2. A modification in the state is performed in the aggregator and stored in REAM. -- Subscribers, mainly projectors receive the event. -- These subscribers perform a change in the schema and publish changes into projections. - -Therefore we have three different but related storage: - -- Events. It's getting events in different streams. We can create as many streams as we need. -- Aggregations. It's storing the state for the aggregators based on the last processed event for a specific stream. -- Projections. Stored the projections based on the information provided by the projectors. - -The main idea is to provide an easy way for implementing aggregators and projectors to process the data we need in the way we need it. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add ream -``` - -and its documentation can be found at <https://hexdocs.pm/ream>. - -## Architecture and Design - -You can check the protocol [here](docs/protocol.md) and how the storage is going to take place [here](docs/storage.md). - -## License - -Apache License Version 2.0, see [LICENSE](LICENSE) - -Copyright 2023 Altenwald - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/test-community-packages-javascript/build/packages/ream/gleam.toml b/test-community-packages-javascript/build/packages/ream/gleam.toml deleted file mode 100644 index 43c839f2fbc..00000000000 --- a/test-community-packages-javascript/build/packages/ream/gleam.toml +++ /dev/null @@ -1,27 +0,0 @@ -name = "ream" -version = "0.1.0" -description = "REAM is an event sourcing system" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. - -licences = ["Apache-2.0"] -repository = { type = "github", user = "altenwald", repo = "ream" } -# links = [{ title = "Website", href = "https://gleam.run" }] - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_otp = "~> 0.5" -hug = "~> 0.1" -gloml = "~> 0.1" -gleam_erlang = "~> 0.19" - -[dev-dependencies] -glacier = "~> 0.8" - -[documentation] -pages = [ - { title = "LICENSE", path = "license.html", source = "LICENSE" }, - { title = "Protocol", path = "protocol.html", source = "docs/protocol.md" }, - { title = "Storage", path = "storage.html", source = "docs/storage.md" } -] diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl deleted file mode 100644 index 686a9b2f541..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl +++ /dev/null @@ -1 +0,0 @@ --record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl deleted file mode 100644 index 686a9b2f541..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl +++ /dev/null @@ -1 +0,0 @@ --record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl deleted file mode 100644 index db5abbdf21d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ok, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl deleted file mode 100644 index 686a9b2f541..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl +++ /dev/null @@ -1 +0,0 @@ --record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl deleted file mode 100644 index eb7e3ac051a..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl +++ /dev/null @@ -1 +0,0 @@ --record(delayed_write, {size :: integer(), delay :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl deleted file mode 100644 index 2d13f93ccb9..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl +++ /dev/null @@ -1 +0,0 @@ --record(encoding, {encoding :: ream@storage@file:encoding_type()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl deleted file mode 100644 index 963a65ce424..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl +++ /dev/null @@ -1 +0,0 @@ --record(read_ahead, {size :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl deleted file mode 100644 index 0be9823bd17..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(mem_table, { - entries :: gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry()), - size :: integer(), - max_size :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl deleted file mode 100644 index b342d1a4d84..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(mem_table_entry, { - key :: binary(), - value :: ream@storage@kv@value:value() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl deleted file mode 100644 index 1631ca7075a..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(value, { - offset :: integer(), - deleted :: boolean(), - data :: gleam@option:option(bitstring()), - file_id :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl deleted file mode 100644 index b8fd91be66a..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(value_file, { - id :: integer(), - handler :: gleam@erlang@process:pid_(), - size :: integer(), - max_size :: integer(), - file_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl deleted file mode 100644 index 9582b309c40..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(value_file_info, { - file_id :: integer(), - size :: integer(), - max_size :: integer(), - entries :: integer(), - deleted :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl deleted file mode 100644 index 75884f81d1d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl +++ /dev/null @@ -1,11 +0,0 @@ --record(kv, { - base_path :: binary(), - name :: binary(), - memtable_ranges :: gleam@map:map_(integer(), ream@storage@kv:mem_table_range()), - active_value_file :: gleam@option:option(integer()), - values :: gleam@map:map_(integer(), ream@storage@kv@value:value_file()), - memtables_loaded :: integer(), - max_memtables_loaded :: integer(), - max_memtable_size :: integer(), - max_value_size :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl deleted file mode 100644 index 3bd9ff18d40..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl +++ /dev/null @@ -1,12 +0,0 @@ --record(kv_info, { - base_path :: binary(), - name :: binary(), - values :: integer(), - values_size_bytes :: integer(), - memtables_total :: integer(), - memtables_loaded :: integer(), - memtables_loaded_size_bytes :: integer(), - max_memtables_loaded :: integer(), - max_memtable_size :: integer(), - max_value_size :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl deleted file mode 100644 index 71ec67b0599..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(mem_table_range, { - lower :: integer(), - upper :: integer(), - memtable :: gleam@option:option(ream@storage@kv@memtable:mem_table()) -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl deleted file mode 100644 index 8eaa99ab752..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl +++ /dev/null @@ -1 +0,0 @@ --record(event, {offset :: integer(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl deleted file mode 100644 index eab4d784cf5..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(event_file, { - id :: integer(), - handler :: gleam@erlang@process:pid_(), - size :: integer(), - file_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl deleted file mode 100644 index eed9e04ebec..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl +++ /dev/null @@ -1 +0,0 @@ --record(index, {offset :: integer(), size :: integer(), file_id :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl deleted file mode 100644 index 7a25f9bdfcb..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(index_file, { - handler :: gleam@erlang@process:pid_(), - size :: integer(), - file_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl deleted file mode 100644 index ff7a5576983..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(stream, { - name :: binary(), - index :: ream@storage@stream@index:index_file(), - active_file :: gleam@option:option(ream@storage@stream@event:event_file()), - files :: gleam@map:map_(integer(), ream@storage@stream@event:event_file()), - base_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.app.src b/test-community-packages-javascript/build/packages/ream/src/ream.app.src deleted file mode 100644 index ad44dc9c44d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream.app.src +++ /dev/null @@ -1,24 +0,0 @@ -{application, ream, [ - {vsn, "0.1.0"}, - {applications, [glacier, - gleam_erlang, - gleam_otp, - gleam_stdlib, - gloml, - hug]}, - {description, "REAM is an event sourcing system"}, - {modules, [ream, - ream@storage@file, - ream@storage@file@close, - ream@storage@file@read, - ream@storage@file@write, - ream@storage@kv, - ream@storage@kv@memtable, - ream@storage@kv@sstable, - ream@storage@kv@value, - ream@storage@stream, - ream@storage@stream@event, - ream@storage@stream@index, - ream@uuid]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.erl b/test-community-packages-javascript/build/packages/ream/src/ream.erl deleted file mode 100644 index a54ca2a1af2..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream.erl +++ /dev/null @@ -1 +0,0 @@ --module(ream). diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.gleam b/test-community-packages-javascript/build/packages/ream/src/ream.gleam deleted file mode 100644 index 8b137891791..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream.gleam +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam deleted file mode 100644 index 64e87f2e0d3..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam +++ /dev/null @@ -1,103 +0,0 @@ -import gleam/erlang/process.{Pid} -import gleam/erlang/file -import ream/storage/file/read -import ream/storage/file/close -import ream/storage/file/write - -pub type Endian { - Big - Little -} - -pub type EncodingType { - Unicode - Utf8 - Utf16(Endian) - Utf32(Endian) - Latin1 -} - -pub type Mode { - Read - Write - Append - Exclusive - Raw - Binary - DelayedWrite(size: Int, delay: Int) - ReadAhead(size: Int) - Compressed - CompressedOne - Encoding(encoding: EncodingType) - Ram - Sync - Directory -} - -pub type Location { - Bof(Int) - Cur(Int) - Eof(Int) -} - -pub fn open(filename: String, mode: List(Mode)) -> Result(Pid, file.Reason) { - do_open(filename, [Binary, ..mode]) -} - -pub external fn do_open( - filename: String, - mode: List(Mode), -) -> Result(Pid, file.Reason) = - "file" "open" - -pub external fn read(io_device: Pid, bytes: Int) -> read.Result = - "file" "read" - -pub fn close(io_device: Pid) -> Result(Bool, file.Reason) { - case do_close(io_device) { - close.Ok -> Ok(True) - close.Error(reason) -> Error(reason) - } -} - -external fn do_close(io_device: Pid) -> close.Result = - "file" "close" - -pub fn write(io_device: Pid, data: BitString) -> Result(Bool, file.Reason) { - case do_write(io_device, data) { - write.Ok -> Ok(True) - write.Error(reason) -> Error(reason) - } -} - -external fn do_write(io_device: Pid, data: BitString) -> write.Result = - "file" "write" - -pub external fn dirname(filename: String) -> String = - "filename" "dirname" - -pub external fn basename(filename: String) -> String = - "filename" "basename" - -pub external fn join(parts: List(String)) -> String = - "filename" "join" - -pub external fn position( - io_device: Pid, - location: Location, -) -> Result(Int, file.Reason) = - "file" "position" - -pub fn recursive_make_directory(path: String) -> Result(Bool, file.Reason) { - case file.is_directory(path) { - Error(file.Enoent) -> { - let prev_dir = dirname(path) - let assert Ok(True) = recursive_make_directory(prev_dir) - let assert Ok(_) = file.make_directory(path) - Ok(True) - } - Error(file.Eexist) -> Ok(True) - Ok(True) -> Ok(True) - _ -> Error(file.Einval) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam deleted file mode 100644 index 8d98d62ae47..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam +++ /dev/null @@ -1,6 +0,0 @@ -import gleam/erlang/file - -pub type Result { - Ok - Error(reason: file.Reason) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam deleted file mode 100644 index 571e0b0cb92..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam +++ /dev/null @@ -1,7 +0,0 @@ -import gleam/erlang/file - -pub type Result { - Ok(data: BitString) - Eof - Error(reason: file.Reason) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam deleted file mode 100644 index 8d98d62ae47..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam +++ /dev/null @@ -1,6 +0,0 @@ -import gleam/erlang/file - -pub type Result { - Ok - Error(reason: file.Reason) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam deleted file mode 100644 index 81f59437b30..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam +++ /dev/null @@ -1,430 +0,0 @@ -import gleam/erlang/process.{Pid} -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read -import ream/storage/kv/memtable.{CapacityExceeded, MemTable} -import ream/storage/kv/sstable -import ream/storage/kv/value.{Value, ValueFile} -import ream/uuid - -pub type MemTableRange { - MemTableRange(lower: Int, upper: Int, memtable: Option(MemTable)) -} - -pub type KV { - KV( - base_path: String, - name: String, - memtable_ranges: Map(Int, MemTableRange), - active_value_file: Option(Int), - values: Map(Int, ValueFile), - memtables_loaded: Int, - max_memtables_loaded: Int, - max_memtable_size: Int, - max_value_size: Int, - ) -} - -pub type KVInfo { - KVInfo( - base_path: String, - name: String, - values: Int, - values_size_bytes: Int, - memtables_total: Int, - memtables_loaded: Int, - memtables_loaded_size_bytes: Int, - max_memtables_loaded: Int, - max_memtable_size: Int, - max_value_size: Int, - ) -} - -const min_bound = 0 - -const max_bound = 340_282_366_920_938_463_463_374_607_431_768_211_455 - -pub fn open( - path: String, - name: String, - max_memtables_loaded: Int, - max_memtable_size: Int, - max_value_size: Int, -) -> KV { - let path = fs.join([path, "kv", name]) - - let key_index_file = fs.join([path, "key", "index"]) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(key_index_file)) - let assert Ok(kv) = fs.open(key_index_file, [fs.Read, fs.Write]) - let ranges = - read_memtable_ranges( - kv, - fs.join([path, "key"]), - max_memtable_size, - map.new(), - ) - let #(memtables_loaded, ranges) = case map.size(ranges) == 0 { - True -> { - let memtable = memtable.new(max_memtable_size) - let ranges = - [#(new_id(), MemTableRange(min_bound, max_bound, Some(memtable)))] - |> map.from_list() - #(1, ranges) - } - False -> #(0, ranges) - } - let assert Ok(_) = fs.close(kv) - - let value_index_file = fs.join([path, "value", "index"]) - let assert Ok(True) = - fs.recursive_make_directory(fs.dirname(value_index_file)) - let assert Ok(kv) = fs.open(value_index_file, [fs.Read, fs.Write]) - let #(active_value_file, values) = - read_values(kv, fs.join([path, "value"]), None, max_value_size, map.new()) - let assert Ok(_) = fs.close(kv) - - KV( - path, - name, - ranges, - active_value_file, - values, - memtables_loaded, - max_memtables_loaded, - max_memtable_size, - max_value_size, - ) -} - -fn new_id() -> Int { - uuid.to_int(uuid.new()) -} - -fn read_memtable_ranges( - kv: Pid, - path: String, - max_size: Int, - acc: Map(Int, MemTableRange), -) -> Map(Int, MemTableRange) { - case fs.read(kv, 48) { - read.Ok(<<lower:size(128), upper:size(128), id:size(128)>>) -> { - let range = MemTableRange(lower, upper, None) - read_memtable_ranges(kv, path, max_size, map.insert(acc, id, range)) - } - read.Eof -> acc - read.Error(_err) -> { - let assert Ok(_) = fs.close(kv) - // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed - panic - } - } -} - -fn read_values( - kv: Pid, - path: String, - last_file_id: Option(Int), - max_value_size: Int, - acc: Map(Int, ValueFile), -) -> #(Option(Int), Map(Int, ValueFile)) { - case fs.read(kv, 16) { - read.Ok(<<file_id:size(128)>>) -> { - let assert Ok(value_file) = value.open(path, file_id, max_value_size) - read_values( - kv, - path, - Some(file_id), - max_value_size, - map.insert(acc, file_id, value_file), - ) - } - read.Eof -> #(last_file_id, acc) - read.Error(_err) -> { - let assert Ok(_) = fs.close(kv) - // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed - panic - } - } -} - -fn sstable_path(path: String, id: Int) -> String { - let parts = uuid.parts(uuid.from_int(id)) - fs.join([path, "key", ..parts]) -} - -fn find_range(kv: KV, key_hash: Int, max_size: Int) -> #(Int, KV) { - let max_memtables_loaded = kv.max_memtables_loaded - let assert #(#(loaded, Some(range_id)), range_list) = - kv.memtable_ranges - |> map.to_list() - |> list.map_fold( - #(kv.memtables_loaded, None), - fn(acc, entry) { - let #(id, range) = entry - let #(loaded, range_id) = acc - case - key_hash >= range.lower && key_hash <= range.upper, - range.memtable - { - True, Some(_) -> #(#(loaded, Some(id)), #(id, range)) - True, None -> { - let assert Ok(memtable) = - sstable.load(sstable_path(kv.base_path, id), max_size) - #( - #(loaded + 1, Some(id)), - #(id, MemTableRange(..range, memtable: Some(memtable))), - ) - } - False, Some(memtable) if loaded >= max_memtables_loaded -> { - let assert Ok(_) = - sstable.flush(memtable, sstable_path(kv.base_path, id)) - #( - #(loaded - 1, range_id), - #(id, MemTableRange(..range, memtable: None)), - ) - } - False, _ -> #(acc, #(id, range)) - } - }, - ) - - #( - range_id, - KV( - ..kv, - memtable_ranges: map.from_list(range_list), - memtables_loaded: loaded, - ), - ) -} - -pub fn close(kv: KV) -> Result(Nil, Nil) { - let assert Ok(_) = flush(kv) - - map.values(kv.values) - |> list.each(fn(v) { value.close(v) }) - - Ok(Nil) -} - -pub fn flush(kv: KV) -> Result(Nil, Nil) { - let key_index_file = fs.join([kv.base_path, "key", "index"]) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(key_index_file)) - let assert Ok(kv_file) = fs.open(key_index_file, [fs.Write]) - let memtable_ranges = map.to_list(kv.memtable_ranges) - let assert Ok(_) = - write_memtable_ranges(kv_file, kv.base_path, memtable_ranges) - let assert Ok(_) = fs.close(kv_file) - - let value_index_file = fs.join([kv.base_path, "value", "index"]) - let assert Ok(True) = - fs.recursive_make_directory(fs.dirname(value_index_file)) - let assert Ok(kv_file) = fs.open(value_index_file, [fs.Write]) - let assert Ok(_) = write_values(kv_file, map.keys(kv.values)) - let assert Ok(_) = fs.close(kv_file) - - Ok(Nil) -} - -fn write_memtable_ranges( - kv_file: Pid, - base_path: String, - memtable_ranges: List(#(Int, MemTableRange)), -) -> Result(Nil, Nil) { - case memtable_ranges { - [#(id, MemTableRange(lower, upper, Some(memtable))), ..rest] -> { - let assert Ok(True) = sstable.flush(memtable, sstable_path(base_path, id)) - let assert Ok(_) = fs.write(kv_file, <<lower:128, upper:128, id:128>>) - write_memtable_ranges(kv_file, base_path, rest) - } - [#(id, MemTableRange(lower, upper, None)), ..rest] -> { - let assert Ok(_) = fs.write(kv_file, <<lower:128, upper:128, id:128>>) - write_memtable_ranges(kv_file, base_path, rest) - } - [] -> Ok(Nil) - } -} - -fn write_values(kv: Pid, values: List(Int)) -> Result(Nil, Nil) { - case values { - [id, ..rest] -> { - let assert Ok(_) = fs.write(kv, <<id:128>>) - write_values(kv, rest) - } - [] -> Ok(Nil) - } -} - -pub fn get(kv: KV, key: String) -> #(Result(BitString, Nil), KV) { - let key_hash = memtable.hash(key) - let #(range_id, kv) = find_range(kv, key_hash, kv.max_memtable_size) - let assert Ok(range) = map.get(kv.memtable_ranges, range_id) - let assert Some(memtable) = range.memtable - case memtable.get(memtable, key) { - Ok(value) -> { - let assert Ok(vfile) = map.get(kv.values, value.file_id) - case value.read(vfile, value.offset) { - Ok(Value(deleted: False, file_id: _, offset: _, data: Some(data))) -> #( - Ok(data), - kv, - ) - _ -> #(Error(Nil), kv) - } - } - Error(_err) -> #(Error(Nil), kv) - } -} - -pub fn set(kv: KV, key: String, value: BitString) -> KV { - let key_hash = memtable.hash(key) - let #(range_id, kv) = find_range(kv, key_hash, kv.max_memtable_size) - let assert Ok(range) = map.get(kv.memtable_ranges, range_id) - let assert Some(memtable) = range.memtable - let kv = case kv.active_value_file { - Some(_file_id) -> kv - None -> { - let assert Ok(vfile) = - value.create(fs.join([kv.base_path, "value"]), kv.max_value_size) - KV( - ..kv, - active_value_file: Some(vfile.id), - values: map.insert(kv.values, vfile.id, vfile), - ) - } - } - case memtable.get(memtable, key) { - Ok(old_value) -> { - // key is in the index, we have to replace it - case store_value(kv, key, range_id, range, memtable, value) { - Ok(kv) -> kv - Error(CapacityExceeded) -> { - let kv = split(kv, key_hash, range_id, range, memtable) - set(kv, key, value) - } - } - let assert Ok(kv) = delete_value(kv, old_value) - kv - } - Error(Nil) -> { - // key isn't in the index yet, insert it as a new key - case store_value(kv, key, range_id, range, memtable, value) { - Ok(kv) -> kv - Error(CapacityExceeded) -> { - let kv = split(kv, key_hash, range_id, range, memtable) - set(kv, key, value) - } - } - } - } -} - -fn split( - kv: KV, - key_hash: Int, - range_id: Int, - range: MemTableRange, - memtable: MemTable, -) -> KV { - let #(memtable_low, memtable_high, pivot) = memtable.split(memtable, key_hash) - let assert MemTableRange(lower, upper, _) = range - let #(memtable_range_low, memtable_range_high) = case - memtable_low.size >= memtable_high.size - { - False -> #( - MemTableRange(lower, pivot - 1, Some(memtable_low)), - MemTableRange(pivot, upper, None), - ) - True -> #( - MemTableRange(lower, pivot - 1, None), - MemTableRange(pivot, upper, Some(memtable_high)), - ) - } - let memtable_high_id = new_id() - let memtable_ranges = - kv.memtable_ranges - |> map.insert(range_id, memtable_range_low) - |> map.insert(memtable_high_id, memtable_range_high) - - let assert Ok(True) = - sstable.flush(memtable_high, sstable_path(kv.base_path, memtable_high_id)) - - let assert Ok(True) = - sstable.flush(memtable_low, sstable_path(kv.base_path, range_id)) - - KV(..kv, memtable_ranges: memtable_ranges) -} - -fn store_value( - kv: KV, - key: String, - range_id: Int, - range: MemTableRange, - memtable: MemTable, - value_data: BitString, -) -> Result(KV, memtable.Reason) { - let assert Some(file_id) = kv.active_value_file - let assert Ok(vfile) = map.get(kv.values, file_id) - case value.write(vfile, value_data) { - Ok(#(vfile, value)) -> { - use memtable <- try(memtable.set(memtable, key, value)) - let range = MemTableRange(..range, memtable: Some(memtable)) - Ok( - KV( - ..kv, - active_value_file: Some(vfile.id), - values: map.insert(kv.values, vfile.id, vfile), - memtable_ranges: map.insert(kv.memtable_ranges, range_id, range), - ), - ) - } - Error(value.CapacityExceeded) -> { - let assert Ok(vfile) = - value.create(fs.join([kv.base_path, "value"]), kv.max_value_size) - KV( - ..kv, - active_value_file: Some(vfile.id), - values: map.insert(kv.values, vfile.id, vfile), - ) - |> store_value(key, range_id, range, memtable, value_data) - } - } -} - -fn delete_value(kv: KV, value: Value) -> Result(KV, Nil) { - let file_id = value.file_id - let assert Ok(vfile) = map.get(kv.values, file_id) - let assert Ok(vfile) = value.delete(vfile, value) - let values = map.insert(kv.values, file_id, vfile) - Ok(KV(..kv, values: values)) -} - -pub fn info(kv: KV) -> KVInfo { - KVInfo( - base_path: kv.base_path, - name: kv.name, - values: map.size(kv.values), - values_size_bytes: map.fold( - kv.values, - 0, - fn(acc, _key, value_file) { acc + value_file.size }, - ), - memtables_total: map.size(kv.memtable_ranges), - memtables_loaded: kv.memtables_loaded, - memtables_loaded_size_bytes: map.fold( - kv.memtable_ranges, - 0, - fn(acc, _key, memtable_range) { - case memtable_range.memtable { - Some(memtable) -> acc + memtable.size - None -> acc - } - }, - ), - max_memtables_loaded: kv.max_memtables_loaded, - max_memtable_size: kv.max_memtable_size, - max_value_size: kv.max_value_size, - ) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam deleted file mode 100644 index 1b49010d665..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam +++ /dev/null @@ -1,287 +0,0 @@ -//// MemTable is an in-memory data structure that holds the latest written -//// records. It is a sorted list of records sorted by the key hash. When the -//// MemTable reaches its capacity, it is flushed to disk as a Table (Sorted -//// String Table or SSTable). See the sstable module for more details. - -import gleam/bit_string -import gleam/list -import gleam/map.{Map} -import gleam/option.{None} -import ream/storage/kv/value.{Value} - -/// MemTable holds a sorted list of the latest written records. Generally, we -/// could implement a sorted list algorithm like skip list, but for simplicity -/// we use a map instead. -/// -/// MemTables have a max capacity and when that is reached, we flush the MemTable -/// to disk as a Table (Sorted String Table or SSTable). See the sstable module -/// for more details. -/// -/// The MemTable structure is as follows: -/// - `entries`: a map of key hash to MemTableEntry. The key hash is the hash of -/// the key string. -/// - `size`: the total size of the MemTable in bytes. -/// - `max_size`: the maximum size of the MemTable in bytes. -pub type MemTable { - MemTable(entries: Map(Int, MemTableEntry), size: Int, max_size: Int) -} - -/// MemTableEntry is a single entry in the MemTable. -pub type MemTableEntry { - MemTableEntry(key: String, value: Value) -} - -/// Reason is the reason why a MemTable operation failed. -pub type Reason { - /// The MemTable is full and cannot accept more entries. - CapacityExceeded -} - -/// The key hash size is 32-bit integer -pub const key_hash_size_bytes = 4 - -/// The key string size data is 16-bit integer -pub const key_size_bytes = 2 - -/// The file ID size is 128-bit integer corresponding to the UUID -/// of the file in binary format. -pub const file_id_size_bytes = 16 - -/// The file offset size is 32-bit integer. -pub const file_offset_size_bytes = 4 - -/// The payload size for the memtable entry, it is the sum of the -/// key hash size, file ID size, file offset size and key size. -pub const payload_size_bytes = 26 - -pub fn new(max_size: Int) -> MemTable { - MemTable(entries: map.new(), size: 0, max_size: max_size) -} - -/// calculate_entries_size calculates the total size of the entries in the -/// MemTable. It is mainly used when we load the MemTable from disk. -pub fn from_entries(entries: Map(Int, MemTableEntry), max_size: Int) -> MemTable { - let size = calculate_entries_size(entries) - MemTable(entries: entries, size: size, max_size: max_size) -} - -/// entry_to_bitstring converts a MemTableEntry to a bitstring. It is mainly used -/// when we need to convert the MemTableEntry to its binary representation. -pub fn entry_to_bitstring(entry: MemTableEntry) -> BitString { - let key_hash = hash(entry.key) - let key_string = bit_string.from_string(entry.key) - let key_size = bit_string.byte_size(key_string) - let file_id = entry.value.file_id - let file_offset = entry.value.offset - << - key_hash:128, - key_size:16, - file_id:128, - file_offset:32, - key_string:bit_string, - >> -} - -/// bitstring_to_entry converts a bitstring to a MemTableEntry. It is mainly used -/// when we need to convert the binary representation of a MemTableEntry to a -/// MemTableEntry. -pub fn bitstring_to_entry(bitstring: BitString) -> #(Int, MemTableEntry) { - let << - key_hash:128, - _key_size:16, - file_id:128, - file_offset:32, - key_string:bit_string, - >> = bitstring - let assert Ok(key) = bit_string.to_string(key_string) - let value = - Value(data: None, deleted: False, file_id: file_id, offset: file_offset) - #(key_hash, MemTableEntry(key: key, value: value)) -} - -/// contains checks if the MemTable contains the given key. -pub fn contains(mem_table: MemTable, key: String) -> Bool { - map.has_key(mem_table.entries, hash(key)) -} - -/// generates a hash for the given key. -pub external fn hash(key: String) -> Int = - "erlang" "phash2" - -/// set sets the given key to the given value in the MemTable. If the MemTable -/// reaches its capacity, it returns an error. Otherwise, it returns the updated -/// MemTable. -pub fn set( - mem_table: MemTable, - key: String, - value: Value, -) -> Result(MemTable, Reason) { - let key_hash = hash(key) - case map.get(mem_table.entries, key_hash) { - Error(Nil) -> { - let entry = MemTableEntry(key, value) - let entry_size = calculate_size(entry) - let current_size = mem_table.size + entry_size - case current_size > mem_table.max_size { - True -> Error(CapacityExceeded) - False -> - Ok( - MemTable( - ..mem_table, - entries: map.insert(mem_table.entries, key_hash, entry), - size: current_size, - ), - ) - } - } - Ok(old_entry) -> { - let old_entry_size = calculate_size(old_entry) - let entry = MemTableEntry(..old_entry, value: value) - let current_entry_size = calculate_size(entry) - let mem_table_size = mem_table.size + current_entry_size - old_entry_size - case mem_table_size > mem_table.max_size { - True -> Error(CapacityExceeded) - False -> - Ok( - MemTable( - ..mem_table, - entries: map.insert(mem_table.entries, key_hash, entry), - size: mem_table_size, - ), - ) - } - } - } -} - -/// deletes the given key from the MemTable. If the key does not exist, it -/// returns the original MemTable. Otherwise, it returns the updated MemTable. -pub fn delete(mem_table: MemTable, key: String) -> MemTable { - let key_hash = hash(key) - case map.get(mem_table.entries, key_hash) { - Error(Nil) -> mem_table - Ok(entry) -> { - MemTable( - ..mem_table, - entries: map.delete(mem_table.entries, key_hash), - size: mem_table.size - calculate_size(entry), - ) - } - } -} - -/// gets the value of the given key from the MemTable. If the key does not -/// exist, it returns an error. -pub fn get(mem_table: MemTable, key: String) -> Result(Value, Nil) { - case map.get(mem_table.entries, hash(key)) { - Ok(MemTableEntry(key: stored_key, value: value)) if key == stored_key -> - Ok(value) - Ok(MemTableEntry(key: _stored_key, value: _)) -> { - // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed - // let errmsg = - // "collision hash function between " <> key <> " and " <> stored_key - panic - } - Error(Nil) -> Error(Nil) - } -} - -/// search for a pivot in the MemTable. The pivot is the middle key in the -/// MemTable. -pub fn search_pivot(mem_table: MemTable) -> Int { - let entries = mem_table.entries - let keys = map.keys(entries) - let entries_count = map.size(entries) - let #(_, [pivot, ..]) = list.split(keys, at: entries_count / 2) - pivot -} - -/// splits the MemTable into two MemTables. The first MemTable contains -/// MemTableEntries with keys less than the pivot. The second MemTable contains -/// MemTableEntries with keys greater than or equal to the pivot. The pivot is -/// the middle key in the MemTable. -pub fn split(mem_table: MemTable, pivot: Int) -> #(MemTable, MemTable, Int) { - let #(low_entries, high_entries) = - mem_table.entries - |> map.to_list() - |> list.partition(fn(entry) { entry.0 < pivot }) - - let low_entries = map.from_list(low_entries) - - let low = - MemTable( - ..mem_table, - entries: low_entries, - size: calculate_entries_size(low_entries), - ) - - let high_entries = map.from_list(high_entries) - - let high = - MemTable( - ..mem_table, - entries: high_entries, - size: calculate_entries_size(high_entries), - ) - - case low.size >= high.size, map.get(high.entries, pivot) { - True, _ -> #(low, high, pivot) - False, Error(Nil) -> #(low, high, pivot + 1) - False, Ok(entry) -> { - let high = - MemTable( - ..high, - entries: map.delete(high.entries, pivot), - size: high.size - calculate_size(entry), - ) - let low = - MemTable( - ..low, - entries: map.insert(low.entries, pivot, entry), - size: low.size + calculate_size(entry), - ) - #(low, high, pivot + 1) - } - } -} - -fn calculate_entries_size(entries: Map(Int, MemTableEntry)) -> Int { - map.fold(entries, 0, fn(acc, _key, entry) { acc + calculate_size(entry) }) -} - -fn calculate_size(entry: MemTableEntry) -> Int { - bit_string.byte_size(entry_to_bitstring(entry)) -} - -/// get_bounds returns the lower and higher bounds of the MemTable. If the -/// MemTable is empty, it returns `#(0, 0)`. -pub fn get_bounds(mem_table: MemTable) -> #(Int, Int) { - case map.to_list(mem_table.entries) { - [] -> #(0, 0) - [#(k, _), ..entries] -> { - list.fold( - entries, - #(k, k), - fn(acc: #(Int, Int), entry) { - #(get_lower(acc.0, entry.0), get_higher(acc.1, entry.0)) - }, - ) - } - } -} - -fn get_lower(lower_bound: Int, key: Int) -> Int { - case lower_bound { - 0 -> key - lower_bound if key < lower_bound -> key - lower_bound -> lower_bound - } -} - -fn get_higher(higher_bound: Int, key: Int) -> Int { - case higher_bound { - 0 -> key - higher_bound if key > higher_bound -> key - higher_bound -> higher_bound - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam deleted file mode 100644 index ec218baab55..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam +++ /dev/null @@ -1,54 +0,0 @@ -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/map.{Map} -import ream/storage/file as fs -import ream/storage/file/read -import ream/storage/kv/memtable.{MemTable, MemTableEntry} - -const header_size = 38 - -pub fn flush(mem_table: MemTable, path: String) -> Result(Bool, file.Reason) { - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(path)) - let assert Ok(file) = fs.open(path, [fs.Write]) - // TODO maybe suggest the inclusion of `map.each/2` for gleam/stdlib - map.filter( - mem_table.entries, - fn(_key, entry) { - let content = memtable.entry_to_bitstring(entry) - let assert Ok(_) = fs.write(file, content) - False - }, - ) - let assert Ok(_) = fs.close(file) - Ok(True) -} - -pub fn load(path: String, max_size: Int) -> Result(MemTable, file.Reason) { - let assert Ok(file) = fs.open(path, [fs.Read]) - let assert Ok(entries) = read_entries(file, map.new()) - let assert Ok(_) = fs.close(file) - Ok(memtable.from_entries(entries, max_size)) -} - -fn read_entries( - file: Pid, - entries: Map(Int, MemTableEntry), -) -> Result(Map(Int, MemTableEntry), file.Reason) { - case fs.read(file, header_size) { - read.Ok(<<key_hash:128, key_size:16, file_id:128, offset:32>>) -> { - let assert read.Ok(key_string) = fs.read(file, key_size) - let #(_key, entry) = - memtable.bitstring_to_entry(<< - key_hash:128, - key_size:16, - file_id:128, - offset:32, - key_string:bit_string, - >>) - let entries = map.insert(entries, key_hash, entry) - read_entries(file, entries) - } - read.Eof -> Ok(entries) - read.Error(reason) -> Error(reason) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam deleted file mode 100644 index 8711085f8f6..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam +++ /dev/null @@ -1,206 +0,0 @@ -//// Store the information of the values for kv. -//// -//// The events stored in the file are in the following format: -//// - 4 bytes: the size of the event -//// - 1 byte: 0 if the event is not deleted, 1 if it is -//// - n bytes: the event -//// -//// The KV system is split into two parts: the key store and the value store. -//// The file is related to the value store. As we said it's a file with the -//// content marking the size of the value, if it's deleted and the value itself. -//// -//// The file is append only. When a value is written, it's appended to the end -//// of the file. When a value is deleted, it's not deleted from the file, it's -//// marked as deleted. When a value is updated, it's deleted and a new value is -//// appended to the end of the file. - -import gleam/bit_string -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/option.{None, Option, Some} -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read -import ream/uuid - -pub const value_size_bits = 32 - -pub type Reason { - CapacityExceeded -} - -/// The information for a value. The fields are: -/// - `offset`: the offset of the value in the file. -/// - `deleted`: if the value is deleted. -/// - `data`: the value. It can be `None` if we didn't read the value yet. -/// - `file_id`: the id of the file where the value is stored. -pub type Value { - Value(offset: Int, deleted: Bool, data: Option(BitString), file_id: Int) -} - -/// The information for the kv file. The fields are: -/// - `id`: the id of the file. It's intended to be a UUID but it's stored as an Int. -/// - `handler`: the file handler to read and write values. -/// - `size`: the size of the file. -/// - `max_size`: the maximum size of the file. -/// - `file_path`: the path of the file. -pub type ValueFile { - ValueFile(id: Int, handler: Pid, size: Int, max_size: Int, file_path: String) -} - -/// The information for the kv file. The fields are: -/// - `file_id`: the id of the file. It's intended to be a UUID but it's stored as an Int. -/// - `size`: the size of the file. -/// - `entries`: the number of entries in the file. -/// - `deleted`: the number of deleted entries in the file. -pub type ValueFileInfo { - ValueFileInfo( - file_id: Int, - size: Int, - max_size: Int, - entries: Int, - deleted: Int, - ) -} - -/// Create a new kv file. It creates a new file with a random UUID as the -/// path for finding the file. -/// -/// For example, if the UUID is `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, the -/// file will be created in the following path: -/// `base_path/f81d4fae/7dec/11d0/a765/00a0c91e6bf6`. -pub fn create( - base_path: String, - max_size: Int, -) -> Result(ValueFile, file.Reason) { - let file_id = uuid.to_int(uuid.new()) - let file_name = get_file_name(base_path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - use file_pid <- try(fs.open(file_name, [fs.Read, fs.Write])) - Ok(ValueFile(file_id, file_pid, 0, max_size, file_name)) -} - -fn get_file_name(base_path: String, file_id: Int) -> String { - fs.join([base_path, ..uuid.parts(uuid.from_int(file_id))]) -} - -/// Open a kv file. It opens the file with the given file id. -/// If the file doesn't exist, it is creating it. The main difference -/// with `create` is that `open` doesn't generate a new UUID. -/// It returns the kv file with the file handler and the file size. -pub fn open( - path: String, - file_id: Int, - max_size: Int, -) -> Result(ValueFile, file.Reason) { - let file_name = get_file_name(path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - let assert Ok(file_pid) = fs.open(file_name, [fs.Read, fs.Write]) - let assert Ok(file_info) = file.file_info(file_name) - Ok(ValueFile(file_id, file_pid, file_info.size, max_size, file_name)) -} - -/// Close a kv file. It closes the file handler. -pub fn close(vfile: ValueFile) -> Result(Nil, file.Reason) { - let assert Ok(_) = fs.close(vfile.handler) - Ok(Nil) -} - -/// Write a value to the kv file. It writes the value in the following -/// format: -/// - 4 bytes: the size of the value -/// - 1 byte: 0 if the value is not deleted, 1 if it is -/// - n bytes: the value -/// It returns the updated kv file with the new size. -pub fn write_value(vfile: ValueFile, value: Value) -> Result(ValueFile, Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let value_size_bits = value_size_bits - // end FIXME - let value_size_bytes = value_size_bits / 8 - let assert Some(data) = value.data - let data_size = bit_string.byte_size(data) + value_size_bytes + 1 - let deleted = case value.deleted { - True -> 1 - False -> 0 - } - let packed_data = << - data_size:size(value_size_bits), - deleted:8, - data:bit_string, - >> - let assert Ok(offset) = fs.position(vfile.handler, fs.Bof(value.offset)) - case offset + data_size > vfile.max_size { - True -> Error(CapacityExceeded) - False -> { - let assert Ok(_) = fs.write(vfile.handler, packed_data) - case offset + data_size > vfile.size { - True -> Ok(ValueFile(..vfile, size: offset + data_size)) - False -> Ok(vfile) - } - } - } -} - -pub fn write( - vfile: ValueFile, - value: BitString, -) -> Result(#(ValueFile, Value), Reason) { - let value = Value(vfile.size, False, Some(value), vfile.id) - use vfile <- try(write_value(vfile, value)) - Ok(#(vfile, Value(..value, data: None))) -} - -/// Delete a value from the kv file. It marks the value as deleted. -/// It returns the updated kv file with the new size. -pub fn delete(vfile: ValueFile, value: Value) -> Result(ValueFile, Reason) { - use value <- try(read(vfile, value.offset)) - write_value(vfile, Value(..value, deleted: True)) -} - -/// Read a value from the kv file. It reads the value and returns it as -/// a BitString with the following format: -/// - 4 bytes: the size of the value -/// - 1 byte: 0 if the value is not deleted, 1 if it is -/// - n bytes: the value -pub fn read(vfile: ValueFile, offset: Int) -> Result(Value, Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let value_size_bits = value_size_bits - // end FIXME - let value_size_bytes = value_size_bits / 8 - let assert Ok(_) = fs.position(vfile.handler, fs.Bof(offset)) - let assert read.Ok(<<size:size(value_size_bits), deleted:8>>) = - fs.read(vfile.handler, value_size_bytes + 1) - let content_size = size - value_size_bytes - 1 - let assert read.Ok(data) = fs.read(vfile.handler, content_size) - let deleted = case deleted { - 0 -> False - 1 -> True - } - Ok(Value(offset, deleted, Some(data), vfile.id)) -} - -pub fn get_file_info(vfile: ValueFile) -> ValueFileInfo { - let assert Ok(_) = fs.position(vfile.handler, fs.Bof(0)) - let assert Ok(#(entries, deleted)) = - get_entries_and_deleted(vfile.handler, #(0, 0)) - ValueFileInfo(vfile.id, vfile.size, vfile.max_size, entries, deleted) -} - -fn get_entries_and_deleted( - handler: Pid, - acc: #(Int, Int), -) -> Result(#(Int, Int), file.Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let value_size_bits = value_size_bits - // end FIXME - let value_size_bytes = value_size_bits / 8 - case fs.read(handler, value_size_bytes + 1) { - read.Ok(<<size:size(value_size_bits), deleted:8>>) -> { - let payload_size = size - value_size_bytes - 1 - let assert Ok(_) = fs.position(handler, fs.Cur(payload_size)) - get_entries_and_deleted(handler, #(acc.0 + 1, acc.1 + deleted)) - } - read.Eof -> Ok(acc) - read.Error(reason) -> Error(reason) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam deleted file mode 100644 index 7d40439966f..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam +++ /dev/null @@ -1,139 +0,0 @@ -import gleam/bit_string -import gleam/erlang/file -import gleam/iterator -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/stream/event.{Event, EventFile} -import ream/storage/stream/index.{Index, IndexFile} - -pub type Stream { - Stream( - name: String, - index: IndexFile, - active_file: Option(EventFile), - files: Map(Int, EventFile), - base_path: String, - ) -} - -pub fn get_base_path(path: String, name: String) -> String { - fs.join([path, "stream", name]) -} - -pub fn open(name: String, path path: String) -> Result(Stream, file.Reason) { - let base_path = fs.join([path, "stream", name]) - let assert Ok(index_file) = index.open(base_path) - use files <- try(do_open_files(index_file, base_path, map.new())) - let active_file = less_populated_file(map.values(files)) - Ok(Stream(name, index_file, active_file, files, base_path)) -} - -fn less_populated_file(files: List(EventFile)) -> Option(EventFile) { - files - |> list.fold( - with: fn(acc, file) { - let file_size = file.size - case acc { - Some(EventFile(_id, _handler, size, _file_id)) if file_size >= size -> - acc - _ -> Some(file) - } - }, - from: None, - ) -} - -pub fn close(stream: Stream) -> Result(Nil, file.Reason) { - let assert Ok(_) = index.close(stream.index) - - stream.files - |> map.values() - |> list.each(fn(file) { fs.close(file.handler) }) - - Ok(Nil) -} - -fn do_open_files( - index_file: IndexFile, - path: String, - acc: Map(Int, EventFile), -) -> Result(Map(Int, EventFile), file.Reason) { - case index.count(index_file) { - 0 -> Ok(acc) - num_of_events -> { - let _ = index.set_pos(index_file, 0) - - let files = - num_of_events - 1 - |> iterator.range(0, _) - |> iterator.fold( - from: acc, - with: fn(acc, _idx) { - let assert Ok(Index(_offset, _size, file_id)) = - index.get_next(index_file) - case map.has_key(acc, file_id) { - True -> acc - False -> { - let assert Ok(file) = event.open(path, file_id) - map.insert(acc, file_id, file) - } - } - }, - ) - - Ok(files) - } - } -} - -pub fn add_event( - stream: Stream, - event_content: BitString, -) -> Result(Stream, file.Reason) { - let event_size = bit_string.byte_size(event_content) - let #(stream, index) = case index.count(stream.index) { - 0 -> { - let assert Ok(stream_file) = event.create(stream.base_path) - let #(index, index_file) = - index.add(stream.index, event_size, stream_file.id) - let stream = - Stream( - ..stream, - index: index_file, - active_file: Some(stream_file), - files: map.insert(stream.files, stream_file.id, stream_file), - ) - #(stream, index) - } - _ -> { - let assert Some(active_file) = stream.active_file - let #(index, index_file) = - index.add(stream.index, event_size, active_file.id) - let stream = Stream(..stream, index: index_file) - #(stream, index) - } - } - - let assert Ok(file) = map.get(stream.files, index.file_id) - let event = Event(index.offset, event_content) - let stream_file = event.write(file, event) - - let files = map.insert(stream.files, stream_file.id, stream_file) - Ok(Stream(..stream, files: files)) -} - -pub fn get_event(stream: Stream, index: Int) -> Result(BitString, file.Reason) { - case index.count(stream.index) > index { - True -> { - let assert Ok(Index(offset, _size, file_id)) = - index.get(stream.index, index) - let assert Ok(file) = map.get(stream.files, file_id) - let assert Ok(Event(_offset, data)) = event.read(file, offset) - Ok(data) - } - False -> Error(file.Einval) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam deleted file mode 100644 index 14ab0e946dc..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam +++ /dev/null @@ -1,95 +0,0 @@ -//// Store the information of the event that is being streamed. It is used to -//// write and read events from the file. -//// -//// The events stored in the file are in the following format: -//// - 4 bytes: the size of the event -//// - n bytes: the event - -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/bit_string -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read -import ream/storage/stream/index -import ream/uuid - -pub type Event { - Event(offset: Int, data: BitString) -} - -/// The information for the stream file. The fields are: -/// - `id`: the id of the file. It's intended to be a UUID but it's stored as an Int. -/// - `handler`: the file handler to read and write events. -/// - `size`: the size of the file. -/// - `file_path`: the path of the file. -pub type EventFile { - EventFile(id: Int, handler: Pid, size: Int, file_path: String) -} - -/// Create a new stream file. It creates a new file with a random UUID as the -/// path for finding the file. -/// -/// For example, if the UUID is `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, the -/// file will be created in the following path: -/// `base_path/f81d4fae/7dec/11d0/a765/00a0c91e6bf6`. -pub fn create(base_path: String) -> Result(EventFile, file.Reason) { - let <<file_id:128>> = uuid.new() - let file_name = get_file_name(base_path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - use file_pid <- try(fs.open(file_name, [fs.Read, fs.Append])) - Ok(EventFile(file_id, file_pid, 0, file_name)) -} - -fn get_file_name(base_path: String, file_id: Int) -> String { - fs.join([base_path, ..uuid.parts(<<file_id:128>>)]) -} - -/// Open a stream file. It opens the file with the given file id. -/// If the file doesn't exist, it is creating it. The main difference -/// with `create` is that `open` doesn't generate a new UUID. -/// It returns the stream file with the file handler and the file size. -pub fn open(path: String, file_id: Int) -> Result(EventFile, file.Reason) { - let file_name = get_file_name(path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - let assert Ok(file_pid) = fs.open(file_name, [fs.Read, fs.Append]) - let assert Ok(file_info) = file.file_info(file_name) - Ok(EventFile(file_id, file_pid, file_info.size, file_name)) -} - -/// Close a stream file. It closes the file handler. -pub fn close(stream_file: EventFile) -> Result(Nil, file.Reason) { - let assert Ok(_) = fs.close(stream_file.handler) - Ok(Nil) -} - -/// Write an event to the stream file. It writes the event in the following -/// format: -/// - 4 bytes: the size of the event -/// - n bytes: the event -/// It returns the updated stream file with the new size. -pub fn write(stream_file: EventFile, event: Event) -> EventFile { - let event_size_bits = index.event_size_bits - let event_size_bytes = event_size_bits / 8 - let data_size = bit_string.byte_size(event.data) + event_size_bytes - let data = <<data_size:size(event_size_bits), event.data:bit_string>> - let assert Ok(_) = fs.position(stream_file.handler, fs.Bof(event.offset)) - let assert Ok(_) = fs.write(stream_file.handler, data) - let data_size = bit_string.byte_size(data) - EventFile(..stream_file, size: stream_file.size + data_size) -} - -/// Read an event from the stream file. It reads the event and returns it as -/// a BitString with the following format: -/// - 4 bytes: the size of the event -/// - n bytes: the event -pub fn read(stream_file: EventFile, offset: Int) -> Result(Event, file.Reason) { - let event_size_bits = index.event_size_bits - let event_size_bytes = event_size_bits / 8 - let assert Ok(_) = fs.position(stream_file.handler, fs.Bof(offset)) - let assert read.Ok(<<size:size(event_size_bits)>>) = - fs.read(stream_file.handler, event_size_bytes) - let content_size = size - event_size_bytes - let assert read.Ok(data) = fs.read(stream_file.handler, content_size) - Ok(Event(offset, data)) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam deleted file mode 100644 index 83f5104c935..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam +++ /dev/null @@ -1,153 +0,0 @@ -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/int -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read - -/// the size of the offset in bytes, it's 6 bytes or 48 bits -/// letting us store offsets of 2^48 bytes (256TB) of data -pub const offset_size_bits = 48 - -/// event size (in bits) is storing letting us store events -/// of 2^24 bits (16MB) of data -pub const event_size_bits = 24 - -/// the size of the file id in bytes, it's 16 bytes or 128 bits -/// representing a 128 bit integer (UUID) -pub const file_id_size_bits = 128 - -/// the size of the index entry in bytes, it's 25 bytes because -/// we're storing the offset (6 bytes), the event size (3 bytes) -/// and the file id (16 bytes). -pub const index_size_bytes = 25 - -pub type Index { - Index(offset: Int, size: Int, file_id: Int) -} - -pub type IndexFile { - IndexFile(handler: Pid, size: Int, file_path: String) -} - -pub fn open(path: String) -> Result(IndexFile, file.Reason) { - let assert Ok(True) = fs.recursive_make_directory(path) - let index = fs.join([path, "index"]) - use index_pid <- try(fs.open(index, [fs.Read, fs.Append])) - use index_info <- try(file.file_info(index)) - Ok(IndexFile(index_pid, index_info.size, index)) -} - -pub fn close(index_file: IndexFile) -> Result(Nil, file.Reason) { - let assert Ok(_) = fs.close(index_file.handler) - Ok(Nil) -} - -pub fn add( - index_file: IndexFile, - event_size: Int, - file_id: Int, -) -> #(Index, IndexFile) { - let event_size_bytes = event_size_bits / 8 - let #(index_content, index) = case index_file.size { - 0 -> { - let index = Index(0, event_size + event_size_bytes, file_id) - #(index_binary(index), index) - } - _ -> { - let assert Ok(_) = - fs.position(index_file.handler, fs.Eof(-index_size_bytes)) - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - let assert Ok(<< - offset:size(offset_size_bits), - prev_size:size(event_size_bits), - _file_id:size(file_id_size_bits), - >>) = last_entry_for_file(index_file.handler, file_id) - let offset = offset + prev_size - let index = Index(offset, event_size + event_size_bytes, file_id) - #(index_binary(index), index) - } - } - let assert Ok(_) = fs.write(index_file.handler, index_content) - let index_file = - IndexFile(..index_file, size: index_file.size + index_size_bytes) - #(index, index_file) -} - -fn index_binary(index: Index) -> BitString { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - << - index.offset:size(offset_size_bits), - index.size:size(event_size_bits), - index.file_id:size(file_id_size_bits), - >> -} - -fn last_entry_for_file( - index_file: Pid, - file_id: Int, -) -> Result(BitString, file.Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - let assert read.Ok(<< - offset:size(offset_size_bits), - size:size(event_size_bits), - new_file_id:size(file_id_size_bits), - >>) = fs.read(index_file, index_size_bytes) - case new_file_id == file_id { - True -> Ok(index_binary(Index(offset, size, file_id))) - False -> { - case fs.position(index_file, fs.Cur(-2 * index_size_bytes)) { - Ok(_) -> last_entry_for_file(index_file, file_id) - Error(file.Einval) -> Ok(index_binary(Index(0, 0, file_id))) - } - } - } -} - -pub fn count(index_file: IndexFile) -> Int { - let assert Ok(result) = int.divide(index_file.size, index_size_bytes) - result -} - -pub fn set_pos(index_file: IndexFile, index: Int) -> Result(Int, file.Reason) { - fs.position(index_file.handler, fs.Bof(index * index_size_bytes)) -} - -pub fn get_next(index_file: IndexFile) -> Result(Index, file.Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - case fs.read(index_file.handler, index_size_bytes) { - read.Ok(<< - offset:size(offset_size_bits), - size:size(event_size_bits), - file_id:size(file_id_size_bits), - >>) -> Ok(Index(offset, size, file_id)) - read.Eof -> Error(file.Espipe) - _ -> Error(file.Einval) - } -} - -pub fn get(index_file: IndexFile, index: Int) -> Result(Index, file.Reason) { - case count(index_file) > index { - True -> { - let assert Ok(_) = set_pos(index_file, index) - get_next(index_file) - } - False -> Error(file.Einval) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam deleted file mode 100644 index 03a489db8b2..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam +++ /dev/null @@ -1,48 +0,0 @@ -//// This module implements the UUID v4 generation algorithm. - -import gleam/int -import gleam/string - -pub fn new() -> BitString { - let <<u0:size(48), _:size(4), u1:size(12), _:size(2), u2:size(62)>> = - crypto_strong_rand_bytes(16) - - <<u0:size(48), 4:size(4), u1:size(12), 2:size(2), u2:size(62)>> -} - -pub fn to_string(uuid: BitString) -> String { - parts(uuid) - |> string.join(with: "-") -} - -pub fn to_int(uuid: BitString) -> Int { - let <<uuid_int:128>> = uuid - uuid_int -} - -pub fn from_int(uuid: Int) -> BitString { - <<uuid:128>> -} - -pub fn from_string(uuid: String) -> BitString { - let assert Ok(uuid_int) = - uuid - |> string.replace(each: "-", with: "") - |> int.base_parse(16) - - from_int(uuid_int) -} - -pub fn parts(uuid: BitString) -> List(String) { - let <<p1:32, p2:16, p3:16, p4:16, p5:48>> = uuid - [to_hex(p1, 8), to_hex(p2, 4), to_hex(p3, 4), to_hex(p4, 4), to_hex(p5, 12)] -} - -fn to_hex(n: Int, size: Int) -> String { - int.to_base16(n) - |> string.lowercase() - |> string.pad_left(to: size, with: "0") -} - -external fn crypto_strong_rand_bytes(Int) -> BitString = - "crypto" "strong_rand_bytes" diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl deleted file mode 100644 index 9120a478ea0..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl +++ /dev/null @@ -1,123 +0,0 @@ --module(ream@storage@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([do_open/2, open/2, read/2, close/1, write/2, dirname/1, basename/1, join/1, position/2, recursive_make_directory/1]). --export_type([endian/0, encoding_type/0, mode/0, location/0]). - --type endian() :: big | little. - --type encoding_type() :: unicode | - utf8 | - {utf16, endian()} | - {utf32, endian()} | - latin1. - --type mode() :: read | - write | - append | - exclusive | - raw | - binary | - {delayed_write, integer(), integer()} | - {read_ahead, integer()} | - compressed | - compressed_one | - {encoding, encoding_type()} | - ram | - sync | - directory. - --type location() :: {bof, integer()} | {cur, integer()} | {eof, integer()}. - --spec do_open(binary(), list(mode())) -> {ok, gleam@erlang@process:pid_()} | - {error, gleam@erlang@file:reason()}. -do_open(Field@0, Field@1) -> - file:open(Field@0, Field@1). - --spec open(binary(), list(mode())) -> {ok, gleam@erlang@process:pid_()} | - {error, gleam@erlang@file:reason()}. -open(Filename, Mode) -> - file:open(Filename, [binary | Mode]). - --spec read(gleam@erlang@process:pid_(), integer()) -> ream@storage@file@read:result(). -read(Field@0, Field@1) -> - file:read(Field@0, Field@1). - --spec close(gleam@erlang@process:pid_()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -close(Io_device) -> - case file:close(Io_device) of - ok -> - {ok, true}; - - {error, Reason} -> - {error, Reason} - end. - --spec write(gleam@erlang@process:pid_(), bitstring()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -write(Io_device, Data) -> - case file:write(Io_device, Data) of - ok -> - {ok, true}; - - {error, Reason} -> - {error, Reason} - end. - --spec dirname(binary()) -> binary(). -dirname(Field@0) -> - filename:dirname(Field@0). - --spec basename(binary()) -> binary(). -basename(Field@0) -> - filename:basename(Field@0). - --spec join(list(binary())) -> binary(). -join(Field@0) -> - filename:join(Field@0). - --spec position(gleam@erlang@process:pid_(), location()) -> {ok, integer()} | - {error, gleam@erlang@file:reason()}. -position(Field@0, Field@1) -> - file:position(Field@0, Field@1). - --spec recursive_make_directory(binary()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -recursive_make_directory(Path) -> - case gleam@erlang@file:is_directory(Path) of - {error, enoent} -> - Prev_dir = filename:dirname(Path), - _assert_subject = recursive_make_directory(Prev_dir), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/file"/utf8>>, - function => <<"recursive_make_directory"/utf8>>, - line => 95}) - end, - _assert_subject@1 = gleam_erlang_ffi:make_directory(Path), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/file"/utf8>>, - function => <<"recursive_make_directory"/utf8>>, - line => 96}) - end, - {ok, true}; - - {error, eexist} -> - {ok, true}; - - {ok, true} -> - {ok, true}; - - _ -> - {error, einval} - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl deleted file mode 100644 index 3cd71df7c31..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(ream@storage@file@close). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([result/0]). - --type result() :: ok | {error, gleam@erlang@file:reason()}. - - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl deleted file mode 100644 index ab021bd22bd..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(ream@storage@file@read). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([result/0]). - --type result() :: {ok, bitstring()} | eof | {error, gleam@erlang@file:reason()}. - - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl deleted file mode 100644 index 7bdc59d9767..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(ream@storage@file@write). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([result/0]). - --type result() :: ok | {error, gleam@erlang@file:reason()}. - - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl deleted file mode 100644 index 00b8caa6701..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl +++ /dev/null @@ -1,901 +0,0 @@ --module(ream@storage@kv). --compile([no_auto_import, nowarn_unused_vars]). - --export([get/2, info/1, open/5, flush/1, close/1, set/3]). --export_type([mem_table_range/0, kv/0, kv_info/0]). - --type mem_table_range() :: {mem_table_range, - integer(), - integer(), - gleam@option:option(ream@storage@kv@memtable:mem_table())}. - --type kv() :: {kv, - binary(), - binary(), - gleam@map:map_(integer(), mem_table_range()), - gleam@option:option(integer()), - gleam@map:map_(integer(), ream@storage@kv@value:value_file()), - integer(), - integer(), - integer(), - integer()}. - --type kv_info() :: {kv_info, - binary(), - binary(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec new_id() -> integer(). -new_id() -> - ream@uuid:to_int(ream@uuid:new()). - --spec sstable_path(binary(), integer()) -> binary(). -sstable_path(Path, Id) -> - Parts = ream@uuid:parts(ream@uuid:from_int(Id)), - filename:join([Path, <<"key"/utf8>> | Parts]). - --spec find_range(kv(), integer(), integer()) -> {integer(), kv()}. -find_range(Kv, Key_hash, Max_size) -> - Max_memtables_loaded = erlang:element(8, Kv), - _assert_subject@2 = begin - _pipe = erlang:element(4, Kv), - _pipe@1 = gleam@map:to_list(_pipe), - gleam@list:map_fold( - _pipe@1, - {erlang:element(7, Kv), none}, - fun(Acc, Entry) -> - {Id, Range} = Entry, - {Loaded, Range_id} = Acc, - case {(Key_hash >= erlang:element(2, Range)) andalso (Key_hash - =< erlang:element(3, Range)), - erlang:element(4, Range)} of - {true, {some, _}} -> - {{Loaded, {some, Id}}, {Id, Range}}; - - {true, none} -> - _assert_subject = ream@storage@kv@sstable:load( - sstable_path(erlang:element(2, Kv), Id), - Max_size - ), - {ok, Memtable} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"find_range"/utf8>>, - line => 174}) - end, - {{Loaded + 1, {some, Id}}, - {Id, erlang:setelement(4, Range, {some, Memtable})}}; - - {false, {some, Memtable@1}} when Loaded >= Max_memtables_loaded -> - _assert_subject@1 = ream@storage@kv@sstable:flush( - Memtable@1, - sstable_path(erlang:element(2, Kv), Id) - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"find_range"/utf8>>, - line => 182}) - end, - {{Loaded - 1, Range_id}, - {Id, erlang:setelement(4, Range, none)}}; - - {false, _} -> - {Acc, {Id, Range}} - end - end - ) - end, - {{Loaded@1, {some, Range_id@1}}, Range_list} = case _assert_subject@2 of - {{_, {some, _}}, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"find_range"/utf8>>, - line => 160}) - end, - {Range_id@1, - erlang:setelement( - 7, - erlang:setelement(4, Kv, gleam@map:from_list(Range_list)), - Loaded@1 - )}. - --spec get(kv(), binary()) -> {{ok, bitstring()} | {error, nil}, kv()}. -get(Kv, Key) -> - Key_hash = erlang:phash2(Key), - {Range_id, Kv@1} = find_range(Kv, Key_hash, erlang:element(9, Kv)), - _assert_subject = gleam@map:get(erlang:element(4, Kv@1), Range_id), - {ok, Range} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"get"/utf8>>, - line => 264}) - end, - _assert_subject@1 = erlang:element(4, Range), - {some, Memtable} = case _assert_subject@1 of - {some, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"get"/utf8>>, - line => 265}) - end, - case ream@storage@kv@memtable:get(Memtable, Key) of - {ok, Value} -> - _assert_subject@2 = gleam@map:get( - erlang:element(6, Kv@1), - erlang:element(5, Value) - ), - {ok, Vfile} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"get"/utf8>>, - line => 268}) - end, - case ream@storage@kv@value:read(Vfile, erlang:element(2, Value)) of - {ok, {value, _, false, {some, Data}, _}} -> - {{ok, Data}, Kv@1}; - - _ -> - {{error, nil}, Kv@1} - end; - - {error, _} -> - {{error, nil}, Kv@1} - end. - --spec split( - kv(), - integer(), - integer(), - mem_table_range(), - ream@storage@kv@memtable:mem_table() -) -> kv(). -split(Kv, Key_hash, Range_id, Range, Memtable) -> - {Memtable_low, Memtable_high, Pivot} = ream@storage@kv@memtable:split( - Memtable, - Key_hash - ), - {mem_table_range, Lower, Upper, _} = case Range of - {mem_table_range, _, _, _} -> Range; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"split"/utf8>>, - line => 332}) - end, - {Memtable_range_low, Memtable_range_high} = case erlang:element( - 3, - Memtable_low - ) - >= erlang:element(3, Memtable_high) of - false -> - {{mem_table_range, Lower, Pivot - 1, {some, Memtable_low}}, - {mem_table_range, Pivot, Upper, none}}; - - true -> - {{mem_table_range, Lower, Pivot - 1, none}, - {mem_table_range, Pivot, Upper, {some, Memtable_high}}} - end, - Memtable_high_id = new_id(), - Memtable_ranges = begin - _pipe = erlang:element(4, Kv), - _pipe@1 = gleam@map:insert(_pipe, Range_id, Memtable_range_low), - gleam@map:insert(_pipe@1, Memtable_high_id, Memtable_range_high) - end, - _assert_subject = ream@storage@kv@sstable:flush( - Memtable_high, - sstable_path(erlang:element(2, Kv), Memtable_high_id) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"split"/utf8>>, - line => 351}) - end, - _assert_subject@1 = ream@storage@kv@sstable:flush( - Memtable_low, - sstable_path(erlang:element(2, Kv), Range_id) - ), - {ok, true} = case _assert_subject@1 of - {ok, true} -> _assert_subject@1; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"split"/utf8>>, - line => 354}) - end, - erlang:setelement(4, Kv, Memtable_ranges). - --spec delete_value(kv(), ream@storage@kv@value:value()) -> {ok, kv()} | - {error, nil}. -delete_value(Kv, Value) -> - File_id = erlang:element(5, Value), - _assert_subject = gleam@map:get(erlang:element(6, Kv), File_id), - {ok, Vfile} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"delete_value"/utf8>>, - line => 398}) - end, - _assert_subject@1 = ream@storage@kv@value:delete(Vfile, Value), - {ok, Vfile@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"delete_value"/utf8>>, - line => 399}) - end, - Values = gleam@map:insert(erlang:element(6, Kv), File_id, Vfile@1), - {ok, erlang:setelement(6, Kv, Values)}. - --spec info(kv()) -> kv_info(). -info(Kv) -> - {kv_info, - erlang:element(2, Kv), - erlang:element(3, Kv), - gleam@map:size(erlang:element(6, Kv)), - gleam@map:fold( - erlang:element(6, Kv), - 0, - fun(Acc, _, Value_file) -> Acc + erlang:element(4, Value_file) end - ), - gleam@map:size(erlang:element(4, Kv)), - erlang:element(7, Kv), - gleam@map:fold( - erlang:element(4, Kv), - 0, - fun(Acc@1, _, Memtable_range) -> - case erlang:element(4, Memtable_range) of - {some, Memtable} -> - Acc@1 + erlang:element(3, Memtable); - - none -> - Acc@1 - end - end - ), - erlang:element(8, Kv), - erlang:element(9, Kv), - erlang:element(10, Kv)}. - --spec read_memtable_ranges( - gleam@erlang@process:pid_(), - binary(), - integer(), - gleam@map:map_(integer(), mem_table_range()) -) -> gleam@map:map_(integer(), mem_table_range()). -read_memtable_ranges(Kv, Path, Max_size, Acc) -> - case file:read(Kv, 48) of - {ok, <<Lower:128, Upper:128, Id:128>>} -> - Range = {mem_table_range, Lower, Upper, none}, - read_memtable_ranges( - Kv, - Path, - Max_size, - gleam@map:insert(Acc, Id, Range) - ); - - eof -> - Acc; - - {error, _} -> - _assert_subject = ream@storage@file:close(Kv), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_memtable_ranges"/utf8>>, - line => 119}) - end, - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_memtable_ranges"/utf8>>, - line => 121}) - end. - --spec read_values( - gleam@erlang@process:pid_(), - binary(), - gleam@option:option(integer()), - integer(), - gleam@map:map_(integer(), ream@storage@kv@value:value_file()) -) -> {gleam@option:option(integer()), - gleam@map:map_(integer(), ream@storage@kv@value:value_file())}. -read_values(Kv, Path, Last_file_id, Max_value_size, Acc) -> - case file:read(Kv, 16) of - {ok, <<File_id:128>>} -> - _assert_subject = ream@storage@kv@value:open( - Path, - File_id, - Max_value_size - ), - {ok, Value_file} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_values"/utf8>>, - line => 135}) - end, - read_values( - Kv, - Path, - {some, File_id}, - Max_value_size, - gleam@map:insert(Acc, File_id, Value_file) - ); - - eof -> - {Last_file_id, Acc}; - - {error, _} -> - _assert_subject@1 = ream@storage@file:close(Kv), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_values"/utf8>>, - line => 146}) - end, - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_values"/utf8>>, - line => 148}) - end. - --spec open(binary(), binary(), integer(), integer(), integer()) -> kv(). -open(Path, Name, Max_memtables_loaded, Max_memtable_size, Max_value_size) -> - Path@1 = filename:join([Path, <<"kv"/utf8>>, Name]), - Key_index_file = filename:join([Path@1, <<"key"/utf8>>, <<"index"/utf8>>]), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(Key_index_file) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 60}) - end, - _assert_subject@1 = ream@storage@file:open(Key_index_file, [read, write]), - {ok, Kv} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 61}) - end, - Ranges = read_memtable_ranges( - Kv, - filename:join([Path@1, <<"key"/utf8>>]), - Max_memtable_size, - gleam@map:new() - ), - {Memtables_loaded, Ranges@2} = case gleam@map:size(Ranges) =:= 0 of - true -> - Memtable = ream@storage@kv@memtable:new(Max_memtable_size), - Ranges@1 = begin - _pipe = [{new_id(), - {mem_table_range, - 0, - 340282366920938463463374607431768211455, - {some, Memtable}}}], - gleam@map:from_list(_pipe) - end, - {1, Ranges@1}; - - false -> - {0, Ranges} - end, - _assert_subject@2 = ream@storage@file:close(Kv), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 79}) - end, - Value_index_file = filename:join( - [Path@1, <<"value"/utf8>>, <<"index"/utf8>>] - ), - _assert_subject@3 = ream@storage@file:recursive_make_directory( - filename:dirname(Value_index_file) - ), - {ok, true} = case _assert_subject@3 of - {ok, true} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 82}) - end, - _assert_subject@4 = ream@storage@file:open(Value_index_file, [read, write]), - {ok, Kv@1} = case _assert_subject@4 of - {ok, _} -> _assert_subject@4; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 84}) - end, - {Active_value_file, Values} = read_values( - Kv@1, - filename:join([Path@1, <<"value"/utf8>>]), - none, - Max_value_size, - gleam@map:new() - ), - _assert_subject@5 = ream@storage@file:close(Kv@1), - {ok, _} = case _assert_subject@5 of - {ok, _} -> _assert_subject@5; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 87}) - end, - {kv, - Path@1, - Name, - Ranges@2, - Active_value_file, - Values, - Memtables_loaded, - Max_memtables_loaded, - Max_memtable_size, - Max_value_size}. - --spec write_memtable_ranges( - gleam@erlang@process:pid_(), - binary(), - list({integer(), mem_table_range()}) -) -> {ok, nil} | {error, nil}. -write_memtable_ranges(Kv_file, Base_path, Memtable_ranges) -> - case Memtable_ranges of - [{Id, {mem_table_range, Lower, Upper, {some, Memtable}}} | Rest] -> - _assert_subject = ream@storage@kv@sstable:flush( - Memtable, - sstable_path(Base_path, Id) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_memtable_ranges"/utf8>>, - line => 239}) - end, - _assert_subject@1 = ream@storage@file:write( - Kv_file, - <<Lower:128, Upper:128, Id:128>> - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_memtable_ranges"/utf8>>, - line => 240}) - end, - write_memtable_ranges(Kv_file, Base_path, Rest); - - [{Id@1, {mem_table_range, Lower@1, Upper@1, none}} | Rest@1] -> - _assert_subject@2 = ream@storage@file:write( - Kv_file, - <<Lower@1:128, Upper@1:128, Id@1:128>> - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_memtable_ranges"/utf8>>, - line => 244}) - end, - write_memtable_ranges(Kv_file, Base_path, Rest@1); - - [] -> - {ok, nil} - end. - --spec write_values(gleam@erlang@process:pid_(), list(integer())) -> {ok, nil} | - {error, nil}. -write_values(Kv, Values) -> - case Values of - [Id | Rest] -> - _assert_subject = ream@storage@file:write(Kv, <<Id:128>>), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_values"/utf8>>, - line => 254}) - end, - write_values(Kv, Rest); - - [] -> - {ok, nil} - end. - --spec flush(kv()) -> {ok, nil} | {error, nil}. -flush(Kv) -> - Key_index_file = filename:join( - [erlang:element(2, Kv), <<"key"/utf8>>, <<"index"/utf8>>] - ), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(Key_index_file) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 215}) - end, - _assert_subject@1 = ream@storage@file:open(Key_index_file, [write]), - {ok, Kv_file} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 216}) - end, - Memtable_ranges = gleam@map:to_list(erlang:element(4, Kv)), - _assert_subject@2 = write_memtable_ranges( - Kv_file, - erlang:element(2, Kv), - Memtable_ranges - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 218}) - end, - _assert_subject@3 = ream@storage@file:close(Kv_file), - {ok, _} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 220}) - end, - Value_index_file = filename:join( - [erlang:element(2, Kv), <<"value"/utf8>>, <<"index"/utf8>>] - ), - _assert_subject@4 = ream@storage@file:recursive_make_directory( - filename:dirname(Value_index_file) - ), - {ok, true} = case _assert_subject@4 of - {ok, true} -> _assert_subject@4; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 223}) - end, - _assert_subject@5 = ream@storage@file:open(Value_index_file, [write]), - {ok, Kv_file@1} = case _assert_subject@5 of - {ok, _} -> _assert_subject@5; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 225}) - end, - _assert_subject@6 = write_values( - Kv_file@1, - gleam@map:keys(erlang:element(6, Kv)) - ), - {ok, _} = case _assert_subject@6 of - {ok, _} -> _assert_subject@6; - _assert_fail@6 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@6, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 226}) - end, - _assert_subject@7 = ream@storage@file:close(Kv_file@1), - {ok, _} = case _assert_subject@7 of - {ok, _} -> _assert_subject@7; - _assert_fail@7 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@7, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 227}) - end, - {ok, nil}. - --spec close(kv()) -> {ok, nil} | {error, nil}. -close(Kv) -> - _assert_subject = flush(Kv), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"close"/utf8>>, - line => 205}) - end, - _pipe = gleam@map:values(erlang:element(6, Kv)), - gleam@list:each(_pipe, fun(V) -> ream@storage@kv@value:close(V) end), - {ok, nil}. - --spec set(kv(), binary(), bitstring()) -> kv(). -set(Kv, Key, Value) -> - Key_hash = erlang:phash2(Key), - {Range_id, Kv@1} = find_range(Kv, Key_hash, erlang:element(9, Kv)), - _assert_subject = gleam@map:get(erlang:element(4, Kv@1), Range_id), - {ok, Range} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 284}) - end, - _assert_subject@1 = erlang:element(4, Range), - {some, Memtable} = case _assert_subject@1 of - {some, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 285}) - end, - Kv@2 = case erlang:element(5, Kv@1) of - {some, _} -> - Kv@1; - - none -> - _assert_subject@2 = ream@storage@kv@value:create( - filename:join([erlang:element(2, Kv@1), <<"value"/utf8>>]), - erlang:element(10, Kv@1) - ), - {ok, Vfile} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 289}) - end, - erlang:setelement( - 6, - erlang:setelement(5, Kv@1, {some, erlang:element(2, Vfile)}), - gleam@map:insert( - erlang:element(6, Kv@1), - erlang:element(2, Vfile), - Vfile - ) - ) - end, - case ream@storage@kv@memtable:get(Memtable, Key) of - {ok, Old_value} -> - case store_value(Kv@2, Key, Range_id, Range, Memtable, Value) of - {ok, Kv@3} -> - Kv@3; - - {error, capacity_exceeded} -> - Kv@4 = split(Kv@2, Key_hash, Range_id, Range, Memtable), - set(Kv@4, Key, Value) - end, - _assert_subject@3 = delete_value(Kv@2, Old_value), - {ok, Kv@5} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 308}) - end, - Kv@5; - - {error, nil} -> - case store_value(Kv@2, Key, Range_id, Range, Memtable, Value) of - {ok, Kv@6} -> - Kv@6; - - {error, capacity_exceeded} -> - Kv@7 = split(Kv@2, Key_hash, Range_id, Range, Memtable), - set(Kv@7, Key, Value) - end - end. - --spec store_value( - kv(), - binary(), - integer(), - mem_table_range(), - ream@storage@kv@memtable:mem_table(), - bitstring() -) -> {ok, kv()} | {error, ream@storage@kv@memtable:reason()}. -store_value(Kv, Key, Range_id, Range, Memtable, Value_data) -> - _assert_subject = erlang:element(5, Kv), - {some, File_id} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"store_value"/utf8>>, - line => 368}) - end, - _assert_subject@1 = gleam@map:get(erlang:element(6, Kv), File_id), - {ok, Vfile} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"store_value"/utf8>>, - line => 369}) - end, - case ream@storage@kv@value:write(Vfile, Value_data) of - {ok, {Vfile@1, Value}} -> - gleam@result:'try'( - ream@storage@kv@memtable:set(Memtable, Key, Value), - fun(Memtable@1) -> - Range@1 = erlang:setelement(4, Range, {some, Memtable@1}), - {ok, - erlang:setelement( - 4, - erlang:setelement( - 6, - erlang:setelement( - 5, - Kv, - {some, erlang:element(2, Vfile@1)} - ), - gleam@map:insert( - erlang:element(6, Kv), - erlang:element(2, Vfile@1), - Vfile@1 - ) - ), - gleam@map:insert( - erlang:element(4, Kv), - Range_id, - Range@1 - ) - )} - end - ); - - {error, capacity_exceeded} -> - _assert_subject@2 = ream@storage@kv@value:create( - filename:join([erlang:element(2, Kv), <<"value"/utf8>>]), - erlang:element(10, Kv) - ), - {ok, Vfile@2} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"store_value"/utf8>>, - line => 384}) - end, - _pipe = erlang:setelement( - 6, - erlang:setelement(5, Kv, {some, erlang:element(2, Vfile@2)}), - gleam@map:insert( - erlang:element(6, Kv), - erlang:element(2, Vfile@2), - Vfile@2 - ) - ), - store_value(_pipe, Key, Range_id, Range, Memtable, Value_data) - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl deleted file mode 100644 index dd2140c0085..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl +++ /dev/null @@ -1,277 +0,0 @@ --module(ream@storage@kv@memtable). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, bitstring_to_entry/1, search_pivot/1, get_bounds/1, hash/1, entry_to_bitstring/1, contains/2, get/2, set/3, delete/2, from_entries/2, split/2]). --export_type([mem_table/0, mem_table_entry/0, reason/0]). - --type mem_table() :: {mem_table, - gleam@map:map_(integer(), mem_table_entry()), - integer(), - integer()}. - --type mem_table_entry() :: {mem_table_entry, - binary(), - ream@storage@kv@value:value()}. - --type reason() :: capacity_exceeded. - --spec new(integer()) -> mem_table(). -new(Max_size) -> - {mem_table, gleam@map:new(), 0, Max_size}. - --spec bitstring_to_entry(bitstring()) -> {integer(), mem_table_entry()}. -bitstring_to_entry(Bitstring) -> - <<Key_hash:128, _:16, File_id:128, File_offset:32, Key_string/bitstring>> = Bitstring, - _assert_subject = gleam@bit_string:to_string(Key_string), - {ok, Key} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/memtable"/utf8>>, - function => <<"bitstring_to_entry"/utf8>>, - line => 96}) - end, - Value = {value, File_offset, false, none, File_id}, - {Key_hash, {mem_table_entry, Key, Value}}. - --spec search_pivot(mem_table()) -> integer(). -search_pivot(Mem_table) -> - Entries = erlang:element(2, Mem_table), - Keys = gleam@map:keys(Entries), - Entries_count = gleam@map:size(Entries), - {_, [Pivot | _]} = gleam@list:split(Keys, Entries_count div 2), - Pivot. - --spec get_lower(integer(), integer()) -> integer(). -get_lower(Lower_bound, Key) -> - case Lower_bound of - 0 -> - Key; - - Lower_bound@1 when Key < Lower_bound@1 -> - Key; - - Lower_bound@2 -> - Lower_bound@2 - end. - --spec get_higher(integer(), integer()) -> integer(). -get_higher(Higher_bound, Key) -> - case Higher_bound of - 0 -> - Key; - - Higher_bound@1 when Key > Higher_bound@1 -> - Key; - - Higher_bound@2 -> - Higher_bound@2 - end. - --spec get_bounds(mem_table()) -> {integer(), integer()}. -get_bounds(Mem_table) -> - case gleam@map:to_list(erlang:element(2, Mem_table)) of - [] -> - {0, 0}; - - [{K, _} | Entries] -> - gleam@list:fold( - Entries, - {K, K}, - fun(Acc, Entry) -> - {get_lower(erlang:element(1, Acc), erlang:element(1, Entry)), - get_higher( - erlang:element(2, Acc), - erlang:element(1, Entry) - )} - end - ) - end. - --spec hash(binary()) -> integer(). -hash(Field@0) -> - erlang:phash2(Field@0). - --spec entry_to_bitstring(mem_table_entry()) -> bitstring(). -entry_to_bitstring(Entry) -> - Key_hash = erlang:phash2(erlang:element(2, Entry)), - Key_string = gleam@bit_string:from_string(erlang:element(2, Entry)), - Key_size = gleam@bit_string:byte_size(Key_string), - File_id = erlang:element(5, erlang:element(3, Entry)), - File_offset = erlang:element(2, erlang:element(3, Entry)), - <<Key_hash:128, - Key_size:16, - File_id:128, - File_offset:32, - Key_string/bitstring>>. - --spec contains(mem_table(), binary()) -> boolean(). -contains(Mem_table, Key) -> - gleam@map:has_key(erlang:element(2, Mem_table), erlang:phash2(Key)). - --spec get(mem_table(), binary()) -> {ok, ream@storage@kv@value:value()} | - {error, nil}. -get(Mem_table, Key) -> - case gleam@map:get(erlang:element(2, Mem_table), erlang:phash2(Key)) of - {ok, {mem_table_entry, Stored_key, Value}} when Key =:= Stored_key -> - {ok, Value}; - - {ok, {mem_table_entry, _, _}} -> - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"ream/storage/kv/memtable"/utf8>>, - function => <<"get"/utf8>>, - line => 183}); - - {error, nil} -> - {error, nil} - end. - --spec calculate_size(mem_table_entry()) -> integer(). -calculate_size(Entry) -> - gleam@bit_string:byte_size(entry_to_bitstring(Entry)). - --spec set(mem_table(), binary(), ream@storage@kv@value:value()) -> {ok, - mem_table()} | - {error, reason()}. -set(Mem_table, Key, Value) -> - Key_hash = erlang:phash2(Key), - case gleam@map:get(erlang:element(2, Mem_table), Key_hash) of - {error, nil} -> - Entry = {mem_table_entry, Key, Value}, - Entry_size = calculate_size(Entry), - Current_size = erlang:element(3, Mem_table) + Entry_size, - case Current_size > erlang:element(4, Mem_table) of - true -> - {error, capacity_exceeded}; - - false -> - {ok, - erlang:setelement( - 3, - erlang:setelement( - 2, - Mem_table, - gleam@map:insert( - erlang:element(2, Mem_table), - Key_hash, - Entry - ) - ), - Current_size - )} - end; - - {ok, Old_entry} -> - Old_entry_size = calculate_size(Old_entry), - Entry@1 = erlang:setelement(3, Old_entry, Value), - Current_entry_size = calculate_size(Entry@1), - Mem_table_size = (erlang:element(3, Mem_table) + Current_entry_size) - - Old_entry_size, - case Mem_table_size > erlang:element(4, Mem_table) of - true -> - {error, capacity_exceeded}; - - false -> - {ok, - erlang:setelement( - 3, - erlang:setelement( - 2, - Mem_table, - gleam@map:insert( - erlang:element(2, Mem_table), - Key_hash, - Entry@1 - ) - ), - Mem_table_size - )} - end - end. - --spec delete(mem_table(), binary()) -> mem_table(). -delete(Mem_table, Key) -> - Key_hash = erlang:phash2(Key), - case gleam@map:get(erlang:element(2, Mem_table), Key_hash) of - {error, nil} -> - Mem_table; - - {ok, Entry} -> - erlang:setelement( - 3, - erlang:setelement( - 2, - Mem_table, - gleam@map:delete(erlang:element(2, Mem_table), Key_hash) - ), - erlang:element(3, Mem_table) - calculate_size(Entry) - ) - end. - --spec calculate_entries_size(gleam@map:map_(integer(), mem_table_entry())) -> integer(). -calculate_entries_size(Entries) -> - gleam@map:fold( - Entries, - 0, - fun(Acc, _, Entry) -> Acc + calculate_size(Entry) end - ). - --spec from_entries(gleam@map:map_(integer(), mem_table_entry()), integer()) -> mem_table(). -from_entries(Entries, Max_size) -> - Size = calculate_entries_size(Entries), - {mem_table, Entries, Size, Max_size}. - --spec split(mem_table(), integer()) -> {mem_table(), mem_table(), integer()}. -split(Mem_table, Pivot) -> - {Low_entries, High_entries} = begin - _pipe = erlang:element(2, Mem_table), - _pipe@1 = gleam@map:to_list(_pipe), - gleam@list:partition( - _pipe@1, - fun(Entry) -> erlang:element(1, Entry) < Pivot end - ) - end, - Low_entries@1 = gleam@map:from_list(Low_entries), - Low = erlang:setelement( - 3, - erlang:setelement(2, Mem_table, Low_entries@1), - calculate_entries_size(Low_entries@1) - ), - High_entries@1 = gleam@map:from_list(High_entries), - High = erlang:setelement( - 3, - erlang:setelement(2, Mem_table, High_entries@1), - calculate_entries_size(High_entries@1) - ), - case {erlang:element(3, Low) >= erlang:element(3, High), - gleam@map:get(erlang:element(2, High), Pivot)} of - {true, _} -> - {Low, High, Pivot}; - - {false, {error, nil}} -> - {Low, High, Pivot + 1}; - - {false, {ok, Entry@1}} -> - High@1 = erlang:setelement( - 3, - erlang:setelement( - 2, - High, - gleam@map:delete(erlang:element(2, High), Pivot) - ), - erlang:element(3, High) - calculate_size(Entry@1) - ), - Low@1 = erlang:setelement( - 3, - erlang:setelement( - 2, - Low, - gleam@map:insert(erlang:element(2, Low), Pivot, Entry@1) - ), - erlang:element(3, Low) + calculate_size(Entry@1) - ), - {Low@1, High@1, Pivot + 1} - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl deleted file mode 100644 index c8800712fc5..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl +++ /dev/null @@ -1,136 +0,0 @@ --module(ream@storage@kv@sstable). --compile([no_auto_import, nowarn_unused_vars]). - --export([flush/2, load/2]). - --spec flush(ream@storage@kv@memtable:mem_table(), binary()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -flush(Mem_table, Path) -> - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(Path) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 11}) - end, - _assert_subject@1 = ream@storage@file:open(Path, [write]), - {ok, File} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 12}) - end, - gleam@map:filter( - erlang:element(2, Mem_table), - fun(_, Entry) -> - Content = ream@storage@kv@memtable:entry_to_bitstring(Entry), - _assert_subject@2 = ream@storage@file:write(File, Content), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 18}) - end, - false - end - ), - _assert_subject@3 = ream@storage@file:close(File), - {ok, _} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 22}) - end, - {ok, true}. - --spec read_entries( - gleam@erlang@process:pid_(), - gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry()) -) -> {ok, gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry())} | - {error, gleam@erlang@file:reason()}. -read_entries(File, Entries) -> - case file:read(File, 38) of - {ok, <<Key_hash:128, Key_size:16, File_id:128, Offset:32>>} -> - _assert_subject = file:read(File, Key_size), - {ok, Key_string} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"read_entries"/utf8>>, - line => 39}) - end, - {_, Entry} = ream@storage@kv@memtable:bitstring_to_entry( - <<Key_hash:128, - Key_size:16, - File_id:128, - Offset:32, - Key_string/bitstring>> - ), - Entries@1 = gleam@map:insert(Entries, Key_hash, Entry), - read_entries(File, Entries@1); - - eof -> - {ok, Entries}; - - {error, Reason} -> - {error, Reason} - end. - --spec load(binary(), integer()) -> {ok, ream@storage@kv@memtable:mem_table()} | - {error, gleam@erlang@file:reason()}. -load(Path, Max_size) -> - _assert_subject = ream@storage@file:open(Path, [read]), - {ok, File} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"load"/utf8>>, - line => 27}) - end, - _assert_subject@1 = read_entries(File, gleam@map:new()), - {ok, Entries} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"load"/utf8>>, - line => 28}) - end, - _assert_subject@2 = ream@storage@file:close(File), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"load"/utf8>>, - line => 29}) - end, - {ok, ream@storage@kv@memtable:from_entries(Entries, Max_size)}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl deleted file mode 100644 index 5d11a993bde..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl +++ /dev/null @@ -1,326 +0,0 @@ --module(ream@storage@kv@value). --compile([no_auto_import, nowarn_unused_vars]). - --export([create/2, open/3, close/1, write_value/2, write/2, read/2, delete/2, get_file_info/1]). --export_type([reason/0, value/0, value_file/0, value_file_info/0]). - --type reason() :: capacity_exceeded. - --type value() :: {value, - integer(), - boolean(), - gleam@option:option(bitstring()), - integer()}. - --type value_file() :: {value_file, - integer(), - gleam@erlang@process:pid_(), - integer(), - integer(), - binary()}. - --type value_file_info() :: {value_file_info, - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec get_file_name(binary(), integer()) -> binary(). -get_file_name(Base_path, File_id) -> - filename:join([Base_path | ream@uuid:parts(ream@uuid:from_int(File_id))]). - --spec create(binary(), integer()) -> {ok, value_file()} | - {error, gleam@erlang@file:reason()}. -create(Base_path, Max_size) -> - File_id = ream@uuid:to_int(ream@uuid:new()), - File_name = get_file_name(Base_path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"create"/utf8>>, - line => 78}) - end, - gleam@result:'try'( - ream@storage@file:open(File_name, [read, write]), - fun(File_pid) -> - {ok, {value_file, File_id, File_pid, 0, Max_size, File_name}} - end - ). - --spec open(binary(), integer(), integer()) -> {ok, value_file()} | - {error, gleam@erlang@file:reason()}. -open(Path, File_id, Max_size) -> - File_name = get_file_name(Path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"open"/utf8>>, - line => 97}) - end, - _assert_subject@1 = ream@storage@file:open(File_name, [read, write]), - {ok, File_pid} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"open"/utf8>>, - line => 98}) - end, - _assert_subject@2 = gleam_erlang_ffi:file_info(File_name), - {ok, File_info} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"open"/utf8>>, - line => 99}) - end, - {ok, - {value_file, - File_id, - File_pid, - erlang:element(2, File_info), - Max_size, - File_name}}. - --spec close(value_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Vfile) -> - _assert_subject = ream@storage@file:close(erlang:element(3, Vfile)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"close"/utf8>>, - line => 105}) - end, - {ok, nil}. - --spec write_value(value_file(), value()) -> {ok, value_file()} | - {error, reason()}. -write_value(Vfile, Value) -> - Value_size_bits = 32, - Value_size_bytes = Value_size_bits div 8, - _assert_subject = erlang:element(4, Value), - {some, Data} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"write_value"/utf8>>, - line => 120}) - end, - Data_size = (gleam@bit_string:byte_size(Data) + Value_size_bytes) + 1, - Deleted = case erlang:element(3, Value) of - true -> - 1; - - false -> - 0 - end, - Packed_data = <<Data_size:(lists:max([(Value_size_bits), 0])), - Deleted:8, - Data/bitstring>>, - _assert_subject@1 = file:position( - erlang:element(3, Vfile), - {bof, erlang:element(2, Value)} - ), - {ok, Offset} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"write_value"/utf8>>, - line => 131}) - end, - case (Offset + Data_size) > erlang:element(5, Vfile) of - true -> - {error, capacity_exceeded}; - - false -> - _assert_subject@2 = ream@storage@file:write( - erlang:element(3, Vfile), - Packed_data - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"write_value"/utf8>>, - line => 135}) - end, - case (Offset + Data_size) > erlang:element(4, Vfile) of - true -> - {ok, erlang:setelement(4, Vfile, Offset + Data_size)}; - - false -> - {ok, Vfile} - end - end. - --spec write(value_file(), bitstring()) -> {ok, {value_file(), value()}} | - {error, reason()}. -write(Vfile, Value) -> - Value@1 = {value, - erlang:element(4, Vfile), - false, - {some, Value}, - erlang:element(2, Vfile)}, - gleam@result:'try'( - write_value(Vfile, Value@1), - fun(Vfile@1) -> {ok, {Vfile@1, erlang:setelement(4, Value@1, none)}} end - ). - --spec read(value_file(), integer()) -> {ok, value()} | {error, reason()}. -read(Vfile, Offset) -> - Value_size_bits = 32, - Value_size_bytes = Value_size_bits div 8, - _assert_subject = file:position(erlang:element(3, Vfile), {bof, Offset}), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"read"/utf8>>, - line => 170}) - end, - _assert_subject@1 = file:read( - erlang:element(3, Vfile), - Value_size_bytes + 1 - ), - {ok, <<Size:Value_size_bits, Deleted:8>>} = case _assert_subject@1 of - {ok, <<_:Value_size_bits, _:8>>} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"read"/utf8>>, - line => 171}) - end, - Content_size = (Size - Value_size_bytes) - 1, - _assert_subject@2 = file:read(erlang:element(3, Vfile), Content_size), - {ok, Data} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"read"/utf8>>, - line => 174}) - end, - Deleted@1 = case Deleted of - 0 -> - false; - - 1 -> - true - end, - {ok, {value, Offset, Deleted@1, {some, Data}, erlang:element(2, Vfile)}}. - --spec delete(value_file(), value()) -> {ok, value_file()} | {error, reason()}. -delete(Vfile, Value) -> - gleam@result:'try'( - read(Vfile, erlang:element(2, Value)), - fun(Value@1) -> - write_value(Vfile, erlang:setelement(3, Value@1, true)) - end - ). - --spec get_entries_and_deleted( - gleam@erlang@process:pid_(), - {integer(), integer()} -) -> {ok, {integer(), integer()}} | {error, gleam@erlang@file:reason()}. -get_entries_and_deleted(Handler, Acc) -> - Value_size_bits = 32, - Value_size_bytes = Value_size_bits div 8, - case file:read(Handler, Value_size_bytes + 1) of - {ok, <<Size:Value_size_bits, Deleted:8>>} -> - Payload_size = (Size - Value_size_bytes) - 1, - _assert_subject = file:position(Handler, {cur, Payload_size}), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"get_entries_and_deleted"/utf8>>, - line => 200}) - end, - get_entries_and_deleted( - Handler, - {erlang:element(1, Acc) + 1, erlang:element(2, Acc) + Deleted} - ); - - eof -> - {ok, Acc}; - - {error, Reason} -> - {error, Reason} - end. - --spec get_file_info(value_file()) -> value_file_info(). -get_file_info(Vfile) -> - _assert_subject = file:position(erlang:element(3, Vfile), {bof, 0}), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"get_file_info"/utf8>>, - line => 183}) - end, - _assert_subject@1 = get_entries_and_deleted( - erlang:element(3, Vfile), - {0, 0} - ), - {ok, {Entries, Deleted}} = case _assert_subject@1 of - {ok, {_, _}} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"get_file_info"/utf8>>, - line => 184}) - end, - {value_file_info, - erlang:element(2, Vfile), - erlang:element(4, Vfile), - erlang:element(5, Vfile), - Entries, - Deleted}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl deleted file mode 100644 index fd978abe885..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl +++ /dev/null @@ -1,272 +0,0 @@ --module(ream@storage@stream). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_base_path/2, close/1, open/2, add_event/2, get_event/2]). --export_type([stream/0]). - --type stream() :: {stream, - binary(), - ream@storage@stream@index:index_file(), - gleam@option:option(ream@storage@stream@event:event_file()), - gleam@map:map_(integer(), ream@storage@stream@event:event_file()), - binary()}. - --spec get_base_path(binary(), binary()) -> binary(). -get_base_path(Path, Name) -> - filename:join([Path, <<"stream"/utf8>>, Name]). - --spec less_populated_file(list(ream@storage@stream@event:event_file())) -> gleam@option:option(ream@storage@stream@event:event_file()). -less_populated_file(Files) -> - _pipe = Files, - gleam@list:fold( - _pipe, - none, - fun(Acc, File) -> - File_size = erlang:element(4, File), - case Acc of - {some, {event_file, _, _, Size, _}} when File_size >= Size -> - Acc; - - _ -> - {some, File} - end - end - ). - --spec close(stream()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Stream) -> - _assert_subject = ream@storage@stream@index:close(erlang:element(3, Stream)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"close"/utf8>>, - line => 50}) - end, - _pipe = erlang:element(5, Stream), - _pipe@1 = gleam@map:values(_pipe), - gleam@list:each( - _pipe@1, - fun(File) -> ream@storage@file:close(erlang:element(3, File)) end - ), - {ok, nil}. - --spec do_open_files( - ream@storage@stream@index:index_file(), - binary(), - gleam@map:map_(integer(), ream@storage@stream@event:event_file()) -) -> {ok, gleam@map:map_(integer(), ream@storage@stream@event:event_file())} | - {error, gleam@erlang@file:reason()}. -do_open_files(Index_file, Path, Acc) -> - case ream@storage@stream@index:count(Index_file) of - 0 -> - {ok, Acc}; - - Num_of_events -> - _ = ream@storage@stream@index:set_pos(Index_file, 0), - Files = begin - _pipe = Num_of_events - 1, - _pipe@1 = gleam@iterator:range(0, _pipe), - gleam@iterator:fold( - _pipe@1, - Acc, - fun(Acc@1, _) -> - _assert_subject = ream@storage@stream@index:get_next( - Index_file - ), - {ok, {index, _, _, File_id}} = case _assert_subject of - {ok, {index, _, _, _}} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"do_open_files"/utf8>>, - line => 75}) - end, - case gleam@map:has_key(Acc@1, File_id) of - true -> - Acc@1; - - false -> - _assert_subject@1 = ream@storage@stream@event:open( - Path, - File_id - ), - {ok, File} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream"/utf8>>, - function => <<"do_open_files"/utf8>>, - line => 80}) - end, - gleam@map:insert(Acc@1, File_id, File) - end - end - ) - end, - {ok, Files} - end. - --spec open(binary(), binary()) -> {ok, stream()} | - {error, gleam@erlang@file:reason()}. -open(Name, Path) -> - Base_path = filename:join([Path, <<"stream"/utf8>>, Name]), - _assert_subject = ream@storage@stream@index:open(Base_path), - {ok, Index_file} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"open"/utf8>>, - line => 28}) - end, - gleam@result:'try'( - do_open_files(Index_file, Base_path, gleam@map:new()), - fun(Files) -> - Active_file = less_populated_file(gleam@map:values(Files)), - {ok, {stream, Name, Index_file, Active_file, Files, Base_path}} - end - ). - --spec add_event(stream(), bitstring()) -> {ok, stream()} | - {error, gleam@erlang@file:reason()}. -add_event(Stream, Event_content) -> - Event_size = gleam@bit_string:byte_size(Event_content), - {Stream@3, Index@2} = case ream@storage@stream@index:count( - erlang:element(3, Stream) - ) of - 0 -> - _assert_subject = ream@storage@stream@event:create( - erlang:element(6, Stream) - ), - {ok, Stream_file} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"add_event"/utf8>>, - line => 99}) - end, - {Index, Index_file} = ream@storage@stream@index:add( - erlang:element(3, Stream), - Event_size, - erlang:element(2, Stream_file) - ), - Stream@1 = erlang:setelement( - 5, - erlang:setelement( - 4, - erlang:setelement(3, Stream, Index_file), - {some, Stream_file} - ), - gleam@map:insert( - erlang:element(5, Stream), - erlang:element(2, Stream_file), - Stream_file - ) - ), - {Stream@1, Index}; - - _ -> - _assert_subject@1 = erlang:element(4, Stream), - {some, Active_file} = case _assert_subject@1 of - {some, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream"/utf8>>, - function => <<"add_event"/utf8>>, - line => 112}) - end, - {Index@1, Index_file@1} = ream@storage@stream@index:add( - erlang:element(3, Stream), - Event_size, - erlang:element(2, Active_file) - ), - Stream@2 = erlang:setelement(3, Stream, Index_file@1), - {Stream@2, Index@1} - end, - _assert_subject@2 = gleam@map:get( - erlang:element(5, Stream@3), - erlang:element(4, Index@2) - ), - {ok, File} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream"/utf8>>, - function => <<"add_event"/utf8>>, - line => 120}) - end, - Event = {event, erlang:element(2, Index@2), Event_content}, - Stream_file@1 = ream@storage@stream@event:write(File, Event), - Files = gleam@map:insert( - erlang:element(5, Stream@3), - erlang:element(2, Stream_file@1), - Stream_file@1 - ), - {ok, erlang:setelement(5, Stream@3, Files)}. - --spec get_event(stream(), integer()) -> {ok, bitstring()} | - {error, gleam@erlang@file:reason()}. -get_event(Stream, Index) -> - case ream@storage@stream@index:count(erlang:element(3, Stream)) > Index of - true -> - _assert_subject = ream@storage@stream@index:get( - erlang:element(3, Stream), - Index - ), - {ok, {index, Offset, _, File_id}} = case _assert_subject of - {ok, {index, _, _, _}} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"get_event"/utf8>>, - line => 131}) - end, - _assert_subject@1 = gleam@map:get( - erlang:element(5, Stream), - File_id - ), - {ok, File} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream"/utf8>>, - function => <<"get_event"/utf8>>, - line => 133}) - end, - _assert_subject@2 = ream@storage@stream@event:read(File, Offset), - {ok, {event, _, Data}} = case _assert_subject@2 of - {ok, {event, _, _}} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream"/utf8>>, - function => <<"get_event"/utf8>>, - line => 134}) - end, - {ok, Data}; - - false -> - {error, einval} - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl deleted file mode 100644 index f52e4f21270..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl +++ /dev/null @@ -1,186 +0,0 @@ --module(ream@storage@stream@event). --compile([no_auto_import, nowarn_unused_vars]). - --export([create/1, open/2, close/1, write/2, read/2]). --export_type([event/0, event_file/0]). - --type event() :: {event, integer(), bitstring()}. - --type event_file() :: {event_file, - integer(), - gleam@erlang@process:pid_(), - integer(), - binary()}. - --spec get_file_name(binary(), integer()) -> binary(). -get_file_name(Base_path, File_id) -> - filename:join([Base_path | ream@uuid:parts(<<File_id:128>>)]). - --spec create(binary()) -> {ok, event_file()} | - {error, gleam@erlang@file:reason()}. -create(Base_path) -> - <<File_id:128>> = ream@uuid:new(), - File_name = get_file_name(Base_path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"create"/utf8>>, - line => 39}) - end, - gleam@result:'try'( - ream@storage@file:open(File_name, [read, append]), - fun(File_pid) -> {ok, {event_file, File_id, File_pid, 0, File_name}} end - ). - --spec open(binary(), integer()) -> {ok, event_file()} | - {error, gleam@erlang@file:reason()}. -open(Path, File_id) -> - File_name = get_file_name(Path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"open"/utf8>>, - line => 54}) - end, - _assert_subject@1 = ream@storage@file:open(File_name, [read, append]), - {ok, File_pid} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"open"/utf8>>, - line => 55}) - end, - _assert_subject@2 = gleam_erlang_ffi:file_info(File_name), - {ok, File_info} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"open"/utf8>>, - line => 56}) - end, - {ok, - {event_file, File_id, File_pid, erlang:element(2, File_info), File_name}}. - --spec close(event_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Stream_file) -> - _assert_subject = ream@storage@file:close(erlang:element(3, Stream_file)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"close"/utf8>>, - line => 62}) - end, - {ok, nil}. - --spec write(event_file(), event()) -> event_file(). -write(Stream_file, Event) -> - Event_size_bits = 24, - Event_size_bytes = Event_size_bits div 8, - Data_size = gleam@bit_string:byte_size(erlang:element(3, Event)) + Event_size_bytes, - Data = <<Data_size:(lists:max([(Event_size_bits), 0])), - (erlang:element(3, Event))/bitstring>>, - _assert_subject = file:position( - erlang:element(3, Stream_file), - {bof, erlang:element(2, Event)} - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"write"/utf8>>, - line => 76}) - end, - _assert_subject@1 = ream@storage@file:write( - erlang:element(3, Stream_file), - Data - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"write"/utf8>>, - line => 77}) - end, - Data_size@1 = gleam@bit_string:byte_size(Data), - erlang:setelement( - 4, - Stream_file, - erlang:element(4, Stream_file) + Data_size@1 - ). - --spec read(event_file(), integer()) -> {ok, event()} | - {error, gleam@erlang@file:reason()}. -read(Stream_file, Offset) -> - Event_size_bits = 24, - Event_size_bytes = Event_size_bits div 8, - _assert_subject = file:position( - erlang:element(3, Stream_file), - {bof, Offset} - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"read"/utf8>>, - line => 89}) - end, - _assert_subject@1 = file:read( - erlang:element(3, Stream_file), - Event_size_bytes - ), - {ok, <<Size:Event_size_bits>>} = case _assert_subject@1 of - {ok, <<_:Event_size_bits>>} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"read"/utf8>>, - line => 90}) - end, - Content_size = Size - Event_size_bytes, - _assert_subject@2 = file:read(erlang:element(3, Stream_file), Content_size), - {ok, Data} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"read"/utf8>>, - line => 93}) - end, - {ok, {event, Offset, Data}}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl deleted file mode 100644 index 1580dada363..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl +++ /dev/null @@ -1,234 +0,0 @@ --module(ream@storage@stream@index). --compile([no_auto_import, nowarn_unused_vars]). - --export([open/1, close/1, count/1, set_pos/2, get_next/1, get/2, add/3]). --export_type([index/0, index_file/0]). - --type index() :: {index, integer(), integer(), integer()}. - --type index_file() :: {index_file, - gleam@erlang@process:pid_(), - integer(), - binary()}. - --spec open(binary()) -> {ok, index_file()} | {error, gleam@erlang@file:reason()}. -open(Path) -> - _assert_subject = ream@storage@file:recursive_make_directory(Path), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"open"/utf8>>, - line => 34}) - end, - Index = filename:join([Path, <<"index"/utf8>>]), - gleam@result:'try'( - ream@storage@file:open(Index, [read, append]), - fun(Index_pid) -> - gleam@result:'try'( - gleam_erlang_ffi:file_info(Index), - fun(Index_info) -> - {ok, - {index_file, - Index_pid, - erlang:element(2, Index_info), - Index}} - end - ) - end - ). - --spec close(index_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Index_file) -> - _assert_subject = ream@storage@file:close(erlang:element(2, Index_file)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"close"/utf8>>, - line => 42}) - end, - {ok, nil}. - --spec index_binary(index()) -> bitstring(). -index_binary(Index) -> - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - <<(erlang:element(2, Index)):(lists:max([(Offset_size_bits), 0])), - (erlang:element(3, Index)):(lists:max([(Event_size_bits), 0])), - (erlang:element(4, Index)):(lists:max([(File_id_size_bits), 0]))>>. - --spec count(index_file()) -> integer(). -count(Index_file) -> - _assert_subject = gleam@int:divide(erlang:element(3, Index_file), 25), - {ok, Result} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"count"/utf8>>, - line => 120}) - end, - Result. - --spec set_pos(index_file(), integer()) -> {ok, integer()} | - {error, gleam@erlang@file:reason()}. -set_pos(Index_file, Index) -> - file:position(erlang:element(2, Index_file), {bof, Index * 25}). - --spec get_next(index_file()) -> {ok, index()} | - {error, gleam@erlang@file:reason()}. -get_next(Index_file) -> - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - case file:read(erlang:element(2, Index_file), 25) of - {ok, - <<Offset:Offset_size_bits, - Size:Event_size_bits, - File_id:File_id_size_bits>>} -> - {ok, {index, Offset, Size, File_id}}; - - eof -> - {error, espipe}; - - _ -> - {error, einval} - end. - --spec get(index_file(), integer()) -> {ok, index()} | - {error, gleam@erlang@file:reason()}. -get(Index_file, Index) -> - case count(Index_file) > Index of - true -> - _assert_subject = set_pos(Index_file, Index), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"get"/utf8>>, - line => 148}) - end, - get_next(Index_file); - - false -> - {error, einval} - end. - --spec last_entry_for_file(gleam@erlang@process:pid_(), integer()) -> {ok, - bitstring()} | - {error, gleam@erlang@file:reason()}. -last_entry_for_file(Index_file, File_id) -> - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - _assert_subject = file:read(Index_file, 25), - {ok, - <<Offset:Offset_size_bits, - Size:Event_size_bits, - New_file_id:File_id_size_bits>>} = case _assert_subject of - {ok, <<_:Offset_size_bits, _:Event_size_bits, _:File_id_size_bits>>} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"last_entry_for_file"/utf8>>, - line => 103}) - end, - case New_file_id =:= File_id of - true -> - {ok, index_binary({index, Offset, Size, File_id})}; - - false -> - case file:position(Index_file, {cur, -2 * 25}) of - {ok, _} -> - last_entry_for_file(Index_file, File_id); - - {error, einval} -> - {ok, index_binary({index, 0, 0, File_id})} - end - end. - --spec add(index_file(), integer(), integer()) -> {index(), index_file()}. -add(Index_file, Event_size, File_id) -> - Event_size_bytes = 24 div 8, - {Index_content, Index@2} = case erlang:element(3, Index_file) of - 0 -> - Index = {index, 0, Event_size + Event_size_bytes, File_id}, - {index_binary(Index), Index}; - - _ -> - _assert_subject = file:position( - erlang:element(2, Index_file), - {eof, - 25} - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"add"/utf8>>, - line => 58}) - end, - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - _assert_subject@1 = last_entry_for_file( - erlang:element(2, Index_file), - File_id - ), - {ok, - <<Offset:Offset_size_bits, - Prev_size:Event_size_bits, - _:File_id_size_bits>>} = case _assert_subject@1 of - {ok, - <<_:Offset_size_bits, - _:Event_size_bits, - _:File_id_size_bits>>} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"add"/utf8>>, - line => 65}) - end, - Offset@1 = Offset + Prev_size, - Index@1 = {index, Offset@1, Event_size + Event_size_bytes, File_id}, - {index_binary(Index@1), Index@1} - end, - _assert_subject@2 = ream@storage@file:write( - erlang:element(2, Index_file), - Index_content - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"add"/utf8>>, - line => 75}) - end, - Index_file@1 = erlang:setelement( - 3, - Index_file, - erlang:element(3, Index_file) + 25 - ), - {Index@2, Index_file@1}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl b/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl deleted file mode 100644 index 67ad2a2773d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(ream@uuid). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_int/1, from_int/1, from_string/1, parts/1, to_string/1, new/0]). - --spec to_int(bitstring()) -> integer(). -to_int(Uuid) -> - <<Uuid_int:128>> = Uuid, - Uuid_int. - --spec from_int(integer()) -> bitstring(). -from_int(Uuid) -> - <<Uuid:128>>. - --spec from_string(binary()) -> bitstring(). -from_string(Uuid) -> - _assert_subject = begin - _pipe = Uuid, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<""/utf8>>), - gleam@int:base_parse(_pipe@1, 16) - end, - {ok, Uuid_int} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/uuid"/utf8>>, - function => <<"from_string"/utf8>>, - line => 28}) - end, - from_int(Uuid_int). - --spec to_hex(integer(), integer()) -> binary(). -to_hex(N, Size) -> - _pipe = gleam@int:to_base16(N), - _pipe@1 = gleam@string:lowercase(_pipe), - gleam@string:pad_left(_pipe@1, Size, <<"0"/utf8>>). - --spec parts(bitstring()) -> list(binary()). -parts(Uuid) -> - <<P1:32, P2:16, P3:16, P4:16, P5:48>> = Uuid, - [to_hex(P1, 8), to_hex(P2, 4), to_hex(P3, 4), to_hex(P4, 4), to_hex(P5, 12)]. - --spec to_string(bitstring()) -> binary(). -to_string(Uuid) -> - _pipe = parts(Uuid), - gleam@string:join(_pipe, <<"-"/utf8>>). - --spec new() -> bitstring(). -new() -> - <<U0:48, _:4, U1:12, _:2, U2:62>> = crypto:strong_rand_bytes(16), - <<U0:48, 4:4, U1:12, 2:2, U2:62>>. diff --git a/test-community-packages-javascript/build/packages/simplifile/README.md b/test-community-packages-javascript/build/packages/simplifile/README.md deleted file mode 100644 index 006d5b762a7..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# simplifile - -[![Package Version](https://img.shields.io/hexpm/v/simplifile)](https://hex.pm/packages/simplifile) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/simplifile/) - -Simplifile provides basic file operations (read, write, append, and delete) that work -for all targets (Erlang, Node, and Deno). It also provides functions for working with directories. - -## Example -```gleam -let filepath = "./test/hello.txt" -let assert Ok(_) = "Hello, World" |> write(to: filepath) -let assert Ok(_) = "Goodbye, Mars" |> append(to: filepath) -let assert Ok("Hello, WorldGoodbye, Mars") = read(from: filepath) -let assert Ok(_) = delete(filepath) -let assert Error(_) = read(from: filepath) -``` - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add simplifile -``` - -and its documentation can be found at <https://hexdocs.pm/simplifile>. diff --git a/test-community-packages-javascript/build/packages/simplifile/gleam.toml b/test-community-packages-javascript/build/packages/simplifile/gleam.toml deleted file mode 100644 index be16a280dd5..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/gleam.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "simplifile" -version = "0.1.4" -description = "Basic file operations that work on all targets" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -licences = ["Apache-2.0"] -repository = { type = "github", user = "bcpeinhardt", repo = "simplifile" } -# links = [{ title = "Website", href = "https://gleam.run" }] - -[javascript.deno] -allow_all = true - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/simplifile/src/file.mjs b/test-community-packages-javascript/build/packages/simplifile/src/file.mjs deleted file mode 100644 index a707f9e5f6d..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/file.mjs +++ /dev/null @@ -1,84 +0,0 @@ -import fs from "node:fs" -import path from "node:path" -import { BitString, Ok, Error as GError, toList} from "./gleam.mjs"; - -export function readFile(filepath) { - try { - const contents = fs.readFileSync(path.normalize(filepath)).toString() - return new Ok(contents) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function readBits(filepath) { - try { - const contents = fs.readFileSync(path.normalize(filepath)) - return new Ok(new BitString(new Uint8Array(contents))) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function writeFile(contents, filepath) { - try { - fs.writeFileSync(path.normalize(filepath), contents) - return new Ok(undefined) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function writeBits(contents, filepath) { - try { - fs.writeFileSync(path.normalize(filepath), contents.buffer) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -export function deleteFile(filepath) { - try { - fs.unlinkSync(path.normalize(filepath)) - return new Ok(undefined) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function appendFile(contents, filepath) { - try { - fs.appendFileSync(path.normalize(filepath), contents) - return new Ok(undefined) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function appendBits(contents, filepath) { - try { - fs.appendFileSync(path.normalize(filepath), contents.buffer) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -function stringifyError(e) { - return e.code -} - -export function isDirectory(filepath) { - let fp = path.normalize(filepath) - return fs.existsSync(fp) && fs.lstatSync(fp).isDirectory(); -} - -export function listContents(filepath) { - try { - const stuff = toList(fs.readdirSync(path.normalize(filepath))) - return new Ok(stuff) - } catch(e) { - return new GError(stringifyError(e)) - } -} \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl deleted file mode 100644 index b902c92cf1b..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl +++ /dev/null @@ -1,218 +0,0 @@ --module(gleam_erlang_ffi). --export([ - atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, - ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, - append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, - set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, - list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, - insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, - merge_selector/2, flush_messages/0, file_info/1, link_info/1 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - --spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. -atom_from_string(S) -> - try {ok, binary_to_existing_atom(S)} - catch error:badarg -> {error, atom_not_loaded} - end. - -atom_from_dynamic(Data) when is_atom(Data) -> - {ok, Data}; -atom_from_dynamic(Data) -> - {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. - -rescue(F) -> - try {ok, F()} - catch - throw:X -> {error, {thrown, X}}; - error:X -> {error, {errored, X}}; - exit:X -> {error, {exited, X}} - end. - -ensure_all_started(Application) -> - case application:ensure_all_started(Application) of - {ok, _} = Ok -> Ok; - - {error, {ProblemApp, {"no such file or directory", _}}} -> - {error, {unknown_application, ProblemApp}} - end. - -sleep(Microseconds) -> - timer:sleep(Microseconds), - nil. - -sleep_forever() -> - timer:sleep(infinity), - nil. - -file_info_result(Result) -> - case Result of - {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> - {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; - {ok, _} -> - Result; - {error, Reason} when ?is_posix_error(Reason) -> - Result - end. - -file_info(Filename) -> - file_info_result(file:read_file_info(Filename, [{time, posix}])). - -link_info(Filename) -> - file_info_result(file:read_link_info(Filename, [{time, posix}])). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -get_all_env() -> - BinVars = lists:map(fun(VarString) -> - [VarName, VarVal] = string:split(VarString, "="), - {list_to_binary(VarName), list_to_binary(VarVal)} - end, os:getenv()), - maps:from_list(BinVars). - -get_env(Name) -> - case os:getenv(binary_to_list(Name)) of - false -> {error, nil}; - Value -> {ok, list_to_binary(Value)} - end. - -set_env(Name, Value) -> - os:putenv(binary_to_list(Name), binary_to_list(Value)), - nil. - -unset_env(Name) -> - os:unsetenv(binary_to_list(Name)), - nil. - -os_family() -> - case os:type() of - {win32, nt} -> - windows_nt; - {unix, linux} -> - linux; - {unix, darwin} -> - darwin; - {unix, freebsd} -> - free_bsd; - {_, Other} -> - {other, atom_to_binary(Other, utf8)} - end. - -new_selector() -> - {selector, #{}}. - -map_selector({selector, Handlers}, Fn) -> - MappedHandlers = maps:map(fun(_Tag, Handler) -> - fun(Message) -> Fn(Handler(Message)) end - end, Handlers), - {selector, MappedHandlers}. - -merge_selector({selector, HandlersA}, {selector, HandlersB}) -> - {selector, maps:merge(HandlersA, HandlersB)}. - -insert_selector_handler({selector, Handlers}, Tag, Fn) -> - {selector, Handlers#{Tag => Fn}}. - -select(Selector) -> - {ok, Message} = select(Selector, infinity), - Message. - -select({selector, Handlers}, Timeout) -> - AnythingHandler = maps:get(anything, Handlers, undefined), - receive - % Monitored process down messages. - % This is special cased so we can selectively receive based on the - % reference as well as the record tag. - {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> - Fn = maps:get(Ref, Handlers), - {ok, Fn({process_down, Pid, Reason})}; - - Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> - Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), - {ok, Fn(Msg)}; - - Msg when AnythingHandler =/= undefined -> - {ok, AnythingHandler(Msg)} - after Timeout -> - {error, nil} - end. - -demonitor({_, Reference}) -> - erlang:demonitor(Reference, [flush]). - -link(Pid) -> - try - erlang:link(Pid) - catch - error:_ -> false - end. - -trap_exits(ShouldTrap) -> - erlang:process_flag(trap_exit, ShouldTrap), - nil. - -flush_messages() -> - receive _Message -> flush_messages() - after 0 -> nil - end. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src deleted file mode 100644 index 5e1c9b5afca..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, simplifile, [ - {vsn, "0.1.4"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Basic file operations that work on all targets"}, - {modules, [simplifile]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl deleted file mode 100644 index e6cacc110b1..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl +++ /dev/null @@ -1,131 +0,0 @@ --module(simplifile). --compile([no_auto_import, nowarn_unused_vars]). - --export([append_bits/2, append/2, write_bits/2, write/2, read_bits/1, read/1, delete/1, is_directory/1, list_contents/1]). --export_type([file_error/0]). - --type file_error() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8 | - unknown. - --spec cast_error({ok, EXS} | {error, file_error()}) -> {ok, EXS} | - {error, file_error()}. -cast_error(Input) -> - Input. - --spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, file_error()}. -append_bits(Bits, Filepath) -> - _pipe = gleam_erlang_ffi:append_file(Bits, Filepath), - cast_error(_pipe). - --spec do_append(binary(), binary()) -> {ok, nil} | {error, file_error()}. -do_append(Content, Filepath) -> - _pipe = Content, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:append_file(_pipe@1, Filepath). - --spec append(binary(), binary()) -> {ok, nil} | {error, file_error()}. -append(Contents, Filepath) -> - _pipe = do_append(Contents, Filepath), - cast_error(_pipe). - --spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, file_error()}. -write_bits(Bits, Filepath) -> - _pipe = gleam_erlang_ffi:write_file(Bits, Filepath), - cast_error(_pipe). - --spec do_write(binary(), binary()) -> {ok, nil} | {error, file_error()}. -do_write(Content, Filepath) -> - _pipe = Content, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:write_file(_pipe@1, Filepath). - --spec write(binary(), binary()) -> {ok, nil} | {error, file_error()}. -write(Contents, Filepath) -> - _pipe = do_write(Contents, Filepath), - cast_error(_pipe). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, file_error()}. -read_bits(Filepath) -> - _pipe = gleam_erlang_ffi:read_file(Filepath), - cast_error(_pipe). - --spec do_read(binary()) -> {ok, binary()} | {error, file_error()}. -do_read(Filepath) -> - case gleam_erlang_ffi:read_file(Filepath) of - {ok, Bit_str} -> - case gleam@bit_string:to_string(Bit_str) of - {ok, Str} -> - {ok, Str}; - - _ -> - {error, not_utf8} - end; - - {error, E} -> - {error, E} - end. - --spec read(binary()) -> {ok, binary()} | {error, file_error()}. -read(Filepath) -> - _pipe = do_read(Filepath), - cast_error(_pipe). - --spec delete(binary()) -> {ok, nil} | {error, file_error()}. -delete(Filepath) -> - _pipe = gleam_erlang_ffi:delete_file(Filepath), - cast_error(_pipe). - --spec is_directory(binary()) -> boolean(). -is_directory(Filepath) -> - filelib:is_dir(Filepath). - --spec list_contents(binary()) -> {ok, list(binary())} | {error, file_error()}. -list_contents(Directory) -> - gleam_erlang_ffi:list_directory(Directory). diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam deleted file mode 100644 index 0a94ea185a6..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam +++ /dev/null @@ -1,359 +0,0 @@ -/// This type represents all of the reasons for why a file system operation could fail. -/// -/// Most of these reasons are POSIX errors, which come from the operating system -/// and start with E. Others have been added to represent other issues that may -/// arise specific to this library. -/// -pub type FileError { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 - /// Any error not accounted for by this type - Unknown -} - -/// Read a files contents as a string -/// ## Example -/// ```gleam -/// let assert Ok(records) = read(from: "./users.csv") -/// ``` -/// ### A note about utf8 -/// Currently on the erlang target, this function expects a utf8 string -/// and returns a `NotUtf8` error if it reads a non utf8 string. -/// On the javascript target, it will read any string. -/// This behavior will probably change soon. -/// -pub fn read(from filepath: String) -> Result(String, FileError) { - do_read(filepath) - |> cast_error -} - -/// Write a string to a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = write("Hello, World!", to: "./hello_world.txt") -/// ``` -/// -pub fn write(contents: String, to filepath: String) -> Result(Nil, FileError) { - do_write(contents, to: filepath) - |> cast_error -} - -/// Delete a file at a given filepath -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = delete(file_at: "./delete_me.txt") -/// ``` -/// -pub fn delete(file_at filepath: String) -> Result(Nil, FileError) { - do_delete(filepath) - |> cast_error -} - -/// Append a string to the contents of a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = append("more text", to: "./needs_more_text.txt") -/// ``` -/// -pub fn append(contents: String, to filepath: String) -> Result(Nil, FileError) { - do_append(contents, to: filepath) - |> cast_error -} - -/// Read a files contents as a bitstring -/// ## Example -/// ```gleam -/// let assert Ok(records) = read_bits(from: "./users.csv") -/// ``` -/// -pub fn read_bits(from filepath: String) -> Result(BitString, FileError) { - do_read_bits(filepath) - |> cast_error -} - -/// Write a bitstring to a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = write_bits(<<"Hello, World!":utf8>>, to: "./hello_world.txt") -/// ``` -/// -pub fn write_bits( - bits: BitString, - to filepath: String, -) -> Result(Nil, FileError) { - do_write_bits(bits, filepath) - |> cast_error -} - -/// Append a bitstring to the contents of a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = append_bits(<<"more text":utf8>>, to: "./needs_more_text.txt") -/// ``` -/// -pub fn append_bits( - bits: BitString, - to filepath: String, -) -> Result(Nil, FileError) { - do_append_bits(bits, filepath) - |> cast_error -} - -/// Checks if the provided filepath is a directory -/// ## Example -/// ```gleam -/// let assert True = is_directory("./test") -/// ``` -pub fn is_directory(filepath: String) -> Bool { - do_is_directory(filepath) -} - -/// Lists the contents of a directory. -/// The list contains directory and file names, and is not recursive. -/// -/// ## Example -/// ```gleam -/// let assert Ok(files_and_folders) = list_contents(of: "./Folder1") -/// ``` -/// -pub fn list_contents(of directory: String) -> Result(List(String), FileError) { - do_list_contents(directory) -} - -if javascript { - import gleam/result - - external fn do_read(from: String) -> Result(String, String) = - "./file.mjs" "readFile" - - external fn do_write(String, to: String) -> Result(Nil, String) = - "./file.mjs" "writeFile" - - external fn do_delete(file_at: String) -> Result(Nil, String) = - "./file.mjs" "deleteFile" - - external fn do_append(String, to: String) -> Result(Nil, String) = - "./file.mjs" "appendFile" - - external fn do_read_bits(from: String) -> Result(BitString, String) = - "./file.mjs" "readBits" - - external fn do_write_bits(BitString, to: String) -> Result(Nil, String) = - "./file.mjs" "writeBits" - - external fn do_append_bits(BitString, to: String) -> Result(Nil, String) = - "./file.mjs" "appendBits" - - external fn do_is_directory(String) -> Bool = - "./file.mjs" "isDirectory" - - external fn do_list_contents(String) -> Result(List(String), FileError) = - "./file.mjs" "listContents" - - fn cast_error(input: Result(a, String)) -> Result(a, FileError) { - result.map_error( - input, - fn(e) { - case e { - "EACCES" -> Eacces - "EAGAIN" -> Eagain - "EBADF" -> Ebadf - "EBADMSG" -> Ebadmsg - "EBUSY" -> Ebusy - "EDEADLK" -> Edeadlk - "EDEADLOCK" -> Edeadlock - "EDQUOT" -> Edquot - "EEXIST" -> Eexist - "EFAULT" -> Efault - "EFBIG" -> Efbig - "EFTYPE" -> Eftype - "EINTR" -> Eintr - "EINVAL" -> Einval - "EIO" -> Eio - "EISDIR" -> Eisdir - "ELOOP" -> Eloop - "EMFILE" -> Emfile - "EMLINK" -> Emlink - "EMULTIHOP" -> Emultihop - "ENAMETOOLONG" -> Enametoolong - "ENFILE" -> Enfile - "ENOBUFS" -> Enobufs - "ENODEV" -> Enodev - "ENOLCK" -> Enolck - "ENOLINK" -> Enolink - "ENOENT" -> Enoent - "ENOMEM" -> Enomem - "ENOSPC" -> Enospc - "ENOSR" -> Enosr - "ENOSTR" -> Enostr - "ENOSYS" -> Enosys - "ENOBLK" -> Enotblk - "ENODIR" -> Enotdir - "ENOTSUP" -> Enotsup - "ENXIO" -> Enxio - "EOPNOTSUPP" -> Eopnotsupp - "EOVERFLOW" -> Eoverflow - "EPERM" -> Eperm - "EPIPE" -> Epipe - "ERANGE" -> Erange - "EROFS" -> Erofs - "ESPIPE" -> Espipe - "ESRCH" -> Esrch - "ESTALE" -> Estale - "ETXTBSY" -> Etxtbsy - "EXDEV" -> Exdev - "NOTUTF8" -> NotUtf8 - _ -> Unknown - } - }, - ) - } -} - -if erlang { - import gleam/bit_string - - external fn do_append_bits(BitString, to: String) -> Result(Nil, FileError) = - "gleam_erlang_ffi" "append_file" - - external fn do_write_bits(BitString, to: String) -> Result(Nil, FileError) = - "gleam_erlang_ffi" "write_file" - - external fn do_read_bits(from: String) -> Result(BitString, FileError) = - "gleam_erlang_ffi" "read_file" - - external fn do_delete(String) -> Result(Nil, FileError) = - "gleam_erlang_ffi" "delete_file" - - fn do_append(content: String, to filepath: String) -> Result(Nil, FileError) { - content - |> bit_string.from_string - |> do_append_bits(filepath) - } - - fn do_write(content: String, to filepath: String) -> Result(Nil, FileError) { - content - |> bit_string.from_string - |> do_write_bits(filepath) - } - - fn do_read(from filepath: String) -> Result(String, FileError) { - case do_read_bits(filepath) { - Ok(bit_str) -> { - case bit_string.to_string(bit_str) { - Ok(str) -> Ok(str) - _ -> Error(NotUtf8) - } - } - Error(e) -> Error(e) - } - } - - fn cast_error(input: Result(a, FileError)) -> Result(a, FileError) { - input - } - - external fn do_is_directory(String) -> Bool = - "filelib" "is_dir" - - external fn do_list_contents( - directory: String, - ) -> Result(List(String), FileError) = - "gleam_erlang_ffi" "list_directory" -} diff --git a/test-community-packages-javascript/build/packages/toml/LICENSE b/test-community-packages-javascript/build/packages/toml/LICENSE deleted file mode 100644 index e1ebf2e95c4..00000000000 --- a/test-community-packages-javascript/build/packages/toml/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/test-community-packages-javascript/build/packages/toml/README.md b/test-community-packages-javascript/build/packages/toml/README.md deleted file mode 100644 index 8fb93a965d3..00000000000 --- a/test-community-packages-javascript/build/packages/toml/README.md +++ /dev/null @@ -1,338 +0,0 @@ -# TOML for Elixir - -[![Main](https://github.com/bitwalker/toml-elixir/workflows/elixir/badge.svg?branch=main)](https://github.com/bitwalker/toml-elixir/actions?query=workflow%3A%22elixir%22+branch%3Amain) -[![Hex.pm Version](https://img.shields.io/hexpm/v/toml.svg?style=flat)](https://hex.pm/packages/toml) -[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg?style=flat)](https://hexdocs.pm/toml) -[![Total Download](https://img.shields.io/hexpm/dt/toml.svg?style=flat)](https://hex.pm/packages/toml) -[![Last Updated](https://img.shields.io/github/last-commit/bitwalker/toml-elixir.svg?style=flat)](https://github.com/bitwalker/toml-elixir/commits/main) - -This is a TOML library for Elixir projects. - -It is compliant with version 1.0 of the [official TOML specification](https://github.com/toml-lang/toml). You can find a -brief overview of the feature set below, but you are encouraged to read the full spec at the link above (it is short and easy to read!). - -## Features - -- Decode from string, file, or stream -- Fully compliant with the latest version of the TOML spec -- Is tested against [toml-test](https://github.com/BurntSushi/toml-test), a test - suite for spec-compliant TOML encoders/decoders, used by implementations in - multiple languages. The test suite has been integrated into this project to be - run under Mix so that we get better error information and so it can run as - part of the test suite. -- Decoder produces a map with values using the appropriate Elixir data types for - representation -- Supports extension via value transformers (see `Toml.Transform` docs for details) -- Supports use as a configuration provider in Distillery 2.x+ (use TOML - files for configuration!) -- Decoder is written by hand to take advantage of various optimizations. -- Library passes Dialyzer checks - -## Comparison To Other Libraries - -I compared `toml` to four other libraries: - -- `toml_elixir` -- `tomlex` -- `jerry` -- `etoml` - -Of these four, none correctly implement the 0.5.0 specification. Either they are -targeting older versions of the spec (in `etoml`, it is built against pre-0.1), -are not fully implemented (i.e. don't support all features), or have bugs which -prevent them from properly parsing a 0.5.0 example file (the -`test/fixtures/example.toml` file in this repository). - -If you are looking for a TOML library, at present `toml` is the only one which -full implements the spec and correctly decodes `example.toml`. - -## Installation - -This library is available on Hex as `:toml`, and can be added to your deps like so: - -```elixir -def deps do - [ - {:toml, "~> 0.7"} - ] -end -``` - -NOTE: You can determine the latest version on Hex by running `mix hex.info toml`. - -## Type Conversions - -In case you are curious how TOML types are translated to Elixir types, the -following table provides the conversions. - -**NOTE:** The various possible representations of each type, such as -hex/octal/binary integers, quoted/literal strings, etc., are considered to be -the same base type (e.g. integer and string respectively in the examples given). - -| TOML | Elixir | -|-------|-------| -| String | String.t (binary) | -| Integer | integer | -| inf | :infinity | -| +inf | :infinity | -| -inf | :negative_infinity | -| nan | :nan | -| +nan | :nan | -| -nan | :negative_nan | -| Boolean | boolean | -| Offset Date-Time | DateTime.t | -| Local Date-Time | NaiveDateTime.t | -| Local Date | Date.t | -| Local Time | Time.t | -| Array | list | -| Table | map | -| Table Array | list(map) | - -## Implementation-specific Behaviors - -Certain features of TOML have implementation-specific behavior: - -- `-inf`, `inf`, and `+inf` are all valid infinity values in TOML. - In Erlang/Elixir, these don't have exact representations. Instead, by convention, - `:infinity` is used for positive infinity, as atoms are always larger than integers - when using comparison operators, so `:infinity > <any integer>` will always be true. - However, negative infinity cannot be represented, as numbers are always considered smaller - than every other type in term comparisons. Instead, we represent it with `:negative_infinity`, - so that the type information is not lost, but you must be careful to deal with it specifically - in comparisons/sorting/etc. -- `-nan`, `nan`, and `+nan` are all valid NaN (not a number) values in TOML. In Erlang/Elixir, - NaN is traditionally represented with `:nan`, but there is no representation for negative NaN, - and no API actually produces `:nan`, instead invalid numbers typically raise errors, in the typical - spirit of "let it crash" in the face of errors. For purposes of preserving type information though, - we use the `:nan` convention, and `:negative_nan` for -NaN. You will need to take care to deal with - these values manually if the values need to be preserved. -- The maximum precision of times in the various time types is microseconds (i.e. precision to six decimal places), - if you provide higher precision values (i.e. nanoseconds), the extra precision will be lost. -- Hex, octal, and binary numbers are converted to integers, so serializing those values after decoding - them from a TOML document will be in their decimal representation. - -## Example Usage - -The following is a brief overview of how to use this library. First, let's take -a look at an example TOML file, as borrowed from the [TOML -homepage](https://github.com/toml-lang/toml): - -``` toml -# This is a TOML document. - -title = "TOML Example" - -[owner] -name = "Tom Preston-Werner" -dob = 1979-05-27T07:32:00-08:00 # First class dates - -[database] -server = "192.168.1.1" -ports = [ 8001, 8001, 8002 ] -connection_max = 5000 -enabled = true - -[servers] - - # Indentation (tabs and/or spaces) is allowed but not required - [servers.alpha] - ip = "10.0.0.1" - dc = "eqdc10" - - [servers.beta] - ip = "10.0.0.2" - dc = "eqdc10" - -[clients] -data = [ ["gamma", "delta"], [1, 2] ] - -# Line breaks are OK when inside arrays -hosts = [ - "alpha", - "omega" -] -``` - -### Parsing - -```elixir -iex> input = """ -[database] -server = "192.168.1.1" -""" -...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode(input) -...> {:ok, %{database: %{server: "192.168.1.1"}}} = Toml.decode(input, keys: :atoms) -...> stream = File.stream!("example.toml") -...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode_stream(stream) -...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode_file("example.toml") -...> invalid = """ -[invalid] -a = 1 b = 2 -""" -...> {:error, {:invalid_toml, reason}} = Toml.decode(invalid); IO.puts(reason) -expected '\n', but got 'b' in nofile on line 2: - - a = 1 b = 2 - ^ - -:ok -``` - -### Transforms - -Support for extending value conversions is provided by the `Toml.Transform` -behavior. An example is shown below: - -Given the following TOML document: - -``` toml -[servers.alpha] -ip = "192.168.1.1" -ports = [8080, 8081] - -[servers.beta] -ip = "192.168.1.2" -ports = [8082, 8083] -``` - -And the following modules: - -``` elixir -defmodule Server do - defstruct [:name, :ip, :ports] -end - -defmodule IPStringToCharlist do - use Toml.Transform - - def transform(:ip, v) when is_binary(v) do - String.to_charlist(v) - end - def transform(_k, v), do: v -end - -defmodule CharlistToIP do - use Toml.Transform - - def transform(:ip, v) when is_list(v) do - case :inet.parse_ipv4_address(v) do - {:ok, address} -> - address - {:error, reason} -> - {:error, {:invalid_ip_address, reason}} - end - end - def transform(:ip, v), do: {:error, {:invalid_ip_address, v}} - def transform(_k, v), do: v -end - -defmodule ServerMapToList do - use Toml.Transform - - def transform(:servers, v) when is_map(v) do - for {name, server} <- v, do: struct(Server, Map.put(server, :name, name)) - end - def transform(_k, v), do: v -end -``` - -You can convert the TOML document to a more strongly-typed version using the -above transforms like so: - -```elixir -iex> transforms = [IPStringToCharlist, CharlistToIP, ServerMapToList] -...> {:ok, result} = Toml.decode("example.toml", keys: :atoms, transforms: transforms) -%{servers: [%Server{name: :alpha, ip: {192,168,1,1}}, ports: [8080, 8081] | _]} -``` - -The transforms given here are intended to show how they can be composed: they -are applied in the order provided, and the document is transformed using a -depth-first, bottom-up traversal. Put another way, you transform the leaves of -the tree before the branches; as shown in the example above, this means the -`:ip` key is converted to an address tuple before the `:servers` key is -transformed into a list of `Server` structs. - -## Using with Elixir Releases (1.9+) - -To use this library as a configuration provider in Elixir, use the following -example of how one might use it in their release configuration, and tailor it -to your needs: - -```elixir -config_providers: [ - {Toml.Provider, [ - path: {:system, "XDG_CONFIG_DIR", "myapp.toml"}, - transforms: [...] - ]} -] -``` - -See the "Using as a Config Provider" section for more info. - -## Using with Distillery - -Like the above, use the following example as a guideline for how you use this -in your own release configuration (i.e. in `rel/config.exs`): - -``` elixir -release :myapp do - # ...snip... - set config_providers: [ - {Toml.Provider, [path: "${XDG_CONFIG_DIR}/myapp.toml", transforms: [...]]} - ] -end -``` - -## Using as a Config Provider - -The usages described above will result in `Toml.Provider` being invoked during boot, at which point it -will evaluate the given path and read the TOML file it finds. If one is not -found, or is not accessible, the provider will raise an error, and the boot -sequence will terminate unsuccessfully. If it succeeds, it persists settings in -the file to the application environment (i.e. you access it via -`Application.get_env/2`). - -You can pass the same options in the arguments list for `Toml.Provider` as you -can to `Toml.decode/2`, but `:path` is required, and `:keys` only supports -`:atoms` and `:atoms!` values. - -The config provider expects a certain format to the TOML file, namely that keys -at the root of the document correspond to applications which need to be configured. -If it encounters keys at the root of the document which are not tables, they are ignored. - -``` toml -# This is an example of something that would be ignored -title = "My config file" - -# We're expecting something like this: -[myapp] -key = "value" - -# To use a bit of Phoenix config, you translate to TOML like so: -[myapp."MyApp.Endpoint"] -cache_static_manifest = "priv/static/cache_manifest.json" - -[myapp."MyApp.Endpoint".http] -port = "4000" - -[myapp."MyApp.Endpoint".force_ssl] -hsts = true - -# Or logger.. -[logger] -level = "info" - -[logger.console] -format = "[$level] $message \n" -``` - -## Roadmap - -- [x] Add benchmarking suite -- [x] Provide options for converting keys to atom, similar to Jason/Poison/etc. -- [ ] Optimize lexer to always send offsets to decoder, rather than only in some cases -- [ ] Try to find pathological TOML files to test - -## License - -This project is licensed Apache 2.0, see the `LICENSE` file in this repo for details. diff --git a/test-community-packages-javascript/build/packages/toml/lib/builder.ex b/test-community-packages-javascript/build/packages/toml/lib/builder.ex deleted file mode 100644 index 8491af59817..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/builder.ex +++ /dev/null @@ -1,413 +0,0 @@ -defmodule Toml.Builder do - @moduledoc false - - @compile inline: [key: 3, keys: 2, comment: 2, open: 2, close: 1, to_result: 1] - - # Builds a Document, performing validation along the way - - alias Toml.Document - - @doc """ - Creates a new empty TOML document to build with. - """ - defdelegate new(opts), to: Document - - @doc """ - Starts a new table and sets the context for subsequent key/values - """ - def push_table(%Document{} = doc, keypath) do - with {:ok, doc} = push_key(%Document{doc | open_table: nil}, keypath, {:table_decl, %{}}) do - # We're explicitly opening a new table - doc |> open(keypath) |> to_result() - end - end - - @doc """ - Starts a new array of tables and sets the context for subsequent key/values - """ - def push_table_array(%Document{} = doc, keypath) do - with {:ok, doc} = push_key(%Document{doc | open_table: nil}, keypath, {:table_array, []}) do - # We're explicitly opening a new table - doc |> open(keypath) |> to_result() - end - end - - @doc """ - Push a comment on a stack containing lines of comments applying to some element. - Comments are collected and assigned to key paths when a key is set, table created, etc. - """ - def push_comment(%Document{comment_stack: cs} = doc, comment) do - %Document{doc | comment_stack: [comment | cs]} - end - - @doc """ - Push a value for a key into the TOML document. - - This operation is used when any key/value pair is set, and table or table array is defined. - - Based on the key the type of the value provided, the behavior of this function varies, as validation - as performed as part of setting the key, to ensure that redefining keys is prohibited, but that setting - child keys of existing tables is allowed. Table arrays considerably complicate this unfortunately. - """ - def push_key(%Document{keys: ks} = doc, [key], value) - when is_map(value) and map_size(value) == 0 - when is_tuple(value) and elem(value, 0) == :table_decl do - # New table - keypath = [key] - - case Map.get(ks, key) do - nil -> - doc - |> key(key, %{}) - |> comment(keypath) - |> open(keypath) - |> to_result() - - exists when is_map(exists) -> - cond do - map_size(exists) == 0 -> - # Redefinition - key_exists!(keypath) - - Enum.all?(exists, fn - {_, v} when is_map(v) -> true - _ -> false - end) -> - # All keys are sub-tables, we'll allow this - doc - |> comment(keypath) - |> open(keypath) - |> to_result() - - :else -> - {k, _} = Enum.find(exists, fn {_, v} -> not is_map(v) end) - key_exists!(keypath ++ [k]) - end - - _exists -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, [key], value) when is_map(value) do - # Pushing an inline table - keypath = - case doc.open_table do - nil -> - [key] - - opened -> - opened ++ [key] - end - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, [key], {:table_array, _} = value) do - keypath = [key] - - case push_key_into_table(ks, [key], value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> close() - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks, open_table: nil} = doc, [key], value) do - # Pushing a key/value pair at the root level of the document - keypath = [key] - - if Map.has_key?(ks, key) do - key_exists!(keypath) - end - - doc - |> key(key, value) - |> comment(keypath) - |> close() - |> to_result() - end - - def push_key(%Document{keys: ks, open_table: opened} = doc, [key], value) do - # Pushing a key/value pair when a table is open - keypath = opened ++ [key] - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, keypath, value) - when is_list(keypath) and is_map(value) - when is_list(keypath) and is_tuple(value) and elem(value, 0) == :table_decl do - # Pushing a multi-part key with a table value - keypath = - case doc.open_table do - nil -> - keypath - - opened -> - opened ++ keypath - end - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, keypath, value) when is_list(keypath) do - # Pushing a multi-part key with a plain value - keypath = - case doc.open_table do - nil -> - keypath - - opened -> - opened ++ keypath - end - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - # Handles pushing a value into a map, arbitrarily deep, and respecting - # the desired behavior of table arrays. Can be used with any map. - # - # NOTE: This is similar to `put_in/3`, but does not raise if a key does - # exist, instead it creates a new table (map) at the level needed, and continues - # pushing the key into this new table - @doc false - def push_key_into_table({:table_array, array}, [key], {:table_array, _} = value) do - case array do - [] -> - {:ok, {:table_array, [Map.put(%{}, key, value)]}} - - [h | t] when is_map(h) -> - case Map.get(h, key) do - nil -> - {:ok, {:table_array, [Map.put(h, key, value) | t]}} - - {:table_array, items} -> - {:ok, {:table_array, [Map.put(h, key, {:table_array, [%{} | items]}) | t]}} - - _ -> - {:error, :key_exists} - end - end - end - - def push_key_into_table({:table_array, array}, keypath, {:table_decl, value}) do - case array do - [] -> - {:ok, {:table_array, [value]}} - - [h | t] when is_map(h) -> - case push_key_into_table(h, keypath, {:table_decl, value}) do - {:ok, h2} -> - {:ok, {:table_array, [h2 | t]}} - - {:error, _} = err -> - err - end - end - end - - def push_key_into_table({:table_array, array}, keypath, value) when is_map(value) do - case array do - [] -> - {:ok, {:table_array, [value]}} - - [h | t] when is_map(h) -> - case push_key_into_table(h, keypath, value) do - {:ok, h2} -> - {:ok, {:table_array, [h2 | t]}} - - {:error, _} = err -> - err - end - end - end - - def push_key_into_table({:table_array, array}, keypath, value) do - # Adding key/value to last table item - case array do - [] -> - case push_key_into_table(%{}, keypath, value) do - {:ok, item} -> - {:ok, {:table_array, [item]}} - - {:error, _} = err -> - err - end - - [h | t] when is_map(h) -> - case push_key_into_table(h, keypath, value) do - {:ok, h2} -> - {:ok, {:table_array, [h2 | t]}} - - {:error, _} = err -> - err - end - end - end - - def push_key_into_table(ts, [key], {:table_decl, value}) do - case Map.get(ts, key) do - nil -> - {:ok, Map.put(ts, key, value)} - - exists when is_map(exists) -> - # We're reopening a table, but we allow it as long as keys - # in that table don't override previously defined keys - {:ok, ts} - - _exists -> - {:error, :key_exists} - end - end - - def push_key_into_table(ts, [key], value) when is_map(ts) do - # Reached final table - case Map.get(ts, key) do - nil -> - {:ok, Map.put(ts, key, value)} - - {:table_array, items} - when is_list(items) and is_tuple(value) and elem(value, 0) == :table_array -> - # Appending to table array - {:ok, Map.put(ts, key, {:table_array, [%{} | items]})} - - {:table_array, items} when is_list(items) and is_map(value) -> - # Pushing into table array - {:ok, Map.put(ts, key, {:table_array, [value | items]})} - - exists when is_map(exists) and is_map(value) and map_size(value) > 0 -> - result = - Enum.reduce(value, exists, fn {k, v}, acc -> - case push_key_into_table(acc, [k], v) do - {:ok, acc2} -> - acc2 - - {:error, _} = err -> - throw(err) - end - end) - - {:ok, result} - - _exists -> - {:error, :key_exists} - end - catch - :throw, {:error, _} = err -> - err - end - - def push_key_into_table(ts, _keypath, _value) when not is_map(ts) do - # The table we're trying to push into is not itself a table, this is redefinition! - {:error, :key_exists} - end - - def push_key_into_table(ts, [table | keypath], value) when is_map(ts) do - result = - case Map.get(ts, table) do - nil -> - push_key_into_table(%{}, keypath, value) - - child -> - push_key_into_table(child, keypath, value) - end - - case result do - {:ok, child} -> - {:ok, Map.put(ts, table, child)} - - {:error, _} = err -> - err - end - end - - # Raised if the given keypath has already been defined - # and the value being set at that keypath is not an inline - # table (effectively extending the keypath and pushing multiple values), - # or table array (resulting in a new table being pushed into that array) - @spec key_exists!([binary]) :: no_return - defp key_exists!(keypath), - do: error!({:key_exists, Enum.join(keypath, ".")}) - - # Raised due to any other document builder error - @spec error!([binary]) :: no_return - defp error!(reason), - do: throw({:error, {:invalid_toml, reason}}) - - # Set a key at the document root - defp key(%Document{keys: keys} = doc, key, value), - do: %Document{doc | keys: Map.put(keys, key, value)} - - # Replace the set of keys in the document - defp keys(%Document{} = doc, keys), - do: %Document{doc | keys: keys} - - # Comment the given key, if comments are available on the stack - defp comment(%Document{comments: cs, comment_stack: stack} = doc, key) do - comment = - stack - |> Enum.reverse() - |> Enum.join("\n") - - if byte_size(comment) > 0 do - %Document{doc | comment_stack: [], comments: Map.put(cs, key, comment)} - else - %Document{doc | comment_stack: []} - end - end - - # Open a table at the given key - defp open(%Document{} = doc, key), - do: %Document{doc | open_table: key} - - # Close any open table - defp close(%Document{} = doc), - do: %Document{doc | open_table: nil} - - # Wrap the document in a ok tuple - defp to_result(%Document{} = doc), - do: {:ok, doc} -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/decoder.ex b/test-community-packages-javascript/build/packages/toml/lib/decoder.ex deleted file mode 100644 index ac0801adab1..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/decoder.ex +++ /dev/null @@ -1,1055 +0,0 @@ -defmodule Toml.Decoder do - @moduledoc false - - alias Toml.Document - alias Toml.Builder - alias Toml.Lexer - - @compile :inline_list_funs - @compile inline: [ - pop_skip: 2, - peek_skip: 2, - iodata_to_str: 1, - iodata_to_integer: 1, - iodata_to_float: 1 - ] - - @doc """ - Decodes a raw binary into a map. - - `Toml.Error` is raised if decoding fails. - """ - @spec decode!(binary, Toml.opts()) :: map | no_return - def decode!(bin, opts) when is_binary(bin) and is_list(opts) do - # Raise if the filename is invalid - filename = - case Keyword.get(opts, :filename, "nofile") do - name when is_binary(name) -> - name - - n -> - raise ArgumentError, "invalid :filename option '#{inspect(n)}', must be a binary!" - end - - # Get our lexer outside the try so that we can stop it if things go south - # This can only fail if the lexer process itself crashes during init - {:ok, lexer} = Lexer.new(bin) - - try do - case do_decode(lexer, bin, Builder.new(opts)) do - {:ok, doc} -> - case Document.to_map(doc) do - {:ok, result} -> - result - - {:error, reason} -> - raise Toml.Error, reason - end - - {:error, reason, skip, lines} -> - raise Toml.Error, format_error(reason, bin, filename, skip, lines) - end - catch - :throw, {:error, {:invalid_toml, reason}} -> - raise Toml.Error, reason - - :throw, {:badarg, {option, value, valid}} -> - raise Toml.Error, {:badarg, option, value, valid} - after - Lexer.stop(lexer) - end - end - - @doc """ - Decodes a raw binary safely, returns `{:ok, map}` or `{:error, reason}` - """ - @spec decode(binary, Toml.opts()) :: {:ok, map} | Toml.error() - def decode(bin, opts) when is_binary(bin) and is_list(opts) do - {:ok, decode!(bin, opts)} - rescue - err in [Toml.Error] -> - {:error, {:invalid_toml, Exception.message(err)}} - - err in [ArgumentError] -> - {:error, err.message} - catch - :error, reason -> - {:error, Toml.Error.format_reason(reason)} - end - - @doc """ - Decodes a stream. - - Raises `Toml.Error` if decoding fails. - """ - @spec decode_stream!(Enumerable.t(), Toml.opts()) :: map | no_return - def decode_stream!(stream, opts) do - decode!(Enum.into(stream, <<>>), opts) - end - - @doc """ - Decodes a stream safely. - - Returns same type as `decode/2` - """ - @spec decode_stream(Enumerable.t(), Toml.opts()) :: {:ok, map} | Toml.error() - def decode_stream(stream, opts) do - decode(Enum.into(stream, <<>>), opts) - end - - @doc """ - Decodes a file. - - Raises `Toml.Error` if decoding fails. - """ - @spec decode_file!(String.t(), Toml.opts()) :: map | no_return - def decode_file!(path, opts) when is_binary(path) do - with {:ok, opts} <- set_filename_opt(opts, path), - bin = File.read!(path) do - decode!(bin, opts) - end - end - - @doc """ - Decodes a file safely. - - Returns same type as `decode/2` - """ - @spec decode_file(String.t(), Toml.opts()) :: {:ok, map} | Toml.error() - def decode_file(path, opts) when is_binary(path) do - with {:ok, opts} <- set_filename_opt(opts, path), - {:ok, bin} <- File.read(path) do - decode(bin, opts) - else - {:error, reason} -> - {:error, "unable to open file '#{Path.relative_to_cwd(path)}': #{inspect(reason)}"} - end - end - - defp set_filename_opt(opts, default) do - case Keyword.get(opts, :filename) do - nil -> - {:ok, Keyword.put(opts, :filename, default)} - - _name -> - {:ok, opts} - end - end - - ## Decoder Implementation - - @spec do_decode(Lexer.t(), binary, Document.t()) :: {:ok, Document.t()} | Lexer.lexer_err() - defp do_decode(lexer, original, %Document{} = doc) do - with {:ok, {type, skip, data, lines}} <- Lexer.pop(lexer) do - handle_token(lexer, original, doc, type, skip, data, lines) - end - end - - # Converts an error into a friendly, printable representation - defp format_error(reason, original, filename, skip, lines) do - msg = - "#{Toml.Error.format_reason(reason)} in #{Path.relative_to_cwd(filename)} on line #{lines}" - - {ctx, pos} = seek_line(original, skip - 1, lines) - - """ - #{msg}: - - #{ctx} - #{String.duplicate(" ", pos)}^ at column #{pos} - """ - end - - # Finds the line of context for display in a formatted error - defp seek_line(original, skip, lines) do - seek_line(original, original, 0, 0, skip, lines - 1) - end - - defp seek_line(original, rest, lastnl, from, len, 0) do - case seek_to_eol(rest, 0) do - 0 -> - {binary_part(original, lastnl, from - lastnl), from - lastnl} - - len_to_eol when len_to_eol > 0 -> - {binary_part(original, from, len_to_eol), len} - end - end - - defp seek_line(original, <<?\r, ?\n, rest::binary>>, lastnl, from, len, 1) when len <= 0 do - # Content occurred on the last line right before the newline - seek_line(original, rest, lastnl, from + 2, 0, 0) - end - - defp seek_line(original, <<?\r, ?\n, rest::binary>>, _, from, len, lines) do - seek_line(original, rest, from + 2, from + 2, len - 2, lines - 1) - end - - defp seek_line(original, <<?\n, rest::binary>>, lastnl, from, len, 1) when len <= 0 do - # Content occurred on the last line right before the newline - seek_line(original, rest, lastnl, from + 1, 0, 0) - end - - defp seek_line(original, <<?\n, rest::binary>>, _, from, len, lines) do - seek_line(original, rest, from + 1, from + 1, len - 1, lines - 1) - end - - defp seek_line(original, <<_::utf8, rest::binary>>, lastnl, from, len, lines) do - seek_line(original, rest, lastnl, from + 1, len - 1, lines) - end - - # Find the number of bytes to the end of the current line in the input - defp seek_to_eol(<<>>, len), do: len - defp seek_to_eol(<<?\r, ?\n, _::binary>>, len), do: len - defp seek_to_eol(<<?\n, _::binary>>, len), do: len - - defp seek_to_eol(<<_::utf8, rest::binary>>, len) do - seek_to_eol(rest, len + 1) - end - - # Handles invalid byte sequences (i.e. invalid unicode) - # Considers the invalid byte as EOL so context can still be shown - defp seek_to_eol(<<_, _rest::binary>>, len), do: len - - # Skip top-level whitespace and newlines - @spec handle_token( - Lexer.t(), - binary, - Document.t(), - Lexer.type(), - Lexer.skip(), - binary | non_neg_integer, - Lexer.lines() - ) :: {:ok, Document.t()} | Lexer.lexer_err() - defp handle_token(lexer, original, doc, :whitespace, _skip, _data, _lines), - do: do_decode(lexer, original, doc) - - defp handle_token(lexer, original, doc, :newline, _skip, _data, _lines), - do: do_decode(lexer, original, doc) - - # Push comments on the comment stack - defp handle_token(lexer, original, doc, :comment, skip, size, _lines) do - comment = binary_part(original, skip - size, size) - do_decode(lexer, original, Builder.push_comment(doc, comment)) - end - - # Handle valid top-level entities - # - array of tables - # - table - # - key/value - defp handle_token(lexer, original, doc, ?\[, skip, data, lines) do - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {?\[, _, _, _}} -> - # Push opening bracket, second was peeked, so no need - Lexer.push(lexer, {?\[, skip, data, lines}) - handle_table_array(lexer, original, doc) - - {:ok, {_, _, _, _}} -> - Lexer.push(lexer, {?\[, skip, data, lines}) - handle_table(lexer, original, doc) - end - end - - defp handle_token(lexer, original, doc, type, skip, data, lines) - when type in [:digits, :alpha, :string] do - Lexer.push(lexer, {type, skip, data, lines}) - - with {:ok, key, _skip, _lines} <- key(lexer) do - handle_key(lexer, original, doc, key) - end - end - - defp handle_token(lexer, original, doc, type, skip, _data, lines) when type in '-_' do - handle_token(lexer, original, doc, :string, skip, <<type::utf8>>, lines) - end - - # We're done - defp handle_token(_lexer, _original, doc, :eof, _skip, _data, _lines) do - {:ok, doc} - end - - # Anything else at top-level is invalid - defp handle_token(_lexer, _original, _doc, type, skip, data, lines) do - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - defp handle_key(lexer, original, doc, key) do - with {:ok, {?=, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, value} <- value(lexer), - {:ok, doc} <- Builder.push_key(doc, key, value) do - # Make sure key/value pairs are separated by a newline - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - # Implies newline - do_decode(lexer, original, doc) - - {:ok, {type, _, _, _}} when type in [:newline, :eof] -> - do_decode(lexer, original, doc) - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, :newline, {type, data}}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, ?=, {type, data}}, skip, lines} - end - end - - defp handle_table(lexer, original, doc) do - # Guaranteed to have an open bracket - with {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, key, _line, _col} <- key(lexer), - {:ok, {?\], _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, doc} <- Builder.push_table(doc, key) do - # Make sure table opening is followed by newline - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - do_decode(lexer, original, doc) - - {:ok, {type, _, _, _}} when type in [:newline, :eof] -> - do_decode(lexer, original, doc) - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, :newline, {type, data}}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp handle_table_array(lexer, original, doc) do - # Guaranteed to have two open brackets - with {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, key, _, _} <- key(lexer), - {_, {:ok, {?\], _, _, _}}} <- {:close, pop_skip(lexer, [:whitespace])}, - {_, {:ok, {?\], _, _, _}}} <- {:close, pop_skip(lexer, [:whitespace])}, - {:ok, doc} <- Builder.push_table_array(doc, key) do - # Make sure table opening is followed by newline - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - do_decode(lexer, original, doc) - - {:ok, {type, _, _, _}} when type in [:newline, :eof] -> - do_decode(lexer, original, doc) - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, :newline, {type, data}}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {_, {:error, _, _, _} = err} -> - err - - {:close, {:ok, {type, skip, data, lines}}} -> - {:error, {:unclosed_table_array_name, {type, data}}, skip, lines} - end - end - - defp maybe_integer(lexer) do - case pop_skip(lexer, [:whitespace]) do - {:ok, {type, _skip, _data, _lines}} when type in '-+' -> - # Can be integer, float - case Lexer.peek(lexer) do - {:error, _, _, _} = err -> - err - - # Handle infinity/nan with leading sign - {:ok, {:alpha, _, "inf", _}} -> - Lexer.advance(lexer) - - if type == ?\+ do - {:ok, :infinity} - else - {:ok, :negative_infinity} - end - - {:ok, {:alpha, _, "nan", _}} -> - Lexer.advance(lexer) - - if type == ?\+ do - {:ok, :nan} - else - {:ok, :negative_nan} - end - - # Must be a signed integer or float - {:ok, {:digits, _, d, _}} -> - Lexer.advance(lexer) - maybe_integer(lexer, [d, type]) - - # Invalid - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - {:ok, {:digits, skip, <<leader::utf8, _::utf8, _::utf8, _::utf8>> = d, lines} = token} -> - # Could be a datetime - case Lexer.peek(lexer) do - {:ok, {?-, _, _, _}} -> - # This is a date or datetime - Lexer.push(lexer, token) - maybe_datetime(lexer) - - {:ok, {?., _, _, _}} -> - # Float - Lexer.advance(lexer) - float(lexer, ?., [?., d]) - - {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' -> - # Float - Lexer.advance(lexer) - float(lexer, ?e, [?e, ?0, ?., d]) - - {:ok, {?_, _, _, _}} -> - # Integer - maybe_integer(lexer, [d]) - - _ -> - # Just an integer - if leader == ?0 do - # Leading zeroes not allowed - {:error, {:invalid_integer, :leading_zero}, skip, lines} - else - {:ok, String.to_integer(d)} - end - end - - {:ok, {:digits, skip, <<leader::utf8, _::utf8>> = d, lines} = token} -> - # Could be a time - case Lexer.peek(lexer) do - {:ok, {?:, _, _, _}} -> - # This is a local time - Lexer.push(lexer, token) - time(lexer) - - _ -> - # It's just an integer - if leader == ?0 do - # Leading zeros not allowed - {:error, {:invalid_integer, :leading_zero}, skip, lines} - else - maybe_integer(lexer, [d]) - end - end - - {:ok, {:digits, _, d, _}} -> - # Just a integer or float - maybe_integer(lexer, [d]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp maybe_integer(lexer, parts) do - case Lexer.pop(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {?., _, _, _}} -> - # Float - float(lexer, ?., [?. | parts]) - - {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' -> - # Float, need to add .0 before e, or String.to_float fails - float(lexer, ?e, [?e, ?0, ?. | parts]) - - {:ok, {?_, _, _, _}} -> - case Lexer.peek(lexer) do - {:ok, {:digits, _, d, _}} -> - # Allowed, just skip the underscore - Lexer.advance(lexer) - maybe_integer(lexer, [d | parts]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - - {:error, _, _, _} = err -> - err - end - - {:ok, {_, skip, _, lines} = token} -> - # Just an integer - Lexer.push(lexer, token) - - with {:ok, _} = result <- iodata_to_integer(parts) do - result - else - {:error, reason} -> - {:error, reason, skip, lines} - end - end - end - - defp float(lexer, signal, [last | _] = parts) do - case Lexer.pop(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {?., skip, _, lines}} -> - # Always an error at this point, as either duplicate or after E - {:error, {:invalid_float, {?., 0}}, skip, lines} - - {:ok, {sign, _, _, _}} when sign in '-+' and last == ?e -> - # +/- are allowed after e/E - float(lexer, signal, [sign | parts]) - - {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' and signal == ?. -> - # Valid if after a dot - float(lexer, ?e, [?e | parts]) - - {:ok, {?_, skip, _, lines}} when last not in '_e.' -> - # Valid only when surrounded by digits - with {:ok, {:digits, _, d, _}} <- Lexer.peek(lexer), - _ = Lexer.advance(lexer) do - float(lexer, signal, [d | parts]) - else - {:error, _, _, _} = err -> - err - - {:ok, {_, _, _, _}} -> - {:error, {:invalid_float, {?_, 0}}, skip, lines} - end - - {:ok, {:digits, _, d, _}} -> - float(lexer, signal, [d | parts]) - - {:ok, {type, skip, data, lines}} when last in 'e.' -> - # Incomplete float - {:error, {:invalid_float, {type, data}}, skip, lines} - - {:ok, {_type, skip, _data, lines} = token} when last not in '_e.' -> - # Done - Lexer.push(lexer, token) - - with {:ok, _} = result <- iodata_to_float(parts) do - result - else - {:error, reason} -> - {:error, reason, skip, lines} - end - end - end - - defp time(lexer) do - # At this point we know we have at least HH: - with {:ok, {:digits, skip, <<_::utf8, _::utf8>> = hh, lines}} <- Lexer.pop(lexer), - {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer), - {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = ss, _}} <- Lexer.pop(lexer) do - # Check for fractional - parts = [ss, ?:, mm, ?:, hh] - - parts = - case Lexer.peek(lexer) do - {:ok, {?., _, _, _}} -> - Lexer.advance(lexer) - - case Lexer.pop(lexer) do - {:ok, {:digits, _, d, _}} -> - [d, ?. | parts] - - {:ok, {type, skip, data, lines}} -> - # Invalid - throw({:error, {:invalid_token, {type, data}}, skip, lines}) - - {:error, reason, skip, lines} -> - throw({:error, {:invalid_fractional_seconds, reason}, skip, lines}) - end - - {:ok, _} -> - parts - end - - case Time.from_iso8601(iodata_to_str(parts)) do - {:ok, _} = result -> - result - - {:error, :invalid_time} -> - {:error, :invalid_time, skip, lines} - - {:error, reason} -> - {:error, {:invalid_time, reason}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - catch - :throw, {:error, _, _, _} = err -> - err - end - - defp maybe_datetime(lexer) do - # At this point we have at least YYYY- - with {:ok, {:digits, _, <<_::utf8, _::utf8, _::utf8, _::utf8>> = yy, _}} <- Lexer.pop(lexer), - {:ok, {?-, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer), - {:ok, {?-, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, skip, <<_::utf8, _::utf8>> = dd, lines}} <- Lexer.pop(lexer) do - # At this point we have a full date, check for time - case Lexer.pop(lexer) do - {:ok, {:alpha, _, "T", _}} -> - # Expecting a time - with {:ok, time} <- time(lexer) do - datetime(lexer, [dd, ?-, mm, ?-, yy], time) - end - - {:ok, {:whitespace, _, _, _}} -> - case Lexer.peek(lexer) do - {:ok, {:digits, _, <<_::utf8, _::utf8>>, _}} -> - # Expecting a time - with {:ok, time} <- time(lexer) do - datetime(lexer, [dd, ?-, mm, ?-, yy], time) - end - - _ -> - # Just a date - case Date.from_iso8601(iodata_to_str([dd, ?-, mm, ?-, yy])) do - {:ok, _} = result -> - result - - {:error, :invalid_date} -> - {:error, :invalid_date, skip, lines} - - {:error, reason} -> - {:error, {:invalid_date, reason}, skip, lines} - end - end - - {:ok, {_type, skip, _data, lines} = token} -> - # Just a date - Lexer.push(lexer, token) - - case Date.from_iso8601(iodata_to_str([dd, ?-, mm, ?-, yy])) do - {:ok, _} = result -> - result - - {:error, :invalid_date} -> - {:error, :invalid_date, skip, lines} - - {:error, reason} -> - {:error, {:invalid_date, reason}, skip, lines} - end - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp datetime(lexer, parts, time) do - # Track the current lexer position for errors - {:ok, skip, lines} = Lexer.pos(lexer) - # Convert parts to string - datestr = iodata_to_str(parts) - # At this point we have at least YYYY-mm-dd and a fully decoded time - with {_, {:ok, date}} <- {:date, Date.from_iso8601(datestr)}, - {_, {:ok, naive}} <- {:datetime, NaiveDateTime.new(date, time)} do - # We just need to check for Z or UTC offset - case Lexer.pop(lexer) do - {:ok, {:alpha, _, "Z", _}} -> - DateTime.from_naive(naive, "Etc/UTC") - - {:ok, {sign, _, _, _}} when sign in '-+' -> - # We have an offset - with {:ok, {:digits, _, <<_::utf8, _::utf8>> = hh, _}} <- Lexer.pop(lexer), - {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer) do - # Shift naive to account for offset - hours = String.to_integer(hh) - mins = String.to_integer(mm) - offset = hours * 60 * 60 + mins * 60 - - naive = - case sign do - ?- -> - NaiveDateTime.add(naive, offset * -1, :second) - - ?+ -> - NaiveDateTime.add(naive, offset, :second) - end - - DateTime.from_naive(naive, "Etc/UTC") - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_datetime_offset, {type, data}}, skip, lines} - end - - {:ok, {type, _, _, _} = token} when type in [:eof, :whitespace, :newline] -> - # Just a local date/time - Lexer.push(lexer, token) - {:ok, naive} - end - else - {:date, {:error, :invalid_date}} -> - {:error, {:invalid_date, datestr}, skip, lines} - - {:date, {:error, reason}} -> - {:error, {:invalid_date, reason, datestr}, skip, lines} - - {:datetime, {:error, :invalid_date}} -> - {:error, {:invalid_datetime, {datestr, time}}, skip, lines} - - {:datetime, {:error, reason}} -> - {:error, {:invalid_date, reason, {datestr, time}}, skip, lines} - - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - # Allowed values - # - Array - # - Inline table - # - Integer (in all forms) - # - Float - # - String - # - DateTime - defp value(lexer) do - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - Lexer.advance(lexer) - value(lexer) - - {:ok, {?\[, _skip, _, _lines}} -> - # Need to embellish some errors with line/col - with {:ok, _} = ok <- array(lexer) do - ok - else - {:error, _, _, _} = err -> - err - end - - {:ok, {?\{, _, _, _}} -> - inline_table(lexer) - - {:ok, {:hex, _, v, _}} -> - Lexer.advance(lexer) - {:ok, String.to_integer(v, 16)} - - {:ok, {:octal, _, v, _}} -> - Lexer.advance(lexer) - {:ok, String.to_integer(v, 8)} - - {:ok, {:binary, _, v, _}} -> - Lexer.advance(lexer) - {:ok, String.to_integer(v, 2)} - - {:ok, {true, _, _, _}} -> - Lexer.advance(lexer) - {:ok, true} - - {:ok, {false, _, _, _}} -> - Lexer.advance(lexer) - {:ok, false} - - {:ok, {:alpha, _, "inf", _}} -> - Lexer.advance(lexer) - {:ok, :infinity} - - {:ok, {:alpha, _, "nan", _}} -> - Lexer.advance(lexer) - {:ok, :nan} - - {:ok, {type, _, v, _}} when type in [:string, :multiline_string] -> - Lexer.advance(lexer) - {:ok, v} - - {:ok, {sign, _, _, _}} when sign in '-+' -> - maybe_integer(lexer) - - {:ok, {:digits, _, _, _}} -> - maybe_integer(lexer) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp array(lexer) do - with {:ok, {?\[, skip, _, lines}} <- pop_skip(lexer, [:whitespace]), - {:ok, elements} <- accumulate_array_elements(lexer), - {_, _, {:ok, {?\], _, _, _}}} <- - {:close, {skip, lines}, pop_skip(lexer, [:whitespace, :newline, :comment])} do - {:ok, elements} - else - {:error, _, _, _} = err -> - err - - {:close, {:error, _, _, _} = err} -> - err - - {:close, {_oline, _ocol} = opened, {:ok, {_, eskip, _, elines}}} -> - {:error, {:unclosed_array, opened}, eskip, elines} - - {:valid?, err} -> - err - end - end - - defp inline_table(lexer) do - with {:ok, {?\{, skip, _, lines}} <- pop_skip(lexer, [:whitespace]), - {:ok, elements} <- accumulate_table_elements(lexer), - {_, _, {:ok, {?\}, _, _, _}}} <- {:close, {skip, lines}, pop_skip(lexer, [:whitespace])} do - {:ok, elements} - else - {:error, _, _, _} = err -> - err - - {:close, {:error, _, _, _} = err} -> - err - - {:close, {_oskip, _olines} = opened, {:ok, {_, eskip, _, elines}}} -> - {:error, {:unclosed_inline_table, opened}, eskip, elines} - end - end - - defp accumulate_array_elements(lexer) do - accumulate_array_elements(lexer, []) - end - - defp accumulate_array_elements(lexer, acc) do - with {:ok, {type, _, _, _}} <- peek_skip(lexer, [:whitespace, :newline, :comment]), - {_, false} <- {:trailing_comma, type == ?\]}, - {:ok, value} <- value(lexer), - {:ok, {next, _, _, _}} <- peek_skip(lexer, [:whitespace]) do - if next == ?, do - Lexer.advance(lexer) - accumulate_array_elements(lexer, [value | acc]) - else - {:ok, Enum.reverse([value | acc])} - end - else - {:error, _, _, _} = err -> - err - - {:trailing_comma, true} -> - {:ok, Enum.reverse(acc)} - end - end - - defp accumulate_table_elements(lexer) do - accumulate_table_elements(lexer, %{}) - end - - defp accumulate_table_elements(lexer, acc) do - with {:ok, {type, _, _, _}} <- peek_skip(lexer, [:whitespace, :newline, :comment]), - {_, false} <- {:trailing_comma, type == ?\}}, - {:ok, key, skip, lines} <- key(lexer), - {_, _, false, _, _} <- {:key_exists, key, Map.has_key?(acc, key), skip, lines}, - {:ok, {?=, _, _, _}} <- pop_skip(lexer, [:whitespace, :comments]), - {:ok, value} <- value(lexer), - {_, {:ok, acc2}} <- {key, Builder.push_key_into_table(acc, key, value)}, - {:ok, {next, _, _, _}} <- peek_skip(lexer, [:whitespace, :comments]) do - if next == ?, do - Lexer.advance(lexer) - accumulate_table_elements(lexer, acc2) - else - {:ok, acc2} - end - else - {:error, _, _, _} = err -> - err - - {:key_exists, key, true, line, col} -> - {:error, {:key_exists, key}, line, col} - - {table, {:error, :key_exists}} -> - {:error, {:key_exists_in_table, table}, -1, -1} - - {:trailing_comma, true} -> - {:ok, acc} - - {:ok, {type, skip, data, lines} = token} -> - Lexer.push(lexer, token) - {:error, {:invalid_key_value, {type, data}}, skip, lines} - end - end - - defp key(lexer) do - result = - case pop_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, s, lines}} when type in [:digits, :alpha, :string] -> - {key(lexer, s, []), skip, lines} - - {:ok, {type, skip, _, lines}} when type in '-_' -> - {key(lexer, <<type::utf8>>, []), skip, lines} - - {:ok, {type, skip, data, lines} = token} -> - Lexer.push(lexer, token) - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - case result do - {:error, _, _, _} = err -> - err - - {{:ok, key}, skip, lines} -> - {:ok, key, skip, lines} - - {{:error, _, _, _} = err, _, _} -> - err - end - end - - defp key(lexer, word, acc) do - case Lexer.peek(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {:whitespace, _, _, _}} -> - # The only allowed continuation now is a . followed by key char - case peek_skip(lexer, [:whitespace]) do - {:ok, {?., _, _, _}} -> - Lexer.advance(lexer) - - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} when type in [:digits, :alpha, :string] -> - key(lexer, "", [word | acc]) - - {:ok, {type, _, _, _}} when type in '-_' -> - key(lexer, "", [word | acc]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - {:ok, _} -> - {:ok, Enum.reverse([word | acc])} - end - - {:ok, {type, _, s, _}} when type in [:digits, :alpha, :string] -> - Lexer.advance(lexer) - key(lexer, word <> s, acc) - - {:ok, {type, _, _, _}} when type in '-_' -> - Lexer.advance(lexer) - key(lexer, word <> iodata_to_str([type]), acc) - - {:ok, {?., _, _, _}} -> - Lexer.advance(lexer) - - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} when type in [:digits, :alpha, :string] -> - key(lexer, "", [word | acc]) - - {:ok, {type, _, _, _}} when type in '-_' -> - key(lexer, "", [word | acc]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - {:ok, _} -> - {:ok, Enum.reverse([word | acc])} - end - end - - defp iodata_to_integer(data) do - case iodata_to_str(data) do - <<?0, rest::binary>> when byte_size(rest) > 0 -> - {:error, {:invalid_integer, :leading_zero}} - - <<sign::utf8, ?0, rest::binary>> when (sign == ?- or sign == ?+) and byte_size(rest) > 0 -> - {:error, {:invalid_integer, :leading_zero}} - - s -> - {:ok, String.to_integer(s)} - end - end - - defp iodata_to_float(data) do - case iodata_to_str(data) do - <<?0, next::utf8, _::binary>> when next != ?. -> - {:error, {:invalid_float, :leading_zero}} - - <<sign::utf8, ?0, next::utf8, _::binary>> when (sign == ?- or sign == ?+) and next != ?. -> - {:error, {:invalid_float, :leading_zero}} - - s -> - {:ok, String.to_float(s)} - end - end - - defp iodata_to_str(parts) do - parts - |> Enum.reverse() - |> IO.chardata_to_string() - end - - defp pop_skip(lexer, skip) do - case Lexer.pop(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} = result -> - if :lists.member(type, skip) do - pop_skip(lexer, skip) - else - result - end - end - end - - defp peek_skip(lexer, skip) do - case Lexer.peek(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} = result -> - if :lists.member(type, skip) do - Lexer.advance(lexer) - peek_skip(lexer, skip) - else - result - end - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/document.ex b/test-community-packages-javascript/build/packages/toml/lib/document.ex deleted file mode 100644 index 730abd17f86..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/document.ex +++ /dev/null @@ -1,182 +0,0 @@ -defmodule Toml.Document do - @moduledoc false - - # Represents a TOML document, and handles conversion to a plain map - # See `Toml.Builder` for the actual logic for constructing the document. - - defstruct [:keys, :comments, :open_table, :comment_stack, :keyfun, :transforms] - - # A key is either binary or atom depending on the decoder option value - @type key :: binary | atom | term - - # A value is the fully decoded value from the TOML - @type value :: - %{key => value} - | {:table_array, [%{key => value}]} - | number - | binary - | NaiveDateTime.t() - | DateTime.t() - | Date.t() - | Time.t() - | [value] - - # A keypath is a list of keys, they are all of the same key type - @type keypath :: list(binary) | list(atom) | list(term) - - @type t :: %__MODULE__{ - keys: %{key => value}, - comments: %{keypath => binary}, - open_table: keypath | nil, - comment_stack: [binary], - keyfun: nil | (binary -> term | no_return), - transforms: [Toml.Transform.t()] - } - - @doc """ - Create a new empty TOML document - """ - @spec new(Toml.opts()) :: t - def new(opts) when is_list(opts) do - keyfun = to_key_fun(Keyword.get(opts, :keys, :strings)) - transforms = Keyword.get(opts, :transforms, []) - - %__MODULE__{ - keys: %{}, - comments: %{}, - open_table: nil, - comment_stack: [], - keyfun: keyfun, - transforms: transforms - } - end - - @doc """ - Convert the given TOML document to a plain map. - - During conversion to a plain map, keys are converted according - to the key type defined when the document was created. - - In addition to converting keys, if transforms were defined, they are - applied to values depth-first, bottom-up. Transforms are first composed - into a single function, designed to be executed in the order they appear - in the list provided; if any transform returns an error, conversion is - stopped and an error is returned - otherwise, the value is passed from - transformer to transformer and the final result replaces the value in the - document. - """ - def to_map(%__MODULE__{keys: keys, keyfun: keyfun, transforms: ts}) do - transform = - case ts do - [] -> - nil - - ts when is_list(ts) -> - Toml.Transform.compose(ts) - end - - {:ok, to_map2(keys, keyfun, transform)} - catch - _, {:error, {:keys, {:non_existing_atom, _}}} = err -> - err - end - - # Called when a table is being converted - defp to_map2(m, nil, nil) when is_map(m) do - for {k, v} <- m, into: %{}, do: {k, to_map3(k, v, nil, nil)} - end - - defp to_map2(m, keyfun, nil) when is_map(m) and is_function(keyfun, 1) do - for {k, v} <- m, into: %{} do - k2 = keyfun.(k) - {k2, to_map3(k2, v, keyfun, nil)} - end - end - - defp to_map2(m, nil, transform) when is_map(m) and is_function(transform, 2) do - for {k, v} <- m, into: %{} do - v2 = to_map3(k, v, nil, transform) - {k, v2} - end - end - - defp to_map2(m, keyfun, transform) - when is_map(m) and is_function(keyfun, 1) and is_function(transform, 2) do - for {k, v} <- m, into: %{} do - k2 = keyfun.(k) - v2 = to_map3(k2, v, keyfun, transform) - {k2, v2} - end - end - - # Called when a table value is being converted - defp to_map3(_key, %_{} = s, _keyfun, nil), do: s - defp to_map3(key, %_{} = s, _keyfun, transform), do: transform.(key, s) - - defp to_map3(key, list, keyfun, nil) when is_list(list) do - for v <- list, do: to_map3(key, v, keyfun, nil) - end - - defp to_map3(key, list, _keyfun, transform) when is_list(list) do - transform.(key, list) - end - - defp to_map3(_key, {:table_array, list}, keyfun, nil) do - for v <- Enum.reverse(list) do - to_map2(v, keyfun, nil) - end - end - - defp to_map3(key, {:table_array, list}, keyfun, transform) do - for v <- Enum.reverse(list) do - to_map2(v, keyfun, transform) - end - |> (&transform.(key, &1)).() - end - - defp to_map3(_key, v, keyfun, nil) when is_map(v) do - to_map2(v, keyfun, nil) - end - - defp to_map3(key, v, keyfun, transform) when is_map(v) and is_function(transform) do - transform.(key, to_map2(v, keyfun, transform)) - end - - defp to_map3(_key, v, _keyfun, nil), do: v - defp to_map3(key, v, _keyfun, transform), do: transform.(key, v) - - # Convert the value of `:keys` to a key conversion function (if not already one) - @valid_keys_opts [:atoms, :atoms!, :strings, "(key :: String.t) -> term"] - defp to_key_fun(:atoms), do: &to_atom/1 - defp to_key_fun(:atoms!), do: &to_existing_atom/1 - defp to_key_fun(:strings), do: nil - defp to_key_fun(fun) when is_function(fun, 1), do: fun - defp to_key_fun(invalid), do: throw({:badarg, {:keys, invalid, @valid_keys_opts}}) - - # Convert the given key (as binary) to an atom - # Handle converting uppercase keys to module names rather than plain atoms - defp to_atom(<<c::utf8, _::binary>> = key) when c >= ?A and c <= ?Z do - Module.concat([key]) - end - - defp to_atom(key), do: String.to_atom(key) - - # Convert the given key (as binary) to an existing atom - # Handle converting uppercase keys to module names rather than plain atoms - # - # NOTE: This throws an error if the atom does not exist, and is intended to - # be handled in the decoder - defp to_existing_atom(<<c::utf8, _::binary>> = key) when c >= ?A and c <= ?Z do - Module.concat([String.to_existing_atom(key)]) - rescue - _ -> - throw({:error, {:keys, {:non_existing_atom, key}}}) - end - - defp to_existing_atom(key) do - String.to_existing_atom(key) - rescue - _ -> - throw({:error, {:keys, {:non_existing_atom, key}}}) - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/error.ex b/test-community-packages-javascript/build/packages/toml/lib/error.ex deleted file mode 100644 index c4690b7b333..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/error.ex +++ /dev/null @@ -1,143 +0,0 @@ -defmodule Toml.Error do - @moduledoc false - - defexception [:message, :reason] - - def exception(msg) when is_binary(msg) do - %__MODULE__{message: msg, reason: nil} - end - - def exception({:error, reason}) do - %__MODULE__{message: format_reason(reason), reason: reason} - end - - def exception(reason) when is_tuple(reason) do - %__MODULE__{message: format_reason(reason), reason: reason} - end - - def message(%__MODULE__{message: message}) do - message - end - - @doc """ - Convert internal error reasons into friendly, printable form - """ - def format_reason({:keys, {:non_existing_atom, key}}), - do: "unable to convert '#{key}' to an existing atom" - - def format_reason({:expected, token, other}), - do: "expected #{format_token(token)}, but got #{format_token(other)}" - - def format_reason({:invalid_token, token}), - do: "invalid token #{format_token(token)}" - - def format_reason({:invalid_integer, :leading_zero}), - do: "invalid integer syntax, leading zeros are not allowed" - - def format_reason({:invalid_float, :leading_zero}), - do: "invalid float syntax, leading zeros are not allowed" - - def format_reason({:invalid_float, token}), - do: "invalid float syntax, unexpected token #{format_token(token)}" - - def format_reason({:invalid_datetime, reason}), - do: "invalid datetime syntax, #{inspect(reason)}" - - def format_reason({:invalid_datetime_offset, reason}), - do: "invalid datetime offset syntax, #{inspect(reason)}" - - def format_reason({:invalid_date, reason}), - do: "invalid date syntax, #{inspect(reason)}" - - def format_reason({:invalid_time, reason}), - do: "invalid time syntax, #{inspect(reason)}" - - def format_reason({:invalid_key_value, token}), - do: "invalid key/value syntax, unexpected token #{format_token(token)}" - - def format_reason({:unclosed_table_array_name, token}), - do: "unclosed table array name at #{format_token(token)}" - - def format_reason({:unclosed_array, {oline, ocol}}), - do: "unclosed array started on line #{oline}, column #{ocol}" - - def format_reason({:unclosed_inline_table, {oline, ocol}}), - do: "unclosed inline table started on line #{oline}, column #{ocol}" - - def format_reason(:unclosed_quote), - do: "unclosed quoted string" - - def format_reason(:unexpected_newline), - do: "unexpected newline in single-quoted string" - - def format_reason(:unexpected_eof), - do: "unexpected end of file" - - def format_reason({:invalid_escape, char}), - do: "illegal escape sequence #{char}" - - def format_reason({:invalid_control_char, char}) do - if String.printable?(char) do - "illegal control character #{inspect(char, base: :hex)} ('#{char}')" - else - "illegal control character #{inspect(char, base: :hex)}" - end - end - - def format_reason({:invalid_char, char}) do - if String.printable?(char) do - "illegal character #{inspect(char, base: :hex)} ('#{char}')" - else - "illegal character #{inspect(char, base: :hex)}" - end - end - - def format_reason({:invalid_unicode, char}) do - if String.printable?(char) do - "illegal unicode escape, #{inspect(char, base: :hex)} ('#{char}')" - else - "illegal unicode escape, #{inspect(char, base: :hex)}" - end - end - - def format_reason({:key_exists, key}) do - "cannot redefine key in path '#{key}'" - end - - def format_reason({:badarg, option, value, valid}) when is_list(valid) do - valid = - valid - |> Enum.map(fn - a when is_atom(a) -> - "#{inspect(a)}" - - s when is_binary(s) -> - s - - v -> - "#{inspect(v)}" - end) - |> Enum.join(", ") - - "invalid value `#{inspect(value)}` for option #{inspect(option)}; must be one of [#{valid}]" - end - - def format_reason(reason), do: "#{inspect(reason)}" - - # Format a token in `{type, data}`, or `type` form into printable representation - defp format_token({true, _}), do: "'true'" - defp format_token({false, _}), do: "'false'" - defp format_token(:newline), do: "'\\n'" - - defp format_token({_, data}) when is_binary(data), - do: "'#{data}'" - - defp format_token({token, data}) when is_atom(token), - do: "'#{data}' (#{token})" - - defp format_token({token, _}), - do: "'#{<<token>>}'" - - defp format_token(token), - do: "'#{<<token>>}'" -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer.ex deleted file mode 100644 index 58824f1d3e1..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/lexer.ex +++ /dev/null @@ -1,392 +0,0 @@ -defmodule Toml.Lexer do - @moduledoc false - - import __MODULE__.Guards - - defstruct [:pid] - - @type t :: %__MODULE__{pid: pid} - - # The type of the token - @type type :: - :whitespace - | :newline - | :comment - | :digits - | :hex - | :octal - | :binary - | :alpha - | __MODULE__.String.type() - | boolean - | non_neg_integer - | :eof - # The number of bytes in the input to skip to reach the beginning of the token - @type skip :: non_neg_integer - # The data representation of a token (either size, a character, or string) - @type data :: non_neg_integer | binary - # The line number of the token - @type lines :: non_neg_integer - # The full shape of a token - @type token :: {type, skip, data, lines} - # The shape of errors the lexer produces - @type lexer_err :: {:error, term, skip, lines} - # The shape of the lexer stack - @type stack :: [token] | lexer_err - # The shape of replies which return tokens - @type token_reply :: - {:ok, token} - | lexer_err - - @doc """ - Creates a new Lexer with the given binary content. - - The lexer is a process, which manages the state of the lexer, - and provides the following benefits: - - - Only lexes content as the decoder walks the document, minimizing - the work performed, and resources (i.e. memory) used. - - Allows pushing an arbitrary tokens back on the stack, allowing the - decoder to "rewind" the lexer and try an alternative path. - - Lexing the next token happens concurrently with the decoder handling the last token - - Currently, the lexer will build up strings for most tokens and send them back to - the decoder, since these are running in separate processes, this means all string data - contained in the tokens is copied. For some tokens, like comments, the lexer will send - only the token type (e.g. `:comment`), and indexes into the original input, so that the - content can be extracted only when needed, and in the most efficient manner possible. In - the future, the lexer will do this will all tokens, allowing us to only make copies or store - references into the original input when absolutely needed. We do not do this currently, as - strings in TOML have escapes, which need to be unescaped during parsing. This could be deferred - and done in the decoder, but is not done so right now. - - Returns `{:ok, %#{__MODULE__}{}}`. - """ - @spec new(binary) :: {:ok, t} - def new(content) when is_binary(content) do - {:ok, pid} = :proc_lib.start_link(__MODULE__, :init, [self(), content]) - {:ok, %__MODULE__{pid: pid}} - end - - @doc """ - Pops the next token from the lexer. This advances the lexer to the next token. - """ - @spec pop(t) :: token_reply - def pop(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :pop) - - @doc """ - Advances the lexer to the next token, without returning the current token on the stack, - effectively skipping the current token. - """ - @spec advance(t) :: :ok - def advance(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :advance) - - @doc """ - Peeks at the next token the lexer will return from `pop/1`. - - Always returns the same result until the lexer advances. - """ - @spec peek(t) :: token_reply - def peek(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :peek) - - @doc """ - Pushes a token back on the lexer's stack. - - You may push as many tokens back on the stack as desired. - """ - @spec push(t, token) :: :ok - def push(%__MODULE__{pid: pid}, {_type, _skip, _data, _lines} = token) when is_pid(pid), - do: server_call(pid, {:push, token}) - - @doc """ - Retrieves the position of the lexer in the current input - """ - @spec pos(t) :: {:ok, skip, lines} - def pos(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :pos) - - @doc """ - Terminates the lexer process. - """ - @spec stop(t) :: :ok - def stop(%__MODULE__{pid: pid}) when is_pid(pid) do - if Process.alive?(pid) do - server_call(pid, :stop) - else - :ok - end - end - - @doc """ - Converts the lexer in to a `Stream`. Not currently used. - """ - @spec stream(t) :: Enumerable.t() - def stream(%__MODULE__{} = lexer) do - Stream.resource( - fn -> {lexer, false, false} end, - fn - {_lexer, true, _error?} = acc -> - {:halt, acc} - - {_lexer, _eof?, true} = acc -> - {:halt, acc} - - {lexer, false, false} -> - case pop(lexer) do - {:error, _, _, _} = err -> - {[err], {lexer, false, true}} - - {:ok, {:eof, _, _, _}} = ok -> - {[ok], {lexer, true, false}} - - {:ok, _} = ok -> - {[ok], {lexer, false, false}} - end - end, - fn {lexer, _, _} -> stop(lexer) end - ) - end - - ## Private - - def init(parent, {:stream, stream}) when is_pid(parent) do - init(parent, Enum.into(stream, <<>>)) - end - - def init(parent, data) when is_pid(parent) and is_binary(data) do - Process.flag(:trap_exit, true) - :proc_lib.init_ack(parent, {:ok, self()}) - lex(parent, :sys.debug_options([]), data, 0, 1, []) - end - - # If an error is on the stack keep it there unless we push a valid token back on - @spec lex(pid, term, binary, skip, lines, stack) :: no_return - defp lex(parent, debug, data, skip, lines, {:error, _, eskip, elines} = err) do - receive do - {:EXIT, ^parent, reason} -> - exit(reason) - - {from, :stop} -> - send(from, {self(), :ok}) - exit(:normal) - - {from, {:push, {_type, _tskip, _tsize, _tline} = token}} -> - send(from, {self(), :ok}) - lex(parent, debug, data, skip, lines, [token]) - - {from, op} when op in [:pop, :peek, :advance] -> - send(from, {self(), err}) - lex(parent, debug, data, skip, lines, err) - - {from, :pos} -> - send(from, {self(), {:ok, eskip, elines}}) - lex(parent, debug, data, skip, lines, err) - end - end - - defp lex(parent, debug, data, skip, lines, []) do - case do_lex(data, skip, lines) do - {:error, _, _, _} = err -> - lex(parent, debug, data, skip, lines, err) - - {:ok, data, {_type, skip, _size, lines} = token} -> - lex(parent, debug, data, skip, lines, [token]) - end - end - - defp lex(parent, debug, data, skip, lines, [{_, tskip, _, tlines} = token | stack] = ostack) do - receive do - {:EXIT, ^parent, reason} -> - exit(reason) - - {from, :stop} -> - send(from, {self(), :ok}) - exit(:normal) - - {from, :pop} -> - send(from, {self(), {:ok, token}}) - lex(parent, debug, data, skip, lines, stack) - - {from, :advance} -> - send(from, {self(), :ok}) - lex(parent, debug, data, skip, lines, stack) - - {from, :peek} -> - send(from, {self(), {:ok, token}}) - lex(parent, debug, data, skip, lines, ostack) - - {from, {:push, pushed}} -> - send(from, {self(), :ok}) - lex(parent, debug, data, skip, lines, [pushed | ostack]) - - {from, :pos} -> - send(from, {self(), {:ok, tskip, tlines}}) - lex(parent, debug, data, skip, lines, ostack) - end - end - - @spec do_lex(binary, skip, lines) :: {:ok, binary, token} | {:error, term, skip, lines} - defp do_lex(data, skip, lines) - - defp do_lex(<<>> = data, skip, lines), - do: {:ok, data, {:eof, skip, 0, lines}} - - defp do_lex(<<?\#, rest::binary>>, skip, lines), - do: lex_comment(rest, skip + 1, 0, lines) - - defp do_lex(<<?\r, ?\n, rest::binary>>, skip, lines), - do: {:ok, rest, {:newline, skip + 2, 0, lines + 1}} - - defp do_lex(<<?\n, rest::binary>>, skip, lines), - do: {:ok, rest, {:newline, skip + 1, 0, lines + 1}} - - defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), - do: lex_whitespace(rest, skip + 1, lines) - - defp do_lex(<<"true", rest::binary>>, skip, lines), - do: {:ok, rest, {true, skip + 4, 0, lines}} - - defp do_lex(<<"false", rest::binary>>, skip, lines), - do: {:ok, rest, {false, skip + 5, 0, lines}} - - defp do_lex(<<?=, rest::binary>>, skip, lines), - do: {:ok, rest, {?=, skip + 1, 0, lines}} - - defp do_lex(<<?., rest::binary>>, skip, lines), - do: {:ok, rest, {?., skip + 1, 0, lines}} - - defp do_lex(<<?\[, rest::binary>>, skip, lines), - do: {:ok, rest, {?\[, skip + 1, 0, lines}} - - defp do_lex(<<?\], rest::binary>>, skip, lines), - do: {:ok, rest, {?\], skip + 1, 0, lines}} - - defp do_lex(<<?\{, rest::binary>>, skip, lines), - do: {:ok, rest, {?\{, skip + 1, 0, lines}} - - defp do_lex(<<?\}, rest::binary>>, skip, lines), - do: {:ok, rest, {?\}, skip + 1, 0, lines}} - - defp do_lex(<<?+, rest::binary>>, skip, lines), - do: {:ok, rest, {?+, skip + 1, 0, lines}} - - defp do_lex(<<?-, rest::binary>>, skip, lines), - do: {:ok, rest, {?-, skip + 1, 0, lines}} - - defp do_lex(<<?:, rest::binary>>, skip, lines), - do: {:ok, rest, {?:, skip + 1, 0, lines}} - - defp do_lex(<<?,, rest::binary>>, skip, lines), - do: {:ok, rest, {?,, skip + 1, 0, lines}} - - defp do_lex(<<?_, rest::binary>>, skip, lines), - do: {:ok, rest, {?_, skip + 1, 0, lines}} - - defp do_lex(<<?0, ?x, c::utf8, rest::binary>>, skip, lines) when is_hex(c), - do: lex_hex(rest, skip + 3, [c], lines) - - defp do_lex(<<?0, ?o, c::utf8, rest::binary>>, skip, lines) when is_octal(c), - do: lex_octal(rest, skip + 3, [c], lines) - - defp do_lex(<<?0, ?b, c::utf8, rest::binary>>, skip, lines) when is_bin(c), - do: lex_binary(rest, skip + 3, [c], lines) - - defp do_lex(<<c::utf8, _::binary>> = data, skip, lines) when is_quote(c), - do: __MODULE__.String.lex(data, skip, lines) - - defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_digit(c), - do: lex_digits(rest, skip + 1, [c], lines) - - defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_alpha(c), - do: lex_alpha(rest, skip + 1, [c], lines) - - defp do_lex(<<c::utf8, _::binary>>, skip, lines), - do: {:error, {:invalid_char, <<c::utf8>>}, skip + 1, lines} - - defp lex_whitespace(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), - do: lex_whitespace(rest, skip + 1, lines) - - defp lex_whitespace(rest, skip, lines), - do: {:ok, rest, {:whitespace, skip, 0, lines}} - - defp lex_comment(<<?\r, ?\n, rest::binary>>, skip, size, lines), - do: {:ok, rest, {:comment, skip + 2, size, lines + 1}} - - defp lex_comment(<<?\n, rest::binary>>, skip, size, lines), - do: {:ok, rest, {:comment, skip + 1, size, lines + 1}} - - defp lex_comment(<<_::utf8, rest::binary>>, skip, size, lines), - do: lex_comment(rest, skip + 1, size + 1, lines) - - defp lex_comment(<<>> = rest, skip, size, lines), - do: {:ok, rest, {:comment, skip, size, lines}} - - defp lex_digits(<<c::utf8, rest::binary>>, skip, acc, lines) when is_digit(c), - do: lex_digits(rest, skip + 1, [c | acc], lines) - - defp lex_digits(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:digits, skip, bin, lines}} - end - - defp lex_hex(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) - when is_hex(c) and is_hex(d), - do: lex_hex(rest, skip + 3, [d, c | acc], lines) - - defp lex_hex(<<c::utf8, rest::binary>>, skip, acc, lines) when is_hex(c), - do: lex_hex(rest, skip + 1, [c | acc], lines) - - defp lex_hex(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:hex, skip, bin, lines}} - end - - defp lex_octal(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) - when is_octal(c) and is_octal(d), - do: lex_octal(rest, skip + 3, [d, c | acc], lines) - - defp lex_octal(<<c::utf8, rest::binary>>, skip, acc, lines) when is_octal(c), - do: lex_octal(rest, skip + 1, [c | acc], lines) - - defp lex_octal(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:octal, skip, bin, lines}} - end - - defp lex_binary(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) - when is_bin(c) and is_bin(d), - do: lex_binary(rest, skip + 3, [d, c | acc], lines) - - defp lex_binary(<<c::utf8, rest::binary>>, skip, acc, lines) when is_bin(c), - do: lex_binary(rest, skip + 1, [c | acc], lines) - - defp lex_binary(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:binary, skip, bin, lines}} - end - - defp lex_alpha(<<c::utf8, rest::binary>>, skip, acc, lines) when is_alpha(c), - do: lex_alpha(rest, skip + 1, [c | acc], lines) - - defp lex_alpha(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:alpha, skip, bin, lines}} - end - - defp server_call(pid, msg) do - ref = Process.monitor(pid) - send(pid, {self(), msg}) - - receive do - {:DOWN, ^ref, _type, _pid, info} -> - {:error, info} - - {^pid, reply} -> - Process.demonitor(ref, [:flush]) - reply - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex deleted file mode 100644 index bd3df5f7c27..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex +++ /dev/null @@ -1,21 +0,0 @@ -defmodule Toml.Lexer.Guards do - @moduledoc false - - defguard is_lowercase(c) when c >= ?a and c <= ?z - - defguard is_uppercase(c) when c >= ?A and c <= ?Z - - defguard is_alpha(c) when is_lowercase(c) or is_uppercase(c) - - defguard is_digit(c) when c >= ?0 and c <= ?9 - - defguard is_hex(c) when is_digit(c) or (c >= ?a and c <= ?z) or (c >= ?A and c <= ?Z) - - defguard is_octal(c) when c >= ?0 and c <= ?8 - - defguard is_bin(c) when c == ?0 or c == ?1 - - defguard is_whitespace(c) when c == ?\s or c == ?\t - - defguard is_quote(c) when c == ?\" or c == ?\' -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex deleted file mode 100644 index dbe7635f699..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex +++ /dev/null @@ -1,294 +0,0 @@ -defmodule Toml.Lexer.String do - @moduledoc false - - # This module manages the complexity of lexing quoted and literal - # strings as defined by the TOML spec. - - import Toml.Lexer.Guards - - @type type :: - :string - | :multiline_string - - @type skip :: Toml.Lexer.skip() - @type lines :: Toml.Lexer.lines() - @type lexer_err :: Toml.Lexer.lexer_err() - @type result :: {:ok, binary, {type, skip, binary, lines}} | lexer_err - - @spec lex(binary, skip, lines) :: result - def lex(binary, skip, lines) - - def lex(<<>>, skip, lines), - do: {:error, :unexpected_eof, skip, lines} - - def lex(<<?\', ?\', ?\', rest::binary>>, skip, lines) do - {rest, skip, lines} = trim_newline(rest, skip + 3, lines) - lex_literal(:multi, rest, skip, [], lines) - end - - def lex(<<?\', ?\', rest::binary>>, skip, lines), - do: {:ok, rest, {:string, skip + 2, <<>>, lines}} - - def lex(<<?\', rest::binary>>, skip, lines), - do: lex_literal(:single, rest, skip + 1, [], lines) - - def lex(<<?\", ?\", ?\", rest::binary>>, skip, lines) do - {rest, skip, lines} = trim_newline(rest, skip + 3, lines) - lex_quoted(:multi, rest, skip, [], lines) - end - - def lex(<<?\", ?\", rest::binary>>, skip, lines), - do: {:ok, rest, {:string, skip + 2, <<>>, lines}} - - def lex(<<?\", rest::binary>>, skip, lines), - do: lex_quoted(:single, rest, skip + 1, [], lines) - - defp lex_literal(_type, <<>>, skip, _acc, lines), - do: {:error, :unclosed_quote, skip, lines} - - # Disallow newlines in single-line literals - defp lex_literal(:single, <<?\r, ?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_literal(:single, <<?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_literal(type, <<?\r, ?\n, rest::binary>>, skip, acc, lines), - do: lex_literal(type, rest, skip + 2, [?\n | acc], lines + 1) - - defp lex_literal(type, <<?\n, rest::binary>>, skip, acc, lines), - do: lex_literal(type, rest, skip + 1, [?\n | acc], lines + 1) - - # Closing quotes - defp lex_literal(:single, <<?\', rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:string, skip + 1, bin, lines}} - end - - defp lex_literal(:multi, <<?\', ?\', ?\', rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:multiline_string, skip + 3, bin, lines}} - end - - # Disallow any control chars in single quoted literals - defp lex_literal(:single, <<c::utf8, _::binary>>, skip, _acc, lines) - when (c >= 0 and c <= 31) or c == 127, - do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} - - # Disallow any control chars in single quoted literals, EXCEPT \t in multi-line literals - defp lex_literal(:multi, <<?\t, rest::binary>>, skip, acc, lines), - do: lex_literal(:multi, rest, skip + 1, [?\t | acc], lines) - - defp lex_literal(:multi, <<c::utf8, _::binary>>, skip, _acc, lines) - when (c >= 0 and c <= 31) or c == 127, - do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} - - # Eat next character in string - defp lex_literal(type, <<c::utf8, rest::binary>>, skip, acc, lines), - do: lex_literal(type, rest, skip + 1, [c | acc], lines) - - # Invalid byte sequence (i.e. invalid unicode) - defp lex_literal(_type, <<c, _::binary>>, skip, _acc, lines), - do: {:error, {:invalid_unicode, <<c>>}, skip + 1, lines} - - defp lex_quoted(_type, <<>>, skip, _acc, lines), - do: {:error, :unclosed_quote, skip, lines} - - # Disallow newlines in single-line strings - defp lex_quoted(:single, <<?\r, ?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_quoted(:single, <<?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_quoted(type, <<?\r, ?\n, rest::binary>>, skip, acc, lines), - do: lex_quoted(type, rest, skip + 2, [?\n | acc], lines + 1) - - defp lex_quoted(type, <<?\n, rest::binary>>, skip, acc, lines), - do: lex_quoted(type, rest, skip + 1, [?\n | acc], lines + 1) - - # Allow escaping newlines in multi-ine strings - defp lex_quoted(:multi, <<?\\, ?\r, ?\n, rest::binary>>, skip, acc, lines) do - {rest, skip, lines} = trim_whitespace(rest, skip + 3, lines + 1) - lex_quoted(:multi, rest, skip, acc, lines) - end - - defp lex_quoted(:multi, <<?\\, ?\n, rest::binary>>, skip, acc, lines) do - {rest, skip, lines} = trim_whitespace(rest, skip + 2, lines + 1) - lex_quoted(:multi, rest, skip, acc, lines) - end - - # Trim trailing whitespace at end of line - defp lex_quoted(:multi, <<?\\, ?\s, rest::binary>>, skip, acc, lines) do - lex_quoted(:multi, <<?\\, rest::binary>>, skip, acc, lines) - end - - # Allowed escapes - defp lex_quoted(type, <<?\\, ?\\, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\\ | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?b, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\b | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?d, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\d | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?f, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\f | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?n, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\n | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?r, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\r | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?t, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\t | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?\", rest::binary>>, skip, acc, lines), - do: lex_quoted(type, rest, skip + 2, [?\" | acc], lines) - - defp lex_quoted(type, <<?\\, ?u, rest::binary>>, skip, acc, lines) do - {char, rest, skip2} = unescape_unicode(?u, rest) - lex_quoted(type, rest, 2 + skip + skip2, [char | acc], lines) - catch - :throw, {:invalid_unicode, _} = reason -> - {:error, reason, skip + 1, lines} - end - - defp lex_quoted(type, <<?\\, ?U, rest::binary>>, skip, acc, lines) do - {char, rest, skip2} = unescape_unicode(?U, rest) - lex_quoted(type, rest, 2 + skip + skip2, [char | acc], lines) - catch - :throw, {:invalid_unicode, _} = reason -> - {:error, reason, skip + 1, lines} - end - - # Bad escape - defp lex_quoted(_type, <<?\\, char::utf8, _::binary>>, skip, _acc, lines) do - {:error, {:invalid_escape, <<?\\, char::utf8>>}, skip + 1, lines} - end - - # Closing quotes - defp lex_quoted(:multi, <<?\", ?\", ?\", rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:multiline_string, skip + 3, bin, lines}} - end - - defp lex_quoted(:single, <<?\", rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:string, skip + 1, bin, lines}} - end - - # Disallow any unescaped control chars in quoted strings - defp lex_quoted(_type, <<c::utf8, _::binary>>, skip, _acc, lines) - when (c >= 0 and c <= 31) or c == 127, - do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} - - # Eat next character in string - defp lex_quoted(type, <<c::utf8, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 1, [c | acc], lines) - end - - defp lex_quoted(_type, <<c, _::binary>>, skip, _acc, lines), - do: {:error, {:invalid_unicode, <<c>>}, skip + 1, lines} - - defp trim_newline(<<?\r, ?\n, rest::binary>>, skip, lines), do: {rest, skip + 2, lines + 1} - defp trim_newline(<<?\n, rest::binary>>, skip, lines), do: {rest, skip + 1, lines + 1} - defp trim_newline(rest, skip, lines), do: {rest, skip, lines} - - # Trims whitespace (tab, space) up until next non-whitespace character, - # or until closing delimiter. Only allowed with mulit-line quoted strings. - defp trim_whitespace(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), - do: trim_whitespace(rest, skip + 1, lines) - - defp trim_whitespace(<<?\", ?\", ?\", _::binary>> = rest, skip, lines), - do: {rest, skip, lines} - - defp trim_whitespace(rest, skip, lines), - do: {rest, skip, lines} - - def unescape_unicode(?U, <<n::8-binary, bin::binary>>) do - char = - case :erlang.binary_to_integer(n, 16) do - u when u <= 0x007F -> - <<u>> - - u when 0x0080 <= u and u <= 0x07FF -> - u1 = div(u, 64) + 192 - u2 = mod(u, 64) + 128 - <<u1, u2>> - - u when (0x0080 <= u and u <= 0xD7FF) or (0xE000 <= u and u <= 0xFFFF) -> - u1 = div(u, 4096) + 224 - u2 = div(mod(u, 4096), 64) + 128 - u3 = mod(u, 64) + 128 - <<u1, u2, u3>> - - u -> - u1 = div(u, 262_144) + 240 - u2 = div(mod(u, 262_144), 4096) + 128 - u3 = div(mod(u, 4096), 64) + 128 - u4 = mod(u, 64) + 128 - <<u1, u2, u3, u4>> - end - - # Check that we have a valid utf8 encoding - case char do - <<_::utf8>> -> - {char, bin, 8} - - _ -> - bad_unicode!(char) - end - end - - def unescape_unicode(?u, <<n::4-binary, bin::binary>>) do - case :erlang.binary_to_integer(n, 16) do - high when 0xD800 <= high and high <= 0xDBFF -> - # surrogate pair - case bin do - <<?\\, ?u, n2::4-binary, bin2::binary>> -> - case :erlang.binary_to_integer(n2, 16) do - low when 0xDC00 <= low and low <= 0xDFFF -> - <<u::utf16>> = <<high::16, low::16>> - {<<u::utf8>>, bin2, 4 + 6} - - _ -> - bad_unicode!(n) - end - - _ -> - bad_unicode!(n) - end - - # second part of surrogate pair (without first part) - u when (0xDC00 <= u and u <= 0xDFFF) or u < 0 -> - bad_unicode!(n) - - u -> - {<<u::utf8>>, bin, 4} - end - catch - :error, :badarg -> - bad_unicode!(n) - end - - def unescape_unicode(_type, <<c, _::binary>>) do - bad_unicode!(<<c>>) - end - - @spec bad_unicode!(binary) :: no_return - defp bad_unicode!(byte), do: throw({:invalid_unicode, byte}) - - defp mod(x, y) when x > 0, do: rem(x, y) - defp mod(x, y) when x < 0, do: y + rem(x, y) - defp mod(0, _), do: 0 -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/provider.ex b/test-community-packages-javascript/build/packages/toml/lib/provider.ex deleted file mode 100644 index 400d72a3478..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/provider.ex +++ /dev/null @@ -1,227 +0,0 @@ -defmodule Toml.Provider do - @moduledoc """ - This module provides an implementation of both the Distilery and Elixir - config provider behaviours, so that TOML files can be used for configuration - in releases. - - ## Distillery Usage - - Add the following to your `rel/config.exs` - - release :myapp do - # ...snip... - set config_providers: [ - {Toml.Provider, [path: "${XDG_CONFIG_DIR}/myapp.toml", transforms: [...]]} - ] - end - - ## Elixir Usage - - config_providers: [ - {Toml.Provider, [ - path: {:system, "XDG_CONFIG_DIR", "myapp.toml"}, - transforms: [...] - ]} - ] - - This will result in `Toml.Provider` being invoked during boot, at which point it - will evaluate the given path and read the TOML file it finds. If one is not - found, or is not accessible, the provider will raise an error, and the boot - sequence will terminate unsuccessfully. If it succeeds, it persists settings in - the file to the application environment (i.e. you access it via - `Application.get_env/2`). - - The config provider expects a certain format to the TOML file, namely that - keys at the root of the document are tables which correspond to applications - which need to be configured. If it encounters keys at the root of the document - which are not tables, they are ignored. - - ## Options - - The same options that `Toml.parse/2` accepts are able to be provided to `Toml.Provider`, - but there are two main differences: - - * `:path` (required) - sets the path to the TOML file to load config from - * `:keys` - defaults to `:atoms`, but can be set to `:atoms!` if desired, all other - key types are ignored, as it results in an invalid config structure - - """ - has_config_api? = Version.match?(Version.parse!(System.version()), ">= 1.9.0") - - if has_config_api? do - @behaviour Config.Provider - end - - @doc false - def init(opts) when is_list(opts) do - opts = - case Keyword.get(opts, :keys) do - a when a in [:atoms, :atoms!] -> - opts - - _ -> - Keyword.put(opts, :keys, :atoms) - end - - if is_distillery_env?() do - # When running under Distillery, init performs load - load([], opts) - opts - else - # With 1.9 releases, init just preps arguments for `load` - opts - end - end - - @doc false - def load(config, opts) when is_list(opts) do - path = Keyword.fetch!(opts, :path) - # path expansion should happen in load rather than init, otherwise - # in 1.9 releases using a {:system, env_var, path} tuple an error - # will be raised if the env var is not set in the build environment - with {:ok, path} <- expand_path(path) do - map = Toml.decode_file!(path, opts) - persist(config, to_keyword(map)) - else - {:error, reason} -> - exit(reason) - end - end - - @doc false - def get([app | keypath]) do - config = Application.get_all_env(app) - - case get_in(config, keypath) do - nil -> - nil - - val -> - {:ok, val} - end - end - - if has_config_api? do - defp persist(config, keyword) when is_list(keyword) do - config = Config.Reader.merge(config, keyword) - Application.put_all_env(config, persistent: true) - config - end - else - defp persist(config, keyword) when is_list(keyword) do - # For each app - for {app, app_config} <- keyword do - # Get base config - base = Application.get_all_env(app) - base = deep_merge(base, Keyword.get(config, app, [])) - # Merge this app's TOML config over the base config - merged = deep_merge(base, app_config) - # Persist key/value pairs for this app - for {k, v} <- merged do - Application.put_env(app, k, v, persistent: true) - end - - # Return merged config - {app, merged} - end - end - - defp deep_merge(a, b) when is_list(a) and is_list(b) do - if Keyword.keyword?(a) and Keyword.keyword?(b) do - Keyword.merge(a, b, &deep_merge/3) - else - b - end - end - - defp deep_merge(_k, a, b) when is_list(a) and is_list(b) do - if Keyword.keyword?(a) and Keyword.keyword?(b) do - Keyword.merge(a, b, &deep_merge/3) - else - b - end - end - - defp deep_merge(_k, a, b) when is_map(a) and is_map(b) do - Map.merge(a, b, &deep_merge/3) - end - - defp deep_merge(_k, _a, b), do: b - end - - # At the top level, convert the map to a keyword list of keyword lists - # Keys with no children (i.e. keys which are not tables) are dropped - defp to_keyword(map) when is_map(map) do - for {k, v} <- map, v2 = to_keyword2(v), is_list(v2), into: [] do - {k, v2} - end - end - - # For all other values, convert tables to keywords - defp to_keyword2(map) when is_map(map) do - Enum.map(map, fn {k, v} -> {k, to_keyword2(v)} end) - end - - # And leave all other values untouched - defp to_keyword2(term), do: term - - def expand_path(path) when is_binary(path) do - case expand_path(path, <<>>) do - {:ok, p} -> - {:ok, Path.expand(p)} - - {:error, _} = err -> - err - end - end - - if has_config_api? do - def expand_path(path) do - {:ok, Config.Provider.resolve_config_path!(path)} - end - end - - defp expand_path(<<>>, acc), - do: {:ok, acc} - - defp expand_path(<<?$, ?\{, rest::binary>>, acc) do - case expand_var(rest) do - {:ok, var, rest} -> - expand_path(rest, acc <> var) - - {:error, _} = err -> - err - end - end - - defp expand_path(<<c::utf8, rest::binary>>, acc) do - expand_path(rest, <<acc::binary, c::utf8>>) - end - - defp expand_var(bin), - do: expand_var(bin, <<>>) - - defp expand_var(<<>>, _acc), - do: {:error, :unclosed_var_expansion} - - defp expand_var(<<?\}, rest::binary>>, acc), - do: {:ok, System.get_env(acc) || "", rest} - - defp expand_var(<<c::utf8, rest::binary>>, acc) do - expand_var(rest, <<acc::binary, c::utf8>>) - end - - defp is_distillery_env? do - if Version.match?(Version.parse!(System.version()), ">= 1.9.0") do - Code.ensure_loaded?(Distillery.Releases.Config.Provider) - else - true - end - rescue - _ -> - case :erlang.phash2(1, 1) do - 0 -> true - _ -> false - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/toml.ex b/test-community-packages-javascript/build/packages/toml/lib/toml.ex deleted file mode 100644 index c040f5c2944..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/toml.ex +++ /dev/null @@ -1,94 +0,0 @@ -defmodule Toml do - @external_resource "README.md" - - @moduledoc File.read!(Path.join([__DIR__, "..", "README.md"])) - - @type key :: binary | atom | term - @type opt :: - {:keys, :atoms | :atoms! | :string | (key -> term)} - | {:filename, String.t()} - | {:transforms, [Toml.Transform.t()]} - @type opts :: [opt] - - @type reason :: {:invalid_toml, binary} | binary - @type error :: {:error, reason} - - @doc """ - Decode the given binary as TOML content - - ## Options - - You can pass the following options to configure the decoder behavior: - - * `:filename` - pass a filename to use in error messages - * `:keys` - controls how keys in the document are decoded. Possible values are: - * `:strings` (default) - decodes keys as strings - * `:atoms` - converts keys to atoms with `String.to_atom/1` - * `:atoms!` - converts keys to atoms with `String.to_existing_atom/1` - * `(key -> term)` - converts keys using the provided function - * `:transforms` - a list of custom transformations to apply to decoded TOML values, - see `c:Toml.Transform.transform/2` for details. - - ## Decoding keys to atoms - - The `:atoms` option uses the `String.to_atom/1` call that can create atoms at runtime. - Since the atoms are not garbage collected, this can pose a DoS attack vector when used - on user-controlled data. It is recommended that if you either avoid converting to atoms, - by using `keys: :strings`, or require known keys, by using the `keys: :atoms!` option, - which will cause decoding to fail if the key is not an atom already in the atom table. - - ## Transformations - - You should rarely need custom datatype transformations, but in some cases it can be quite - useful. In particular if you want to transform things like IP addresses from their string - form to the Erlang address tuples used in most `:inet` APIs, a custom transform can ensure - that all addresses are usable right away, and that validation of those addresses is done as - part of decoding the document. - - Keep in mind that transforms add additional work to decoding, which may result in reduced - performance, if you don't need the convenience, or the validation, deferring such conversions - until the values are used may be a better approach, rather than incurring the overhead during decoding. - """ - @spec decode(binary) :: {:ok, map} | error - @spec decode(binary, opts) :: {:ok, map} | error - defdelegate decode(bin, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Same as `decode/1`, but returns the document directly, or raises `Toml.Error` if it fails. - """ - @spec decode!(binary) :: map | no_return - @spec decode!(binary, opts) :: map | no_return - defdelegate decode!(bin, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Decode the file at the given path as TOML - - Takes same options as `decode/2` - """ - @spec decode_file(binary) :: {:ok, map} | error - @spec decode_file(binary, opts) :: {:ok, map} | error - defdelegate decode_file(path, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Same as `decode_file/1`, but returns the document directly, or raises `Toml.Error` if it fails. - """ - @spec decode_file!(binary) :: map | no_return - @spec decode_file!(binary, opts) :: map | no_return - defdelegate decode_file!(path, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Decode the given stream as TOML. - - Takes same options as `decode/2` - """ - @spec decode_stream(Enumerable.t()) :: {:ok, map} | error - @spec decode_stream(Enumerable.t(), opts) :: {:ok, map} | error - defdelegate decode_stream(stream, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Same as `decode_stream/1`, but returns the document directly, or raises `Toml.Error` if it fails. - """ - @spec decode_stream!(Enumerable.t()) :: map | no_return - @spec decode_stream!(Enumerable.t(), opts) :: map | no_return - defdelegate decode_stream!(stream, opts \\ []), to: __MODULE__.Decoder -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/transform.ex b/test-community-packages-javascript/build/packages/toml/lib/transform.ex deleted file mode 100644 index 78cd21741b7..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/transform.ex +++ /dev/null @@ -1,127 +0,0 @@ -defmodule Toml.Transform do - @moduledoc """ - Defines the behavior for custom transformations of decoded TOML values. - - See the documentation for `c:transform/2` for more details. - """ - - @type t :: module - @type key :: binary | atom | term - @type keypath :: [binary] | [atom] | [term] - @type value :: - %{key => value} - | [value] - | number - | binary - | NaiveDateTime.t() - | DateTime.t() - | Date.t() - | Time.t() - - def __using__(_) do - quote do - @behaviour unquote(__MODULE__) - end - end - - @doc """ - This function is invoked for every key/value pair in the document, in a depth-first, - bottom-up, traversal of the document. - - The transformer must return one of two values: - - * `{:error, term}` - an error occurred in the transformer, and decoding should fail - * `term` - replace the value for the given key with the value returned from the - transformer in the final document - - ## Example - - An example transformation would be the conversion of tables of a certain shape to a known struct value. - - The struct: - - defmodule Server do - defstruct [:name, :ip, :ports] - end - - - TOML which contains a table of this shape: - - [servers.alpha] - ip = "192.168.1.1" - ports = [8080, 8081] - - [servers.beta] - ip = "192.168.1.2" - ports = [8082, 8083] - - - And finally, the transforer implementation: - - defmodule ServerTransform do - use Toml.Transform - - # Transform IP strings to Erlang address tuples - def transform(:ip, ip) when is_binary(ip) do - case :inet.parse_ipv4_address(String.to_charlist(ip)) do - {:ok, result} -> - result - {:error, reason} -> - {:error, {:invalid_ip, ip, reason}} - end - end - - # Non-binary values for IP addresses should return an error - def transform(:ip, ip), do: {:error, {:invalid_ip, ip, :expected_string}} - - # Transform the server objects to Server structs - def transform(:servers, servers) when is_map(servers) do - for {name, server} <- servers do - struct(Server, Map.put(server, :name, name)) - end - end - - # Non-map values for servers should return an error - def transform(:servers, s), do: {:error, {:invalid_server, s}} - - # Ignore all other values - def transform(_key, v), do: v - end - - Assuming we decode with the following options: - - Toml.decode!(content, keys: :atoms, transforms: [ServerTransform]) - - The result would be: - - %{ - servers: [ - %Server{name: :alpha, ip: {192,168,1,1}, ports: [8080, 8081]}, - %Server{name: :beta, ip: {192,168,1,2}, ports: [8082, 8083]} - ] - } - - """ - @callback transform(key, value) :: {:error, term} | term - - # Given a list of transform functions, compose them into a single transformation pass - @doc false - def compose(mods) when is_list(mods) do - Enum.reduce(mods, nil, &compose_transforms/2) - end - - # The first transform in the list does not require composition - defp compose_transforms(mod, nil), do: &mod.transform/2 - # All subsequent transforms are composed with the previous - defp compose_transforms(mod, acc) when is_atom(mod) and is_function(acc) do - fn k, v -> - case acc.(k, v) do - {:error, _} = err -> - throw(err) - - v2 -> - mod.transform(k, v2) - end - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/mix.exs b/test-community-packages-javascript/build/packages/toml/mix.exs deleted file mode 100644 index cc5511df9f2..00000000000 --- a/test-community-packages-javascript/build/packages/toml/mix.exs +++ /dev/null @@ -1,125 +0,0 @@ -defmodule Toml.MixProject do - use Mix.Project - - @version "0.7.0" - @source_url "https://github.com/bitwalker/toml-elixir" - - def project do - [ - app: :toml, - version: @version, - elixir: "~> 1.9", - start_permanent: Mix.env() == :prod, - consolidate_protocols: Mix.env() != :test, - description: "An implementation of TOML for Elixir projects", - package: package(), - deps: deps(), - aliases: aliases(Mix.env()), - preferred_cli_env: [ - bench: :bench, - "bench.decoder": :bench, - "bench.lexer": :bench, - docs: :docs, - "hex.publish": :docs, - coveralls: :test, - "coveralls.html": :test, - "coveralls.details": :test - ], - dialyzer: dialyzer(), - docs: docs(), - elixirc_paths: elixirc_paths(Mix.env()), - escript: escript(Mix.env()), - test_coverage: [tool: ExCoveralls] - ] - end - - # Run "mix help compile.app" to learn about applications. - def application do - [ - extra_applications: [] - ] - end - - # Run "mix help deps" to learn about dependencies. - defp deps do - [ - {:ex_doc, ">= 0.0.0", only: [:docs]}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, - {:benchee, "~> 1.0", only: [:bench]}, - {:benchee_html, "~> 1.0", only: [:bench]}, - {:jason, "~> 1.0", only: [:test, :bench]}, - {:excoveralls, "~> 0.9", only: [:test]} - # For benchmarking, though none of these libraries work at this point - # {:tomlex, "~> 0.0.5", only: [:bench]}, - # {:toml_elixir, "~> 2.0.1", only: [:bench]}, - # {:jerry, "~> 0.1.4", only: [:bench]}, - # {:etoml, "~> 0.1.0", only: [:bench]}, - ] - end - - defp package do - [ - files: ["lib", "mix.exs", "README.md", "LICENSE"], - maintainers: ["Paul Schoenfelder"], - licenses: ["Apache-2.0"], - links: %{"GitHub" => @source_url} - ] - end - - defp docs do - [ - main: "readme", - source_url: @source_url, - source_ref: @version, - extras: [ - LICENSE: [title: "License"], - "README.md": [title: "Overview"] - ], - formatters: ["html"] - ] - end - - defp escript(:test) do - [ - main_module: Toml.CLI, - name: :toml, - path: Path.join([__DIR__, "bin", "toml"]) - ] - end - - defp escript(_), do: nil - - defp aliases(_env) do - [ - "compile-check": [ - "compile --warnings-as-errors", - "format --check-formatted --dry-run", - "dialyzer --format dialyxir" - ], - clean: ["clean", &clean/1], - bench: ["bench.decoder", "bench.lexer"], - "bench.decoder": ["run bench/bench.decoder.exs"], - "bench.lexer": ["run bench/bench.lexer.exs"] - ] - end - - defp elixirc_paths(:test), do: ["lib", "test/support"] - defp elixirc_paths(:bench), do: ["lib", "bench/support"] - defp elixirc_paths(_), do: ["lib"] - - defp dialyzer do - [ - ignore_warnings: "dialyzer.ignore", - flags: [:error_handling, :underspecs], - plt_core_path: System.get_env("PLT_PATH") || System.get_env("MIX_HOME") - ] - end - - defp clean(_args) do - toml = Path.join([__DIR__, "bin", "toml"]) - - if File.exists?(toml) do - _ = File.rm(toml) - end - end -end diff --git a/test-community-packages-javascript/build/packages/trie_again/LICENSE b/test-community-packages-javascript/build/packages/trie_again/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/test-community-packages-javascript/build/packages/trie_again/README.md b/test-community-packages-javascript/build/packages/trie_again/README.md deleted file mode 100644 index 0dbd9478a04..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# trie_again - -[![Package Version](https://img.shields.io/hexpm/v/trie_again)](https://hex.pm/packages/trie_again) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/trie_again/) -![CI](https://github.com/giacomocavalieri/trie_again/workflows/CI/badge.svg?branch=main) - -Tries in Gleam 🌳 - -> ⚙️ This package supports the Erlang and Javascript targets! - -## Why tries? - -A [trie](https://en.wikipedia.org/wiki/Trie) is a data structure that uses lists as keys. By taking advantage of this property it is possible to efficiently perform some queries: for example imagine you want to find all the elements that are associated with a key with the same prefix; with a trie the complexity of the lookup is linear in the size of the prefix you're looking for. - -That is why tries can be used to implement autocompleting text dictionaries, spell checking or prefix matching algorithms. - -In this example a trie is used to store words (as lists of graphemes) as keys associated with a definition. With the `subtrie` function one can look for all the elements sharing a commong prefix in their key: - -```gleam -import trie -import string - -let dictionary = - trie.new() - |> trie.insert(at: string.to_graphemes("gleam"), value: "To produce a small, bright light") - |> trie.insert(at: string.to_graphemes("gleaming"), value: "Bright and shiny") - |> trie.insert(at: string.to_graphemes("beam"), value: "A line of light that shines from a bright object") - -dictionary -|> trie.subtrie(at: ["g", "l"]) -|> trie.to_list -// -> [ -// #(["g", "l", "e", "a", "m"], "To produce a small, bright light"), -// #(["g", "l", "e", "a", "m", "i", "n", "g"], "Bright and shiny"), -// ] -``` - -## Installation - -To add this package to your Gleam project: - -```sh -gleam add trie_again -``` - -## Usage - -Import the `trie` module and write some code! You can find many examples of how the different functions work in the [project documentation](https://hexdocs.pm/trie_again/). - -```gleam -import trie - -trie.new() -|> trie.insert(at: ["c", "a", "r"], value: 1) -|> trie.insert(at: ["c", "a", "t"], value: 10) -|> trie.get(at: ["c", "a", "t"]) -// -> Ok(10) -``` - -## Contributing - -If you think there's any way to improve this package, or if you spot a bug don't be afraid to open PRs, issues or requests of any kind! Any contribution is welcome 💜 diff --git a/test-community-packages-javascript/build/packages/trie_again/gleam.toml b/test-community-packages-javascript/build/packages/trie_again/gleam.toml deleted file mode 100644 index 75fa79b7bcd..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/gleam.toml +++ /dev/null @@ -1,12 +0,0 @@ -name = "trie_again" -version = "1.1.1" -description = "Tries in Gleam" -licences = ["Apache-2.0"] -repository = { type = "github", user = "giacomocavalieri", repo = "trie_again" } -links = [] - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl b/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl deleted file mode 100644 index b5da5c01430..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(trie, { - entry :: gleam@option:option(any()), - children_map :: gleam@map:map_(any(), trie:trie(any(), any())) -}). diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie.erl b/test-community-packages-javascript/build/packages/trie_again/src/trie.erl deleted file mode 100644 index 47d83f03ca4..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/src/trie.erl +++ /dev/null @@ -1,232 +0,0 @@ --module(trie). --compile([no_auto_import, nowarn_unused_vars]). - --export([map/2, new/0, delete/2, fold/3, paths/1, size/1, is_empty/1, to_list/1, values/1, insert/3, from_list/1, singleton/2, get/2, has_path/2, subtrie/2, update/3]). --export_type([trie/2]). - --opaque trie(EWX, EWY) :: {trie, - gleam@option:option(EWY), - gleam@map:map_(EWX, trie(EWX, EWY))}. - --spec do_delete(trie(EXG, EXH), list(EXG)) -> gleam@option:option(trie(EXG, EXH)). -do_delete(Trie, Path) -> - case {Path, Trie} of - {[], {trie, _, Children_map}} -> - case gleam@map:size(Children_map) of - 0 -> - none; - - _ -> - {some, {trie, none, Children_map}} - end; - - {[First | Rest], {trie, Entry, Children_map@1}} -> - New_children = case gleam@map:get(Children_map@1, First) of - {error, _} -> - Children_map@1; - - {ok, Child} -> - case do_delete(Child, Rest) of - none -> - gleam@map:delete(Children_map@1, First); - - {some, Trie@1} -> - gleam@map:insert(Children_map@1, First, Trie@1) - end - end, - case {Entry, gleam@map:size(New_children)} of - {none, 0} -> - none; - - {_, _} -> - {some, {trie, Entry, New_children}} - end - end. - --spec map(trie(EYX, EYY), fun((EYY) -> EZB)) -> trie(EYX, EZB). -map(Trie, Fun) -> - {trie, - gleam@option:map(erlang:element(2, Trie), Fun), - gleam@map:map_values( - erlang:element(3, Trie), - fun(_, T) -> map(T, Fun) end - )}. - --spec new() -> trie(any(), any()). -new() -> - {trie, none, gleam@map:new()}. - --spec delete(trie(EWZ, EXA), list(EWZ)) -> trie(EWZ, EXA). -delete(Trie, Path) -> - _pipe = do_delete(Trie, Path), - gleam@option:unwrap(_pipe, new()). - --spec fold(trie(EXO, EXP), EXS, fun((EXS, list(EXO), EXP) -> EXS)) -> EXS. -fold(Trie, Initial, Fun) -> - gleam@map:fold( - erlang:element(3, Trie), - begin - _pipe = erlang:element(2, Trie), - _pipe@1 = gleam@option:map( - _pipe, - fun(_capture) -> Fun(Initial, [], _capture) end - ), - gleam@option:unwrap(_pipe@1, Initial) - end, - fun(Acc, First, Trie@1) -> - fold( - Trie@1, - Acc, - fun(Acc@1, Rest, Value) -> Fun(Acc@1, [First | Rest], Value) end - ) - end - ). - --spec paths(trie(EZI, any())) -> list(list(EZI)). -paths(Trie) -> - fold(Trie, [], fun(Rest, Path, _) -> [Path | Rest] end). - --spec size(trie(any(), any())) -> integer(). -size(Trie) -> - fold(Trie, 0, fun(Acc, _, _) -> Acc + 1 end). - --spec is_empty(trie(any(), any())) -> boolean(). -is_empty(Trie) -> - size(Trie) =:= 0. - --spec to_list(trie(FAG, FAH)) -> list({list(FAG), FAH}). -to_list(Trie) -> - fold(Trie, [], fun(Rest, Path, Value) -> [{Path, Value} | Rest] end). - --spec values(trie(any(), FBG)) -> list(FBG). -values(Trie) -> - fold(Trie, [], fun(Values, _, Value) -> [Value | Values] end). - --spec insert(trie(EYM, EYN), list(EYM), EYN) -> trie(EYM, EYN). -insert(Trie, Path, Value) -> - case {Path, Trie} of - {[], {trie, _, Children_map}} -> - {trie, {some, Value}, Children_map}; - - {[First | Rest], {trie, Entry, Children_map@1}} -> - _pipe = gleam@map:get(Children_map@1, First), - _pipe@1 = gleam@result:unwrap(_pipe, new()), - _pipe@2 = insert(_pipe@1, Rest, Value), - _pipe@3 = gleam@map:insert(Children_map@1, First, _pipe@2), - {trie, Entry, _pipe@3} - end. - --spec from_list(list({list(EXU), EXW})) -> trie(EXU, EXW). -from_list(List) -> - gleam@list:fold( - List, - new(), - fun(Trie, Pair) -> - insert(Trie, erlang:element(1, Pair), erlang:element(2, Pair)) - end - ). - --spec singleton(list(EZO), EZQ) -> trie(EZO, EZQ). -singleton(Path, Value) -> - insert(new(), Path, Value). - --spec get(trie(EYA, EYB), list(EYA)) -> {ok, EYB} | {error, nil}. -get(From, Path) -> - case {Path, From} of - {[], {trie, none, _}} -> - {error, nil}; - - {[], {trie, {some, Value}, _}} -> - {ok, Value}; - - {[First | Rest], {trie, _, Children_map}} -> - _pipe = Children_map, - _pipe@1 = gleam@map:get(_pipe, First), - gleam@result:then(_pipe@1, fun(_capture) -> get(_capture, Rest) end) - end. - --spec has_path(trie(EYH, any()), list(EYH)) -> boolean(). -has_path(Trie, Path) -> - case get(Trie, Path) of - {ok, _} -> - true; - - {error, _} -> - false - end. - --spec subtrie(trie(EZX, EZY), list(EZX)) -> {ok, trie(EZX, EZY)} | {error, nil}. -subtrie(Trie, Prefix) -> - case {Prefix, Trie} of - {[], _} -> - {ok, Trie}; - - {[First | Rest], {trie, _, Children_map}} -> - _pipe = Children_map, - _pipe@1 = gleam@map:get(_pipe, First), - _pipe@2 = gleam@result:'try'( - _pipe@1, - fun(_capture) -> subtrie(_capture, Rest) end - ), - gleam@result:map(_pipe@2, fun(Subtrie) -> _pipe@3 = gleam@map:new(), - _pipe@4 = gleam@map:insert(_pipe@3, First, Subtrie), - {trie, none, _pipe@4} end) - end. - --spec do_update( - trie(FAV, FAW), - list(FAV), - fun((gleam@option:option(FAW)) -> gleam@option:option(FAW)) -) -> gleam@option:option(trie(FAV, FAW)). -do_update(Trie, Path, Fun) -> - case {Path, Trie} of - {[], {trie, Entry, Children_map}} -> - case {Fun(Entry), gleam@map:size(Children_map)} of - {none, 0} -> - none; - - {_ = New_entry, _} -> - {some, {trie, New_entry, Children_map}} - end; - - {[First | Rest], {trie, Entry@1, Children_map@1}} -> - New_children = case gleam@map:get(Children_map@1, First) of - {ok, Child} -> - case do_update(Child, Rest, Fun) of - none -> - gleam@map:delete(Children_map@1, First); - - {some, New_child} -> - gleam@map:insert(Children_map@1, First, New_child) - end; - - {error, _} -> - case Fun(none) of - none -> - Children_map@1; - - {some, Value} -> - gleam@map:insert( - Children_map@1, - First, - singleton(Rest, Value) - ) - end - end, - case {Entry@1, gleam@map:size(New_children)} of - {none, 0} -> - none; - - {_, _} -> - {some, {trie, Entry@1, New_children}} - end - end. - --spec update( - trie(FAM, FAN), - list(FAM), - fun((gleam@option:option(FAN)) -> gleam@option:option(FAN)) -) -> trie(FAM, FAN). -update(Trie, Path, Fun) -> - _pipe = do_update(Trie, Path, Fun), - gleam@option:unwrap(_pipe, new()). diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam b/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam deleted file mode 100644 index 406e483a2dd..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam +++ /dev/null @@ -1,466 +0,0 @@ -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/result - -/// A `Trie(k, v)` is a data structure that allows to store values of type `v` indexed by lists -/// of values of type `k`. -/// -pub opaque type Trie(k, v) { - /// The trie constructor, its implementation is based on the one described by Okasaki in - /// Purely Functional Data Structures. - /// - Trie(entry: Option(v), children_map: Map(k, Trie(k, v))) -} - -/// Deletes from a trie the value associated with a given path. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> delete(at: [1, 2]) -/// > |> to_list -/// [#([1], "b")] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> delete(at: [1, 2]) -/// > |> to_list -/// [] -/// ``` -/// -pub fn delete(from trie: Trie(k, v), at path: List(k)) -> Trie(k, v) { - do_delete(from: trie, at: path) - |> option.unwrap(new()) -} - -/// Exactly same behaviour as delete but returns `None` if the tree is empty as a -/// result of the deletion. -/// -fn do_delete(from trie: Trie(k, v), at path: List(k)) -> Option(Trie(k, v)) { - case path, trie { - [], Trie(_, children_map) -> - case map.size(children_map) { - 0 -> None - _ -> Some(Trie(None, children_map)) - } - [first, ..rest], Trie(entry, children_map) -> { - let new_children = case map.get(children_map, first) { - Error(_) -> children_map - Ok(child) -> - case do_delete(from: child, at: rest) { - None -> map.delete(children_map, first) - Some(trie) -> map.insert(children_map, first, trie) - } - } - case entry, map.size(new_children) { - None, 0 -> None - _, _ -> Some(Trie(entry, new_children)) - } - } - } -} - -/// Combines all the trie's values into a single one by calling a given function on each one. -/// -/// The function takes as input the accumulator, the path of a value and the corresponding value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], 10), #([1], 1)] -/// > |> from_list -/// > |> fold(from: 0, with: fn(sum, _, value) { sum + value }) -/// 11 -/// ``` -/// -pub fn fold( - over trie: Trie(k, a), - from initial: b, - with fun: fn(b, List(k), a) -> b, -) -> b { - map.fold( - over: trie.children_map, - from: trie.entry - |> option.map(fun(initial, [], _)) - |> option.unwrap(initial), - with: fn(acc, first, trie) { - fold( - over: trie, - from: acc, - with: fn(acc, rest, value) { fun(acc, [first, ..rest], value) }, - ) - }, - ) -} - -/// Creates a new trie from a list of path-value pairs. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> to_list -/// [#([1, 2], "a"), #([1], "b")] -/// ``` -/// -pub fn from_list(list: List(#(List(k), v))) -> Trie(k, v) { - list.fold( - over: list, - from: new(), - with: fn(trie, pair) { insert(trie, pair.0, pair.1) }, - ) -} - -/// Fetches a value from a trie for a given path. -/// If a value is present at the given path it returns it wrapped in an `Ok`, -/// otherwise it returns `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> get(at: [1, 2]) -/// Result(Nil) -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> get(at: [1, 2]) -/// Ok("a") -/// ``` -/// -pub fn get(from: Trie(k, v), at path: List(k)) -> Result(v, Nil) { - case path, from { - [], Trie(None, _) -> Error(Nil) - [], Trie(Some(value), _) -> Ok(value) - [first, ..rest], Trie(_, children_map) -> - children_map - |> map.get(first) - |> result.then(get(_, rest)) - } -} - -/// Determines wether a trie contains a value associated with the given path. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> has_path([1, 2]) -/// True -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> has_path([1]) -/// False -/// ``` -/// -pub fn has_path(trie: Trie(k, v), path: List(k)) -> Bool { - case get(trie, path) { - Ok(_) -> True - Error(_) -> False - } -} - -/// Inserts a value in a trie at a given path. If there already is a value -/// at the given path it is replaced by the new one. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(at: [1, 2], value: "a") -/// > |> insert(at: [1], value: "b") -/// > |> to_list -/// [#([1, 2], "a"), #([1], "b")] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(at: [1, 2], value: "a") -/// > |> insert(at: [1, 2], value: "b") -/// > |> to_list -/// [#([1, 2], "b")] -/// ``` -/// -pub fn insert( - into trie: Trie(k, v), - at path: List(k), - value value: v, -) -> Trie(k, v) { - case path, trie { - [], Trie(_, children_map) -> Trie(Some(value), children_map) - [first, ..rest], Trie(entry, children_map) -> { - map.get(children_map, first) - |> result.unwrap(new()) - |> insert(rest, value) - |> map.insert(children_map, first, _) - |> Trie(entry, _) - } - } -} - -/// Determines wether or not the trie is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> is_empty -/// False -/// ``` -/// -pub fn is_empty(trie: Trie(k, v)) -> Bool { - size(trie) == 0 -} - -/// Updates all the values in a given trie by calling a function on each value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> map(fn(s) { s <> "!" }) -/// > |> to_list -/// [#([1, 2], "a!"), #([1], "b!")] -/// ``` -/// -pub fn map(over trie: Trie(k, v), with fun: fn(v) -> a) -> Trie(k, a) { - Trie( - option.map(trie.entry, fun), - map.map_values(trie.children_map, fn(_, t) { map(t, fun) }), - ) -} - -/// Creates a new empty trie. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> to_list -/// [] -/// ``` -/// -pub fn new() -> Trie(k, v) { - Trie(None, map.new()) -} - -/// Gets a list of all the valid paths in the trie. That is all the paths associated with a value. -/// -/// Tries are not ordered so the paths are not returned in any specific order. -/// Do not write code that relies on the order paths are returned by this function -/// as it may change in later versions of the library. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> paths -/// [[1, 2], [1]] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> paths -/// [] -/// ``` -pub fn paths(trie: Trie(k, v)) -> List(List(k)) { - fold(over: trie, from: [], with: fn(rest, path, _) { [path, ..rest] }) -} - -/// Creates a new trie with a single value associated to the given path. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> to_list -/// [#([1, 2], "a")] -/// ``` -/// -pub fn singleton(path: List(k), value: v) -> Trie(k, v) { - insert(new(), at: path, value: value) -} - -/// Gets the number of elements in the trie. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> size -/// 2 -/// ``` -/// -pub fn size(trie: Trie(k, v)) -> Int { - fold(trie, from: 0, with: fn(acc, _, _) { acc + 1 }) -} - -/// Gets the subtrie whose elements all share a common given prefix. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2, 3], "a"), #([1, 2, 4, 5], "b"), #([3, 4], "c")] -/// > |> from_list -/// > |> subtrie(at: [1, 2]) -/// > |> to_list -/// [#([1, 2, 3], "a"), #([1, 2, 4, 5], "b")] -/// ``` -/// -pub fn subtrie(trie: Trie(k, v), at prefix: List(k)) -> Result(Trie(k, v), Nil) { - case prefix, trie { - [], _ -> Ok(trie) - [first, ..rest], Trie(_, children_map) -> - children_map - |> map.get(first) - |> result.try(subtrie(_, rest)) - |> result.map(fn(subtrie) { - map.new() - |> map.insert(first, subtrie) - |> Trie(None, _) - }) - } -} - -/// Turns a trie into a list of path-value pairs. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> to_list -/// [#([1, 2], "a")] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> to_list -/// [] -/// ``` -/// -pub fn to_list(trie: Trie(k, v)) -> List(#(List(k), v)) { - fold( - over: trie, - from: [], - with: fn(rest, path, value) { [#(path, value), ..rest] }, - ) -} - -/// Updates the value associated with a path applying it the given function. -/// If there is no value associated with the given path the function is passed `None`. -/// -/// If the function returns `None` any value associated with the path is deleted from the trie. -/// If the function returns `Some(value)` then the new value is associated to the given path. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> update(at: [1, 2], with: fn(n) { n |> option.map(fn(_) { "b" }) }) -/// > |> to_list -/// [#([1, 2], "b")] -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> update(at: [1, 2], with: fn(_) { None }) -/// > |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> update(at: [1], with: fn(_) { Some("b") }) -/// > |> to_list -/// [#([1, 2], "a"), #([1], "b")] -/// ``` -/// -pub fn update( - trie: Trie(k, v), - at path: List(k), - with fun: fn(Option(v)) -> Option(v), -) -> Trie(k, v) { - do_update(trie, at: path, with: fun) - |> option.unwrap(new()) -} - -/// Exactly same behaviour as update but returns `None` if the tree is empty as a -/// result of the (possible) deletion. -/// -fn do_update( - trie: Trie(k, v), - at path: List(k), - with fun: fn(Option(v)) -> Option(v), -) -> Option(Trie(k, v)) { - case path, trie { - [], Trie(entry, children_map) -> { - case fun(entry), map.size(children_map) { - None, 0 -> None - _ as new_entry, _ -> Some(Trie(new_entry, children_map)) - } - } - [first, ..rest], Trie(entry, children_map) -> { - let new_children = case map.get(children_map, first) { - Ok(child) -> - case do_update(child, at: rest, with: fun) { - None -> map.delete(children_map, first) - Some(new_child) -> map.insert(children_map, first, new_child) - } - Error(_) -> { - case fun(None) { - None -> children_map - Some(value) -> - map.insert(children_map, first, singleton(rest, value)) - } - } - } - - case entry, map.size(new_children) { - None, 0 -> None - _, _ -> Some(Trie(entry, new_children)) - } - } - } -} - -/// Gets a list of all the values in a given trie. -/// -/// Tries are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order values are returned by this function -/// as it may change in later versions of the library. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> values -/// ["a", "b"] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> values -/// [] -/// ``` -/// -pub fn values(trie: Trie(k, v)) -> List(v) { - fold(trie, from: [], with: fn(values, _, value) { [value, ..values] }) -} diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src b/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src deleted file mode 100644 index e48a5f7a864..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, trie_again, [ - {vsn, "1.1.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Tries in Gleam"}, - {modules, [trie]}, - {registered, []} -]}. From cf8ceadb6cb2a35dcce4ef1803e80661646cfc9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Wed, 10 Apr 2024 20:10:55 +0200 Subject: [PATCH 04/11] Remove cov-mark feature + add descriptive comments --- Cargo.lock | 7 ------- compiler-core/Cargo.toml | 2 -- compiler-core/src/ast.rs | 8 ++++++-- compiler-core/src/ast/tests.rs | 5 ----- compiler-core/src/ast/typed.rs | 7 +++++-- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de01f126ecc..75ba9328c8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,12 +435,6 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" -[[package]] -name = "cov-mark" -version = "2.0.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d48d8f76bd9331f19fe2aaf3821a9f9fb32c3963e1e3d6ce82a8c09cef7444a" - [[package]] name = "cpufeatures" version = "0.2.12" @@ -895,7 +889,6 @@ dependencies = [ "capnp", "capnpc", "codespan-reporting", - "cov-mark", "debug-ignore", "dirs-next", "ecow", diff --git a/compiler-core/Cargo.toml b/compiler-core/Cargo.toml index d281c9f6373..43d9e200083 100644 --- a/compiler-core/Cargo.toml +++ b/compiler-core/Cargo.toml @@ -42,8 +42,6 @@ pubgrub = "0.2" pathdiff = { version = "0.2.1", features = ["camino"] } # Memory arena using ids rather than references id-arena = "2.1" -# Assert certain code path executions -cov-mark = "2.0.0-pre.1" async-trait.workspace = true base16.workspace = true bytes.workspace = true diff --git a/compiler-core/src/ast.rs b/compiler-core/src/ast.rs index fd436fbc155..50ac9234fd3 100644 --- a/compiler-core/src/ast.rs +++ b/compiler-core/src/ast.rs @@ -574,6 +574,9 @@ impl TypedDefinition { pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { match self { Definition::Function(function) => { + + // Search for the corresponding node inside the function + // only if the index falls within the function's full location. if function.full_location().contains(byte_index) { if let Some(found) = function.body.iter().find_map(|s| s.find_node(byte_index)) { @@ -604,7 +607,6 @@ impl TypedDefinition { Some(Located::FunctionBody(function)) } else { - cov_mark::hit!(prune_function_definition); None } } @@ -1754,6 +1756,9 @@ impl TypedStatement { } pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { + + // Search for the corresponding node inside the statement + // only if the index falls within the statement's location. if self.location().contains(byte_index) { match self { Statement::Use(_) => None, @@ -1769,7 +1774,6 @@ impl TypedStatement { } } } else { - cov_mark::hit!(prune_statement); None } } diff --git a/compiler-core/src/ast/tests.rs b/compiler-core/src/ast/tests.rs index f24e8301d73..78d3585cf94 100644 --- a/compiler-core/src/ast/tests.rs +++ b/compiler-core/src/ast/tests.rs @@ -245,7 +245,6 @@ fn find_node_sequence() { #[test] fn find_node_sequence_early_exit() { let block = compile_expression(r#"{ 1 2 3 }"#); - cov_mark::check!(early_exit_block); assert!(block.find_node(1).is_none()); } @@ -289,7 +288,6 @@ fn find_node_list_early_exit() { let statement = compile_expression(r#"[1, 2, 3]"#); let list = get_bare_expression(&statement); - cov_mark::check!(early_exit_tuple_list); assert_eq!(list.find_node(2), Some(Located::Expression(list))); } @@ -334,7 +332,6 @@ fn find_node_tuple_early_exit() { let statement = compile_expression(r#"#(1, 2, 3)"#); let tuple = get_bare_expression(&statement); - cov_mark::check!(early_exit_tuple_list); assert_eq!(tuple.find_node(3), Some(Located::Expression(tuple))); } @@ -633,7 +630,6 @@ fn i_am_here(){ value: "3".into(), }; - cov_mark::check!(prune_function_definition); //main() and test1() should be pruned assert_eq!(module.find_node(68), Some(Located::Expression(&int3))); } @@ -656,6 +652,5 @@ pub fn main() { value: "3".into(), }; - cov_mark::check!(prune_statement); //let s1 and let s2 should be pruned assert_eq!(module.find_node(60), Some(Located::Expression(&int3))); } diff --git a/compiler-core/src/ast/typed.rs b/compiler-core/src/ast/typed.rs index 05467cb0e5e..5987d91fe60 100644 --- a/compiler-core/src/ast/typed.rs +++ b/compiler-core/src/ast/typed.rs @@ -183,10 +183,11 @@ impl TypedExpr { .find_map(|e| e.find_node(byte_index)) .or_else(|| finally.find_node(byte_index)), + // Exit the search and return None if during iteration a statement + // is found with a start index beyond the index under search. Self::Block { statements, .. } => { for statement in statements { if statement.location().start > byte_index { - cov_mark::hit!(early_exit_block); break; } @@ -198,6 +199,9 @@ impl TypedExpr { None } + // Exit the search and return the encompassing type (e.g., list or tuple) + // if during iteration, an element is encountered with a start index + // beyond the index under search. Self::Tuple { elems: expressions, .. } @@ -207,7 +211,6 @@ impl TypedExpr { } => { for expression in expressions { if expression.location().start > byte_index { - cov_mark::hit!(early_exit_tuple_list); break; } From b4ac5ffb3e00d4b0c9464294cc71c651aae14710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Tue, 9 Apr 2024 20:06:17 +0200 Subject: [PATCH 05/11] Make AST traversal more efficient * pruning on definition nodes * pruning on statement nodes * early exit list, block and tuple expressions --- compiler-core/Cargo.toml | 2 + compiler-core/src/ast.rs | 79 ++++++++++++++++++-------------- compiler-core/src/ast/tests.rs | 83 ++++++++++++++++++++++++++++++++++ compiler-core/src/ast/typed.rs | 33 +++++++++++--- 4 files changed, 156 insertions(+), 41 deletions(-) diff --git a/compiler-core/Cargo.toml b/compiler-core/Cargo.toml index cdec2512291..79b637c0ff1 100644 --- a/compiler-core/Cargo.toml +++ b/compiler-core/Cargo.toml @@ -42,6 +42,8 @@ pubgrub = "0.2" pathdiff = { version = "0.2.1", features = ["camino"] } # Memory arena using ids rather than references id-arena = "2.1" +# Assert certain code path executions +cov-mark = "2.0.0-pre.1" async-trait.workspace = true base16.workspace = true bytes.workspace = true diff --git a/compiler-core/src/ast.rs b/compiler-core/src/ast.rs index f21e1e60a0f..fd436fbc155 100644 --- a/compiler-core/src/ast.rs +++ b/compiler-core/src/ast.rs @@ -574,33 +574,37 @@ impl TypedDefinition { pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { match self { Definition::Function(function) => { - if let Some(found) = function.body.iter().find_map(|s| s.find_node(byte_index)) { - return Some(found); - }; - - if let Some(found_arg) = function - .arguments - .iter() - .find(|arg| arg.location.contains(byte_index)) - { - return Some(Located::Arg(found_arg)); - }; - - if let Some(found_statement) = function - .body - .iter() - .find(|statement| statement.location().contains(byte_index)) - { - return Some(Located::Statement(found_statement)); - }; - - // Note that the fn `.location` covers the function head, not - // the entire statement. - if function.location.contains(byte_index) { - Some(Located::ModuleStatement(self)) - } else if function.full_location().contains(byte_index) { + if function.full_location().contains(byte_index) { + if let Some(found) = function.body.iter().find_map(|s| s.find_node(byte_index)) + { + return Some(found); + }; + + if let Some(found_arg) = function + .arguments + .iter() + .find(|arg| arg.location.contains(byte_index)) + { + return Some(Located::Arg(found_arg)); + }; + + if let Some(found_statement) = function + .body + .iter() + .find(|statement| statement.location().contains(byte_index)) + { + return Some(Located::Statement(found_statement)); + }; + + // Note that the fn `.location` covers the function head, not + // the entire statement. + if function.location.contains(byte_index) { + return Some(Located::ModuleStatement(self)); + } + Some(Located::FunctionBody(function)) } else { + cov_mark::hit!(prune_function_definition); None } } @@ -1750,16 +1754,23 @@ impl TypedStatement { } pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { - match self { - Statement::Use(_) => None, - Statement::Expression(expression) => expression.find_node(byte_index), - Statement::Assignment(assignment) => assignment.find_node(byte_index).or_else(|| { - if assignment.location.contains(byte_index) { - Some(Located::Statement(self)) - } else { - None + if self.location().contains(byte_index) { + match self { + Statement::Use(_) => None, + Statement::Expression(expression) => expression.find_node(byte_index), + Statement::Assignment(assignment) => { + assignment.find_node(byte_index).or_else(|| { + if assignment.location.contains(byte_index) { + Some(Located::Statement(self)) + } else { + None + } + }) } - }), + } + } else { + cov_mark::hit!(prune_statement); + None } } diff --git a/compiler-core/src/ast/tests.rs b/compiler-core/src/ast/tests.rs index fb2763cb338..f24e8301d73 100644 --- a/compiler-core/src/ast/tests.rs +++ b/compiler-core/src/ast/tests.rs @@ -240,6 +240,15 @@ fn find_node_sequence() { assert!(block.find_node(7).is_none()); } +// The function exits early when attempting to find the AST node for a specific index, +// if the remaining elements have indices beyond the search index, returning none. +#[test] +fn find_node_sequence_early_exit() { + let block = compile_expression(r#"{ 1 2 3 }"#); + cov_mark::check!(early_exit_block); + assert!(block.find_node(1).is_none()); +} + #[test] fn find_node_list() { let statement = compile_expression(r#"[1, 2, 3]"#); @@ -273,6 +282,17 @@ fn find_node_list() { assert_eq!(list.find_node(9), None); } +// The function exits early when attempting to find the AST node for a specific index, +// if the remaining elements have indices beyond the search index, returning the list itself. +#[test] +fn find_node_list_early_exit() { + let statement = compile_expression(r#"[1, 2, 3]"#); + let list = get_bare_expression(&statement); + + cov_mark::check!(early_exit_tuple_list); + assert_eq!(list.find_node(2), Some(Located::Expression(list))); +} + #[test] fn find_node_tuple() { let statement = compile_expression(r#"#(1, 2, 3)"#); @@ -307,6 +327,17 @@ fn find_node_tuple() { assert_eq!(tuple.find_node(10), None); } +// The function exits early when attempting to find the AST node for a specific index, +// if the remaining elements have indices beyond the search index, returning the tuple itself. +#[test] +fn find_node_tuple_early_exit() { + let statement = compile_expression(r#"#(1, 2, 3)"#); + let tuple = get_bare_expression(&statement); + + cov_mark::check!(early_exit_tuple_list); + assert_eq!(tuple.find_node(3), Some(Located::Expression(tuple))); +} + #[test] fn find_node_binop() { let statement = compile_expression(r#"1 + 2"#); @@ -576,3 +607,55 @@ use x <- fn(f) { f(1) } assert!(use_.find_node(26).is_some()); // The int } + +// Check that the AST tree gets pruned at the definition level. +#[test] +fn find_node_with_pruning_definition() { + let module = compile_module( + r#" +pub fn main() { + 1 +} + +fn test1() { + 2 +} + +fn i_am_here(){ + 3 +} + "#, + ); + + let int3 = TypedExpr::Int { + location: SrcSpan { start: 68, end: 69 }, + typ: type_::int(), + value: "3".into(), + }; + + cov_mark::check!(prune_function_definition); //main() and test1() should be pruned + assert_eq!(module.find_node(68), Some(Located::Expression(&int3))); +} + +// Check that the AST tree gets pruned at the statement level. +#[test] +fn find_node_with_pruning_statement() { + let module = compile_module( + r#" +pub fn main() { + let s1 = 1 + let s2 = 2 + let s3 = 3 +} + "#, + ); + + let int3 = TypedExpr::Int { + location: SrcSpan { start: 60, end: 61 }, + typ: type_::int(), + value: "3".into(), + }; + + cov_mark::check!(prune_statement); //let s1 and let s2 should be pruned + assert_eq!(module.find_node(60), Some(Located::Expression(&int3))); +} diff --git a/compiler-core/src/ast/typed.rs b/compiler-core/src/ast/typed.rs index aa4b2a95238..05467cb0e5e 100644 --- a/compiler-core/src/ast/typed.rs +++ b/compiler-core/src/ast/typed.rs @@ -164,8 +164,6 @@ impl TypedExpr { } } - // This could be optimised in places to exit early if the first of a series - // of expressions is after the byte index. pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { match self { Self::Var { .. } @@ -186,7 +184,18 @@ impl TypedExpr { .or_else(|| finally.find_node(byte_index)), Self::Block { statements, .. } => { - statements.iter().find_map(|e| e.find_node(byte_index)) + for statement in statements { + if statement.location().start > byte_index { + cov_mark::hit!(early_exit_block); + break; + } + + if let Some(located) = statement.find_node(byte_index) { + return Some(located); + } + } + + None } Self::Tuple { @@ -195,10 +204,20 @@ impl TypedExpr { | Self::List { elements: expressions, .. - } => expressions - .iter() - .find_map(|e| e.find_node(byte_index)) - .or_else(|| self.self_if_contains_location(byte_index)), + } => { + for expression in expressions { + if expression.location().start > byte_index { + cov_mark::hit!(early_exit_tuple_list); + break; + } + + if let Some(located) = expression.find_node(byte_index) { + return Some(located); + } + } + + self.self_if_contains_location(byte_index) + } Self::NegateBool { value, .. } | Self::NegateInt { value, .. } => value .find_node(byte_index) From ee04829f24f38ba18ef172428322441f7134a301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Tue, 9 Apr 2024 20:46:06 +0200 Subject: [PATCH 06/11] remove this folder? --- Cargo.lock | 7 + .../build/lsp/erlang/gleam_version | 1 - .../build/packages/gleam_bitwise/LICENSE | 191 -- .../build/packages/gleam_bitwise/README.md | 24 - .../build/packages/gleam_bitwise/gleam.toml | 16 - .../gleam_bitwise/src/gleam/bitwise.gleam | 91 - .../gleam_bitwise/src/gleam@bitwise.erl | 28 - .../gleam_bitwise/src/gleam_bitwise.app.src | 8 - .../gleam_bitwise/src/gleam_bitwise.mjs | 28 - .../packages/gleam_community_ansi/LICENCE | 190 -- .../packages/gleam_community_ansi/README.md | 72 - .../packages/gleam_community_ansi/gleam.toml | 13 - .../src/gleam_community/ansi.gleam | 2318 ----------------- .../src/gleam_community@ansi.erl | 263 -- .../src/gleam_community_ansi.app.src | 10 - .../packages/gleam_community_colour/LICENCE | 190 -- .../packages/gleam_community_colour/README.md | 36 - .../gleam_community_colour/gleam.toml | 12 - .../include/gleam_community@colour_Hsla.hrl | 1 - .../include/gleam_community@colour_Rgba.hrl | 1 - .../src/gleam_community/colour.gleam | 1127 -------- .../colour/accessibility.gleam | 173 -- .../src/gleam_community@colour.erl | 525 ---- .../gleam_community@colour@accessibility.erl | 75 - .../src/gleam_community_colour.app.src | 10 - .../build/packages/gleam_cors/LICENSE | 21 - .../build/packages/gleam_cors/README.md | 38 - .../build/packages/gleam_cors/gleam.toml | 13 - .../gleam_cors/src/gleam/http/cors.gleam | 227 -- .../gleam_cors/src/gleam@http@cors.erl | 243 -- .../gleam_cors/src/gleam_cors.app.src | 9 - .../build/packages/gleam_crypto/LICENSE | 191 -- .../build/packages/gleam_crypto/README.md | 13 - .../build/packages/gleam_crypto/gleam.toml | 17 - .../gleam_crypto/src/gleam/crypto.gleam | 135 - .../gleam_crypto/src/gleam@crypto.erl | 135 - .../gleam_crypto/src/gleam_crypto.app.src | 9 - .../build/packages/gleam_erlang/LICENSE | 191 -- .../build/packages/gleam_erlang/README.md | 34 - .../build/packages/gleam_erlang/gleam.toml | 17 - .../include/gleam@erlang@file_FileInfo.hrl | 15 - .../include/gleam@erlang@process_Abnormal.hrl | 1 - .../gleam@erlang@process_CalleeDown.hrl | 1 - .../gleam@erlang@process_Cancelled.hrl | 1 - .../gleam@erlang@process_ExitMessage.hrl | 4 - .../gleam@erlang@process_ProcessDown.hrl | 4 - .../gleam@erlang@process_ProcessMonitor.hrl | 1 - .../include/gleam@erlang@process_Subject.hrl | 4 - .../gleam@erlang_ApplicationFailedToStart.hrl | 4 - .../gleam@erlang_UnknownApplication.hrl | 1 - .../gleam_erlang/src/gleam/erlang.gleam | 143 - .../gleam_erlang/src/gleam/erlang/atom.gleam | 79 - .../src/gleam/erlang/charlist.gleam | 25 - .../gleam_erlang/src/gleam/erlang/file.gleam | 713 ----- .../gleam_erlang/src/gleam/erlang/os.gleam | 95 - .../src/gleam/erlang/process.gleam | 716 ----- .../gleam_erlang/src/gleam@erlang.erl | 86 - .../gleam_erlang/src/gleam@erlang@atom.erl | 26 - .../src/gleam@erlang@charlist.erl | 15 - .../gleam_erlang/src/gleam@erlang@file.erl | 190 -- .../gleam_erlang/src/gleam@erlang@os.erl | 27 - .../gleam_erlang/src/gleam@erlang@process.erl | 362 --- .../gleam_erlang/src/gleam_erlang.app.src | 13 - .../gleam_erlang/src/gleam_erlang_ffi.erl | 218 -- .../build/packages/gleam_http/LICENSE | 191 -- .../build/packages/gleam_http/README.md | 65 - .../build/packages/gleam_http/gleam.toml | 16 - .../include/gleam@http@cookie_Attributes.hrl | 8 - .../include/gleam@http@request_Request.hrl | 10 - .../include/gleam@http@response_Response.hrl | 5 - .../packages/gleam_http/src/gleam/http.gleam | 122 - .../gleam_http/src/gleam/http/cookie.gleam | 128 - .../gleam_http/src/gleam/http/request.gleam | 258 -- .../gleam_http/src/gleam/http/response.gleam | 141 - .../gleam_http/src/gleam/http/service.gleam | 82 - .../packages/gleam_http/src/gleam@http.erl | 124 - .../gleam_http/src/gleam@http@cookie.erl | 153 -- .../gleam_http/src/gleam@http@request.erl | 202 -- .../gleam_http/src/gleam@http@response.erl | 97 - .../gleam_http/src/gleam@http@service.erl | 82 - .../gleam_http/src/gleam_http.app.src | 12 - .../gleam_http/src/gleam_http_native.erl | 88 - .../gleam_http/src/gleam_http_native.mjs | 38 - .../build/packages/gleam_otp/LICENCE | 191 -- .../build/packages/gleam_otp/README.md | 91 - .../build/packages/gleam_otp/gleam.toml | 17 - .../include/gleam@otp@actor_Ready.hrl | 1 - .../include/gleam@otp@actor_Spec.hrl | 5 - ...otp@intensity_tracker_IntensityTracker.hrl | 5 - .../gleam@otp@supervisor_ChildSpec.hrl | 5 - .../include/gleam@otp@supervisor_Spec.hrl | 6 - .../include/gleam@otp@system_StatusInfo.hrl | 7 - .../gleam_otp/include/gleam@otp@task_Exit.hrl | 1 - .../gleam_otp/include/gleam@otp@task_Task.hrl | 6 - .../gleam_otp/src/gleam/otp/actor.gleam | 473 ---- .../src/gleam/otp/intensity_tracker.gleam | 46 - .../gleam_otp/src/gleam/otp/node.gleam | 1 - .../gleam_otp/src/gleam/otp/port.gleam | 9 - .../gleam_otp/src/gleam/otp/supervisor.gleam | 403 --- .../gleam_otp/src/gleam/otp/system.gleam | 89 - .../gleam_otp/src/gleam/otp/task.gleam | 151 -- .../gleam_otp/src/gleam@otp@actor.erl | 233 -- .../src/gleam@otp@intensity_tracker.erl | 53 - .../packages/gleam_otp/src/gleam@otp@node.erl | 8 - .../packages/gleam_otp/src/gleam@otp@port.erl | 8 - .../gleam_otp/src/gleam@otp@supervisor.erl | 322 --- .../gleam_otp/src/gleam@otp@system.erl | 43 - .../packages/gleam_otp/src/gleam@otp@task.erl | 111 - .../packages/gleam_otp/src/gleam_otp.app.src | 15 - .../gleam_otp/src/gleam_otp_external.erl | 43 - .../build/packages/gleam_stdlib/LICENCE | 191 -- .../build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 19 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../gleam_stdlib/src/gleam/base.gleam | 59 - .../gleam_stdlib/src/gleam/bit_builder.gleam | 276 -- .../gleam_stdlib/src/gleam/bit_string.gleam | 155 -- .../gleam_stdlib/src/gleam/bool.gleam | 388 --- .../gleam_stdlib/src/gleam/dynamic.gleam | 1613 ------------ .../gleam_stdlib/src/gleam/float.gleam | 589 ----- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 854 ------ .../packages/gleam_stdlib/src/gleam/io.gleam | 147 -- .../gleam_stdlib/src/gleam/iterator.gleam | 1442 ---------- .../gleam_stdlib/src/gleam/list.gleam | 2075 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 593 ----- .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 119 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 233 -- .../gleam_stdlib/src/gleam/result.gleam | 483 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 1046 -------- .../src/gleam/string_builder.gleam | 356 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 476 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 45 - .../gleam_stdlib/src/gleam@bit_builder.erl | 63 - .../gleam_stdlib/src/gleam@bit_string.erl | 56 - .../packages/gleam_stdlib/src/gleam@bool.erl | 152 -- .../gleam_stdlib/src/gleam@dynamic.erl | 794 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 193 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 323 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 707 ----- .../packages/gleam_stdlib/src/gleam@list.erl | 1082 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 97 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 75 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 393 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 255 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 28 - .../gleam_stdlib/src/gleam_stdlib.erl | 441 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 739 ------ .../gleam_stdlib/src/persistent-hash-map.mjs | 957 ------- .../packages/gleamy_structures/README.md | 27 - .../packages/gleamy_structures/gleam.toml | 15 - ...eamy_structures@heap@leftist_heap_Heap.hrl | 4 - ...eamy_structures@heap@pairing_heap_Heap.hrl | 4 - .../gleamy_structures@non_empty_list_End.hrl | 1 - .../gleamy_structures@non_empty_list_Next.hrl | 4 - ...tructures@tree@binary_search_tree_Tree.hrl | 4 - ...my_structures@tree@red_black_tree_Tree.hrl | 4 - ...structures@tree@red_black_tree_kv_Tree.hrl | 4 - .../src/gleamy_structures.app.src | 16 - .../gleamy_structures/heap/leftist_heap.gleam | 61 - .../gleamy_structures/heap/pairing_heap.gleam | 55 - .../src/gleamy_structures/map.gleam | 85 - .../gleamy_structures/non_empty_list.gleam | 63 - .../gleamy_structures/priority_queue.gleam | 54 - .../src/gleamy_structures/set.gleam | 91 - .../tree/binary_search_tree.gleam | 123 - .../tree/red_black_tree.gleam | 224 -- .../tree/red_black_tree_kv.gleam | 232 -- .../gleamy_structures@heap@leftist_heap.erl | 90 - .../gleamy_structures@heap@pairing_heap.erl | 75 - .../src/gleamy_structures@map.erl | 121 - .../src/gleamy_structures@non_empty_list.erl | 77 - .../src/gleamy_structures@priority_queue.erl | 74 - .../src/gleamy_structures@set.erl | 123 - ...amy_structures@tree@binary_search_tree.erl | 167 -- .../gleamy_structures@tree@red_black_tree.erl | 326 --- ...eamy_structures@tree@red_black_tree_kv.erl | 336 --- .../build/packages/gleeunit/LICENCE | 191 -- .../build/packages/gleeunit/README.md | 52 - .../build/packages/gleeunit/gleam.toml | 17 - .../packages/gleeunit/src/gleeunit.app.src | 8 - .../build/packages/gleeunit/src/gleeunit.erl | 59 - .../packages/gleeunit/src/gleeunit.gleam | 80 - .../gleeunit/src/gleeunit/should.gleam | 83 - .../packages/gleeunit/src/gleeunit@should.erl | 34 - .../packages/gleeunit/src/gleeunit_ffi.erl | 24 - .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 - .../gleeunit/src/gleeunit_progress.erl | 607 ----- .../build/packages/glenvy/LICENSE | 21 - .../build/packages/glenvy/README.md | 31 - .../build/packages/glenvy/gleam.toml | 13 - .../glenvy/include/glenvy@error_Io.hrl | 1 - .../build/packages/glenvy/src/glenvy.app.src | 16 - .../packages/glenvy/src/glenvy/dotenv.gleam | 42 - .../packages/glenvy/src/glenvy/env.gleam | 81 - .../packages/glenvy/src/glenvy/error.gleam | 5 - .../glenvy/src/glenvy/internal/file.gleam | 15 - .../glenvy/src/glenvy/internal/os.gleam | 26 - .../glenvy/src/glenvy/internal/parser.gleam | 69 - .../glenvy/src/glenvy/internal/string.gleam | 33 - .../packages/glenvy/src/glenvy@dotenv.erl | 40 - .../build/packages/glenvy/src/glenvy@env.erl | 69 - .../packages/glenvy/src/glenvy@error.erl | 8 - .../glenvy/src/glenvy@internal@file.erl | 9 - .../glenvy/src/glenvy@internal@os.erl | 16 - .../glenvy/src/glenvy@internal@parser.erl | 75 - .../glenvy/src/glenvy@internal@string.erl | 40 - .../build/packages/glenvy/src/glenvy_ffi.mjs | 32 - .../build/packages/glerm/README.md | 44 - .../gleam_community@ansi.cache | Bin 62841 -> 0 bytes .../gleam_community@ansi.cache_meta | Bin 114 -> 0 bytes .../gleam_community@colour.cache | Bin 27832 -> 0 bytes .../gleam_community@colour.cache_meta | Bin 123 -> 0 bytes ...gleam_community@colour@accessibility.cache | Bin 3072 -> 0 bytes ..._community@colour@accessibility.cache_meta | Bin 96 -> 0 bytes .../_gleam_artefacts/gleam@erlang.cache | Bin 8464 -> 0 bytes .../_gleam_artefacts/gleam@erlang.cache_meta | Bin 122 -> 0 bytes .../_gleam_artefacts/gleam@erlang@atom.cache | Bin 2814 -> 0 bytes .../gleam@erlang@atom.cache_meta | Bin 50 -> 0 bytes .../gleam@erlang@charlist.cache | Bin 789 -> 0 bytes .../gleam@erlang@charlist.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@erlang@file.cache | Bin 27622 -> 0 bytes .../gleam@erlang@file.cache_meta | Bin 72 -> 0 bytes .../_gleam_artefacts/gleam@erlang@node.cache | Bin 2992 -> 0 bytes .../gleam@erlang@node.cache_meta | Bin 54 -> 0 bytes .../_gleam_artefacts/gleam@erlang@os.cache | Bin 3171 -> 0 bytes .../gleam@erlang@os.cache_meta | Bin 46 -> 0 bytes .../gleam@erlang@process.cache | Bin 30881 -> 0 bytes .../gleam@erlang@process.cache_meta | Bin 115 -> 0 bytes .../_gleam_artefacts/gleam@otp@actor.cache | Bin 12240 -> 0 bytes .../gleam@otp@actor.cache_meta | Bin 196 -> 0 bytes .../gleam@otp@intensity_tracker.cache | Bin 2254 -> 0 bytes .../gleam@otp@intensity_tracker.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@otp@port.cache | Bin 273 -> 0 bytes .../gleam@otp@port.cache_meta | Bin 29 -> 0 bytes .../gleam@otp@supervisor.cache | Bin 14883 -> 0 bytes .../gleam@otp@supervisor.cache_meta | Bin 200 -> 0 bytes .../_gleam_artefacts/gleam@otp@system.cache | Bin 5222 -> 0 bytes .../gleam@otp@system.cache_meta | Bin 103 -> 0 bytes .../_gleam_artefacts/gleam@otp@task.cache | Bin 3940 -> 0 bytes .../gleam@otp@task.cache_meta | Bin 78 -> 0 bytes .../_gleam_artefacts/gleam_otp.cache | Bin 650 -> 0 bytes .../_gleam_artefacts/gleam_otp.cache_meta | Bin 130 -> 0 bytes .../_gleam_artefacts/gleam@base.cache | Bin 1223 -> 0 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 4956 -> 0 bytes .../gleam@bit_array.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 4184 -> 0 bytes .../gleam@bit_builder.cache_meta | Bin 84 -> 0 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 1934 -> 0 bytes .../gleam@bit_string.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 7081 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 48 -> 0 bytes .../gleam@bytes_builder.cache | Bin 6045 -> 0 bytes .../gleam@bytes_builder.cache_meta | Bin 98 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 12265 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 49248 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 173 -> 0 bytes .../_gleam_artefacts/gleam@float.cache | Bin 11372 -> 0 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 48 -> 0 bytes .../_gleam_artefacts/gleam@function.cache | Bin 5798 -> 0 bytes .../gleam@function.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@int.cache | Bin 18139 -> 0 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@io.cache | Bin 2856 -> 0 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 37907 -> 0 bytes .../gleam@iterator.cache_meta | Bin 141 -> 0 bytes .../_gleam_artefacts/gleam@list.cache | Bin 46246 -> 0 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 120 -> 0 bytes .../_gleam_artefacts/gleam@map.cache | Bin 4740 -> 0 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@option.cache | Bin 7258 -> 0 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@order.cache | Bin 2702 -> 0 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 1882 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 7021 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 6600 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@result.cache | Bin 10378 -> 0 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@set.cache | Bin 6383 -> 0 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 85 -> 0 bytes .../_gleam_artefacts/gleam@string.cache | Bin 21827 -> 0 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 136 -> 0 bytes .../gleam@string_builder.cache | Bin 10568 -> 0 bytes .../gleam@string_builder.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 7764 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 132 -> 0 bytes .../glerm/build/lsp/erlang/gleam_version | 1 - .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 3252 -> 0 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 108 -> 0 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 1132 -> 0 bytes .../gleeunit@should.cache_meta | Bin 29 -> 0 bytes .../packages/gleam_community_ansi/LICENCE | 190 -- .../packages/gleam_community_ansi/README.md | 72 - .../packages/gleam_community_ansi/gleam.toml | 13 - .../src/gleam_community/ansi.gleam | 2317 ---------------- .../src/gleam_community@ansi.erl | 263 -- .../src/gleam_community_ansi.app.src | 9 - .../packages/gleam_community_colour/LICENCE | 190 -- .../packages/gleam_community_colour/README.md | 36 - .../gleam_community_colour/gleam.toml | 11 - .../include/gleam_community@colour_Hsla.hrl | 1 - .../include/gleam_community@colour_Rgba.hrl | 1 - .../src/gleam_community/colour.gleam | 1126 -------- .../colour/accessibility.gleam | 173 -- .../src/gleam_community@colour.erl | 511 ---- .../gleam_community@colour@accessibility.erl | 73 - .../src/gleam_community_colour.app.src | 9 - .../glerm/build/packages/gleam_erlang/LICENSE | 191 -- .../build/packages/gleam_erlang/README.md | 37 - .../build/packages/gleam_erlang/gleam.toml | 18 - .../include/gleam@erlang@file_FileInfo.hrl | 15 - .../include/gleam@erlang@process_Abnormal.hrl | 1 - .../gleam@erlang@process_CalleeDown.hrl | 1 - .../gleam@erlang@process_Cancelled.hrl | 1 - .../gleam@erlang@process_ExitMessage.hrl | 4 - .../gleam@erlang@process_ProcessDown.hrl | 4 - .../gleam@erlang@process_ProcessMonitor.hrl | 1 - .../include/gleam@erlang@process_Subject.hrl | 4 - .../gleam@erlang_ApplicationFailedToStart.hrl | 4 - .../gleam@erlang_UnknownApplication.hrl | 1 - .../gleam_erlang/src/gleam/erlang.gleam | 158 -- .../gleam_erlang/src/gleam/erlang/atom.gleam | 79 - .../src/gleam/erlang/charlist.gleam | 25 - .../gleam_erlang/src/gleam/erlang/file.gleam | 737 ------ .../gleam_erlang/src/gleam/erlang/node.gleam | 62 - .../gleam_erlang/src/gleam/erlang/os.gleam | 95 - .../src/gleam/erlang/process.gleam | 744 ------ .../gleam_erlang/src/gleam@erlang.erl | 90 - .../gleam_erlang/src/gleam@erlang@atom.erl | 26 - .../src/gleam@erlang@charlist.erl | 15 - .../gleam_erlang/src/gleam@erlang@file.erl | 190 -- .../gleam_erlang/src/gleam@erlang@node.erl | 33 - .../gleam_erlang/src/gleam@erlang@os.erl | 27 - .../gleam_erlang/src/gleam@erlang@process.erl | 374 --- .../gleam_erlang/src/gleam_erlang.app.src | 14 - .../gleam_erlang/src/gleam_erlang_ffi.erl | 263 -- .../glerm/build/packages/gleam_otp/LICENCE | 191 -- .../glerm/build/packages/gleam_otp/README.md | 91 - .../glerm/build/packages/gleam_otp/gleam.toml | 19 - .../include/gleam@otp@actor_Continue.hrl | 4 - .../include/gleam@otp@actor_Ready.hrl | 1 - .../include/gleam@otp@actor_Spec.hrl | 5 - ...otp@intensity_tracker_IntensityTracker.hrl | 5 - .../gleam@otp@supervisor_ChildSpec.hrl | 5 - .../include/gleam@otp@supervisor_Spec.hrl | 6 - .../include/gleam@otp@system_StatusInfo.hrl | 7 - .../gleam_otp/include/gleam@otp@task_Exit.hrl | 1 - .../gleam_otp/include/gleam@otp@task_Task.hrl | 6 - .../gleam_otp/src/gleam/otp/actor.gleam | 504 ---- .../src/gleam/otp/intensity_tracker.gleam | 46 - .../gleam_otp/src/gleam/otp/port.gleam | 9 - .../gleam_otp/src/gleam/otp/supervisor.gleam | 410 --- .../gleam_otp/src/gleam/otp/system.gleam | 89 - .../gleam_otp/src/gleam/otp/task.gleam | 151 -- .../gleam_otp/src/gleam@otp@actor.erl | 273 -- .../src/gleam@otp@intensity_tracker.erl | 53 - .../packages/gleam_otp/src/gleam@otp@port.erl | 8 - .../gleam_otp/src/gleam@otp@supervisor.erl | 322 --- .../gleam_otp/src/gleam@otp@system.erl | 43 - .../packages/gleam_otp/src/gleam@otp@task.erl | 111 - .../packages/gleam_otp/src/gleam_otp.app.src | 15 - .../packages/gleam_otp/src/gleam_otp.erl | 28 - .../packages/gleam_otp/src/gleam_otp.gleam | 27 - .../gleam_otp/src/gleam_otp_external.erl | 43 - .../glerm/build/packages/gleam_stdlib/LICENCE | 191 -- .../build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 16 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../build/packages/gleam_stdlib/src/dict.mjs | 957 ------- .../gleam_stdlib/src/gleam/base.gleam | 21 - .../gleam_stdlib/src/gleam/bit_array.gleam | 157 -- .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 - .../gleam_stdlib/src/gleam/bit_string.gleam | 43 - .../gleam_stdlib/src/gleam/bool.gleam | 428 --- .../src/gleam/bytes_builder.gleam | 197 -- .../gleam_stdlib/src/gleam/dict.gleam | 544 ---- .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 ----------- .../gleam_stdlib/src/gleam/float.gleam | 546 ---- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 874 ------- .../packages/gleam_stdlib/src/gleam/io.gleam | 117 - .../gleam_stdlib/src/gleam/iterator.gleam | 1530 ----------- .../gleam_stdlib/src/gleam/list.gleam | 2154 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 127 - .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 133 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 214 -- .../gleam_stdlib/src/gleam/result.gleam | 482 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 913 ------- .../src/gleam/string_builder.gleam | 298 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 20 - .../gleam_stdlib/src/gleam@bit_array.erl | 102 - .../gleam_stdlib/src/gleam@bit_builder.erl | 66 - .../gleam_stdlib/src/gleam@bit_string.erl | 33 - .../packages/gleam_stdlib/src/gleam@bool.erl | 162 -- .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 - .../packages/gleam_stdlib/src/gleam@dict.erl | 97 - .../gleam_stdlib/src/gleam@dynamic.erl | 808 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 181 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 332 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 744 ------ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 76 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 79 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 352 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 252 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 31 - .../gleam_stdlib/src/gleam_stdlib.erl | 529 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 878 ------- .../glerm/build/packages/gleeunit/LICENCE | 191 -- .../glerm/build/packages/gleeunit/README.md | 52 - .../glerm/build/packages/gleeunit/gleam.toml | 17 - .../packages/gleeunit/src/gleeunit.app.src | 8 - .../build/packages/gleeunit/src/gleeunit.erl | 59 - .../packages/gleeunit/src/gleeunit.gleam | 92 - .../gleeunit/src/gleeunit/should.gleam | 90 - .../packages/gleeunit/src/gleeunit@should.erl | 34 - .../packages/gleeunit/src/gleeunit_ffi.erl | 24 - .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 - .../gleeunit/src/gleeunit_progress.erl | 607 ----- .../glerm/build/packages/packages.toml | 7 - .../build/packages/glerm/gleam.toml | 17 - .../packages/glerm/include/glerm_Drag.hrl | 4 - .../packages/glerm/include/glerm_Focus.hrl | 1 - .../packages/glerm/include/glerm_Key.hrl | 4 - .../glerm/include/glerm_ListenerSpec.hrl | 5 - .../packages/glerm/include/glerm_Mouse.hrl | 1 - .../glerm/include/glerm_MouseDown.hrl | 4 - .../packages/glerm/include/glerm_MouseUp.hrl | 4 - .../packages/glerm/include/glerm_Unknown.hrl | 1 - .../build/packages/glerm/manifest.toml | 18 - .../packages/glerm/priv/linux/libglerm.so | Bin 4550752 -> 0 bytes .../packages/glerm/priv/windows/libglerm.dll | Bin 352768 -> 0 bytes .../build/packages/glerm/src/glerm.app.src | 11 - .../build/packages/glerm/src/glerm.erl | 397 --- .../build/packages/glerm/src/glerm.gleam | 354 --- .../build/packages/glerm/src/glerm_ffi.erl | 67 - .../build/packages/gliew/README.md | 393 --- .../build/packages/gliew/gleam.toml | 16 - .../gliew@internal@event_LiveMount.hrl | 3 - .../gliew@internal@manager_GetWorker.hrl | 7 - .../gliew@internal@manager_ProcessTree.hrl | 5 - .../gliew@internal@worker_ConnectSocket.hrl | 3 - ...gliew@internal@worker_DisconnectSocket.hrl | 3 - .../gliew@internal@worker_LiveUpdate.hrl | 1 - .../packages/gliew/include/gliew_Response.hrl | 5 - .../packages/gliew/include/gliew_Server.hrl | 5 - .../packages/gliew/include/gliew_View.hrl | 5 - .../build/packages/gliew/src/gliew.app.src | 17 - .../build/packages/gliew/src/gliew.erl | 495 ---- .../build/packages/gliew/src/gliew.gleam | 477 ---- .../gliew/src/gliew/internal/event.gleam | 20 - .../gliew/src/gliew/internal/manager.gleam | 222 -- .../gliew/src/gliew/internal/util.gleam | 18 - .../gliew/src/gliew/internal/worker.gleam | 128 - .../gliew/src/gliew@internal@event.erl | 11 - .../gliew/src/gliew@internal@manager.erl | 216 -- .../gliew/src/gliew@internal@util.erl | 23 - .../gliew/src/gliew@internal@worker.erl | 129 - .../build/packages/glisten/README.md | 132 - .../build/packages/glisten/gleam.toml | 13 - .../glisten@acceptor_AcceptorState.hrl | 5 - .../glisten/include/glisten@acceptor_Pool.hrl | 9 - .../include/glisten@handler_Handler.hrl | 8 - .../include/glisten@handler_LoopState.hrl | 6 - .../glisten/include/glisten@handler_Ssl.hrl | 1 - .../glisten/include/glisten@handler_Tcp.hrl | 1 - .../include/glisten@socket@transport_Ssl.hrl | 34 - .../include/glisten@socket@transport_Tcp.hrl | 34 - .../packages/glisten/src/glisten.app.src | 18 - .../build/packages/glisten/src/glisten.erl | 102 - .../build/packages/glisten/src/glisten.gleam | 85 - .../glisten/src/glisten/acceptor.gleam | 204 -- .../glisten/src/glisten/handler.gleam | 160 -- .../packages/glisten/src/glisten/logger.gleam | 8 - .../packages/glisten/src/glisten/socket.gleam | 93 - .../glisten/src/glisten/socket/options.gleam | 83 - .../src/glisten/socket/transport.gleam | 122 - .../packages/glisten/src/glisten/ssl.gleam | 93 - .../packages/glisten/src/glisten/tcp.gleam | 94 - .../packages/glisten/src/glisten@acceptor.erl | 232 -- .../packages/glisten/src/glisten@handler.erl | 234 -- .../packages/glisten/src/glisten@logger.erl | 8 - .../packages/glisten/src/glisten@socket.erl | 90 - .../glisten/src/glisten@socket@options.erl | 79 - .../glisten/src/glisten@socket@transport.erl | 102 - .../packages/glisten/src/glisten@ssl.erl | 94 - .../packages/glisten/src/glisten@tcp.erl | 96 - .../build/packages/glisten/src/ssl_ffi.erl | 60 - .../build/packages/glisten/src/tcp_ffi.erl | 32 - .../build/packages/globe/LICENSE | 21 - .../build/packages/globe/README.md | 26 - .../build/packages/globe/gleam.toml | 12 - .../build/packages/globe/src/globe.app.src | 8 - .../build/packages/globe/src/globe.erl | 8 - .../build/packages/globe/src/globe.gleam | 5 - .../build/packages/gloml/README.md | 40 - .../build/packages/gloml/gleam.toml | 16 - .../packages/gloml/priv/package-lock.json | 18 - .../build/packages/gloml/priv/package.json | 5 - .../build/packages/gloml/src/TomlFFI.ex | 5 - .../build/packages/gloml/src/gloml.app.src | 9 - .../build/packages/gloml/src/gloml.erl | 44 - .../build/packages/gloml/src/gloml.gleam | 77 - .../build/packages/gloml/src/toml_ffi.mjs | 14 - .../build/packages/glove/LICENSE | 21 - .../build/packages/glove/README.md | 40 - .../build/packages/glove/gleam.toml | 11 - .../packages/glove/include/glove_Block.hrl | 1 - .../packages/glove/include/glove_Const.hrl | 1 - .../packages/glove/include/glove_DataDef.hrl | 6 - .../packages/glove/include/glove_Function.hrl | 7 - .../packages/glove/include/glove_Global.hrl | 1 - .../packages/glove/include/glove_Linkage.hrl | 5 - .../packages/glove/include/glove_Module.hrl | 5 - .../glove/include/glove_Temporary.hrl | 1 - .../packages/glove/include/glove_TypeDef.hrl | 5 - .../build/packages/glove/src/glove.app.src | 8 - .../build/packages/glove/src/glove.erl | 640 ----- .../build/packages/glove/src/glove.gleam | 563 ---- .../build/packages/glx/LICENSE | 21 - .../build/packages/glx/README.md | 12 - .../_gleam_artefacts/gleam@base.cache | Bin 1223 -> 0 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 4959 -> 0 bytes .../gleam@bit_array.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 4184 -> 0 bytes .../gleam@bit_builder.cache_meta | Bin 84 -> 0 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 1934 -> 0 bytes .../gleam@bit_string.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 7081 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 48 -> 0 bytes .../gleam@bytes_builder.cache | Bin 6045 -> 0 bytes .../gleam@bytes_builder.cache_meta | Bin 98 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 12276 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 49265 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 173 -> 0 bytes .../_gleam_artefacts/gleam@float.cache | Bin 11362 -> 0 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 48 -> 0 bytes .../_gleam_artefacts/gleam@function.cache | Bin 5793 -> 0 bytes .../gleam@function.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@int.cache | Bin 18155 -> 0 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@io.cache | Bin 2856 -> 0 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 37897 -> 0 bytes .../gleam@iterator.cache_meta | Bin 141 -> 0 bytes .../_gleam_artefacts/gleam@list.cache | Bin 46265 -> 0 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 120 -> 0 bytes .../_gleam_artefacts/gleam@map.cache | Bin 4750 -> 0 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@option.cache | Bin 7259 -> 0 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@order.cache | Bin 2704 -> 0 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 1879 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 7006 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 6599 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@result.cache | Bin 10381 -> 0 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@set.cache | Bin 6395 -> 0 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 85 -> 0 bytes .../_gleam_artefacts/gleam@string.cache | Bin 21839 -> 0 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 136 -> 0 bytes .../gleam@string_builder.cache | Bin 10571 -> 0 bytes .../gleam@string_builder.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 7769 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 132 -> 0 bytes .../glx/build/lsp/erlang/gleam_version | 1 - .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 3252 -> 0 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 108 -> 0 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 1132 -> 0 bytes .../gleeunit@should.cache_meta | Bin 29 -> 0 bytes .../glx/_gleam_artefacts/glx@stringx.cache | Bin 552 -> 0 bytes .../_gleam_artefacts/glx@stringx.cache_meta | Bin 104 -> 0 bytes .../glx/build/packages/gleam_stdlib/LICENCE | 191 -- .../glx/build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 16 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../build/packages/gleam_stdlib/src/dict.mjs | 957 ------- .../gleam_stdlib/src/gleam/base.gleam | 21 - .../gleam_stdlib/src/gleam/bit_array.gleam | 157 -- .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 - .../gleam_stdlib/src/gleam/bit_string.gleam | 43 - .../gleam_stdlib/src/gleam/bool.gleam | 428 --- .../src/gleam/bytes_builder.gleam | 197 -- .../gleam_stdlib/src/gleam/dict.gleam | 544 ---- .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 ----------- .../gleam_stdlib/src/gleam/float.gleam | 546 ---- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 874 ------- .../packages/gleam_stdlib/src/gleam/io.gleam | 117 - .../gleam_stdlib/src/gleam/iterator.gleam | 1530 ----------- .../gleam_stdlib/src/gleam/list.gleam | 2154 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 127 - .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 133 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 214 -- .../gleam_stdlib/src/gleam/result.gleam | 482 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 913 ------- .../src/gleam/string_builder.gleam | 298 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 20 - .../gleam_stdlib/src/gleam@bit_array.erl | 102 - .../gleam_stdlib/src/gleam@bit_builder.erl | 66 - .../gleam_stdlib/src/gleam@bit_string.erl | 33 - .../packages/gleam_stdlib/src/gleam@bool.erl | 162 -- .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 - .../packages/gleam_stdlib/src/gleam@dict.erl | 97 - .../gleam_stdlib/src/gleam@dynamic.erl | 808 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 181 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 332 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 744 ------ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 76 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 79 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 352 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 252 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 31 - .../gleam_stdlib/src/gleam_stdlib.erl | 529 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 878 ------- .../glx/build/packages/gleeunit/LICENCE | 191 -- .../glx/build/packages/gleeunit/README.md | 52 - .../_gleam_artefacts/gleam@base.cache | Bin 1223 -> 0 bytes .../_gleam_artefacts/gleam@base.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bit_array.cache | Bin 4962 -> 0 bytes .../gleam@bit_array.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@bit_builder.cache | Bin 4184 -> 0 bytes .../gleam@bit_builder.cache_meta | Bin 84 -> 0 bytes .../_gleam_artefacts/gleam@bit_string.cache | Bin 1934 -> 0 bytes .../gleam@bit_string.cache_meta | Bin 52 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache | Bin 7078 -> 0 bytes .../_gleam_artefacts/gleam@bool.cache_meta | Bin 48 -> 0 bytes .../gleam@bytes_builder.cache | Bin 6050 -> 0 bytes .../gleam@bytes_builder.cache_meta | Bin 98 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache | Bin 12268 -> 0 bytes .../_gleam_artefacts/gleam@dict.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache | Bin 49216 -> 0 bytes .../_gleam_artefacts/gleam@dynamic.cache_meta | Bin 173 -> 0 bytes .../_gleam_artefacts/gleam@float.cache | Bin 11377 -> 0 bytes .../_gleam_artefacts/gleam@float.cache_meta | Bin 48 -> 0 bytes .../_gleam_artefacts/gleam@function.cache | Bin 5806 -> 0 bytes .../gleam@function.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@int.cache | Bin 18138 -> 0 bytes .../_gleam_artefacts/gleam@int.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@io.cache | Bin 2856 -> 0 bytes .../_gleam_artefacts/gleam@io.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@iterator.cache | Bin 37904 -> 0 bytes .../gleam@iterator.cache_meta | Bin 141 -> 0 bytes .../_gleam_artefacts/gleam@list.cache | Bin 46259 -> 0 bytes .../_gleam_artefacts/gleam@list.cache_meta | Bin 120 -> 0 bytes .../_gleam_artefacts/gleam@map.cache | Bin 4737 -> 0 bytes .../_gleam_artefacts/gleam@map.cache_meta | Bin 67 -> 0 bytes .../_gleam_artefacts/gleam@option.cache | Bin 7261 -> 0 bytes .../_gleam_artefacts/gleam@option.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@order.cache | Bin 2704 -> 0 bytes .../_gleam_artefacts/gleam@order.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache | Bin 1880 -> 0 bytes .../_gleam_artefacts/gleam@pair.cache_meta | Bin 29 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache | Bin 7006 -> 0 bytes .../_gleam_artefacts/gleam@queue.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache | Bin 6607 -> 0 bytes .../_gleam_artefacts/gleam@regex.cache_meta | Bin 49 -> 0 bytes .../_gleam_artefacts/gleam@result.cache | Bin 10388 -> 0 bytes .../_gleam_artefacts/gleam@result.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@set.cache | Bin 6402 -> 0 bytes .../_gleam_artefacts/gleam@set.cache_meta | Bin 85 -> 0 bytes .../_gleam_artefacts/gleam@string.cache | Bin 21832 -> 0 bytes .../_gleam_artefacts/gleam@string.cache_meta | Bin 136 -> 0 bytes .../gleam@string_builder.cache | Bin 10562 -> 0 bytes .../gleam@string_builder.cache_meta | Bin 47 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache | Bin 7759 -> 0 bytes .../_gleam_artefacts/gleam@uri.cache_meta | Bin 132 -> 0 bytes .../gleeunit/build/lsp/erlang/gleam_version | 1 - .../gleeunit/_gleam_artefacts/gleeunit.cache | Bin 3254 -> 0 bytes .../_gleam_artefacts/gleeunit.cache_meta | Bin 108 -> 0 bytes .../_gleam_artefacts/gleeunit@should.cache | Bin 1134 -> 0 bytes .../gleeunit@should.cache_meta | Bin 29 -> 0 bytes .../build/packages/gleam_stdlib/LICENCE | 191 -- .../build/packages/gleam_stdlib/README.md | 39 - .../build/packages/gleam_stdlib/gleam.toml | 16 - .../include/gleam@dynamic_DecodeError.hrl | 5 - .../include/gleam@iterator_Iterator.hrl | 1 - .../include/gleam@iterator_Next.hrl | 1 - .../include/gleam@queue_Queue.hrl | 1 - .../include/gleam@regex_CompileError.hrl | 1 - .../include/gleam@regex_Match.hrl | 4 - .../include/gleam@regex_Options.hrl | 1 - .../gleam_stdlib/include/gleam@set_Set.hrl | 1 - .../gleam_stdlib/include/gleam@uri_Uri.hrl | 9 - .../build/packages/gleam_stdlib/src/dict.mjs | 957 ------- .../gleam_stdlib/src/gleam/base.gleam | 21 - .../gleam_stdlib/src/gleam/bit_array.gleam | 157 -- .../gleam_stdlib/src/gleam/bit_builder.gleam | 80 - .../gleam_stdlib/src/gleam/bit_string.gleam | 43 - .../gleam_stdlib/src/gleam/bool.gleam | 428 --- .../src/gleam/bytes_builder.gleam | 197 -- .../gleam_stdlib/src/gleam/dict.gleam | 544 ---- .../gleam_stdlib/src/gleam/dynamic.gleam | 1508 ----------- .../gleam_stdlib/src/gleam/float.gleam | 546 ---- .../gleam_stdlib/src/gleam/function.gleam | 162 -- .../packages/gleam_stdlib/src/gleam/int.gleam | 874 ------- .../packages/gleam_stdlib/src/gleam/io.gleam | 117 - .../gleam_stdlib/src/gleam/iterator.gleam | 1530 ----------- .../gleam_stdlib/src/gleam/list.gleam | 2154 --------------- .../packages/gleam_stdlib/src/gleam/map.gleam | 127 - .../gleam_stdlib/src/gleam/option.gleam | 346 --- .../gleam_stdlib/src/gleam/order.gleam | 133 - .../gleam_stdlib/src/gleam/pair.gleam | 85 - .../gleam_stdlib/src/gleam/queue.gleam | 292 --- .../gleam_stdlib/src/gleam/regex.gleam | 214 -- .../gleam_stdlib/src/gleam/result.gleam | 482 ---- .../packages/gleam_stdlib/src/gleam/set.gleam | 264 -- .../gleam_stdlib/src/gleam/string.gleam | 913 ------- .../src/gleam/string_builder.gleam | 298 --- .../packages/gleam_stdlib/src/gleam/uri.gleam | 462 ---- .../packages/gleam_stdlib/src/gleam@base.erl | 20 - .../gleam_stdlib/src/gleam@bit_array.erl | 102 - .../gleam_stdlib/src/gleam@bit_builder.erl | 66 - .../gleam_stdlib/src/gleam@bit_string.erl | 33 - .../packages/gleam_stdlib/src/gleam@bool.erl | 162 -- .../gleam_stdlib/src/gleam@bytes_builder.erl | 87 - .../packages/gleam_stdlib/src/gleam@dict.erl | 97 - .../gleam_stdlib/src/gleam@dynamic.erl | 808 ------ .../packages/gleam_stdlib/src/gleam@float.erl | 181 -- .../gleam_stdlib/src/gleam@function.erl | 67 - .../packages/gleam_stdlib/src/gleam@int.erl | 332 --- .../packages/gleam_stdlib/src/gleam@io.erl | 27 - .../gleam_stdlib/src/gleam@iterator.erl | 744 ------ .../packages/gleam_stdlib/src/gleam@list.erl | 1136 -------- .../packages/gleam_stdlib/src/gleam@map.erl | 76 - .../gleam_stdlib/src/gleam@option.erl | 147 -- .../packages/gleam_stdlib/src/gleam@order.erl | 79 - .../packages/gleam_stdlib/src/gleam@pair.erl | 33 - .../packages/gleam_stdlib/src/gleam@queue.erl | 121 - .../packages/gleam_stdlib/src/gleam@regex.erl | 33 - .../gleam_stdlib/src/gleam@result.erl | 201 -- .../packages/gleam_stdlib/src/gleam@set.erl | 85 - .../gleam_stdlib/src/gleam@string.erl | 352 --- .../gleam_stdlib/src/gleam@string_builder.erl | 91 - .../packages/gleam_stdlib/src/gleam@uri.erl | 252 -- .../gleam_stdlib/src/gleam_stdlib.app.src | 31 - .../gleam_stdlib/src/gleam_stdlib.erl | 529 ---- .../gleam_stdlib/src/gleam_stdlib.mjs | 878 ------- .../gleeunit/build/packages/packages.toml | 2 - .../glx/build/packages/gleeunit/gleam.toml | 17 - .../glx/build/packages/gleeunit/manifest.toml | 9 - .../packages/gleeunit/src/gleeunit.app.src | 8 - .../build/packages/gleeunit/src/gleeunit.erl | 59 - .../packages/gleeunit/src/gleeunit.gleam | 92 - .../gleeunit/src/gleeunit/should.gleam | 90 - .../packages/gleeunit/src/gleeunit@should.erl | 34 - .../packages/gleeunit/src/gleeunit_ffi.erl | 24 - .../packages/gleeunit/src/gleeunit_ffi.mjs | 101 - .../gleeunit/src/gleeunit_progress.erl | 607 ----- .../packages/glx/build/packages/packages.toml | 3 - .../build/packages/glx/gleam.toml | 11 - .../build/packages/glx/manifest.toml | 11 - .../build/packages/glx/src/glx.app.src | 8 - .../build/packages/glx/src/glx/stringx.gleam | 31 - .../build/packages/glx/src/glx@stringx.erl | 24 - .../build/packages/gsv/README.md | 45 - .../build/packages/gsv/gleam.toml | 20 - .../include/gsv@internal@token_Textdata.hrl | 1 - .../build/packages/gsv/src/gsv.app.src | 10 - .../build/packages/gsv/src/gsv.erl | 58 - .../build/packages/gsv/src/gsv.gleam | 62 - .../packages/gsv/src/gsv/internal/ast.gleam | 140 - .../packages/gsv/src/gsv/internal/token.gleam | 54 - .../packages/gsv/src/gsv@internal@ast.erl | 125 - .../packages/gsv/src/gsv@internal@token.erl | 59 - .../build/packages/hug/README.md | 47 - .../build/packages/hug/gleam.toml | 16 - .../build/packages/hug/src/hug.app.src | 10 - .../build/packages/hug/src/hug.erl | 303 --- .../build/packages/hug/src/hug.gleam | 405 --- .../build/packages/mist/README.md | 202 -- .../build/packages/mist/gleam.toml | 17 - .../mist@internal@handler_Response.hrl | 3 - .../include/mist@internal@handler_State.hrl | 4 - .../include/mist@internal@http_Buffer.hrl | 1 - .../include/mist@internal@http_FileBody.hrl | 6 - .../mist/include/mist@internal@http_Read.hrl | 1 - .../include/mist@internal@http_Unread.hrl | 1 - .../mist@internal@websocket_BinaryFrame.hrl | 1 - .../mist@internal@websocket_BinaryMessage.hrl | 1 - .../mist@internal@websocket_CloseFrame.hrl | 1 - .../mist@internal@websocket_PingFrame.hrl | 1 - .../mist@internal@websocket_PongFrame.hrl | 1 - .../mist@internal@websocket_TextFrame.hrl | 1 - .../mist@internal@websocket_TextMessage.hrl | 1 - ...st@internal@websocket_WebsocketHandler.hrl | 7 - .../build/packages/mist/src/mist.app.src | 20 - .../build/packages/mist/src/mist.erl | 116 - .../build/packages/mist/src/mist.gleam | 165 -- .../mist/src/mist/internal/encoder.gleam | 104 - .../mist/src/mist/internal/file.gleam | 26 - .../mist/src/mist/internal/handler.gleam | 350 --- .../mist/src/mist/internal/http.gleam | 393 --- .../mist/src/mist/internal/logger.gleam | 8 - .../mist/src/mist/internal/websocket.gleam | 167 -- .../packages/mist/src/mist/websocket.gleam | 51 - .../mist/src/mist@internal@encoder.erl | 209 -- .../packages/mist/src/mist@internal@file.erl | 27 - .../mist/src/mist@internal@handler.erl | 577 ---- .../packages/mist/src/mist@internal@http.erl | 591 ----- .../mist/src/mist@internal@logger.erl | 8 - .../mist/src/mist@internal@websocket.erl | 359 --- .../packages/mist/src/mist@websocket.erl | 52 - .../build/packages/mist/src/mist_ffi.erl | 47 - .../build/packages/nakai/LICENSE | 22 - .../build/packages/nakai/README.md | 46 - .../build/packages/nakai/gleam.toml | 20 - .../nakai/include/nakai@html@attrs_Attr.hrl | 1 - .../nakai/include/nakai@html@attrs_Event.hrl | 1 - .../nakai/include/nakai@html_Body.hrl | 4 - .../nakai/include/nakai@html_Comment.hrl | 1 - .../nakai/include/nakai@html_Doctype.hrl | 1 - .../nakai/include/nakai@html_Element.hrl | 5 - .../nakai/include/nakai@html_Fragment.hrl | 1 - .../nakai/include/nakai@html_Head.hrl | 1 - .../nakai/include/nakai@html_Html.hrl | 4 - .../nakai/include/nakai@html_LeafElement.hrl | 4 - .../nakai/include/nakai@html_Script.hrl | 1 - .../nakai/include/nakai@html_Text.hrl | 1 - .../nakai/include/nakai@html_UnsafeText.hrl | 1 - .../nakai@internal@document_Document.hrl | 8 - .../build/packages/nakai/src/nakai.app.src | 18 - .../build/packages/nakai/src/nakai.erl | 22 - .../build/packages/nakai/src/nakai.gleam | 60 - .../nakai/src/nakai/experimental/head.gleam | 22 - .../nakai/src/nakai/experimental/on.gleam | 5 - .../nakai/experimental/web_components.gleam | 10 - .../build/packages/nakai/src/nakai/html.gleam | 1164 --------- .../packages/nakai/src/nakai/html/attrs.gleam | 203 -- .../nakai/src/nakai/internal/document.gleam | 97 - .../nakai/src/nakai/internal/render.gleam | 211 -- .../nakai/src/nakai@experimental@head.erl | 34 - .../nakai/src/nakai@experimental@on.erl | 8 - .../src/nakai@experimental@web_components.erl | 12 - .../build/packages/nakai/src/nakai@html.erl | 830 ------ .../packages/nakai/src/nakai@html@attrs.erl | 191 -- .../nakai/src/nakai@internal@document.erl | 117 - .../nakai/src/nakai@internal@render.erl | 297 --- .../build/packages/nibble/LICENSE | 18 - .../build/packages/nibble/README.md | 46 - .../build/packages/nibble/gleam.toml | 15 - .../nibble/include/nibble@pratt_Config.hrl | 5 - .../nibble/include/nibble_DeadEnd.hrl | 6 - .../nibble/include/nibble_Located.hrl | 1 - .../build/packages/nibble/src/nibble.app.src | 10 - .../build/packages/nibble/src/nibble.erl | 517 ---- .../build/packages/nibble/src/nibble.gleam | 519 ---- .../packages/nibble/src/nibble/pratt.gleam | 113 - .../nibble/src/nibble/predicates.gleam | 59 - .../packages/nibble/src/nibble@pratt.erl | 120 - .../packages/nibble/src/nibble@predicates.erl | 234 -- .../build/packages/non_empty_list/LICENSE | 201 -- .../build/packages/non_empty_list/README.md | 40 - .../build/packages/non_empty_list/gleam.toml | 13 - .../include/non_empty_list_NonEmptyList.hrl | 1 - .../non_empty_list/src/non_empty_list.app.src | 8 - .../non_empty_list/src/non_empty_list.erl | 304 --- .../non_empty_list/src/non_empty_list.gleam | 607 ----- .../build/packages/packages.toml | 30 - .../build/packages/ream/LICENSE | 201 -- .../build/packages/ream/README.md | 64 - .../build/packages/ream/gleam.toml | 27 - .../include/ream@storage@file@close_Error.hrl | 1 - .../include/ream@storage@file@read_Error.hrl | 1 - .../include/ream@storage@file@read_Ok.hrl | 1 - .../include/ream@storage@file@write_Error.hrl | 1 - .../ream@storage@file_DelayedWrite.hrl | 1 - .../include/ream@storage@file_Encoding.hrl | 1 - .../include/ream@storage@file_ReadAhead.hrl | 1 - .../ream@storage@kv@memtable_MemTable.hrl | 5 - ...ream@storage@kv@memtable_MemTableEntry.hrl | 4 - .../include/ream@storage@kv@value_Value.hrl | 6 - .../ream@storage@kv@value_ValueFile.hrl | 7 - .../ream@storage@kv@value_ValueFileInfo.hrl | 7 - .../ream/include/ream@storage@kv_KV.hrl | 11 - .../ream/include/ream@storage@kv_KVInfo.hrl | 12 - .../include/ream@storage@kv_MemTableRange.hrl | 5 - .../ream@storage@stream@event_Event.hrl | 1 - .../ream@storage@stream@event_EventFile.hrl | 6 - .../ream@storage@stream@index_Index.hrl | 1 - .../ream@storage@stream@index_IndexFile.hrl | 5 - .../include/ream@storage@stream_Stream.hrl | 7 - .../build/packages/ream/src/ream.app.src | 24 - .../build/packages/ream/src/ream.erl | 1 - .../build/packages/ream/src/ream.gleam | 1 - .../packages/ream/src/ream/storage/file.gleam | 103 - .../ream/src/ream/storage/file/close.gleam | 6 - .../ream/src/ream/storage/file/read.gleam | 7 - .../ream/src/ream/storage/file/write.gleam | 6 - .../packages/ream/src/ream/storage/kv.gleam | 430 --- .../ream/src/ream/storage/kv/memtable.gleam | 287 -- .../ream/src/ream/storage/kv/sstable.gleam | 54 - .../ream/src/ream/storage/kv/value.gleam | 206 -- .../ream/src/ream/storage/stream.gleam | 139 - .../ream/src/ream/storage/stream/event.gleam | 95 - .../ream/src/ream/storage/stream/index.gleam | 153 -- .../build/packages/ream/src/ream/uuid.gleam | 48 - .../packages/ream/src/ream@storage@file.erl | 123 - .../ream/src/ream@storage@file@close.erl | 8 - .../ream/src/ream@storage@file@read.erl | 8 - .../ream/src/ream@storage@file@write.erl | 8 - .../packages/ream/src/ream@storage@kv.erl | 901 ------- .../ream/src/ream@storage@kv@memtable.erl | 277 -- .../ream/src/ream@storage@kv@sstable.erl | 136 - .../ream/src/ream@storage@kv@value.erl | 326 --- .../packages/ream/src/ream@storage@stream.erl | 272 -- .../ream/src/ream@storage@stream@event.erl | 186 -- .../ream/src/ream@storage@stream@index.erl | 234 -- .../build/packages/ream/src/ream@uuid.erl | 53 - .../build/packages/simplifile/README.md | 35 - .../build/packages/simplifile/gleam.toml | 19 - .../build/packages/simplifile/src/file.mjs | 84 - .../simplifile/src/gleam_erlang_ffi.erl | 218 -- .../simplifile/src/simplifile.app.src | 8 - .../packages/simplifile/src/simplifile.erl | 131 - .../packages/simplifile/src/simplifile.gleam | 359 --- .../build/packages/toml/LICENSE | 176 -- .../build/packages/toml/README.md | 338 --- .../build/packages/toml/lib/builder.ex | 413 --- .../build/packages/toml/lib/decoder.ex | 1055 -------- .../build/packages/toml/lib/document.ex | 182 -- .../build/packages/toml/lib/error.ex | 143 - .../build/packages/toml/lib/lexer.ex | 392 --- .../build/packages/toml/lib/lexer/guards.ex | 21 - .../build/packages/toml/lib/lexer/string.ex | 294 --- .../build/packages/toml/lib/provider.ex | 227 -- .../build/packages/toml/lib/toml.ex | 94 - .../build/packages/toml/lib/transform.ex | 127 - .../build/packages/toml/mix.exs | 125 - .../build/packages/trie_again/LICENSE | 201 -- .../build/packages/trie_again/README.md | 62 - .../build/packages/trie_again/gleam.toml | 12 - .../packages/trie_again/include/trie_Trie.hrl | 4 - .../build/packages/trie_again/src/trie.erl | 232 -- .../build/packages/trie_again/src/trie.gleam | 466 ---- .../trie_again/src/trie_again.app.src | 8 - 1015 files changed, 7 insertions(+), 138937 deletions(-) delete mode 100644 test-community-packages-javascript/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl delete mode 100644 test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/README.md delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glenvy/README.md delete mode 100644 test-community-packages-javascript/build/packages/glenvy/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl delete mode 100644 test-community-packages-javascript/build/packages/glerm/manifest.toml delete mode 100755 test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so delete mode 100644 test-community-packages-javascript/build/packages/glerm/priv/windows/libglerm.dll delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.app.src delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.erl delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm.gleam delete mode 100644 test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/README.md delete mode 100644 test-community-packages-javascript/build/packages/gliew/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.app.src delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl delete mode 100644 test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/README.md delete mode 100644 test-community-packages-javascript/build/packages/glisten/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.app.src delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/globe/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/globe/README.md delete mode 100644 test-community-packages-javascript/build/packages/globe/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.app.src delete mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.erl delete mode 100644 test-community-packages-javascript/build/packages/globe/src/globe.gleam delete mode 100644 test-community-packages-javascript/build/packages/gloml/README.md delete mode 100644 test-community-packages-javascript/build/packages/gloml/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gloml/priv/package-lock.json delete mode 100644 test-community-packages-javascript/build/packages/gloml/priv/package.json delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.app.src delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.erl delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/gloml.gleam delete mode 100644 test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glove/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glove/README.md delete mode 100644 test-community-packages-javascript/build/packages/glove/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl delete mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.app.src delete mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.erl delete mode 100644 test-community-packages-javascript/build/packages/glove/src/glove.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/glx/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl delete mode 100644 test-community-packages-javascript/build/packages/glx/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/manifest.toml delete mode 100644 test-community-packages-javascript/build/packages/glx/src/glx.app.src delete mode 100644 test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam delete mode 100644 test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl delete mode 100644 test-community-packages-javascript/build/packages/gsv/README.md delete mode 100644 test-community-packages-javascript/build/packages/gsv/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.app.src delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.erl delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv.gleam delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl delete mode 100644 test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl delete mode 100644 test-community-packages-javascript/build/packages/hug/README.md delete mode 100644 test-community-packages-javascript/build/packages/hug/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.app.src delete mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.erl delete mode 100644 test-community-packages-javascript/build/packages/hug/src/hug.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/README.md delete mode 100644 test-community-packages-javascript/build/packages/mist/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.app.src delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl delete mode 100644 test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/nakai/README.md delete mode 100644 test-community-packages-javascript/build/packages/nakai/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.app.src delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl delete mode 100644 test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl delete mode 100644 test-community-packages-javascript/build/packages/nibble/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/nibble/README.md delete mode 100644 test-community-packages-javascript/build/packages/nibble/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl delete mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl delete mode 100644 test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.app.src delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.erl delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble.gleam delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl delete mode 100644 test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/README.md delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl delete mode 100644 test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam delete mode 100644 test-community-packages-javascript/build/packages/packages.toml delete mode 100644 test-community-packages-javascript/build/packages/ream/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/ream/README.md delete mode 100644 test-community-packages-javascript/build/packages/ream/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.app.src delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl delete mode 100644 test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl delete mode 100644 test-community-packages-javascript/build/packages/simplifile/README.md delete mode 100644 test-community-packages-javascript/build/packages/simplifile/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/file.mjs delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl delete mode 100644 test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam delete mode 100644 test-community-packages-javascript/build/packages/toml/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/toml/README.md delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/builder.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/decoder.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/document.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/error.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/provider.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/toml.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/lib/transform.ex delete mode 100644 test-community-packages-javascript/build/packages/toml/mix.exs delete mode 100644 test-community-packages-javascript/build/packages/trie_again/LICENSE delete mode 100644 test-community-packages-javascript/build/packages/trie_again/README.md delete mode 100644 test-community-packages-javascript/build/packages/trie_again/gleam.toml delete mode 100644 test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl delete mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie.erl delete mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie.gleam delete mode 100644 test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src diff --git a/Cargo.lock b/Cargo.lock index abac62c1948..555ae4a9029 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,6 +435,12 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cov-mark" +version = "2.0.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d48d8f76bd9331f19fe2aaf3821a9f9fb32c3963e1e3d6ce82a8c09cef7444a" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -889,6 +895,7 @@ dependencies = [ "capnp", "capnpc", "codespan-reporting", + "cov-mark", "debug-ignore", "dirs-next", "ecow", diff --git a/test-community-packages-javascript/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE b/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/README.md b/test-community-packages-javascript/build/packages/gleam_bitwise/README.md deleted file mode 100644 index 6838e2232b1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# bitwise - -[![Package Version](https://img.shields.io/hexpm/v/gleam_bitwise)](https://hex.pm/packages/gleam_bitwise) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_bitwise/) - -🍓 Bitwise operations on integers. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gleam_bitwise -``` - -and its documentation can be found at <https://hexdocs.pm/gleam_bitwise/>. diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml b/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml deleted file mode 100644 index dd8cd839a87..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_bitwise" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "Bitwise operations on integers" - -repository = { type = "github", user = "gleam-lang", repo = "bitwise" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.21" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam deleted file mode 100644 index 662f9104da6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam/bitwise.gleam +++ /dev/null @@ -1,91 +0,0 @@ -//// A set of functions for bitwise operations on integers. - -/// Calculates the bitwise AND of its arguments. -pub fn and(x: Int, y: Int) -> Int { - do_and(x, y) -} - -if erlang { - external fn do_and(Int, Int) -> Int = - "erlang" "band" -} - -if javascript { - external fn do_and(Int, Int) -> Int = - "../gleam_bitwise.mjs" "and" -} - -/// Calculates the bitwise NOT of its argument. -pub fn not(x: Int) -> Int { - do_not(x) -} - -if erlang { - external fn do_not(Int) -> Int = - "erlang" "bnot" -} - -if javascript { - external fn do_not(Int) -> Int = - "../gleam_bitwise.mjs" "not" -} - -/// Calculates the bitwise OR of its arguments. -pub fn or(x: Int, y: Int) -> Int { - do_or(x, y) -} - -if erlang { - external fn do_or(Int, Int) -> Int = - "erlang" "bor" -} - -if javascript { - external fn do_or(Int, Int) -> Int = - "../gleam_bitwise.mjs" "or" -} - -/// Calculates the bitwise XOR of its arguments. -pub fn exclusive_or(x: Int, y: Int) -> Int { - do_exclusive_or(x, y) -} - -if erlang { - external fn do_exclusive_or(Int, Int) -> Int = - "erlang" "bxor" -} - -if javascript { - external fn do_exclusive_or(Int, Int) -> Int = - "../gleam_bitwise.mjs" "exclusive_or" -} - -/// Calculates the result of an arithmetic left bitshift. -pub fn shift_left(x: Int, y: Int) -> Int { - do_shift_left(x, y) -} - -if erlang { - external fn do_shift_left(Int, Int) -> Int = - "erlang" "bsl" -} - -if javascript { - external fn do_shift_left(Int, Int) -> Int = - "../gleam_bitwise.mjs" "shift_left" -} - -/// Calculates the result of an arithmetic right bitshift. -pub fn shift_right(x: Int, y: Int) -> Int { - do_shift_right(x, y) -} - -if erlang { - external fn do_shift_right(Int, Int) -> Int = - "erlang" "bsr" -} - -if javascript { - external fn do_shift_right(Int, Int) -> Int = - "../gleam_bitwise.mjs" "shift_right" -} diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl deleted file mode 100644 index 57d63544e64..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam@bitwise.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(gleam@bitwise). --compile(no_auto_import). - --export(['and'/2, 'not'/1, 'or'/2, exclusive_or/2, shift_left/2, shift_right/2]). - --spec 'and'(integer(), integer()) -> integer(). -'and'(X, Y) -> - erlang:'band'(X, Y). - --spec 'not'(integer()) -> integer(). -'not'(X) -> - erlang:'bnot'(X). - --spec 'or'(integer(), integer()) -> integer(). -'or'(X, Y) -> - erlang:'bor'(X, Y). - --spec exclusive_or(integer(), integer()) -> integer(). -exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec shift_left(integer(), integer()) -> integer(). -shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec shift_right(integer(), integer()) -> integer(). -shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src deleted file mode 100644 index bd9497aca13..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleam_bitwise, [ - {vsn, "1.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Bitwise operations on integers"}, - {modules, [gleam@bitwise]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs b/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs deleted file mode 100644 index 4f928cbc42e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_bitwise/src/gleam_bitwise.mjs +++ /dev/null @@ -1,28 +0,0 @@ -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function not(x) { - return Number(~BigInt(x)); -} - -export function or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE b/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md b/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md deleted file mode 100644 index 90ab0d56c57..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# gleam-community/ansi - -Format text with ANSI escape sequences. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_ansi)](https://hex.pm/packages/gleam_community_ansi) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_ansi/) - -✨ This project is written in _pure Gleam_ so you can use it anywhere Gleam runs: -Erlang, Elixir, Node, Deno, even [some browsers](https://bit.ly/devtools-console-ansi-support)! - ---- - -## Quickstart - -```gleam -import gleam/io -import gleam_community/ansi - -pub fn main() { - let greeting = "Hello, " <> ansi.pink("world") <> "!" - - greeting - |> ansi.bg_white - |> io.println -} - -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_ansi) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_ansi -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_ansi). - -## ANSI-what? - -ANSI escape sequences date back to the 70s as a standard way to format text on -various video text terminals. Since then they have been adopted by many software -terminal emulators and platforms, including some Web browsers, and are a simple -way to format text without platform-specific APIs. - -The point of this package is to abstract the specific codes away and give you an -easy-to-understand API for formatting and colouring terminal text. Still, here is -a quick couple of examples of what's happening under the hood. - -You can copy these examples straight into your terminal to see them in action! - -- Colour text yellow: - - ```shell - $ echo "\e[33mhello" - ``` - -- Colour the background pink: - - ```shell - $ echo "\e[45mhello" - ``` - -- Render text italic: - - ```shell - $ echo "\e[3mhello\e[23m" - ``` - -As you can see, the escape sequences are a bit obscure. Sure, you could hard code -them, or you could use this package! diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml b/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml deleted file mode 100644 index 026a2d2baa0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "gleam_community_ansi" -version = "1.1.0" -licences = ["Apache-2.0"] -description = "ANSI colours, formatting, and control codes" -repository = { type = "github", user = "gleam-community", repo = "ansi" } - -[dependencies] -gleam_bitwise = "~> 1.2" -gleam_stdlib = "~> 0.25" -gleam_community_colour = "~> 1.0" - -[dev-dependencies] -gleeunit = "~> 0.7" diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam deleted file mode 100644 index 045273abd09..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam +++ /dev/null @@ -1,2318 +0,0 @@ -//// -//// - **Text style** -//// - [`bold`](#bold) -//// - [`italic`](#italic) -//// - [`underline`](#underline) -//// - [`strikethrough`](#strikethrough) -//// - [`inverse`](#inverse) -//// - [`dim`](#dim) -//// - [`hidden`](#hidden) -//// - [`reset`](#reset) -//// - **Text colour** -//// - [`black`](#black) -//// - [`red`](#red) -//// - [`green`](#green) -//// - [`yellow`](#yellow) -//// - [`blue`](#blue) -//// - [`magenta`](#magenta) -//// - [`cyan`](#cyan) -//// - [`white`](#white) -//// - [`pink`](#pink) -//// - [`grey`](#grey) -//// - [`gray`](#gray) -//// - [`bright_black`](#bright_black) -//// - [`bright_red`](#bright_red) -//// - [`bright_green`](#bright_green) -//// - [`bright_yellow`](#bright_yellow) -//// - [`bright_blue`](#bright_blue) -//// - [`bright_magenta`](#bright_magenta) -//// - [`bright_cyan`](#bright_cyan) -//// - [`bright_white`](#bright_white) -//// - [`hex`](#hex) -//// - [`colour`](#colour) -//// - [`color`](#color) -//// - **Background colour** -//// - [`bg_black`](#bg_black) -//// - [`bg_red`](#bg_red) -//// - [`bg_green`](#bg_green) -//// - [`bg_yellow`](#bg_yellow) -//// - [`bg_blue`](#bg_blue) -//// - [`bg_magenta`](#bg_magenta) -//// - [`bg_cyan`](#bg_cyan) -//// - [`bg_white`](#bg_white) -//// - [`bg_pink`](#bg_pink) -//// - [`bg_bright_black`](#bg_bright_black) -//// - [`bg_bright_red`](#bg_bright_red) -//// - [`bg_bright_green`](#bg_bright_green) -//// - [`bg_bright_yellow`](#bg_bright_yellow) -//// - [`bg_bright_blue`](#bg_bright_blue) -//// - [`bg_bright_magenta`](#bg_bright_magenta) -//// - [`bg_bright_cyan`](#bg_bright_cyan) -//// - [`bg_bright_white`](#bg_bright_white) -//// - [`bg_hex`](#bg_hex) -//// - [`bg_colour`](#bg_colour) -//// - [`bg_color`](#bg_color) -//// -//// --- -//// -//// This package was heavily inspired by the `colours` module in the Deno standard -//// library. The original source code can be found -//// <a href="https://deno.land/std@0.167.0/fmt/colours.ts">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018-2022 the Deno authors. -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the Deno `colours` module: -// -// https://deno.land/std@0.167.0/fmt/colours.ts -// - -// This seems like a really handy reference if/when we want to expand this beyond -// formatting escape sequences: -// -// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/bitwise -import gleam/int -import gleam/list -import gleam/string -import gleam_community/colour.{Colour} as gc_colour - -// CONSTS --------------------------------------------------------------------- - -const asci_escape_character = "" - -// TYPES ---------------------------------------------------------------------- - -type Code { - Code(open: String, close: String, regexp: String) -} - -// UTILITY -------------------------------------------------------------------- - -/// Builds colour code -fn code(open: List(Int), close: Int) -> Code { - let close_str = int.to_string(close) - let open_strs = list.map(open, int.to_string) - - Code( - open: asci_escape_character <> "[" <> string.join(open_strs, ";") <> "m", - close: asci_escape_character <> "[" <> close_str <> "m", - regexp: asci_escape_character <> "[" <> close_str <> "m", - ) -} - -/// Applies colour and background based on colour code and its associated text -fn run(text: String, code: Code) -> String { - code.open <> string.replace(text, code.regexp, code.open) <> code.close -} - -// STYLES --------------------------------------------------------------------- - -/// Reset the text modified -pub fn reset(text: String) -> String { - run(text, code([0], 0)) -} - -/// Style the given text bold. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bold("lucy") -/// // => "\x1B[1mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bold(text: String) -> String { - run(text, code([1], 22)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("lucy") -/// // => "\x1B[2mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn dim(text: String) -> String { - run(text, code([2], 22)) -} - -/// Style the given text italic. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.italic("lucy") -/// // => "\x1B[3mlucy\x1B[23m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[23m"` added to the string. This is the escape code -/// for the "default" italic style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be underlined but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn italic(text: String) -> String { - run(text, code([3], 23)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("lucy") -/// // => "\x1B[4mlucy\x1B[24m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[24m"` added to the string. This is the escape code -/// for the "default" underline style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn underline(text: String) -> String { - run(text, code([4], 24)) -} - -/// Inverse the given text's colour, and background colour. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.inverse("lucy") -/// // => "\x1B[7mlucy\x1B[27m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[27m"` added to the string. This is the escape code -/// for the "default" inverse style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn inverse(text: String) -> String { - run(text, code([7], 27)) -} - -/// Style the given text to be hidden. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hidden("lucy") -/// // => "\x1B[8mlucy\x1B[28m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[28m"` added to the string. This is the escape code -/// for the "default" hidden style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hidden(text: String) -> String { - run(text, code([8], 28)) -} - -/// Style the given text to be striked through. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.strikethrough("lucy") -/// // => "\x1B[9mlucy\x1B[29m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[29m"` added to the string. This is the escape code -/// for the "default" strikethrough style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn strikethrough(text: String) -> String { - run(text, code([9], 29)) -} - -// FOREGROUND ----------------------------------------------------------------- - -/// Colour the given text black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.black("lucy") -/// // => "\x1B[30mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn black(text: String) -> String { - run(text, code([30], 39)) -} - -/// Colour the given text red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.red("lucy") -/// // => "\x1B[31mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn red(text: String) -> String { - run(text, code([31], 39)) -} - -/// Colour the given text green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.green("lucy") -/// // => "\x1B[32mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn green(text: String) -> String { - run(text, code([32], 39)) -} - -/// Colour the given text yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("lucy") -/// // => "\x1B[33mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn yellow(text: String) -> String { - run(text, code([33], 39)) -} - -/// Colour the given text blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.blue("lucy") -/// // => "\x1B[34mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn blue(text: String) -> String { - run(text, code([34], 39)) -} - -/// Colour the given text magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.magenta("lucy") -/// // => "\x1B[35mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn magenta(text: String) -> String { - run(text, code([35], 39)) -} - -/// Colour the given text cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.cyan("lucy") -/// // => "\x1B[36mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cyan(text: String) -> String { - run(text, code([36], 39)) -} - -/// Colour the given text white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.white("lucy") -/// // => "\x1B[37mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn white(text: String) -> String { - run(text, code([37], 39)) -} - -/// Colour the given text gray. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.gray("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn grey(text: String) -> String { - bright_black(text) -} - -/// This is an alias for [`grey`](#grey) for those who prefer the American English -/// spelling. -/// -pub fn gray(text: String) -> String { - bright_black(text) -} - -/// Colour the given text bright black. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_black("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_black(text: String) -> String { - run(text, code([90], 39)) -} - -/// Colour the given text bright red. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_red("lucy") -/// // => "\x1B[91mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_red(text: String) -> String { - run(text, code([91], 39)) -} - -/// Colour the given text bright green. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_green("lucy") -/// // => "\x1B[92mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_green(text: String) -> String { - run(text, code([92], 39)) -} - -/// Colour the given text bright yellow. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_yellow("lucy") -/// // => "\x1B[93mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_yellow(text: String) -> String { - run(text, code([93], 39)) -} - -/// Colour the given text bright blue. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_blue("lucy") -/// // => "\x1B[94mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_blue(text: String) -> String { - run(text, code([94], 39)) -} - -/// Colour the given text bright gremagentaen. This should increase the luminosity -/// of the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_magenta("lucy") -/// // => "\x1B[95mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_magenta(text: String) -> String { - run(text, code([95], 39)) -} - -/// Colour the given text bright cyan. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_cyan("lucy") -/// // => "\x1B[96mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_cyan(text: String) -> String { - run(text, code([96], 39)) -} - -/// Colour the given text bright white. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_white("lucy") -/// // => "\x1B[97mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_white(text: String) -> String { - run(text, code([97], 39)) -} - -/// Colour the given text pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.pink("lucy") -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn pink(text: String) -> String { - hex(text, 0xffaff3) -} - -/// Colour the given text the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hex(text: String, colour: Int) -> String { - let colour = int.clamp(colour, max: 0xffffff, min: 0x0) - run( - text, - code( - [ - 38, - 2, - bitwise.shift_right(colour, 16) - |> bitwise.and(0xff), - bitwise.shift_right(colour, 8) - |> bitwise.and(0xff), - bitwise.and(colour, 0xff), - ], - 39, - ), - ) -} - -/// Colour the given text the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - hex(text, hex_colour) -} - -/// This is an alias for [`colour`](#colour) for those who prefer the American English -/// spelling. -/// -pub fn color(text: String, color: Colour) -> String { - colour(text, color) -} - -// BACKGROUND ----------------------------------------------------------------- - -/// Colour the given text's background black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_black("lucy") -/// // => "\x1B[40mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_black(text: String) -> String { - run(text, code([40], 49)) -} - -/// Colour the given text's background red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_red("lucy") -/// // => "\x1B[41mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_red(text: String) -> String { - run(text, code([41], 49)) -} - -/// Colour the given text's background green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_green("lucy") -/// // => "\x1B[42mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_green(text: String) -> String { - run(text, code([42], 49)) -} - -/// Colour the given text's background yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_yellow("lucy") -/// // => "\x1B[43mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_yellow(text: String) -> String { - run(text, code([43], 49)) -} - -/// Colour the given text's background blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_blue("lucy") -/// // => "\x1B[44mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_blue(text: String) -> String { - run(text, code([44], 49)) -} - -/// Colour the given text's background magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_magenta("lucy") -/// // => "\x1B[45mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_magenta(text: String) -> String { - run(text, code([45], 49)) -} - -/// Colour the given text's background cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_cyan("lucy") -/// // => "\x1B[46mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_cyan(text: String) -> String { - run(text, code([46], 49)) -} - -/// Colour the given text's background white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_white("lucy") -/// // => "\x1B[47mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_white(text: String) -> String { - run(text, code([47], 49)) -} - -/// Colour the given text's background bright black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_black("lucy") -/// // => "\x1B[100mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_black(text: String) -> String { - run(text, code([100], 49)) -} - -/// Colour the given text's background bright red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_red("lucy") -/// // => "\x1B[101mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_red(text: String) -> String { - run(text, code([101], 49)) -} - -/// Colour the given text's background bright green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_green("lucy") -/// // => "\x1B[102mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_green(text: String) -> String { - run(text, code([102], 49)) -} - -/// Colour the given text's background bright yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_yellow("lucy") -/// // => "\x1B[103mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_yellow(text: String) -> String { - run(text, code([103], 49)) -} - -/// Colour the given text's background bright blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_blue("lucy") -/// // => "\x1B[104mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_blue(text: String) -> String { - run(text, code([104], 49)) -} - -/// Colour the given text's background bright magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_magenta("lucy") -/// // => "\x1B[105mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_magenta(text: String) -> String { - run(text, code([105], 49)) -} - -/// Colour the given text's background bright cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_cyan("lucy") -/// // => "\x1B[106mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_cyan(text: String) -> String { - run(text, code([106], 49)) -} - -/// Colour the given text's background bright white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_white("lucy") -/// // => "\x1B[107mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_white(text: String) -> String { - run(text, code([107], 49)) -} - -/// Colour the given text's background pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_pink("lucy") -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_pink(text: String) -> String { - bg_hex(text, 0xffaff3) -} - -/// Colour the given text's background the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_hex(text: String, colour: Int) -> String { - run( - text, - code( - [ - 48, - 2, - bitwise.shift_right(colour, 16) - |> bitwise.and(0xff), - bitwise.shift_right(colour, 8) - |> bitwise.and(0xff), - bitwise.and(colour, 0xff), - ], - 49, - ), - ) -} - -/// Colour the given text's background with the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.bg_colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - bg_hex(text, hex_colour) -} - -/// This is an alias for [`bg_colour`](#bg_colour) for those who prefer the American English -/// spelling. -/// -pub fn bg_color(text: String, colour: Colour) -> String { - bg_colour(text, colour) -} diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl deleted file mode 100644 index 0db99ed781b..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_community@ansi). --compile(no_auto_import). - --export([reset/1, bold/1, dim/1, italic/1, underline/1, inverse/1, hidden/1, strikethrough/1, black/1, red/1, green/1, yellow/1, blue/1, magenta/1, cyan/1, white/1, grey/1, gray/1, bright_black/1, bright_red/1, bright_green/1, bright_yellow/1, bright_blue/1, bright_magenta/1, bright_cyan/1, bright_white/1, pink/1, hex/2, colour/2, color/2, bg_black/1, bg_red/1, bg_green/1, bg_yellow/1, bg_blue/1, bg_magenta/1, bg_cyan/1, bg_white/1, bg_bright_black/1, bg_bright_red/1, bg_bright_green/1, bg_bright_yellow/1, bg_bright_blue/1, bg_bright_magenta/1, bg_bright_cyan/1, bg_bright_white/1, bg_pink/1, bg_hex/2, bg_colour/2, bg_color/2]). --export_type([code/0]). - --type code() :: {code, binary(), binary(), binary()}. - --spec code(list(integer()), integer()) -> code(). -code(Open, Close) -> - Close_str = gleam@int:to_string(Close), - Open_strs = gleam@list:map(Open, fun gleam@int:to_string/1), - {code, - <<<<<<""/utf8, "["/utf8>>/binary, - (gleam@string:join(Open_strs, <<";"/utf8>>))/binary>>/binary, - "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>}. - --spec run(binary(), code()) -> binary(). -run(Text, Code) -> - <<<<(erlang:element(2, Code))/binary, - (gleam@string:replace( - Text, - erlang:element(4, Code), - erlang:element(2, Code) - ))/binary>>/binary, - (erlang:element(3, Code))/binary>>. - --spec reset(binary()) -> binary(). -reset(Text) -> - run(Text, code([0], 0)). - --spec bold(binary()) -> binary(). -bold(Text) -> - run(Text, code([1], 22)). - --spec dim(binary()) -> binary(). -dim(Text) -> - run(Text, code([2], 22)). - --spec italic(binary()) -> binary(). -italic(Text) -> - run(Text, code([3], 23)). - --spec underline(binary()) -> binary(). -underline(Text) -> - run(Text, code([4], 24)). - --spec inverse(binary()) -> binary(). -inverse(Text) -> - run(Text, code([7], 27)). - --spec hidden(binary()) -> binary(). -hidden(Text) -> - run(Text, code([8], 28)). - --spec strikethrough(binary()) -> binary(). -strikethrough(Text) -> - run(Text, code([9], 29)). - --spec black(binary()) -> binary(). -black(Text) -> - run(Text, code([30], 39)). - --spec red(binary()) -> binary(). -red(Text) -> - run(Text, code([31], 39)). - --spec green(binary()) -> binary(). -green(Text) -> - run(Text, code([32], 39)). - --spec yellow(binary()) -> binary(). -yellow(Text) -> - run(Text, code([33], 39)). - --spec blue(binary()) -> binary(). -blue(Text) -> - run(Text, code([34], 39)). - --spec magenta(binary()) -> binary(). -magenta(Text) -> - run(Text, code([35], 39)). - --spec cyan(binary()) -> binary(). -cyan(Text) -> - run(Text, code([36], 39)). - --spec white(binary()) -> binary(). -white(Text) -> - run(Text, code([37], 39)). - --spec grey(binary()) -> binary(). -grey(Text) -> - bright_black(Text). - --spec gray(binary()) -> binary(). -gray(Text) -> - bright_black(Text). - --spec bright_black(binary()) -> binary(). -bright_black(Text) -> - run(Text, code([90], 39)). - --spec bright_red(binary()) -> binary(). -bright_red(Text) -> - run(Text, code([91], 39)). - --spec bright_green(binary()) -> binary(). -bright_green(Text) -> - run(Text, code([92], 39)). - --spec bright_yellow(binary()) -> binary(). -bright_yellow(Text) -> - run(Text, code([93], 39)). - --spec bright_blue(binary()) -> binary(). -bright_blue(Text) -> - run(Text, code([94], 39)). - --spec bright_magenta(binary()) -> binary(). -bright_magenta(Text) -> - run(Text, code([95], 39)). - --spec bright_cyan(binary()) -> binary(). -bright_cyan(Text) -> - run(Text, code([96], 39)). - --spec bright_white(binary()) -> binary(). -bright_white(Text) -> - run(Text, code([97], 39)). - --spec pink(binary()) -> binary(). -pink(Text) -> - hex(Text, 16#ffaff3). - --spec hex(binary(), integer()) -> binary(). -hex(Text, Colour) -> - Colour@1 = gleam@int:clamp(Colour, 16#0, 16#ffffff), - run( - Text, - code( - [38, - 2, - begin - _pipe = gleam@bitwise:shift_right(Colour@1, 16), - gleam@bitwise:'and'(_pipe, 16#ff) - end, - begin - _pipe@1 = gleam@bitwise:shift_right(Colour@1, 8), - gleam@bitwise:'and'(_pipe@1, 16#ff) - end, - gleam@bitwise:'and'(Colour@1, 16#ff)], - 39 - ) - ). - --spec colour(binary(), gleam_community@colour:colour()) -> binary(). -colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - hex(Text, Hex_colour). - --spec color(binary(), gleam_community@colour:colour()) -> binary(). -color(Text, Color) -> - colour(Text, Color). - --spec bg_black(binary()) -> binary(). -bg_black(Text) -> - run(Text, code([40], 49)). - --spec bg_red(binary()) -> binary(). -bg_red(Text) -> - run(Text, code([41], 49)). - --spec bg_green(binary()) -> binary(). -bg_green(Text) -> - run(Text, code([42], 49)). - --spec bg_yellow(binary()) -> binary(). -bg_yellow(Text) -> - run(Text, code([43], 49)). - --spec bg_blue(binary()) -> binary(). -bg_blue(Text) -> - run(Text, code([44], 49)). - --spec bg_magenta(binary()) -> binary(). -bg_magenta(Text) -> - run(Text, code([45], 49)). - --spec bg_cyan(binary()) -> binary(). -bg_cyan(Text) -> - run(Text, code([46], 49)). - --spec bg_white(binary()) -> binary(). -bg_white(Text) -> - run(Text, code([47], 49)). - --spec bg_bright_black(binary()) -> binary(). -bg_bright_black(Text) -> - run(Text, code([100], 49)). - --spec bg_bright_red(binary()) -> binary(). -bg_bright_red(Text) -> - run(Text, code([101], 49)). - --spec bg_bright_green(binary()) -> binary(). -bg_bright_green(Text) -> - run(Text, code([102], 49)). - --spec bg_bright_yellow(binary()) -> binary(). -bg_bright_yellow(Text) -> - run(Text, code([103], 49)). - --spec bg_bright_blue(binary()) -> binary(). -bg_bright_blue(Text) -> - run(Text, code([104], 49)). - --spec bg_bright_magenta(binary()) -> binary(). -bg_bright_magenta(Text) -> - run(Text, code([105], 49)). - --spec bg_bright_cyan(binary()) -> binary(). -bg_bright_cyan(Text) -> - run(Text, code([106], 49)). - --spec bg_bright_white(binary()) -> binary(). -bg_bright_white(Text) -> - run(Text, code([107], 49)). - --spec bg_pink(binary()) -> binary(). -bg_pink(Text) -> - bg_hex(Text, 16#ffaff3). - --spec bg_hex(binary(), integer()) -> binary(). -bg_hex(Text, Colour) -> - run( - Text, - code( - [48, - 2, - begin - _pipe = gleam@bitwise:shift_right(Colour, 16), - gleam@bitwise:'and'(_pipe, 16#ff) - end, - begin - _pipe@1 = gleam@bitwise:shift_right(Colour, 8), - gleam@bitwise:'and'(_pipe@1, 16#ff) - end, - gleam@bitwise:'and'(Colour, 16#ff)], - 49 - ) - ). - --spec bg_colour(binary(), gleam_community@colour:colour()) -> binary(). -bg_colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - bg_hex(Text, Hex_colour). - --spec bg_color(binary(), gleam_community@colour:colour()) -> binary(). -bg_color(Text, Colour) -> - bg_colour(Text, Colour). diff --git a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src b/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src deleted file mode 100644 index 75be12e5003..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, gleam_community_ansi, [ - {vsn, "1.1.0"}, - {applications, [gleam_bitwise, - gleam_community_colour, - gleam_stdlib, - gleeunit]}, - {description, "ANSI colours, formatting, and control codes"}, - {modules, [gleam_community@ansi]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE b/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/README.md b/test-community-packages-javascript/build/packages/gleam_community_colour/README.md deleted file mode 100644 index 0eccdd7dd50..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# gleam-community/colour - -A package for a standard Colour type, conversions, and other utilities. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_colour)](https://hex.pm/packages/gleam_community_colour) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_colour/) - -✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! - ---- - -## Quickstart - -```gleam -import gleam_community/colour -import gleam_community/colour/accessibility - -pub fn main() { - let foreground = colour.from_hsl(h: 0.858, s: 1.0, l: 0.843) - - let background_options = [colour.light_grey, colour.dark_grey] - - let background = accessibility.maximum_contrast(foreground, background_options) -} -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_colour) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_colour -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_colour). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml b/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml deleted file mode 100644 index 36aa4270553..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/gleam.toml +++ /dev/null @@ -1,12 +0,0 @@ -name = "gleam_community_colour" -version = "1.1.0" -licences = ["Apache-2.0"] -description = "Colour types, conversions, and other utilities" -repository = { type = "github", user = "gleam-community", repo = "colour" } - -[dependencies] -gleam_bitwise = "~> 1.2" -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl deleted file mode 100644 index 06116dfe288..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl +++ /dev/null @@ -1 +0,0 @@ --record(hsla, {h :: float(), s :: float(), l :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl b/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl deleted file mode 100644 index fff139e06ac..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl +++ /dev/null @@ -1 +0,0 @@ --record(rgba, {r :: float(), g :: float(), b :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam deleted file mode 100644 index 50244b5ab4f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour.gleam +++ /dev/null @@ -1,1127 +0,0 @@ -//// -//// - **Types** -//// - [`Colour`](#Colour) -//// - [`Color`](#Color) -//// - **Constructors** -//// - [`from_rgb255`](#from_rgb255) -//// - [`from_rgb`](#from_rgb) -//// - [`from_rgba`](#from_rgba) -//// - [`from_hsl`](#from_hsl) -//// - [`from_hsla`](#from_hsla) -//// - [`from_rgb_hex`](#from_rgb_hex) -//// - [`from_rgba_hex`](#from_rgba_hex) -//// - [`from_rgb_hex_string`](#from_rgb_hex_string) -//// - [`from_rgba_hex_string`](#from_rgba_hex_string) -//// - **Conversions** -//// - [`to_rgba`](#to_rgba) -//// - [`to_hsla`](#hsla) -//// - [`to_css_rgba_string`](#to_css_rgba_string) -//// - [`to_rgba_hex_string`](#to_rgba_hex_string) -//// - [`to_rgb_hex_string`](#to_rgb_hex_string) -//// - [`to_rgba_hex`](#to_rgba_hex) -//// - [`to_rgb_hex`](#to_rgb_hex) -//// - **Colours** -//// - [`light_red`](#light_red) -//// - [`red`](#red) -//// - [`dark_red`](#dark_red) -//// - [`light_orange`](#light_orange) -//// - [`orange`](#orange) -//// - [`dark_orange`](#dark_orange) -//// - [`light_yellow`](#light_yellow) -//// - [`yellow`](#yellow) -//// - [`dark_yellow`](#dark_yellow) -//// - [`light_green`](#light_green) -//// - [`green`](#green) -//// - [`dark_green`](#dark_green) -//// - [`light_blue`](#light_blue) -//// - [`blue`](#blue) -//// - [`dark_blue`](#dark_blue) -//// - [`light_purple`](#light_purple) -//// - [`purple`](#purple) -//// - [`dark_purple`](#dark_purple) -//// - [`light_brown`](#light_brown) -//// - [`brown`](#brown) -//// - [`dark_brown`](#dark_brown) -//// - [`black`](#black) -//// - [`white`](#white) -//// - [`light_grey`](#light_grey) -//// - [`grey`](#grey) -//// - [`dark_grey`](#dark_grey) -//// - [`light_gray`](#light_gray) -//// - [`gray`](#gray) -//// - [`dark_gray`](#dark_gray) -//// - [`light_charcoal`](#light_charcoal) -//// - [`charcoal`](#charcoal) -//// - [`dark_charcoal`](#dark_charcoal) -//// - [`pink`](#pink) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color` module. -//// The original source code can be found -//// <a href="https://github.com/avh4/elm-color/">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018 Aaron VonderHaar -//// -//// > Redistribution and use in source and binary forms, with or without modification, -//// are permitted provided that the following conditions are met: -//// -//// 1. Redistributions of source code must retain the above copyright notice, -//// this list of conditions and the following disclaimer. -//// -//// 2. Redistributions in binary form must reproduce the above copyright notice, -//// this list of conditions and the following disclaimer in the documentation -//// and/or other materials provided with the distribution. -//// -//// 3. Neither the name of the copyright holder nor the names of its contributors -//// may be used to endorse or promote products derived from this software without -//// specific prior written permission. -//// -//// > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -//// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -//// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -//// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -//// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -//// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color` module: -// -// https://github.com/avh4/elm-color/ -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/bitwise -import gleam/int -import gleam/float -import gleam/result -import gleam/string -import gleam/list - -// TYPES ---------------------------------------------------------------------- - -/// A representation of a colour that can be converted to RGBA or HSLA format. -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub opaque type Colour { - Rgba(r: Float, g: Float, b: Float, a: Float) - Hsla(h: Float, s: Float, l: Float, a: Float) -} - -/// Type alias for `Colour` -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub type Color = - Colour - -// UTILITY -------------------------------------------------------------------- - -fn valid_colour_value(c: Float) -> Result(Float, Nil) { - case c >. 1.0 || c <. 0.0 { - True -> Error(Nil) - False -> Ok(c) - } -} - -fn hue_to_rgb(hue: Float, m1: Float, m2: Float) -> Float { - let h = case hue { - _ if hue <. 0.0 -> hue +. 1.0 - _ if hue >. 1.0 -> hue -. 1.0 - _ -> hue - } - - let h_t_6 = h *. 6.0 - let h_t_2 = h *. 2.0 - let h_t_3 = h *. 3.0 - - case h { - _ if h_t_6 <. 1.0 -> m1 +. { m2 -. m1 } *. h *. 6.0 - _ if h_t_2 <. 1.0 -> m2 - _ if h_t_3 <. 2.0 -> m1 +. { m2 -. m1 } *. { 2.0 /. 3.0 -. h } *. 6.0 - _ -> m1 - } -} - -fn hex_string_to_int(hex_string: String) -> Result(Int, Nil) { - let hex = case hex_string { - "#" <> hex_number -> hex_number - "0x" <> hex_number -> hex_number - _ -> hex_string - } - - hex - |> string.lowercase() - |> string.to_graphemes() - |> list.reverse() - |> list.index_fold( - Ok(0), - fn(total, char, index) { - case total { - Error(Nil) -> Error(Nil) - Ok(v) -> { - use num <- result.then(case char { - "a" -> Ok(10) - "b" -> Ok(11) - "c" -> Ok(12) - "d" -> Ok(13) - "e" -> Ok(14) - "f" -> Ok(15) - _ -> int.parse(char) - }) - use base <- result.then(int.power(16, int.to_float(index))) - Ok(v + float.round(int.to_float(num) *. base)) - } - } - }, - ) -} - -fn hsla_to_rgba( - h: Float, - s: Float, - l: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let m2 = case l <=. 0.5 { - True -> l *. { s +. 1.0 } - False -> l +. s -. l *. s - } - - let m1 = l *. 2.0 -. m2 - - let r = hue_to_rgb(h +. 1.0 /. 3.0, m1, m2) - let g = hue_to_rgb(h, m1, m2) - let b = hue_to_rgb(h -. 1.0 /. 3.0, m1, m2) - - #(r, g, b, a) -} - -fn rgba_to_hsla( - r: Float, - g: Float, - b: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let min_colour = float.min(r, float.min(g, b)) - - let max_colour = float.max(r, float.max(g, b)) - - let h1 = case True { - _ if max_colour == r -> float.divide(g -. b, max_colour -. min_colour) - _ if max_colour == g -> - float.divide(b -. r, max_colour -. min_colour) - |> result.then(fn(d) { Ok(2.0 +. d) }) - _ -> - float.divide(r -. g, max_colour -. min_colour) - |> result.then(fn(d) { Ok(4.0 +. d) }) - } - - let h2 = case h1 { - Ok(v) -> Ok(v *. { 1.0 /. 6.0 }) - _ -> h1 - } - - let h3 = case h2 { - Ok(v) if v <. 0.0 -> v +. 1.0 - Ok(v) -> v - _ -> 0.0 - } - - let l = { min_colour +. max_colour } /. 2.0 - - let s = case True { - _ if min_colour == max_colour -> 0.0 - _ if l <. 0.5 -> - { max_colour -. min_colour } /. { max_colour +. min_colour } - _ -> { max_colour -. min_colour } /. { 2.0 -. max_colour -. min_colour } - } - - #(h3, s, l, a) -} - -// CONSTRUCTORS --------------------------------------------------------------- - -/// Returns a `Result(Colour)` created from the given 8 bit RGB values. -/// -/// Returns `Error(Nil)` if the supplied RGB values are greater than 255 or less than 0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb255(r red: Int, g green: Int, b blue: Int) -> Result(Colour, Nil) { - use r <- result.then( - red - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use g <- result.then( - green - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use b <- result.then( - blue - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGB values. -/// -/// If the supplied RGB values are greater than 1.0 or less than 0.0 returns `Error(Nil)` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb(1.0, 0.0, 0.0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb( - r red: Float, - g green: Float, - b blue: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGBA values. -/// -/// Returns `Error(Nil)` if the supplied RGBA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rbga(1.0, 0.0, 0.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba( - r red: Float, - g green: Float, - b blue: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Rgba(r: r, g: g, b: b, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSLA values. -/// -/// Returns `Error(Nil)`f the supplied HSLA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_hsla(0.0, 1.0, 0.5, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsla( - h hue: Float, - s saturation: Float, - l lightness: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use h <- result.then(valid_colour_value(hue)) - use s <- result.then(valid_colour_value(saturation)) - use l <- result.then(valid_colour_value(lightness)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Hsla(h: h, s: s, l: l, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSL values. -/// -/// Returns `Error(Nil)` if the supplied HSL values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_hsla(0.0, 1.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsl( - h hue: Float, - s saturation: Float, - l lightness: Float, -) -> Result(Colour, Nil) { - from_hsla(hue, saturation, lightness, 1.0) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex(0xff0000) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffff || hex < 0 { - True -> Error(Nil) - False -> { - let r = - bitwise.shift_right(hex, 16) - |> bitwise.and(0xff) - let g = - bitwise.shift_right(hex, 8) - |> bitwise.and(0xff) - let b = bitwise.and(hex, 0xff) - from_rgb255(r, g, b) - } - } -} - -/// Returns a `Result(Colour)` created from the given RGB hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex_string("#ff0000") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgb_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given RGBA hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex_string("#ff00007f") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgba_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex(0xff00007f) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffffff || hex < 0 { - True -> Error(Nil) - False -> { - // This won't fail because we are always dividing by 255.0 - let assert Ok(r) = - bitwise.shift_right(hex, 24) - |> bitwise.and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(g) = - bitwise.shift_right(hex, 16) - |> bitwise.and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(b) = - bitwise.shift_right(hex, 8) - |> bitwise.and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(a) = - bitwise.and(hex, 0xff) - |> int.to_float() - |> float.divide(255.0) - from_rgba(r, g, b, a) - } - } -} - -// CONVERSIONS ---------------------------------------------------------------- - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// R, G, B, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(r, g, b, a) = to_rgba(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Rgba(r, g, b, a) -> #(r, g, b, a) - Hsla(h, s, l, a) -> hsla_to_rgba(h, s, l, a) - } -} - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// H, S, L, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(h, s, l, a) = to_hsla(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_hsla(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Hsla(h, s, l, a) -> #(h, s, l, a) - Rgba(r, g, b, a) -> rgba_to_hsla(r, g, b, a) - } -} - -/// Returns an rgba formatted CSS `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let css_red = to_css_rgba_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_css_rgba_string(colour: Colour) -> String { - let #(r, g, b, a) = to_rgba(colour) - - let percent = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 100.0 - let assert Ok(p) = - x - |> float.multiply(10_000.0) - |> float.round() - |> int.to_float() - |> float.divide(100.0) - - p - } - - let round_to = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 1000.0 - let assert Ok(r) = - x - |> float.multiply(1000.0) - |> float.round() - |> int.to_float() - |> float.divide(1000.0) - - r - } - - string.join( - [ - "rgba(", - float.to_string(percent(r)) <> "%,", - float.to_string(percent(g)) <> "%,", - float.to_string(percent(b)) <> "%,", - float.to_string(round_to(a)), - ")", - ], - "", - ) -} - -/// Returns an rgba hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex = to_rgba_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex_string(colour: Colour) -> String { - to_rgba_hex(colour) - |> int.to_base16() -} - -/// Returns an rgb hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex = to_rgb_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex_string(colour: Colour) -> String { - to_rgb_hex(colour) - |> int.to_base16() -} - -/// Returns an hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex_int = to_rgba_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex(colour: Colour) -> Int { - let #(r, g, b, a) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> bitwise.shift_left(24) - - let green = - g *. 255.0 - |> float.round() - |> bitwise.shift_left(16) - - let blue = - b *. 255.0 - |> float.round() - |> bitwise.shift_left(8) - - let alpha = - a *. 255.0 - |> float.round() - - red + green + blue + alpha -} - -/// Returns a rgb hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex_int = to_rgb_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex(colour: Colour) -> Int { - let #(r, g, b, _) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> bitwise.shift_left(16) - - let green = - g *. 255.0 - |> float.round() - |> bitwise.shift_left(8) - - let blue = - b *. 255.0 - |> float.round() - - red + green + blue -} - -// COLOURS -------------------------------------------------------------------- - -/// A `Colour` reprsenting the colour RGBA(239, 41, 41, 1.0) -pub const light_red = Rgba( - r: 0.9372549019607843, - g: 0.1607843137254902, - b: 0.1607843137254902, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(204, 0, 0, 1.0) -pub const red = Rgba(r: 0.8, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(164, 0, 0, 1.0) -pub const dark_red = Rgba(r: 0.6431372549019608, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(252, 175, 62, 1.0) -pub const light_orange = Rgba( - r: 0.9882352941176471, - g: 0.6862745098039216, - b: 0.24313725490196078, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(245, 121, 0, 1.0) -pub const orange = Rgba( - r: 0.9607843137254902, - g: 0.4745098039215686, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(206, 92, 0, 1.0) -pub const dark_orange = Rgba( - r: 0.807843137254902, - g: 0.3607843137254902, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 233, 79, 1.0) -pub const light_yellow = Rgba( - r: 1.0, - g: 0.9137254901960784, - b: 0.30980392156862746, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(237, 212, 0, 1.0) -pub const yellow = Rgba( - r: 0.9294117647058824, - g: 0.8313725490196079, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(196, 160, 0, 1.0) -pub const dark_yellow = Rgba( - r: 0.7686274509803922, - g: 0.6274509803921569, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(138, 226, 52, 1.0) -pub const light_green = Rgba( - r: 0.5411764705882353, - g: 0.8862745098039215, - b: 0.20392156862745098, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(115, 210, 22, 1.0) -pub const green = Rgba( - r: 0.45098039215686275, - g: 0.8235294117647058, - b: 0.08627450980392157, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(78, 154, 6, 1.0) -pub const dark_green = Rgba( - r: 0.3058823529411765, - g: 0.6039215686274509, - b: 0.023529411764705882, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(114, 159, 207, 1.0) -pub const light_blue = Rgba( - r: 0.4470588235294118, - g: 0.6235294117647059, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(52, 101, 164, 1.0) -pub const blue = Rgba( - r: 0.20392156862745098, - g: 0.396078431372549, - b: 0.6431372549019608, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(32, 74, 135, 1.0) -pub const dark_blue = Rgba( - r: 0.12549019607843137, - g: 0.2901960784313726, - b: 0.5294117647058824, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(173, 127, 168, 1.0) -pub const light_purple = Rgba( - r: 0.6784313725490196, - g: 0.4980392156862745, - b: 0.6588235294117647, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(117, 80, 123, 1.0) -pub const purple = Rgba( - r: 0.4588235294117647, - g: 0.3137254901960784, - b: 0.4823529411764706, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(92, 53, 102, 1.0) -pub const dark_purple = Rgba( - r: 0.3607843137254902, - g: 0.20784313725490197, - b: 0.4, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(233, 185, 110, 1.0) -pub const light_brown = Rgba( - r: 0.9137254901960784, - g: 0.7254901960784313, - b: 0.43137254901960786, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(193, 125, 17, 1.0) -pub const brown = Rgba( - r: 0.7568627450980392, - g: 0.49019607843137253, - b: 0.06666666666666667, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(143, 89, 2, 1.0) -pub const dark_brown = Rgba( - r: 0.5607843137254902, - g: 0.34901960784313724, - b: 0.00784313725490196, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(0, 0, 0, 1.0) -pub const black = Rgba(r: 0.0, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(255, 255, 255, 1.0) -pub const white = Rgba(r: 1.0, g: 1.0, b: 1.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_grey = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const grey = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_grey = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_gray = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const gray = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_gray = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(136, 138, 133, 1.0) -pub const light_charcoal = Rgba( - r: 0.5333333333333333, - g: 0.5411764705882353, - b: 0.5215686274509804, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(85, 87, 83, 1.0) -pub const charcoal = Rgba( - r: 0.3333333333333333, - g: 0.3411764705882353, - b: 0.3254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(46, 52, 54, 1.0) -pub const dark_charcoal = Rgba( - r: 0.1803921568627451, - g: 0.20392156862745098, - b: 0.21176470588235294, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 175, 243, 1.0) -pub const pink = Rgba( - r: 1.0, - g: 0.6862745098039216, - b: 0.9529411764705882, - a: 1.0, -) diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam deleted file mode 100644 index 471685732f9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam +++ /dev/null @@ -1,173 +0,0 @@ -//// -//// - **Accessibility** -//// - [`luminance`](#luminance) -//// - [`contrast_ratio`](#contrast_ratio) -//// - [`maximum_contrast`](#maximum_contrast) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color-extra` module. -//// The original source code can be found -//// <a href="https://github.com/noahzgordon/elm-color-extra">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright (c) 2016 Andreas Köberle -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// -//// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -//// SOFTWARE. -//// -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color-extra` module: -// -// https://github.com/noahzgordon/elm-color-extra -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/float -import gleam/list -import gleam_community/colour.{Colour} - -// UTILITIES ------------------------------------------------------------------ - -fn intensity(colour_value: Float) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - case True { - _ if colour_value <=. 0.03928 -> colour_value /. 12.92 - _ -> { - // Is this guaranteed to be `OK`? - let assert Ok(i) = float.power({ colour_value +. 0.055 } /. 1.055, 2.4) - i - } - } -} - -// ACCESSIBILITY -------------------------------------------------------------- - -/// Returns the relative brightness of the given `Colour` as a `Float` between -/// 0.0, and 1.0 with 0.0 being the darkest possible colour and 1.0 being the lightest. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// luminance(colour.white) // 1.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn luminance(colour: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - let #(r, g, b, _) = colour.to_rgba(colour) - - let r_intensity = intensity(r) - let g_intensity = intensity(g) - let b_intensity = intensity(b) - - 0.2126 *. r_intensity +. 0.7152 *. g_intensity +. 0.0722 *. b_intensity -} - -/// Returns the contrast between two `Colour` values as a `Float` between 1.0, -/// and 21.0 with 1.0 being no contrast and, 21.0 being the highest possible contrast. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// contrast_ratio(between: colour.white, and: colour.black) // 21.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn contrast_ratio(between colour_a: Colour, and colour_b: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#contrast-ratiodef - let luminance_a = luminance(colour_a) +. 0.05 - let luminance_b = luminance(colour_b) +. 0.05 - - case luminance_a >. luminance_b { - True -> luminance_a /. luminance_b - False -> luminance_b /. luminance_a - } -} - -/// Returns the `Colour` with the highest contrast between the base `Colour`, -/// and and the other provided `Colour` values. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// maximum_contrast( -/// colour.yellow, -/// [colour.white, colour.dark_blue, colour.green], -/// ) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn maximum_contrast( - base: Colour, - colours: List(Colour), -) -> Result(Colour, Nil) { - colours - |> list.sort(fn(colour_a, colour_b) { - let contrast_a = contrast_ratio(base, colour_a) - let contrast_b = contrast_ratio(base, colour_b) - - float.compare(contrast_b, contrast_a) - }) - |> list.first() -} diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl deleted file mode 100644 index 6b3063f7aa0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour.erl +++ /dev/null @@ -1,525 +0,0 @@ --module(gleam_community@colour). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_rgb255/3, from_rgb/3, from_rgba/4, from_hsla/4, from_hsl/3, from_rgb_hex/1, from_rgb_hex_string/1, from_rgba_hex/1, from_rgba_hex_string/1, to_rgba/1, to_hsla/1, to_css_rgba_string/1, to_rgba_hex/1, to_rgba_hex_string/1, to_rgb_hex/1, to_rgb_hex_string/1]). --export_type([colour/0]). - --opaque colour() :: {rgba, float(), float(), float(), float()} | - {hsla, float(), float(), float(), float()}. - --spec valid_colour_value(float()) -> {ok, float()} | {error, nil}. -valid_colour_value(C) -> - case (C > 1.0) orelse (C < 0.0) of - true -> - {error, nil}; - - false -> - {ok, C} - end. - --spec hue_to_rgb(float(), float(), float()) -> float(). -hue_to_rgb(Hue, M1, M2) -> - H = case Hue of - _ when Hue < 0.0 -> - Hue + 1.0; - - _ when Hue > 1.0 -> - Hue - 1.0; - - _ -> - Hue - end, - H_t_6 = H * 6.0, - H_t_2 = H * 2.0, - H_t_3 = H * 3.0, - case H of - _ when H_t_6 < 1.0 -> - M1 + (((M2 - M1) * H) * 6.0); - - _ when H_t_2 < 1.0 -> - M2; - - _ when H_t_3 < 2.0 -> - M1 + (((M2 - M1) * ((2.0 / 3.0) - H)) * 6.0); - - _ -> - M1 - end. - --spec hex_string_to_int(binary()) -> {ok, integer()} | {error, nil}. -hex_string_to_int(Hex_string) -> - Hex = case Hex_string of - <<"#"/utf8, Hex_number/binary>> -> - Hex_number; - - <<"0x"/utf8, Hex_number@1/binary>> -> - Hex_number@1; - - _ -> - Hex_string - end, - _pipe = Hex, - _pipe@1 = gleam@string:lowercase(_pipe), - _pipe@2 = gleam@string:to_graphemes(_pipe@1), - _pipe@3 = gleam@list:reverse(_pipe@2), - gleam@list:index_fold( - _pipe@3, - {ok, 0}, - fun(Total, Char, Index) -> case Total of - {error, nil} -> - {error, nil}; - - {ok, V} -> - gleam@result:then(case Char of - <<"a"/utf8>> -> - {ok, 10}; - - <<"b"/utf8>> -> - {ok, 11}; - - <<"c"/utf8>> -> - {ok, 12}; - - <<"d"/utf8>> -> - {ok, 13}; - - <<"e"/utf8>> -> - {ok, 14}; - - <<"f"/utf8>> -> - {ok, 15}; - - _ -> - gleam@int:parse(Char) - end, fun(Num) -> - gleam@result:then( - gleam@int:power(16, gleam@int:to_float(Index)), - fun(Base) -> - {ok, - V - + gleam@float:round( - gleam@int:to_float(Num) - * Base - )} - end - ) - end) - end end - ). - --spec hsla_to_rgba(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -hsla_to_rgba(H, S, L, A) -> - M2 = case L =< 0.5 of - true -> - L * (S + 1.0); - - false -> - (L + S) - (L * S) - end, - M1 = (L * 2.0) - M2, - R = hue_to_rgb(H + (1.0 / 3.0), M1, M2), - G = hue_to_rgb(H, M1, M2), - B = hue_to_rgb(H - (1.0 / 3.0), M1, M2), - {R, G, B, A}. - --spec rgba_to_hsla(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -rgba_to_hsla(R, G, B, A) -> - Min_colour = gleam@float:min(R, gleam@float:min(G, B)), - Max_colour = gleam@float:max(R, gleam@float:max(G, B)), - H1 = case true of - _ when Max_colour =:= R -> - gleam@float:divide(G - B, Max_colour - Min_colour); - - _ when Max_colour =:= G -> - _pipe = gleam@float:divide(B - R, Max_colour - Min_colour), - gleam@result:then(_pipe, fun(D) -> {ok, 2.0 + D} end); - - _ -> - _pipe@1 = gleam@float:divide(R - G, Max_colour - Min_colour), - gleam@result:then(_pipe@1, fun(D@1) -> {ok, 4.0 + D@1} end) - end, - H2 = case H1 of - {ok, V} -> - {ok, V * (1.0 / 6.0)}; - - _ -> - H1 - end, - H3 = case H2 of - {ok, V@1} when V@1 < 0.0 -> - V@1 + 1.0; - - {ok, V@2} -> - V@2; - - _ -> - 0.0 - end, - L = (Min_colour + Max_colour) / 2.0, - S = case true of - _ when Min_colour =:= Max_colour -> - 0.0; - - _ when L < 0.5 -> - case (Max_colour + Min_colour) of - 0.0 -> 0.0; - Gleam@denominator -> (Max_colour - Min_colour) / Gleam@denominator - end; - - _ -> - case ((2.0 - Max_colour) - Min_colour) of - 0.0 -> 0.0; - Gleam@denominator@1 -> (Max_colour - Min_colour) / Gleam@denominator@1 - end - end, - {H3, S, L, A}. - --spec from_rgb255(integer(), integer(), integer()) -> {ok, colour()} | - {error, nil}. -from_rgb255(Red, Green, Blue) -> - gleam@result:then( - begin - _pipe = Red, - _pipe@1 = gleam@int:to_float(_pipe), - _pipe@2 = gleam@float:divide(_pipe@1, 255.0), - gleam@result:then(_pipe@2, fun valid_colour_value/1) - end, - fun(R) -> - gleam@result:then( - begin - _pipe@3 = Green, - _pipe@4 = gleam@int:to_float(_pipe@3), - _pipe@5 = gleam@float:divide(_pipe@4, 255.0), - gleam@result:then(_pipe@5, fun valid_colour_value/1) - end, - fun(G) -> - gleam@result:then( - begin - _pipe@6 = Blue, - _pipe@7 = gleam@int:to_float(_pipe@6), - _pipe@8 = gleam@float:divide(_pipe@7, 255.0), - gleam@result:then(_pipe@8, fun valid_colour_value/1) - end, - fun(B) -> - {ok, {rgba, R, G, B, 1.0}} - end - ) - end - ) - end - ). - --spec from_rgb(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_rgb(Red, Green, Blue) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> - {ok, {rgba, R, G, B, 1.0}} - end - ) - end - ) - end - ). - --spec from_rgba(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_rgba(Red, Green, Blue, Alpha) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> - {ok, {rgba, R, G, B, A}} - end - ) - end - ) - end - ) - end - ). - --spec from_hsla(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_hsla(Hue, Saturation, Lightness, Alpha) -> - gleam@result:then( - valid_colour_value(Hue), - fun(H) -> - gleam@result:then( - valid_colour_value(Saturation), - fun(S) -> - gleam@result:then( - valid_colour_value(Lightness), - fun(L) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> - {ok, {hsla, H, S, L, A}} - end - ) - end - ) - end - ) - end - ). - --spec from_hsl(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_hsl(Hue, Saturation, Lightness) -> - from_hsla(Hue, Saturation, Lightness, 1.0). - --spec from_rgb_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgb_hex(Hex) -> - case (Hex > 16#ffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - R = begin - _pipe = gleam@bitwise:shift_right(Hex, 16), - gleam@bitwise:'and'(_pipe, 16#ff) - end, - G = begin - _pipe@1 = gleam@bitwise:shift_right(Hex, 8), - gleam@bitwise:'and'(_pipe@1, 16#ff) - end, - B = gleam@bitwise:'and'(Hex, 16#ff), - from_rgb255(R, G, B) - end. - --spec from_rgb_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgb_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> - from_rgb_hex(Hex_int) - end - ). - --spec from_rgba_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgba_hex(Hex) -> - case (Hex > 16#ffffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - _assert_subject = begin - _pipe = gleam@bitwise:shift_right(Hex, 24), - _pipe@1 = gleam@bitwise:'and'(_pipe, 16#ff), - _pipe@2 = gleam@int:to_float(_pipe@1), - gleam@float:divide(_pipe@2, 255.0) - end, - {ok, R} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 589}) - end, - _assert_subject@1 = begin - _pipe@3 = gleam@bitwise:shift_right(Hex, 16), - _pipe@4 = gleam@bitwise:'and'(_pipe@3, 16#ff), - _pipe@5 = gleam@int:to_float(_pipe@4), - gleam@float:divide(_pipe@5, 255.0) - end, - {ok, G} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 595}) - end, - _assert_subject@2 = begin - _pipe@6 = gleam@bitwise:shift_right(Hex, 8), - _pipe@7 = gleam@bitwise:'and'(_pipe@6, 16#ff), - _pipe@8 = gleam@int:to_float(_pipe@7), - gleam@float:divide(_pipe@8, 255.0) - end, - {ok, B} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 601}) - end, - _assert_subject@3 = begin - _pipe@9 = gleam@bitwise:'and'(Hex, 16#ff), - _pipe@10 = gleam@int:to_float(_pipe@9), - gleam@float:divide(_pipe@10, 255.0) - end, - {ok, A} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 607}) - end, - from_rgba(R, G, B, A) - end. - --spec from_rgba_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgba_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> - from_rgba_hex(Hex_int) - end - ). - --spec to_rgba(colour()) -> {float(), float(), float(), float()}. -to_rgba(Colour) -> - case Colour of - {rgba, R, G, B, A} -> - {R, G, B, A}; - - {hsla, H, S, L, A@1} -> - hsla_to_rgba(H, S, L, A@1) - end. - --spec to_hsla(colour()) -> {float(), float(), float(), float()}. -to_hsla(Colour) -> - case Colour of - {hsla, H, S, L, A} -> - {H, S, L, A}; - - {rgba, R, G, B, A@1} -> - rgba_to_hsla(R, G, B, A@1) - end. - --spec to_css_rgba_string(colour()) -> binary(). -to_css_rgba_string(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Percent = fun(X) -> - _assert_subject = begin - _pipe = X, - _pipe@1 = gleam@float:multiply(_pipe, 10000.0), - _pipe@2 = gleam@float:round(_pipe@1), - _pipe@3 = gleam@int:to_float(_pipe@2), - gleam@float:divide(_pipe@3, 100.0) - end, - {ok, P} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 705}) - end, - P - end, - Round_to = fun(X@1) -> - _assert_subject@1 = begin - _pipe@4 = X@1, - _pipe@5 = gleam@float:multiply(_pipe@4, 1000.0), - _pipe@6 = gleam@float:round(_pipe@5), - _pipe@7 = gleam@int:to_float(_pipe@6), - gleam@float:divide(_pipe@7, 1000.0) - end, - {ok, R@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 717}) - end, - R@1 - end, - gleam@string:join( - [<<"rgba("/utf8>>, - <<(gleam@float:to_string(Percent(R)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(G)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(B)))/binary, "%,"/utf8>>, - gleam@float:to_string(Round_to(A)), - <<")"/utf8>>], - <<""/utf8>> - ). - --spec to_rgba_hex(colour()) -> integer(). -to_rgba_hex(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - gleam@bitwise:shift_left(_pipe@1, 24) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - gleam@bitwise:shift_left(_pipe@3, 16) - end, - Blue = begin - _pipe@4 = B * 255.0, - _pipe@5 = gleam@float:round(_pipe@4), - gleam@bitwise:shift_left(_pipe@5, 8) - end, - Alpha = begin - _pipe@6 = A * 255.0, - gleam@float:round(_pipe@6) - end, - ((Red + Green) + Blue) + Alpha. - --spec to_rgba_hex_string(colour()) -> binary(). -to_rgba_hex_string(Colour) -> - _pipe = to_rgba_hex(Colour), - gleam@int:to_base16(_pipe). - --spec to_rgb_hex(colour()) -> integer(). -to_rgb_hex(Colour) -> - {R, G, B, _} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - gleam@bitwise:shift_left(_pipe@1, 16) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - gleam@bitwise:shift_left(_pipe@3, 8) - end, - Blue = begin - _pipe@4 = B * 255.0, - gleam@float:round(_pipe@4) - end, - (Red + Green) + Blue. - --spec to_rgb_hex_string(colour()) -> binary(). -to_rgb_hex_string(Colour) -> - _pipe = to_rgb_hex(Colour), - gleam@int:to_base16(_pipe). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl deleted file mode 100644 index cacebf288c5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(gleam_community@colour@accessibility). --compile([no_auto_import, nowarn_unused_vars]). - --export([luminance/1, contrast_ratio/2, maximum_contrast/2]). - --spec intensity(float()) -> float(). -intensity(Colour_value) -> - case true of - _ when Colour_value =< 0.03928 -> - Colour_value / 12.92; - - _ -> - _assert_subject = gleam@float:power( - (Colour_value - + 0.055) - / 1.055, - 2.4 - ), - {ok, I} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour/accessibility"/utf8>>, - function => <<"intensity"/utf8>>, - line => 62}) - end, - I - end. - --spec luminance(gleam_community@colour:colour()) -> float(). -luminance(Colour) -> - {R, G, B, _} = gleam_community@colour:to_rgba(Colour), - R_intensity = intensity(R), - G_intensity = intensity(G), - B_intensity = intensity(B), - ((0.2126 * R_intensity) + (0.7152 * G_intensity)) + (0.0722 * B_intensity). - --spec contrast_ratio( - gleam_community@colour:colour(), - gleam_community@colour:colour() -) -> float(). -contrast_ratio(Colour_a, Colour_b) -> - Luminance_a = luminance(Colour_a) + 0.05, - Luminance_b = luminance(Colour_b) + 0.05, - case Luminance_a > Luminance_b of - true -> - case Luminance_b of - 0.0 -> 0.0; - Gleam@denominator -> Luminance_a / Gleam@denominator - end; - - false -> - case Luminance_a of - 0.0 -> 0.0; - Gleam@denominator@1 -> Luminance_b / Gleam@denominator@1 - end - end. - --spec maximum_contrast( - gleam_community@colour:colour(), - list(gleam_community@colour:colour()) -) -> {ok, gleam_community@colour:colour()} | {error, nil}. -maximum_contrast(Base, Colours) -> - _pipe = Colours, - _pipe@1 = gleam@list:sort( - _pipe, - fun(Colour_a, Colour_b) -> - Contrast_a = contrast_ratio(Base, Colour_a), - Contrast_b = contrast_ratio(Base, Colour_b), - gleam@float:compare(Contrast_b, Contrast_a) - end - ), - gleam@list:first(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src b/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src deleted file mode 100644 index 4755b196289..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_community_colour/src/gleam_community_colour.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, gleam_community_colour, [ - {vsn, "1.1.0"}, - {applications, [gleam_bitwise, - gleam_stdlib, - gleeunit]}, - {description, "Colour types, conversions, and other utilities"}, - {modules, [gleam_community@colour, - gleam_community@colour@accessibility]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/LICENSE b/test-community-packages-javascript/build/packages/gleam_cors/LICENSE deleted file mode 100644 index 728cade93fb..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Filip Figiel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/README.md b/test-community-packages-javascript/build/packages/gleam_cors/README.md deleted file mode 100644 index d753b8da638..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# gleam_cors - -[![Package Version](https://img.shields.io/hexpm/v/gleam_cors)](https://hex.pm/packages/gleam_cors) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_cors/) - -Unofficial CORS middleware for the [`gleam_http`](https://hexdocs.pm/gleam_http/index.html) library. - -## Installation - -```sh -gleam add gleam_cors -``` - -## Usage - -Use the `middleware` function to set up CORS for your application. This middleware should be -placed early in your middleware stack (late in the pipeline). - -```diff -+import gleam/http/cors -+import gleam/http - import myproject/web/middleware - - pub fn stack() { - service - |> middleware.rescue - |> middleware.log -+ |> cors.middleware( -+ origins: ["http://localhost:8000"], -+ methods: [http.Get, http.Post, http.Delete], -+ headers: ["Authorization", "Content-Type"], -+ ) - } -``` - -## Changelog - -See [CHANGELOG.md](CHANGELOG.md) in the project repository diff --git a/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml b/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml deleted file mode 100644 index c6861872847..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "gleam_cors" -version = "0.2.0" - -licences = ["MIT"] -description = "A CORS middleware for Gleam" -repository = { type = "github", user = "megapctr", repo = "gleam_cors" } - -[dependencies] -gleam_stdlib = "~> 0.29" -gleam_http = "~> 3.2" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam deleted file mode 100644 index 42a869b6441..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam/http/cors.gleam +++ /dev/null @@ -1,227 +0,0 @@ -import gleam/http.{Method, Options} -import gleam/http/request.{Request} -import gleam/http/response -import gleam/http/service.{Middleware} -import gleam/bit_builder.{BitBuilder} -import gleam/result.{try} -import gleam/list -import gleam/set.{Set} -import gleam/function -import gleam/string - -type Config { - Config( - allowed_origins: AllowedOrigins, - allowed_methods: AllowedMethods, - allowed_headers: AllowedHeaders, - ) -} - -type AllowedOrigins { - AllowAll - AllowSome(Set(String)) -} - -type AllowedMethods = - Set(Method) - -type AllowedHeaders = - Set(String) - -const allow_origin_header = "Access-Control-Allow-Origin" - -const allow_all_origins = "*" - -const request_method_header = "Access-Control-Request-Method" - -const request_headers_header = "Access-Control-Request-Headers" - -const allow_headers_header = "Access-Control-Allow-Headers" - -fn parse_config( - allowed_origins: List(String), - allowed_methods: List(Method), - allowed_headers: List(String), -) -> Result(Config, Nil) { - use allowed_origins <- try(parse_allowed_origins(allowed_origins)) - use allowed_methods <- try(parse_allowed_methods(allowed_methods)) - use allowed_headers <- try(parse_allowed_headers(allowed_headers)) - Config(allowed_origins, allowed_methods, allowed_headers) - |> Ok -} - -fn parse_allowed_origins(l: List(String)) -> Result(AllowedOrigins, Nil) { - case list.contains(l, allow_all_origins), l { - True, _ -> Ok(AllowAll) - _, origins -> { - let origins_set = - origins - |> list.map(string.lowercase) - |> set.from_list - // `handler` relies on "" not being in the set, "" is not a valid origin anyway - |> set.delete("") - case set.size(origins_set) { - 0 -> Error(Nil) - _ -> - AllowSome(origins_set) - |> Ok - } - } - } -} - -fn parse_allowed_methods(l: List(Method)) -> Result(AllowedMethods, Nil) { - let methods_set = set.from_list(l) - case set.size(methods_set) { - 0 -> Error(Nil) - _ -> Ok(methods_set) - } -} - -fn parse_allowed_headers(l: List(String)) -> Result(AllowedHeaders, Nil) { - let headers_set = - l - |> list.map(string.lowercase) - |> set.from_list - Ok(headers_set) -} - -type Response = - response.Response(BitBuilder) - -/// A middleware that adds CORS headers to responses based on the given configuration. -/// -/// ## Examples -/// -/// service -/// |> cors.middleware( -/// origins: ["https://staging.example.com", "http://localhost:8000"], -/// methods: [Get, Post, Delete], -/// headers: ["Authorization", "Content-Type"], -/// ) -pub fn middleware( - origins allowed_origins: List(String), - methods allowed_methods: List(Method), - headers allowed_headers: List(String), -) -> Middleware(a, BitBuilder, a, BitBuilder) { - case parse_config(allowed_origins, allowed_methods, allowed_headers) { - Ok(config) -> middleware_from_config(config) - Error(_) -> function.identity - } -} - -fn middleware_from_config( - config: Config, -) -> Middleware(a, BitBuilder, a, BitBuilder) { - fn(service) { - fn(request: Request(a)) -> Response { - case request.method { - Options -> handle_options_request(request, config) - _ -> handle_other_request(service, request, config.allowed_origins) - } - } - } -} - -/// For OPTIONS requests, we must check if request origin, request method and request headers are -/// allowed, and include CORS headers for allowed origin and allowed headers. -fn handle_options_request(request: Request(a), config: Config) -> Response { - let response = - response.new(200) - |> response.set_body(bit_builder.new()) - - let origin = get_origin(request) - - let ac_request_method = - request.get_header(request, request_method_header) - |> result.then(http.parse_method) - |> result.unwrap(http.Other("")) - - let ac_request_headers = - request.get_header(request, request_headers_header) - |> result.map(string.split(_, ", ")) - |> result.unwrap([]) - - let is_request_allowed = - is_origin_allowed(origin, config.allowed_origins) && is_method_allowed( - ac_request_method, - config.allowed_methods, - ) && are_headers_allowed(ac_request_headers, config.allowed_headers) - case is_request_allowed { - True -> - response - |> prepend_allow_origin_header(origin, config.allowed_origins) - |> prepend_allow_headers_header(ac_request_headers) - False -> response - } -} - -/// For other requests, if the request Origin header matches allowed origins, we must include the CORS header for allowed origin. -fn handle_other_request( - service, - request: Request(a), - allowed_origins: AllowedOrigins, -) -> Response { - let origin = get_origin(request) - let response = service(request) - case is_origin_allowed(origin, allowed_origins) { - True -> - response - |> prepend_allow_origin_header(origin, allowed_origins) - False -> response - } -} - -fn get_origin(request: Request(a)) -> String { - request.get_header(request, "origin") - |> result.unwrap("") -} - -fn is_origin_allowed(origin: String, allowed_origins: AllowedOrigins) -> Bool { - case allowed_origins { - AllowAll -> True - AllowSome(origins) -> set.contains(origins, string.lowercase(origin)) - } -} - -fn is_method_allowed(method: Method, allowed_methods: AllowedMethods) -> Bool { - set.contains(allowed_methods, method) -} - -fn are_headers_allowed( - request_headers: List(String), - allowed_headers: AllowedHeaders, -) -> Bool { - list.all( - request_headers, - fn(header) { set.contains(allowed_headers, string.lowercase(header)) }, - ) -} - -fn prepend_allow_origin_header( - response: Response, - origin: String, - allowed_origins: AllowedOrigins, -) -> Response { - case allowed_origins { - AllowAll -> - response - |> response.prepend_header(allow_origin_header, allow_all_origins) - AllowSome(_) -> - response - |> response.prepend_header(allow_origin_header, origin) - |> response.prepend_header("Vary", "Origin") - } -} - -fn prepend_allow_headers_header( - response: Response, - headers: List(String), -) -> Response { - case list.length(headers) { - 0 -> response - _ -> - string.join(headers, ", ") - |> response.prepend_header(response, allow_headers_header, _) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl deleted file mode 100644 index 0f9d5b47cd9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam@http@cors.erl +++ /dev/null @@ -1,243 +0,0 @@ --module(gleam@http@cors). --compile([no_auto_import, nowarn_unused_vars]). - --export([middleware/3]). --export_type([config/0, allowed_origins/0]). - --type config() :: {config, - allowed_origins(), - gleam@set:set(gleam@http:method()), - gleam@set:set(binary())}. - --type allowed_origins() :: allow_all | {allow_some, gleam@set:set(binary())}. - --spec parse_allowed_origins(list(binary())) -> {ok, allowed_origins()} | - {error, nil}. -parse_allowed_origins(L) -> - case {gleam@list:contains(L, <<"*"/utf8>>), L} of - {true, _} -> - {ok, allow_all}; - - {_, Origins} -> - Origins_set = begin - _pipe = Origins, - _pipe@1 = gleam@list:map(_pipe, fun gleam@string:lowercase/1), - _pipe@2 = gleam@set:from_list(_pipe@1), - gleam@set:delete(_pipe@2, <<""/utf8>>) - end, - case gleam@set:size(Origins_set) of - 0 -> - {error, nil}; - - _ -> - _pipe@3 = {allow_some, Origins_set}, - {ok, _pipe@3} - end - end. - --spec parse_allowed_methods(list(gleam@http:method())) -> {ok, - gleam@set:set(gleam@http:method())} | - {error, nil}. -parse_allowed_methods(L) -> - Methods_set = gleam@set:from_list(L), - case gleam@set:size(Methods_set) of - 0 -> - {error, nil}; - - _ -> - {ok, Methods_set} - end. - --spec parse_allowed_headers(list(binary())) -> {ok, gleam@set:set(binary())} | - {error, nil}. -parse_allowed_headers(L) -> - Headers_set = begin - _pipe = L, - _pipe@1 = gleam@list:map(_pipe, fun gleam@string:lowercase/1), - gleam@set:from_list(_pipe@1) - end, - {ok, Headers_set}. - --spec parse_config(list(binary()), list(gleam@http:method()), list(binary())) -> {ok, - config()} | - {error, nil}. -parse_config(Allowed_origins, Allowed_methods, Allowed_headers) -> - gleam@result:'try'( - parse_allowed_origins(Allowed_origins), - fun(Allowed_origins@1) -> - gleam@result:'try'( - parse_allowed_methods(Allowed_methods), - fun(Allowed_methods@1) -> - gleam@result:'try'( - parse_allowed_headers(Allowed_headers), - fun(Allowed_headers@1) -> - _pipe = {config, - Allowed_origins@1, - Allowed_methods@1, - Allowed_headers@1}, - {ok, _pipe} - end - ) - end - ) - end - ). - --spec get_origin(gleam@http@request:request(any())) -> binary(). -get_origin(Request) -> - _pipe = gleam@http@request:get_header(Request, <<"origin"/utf8>>), - gleam@result:unwrap(_pipe, <<""/utf8>>). - --spec is_origin_allowed(binary(), allowed_origins()) -> boolean(). -is_origin_allowed(Origin, Allowed_origins) -> - case Allowed_origins of - allow_all -> - true; - - {allow_some, Origins} -> - gleam@set:contains(Origins, gleam@string:lowercase(Origin)) - end. - --spec is_method_allowed(gleam@http:method(), gleam@set:set(gleam@http:method())) -> boolean(). -is_method_allowed(Method, Allowed_methods) -> - gleam@set:contains(Allowed_methods, Method). - --spec are_headers_allowed(list(binary()), gleam@set:set(binary())) -> boolean(). -are_headers_allowed(Request_headers, Allowed_headers) -> - gleam@list:all( - Request_headers, - fun(Header) -> - gleam@set:contains(Allowed_headers, gleam@string:lowercase(Header)) - end - ). - --spec prepend_allow_origin_header( - gleam@http@response:response(gleam@bit_builder:bit_builder()), - binary(), - allowed_origins() -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -prepend_allow_origin_header(Response, Origin, Allowed_origins) -> - case Allowed_origins of - allow_all -> - _pipe = Response, - gleam@http@response:prepend_header( - _pipe, - <<"Access-Control-Allow-Origin"/utf8>>, - <<"*"/utf8>> - ); - - {allow_some, _} -> - _pipe@1 = Response, - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"Access-Control-Allow-Origin"/utf8>>, - Origin - ), - gleam@http@response:prepend_header( - _pipe@2, - <<"Vary"/utf8>>, - <<"Origin"/utf8>> - ) - end. - --spec handle_other_request( - fun((gleam@http@request:request(FTP)) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - gleam@http@request:request(FTP), - allowed_origins() -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -handle_other_request(Service, Request, Allowed_origins) -> - Origin = get_origin(Request), - Response = Service(Request), - case is_origin_allowed(Origin, Allowed_origins) of - true -> - _pipe = Response, - prepend_allow_origin_header(_pipe, Origin, Allowed_origins); - - false -> - Response - end. - --spec prepend_allow_headers_header( - gleam@http@response:response(gleam@bit_builder:bit_builder()), - list(binary()) -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -prepend_allow_headers_header(Response, Headers) -> - case gleam@list:length(Headers) of - 0 -> - Response; - - _ -> - _pipe = gleam@string:join(Headers, <<", "/utf8>>), - gleam@http@response:prepend_header( - Response, - <<"Access-Control-Allow-Headers"/utf8>>, - _pipe - ) - end. - --spec handle_options_request(gleam@http@request:request(any()), config()) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -handle_options_request(Request, Config) -> - Response = begin - _pipe = gleam@http@response:new(200), - gleam@http@response:set_body(_pipe, gleam@bit_builder:new()) - end, - Origin = get_origin(Request), - Ac_request_method = begin - _pipe@1 = gleam@http@request:get_header( - Request, - <<"Access-Control-Request-Method"/utf8>> - ), - _pipe@2 = gleam@result:then(_pipe@1, fun gleam@http:parse_method/1), - gleam@result:unwrap(_pipe@2, {other, <<""/utf8>>}) - end, - Ac_request_headers = begin - _pipe@3 = gleam@http@request:get_header( - Request, - <<"Access-Control-Request-Headers"/utf8>> - ), - _pipe@4 = gleam@result:map( - _pipe@3, - fun(_capture) -> gleam@string:split(_capture, <<", "/utf8>>) end - ), - gleam@result:unwrap(_pipe@4, []) - end, - Is_request_allowed = (is_origin_allowed(Origin, erlang:element(2, Config)) - andalso is_method_allowed(Ac_request_method, erlang:element(3, Config))) - andalso are_headers_allowed(Ac_request_headers, erlang:element(4, Config)), - case Is_request_allowed of - true -> - _pipe@5 = Response, - _pipe@6 = prepend_allow_origin_header( - _pipe@5, - Origin, - erlang:element(2, Config) - ), - prepend_allow_headers_header(_pipe@6, Ac_request_headers); - - false -> - Response - end. - --spec middleware_from_config(config()) -> fun((fun((gleam@http@request:request(FTH)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))) -> fun((gleam@http@request:request(FTH)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))). -middleware_from_config(Config) -> - fun(Service) -> fun(Request) -> case erlang:element(2, Request) of - options -> - handle_options_request(Request, Config); - - _ -> - handle_other_request( - Service, - Request, - erlang:element(2, Config) - ) - end end end. - --spec middleware(list(binary()), list(gleam@http:method()), list(binary())) -> fun((fun((gleam@http@request:request(FTC)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))) -> fun((gleam@http@request:request(FTC)) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))). -middleware(Allowed_origins, Allowed_methods, Allowed_headers) -> - case parse_config(Allowed_origins, Allowed_methods, Allowed_headers) of - {ok, Config} -> - middleware_from_config(Config); - - {error, _} -> - fun gleam@function:identity/1 - end. diff --git a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src b/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src deleted file mode 100644 index 3a52ceb19fa..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_cors/src/gleam_cors.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_cors, [ - {vsn, "0.2.0"}, - {applications, [gleam_http, - gleam_stdlib, - gleeunit]}, - {description, "A CORS middleware for Gleam"}, - {modules, [gleam@http@cors]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE b/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/README.md b/test-community-packages-javascript/build/packages/gleam_crypto/README.md deleted file mode 100644 index c499e15941c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# crypto - -<a href="https://github.com/gleam-experiments/crypto/releases"><img src="https://img.shields.io/github/release/gleam-experiments/crypto" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-experiments/crypto/workflows/test/badge.svg?branch=main) - -Gleam bindings to the BEAM cryptography functions. - -## Installation - -``` -gleam add gleam_crypto -``` diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml b/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml deleted file mode 100644 index b5fec372ee5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleam_crypto" -version = "0.3.1" -licences = ["Apache-2.0"] -description = "Gleam bindings to the BEAM cryptography functions" - -repository = { type = "github", user = "gleam-experiments", repo = "crypto" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.19" -gleam_bitwise = "~> 1.1" - -[dev-dependencies] -gleeunit = "~> 0.5" diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam deleted file mode 100644 index 94223390f0c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam/crypto.gleam +++ /dev/null @@ -1,135 +0,0 @@ -//// Set of cryptographic functions. - -import gleam/bit_string -import gleam/bitwise -import gleam/string -import gleam/base -import gleam/result - -/// Generates N bytes randomly uniform 0..255, and returns the result in a binary. -/// -/// Uses a cryptographically secure prng seeded and periodically mixed with -/// operating system provided entropy. -/// By default this is the RAND_bytes method from OpenSSL. -/// -/// https://erlang.org/doc/man/crypto.html#strong_rand_bytes-1 -pub external fn strong_random_bytes(Int) -> BitString = - "crypto" "strong_rand_bytes" - -pub type HashAlgorithm { - Sha224 - Sha256 - Sha384 - Sha512 -} - -/// Computes a digest of the input bit string. -pub external fn hash(HashAlgorithm, BitString) -> BitString = - "crypto" "hash" - -type Hmac { - Hmac -} - -external fn erl_hmac(Hmac, HashAlgorithm, BitString, BitString) -> BitString = - "crypto" "mac" - -/// Calculates the HMAC (hash-based message authentication code) for a bit -/// string. -/// -/// Based on the Erlang [`crypto:mac`](https://www.erlang.org/doc/man/crypto.html#mac-4) -/// function. -/// -pub fn hmac(data: BitString, algorithm: HashAlgorithm, key: BitString) { - erl_hmac(Hmac, algorithm, key, data) -} - -fn do_secure_compare( - left: BitString, - right: BitString, - accumulator: Int, -) -> Bool { - case left, right { - <<x, left:bit_string>>, <<y, right:bit_string>> -> { - let accumulator = bitwise.or(accumulator, bitwise.exclusive_or(x, y)) - do_secure_compare(left, right, accumulator) - } - <<>>, <<>> -> accumulator == 0 - } -} - -/// Compares the two binaries in constant-time to avoid timing attacks. -/// -/// For more details see: http://codahale.com/a-lesson-in-timing-attacks/ -/// -pub fn secure_compare(left: BitString, right: BitString) -> Bool { - case bit_string.byte_size(left) == bit_string.byte_size(right) { - True -> do_secure_compare(left, right, 0) - False -> False - } -} - -// Based off of https://github.com/elixir-plug/plug_crypto/blob/v1.2.1/lib/plug/crypto/message_verifier.ex#L1 -// -/// Sign a message which can later be verified using the `verify_signed_message` -/// function to detect if the message has been tampered with. -/// -/// A web application could use this verifier to sign HTTP cookies. The data can -/// be read by the user, but cannot be tampered with. -/// -pub fn sign_message( - message: BitString, - secret: BitString, - digest_type: HashAlgorithm, -) -> String { - let input = signing_input(digest_type, message) - let signature = hmac(<<input:utf8>>, digest_type, secret) - - string.concat([input, ".", base.url_encode64(signature, False)]) -} - -fn signing_input(digest_type: HashAlgorithm, message: BitString) -> String { - let protected = case digest_type { - Sha224 -> "HS224" - Sha256 -> "HS256" - Sha384 -> "HS384" - Sha512 -> "HS512" - } - string.concat([ - base.url_encode64(<<protected:utf8>>, False), - ".", - base.url_encode64(message, False), - ]) -} - -// Based off of https://github.com/elixir-plug/plug_crypto/blob/v1.2.1/lib/plug/crypto/message_verifier.ex#L1 -// -/// Verify a message created by the `sign_message` function. -/// -pub fn verify_signed_message( - message: String, - secret: BitString, -) -> Result(BitString, Nil) { - use #(protected, payload, signature) <- result.then(case - string.split(message, on: ".") - { - [a, b, c] -> Ok(#(a, b, c)) - _ -> Error(Nil) - }) - let text = string.concat([protected, ".", payload]) - use payload <- result.then(base.url_decode64(payload)) - use signature <- result.then(base.url_decode64(signature)) - use protected <- result.then(base.url_decode64(protected)) - use digest_type <- result.then(case protected { - <<"HS224":utf8>> -> Ok(Sha224) - <<"HS256":utf8>> -> Ok(Sha256) - <<"HS384":utf8>> -> Ok(Sha384) - <<"HS512":utf8>> -> Ok(Sha512) - _ -> Error(Nil) - }) - let challenge = hmac(<<text:utf8>>, digest_type, secret) - case secure_compare(challenge, signature) { - True -> Ok(payload) - False -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl deleted file mode 100644 index b3b97bcf73d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam@crypto.erl +++ /dev/null @@ -1,135 +0,0 @@ --module(gleam@crypto). --compile([no_auto_import, nowarn_unused_vars]). - --export([strong_random_bytes/1, hash/2, hmac/3, sign_message/3, secure_compare/2, verify_signed_message/2]). --export_type([hash_algorithm/0, hmac/0]). - --type hash_algorithm() :: sha224 | sha256 | sha384 | sha512. - --type hmac() :: hmac. - --spec signing_input(hash_algorithm(), bitstring()) -> binary(). -signing_input(Digest_type, Message) -> - Protected = case Digest_type of - sha224 -> - <<"HS224"/utf8>>; - - sha256 -> - <<"HS256"/utf8>>; - - sha384 -> - <<"HS384"/utf8>>; - - sha512 -> - <<"HS512"/utf8>> - end, - gleam@string:concat( - [gleam@base:url_encode64(<<Protected/binary>>, false), - <<"."/utf8>>, - gleam@base:url_encode64(Message, false)] - ). - --spec strong_random_bytes(integer()) -> bitstring(). -strong_random_bytes(Field@0) -> - crypto:strong_rand_bytes(Field@0). - --spec hash(hash_algorithm(), bitstring()) -> bitstring(). -hash(Field@0, Field@1) -> - crypto:hash(Field@0, Field@1). - --spec hmac(bitstring(), hash_algorithm(), bitstring()) -> bitstring(). -hmac(Data, Algorithm, Key) -> - crypto:mac(hmac, Algorithm, Key, Data). - --spec sign_message(bitstring(), bitstring(), hash_algorithm()) -> binary(). -sign_message(Message, Secret, Digest_type) -> - Input = signing_input(Digest_type, Message), - Signature = hmac(<<Input/binary>>, Digest_type, Secret), - gleam@string:concat( - [Input, <<"."/utf8>>, gleam@base:url_encode64(Signature, false)] - ). - --spec do_secure_compare(bitstring(), bitstring(), integer()) -> boolean(). -do_secure_compare(Left, Right, Accumulator) -> - case {Left, Right} of - {<<X, Left@1/bitstring>>, <<Y, Right@1/bitstring>>} -> - Accumulator@1 = gleam@bitwise:'or'( - Accumulator, - gleam@bitwise:exclusive_or(X, Y) - ), - do_secure_compare(Left@1, Right@1, Accumulator@1); - - {<<>>, <<>>} -> - Accumulator =:= 0 - end. - --spec secure_compare(bitstring(), bitstring()) -> boolean(). -secure_compare(Left, Right) -> - case gleam@bit_string:byte_size(Left) =:= gleam@bit_string:byte_size(Right) of - true -> - do_secure_compare(Left, Right, 0); - - false -> - false - end. - --spec verify_signed_message(binary(), bitstring()) -> {ok, bitstring()} | - {error, nil}. -verify_signed_message(Message, Secret) -> - gleam@result:then(case gleam@string:split(Message, <<"."/utf8>>) of - [A, B, C] -> - {ok, {A, B, C}}; - - _ -> - {error, nil} - end, fun(_use0) -> - {Protected, Payload, Signature} = _use0, - Text = gleam@string:concat([Protected, <<"."/utf8>>, Payload]), - gleam@result:then( - gleam@base:url_decode64(Payload), - fun(Payload@1) -> - gleam@result:then( - gleam@base:url_decode64(Signature), - fun(Signature@1) -> - gleam@result:then( - gleam@base:url_decode64(Protected), - fun(Protected@1) -> - gleam@result:then(case Protected@1 of - <<"HS224"/utf8>> -> - {ok, sha224}; - - <<"HS256"/utf8>> -> - {ok, sha256}; - - <<"HS384"/utf8>> -> - {ok, sha384}; - - <<"HS512"/utf8>> -> - {ok, sha512}; - - _ -> - {error, nil} - end, fun(Digest_type) -> - Challenge = hmac( - <<Text/binary>>, - Digest_type, - Secret - ), - case secure_compare( - Challenge, - Signature@1 - ) of - true -> - {ok, Payload@1}; - - false -> - {error, nil} - end - end) - end - ) - end - ) - end - ) - end). diff --git a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src b/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src deleted file mode 100644 index f62b69f0512..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_crypto/src/gleam_crypto.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_crypto, [ - {vsn, "0.3.1"}, - {applications, [gleam_bitwise, - gleam_stdlib, - gleeunit]}, - {description, "Gleam bindings to the BEAM cryptography functions"}, - {modules, [gleam@crypto]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE b/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/README.md b/test-community-packages-javascript/build/packages/gleam_erlang/README.md deleted file mode 100644 index e91ad24d748..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Gleam Erlang 🐙 - -A library for making use of Erlang specific code! - -## Features - -- Typed Erlang processes and message sending. -- Erlang binary format (de)serialisation. -- Functions for working with Erlang's charlists. -- Reading, writing, and deletion of files. - -## Usage - -Add this library to your Gleam project - -```shell -gleam add gleam_erlang -``` - -And then use it in your code - -```gleam -import gleam/io -import gleam/erlang/file - -pub fn main() { - assert Ok(contents) = file.read("pokedex.txt") - io.println(contents) -} -``` - -Documentation can be found at <https://hexdocs.pm/gleam_erlang/>. - -This library requires OTP 23.0 or higher. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml b/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml deleted file mode 100644 index 8f978f6781a..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleam_erlang" - -version = "0.19.0" -licences = ["Apache-2.0"] -description = "A Gleam library for working with Erlang" - -repository = { type = "github", user = "gleam-lang", repo = "erlang" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl deleted file mode 100644 index b38d11e0f65..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl +++ /dev/null @@ -1,15 +0,0 @@ --record(file_info, { - size :: integer(), - file_type :: gleam@erlang@file:file_type(), - access :: gleam@erlang@file:access(), - atime :: integer(), - mtime :: integer(), - ctime :: integer(), - mode :: integer(), - links :: integer(), - major_device :: integer(), - minor_device :: integer(), - inode :: integer(), - user_id :: integer(), - group_id :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl deleted file mode 100644 index 4cd04529eb4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl +++ /dev/null @@ -1 +0,0 @@ --record(abnormal, {reason :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl deleted file mode 100644 index 7fe79877634..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl +++ /dev/null @@ -1 +0,0 @@ --record(callee_down, {reason :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl deleted file mode 100644 index b82b49fc597..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl +++ /dev/null @@ -1 +0,0 @@ --record(cancelled, {time_remaining :: integer()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl deleted file mode 100644 index c476308c591..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(exit_message, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@erlang@process:exit_reason() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl deleted file mode 100644 index 8c75d5913d8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(process_down, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@dynamic:dynamic() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl deleted file mode 100644 index ce552e209e6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl +++ /dev/null @@ -1 +0,0 @@ --record(process_monitor, {tag :: gleam@erlang:reference_()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl deleted file mode 100644 index abc46b2ecd4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(subject, { - owner :: gleam@erlang@process:pid_(), - tag :: gleam@erlang:reference_() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl deleted file mode 100644 index aeba26d8240..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(application_failed_to_start, { - name :: gleam@erlang@atom:atom_(), - reason :: gleam@dynamic:dynamic() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl deleted file mode 100644 index fde3c61706e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unknown_application, {name :: gleam@erlang@atom:atom_()}). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam deleted file mode 100644 index 7720a71c616..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang.gleam +++ /dev/null @@ -1,143 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/list -import gleam/erlang/atom.{Atom} -import gleam/erlang/charlist.{Charlist} - -external fn erl_format(String, List(a)) -> Charlist = - "io_lib" "format" - -/// Return a string representation of any term -pub fn format(term: any) -> String { - charlist.to_string(erl_format("~p", [term])) -} - -pub external fn term_to_binary(a) -> BitString = - "erlang" "term_to_binary" - -type Safe { - Safe -} - -external fn erl_binary_to_term(BitString, List(Safe)) -> Dynamic = - "erlang" "binary_to_term" - -pub fn binary_to_term(binary: BitString) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, [Safe]) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -pub fn unsafe_binary_to_term(binary: BitString) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, []) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -/// Error value returned by `get_line` function -/// -pub type GetLineError { - Eof - NoData -} - -/// Reads a line from standard input with the given prompt. -/// -/// # Example -/// -/// > get_line("Language: ") -/// // -> Language: <- gleam -/// Ok("gleam\n") -/// -pub external fn get_line(prompt: String) -> Result(String, GetLineError) = - "gleam_erlang_ffi" "get_line" - -pub type TimeUnit { - Second - Millisecond - Microsecond - Nanosecond -} - -/// Returns the current OS system time. -/// -/// <https://erlang.org/doc/apps/erts/time_correction.html#OS_System_Time> -pub external fn system_time(TimeUnit) -> Int = - "os" "system_time" - -/// Returns the current OS system time as a tuple of Ints -/// -/// http://erlang.org/doc/man/os.html#timestamp-0 -pub external fn erlang_timestamp() -> #(Int, Int, Int) = - "os" "timestamp" - -/// Gleam doesn't offer any way to raise exceptions, but they may still occur -/// due to bugs when working with unsafe code, such as when calling Erlang -/// function. -/// -/// This function will catch any error thrown and convert it into a result -/// rather than crashing the process. -/// -pub external fn rescue(fn() -> a) -> Result(a, Crash) = - "gleam_erlang_ffi" "rescue" - -pub type Crash { - Exited(Dynamic) - Thrown(Dynamic) - Errored(Dynamic) -} - -external fn get_start_arguments() -> List(Charlist) = - "init" "get_plain_arguments" - -/// Get the arguments given to the program when it was started. -/// -/// This is sometimes called `argv` in other languages. -pub fn start_arguments() -> List(String) { - get_start_arguments() - |> list.map(charlist.to_string) -} - -/// Starts an OTP application's process tree in the background, as well as -/// the trees of any applications that the given application depends upon. An -/// OTP application typically maps onto a Gleam or Hex package. -/// -/// Returns a list of the applications that were started. Calling this function -/// for application that have already been started is a no-op so you do not need -/// to check the application state beforehand. -/// -/// In Gleam we prefer to not use these implicit background process trees, but -/// you will likely still need to start the trees of OTP applications written in -/// other BEAM languages such as Erlang or Elixir, including those included by -/// default with Erlang/OTP. -/// -/// For more information see the OTP documentation. -/// - <https://www.erlang.org/doc/man/application.html#ensure_all_started-1> -/// - <https://www.erlang.org/doc/man/application.html#start-1> -/// -pub external fn ensure_all_started( - application: Atom, -) -> Result(List(Atom), EnsureAllStartedError) = - "gleam_erlang_ffi" "ensure_all_started" - -pub type EnsureAllStartedError { - UnknownApplication(name: Atom) - ApplicationFailedToStart(name: Atom, reason: Dynamic) -} - -/// A unique reference value. -/// -/// It holds no particular meaning or value, but unique values are often useful -/// in programs are used heavily within both Gleam and Erlang's OTP frameworks. -/// -/// More can be read about refernces in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/efficiency_guide/advanced.html#unique_references -/// -pub external type Reference - -/// Create a new unique reference. -/// -pub external fn make_reference() -> Reference = - "erlang" "make_ref" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam deleted file mode 100644 index 1e0aac62a9c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam +++ /dev/null @@ -1,79 +0,0 @@ -import gleam/dynamic.{DecodeErrors, Dynamic} - -/// Atom is a special string-like data-type that is most commonly used for -/// interfacing with code written in other BEAM languages such as Erlang and -/// Elixir. It is preferable to define your own custom types to use instead of -/// atoms where possible. -/// -/// Atoms are not used much in typical Gleam code! -/// -/// ## Creating atoms -/// -/// We can create atoms with the the [`create_from_string`](#create_from_string) -/// function, though we must be careful when doing so as atoms are never -/// garbage collected. If we create too many atoms (for example, if we convert -/// user input into atoms) we may hit the max limit of atoms and cause the -/// virtual machine to crash. -/// -pub external type Atom - -/// An error returned when no atom is found in the virtual machine's atom table -/// for a given string when calling the [`from_string`](#from_string) function. -pub type FromStringError { - AtomNotLoaded -} - -/// Finds an existing Atom for the given String. -/// -/// If no atom is found in the virtual machine's atom table for the String then -/// an error is returned. -/// -/// ## Examples -/// -/// > from_string("ok") -/// Ok(create_from_string("ok")) -/// -/// > from_string("some_new_atom") -/// Error(AtomNotLoaded) -/// -pub external fn from_string(String) -> Result(Atom, FromStringError) = - "gleam_erlang_ffi" "atom_from_string" - -/// Creates an atom from a string, inserting a new value into the virtual -/// machine's atom table if an atom does not already exist for the given -/// string. -/// -/// We must be careful when using this function as there is a limit to the -/// number of atom that can fit in the virtual machine's atom table. Never -/// convert user input into atoms as filling the atom table will cause the -/// virtual machine to crash! -/// -pub external fn create_from_string(String) -> Atom = - "erlang" "binary_to_atom" - -/// Retuns a `String` corresponding to the text representation of the given -/// `Atom`. -/// -/// ## Examples -/// -/// > let ok_atom = create_from_string("ok") -/// > to_string(ok_atom) -/// "ok" -/// -pub external fn to_string(Atom) -> String = - "erlang" "atom_to_binary" - -/// Checks to see whether a `Dynamic` value is an atom, and return the atom if -/// it is. -/// -/// ## Examples -/// -/// > import gleam/dynamic -/// > from_dynamic(dynamic.from(create_from_string("hello"))) -/// Ok(create_from_string("hello")) -/// -/// > from_dynamic(dynamic.from(123)) -/// Error([DecodeError(expected: "Atom", found: "Int", path: [])]) -/// -pub external fn from_dynamic(from: Dynamic) -> Result(Atom, DecodeErrors) = - "gleam_erlang_ffi" "atom_from_dynamic" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam deleted file mode 100644 index a88c57fa7a8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam +++ /dev/null @@ -1,25 +0,0 @@ -//// A charlist is a list of integers where all the integers are valid code -//// points. -//// -//// In practice, you will not come across them often, except perhaps when -//// interfacing with Erlang, in particular when using older libraries that do -//// not accept binaries as arguments. - -/// A list of characters represented as ints. Commonly used by older Erlang -/// modules. -pub external type Charlist - -/// Transform a charlist to a string -pub external fn to_string(Charlist) -> String = - "unicode" "characters_to_binary" - -// Calls `unicode:characters_to_binary(Data, unicode, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_binary-1> - -/// Transform a string to a charlist -pub external fn from_string(String) -> Charlist = - "unicode" "characters_to_list" -// Calls `unicode:characters_to_list(Data, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_list-1> diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam deleted file mode 100644 index 2e780518726..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/file.gleam +++ /dev/null @@ -1,713 +0,0 @@ -//// Working with files on the filesystem. -//// -//// The functions included in this module are for high-level concepts such as -//// reading and writing. - -import gleam/bit_string -import gleam/result - -/// Reason represents all of the reasons that Erlang surfaces of why a file -/// system operation could fail. Most of these reasons are POSIX errors, which -/// come from the operating system and start with `E`. Others have been added to -/// represent other issues that may arise. -pub type Reason { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 -} - -/// The type of file found by `file_info` or `link_info`. -/// -pub type FileType { - Device - Directory - Other - Regular - Symlink -} - -/// The read/write permissions a user can have for a file. -/// -pub type Access { - NoAccess - Read - ReadWrite - Write -} - -/// Meta information for a file. -/// -/// Timestamps are in seconds before or after the Unix time epoch, -/// `1970-01-01 00:00:00 UTC`. -/// -pub type FileInfo { - FileInfo( - /// File size in bytes. - /// - size: Int, - /// `Regular`, `Directory`, `Symlink`, `Device`, or `Other`. - /// - file_type: FileType, - /// `ReadWrite`, `Read`, `Write`, or `NoAccess`. - /// - access: Access, - /// Timestamp of most recent access. - /// - atime: Int, - /// Timestamp of most recent modification. - /// - mtime: Int, - /// Timestamp of most recent change (or file creation, depending on - /// operating system). - /// - ctime: Int, - /// File permissions encoded as a sum of bit values, including but not - /// limited to: - /// - /// Owner read, write, execute. - /// - /// `0o400`, `0o200`, `0o100` - /// - /// Group read, write, execute. - /// - /// `0o40`, `0o20`, `0o10` - /// - /// Other read, write, execute. - /// - /// `0o4`, `0o2`, `0o1` - /// - /// Set user ID, group ID on execution. - /// - /// `0x800`, `0x400` - /// - mode: Int, - /// Total links to a file (always `1` for file systems without links). - /// - links: Int, - /// The file system where a file is located (`0` for drive `A:` on Windows, - /// `1` for `B:`, etc.). - /// - major_device: Int, - /// Character device (or `0` on non-Unix systems). - /// - minor_device: Int, - /// The `inode` number for a file (always `0` on non-Unix file systems). - /// - inode: Int, - /// The owner of a file (always `0` on non-Unix file systems). - /// - user_id: Int, - /// The group id of a file (always `0` on non-Unix file systems). - /// - group_id: Int, - ) -} - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To get `FileInfo` about a symlink itself, use `link_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > file_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 140, -/// file_type: Directory, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/does_not_exist") -/// Error(Enoent) -/// -/// > file_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub external fn file_info(String) -> Result(FileInfo, Reason) = - "gleam_erlang_ffi" "file_info" - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To get `FileInfo` about a symlink's target, use `file_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > link_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 41, -/// file_type: Symlink, -/// access: ReadWrite, -/// atime: 1680581150, -/// mtime: 1680581150, -/// ctime: 1680581150, -/// mode: 41471, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 471587, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/does_not_exist") -/// Error(Enoent) -/// -/// > link_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub external fn link_info(String) -> Result(FileInfo, Reason) = - "gleam_erlang_ffi" "link_info" - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Directory` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_directory("/tmp") -/// Ok(True) -/// -/// > is_directory("resume.pdf") -/// Ok(False) -/// -/// > is_directory("/does_not_exist") -/// Error(Enoent) -/// ``` -/// -pub fn is_directory(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: file_info(path)) - file_type == Directory -} - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Regular` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_regular("resume.pdf") -/// Ok(True) -/// -/// > is_regular("/tmp") -/// Ok(False) -/// -/// > is_regular("/does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -pub fn is_regular(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: file_info(path)) - file_type == Regular -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To find whether a symlink itself exists, use `link_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_exists("resume.pdf") -/// Ok(True) -/// -/// > file_exists("/tmp") -/// Ok(True) -/// -/// > file_exists("/does_not_exist") -/// Ok(False) -/// -/// > file_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub fn file_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> file_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To find whether a symlink's target exists, use `file_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_exists("resume.pdf") -/// Ok(True) -/// -/// > link_exists("/tmp") -/// Ok(True) -/// -/// > link_exists("/does_not_exist") -/// Ok(False) -/// -/// > link_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -pub fn link_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> link_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Tries to create a directory. Missing parent directories are not created. -/// -/// Returns a Result of nil if the directory is created or Reason if the -/// operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > make_directory("/tmp/foo") -/// Ok(Nil) -/// -/// > make_directory("relative_directory") -/// Ok(Nil) -/// -/// > make_directory("/tmp/missing_intermediate_directory/foo") -/// Error(Enoent) -/// ``` -/// -pub external fn make_directory(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "make_directory" - -/// Lists all files in a directory, except files with -/// [raw filenames](https://www.erlang.org/doc/apps/stdlib/unicode_usage.html#notes-about-raw-filenames). -/// -/// Returns a Result containing the list of filenames in the directory, or Reason -/// if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > list_directory("/tmp") -/// Ok(["FB01293B-8597-4359-80D5-130140A0C0DE","AlTest2.out"]) -/// -/// > list_directory("resume.docx") -/// Error(Enotdir) -/// ``` -/// -pub external fn list_directory(String) -> Result(List(String), Reason) = - "gleam_erlang_ffi" "list_directory" - -/// Deletes a directory. -/// -/// The directory must be empty before it can be deleted. Returns a nil Success -/// or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > delete_directory("foo") -/// Ok(Nil) -/// -/// > delete_directory("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -pub external fn delete_directory(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "delete_directory" - -/// Deletes a file or directory recursively. -/// -/// Returns a nil Success or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > recursive_delete("foo") -/// Ok(Nil) -/// -/// > recursive_delete("/bar") -/// Ok(Nil) -/// -/// > recursive_delete("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -pub external fn recursive_delete(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "recursive_delete" - -/// Read the contents of the given file as a String -/// -/// Assumes the file is UTF-8 encoded. Returns a Result containing the file's -/// contents as a String if the operation was successful, or Reason if the file -/// operation failed. If the file is not UTF-8 encoded, the `NotUTF8` variant -/// will be returned. -/// -/// ## Examples -/// -/// ```gleam -/// > read("example.txt") -/// Ok("Hello, World!") -/// -/// > read(from: "example.txt") -/// Ok("Hello, World!") -/// -/// > read("does_not_exist.txt") -/// Error(Enoent) -/// -/// > read("cat.gif") -/// Error(NotUTF8) -/// ``` -/// -pub fn read(from path: String) -> Result(String, Reason) { - path - |> do_read_bits() - |> result.then(fn(content) { - case bit_string.to_string(content) { - Ok(string) -> Ok(string) - Error(Nil) -> Error(NotUtf8) - } - }) -} - -/// Read the contents of the given file as a BitString -/// -/// Returns a Result containing the file's contents as a BitString if the -/// operation was successful, or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > read_bits("example.txt") -/// Ok(<<"Hello, World!">>) -/// -/// > read_bits(from: "cat.gif") -/// Ok(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// -/// > read_bits("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -pub fn read_bits(from path: String) -> Result(BitString, Reason) { - do_read_bits(path) -} - -external fn do_read_bits(path) -> Result(BitString, Reason) = - "gleam_erlang_ffi" "read_file" - -/// Write the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > write(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > write("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -pub fn write(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_string.from_string - |> do_write_bits(path) -} - -/// Write the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > write_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -pub fn write_bits( - contents contents: BitString, - to path: String, -) -> Result(Nil, Reason) { - do_write_bits(contents, path) -} - -external fn do_write_bits(BitString, String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "write_file" - -/// Append the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > append(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > append("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -pub fn append(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_string.from_string - |> do_append_bits(path) -} - -/// Append the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > append_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -pub fn append_bits( - contents contents: BitString, - to path: String, -) -> Result(Nil, Reason) { - do_append_bits(contents, path) -} - -external fn do_append_bits( - contents: BitString, - path: String, -) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "append_file" - -/// Delete the given file. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > delete("file.txt") -/// Ok(Nil) -/// -/// > delete("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -pub external fn delete(String) -> Result(Nil, Reason) = - "gleam_erlang_ffi" "delete_file" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam deleted file mode 100644 index 68326962a71..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/os.gleam +++ /dev/null @@ -1,95 +0,0 @@ -//// Access to the shell's environment variables - -import gleam/map.{Map} - -/// Returns the list of all available environment variables as a list of key, -/// tuples. -/// -/// ## Examples -/// -/// > get_all_env() -/// map.from_list([ -/// #("SHELL", "/bin/bash"), -/// #("PWD", "/home/j3rn"), -/// ... -/// ]) -/// -pub external fn get_all_env() -> Map(String, String) = - "gleam_erlang_ffi" "get_all_env" - -/// Returns the value associated with the given environment variable name. -/// -/// ## Examples -/// -/// > get_env("SHELL") -/// "/bin/bash" -/// -/// > get_env(name: "PWD") -/// "/home/j3rn" -/// -pub external fn get_env(name: String) -> Result(String, Nil) = - "gleam_erlang_ffi" "get_env" - -/// Associates the given value with the given environment variable name. -/// -/// ## Examples -/// -/// > set_env("MYVAR", "MYVALUE") -/// Nil -/// > get_env("MYVAR") -/// "MYVALUE" -/// -/// > set_env(value: "MYVALUE", name: "MYVAR") -/// Nil -/// -pub external fn set_env(name: String, value: String) -> Nil = - "gleam_erlang_ffi" "set_env" - -/// Removes the environment variable with the given name. -/// -/// Returns Nil regardless of whether the variable ever existed. -/// -/// ## Examples -/// -/// > get_env("MYVAR") -/// Ok("MYVALUE") -/// > unset_env("MYVAR") -/// Nil -/// > get_env("MYVAR") -/// Error(Nil) -/// -/// > unset_env(name: "MYVAR") -/// Nil -/// -pub external fn unset_env(name: String) -> Nil = - "gleam_erlang_ffi" "unset_env" - -/// Represents operating system kernels -pub type OsFamily { - // The family which includes modern versions of the Windows operating system. - WindowsNt - // The family of operating systems based on the open source Linux kernel. - Linux - // The family of Apple operating systems such as macOS and iOS. - Darwin - // The family of operating systems based on the FreeBSD kernel. - FreeBsd - // An operating system kernel other than Linux, Darwin, FreeBSD, or NT. - Other(String) -} - -/// Returns the kernel of the host operating system. -/// -/// Unknown kernels are reported as `Other(String)`; e.g. `Other("sunos")`. -/// -/// ## Examples -/// -/// > family() -/// Linux -/// > family() -/// Darwin -/// > family() -/// Other("sunos") -/// -pub external fn family() -> OsFamily = - "gleam_erlang_ffi" "os_family" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam deleted file mode 100644 index 6e7e03f66c7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam/erlang/process.gleam +++ /dev/null @@ -1,716 +0,0 @@ -import gleam/string -import gleam/dynamic.{Dynamic} -import gleam/erlang.{Reference} -import gleam/erlang/atom.{Atom} - -/// A `Pid` (or Process identifier) is a reference to an Erlang process. Each -/// process has a `Pid` and it is one of the lowest level building blocks of -/// inter-process communication in the Erlang and Gleam OTP frameworks. -/// -pub external type Pid - -/// Get the `Pid` for the current process. -pub external fn self() -> Pid = - "erlang" "self" - -/// Create a new Erlang process that runs concurrently to the creator. In other -/// languages this might be called a fibre, a green thread, or a coroutine. -/// -/// If `linked` is `True` then the created process is linked to the creator -/// process. When a process terminates an exit signal is sent to all other -/// processes that are linked to it, causing the process to either terminate or -/// have to handle the signal. -/// -/// More can be read about processes and links in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/reference_manual/processes.html -/// -pub fn start(running implementation: fn() -> anything, linked link: Bool) -> Pid { - case link { - True -> spawn_link(implementation) - False -> spawn(implementation) - } -} - -external fn spawn(fn() -> anything) -> Pid = - "erlang" "spawn" - -external fn spawn_link(fn() -> anything) -> Pid = - "erlang" "spawn_link" - -/// A `Subject` is a value that processes can use to send and receive messages -/// to and from each other in a well typed way. -/// -/// Each subject is "owned" by the process that created it. Any process can use -/// the `send` function to sent a message of the correct type to the process -/// that owns the subject, and the owner can use the `receive` function or the -/// `Selector` type to receive these messages. -/// -/// The `Subject` type is similar to the "channel" types found in other -/// languages and the "topic" concept found in some pub-sub systems. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// -/// // Send a message with the subject -/// send(subject, "Hello, Joe!") -/// -/// // Receive the message -/// receive(subject, within: 10) -/// ``` -/// -pub opaque type Subject(message) { - Subject(owner: Pid, tag: Reference) -} - -/// Create a new `Subject` owned by the current process. -/// -pub fn new_subject() -> Subject(message) { - Subject(owner: self(), tag: erlang.make_reference()) -} - -/// Get the owner process for a `Subject`. This is the process that created the -/// `Subject` and will receive messages sent with it. -/// -pub fn subject_owner(subject: Subject(message)) -> Pid { - subject.owner -} - -external type DoNotLeak - -external fn raw_send(Pid, message) -> DoNotLeak = - "erlang" "send" - -/// Send a message to a process using a `Subject`. The message must be of the -/// type that the `Subject` accepts. -/// -/// This function does not wait for the `Subject` owner process to call the -/// `receive` function, instead it returns once the message has been placed in -/// the process' mailbox. -/// -/// # Ordering -/// -/// If process P1 sends two messages to process P2 it is guarenteed that process -/// P1 will receive the messages in the order they were sent. -/// -/// If you wish to receive the messages in a different order you can send them -/// on two different subjects and the receiver function can call the `receive` -/// function for each subject in the desired order, or you can write some Erlang -/// code to perform a selective receive. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// send(subject, "Hello, Joe!") -/// ``` -/// -pub fn send(subject: Subject(message), message: message) -> Nil { - raw_send(subject.owner, #(subject.tag, message)) - Nil -} - -/// Receive a message that has been sent to current process using the `Subject`. -/// -/// If there is not an existing message for the `Subject` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject` can receive a message using -/// it. If a process that does not own the `Subject` attempts to receive with it -/// then it will not receive a message. -/// -/// To wait for messages from multiple `Subject`s at the same time see the -/// `Selector` type. -/// -pub fn receive( - from subject: Subject(message), - within milliseconds: Int, -) -> Result(message, Nil) { - new_selector() - |> selecting(subject, fn(x) { x }) - |> select(within: milliseconds) -} - -/// A type that enables a process to wait for messages from multiple `Subject`s -/// at the same time, returning whichever message arrives first. -/// -/// Used with the `new_selector`, `selecting`, and `select` functions. -/// -/// # Examples -/// -/// ```gleam -/// > let int_subject = new_subject() -/// > let float_subject = new_subject() -/// > send(int_subject, 1) -/// > -/// > let selector = -/// > new_selector() -/// > |> selecting(int_subject, int.to_string) -/// > |> selecting(float_subject, float.to_string) -/// > -/// > select(selector) -/// Ok("1") -/// ``` -/// -pub external type Selector(payload) - -/// Create a new `Selector` which can be used to receive messages on multiple -/// `Subject`s at once. -/// -pub external fn new_selector() -> Selector(payload) = - "gleam_erlang_ffi" "new_selector" - -/// Receive a message that has been sent to current process using any of the -/// `Subject`s that have been added to the `Selector` with the `selecting` -/// function. -/// -/// If there is not an existing message for the `Selector` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject`s can receive a message using -/// them. If a process that does not own the a `Subject` attempts to receive -/// with it then it will not receive a message. -/// -/// To wait forever for the next message rather than for a limited amount of -/// time see the `select_forever` function. -/// -pub external fn select( - from: Selector(payload), - within: Int, -) -> Result(payload, Nil) = - "gleam_erlang_ffi" "select" - -/// Similar to the `select` function but will wait forever for a message to -/// arrive rather than timing out after a specified amount of time. -/// -pub external fn select_forever(from: Selector(payload)) -> payload = - "gleam_erlang_ffi" "select" - -/// Add a transformation function to a selector. When a message is received -/// using this selector the tranformation function is applied to the message. -/// -/// This function can be used to change the type of messages received and may -/// be useful when combined with the `merge_selector` function. -/// -pub external fn map_selector(Selector(a), fn(a) -> b) -> Selector(b) = - "gleam_erlang_ffi" "map_selector" - -/// Merge one selector into another, producing a selector that contains the -/// message handlers of both. -/// -/// If a subject is handled by both selectors the handler function of the -/// second selector is used. -/// -pub external fn merge_selector(Selector(a), Selector(a)) -> Selector(a) = - "gleam_erlang_ffi" "merge_selector" - -pub type ExitMessage { - ExitMessage(pid: Pid, reason: ExitReason) -} - -pub type ExitReason { - Normal - Killed - Abnormal(reason: String) -} - -/// Add a handler for trapped exit messages. In order for these messages to be -/// sent to the process when a linked process exits the process must call the -/// `trap_exit` beforehand. -/// -pub fn selecting_trapped_exits( - selector: Selector(a), - handler: fn(ExitMessage) -> a, -) -> Selector(a) { - let tag = atom.create_from_string("EXIT") - let handler = fn(message: #(Atom, Pid, Dynamic)) -> a { - let reason = message.2 - let normal = dynamic.from(Normal) - let killed = dynamic.from(Killed) - let reason = case dynamic.string(reason) { - _ if reason == normal -> Normal - _ if reason == killed -> Killed - Ok(reason) -> Abnormal(reason) - Error(_) -> Abnormal(string.inspect(reason)) - } - handler(ExitMessage(message.1, reason)) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -// TODO: implement in Gleam -/// Discard all messages in the current process' mailbox. -/// -/// Warning: This function may cause other processes to crash if they sent a -/// message to the current process and are waiting for a response, so use with -/// caution. -/// -pub external fn flush_messages() -> Nil = - "gleam_erlang_ffi" "flush_messages" - -/// Add a new `Subject` to the `Selector` to that it's messages can be received. -/// -/// The `mapping` function provided with the `Subject` can be used to convert -/// the type of messages received using this `Subject`. This is useful for when -/// you wish to add multiple `Subject`s to a `Seletor` when they have differing -/// message types. If you do not wish to transform the incoming messages in any -/// way then the `identity` function can be given. -/// -pub fn selecting( - selector: Selector(payload), - for subject: Subject(message), - mapping transform: fn(message) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(Reference, message)) { transform(message.1) } - insert_selector_handler(selector, #(subject.tag, 2), handler) -} - -/// Add a handler to a selector for 2 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record2( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic)) { transform(message.1) } - insert_selector_handler(selector, #(tag, 2), handler) -} - -/// Add a handler to a selector for 3 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record3( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic)) { - transform(message.1, message.2) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -/// Add a handler to a selector for 4 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record4( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3) - } - insert_selector_handler(selector, #(tag, 4), handler) -} - -/// Add a handler to a selector for 5 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record5( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4) - } - insert_selector_handler(selector, #(tag, 5), handler) -} - -/// Add a handler to a selector for 6 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record6( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4, message.5) - } - insert_selector_handler(selector, #(tag, 6), handler) -} - -/// Add a handler to a selector for 7 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record7( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - ) { - transform(message.1, message.2, message.3, message.4, message.5, message.6) - } - insert_selector_handler(selector, #(tag, 7), handler) -} - -/// Add a handler to a selector for 8 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record8( - selector: Selector(payload), - tag: tag, - mapping transform: fn( - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #( - tag, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ), - ) { - transform( - message.1, - message.2, - message.3, - message.4, - message.5, - message.6, - message.7, - ) - } - insert_selector_handler(selector, #(tag, 8), handler) -} - -type AnythingSelectorTag { - Anything -} - -/// Add a catch-all handler to a selector that will be used when no other -/// handler in a selector is suitable for a given message. -/// -/// This may be useful for when you want to ensure that any message in the inbox -/// is handled, or when you need to handle messages from other BEAM languages -/// which do not use subjects or record format messages. -/// -pub fn selecting_anything( - selector: Selector(payload), - mapping handler: fn(Dynamic) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, Anything, handler) -} - -external fn insert_selector_handler( - Selector(payload), - for: tag, - mapping: fn(message) -> payload, -) -> Selector(payload) = - "gleam_erlang_ffi" "insert_selector_handler" - -/// Suspends the process calling this function for the specified number of -/// milliseconds. -/// -pub external fn sleep(Int) -> Nil = - "gleam_erlang_ffi" "sleep" - -/// Suspends the process forever! This may be useful for suspending the main -/// process in a Gleam program when it has no more work to do but we want other -/// processes to continue to work. -/// -pub external fn sleep_forever() -> Nil = - "gleam_erlang_ffi" "sleep_forever" - -/// Check to see whether the process for a given `Pid` is alive. -/// -/// See the [Erlang documentation][1] for more information. -/// -/// [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1 -/// -pub external fn is_alive(Pid) -> Bool = - "erlang" "is_process_alive" - -type ProcessMonitorFlag { - Process -} - -external fn erlang_monitor_process(ProcessMonitorFlag, Pid) -> Reference = - "erlang" "monitor" - -pub opaque type ProcessMonitor { - ProcessMonitor(tag: Reference) -} - -/// A message received when a monitored process exits. -/// -pub type ProcessDown { - ProcessDown(pid: Pid, reason: Dynamic) -} - -/// Start monitoring a process so that when the monitored process exits a -/// message is to the monitoring process. -/// -/// The message is only sent once, when the target process exits. If the -/// process was not alive when this function is called the message will never -/// be received. -/// -/// The down message can be received with a `Selector` and the -/// `selecting_process_down` function. -/// -/// The process can be demonitored with the `demonitor_process` function. -/// -pub fn monitor_process(pid: Pid) -> ProcessMonitor { - Process - |> erlang_monitor_process(pid) - |> ProcessMonitor -} - -/// Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can -/// be received using the `Selector` and the `select` function. -/// -pub fn selecting_process_down( - selector: Selector(payload), - monitor: ProcessMonitor, - mapping: fn(ProcessDown) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, monitor.tag, mapping) -} - -/// Remove the monitor for a process so that when the monitor process exits a -/// `ProcessDown` message is not sent to the monitoring process. -/// -/// If the message has already been sent it is removed from the monitoring -/// process' mailbox. -/// -pub external fn demonitor_process(monitor: ProcessMonitor) -> Nil = - "gleam_erlang_ffi" "demonitor" - -/// An error returned when making a call to a process. -/// -pub type CallError(msg) { - /// The process being called exited before it sent a response. - /// - CalleeDown(reason: Dynamic) - - /// The process being called did not response within the permitted amount of - /// time. - /// - CallTimeout -} - -// This function is based off of Erlang's gen:do_call/4. -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time then an error is returned. -/// -pub fn try_call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> Result(response, CallError(response)) { - let reply_subject = new_subject() - - // Monitor the callee process so we can tell if it goes down (meaning we - // won't get a reply) - let monitor = monitor_process(subject_owner(subject)) - - // Send the request to the process over the channel - send(subject, make_request(reply_subject)) - - // Await a reply or handle failure modes (timeout, process down, etc) - let result = - new_selector() - |> selecting(reply_subject, Ok) - |> selecting_process_down( - monitor, - fn(down: ProcessDown) { Error(CalleeDown(reason: down.reason)) }, - ) - |> select(timeout) - - // Demonitor the process and close the channels as we're done - demonitor_process(monitor) - - // Prepare an appropriate error (if present) for the caller - case result { - Error(Nil) -> Error(CallTimeout) - Ok(res) -> res - } -} - -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time the calling process crashes. If you wish an error to be returned -/// instead see the `try_call` function. -/// -pub fn call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> response { - let assert Ok(resp) = try_call(subject, make_request, timeout) - resp -} - -/// Creates a link between the calling process and another process. -/// -/// When a process crashes any linked processes will also crash. This is useful -/// to ensure that groups of processes that depend on each other all either -/// succeed or fail together. -/// -/// Returns `True` if the link was created successfully, returns `False` if the -/// process was not alive and as such could not be linked. -/// -pub external fn link(pid: Pid) -> Bool = - "gleam_erlang_ffi" "link" - -external fn erlang_unlink(pid: Pid) -> Bool = - "erlang" "unlink" - -/// Removes any existing link between the caller process and the target process. -/// -pub fn unlink(pid: Pid) -> Nil { - erlang_unlink(pid) - Nil -} - -pub external type Timer - -external fn erlang_send_after(Int, Pid, msg) -> Timer = - "erlang" "send_after" - -/// Send a message over a channel after a specified number of milliseconds. -/// -pub fn send_after(subject: Subject(msg), delay: Int, message: msg) -> Timer { - erlang_send_after(delay, subject.owner, #(subject.tag, message)) -} - -external fn erlang_cancel_timer(Timer) -> Dynamic = - "erlang" "cancel_timer" - -/// Values returned when a timer is cancelled. -/// -pub type Cancelled { - /// The timer could not be found. It likely has already triggered. - /// - TimerNotFound - - /// The timer was found and cancelled before it triggered. - /// - /// The amount of remaining time before the timer was due to be triggered is - /// returned in milliseconds. - /// - Cancelled(time_remaining: Int) -} - -/// Cancel a given timer, causing it not to trigger if it has not done already. -/// -pub fn cancel_timer(timer: Timer) -> Cancelled { - case dynamic.int(erlang_cancel_timer(timer)) { - Ok(i) -> Cancelled(i) - Error(_) -> TimerNotFound - } -} - -type KillFlag { - Kill -} - -external fn erlang_kill(to: Pid, because: KillFlag) -> Bool = - "erlang" "exit" - -// Go, my pretties. Kill! Kill! -// - Bart Simpson -// -/// Send an untrappable `kill` exit signal to the target process. -/// -/// See the documentation for the Erlang [`erlang:exit`][1] function for more -/// information. -/// -/// [1]: https://erlang.org/doc/man/erlang.html#exit-1 -/// -pub fn kill(pid: Pid) -> Nil { - erlang_kill(pid, Kill) - Nil -} - -external fn erlang_send_exit(to: Pid, because: whatever) -> Bool = - "erlang" "exit" - -// TODO: test -/// Sends an exit signal to a process, indicating that the process is to shut -/// down. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_exit(to pid: Pid) -> Nil { - erlang_send_exit(pid, Normal) - Nil -} - -/// Sends an exit signal to a process, indicating that the process is to shut -/// down due to an abnormal reason such as a failure. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_abnormal_exit(pid: Pid, reason: String) -> Nil { - erlang_send_exit(pid, Abnormal(reason)) - Nil -} - -/// Set whether the current process is to trap exit signals or not. -/// -/// When not trapping exits if a linked process crashes the exit signal -/// propagates to the process which will also crash. -/// This is the normal behaviour before this function is called. -/// -/// When trapping exits (after this function is called) if a linked process -/// crashes an exit message is sent to the process instead. These messages can -/// be handled with the `selecting_trapped_exits` function. -/// -pub external fn trap_exits(Bool) -> Nil = - "gleam_erlang_ffi" "trap_exits" diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl deleted file mode 100644 index 39fdc1855ed..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang.erl +++ /dev/null @@ -1,86 +0,0 @@ --module(gleam@erlang). --compile([no_auto_import, nowarn_unused_vars]). - --export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0]). --export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]). - --type safe() :: safe. - --type get_line_error() :: eof | no_data. - --type time_unit() :: second | millisecond | microsecond | nanosecond. - --type crash() :: {exited, gleam@dynamic:dynamic()} | - {thrown, gleam@dynamic:dynamic()} | - {errored, gleam@dynamic:dynamic()}. - --type ensure_all_started_error() :: {unknown_application, - gleam@erlang@atom:atom_()} | - {application_failed_to_start, - gleam@erlang@atom:atom_(), - gleam@dynamic:dynamic()}. - --type reference_() :: any(). - --spec format(any()) -> binary(). -format(Term) -> - unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])). - --spec term_to_binary(any()) -> bitstring(). -term_to_binary(Field@0) -> - erlang:term_to_binary(Field@0). - --spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. -get_line(Field@0) -> - gleam_erlang_ffi:get_line(Field@0). - --spec system_time(time_unit()) -> integer(). -system_time(Field@0) -> - os:system_time(Field@0). - --spec erlang_timestamp() -> {integer(), integer(), integer()}. -erlang_timestamp() -> - os:timestamp(). - --spec rescue(fun(() -> EYG)) -> {ok, EYG} | {error, crash()}. -rescue(Field@0) -> - gleam_erlang_ffi:rescue(Field@0). - --spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic()} | - {error, nil}. -binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue( - fun() -> erlang:binary_to_term(Binary, [safe]) end - ) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic()} | - {error, nil}. -unsafe_binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec start_arguments() -> list(binary()). -start_arguments() -> - _pipe = init:get_plain_arguments(), - gleam@list:map(_pipe, fun gleam@erlang@charlist:to_string/1). - --spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok, - list(gleam@erlang@atom:atom_())} | - {error, ensure_all_started_error()}. -ensure_all_started(Field@0) -> - gleam_erlang_ffi:ensure_all_started(Field@0). - --spec make_reference() -> reference_(). -make_reference() -> - erlang:make_ref(). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl deleted file mode 100644 index 70b92f520e7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@atom.erl +++ /dev/null @@ -1,26 +0,0 @@ --module(gleam@erlang@atom). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]). --export_type([from_string_error/0, atom_/0]). - --type from_string_error() :: atom_not_loaded. - --type atom_() :: any(). - --spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}. -from_string(Field@0) -> - gleam_erlang_ffi:atom_from_string(Field@0). - --spec create_from_string(binary()) -> atom_(). -create_from_string(Field@0) -> - erlang:binary_to_atom(Field@0). - --spec to_string(atom_()) -> binary(). -to_string(Field@0) -> - erlang:atom_to_binary(Field@0). - --spec from_dynamic(gleam@dynamic:dynamic()) -> {ok, atom_()} | - {error, list(gleam@dynamic:decode_error())}. -from_dynamic(Field@0) -> - gleam_erlang_ffi:atom_from_dynamic(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl deleted file mode 100644 index 8dbbd144055..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl +++ /dev/null @@ -1,15 +0,0 @@ --module(gleam@erlang@charlist). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_string/1, from_string/1]). --export_type([charlist/0]). - --type charlist() :: any(). - --spec to_string(charlist()) -> binary(). -to_string(Field@0) -> - unicode:characters_to_binary(Field@0). - --spec from_string(binary()) -> charlist(). -from_string(Field@0) -> - unicode:characters_to_list(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl deleted file mode 100644 index 829b69aa304..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@file.erl +++ /dev/null @@ -1,190 +0,0 @@ --module(gleam@erlang@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([file_info/1, is_directory/1, is_regular/1, file_exists/1, link_info/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]). --export_type([reason/0, file_type/0, access/0, file_info/0]). - --type reason() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8. - --type file_type() :: device | directory | other | regular | symlink. - --type access() :: no_access | read | read_write | write. - --type file_info() :: {file_info, - integer(), - file_type(), - access(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec file_info(binary()) -> {ok, file_info()} | {error, reason()}. -file_info(Field@0) -> - gleam_erlang_ffi:file_info(Field@0). - --spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}. -is_directory(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= directory - end - ). - --spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}. -is_regular(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= regular - end - ). - --spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}. -file_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:file_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec link_info(binary()) -> {ok, file_info()} | {error, reason()}. -link_info(Field@0) -> - gleam_erlang_ffi:link_info(Field@0). - --spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}. -link_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:link_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec make_directory(binary()) -> {ok, nil} | {error, reason()}. -make_directory(Field@0) -> - gleam_erlang_ffi:make_directory(Field@0). - --spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}. -list_directory(Field@0) -> - gleam_erlang_ffi:list_directory(Field@0). - --spec delete_directory(binary()) -> {ok, nil} | {error, reason()}. -delete_directory(Field@0) -> - gleam_erlang_ffi:delete_directory(Field@0). - --spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}. -recursive_delete(Field@0) -> - gleam_erlang_ffi:recursive_delete(Field@0). - --spec read(binary()) -> {ok, binary()} | {error, reason()}. -read(Path) -> - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:read_file(_pipe), - gleam@result:then( - _pipe@1, - fun(Content) -> case gleam@bit_string:to_string(Content) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, not_utf8} - end end - ). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}. -read_bits(Path) -> - gleam_erlang_ffi:read_file(Path). - --spec write(binary(), binary()) -> {ok, nil} | {error, reason()}. -write(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:write_file(_pipe@1, Path). - --spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -write_bits(Contents, Path) -> - gleam_erlang_ffi:write_file(Contents, Path). - --spec append(binary(), binary()) -> {ok, nil} | {error, reason()}. -append(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:append_file(_pipe@1, Path). - --spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -append_bits(Contents, Path) -> - gleam_erlang_ffi:append_file(Contents, Path). - --spec delete(binary()) -> {ok, nil} | {error, reason()}. -delete(Field@0) -> - gleam_erlang_ffi:delete_file(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl deleted file mode 100644 index 8bfcc227db3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@os.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@erlang@os). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]). --export_type([os_family/0]). - --type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}. - --spec get_all_env() -> gleam@map:map_(binary(), binary()). -get_all_env() -> - gleam_erlang_ffi:get_all_env(). - --spec get_env(binary()) -> {ok, binary()} | {error, nil}. -get_env(Field@0) -> - gleam_erlang_ffi:get_env(Field@0). - --spec set_env(binary(), binary()) -> nil. -set_env(Field@0, Field@1) -> - gleam_erlang_ffi:set_env(Field@0, Field@1). - --spec unset_env(binary()) -> nil. -unset_env(Field@0) -> - gleam_erlang_ffi:unset_env(Field@0). - --spec family() -> os_family(). -family() -> - gleam_erlang_ffi:os_family(). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl deleted file mode 100644 index 56f787e638a..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam@erlang@process.erl +++ /dev/null @@ -1,362 +0,0 @@ --module(gleam@erlang@process). --compile([no_auto_import, nowarn_unused_vars]). - --export([subject_owner/1, self/0, new_subject/0, start/2, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, selecting_process_down/3, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1]). --export_type([subject/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, cancelled/0, kill_flag/0, pid_/0, do_not_leak/0, selector/1, timer/0]). - --opaque subject(EZP) :: {subject, pid_(), gleam@erlang:reference_()} | - {gleam_phantom, EZP}. - --type exit_message() :: {exit_message, pid_(), exit_reason()}. - --type exit_reason() :: normal | killed | {abnormal, binary()}. - --type anything_selector_tag() :: anything. - --type process_monitor_flag() :: process. - --opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}. - --type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic()}. - --type call_error(EZQ) :: {callee_down, gleam@dynamic:dynamic()} | - call_timeout | - {gleam_phantom, EZQ}. - --type cancelled() :: timer_not_found | {cancelled, integer()}. - --type kill_flag() :: kill. - --type pid_() :: any(). - --type do_not_leak() :: any(). - --type selector(Payload) :: any() | {gleam_phantom, Payload}. - --type timer() :: any(). - --spec subject_owner(subject(any())) -> pid_(). -subject_owner(Subject) -> - erlang:element(2, Subject). - --spec self() -> pid_(). -self() -> - erlang:self(). - --spec new_subject() -> subject(any()). -new_subject() -> - {subject, erlang:self(), erlang:make_ref()}. - --spec start(fun(() -> any()), boolean()) -> pid_(). -start(Implementation, Link) -> - case Link of - true -> - erlang:spawn_link(Implementation); - - false -> - erlang:spawn(Implementation) - end. - --spec send(subject(EZW), EZW) -> nil. -send(Subject, Message) -> - erlang:send( - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ), - nil. - --spec new_selector() -> selector(any()). -new_selector() -> - gleam_erlang_ffi:new_selector(). - --spec select(selector(FCK), integer()) -> {ok, FCK} | {error, nil}. -select(Field@0, Field@1) -> - gleam_erlang_ffi:select(Field@0, Field@1). - --spec select_forever(selector(FCO)) -> FCO. -select_forever(Field@0) -> - gleam_erlang_ffi:select(Field@0). - --spec map_selector(selector(FCS), fun((FCS) -> FCQ)) -> selector(FCQ). -map_selector(Field@0, Field@1) -> - gleam_erlang_ffi:map_selector(Field@0, Field@1). - --spec merge_selector(selector(FCU), selector(FCU)) -> selector(FCU). -merge_selector(Field@0, Field@1) -> - gleam_erlang_ffi:merge_selector(Field@0, Field@1). - --spec flush_messages() -> nil. -flush_messages() -> - gleam_erlang_ffi:flush_messages(). - --spec selecting_trapped_exits(selector(FAC), fun((exit_message()) -> FAC)) -> selector(FAC). -selecting_trapped_exits(Selector, Handler) -> - Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>), - Handler@1 = fun(Message) -> - Reason = erlang:element(3, Message), - Normal = gleam@dynamic:from(normal), - Killed = gleam@dynamic:from(killed), - Reason@2 = case gleam@dynamic:string(Reason) of - _ when Reason =:= Normal -> - normal; - - _ when Reason =:= Killed -> - killed; - - {ok, Reason@1} -> - {abnormal, Reason@1}; - - {error, _} -> - {abnormal, gleam@string:inspect(Reason)} - end, - Handler({exit_message, erlang:element(2, Message), Reason@2}) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1). - --spec selecting(selector(FAF), subject(FAH), fun((FAH) -> FAF)) -> selector(FAF). -selecting(Selector, Subject, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler( - Selector, - {erlang:element(3, Subject), 2}, - Handler - ). - --spec 'receive'(subject(EZY), integer()) -> {ok, EZY} | {error, nil}. -'receive'(Subject, Milliseconds) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end), - gleam_erlang_ffi:select(_pipe@1, Milliseconds). - --spec selecting_record2( - selector(FAK), - any(), - fun((gleam@dynamic:dynamic()) -> FAK) -) -> selector(FAK). -selecting_record2(Selector, Tag, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler). - --spec selecting_record3( - selector(FAO), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAO) -) -> selector(FAO). -selecting_record3(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform(erlang:element(2, Message), erlang:element(3, Message)) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler). - --spec selecting_record4( - selector(FAS), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAS) -) -> selector(FAS). -selecting_record4(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler). - --spec selecting_record5( - selector(FAW), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FAW) -) -> selector(FAW). -selecting_record5(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler). - --spec selecting_record6( - selector(FBA), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBA) -) -> selector(FBA). -selecting_record6(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler). - --spec selecting_record7( - selector(FBE), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBE) -) -> selector(FBE). -selecting_record7(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler). - --spec selecting_record8( - selector(FBI), - any(), - fun((gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic(), gleam@dynamic:dynamic()) -> FBI) -) -> selector(FBI). -selecting_record8(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message), - erlang:element(8, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler). - --spec selecting_anything(selector(FBM), fun((gleam@dynamic:dynamic()) -> FBM)) -> selector(FBM). -selecting_anything(Selector, Handler) -> - gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler). - --spec selecting_process_down( - selector(FBP), - process_monitor(), - fun((process_down()) -> FBP) -) -> selector(FBP). -selecting_process_down(Selector, Monitor, Mapping) -> - gleam_erlang_ffi:insert_selector_handler( - Selector, - erlang:element(2, Monitor), - Mapping - ). - --spec sleep(integer()) -> nil. -sleep(Field@0) -> - gleam_erlang_ffi:sleep(Field@0). - --spec sleep_forever() -> nil. -sleep_forever() -> - gleam_erlang_ffi:sleep_forever(). - --spec is_alive(pid_()) -> boolean(). -is_alive(Field@0) -> - erlang:is_process_alive(Field@0). - --spec monitor_process(pid_()) -> process_monitor(). -monitor_process(Pid) -> - _pipe = process, - _pipe@1 = erlang:monitor(_pipe, Pid), - {process_monitor, _pipe@1}. - --spec demonitor_process(process_monitor()) -> nil. -demonitor_process(Field@0) -> - gleam_erlang_ffi:demonitor(Field@0). - --spec try_call(subject(FBS), fun((subject(FBU)) -> FBS), integer()) -> {ok, FBU} | - {error, call_error(FBU)}. -try_call(Subject, Make_request, Timeout) -> - Reply_subject = new_subject(), - Monitor = monitor_process(subject_owner(Subject)), - send(Subject, Make_request(Reply_subject)), - Result = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting( - _pipe, - Reply_subject, - fun(Field@0) -> {ok, Field@0} end - ), - _pipe@2 = selecting_process_down( - _pipe@1, - Monitor, - fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end - ), - gleam_erlang_ffi:select(_pipe@2, Timeout) - end, - gleam_erlang_ffi:demonitor(Monitor), - case Result of - {error, nil} -> - {error, call_timeout}; - - {ok, Res} -> - Res - end. - --spec call(subject(FBZ), fun((subject(FCB)) -> FBZ), integer()) -> FCB. -call(Subject, Make_request, Timeout) -> - _assert_subject = try_call(Subject, Make_request, Timeout), - {ok, Resp} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/erlang/process"/utf8>>, - function => <<"call"/utf8>>, - line => 593}) - end, - Resp. - --spec link(pid_()) -> boolean(). -link(Field@0) -> - gleam_erlang_ffi:link(Field@0). - --spec unlink(pid_()) -> nil. -unlink(Pid) -> - erlang:unlink(Pid), - nil. - --spec send_after(subject(FCD), integer(), FCD) -> timer(). -send_after(Subject, Delay, Message) -> - erlang:send_after( - Delay, - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ). - --spec cancel_timer(timer()) -> cancelled(). -cancel_timer(Timer) -> - case gleam@dynamic:int(erlang:cancel_timer(Timer)) of - {ok, I} -> - {cancelled, I}; - - {error, _} -> - timer_not_found - end. - --spec kill(pid_()) -> nil. -kill(Pid) -> - erlang:exit(Pid, kill), - nil. - --spec send_exit(pid_()) -> nil. -send_exit(Pid) -> - erlang:exit(Pid, normal), - nil. - --spec send_abnormal_exit(pid_(), binary()) -> nil. -send_abnormal_exit(Pid, Reason) -> - erlang:exit(Pid, {abnormal, Reason}), - nil. - --spec trap_exits(boolean()) -> nil. -trap_exits(Field@0) -> - gleam_erlang_ffi:trap_exits(Field@0). diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src deleted file mode 100644 index 7682a9cebe8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang.app.src +++ /dev/null @@ -1,13 +0,0 @@ -{application, gleam_erlang, [ - {vsn, "0.19.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A Gleam library for working with Erlang"}, - {modules, [gleam@erlang, - gleam@erlang@atom, - gleam@erlang@charlist, - gleam@erlang@file, - gleam@erlang@os, - gleam@erlang@process]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl deleted file mode 100644 index 2c6bd5f09d5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl +++ /dev/null @@ -1,218 +0,0 @@ --module(gleam_erlang_ffi). --export([ - atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, - ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, - append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, - set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, - list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, - insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, - merge_selector/2, flush_messages/0, file_info/1, link_info/1 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - --spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. -atom_from_string(S) -> - try {ok, binary_to_existing_atom(S)} - catch error:badarg -> {error, atom_not_loaded} - end. - -atom_from_dynamic(Data) when is_atom(Data) -> - {ok, Data}; -atom_from_dynamic(Data) -> - {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. - -rescue(F) -> - try {ok, F()} - catch - throw:X -> {error, {thrown, X}}; - error:X -> {error, {errored, X}}; - exit:X -> {error, {exited, X}} - end. - -ensure_all_started(Application) -> - case application:ensure_all_started(Application) of - {ok, _} = Ok -> Ok; - - {error, {ProblemApp, {"no such file or directory", _}}} -> - {error, {unknown_application, ProblemApp}} - end. - -sleep(Microseconds) -> - timer:sleep(Microseconds), - nil. - -sleep_forever() -> - timer:sleep(infinity), - nil. - -file_info_result(Result) -> - case Result of - {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> - {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; - {ok, _} -> - Result; - {error, Reason} when ?is_posix_error(Reason) -> - Result - end. - -file_info(Filename) -> - file_info_result(file:read_file_info(Filename, [{time, posix}])). - -link_info(Filename) -> - file_info_result(file:read_link_info(Filename, [{time, posix}])). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -get_all_env() -> - BinVars = lists:map(fun(VarString) -> - [VarName, VarVal] = string:split(VarString, "="), - {list_to_binary(VarName), list_to_binary(VarVal)} - end, os:getenv()), - maps:from_list(BinVars). - -get_env(Name) -> - case os:getenv(binary_to_list(Name)) of - false -> {error, nil}; - Value -> {ok, list_to_binary(Value)} - end. - -set_env(Name, Value) -> - os:putenv(binary_to_list(Name), binary_to_list(Value)), - nil. - -unset_env(Name) -> - os:unsetenv(binary_to_list(Name)), - nil. - -os_family() -> - case os:type() of - {win32, nt} -> - windows_nt; - {unix, linux} -> - linux; - {unix, darwin} -> - darwin; - {unix, freebsd} -> - free_bsd; - {_, Other} -> - {other, atom_to_binary(Other, utf8)} - end. - -new_selector() -> - {selector, #{}}. - -map_selector({selector, Handlers}, Fn) -> - MappedHandlers = maps:map(fun(_Tag, Handler) -> - fun(Message) -> Fn(Handler(Message)) end - end, Handlers), - {selector, MappedHandlers}. - -merge_selector({selector, HandlersA}, {selector, HandlersB}) -> - {selector, maps:merge(HandlersA, HandlersB)}. - -insert_selector_handler({selector, Handlers}, Tag, Fn) -> - {selector, Handlers#{Tag => Fn}}. - -select(Selector) -> - {ok, Message} = select(Selector, infinity), - Message. - -select({selector, Handlers}, Timeout) -> - AnythingHandler = maps:get(anything, Handlers, undefined), - receive - % Monitored process down messages. - % This is special cased so we can selectively receive based on the - % reference as well as the record tag. - {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> - Fn = maps:get(Ref, Handlers), - {ok, Fn({process_down, Pid, Reason})}; - - Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> - Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), - {ok, Fn(Msg)}; - - Msg when AnythingHandler =/= undefined -> - {ok, AnythingHandler(Msg)} - after Timeout -> - {error, nil} - end. - -demonitor({_, Reference}) -> - erlang:demonitor(Reference, [flush]). - -link(Pid) -> - try - erlang:link(Pid) - catch - error:_ -> false - end. - -trap_exits(ShouldTrap) -> - erlang:process_flag(trap_exit, ShouldTrap), - nil. - -flush_messages() -> - receive _Message -> flush_messages() - after 0 -> nil - end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/LICENSE b/test-community-packages-javascript/build/packages/gleam_http/LICENSE deleted file mode 100644 index 619ec77e6e1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_http/README.md b/test-community-packages-javascript/build/packages/gleam_http/README.md deleted file mode 100644 index 5c0a7f685a3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Gleam HTTP - -Types and functions for HTTP clients and servers! - -## HTTP Service Example - -```gleam -import gleam/http/elli -import gleam/http/response.{Response} -import gleam/http/request.{Request} -import gleam/bit_builder.{BitBuilder} - -// Define a HTTP service -// -pub fn my_service(request: Request(t)) -> Response(BitBuilder) { - let body = bit_builder.from_string("Hello, world!") - - response.new(200) - |> response.prepend_header("made-with", "Gleam") - |> response.set_body(body) -} - -// Start it on port 3000 using the Elli web server -// -pub fn main() { - elli.become(my_service, on_port: 3000) -} -``` - -## Server adapters - -In the example above the Elli Erlang web server is used to run the Gleam HTTP -service. Here's a full list of the server adapters available, sorted -alphabetically. - -| Adapter | About | -| --- | --- | -| [gleam_cowboy][cowboy-adapter] | [Cowboy][cowboy] is an Erlang HTTP2 & HTTP1.1 web server | -| [gleam_elli][elli-adapter] | [Elli][elli] is an Erlang HTTP1.1 web server | -| [gleam_plug][plug-adapter] | [Plug][plug] is an Elixir web application interface | - -[cowboy]:https://github.com/ninenines/cowboy -[cowboy-adapter]: https://github.com/gleam-lang/cowboy -[elli]:https://github.com/elli-lib/elli -[elli-adapter]: https://github.com/gleam-lang/elli -[plug]:https://github.com/elixir-plug/plug -[plug-adapter]: https://github.com/gleam-lang/plug - -## Client adapters - -Client adapters are used to send HTTP requests to services over the network. -Here's a full list of the client adapters available, sorted alphabetically. - -| Adapter | About | -| --- | --- | -| [gleam_fetch][fetch-adapter] | [fetch][fetch] is a HTTP client included with JavaScript | -| [gleam_hackney][hackney-adapter] | [Hackney][hackney] is a simple HTTP client for Erlang | -| [gleam_httpc][httpc-adapter] | [httpc][httpc] is a HTTP client included with Erlang | - -[hackney]: https://github.com/benoitc/hackney -[hackney-adapter]: https://github.com/gleam-lang/hackney -[httpc]: https://erlang.org/doc/man/httpc.html -[httpc-adapter]: https://github.com/gleam-lang/httpc -[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API -[fetch-adapter]: https://github.com/gleam-lang/fetch diff --git a/test-community-packages-javascript/build/packages/gleam_http/gleam.toml b/test-community-packages-javascript/build/packages/gleam_http/gleam.toml deleted file mode 100644 index 6955a79b2ed..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_http" -version = "3.2.0" -licences = ["Apache-2.0"] -description = "Types and functions for Gleam HTTP clients and servers" - -repository = { type = "github", user = "gleam-lang", repo = "http" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.18" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl deleted file mode 100644 index 78a7d02c930..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl +++ /dev/null @@ -1,8 +0,0 @@ --record(attributes, { - max_age :: gleam@option:option(integer()), - domain :: gleam@option:option(binary()), - path :: gleam@option:option(binary()), - secure :: boolean(), - http_only :: boolean(), - same_site :: gleam@option:option(gleam@http@cookie:same_site_policy()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl deleted file mode 100644 index c8bbae649d5..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@request_Request.hrl +++ /dev/null @@ -1,10 +0,0 @@ --record(request, { - method :: gleam@http:method(), - headers :: list({binary(), binary()}), - body :: any(), - scheme :: gleam@http:scheme(), - host :: binary(), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl b/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl deleted file mode 100644 index ba6f07701c7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/include/gleam@http@response_Response.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(response, { - status :: integer(), - headers :: list({binary(), binary()}), - body :: any() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam deleted file mode 100644 index ec17246b90f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http.gleam +++ /dev/null @@ -1,122 +0,0 @@ -//// Functions for working with HTTP data structures in Gleam. -//// -//// This module makes it easy to create and modify Requests and Responses, data types. -//// A general HTTP message type is defined that enables functions to work on both requests and responses. -//// -//// This module does not implement a HTTP client or HTTP server, but it can be used as a base for them. - -import gleam/dynamic.{DecodeError, Dynamic} -import gleam/string - -/// HTTP standard method as defined by [RFC 2616](https://tools.ietf.org/html/rfc2616), -/// and PATCH which is defined by [RFC 5789](https://tools.ietf.org/html/rfc5789). -pub type Method { - Get - Post - Head - Put - Delete - Trace - Connect - Options - Patch - - /// Non-standard but valid HTTP methods. - Other(String) -} - -// TODO: check if the a is a valid HTTP method (i.e. it is a token, as per the -// spec) and return Ok(Other(s)) if so. -pub fn parse_method(s) -> Result(Method, Nil) { - case string.lowercase(s) { - "connect" -> Ok(Connect) - "delete" -> Ok(Delete) - "get" -> Ok(Get) - "head" -> Ok(Head) - "options" -> Ok(Options) - "patch" -> Ok(Patch) - "post" -> Ok(Post) - "put" -> Ok(Put) - "trace" -> Ok(Trace) - _ -> Error(Nil) - } -} - -pub fn method_to_string(method: Method) -> String { - case method { - Connect -> "connect" - Delete -> "delete" - Get -> "get" - Head -> "head" - Options -> "options" - Patch -> "patch" - Post -> "post" - Put -> "put" - Trace -> "trace" - Other(s) -> s - } -} - -/// The two URI schemes for HTTP -/// -pub type Scheme { - Http - Https -} - -/// Convert a scheme into a string. -/// -/// # Examples -/// -/// > scheme_to_string(Http) -/// "http" -/// -/// > scheme_to_string(Https) -/// "https" -/// -pub fn scheme_to_string(scheme: Scheme) -> String { - case scheme { - Http -> "http" - Https -> "https" - } -} - -/// Parse a HTTP scheme from a string -/// -/// # Examples -/// -/// > scheme_to_string("http") -/// Ok(Http) -/// -/// > scheme_to_string("ftp") -/// Error(Nil) -/// -pub fn scheme_from_string(scheme: String) -> Result(Scheme, Nil) { - case string.lowercase(scheme) { - "http" -> Ok(Http) - "https" -> Ok(Https) - _ -> Error(Nil) - } -} - -pub fn method_from_dynamic(value: Dynamic) -> Result(Method, List(DecodeError)) { - case do_method_from_dynamic(value) { - Ok(method) -> Ok(method) - Error(_) -> Error([DecodeError("HTTP method", dynamic.classify(value), [])]) - } -} - -if erlang { - external fn do_method_from_dynamic(Dynamic) -> Result(Method, nil) = - "gleam_http_native" "decode_method" -} - -if javascript { - external fn do_method_from_dynamic(Dynamic) -> Result(Method, Nil) = - "../gleam_http_native.mjs" "decode_method" -} - -/// A HTTP header is a key-value pair. Header keys should be all lowercase -/// characters. -pub type Header = - #(String, String) diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam deleted file mode 100644 index 79c9faf4917..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/cookie.gleam +++ /dev/null @@ -1,128 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/regex -import gleam/string -import gleam/option.{Option, Some} -import gleam/http.{Scheme} - -/// Policy options for the SameSite cookie attribute -/// -/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite -pub type SameSitePolicy { - Lax - Strict - None -} - -fn same_site_to_string(policy) { - case policy { - Lax -> "Lax" - Strict -> "Strict" - None -> "None" - } -} - -/// Attributes of a cookie when sent to a client in the `set-cookie` header. -pub type Attributes { - Attributes( - max_age: Option(Int), - domain: Option(String), - path: Option(String), - secure: Bool, - http_only: Bool, - same_site: Option(SameSitePolicy), - ) -} - -/// Helper to create sensible default attributes for a set cookie. -/// -/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Attributes -pub fn defaults(scheme: Scheme) { - Attributes( - max_age: option.None, - domain: option.None, - path: option.Some("/"), - secure: scheme == http.Https, - http_only: True, - same_site: Some(Lax), - ) -} - -const epoch = "Expires=Thu, 01 Jan 1970 00:00:00 GMT" - -fn cookie_attributes_to_list(attributes) { - let Attributes( - max_age: max_age, - domain: domain, - path: path, - secure: secure, - http_only: http_only, - same_site: same_site, - ) = attributes - [ - // Expires is a deprecated attribute for cookies, it has been replaced with MaxAge - // MaxAge is widely supported and so Expires values are not set. - // Only when deleting cookies is the exception made to use the old format, - // to ensure complete clearup of cookies if required by an application. - case max_age { - option.Some(0) -> option.Some([epoch]) - _ -> option.None - }, - option.map(max_age, fn(max_age) { ["Max-Age=", int.to_string(max_age)] }), - option.map(domain, fn(domain) { ["Domain=", domain] }), - option.map(path, fn(path) { ["Path=", path] }), - case secure { - True -> option.Some(["Secure"]) - False -> option.None - }, - case http_only { - True -> option.Some(["HttpOnly"]) - False -> option.None - }, - option.map( - same_site, - fn(same_site) { ["SameSite=", same_site_to_string(same_site)] }, - ), - ] - |> list.filter_map(option.to_result(_, Nil)) -} - -pub fn set_header(name: String, value: String, attributes: Attributes) -> String { - [[name, "=", value], ..cookie_attributes_to_list(attributes)] - |> list.map(string.join(_, "")) - |> string.join("; ") -} - -/// Parse a list of cookies from a header string. Any malformed cookies will be -/// discarded. -/// -pub fn parse(cookie_string: String) -> List(#(String, String)) { - let assert Ok(re) = regex.from_string("[,;]") - regex.split(re, cookie_string) - |> list.filter_map(fn(pair) { - case string.split_once(string.trim(pair), "=") { - Ok(#("", _)) -> Error(Nil) - Ok(#(key, value)) -> { - let key = string.trim(key) - let value = string.trim(value) - use _ <- result.then(check_token(key)) - use _ <- result.then(check_token(value)) - Ok(#(key, value)) - } - Error(Nil) -> Error(Nil) - } - }) -} - -fn check_token(token: String) -> Result(Nil, Nil) { - case string.pop_grapheme(token) { - Error(Nil) -> Ok(Nil) - Ok(#(" ", _)) -> Error(Nil) - Ok(#("\t", _)) -> Error(Nil) - Ok(#("\r", _)) -> Error(Nil) - Ok(#("\n", _)) -> Error(Nil) - Ok(#("\f", _)) -> Error(Nil) - Ok(#(_, rest)) -> check_token(rest) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam deleted file mode 100644 index f4fbe9bc30c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/request.gleam +++ /dev/null @@ -1,258 +0,0 @@ -import gleam/result -// TODO: validate_req -import gleam/http.{Get, Header, Method, Scheme} -import gleam/http/cookie -import gleam/option.{None, Option, Some} -import gleam/uri.{Uri} -import gleam/list -import gleam/string -import gleam/string_builder - -// TODO: document -pub type Request(body) { - Request( - method: Method, - headers: List(Header), - body: body, - scheme: Scheme, - host: String, - port: Option(Int), - path: String, - query: Option(String), - ) -} - -/// Return the uri that a request was sent to. -/// -pub fn to_uri(request: Request(a)) -> Uri { - Uri( - scheme: option.Some(http.scheme_to_string(request.scheme)), - userinfo: option.None, - host: option.Some(request.host), - port: request.port, - path: request.path, - query: request.query, - fragment: option.None, - ) -} - -/// Construct a request from a URI. -/// -pub fn from_uri(uri: Uri) -> Result(Request(String), Nil) { - use scheme <- result.then( - uri.scheme - |> option.unwrap("") - |> http.scheme_from_string, - ) - use host <- result.then( - uri.host - |> option.to_result(Nil), - ) - let req = - Request( - method: Get, - headers: [], - body: "", - scheme: scheme, - host: host, - port: uri.port, - path: uri.path, - query: uri.query, - ) - Ok(req) -} - -/// Get the value for a given header. -/// -/// If the request does not have that header then `Error(Nil)` is returned. -/// -pub fn get_header(request: Request(body), key: String) -> Result(String, Nil) { - list.key_find(request.headers, string.lowercase(key)) -} - -/// Set the header with the given value under the given header key. -/// -/// If already present, it is replaced. -pub fn set_header( - request: Request(body), - key: String, - value: String, -) -> Request(body) { - let headers = list.key_set(request.headers, string.lowercase(key), value) - Request(..request, headers: headers) -} - -/// Prepend the header with the given value under the given header key. -/// -/// Similar to `set_header` except if the header already exists it prepends -/// another header with the same key. -pub fn prepend_header( - request: Request(body), - key: String, - value: String, -) -> Request(body) { - let headers = [#(string.lowercase(key), value), ..request.headers] - Request(..request, headers: headers) -} - -// TODO: record update syntax, which can't be done currently as body type changes -/// Set the body of the request, overwriting any existing body. -/// -pub fn set_body(req: Request(old_body), body: new_body) -> Request(new_body) { - let Request( - method: method, - headers: headers, - scheme: scheme, - host: host, - port: port, - path: path, - query: query, - .., - ) = req - Request( - method: method, - headers: headers, - body: body, - scheme: scheme, - host: host, - port: port, - path: path, - query: query, - ) -} - -/// Update the body of a request using a given function. -/// -pub fn map( - request: Request(old_body), - transform: fn(old_body) -> new_body, -) -> Request(new_body) { - request.body - |> transform - |> set_body(request, _) -} - -/// Return the non-empty segments of a request path. -/// -pub fn path_segments(request: Request(body)) -> List(String) { - request.path - |> uri.path_segments -} - -/// Decode the query of a request. -pub fn get_query(request: Request(body)) -> Result(List(#(String, String)), Nil) { - case request.query { - option.Some(query_string) -> uri.parse_query(query_string) - option.None -> Ok([]) - } -} - -// TODO: escape -/// Set the query of the request. -/// -pub fn set_query( - req: Request(body), - query: List(#(String, String)), -) -> Request(body) { - let pair = fn(t: #(String, String)) { - string_builder.from_strings([t.0, "=", t.1]) - } - let query = - query - |> list.map(pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string - |> option.Some - Request(..req, query: query) -} - -/// Set the method of the request. -/// -pub fn set_method(req: Request(body), method: Method) -> Request(body) { - Request(..req, method: method) -} - -/// A request with commonly used default values. This request can be used as -/// an initial value and then update to create the desired request. -/// -pub fn new() -> Request(String) { - Request( - method: Get, - headers: [], - body: "", - scheme: http.Https, - host: "localhost", - port: option.None, - path: "", - query: option.None, - ) -} - -/// Construct a request from a URL string -/// -pub fn to(url: String) -> Result(Request(String), Nil) { - url - |> uri.parse - |> result.then(from_uri) -} - -/// Set the scheme (protocol) of the request. -/// -pub fn set_scheme(req: Request(body), scheme: Scheme) -> Request(body) { - Request(..req, scheme: scheme) -} - -/// Set the method of the request. -/// -pub fn set_host(req: Request(body), host: String) -> Request(body) { - Request(..req, host: host) -} - -/// Set the port of the request. -/// -pub fn set_port(req: Request(body), port: Int) -> Request(body) { - Request(..req, port: option.Some(port)) -} - -/// Set the path of the request. -/// -pub fn set_path(req: Request(body), path: String) -> Request(body) { - Request(..req, path: path) -} - -/// Send a cookie with a request -/// -/// Multiple cookies are added to the same cookie header. -pub fn set_cookie(req: Request(body), name: String, value: String) { - let new_cookie_string = string.join([name, value], "=") - - let #(cookies_string, headers) = case list.key_pop(req.headers, "cookie") { - Ok(#(cookies_string, headers)) -> { - let cookies_string = - string.join([cookies_string, new_cookie_string], "; ") - #(cookies_string, headers) - } - Error(Nil) -> #(new_cookie_string, req.headers) - } - - Request(..req, headers: [#("cookie", cookies_string), ..headers]) -} - -/// Fetch the cookies sent in a request. -/// -/// Note badly formed cookie pairs will be ignored. -/// RFC6265 specifies that invalid cookie names/attributes should be ignored. -pub fn get_cookies(req) -> List(#(String, String)) { - let Request(headers: headers, ..) = req - - headers - |> list.filter_map(fn(header) { - let #(name, value) = header - case name { - "cookie" -> Ok(cookie.parse(value)) - _ -> Error(Nil) - } - }) - |> list.flatten() -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam deleted file mode 100644 index 56f42d19b2c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/response.gleam +++ /dev/null @@ -1,141 +0,0 @@ -import gleam/result -import gleam/http.{Header} -import gleam/http/cookie -import gleam/list -import gleam/string -import gleam/option - -// TODO: document -pub type Response(body) { - Response(status: Int, headers: List(Header), body: body) -} - -/// Update the body of a response using a given result returning function. -/// -/// If the given function returns an `Ok` value the body is set, if it returns -/// an `Error` value then the error is returned. -/// -pub fn try_map( - response: Response(old_body), - transform: fn(old_body) -> Result(new_body, error), -) -> Result(Response(new_body), error) { - use body <- result.then(transform(response.body)) - Ok(set_body(response, body)) -} - -/// Construct an empty Response. -/// -/// The body type of the returned response is `String` and could be set with a -/// call to `set_body`. -/// -pub fn new(status: Int) -> Response(String) { - Response(status: status, headers: [], body: "") -} - -/// Get the value for a given header. -/// -/// If the response does not have that header then `Error(Nil)` is returned. -/// -pub fn get_header(response: Response(body), key: String) -> Result(String, Nil) { - list.key_find(response.headers, string.lowercase(key)) -} - -/// Set the header with the given value under the given header key. -/// -/// If the response already has that key, it is replaced. -pub fn set_header( - response: Response(body), - key: String, - value: String, -) -> Response(body) { - let headers = list.key_set(response.headers, key, string.lowercase(value)) - Response(..response, headers: headers) -} - -/// Prepend the header with the given value under the given header key. -/// -/// Similar to `set_header` except if the header already exists it prepends -/// another header with the same key. -pub fn prepend_header( - response: Response(body), - key: String, - value: String, -) -> Response(body) { - let headers = [#(string.lowercase(key), value), ..response.headers] - Response(..response, headers: headers) -} - -/// Set the body of the response, overwriting any existing body. -/// -pub fn set_body( - response: Response(old_body), - body: new_body, -) -> Response(new_body) { - let Response(status: status, headers: headers, ..) = response - Response(status: status, headers: headers, body: body) -} - -/// Update the body of a response using a given function. -/// -pub fn map( - response: Response(old_body), - transform: fn(old_body) -> new_body, -) -> Response(new_body) { - response.body - |> transform - |> set_body(response, _) -} - -/// Create a response that redirects to the given uri. -/// -pub fn redirect(uri: String) -> Response(String) { - Response( - status: 303, - headers: [#("location", uri)], - body: string.append("You are being redirected to ", uri), - ) -} - -/// Fetch the cookies sent in a response. -/// -/// Badly formed cookies will be discarded. -/// -pub fn get_cookies(resp) -> List(#(String, String)) { - let Response(headers: headers, ..) = resp - headers - |> list.filter_map(fn(header) { - let #(name, value) = header - case name { - "set-cookie" -> Ok(cookie.parse(value)) - _ -> Error(Nil) - } - }) - |> list.flatten() -} - -/// Set a cookie value for a client -/// -pub fn set_cookie( - response: Response(t), - name: String, - value: String, - attributes: cookie.Attributes, -) -> Response(t) { - prepend_header( - response, - "set-cookie", - cookie.set_header(name, value, attributes), - ) -} - -/// Expire a cookie value for a client -/// -/// Note: The attributes value should be the same as when the response cookie was set. -pub fn expire_cookie( - response: Response(t), - name: String, - attributes: cookie.Attributes, -) -> Response(t) { - let attrs = cookie.Attributes(..attributes, max_age: option.Some(0)) - set_cookie(response, name, "", attrs) -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam b/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam deleted file mode 100644 index fddf362b525..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam/http/service.gleam +++ /dev/null @@ -1,82 +0,0 @@ -import gleam/http.{Delete, Patch, Post, Put} -import gleam/http/request.{Request} -import gleam/http/response.{Response} -import gleam/list -import gleam/result - -// TODO: document -pub type Service(in, out) = - fn(Request(in)) -> Response(out) - -pub type Middleware(before_req, before_resp, after_req, after_resp) = - fn(Service(before_req, before_resp)) -> Service(after_req, after_resp) - -/// A middleware that transform the response body returned by the service using -/// a given function. -/// -pub fn map_response_body( - service: Service(req, a), - with mapper: fn(a) -> b, -) -> Service(req, b) { - fn(req) { - req - |> service - |> response.map(mapper) - } -} - -/// A middleware that prepends a header to the request. -/// -pub fn prepend_response_header( - service: Service(req, resp), - key: String, - value: String, -) -> Service(req, resp) { - fn(req) { - req - |> service - |> response.prepend_header(key, value) - } -} - -fn ensure_post(req: Request(a)) { - case req.method { - Post -> Ok(req) - _ -> Error(Nil) - } -} - -fn get_override_method(request: Request(t)) -> Result(http.Method, Nil) { - use query_params <- result.then(request.get_query(request)) - use method <- result.then(list.key_find(query_params, "_method")) - use method <- result.then(http.parse_method(method)) - case method { - Put | Patch | Delete -> Ok(method) - _ -> Error(Nil) - } -} - -/// A middleware that overrides an incoming POST request with a method given in -/// the request's `_method` query paramerter. This is useful as web browsers -/// typically only support GET and POST requests, but our application may -/// expect other HTTP methods that are more semantically correct. -/// -/// The methods PUT, PATCH, and DELETE are accepted for overriding, all others -/// are ignored. -/// -/// The `_method` query paramerter can be specified in a HTML form like so: -/// -/// <form method="POST" action="/item/1?_method=DELETE"> -/// <button type="submit">Delete item</button> -/// </form> -/// -pub fn method_override(service: Service(req, resp)) -> Service(req, resp) { - fn(request) { - request - |> ensure_post - |> result.then(get_override_method) - |> result.map(request.set_method(request, _)) - |> result.unwrap(request) - |> service - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl deleted file mode 100644 index 3baae58a314..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http.erl +++ /dev/null @@ -1,124 +0,0 @@ --module(gleam@http). --compile([no_auto_import, nowarn_unused_vars]). - --export([parse_method/1, method_to_string/1, scheme_to_string/1, scheme_from_string/1, method_from_dynamic/1]). --export_type([method/0, scheme/0]). - --type method() :: get | - post | - head | - put | - delete | - trace | - connect | - options | - patch | - {other, binary()}. - --type scheme() :: http | https. - --spec parse_method(binary()) -> {ok, method()} | {error, nil}. -parse_method(S) -> - case gleam@string:lowercase(S) of - <<"connect"/utf8>> -> - {ok, connect}; - - <<"delete"/utf8>> -> - {ok, delete}; - - <<"get"/utf8>> -> - {ok, get}; - - <<"head"/utf8>> -> - {ok, head}; - - <<"options"/utf8>> -> - {ok, options}; - - <<"patch"/utf8>> -> - {ok, patch}; - - <<"post"/utf8>> -> - {ok, post}; - - <<"put"/utf8>> -> - {ok, put}; - - <<"trace"/utf8>> -> - {ok, trace}; - - _ -> - {error, nil} - end. - --spec method_to_string(method()) -> binary(). -method_to_string(Method) -> - case Method of - connect -> - <<"connect"/utf8>>; - - delete -> - <<"delete"/utf8>>; - - get -> - <<"get"/utf8>>; - - head -> - <<"head"/utf8>>; - - options -> - <<"options"/utf8>>; - - patch -> - <<"patch"/utf8>>; - - post -> - <<"post"/utf8>>; - - put -> - <<"put"/utf8>>; - - trace -> - <<"trace"/utf8>>; - - {other, S} -> - S - end. - --spec scheme_to_string(scheme()) -> binary(). -scheme_to_string(Scheme) -> - case Scheme of - http -> - <<"http"/utf8>>; - - https -> - <<"https"/utf8>> - end. - --spec scheme_from_string(binary()) -> {ok, scheme()} | {error, nil}. -scheme_from_string(Scheme) -> - case gleam@string:lowercase(Scheme) of - <<"http"/utf8>> -> - {ok, http}; - - <<"https"/utf8>> -> - {ok, https}; - - _ -> - {error, nil} - end. - --spec method_from_dynamic(gleam@dynamic:dynamic()) -> {ok, method()} | - {error, list(gleam@dynamic:decode_error())}. -method_from_dynamic(Value) -> - case gleam_http_native:decode_method(Value) of - {ok, Method} -> - {ok, Method}; - - {error, _} -> - {error, - [{decode_error, - <<"HTTP method"/utf8>>, - gleam@dynamic:classify(Value), - []}]} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl deleted file mode 100644 index f7451c7ada6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@cookie.erl +++ /dev/null @@ -1,153 +0,0 @@ --module(gleam@http@cookie). --compile([no_auto_import, nowarn_unused_vars]). - --export([defaults/1, set_header/3, parse/1]). --export_type([same_site_policy/0, attributes/0]). - --type same_site_policy() :: lax | strict | none. - --type attributes() :: {attributes, - gleam@option:option(integer()), - gleam@option:option(binary()), - gleam@option:option(binary()), - boolean(), - boolean(), - gleam@option:option(same_site_policy())}. - --spec same_site_to_string(same_site_policy()) -> binary(). -same_site_to_string(Policy) -> - case Policy of - lax -> - <<"Lax"/utf8>>; - - strict -> - <<"Strict"/utf8>>; - - none -> - <<"None"/utf8>> - end. - --spec defaults(gleam@http:scheme()) -> attributes(). -defaults(Scheme) -> - {attributes, - none, - none, - {some, <<"/"/utf8>>}, - Scheme =:= https, - true, - {some, lax}}. - --spec cookie_attributes_to_list(attributes()) -> list(list(binary())). -cookie_attributes_to_list(Attributes) -> - {attributes, Max_age, Domain, Path, Secure, Http_only, Same_site} = Attributes, - _pipe = [case Max_age of - {some, 0} -> - {some, [<<"Expires=Thu, 01 Jan 1970 00:00:00 GMT"/utf8>>]}; - - _ -> - none - end, gleam@option:map( - Max_age, - fun(Max_age@1) -> - [<<"Max-Age="/utf8>>, gleam@int:to_string(Max_age@1)] - end - ), gleam@option:map( - Domain, - fun(Domain@1) -> [<<"Domain="/utf8>>, Domain@1] end - ), gleam@option:map(Path, fun(Path@1) -> [<<"Path="/utf8>>, Path@1] end), case Secure of - true -> - {some, [<<"Secure"/utf8>>]}; - - false -> - none - end, case Http_only of - true -> - {some, [<<"HttpOnly"/utf8>>]}; - - false -> - none - end, gleam@option:map( - Same_site, - fun(Same_site@1) -> - [<<"SameSite="/utf8>>, same_site_to_string(Same_site@1)] - end - )], - gleam@list:filter_map( - _pipe, - fun(_capture) -> gleam@option:to_result(_capture, nil) end - ). - --spec set_header(binary(), binary(), attributes()) -> binary(). -set_header(Name, Value, Attributes) -> - _pipe = [[Name, <<"="/utf8>>, Value] | - cookie_attributes_to_list(Attributes)], - _pipe@1 = gleam@list:map( - _pipe, - fun(_capture) -> gleam@string:join(_capture, <<""/utf8>>) end - ), - gleam@string:join(_pipe@1, <<"; "/utf8>>). - --spec check_token(binary()) -> {ok, nil} | {error, nil}. -check_token(Token) -> - case gleam@string:pop_grapheme(Token) of - {error, nil} -> - {ok, nil}; - - {ok, {<<" "/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\t"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\r"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\n"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\f"/utf8>>, _}} -> - {error, nil}; - - {ok, {_, Rest}} -> - check_token(Rest) - end. - --spec parse(binary()) -> list({binary(), binary()}). -parse(Cookie_string) -> - _assert_subject = gleam@regex:from_string(<<"[,;]"/utf8>>), - {ok, Re} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/http/cookie"/utf8>>, - function => <<"parse"/utf8>>, - line => 101}) - end, - _pipe = gleam@regex:split(Re, Cookie_string), - gleam@list:filter_map( - _pipe, - fun(Pair) -> - case gleam@string:split_once(gleam@string:trim(Pair), <<"="/utf8>>) of - {ok, {<<""/utf8>>, _}} -> - {error, nil}; - - {ok, {Key, Value}} -> - Key@1 = gleam@string:trim(Key), - Value@1 = gleam@string:trim(Value), - gleam@result:then( - check_token(Key@1), - fun(_) -> - gleam@result:then( - check_token(Value@1), - fun(_) -> {ok, {Key@1, Value@1}} end - ) - end - ); - - {error, nil} -> - {error, nil} - end - end - ). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl deleted file mode 100644 index 97616ed4506..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@request.erl +++ /dev/null @@ -1,202 +0,0 @@ --module(gleam@http@request). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_uri/1, from_uri/1, get_header/2, set_header/3, prepend_header/3, set_body/2, map/2, path_segments/1, get_query/1, set_query/2, set_method/2, new/0, to/1, set_scheme/2, set_host/2, set_port/2, set_path/2, set_cookie/3, get_cookies/1]). --export_type([request/1]). - --type request(FBL) :: {request, - gleam@http:method(), - list({binary(), binary()}), - FBL, - gleam@http:scheme(), - binary(), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary())}. - --spec to_uri(request(any())) -> gleam@uri:uri(). -to_uri(Request) -> - {uri, - {some, gleam@http:scheme_to_string(erlang:element(5, Request))}, - none, - {some, erlang:element(6, Request)}, - erlang:element(7, Request), - erlang:element(8, Request), - erlang:element(9, Request), - none}. - --spec from_uri(gleam@uri:uri()) -> {ok, request(binary())} | {error, nil}. -from_uri(Uri) -> - gleam@result:then( - begin - _pipe = erlang:element(2, Uri), - _pipe@1 = gleam@option:unwrap(_pipe, <<""/utf8>>), - gleam@http:scheme_from_string(_pipe@1) - end, - fun(Scheme) -> - gleam@result:then( - begin - _pipe@2 = erlang:element(4, Uri), - gleam@option:to_result(_pipe@2, nil) - end, - fun(Host) -> - Req = {request, - get, - [], - <<""/utf8>>, - Scheme, - Host, - erlang:element(5, Uri), - erlang:element(6, Uri), - erlang:element(7, Uri)}, - {ok, Req} - end - ) - end - ). - --spec get_header(request(any()), binary()) -> {ok, binary()} | {error, nil}. -get_header(Request, Key) -> - gleam@list:key_find(erlang:element(3, Request), gleam@string:lowercase(Key)). - --spec set_header(request(FBV), binary(), binary()) -> request(FBV). -set_header(Request, Key, Value) -> - Headers = gleam@list:key_set( - erlang:element(3, Request), - gleam@string:lowercase(Key), - Value - ), - erlang:setelement(3, Request, Headers). - --spec prepend_header(request(FBY), binary(), binary()) -> request(FBY). -prepend_header(Request, Key, Value) -> - Headers = [{gleam@string:lowercase(Key), Value} | - erlang:element(3, Request)], - erlang:setelement(3, Request, Headers). - --spec set_body(request(any()), FCD) -> request(FCD). -set_body(Req, Body) -> - {request, Method, Headers, _, Scheme, Host, Port, Path, Query} = Req, - {request, Method, Headers, Body, Scheme, Host, Port, Path, Query}. - --spec map(request(FCF), fun((FCF) -> FCH)) -> request(FCH). -map(Request, Transform) -> - _pipe = erlang:element(4, Request), - _pipe@1 = Transform(_pipe), - set_body(Request, _pipe@1). - --spec path_segments(request(any())) -> list(binary()). -path_segments(Request) -> - _pipe = erlang:element(8, Request), - gleam@uri:path_segments(_pipe). - --spec get_query(request(any())) -> {ok, list({binary(), binary()})} | - {error, nil}. -get_query(Request) -> - case erlang:element(9, Request) of - {some, Query_string} -> - gleam@uri:parse_query(Query_string); - - none -> - {ok, []} - end. - --spec set_query(request(FCR), list({binary(), binary()})) -> request(FCR). -set_query(Req, Query) -> - Pair = fun(T) -> - gleam@string_builder:from_strings( - [erlang:element(1, T), <<"="/utf8>>, erlang:element(2, T)] - ) - end, - Query@1 = begin - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, Pair), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - _pipe@4 = gleam@string_builder:to_string(_pipe@3), - {some, _pipe@4} - end, - erlang:setelement(9, Req, Query@1). - --spec set_method(request(FCV), gleam@http:method()) -> request(FCV). -set_method(Req, Method) -> - erlang:setelement(2, Req, Method). - --spec new() -> request(binary()). -new() -> - {request, - get, - [], - <<""/utf8>>, - https, - <<"localhost"/utf8>>, - none, - <<""/utf8>>, - none}. - --spec to(binary()) -> {ok, request(binary())} | {error, nil}. -to(Url) -> - _pipe = Url, - _pipe@1 = gleam@uri:parse(_pipe), - gleam@result:then(_pipe@1, fun from_uri/1). - --spec set_scheme(request(FDC), gleam@http:scheme()) -> request(FDC). -set_scheme(Req, Scheme) -> - erlang:setelement(5, Req, Scheme). - --spec set_host(request(FDF), binary()) -> request(FDF). -set_host(Req, Host) -> - erlang:setelement(6, Req, Host). - --spec set_port(request(FDI), integer()) -> request(FDI). -set_port(Req, Port) -> - erlang:setelement(7, Req, {some, Port}). - --spec set_path(request(FDL), binary()) -> request(FDL). -set_path(Req, Path) -> - erlang:setelement(8, Req, Path). - --spec set_cookie(request(FDO), binary(), binary()) -> request(FDO). -set_cookie(Req, Name, Value) -> - New_cookie_string = gleam@string:join([Name, Value], <<"="/utf8>>), - {Cookies_string@2, Headers@1} = case gleam@list:key_pop( - erlang:element(3, Req), - <<"cookie"/utf8>> - ) of - {ok, {Cookies_string, Headers}} -> - Cookies_string@1 = gleam@string:join( - [Cookies_string, New_cookie_string], - <<"; "/utf8>> - ), - {Cookies_string@1, Headers}; - - {error, nil} -> - {New_cookie_string, erlang:element(3, Req)} - end, - erlang:setelement( - 3, - Req, - [{<<"cookie"/utf8>>, Cookies_string@2} | Headers@1] - ). - --spec get_cookies(request(any())) -> list({binary(), binary()}). -get_cookies(Req) -> - {request, _, Headers, _, _, _, _, _, _} = Req, - _pipe = Headers, - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Header) -> - {Name, Value} = Header, - case Name of - <<"cookie"/utf8>> -> - {ok, gleam@http@cookie:parse(Value)}; - - _ -> - {error, nil} - end - end - ), - gleam@list:flatten(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl deleted file mode 100644 index 1769c814143..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@response.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@http@response). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, get_header/2, set_header/3, prepend_header/3, set_body/2, try_map/2, map/2, redirect/1, get_cookies/1, set_cookie/4, expire_cookie/3]). --export_type([response/1]). - --type response(FIP) :: {response, integer(), list({binary(), binary()}), FIP}. - --spec new(integer()) -> response(binary()). -new(Status) -> - {response, Status, [], <<""/utf8>>}. - --spec get_header(response(any()), binary()) -> {ok, binary()} | {error, nil}. -get_header(Response, Key) -> - gleam@list:key_find( - erlang:element(3, Response), - gleam@string:lowercase(Key) - ). - --spec set_header(response(FJE), binary(), binary()) -> response(FJE). -set_header(Response, Key, Value) -> - Headers = gleam@list:key_set( - erlang:element(3, Response), - Key, - gleam@string:lowercase(Value) - ), - erlang:setelement(3, Response, Headers). - --spec prepend_header(response(FJH), binary(), binary()) -> response(FJH). -prepend_header(Response, Key, Value) -> - Headers = [{gleam@string:lowercase(Key), Value} | - erlang:element(3, Response)], - erlang:setelement(3, Response, Headers). - --spec set_body(response(any()), FJM) -> response(FJM). -set_body(Response, Body) -> - {response, Status, Headers, _} = Response, - {response, Status, Headers, Body}. - --spec try_map(response(FIQ), fun((FIQ) -> {ok, FIS} | {error, FIT})) -> {ok, - response(FIS)} | - {error, FIT}. -try_map(Response, Transform) -> - gleam@result:then( - Transform(erlang:element(4, Response)), - fun(Body) -> {ok, set_body(Response, Body)} end - ). - --spec map(response(FJO), fun((FJO) -> FJQ)) -> response(FJQ). -map(Response, Transform) -> - _pipe = erlang:element(4, Response), - _pipe@1 = Transform(_pipe), - set_body(Response, _pipe@1). - --spec redirect(binary()) -> response(binary()). -redirect(Uri) -> - {response, - 303, - [{<<"location"/utf8>>, Uri}], - gleam@string:append(<<"You are being redirected to "/utf8>>, Uri)}. - --spec get_cookies(response(any())) -> list({binary(), binary()}). -get_cookies(Resp) -> - {response, _, Headers, _} = Resp, - _pipe = Headers, - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Header) -> - {Name, Value} = Header, - case Name of - <<"set-cookie"/utf8>> -> - {ok, gleam@http@cookie:parse(Value)}; - - _ -> - {error, nil} - end - end - ), - gleam@list:flatten(_pipe@1). - --spec set_cookie( - response(FJV), - binary(), - binary(), - gleam@http@cookie:attributes() -) -> response(FJV). -set_cookie(Response, Name, Value, Attributes) -> - prepend_header( - Response, - <<"set-cookie"/utf8>>, - gleam@http@cookie:set_header(Name, Value, Attributes) - ). - --spec expire_cookie(response(FJY), binary(), gleam@http@cookie:attributes()) -> response(FJY). -expire_cookie(Response, Name, Attributes) -> - Attrs = erlang:setelement(2, Attributes, {some, 0}), - set_cookie(Response, Name, <<""/utf8>>, Attrs). diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl deleted file mode 100644 index bb7ef2ef6a7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam@http@service.erl +++ /dev/null @@ -1,82 +0,0 @@ --module(gleam@http@service). --compile([no_auto_import, nowarn_unused_vars]). - --export([map_response_body/2, prepend_response_header/3, method_override/1]). - --spec map_response_body( - fun((gleam@http@request:request(FMN)) -> gleam@http@response:response(FMO)), - fun((FMO) -> FMR) -) -> fun((gleam@http@request:request(FMN)) -> gleam@http@response:response(FMR)). -map_response_body(Service, Mapper) -> - fun(Req) -> _pipe = Req, - _pipe@1 = Service(_pipe), - gleam@http@response:map(_pipe@1, Mapper) end. - --spec prepend_response_header( - fun((gleam@http@request:request(FMU)) -> gleam@http@response:response(FMV)), - binary(), - binary() -) -> fun((gleam@http@request:request(FMU)) -> gleam@http@response:response(FMV)). -prepend_response_header(Service, Key, Value) -> - fun(Req) -> _pipe = Req, - _pipe@1 = Service(_pipe), - gleam@http@response:prepend_header(_pipe@1, Key, Value) end. - --spec ensure_post(gleam@http@request:request(FNA)) -> {ok, - gleam@http@request:request(FNA)} | - {error, nil}. -ensure_post(Req) -> - case erlang:element(2, Req) of - post -> - {ok, Req}; - - _ -> - {error, nil} - end. - --spec get_override_method(gleam@http@request:request(any())) -> {ok, - gleam@http:method()} | - {error, nil}. -get_override_method(Request) -> - gleam@result:then( - gleam@http@request:get_query(Request), - fun(Query_params) -> - gleam@result:then( - gleam@list:key_find(Query_params, <<"_method"/utf8>>), - fun(Method) -> - gleam@result:then( - gleam@http:parse_method(Method), - fun(Method@1) -> case Method@1 of - put -> - {ok, Method@1}; - - patch -> - {ok, Method@1}; - - delete -> - {ok, Method@1}; - - _ -> - {error, nil} - end end - ) - end - ) - end - ). - --spec method_override( - fun((gleam@http@request:request(FNH)) -> gleam@http@response:response(FNI)) -) -> fun((gleam@http@request:request(FNH)) -> gleam@http@response:response(FNI)). -method_override(Service) -> - fun(Request) -> _pipe = Request, - _pipe@1 = ensure_post(_pipe), - _pipe@2 = gleam@result:then(_pipe@1, fun get_override_method/1), - _pipe@3 = gleam@result:map( - _pipe@2, - fun(_capture) -> - gleam@http@request:set_method(Request, _capture) - end - ), - _pipe@4 = gleam@result:unwrap(_pipe@3, Request), - Service(_pipe@4) end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src deleted file mode 100644 index 8d43953c74e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http.app.src +++ /dev/null @@ -1,12 +0,0 @@ -{application, gleam_http, [ - {vsn, "3.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Types and functions for Gleam HTTP clients and servers"}, - {modules, [gleam@http, - gleam@http@cookie, - gleam@http@request, - gleam@http@response, - gleam@http@service]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl deleted file mode 100644 index bb499bb57fd..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.erl +++ /dev/null @@ -1,88 +0,0 @@ --module(gleam_http_native). --export([decode_method/1]). - -decode_method(Term) -> - case Term of - "connect" -> {ok, connect}; - "delete" -> {ok, delete}; - "get" -> {ok, get}; - "head" -> {ok, head}; - "options" -> {ok, options}; - "patch" -> {ok, patch}; - "post" -> {ok, post}; - "put" -> {ok, put}; - "trace" -> {ok, trace}; - "CONNECT" -> {ok, connect}; - "DELETE" -> {ok, delete}; - "GET" -> {ok, get}; - "HEAD" -> {ok, head}; - "OPTIONS" -> {ok, options}; - "PATCH" -> {ok, patch}; - "POST" -> {ok, post}; - "PUT" -> {ok, put}; - "TRACE" -> {ok, trace}; - "Connect" -> {ok, connect}; - "Delete" -> {ok, delete}; - "Get" -> {ok, get}; - "Head" -> {ok, head}; - "Options" -> {ok, options}; - "Patch" -> {ok, patch}; - "Post" -> {ok, post}; - "Put" -> {ok, put}; - "Trace" -> {ok, trace}; - 'connect' -> {ok, connect}; - 'delete' -> {ok, delete}; - 'get' -> {ok, get}; - 'head' -> {ok, head}; - 'options' -> {ok, options}; - 'patch' -> {ok, patch}; - 'post' -> {ok, post}; - 'put' -> {ok, put}; - 'trace' -> {ok, trace}; - 'CONNECT' -> {ok, connect}; - 'DELETE' -> {ok, delete}; - 'GET' -> {ok, get}; - 'HEAD' -> {ok, head}; - 'OPTIONS' -> {ok, options}; - 'PATCH' -> {ok, patch}; - 'POST' -> {ok, post}; - 'PUT' -> {ok, put}; - 'TRACE' -> {ok, trace}; - 'Connect' -> {ok, connect}; - 'Delete' -> {ok, delete}; - 'Get' -> {ok, get}; - 'Head' -> {ok, head}; - 'Options' -> {ok, options}; - 'Patch' -> {ok, patch}; - 'Post' -> {ok, post}; - 'Put' -> {ok, put}; - 'Trace' -> {ok, trace}; - <<"connect">> -> {ok, connect}; - <<"delete">> -> {ok, delete}; - <<"get">> -> {ok, get}; - <<"head">> -> {ok, head}; - <<"options">> -> {ok, options}; - <<"patch">> -> {ok, patch}; - <<"post">> -> {ok, post}; - <<"put">> -> {ok, put}; - <<"trace">> -> {ok, trace}; - <<"CONNECT">> -> {ok, connect}; - <<"DELETE">> -> {ok, delete}; - <<"GET">> -> {ok, get}; - <<"HEAD">> -> {ok, head}; - <<"OPTIONS">> -> {ok, options}; - <<"PATCH">> -> {ok, patch}; - <<"POST">> -> {ok, post}; - <<"PUT">> -> {ok, put}; - <<"TRACE">> -> {ok, trace}; - <<"Connect">> -> {ok, connect}; - <<"Delete">> -> {ok, delete}; - <<"Get">> -> {ok, get}; - <<"Head">> -> {ok, head}; - <<"Options">> -> {ok, options}; - <<"Patch">> -> {ok, patch}; - <<"Post">> -> {ok, post}; - <<"Put">> -> {ok, put}; - <<"Trace">> -> {ok, trace}; - _ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs b/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs deleted file mode 100644 index c871a8b9514..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_http/src/gleam_http_native.mjs +++ /dev/null @@ -1,38 +0,0 @@ -import { Ok, Error } from "./gleam.mjs"; -import { - Get, - Post, - Head, - Put, - Delete, - Trace, - Connect, - Options, - Patch, -} from "./gleam/http.mjs"; - -export function decode_method(value) { - try { - switch (value.toLowerCase()) { - case "get": - return new Ok(new Get()); - case "post": - return new Ok(new Post()); - case "head": - return new Ok(new Head()); - case "put": - return new Ok(new Put()); - case "delete": - return new Ok(new Delete()); - case "trace": - return new Ok(new Trace()); - case "connect": - return new Ok(new Connect()); - case "options": - return new Ok(new Options()); - case "patch": - return new Ok(new Patch()); - } - } catch {} - return new Error(undefined); -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/LICENCE b/test-community-packages-javascript/build/packages/gleam_otp/LICENCE deleted file mode 100644 index 619ec77e6e1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_otp/README.md b/test-community-packages-javascript/build/packages/gleam_otp/README.md deleted file mode 100644 index 3c313a1c8c9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Gleam OTP - -<a href="https://github.com/gleam-lang/otp/releases"><img src="https://img.shields.io/github/release/gleam-lang/otp" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/otp/workflows/test/badge.svg?branch=main) - -A Gleam library for building fault tolerant multi-core programs using the -actor model. It is compatible with Erlang's OTP framework. - -This library is experimental and will likely have many breaking changes in the -future! - -Gleam’s actor system is built with a few primary goals: - -- Full type safety of actors and messages. -- Be compatible with Erlang’s OTP actor framework. -- Provide fault tolerance and self-healing through supervisors. -- Have equivalent performance to Erlang’s OTP. - -This library documents its abstractions and functionality, but you may also wish -to read the documentation or other material on Erlang’s OTP framework to get a -fuller understanding of OTP, the problems it solves, and and the motivations for -its design. - -## Usage - -Add this library to your Gleam project. - -```shell -gleam add gleam_otp -``` - -## Actor hierarchy - -This library provides several different types of actor that can be used in -Gleam programs. - -### Process - -The process is the lowest level building block of OTP, all other actors are -built on top of processes either directly or indirectly. Typically this -abstraction would be not be used very often in Gleam applications, favour -other actor types that provide more functionality. - -Gleam's process module is defined in the `gleam_erlang` library. - -[[Documentation]](https://hexdocs.pm/gleam_erlang/gleam/erlang/process.html) - -### Actor - -The `actor` is the most commonly used process type in Gleam and serves as a good -building block for other abstractions. Like Erlang's `gen_server` it handles -OTP's system messages automatically to enable OTP's debugging and tracing -functionality. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/actor.html) - -### Task - -A task is a kind of process that performs a single task and then shuts down. -Commonly tasks are used to convert sequential code into concurrent code by -performing computation in another process. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/task.html) - -### Supervisor - -Supervisors is a process that starts and then supervises a group of processes, -restarting them if they crash. Supervisors can start other supervisors, -resulting in a hierarchical process structure called a supervision tree, -providing fault tolerance to a Gleam application. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/supervisor.html) - -## Limitations and known issues - -This library is experimental there are some limitations that not yet been resolved. - -- There is no support for named processes. They are untyped global mutable - variables which may be uninitialized, more research is needed to find a - suitable type safe alternative. -- There are relatively few actor abstractions provided by this library. More - will be added in the future. -- Actors do not yet support all OTP system messages. Unsupported messages are - dropped. -- Supervisors do not yet support different shutdown periods per child. In - practice this means that children that are supervisors do not get an - unlimited amount of time to shut down, as is expected in Erlang or Elixir. -- This library has not seen much testing compared to the Erlang OTP - libraries, both in terms of unit tests and real world testing in - applications. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml b/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml deleted file mode 100644 index 849e41ed186..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleam_otp" -version = "0.5.3" -licences = ["Apache-2.0"] -description = "Fault tolerant multicore Gleam programs with OTP" - -repository = { type = "github", user = "gleam-lang", repo = "otp" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.19" -gleam_erlang = "~> 0.2" - -[dev-dependencies] -gleeunit = "~> 0.5" diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl deleted file mode 100644 index 75faa95149f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ready, {state :: any(), selector :: gleam@erlang@process:selector(any())}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl deleted file mode 100644 index 05f87d87d7b..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(spec, { - init :: fun(() -> gleam@otp@actor:init_result(any(), any())), - init_timeout :: integer(), - loop :: fun((any(), any()) -> gleam@otp@actor:next(any())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl deleted file mode 100644 index 3ed0b0122d4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(intensity_tracker, { - limit :: integer(), - period :: integer(), - events :: list(integer()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl deleted file mode 100644 index 7afd07f0319..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(child_spec, { - start :: fun((any()) -> {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()}), - returning :: fun((any(), gleam@erlang@process:subject(any())) -> any()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl deleted file mode 100644 index b10bd9fa3f7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(spec, { - argument :: any(), - max_frequency :: integer(), - frequency_period :: integer(), - init :: fun((gleam@otp@supervisor:children(any())) -> gleam@otp@supervisor:children(any())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl deleted file mode 100644 index de1c1ac340e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(status_info, { - module :: gleam@erlang@atom:atom_(), - parent :: gleam@erlang@process:pid_(), - mode :: gleam@otp@system:mode(), - debug_state :: gleam@otp@system:debug_state(), - state :: gleam@dynamic:dynamic() -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl deleted file mode 100644 index 8d84d3fc503..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl +++ /dev/null @@ -1 +0,0 @@ --record(exit, {reason :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl b/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl deleted file mode 100644 index 959bea8e9b9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(task, { - owner :: gleam@erlang@process:pid_(), - pid :: gleam@erlang@process:pid_(), - monitor :: gleam@erlang@process:process_monitor(), - selector :: gleam@erlang@process:selector(gleam@otp@task:message(any())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam deleted file mode 100644 index 4a4ca5ed712..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/actor.gleam +++ /dev/null @@ -1,473 +0,0 @@ -//// This module provides the _Actor_ abstraction, one of the most common -//// building blocks of Gleam OTP programs. -//// -//// An Actor is a process like any other BEAM process and can be be used to hold -//// state, execute code, and communicate with other processes by sending and -//// receiving messages. The advantage of using the actor abstraction over a bare -//// process is that it provides a single interface for commonly needed -//// functionality, including support for the [tracing and debugging -//// features in OTP](erlang-sys). -//// -//// Gleam's Actor is similar to Erlang's `gen_server` and Elixir's `GenServer` -//// but differs in that it offers a fully typed interface. This different API is -//// why Gleam uses the name Actor rather than some variation of generic-server. -//// -//// [erlang-sys]: https://www.erlang.org/doc/man/sys.html -//// -//// ## Example -//// -//// An Actor can be used to create a client-server interaction between an Actor -//// (the server) and other processes (the clients). In this example we have an -//// Actor that works as a stack, allowing clients to push and pop elements. -//// -//// ```gleam -//// pub fn main() { -//// // Start the actor with initial state of an empty list, and the -//// // `handle_message` callback function (defined below). -//// // We assert that it starts successfully. -//// // -//// // In real-world Gleam OTP programs we would likely write a wrapper functions -//// // called `start`, `push` `pop`, `shutdown` to start and interact with the -//// // Actor. We are not doing that here for the sake of showing how the Actor -//// // API works. -//// let assert Ok(actor) = actor.start([], handle_message) -//// -//// // We can send a message to the actor to push elements onto the stack. -//// process.send(actor, Push("Joe")) -//// process.send(actor, Push("Mike")) -//// process.send(actor, Push("Robert")) -//// -//// // The `Push` message expects no response, these messages are sent purely for -//// // the side effect of mutating the state held by the actor. -//// // -//// // We can also send the `Pop` message to take a value off of the actor's -//// // stack. This message expects a response, so we use `process.call` to send a -//// // message and wait until a reply is received. -//// // -//// // In this instance we are giving the actor 10 milliseconds to reply, if the -//// // `call` function doesn't get a reply within this time it will panic and -//// // crash the client process. -//// let assert Ok("Robert") = process.call(actor, Pop, 10) -//// let assert Ok("Mike") = process.call(actor, Pop, 10) -//// let assert Ok("Joe") = process.call(actor, Pop, 10) -//// -//// // The stack is now empty, so if we pop again the actor replies with an error. -//// let assert Error(Nil) = process.call(actor, Pop, 10) -//// -//// // Lastly, we can send a message to the actor asking it to shut down. -//// process.send(actor, Shutdown) -//// } -//// ``` -//// -//// Here is the code that is used to implement this actor: -//// -//// ```gleam -//// // First step of implementing the stack Actor is to define the message type that -//// // it can receive. -//// // -//// // The type of the elements in the stack is no fixed so a type parameter is used -//// // for it instead of a concrete type such as `String` or `Int`. -//// pub type Message(element) { -//// // The `Shutdown` message is used to tell the actor to stop. -//// // It is the simplest message type, it contains no data. -//// Shutdown -//// -//// // The `Push` message is used to add a new element to the stack. -//// // It contains the item to add, the type of which is the `element` -//// // parameterised type. -//// Push(push: element) -//// -//// // The `Pop` message is used to remove an element from the stack. -//// // It contains a `Subject`, which is used to send the response back to the -//// // message sender. In this case the reply is of type `Result(element, Nil)`. -//// Pop(reply_with: Subject(Result(element, Nil))) -//// } -//// -//// // The last part is to implement the `handle_message` callback function. -//// // -//// // This function is called by the Actor each for each message it receives. -//// // Actor is single threaded only does one thing at a time, so it handles -//// // messages sequentially and one at a time, in the order they are received. -//// // -//// // The function takes the message and the current state, and returns a data -//// // structure that indicates what to do next, along with the new state. -//// fn handle_message(message: Message(e), stack: List(e)) -> actor.Next(List(e)) { -//// case message { -//// // For the `Shutdown` message we return the `actor.Stop` value, which causes -//// // the actor to discard any remaining messages and stop. -//// Shutdown -> actor.Stop(process.Normal) -//// -//// // For the `Push` message we add the new element to the stack and return -//// // `actor.Continue` with this new stack, causing the actor to process any -//// // queued messages or wait for more. -//// Push(value) -> { -//// let new_state = [value, ..stack] -//// actor.Continue(new_state) -//// } -//// -//// // For the `Pop` message we attempt to remove an element from the stack, -//// // sending it or an error back to the caller, before continuing. -//// Pop(client) -> -//// case stack { -//// [] -> { -//// // When the stack is empty we can't pop an element, so we send an -//// // error back. -//// process.send(client, Error(Nil)) -//// actor.Continue([]) -//// } -//// -//// [first, ..rest] -> { -//// // Otherwise we send the first element back and use the remaining -//// // elements as the new state. -//// process.send(client, Ok(first)) -//// actor.Continue(rest) -//// } -//// } -//// } -//// } -//// ``` - -import gleam/erlang/process.{Abnormal, ExitReason, Pid, Selector, Subject} -import gleam/erlang/charlist.{Charlist} -import gleam/otp/system.{ - DebugState, GetState, GetStatus, Mode, Resume, Running, StatusInfo, Suspend, - Suspended, SystemMessage, -} -import gleam/string -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom - -type Message(message) { - /// A regular message excepted by the process - Message(message) - - /// An OTP system message, for debugging or maintenance - System(SystemMessage) - - /// An unexpected message - Unexpected(Dynamic) -} - -/// The type used to indicate what to do after handling a message. -/// -pub type Next(state) { - /// Continue handling messages. - /// - Continue(state) - - /// Stop handling messages and shut down. - /// - Stop(ExitReason) -} - -/// The type used to indicate whether an actor has started successfully or not. -/// -pub type InitResult(state, message) { - /// The actor has successfully initialised. The actor can start handling - /// messages and actor's channel sender can be returned to the parent - /// process. - /// - Ready(state: state, selector: Selector(message)) - - /// The actor has failed to initialise. The actor shuts down and an error is - /// returned to the parent process. - /// - Failed(String) -} - -type Self(state, msg) { - Self( - mode: Mode, - parent: Pid, - state: state, - selector: Selector(Message(msg)), - debug_state: DebugState, - message_handler: fn(msg, state) -> Next(state), - ) -} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an actor. -/// -/// If you do not need to configure the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub type Spec(state, msg) { - Spec( - /// The initialisation functionality for the actor. This function is called - /// just after the actor starts but before the channel sender is returned - /// to the parent. - /// - /// This function is used to ensure that any required data or state is - /// correct. If this function returns an error it means that the actor has - /// failed to start and an error is returned to the parent. - /// - init: fn() -> InitResult(state, msg), - /// How many milliseconds the `init` function has to return before it is - /// considered to have taken too long and failed. - /// - init_timeout: Int, - /// This function is called to handle each message that the actor receives. - /// - loop: fn(msg, state) -> Next(state), - ) -} - -// TODO: Check needed functionality here to be OTP compatible -fn exit_process(reason: ExitReason) -> ExitReason { - // TODO - reason -} - -fn receive_message(self: Self(state, msg)) -> Message(msg) { - let selector = case self.mode { - // When suspended we only respond to system messages - Suspended -> - process.new_selector() - |> selecting_system_messages - - // When running we respond to all messages - Running -> - // We add the handler for unexpected messages first so that the user - // supplied selector can override it if desired - process.new_selector() - |> process.selecting_anything(Unexpected) - |> process.merge_selector(self.selector) - |> selecting_system_messages - } - - process.select_forever(selector) -} - -fn selecting_system_messages( - selector: Selector(Message(msg)), -) -> Selector(Message(msg)) { - selector - |> process.selecting_record3( - atom.create_from_string("system"), - convert_system_message, - ) -} - -external fn convert_system_message(Dynamic, Dynamic) -> Message(msg) = - "gleam_otp_external" "convert_system_message" - -fn process_status_info(self: Self(state, msg)) -> StatusInfo { - StatusInfo( - module: atom.create_from_string("gleam@otp@actor"), - parent: self.parent, - mode: self.mode, - debug_state: self.debug_state, - state: dynamic.from(self.state), - ) -} - -fn loop(self: Self(state, msg)) -> ExitReason { - case receive_message(self) { - System(system) -> - case system { - GetState(callback) -> { - callback(dynamic.from(self.state)) - loop(self) - } - Resume(callback) -> { - callback() - loop(Self(..self, mode: Running)) - } - Suspend(callback) -> { - callback() - loop(Self(..self, mode: Suspended)) - } - GetStatus(callback) -> { - callback(process_status_info(self)) - loop(self) - } - } - - Unexpected(message) -> { - log_warning( - charlist.from_string("Actor discarding unexpected message: ~s"), - [charlist.from_string(string.inspect(message))], - ) - loop(self) - } - - Message(msg) -> - case self.message_handler(msg, self.state) { - Stop(reason) -> exit_process(reason) - Continue(state) -> loop(Self(..self, state: state)) - } - } -} - -// TODO: replace this when we have Gleam bindings to the logger -external fn log_warning(Charlist, List(Charlist)) -> Nil = - "logger" "warning" - -fn initialise_actor( - spec: Spec(state, msg), - ack: Subject(Result(Subject(msg), ExitReason)), -) { - let subject = process.new_subject() - case spec.init() { - Ready(state, selector) -> { - let selector = - process.new_selector() - |> process.selecting(subject, Message) - |> process.merge_selector(process.map_selector(selector, Message)) - // Signal to parent that the process has initialised successfully - process.send(ack, Ok(subject)) - // Start message receive loop - let self = - Self( - state: state, - parent: process.subject_owner(ack), - selector: selector, - message_handler: spec.loop, - debug_state: system.debug_state([]), - mode: Running, - ) - loop(self) - } - - Failed(reason) -> { - process.send(ack, Error(Abnormal(reason))) - exit_process(Abnormal(reason)) - } - } -} - -pub type StartError { - InitTimeout - InitFailed(ExitReason) - InitCrashed(Dynamic) -} - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - Result(Subject(msg), StartError) - -/// An Erlang supervisor compatible process start result. -/// -/// If you wish to convert this into a `StartResult` compatible with Gleam -/// supervisors see the `from_erlang_start_result` and `wrap_erlang_starter` -/// functions. -/// -pub type ErlangStartResult = - Result(Pid, Dynamic) - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - case res { - Ok(x) -> Ok(process.subject_owner(x)) - Error(x) -> Error(dynamic.from(x)) - } -} - -type StartInitMessage(msg) { - Ack(Result(Subject(msg), ExitReason)) - Mon(process.ProcessDown) -} - -// TODO: test init_timeout. Currently if we test it eunit prints an error from -// the process death. How do we avoid this? -// -/// Start an actor from a given specification. If the actor's `init` function -/// returns an error or does not return within `init_timeout` then an error is -/// returned. -/// -/// If you do not need to specify the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub fn start_spec(spec: Spec(state, msg)) -> Result(Subject(msg), StartError) { - let ack_subject = process.new_subject() - - let child = - process.start( - linked: True, - running: fn() { initialise_actor(spec, ack_subject) }, - ) - - let monitor = process.monitor_process(child) - let selector = - process.new_selector() - |> process.selecting(ack_subject, Ack) - |> process.selecting_process_down(monitor, Mon) - - let result = case process.select(selector, spec.init_timeout) { - // Child started OK - Ok(Ack(Ok(channel))) -> Ok(channel) - - // Child initialiser returned an error - Ok(Ack(Error(reason))) -> Error(InitFailed(reason)) - - // Child went down while initialising - Ok(Mon(down)) -> Error(InitCrashed(down.reason)) - - // Child did not finish initialising in time - Error(Nil) -> { - process.kill(child) - Error(InitTimeout) - } - } - - // Remove the monitor used for the starting of the actor as to avoid an extra - // message arriving at the parent if the child dies later. - process.demonitor_process(monitor) - - result -} - -/// Start an actor with a given initial state and message handling loop -/// function. -/// -/// This function returns a `Result` but it will always be `Ok` so it is safe -/// to use with `assert` if you are not starting this actor as part of a -/// supervision tree. -/// -/// If you wish to configure the initialisation behaviour of a new actor see -/// the `Spec` record and the `start_spec` function. -/// -pub fn start( - state: state, - loop: fn(msg, state) -> Next(state), -) -> Result(Subject(msg), StartError) { - start_spec(Spec( - init: fn() { Ready(state, process.new_selector()) }, - loop: loop, - init_timeout: 5000, - )) -} - -/// Send a message over a given channel. -/// -/// This is a re-export of `process.send`, for the sake of convenience. -/// -pub fn send(subject: Subject(msg), msg: msg) -> Nil { - process.send(subject, msg) -} - -// TODO: test -/// Send a synchronous message and wait for a response from the receiving -/// process. -/// -/// If a reply is not received within the given timeout then the sender process -/// crashes. If you wish receive a `Result` rather than crashing see the -/// `process.try_call` function. -/// -/// This is a re-export of `process.call`, for the sake of convenience. -/// -pub fn call( - selector: Subject(message), - make_message: fn(Subject(reply)) -> message, - timeout: Int, -) -> reply { - process.call(selector, make_message, timeout) -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam deleted file mode 100644 index b53e1006325..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam +++ /dev/null @@ -1,46 +0,0 @@ -//// The intensity tracker is used to monitor how frequently an event happens, -//// erroring if it happens too many times within a period of time. - -import gleam/list - -// TODO: test -pub opaque type IntensityTracker { - IntensityTracker(limit: Int, period: Int, events: List(Int)) -} - -pub type TooIntense { - TooIntense -} - -pub fn new(limit limit: Int, period period: Int) -> IntensityTracker { - IntensityTracker(limit: limit, period: period, events: []) -} - -external fn monotonic_time(Int) -> Int = - "erlang" "monotonic_time" - -fn now_seconds() -> Int { - monotonic_time(1) -} - -pub fn trim_window(events: List(Int), now: Int, period: Int) -> List(Int) { - case events { - [] -> [] - [event, ..events] -> - case now >= event + period { - True -> [event, ..trim_window(events, now, period)] - False -> [] - } - } -} - -pub fn add_event( - tracker: IntensityTracker, -) -> Result(IntensityTracker, TooIntense) { - let now = now_seconds() - let events = trim_window([now, ..tracker.events], now, tracker.period) - case list.length(events) >= tracker.limit { - True -> Error(TooIntense) - False -> Ok(IntensityTracker(..tracker, events: events)) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam deleted file mode 100644 index 19c77fa6a58..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/node.gleam +++ /dev/null @@ -1 +0,0 @@ -pub external type Node diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam deleted file mode 100644 index c312494d733..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/port.gleam +++ /dev/null @@ -1,9 +0,0 @@ -/// Ports are how code running on the Erlang virtual machine interacts with -/// the outside world. Bytes of data can be sent to and read from ports, -/// providing a form of message passing to an external program or resource. -/// -/// For more information on ports see the [Erlang ports documentation][1]. -/// -/// [1]: https://erlang.org/doc/reference_manual/ports.html -/// -pub external type Port diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam deleted file mode 100644 index f710b05c155..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam +++ /dev/null @@ -1,403 +0,0 @@ -// TODO: specify amount of time permitted for shut-down -import gleam/result -import gleam/string -import gleam/option.{None, Option, Some} -import gleam/erlang/process.{Pid, Subject} -import gleam/otp/actor.{StartError} -import gleam/otp/intensity_tracker.{IntensityTracker} -import gleam/otp/node.{Node} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an supervisor. -/// -/// If you do not need to configure the behaviour of your supervisor consider -/// using the `start` function. -/// -pub type Spec(argument, return) { - Spec( - argument: argument, - max_frequency: Int, - frequency_period: Int, - init: fn(Children(argument)) -> Children(return), - ) -} - -/// This type represents the starting children of a supervisor within the -/// `init` function. -/// -pub opaque type Children(argument) { - Ready(Starter(argument)) - Failed(ChildStartError) -} - -/// This type contains all the information required to start a new child and -/// add it to the `Children`. -/// -/// This is typically created with the `worker` function. -/// -pub opaque type ChildSpec(msg, argument, returning) { - ChildSpec( - // TODO: merge this into one field - start: fn(argument) -> Result(Subject(msg), StartError), - returning: fn(argument, Subject(msg)) -> returning, - ) -} - -type ChildStartError { - ChildStartError(previous_pid: Option(Pid), error: StartError) -} - -pub opaque type Message { - Exit(process.ExitMessage) - RetryRestart(Pid) -} - -type Instruction { - StartAll - StartFrom(Pid) -} - -type State(a) { - State( - restarts: IntensityTracker, - starter: Starter(a), - retry_restarts: Subject(Pid), - ) -} - -type Starter(argument) { - Starter( - argument: argument, - exec: Option( - fn(Instruction) -> - Result(#(Starter(argument), Instruction), ChildStartError), - ), - ) -} - -type Child(argument) { - Child(pid: Pid, argument: argument) -} - -fn start_child( - child_spec: ChildSpec(msg, argument_in, argument_out), - argument: argument_in, -) -> Result(Child(argument_out), ChildStartError) { - use subject <- result.then( - child_spec.start(argument) - |> result.map_error(ChildStartError(None, _)), - ) - - Ok(Child( - pid: process.subject_owner(subject), - // Merge the new child's pid into the argument to produce the new argument - // used to start any remaining children. - argument: child_spec.returning(argument, subject), - )) -} - -// TODO: more sophsiticated stopping of processes. i.e. give supervisors -// more time to shut down. -fn shutdown_child(pid: Pid, _spec: ChildSpec(msg, arg_1, arg_2)) -> Nil { - process.send_exit(pid) -} - -fn perform_instruction_for_child( - argument: argument_in, - instruction: Instruction, - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Result(#(Child(argument_out), Instruction), ChildStartError) { - let current = child.pid - case instruction { - // This child is older than the StartFrom target, we don't need to - // restart it - StartFrom(target) if target != current -> Ok(#(child, instruction)) - - // This pid either is the cause of the problem, or we have the StartAll - // instruction. Either way it and its younger siblings need to be restarted. - _ -> { - shutdown_child(current, child_spec) - use child <- result.then(start_child(child_spec, argument)) - Ok(#(child, StartAll)) - } - } -} - -fn add_child_to_starter( - starter: Starter(argument_in), - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Starter(argument_out) { - let starter = fn(instruction) { - // Restart the older children. We use `try` to return early if the older - // children failed to start - use #(starter, instruction) <- result.then(case starter.exec { - Some(start) -> start(instruction) - None -> Ok(#(starter, instruction)) - }) - - // Perform the instruction, restarting the child as required - use #(child, instruction) <- result.then(perform_instruction_for_child( - starter.argument, - instruction, - child_spec, - child, - )) - - // Create a new starter for the next time the supervisor needs to restart - let starter = add_child_to_starter(starter, child_spec, child) - - Ok(#(starter, instruction)) - } - - Starter(exec: Some(starter), argument: child.argument) -} - -fn start_and_add_child( - state: Starter(argument_0), - child_spec: ChildSpec(msg, argument_0, argument_1), -) -> Children(argument_1) { - case start_child(child_spec, state.argument) { - Ok(child) -> Ready(add_child_to_starter(state, child_spec, child)) - Error(reason) -> Failed(reason) - } -} - -/// Add a child to the collection of children of the supervisor -/// -/// This function starts the child from the child spec. -/// -pub fn add( - children: Children(argument), - child_spec: ChildSpec(msg, argument, new_argument), -) -> Children(new_argument) { - case children { - // If one of the previous children has failed then we cannot continue - Failed(fail) -> Failed(fail) - - // If everything is OK so far then we can add the child - Ready(state) -> start_and_add_child(state, child_spec) - } -} - -// TODO: test -// TODO: unlimitd shut down duration -/// Prepare a new supervisor type child. -/// -/// If you wish to prepare a new non-supervisor type child see the `worker` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -/// Note: Gleam supervisors do not yet support different shutdown periods per -/// child so this function is currently identical in behaviour to `worker`. It is -/// recommended to use this function for supervisor children nevertheless so the -/// correct shut down behaviour is used in later releases of this library. -/// -pub fn supervisor( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -/// Prepare a new worker type child. -/// -/// If you wish to prepare a new supervisor type child see the `supervisor` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -pub fn worker( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -// TODO: test -/// As each child is added to a supervisors children a new argument is prepared -/// with which to start the next child. By default argument is the same as the -/// previous argument, but this function can be used to change it to something -/// else by passing a function that takes the previous argument and the sender -/// of the previous child. -/// -pub fn returning( - child: ChildSpec(msg, argument_a, argument_b), - updater: fn(argument_a, Subject(msg)) -> argument_c, -) -> ChildSpec(msg, argument_a, argument_c) { - ChildSpec(start: child.start, returning: updater) -} - -fn init( - spec: Spec(argument, return), -) -> actor.InitResult(State(return), Message) { - // Create a subject so that we can asynchronously retry restarting when we - // fail to bring an exited child - let retry = process.new_subject() - - // Trap exits so that we get a message when a child crashes - process.trap_exits(True) - - // Combine selectors - let selector = - process.new_selector() - |> process.selecting(retry, RetryRestart) - |> process.selecting_trapped_exits(Exit) - - // Start any children - let result = - Starter(argument: spec.argument, exec: None) - |> Ready - |> spec.init - - // Pass back up the result - case result { - Ready(starter) -> { - let restarts = - intensity_tracker.new( - limit: spec.max_frequency, - period: spec.frequency_period, - ) - let state = - State(starter: starter, restarts: restarts, retry_restarts: retry) - actor.Ready(state, selector) - } - - Failed(error) -> - actor.Failed(case error.error { - actor.InitTimeout -> "Child initialisation timed out" - actor.InitCrashed(reason) -> - string.append( - "Child crashed during initialisation: ", - string.inspect(reason), - ) - actor.InitFailed(reason) -> - string.append( - "Child failed to start during initialisation: ", - string.inspect(reason), - ) - }) - } -} - -type HandleExitError { - RestartFailed(pid: Pid, restarts: IntensityTracker) - TooManyRestarts -} - -fn handle_exit(pid: Pid, state: State(a)) -> actor.Next(State(a)) { - let outcome = { - // If we are handling an exit then we must have some children - let assert Some(start) = state.starter.exec - - // Check to see if there has been too many restarts in this period - use restarts <- result.then( - state.restarts - |> intensity_tracker.add_event - |> result.map_error(fn(_) { TooManyRestarts }), - ) - - // Restart the exited child and any following children - use #(starter, _) <- result.then( - start(StartFrom(pid)) - |> result.map_error(fn(e: ChildStartError) { - RestartFailed(option.unwrap(e.previous_pid, pid), restarts) - }), - ) - - Ok(State(..state, starter: starter, restarts: restarts)) - } - - case outcome { - Ok(state) -> actor.Continue(state) - Error(RestartFailed(failed_child, restarts)) -> { - // Asynchronously enqueue the restarting of this child again as we were - // unable to restart them this time. We do this asynchronously as we want - // to have a chance to handle any system messages that have come in. - process.send(state.retry_restarts, failed_child) - let state = State(..state, restarts: restarts) - actor.Continue(state) - } - Error(TooManyRestarts) -> - actor.Stop(process.Abnormal( - "Child processes restarted too many times within allowed period", - )) - } -} - -fn loop(message: Message, state: State(argument)) -> actor.Next(State(argument)) { - case message { - Exit(exit_message) -> handle_exit(exit_message.pid, state) - RetryRestart(pid) -> handle_exit(pid, state) - } -} - -/// Start a supervisor from a given specification. -/// -pub fn start_spec(spec: Spec(a, b)) -> Result(Subject(Message), StartError) { - actor.start_spec(actor.Spec( - init: fn() { init(spec) }, - loop: loop, - init_timeout: 60_000, - )) -} - -/// Start a supervisor from a given `init` function. -/// -/// If you wish to have more control over the configuration of the supervisor -/// see the `start_spec` function. -/// -pub fn start( - init: fn(Children(Nil)) -> Children(a), -) -> Result(Subject(Message), StartError) { - start_spec(Spec( - init: init, - argument: Nil, - max_frequency: 5, - frequency_period: 1, - )) -} - -/// A type used to describe the situation in which an Erlang based application -/// is starting. -/// -/// For more information see the [Erlang distributed application -/// documentation][1] and the Learn Your Some Erlang chapter on [distributed -/// applications][2]. -/// -/// [1]: https://erlang.org/doc/design_principles/distributed_applications.html -/// [2]: https://learnyousomeerlang.com/distributed-otp-applications -/// -pub type ApplicationStartMode { - Normal - Takeover(Node) - Failover(Node) -} - -pub external type ApplicationStop - -pub external fn application_stopped() -> ApplicationStop = - "gleam_otp_external" "application_stopped" - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - actor.StartResult(msg) - -/// An Erlang supervisor compatible process start result. -/// -pub type ErlangStartResult = - actor.ErlangStartResult - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - actor.to_erlang_start_result(res) -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam deleted file mode 100644 index 895c3409458..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/system.gleam +++ /dev/null @@ -1,89 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} - -pub type Mode { - Running - Suspended -} - -pub type DebugOption { - NoDebug -} - -pub external type DebugState - -pub external fn debug_state(List(DebugOption)) -> DebugState = - "sys" "debug_options" - -pub type StatusInfo { - StatusInfo( - module: Atom, - parent: Pid, - mode: Mode, - debug_state: DebugState, - state: Dynamic, - ) -} - -// TODO: document -// TODO: implement remaining messages -pub type SystemMessage { - // {replace_state, StateFn} - // {change_code, Mod, Vsn, Extra} - // {terminate, Reason} - // {debug, {log, Flag}} - // {debug, {trace, Flag}} - // {debug, {log_to_file, FileName}} - // {debug, {statistics, Flag}} - // {debug, no_debug} - // {debug, {install, {Func, FuncState}}} - // {debug, {install, {FuncId, Func, FuncState}}} - // {debug, {remove, FuncOrId}} - Resume(fn() -> Nil) - Suspend(fn() -> Nil) - GetState(fn(Dynamic) -> Nil) - GetStatus(fn(StatusInfo) -> Nil) -} - -external type DoNotLeak - -/// Get the state of a given OTP compatible process. This function is only -/// intended for debugging. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#get_state-1 -/// -pub external fn get_state(from: Pid) -> Dynamic = - "sys" "get_state" - -external fn erl_suspend(Pid) -> DoNotLeak = - "sys" "suspend" - -/// Request an OTP compatible process to suspend, causing it to only handle -/// system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#suspend-1 -/// -pub fn suspend(pid: Pid) -> Nil { - erl_suspend(pid) - Nil -} - -external fn erl_resume(from: Pid) -> DoNotLeak = - "sys" "resume" - -/// Request a suspended OTP compatible process to result, causing it to handle -/// all messages rather than only system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#resume-1 -/// -pub fn resume(pid: Pid) -> Nil { - erl_resume(pid) - Nil -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam deleted file mode 100644 index c9adc952f88..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam/otp/task.gleam +++ /dev/null @@ -1,151 +0,0 @@ -//// A task is a kind of process that performs a single task and then shuts -//// down. Commonly tasks are used to convert sequential code into concurrent -//// code by performing computation in another process. -//// -//// let task = task.async(fn() { do_some_work() }) -//// let value = do_some_other_work() -//// value + task.await(task, 100) -//// -//// Tasks spawned with async can be awaited on by their caller process (and -//// only their caller) as shown in the example above. They are implemented by -//// spawning a process that sends a message to the caller once the given -//// computation is performed. -//// -//// There are two important things to consider when using `async`: -//// -//// 1. If you are using async tasks, you must await a reply as they are always -//// sent. -//// -//// 2. async tasks link the caller and the spawned process. This means that, -//// if the caller crashes, the task will crash too and vice-versa. This is -//// on purpose: if the process meant to receive the result no longer -//// exists, there is no purpose in completing the computation. -//// -//// This module is inspired by Elixir's [Task module][1]. -//// -//// [1]: https://hexdocs.pm/elixir/master/Task.html -//// - -// TODO: await_many -import gleam/erlang/process.{Pid, ProcessMonitor, Selector} -import gleam/dynamic.{Dynamic} - -pub opaque type Task(value) { - Task( - owner: Pid, - pid: Pid, - monitor: ProcessMonitor, - selector: Selector(Message(value)), - ) -} - -// TODO: test -/// Spawn a task process that calls a given function in order to perform some -/// work. The result of this function is send back to the parent and can be -/// received using the `await` function. -/// -/// See the top level module documentation for more information on async/await. -/// -pub fn async(work: fn() -> value) -> Task(value) { - let owner = process.self() - let subject = process.new_subject() - let pid = - process.start(linked: True, running: fn() { process.send(subject, work()) }) - let monitor = process.monitor_process(pid) - let selector = - process.new_selector() - |> process.selecting_process_down(monitor, FromMonitor) - |> process.selecting(subject, FromSubject) - Task(owner: owner, pid: pid, monitor: monitor, selector: selector) -} - -pub type AwaitError { - Timeout - Exit(reason: Dynamic) -} - -// We can only wait on a task if we are the owner of it so crash if we are -// waiting on a task we don't own. -fn assert_owner(task: Task(a)) -> Nil { - let self = process.self() - case task.owner == self { - True -> Nil - False -> - process.send_abnormal_exit( - self, - "awaited on a task that does not belong to this process", - ) - } -} - -type Message(value) { - FromMonitor(process.ProcessDown) - FromSubject(value) -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then an error is returned. -/// -pub fn try_await(task: Task(value), timeout: Int) -> Result(value, AwaitError) { - assert_owner(task) - case process.select(task.selector, timeout) { - // The task process has sent back a value - Ok(FromSubject(x)) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) -> - Error(Exit(reason)) - - // The task process is alive but has not sent a value yet - Error(Nil) -> Error(Timeout) - } -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then this function crashes. -/// -pub fn await(task: Task(value), timeout: Int) -> value { - let assert Ok(value) = try_await(task, timeout) - value -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! This function does not return until there is a value to -/// receive. If a value is not received then the process will be stuck waiting -/// forever. -/// -pub fn try_await_forever(task: Task(value)) -> Result(value, AwaitError) { - assert_owner(task) - case process.select_forever(task.selector) { - // The task process has sent back a value - FromSubject(x) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - FromMonitor(process.ProcessDown(reason: reason, ..)) -> Error(Exit(reason)) - } -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! Like `try_await_forever`, this function does not return until there is a value to -/// receive. -/// -/// If the task process crashes then this function crashes. -/// -pub fn await_forever(task: Task(value)) -> value { - let assert Ok(value) = try_await_forever(task) - value -} diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl deleted file mode 100644 index 40e16f7a820..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@actor.erl +++ /dev/null @@ -1,233 +0,0 @@ --module(gleam@otp@actor). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_erlang_start_result/1, send/2, call/3, start_spec/1, start/2]). --export_type([message/1, next/1, init_result/2, self/2, spec/2, start_error/0, start_init_message/1]). - --type message(FIS) :: {message, FIS} | - {system, gleam@otp@system:system_message()} | - {unexpected, gleam@dynamic:dynamic()}. - --type next(FIT) :: {continue, FIT} | {stop, gleam@erlang@process:exit_reason()}. - --type init_result(FIU, FIV) :: {ready, FIU, gleam@erlang@process:selector(FIV)} | - {failed, binary()}. - --type self(FIW, FIX) :: {self, - gleam@otp@system:mode(), - gleam@erlang@process:pid_(), - FIW, - gleam@erlang@process:selector(message(FIX)), - gleam@otp@system:debug_state(), - fun((FIX, FIW) -> next(FIW))}. - --type spec(FIY, FIZ) :: {spec, - fun(() -> init_result(FIY, FIZ)), - integer(), - fun((FIZ, FIY) -> next(FIY))}. - --type start_error() :: init_timeout | - {init_failed, gleam@erlang@process:exit_reason()} | - {init_crashed, gleam@dynamic:dynamic()}. - --type start_init_message(FJA) :: {ack, - {ok, gleam@erlang@process:subject(FJA)} | - {error, gleam@erlang@process:exit_reason()}} | - {mon, gleam@erlang@process:process_down()}. - --spec exit_process(gleam@erlang@process:exit_reason()) -> gleam@erlang@process:exit_reason(). -exit_process(Reason) -> - Reason. - --spec process_status_info(self(any(), any())) -> gleam@otp@system:status_info(). -process_status_info(Self) -> - {status_info, - erlang:binary_to_atom(<<"gleam@otp@actor"/utf8>>), - erlang:element(3, Self), - erlang:element(2, Self), - erlang:element(6, Self), - gleam@dynamic:from(erlang:element(4, Self))}. - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | {error, start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic()}. -to_erlang_start_result(Res) -> - case Res of - {ok, X} -> - {ok, gleam@erlang@process:subject_owner(X)}; - - {error, X@1} -> - {error, gleam@dynamic:from(X@1)} - end. - --spec send(gleam@erlang@process:subject(FKX), FKX) -> nil. -send(Subject, Msg) -> - gleam@erlang@process:send(Subject, Msg). - --spec call( - gleam@erlang@process:subject(FKZ), - fun((gleam@erlang@process:subject(FLB)) -> FKZ), - integer() -) -> FLB. -call(Selector, Make_message, Timeout) -> - gleam@erlang@process:call(Selector, Make_message, Timeout). - --spec selecting_system_messages(gleam@erlang@process:selector(message(FJM))) -> gleam@erlang@process:selector(message(FJM)). -selecting_system_messages(Selector) -> - _pipe = Selector, - gleam@erlang@process:selecting_record3( - _pipe, - erlang:binary_to_atom(<<"system"/utf8>>), - fun gleam_otp_external:convert_system_message/2 - ). - --spec receive_message(self(any(), FJI)) -> message(FJI). -receive_message(Self) -> - Selector = case erlang:element(2, Self) of - suspended -> - _pipe = gleam_erlang_ffi:new_selector(), - selecting_system_messages(_pipe); - - running -> - _pipe@1 = gleam_erlang_ffi:new_selector(), - _pipe@2 = gleam@erlang@process:selecting_anything( - _pipe@1, - fun(Field@0) -> {unexpected, Field@0} end - ), - _pipe@3 = gleam_erlang_ffi:merge_selector( - _pipe@2, - erlang:element(5, Self) - ), - selecting_system_messages(_pipe@3) - end, - gleam_erlang_ffi:select(Selector). - --spec loop(self(any(), any())) -> gleam@erlang@process:exit_reason(). -loop(Self) -> - case receive_message(Self) of - {system, System} -> - case System of - {get_state, Callback} -> - Callback(gleam@dynamic:from(erlang:element(4, Self))), - loop(Self); - - {resume, Callback@1} -> - Callback@1(), - loop(erlang:setelement(2, Self, running)); - - {suspend, Callback@2} -> - Callback@2(), - loop(erlang:setelement(2, Self, suspended)); - - {get_status, Callback@3} -> - Callback@3(process_status_info(Self)), - loop(Self) - end; - - {unexpected, Message} -> - logger:warning( - unicode:characters_to_list( - <<"Actor discarding unexpected message: ~s"/utf8>> - ), - [unicode:characters_to_list(gleam@string:inspect(Message))] - ), - loop(Self); - - {message, Msg} -> - case (erlang:element(7, Self))(Msg, erlang:element(4, Self)) of - {stop, Reason} -> - exit_process(Reason); - - {continue, State} -> - loop(erlang:setelement(4, Self, State)) - end - end. - --spec initialise_actor( - spec(any(), FKA), - gleam@erlang@process:subject({ok, gleam@erlang@process:subject(FKA)} | - {error, gleam@erlang@process:exit_reason()}) -) -> gleam@erlang@process:exit_reason(). -initialise_actor(Spec, Ack) -> - Subject = gleam@erlang@process:new_subject(), - case (erlang:element(2, Spec))() of - {ready, State, Selector} -> - Selector@1 = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun(Field@0) -> {message, Field@0} end - ), - gleam_erlang_ffi:merge_selector( - _pipe@1, - gleam_erlang_ffi:map_selector( - Selector, - fun(Field@0) -> {message, Field@0} end - ) - ) - end, - gleam@erlang@process:send(Ack, {ok, Subject}), - Self = {self, - running, - gleam@erlang@process:subject_owner(Ack), - State, - Selector@1, - sys:debug_options([]), - erlang:element(4, Spec)}, - loop(Self); - - {failed, Reason} -> - gleam@erlang@process:send(Ack, {error, {abnormal, Reason}}), - exit_process({abnormal, Reason}) - end. - --spec start_spec(spec(any(), FKL)) -> {ok, gleam@erlang@process:subject(FKL)} | - {error, start_error()}. -start_spec(Spec) -> - Ack_subject = gleam@erlang@process:new_subject(), - Child = gleam@erlang@process:start( - fun() -> initialise_actor(Spec, Ack_subject) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Child), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Ack_subject, - fun(Field@0) -> {ack, Field@0} end - ), - gleam@erlang@process:selecting_process_down( - _pipe@1, - Monitor, - fun(Field@0) -> {mon, Field@0} end - ) - end, - Result = case gleam_erlang_ffi:select(Selector, erlang:element(3, Spec)) of - {ok, {ack, {ok, Channel}}} -> - {ok, Channel}; - - {ok, {ack, {error, Reason}}} -> - {error, {init_failed, Reason}}; - - {ok, {mon, Down}} -> - {error, {init_crashed, erlang:element(3, Down)}}; - - {error, nil} -> - gleam@erlang@process:kill(Child), - {error, init_timeout} - end, - gleam_erlang_ffi:demonitor(Monitor), - Result. - --spec start(FKR, fun((FKS, FKR) -> next(FKR))) -> {ok, - gleam@erlang@process:subject(FKS)} | - {error, start_error()}. -start(State, Loop) -> - start_spec( - {spec, - fun() -> {ready, State, gleam_erlang_ffi:new_selector()} end, - 5000, - Loop} - ). diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl deleted file mode 100644 index 63a73ea9462..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(gleam@otp@intensity_tracker). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/2, trim_window/3, add_event/1]). --export_type([intensity_tracker/0, too_intense/0]). - --opaque intensity_tracker() :: {intensity_tracker, - integer(), - integer(), - list(integer())}. - --type too_intense() :: too_intense. - --spec new(integer(), integer()) -> intensity_tracker(). -new(Limit, Period) -> - {intensity_tracker, Limit, Period, []}. - --spec now_seconds() -> integer(). -now_seconds() -> - erlang:monotonic_time(1). - --spec trim_window(list(integer()), integer(), integer()) -> list(integer()). -trim_window(Events, Now, Period) -> - case Events of - [] -> - []; - - [Event | Events@1] -> - case Now >= (Event + Period) of - true -> - [Event | trim_window(Events@1, Now, Period)]; - - false -> - [] - end - end. - --spec add_event(intensity_tracker()) -> {ok, intensity_tracker()} | - {error, too_intense()}. -add_event(Tracker) -> - Now = now_seconds(), - Events = trim_window( - [Now | erlang:element(4, Tracker)], - Now, - erlang:element(3, Tracker) - ), - case gleam@list:length(Events) >= erlang:element(2, Tracker) of - true -> - {error, too_intense}; - - false -> - {ok, erlang:setelement(4, Tracker, Events)} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl deleted file mode 100644 index 4176b6ffad7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@node.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gleam@otp@node). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([node_/0]). - --type node_() :: any(). - - diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl deleted file mode 100644 index 4ca9f538511..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@port.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gleam@otp@port). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([port_/0]). - --type port_() :: any(). - - diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl deleted file mode 100644 index a7f39e5fbe2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@supervisor.erl +++ /dev/null @@ -1,322 +0,0 @@ --module(gleam@otp@supervisor). --compile([no_auto_import, nowarn_unused_vars]). - --export([supervisor/1, worker/1, returning/2, start_spec/1, start/1, to_erlang_start_result/1, application_stopped/0, add/2]). --export_type([spec/2, children/1, child_spec/3, child_start_error/0, message/0, instruction/0, state/1, starter/1, child/1, handle_exit_error/0, application_start_mode/0, application_stop/0]). - --type spec(FRW, FRX) :: {spec, - FRW, - integer(), - integer(), - fun((children(FRW)) -> children(FRX))}. - --opaque children(FRY) :: {ready, starter(FRY)} | {failed, child_start_error()}. - --opaque child_spec(FRZ, FSA, FSB) :: {child_spec, - fun((FSA) -> {ok, gleam@erlang@process:subject(FRZ)} | - {error, gleam@otp@actor:start_error()}), - fun((FSA, gleam@erlang@process:subject(FRZ)) -> FSB)}. - --type child_start_error() :: {child_start_error, - gleam@option:option(gleam@erlang@process:pid_()), - gleam@otp@actor:start_error()}. - --opaque message() :: {exit, gleam@erlang@process:exit_message()} | - {retry_restart, gleam@erlang@process:pid_()}. - --type instruction() :: start_all | {start_from, gleam@erlang@process:pid_()}. - --type state(FSC) :: {state, - gleam@otp@intensity_tracker:intensity_tracker(), - starter(FSC), - gleam@erlang@process:subject(gleam@erlang@process:pid_())}. - --type starter(FSD) :: {starter, - FSD, - gleam@option:option(fun((instruction()) -> {ok, - {starter(FSD), instruction()}} | - {error, child_start_error()}))}. - --type child(FSE) :: {child, gleam@erlang@process:pid_(), FSE}. - --type handle_exit_error() :: {restart_failed, - gleam@erlang@process:pid_(), - gleam@otp@intensity_tracker:intensity_tracker()} | - too_many_restarts. - --type application_start_mode() :: normal | - {takeover, gleam@otp@node:node_()} | - {failover, gleam@otp@node:node_()}. - --type application_stop() :: any(). - --spec start_child(child_spec(any(), FSI, FSJ), FSI) -> {ok, child(FSJ)} | - {error, child_start_error()}. -start_child(Child_spec, Argument) -> - gleam@result:then( - begin - _pipe = (erlang:element(2, Child_spec))(Argument), - gleam@result:map_error( - _pipe, - fun(_capture) -> {child_start_error, none, _capture} end - ) - end, - fun(Subject) -> - {ok, - {child, - gleam@erlang@process:subject_owner(Subject), - (erlang:element(3, Child_spec))(Argument, Subject)}} - end - ). - --spec shutdown_child( - gleam@erlang@process:pid_(), - child_spec(any(), any(), any()) -) -> nil. -shutdown_child(Pid, _) -> - gleam@erlang@process:send_exit(Pid). - --spec perform_instruction_for_child( - FSW, - instruction(), - child_spec(any(), FSW, FSY), - child(FSY) -) -> {ok, {child(FSY), instruction()}} | {error, child_start_error()}. -perform_instruction_for_child(Argument, Instruction, Child_spec, Child) -> - Current = erlang:element(2, Child), - case Instruction of - {start_from, Target} when Target =/= Current -> - {ok, {Child, Instruction}}; - - _ -> - shutdown_child(Current, Child_spec), - gleam@result:then( - start_child(Child_spec, Argument), - fun(Child@1) -> {ok, {Child@1, start_all}} end - ) - end. - --spec supervisor( - fun((FUF) -> {ok, gleam@erlang@process:subject(FUG)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(FUG, FUF, FUF). -supervisor(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec worker( - fun((FUN) -> {ok, gleam@erlang@process:subject(FUO)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(FUO, FUN, FUN). -worker(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec returning( - child_spec(FUV, FUW, any()), - fun((FUW, gleam@erlang@process:subject(FUV)) -> FVC) -) -> child_spec(FUV, FUW, FVC). -returning(Child, Updater) -> - {child_spec, erlang:element(2, Child), Updater}. - --spec init(spec(any(), FVH)) -> gleam@otp@actor:init_result(state(FVH), message()). -init(Spec) -> - Retry = gleam@erlang@process:new_subject(), - gleam_erlang_ffi:trap_exits(true), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Retry, - fun(Field@0) -> {retry_restart, Field@0} end - ), - gleam@erlang@process:selecting_trapped_exits( - _pipe@1, - fun(Field@0) -> {exit, Field@0} end - ) - end, - Result = begin - _pipe@2 = {starter, erlang:element(2, Spec), none}, - _pipe@3 = {ready, _pipe@2}, - (erlang:element(5, Spec))(_pipe@3) - end, - case Result of - {ready, Starter} -> - Restarts = gleam@otp@intensity_tracker:new( - erlang:element(3, Spec), - erlang:element(4, Spec) - ), - State = {state, Restarts, Starter, Retry}, - {ready, State, Selector}; - - {failed, Error} -> - {failed, case erlang:element(3, Error) of - init_timeout -> - <<"Child initialisation timed out"/utf8>>; - - {init_crashed, Reason} -> - gleam@string:append( - <<"Child crashed during initialisation: "/utf8>>, - gleam@string:inspect(Reason) - ); - - {init_failed, Reason@1} -> - gleam@string:append( - <<"Child failed to start during initialisation: "/utf8>>, - gleam@string:inspect(Reason@1) - ) - end} - end. - --spec handle_exit(gleam@erlang@process:pid_(), state(FVN)) -> gleam@otp@actor:next(state(FVN)). -handle_exit(Pid, State) -> - Outcome = begin - _assert_subject = erlang:element(3, erlang:element(3, State)), - {some, Start} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/supervisor"/utf8>>, - function => <<"handle_exit"/utf8>>, - line => 293}) - end, - gleam@result:then( - begin - _pipe = erlang:element(2, State), - _pipe@1 = gleam@otp@intensity_tracker:add_event(_pipe), - gleam@result:map_error(_pipe@1, fun(_) -> too_many_restarts end) - end, - fun(Restarts) -> - gleam@result:then( - begin - _pipe@2 = Start({start_from, Pid}), - gleam@result:map_error( - _pipe@2, - fun(E) -> - {restart_failed, - gleam@option:unwrap( - erlang:element(2, E), - Pid - ), - Restarts} - end - ) - end, - fun(_use0) -> - {Starter, _} = _use0, - {ok, - erlang:setelement( - 2, - erlang:setelement(3, State, Starter), - Restarts - )} - end - ) - end - ) - end, - case Outcome of - {ok, State@1} -> - {continue, State@1}; - - {error, {restart_failed, Failed_child, Restarts@1}} -> - gleam@erlang@process:send(erlang:element(4, State), Failed_child), - State@2 = erlang:setelement(2, State, Restarts@1), - {continue, State@2}; - - {error, too_many_restarts} -> - {stop, - {abnormal, - <<"Child processes restarted too many times within allowed period"/utf8>>}} - end. - --spec loop(message(), state(FVR)) -> gleam@otp@actor:next(state(FVR)). -loop(Message, State) -> - case Message of - {exit, Exit_message} -> - handle_exit(erlang:element(2, Exit_message), State); - - {retry_restart, Pid} -> - handle_exit(Pid, State) - end. - --spec start_spec(spec(any(), any())) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start_spec(Spec) -> - gleam@otp@actor:start_spec( - {spec, fun() -> init(Spec) end, 60000, fun loop/2} - ). - --spec start(fun((children(nil)) -> children(any()))) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start(Init) -> - start_spec({spec, nil, 5, 1, Init}). - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic()}. -to_erlang_start_result(Res) -> - gleam@otp@actor:to_erlang_start_result(Res). - --spec application_stopped() -> application_stop(). -application_stopped() -> - gleam_otp_external:application_stopped(). - --spec add_child_to_starter( - starter(FTG), - child_spec(any(), FTG, FTJ), - child(FTJ) -) -> starter(FTJ). -add_child_to_starter(Starter, Child_spec, Child) -> - Starter@3 = fun(Instruction) -> - gleam@result:then(case erlang:element(3, Starter) of - {some, Start} -> - Start(Instruction); - - none -> - {ok, {Starter, Instruction}} - end, fun(_use0) -> - {Starter@1, Instruction@1} = _use0, - gleam@result:then( - perform_instruction_for_child( - erlang:element(2, Starter@1), - Instruction@1, - Child_spec, - Child - ), - fun(_use0@1) -> - {Child@1, Instruction@2} = _use0@1, - Starter@2 = add_child_to_starter( - Starter@1, - Child_spec, - Child@1 - ), - {ok, {Starter@2, Instruction@2}} - end - ) - end) - end, - {starter, erlang:element(3, Child), {some, Starter@3}}. - --spec start_and_add_child(starter(FTP), child_spec(any(), FTP, FTS)) -> children(FTS). -start_and_add_child(State, Child_spec) -> - case start_child(Child_spec, erlang:element(2, State)) of - {ok, Child} -> - {ready, add_child_to_starter(State, Child_spec, Child)}; - - {error, Reason} -> - {failed, Reason} - end. - --spec add(children(FTX), child_spec(any(), FTX, FUA)) -> children(FUA). -add(Children, Child_spec) -> - case Children of - {failed, Fail} -> - {failed, Fail}; - - {ready, State} -> - start_and_add_child(State, Child_spec) - end. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl deleted file mode 100644 index aa5fabd94c8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@system.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam@otp@system). --compile([no_auto_import, nowarn_unused_vars]). - --export([debug_state/1, get_state/1, suspend/1, resume/1]). --export_type([mode/0, debug_option/0, status_info/0, system_message/0, debug_state/0, do_not_leak/0]). - --type mode() :: running | suspended. - --type debug_option() :: no_debug. - --type status_info() :: {status_info, - gleam@erlang@atom:atom_(), - gleam@erlang@process:pid_(), - mode(), - debug_state(), - gleam@dynamic:dynamic()}. - --type system_message() :: {resume, fun(() -> nil)} | - {suspend, fun(() -> nil)} | - {get_state, fun((gleam@dynamic:dynamic()) -> nil)} | - {get_status, fun((status_info()) -> nil)}. - --type debug_state() :: any(). - --type do_not_leak() :: any(). - --spec debug_state(list(debug_option())) -> debug_state(). -debug_state(Field@0) -> - sys:debug_options(Field@0). - --spec get_state(gleam@erlang@process:pid_()) -> gleam@dynamic:dynamic(). -get_state(Field@0) -> - sys:get_state(Field@0). - --spec suspend(gleam@erlang@process:pid_()) -> nil. -suspend(Pid) -> - sys:suspend(Pid), - nil. - --spec resume(gleam@erlang@process:pid_()) -> nil. -resume(Pid) -> - sys:resume(Pid), - nil. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl deleted file mode 100644 index b475694cbfc..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam@otp@task.erl +++ /dev/null @@ -1,111 +0,0 @@ --module(gleam@otp@task). --compile([no_auto_import, nowarn_unused_vars]). - --export([async/1, try_await/2, await/2, try_await_forever/1, await_forever/1]). --export_type([task/1, await_error/0, message/1]). - --opaque task(FFD) :: {task, - gleam@erlang@process:pid_(), - gleam@erlang@process:pid_(), - gleam@erlang@process:process_monitor(), - gleam@erlang@process:selector(message(FFD))}. - --type await_error() :: timeout | {exit, gleam@dynamic:dynamic()}. - --type message(FFE) :: {from_monitor, gleam@erlang@process:process_down()} | - {from_subject, FFE}. - --spec async(fun(() -> FFF)) -> task(FFF). -async(Work) -> - Owner = erlang:self(), - Subject = gleam@erlang@process:new_subject(), - Pid = gleam@erlang@process:start( - fun() -> gleam@erlang@process:send(Subject, Work()) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Pid), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting_process_down( - _pipe, - Monitor, - fun(Field@0) -> {from_monitor, Field@0} end - ), - gleam@erlang@process:selecting( - _pipe@1, - Subject, - fun(Field@0) -> {from_subject, Field@0} end - ) - end, - {task, Owner, Pid, Monitor, Selector}. - --spec assert_owner(task(any())) -> nil. -assert_owner(Task) -> - Self = erlang:self(), - case erlang:element(2, Task) =:= Self of - true -> - nil; - - false -> - gleam@erlang@process:send_abnormal_exit( - Self, - <<"awaited on a task that does not belong to this process"/utf8>> - ) - end. - --spec try_await(task(FFJ), integer()) -> {ok, FFJ} | {error, await_error()}. -try_await(Task, Timeout) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task), Timeout) of - {ok, {from_subject, X}} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {ok, {from_monitor, {process_down, _, Reason}}} -> - {error, {exit, Reason}}; - - {error, nil} -> - {error, timeout} - end. - --spec await(task(FFN), integer()) -> FFN. -await(Task, Timeout) -> - _assert_subject = try_await(Task, Timeout), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await"/utf8>>, - line => 117}) - end, - Value. - --spec try_await_forever(task(FFP)) -> {ok, FFP} | {error, await_error()}. -try_await_forever(Task) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task)) of - {from_subject, X} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {from_monitor, {process_down, _, Reason}} -> - {error, {exit, Reason}} - end. - --spec await_forever(task(FFT)) -> FFT. -await_forever(Task) -> - _assert_subject = try_await_forever(Task), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await_forever"/utf8>>, - line => 149}) - end, - Value. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src deleted file mode 100644 index 79ddc8769ca..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp.app.src +++ /dev/null @@ -1,15 +0,0 @@ -{application, gleam_otp, [ - {vsn, "0.5.3"}, - {applications, [gleam_erlang, - gleam_stdlib, - gleeunit]}, - {description, "Fault tolerant multicore Gleam programs with OTP"}, - {modules, [gleam@otp@actor, - gleam@otp@intensity_tracker, - gleam@otp@node, - gleam@otp@port, - gleam@otp@supervisor, - gleam@otp@system, - gleam@otp@task]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl b/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl deleted file mode 100644 index 8910a67d7e2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_otp/src/gleam_otp_external.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam_otp_external). - --export([application_stopped/0, convert_system_message/2]). - -% TODO: support other system messages -% {replace_state, StateFn} -% {change_code, Mod, Vsn, Extra} -% {terminate, Reason} -% {debug, {log, Flag}} -% {debug, {trace, Flag}} -% {debug, {log_to_file, FileName}} -% {debug, {statistics, Flag}} -% {debug, no_debug} -% {debug, {install, {Func, FuncState}}} -% {debug, {install, {FuncId, Func, FuncState}}} -% {debug, {remove, FuncOrId}} -% GetStatus(Subject(StatusInfo)) -convert_system_message({From, Ref}, Request) when is_pid(From) -> - Reply = fun(Msg) -> - erlang:send(From, {Ref, Msg}), - nil - end, - System = fun(Callback) -> - {system, {Request, Callback}} - end, - case Request of - get_status -> System(fun(Status) -> Reply(process_status(Status)) end); - get_state -> System(Reply); - suspend -> System(fun() -> Reply(ok) end); - resume -> System(fun() -> Reply(ok) end); - Other -> {unexpeceted, Other} - end. - -process_status({status_info, Module, Parent, Mode, DebugState, State}) -> - Data = [ - get(), Mode, Parent, DebugState, - [{header, "Status for Gleam process " ++ pid_to_list(self())}, - {data, [{'Status', Mode}, {'Parent', Parent}, {'State', State}]}] - ], - {status, self(), {module, Module}, Data}. - -application_stopped() -> - ok. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index 44a866e2643..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "gleam_stdlib" -version = "0.29.2" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] - -[dev-dependencies] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 9c903123849..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@map:map_(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index 7ec15580d7c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,59 +0,0 @@ -import gleam/bit_string -import gleam/string - -/// Encodes a BitString into a base 64 encoded string. -/// -pub fn encode64(input: BitString, padding: Bool) -> String { - let encoded = do_encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -if erlang { - external fn do_encode64(BitString) -> String = - "base64" "encode" -} - -if javascript { - external fn do_encode64(BitString) -> String = - "../gleam_stdlib.mjs" "encode64" -} - -/// Decodes a base 64 encoded string into a `BitString`. -/// -pub fn decode64(encoded: String) -> Result(BitString, Nil) { - let padded = case bit_string.byte_size(bit_string.from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - do_decode64(padded) -} - -if erlang { - external fn do_decode64(String) -> Result(BitString, Nil) = - "gleam_stdlib" "base_decode64" -} - -if javascript { - external fn do_decode64(String) -> Result(BitString, Nil) = - "../gleam_stdlib.mjs" "decode64" -} - -/// Encodes a `BitString` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn url_encode64(input: BitString, padding: Bool) -> String { - encode64(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitString`. -/// -pub fn url_decode64(encoded: String) -> Result(BitString, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> decode64() -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index 960d6655559..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,276 +0,0 @@ -//// BitBuilder is a type used for efficiently concatenating bits to create bit -//// strings. -//// -//// If we append one bit string to another the bit strings must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit strings together. -//// -//// BitBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit string using the `to_bit_string` function. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -import gleam/string_builder.{StringBuilder} - -if javascript { - import gleam/list - import gleam/bit_string -} - -if erlang { - pub external type BitBuilder -} - -if javascript { - pub opaque type BitBuilder { - Bits(BitString) - Text(StringBuilder) - Many(List(BitBuilder)) - } -} - -/// Create an empty `BitBuilder`. Useful as the start of a pipe chaning many -/// builders together. -/// -pub fn new() -> BitBuilder { - do_concat([]) -} - -/// Prepends a bit string to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to: BitBuilder, prefix: BitString) -> BitBuilder { - append_builder(from_bit_string(prefix), to) -} - -/// Appends a bit string to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to: BitBuilder, suffix: BitString) -> BitBuilder { - append_builder(to, from_bit_string(suffix)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - append_builder(prefix, to) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - do_append_builder(first, second) -} - -if erlang { - external fn do_append_builder( - to: BitBuilder, - suffix: BitBuilder, - ) -> BitBuilder = - "gleam_stdlib" "iodata_append" -} - -if javascript { - fn do_append_builder(first: BitBuilder, second: BitBuilder) -> BitBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - append_builder(from_string(prefix), to) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - append_builder(to, from_string(suffix)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - do_concat(builders) -} - -if erlang { - external fn do_concat(List(BitBuilder)) -> BitBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - fn do_concat(builders: List(BitBuilder)) -> BitBuilder { - Many(builders) - } -} - -/// Joins a list of bit strings into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat_bit_strings(bits: List(BitString)) -> BitBuilder { - do_concat_bit_strings(bits) -} - -if erlang { - external fn do_concat_bit_strings(List(BitString)) -> BitBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - fn do_concat_bit_strings(bits: List(BitString)) -> BitBuilder { - bits - |> list.map(fn(b) { from_bit_string(b) }) - |> concat() - } -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -pub fn from_string(string: String) -> BitBuilder { - do_from_string(string) -} - -if erlang { - external fn do_from_string(String) -> BitBuilder = - "gleam_stdlib" "wrap_list" -} - -if javascript { - fn do_from_string(string: String) -> BitBuilder { - Text(string_builder.from_string(string)) - } -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - do_from_string_builder(builder) -} - -if erlang { - external fn do_from_string_builder(StringBuilder) -> BitBuilder = - "gleam_stdlib" "wrap_list" -} - -if javascript { - fn do_from_string_builder(builder: StringBuilder) -> BitBuilder { - Text(builder) - } -} - -/// Creates a new builder from a bit string. -/// -/// Runs in constant time. -/// -pub fn from_bit_string(bits: BitString) -> BitBuilder { - do_from_bit_string(bits) -} - -if erlang { - external fn do_from_bit_string(BitString) -> BitBuilder = - "gleam_stdlib" "wrap_list" -} - -if javascript { - fn do_from_bit_string(bits: BitString) -> BitBuilder { - Bits(bits) - } -} - -/// Turns an builder into a bit string. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -pub fn to_bit_string(builder: BitBuilder) -> BitString { - do_to_bit_string(builder) -} - -if erlang { - external fn do_to_bit_string(BitBuilder) -> BitString = - "erlang" "list_to_bitstring" -} - -if javascript { - fn do_to_bit_string(builder: BitBuilder) -> BitString { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_string.concat - } - - fn to_list( - stack: List(List(BitBuilder)), - acc: List(BitString), - ) -> List(BitString) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bits(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_string.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -pub fn byte_size(builder: BitBuilder) -> Int { - do_byte_size(builder) -} - -if erlang { - external fn do_byte_size(BitBuilder) -> Int = - "erlang" "iolist_size" -} - -if javascript { - fn do_byte_size(builder: BitBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_string.byte_size(builder) + acc }) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index 6a67028f16d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,155 +0,0 @@ -//// Working with raw bit string data. -//// The `BitString` type should be used instead of a String type when not utf8 -//// encoded. - -/// Converts a UTF-8 `String` type into a raw `BitString` type. -/// -pub fn from_string(x: String) -> BitString { - do_from_string(x) -} - -if erlang { - external fn do_from_string(String) -> BitString = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from_string(String) -> BitString = - "../gleam_stdlib.mjs" "bit_string_from_string" -} - -/// Returns an integer which is the number of bytes in the bit string. -/// -pub fn byte_size(x: BitString) -> Int { - do_byte_size(x) -} - -if erlang { - external fn do_byte_size(BitString) -> Int = - "erlang" "byte_size" -} - -if javascript { - external fn do_byte_size(BitString) -> Int = - "../gleam_stdlib.mjs" "length" -} - -/// Creates a new bit string by joining two binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitString, suffix second: BitString) -> BitString { - concat([first, second]) -} - -/// Extracts a sub-section of a bit string. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit string. -/// -/// This function runs in constant time. -/// -pub fn slice( - from string: BitString, - at position: Int, - take length: Int, -) -> Result(BitString, Nil) { - do_slice(string, position, length) -} - -if erlang { - external fn do_slice( - string: BitString, - position: Int, - length: Int, - ) -> Result(BitString, Nil) = - "gleam_stdlib" "bit_string_slice" -} - -if javascript { - external fn do_slice( - string: BitString, - position: Int, - length: Int, - ) -> Result(BitString, Nil) = - "../gleam_stdlib.mjs" "bit_string_slice" -} - -/// Tests to see whether a bit string is valid UTF-8. -/// -pub fn is_utf8(bits: BitString) -> Bool { - do_is_utf8(bits) -} - -if erlang { - fn do_is_utf8(bits: BitString) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:binary>> -> do_is_utf8(rest) - _ -> False - } - } -} - -if javascript { - fn do_is_utf8(bits: BitString) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } - } -} - -/// Converts a bit string to a string. -/// -/// Returns an error if the bit string is invalid UTF-8 data. -/// -pub fn to_string(bits: BitString) -> Result(String, Nil) { - do_to_string(bits) -} - -if erlang { - external fn unsafe_to_string(BitString) -> String = - "gleam_stdlib" "identity" - - fn do_to_string(bits: BitString) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } - } -} - -if javascript { - external fn do_to_string(BitString) -> Result(String, Nil) = - "../gleam_stdlib.mjs" "bit_string_to_string" -} - -/// Creates a new bit string by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -pub fn concat(bit_strings: List(BitString)) -> BitString { - do_concat(bit_strings) -} - -if erlang { - external fn do_concat(List(BitString)) -> BitString = - "gleam_stdlib" "bit_string_concat" -} - -if javascript { - external fn do_concat(List(BitString)) -> BitString = - "../gleam_stdlib.mjs" "bit_string_concat" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 66200a8a5b4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,388 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index 86055a003e4..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1613 +0,0 @@ -import gleam/int -import gleam/list -import gleam/map.{Map} -import gleam/option.{Option} -import gleam/result -import gleam/string_builder - -if erlang { - import gleam/bit_string -} - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub external type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -if erlang { - external fn do_from(anything) -> Dynamic = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from(anything) -> Dynamic = - "../gleam_stdlib.mjs" "identity" -} - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -if erlang { - external fn do_unsafe_coerce(Dynamic) -> a = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_unsafe_coerce(Dynamic) -> a = - "../gleam_stdlib.mjs" "identity" -} - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit_string, and returns that bit string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_string(from("Hello")) == bit_string.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_string(from(123)) -/// Error([DecodeError(expected: "BitString", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_string(from data: Dynamic) -> Result(BitString, DecodeErrors) { - decode_bit_string(data) -} - -if erlang { - external fn decode_bit_string(Dynamic) -> Result(BitString, DecodeErrors) = - "gleam_stdlib" "decode_bit_string" -} - -if javascript { - external fn decode_bit_string(Dynamic) -> Result(BitString, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_bit_string" -} - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -if erlang { - fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_string(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_string.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitString", path: [])]) - } - }) - } - - fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) - } -} - -if javascript { - external fn decode_string(Dynamic) -> Result(String, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_string" -} - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -if erlang { - external fn do_classify(Dynamic) -> String = - "gleam_stdlib" "classify_dynamic" -} - -if javascript { - external fn do_classify(Dynamic) -> String = - "../gleam_stdlib.mjs" "classify_dynamic" -} - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -if erlang { - external fn decode_int(Dynamic) -> Result(Int, DecodeErrors) = - "gleam_stdlib" "decode_int" -} - -if javascript { - external fn decode_int(Dynamic) -> Result(Int, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_int" -} - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -if erlang { - external fn decode_float(Dynamic) -> Result(Float, DecodeErrors) = - "gleam_stdlib" "decode_float" -} - -if javascript { - external fn decode_float(Dynamic) -> Result(Float, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_float" -} - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -if erlang { - external fn decode_bool(Dynamic) -> Result(Bool, DecodeErrors) = - "gleam_stdlib" "decode_bool" -} - -if javascript { - external fn decode_bool(Dynamic) -> Result(Bool, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_bool" -} - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -if erlang { - external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_list" -} - -if javascript { - external fn decode_list(Dynamic) -> Result(List(Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_list" -} - -if erlang { - external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeErrors) = - "gleam_stdlib" "decode_result" -} - -if javascript { - external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_result" -} - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -if erlang { - external fn decode_optional( - Dynamic, - Decoder(a), - ) -> Result(Option(a), DecodeErrors) = - "gleam_stdlib" "decode_option" -} - -if javascript { - external fn decode_optional( - Dynamic, - Decoder(a), - ) -> Result(Option(a), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_option" -} - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/map -/// > map.new() -/// > |> map.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/map -/// > map.new() -/// > |> map.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/map -/// > map.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -if erlang { - external fn decode_field( - Dynamic, - name, - ) -> Result(Option(Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_field" -} - -if javascript { - external fn decode_field( - Dynamic, - name, - ) -> Result(Option(Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_field" -} - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -external type UnknownTuple - -if erlang { - external fn decode_tuple(Dynamic) -> Result(UnknownTuple, DecodeErrors) = - "gleam_stdlib" "decode_tuple" - - external fn decode_tuple2( - Dynamic, - ) -> Result(#(Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple2" - - external fn decode_tuple3( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple3" - - external fn decode_tuple4( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple4" - - external fn decode_tuple5( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_tuple5" - - external fn decode_tuple6( - Dynamic, - ) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, - ) = - "gleam_stdlib" "decode_tuple6" - - external fn tuple_get(UnknownTuple, Int) -> Result(Dynamic, DecodeErrors) = - "gleam_stdlib" "tuple_get" - - external fn tuple_size(UnknownTuple) -> Int = - "gleam_stdlib" "size_of_tuple" -} - -if javascript { - external fn decode_tuple(Dynamic) -> Result(UnknownTuple, DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple" - - external fn decode_tuple2( - Dynamic, - ) -> Result(#(Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple2" - - external fn decode_tuple3( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple3" - - external fn decode_tuple4( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple4" - - external fn decode_tuple5( - Dynamic, - ) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_tuple5" - - external fn decode_tuple6( - Dynamic, - ) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, - ) = - "../gleam_stdlib.mjs" "decode_tuple6" - - external fn tuple_get(UnknownTuple, Int) -> Result(Dynamic, DecodeErrors) = - "../gleam_stdlib.mjs" "tuple_get" - - external fn tuple_size(UnknownTuple) -> Int = - "../gleam_stdlib.mjs" "length" -} - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a map. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/map -/// > map.new() |> from |> map(string, int) -/// Ok(map.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Map(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> map.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(map.from_list(pairs)) - } -} - -if erlang { - external fn decode_map(Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) = - "gleam_stdlib" "decode_map" -} - -if javascript { - external fn decode_map(Dynamic) -> Result(Map(Dynamic, Dynamic), DecodeErrors) = - "../gleam_stdlib.mjs" "decode_map" -} - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.flatten([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.flatten([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.flatten([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 1ee175cf7a2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,589 +0,0 @@ -import gleam/order.{Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -if erlang { - external fn do_parse(String) -> Result(Float, Nil) = - "gleam_stdlib" "parse_float" -} - -if javascript { - external fn do_parse(String) -> Result(Float, Nil) = - "../gleam_stdlib.mjs" "parse_float" -} - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -if erlang { - external fn do_to_string(Float) -> String = - "gleam_stdlib" "float_to_string" -} - -if javascript { - external fn do_to_string(Float) -> String = - "../gleam_stdlib.mjs" "float_to_string" -} - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -if erlang { - external fn do_ceiling(Float) -> Float = - "math" "ceil" -} - -if javascript { - external fn do_ceiling(Float) -> Float = - "../gleam_stdlib.mjs" "ceiling" -} - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -if erlang { - external fn do_floor(Float) -> Float = - "math" "floor" -} - -if javascript { - external fn do_floor(Float) -> Float = - "../gleam_stdlib.mjs" "floor" -} - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -if erlang { - external fn do_round(Float) -> Int = - "erlang" "round" -} - -if javascript { - fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } - } - - external fn js_round(Float) -> Int = - "../gleam_stdlib.mjs" "round" -} - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -if erlang { - external fn do_truncate(Float) -> Int = - "erlang" "trunc" -} - -if javascript { - external fn do_truncate(Float) -> Int = - "../gleam_stdlib.mjs" "truncate" -} - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -if erlang { - external fn do_power(Float, Float) -> Float = - "math" "pow" -} - -if javascript { - external fn do_power(Float, Float) -> Float = - "../gleam_stdlib.mjs" "power" -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Returns `0.0` if `boundary_a` and `boundary_b` are equal, -/// otherwise returns a `Float x` where `lower_boundary =< x < upper_boundary`. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(boundary_a: Float, boundary_b: Float) -> Float { - // Based on: - // - // ```javascript - // return Math.random() * (max - min) + min; // The minimum is inclusive and the maximum is exclusive - // ``` - // - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values> - let #(min, max) = case boundary_a, boundary_b { - a, b if a <=. b -> #(a, b) - a, b if a >. b -> #(b, a) - } - case min, max { - min, _max if min == max -> min - min, max -> do_random_uniform() *. { max -. min } +. min - } -} - -if erlang { - /// Returns a random float uniformly distributed in the value range - /// 0.0 =< X < 1.0 and updates the state in the process dictionary. - /// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> - /// - external fn do_random_uniform() -> Float = - "rand" "uniform" -} - -if javascript { - external fn do_random_uniform() -> Float = - "../gleam_stdlib.mjs" "random_uniform" -} - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index 793a85e71a7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,854 +0,0 @@ -import gleam/float -import gleam/order.{Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -if erlang { - external fn do_parse(String) -> Result(Int, Nil) = - "gleam_stdlib" "parse_int" -} - -if javascript { - external fn do_parse(String) -> Result(Int, Nil) = - "../gleam_stdlib.mjs" "parse_int" -} - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -if erlang { - external fn do_base_parse(String, Int) -> Result(Int, Nil) = - "gleam_stdlib" "int_from_base_string" -} - -if javascript { - external fn do_base_parse(String, Int) -> Result(Int, Nil) = - "../gleam_stdlib.mjs" "int_from_base_string" -} - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -if erlang { - external fn do_to_string(Int) -> String = - "erlang" "integer_to_binary" -} - -if javascript { - external fn do_to_string(Int) -> String = - "../gleam_stdlib.mjs" "to_string" -} - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -if erlang { - external fn do_to_base_string(Int, Int) -> String = - "erlang" "integer_to_binary" -} - -if javascript { - external fn do_to_base_string(Int, Int) -> String = - "../gleam_stdlib.mjs" "int_to_base_string" -} - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -if erlang { - external fn do_to_float(Int) -> Float = - "erlang" "float" -} - -if javascript { - external fn do_to_float(Int) -> Float = - "../gleam_stdlib.mjs" "identity" -} - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Returns `0` if `boundary_a` and `boundary_b` are equal, -/// otherwise returns an `Int x` where `lower_boundary =< x < upper_boundary`. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(boundary_a: Int, boundary_b: Int) -> Int { - // Based on: - // - // ```javascript - // min = Math.ceil(min); - // max = Math.floor(max); - // return Math.floor(Math.random() * (max - min) + min); // The minimum is inclusive and the maximum is exclusive - // ``` - // - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values> - let #(min, max) = case boundary_a, boundary_b { - a, b if a <= b -> #(a, b) - a, b if a > b -> #(b, a) - } - - let min = - to_float(min) - |> float.ceiling() - let max = - to_float(max) - |> float.floor() - - float.random(min, max) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index c8524f15d93..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,147 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -if erlang { - external fn do_print(string: String) -> Nil = - "gleam_stdlib" "print" -} - -if javascript { - external fn do_print(String) -> Nil = - "../gleam_stdlib.mjs" "print" -} - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -if erlang { - external fn do_print_error(string: String) -> Nil = - "gleam_stdlib" "print_error" -} - -if javascript { - external fn do_print_error(String) -> Nil = - "../gleam_stdlib.mjs" "print_error" -} - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -if erlang { - external fn do_println(string: String) -> Nil = - "gleam_stdlib" "println" -} - -if javascript { - external fn do_println(String) -> Nil = - "../gleam_stdlib.mjs" "console_log" -} - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -if erlang { - external fn do_println_error(string: String) -> Nil = - "gleam_stdlib" "println_error" -} - -if javascript { - external fn do_println_error(String) -> Nil = - "../gleam_stdlib.mjs" "console_error" -} - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -if erlang { - external fn do_debug_println(string: String) -> Nil = - "gleam_stdlib" "println_error" -} - -if javascript { - external fn do_debug_println(String) -> Nil = - "../gleam_stdlib.mjs" "print_debug" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index 4e5a752c8a8..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1442 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - for predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Map(key, List(element)), element) -> Map(key, List(element)) { - fn(groups, elem) { - groups - |> map.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Map(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// map.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Map(key, List(element)) { - iterator - |> fold(map.new(), group_updater(key)) - |> map.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index 72650163b18..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2075 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{Order} -import gleam/pair -import gleam/map.{Map} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -if erlang { - external fn do_length(List(a)) -> Int = - "erlang" "length" -} - -if javascript { - fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) - } - - fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -if erlang { - external fn do_reverse(List(a)) -> List(a) = - "lists" "reverse" -} - -if javascript { - fn do_reverse(list) { - do_reverse_acc(list, []) - } - - fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Map(key, List(element)), element) -> Map(key, List(element)) { - fn(groups, elem) { - case map.get(groups, f(elem)) { - Ok(existing) -> map.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> map.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> map.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group(from: [1,2,3,4,5], with: fn(i) {fn(i) { i - i / 3 * 3 }}) -/// |> map.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Map(k, List(v)) { - fold(list, map.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), for predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -if erlang { - external fn do_append(List(a), List(a)) -> List(a) = - "lists" "append" -} - -if javascript { - fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) - } - - fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_flatten(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_flatten(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Flattens a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_flatten(lists, []) -} - -/// Maps the list with the given function and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> flatten -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> reverse([stop, ..acc]) - order.Gt -> tail_recursive_range(start - 1, stop, [start, ..acc]) - order.Lt -> tail_recursive_range(start + 1, stop, [start, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> flatten - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> flatten -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> flatten -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> flatten - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - _ -> { - let [elem_pair, ..enumerable] = list - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calcuate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 6f963bceef2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,593 +0,0 @@ -import gleam/option.{Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a map, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a map once. -/// -/// Maps are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub external type Map(key, value) - -/// Determines the number of key-value pairs in the map. -/// This function runs in constant time and does not need to iterate the map. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(map: Map(k, v)) -> Int { - do_size(map) -} - -if erlang { - external fn do_size(Map(k, v)) -> Int = - "maps" "size" -} - -if javascript { - external fn do_size(Map(k, v)) -> Int = - "../gleam_stdlib.mjs" "map_size" -} - -/// Converts the map to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the map. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(map: Map(key, value)) -> List(#(key, value)) { - do_to_list(map) -} - -if erlang { - external fn do_to_list(Map(key, value)) -> List(#(key, value)) = - "maps" "to_list" -} - -if javascript { - external fn do_to_list(Map(key, value)) -> List(#(key, value)) = - "../gleam_stdlib.mjs" "map_to_list" -} - -/// Converts a list of 2-element tuples `#(key, value)` to a map. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the map. -/// -pub fn from_list(list: List(#(k, v))) -> Map(k, v) { - do_from_list(list) -} - -if erlang { - external fn do_from_list(List(#(key, value))) -> Map(key, value) = - "maps" "from_list" -} - -if javascript { - fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Map(k, v), - ) -> Map(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } - } - - fn do_from_list(list: List(#(k, v))) -> Map(k, v) { - fold_list_of_pair(list, new()) - } -} - -/// Determines whether or not a value present in the map for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(map: Map(k, v), key: k) -> Bool { - do_has_key(key, map) -} - -if erlang { - external fn do_has_key(key, Map(key, v)) -> Bool = - "maps" "is_key" -} - -if javascript { - fn do_has_key(key: k, map: Map(k, v)) -> Bool { - get(map, key) != Error(Nil) - } -} - -/// Creates a fresh map that contains no values. -/// -pub fn new() -> Map(key, value) { - do_new() -} - -if erlang { - external fn do_new() -> Map(key, value) = - "maps" "new" -} - -if javascript { - external fn do_new() -> Map(key, value) = - "../gleam_stdlib.mjs" "new_map" -} - -/// Fetches a value from a map for a given key. -/// -/// The map may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Map(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -if erlang { - external fn do_get(Map(key, value), key) -> Result(value, Nil) = - "gleam_stdlib" "map_get" -} - -if javascript { - external fn do_get(Map(key, value), key) -> Result(value, Nil) = - "../gleam_stdlib.mjs" "map_get" -} - -/// Inserts a value into the map with the given key. -/// -/// If the map already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into map: Map(k, v), for key: k, insert value: v) -> Map(k, v) { - do_insert(key, value, map) -} - -if erlang { - external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = - "maps" "put" -} - -if javascript { - external fn do_insert(key, value, Map(key, value)) -> Map(key, value) = - "../gleam_stdlib.mjs" "map_insert" -} - -/// Updates all values in a given map by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in map: Map(k, v), with fun: fn(k, v) -> w) -> Map(k, w) { - do_map_values(fun, map) -} - -if erlang { - external fn do_map_values(fn(key, value) -> b, Map(key, value)) -> Map(key, b) = - "maps" "map" -} - -if javascript { - fn do_map_values(f: fn(key, value) -> b, map: Map(key, value)) -> Map(key, b) { - let f = fn(map, k, v) { insert(map, k, f(k, v)) } - map - |> fold(from: new(), with: f) - } -} - -/// Gets a list of all keys in a given map. -/// -/// Maps are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(map: Map(keys, v)) -> List(keys) { - do_keys(map) -} - -if erlang { - external fn do_keys(Map(keys, v)) -> List(keys) = - "maps" "keys" -} - -if javascript { - fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } - } - - fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } - } - - fn do_keys(map: Map(k, v)) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) - } -} - -/// Gets a list of all values in a given map. -/// -/// Maps are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(map: Map(k, values)) -> List(values) { - do_values(map) -} - -if erlang { - external fn do_values(Map(k, values)) -> List(values) = - "maps" "values" -} - -if javascript { - fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } - } - - fn do_values(map: Map(k, v)) -> List(v) { - let list_of_pairs = - map - |> to_list - do_values_acc(list_of_pairs, []) - } -} - -/// Creates a new map from a given map, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { - do_filter(property, map) -} - -if erlang { - external fn do_filter( - fn(key, value) -> Bool, - Map(key, value), - ) -> Map(key, value) = - "maps" "filter" -} - -if javascript { - fn do_filter( - f: fn(key, value) -> Bool, - map: Map(key, value), - ) -> Map(key, value) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) - } -} - -/// Creates a new map from a given map, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from map: Map(k, v), keeping desired_keys: List(k)) -> Map(k, v) { - do_take(desired_keys, map) -} - -if erlang { - external fn do_take(List(k), Map(k, v)) -> Map(k, v) = - "maps" "with" -} - -if javascript { - fn insert_taken( - map: Map(k, v), - desired_keys: List(k), - acc: Map(k, v), - ) -> Map(k, v) { - let insert = fn(taken, key) { - case get(map, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(map, xs, insert(acc, x)) - } - } - - fn do_take(desired_keys: List(k), map: Map(k, v)) -> Map(k, v) { - insert_taken(map, desired_keys, new()) - } -} - -/// Creates a new map from a pair of given maps by combining their entries. -/// -/// If there are entries with the same keys in both maps the entry from the -/// second map takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into map: Map(k, v), from new_entries: Map(k, v)) -> Map(k, v) { - do_merge(map, new_entries) -} - -if erlang { - external fn do_merge(Map(k, v), Map(k, v)) -> Map(k, v) = - "maps" "merge" -} - -if javascript { - fn insert_pair(map: Map(k, v), pair: #(k, v)) -> Map(k, v) { - insert(map, pair.0, pair.1) - } - - fn fold_inserts(new_entries: List(#(k, v)), map: Map(k, v)) -> Map(k, v) { - case new_entries { - [] -> map - [x, ..xs] -> fold_inserts(xs, insert_pair(map, x)) - } - } - - fn do_merge(map: Map(k, v), new_entries: Map(k, v)) -> Map(k, v) { - new_entries - |> to_list - |> fold_inserts(map) - } -} - -/// Creates a new map from a given map with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from map: Map(k, v), delete key: k) -> Map(k, v) { - do_delete(key, map) -} - -if erlang { - external fn do_delete(k, Map(k, v)) -> Map(k, v) = - "maps" "remove" -} - -if javascript { - external fn do_delete(k, Map(k, v)) -> Map(k, v) = - "../gleam_stdlib.mjs" "map_remove" -} - -/// Creates a new map from a given map with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from map: Map(k, v), drop disallowed_keys: List(k)) -> Map(k, v) { - case disallowed_keys { - [] -> map - [x, ..xs] -> drop(delete(map, x), xs) - } -} - -/// Creates a new map with one entry updated using a given function. -/// -/// If there was not an entry in the map for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let map = from_list([#("a", 0)]) -/// > -/// > update(map, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(map, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in map: Map(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Map(k, v) { - map - |> get(key) - |> option.from_result - |> fun - |> insert(map, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Maps are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let map = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(map, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(map, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over map: Map(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - map - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 979c8c252ef..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,119 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > reverse(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > reverse(Lt) -/// Gt -/// ``` -/// -pub fn reverse(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index f1161cc1b13..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,233 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{Option} - -pub external type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -if erlang { - external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = - "gleam_stdlib" "compile_regex" -} - -if javascript { - external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = - "../gleam_stdlib.mjs" "compile_regex" -} - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -if erlang { - external fn do_check(Regex, String) -> Bool = - "gleam_stdlib" "regex_check" -} - -if javascript { - external fn do_check(Regex, String) -> Bool = - "../gleam_stdlib.mjs" "regex_check" -} - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -if erlang { - external fn do_split(Regex, String) -> List(String) = - "gleam_stdlib" "regex_split" -} - -if javascript { - fn do_split(regex, string) -> List(String) { - js_split(string, regex) - } - - external fn js_split(String, Regex) -> List(String) = - "../gleam_stdlib.mjs" "split" -} - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -if erlang { - external fn do_scan(Regex, String) -> List(Match) = - "gleam_stdlib" "regex_scan" -} - -if javascript { - external fn do_scan(Regex, String) -> List(Match) = - "../gleam_stdlib.mjs" "regex_scan" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index d53b72b690e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,483 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), None, Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index 24409869575..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/map.{Map} -import gleam/result - -if erlang { - // A list is used as the map value as an empty list has the smallest - // representation in Erlang's binary format - type Token = - List(Nil) - - const token = [] -} - -if javascript { - type Token = - Nil - - const token = Nil -} - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Map(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(map.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - map.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: map.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> map.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: map.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - map.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: map.new(), - with: fn(m, k) { map.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - map.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - for property: fn(member) -> Bool, -) -> Set(member) { - Set(map.filter(in: set.map, for: fn(m, _) { property(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(map.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case map.size(first.map) > map.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index b20e7268671..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,1046 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{Iterator} -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/order -import gleam/string_builder.{StringBuilder} - -if erlang { - import gleam/bit_string - import gleam/dynamic.{Dynamic} - import gleam/result -} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -if erlang { - external fn do_length(String) -> Int = - "string" "length" -} - -if javascript { - external fn do_length(String) -> Int = - "../gleam_stdlib.mjs" "string_length" -} - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -if erlang { - fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string - } -} - -if javascript { - fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat - } -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -if erlang { - external fn do_lowercase(String) -> String = - "string" "lowercase" -} - -if javascript { - external fn do_lowercase(String) -> String = - "../gleam_stdlib.mjs" "lowercase" -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -if erlang { - external fn do_uppercase(String) -> String = - "string" "uppercase" -} - -if javascript { - external fn do_uppercase(String) -> String = - "../gleam_stdlib.mjs" "uppercase" -} - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -if erlang { - external fn less_than(String, String) -> Bool = - "gleam_stdlib" "less_than" -} - -if javascript { - external fn less_than(String, String) -> Bool = - "../gleam_stdlib.mjs" "less_than" -} - -/// Takes a substring given a start and end grapheme indexes. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -if erlang { - external fn do_slice(String, Int, Int) -> String = - "string" "slice" -} - -if javascript { - fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat - } -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -pub fn crop(from string: String, before substring: String) -> String { - do_crop(string, substring) -} - -if erlang { - fn do_crop(string: String, substring: String) -> String { - string - |> erl_contains(substring) - |> dynamic.string() - |> result.unwrap(string) - } - - external fn erl_contains(String, String) -> Dynamic = - "string" "find" -} - -if javascript { - external fn do_crop(String, String) -> String = - "../gleam_stdlib.mjs" "crop_string" -} - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -pub fn contains(does haystack: String, contain needle: String) -> Bool { - do_contains(haystack, needle) -} - -if erlang { - fn do_contains(haystack: String, needle: String) -> Bool { - haystack - |> erl_contains(needle) - |> dynamic.bit_string - |> result.is_ok - } -} - -if javascript { - fn do_contains(haystack: String, needle: String) -> Bool { - index_of(haystack, needle) != -1 - } - - external fn index_of(String, String) -> Int = - "../gleam_stdlib.mjs" "index_of" -} - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -if erlang { - external fn do_starts_with(String, String) -> Bool = - "gleam_stdlib" "string_starts_with" -} - -if javascript { - external fn do_starts_with(String, String) -> Bool = - "../gleam_stdlib.mjs" "starts_with" -} - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -if erlang { - external fn do_ends_with(String, String) -> Bool = - "gleam_stdlib" "string_ends_with" -} - -if javascript { - external fn do_ends_with(String, String) -> Bool = - "../gleam_stdlib.mjs" "ends_with" -} - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -if erlang { - external fn erl_split(String, String) -> List(String) = - "string" "split" - - fn do_split_once( - x: String, - substring: String, - ) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } - } -} - -if javascript { - external fn do_split_once( - x: String, - substring: String, - ) -> Result(#(String, String), Nil) = - "../gleam_stdlib.mjs" "split_once" -} - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -if erlang { - fn do_trim(string: String) -> String { - erl_trim(string, Both) - } - - type Direction { - Leading - Trailing - Both - } - - external fn erl_trim(String, Direction) -> String = - "string" "trim" -} - -if javascript { - external fn do_trim(string: String) -> String = - "../gleam_stdlib.mjs" "trim" -} - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -if erlang { - fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) - } -} - -if javascript { - external fn do_trim_left(string: String) -> String = - "../gleam_stdlib.mjs" "trim_left" -} - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -if erlang { - fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) - } -} - -if javascript { - external fn do_trim_right(string: String) -> String = - "../gleam_stdlib.mjs" "trim_right" -} - -/// Splits a non-empty `String` into its head and tail. This lets you -/// pattern match on `String`s exactly as you would with lists. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -if erlang { - external fn do_pop_grapheme(string: String) -> Result(#(String, String), Nil) = - "gleam_stdlib" "string_pop_grapheme" -} - -if javascript { - external fn do_pop_grapheme(string: String) -> Result(#(String, String), Nil) = - "../gleam_stdlib.mjs" "pop_grapheme" -} - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -if erlang { - external fn unsafe_int_to_utf_codepoint(Int) -> UtfCodepoint = - "gleam_stdlib" "identity" -} - -if javascript { - external fn unsafe_int_to_utf_codepoint(Int) -> UtfCodepoint = - "../gleam_stdlib.mjs" "codepoint" -} - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -if erlang { - fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(bit_string.from_string(string), []) - |> list.reverse - } - - fn do_to_utf_codepoints_impl( - bit_string: BitString, - acc: List(UtfCodepoint), - ) -> List(UtfCodepoint) { - case bit_string { - <<first:utf8_codepoint, rest:binary>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - <<>> -> acc - } - } -} - -if javascript { - fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) - } - - external fn string_to_codepoint_integer_list(String) -> List(Int) = - "../gleam_stdlib.mjs" "string_to_codepoint_integer_list" -} - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { - do_from_utf_codepoints(utf_codepoints) -} - -if erlang { - fn do_from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { - let assert Ok(string) = - do_from_utf_codepoints_impl(utf_codepoints, bit_string.from_string("")) - |> bit_string.to_string - string - } - - fn do_from_utf_codepoints_impl( - utf_codepoints: List(UtfCodepoint), - acc: BitString, - ) -> BitString { - case utf_codepoints { - [first, ..rest] -> - do_from_utf_codepoints_impl( - rest, - <<acc:bit_string, first:utf8_codepoint>>, - ) - [] -> acc - } - } -} - -if javascript { - fn do_from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String { - utf_codepoint_list_to_string(utf_codepoints) - } - - external fn utf_codepoint_list_to_string(List(UtfCodepoint)) -> String = - "../gleam_stdlib.mjs" "utf_codepoint_list_to_string" -} - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > utf_codepoint_to_int(128013) |> to_utf_codepoint_int -/// 128013 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -if erlang { - external fn do_utf_codepoint_to_int(cp: UtfCodepoint) -> Int = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_utf_codepoint_to_int(cp: UtfCodepoint) -> Int = - "../gleam_stdlib.mjs" "utf_codepoint_to_int" -} - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -if javascript { - external fn do_inspect(term: anything) -> StringBuilder = - "../gleam.mjs" "inspect" -} - -if erlang { - external fn do_inspect(term: anything) -> StringBuilder = - "gleam_stdlib" "inspect" -} - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -pub fn byte_size(string: String) -> Int { - do_byte_size(string) -} - -if javascript { - external fn do_byte_size(String) -> Int = - "../gleam_stdlib.mjs" "byte_size" -} - -if erlang { - external fn do_byte_size(String) -> Int = - "erlang" "byte_size" -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 6137910c551..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,356 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub external type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -if erlang { - external fn do_append(StringBuilder, StringBuilder) -> StringBuilder = - "gleam_stdlib" "iodata_append" -} - -if javascript { - external fn do_append(StringBuilder, StringBuilder) -> StringBuilder = - "../gleam_stdlib.mjs" "add" -} - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -if erlang { - external fn do_from_strings(List(String)) -> StringBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from_strings(List(String)) -> StringBuilder = - "../gleam_stdlib.mjs" "join" -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -if erlang { - external fn do_concat(List(StringBuilder)) -> StringBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_concat(List(StringBuilder)) -> StringBuilder = - "../gleam_stdlib.mjs" "join" -} - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -if erlang { - external fn do_from_string(String) -> StringBuilder = - "gleam_stdlib" "identity" -} - -if javascript { - external fn do_from_string(String) -> StringBuilder = - "../gleam_stdlib.mjs" "identity" -} - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -if erlang { - external fn do_to_string(StringBuilder) -> String = - "unicode" "characters_to_binary" -} - -if javascript { - external fn do_to_string(StringBuilder) -> String = - "../gleam_stdlib.mjs" "identity" -} - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -if erlang { - external fn do_byte_size(StringBuilder) -> Int = - "erlang" "iolist_size" -} - -if javascript { - external fn do_byte_size(StringBuilder) -> Int = - "../gleam_stdlib.mjs" "length" -} - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -if erlang { - external fn do_lowercase(StringBuilder) -> StringBuilder = - "string" "lowercase" -} - -if javascript { - external fn do_lowercase(StringBuilder) -> StringBuilder = - "../gleam_stdlib.mjs" "lowercase" -} - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -if erlang { - external fn do_uppercase(StringBuilder) -> StringBuilder = - "string" "uppercase" -} - -if javascript { - external fn do_uppercase(StringBuilder) -> StringBuilder = - "../gleam_stdlib.mjs" "uppercase" -} - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -if erlang { - external fn do_reverse(StringBuilder) -> StringBuilder = - "string" "reverse" -} - -if javascript { - fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings - } - - external fn do_to_graphemes(string: String) -> List(String) = - "../gleam_stdlib.mjs" "graphemes" -} - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -if erlang { - type Direction { - All - } - - external fn erl_split(StringBuilder, String, Direction) -> List(StringBuilder) = - "string" "split" - - fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) - } -} - -if javascript { - external fn do_split( - builder: StringBuilder, - pattern: String, - ) -> List(StringBuilder) = - "../gleam_stdlib.mjs" "split" -} - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -if erlang { - fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, - ) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) - } - - external fn erl_replace( - StringBuilder, - String, - String, - Direction, - ) -> StringBuilder = - "string" "replace" -} - -if javascript { - external fn do_replace(StringBuilder, String, String) -> StringBuilder = - "../gleam_stdlib.mjs" "string_replace" -} - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -if erlang { - external fn do_is_equal(StringBuilder, StringBuilder) -> Bool = - "string" "equal" -} - -if javascript { - external fn do_is_equal(StringBuilder, StringBuilder) -> Bool = - "../gleam_stdlib.mjs" "equal" -} - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -if erlang { - external fn do_is_empty(StringBuilder) -> Bool = - "string" "is_empty" -} - -if javascript { - fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 3fdfc6d5b14..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,476 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/string -import gleam/string_builder.{StringBuilder} - -if javascript { - import gleam/pair - import gleam/regex - import gleam/result -} - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -if erlang { - external fn do_parse(String) -> Result(Uri, Nil) = - "gleam_stdlib" "uri_parse" -} - -if javascript { - fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) - } - - fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) - } - - fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } - } - - fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } - } - - // Split an authority into its userinfo, host and port parts. - fn split_authority( - authority: Option(String), - ) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } - } - - fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) - } - - fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -if erlang { - external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = - "gleam_stdlib" "parse_query" -} - -if javascript { - external fn do_parse_query(String) -> Result(List(#(String, String)), Nil) = - "../gleam_stdlib.mjs" "parse_query" -} - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -if erlang { - external fn do_percent_encode(String) -> String = - "gleam_stdlib" "percent_encode" -} - -if javascript { - external fn do_percent_encode(String) -> String = - "../gleam_stdlib.mjs" "percent_encode" -} - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -if erlang { - external fn do_percent_decode(String) -> Result(String, Nil) = - "gleam_stdlib" "percent_decode" -} - -if javascript { - external fn do_percent_decode(String) -> Result(String, Nil) = - "../gleam_stdlib.mjs" "percent_decode" -} - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - None, Some(_), None | None, None, None -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - Uri(scheme: None, host: None, ..) -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65890cc439c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,45 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars]). - --export([encode64/2, url_encode64/2, decode64/1, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - _pipe = encode64(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - Padded = case gleam@bit_string:byte_size( - gleam@bit_string:from_string(Encoded) - ) - rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - decode64(_pipe@2). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 8cc9d3263c3..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,63 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars]). - --export([append_builder/2, prepend_builder/2, new/0, concat/1, concat_bit_strings/1, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_string/1, prepend/2, append/2, to_bit_string/1, byte_size/1]). --export_type([bit_builder/0]). - --type bit_builder() :: any(). - --spec append_builder(bit_builder(), bit_builder()) -> bit_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bit_builder(), bit_builder()) -> bit_builder(). -prepend_builder(To, Prefix) -> - append_builder(Prefix, To). - --spec new() -> bit_builder(). -new() -> - gleam_stdlib:identity([]). - --spec concat(list(bit_builder())) -> bit_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> bit_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> bit_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bit_builder(), binary()) -> bit_builder(). -prepend_string(To, Prefix) -> - append_builder(from_string(Prefix), To). - --spec append_string(bit_builder(), binary()) -> bit_builder(). -append_string(To, Suffix) -> - append_builder(To, from_string(Suffix)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bit_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> bit_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bit_builder(), bitstring()) -> bit_builder(). -prepend(To, Prefix) -> - append_builder(from_bit_string(Prefix), To). - --spec append(bit_builder(), bitstring()) -> bit_builder(). -append(To, Suffix) -> - append_builder(To, from_bit_string(Suffix)). - --spec to_bit_string(bit_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bit_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 8896e3b7aed..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,56 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_string/1, byte_size/1, slice/3, concat/1, append/2, is_utf8/1, to_string/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_string_slice(String, Position, Length). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_string_concat(Bit_strings). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - concat([First, Second]). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 260e759517d..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,152 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), EIA, fun(() -> EIA)) -> EIA. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 61849a790e0..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,794 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars]). - --export([dynamic/1, decode1/2, from/1, unsafe_coerce/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, result/2, any/1, string/1, list/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([decode_error/0, dynamic/0, unknown_tuple/0]). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type dynamic() :: any(). - --type unknown_tuple() :: any(). - --spec dynamic(dynamic()) -> {ok, dynamic()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((CSZ) -> CTA), - fun((dynamic()) -> {ok, CSZ} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTA} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec from(any()) -> dynamic(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec bit_string(dynamic()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_string(Data) -> - gleam_stdlib:decode_bit_string(Data). - --spec classify(dynamic()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec at_least_decode_tuple_error(integer(), dynamic()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec float(dynamic()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic()) -> {ok, list(dynamic())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic()) -> {ok, CPW} | {error, list(decode_error())})) -> fun((dynamic()) -> {ok, - gleam@option:option(CPW)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec result( - fun((dynamic()) -> {ok, CPK} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CPM} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {ok, CPK} | {error, CPM}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec any(list(fun((dynamic()) -> {ok, CSV} | {error, list(decode_error())}))) -> fun((dynamic()) -> {ok, - CSV} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec string(dynamic()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec decode_string(dynamic()) -> {ok, binary()} | {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_string(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_string:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitString"/utf8>>, - []}]} - end end - ). - --spec map_errors( - {ok, COU} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, COU} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec list(fun((dynamic()) -> {ok, CPR} | {error, list(decode_error())})) -> fun((dynamic()) -> {ok, - list(CPR)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec field( - any(), - fun((dynamic()) -> {ok, CQB} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CQB} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic()) -> {ok, CQF} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, gleam@option:option(CQF)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic()) -> {ok, CQJ} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CQJ} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic()) -> {ok, CQV} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CQX} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CQV, CQX}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic()) -> {ok, CRA} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRC} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRE} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CRA, CRC, CRE}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic()) -> {ok, CRH} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRL} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRN} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CRH, CRJ, CRL, CRN}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic()) -> {ok, CRQ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRS} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRU} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRW} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CRY} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CRQ, CRS, CRU, CRW, CRY}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic()) -> {ok, CSB} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSF} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSH} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSL} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, {CSB, CSD, CSF, CSH, CSJ, CSL}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec map( - fun((dynamic()) -> {ok, CSO} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CSQ} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, gleam@map:map_(CSO, CSQ)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@map:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@map:from_list(Pairs)} end - ) - end - ) - end. - --spec decode2( - fun((CTD, CTE) -> CTF), - fun((dynamic()) -> {ok, CTD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTE} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTF} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:flatten([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((CTJ, CTK, CTL) -> CTM), - fun((dynamic()) -> {ok, CTJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTK} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTL} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTM} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((CTR, CTS, CTT, CTU) -> CTV), - fun((dynamic()) -> {ok, CTR} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTS} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTT} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CTU} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CTV} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((CUB, CUC, CUD, CUE, CUF) -> CUG), - fun((dynamic()) -> {ok, CUB} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUC} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUE} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUF} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CUG} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((CUN, CUO, CUP, CUQ, CUR, CUS) -> CUT), - fun((dynamic()) -> {ok, CUN} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUO} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUP} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUQ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUR} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CUS} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CUT} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((CVB, CVC, CVD, CVE, CVF, CVG, CVH) -> CVI), - fun((dynamic()) -> {ok, CVB} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVC} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVD} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVE} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVF} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVG} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVH} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CVI} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((CVR, CVS, CVT, CVU, CVV, CVW, CVX, CVY) -> CVZ), - fun((dynamic()) -> {ok, CVR} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVS} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVT} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVU} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVV} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVW} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVX} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CVY} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CVZ} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((CWJ, CWK, CWL, CWM, CWN, CWO, CWP, CWQ, CWR) -> CWS), - fun((dynamic()) -> {ok, CWJ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWK} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWL} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWM} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWN} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWO} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWP} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWQ} | {error, list(decode_error())}), - fun((dynamic()) -> {ok, CWR} | {error, list(decode_error())}) -) -> fun((dynamic()) -> {ok, CWS} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:flatten( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index f98da7c1365..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,193 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars]). - --export([compare/2, min/2, max/2, clamp/3, absolute_value/1, loosely_compare/3, loosely_equals/3, negate/1, divide/2, add/2, multiply/2, subtract/2, parse/1, to_string/1, ceiling/1, floor/1, round/1, truncate/1, power/2, square_root/1, random/2, sum/1, product/1]). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= 0.0 of - true -> - X; - - _ -> - 0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - 0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - 0.0 -> 0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > 0.0, - case ((Base < 0.0) andalso Fractional) orelse ((Base =:= 0.0) andalso (Exponent - < 0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec random(float(), float()) -> float(). -random(Boundary_a, Boundary_b) -> - {Min, Max} = case {Boundary_a, Boundary_b} of - {A, B} when A =< B -> - {A, B}; - - {A@1, B@1} when A@1 > B@1 -> - {B@1, A@1} - end, - case {Min, Max} of - {Min@1, _} when Min@1 =:= Max -> - Min@1; - - {Min@2, Max@1} -> - (rand:uniform() * (Max@1 - Min@2)) + Min@2 - end. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index 1b8c6d2168c..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((ESR) -> ESS), fun((ESS) -> EST)) -> fun((ESR) -> EST). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((ESU, ESV) -> ESW)) -> fun((ESU) -> fun((ESV) -> ESW)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((ESY, ESZ, ETA) -> ETB)) -> fun((ESY) -> fun((ESZ) -> fun((ETA) -> ETB))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((ETD, ETE, ETF, ETG) -> ETH)) -> fun((ETD) -> fun((ETE) -> fun((ETF) -> fun((ETG) -> ETH)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((ETJ, ETK, ETL, ETM, ETN) -> ETO)) -> fun((ETJ) -> fun((ETK) -> fun((ETL) -> fun((ETM) -> fun((ETN) -> ETO))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((ETQ, ETR, ETS, ETT, ETU, ETV) -> ETW)) -> fun((ETQ) -> fun((ETR) -> fun((ETS) -> fun((ETT) -> fun((ETU) -> fun((ETV) -> ETW)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((ETY, ETZ) -> EUA)) -> fun((ETZ, ETY) -> EUA). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(EUB) -> EUB. -identity(X) -> - X. - --spec constant(EUC) -> fun((any()) -> EUC). -constant(Value) -> - fun(_) -> Value end. - --spec tap(EUE, fun((EUE) -> any())) -> EUE. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((EUG) -> EUH), EUG) -> EUH. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((EUI, EUJ) -> EUK), EUI, EUJ) -> EUK. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((EUL, EUM, EUN) -> EUO), EUL, EUM, EUN) -> EUO. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 4d3c513a1b2..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,323 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars]). - --export([absolute_value/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, random/2, sum/1, product/1, digits/2, undigits/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec random(integer(), integer()) -> integer(). -random(Boundary_a, Boundary_b) -> - {Min, Max} = case {Boundary_a, Boundary_b} of - {A, B} when A =< B -> - {A, B}; - - {A@1, B@1} when A@1 > B@1 -> - {B@1, A@1} - end, - Min@1 = begin - _pipe = to_float(Min), - gleam@float:ceiling(_pipe) - end, - Max@1 = begin - _pipe@1 = to_float(Max), - gleam@float:floor(_pipe@1) - end, - _pipe@2 = gleam@float:random(Min@1, Max@1), - _pipe@3 = gleam@float:floor(_pipe@2), - gleam@float:round(_pipe@3). - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 16dced85238..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ECD) -> ECD. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index 82b4ff1ca55..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,707 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars]). - --export([step/1, empty/0, once/1, single/1, first/1, unfold/2, repeatedly/1, repeat/1, from_list/1, range/2, iterate/2, transform/3, fold/3, run/1, to_list/1, reduce/2, last/1, take/2, drop/2, at/2, map/2, group/2, each/2, append/2, flatten/1, flat_map/2, cycle/1, filter/2, find/2, index/1, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, interleave/2, fold_until/3, try_fold/3, length/1]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BMM) :: stop | {continue, BMM, fun(() -> action(BMM))}. - --opaque iterator(BMN) :: {iterator, fun(() -> action(BMN))}. - --type step(BMO, BMP) :: {next, BMO, BMP} | done. - --type chunk(BMQ, BMR) :: {another_by, - list(BMQ), - BMR, - BMQ, - fun(() -> action(BMQ))} | - {last_by, list(BMQ)}. - --type sized_chunk(BMS) :: {another, list(BMS), fun(() -> action(BMS))} | - {last, list(BMS)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec step(iterator(BOL)) -> step(BOL, iterator(BOL)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec update_group_with(BTZ) -> fun((gleam@option:option(list(BTZ))) -> list(BTZ)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> BVB)) -> iterator(BVB). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec single(BVD) -> iterator(BVD). -single(Elem) -> - once(fun() -> Elem end). - --spec first(iterator(BWL)) -> {ok, BWL} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec do_unfold(BMV, fun((BMV) -> step(BMW, BMV))) -> fun(() -> action(BMW)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BNA, fun((BNA) -> step(BNB, BNA))) -> iterator(BNB). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BNF)) -> iterator(BNF). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BNH) -> iterator(BNH). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BNJ)) -> iterator(BNJ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec iterate(BRD, fun((BRD) -> BRD)) -> iterator(BRD). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_transform( - fun(() -> action(BNM)), - BNO, - fun((BNO, BNM) -> step(BNP, BNO)) -) -> fun(() -> action(BNP)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BNT), BNV, fun((BNV, BNT) -> step(BNW, BNV))) -> iterator(BNW). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BOA)), fun((BOC, BOA) -> BOC), BOC) -> BOC. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BOD), BOF, fun((BOF, BOD) -> BOF)) -> BOF. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BOI)) -> list(BOI). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec reduce(iterator(BUR), fun((BUR, BUR) -> BUR)) -> {ok, BUR} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(BUV)) -> {ok, BUV} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec do_take(fun(() -> action(BOQ)), integer()) -> fun(() -> action(BOQ)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BOT), integer()) -> iterator(BOT). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BOW)), integer()) -> action(BOW). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BOZ), integer()) -> iterator(BOZ). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec at(iterator(BWP), integer()) -> {ok, BWP} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_map(fun(() -> action(BPC)), fun((BPC) -> BPE)) -> fun(() -> action(BPE)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BPG), fun((BPG) -> BPI)) -> iterator(BPI). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec group_updater(fun((BUD) -> BUE)) -> fun((gleam@map:map_(BUE, list(BUD)), BUD) -> gleam@map:map_(BUE, list(BUD))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@map:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(BUL), fun((BUL) -> BUN)) -> gleam@map:map_(BUN, list(BUL)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@map:new(), group_updater(Key)), - gleam@map:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec each(iterator(BWX), fun((BWX) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec do_append(fun(() -> action(BPK)), fun(() -> action(BPK))) -> action(BPK). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BPO), iterator(BPO)) -> iterator(BPO). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BPS)))) -> action(BPS). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BPW))) -> iterator(BPW). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec flat_map(iterator(BQA), fun((BQA) -> iterator(BQC))) -> iterator(BQC). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec cycle(iterator(BQL)) -> iterator(BQL). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_filter(fun(() -> action(BQF)), fun((BQF) -> boolean())) -> action(BQF). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BQI), fun((BQI) -> boolean())) -> iterator(BQI). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_find(fun(() -> action(BQP)), fun((BQP) -> boolean())) -> {ok, BQP} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BQT), fun((BQT) -> boolean())) -> {ok, BQT} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BQX)), integer()) -> fun(() -> action({integer(), - BQX})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BRA)) -> iterator({integer(), BRA}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec do_take_while(fun(() -> action(BRF)), fun((BRF) -> boolean())) -> fun(() -> action(BRF)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BRI), fun((BRI) -> boolean())) -> iterator(BRI). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BRL)), fun((BRL) -> boolean())) -> action(BRL). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BRO), fun((BRO) -> boolean())) -> iterator(BRO). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BRR)), fun((BRT, BRR) -> BRT), BRT) -> fun(() -> action(BRT)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BRV), BRX, fun((BRX, BRV) -> BRX)) -> iterator(BRX). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BRZ)), fun(() -> action(BSB))) -> fun(() -> action({BRZ, - BSB})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BSE), iterator(BSG)) -> iterator({BSE, BSG}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BSJ)), fun((BSJ) -> BSL), BSL, list(BSJ)) -> chunk(BSJ, BSL). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BSP)), fun((BSP) -> BSR), BSR, BSP) -> action(list(BSP)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BSU), fun((BSU) -> any())) -> iterator(list(BSU)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BSZ)), integer(), list(BSZ)) -> sized_chunk(BSZ). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BTD)), integer()) -> fun(() -> action(list(BTD))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BTH), integer()) -> iterator(list(BTH)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BTL)), BTL) -> action(BTL). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BTO), BTO) -> iterator(BTO). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BTR)), fun((BTR) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BTT), fun((BTT) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(BTV)), fun((BTV) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(BTX), fun((BTX) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec do_interleave(fun(() -> action(BVF)), fun(() -> action(BVF))) -> action(BVF). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(BVJ), iterator(BVJ)) -> iterator(BVJ). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(BVN)), - fun((BVP, BVN) -> gleam@list:continue_or_stop(BVP)), - BVP -) -> BVP. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(BVR), - BVT, - fun((BVT, BVR) -> gleam@list:continue_or_stop(BVT)) -) -> BVT. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(BVV)), - fun((BVX, BVV) -> {ok, BVX} | {error, BVY}), - BVX -) -> {ok, BVX} | {error, BVY}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(BWD), BWF, fun((BWF, BWD) -> {ok, BWF} | {error, BWG})) -> {ok, - BWF} | - {error, BWG}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index 6d28be2ad8e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1082 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_empty/1, first/1, rest/1, new/0, prepend/2, length/1, reverse/1, append/2, contains/2, map/2, fold/3, group/2, map_fold/3, reduce/2, last/1, filter/2, filter_map/2, index_map/2, try_map/2, drop/2, at/2, take/2, flatten/1, flat_map/2, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, key_find/2, all/2, any/2, zip/2, strict_zip/2, window_by_2/1, unzip/1, intersperse/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, drop_while/2, take_while/2, chunk/2, sized_chunk/2, scan/3, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(SY) :: {continue, SY} | {stop, SY}. - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec first(list(TI)) -> {ok, TI} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(TM)) -> {ok, list(TM)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec new() -> list(any()). -new() -> - []. - --spec prepend(list(XH), XH) -> list(XH). -prepend(List, Item) -> - [Item | List]. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(TB)) -> list(TB). -reverse(Xs) -> - lists:reverse(Xs). - --spec append(list(XD), list(XD)) -> list(XD). -append(First, Second) -> - lists:append(First, Second). - --spec contains(list(TG), TG) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec do_map(list(VB), fun((VB) -> VD), list(VD)) -> list(VD). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(VG), fun((VG) -> VI)) -> list(VI). -map(List, Fun) -> - do_map(List, Fun, []). - --spec update_group(fun((TR) -> TS)) -> fun((gleam@map:map_(TS, list(TR)), TR) -> gleam@map:map_(TS, list(TR))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@map:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@map:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@map:insert(Groups, F(Elem), [Elem]) - end end. - --spec fold(list(YC), YE, fun((YE, YC) -> YE)) -> YE. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(TZ), fun((TZ) -> UB)) -> gleam@map:map_(UB, list(TZ)). -group(List, Key) -> - fold(List, gleam@map:new(), update_group(Key)). - --spec map_fold(list(VK), VM, fun((VM, VK) -> {VM, VN})) -> {VM, list(VN)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec reduce(list(AHZ), fun((AHZ, AHZ) -> AHZ)) -> {ok, AHZ} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec last(list(AIM)) -> {ok, AIM} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec do_filter(list(UF), fun((UF) -> boolean()), list(UF)) -> list(UF). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(UJ), fun((UJ) -> boolean())) -> list(UJ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(UM), fun((UM) -> {ok, UO} | {error, any()}), list(UO)) -> list(UO). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(UU), fun((UU) -> {ok, UW} | {error, any()})) -> list(UW). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_index_map(list(VP), fun((integer(), VP) -> VR), integer(), list(VR)) -> list(VR). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(VU), fun((integer(), VU) -> VW)) -> list(VW). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(VY), fun((VY) -> {ok, WA} | {error, WB}), list(WA)) -> {ok, - list(WA)} | - {error, WB}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(WI), fun((WI) -> {ok, WK} | {error, WL})) -> {ok, list(WK)} | - {error, WL}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(WR), integer()) -> list(WR). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec at(list(ABY), integer()) -> {ok, ABY} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec do_take(list(WU), integer(), list(WU)) -> list(WU). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(WY), integer()) -> list(WY). -take(List, N) -> - do_take(List, N, []). - --spec reverse_and_prepend(list(XK), list(XK)) -> list(XK). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_flatten(list(list(XO)), list(XO)) -> list(XO). -do_flatten(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_flatten(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec flatten(list(list(XT))) -> list(XT). -flatten(Lists) -> - do_flatten(Lists, []). - --spec flat_map(list(XX), fun((XX) -> list(XZ))) -> list(XZ). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - flatten(_pipe). - --spec fold_right(list(YF), YH, fun((YH, YF) -> YH)) -> YH. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold(list(YI), YK, fun((YK, YI, integer()) -> YK), integer()) -> YK. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(YL), YN, fun((YN, YL, integer()) -> YN)) -> YN. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(YO), YQ, fun((YQ, YO) -> {ok, YQ} | {error, YR})) -> {ok, - YQ} | - {error, YR}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(YW), YY, fun((YY, YW) -> continue_or_stop(YY))) -> YY. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AAA), fun((AAA) -> boolean())) -> {ok, AAA} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AAE), fun((AAE) -> {ok, AAG} | {error, any()})) -> {ok, AAG} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec key_find(list({ADV, ADW}), ADV) -> {ok, ADW} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec all(list(AAM), fun((AAM) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AAO), fun((AAO) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AAQ), list(AAS), list({AAQ, AAS})) -> list({AAQ, AAS}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AAW), list(AAY)) -> list({AAW, AAY}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(ABB), list(ABD)) -> {ok, list({ABB, ABD})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec window_by_2(list(AGO)) -> list({AGO, AGO}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec do_unzip(list({ABM, ABN}), list(ABM), list(ABN)) -> {list(ABM), list(ABN)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({ABM, ABN})) -> {list(ABM), list(ABN)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(ABR), ABR, list(ABR)) -> list(ABR). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(ABV), ABV) -> list(ABV). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec unique(list(ACC)) -> list(ACC). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(ACF), - list(ACF), - list(ACF), - fun((ACF, ACF) -> gleam@order:order()) -) -> list(ACF). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end - end. - --spec merge_down( - integer(), - integer(), - list(ACK), - list(ACK), - list(ACK), - fun((ACK, ACK) -> gleam@order:order()) -) -> list(ACK). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end - end. - --spec merge_sort( - list(ACP), - integer(), - fun((ACP, ACP) -> gleam@order:order()), - boolean() -) -> list(ACP). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(ACS), fun((ACS, ACS) -> gleam@order:order())) -> list(ACS). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec do_shuffle_by_pair_indexes(list({float(), AJO})) -> list({float(), AJO}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - reverse([Stop | Acc]); - - gt -> - tail_recursive_range(Start - 1, Stop, [Start | Acc]); - - lt -> - tail_recursive_range(Start + 1, Stop, [Start | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(ACY, integer(), list(ACY)) -> list(ACY). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(ADB, integer()) -> list(ADB). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(ADD), integer(), list(ADD)) -> {list(ADD), list(ADD)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(ADI), integer()) -> {list(ADI), list(ADI)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(ADM), fun((ADM) -> boolean()), list(ADM)) -> {list(ADM), - list(ADM)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(ADR), fun((ADR) -> boolean())) -> {list(ADR), list(ADR)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec do_pop(list(AEE), fun((AEE) -> boolean()), list(AEE)) -> {ok, - {AEE, list(AEE)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AEE), fun((AEE) -> boolean())) -> {ok, {AEE, list(AEE)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(AEN), fun((AEN) -> {ok, AEP} | {error, any()}), list(AEN)) -> {ok, - {AEP, list(AEN)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AEN), fun((AEN) -> {ok, AEP} | {error, any()})) -> {ok, - {AEP, list(AEN)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AEW, AEX}), AEW) -> {ok, {AEX, list({AEW, AEX})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AFC, AFD}), AFC, AFD) -> list({AFC, AFD}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AFG), fun((AFG) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AFJ), fun((AFJ) -> {ok, any()} | {error, AFM})) -> {ok, nil} | - {error, AFM}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(AFW), fun((AFW) -> boolean()), list(AFW), list(AFW)) -> {list(AFW), - list(AFW)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(AFW), fun((AFW) -> boolean())) -> {list(AFW), list(AFW)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(AGA)) -> list(list(AGA)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - flatten(_pipe@5) - end. - --spec do_window(list(list(AGE)), list(AGE), integer()) -> list(list(AGE)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(AGK), integer()) -> list(list(AGK)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec drop_while(list(AGR), fun((AGR) -> boolean())) -> list(AGR). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AGU), fun((AGU) -> boolean()), list(AGU)) -> list(AGU). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AGY), fun((AGY) -> boolean())) -> list(AGY). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AHB), fun((AHB) -> AHD), AHD, list(AHB), list(list(AHB))) -> list(list(AHB)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AHJ), fun((AHJ) -> any())) -> list(list(AHJ)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AHO), - integer(), - integer(), - list(AHO), - list(list(AHO)) -) -> list(list(AHO)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(AHV), integer()) -> list(list(AHV)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec do_scan(list(AID), AIF, list(AIF), fun((AIF, AID) -> AIF)) -> list(AIF). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(AII), AIK, fun((AIK, AII) -> AIK)) -> list(AIK). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec combinations(list(AIQ), integer()) -> list(list(AIQ)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AIU)) -> list(list({AIU, AIU})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AIY)) -> list({AIY, AIY}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - flatten(_pipe). - --spec transpose(list(list(AJF))) -> list(list(AJF)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - flatten(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AJB))) -> list(AJB). -interleave(List) -> - _pipe = transpose(List), - flatten(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AJK}), list(AJK)) -> list(AJK). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - _ -> - [Elem_pair | Enumerable] = List, - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec shuffle(list(AJR)) -> list(AJR). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index a15f5599921..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, update/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, fold/3]). --export_type([map_/2]). - --type map_(Key, Value) :: any() | {gleam_phantom, Key, Value}. - --spec size(map_(any(), any())) -> integer(). -size(Map) -> - maps:size(Map). - --spec to_list(map_(KF, KG)) -> list({KF, KG}). -to_list(Map) -> - maps:to_list(Map). - --spec from_list(list({KK, KL})) -> map_(KK, KL). -from_list(List) -> - maps:from_list(List). - --spec has_key(map_(KP, any()), KP) -> boolean(). -has_key(Map, Key) -> - maps:is_key(Key, Map). - --spec new() -> map_(any(), any()). -new() -> - maps:new(). - --spec get(map_(KX, KY), KX) -> {ok, KY} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(map_(LD, LE), LD, LE) -> map_(LD, LE). -insert(Map, Key, Value) -> - maps:put(Key, Value, Map). - --spec update(map_(NI, NJ), NI, fun((gleam@option:option(NJ)) -> NJ)) -> map_(NI, NJ). -update(Map, Key, Fun) -> - _pipe = Map, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Map, Key, _pipe@3). - --spec map_values(map_(LJ, LK), fun((LJ, LK) -> LN)) -> map_(LJ, LN). -map_values(Map, Fun) -> - maps:map(Fun, Map). - --spec keys(map_(LQ, any())) -> list(LQ). -keys(Map) -> - maps:keys(Map). - --spec values(map_(any(), LW)) -> list(LW). -values(Map) -> - maps:values(Map). - --spec filter(map_(MA, MB), fun((MA, MB) -> boolean())) -> map_(MA, MB). -filter(Map, Property) -> - maps:filter(Property, Map). - --spec take(map_(MG, MH), list(MG)) -> map_(MG, MH). -take(Map, Desired_keys) -> - maps:with(Desired_keys, Map). - --spec merge(map_(MN, MO), map_(MN, MO)) -> map_(MN, MO). -merge(Map, New_entries) -> - maps:merge(Map, New_entries). - --spec delete(map_(MV, MW), MV) -> map_(MV, MW). -delete(Map, Key) -> - maps:remove(Key, Map). - --spec drop(map_(NB, NC), list(NB)) -> map_(NB, NC). -drop(Map, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Map; - - [X | Xs] -> - drop(delete(Map, X), Xs) - end. - --spec do_fold(list({NP, NQ}), NS, fun((NS, NP, NQ) -> NS)) -> NS. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(map_(NT, NU), NX, fun((NX, NT, NU) -> NX)) -> NX. -fold(Map, Initial, Fun) -> - _pipe = Map, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 04e9e354829..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, all/1, values/1]). --export_type([option/1]). - --type option(FI) :: {some, FI} | none. - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(FY), GB) -> {ok, FY} | {error, GB}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, GE} | {error, any()}) -> option(GE). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(GJ), GJ) -> GJ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(GL), fun(() -> GL)) -> GL. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(GN), fun((GN) -> GP)) -> option(GP). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(GR))) -> option(GR). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(GV), fun((GV) -> option(GX))) -> option(GX). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(HA), option(HA)) -> option(HA). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(HE), fun(() -> option(HE))) -> option(HE). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_all(list(option(FJ)), list(FJ)) -> option(list(FJ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(FP))) -> option(list(FP)). -all(List) -> - do_all(List, []). - --spec do_values(list(option(HI)), list(HI)) -> list(HI). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(HN))) -> list(HN). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index 2f7d2e07100..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars]). - --export([reverse/1, to_int/1, compare/2, max/2, min/2]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec reverse(order()) -> order(). -reverse(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2659d329392..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({ET, any()}) -> ET. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), EW}) -> EW. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({EX, EY}) -> {EY, EX}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({EZ, FA}, fun((EZ) -> FB)) -> {FB, FA}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({FC, FD}, fun((FD) -> FE)) -> {FC, FE}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(FF, FG) -> {FF, FG}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index 6738efd4d7e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, reverse/1, pop_back/1, pop_front/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(ECR) :: {queue, list(ECR), list(ECR)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(ECU)) -> queue(ECU). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(ECX)) -> list(ECX). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EDE), EDE) -> queue(EDE). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EDH), EDH) -> queue(EDH). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec reverse(queue(EDU)) -> queue(EDU). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec pop_back(queue(EDK)) -> {ok, {EDK, queue(EDK)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EDP)) -> {ok, {EDP, queue(EDP)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec check_equal( - list(EDX), - list(EDX), - list(EDX), - list(EDX), - fun((EDX, EDX) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EEC), queue(EEC), fun((EEC, EEC) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EEF), queue(EEF)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index f9c649685ee..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([match/0, compile_error/0, options/0, regex/0]). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --type regex() :: any(). - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index e6c72ebab25..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, replace/2, replace_error/2, values/1, try_recover/2, partition/1]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BCT} | {error, BCU}, fun((BCT) -> BCX)) -> {ok, BCX} | - {error, BCU}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BDA} | {error, BDB}, fun((BDB) -> BDE)) -> {ok, BDA} | - {error, BDE}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BDH} | {error, BDI}} | {error, BDI}) -> {ok, BDH} | - {error, BDI}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BDP} | {error, BDQ}, fun((BDP) -> {ok, BDT} | {error, BDQ})) -> {ok, - BDT} | - {error, BDQ}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BDY} | {error, BDZ}, fun((BDY) -> {ok, BEC} | {error, BDZ})) -> {ok, - BEC} | - {error, BDZ}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BEH} | {error, any()}, BEH) -> BEH. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BEL} | {error, any()}, fun(() -> BEL)) -> BEL. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BEQ}, BEQ) -> BEQ. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BET} | {error, BET}) -> BET. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BEW} | {error, any()}) -> {ok, BEW} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BFC} | {error, BFD}, {ok, BFC} | {error, BFD}) -> {ok, BFC} | - {error, BFD}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BFK} | {error, BFL}, fun(() -> {ok, BFK} | {error, BFL})) -> {ok, - BFK} | - {error, BFL}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BFS} | {error, BFT})) -> {ok, list(BFS)} | {error, BFT}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec replace({ok, any()} | {error, BGQ}, BGT) -> {ok, BGT} | {error, BGQ}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BGW} | {error, any()}, BHA) -> {ok, BGW} | {error, BHA}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BHD} | {error, any()})) -> list(BHD). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BHJ} | {error, BHK}, - fun((BHK) -> {ok, BHJ} | {error, BHN}) -) -> {ok, BHJ} | {error, BHN}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. - --spec do_partition(list({ok, BGH} | {error, BGI}), list(BGH), list(BGI)) -> {list(BGH), - list(BGI)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BGA} | {error, BGB})) -> {list(BGA), list(BGB)}. -partition(Results) -> - do_partition(Results, [], []). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index bc905e1881e..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOC) :: {set, gleam@map:map_(EOC, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@map:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@map:size(erlang:element(2, Set)). - --spec insert(set(EOI), EOI) -> set(EOI). -insert(Set, Member) -> - {set, gleam@map:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOL), EOL) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@map:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EON), EON) -> set(EON). -delete(Set, Member) -> - {set, gleam@map:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOQ)) -> list(EOQ). -to_list(Set) -> - gleam@map:keys(erlang:element(2, Set)). - --spec from_list(list(EOT)) -> set(EOT). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@map:new(), - fun(M, K) -> gleam@map:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EOW), EOY, fun((EOY, EOW) -> EOY)) -> EOY. -fold(Set, Initial, Reducer) -> - gleam@map:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EOZ), fun((EOZ) -> boolean())) -> set(EOZ). -filter(Set, Property) -> - {set, - gleam@map:filter(erlang:element(2, Set), fun(M, _) -> Property(M) end)}. - --spec drop(set(EPC), list(EPC)) -> set(EPC). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPG), list(EPG)) -> set(EPG). -take(Set, Desired) -> - {set, gleam@map:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPK), set(EPK)) -> {set(EPK), set(EPK)}. -order(First, Second) -> - case gleam@map:size(erlang:element(2, First)) > gleam@map:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPP), set(EPP)) -> set(EPP). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EPT), set(EPT)) -> set(EPT). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 275e67ea190..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,393 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_empty/1, reverse/1, replace/3, append/2, concat/1, repeat/2, join/2, to_option/1, length/1, lowercase/1, uppercase/1, compare/2, slice/3, drop_left/2, drop_right/2, pad_left/3, pad_right/3, crop/2, contains/2, starts_with/2, ends_with/2, split_once/2, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, first/1, last/1, capitalise/1, utf_codepoint/1, utf_codepoint_to_int/1, inspect/1, byte_size/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_crop(binary(), binary()) -> binary(). -do_crop(String, Substring) -> - _pipe = String, - _pipe@1 = string:find(_pipe, Substring), - _pipe@2 = gleam@dynamic:string(_pipe@1), - gleam@result:unwrap(_pipe@2, String). - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - do_crop(String, Substring). - --spec do_contains(binary(), binary()) -> boolean(). -do_contains(Haystack, Needle) -> - _pipe = Haystack, - _pipe@1 = string:find(_pipe, Needle), - _pipe@2 = gleam@dynamic:bit_string(_pipe@1), - gleam@result:is_ok(_pipe@2). - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - do_contains(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_string, Acc) -> - case Bit_string of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - <<>> -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(gleam@bit_string:from_string(String), []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec do_from_utf_codepoints_impl(list(integer()), bitstring()) -> bitstring(). -do_from_utf_codepoints_impl(Utf_codepoints, Acc) -> - case Utf_codepoints of - [First | Rest] -> - do_from_utf_codepoints_impl(Rest, <<Acc/bitstring, First/utf8>>); - - [] -> - Acc - end. - --spec do_from_utf_codepoints(list(integer())) -> binary(). -do_from_utf_codepoints(Utf_codepoints) -> - _assert_subject = begin - _pipe = do_from_utf_codepoints_impl( - Utf_codepoints, - gleam@bit_string:from_string(<<""/utf8>>) - ), - gleam@bit_string:to_string(_pipe) - end, - {ok, String} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/string"/utf8>>, - function => <<"do_from_utf_codepoints"/utf8>>, - line => 860}) - end, - String. - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - do_from_utf_codepoints(Utf_codepoints). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 47364425ad7..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, join/2, to_string/1, byte_size/1, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([direction/0, string_builder/0]). - --type direction() :: all. - --type string_builder() :: any(). - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index 692193fd0c6..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,255 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_string/1, origin/1, parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {none, {some, _}, none} -> - Parts@4; - - {none, none, none} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(EJD)) -> list(EJD). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - {uri, none, _, none, _, _, _, _} -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index ed0fcac3f46..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,28 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.29.2"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index 6967cf4a607..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,441 +0,0 @@ --module(gleam_stdlib). - --export([map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, - decode_field/2, parse_int/1, parse_float/1, less_than/2, - string_pop_grapheme/1, string_starts_with/2, wrap_list/1, - string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_string_int_to_u32/1, bit_string_int_from_u32/1, decode_result/1, - bit_string_slice/3, decode_bit_string/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_string_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, - print/1, println/1, print_error/1, println_error/1, inspect/1, - float_to_string/1, int_from_base_string/2]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitString">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_string(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_string(Data) -> decode_error_msg(<<"BitString">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_string_concat(BitStrings) -> - list_to_bitstring(BitStrings). - -bit_string_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_string_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_string_int_to_u32(_) -> - {error, nil}. - -bit_string_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_string_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:badarith -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(Any) when is_atom(Any) -> - lists:map( - fun(Part) -> - [Head | Tail] = string:next_grapheme(unicode:characters_to_binary(Part)), - [string:uppercase([Head]), Tail] - end, - re:split(erlang:atom_to_list(Any), "_+", [{return, iodata}]) - ); -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - -inspect_list([]) -> - {proper, []}; -inspect_list([Head]) -> - {proper, [inspect(Head)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<Head/utf8, Rest/binary>> -> - Escaped = case Head of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 4fd06d9b563..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,739 +0,0 @@ -import { - BitString, - Error, - List, - Ok, - Result, - UtfCodepoint, - inspect, - stringBits, - toBitString, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import PMap from "./persistent-hash-map.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - return List.fromArray( - Array.from(graphemes_iterator(string)).map((item) => item.segment) - ); -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs) { - return xs.toArray().join(""); -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function index_of(haystack, needle) { - return haystack.indexOf(needle) | 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_string_from_string(string) { - return toBitString([stringBits(string)]); -} - -export function bit_string_concat(bit_strings) { - return toBitString(bit_strings.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_string_to_string(bit_string) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_string.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_string_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitString(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return PMap.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_string) { - const aBytes = bit_string.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitString(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (Result.isResult(data)) { - return "Result"; - } else if (List.isList(data)) { - return "List"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (BitString.isBitString(data)) { - return "BitString"; - } else if (data instanceof PMap) { - return "Map"; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_string(data) { - if (BitString.isBitString(data)) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitString(data)); - } - return decoder_error("BitString", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - let list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!List.isList(data)) return; - - let elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (current.isEmpty()) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && current.isEmpty()) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return List.isList(data) ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return Result.isResult(data) ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof PMap) { - return new Ok(PMap.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(PMap.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof PMap || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} diff --git a/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs b/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs deleted file mode 100644 index ff849d8def9..00000000000 --- a/test-community-packages-javascript/build/packages/gleam_stdlib/src/persistent-hash-map.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of map size and clean up the API - * @template K,V - */ -export default class PMap { - /** - * @template V - * @param {Record<string,V>} o - * @returns {PMap<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type PMap<string,V> */ - let m = PMap.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {PMap<K,V>} - */ - static fromMap(o) { - /** @type PMap<K,V> */ - let m = PMap.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new PMap(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {PMap<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new PMap(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {PMap<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return PMap.new(); - } - return new PMap(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof PMap)) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/README.md b/test-community-packages-javascript/build/packages/gleamy_structures/README.md deleted file mode 100644 index 4d7b812da21..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# gleamy_structures - -[![Package Version](https://img.shields.io/hexpm/v/gleamy_structures)](https://hex.pm/packages/gleamy_structures) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleamy_structures/) - -Data structures in pure Gleam. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gleamy_structures -``` - -and its documentation can be found at <https://hexdocs.pm/gleamy_structures>. - -## Contributions Welcome -Feel free to make PRs, issues, or requests for new data structures and functions :) Especially welcome would be more rigorous tests and reviews of the implementation compared to source materials. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml b/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml deleted file mode 100644 index 270dfb77c9e..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/gleam.toml +++ /dev/null @@ -1,15 +0,0 @@ -name = "gleamy_structures" -version = "0.3.0" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -licences = ["Apache-2.0"] -description = "Data structures in pure Gleam." -repository = { type = "github", user = "schurhammer", repo = "gleamy_structures" } -links = [{ title = "Website", href = "https://github.com/schurhammer/gleamy_structures" }] - -[dependencies] -gleam_stdlib = "~> 0.29.0" - -[dev-dependencies] -gleeunit = "~> 0.10.1" diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl deleted file mode 100644 index 8bebbbf34a9..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@leftist_heap_Heap.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(heap, { - root :: gleamy_structures@heap@leftist_heap:t(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl deleted file mode 100644 index e4750eafa6f..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@heap@pairing_heap_Heap.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(heap, { - root :: gleamy_structures@heap@pairing_heap:t(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl deleted file mode 100644 index bc5cc269430..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_End.hrl +++ /dev/null @@ -1 +0,0 @@ --record('end', {first :: any()}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl deleted file mode 100644 index 8b05f955f9c..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@non_empty_list_Next.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(next, { - first :: any(), - rest :: gleamy_structures@non_empty_list:non_empty_list(any()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl deleted file mode 100644 index 680935c5c15..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@binary_search_tree_Tree.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(tree, { - root :: gleamy_structures@tree@binary_search_tree:node_(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl deleted file mode 100644 index b3310a80c4c..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_Tree.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(tree, { - root :: gleamy_structures@tree@red_black_tree:node_(any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl b/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl deleted file mode 100644 index 2b57f9253ec..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/include/gleamy_structures@tree@red_black_tree_kv_Tree.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(tree, { - root :: gleamy_structures@tree@red_black_tree_kv:node_(any(), any()), - compare :: fun((any(), any()) -> gleam@order:order()) -}). diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src deleted file mode 100644 index 01611d955eb..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures.app.src +++ /dev/null @@ -1,16 +0,0 @@ -{application, gleamy_structures, [ - {vsn, "0.3.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Data structures in pure Gleam."}, - {modules, [gleamy_structures@heap@leftist_heap, - gleamy_structures@heap@pairing_heap, - gleamy_structures@map, - gleamy_structures@non_empty_list, - gleamy_structures@priority_queue, - gleamy_structures@set, - gleamy_structures@tree@binary_search_tree, - gleamy_structures@tree@red_black_tree, - gleamy_structures@tree@red_black_tree_kv]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam deleted file mode 100644 index 7d1b51669a8..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/leftist_heap.gleam +++ /dev/null @@ -1,61 +0,0 @@ -// Based on "Purely Functional Data Structures" by Okasaki (1998) - -import gleam/order.{Gt, Order} - -type T(a) { - E - T(Int, a, T(a), T(a)) -} - -pub opaque type Heap(a) { - Heap(root: T(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Heap(a) { - Heap(E, compare) -} - -pub fn insert(heap: Heap(a), item: a) -> Heap(a) { - Heap(merge(T(1, item, E, E), heap.root, heap.compare), heap.compare) -} - -pub fn find_min(heap: Heap(a)) -> Result(a, Nil) { - case heap.root { - T(_, x, _, _) -> Ok(x) - E -> Error(Nil) - } -} - -pub fn delete_min(heap: Heap(a)) -> Result(#(a, Heap(a)), Nil) { - case heap.root { - T(_, x, a, b) -> Ok(#(x, Heap(merge(a, b, heap.compare), heap.compare))) - E -> Error(Nil) - } -} - -fn merge(h1: T(a), h2: T(a), compare: fn(a, a) -> Order) -> T(a) { - case h1, h2 { - h, E -> h - E, h -> h - T(_, x, a1, b1), T(_, y, a2, b2) -> - case compare(x, y) { - Gt -> make(y, a2, merge(h1, b2, compare)) - _ -> make(x, a1, merge(b1, h2, compare)) - } - } -} - -fn make(x, a, b) { - let rank_a = case a { - T(r, _, _, _) -> r - E -> 0 - } - let rank_b = case b { - T(r, _, _, _) -> r - E -> 0 - } - case rank_a < rank_b { - True -> T(rank_a + 1, x, b, a) - _ -> T(rank_b + 1, x, a, b) - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam deleted file mode 100644 index 80f69a31e22..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/heap/pairing_heap.gleam +++ /dev/null @@ -1,55 +0,0 @@ -// Based on "Purely Functional Data Structures" by Okasaki (1998) - -import gleam/order.{Gt, Order} - -type T(a) { - E - T(a, List(T(a))) -} - -pub opaque type Heap(a) { - Heap(root: T(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Heap(a) { - Heap(E, compare) -} - -pub fn insert(heap: Heap(a), key: a) -> Heap(a) { - Heap(merge(T(key, []), heap.root, heap.compare), heap.compare) -} - -pub fn find_min(heap: Heap(a)) -> Result(a, Nil) { - case heap.root { - T(x, _) -> Ok(x) - E -> Error(Nil) - } -} - -pub fn delete_min(heap: Heap(a)) -> Result(#(a, Heap(a)), Nil) { - case heap.root { - T(x, xs) -> Ok(#(x, Heap(merge_pairs(xs, heap.compare), heap.compare))) - E -> Error(Nil) - } -} - -fn merge(x: T(a), y: T(a), compare: fn(a, a) -> Order) -> T(a) { - case x, y { - x, E -> x - E, y -> y - T(xk, xs), T(yk, ys) -> - case compare(xk, yk) { - Gt -> T(yk, [x, ..ys]) - _ -> T(xk, [y, ..xs]) - } - } -} - -fn merge_pairs(l: List(T(a)), compare: fn(a, a) -> Order) -> T(a) { - case l { - [] -> E - [h] -> h - [h1, h2, ..hs] -> - merge(merge(h1, h2, compare), merge_pairs(hs, compare), compare) - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam deleted file mode 100644 index a49180e19ee..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/map.gleam +++ /dev/null @@ -1,85 +0,0 @@ -import gleam/order.{Order} -import gleam/list -import gleamy_structures/tree/red_black_tree_kv as tree - -type Map(k, v) = - tree.Tree(k, v) - -pub fn new(compare: fn(k, k) -> Order) -> Map(k, v) { - tree.new(compare) -} - -pub fn insert(into map: Map(k, v), key key: k, value value: v) -> Map(k, v) { - tree.insert(map, key, value) -} - -pub fn find(in map: Map(k, v), key key: k) -> Result(#(k, v), Nil) { - tree.find(map, key) -} - -pub fn has_key(in map: Map(k, v), key key: k) -> Bool { - case tree.find(map, key) { - Ok(_) -> True - Error(_) -> False - } -} - -pub fn delete(from map: Map(k, v), this key: k) -> Map(k, v) { - tree.delete(map, key) -} - -pub fn count(map: Map(k, v)) -> Int { - tree.fold(map, 0, fn(a, _, _) { a + 1 }) -} - -pub fn fold( - over map: Map(k, v), - from initial: a, - with reducer: fn(a, k, v) -> a, -) -> a { - tree.fold(map, initial, reducer) -} - -pub fn filter(in map: Map(k, v), for property: fn(k, v) -> Bool) -> Map(k, v) { - tree.fold( - map, - map, - fn(map, k, v) { - case property(k, v) { - True -> map - False -> tree.delete(map, k) - } - }, - ) -} - -pub fn merge(this first: Map(k, v), and second: Map(k, v)) -> Map(k, v) { - tree.fold(first, second, fn(a, k, v) { tree.insert(a, k, v) }) -} - -// return the map keeping only keys in the list -pub fn take(from map: Map(k, v), keeping desired: List(k)) -> Map(k, v) { - case desired { - [x, ..xs] -> - case tree.find(map, x) { - Ok(x) -> tree.insert(take(map, xs), x.0, x.1) - Error(_) -> take(map, xs) - } - [] -> tree.clear(map) - } -} - -pub fn from_list( - members: List(#(k, v)), - compare: fn(k, k) -> Order, -) -> Map(k, v) { - list.fold( - members, - tree.new(compare), - fn(tree, i) { tree.insert(tree, i.0, i.1) }, - ) -} - -pub fn to_list(map: Map(k, v)) -> List(#(k, v)) { - tree.foldr(map, [], fn(a, k, v) { [#(k, v), ..a] }) -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam deleted file mode 100644 index 0ba26fd70c4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/non_empty_list.gleam +++ /dev/null @@ -1,63 +0,0 @@ -import gleam/list - -pub type NonEmptyList(a) { - End(first: a) - Next(first: a, rest: NonEmptyList(a)) -} - -pub fn fold( - over list: NonEmptyList(a), - from initial: b, - with fun: fn(b, a) -> b, -) -> b { - case list { - End(item) -> fun(initial, item) - Next(x, xs) -> fold(xs, fun(initial, x), fun) - } -} - -pub fn count(list: NonEmptyList(a)) -> Int { - fold(list, 0, fn(acc, _) { acc + 1 }) -} - -pub fn map(list: NonEmptyList(a), transform: fn(a) -> b) -> NonEmptyList(b) { - case list { - End(x) -> End(transform(x)) - Next(x, xs) -> - fold(xs, End(transform(x)), fn(acc, item) { Next(transform(item), acc) }) - |> reverse - } -} - -pub fn filter(list: NonEmptyList(a), predicate: fn(a) -> Bool) -> List(a) { - fold( - list, - [], - fn(acc, item) { - case predicate(item) { - True -> [item, ..acc] - False -> acc - } - }, - ) - |> list.reverse() -} - -pub fn to_list(list: NonEmptyList(a)) -> List(a) { - fold(list, [], fn(acc, item) { [item, ..acc] }) - |> list.reverse() -} - -pub fn from_list(list: List(a)) -> Result(NonEmptyList(a), Nil) { - case list { - [] -> Error(Nil) - [x, ..xs] -> Ok(list.fold(xs, End(x), fn(acc, item) { Next(item, acc) })) - } -} - -pub fn reverse(list: NonEmptyList(a)) -> NonEmptyList(a) { - case list { - End(_) -> list - Next(x, xs) -> fold(xs, End(x), fn(acc, x) { Next(x, acc) }) - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam deleted file mode 100644 index 0bf0f8a5cc6..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/priority_queue.gleam +++ /dev/null @@ -1,54 +0,0 @@ -import gleam/order.{Order} -import gleam/list -import gleamy_structures/heap/pairing_heap as heap - -type Queue(a) = - heap.Heap(a) - -pub fn from_list(list: List(a), compare: fn(a, a) -> Order) -> Queue(a) { - list.fold(list, new(compare), heap.insert) -} - -pub fn is_empty(queue: Queue(a)) -> Bool { - case heap.find_min(queue) { - Ok(_) -> False - Error(_) -> True - } -} - -pub fn count(queue: Queue(a)) -> Int { - case heap.delete_min(queue) { - Ok(#(_, q)) -> count(q) + 1 - Error(_) -> 0 - } -} - -pub fn new(compare: fn(a, a) -> Order) -> Queue(a) { - heap.new(compare) -} - -pub fn pop(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - heap.delete_min(queue) -} - -pub fn peek(from queue: Queue(a)) -> Result(a, Nil) { - heap.find_min(queue) -} - -pub fn push(onto queue: Queue(a), this item: a) -> Queue(a) { - heap.insert(queue, item) -} - -pub fn reorder(queue: Queue(a), compare: fn(a, a) -> Order) -> Queue(a) { - case heap.delete_min(queue) { - Ok(#(x, q)) -> heap.insert(reorder(q, compare), x) - Error(_) -> heap.new(compare) - } -} - -pub fn to_list(queue: Queue(a)) -> List(a) { - case heap.delete_min(queue) { - Ok(#(x, q)) -> [x, ..to_list(q)] - Error(_) -> [] - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam deleted file mode 100644 index 0448bfbbb24..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/set.gleam +++ /dev/null @@ -1,91 +0,0 @@ -import gleam/order.{Order} -import gleam/list -import gleam/io -import gleam/string -import gleamy_structures/tree/red_black_tree as tree - -type Set(a) = - tree.Tree(a) - -pub fn contains(in set: Set(a), this member: a) -> Bool { - case tree.find(set, member) { - Ok(_) -> True - Error(_) -> False - } -} - -pub fn delete(from set: Set(a), this member: a) -> Set(a) { - tree.delete(set, member) -} - -pub fn filter(in set: Set(a), for property: fn(a) -> Bool) -> Set(a) { - tree.fold( - set, - set, - fn(set, i) { - case property(i) { - True -> set - False -> tree.delete(set, i) - } - }, - ) -} - -pub fn fold(over set: Set(a), from initial: b, with reducer: fn(b, a) -> b) -> b { - tree.fold(set, initial, reducer) -} - -pub fn from_list(members: List(a), compare: fn(a, a) -> Order) -> Set(a) { - list.fold(members, tree.new(compare), tree.insert) -} - -pub fn insert(into set: Set(a), this member: a) -> Set(a) { - tree.insert(set, member) -} - -pub fn intersection(of first: Set(a), and second: Set(a)) -> Set(a) { - tree.fold( - second, - tree.clear(first), - fn(a, i) { - case tree.find(first, i) { - Ok(_) -> tree.insert(a, i) - Error(_) -> a - } - }, - ) -} - -pub fn new(compare: fn(a, a) -> Order) -> Set(a) { - tree.new(compare) -} - -pub fn count(set: Set(a)) -> Int { - tree.fold(set, 0, fn(a, _) { a + 1 }) -} - -pub fn take(from set: Set(a), keeping desired: List(a)) -> Set(a) { - case desired { - [x, ..xs] -> - case tree.find(set, x) { - Ok(x) -> tree.insert(take(set, xs), x) - Error(_) -> take(set, xs) - } - [] -> tree.clear(set) - } -} - -pub fn to_list(set: Set(a)) -> List(a) { - tree.foldr( - set, - [], - fn(a, i) { - io.println(string.inspect(i)) - [i, ..a] - }, - ) -} - -pub fn union(of first: Set(a), and second: Set(a)) -> Set(a) { - tree.fold(first, second, fn(a, i) { tree.insert(a, i) }) -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam deleted file mode 100644 index fdae1f6e999..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/binary_search_tree.gleam +++ /dev/null @@ -1,123 +0,0 @@ -import gleam/order.{Eq, Gt, Lt, Order} - -type Node(a) { - Empty - Node(l: Node(a), k: a, r: Node(a)) -} - -pub opaque type Tree(a) { - Tree(root: Node(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Tree(a) { - Tree(Empty, compare) -} - -pub fn clear(tree: Tree(a)) -> Tree(a) { - Tree(Empty, tree.compare) -} - -pub fn insert(tree: Tree(a), key: a) -> Tree(a) { - Tree(do_insert(tree.root, key, tree.compare), tree.compare) -} - -pub fn delete(tree: Tree(a), key: a) -> Tree(a) { - Tree(do_delete(tree.root, key, tree.compare), tree.compare) -} - -pub fn find(tree: Tree(a), key: a) -> Result(a, Nil) { - do_find(tree.root, key, tree.compare) -} - -pub fn fold(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { - do_fold(tree.root, acc, fun) -} - -pub fn draw(tree: Tree(a), to_string: fn(a) -> String) { - do_draw(tree.root, 0, to_string) -} - -fn do_insert(node, key, compare) { - case node { - Node(l, k, r) -> - case compare(key, k) { - Lt -> Node(do_insert(l, key, compare), k, r) - Gt -> Node(l, k, do_insert(r, key, compare)) - Eq -> Node(l, key, r) - } - Empty -> Node(Empty, key, Empty) - } -} - -fn do_min(node, compare) { - case node { - Node(Node(_, _, _) as l, _, _) -> do_min(l, compare) - Node(Empty, _, _) -> node - Empty -> Empty - } -} - -fn do_delete(node, key, compare) { - case node { - Node(l, k, r) -> - case compare(key, k) { - Lt -> Node(do_delete(l, key, compare), k, r) - Gt -> Node(l, k, do_delete(r, key, compare)) - Eq -> - case node { - Node(Empty, _, r) -> r - Node(l, _, Empty) -> l - Node(l, _, r) -> - case do_min(r, compare) { - Node(_, mk, _) -> Node(l, mk, do_delete(r, mk, compare)) - Empty -> Empty - } - Empty -> Empty - } - } - Empty -> Empty - } -} - -fn do_find(node, key, compare) { - case node { - Node(l, k, r) -> - case compare(key, k) { - Lt -> do_find(l, key, compare) - Gt -> do_find(r, key, compare) - Eq -> Ok(k) - } - Empty -> Error(Nil) - } -} - -fn do_fold(node, acc, fun) { - case node { - Node(r, v, l) -> { - let acc = do_fold(r, acc, fun) - let acc = fun(acc, v) - let acc = do_fold(l, acc, fun) - acc - } - Empty -> acc - } -} - -fn do_indent(acc, i) { - case i { - 0 -> acc - i -> do_indent(". " <> acc, i - 1) - } -} - -fn do_draw(node, indent, to_string) { - case node { - Node(l, k, r) -> { - let ls = do_draw(l, indent + 1, to_string) - let ks = do_indent(to_string(k) <> "\n", indent) - let rs = do_draw(r, indent + 1, to_string) - ls <> ks <> rs - } - Empty -> "" - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam deleted file mode 100644 index 96d9e823b91..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree.gleam +++ /dev/null @@ -1,224 +0,0 @@ -// Based on "Deletion: The curse of the red-black tree" by Germane (2014) - -import gleam/order.{Eq, Gt, Lt, Order} - -type Color { - R - B - BB -} - -type Node(a) { - E - EE - T(c: Color, l: Node(a), k: a, r: Node(a)) -} - -pub opaque type Tree(a) { - Tree(root: Node(a), compare: fn(a, a) -> Order) -} - -pub fn new(compare: fn(a, a) -> Order) -> Tree(a) { - Tree(E, compare) -} - -pub fn clear(tree: Tree(a)) -> Tree(a) { - Tree(E, tree.compare) -} - -pub fn insert(tree: Tree(a), key: a) -> Tree(a) { - Tree(blacken(ins(tree.root, key, tree.compare)), tree.compare) -} - -pub fn delete(tree: Tree(a), key: a) -> Tree(a) { - Tree(del(redden(tree.root), key, tree.compare), tree.compare) -} - -pub fn find(tree: Tree(a), key: a) -> Result(a, Nil) { - do_find(tree.root, key, tree.compare) -} - -pub fn fold(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { - do_fold(tree.root, acc, fun) -} - -pub fn foldr(tree: Tree(a), acc: b, fun: fn(b, a) -> b) -> b { - do_foldr(tree.root, acc, fun) -} - -pub fn draw(tree: Tree(a), to_string: fn(a) -> String) { - do_draw(tree.root, 0, to_string) -} - -fn ins(node, x, compare) { - case node { - E -> T(R, E, x, E) - T(c, a, y, b) -> - case compare(x, y) { - Lt -> balance(c, ins(a, x, compare), y, b) - Gt -> balance(c, a, y, ins(b, x, compare)) - Eq -> T(c, a, x, b) - } - _ -> node - } -} - -fn blacken(node: Node(a)) -> Node(a) { - case node { - T(R, T(R, _, _, _) as l, y, c) -> T(B, l, y, c) - T(R, a, x, T(R, _, _, _) as r) -> T(B, a, x, r) - t -> t - } -} - -fn balance(c: Color, l: Node(a), v: a, r: Node(a)) -> Node(a) { - case c, l, v, r { - B, T(R, T(R, a, x, b), y, c), z, d -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - B, T(R, a, x, T(R, b, y, c)), z, d -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - B, a, x, T(R, T(R, b, y, c), z, d) -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - B, a, x, T(R, b, y, T(R, c, z, d)) -> T(R, T(B, a, x, b), y, T(B, c, z, d)) - BB, a, x, T(R, T(R, b, y, c), z, d) -> T(B, T(B, a, x, b), y, T(B, c, z, d)) - BB, T(R, a, x, T(R, b, y, c)), z, d -> T(B, T(B, a, x, b), y, T(B, c, z, d)) - c, a, x, b -> T(c, a, x, b) - } -} - -fn redden(node: Node(a)) -> Node(a) { - case node { - T(B, T(B, _, _, _) as l, y, T(B, _, _, _) as r) -> T(R, l, y, r) - t -> t - } -} - -fn del(node, x, compare) { - case node { - E -> node - T(R, E, y, E) -> - case compare(x, y) { - Eq -> E - _ -> node - } - T(B, E, y, E) -> - case compare(x, y) { - Eq -> EE - _ -> node - } - T(B, T(R, E, y, E) as l, z, E) -> - case compare(x, z) { - Lt -> T(B, del(l, x, compare), z, E) - Gt -> node - Eq -> T(B, E, y, E) - } - T(c, a, y, b) -> - case compare(x, y) { - Lt -> rotate(c, del(a, x, compare), y, b) - Gt -> rotate(c, a, y, del(b, x, compare)) - Eq -> - case min_del(b) { - Min(y1, b1) -> rotate(c, a, y1, b1) - None -> E - } - } - _ -> node - } -} - -fn rotate(c: Color, l: Node(a), v: a, r: Node(a)) -> Node(a) { - case c, l, v, r { - R, T(BB, a, x, b), y, T(B, c, z, d) -> - balance(B, T(R, T(B, a, x, b), y, c), z, d) - R, EE, y, T(B, c, z, d) -> balance(B, T(R, E, y, c), z, d) - R, T(B, a, x, b), y, T(BB, c, z, d) -> - balance(B, a, x, T(R, b, y, T(B, c, z, d))) - R, T(B, a, x, b), y, EE -> balance(B, a, x, T(R, b, y, E)) - B, T(BB, a, x, b), y, T(B, c, z, d) -> - balance(BB, T(R, T(B, a, x, b), y, c), z, d) - B, EE, y, T(B, c, z, d) -> balance(BB, T(R, E, y, c), z, d) - B, T(B, a, x, b), y, T(BB, c, z, d) -> - balance(BB, a, x, T(R, b, y, T(B, c, z, d))) - B, T(B, a, x, b), y, EE -> balance(BB, a, x, T(R, b, y, E)) - B, T(BB, a, w, b), x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, T(B, a, w, b), x, c), y, d), z, e) - B, EE, x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, E, x, c), y, d), z, e) - B, T(R, a, w, T(B, b, x, c)), y, T(BB, d, z, e) -> - T(B, a, w, balance(B, b, x, T(R, c, y, T(B, d, z, e)))) - B, T(R, a, w, T(B, b, x, c)), y, EE -> - T(B, a, w, balance(B, b, x, T(R, c, y, E))) - c, a, x, b -> T(c, a, x, b) - } -} - -type MinDel(a) { - Min(a, Node(a)) - None -} - -fn min_del(node) -> MinDel(a) { - case node { - T(R, E, x, E) -> Min(x, E) - T(B, E, x, E) -> Min(x, EE) - T(B, E, x, T(R, E, y, E)) -> Min(x, T(B, E, y, E)) - T(c, a, x, b) -> - case min_del(a) { - Min(x1, a1) -> Min(x1, rotate(c, a1, x, b)) - None -> None - } - _ -> None - } -} - -fn do_find(node, key, compare) { - case node { - T(_, l, k, r) -> - case compare(key, k) { - Lt -> do_find(l, key, compare) - Gt -> do_find(r, key, compare) - Eq -> Ok(k) - } - _ -> Error(Nil) - } -} - -fn do_fold(node, acc, fun) { - case node { - T(_, r, v, l) -> { - let acc = do_fold(r, acc, fun) - let acc = fun(acc, v) - let acc = do_fold(l, acc, fun) - acc - } - _ -> acc - } -} - -fn do_foldr(node, acc, fun) { - case node { - T(_, r, v, l) -> { - let acc = do_foldr(l, acc, fun) - let acc = fun(acc, v) - let acc = do_foldr(r, acc, fun) - acc - } - _ -> acc - } -} - -fn do_indent(acc, i) { - case i { - 0 -> acc - i -> do_indent(". " <> acc, i - 1) - } -} - -fn do_draw(node, indent, to_string) { - case node { - T(_, l, k, r) -> { - let ls = do_draw(l, indent + 1, to_string) - let ks = do_indent(to_string(k) <> "\n", indent) - let rs = do_draw(r, indent + 1, to_string) - ls <> ks <> rs - } - _ -> "" - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam deleted file mode 100644 index 9a61ae14b11..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures/tree/red_black_tree_kv.gleam +++ /dev/null @@ -1,232 +0,0 @@ -// Based on "Deletion: The curse of the red-black tree" by Germane (2014) - -import gleam/order.{Eq, Gt, Lt, Order} - -type Color { - R - B - BB -} - -type Node(k, v) { - E - EE - T(c: Color, l: Node(k, v), k: #(k, v), r: Node(k, v)) -} - -pub opaque type Tree(k, v) { - Tree(root: Node(k, v), compare: fn(k, k) -> Order) -} - -pub fn new(compare: fn(k, k) -> Order) -> Tree(k, v) { - Tree(E, compare) -} - -pub fn clear(tree: Tree(k, v)) -> Tree(k, v) { - Tree(E, tree.compare) -} - -pub fn insert(tree: Tree(k, v), key: k, value: v) -> Tree(k, v) { - Tree(blacken(ins(tree.root, #(key, value), tree.compare)), tree.compare) -} - -pub fn delete(tree: Tree(k, v), key: k) -> Tree(k, v) { - Tree(del(redden(tree.root), key, tree.compare), tree.compare) -} - -pub fn find(tree: Tree(k, v), key: k) -> Result(#(k, v), Nil) { - do_find(tree.root, key, tree.compare) -} - -pub fn fold(tree: Tree(k, v), acc: b, fun: fn(b, k, v) -> b) -> b { - do_fold(tree.root, acc, fun) -} - -pub fn foldr(tree: Tree(k, v), acc: b, fun: fn(b, k, v) -> b) -> b { - do_foldr(tree.root, acc, fun) -} - -pub fn draw(tree: Tree(k, v), to_string: fn(k, v) -> String) -> String { - do_draw(tree.root, 0, to_string) -} - -fn ins(node: Node(k, v), x: #(k, v), compare: fn(k, k) -> Order) -> Node(k, v) { - case node { - E -> T(R, E, x, E) - T(c, k, y, b) -> - case compare(x.0, y.0) { - Lt -> balance(c, ins(k, x, compare), y, b) - Gt -> balance(c, k, y, ins(b, x, compare)) - Eq -> T(c, k, x, b) - } - _ -> node - } -} - -fn blacken(node: Node(k, v)) -> Node(k, v) { - case node { - T(R, T(R, _, _, _) as l, y, c) -> T(B, l, y, c) - T(R, k, x, T(R, _, _, _) as r) -> T(B, k, x, r) - t -> t - } -} - -fn balance(c: Color, l: Node(k, v), v: #(k, v), r: Node(k, v)) -> Node(k, v) { - case c, l, v, r { - B, T(R, T(R, k, x, b), y, c), z, d -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - B, T(R, k, x, T(R, b, y, c)), z, d -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - B, k, x, T(R, T(R, b, y, c), z, d) -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - B, k, x, T(R, b, y, T(R, c, z, d)) -> T(R, T(B, k, x, b), y, T(B, c, z, d)) - BB, k, x, T(R, T(R, b, y, c), z, d) -> T(B, T(B, k, x, b), y, T(B, c, z, d)) - BB, T(R, k, x, T(R, b, y, c)), z, d -> T(B, T(B, k, x, b), y, T(B, c, z, d)) - c, k, x, b -> T(c, k, x, b) - } -} - -fn redden(node: Node(k, v)) -> Node(k, v) { - case node { - T(B, T(B, _, _, _) as l, y, T(B, _, _, _) as r) -> T(R, l, y, r) - t -> t - } -} - -fn del(node: Node(k, v), x: k, compare: fn(k, k) -> Order) -> Node(k, v) { - case node { - E -> node - T(R, E, y, E) -> - case compare(x, y.0) { - Eq -> E - _ -> node - } - T(B, E, y, E) -> - case compare(x, y.0) { - Eq -> EE - _ -> node - } - T(B, T(R, E, y, E) as l, z, E) -> - case compare(x, z.0) { - Lt -> T(B, del(l, x, compare), z, E) - Gt -> node - Eq -> T(B, E, y, E) - } - T(c, k, y, b) -> - case compare(x, y.0) { - Lt -> rotate(c, del(k, x, compare), y, b) - Gt -> rotate(c, k, y, del(b, x, compare)) - Eq -> - case min_del(b) { - Min(y1, b1) -> rotate(c, k, y1, b1) - None -> E - } - } - _ -> node - } -} - -fn rotate(c: Color, l: Node(k, v), v: #(k, v), r: Node(k, v)) -> Node(k, v) { - case c, l, v, r { - R, T(BB, k, x, b), y, T(B, c, z, d) -> - balance(B, T(R, T(B, k, x, b), y, c), z, d) - R, EE, y, T(B, c, z, d) -> balance(B, T(R, E, y, c), z, d) - R, T(B, k, x, b), y, T(BB, c, z, d) -> - balance(B, k, x, T(R, b, y, T(B, c, z, d))) - R, T(B, k, x, b), y, EE -> balance(B, k, x, T(R, b, y, E)) - B, T(BB, k, x, b), y, T(B, c, z, d) -> - balance(BB, T(R, T(B, k, x, b), y, c), z, d) - B, EE, y, T(B, c, z, d) -> balance(BB, T(R, E, y, c), z, d) - B, T(B, k, x, b), y, T(BB, c, z, d) -> - balance(BB, k, x, T(R, b, y, T(B, c, z, d))) - B, T(B, k, x, b), y, EE -> balance(BB, k, x, T(R, b, y, E)) - B, T(BB, k, w, b), x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, T(B, k, w, b), x, c), y, d), z, e) - B, EE, x, T(R, T(B, c, y, d), z, e) -> - T(B, balance(B, T(R, E, x, c), y, d), z, e) - B, T(R, k, w, T(B, b, x, c)), y, T(BB, d, z, e) -> - T(B, k, w, balance(B, b, x, T(R, c, y, T(B, d, z, e)))) - B, T(R, k, w, T(B, b, x, c)), y, EE -> - T(B, k, w, balance(B, b, x, T(R, c, y, E))) - c, k, x, b -> T(c, k, x, b) - } -} - -type MinDel(k, v) { - Min(#(k, v), Node(k, v)) - None -} - -fn min_del(node: Node(k, v)) -> MinDel(k, v) { - case node { - T(R, E, x, E) -> Min(x, E) - T(B, E, x, E) -> Min(x, EE) - T(B, E, x, T(R, E, y, E)) -> Min(x, T(B, E, y, E)) - T(c, k, x, b) -> - case min_del(k) { - Min(x1, a1) -> Min(x1, rotate(c, a1, x, b)) - None -> None - } - _ -> None - } -} - -fn do_find( - node: Node(k, v), - key: k, - compare: fn(k, k) -> Order, -) -> Result(#(k, v), Nil) { - case node { - T(_, l, k, r) -> - case compare(key, k.0) { - Lt -> do_find(l, key, compare) - Gt -> do_find(r, key, compare) - Eq -> Ok(k) - } - _ -> Error(Nil) - } -} - -fn do_fold(node: Node(k, v), acc: a, fun: fn(a, k, v) -> a) -> a { - case node { - T(_, r, v, l) -> { - let acc = do_fold(r, acc, fun) - let acc = fun(acc, v.0, v.1) - let acc = do_fold(l, acc, fun) - acc - } - _ -> acc - } -} - -fn do_foldr(node: Node(k, v), acc: a, fun: fn(a, k, v) -> a) -> a { - case node { - T(_, r, v, l) -> { - let acc = do_foldr(l, acc, fun) - let acc = fun(acc, v.0, v.1) - let acc = do_foldr(r, acc, fun) - acc - } - _ -> acc - } -} - -fn do_indent(acc: String, i: Int) -> String { - case i { - 0 -> acc - i -> do_indent(". " <> acc, i - 1) - } -} - -fn do_draw( - node: Node(k, v), - indent: Int, - to_string: fn(k, v) -> String, -) -> String { - case node { - T(_, l, k, r) -> { - let ls = do_draw(l, indent + 1, to_string) - let ks = do_indent(to_string(k.0, k.1) <> "\n", indent) - let rs = do_draw(r, indent + 1, to_string) - ls <> ks <> rs - } - _ -> "" - } -} diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl deleted file mode 100644 index 5f24df08bcb..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@leftist_heap.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(gleamy_structures@heap@leftist_heap). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, find_min/1, insert/2, delete_min/1]). --export_type([t/1, heap/1]). - --type t(FXL) :: e | {t, integer(), FXL, t(FXL), t(FXL)}. - --opaque heap(FXM) :: {heap, t(FXM), fun((FXM, FXM) -> gleam@order:order())}. - --spec new(fun((FXN, FXN) -> gleam@order:order())) -> heap(FXN). -new(Compare) -> - {heap, e, Compare}. - --spec find_min(heap(FXS)) -> {ok, FXS} | {error, nil}. -find_min(Heap) -> - case erlang:element(2, Heap) of - {t, _, X, _, _} -> - {ok, X}; - - e -> - {error, nil} - end. - --spec make(FYX, t(FYX), t(FYX)) -> t(FYX). -make(X, A, B) -> - Rank_a = case A of - {t, R, _, _, _} -> - R; - - e -> - 0 - end, - Rank_b = case B of - {t, R@1, _, _, _} -> - R@1; - - e -> - 0 - end, - case Rank_a < Rank_b of - true -> - {t, Rank_a + 1, X, B, A}; - - _ -> - {t, Rank_b + 1, X, A, B} - end. - --spec merge(t(FYB), t(FYB), fun((FYB, FYB) -> gleam@order:order())) -> t(FYB). -merge(H1, H2, Compare) -> - case {H1, H2} of - {H, e} -> - H; - - {e, H@1} -> - H@1; - - {{t, _, X, A1, B1}, {t, _, Y, A2, B2}} -> - case Compare(X, Y) of - gt -> - make(Y, A2, merge(H1, B2, Compare)); - - _ -> - make(X, A1, merge(B1, H2, Compare)) - end - end. - --spec insert(heap(FXP), FXP) -> heap(FXP). -insert(Heap, Item) -> - {heap, - merge( - {t, 1, Item, e, e}, - erlang:element(2, Heap), - erlang:element(3, Heap) - ), - erlang:element(3, Heap)}. - --spec delete_min(heap(FXW)) -> {ok, {FXW, heap(FXW)}} | {error, nil}. -delete_min(Heap) -> - case erlang:element(2, Heap) of - {t, _, X, A, B} -> - {ok, - {X, - {heap, - merge(A, B, erlang:element(3, Heap)), - erlang:element(3, Heap)}}}; - - e -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl deleted file mode 100644 index 8677af51636..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@heap@pairing_heap.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(gleamy_structures@heap@pairing_heap). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, find_min/1, insert/2, delete_min/1]). --export_type([t/1, heap/1]). - --type t(EWV) :: e | {t, EWV, list(t(EWV))}. - --opaque heap(EWW) :: {heap, t(EWW), fun((EWW, EWW) -> gleam@order:order())}. - --spec new(fun((EWX, EWX) -> gleam@order:order())) -> heap(EWX). -new(Compare) -> - {heap, e, Compare}. - --spec find_min(heap(EXC)) -> {ok, EXC} | {error, nil}. -find_min(Heap) -> - case erlang:element(2, Heap) of - {t, X, _} -> - {ok, X}; - - e -> - {error, nil} - end. - --spec merge(t(EXL), t(EXL), fun((EXL, EXL) -> gleam@order:order())) -> t(EXL). -merge(X, Y, Compare) -> - case {X, Y} of - {X@1, e} -> - X@1; - - {e, Y@1} -> - Y@1; - - {{t, Xk, Xs}, {t, Yk, Ys}} -> - case Compare(Xk, Yk) of - gt -> - {t, Yk, [X | Ys]}; - - _ -> - {t, Xk, [Y | Xs]} - end - end. - --spec insert(heap(EWZ), EWZ) -> heap(EWZ). -insert(Heap, Key) -> - {heap, - merge({t, Key, []}, erlang:element(2, Heap), erlang:element(3, Heap)), - erlang:element(3, Heap)}. - --spec merge_pairs(list(t(EXP)), fun((EXP, EXP) -> gleam@order:order())) -> t(EXP). -merge_pairs(L, Compare) -> - case L of - [] -> - e; - - [H] -> - H; - - [H1, H2 | Hs] -> - merge(merge(H1, H2, Compare), merge_pairs(Hs, Compare), Compare) - end. - --spec delete_min(heap(EXG)) -> {ok, {EXG, heap(EXG)}} | {error, nil}. -delete_min(Heap) -> - case erlang:element(2, Heap) of - {t, X, Xs} -> - {ok, - {X, - {heap, - merge_pairs(Xs, erlang:element(3, Heap)), - erlang:element(3, Heap)}}}; - - e -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl deleted file mode 100644 index 9a5dd176288..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@map.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleamy_structures@map). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, insert/3, find/2, has_key/2, delete/2, count/1, fold/3, filter/2, merge/2, from_list/2, to_list/1, take/2]). - --spec new(fun((GVO, GVO) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree_kv:tree(GVO, any()). -new(Compare) -> - gleamy_structures@tree@red_black_tree_kv:new(Compare). - --spec insert(gleamy_structures@tree@red_black_tree_kv:tree(GVS, GVT), GVS, GVT) -> gleamy_structures@tree@red_black_tree_kv:tree(GVS, GVT). -insert(Map, Key, Value) -> - gleamy_structures@tree@red_black_tree_kv:insert(Map, Key, Value). - --spec find(gleamy_structures@tree@red_black_tree_kv:tree(GVY, GVZ), GVY) -> {ok, - {GVY, GVZ}} | - {error, nil}. -find(Map, Key) -> - gleamy_structures@tree@red_black_tree_kv:find(Map, Key). - --spec has_key(gleamy_structures@tree@red_black_tree_kv:tree(GWE, any()), GWE) -> boolean(). -has_key(Map, Key) -> - case gleamy_structures@tree@red_black_tree_kv:find(Map, Key) of - {ok, _} -> - true; - - {error, _} -> - false - end. - --spec delete(gleamy_structures@tree@red_black_tree_kv:tree(GWI, GWJ), GWI) -> gleamy_structures@tree@red_black_tree_kv:tree(GWI, GWJ). -delete(Map, Key) -> - gleamy_structures@tree@red_black_tree_kv:delete(Map, Key). - --spec count(gleamy_structures@tree@red_black_tree_kv:tree(any(), any())) -> integer(). -count(Map) -> - gleamy_structures@tree@red_black_tree_kv:fold( - Map, - 0, - fun(A, _, _) -> A + 1 end - ). - --spec fold( - gleamy_structures@tree@red_black_tree_kv:tree(GWS, GWT), - GWW, - fun((GWW, GWS, GWT) -> GWW) -) -> GWW. -fold(Map, Initial, Reducer) -> - gleamy_structures@tree@red_black_tree_kv:fold(Map, Initial, Reducer). - --spec filter( - gleamy_structures@tree@red_black_tree_kv:tree(GWX, GWY), - fun((GWX, GWY) -> boolean()) -) -> gleamy_structures@tree@red_black_tree_kv:tree(GWX, GWY). -filter(Map, Property) -> - gleamy_structures@tree@red_black_tree_kv:fold( - Map, - Map, - fun(Map@1, K, V) -> case Property(K, V) of - true -> - Map@1; - - false -> - gleamy_structures@tree@red_black_tree_kv:delete(Map@1, K) - end end - ). - --spec merge( - gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE), - gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE) -) -> gleamy_structures@tree@red_black_tree_kv:tree(GXD, GXE). -merge(First, Second) -> - gleamy_structures@tree@red_black_tree_kv:fold( - First, - Second, - fun(A, K, V) -> - gleamy_structures@tree@red_black_tree_kv:insert(A, K, V) - end - ). - --spec from_list(list({GXS, GXT}), fun((GXS, GXS) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree_kv:tree(GXS, GXT). -from_list(Members, Compare) -> - gleam@list:fold( - Members, - gleamy_structures@tree@red_black_tree_kv:new(Compare), - fun(Tree, I) -> - gleamy_structures@tree@red_black_tree_kv:insert( - Tree, - erlang:element(1, I), - erlang:element(2, I) - ) - end - ). - --spec to_list(gleamy_structures@tree@red_black_tree_kv:tree(GXX, GXY)) -> list({GXX, - GXY}). -to_list(Map) -> - gleamy_structures@tree@red_black_tree_kv:foldr( - Map, - [], - fun(A, K, V) -> [{K, V} | A] end - ). - --spec take(gleamy_structures@tree@red_black_tree_kv:tree(GXL, GXM), list(GXL)) -> gleamy_structures@tree@red_black_tree_kv:tree(GXL, GXM). -take(Map, Desired) -> - case Desired of - [X | Xs] -> - case gleamy_structures@tree@red_black_tree_kv:find(Map, X) of - {ok, X@1} -> - gleamy_structures@tree@red_black_tree_kv:insert( - take(Map, Xs), - erlang:element(1, X@1), - erlang:element(2, X@1) - ); - - {error, _} -> - take(Map, Xs) - end; - - [] -> - gleamy_structures@tree@red_black_tree_kv:clear(Map) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl deleted file mode 100644 index 838f1d99840..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@non_empty_list.erl +++ /dev/null @@ -1,77 +0,0 @@ --module(gleamy_structures@non_empty_list). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_list/1, fold/3, count/1, filter/2, to_list/1, reverse/1, map/2]). --export_type([non_empty_list/1]). - --type non_empty_list(HAU) :: {'end', HAU} | {next, HAU, non_empty_list(HAU)}. - --spec from_list(list(HBK)) -> {ok, non_empty_list(HBK)} | {error, nil}. -from_list(List) -> - case List of - [] -> - {error, nil}; - - [X | Xs] -> - {ok, - gleam@list:fold( - Xs, - {'end', X}, - fun(Acc, Item) -> {next, Item, Acc} end - )} - end. - --spec fold(non_empty_list(HAV), HAX, fun((HAX, HAV) -> HAX)) -> HAX. -fold(List, Initial, Fun) -> - case List of - {'end', Item} -> - Fun(Initial, Item); - - {next, X, Xs} -> - fold(Xs, Fun(Initial, X), Fun) - end. - --spec count(non_empty_list(any())) -> integer(). -count(List) -> - fold(List, 0, fun(Acc, _) -> Acc + 1 end). - --spec filter(non_empty_list(HBE), fun((HBE) -> boolean())) -> list(HBE). -filter(List, Predicate) -> - _pipe = fold(List, [], fun(Acc, Item) -> case Predicate(Item) of - true -> - [Item | Acc]; - - false -> - Acc - end end), - gleam@list:reverse(_pipe). - --spec to_list(non_empty_list(HBH)) -> list(HBH). -to_list(List) -> - _pipe = fold(List, [], fun(Acc, Item) -> [Item | Acc] end), - gleam@list:reverse(_pipe). - --spec reverse(non_empty_list(HBP)) -> non_empty_list(HBP). -reverse(List) -> - case List of - {'end', _} -> - List; - - {next, X, Xs} -> - fold(Xs, {'end', X}, fun(Acc, X@1) -> {next, X@1, Acc} end) - end. - --spec map(non_empty_list(HBA), fun((HBA) -> HBC)) -> non_empty_list(HBC). -map(List, Transform) -> - case List of - {'end', X} -> - {'end', Transform(X)}; - - {next, X@1, Xs} -> - _pipe = fold( - Xs, - {'end', Transform(X@1)}, - fun(Acc, Item) -> {next, Transform(Item), Acc} end - ), - reverse(_pipe) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl deleted file mode 100644 index 7537469dd3c..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@priority_queue.erl +++ /dev/null @@ -1,74 +0,0 @@ --module(gleamy_structures@priority_queue). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_empty/1, new/1, from_list/2, pop/1, peek/1, push/2, count/1, reorder/2, to_list/1]). - --spec is_empty(gleamy_structures@heap@pairing_heap:heap(any())) -> boolean(). -is_empty(Queue) -> - case gleamy_structures@heap@pairing_heap:find_min(Queue) of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec new(fun((EZX, EZX) -> gleam@order:order())) -> gleamy_structures@heap@pairing_heap:heap(EZX). -new(Compare) -> - gleamy_structures@heap@pairing_heap:new(Compare). - --spec from_list(list(EZQ), fun((EZQ, EZQ) -> gleam@order:order())) -> gleamy_structures@heap@pairing_heap:heap(EZQ). -from_list(List, Compare) -> - gleam@list:fold( - List, - new(Compare), - fun gleamy_structures@heap@pairing_heap:insert/2 - ). - --spec pop(gleamy_structures@heap@pairing_heap:heap(EZZ)) -> {ok, - {EZZ, gleamy_structures@heap@pairing_heap:heap(EZZ)}} | - {error, nil}. -pop(Queue) -> - gleamy_structures@heap@pairing_heap:delete_min(Queue). - --spec peek(gleamy_structures@heap@pairing_heap:heap(FAE)) -> {ok, FAE} | - {error, nil}. -peek(Queue) -> - gleamy_structures@heap@pairing_heap:find_min(Queue). - --spec push(gleamy_structures@heap@pairing_heap:heap(FAI), FAI) -> gleamy_structures@heap@pairing_heap:heap(FAI). -push(Queue, Item) -> - gleamy_structures@heap@pairing_heap:insert(Queue, Item). - --spec count(gleamy_structures@heap@pairing_heap:heap(any())) -> integer(). -count(Queue) -> - case gleamy_structures@heap@pairing_heap:delete_min(Queue) of - {ok, {_, Q}} -> - count(Q) + 1; - - {error, _} -> - 0 - end. - --spec reorder( - gleamy_structures@heap@pairing_heap:heap(FAL), - fun((FAL, FAL) -> gleam@order:order()) -) -> gleamy_structures@heap@pairing_heap:heap(FAL). -reorder(Queue, Compare) -> - case gleamy_structures@heap@pairing_heap:delete_min(Queue) of - {ok, {X, Q}} -> - gleamy_structures@heap@pairing_heap:insert(reorder(Q, Compare), X); - - {error, _} -> - gleamy_structures@heap@pairing_heap:new(Compare) - end. - --spec to_list(gleamy_structures@heap@pairing_heap:heap(FAO)) -> list(FAO). -to_list(Queue) -> - case gleamy_structures@heap@pairing_heap:delete_min(Queue) of - {ok, {X, Q}} -> - [X | to_list(Q)]; - - {error, _} -> - [] - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl deleted file mode 100644 index 38ccc7a19a4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@set.erl +++ /dev/null @@ -1,123 +0,0 @@ --module(gleamy_structures@set). --compile([no_auto_import, nowarn_unused_vars]). - --export([contains/2, delete/2, filter/2, fold/3, from_list/2, insert/2, intersection/2, new/1, count/1, to_list/1, union/2, take/2]). - --spec contains(gleamy_structures@tree@red_black_tree:tree(FTU), FTU) -> boolean(). -contains(Set, Member) -> - case gleamy_structures@tree@red_black_tree:find(Set, Member) of - {ok, _} -> - true; - - {error, _} -> - false - end. - --spec delete(gleamy_structures@tree@red_black_tree:tree(FTW), FTW) -> gleamy_structures@tree@red_black_tree:tree(FTW). -delete(Set, Member) -> - gleamy_structures@tree@red_black_tree:delete(Set, Member). - --spec filter( - gleamy_structures@tree@red_black_tree:tree(FTZ), - fun((FTZ) -> boolean()) -) -> gleamy_structures@tree@red_black_tree:tree(FTZ). -filter(Set, Property) -> - gleamy_structures@tree@red_black_tree:fold( - Set, - Set, - fun(Set@1, I) -> case Property(I) of - true -> - Set@1; - - false -> - gleamy_structures@tree@red_black_tree:delete(Set@1, I) - end end - ). - --spec fold( - gleamy_structures@tree@red_black_tree:tree(FUC), - FUE, - fun((FUE, FUC) -> FUE) -) -> FUE. -fold(Set, Initial, Reducer) -> - gleamy_structures@tree@red_black_tree:fold(Set, Initial, Reducer). - --spec from_list(list(FUF), fun((FUF, FUF) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree:tree(FUF). -from_list(Members, Compare) -> - gleam@list:fold( - Members, - gleamy_structures@tree@red_black_tree:new(Compare), - fun gleamy_structures@tree@red_black_tree:insert/2 - ). - --spec insert(gleamy_structures@tree@red_black_tree:tree(FUI), FUI) -> gleamy_structures@tree@red_black_tree:tree(FUI). -insert(Set, Member) -> - gleamy_structures@tree@red_black_tree:insert(Set, Member). - --spec intersection( - gleamy_structures@tree@red_black_tree:tree(FUL), - gleamy_structures@tree@red_black_tree:tree(FUL) -) -> gleamy_structures@tree@red_black_tree:tree(FUL). -intersection(First, Second) -> - gleamy_structures@tree@red_black_tree:fold( - Second, - gleamy_structures@tree@red_black_tree:clear(First), - fun(A, I) -> - case gleamy_structures@tree@red_black_tree:find(First, I) of - {ok, _} -> - gleamy_structures@tree@red_black_tree:insert(A, I); - - {error, _} -> - A - end - end - ). - --spec new(fun((FUP, FUP) -> gleam@order:order())) -> gleamy_structures@tree@red_black_tree:tree(FUP). -new(Compare) -> - gleamy_structures@tree@red_black_tree:new(Compare). - --spec count(gleamy_structures@tree@red_black_tree:tree(any())) -> integer(). -count(Set) -> - gleamy_structures@tree@red_black_tree:fold(Set, 0, fun(A, _) -> A + 1 end). - --spec to_list(gleamy_structures@tree@red_black_tree:tree(FUX)) -> list(FUX). -to_list(Set) -> - gleamy_structures@tree@red_black_tree:foldr( - Set, - [], - fun(A, I) -> - gleam@io:println(gleam@string:inspect(I)), - [I | A] - end - ). - --spec union( - gleamy_structures@tree@red_black_tree:tree(FVA), - gleamy_structures@tree@red_black_tree:tree(FVA) -) -> gleamy_structures@tree@red_black_tree:tree(FVA). -union(First, Second) -> - gleamy_structures@tree@red_black_tree:fold( - First, - Second, - fun(A, I) -> gleamy_structures@tree@red_black_tree:insert(A, I) end - ). - --spec take(gleamy_structures@tree@red_black_tree:tree(FUT), list(FUT)) -> gleamy_structures@tree@red_black_tree:tree(FUT). -take(Set, Desired) -> - case Desired of - [X | Xs] -> - case gleamy_structures@tree@red_black_tree:find(Set, X) of - {ok, X@1} -> - gleamy_structures@tree@red_black_tree:insert( - take(Set, Xs), - X@1 - ); - - {error, _} -> - take(Set, Xs) - end; - - [] -> - gleamy_structures@tree@red_black_tree:clear(Set) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl deleted file mode 100644 index 296ea98d2e4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@binary_search_tree.erl +++ /dev/null @@ -1,167 +0,0 @@ --module(gleamy_structures@tree@binary_search_tree). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, clear/1, insert/2, delete/2, find/2, fold/3, draw/2]). --export_type([node_/1, tree/1]). - --type node_(FCI) :: empty | {node, node_(FCI), FCI, node_(FCI)}. - --opaque tree(FCJ) :: {tree, node_(FCJ), fun((FCJ, FCJ) -> gleam@order:order())}. - --spec new(fun((FCK, FCK) -> gleam@order:order())) -> tree(FCK). -new(Compare) -> - {tree, empty, Compare}. - --spec clear(tree(FCM)) -> tree(FCM). -clear(Tree) -> - {tree, empty, erlang:element(3, Tree)}. - --spec do_insert(node_(FCP), FCP, fun((FCP, FCP) -> gleam@order:order())) -> node_(FCP). -do_insert(Node, Key, Compare) -> - case Node of - {node, L, K, R} -> - case Compare(Key, K) of - lt -> - {node, do_insert(L, Key, Compare), K, R}; - - gt -> - {node, L, K, do_insert(R, Key, Compare)}; - - eq -> - {node, L, Key, R} - end; - - empty -> - {node, empty, Key, empty} - end. - --spec insert(tree(FCP), FCP) -> tree(FCP). -insert(Tree, Key) -> - {tree, - do_insert(erlang:element(2, Tree), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_delete(node_(FCS), FCS, fun((FCS, FCS) -> gleam@order:order())) -> node_(FCS). -do_delete(Node, Key, Compare) -> - case Node of - {node, L, K, R} -> - case Compare(Key, K) of - lt -> - {node, do_delete(L, Key, Compare), K, R}; - - gt -> - {node, L, K, do_delete(R, Key, Compare)}; - - eq -> - case Node of - {node, empty, _, R@1} -> - R@1; - - {node, L@1, _, empty} -> - L@1; - - {node, L@2, _, R@2} -> - case do_min(R@2, Compare) of - {node, _, Mk, _} -> - {node, L@2, Mk, do_delete(R@2, Mk, Compare)}; - - empty -> - empty - end; - - empty -> - empty - end - end; - - empty -> - empty - end. - --spec delete(tree(FCS), FCS) -> tree(FCS). -delete(Tree, Key) -> - {tree, - do_delete(erlang:element(2, Tree), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_find(node_(FCV), FCV, fun((FCV, FCV) -> gleam@order:order())) -> {ok, - FCV} | - {error, nil}. -do_find(Node, Key, Compare) -> - case Node of - {node, L, K, R} -> - case Compare(Key, K) of - lt -> - do_find(L, Key, Compare); - - gt -> - do_find(R, Key, Compare); - - eq -> - {ok, K} - end; - - empty -> - {error, nil} - end. - --spec find(tree(FCV), FCV) -> {ok, FCV} | {error, nil}. -find(Tree, Key) -> - do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). - --spec do_fold(node_(FCZ), FDB, fun((FDB, FCZ) -> FDB)) -> FDB. -do_fold(Node, Acc, Fun) -> - case Node of - {node, R, V, L} -> - Acc@1 = do_fold(R, Acc, Fun), - Acc@2 = Fun(Acc@1, V), - Acc@3 = do_fold(L, Acc@2, Fun), - Acc@3; - - empty -> - Acc - end. - --spec fold(tree(FCZ), FDB, fun((FDB, FCZ) -> FDB)) -> FDB. -fold(Tree, Acc, Fun) -> - do_fold(erlang:element(2, Tree), Acc, Fun). - --spec do_draw(node_(FDC), integer(), fun((FDC) -> binary())) -> binary(). -do_draw(Node, Indent, To_string) -> - case Node of - {node, L, K, R} -> - Ls = do_draw(L, Indent + 1, To_string), - Ks = do_indent(<<(To_string(K))/binary, "\n"/utf8>>, Indent), - Rs = do_draw(R, Indent + 1, To_string), - <<<<Ls/binary, Ks/binary>>/binary, Rs/binary>>; - - empty -> - <<""/utf8>> - end. - --spec draw(tree(FDC), fun((FDC) -> binary())) -> binary(). -draw(Tree, To_string) -> - do_draw(erlang:element(2, Tree), 0, To_string). - --spec do_min(node_(FCS), fun((FCS, FCS) -> gleam@order:order())) -> node_(FCS). -do_min(Node, Compare) -> - case Node of - {node, {node, _, _, _} = L, _, _} -> - do_min(L, Compare); - - {node, empty, _, _} -> - Node; - - empty -> - empty - end. - --spec do_indent(binary(), integer()) -> binary(). -do_indent(Acc, I) -> - case I of - 0 -> - Acc; - - I@1 -> - do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl deleted file mode 100644 index c29bbebf903..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree.erl +++ /dev/null @@ -1,326 +0,0 @@ --module(gleamy_structures@tree@red_black_tree). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, clear/1, insert/2, delete/2, find/2, fold/3, foldr/3, draw/2]). --export_type([color/0, node_/1, tree/1, min_del/1]). - --type color() :: r | b | bb. - --type node_(FHR) :: e | ee | {t, color(), node_(FHR), FHR, node_(FHR)}. - --opaque tree(FHS) :: {tree, node_(FHS), fun((FHS, FHS) -> gleam@order:order())}. - --type min_del(FHT) :: {min, FHT, node_(FHT)} | none. - --spec new(fun((FHU, FHU) -> gleam@order:order())) -> tree(FHU). -new(Compare) -> - {tree, e, Compare}. - --spec clear(tree(FHW)) -> tree(FHW). -clear(Tree) -> - {tree, e, erlang:element(3, Tree)}. - --spec blacken(node_(FIW)) -> node_(FIW). -blacken(Node) -> - case Node of - {t, r, {t, r, _, _, _} = L, Y, C} -> - {t, b, L, Y, C}; - - {t, r, A, X, {t, r, _, _, _} = R} -> - {t, b, A, X, R}; - - T -> - T - end. - --spec balance(color(), node_(FIZ), FIZ, node_(FIZ)) -> node_(FIZ). -balance(C, L, V, R) -> - case {C, L, V, R} of - {b, {t, r, {t, r, A, X, B}, Y, C@1}, Z, D} -> - {t, r, {t, b, A, X, B}, Y, {t, b, C@1, Z, D}}; - - {b, {t, r, A@1, X@1, {t, r, B@1, Y@1, C@2}}, Z@1, D@1} -> - {t, r, {t, b, A@1, X@1, B@1}, Y@1, {t, b, C@2, Z@1, D@1}}; - - {b, A@2, X@2, {t, r, {t, r, B@2, Y@2, C@3}, Z@2, D@2}} -> - {t, r, {t, b, A@2, X@2, B@2}, Y@2, {t, b, C@3, Z@2, D@2}}; - - {b, A@3, X@3, {t, r, B@3, Y@3, {t, r, C@4, Z@3, D@3}}} -> - {t, r, {t, b, A@3, X@3, B@3}, Y@3, {t, b, C@4, Z@3, D@3}}; - - {bb, A@4, X@4, {t, r, {t, r, B@4, Y@4, C@5}, Z@4, D@4}} -> - {t, b, {t, b, A@4, X@4, B@4}, Y@4, {t, b, C@5, Z@4, D@4}}; - - {bb, {t, r, A@5, X@5, {t, r, B@5, Y@5, C@6}}, Z@5, D@5} -> - {t, b, {t, b, A@5, X@5, B@5}, Y@5, {t, b, C@6, Z@5, D@5}}; - - {C@7, A@6, X@6, B@6} -> - {t, C@7, A@6, X@6, B@6} - end. - --spec redden(node_(FJD)) -> node_(FJD). -redden(Node) -> - case Node of - {t, b, {t, b, _, _, _} = L, Y, {t, b, _, _, _} = R} -> - {t, r, L, Y, R}; - - T -> - T - end. - --spec rotate(color(), node_(FJK), FJK, node_(FJK)) -> node_(FJK). -rotate(C, L, V, R) -> - case {C, L, V, R} of - {r, {t, bb, A, X, B}, Y, {t, b, C@1, Z, D}} -> - balance(b, {t, r, {t, b, A, X, B}, Y, C@1}, Z, D); - - {r, ee, Y@1, {t, b, C@2, Z@1, D@1}} -> - balance(b, {t, r, e, Y@1, C@2}, Z@1, D@1); - - {r, {t, b, A@1, X@1, B@1}, Y@2, {t, bb, C@3, Z@2, D@2}} -> - balance(b, A@1, X@1, {t, r, B@1, Y@2, {t, b, C@3, Z@2, D@2}}); - - {r, {t, b, A@2, X@2, B@2}, Y@3, ee} -> - balance(b, A@2, X@2, {t, r, B@2, Y@3, e}); - - {b, {t, bb, A@3, X@3, B@3}, Y@4, {t, b, C@4, Z@3, D@3}} -> - balance(bb, {t, r, {t, b, A@3, X@3, B@3}, Y@4, C@4}, Z@3, D@3); - - {b, ee, Y@5, {t, b, C@5, Z@4, D@4}} -> - balance(bb, {t, r, e, Y@5, C@5}, Z@4, D@4); - - {b, {t, b, A@4, X@4, B@4}, Y@6, {t, bb, C@6, Z@5, D@5}} -> - balance(bb, A@4, X@4, {t, r, B@4, Y@6, {t, b, C@6, Z@5, D@5}}); - - {b, {t, b, A@5, X@5, B@5}, Y@7, ee} -> - balance(bb, A@5, X@5, {t, r, B@5, Y@7, e}); - - {b, {t, bb, A@6, W, B@6}, X@6, {t, r, {t, b, C@7, Y@8, D@6}, Z@6, E}} -> - {t, - b, - balance(b, {t, r, {t, b, A@6, W, B@6}, X@6, C@7}, Y@8, D@6), - Z@6, - E}; - - {b, ee, X@7, {t, r, {t, b, C@8, Y@9, D@7}, Z@7, E@1}} -> - {t, b, balance(b, {t, r, e, X@7, C@8}, Y@9, D@7), Z@7, E@1}; - - {b, - {t, r, A@7, W@1, {t, b, B@7, X@8, C@9}}, - Y@10, - {t, bb, D@8, Z@8, E@2}} -> - {t, - b, - A@7, - W@1, - balance(b, B@7, X@8, {t, r, C@9, Y@10, {t, b, D@8, Z@8, E@2}})}; - - {b, {t, r, A@8, W@2, {t, b, B@8, X@9, C@10}}, Y@11, ee} -> - {t, b, A@8, W@2, balance(b, B@8, X@9, {t, r, C@10, Y@11, e})}; - - {C@11, A@9, X@10, B@9} -> - {t, C@11, A@9, X@10, B@9} - end. - --spec ins(node_(FHZ), FHZ, fun((FHZ, FHZ) -> gleam@order:order())) -> node_(FHZ). -ins(Node, X, Compare) -> - case Node of - e -> - {t, r, e, X, e}; - - {t, C, A, Y, B} -> - case Compare(X, Y) of - lt -> - balance(C, ins(A, X, Compare), Y, B); - - gt -> - balance(C, A, Y, ins(B, X, Compare)); - - eq -> - {t, C, A, X, B} - end; - - _ -> - Node - end. - --spec insert(tree(FHZ), FHZ) -> tree(FHZ). -insert(Tree, Key) -> - {tree, - blacken(ins(erlang:element(2, Tree), Key, erlang:element(3, Tree))), - erlang:element(3, Tree)}. - --spec del(node_(FIC), FIC, fun((FIC, FIC) -> gleam@order:order())) -> node_(FIC). -del(Node, X, Compare) -> - case Node of - e -> - Node; - - {t, r, e, Y, e} -> - case Compare(X, Y) of - eq -> - e; - - _ -> - Node - end; - - {t, b, e, Y@1, e} -> - case Compare(X, Y@1) of - eq -> - ee; - - _ -> - Node - end; - - {t, b, {t, r, e, Y@2, e} = L, Z, e} -> - case Compare(X, Z) of - lt -> - {t, b, del(L, X, Compare), Z, e}; - - gt -> - Node; - - eq -> - {t, b, e, Y@2, e} - end; - - {t, C, A, Y@3, B} -> - case Compare(X, Y@3) of - lt -> - rotate(C, del(A, X, Compare), Y@3, B); - - gt -> - rotate(C, A, Y@3, del(B, X, Compare)); - - eq -> - case min_del(B) of - {min, Y1, B1} -> - rotate(C, A, Y1, B1); - - none -> - e - end - end; - - _ -> - Node - end. - --spec delete(tree(FIC), FIC) -> tree(FIC). -delete(Tree, Key) -> - {tree, - del(redden(erlang:element(2, Tree)), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_find(node_(FIF), FIF, fun((FIF, FIF) -> gleam@order:order())) -> {ok, - FIF} | - {error, nil}. -do_find(Node, Key, Compare) -> - case Node of - {t, _, L, K, R} -> - case Compare(Key, K) of - lt -> - do_find(L, Key, Compare); - - gt -> - do_find(R, Key, Compare); - - eq -> - {ok, K} - end; - - _ -> - {error, nil} - end. - --spec find(tree(FIF), FIF) -> {ok, FIF} | {error, nil}. -find(Tree, Key) -> - do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). - --spec do_fold(node_(FIJ), FIL, fun((FIL, FIJ) -> FIL)) -> FIL. -do_fold(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_fold(R, Acc, Fun), - Acc@2 = Fun(Acc@1, V), - Acc@3 = do_fold(L, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec fold(tree(FIJ), FIL, fun((FIL, FIJ) -> FIL)) -> FIL. -fold(Tree, Acc, Fun) -> - do_fold(erlang:element(2, Tree), Acc, Fun). - --spec do_foldr(node_(FIM), FIO, fun((FIO, FIM) -> FIO)) -> FIO. -do_foldr(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_foldr(L, Acc, Fun), - Acc@2 = Fun(Acc@1, V), - Acc@3 = do_foldr(R, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec foldr(tree(FIM), FIO, fun((FIO, FIM) -> FIO)) -> FIO. -foldr(Tree, Acc, Fun) -> - do_foldr(erlang:element(2, Tree), Acc, Fun). - --spec do_draw(node_(FIP), integer(), fun((FIP) -> binary())) -> binary(). -do_draw(Node, Indent, To_string) -> - case Node of - {t, _, L, K, R} -> - Ls = do_draw(L, Indent + 1, To_string), - Ks = do_indent(<<(To_string(K))/binary, "\n"/utf8>>, Indent), - Rs = do_draw(R, Indent + 1, To_string), - <<<<Ls/binary, Ks/binary>>/binary, Rs/binary>>; - - _ -> - <<""/utf8>> - end. - --spec draw(tree(FIP), fun((FIP) -> binary())) -> binary(). -draw(Tree, To_string) -> - do_draw(erlang:element(2, Tree), 0, To_string). - --spec min_del(node_(any())) -> min_del(any()). -min_del(Node) -> - case Node of - {t, r, e, X, e} -> - {min, X, e}; - - {t, b, e, X@1, e} -> - {min, X@1, ee}; - - {t, b, e, X@2, {t, r, e, Y, e}} -> - {min, X@2, {t, b, e, Y, e}}; - - {t, C, A, X@3, B} -> - case min_del(A) of - {min, X1, A1} -> - {min, X1, rotate(C, A1, X@3, B)}; - - none -> - none - end; - - _ -> - none - end. - --spec do_indent(binary(), integer()) -> binary(). -do_indent(Acc, I) -> - case I of - 0 -> - Acc; - - I@1 -> - do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) - end. diff --git a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl b/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl deleted file mode 100644 index 710e27d32c4..00000000000 --- a/test-community-packages-javascript/build/packages/gleamy_structures/src/gleamy_structures@tree@red_black_tree_kv.erl +++ /dev/null @@ -1,336 +0,0 @@ --module(gleamy_structures@tree@red_black_tree_kv). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, clear/1, insert/3, delete/2, find/2, fold/3, foldr/3, draw/2]). --export_type([color/0, node_/2, tree/2, min_del/2]). - --type color() :: r | b | bb. - --type node_(GAH, GAI) :: e | - ee | - {t, color(), node_(GAH, GAI), {GAH, GAI}, node_(GAH, GAI)}. - --opaque tree(GAJ, GAK) :: {tree, - node_(GAJ, GAK), - fun((GAJ, GAJ) -> gleam@order:order())}. - --type min_del(GAL, GAM) :: {min, {GAL, GAM}, node_(GAL, GAM)} | none. - --spec new(fun((GAN, GAN) -> gleam@order:order())) -> tree(GAN, any()). -new(Compare) -> - {tree, e, Compare}. - --spec clear(tree(GAR, GAS)) -> tree(GAR, GAS). -clear(Tree) -> - {tree, e, erlang:element(3, Tree)}. - --spec blacken(node_(GCJ, GCK)) -> node_(GCJ, GCK). -blacken(Node) -> - case Node of - {t, r, {t, r, _, _, _} = L, Y, C} -> - {t, b, L, Y, C}; - - {t, r, K, X, {t, r, _, _, _} = R} -> - {t, b, K, X, R}; - - T -> - T - end. - --spec balance(color(), node_(GCP, GCQ), {GCP, GCQ}, node_(GCP, GCQ)) -> node_(GCP, GCQ). -balance(C, L, V, R) -> - case {C, L, V, R} of - {b, {t, r, {t, r, K, X, B}, Y, C@1}, Z, D} -> - {t, r, {t, b, K, X, B}, Y, {t, b, C@1, Z, D}}; - - {b, {t, r, K@1, X@1, {t, r, B@1, Y@1, C@2}}, Z@1, D@1} -> - {t, r, {t, b, K@1, X@1, B@1}, Y@1, {t, b, C@2, Z@1, D@1}}; - - {b, K@2, X@2, {t, r, {t, r, B@2, Y@2, C@3}, Z@2, D@2}} -> - {t, r, {t, b, K@2, X@2, B@2}, Y@2, {t, b, C@3, Z@2, D@2}}; - - {b, K@3, X@3, {t, r, B@3, Y@3, {t, r, C@4, Z@3, D@3}}} -> - {t, r, {t, b, K@3, X@3, B@3}, Y@3, {t, b, C@4, Z@3, D@3}}; - - {bb, K@4, X@4, {t, r, {t, r, B@4, Y@4, C@5}, Z@4, D@4}} -> - {t, b, {t, b, K@4, X@4, B@4}, Y@4, {t, b, C@5, Z@4, D@4}}; - - {bb, {t, r, K@5, X@5, {t, r, B@5, Y@5, C@6}}, Z@5, D@5} -> - {t, b, {t, b, K@5, X@5, B@5}, Y@5, {t, b, C@6, Z@5, D@5}}; - - {C@7, K@6, X@6, B@6} -> - {t, C@7, K@6, X@6, B@6} - end. - --spec redden(node_(GCX, GCY)) -> node_(GCX, GCY). -redden(Node) -> - case Node of - {t, b, {t, b, _, _, _} = L, Y, {t, b, _, _, _} = R} -> - {t, r, L, Y, R}; - - T -> - T - end. - --spec rotate(color(), node_(GDJ, GDK), {GDJ, GDK}, node_(GDJ, GDK)) -> node_(GDJ, GDK). -rotate(C, L, V, R) -> - case {C, L, V, R} of - {r, {t, bb, K, X, B}, Y, {t, b, C@1, Z, D}} -> - balance(b, {t, r, {t, b, K, X, B}, Y, C@1}, Z, D); - - {r, ee, Y@1, {t, b, C@2, Z@1, D@1}} -> - balance(b, {t, r, e, Y@1, C@2}, Z@1, D@1); - - {r, {t, b, K@1, X@1, B@1}, Y@2, {t, bb, C@3, Z@2, D@2}} -> - balance(b, K@1, X@1, {t, r, B@1, Y@2, {t, b, C@3, Z@2, D@2}}); - - {r, {t, b, K@2, X@2, B@2}, Y@3, ee} -> - balance(b, K@2, X@2, {t, r, B@2, Y@3, e}); - - {b, {t, bb, K@3, X@3, B@3}, Y@4, {t, b, C@4, Z@3, D@3}} -> - balance(bb, {t, r, {t, b, K@3, X@3, B@3}, Y@4, C@4}, Z@3, D@3); - - {b, ee, Y@5, {t, b, C@5, Z@4, D@4}} -> - balance(bb, {t, r, e, Y@5, C@5}, Z@4, D@4); - - {b, {t, b, K@4, X@4, B@4}, Y@6, {t, bb, C@6, Z@5, D@5}} -> - balance(bb, K@4, X@4, {t, r, B@4, Y@6, {t, b, C@6, Z@5, D@5}}); - - {b, {t, b, K@5, X@5, B@5}, Y@7, ee} -> - balance(bb, K@5, X@5, {t, r, B@5, Y@7, e}); - - {b, {t, bb, K@6, W, B@6}, X@6, {t, r, {t, b, C@7, Y@8, D@6}, Z@6, E}} -> - {t, - b, - balance(b, {t, r, {t, b, K@6, W, B@6}, X@6, C@7}, Y@8, D@6), - Z@6, - E}; - - {b, ee, X@7, {t, r, {t, b, C@8, Y@9, D@7}, Z@7, E@1}} -> - {t, b, balance(b, {t, r, e, X@7, C@8}, Y@9, D@7), Z@7, E@1}; - - {b, - {t, r, K@7, W@1, {t, b, B@7, X@8, C@9}}, - Y@10, - {t, bb, D@8, Z@8, E@2}} -> - {t, - b, - K@7, - W@1, - balance(b, B@7, X@8, {t, r, C@9, Y@10, {t, b, D@8, Z@8, E@2}})}; - - {b, {t, r, K@8, W@2, {t, b, B@8, X@9, C@10}}, Y@11, ee} -> - {t, b, K@8, W@2, balance(b, B@8, X@9, {t, r, C@10, Y@11, e})}; - - {C@11, K@9, X@10, B@9} -> - {t, C@11, K@9, X@10, B@9} - end. - --spec ins(node_(GCD, GCE), {GCD, GCE}, fun((GCD, GCD) -> gleam@order:order())) -> node_(GCD, GCE). -ins(Node, X, Compare) -> - case Node of - e -> - {t, r, e, X, e}; - - {t, C, K, Y, B} -> - case Compare(erlang:element(1, X), erlang:element(1, Y)) of - lt -> - balance(C, ins(K, X, Compare), Y, B); - - gt -> - balance(C, K, Y, ins(B, X, Compare)); - - eq -> - {t, C, K, X, B} - end; - - _ -> - Node - end. - --spec insert(tree(GAX, GAY), GAX, GAY) -> tree(GAX, GAY). -insert(Tree, Key, Value) -> - {tree, - blacken( - ins(erlang:element(2, Tree), {Key, Value}, erlang:element(3, Tree)) - ), - erlang:element(3, Tree)}. - --spec del(node_(GDD, GDE), GDD, fun((GDD, GDD) -> gleam@order:order())) -> node_(GDD, GDE). -del(Node, X, Compare) -> - case Node of - e -> - Node; - - {t, r, e, Y, e} -> - case Compare(X, erlang:element(1, Y)) of - eq -> - e; - - _ -> - Node - end; - - {t, b, e, Y@1, e} -> - case Compare(X, erlang:element(1, Y@1)) of - eq -> - ee; - - _ -> - Node - end; - - {t, b, {t, r, e, Y@2, e} = L, Z, e} -> - case Compare(X, erlang:element(1, Z)) of - lt -> - {t, b, del(L, X, Compare), Z, e}; - - gt -> - Node; - - eq -> - {t, b, e, Y@2, e} - end; - - {t, C, K, Y@3, B} -> - case Compare(X, erlang:element(1, Y@3)) of - lt -> - rotate(C, del(K, X, Compare), Y@3, B); - - gt -> - rotate(C, K, Y@3, del(B, X, Compare)); - - eq -> - case min_del(B) of - {min, Y1, B1} -> - rotate(C, K, Y1, B1); - - none -> - e - end - end; - - _ -> - Node - end. - --spec delete(tree(GBD, GBE), GBD) -> tree(GBD, GBE). -delete(Tree, Key) -> - {tree, - del(redden(erlang:element(2, Tree)), Key, erlang:element(3, Tree)), - erlang:element(3, Tree)}. - --spec do_find(node_(GDX, GDY), GDX, fun((GDX, GDX) -> gleam@order:order())) -> {ok, - {GDX, GDY}} | - {error, nil}. -do_find(Node, Key, Compare) -> - case Node of - {t, _, L, K, R} -> - case Compare(Key, erlang:element(1, K)) of - lt -> - do_find(L, Key, Compare); - - gt -> - do_find(R, Key, Compare); - - eq -> - {ok, K} - end; - - _ -> - {error, nil} - end. - --spec find(tree(GBJ, GBK), GBJ) -> {ok, {GBJ, GBK}} | {error, nil}. -find(Tree, Key) -> - do_find(erlang:element(2, Tree), Key, erlang:element(3, Tree)). - --spec do_fold(node_(GED, GEE), GEH, fun((GEH, GED, GEE) -> GEH)) -> GEH. -do_fold(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_fold(R, Acc, Fun), - Acc@2 = Fun(Acc@1, erlang:element(1, V), erlang:element(2, V)), - Acc@3 = do_fold(L, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec fold(tree(GBP, GBQ), GBT, fun((GBT, GBP, GBQ) -> GBT)) -> GBT. -fold(Tree, Acc, Fun) -> - do_fold(erlang:element(2, Tree), Acc, Fun). - --spec do_foldr(node_(GEI, GEJ), GEM, fun((GEM, GEI, GEJ) -> GEM)) -> GEM. -do_foldr(Node, Acc, Fun) -> - case Node of - {t, _, R, V, L} -> - Acc@1 = do_foldr(L, Acc, Fun), - Acc@2 = Fun(Acc@1, erlang:element(1, V), erlang:element(2, V)), - Acc@3 = do_foldr(R, Acc@2, Fun), - Acc@3; - - _ -> - Acc - end. - --spec foldr(tree(GBU, GBV), GBY, fun((GBY, GBU, GBV) -> GBY)) -> GBY. -foldr(Tree, Acc, Fun) -> - do_foldr(erlang:element(2, Tree), Acc, Fun). - --spec do_draw(node_(GEN, GEO), integer(), fun((GEN, GEO) -> binary())) -> binary(). -do_draw(Node, Indent, To_string) -> - case Node of - {t, _, L, K, R} -> - Ls = do_draw(L, Indent + 1, To_string), - Ks = do_indent( - <<(To_string(erlang:element(1, K), erlang:element(2, K)))/binary, - "\n"/utf8>>, - Indent - ), - Rs = do_draw(R, Indent + 1, To_string), - <<<<Ls/binary, Ks/binary>>/binary, Rs/binary>>; - - _ -> - <<""/utf8>> - end. - --spec draw(tree(GBZ, GCA), fun((GBZ, GCA) -> binary())) -> binary(). -draw(Tree, To_string) -> - do_draw(erlang:element(2, Tree), 0, To_string). - --spec min_del(node_(GDR, GDS)) -> min_del(GDR, GDS). -min_del(Node) -> - case Node of - {t, r, e, X, e} -> - {min, X, e}; - - {t, b, e, X@1, e} -> - {min, X@1, ee}; - - {t, b, e, X@2, {t, r, e, Y, e}} -> - {min, X@2, {t, b, e, Y, e}}; - - {t, C, K, X@3, B} -> - case min_del(K) of - {min, X1, A1} -> - {min, X1, rotate(C, A1, X@3, B)}; - - none -> - none - end; - - _ -> - none - end. - --spec do_indent(binary(), integer()) -> binary(). -do_indent(Acc, I) -> - case I of - 0 -> - Acc; - - I@1 -> - do_indent(<<". "/utf8, Acc/binary>>, I@1 - 1) - end. diff --git a/test-community-packages-javascript/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/gleeunit/LICENCE deleted file mode 100644 index c7967c32d6f..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2021, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/gleeunit/README.md deleted file mode 100644 index 2b685d9bc70..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# gleeunit - -Gleam bindings to the Erlang EUnit test framework. - -A custom test runner is included for when compiled to JavaScript running on -either NodeJS or Deno. - -Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). - -## Usage - -Add this package to your Gleam project. - -```sh -gleam add gleeunit --dev -``` - -And then call the `gleeunit.main` function from your test main function. - -```gleam -// In test/yourapp_test.gleam -import gleeunit - -pub fn main() { - gleeunit.main() -} -``` - -Now any public function with a name ending in `_test` in the `test` directory -will be found and run as a test. - -```gleam -pub fn the_universe_test() { - assert 1 = 1 -} -``` - -Run the tests by entering `gleam test` in the command line. - -### Deno - -If using the Deno JavaScript runtime, you will need to add the following to your -`gleam.toml`. - -```toml -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] -``` diff --git a/test-community-packages-javascript/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/gleeunit/gleam.toml deleted file mode 100644 index 5438dd20a74..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleeunit" -version = "0.10.1" -licences = ["Apache-2.0"] -description = "Gleam bindings to Erlang's EUnit test framework" - -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] - -[dependencies] -gleam_stdlib = "~> 0.19" - -[dev-dependencies] -# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src deleted file mode 100644 index f5525522d33..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleeunit, [ - {vsn, "0.10.1"}, - {applications, [gleam_stdlib]}, - {description, "Gleam bindings to Erlang's EUnit test framework"}, - {modules, [gleeunit, - gleeunit@should]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl deleted file mode 100644 index 916082bcb17..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gleeunit). --compile(no_auto_import). - --export([main/0]). --export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). - --type atom_() :: any(). - --type encoding() :: utf8. - --type report_module_name() :: gleeunit_progress. - --type gleeunit_progress_option() :: {colored, boolean()}. - --type eunit_option() :: verbose | - no_tty | - {report, {report_module_name(), list(gleeunit_progress_option())}}. - --spec main() -> nil. -main() -> - do_main(). - --spec do_main() -> nil. -do_main() -> - Options = [verbose, - no_tty, - {report, {gleeunit_progress, [{colored, true}]}}], - Result = begin - _pipe = gleeunit_ffi:find_files( - <<"**/*.{erl,gleam}"/utf8>>, - <<"test"/utf8>> - ), - _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end - ), - _pipe@3 = eunit:test(_pipe@2, Options), - _pipe@4 = (gleam@dynamic:result( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ))(_pipe@3), - gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) - end, - Code = case Result of - {ok, _} -> - 0; - - {error, _} -> - 1 - end, - erlang:halt(Code). - --spec gleam_to_erlang_module_name(binary()) -> binary(). -gleam_to_erlang_module_name(Path) -> - _pipe = Path, - _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), - gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam deleted file mode 100644 index 751587a977a..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit.gleam +++ /dev/null @@ -1,80 +0,0 @@ -/// Find and run all test functions for the current project using Erlang's EUnit -/// test framework. -/// -/// Any Erlang or Gleam function in the `test` directory with a name editing in -/// `_test` is considered a test function and will be run. -/// -/// If running on JavaScript tests will be run with a custom test runner. -/// -pub fn main() -> Nil { - do_main() -} - -if javascript { - external fn do_main() -> Nil = - "./gleeunit_ffi.mjs" "main" -} - -if erlang { - import gleam/list - import gleam/result - import gleam/string - import gleam/dynamic.{Dynamic} - - fn do_main() -> Nil { - let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] - - let result = - find_files(matching: "**/*.{erl,gleam}", in: "test") - |> list.map(gleam_to_erlang_module_name) - |> list.map(dangerously_convert_string_to_atom(_, Utf8)) - |> run_eunit(options) - |> dynamic.result(dynamic.dynamic, dynamic.dynamic) - |> result.unwrap(Error(dynamic.from(Nil))) - - let code = case result { - Ok(_) -> 0 - Error(_) -> 1 - } - halt(code) - } - - external fn halt(Int) -> Nil = - "erlang" "halt" - - fn gleam_to_erlang_module_name(path: String) -> String { - path - |> string.replace(".gleam", "") - |> string.replace(".erl", "") - |> string.replace("/", "@") - } - - external fn find_files(matching: String, in: String) -> List(String) = - "gleeunit_ffi" "find_files" - - external type Atom - - type Encoding { - Utf8 - } - - external fn dangerously_convert_string_to_atom(String, Encoding) -> Atom = - "erlang" "binary_to_atom" - - type ReportModuleName { - GleeunitProgress - } - - type GleeunitProgressOption { - Colored(Bool) - } - - type EunitOption { - Verbose - NoTty - Report(#(ReportModuleName, List(GleeunitProgressOption))) - } - - external fn run_eunit(List(Atom), List(EunitOption)) -> Dynamic = - "eunit" "test" -} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam deleted file mode 100644 index fc80c7583fd..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit/should.gleam +++ /dev/null @@ -1,83 +0,0 @@ -//// A module for testing your Gleam code. The functions found here are -//// compatible with the Erlang eunit test framework. -//// -//// More information on running eunit can be found in [the rebar3 -//// documentation](https://rebar3.org/docs/testing/eunit/). - -if erlang { - pub external fn equal(a, a) -> Nil = - "gleeunit_ffi" "should_equal" - - pub external fn not_equal(a, a) -> Nil = - "gleeunit_ffi" "should_not_equal" - - pub external fn be_ok(Result(a, b)) -> a = - "gleeunit_ffi" "should_be_ok" - - pub external fn be_error(Result(a, b)) -> b = - "gleeunit_ffi" "should_be_error" -} - -if javascript { - import gleam/string - - external fn stringify(anything) -> String = - "../gleam.mjs" "inspect" - - external fn crash(String) -> anything = - "../gleeunit_ffi.mjs" "crash" - - pub fn equal(a, b) { - case a == b { - True -> Nil - _ -> - crash(string.concat([ - "\n\t", - stringify(a), - "\n\tshould equal \n\t", - stringify(b), - ])) - } - } - - pub fn not_equal(a, b) { - case a != b { - True -> Nil - _ -> - crash(string.concat([ - "\n", - stringify(a), - "\nshould not equal \n", - stringify(b), - ])) - } - } - - pub fn be_ok(a) { - case a { - Ok(value) -> value - _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) - } - } - - pub fn be_error(a) { - case a { - Error(error) -> error - _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) - } - } -} - -pub fn be_true(actual: Bool) -> Nil { - actual - |> equal(True) -} - -pub fn be_false(actual: Bool) -> Nil { - actual - |> equal(False) -} - -pub fn fail() -> Nil { - be_true(False) -} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl deleted file mode 100644 index eb04c98772c..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit@should.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(gleeunit@should). --compile(no_auto_import). - --export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). - --spec equal(EIP, EIP) -> nil. -equal(Field@0, Field@1) -> - gleeunit_ffi:should_equal(Field@0, Field@1). - --spec not_equal(EIQ, EIQ) -> nil. -not_equal(Field@0, Field@1) -> - gleeunit_ffi:should_not_equal(Field@0, Field@1). - --spec be_ok({ok, EIR} | {error, any()}) -> EIR. -be_ok(Field@0) -> - gleeunit_ffi:should_be_ok(Field@0). - --spec be_error({ok, any()} | {error, EIV}) -> EIV. -be_error(Field@0) -> - gleeunit_ffi:should_be_error(Field@0). - --spec be_true(boolean()) -> nil. -be_true(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, true). - --spec be_false(boolean()) -> nil. -be_false(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, false). - --spec fail() -> nil. -fail() -> - be_true(false). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl deleted file mode 100644 index 31f9ef9e2c9..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(gleeunit_ffi). - --export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, - should_be_error/1]). - --include_lib("eunit/include/eunit.hrl"). - -find_files(Pattern, In) -> - Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), - lists:map(fun list_to_binary/1, Results). - - -should_equal(Actual, Expected) -> - ?assertEqual(Expected, Actual), - nil. -should_not_equal(Actual, Expected) -> - ?assertNotEqual(Expected, Actual), - nil. -should_be_ok(A) -> - ?assertMatch({ok, _}, A), - element(2, A). -should_be_error(A) -> - ?assertMatch({error, _}, A), - element(2, A). diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs deleted file mode 100644 index 339a843e5c5..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_ffi.mjs +++ /dev/null @@ -1,101 +0,0 @@ -async function* gleamFiles(directory) { - for (let entry of await read_dir(directory)) { - let path = join_path(directory, entry); - if (path.endsWith(".gleam")) { - yield path; - } else { - try { - yield* gleamFiles(path); - } catch (error) { - // Could not read directory, assume it's a file - } - } - } -} - -async function readRootPackageName() { - let toml = await read_file("gleam.toml", "utf-8"); - for (let line of toml.split("\n")) { - let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() - if (matches) return matches[1]; - } - throw new Error("Could not determine package name from gleam.toml"); -} - -export async function main() { - let passes = 0; - let failures = 0; - - let packageName = await readRootPackageName(); - let dist = `../${packageName}/`; - - for await (let path of await gleamFiles("test")) { - let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); - let module = await import(join_path(dist, js_path)); - for (let fnName of Object.keys(module)) { - if (!fnName.endsWith("_test")) continue; - try { - await module[fnName](); - write(`\u001b[32m.\u001b[0m`); - passes++; - } catch (error) { - let moduleName = "\n" + js_path.slice(0, -4); - let line = error.line ? `:${error.line}` : ""; - write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); - failures++; - } - } - } - - console.log(` -${passes + failures} tests, ${failures} failures`); - exit(failures ? 1 : 0); -} - -export function crash(message) { - throw new Error(message); -} - -function write(message) { - if (globalThis.Deno) { - Deno.stdout.writeSync(new TextEncoder().encode(message)); - } else { - process.stdout.write(message); - } -} - -function exit(code) { - if (globalThis.Deno) { - Deno.exit(code); - } else { - process.exit(code); - } -} - -async function read_dir(path) { - if (globalThis.Deno) { - let items = []; - for await (let item of Deno.readDir(path, { withFileTypes: true })) { - items.push(item.name); - } - return items; - } else { - let { readdir } = await import("fs/promises"); - return readdir(path); - } -} - -function join_path(a, b) { - if (a.endsWith("/")) return a + b; - return a + "/" + b; -} - -async function read_file(path) { - if (globalThis.Deno) { - return Deno.readTextFile(path); - } else { - let { readFile } = await import("fs/promises"); - let contents = await readFile(path); - return contents.toString(); - } -} diff --git a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl deleted file mode 100644 index 1f68eb95e58..00000000000 --- a/test-community-packages-javascript/build/packages/gleeunit/src/gleeunit_progress.erl +++ /dev/null @@ -1,607 +0,0 @@ -%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters - -%% @doc A listener/reporter for eunit that prints '.' for each -%% success, 'F' for each failure, and 'E' for each error. It can also -%% optionally summarize the failures at the end. --compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). --module(gleeunit_progress). --behaviour(eunit_listener). --define(NOTEST, true). --include_lib("eunit/include/eunit.hrl"). - --define(RED, "\e[0;31m"). --define(GREEN, "\e[0;32m"). --define(YELLOW, "\e[0;33m"). --define(WHITE, "\e[0;37m"). --define(CYAN, "\e[0;36m"). --define(RESET, "\e[0m"). - --record(node,{ - rank = 0 :: non_neg_integer(), - key :: term(), - value :: term(), - children = new() :: binomial_heap() - }). - --export_type([binomial_heap/0, heap_node/0]). --type binomial_heap() :: [ heap_node() ]. --type heap_node() :: #node{}. - -%% eunit_listener callbacks --export([ - init/1, - handle_begin/3, - handle_end/3, - handle_cancel/3, - terminate/2, - start/0, - start/1 - ]). - -%% -- binomial_heap.erl content start -- - --record(state, { - status = dict:new() :: euf_dict(), - failures = [] :: [[pos_integer()]], - skips = [] :: [[pos_integer()]], - timings = new() :: binomial_heap(), - colored = true :: boolean(), - profile = false :: boolean() - }). - --type euf_dict() :: dict:dict(). - --spec new() -> binomial_heap(). -new() -> - []. - -% Inserts a new pair into the heap (or creates a new heap) --spec insert(term(), term()) -> binomial_heap(). -insert(Key,Value) -> - insert(Key,Value,[]). - --spec insert(term(), term(), binomial_heap()) -> binomial_heap(). -insert(Key,Value,Forest) -> - insTree(#node{key=Key,value=Value},Forest). - -% Merges two heaps --spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). -merge(TS1,[]) when is_list(TS1) -> TS1; -merge([],TS2) when is_list(TS2) -> TS2; -merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> - if - R1 < R2 -> - [T1 | merge(TS1,F2)]; - R2 < R1 -> - [T2 | merge(F1, TS2)]; - true -> - insTree(link(T1,T2),merge(TS1,TS2)) - end. - -% Deletes the top entry from the heap and returns it --spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. -delete(TS) -> - {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), - {{Key,Value},merge(lists:reverse(TS1),TS2)}. - -% Turns the heap into list in heap order --spec to_list(binomial_heap()) -> [{term(), term()}]. -to_list([]) -> []; -to_list(List) when is_list(List) -> - to_list([],List). -to_list(Acc, []) -> - lists:reverse(Acc); -to_list(Acc,Forest) -> - {Next, Trees} = delete(Forest), - to_list([Next|Acc], Trees). - -% Take N elements from the top of the heap --spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. -take(N,Trees) when is_integer(N), is_list(Trees) -> - take(N,Trees,[]). -take(0,_Trees,Acc) -> - lists:reverse(Acc); -take(_N,[],Acc)-> - lists:reverse(Acc); -take(N,Trees,Acc) -> - {Top,T2} = delete(Trees), - take(N-1,T2,[Top|Acc]). - -% Get an estimate of the size based on the binomial property --spec size(binomial_heap()) -> non_neg_integer(). -size(Forest) -> - erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). - -%% Private API --spec link(heap_node(), heap_node()) -> heap_node(). -link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> - case X1 < X2 of - true -> - T1#node{rank=R+1,children=[T2|C1]}; - _ -> - T2#node{rank=R+1,children=[T1|C2]} - end. - -insTree(Tree, []) -> - [Tree]; -insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> - case R1 < R2 of - true -> - [T1|TS]; - _ -> - insTree(link(T1,T2),Rest) - end. - -getMin([T]) -> - {T,[]}; -getMin([#node{key=K} = T|TS]) -> - {#node{key=K1} = T1,TS1} = getMin(TS), - case K < K1 of - true -> {T,TS}; - _ -> {T1,[T|TS1]} - end. - -%% -- binomial_heap.erl content end -- - -%% Startup -start() -> - start([]). - -start(Options) -> - eunit_listener:start(?MODULE, Options). - -%%------------------------------------------ -%% eunit_listener callbacks -%%------------------------------------------ -init(Options) -> - #state{colored=proplists:get_bool(colored, Options), - profile=proplists:get_bool(profile, Options)}. - -handle_begin(group, Data, St) -> - GID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; -handle_begin(test, Data, St) -> - TID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. - -handle_end(group, Data, St) -> - St#state{status=merge_on_end(Data, St#state.status)}; -handle_end(test, Data, St) -> - NewStatus = merge_on_end(Data, St#state.status), - St1 = print_progress(Data, St), - St2 = record_timing(Data, St1), - St2#state{status=NewStatus}. - -handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> - Status1 = merge_on_end(Data, Status), - ID = proplists:get_value(id, Data), - St#state{status=Status1, skips=[ID|Skips]}. - -terminate({ok, Data}, St) -> - print_failures(St), - print_pending(St), - print_profile(St), - print_timing(St), - print_results(Data, St); -terminate({error, Reason}, St) -> - io:nl(), io:nl(), - print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), - sync_end(error). - -sync_end(Result) -> - receive - {stop, Reference, ReplyTo} -> - ReplyTo ! {result, Reference, Result}, - ok - end. - -%%------------------------------------------ -%% Print and collect information during run -%%------------------------------------------ -print_progress(Data, St) -> - TID = proplists:get_value(id, Data), - case proplists:get_value(status, Data) of - ok -> - print_progress_success(St), - St; - {skipped, _Reason} -> - print_progress_skipped(St), - St#state{skips=[TID|St#state.skips]}; - {error, Exception} -> - print_progress_failed(Exception, St), - St#state{failures=[TID|St#state.failures]} - end. - -record_timing(Data, State=#state{timings=T, profile=true}) -> - TID = proplists:get_value(id, Data), - case lists:keyfind(time, 1, Data) of - {time, Int} -> - %% It's a min-heap, so we insert negative numbers instead - %% of the actuals and normalize when we report on them. - T1 = insert(-Int, TID, T), - State#state{timings=T1}; - false -> - State - end; -record_timing(_Data, State) -> - State. - -print_progress_success(St) -> - print_colored(".", ?GREEN, St). - -print_progress_skipped(St) -> - print_colored("*", ?YELLOW, St). - -print_progress_failed(_Exc, St) -> - print_colored("F", ?RED, St). - -merge_on_end(Data, Dict) -> - ID = proplists:get_value(id, Data), - dict:update(ID, - fun(Old) -> - orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) - end, Dict). - -merge_data(_K, undefined, X) -> X; -merge_data(_K, X, undefined) -> X; -merge_data(_K, _, X) -> X. - -%%------------------------------------------ -%% Print information at end of run -%%------------------------------------------ -print_failures(#state{failures=[]}) -> - ok; -print_failures(#state{failures=Fails}=State) -> - io:nl(), - io:fwrite("Failures:~n",[]), - lists:foldr(print_failure_fun(State), 1, Fails), - ok. - -print_failure_fun(#state{status=Status}=State) -> - fun(Key, Count) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:fwrite("~n ~p) ~ts~n", [Count, TestId]), - print_failure_reason(proplists:get_value(status, TestData), - proplists:get_value(output, TestData), - State), - io:nl(), - Count + 1 - end. - -print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> - X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), - print_colored(X, ?CYAN, State); -print_gleam_location(_, _) -> - ok. - -inspect(X) -> - gleam@string:inspect(X). - -print_gleam_failure_reason( - #{gleam_error := assert, message := Message, value := Value}, - State -) -> - print_colored(indent(5, "~s~n", [Message]), ?RED, State), - print_colored(indent(5, " value: ", []), ?RED, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); -print_gleam_failure_reason( - #{gleam_error := todo, message := Message}, - State -) -> - print_colored(indent(5, "todo expression run~n", []), ?RED, State), - print_colored(indent(5, " message: ", []), ?RED, State), - print_colored(indent(0, "~s~n", [Message]), ?RESET, State); -print_gleam_failure_reason(Error, State) -> - print_colored(indent(5, "~p~n", [Error]), ?RED, State). - -% New Gleeunit specific formatters -print_failure_reason( - {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State -) when is_list(Stack) -> - print_gleam_failure_reason(Error, State), - print_gleam_location(Error, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "No case clause matched~n", []), ?RED, State), - print_colored(indent(5, "Value: ", []), ?CYAN, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -% From the original Erlang version -print_failure_reason({skipped, Reason}, _Output, State) -> - print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), - ?RED, State); -print_failure_reason({error, {_Class, Term, _}}, Output, State) when - is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> - print_assertion_failure(Term, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, Reason}, Output, State) -> - print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), - print_failure_output(5, Output, State). - -gleam_format_module_name(Module) -> - string:replace(atom_to_list(Module), "@", "/", all). - -print_stack(Stack, State) -> - print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), - print_stackframes(Stack, State). -print_stackframes([{eunit_test, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> - GleamModule = gleam_format_module_name(Module), - print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), - print_stackframes(Stack, State); -print_stackframes([], _State) -> - ok. - - -print_failure_output(_, <<>>, _) -> ok; -print_failure_output(_, undefined, _) -> ok; -print_failure_output(Indent, Output, State) -> - print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). - -print_assertion_failure({Type, Props}, State) -> - FailureDesc = format_assertion_failure(Type, Props, 5), - print_colored(FailureDesc, ?RED, State), - io:nl(). - -print_pending(#state{skips=[]}) -> - ok; -print_pending(#state{status=Status, skips=Skips}=State) -> - io:nl(), - io:fwrite("Pending:~n", []), - lists:foreach(fun(ID) -> - Info = dict:fetch(ID, Status), - case proplists:get_value(reason, Info) of - undefined -> - ok; - Reason -> - print_pending_reason(Reason, Info, State) - end - end, lists:reverse(Skips)), - io:nl(). - -print_pending_reason(Reason0, Data, State) -> - Text = case proplists:get_value(type, Data) of - group -> - io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); - test -> - io_lib:format(" ~ts~n", [format_test_identifier(Data)]) - end, - Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), - print_colored(Text, ?YELLOW, State), - print_colored(Reason, ?CYAN, State). - -print_profile(#state{timings=T, status=Status, profile=true}=State) -> - TopN = take(10, T), - TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), - TLG = dict:fetch([], Status), - TotalTime = proplists:get_value(time, TLG), - if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> - TopNPct = (TopNTime / TotalTime) * 100, - io:nl(), io:nl(), - io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), - lists:foreach(print_timing_fun(State), TopN), - io:nl(); - true -> ok - end; -print_profile(#state{profile=false}) -> - ok. - -print_timing(#state{status=Status}) -> - TLG = dict:fetch([], Status), - Time = proplists:get_value(time, TLG), - io:nl(), - io:fwrite("Finished in ~ts~n", [format_time(Time)]), - ok. - -print_results(Data, State) -> - Pass = proplists:get_value(pass, Data, 0), - Fail = proplists:get_value(fail, Data, 0), - Skip = proplists:get_value(skip, Data, 0), - Cancel = proplists:get_value(cancel, Data, 0), - Total = Pass + Fail + Skip + Cancel, - {Color, Result} = if Fail > 0 -> {?RED, error}; - Skip > 0; Cancel > 0 -> {?YELLOW, error}; - Pass =:= 0 -> {?YELLOW, ok}; - true -> {?GREEN, ok} - end, - print_results(Color, Total, Fail, Skip, Cancel, State), - sync_end(Result). - -print_results(Color, 0, _, _, _, State) -> - print_colored(Color, "0 tests\n", State); -print_results(Color, Total, Fail, Skip, Cancel, State) -> - SkipText = format_optional_result(Skip, "skipped"), - CancelText = format_optional_result(Cancel, "cancelled"), - Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), - print_colored(Text, Color, State). - -print_timing_fun(#state{status=Status}=State) -> - fun({Time, Key}) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:nl(), - io:fwrite(" ~ts~n", [TestId]), - print_colored([" "|format_time(abs(Time))], ?CYAN, State) - end. - -%%------------------------------------------ -%% Print to the console with the given color -%% if enabled. -%%------------------------------------------ -print_colored(Text, Color, #state{colored=true}) -> - io:fwrite("~s~ts~s", [Color, Text, ?RESET]); -print_colored(Text, _Color, #state{colored=false}) -> - io:fwrite("~ts", [Text]). - -%%------------------------------------------ -%% Generic data formatters -%%------------------------------------------ -format_function_name(M, F) -> - M1 = gleam_format_module_name(M), - io_lib:format("~ts.~ts", [M1, F]). - -format_optional_result(0, _) -> - []; -format_optional_result(Count, Text) -> - io_lib:format(", ~p ~ts", [Count, Text]). - -format_test_identifier(Data) -> - {Mod, Fun, _} = proplists:get_value(source, Data), - Line = case proplists:get_value(line, Data) of - 0 -> ""; - L -> io_lib:format(":~p", [L]) - end, - Desc = case proplists:get_value(desc, Data) of - undefined -> ""; - DescText -> io_lib:format(": ~ts", [DescText]) - end, - io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). - -format_time(undefined) -> - "? seconds"; -format_time(Time) -> - io_lib:format("~.3f seconds", [Time / 1000]). - -format_pending_reason({module_not_found, M}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Module '~ts' missing", [M1]); -format_pending_reason({no_such_function, {M,F,_}}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); -format_pending_reason({exit, Reason}) -> - io_lib:format("Related process exited with reason: ~p", [Reason]); -format_pending_reason(Reason) -> - io_lib:format("Unknown error: ~p", [Reason]). - -%% @doc Formats all the known eunit assertions, you're on your own if -%% you make an assertion yourself. -format_assertion_failure(Type, Props, I) when Type =:= assertion_failed - ; Type =:= assert -> - Keys = proplists:get_keys(Props), - HasEUnitProps = ([expression, value] -- Keys) =:= [], - HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], - if - HasEUnitProps -> - [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), - indent(I, " expected: true~n", []), - case proplists:get_value(value, Props) of - false -> - indent(I, " got: false", []); - {not_a_boolean, V} -> - indent(I, " got: ~p", [V]) - end]; - HasHamcrestProps -> - [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), - indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), - indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; - true -> - [indent(I, "Failure: unknown assert: ~p", [Props])] - end; - -format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed - ; Type =:= assertMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed - ; Type =:= assertNotMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected not: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed - ; Type =:= assertEqual -> - Expected = inspect(proplists:get_value(expected, Props)), - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were not equal~n", []), - indent(I, "expected: ~ts~n", [Expected]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed - ; Type =:= assertNotEqual -> - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were equal~n", []), - indent(I, "expected: not ~ts~n,", [Value]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertException_failed - ; Type =:= assertException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA - [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - case proplists:is_defined(unexpected_success, Props) of - true -> - [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), - indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; - false -> - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, " expected: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])] - end]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed - ; Type =:= assertNotException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - indent(I, " expected not: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])]; - -format_assertion_failure(Type, Props, I) when Type =:= command_failed - ; Type =:= command -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed - ; Type =:= assertCmd -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed - ; Type =:= assertCmdOutput -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_output, Props), - Output = proplists:get_value(output, Props), - [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: ~p~n", [Expected]), - indent(I, " got: ~p", [Output])]; - -format_assertion_failure(Type, Props, I) -> - indent(I, "~p", [{Type, Props}]). - -indent(I, Fmt, Args) -> - io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). - -extract_exception_pattern(Str) -> - ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), - {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glenvy/LICENSE b/test-community-packages-javascript/build/packages/glenvy/LICENSE deleted file mode 100644 index b96ba24ed35..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Marshall Bowers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glenvy/README.md b/test-community-packages-javascript/build/packages/glenvy/README.md deleted file mode 100644 index ac251f80ec8..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# glenvy - -[![Package Version](https://img.shields.io/hexpm/v/glenvy)](https://hex.pm/packages/glenvy) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glenvy/) - -🏞️ A pleasant way to interact with your environment. - -## Installation - -```sh -gleam add glenvy -``` - -## Usage - -```gleam -import gleam/io -import gleam/result.{try} -import glenvy/dotenv -import glenvy/env - -pub fn main() { - let _ = dotenv.load() - - use hello <- try(env.get_string("HELLO")) - - io.println("HELLO=" <> hello) - - Ok(Nil) -} -``` diff --git a/test-community-packages-javascript/build/packages/glenvy/gleam.toml b/test-community-packages-javascript/build/packages/glenvy/gleam.toml deleted file mode 100644 index c1f7effe367..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "glenvy" -version = "0.4.0" -description = "A pleasant way to interact with your environment." -licences = ["MIT"] -repository = { type = "github", user = "maxdeviant", repo = "glenvy" } - -[dependencies] -gleam_stdlib = "~> 0.29" -gleam_erlang = "~> 0.19" -glx = "~> 0.2" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl b/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl deleted file mode 100644 index a6b1bdc2a61..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/include/glenvy@error_Io.hrl +++ /dev/null @@ -1 +0,0 @@ --record(io, {message :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src b/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src deleted file mode 100644 index 5c82e5464a5..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy.app.src +++ /dev/null @@ -1,16 +0,0 @@ -{application, glenvy, [ - {vsn, "0.4.0"}, - {applications, [gleam_erlang, - gleam_stdlib, - gleeunit, - glx]}, - {description, "A pleasant way to interact with your environment."}, - {modules, [glenvy@dotenv, - glenvy@env, - glenvy@error, - glenvy@internal@file, - glenvy@internal@os, - glenvy@internal@parser, - glenvy@internal@string]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam deleted file mode 100644 index 9cda7d92bcc..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/dotenv.gleam +++ /dev/null @@ -1,42 +0,0 @@ -//// Support for `.env` files. - -import gleam/list -import gleam/map -import gleam/result.{try} -import glenvy/error.{Error} -import glenvy/internal/file -import glenvy/internal/os -import glenvy/internal/parser - -/// Loads the `.env` file. -pub fn load() -> Result(Nil, Error) { - load_from(".env") -} - -/// Loads the file at the specified path as a `.env` file. -pub fn load_from(path filepath: String) -> Result(Nil, Error) { - use env_file <- try(find(filepath)) - - let env_vars = - env_file - |> parser.parse_env_file - - env_vars - |> map.to_list - |> list.each(fn(env_var) { - let #(key, value) = env_var - - os.set_env(key, value) - }) - - Ok(Nil) -} - -fn find(filepath: String) -> Result(String, Error) { - use contents <- try( - file.read(filepath) - |> result.map_error(error.Io), - ) - - Ok(contents) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam deleted file mode 100644 index 927a88e973a..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/env.gleam +++ /dev/null @@ -1,81 +0,0 @@ -//// Strongly-typed access to environment variables. - -import gleam/float -import gleam/int -import gleam/result.{try} -import gleam/string -import glenvy/internal/os - -/// Returns the value for the environment variable with the given name as a `String`. -pub fn get_string(name: String) -> Result(String, Nil) { - os.get_env(name) -} - -/// Returns the value for the environment variable with the given name. -/// -/// Uses the provided `parser` to parse the value. -/// -/// Returns `Error(Nil)` if the provided `parser` returns `Error(Nil)`. -pub fn get( - name: String, - parser parse: fn(String) -> Result(a, Nil), -) -> Result(a, Nil) { - use value <- try(get_string(name)) - - value - |> parse -} - -/// Returns the value for the environment variable with the given name as an `Int`. -/// -/// Returns `Error(Nil)` if the environment variable cannot be parsed as an `Int`. -pub fn get_int(name: String) -> Result(Int, Nil) { - name - |> get(parser: int.parse) -} - -/// Returns the value for the environment variable with the given name as a `Float`. -/// -/// Returns `Error(Nil)` if the environment variable cannot be parsed as a `Float`. -pub fn get_float(name: String) -> Result(Float, Nil) { - name - |> get(parser: float.parse) -} - -/// Returns the value for the environment variable with the given name as a `Bool`. -/// -/// The following values are parsed as `True`: -/// - `true` -/// - `t` -/// - `yes` -/// - `y` -/// - `1` -/// -/// The following values are pased as `False`: -/// - `false` -/// - `f` -/// - `no` -/// - `n` -/// - `0` -/// -/// The parsing is case-insensitive. -/// -/// Returns `Error(Nil)` if the environment variable cannot be parsed as a `Bool`. -/// -/// Use `get` if you want to provide your own parser. -pub fn get_bool(name: String) -> Result(Bool, Nil) { - let parse_bool = fn(value) { - let value = - value - |> string.lowercase - - case value { - "true" | "t" | "yes" | "y" | "1" -> Ok(True) - "false" | "f" | "no" | "n" | "0" -> Ok(False) - _ -> Error(Nil) - } - } - - name - |> get(parser: parse_bool) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam deleted file mode 100644 index bdd8726251a..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/error.gleam +++ /dev/null @@ -1,5 +0,0 @@ -/// An error that occurred while reading a `.env` file. -pub type Error { - /// An IO error. - Io(message: String) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam deleted file mode 100644 index 125217a90fd..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/file.gleam +++ /dev/null @@ -1,15 +0,0 @@ -if erlang { - import gleam/erlang/file - import gleam/result - import gleam/string - - pub fn read(from path: String) -> Result(String, String) { - file.read(from: path) - |> result.map_error(string.inspect) - } -} - -if javascript { - pub external fn read(from: String) -> Result(String, String) = - "../../glenvy_ffi.mjs" "read_file" -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam deleted file mode 100644 index 898a91b7aa2..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/os.gleam +++ /dev/null @@ -1,26 +0,0 @@ -if erlang { - import gleam/erlang/os - - pub fn get_env(name: String) -> Result(String, Nil) { - os.get_env(name) - } - - pub fn set_env(name: String, value: String) -> Nil { - os.set_env(name, value) - } - - pub fn unset_env(name: String) -> Nil { - os.unset_env(name) - } -} - -if javascript { - pub external fn get_env(name: String) -> Result(String, Nil) = - "../../glenvy_ffi.mjs" "get_env" - - pub external fn set_env(name: String, value: String) -> Nil = - "../../glenvy_ffi.mjs" "set_env" - - pub external fn unset_env(name: String) -> Nil = - "../../glenvy_ffi.mjs" "unset_env" -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam deleted file mode 100644 index a5d478386c4..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/parser.gleam +++ /dev/null @@ -1,69 +0,0 @@ -//// A `.env` file parser. - -import gleam/list -import gleam/map.{Map} -import gleam/result.{try} -import gleam/string -import glenvy/internal/string as glenvy_string -import glx/stringx - -/// Parses a `.env` file into its contained environment variables. -pub fn parse_env_file(contents: String) -> Map(String, String) { - let lines = stringx.lines(contents) - - let env_vars = - lines - |> list.filter_map(parse_line) - |> map.from_list - - env_vars -} - -/// Parses a single line from a `.env` file into the key and the value. -fn parse_line(line: String) -> Result(#(String, String), Nil) { - use line <- try(skip_line_comment(line)) - - use #(key, value) <- try( - line - |> string.split_once(on: "="), - ) - - use value <- try(strip_comments(value)) - - let value = - value - |> string.trim - |> unquote(quote: "'") - |> unquote(quote: "\"") - - Ok(#(key, value)) -} - -/// Skips a line that starts with a comment. -fn skip_line_comment(line: String) -> Result(String, Nil) { - case - line - |> string.starts_with("#") - { - False -> Ok(line) - True -> Error(Nil) - } -} - -/// Strips the comments out of the given line. -fn strip_comments(line: String) -> Result(String, Nil) { - case - line - |> string.split_once(on: "#") - { - Ok(#(value, _)) -> Ok(value) - Error(Nil) -> Ok(line) - } -} - -/// Unquotes the given string using the specified quote character. -fn unquote(line: String, quote quote_char: String) -> String { - line - |> glenvy_string.trim_chars_left(quote_char) - |> glenvy_string.trim_chars_right(quote_char) -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam b/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam deleted file mode 100644 index 38d775ac6a5..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy/internal/string.gleam +++ /dev/null @@ -1,33 +0,0 @@ -//// Extensions to `gleam/string`. - -import gleam/string - -/// Returns the given string after trimming the indicated characters from the left. -pub fn trim_chars_left(value: String, trim chars_to_trim: String) -> String { - case - string.is_empty(chars_to_trim) || !string.starts_with(value, chars_to_trim) - { - True -> value - False -> - value - |> string.slice( - at_index: string.length(chars_to_trim), - length: string.length(value), - ) - } -} - -/// Returns the given string after trimming the indicated characters from the right. -pub fn trim_chars_right(value: String, trim chars_to_trim: String) -> String { - case - string.is_empty(chars_to_trim) || !string.ends_with(value, chars_to_trim) - { - True -> value - False -> - value - |> string.slice( - at_index: 0, - length: string.length(value) - string.length(chars_to_trim), - ) - } -} diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl deleted file mode 100644 index e5405238329..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@dotenv.erl +++ /dev/null @@ -1,40 +0,0 @@ --module(glenvy@dotenv). --compile([no_auto_import, nowarn_unused_vars]). - --export([load_from/1, load/0]). - --spec find(binary()) -> {ok, binary()} | {error, glenvy@error:error()}. -find(Filepath) -> - gleam@result:'try'( - begin - _pipe = glenvy@internal@file:read(Filepath), - gleam@result:map_error(_pipe, fun(Field@0) -> {io, Field@0} end) - end, - fun(Contents) -> {ok, Contents} end - ). - --spec load_from(binary()) -> {ok, nil} | {error, glenvy@error:error()}. -load_from(Filepath) -> - gleam@result:'try'( - find(Filepath), - fun(Env_file) -> - Env_vars = begin - _pipe = Env_file, - glenvy@internal@parser:parse_env_file(_pipe) - end, - _pipe@1 = Env_vars, - _pipe@2 = gleam@map:to_list(_pipe@1), - gleam@list:each( - _pipe@2, - fun(Env_var) -> - {Key, Value} = Env_var, - glenvy@internal@os:set_env(Key, Value) - end - ), - {ok, nil} - end - ). - --spec load() -> {ok, nil} | {error, glenvy@error:error()}. -load() -> - load_from(<<".env"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl deleted file mode 100644 index a70577b44a5..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@env.erl +++ /dev/null @@ -1,69 +0,0 @@ --module(glenvy@env). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_string/1, get/2, get_int/1, get_float/1, get_bool/1]). - --spec get_string(binary()) -> {ok, binary()} | {error, nil}. -get_string(Name) -> - glenvy@internal@os:get_env(Name). - --spec get(binary(), fun((binary()) -> {ok, FNV} | {error, nil})) -> {ok, FNV} | - {error, nil}. -get(Name, Parse) -> - gleam@result:'try'(get_string(Name), fun(Value) -> _pipe = Value, - Parse(_pipe) end). - --spec get_int(binary()) -> {ok, integer()} | {error, nil}. -get_int(Name) -> - _pipe = Name, - get(_pipe, fun gleam@int:parse/1). - --spec get_float(binary()) -> {ok, float()} | {error, nil}. -get_float(Name) -> - _pipe = Name, - get(_pipe, fun gleam@float:parse/1). - --spec get_bool(binary()) -> {ok, boolean()} | {error, nil}. -get_bool(Name) -> - Parse_bool = fun(Value) -> - Value@1 = begin - _pipe = Value, - gleam@string:lowercase(_pipe) - end, - case Value@1 of - <<"true"/utf8>> -> - {ok, true}; - - <<"t"/utf8>> -> - {ok, true}; - - <<"yes"/utf8>> -> - {ok, true}; - - <<"y"/utf8>> -> - {ok, true}; - - <<"1"/utf8>> -> - {ok, true}; - - <<"false"/utf8>> -> - {ok, false}; - - <<"f"/utf8>> -> - {ok, false}; - - <<"no"/utf8>> -> - {ok, false}; - - <<"n"/utf8>> -> - {ok, false}; - - <<"0"/utf8>> -> - {ok, false}; - - _ -> - {error, nil} - end - end, - _pipe@1 = Name, - get(_pipe@1, Parse_bool). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl deleted file mode 100644 index 69e5d489294..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@error.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(glenvy@error). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([error/0]). - --type error() :: {io, binary()}. - - diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl deleted file mode 100644 index d442cb7aa15..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@file.erl +++ /dev/null @@ -1,9 +0,0 @@ --module(glenvy@internal@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([read/1]). - --spec read(binary()) -> {ok, binary()} | {error, binary()}. -read(Path) -> - _pipe = gleam@erlang@file:read(Path), - gleam@result:map_error(_pipe, fun gleam@string:inspect/1). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl deleted file mode 100644 index 9794d8dd6f7..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@os.erl +++ /dev/null @@ -1,16 +0,0 @@ --module(glenvy@internal@os). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_env/1, set_env/2, unset_env/1]). - --spec get_env(binary()) -> {ok, binary()} | {error, nil}. -get_env(Name) -> - gleam_erlang_ffi:get_env(Name). - --spec set_env(binary(), binary()) -> nil. -set_env(Name, Value) -> - gleam_erlang_ffi:set_env(Name, Value). - --spec unset_env(binary()) -> nil. -unset_env(Name) -> - gleam_erlang_ffi:unset_env(Name). diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl deleted file mode 100644 index c271f7e9800..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@parser.erl +++ /dev/null @@ -1,75 +0,0 @@ --module(glenvy@internal@parser). --compile([no_auto_import, nowarn_unused_vars]). - --export([parse_env_file/1]). - --spec skip_line_comment(binary()) -> {ok, binary()} | {error, nil}. -skip_line_comment(Line) -> - case begin - _pipe = Line, - gleam@string:starts_with(_pipe, <<"#"/utf8>>) - end of - false -> - {ok, Line}; - - true -> - {error, nil} - end. - --spec strip_comments(binary()) -> {ok, binary()} | {error, nil}. -strip_comments(Line) -> - case begin - _pipe = Line, - gleam@string:split_once(_pipe, <<"#"/utf8>>) - end of - {ok, {Value, _}} -> - {ok, Value}; - - {error, nil} -> - {ok, Line} - end. - --spec unquote(binary(), binary()) -> binary(). -unquote(Line, Quote_char) -> - _pipe = Line, - _pipe@1 = glenvy@internal@string:trim_chars_left(_pipe, Quote_char), - glenvy@internal@string:trim_chars_right(_pipe@1, Quote_char). - --spec parse_line(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -parse_line(Line) -> - gleam@result:'try'( - skip_line_comment(Line), - fun(Line@1) -> - gleam@result:'try'( - begin - _pipe = Line@1, - gleam@string:split_once(_pipe, <<"="/utf8>>) - end, - fun(_use0) -> - {Key, Value} = _use0, - gleam@result:'try'( - strip_comments(Value), - fun(Value@1) -> - Value@2 = begin - _pipe@1 = Value@1, - _pipe@2 = gleam@string:trim(_pipe@1), - _pipe@3 = unquote(_pipe@2, <<"'"/utf8>>), - unquote(_pipe@3, <<"\""/utf8>>) - end, - {ok, {Key, Value@2}} - end - ) - end - ) - end - ). - --spec parse_env_file(binary()) -> gleam@map:map_(binary(), binary()). -parse_env_file(Contents) -> - Lines = glx@stringx:lines(Contents), - Env_vars = begin - _pipe = Lines, - _pipe@1 = gleam@list:filter_map(_pipe, fun parse_line/1), - gleam@map:from_list(_pipe@1) - end, - Env_vars. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl b/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl deleted file mode 100644 index eece3a111bc..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy@internal@string.erl +++ /dev/null @@ -1,40 +0,0 @@ --module(glenvy@internal@string). --compile([no_auto_import, nowarn_unused_vars]). - --export([trim_chars_left/2, trim_chars_right/2]). - --spec trim_chars_left(binary(), binary()) -> binary(). -trim_chars_left(Value, Chars_to_trim) -> - case gleam@string:is_empty(Chars_to_trim) orelse not gleam@string:starts_with( - Value, - Chars_to_trim - ) of - true -> - Value; - - false -> - _pipe = Value, - gleam@string:slice( - _pipe, - gleam@string:length(Chars_to_trim), - gleam@string:length(Value) - ) - end. - --spec trim_chars_right(binary(), binary()) -> binary(). -trim_chars_right(Value, Chars_to_trim) -> - case gleam@string:is_empty(Chars_to_trim) orelse not gleam@string:ends_with( - Value, - Chars_to_trim - ) of - true -> - Value; - - false -> - _pipe = Value, - gleam@string:slice( - _pipe, - 0, - gleam@string:length(Value) - gleam@string:length(Chars_to_trim) - ) - end. diff --git a/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs b/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs deleted file mode 100644 index 0e641dbc1e0..00000000000 --- a/test-community-packages-javascript/build/packages/glenvy/src/glenvy_ffi.mjs +++ /dev/null @@ -1,32 +0,0 @@ -import { Ok, Error } from "./gleam.mjs"; -import { readFileSync } from "node:fs"; - -const Nil = undefined; - -export function get_env(name) { - if (process.env[name]) { - return new Ok(process.env[name]); - } else { - return new Error(Nil); - } -} - -export function set_env(name, value) { - process.env[name] = value; - - return Nil; -} - -export function unset_env(name) { - delete process.env[name]; - - return Nil; -} - -export function read_file(path) { - try { - return new Ok(readFileSync(path, "utf-8")); - } catch (error) { - return new Error(error.message || ""); - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/README.md b/test-community-packages-javascript/build/packages/glerm/README.md deleted file mode 100644 index ffefb5af462..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# glerm - -[![Package Version](https://img.shields.io/hexpm/v/glerm)](https://hex.pm/packages/glerm) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glerm/) - -A Gleam wrapper around `crossterm` to create terminal applications - -## Quick start - -### Caveats - -Currently, this only works on Linux. Gleam doesn't support any mechanism to -build the NIFs on your machine. To get around this for now, I am shipping -pre-compiled library files in the `priv/` directory. - -The `.dll` for windows does actually allow the program to run. Most of the -methods seem to work, but unfortunately the blocking `event::read()` call -just hangs. I expect this is some interaction between `erlang`, `crossterm`, -and Windows. I may try to look more into this, but right now I don't really -know what the issue is. Would love some help with this if possible! - -I tried to build this on my Intel Macbook, but got some errors from `rustler`. -I'm not sure if that's not considered a supported platform anymore by them, -but it's also currently not working. Any help with that would also be -appreciated. - -I don't have access to anything ARM, so unfortunately will not be able to -provide anything in that regard. - -### Getting started - -The docs should hopefully be helpful. Additionally, there is at least one -example usage in `examples/` that you can run with `gleam run` (if you are -using a version of Gleam that supports path dependencies). - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add glerm -``` - -and its documentation can be found at <https://hexdocs.pm/glerm>. diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache deleted file mode 100644 index 92df63b06d41e6efd65b6315a7f45eecda1989b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62841 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_ansi/_gleam_artefacts/gleam_community@ansi.cache_meta deleted file mode 100644 index 698890486b4eefd538d84a817bea5b94838a49b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114 zcmbQ#@07{_11wMmCzMXlNlnbv&&(^~LJ`QxEH2?e5h*Sy%FIg_Ll%oq&d<#)&C4vQ U)KAXO$uBKRP|)c6$?53<0DaOL6#xJL diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache deleted file mode 100644 index 281d600331ef41cc683b222c82019938ad83533a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27832 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 Xr2;?H=(%Don|&{23S|@5-_QOJqO9cK diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour.cache_meta deleted file mode 100644 index 53e1ad9d70b13428390bf75760603d9fea78299d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmY%Gc1mS{0ahr36H2G&q$cL-XXce~qX?ws<R_N!pa>PE7MJFri4~U=W#*-Gp{UEr QEH0To^=sb0;|Fd400}J|+W-In diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache deleted file mode 100644 index e1d665bc07813583c29f571837c1676f1a4eae70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3072 zcmeH}&u<$=6vub$gmqSllBsE>AX%9jp*ohEbrSXBq;V2x5mMFGcBLR86p!tRy~^y4 zwL2TfMTi@Raw&fV{{zaA8wdC!IB@6I3o>tJe<UF(7?fizYdxBMyYKnU`+VQ4&SiGZ z_2n|c4@~^v)BG={i3?}>pUr!DlrtxN&Zv9X6<OB}Jx7l1uHYi{ZQAX!AaFX)B8T17 z48>-L^~i2Fv$vGNg=T}GZ2nL5vYCP3y_sg~lNnh2G4rbR1{M<@x{gP^u7MarjrmNr zF+j5zS%!g-Vc<EtQO#rxqcH<lgy(8_?hIqI{;`hbigP=5{yehYz;p05R~~ag<%<48 zaAy`FjGL_&2%&XcMtNAQ7tU^73?+T>zx;X9WHR)<;4>lzjQEUG>6|dq@tyuadXOd} zj`XcQY<r{~h217JAe6LqSZ&f_a>STtk?LBtLa5gx>uXgqa^yhmz-`Ct>zDMXf6M|& zhC=0^GZJMwedOGdEB|1+W?5vr$0T)lumj5=bY1F?cOIQmcgR_7+fH`Cu-$I!6j|iR zBP_Bgt&*=SLP&B<tQ7fN8x0)ER*7w^U@h{sejGg5sW;`>IU#`@bM~+ZF+0)`UM<bi zRuLjnpKW^8h;{<OL&>%XXGgL|s#`@e@Y&JB;y}t_P_ykm<R|Q`b%kr|sPDt-a-ljw z5V9cgqCEvJ<$R|#6cX|;$3syk&xUX?)FayZE+j;o#F5!_su=ZgUkviYYrO8$?lF-9 zzC-fcx8GmqY1^(t%62TvK$}0z|2jYE3QzhpkVgH`htd);BCjtYa?to(Ba+iaU#J1Z z_#+c&NtRR4GKGo4?`=S3Fn-zUB|yDaK>d`z68(Rr>Zz{!BnJs6M2^HcNhg%UAzurW zs?3U|>DWk#Qj3TaPXIqrdX-IuXrpt62EfqYXp5|G464L^bhf2f2Wm0a5n@^p(yb1M zBGS~UVBcW}Dt9B;CDftkP{SFF?(O9=cwryUBfL<A>o@V)7={U@g3#uVOYh-{<4NX$ ztQlww9ZL1C_9ZawMoEJi_pa;V`6sMYpK4U1Hiatyv~|(vlsFlgO`7{IH*x8y<A&}b zO3F^PSRM77OHm&*PTwLYWn9?61$zpuSbX9Hal`$8og4Z*r0byGWI@Q2H(eFDqK;^q zalm})@Cy?F2-d4eux`Ty04KVBx0AmvMN=kul1u_mv}UD^UUzXd8zgFyB>!B^;AV#g zES0oaveX=)9u#o#$<P-kPLK6cD-sFcjcHL*9Z7s8-2vlfKW3bZ5d;RGFD?!Ml|-x5 zXmZ#ADNc9#KFl;<s%KW;>C_GClo^c&zrVkG8%As;Q#HJB2QQcL@|_qLJo^Ej-N-&W dUU}sE!e87Mg5%jT>@B|VL$>mm@_;R&zW|Mmo`C=W diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_community_colour/_gleam_artefacts/gleam_community@colour@accessibility.cache_meta deleted file mode 100644 index e926edf4bd2ba9772666976608cd9c70fb8c7d63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmY%Gc1mS{0cI$J8%n3=q$cL-r{&})mT;j6<zyC@h#`x_C+FwpmgZ%aRO%<^=j4|b NZJ%QI>{9;O9{>a>7(@U7 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache deleted file mode 100644 index fec2276ac9ed8a761261ebb7794f915b24598595..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8464 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 M*)452i|k|n0tn9F4*&oF diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang.cache_meta deleted file mode 100644 index d76e6b61fe72a6e8f684b40640d58cd0bbc4a62a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122 zcmY$r>zv8}11wMmFO*KtNlnbvPpQmH%*{;ZLJ`c#EG`j55lJn|Nz6;vPb|sL6~!iz SoRL@r()E&cT71TzYp(%&E*``H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache deleted file mode 100644 index 95b84a6370bf85d384448e840a67e10752456d39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2814 zcmbW3TW{Mo6vsu`o@}9>L!{}@VL@28U2G%Eb$!XOChn3H1&XFl24p}{*s@LAY9z{_ zs9XjN+k!pyt$ysM*h60T4fZtb1N3qG6y6~zxoK`qW*D|aiHGO%JAZQiOLNu2w+Fa9 zjsM*le`8JKiC5zj*~jBi)*5y_>iBb%BhO*oIY$J@*JE|cje;DkW=)(ws*RyEb}F?7 zN)I=9;BO1=BGz5!Jm3aGwJ*#RUbk>&fb;fwMhz3^j&Oc}C#=!@R5Cwt;=K>g%@lkK zRT22H@#;s6S8#5Cv8AS*=YY0Yy=mh6uWBWf8qb(~J8QzluV!=mH+hjyzumr>hKrvv zTid^6P-@tLNbBuGW)vLXZGk5@%v9}fl)=b0AZo+Fxw+bmnKF!88h#PZJ;FJT^VZL6 zhfGe1J!u~rQ|cbPkZ&#H+#=5HtZdOR^2C&izm`?cCM$SyfbU!In!H@ZlXI8FRCwx! ziGkRKCeCxn#Bhzaf;L^}h6Ob`$B_&|7!PWH!r#Pe{0~~V-L!{5fM18Ok%}8aKyeJf zgJPuK>9~e5B;WODYd0h%5s;8lvfrbkM>%mwBM!Ym_8c#w#0`nVh_pKc7j43+h&Utg zwi+aE$0n|T*Jf>-+`UWI4;;Vm(Gc$7^N_fHKj4CBMxYilt?{FzJaVWMKbn<;r52}- zpfV7@9s;VYTPpUb=LN-bxvXYy?q2#*viikKEG#a?rc@J@UL^U3Y?tUkpSA>TFO#BV zxHv;PLB!<k6DHuU?}*+qdGWIR(kk0FLeCL=F#4>THgTqc)2JX9HjJgmHnWG)#Iry= zHKqcmP1`YtUuzDp-B{R!y7SsSSg?dtOP*QbyaqDNrQcJ3#61ByH7v+#?8@<}mMEQU z2@SioA|-=$HSE{xgCl$g<m=MjzM`lo=3m#2HS@>7{9oCV%xhMFZ-v`w<~Ll{2AYeE z&;w{Yh=$10KyA6=x$EvxMs%E#<|iG(f|&A96F^*z{+`Q4<aoq)T0NK1X)r4-38(4N zkv(lmnr60aA}ZBZHk9rm+P<J=KEOWMEnZ5zd=3oiX8T}f82Gf#=zd+g78}v5CqOD3 z%QmPXTKXpQLuQ!t9ZDJxG(Kje_dglAg0QQq{#bhlRmIEr9a_jYZw#9*bNFFh7%PDa zV1;tIzkqTnZ3yQRSt2rM5H4N&8K_W5xhk$hAo@hc7$}_-t+;ab`K5C^BeU&*hERV& z91m7(A8Keu#Z|D_@v5?rJCyiQC`gl%mcwZ$@}#OV5`_{p(Sy2oBGwXa0CE~iU$|CR z;<-L3sP@k$Eb^P6!~uAskm@-C3^LM@D*JKzX2~<UN4ZT}0fT=5>w`6y^&>eQ7Lir~ zSMbL5JndR6<(l4o7={I5n)K055|-pk`q|=6*t71~lABE{w1y(kGHsxXaG5_TDOX_P z{Wg0>d173I#zg=wZ!=m1zzt(XgEPWqOYK+TgxuP6LpC5aoYSx$u(pa{gCXdFfX?j0 z6Uv06>I6lQ%*3^B$i8V@(6k;EB-mA`l5ZhHXE(4>CqIN7Cfiy(MYnhnUP-B}9%SES z^~tR|X5#fqb<G?}<mlWc4=wmBdDOV(*=*HRXA(8Ptma>#BCDo!WfH{vQ(Ug#@-6&e z89%s%s})@R<g9ZT@zWb$;ZYEHa(~P$7QW{Zo!W4`kjAGdocSEaQ=7X}N~4s6W9UE5 CnKg0% diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@atom.cache_meta deleted file mode 100644 index bfd938d1e8461ba9d199d56502092e325f58afa6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50 ocmY$r>zv8}1B_4xFO*KtNlnbvPpQmH%*{+@4&1o8X5AD)0Ik{zS^xk5 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache deleted file mode 100644 index bcc6f81a0dfa2081c8eb92964871ea0f0b07c088..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 789 zcmb7?&rZTX5XN_Qsii~$6H<uA1UMM~BnCwjBNs%Y2QFIVP8KYsTH3fR2TwkMFW@71 z<YIgX6Q9D@sJq1jmzt1lcC))P`+dKeEq<KqxG~4Q3cl`?4rm3<htd;0Eqziwc08L; z8@2$C`%Yst;Z@<eVYE0O*n$+)MJGd1>sndJ#FrDEL=Zv%tS!p$N=I#u`CQstgrd>K z{2WbvIXf-<mNGdyS&I3dRRo4#L+cw@90h|g60T3ck;3bgSsrKzIpu>8G#b_kWrSE6 zIm4=oDx-x)6Ait6r&OG3QW@z)13-MY4&`EA;2|90Cd9H(f{!8_L^zPfhHk;<;`wFf zyQARVj%$6v{cs#GF|F~M3RXp}MS<KU5X{LDIQ{`f<FN>)ij3$|HHB<<nJmTU>d*<< z+y7*q%fcvyD<N?fRDX;tQe0c?j4i&5Y~ymzRdet_U)}0C?W|KY_t7k4y^GsxSZ`sy qT(}4V54C;NnuWfY+0|?Ah4!*yyJv?pFG6io#;}{m>Xi_ID8es7D$^VQ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@charlist.cache_meta deleted file mode 100644 index 7996afcc06d5ef47b53a066d1ed8fc8ff6d3e41f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 WcmY$r>zvAf4*c?#2l@L(90veAT?HEe diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache deleted file mode 100644 index 4b38dc11252b6a5b8cd02c701e01e3383c6f92bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27622 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@file.cache_meta deleted file mode 100644 index e194cadac1c0380e6695db697ed205c3b05b0877..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72 zcmaF#D<qWx2AH4>ekh%ulbV>TpOje=pIB6sSjmGTT$EZ|np2{1>gDVm*}3Nd>o*cc diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache deleted file mode 100644 index 724743b1b747f11d9798850084ff30365355adb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2992 zcmbtW&rjS&6!whQn6-j7PXv@yK};%8gGC_=NTo<oSQ4T(0vfYKB&jMGb_ej{wUO<m z;)E1Msv70AmtHH>9(t=(Rm!2aUV7@E&_hq{pODk`&3HE9R~Dj5h#f!AkN3XsoA3En zlg`?3tqCKa^e&QbdT-=Eg1%bskNMT!VaIN51%lVdMN9%7ZjFagm5401CSs!?gQZIp z`dse{$pNo<Rs8vN*?UEDg{7z}2=T5{6G}E%P3UpX+RmVmcOl;du+@^Y<~*b({<ZE# zVJIr;yithbDAs$=pR;!jdYaH@pIF@ClzY)qlr9KvkR8KN>7RGRvOeO-%6IQyViaya z@MekGTOxDiS%QN{bgsNYaWG)I<?AL6elicsKg+?R9KOoo;9tuv|6}36vY(Z^ZDO`! z{`FcS!m42q?-Dh=KZpgy!6#xEkYDwlQxgm5rnn6T23GL}HB1>W2n@I|(1c<8$gogK zqxy-&c^Z*AV&91x+#-K*2rNPYT<<C&&@%&9ajjF3RooG=l#@Xxf45#+2YY_vZv;|6 zvb61ErP-<m1Jja6qj)ADKVDeylXOt&)yutkbDpd)3z+a;X34xH#r#uy5LGS`olc7_ zi?k7k>^f%w9>Aha#)E+A^q88<{E(&Ff>nY>l8Sf~qbbJlvFe9g*{enzi!gQ6f-%Qo zD{_7oR54cJA=?monW(ajeGCPG++aNs!RF18b;iRg+l|F8!lgHMSS*r8kjgFB*Vk3~ z4huvovs}xvyUo6ogRyLvQ8qTF9(4&fN4`=^O~*0F<e%g(a*#%A$a`I5zk3Y(aqpIr z)x{y!94RI`D9n;nJn*LF&kL9)#lEMc<yR3jKixMBBNHatj<TY)%}pO;3@u?##A%N4 z48=53aLe>1ReqYVkk`dnR$Z;@c^8T;*wm$ccC55hvbu<PTyH27&k#!S?}9}3q;#m# z#u2V<WD8Mw@m*^nLXMZDtA3uK>y!f9-)n1rDoYOS@x3ezDBiC_?;&Qjf>1V#*AD5~ z=bX6em^zxf5@rxp@;t~8^$|goGY>GcQI<rADbumtC{dS`A?lUPo8?fJ8{xlLsofT1 zQdr;9U+96Jq|yKF82axJRtLpMVa=$^zj|j`-2#36Pdi)<ZeWM&*kCT!Ae2gL*x!^& zU!h8u^DSN0nxW`FTd4C%$~OXkDA`7->IHs;z7c8ZDr_ZmQbLKc18Iw_E|P?AVFYIi zUfFgsY?T-Aa9=;^9nm+`a%l&daV2bhUUtiy_qiX4>PmDsBMRNb-&9n|1#L!Sc>?B% zoSoXBt<|<vQ4eo7LB*Ucn7ZI0dX;lTHgO}AA?cb`wA9$&Xr!2UU3!#*4U9}ixo>l- zDQKnqa7-x&UZ5-p8v{z9=t8jxpUOto9ukTzkalWWom!og)rU$}w!P#BnWnJUVDFWU z>#@A<O?XU-&@@$&XWyf;B#*Nm&7US3y+~SkR6$l5($Coz;utE{B<3sIA`x#n=doao zFx}r3)luv}I|A)~s}b;+&8u$tW~K&i%G$MBZKjE)8vDL#qW{NGo_SMP_p~g%*yoZr zXPE6X+8>HXz7yFhPcVCKqMl^=TBCB9>AWBbN4kr2mX^9H^wdh1Da^a2d-TL@lpP&D zmK?vI8O~-ZP|HWu@(X-wVlr1K3@^h-7Yx^6q#sHyl=@+D1{V9_i3?A<T1P+iGz9vy z6s%{EKRgZ4$?GGXzAzU>0az|r6NQzyAqMaBAQ9Tk!1@5=<`+AI>H;e{Unc(nzMMkP diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@node.cache_meta deleted file mode 100644 index 4423143044877dc88fbf4e2fcfa1aa45a6e49927..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 scmY$r>zv8}1B_6HAe2teNlnbvPc6zx%uCl#EXmK^rz=1CkN%`J0NM!*Q2+n{ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache deleted file mode 100644 index b1ab52ad3ff109aa0ca7422ecccc100f435855e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3171 zcmbtW&u<%55Z<?IXX90)Fr-c)5c$;sVMoDfoCC;+q_L8ys+=ZkQzAfBvWZ{fZPvTd z?%GKXs1Ws3amb-U;?^626UXv5z=aD34xB)O0|yWnxP*D{?KXDeMxkA;ywC5)%)I$# zzL{%})ayFDd<d^!flt32`YLq=;O@}xskesi82a(H!>r~c^Hs-kw<o<o5ff|7ALJ8r z2^Eqz&3=+NUJe$mrtKUkib9C_lB&VGIwTJvWjv8VVi}4Gshcox2%vYKJG*g3)$pCm zsjyTuD@21oH_X3@Hk4P(wVaBB1Fcls*KqKwR;>NP2WFyFTS?$xDOs*nk~sJl2aovx z^lI(0jsvT|TC4XHEwdapn2+XOQZ=(dl0Xb@y`n&B(#)xvqL>N%C6FpXst754wif!f zyPXkEK+E{jMK6+8Q2`XqR|x@%=MG`OkOrK+x1vt}p#O~CXW^RVIBSZ|+;(K={VqFo zv!B};*)k5P4`E<+aNgbwBdK*;(KbV|i@<0JMvE}2quuEeq>GR~bEVT)L~CKgJmQ}R za73okKlOE+CG}uL2zb}FwroW?rd1ZUd^Z@O=wa&EK}fwVidUgl+p-;N!(kM!Wc!}m zWNt{?mT&XPfLi!IIk3YHCJY+3c5$U(7<6omF6>)P{ulq@Gect+p|o6H%r&ju!j|tf z*SOl;M`DiBv0S!xW1&*XPSEV+hV4#nSV1G3NAcpp<(1WWvDomMZ1V23@1Cp{3I(z6 zPF^z%g-jok&&fTm`2?0nU9em{d}L&;&Q@8_azYtdJ<!VbMoYhCJMs)hK$3%0HbeXj z2&~|4GPd$ulr9UD+LqH|=>Ndmw5^cU>7E@n#LBkaW^PZssB1OZImmESBEL&;I(*-W zAm7JDm8gIr-Wx+P=w=OrkQIUtkSl_A#vwrl`58r-{#yM`ot?M*J==}4<eG%ze-I6* zn4YDs^o&GG-ysQh5ZH84e_PK~Y`3-ld>T&?f{@r#;ctC^^v!Mwj*T?l=nA=RCb%do z@sO#S5BcW-JjC>VQ9t&AHK9i#2j_;(D<U{{nC~)&r#DaahR0KVm-$wRL`j2#AY@G* zAh+Ee*V}Wc+>S}^GwQQl&*zbbNxv?*I421<zy1zoh3!H-n+;m77i9D6PYE^YmMH&) z3q`ul(5?j;AiY+k?pTX~Wq?eNrY2JN7JbIbLH+q4E_Vf0EVC!bAM5w^dqEemeA0#T zs(C}yCC>WK#OJ(ZWo0!xMII_AkIy7|JSJ1{S6^&N?<km)OfeE7Yjfx&OGp-ZPU?s} zkjpN8@cvwtvoar4ZZBjdGa&0lFh(RC?~I5e-W^j+EKeAR922ik2>yyDs*&&vmmaZ= z3gnHseia6aa0yv;9Dg%H2zkOi!--1bxaCR}3W>|~dKYXLuLr%c5n1|;%+l{MOaJZf zRM{J!Dr<Ue7GwoDNU&#$?P-FKxjd@f6#alHx^4M&thWKr@Vy4(9g~n4mu$+~IK%d_ z*s}Ul^0OyO%R3Ua6If?x>_@B`68a0_z2N(vpF?x=G2kb1qN>s%ZI)jw2DoQA`7!xV z@_5yD>)u{)OCeZLMThu|HKl4&1nxBqA8dGyPPsiP;HdA5KG|1e;B~ggycdN$@7*rk zb6!{HE~$_nhx9O9Ey2}cc=IMq6$Z<m=Rk5ClEuOI{1(eBT28>C76g(bIIk`5WQ1Eg dEx=MC+7N6V%Q)z~iY$du!Hg+Rwzn^k{{Z{vFuMQ% diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@os.cache_meta deleted file mode 100644 index a5a851f1c263bb78396ce9ebd74ca3c7667c6267..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46 kcmY$r>zv8}1B_4xCzMXlNlnbv&rK{?-X61bPE$%K0E>MIE&u=k diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache deleted file mode 100644 index ea7ffa3c47808ae67a2e15b6974cbf163c180ca5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30881 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 SYHzeOgWv4%3SlI68vhGu1`bgG diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_erlang/_gleam_artefacts/gleam@erlang@process.cache_meta deleted file mode 100644 index 90df4b90772a5995736af489dfdd0d0f028aa906..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115 zcmY$r>zv8}11wMm50p;NNlnbvFD@y{%uDA*5lgAeOU%toMpc+vl#`g3E{LKKBBq~M PlApUORpoUXPcJh7xDFae diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache deleted file mode 100644 index df361f2d9db1c6d104f839b32e4af8efe121dbf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12240 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 UEmM0Af^=Q>Dt6zqR@t}zAJ|)+P5=M^ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@actor.cache_meta deleted file mode 100644 index 01991ea93819cf78ea5922d9d397c28c0bf7596a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmd=2<B`e$1ME<S2$W9GNlnbvPc6zx%uClVD9TSxEiM+tCYPL%Sd^1lTq1xXnO{<% zUtC#SlA6ndB3@ill$n>#iz1d%nU|QGnJkDR2(>w}Bp=O${DP9q{Je+jWZ$%l-Z%gN D0-Q3b diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache deleted file mode 100644 index 2f2cb4fe0a7c2a2ade829942c989b0f2be8e1794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2254 zcmbtVU27Xh6rDS(?OMWL2SpAp7Ot0;*dmUiH6f`;kX2|KK|(#UA)psUwwAC&+I3c& z7>7V!@=)|v$WKUqNT5HV52a5<5a=K1V^Qy}<dCU_t=b?~cV_3~o^#JVd()BI7M2It zyq2A#qwGiPDwgZn&6yvw?`N#xlaAZ!7K2D07Ck?5{hk*cH>0q1U_Eui(c5Ma2|BFK zNX+%s6-wb*Lq(Jt*2e4Uc#qffav_M+SJHs8U=D!H*{2JMbRQTXZ%sPu?9DsU;NNgB z2$D2}(R0U_Kb-pV2IdA>wzNa0xwX0?acf`QAp;-k>Q^$dA8CL0FX8}(y}M{|kW2M< zS5h1tn~mL9CI|nRFY8~BG4z9@X3sqcgypw;La143sBJPqnV3Hzkhau}G=yM$f{?b6 zc6iQWoU2K-c%BH@SL^ZL0PBS1jDGCdD1_X)DsRYPtKDw8FI-<x#N5Ss{I2CuRCnV% zRBDvSWoi`zDJMW4RqAf<d1s6zK}yK?@y!4wi<fOQusOiD7n8*QE2SCpSJ!F$jFWRo zd|<pYhEeEsn@656taflTrtwdW#@FiSghnQq@s$cFIVcr5tl6kJsKuzOHmVM)*1`j? zcS6mW_DS{E#GnoMtaKqEx;W)otj$wm(m<Wd!+rUSw0!pj{aX$FBXvJPA4{4GZ6oh+ z!*iIkk#msKg?$RkWkhF^1Z?#+mzf)Vhp)`UX`X|Jn{bDSx6-x5^U9dz{SH4Xhi>Qv zZKBnV*YzSHwzlaFP4KQ!GySIV@E;Y}i3$?I+t_fh5r=C9tT|XKYAk4jDQg<5;4;kR z*kXXby3W*f5|hbiCg2p)QE7l~S7&8h?kik`@~7tskCoVkq8`al443{`BCVOnopoo# zDStUGWZsYrrjc~~^+XhGoS%O}&cP$M9J))xZr}$|;CrHS(2TsUJ2vshTD^;EJ<<Ic zT^v_wQg<i5^ir+F_Eg3SCz?5RXT=RWE&mBy`QJ1zt0@Vy!E)8m#Kt``)r+yUEvt(X z`7-iL*yy7)k9!5&TSBdYhx20_hxsK;$N1^#>i1z7gp))9>Q9<p_$~-KFblkWVK02{ RuKv*K^jr-9sG*G)>0hwARUQBU diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@intensity_tracker.cache_meta deleted file mode 100644 index ad921d20ba6b51a57503d0e2a53829e220a0564a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmd=2<B`e$1B_4x7nDxVNlnbv&&ez<vF5ruUGm+cKLC?C3J3rI diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache deleted file mode 100644 index e4866da8fe5cda41a5fff257a7c8c157a418726e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 273 zcmaivF$;oF6oq}yXAh&$Gn5sGlZ%Vc618MOuBo(#gEVA3dFi14svp-}4;vkV%N@S^ zodeg7BaUSU-$BdKIzWck25<hkl|}vtMXl|tuoANVfvW<fIxq?&NEu;PqE3XQ3#wzw zVRSIZgQ!Mf1~5BJdG8N|gz9P{`s-D@*HWfReXf!JX%(GN%mU0tzz&$h4dBlEntfJ0 io3e(ng0a@mckd*nkk(O%Qaz!Vb&*Zs#d-NGZ1M%j{X(7q diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@port.cache_meta deleted file mode 100644 index ac4a4c20f31bc323bfb14d6bf926cbe2022ef1f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmd=2<B`gM4jR1El=qw~UJ3v{=mo3* diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache deleted file mode 100644 index ae88169bb56694a077f754883ef09345dd2d5381..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14883 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 a5dbf$f`x8%=+4q$LTt&ef^Zf)!u|&!=Jz!K diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@supervisor.cache_meta deleted file mode 100644 index a58472ac5a3334d4ebecc990a11a97146d84232c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200 zcmd=2<B`e$1ME-+50p;NNlnbvFG?*g%_%_@D=sO@%u7cV%P%O&%+C`+(VJS7lbDyT zUr>~voLXGWk0O^}QlOuhT#{cTjUk+wSCX1noLN#CUs9BqoSj-Eh@u2)YF>UyYG>nW JlRa5%y8#W;Gll>F diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache deleted file mode 100644 index 766ae18587236f92eb0a1c1c6979bb83bffd27d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5222 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 CU~~Qe diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@system.cache_meta deleted file mode 100644 index 830d43596b10edc15b7bc2ceddbff2f713b2ccc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103 zcmd=2<B`e$1I$ncFO*KtNlnbvPpQmH%*{*|L=j9a%1O*i*H0|T&lSNYQBahhoLXFb Md0NZ{gHzJ60N(l;RsaA1 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache deleted file mode 100644 index 6c262ed8ce77420e7064508ac4c562e934af4e4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3940 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam@otp@task.cache_meta deleted file mode 100644 index 26c03cf3cb81f45c2b93bb6bf8021044c38675eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78 zcmd=2<B`e$158kc2$W9GNlnbvPc6zx%uClVD9TSxEiUFokxQw}OU%toe#!RnuiB(s F4FDhE68QiC diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache deleted file mode 100644 index cf4083871e1a8b155040dfe8f81f756bf266e6f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmaKqK}*~~6vyXHHjG(Z;$u<SVp$Qy5(*JL6uh_!ioNJg>d8wObcoAllbB3s>Dhx{ zzz?BUFRe$9ehsg^2p)y)%UTxKf^&Ei9+`Q+-#?kT=?H8ExGZq_OS9wxF=(FgmF5)} z!zk8j5T=Gf_WHTQx28GH-pfU>@bO4Kfz|vC-nU->)-cj09O$CpD$?OusY@NkI*H6F z13Aqtc?vc{oiPB$(DCIew-}Q(s({WCI@gFobbBW+1AU!Ctdhvj^3*-1YrEqY*U%B- zYhv0XO6uDHi1+d{ZLK@p1N>NjhlY)fcorI6m{9*PI!{#0D!4AtLYUvGakQ7P1|sX7 z5b^E9u*lT+Bs7XyMW4_ssq;5dpWaCQ$6CpH=={Wn?;fh6|Ie19-pqVMjaP|`4)6Ek zNzo%ppL_#cq*|YV8k^B~V;uiHy93or;3fag1gelz73w>wRzp0wKwBfg1*-MYZId(B zFW?gBx0vGC*ucgdwmfXjZ3en1V}tewwAZYIetRd+)7;%o(->`!dhTIf>h`XR3q1pW E0Rs$`IsgCw diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_otp/_gleam_artefacts/gleam_otp.cache_meta deleted file mode 100644 index 6beed5ed725df6a3a8e7149a83e1459488f7153b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 130 zcmWgo<B`e$1FTR62b50FNlnbv&&=mU<>!@fp$Oz;7MJj$h~$?P=$9lGXN#bSrWWNS X=B4Ww6y+zU78mEVy3OV1H*Wv{xKbQz diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache deleted file mode 100644 index e087e75295da251e35223689a9dd0607ba37764f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1223 zcmc(f&r9P#6vyXH8m1LW`zQ!mD2+m?$f9l)4_>qdS18M_u?vEiHZ_B$#s>1^;Q!;n zKg2)8i+_UPE&GyGlXkVZm-RB4nKyZv@8^AAwpwr?P&>n>z~)iyupkh}wN9Z`yD5n1 z!jb0n=E!7<FVn@q4_L)=?9l=5R5{jrh7L-t3FH16(4@?J{VJ!)6Cd}VX%boT+_mKH z4r2_!_{tUI9@KBJ%A;dS?n^xsGz>>H-Q5|ar-!;d(Su9co?gHX2BznkH$(l}wL(Wy z+z+HMtqlOiu(WBcafLCXKqFvj4@+$<iT!@y*^`S#lH@oaI^92!e&_^g$S5YUdJk9H zxFRTnwu)LCH4$~~pc8+XZvUD_{Is3dg$jTeL!ieQ>NGCpB}aLJjBmGK2vO)c135W& z2_$KrQn`((bTcZ&9F><BEcrn)1cqqGWKNAA37Nkot}l>S>AG&FaRE{lIQeB({>yDs zdGiDwpw6RM{j4bx`R|w_J^exHnJNB<^tsCCbj|6;tJ|dRvB78Ro^->4y8ly0WOe`K zj(EconesU_+jsnt)9<9nvAl=nWz@);%hL`;^$V(P<=0i?(DPg`F(#_(v{(7<g|hM8 IbbMKbKXM>6CjbBd diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta deleted file mode 100644 index d03bd4e27eedf3cf7c1040715866556930eeee16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache deleted file mode 100644 index 7c790c0d491ccc8bd66f0fa11a008acd12df3a5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4956 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 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta deleted file mode 100644 index 09e2f8acc9336bce7885613638b9b2af3ff95002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd;&v`S@w0Y)f;2TG^sq$cL-7nc-e=B0~Ie!%wp&?033h=d8> diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache deleted file mode 100644 index 734764605f44fe1908f5139e0c3456768538a0a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 zcmd^?O>g655XYaf<2ueZ4WlZHvg#^H)v7N7vZNrPT(XU{NUT<(u6NZH0wwXrEe>f? zJ$3}`1yt<;4oDDjVYPe73GE394jkaj1-=3t`2ryA&5YkllE$bn=E6#mGkN0J{{Nnt z|4eQ?5pT+v8{pcD`1v36*XLx+w&!zmEA#4{?Cf=n=6*>x!LI9lv(qww`)hT}W|>yU z)Hf3XO7EyiNH{gquDK^M(cl2;f*|588KnWHQ`0WQ1XS9X9%5E@YKOLA(T`b%?h)Lg zq#pvUdN-D7bxRQGwfTmC`xUhV;{1D{YYm`aO?af;5GW{$6|EprkWCD=g#-nEB^I?m z-Qa8KSbHo{V9p$Aof&sU=GtSKf-jR?`zlF6Q>keUg@SvjZS8)Fg5s4UZRrXHx!GfF zVHU*dgI@PR(<XUKf~bBA(yQ<koGrp+8HK(?2m5`a&<MD>sseDlQP}Ub`W>TSb}c(& zG+VC#FosG=y(@@}sR=p)D(k3}X)$xhwCuchnedx)vT`qW&YwsCh!wR!Z|MOR=tC;d zJAMB)ev`5@&MxomQ#x=ao87$t%)?l~td4@IcwpqJW^=lakB0K$qB3=L$yGbRCBSTI zTttN0l3bS^fB)+`n6@k0?23C<Ao`nFMBf<|9i0ugF<r(qRgP(Ia^5^-j9r?^BXyOS zWCyqkm`hES8iD4MnV)8=&4UA@+X`TO9|MdX^}Yuq>234%HWr7tCew}=Z{u<qm(T1Q z@lg^^6^O4og3Idy7fx~uC~r^PEWq?d446vlYoj^CG5yr_RKHMaeU^8PJ2X|x2Dg6P z=kUDt5+yVoPnXaK#$-lt`BhFQ<*xBzK%o@_1zB~|gk4OJYXysA#^*j=#KUJ`4g5{j zO&fd{*kgf|Ph*f$QePU~(Ep;;kEhrlsS!gpVdMX&?=xZJVe*Hh<L7%_XH{<?a67%* z3V)12_m0}|bf2#GHZBkG<#W{g+2)B0H4n0YqmbT~*E}YXOwAigkSzcZ5LPym0;aFw zEVbDR9YwpxSk>z9?wTI~Y&;R4i6Lc+<-K+nK#pVH*a_y1(~v7zEMxJ^kYnk@1e1p_ z{Z1Uf43$r1DQv7tZOO5Fb;{X#cxtQ_IA*EmoTJ>d`nRI>=Bx?X6Ivo<uPE;-A0Kez zxoEVtF+&bzN09jpeg;RUvaeg_5d$MghIj_i%O=C3KfB6rb%U9nx|Ej$+vB-E^867p ze^H((PLKd~GL8SeJDgap?+%mFBQPB#zDt~70{^co4_owe)v6{MeaKG?nM`f;zY8nk zO~GqZ6--~n+&bp2R<{kS-?34;hEiF4`-A)~&U-vl>-9P)t<zfOF7F%pH=7;Hcme(f DbZEKk diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta deleted file mode 100644 index b59a80e2912f11ad19fd2dd2d30e22bb976c9293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmX^5A|sUn2AH4>VJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache deleted file mode 100644 index 46c9dc055260a8dd3af66ee241d2438c6ae38c14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1934 zcmchYQE$>v6vywmr70{Uc!Dfpae)yQ9dXWeE*f4KB$^DTu3)kk6IP(iZXKO%iOy)I zuY8I<_yP36Hy_k*;G-|Tndqm$(-sJ1-PB-w=*?-<_MHFk{O`Hff5N(i$u2HRxcD@F zPm(aP7vGRB$6rfQZ`aV&gXOvoPR({Ky}iqr|BP-~tZC@=bzZ#0aZOfkfDnHN`RZGs z;1e%ZKXM9Q3iawMfr4TvUtJGTFfUfBS&@S86#SqdWgB`!15mPDr~rs7(1qR>CAPJ6 zN2JAhtfhAbl{hukvecuU^nuyz7+P9y+m5C-uQ3L|7)Fj2gA0r))3gGvl&LgalPFxu z;F63>Zn%)a1sNBlUP*U~?%x<=DKEhm7o?506MREoM)DYuF|u8#Xm-cwzo&$~Tytfd zmvP=rkj!9G#^f0Z?(4=d0qIASl{5fGyZ8tYr+gkh<}vgDutk@EaI-kgF)@o50Ta35 zDyR-X%u)9>;IWov9x%3g$iMP}dU&X{n?7OX&7_346{19hPpdBDoQ!k9ssmZOM9UbJ zF&g}l2plm#ptI@H>5DlV4@bCM40DX;ahjmc(ps=Pt(N|b&^abC`3zxxtlPDY)4J7% z@?ugb%gR*`O31UqxuRUrInPE?tYn&_ULb*`f!egIc2H)3Tw(RD@I>gjeRlUIlW2GT zJ2h8E)%d2D3RQ0e488mN?vaGLk|l3r7qjHmsqu1yRN?z?g@)N~xL$TAf^sr>Yc@y4 z_~@5oo4P&Nzkk@Y^PNf}hfei+*Ow6_a&<3s66)2D9Ia;S&l&WmpYp$LnDK2mHu6Nb zU6t{!jZ_*arvMG;Ii`O`Fc|po!{n{|t6g>8aL)U)i9DOgU_!>kDLYH!bNMud5rKge zz6jwE9f$txiOyg$hsl}#NrB=lin8!vKXu!(Ov~H&DCX!{?4i}sQg>9t)-J#=bkpAw diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta deleted file mode 100644 index e7f013d77b779ab53ac19ad95a796aa2567c499e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache deleted file mode 100644 index 3c7e20ee8e09fbc83b25777f5a83a38a92dc43d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7081 zcmc&(O>7&-73PqlDAJMXF(W4uYG_0wwj|JUMK@@o#**d2`RQLwF@+r!g?32}sg;(y z?Ch?75*5+GKz%OKOD{EwoQfQKNCO{QG=~=Gsc0{`wU+`pwU=Ji_hxpN-1SnH6GJ^n zT5{gb&-cFfz4t~lWF)gfZszFZI(;ceU;0;RJx?gzDsAOS>5Du$>X=;bUTfH?jBTn9 z8;+YQwoIdOGrjssns(=FCdrh3L2lJQB=GQubh-ZfG(7x0Q?CCl0}uZhS*rhg1RnmJ zU90~k3lF~=74=7>@Ic0@Yh&>D<umK`SI(fx_*DH*<M1$3EZ12P9(b`_x|JrSUyqQ| zr||P`ajEp394T75)gq+!Tsl)bBw0!dsT3ip6wTkQy_wFWQnfMoP3XmWda+6`=HPK+ zo=#NhM6P(tw#{jIusi8Y^b?rn=V`u5^D(n5NmDvsdq4;sU#Abq;`kS%at~32*cx{| zVL4OG-Q*1S$m}+AcWu^yMV*C0fnB=9Ztv;cp2;2fq-mPmNr5d(^V!#R)8Q2+|I8KG zJHq4A>KI$Jd6FsGoN!iU>Q5^70UIc4TA`34*Bkkt<v(cJ-JUME5C8pV3qN4rpyRpe zw?&H!A6;9da_|Y<CH-&<C>Q#nkPY?|bH%sSE=x`ye})bb%0<#cZ9_ON+tE#rUvZcw z*VLG6%Rz@XZL4*>&x~%*7A{j^V&j(4lRiMRQPkz|!W*vdPbBOeLV#H0h1HQX&Cb&i zQrtD%O+v1JeD?FRxvpWIHpR;|S3&Cn#eb8<EyQ5;89u=@$qkJeZN_2KTu6>9Fqr{p zs`2CTgZX191&l+&MZyD3<zPid1u$NjBH#mK^2>0r&)kRfGn(t_d#8`+fkN~E5Uq~l z7LpNtfoaH>K|poU@w(h{ft!+}5>{#S1XT6C7^?VEl8(S`VxXSDG6wN9h?o=y?cDuy zE3Um^SU@5v&00houGMCxG>=GWP8M2J;IdNS+*_7A9q4oxK%`5xdkV{YD8Lzitz<aQ zGM!m~o-mpa@;$*F08)1i+mezD^4u|YxFtz@Jeul65>VjPBG7UfBmz&Vpo1^JJ|L05 zJpbwWBN%sFVOS~B`ASeMDJWLzI9Vr(#+sBtx=u~9NdGx9xMngW=K&JAtIk(PM9mX` zQbyL4lL!_7(Fw6COZrIToZ`)IOP`mH_+HcW9AhUn%{MGtoOYOs+DFK+b@~y2xjq)( zPBNfO=80hEknnBs6!|`U56>G!VGvux!Z7hAG#-$=$D}j*5?c3b0l8q3=aOFX7Ya9* zk#Ya}xH~@G@pKVXWFJPt{)5`4411{6Ai5Xl>0*^G=14k~krmrSuJ$~RM=LSN_0j^Y zpk$=9TECf=v0pk&L-4Pc)q-)qcouNH`9L?#hThy}ZO>}TkcT9N6<I&z2QpNJ*_gg| z4Tt;10n-bt#oM}P`o#eX#9c^oFuCSApwWB}6~#d{aW^5^g$p%xi#bNuGj*3McId*~ zzp9E3*3(^=3#-7|wg;t%0k(FRtMyq=*d3vFA(wTSsapVOhs%=jEj$#AHhIevx)}~G zsSLU06fg<T!j4)-6V{yzjv<rAw+igqHMX#@5I7m8djrdQhP6h*iTr8(x)hGfUc1Vq zduMkyxwQma@fWK23oWVi1Qd*}^gUynGrq&cK7a(Lg7d1C6^MWvpw)-60%$P9WzHtn zR82!PJ;R0aZ4**g(-Q&&oHb0lxm|%sa}~OlYX}~~zra>uPS}-$uG_aghW^mOQ5|#? zSNkkrg{Q-_F!YAWqvtib%l6m}_I`me_H>75;qiYOVEqGI(m;2aXPJlwK#<@`c}S)y zmT3KC&(VY6(N+Orv>4(q&k?#H!ea#=!rIy~96Xx>%4R(-+P3JzG<!X6fy{DQq<Vfv zME-Li`El(D0%PgG)*Gx0>b;x<jv7aUJ~hgBxd{a^pD6=BmRb2tZkl$5mDy|9@^rzs zeTx9L!M12{-S6sMeOrIVtNR-Y=Z3{W*Hm$yq2!yZ&!y?a5`7+8$Tj*Rp_B9Qdqw$* zkfT66QiPLq5j~VjRVTM6k4*i&{SAnlR3;S0k7L4km?VtY#?Iwbtt1ulYOYopqL472 zmQsli1QarrmU6jXzYnbi<g?Oe1QMFK5ZTS+s)<o^uX#e*METbus_9u6$_1vIC~r_@ zA;03Yp@{y_;cd@UJZ^gec^4rfguZ9CSc8N9n)*J+cC7=61-fM?QnwXk;T9CeICY(K z_9IQ|l=kD<OY&h3gjTSw4H98kZ5z#o_uoT^hF=@jPdr2H1NGb1>>PU^SZwdIuD;K9 zIRsk^a{<cDN|{0EhoKQLK(u`2Oo|VG?xDevKu<WvV1z`PP$)}r2ZM)^@q%A;1m`Xa z@xVD^(RlLx2fXJ?;k@z;a%HdE0MFh4;M@fPUANtxU97NIU+r7?N&<usN(<1mUoArE z4l^iFd;v++j0#dpu$R99hg6M7EO6&#;P%7UkI*6Ud;K3@d-r1I^vlnw+9#^B`2;(g zJnSGIqw3b;vQ+<AnOR{C4>;;Vj!@~sf#AT@?zfMsh`=rqQ(#!CaNsn&fLRqUsbEMu zIMA34xk7hs0rkQ=k<te83gkl!Ur1t`Mh9b8-f4tWLWm01GkU6Q86Ig+?y4d*UQfn| z-7kxuU?_`NcCZZV2Q3M{0bvqcT>W=sGMfwU4C&8F|H?2;YS@vchg|*TpgLc%K!sdR z$=xq^uXu-K<;_*O_DH$;5x9A(fE!Bo^A+h2ysjF&KYVtMzI^#q91RCJnWxcEIx%*+ zgE|)@Md<5bauA7r6Qeqk+ZiKshd_UEx);Rd!3*NQjv{lC-Rs{E$Kv?-^z;->;()0i zIDLR(Xrd|FoS-4>n?61%+`p6SzsmhFN6A*dcP{b`Tl^pVuvL2~iy!(BYM<&rGcPxk z?2>62abeSoN;VjJ$NMIH4bB_zSVA7*W(@kImwaULPf{%$c_r$$r+CF*#OFkKefRw{ z@15y8>&so;4f*GZyt_M8(su~bw>Ii4YO*h0l)kWgJ=-y$f5QKrsGbPDAd?d0B1~8g zRuQ`2J<Wim38q17*w;1(bJakP9qFrwCnzQNK`I#@JTfbUH(Pxd$Z(h$y){Zn?j~ID zUs)YX)A1!begV6O$qOrMvO}fWDVnWj-rk<RErc!P4G8`pAX_csT+?!4nBpAyABtz6 Ai~s-t diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta deleted file mode 100644 index e616ec00377dd7ef4a8bfede2ea0cd223bda2c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmaz!7?a8X1B_4xH<V7#Nlnbv&o4?zEix6=4Ak0}oeTh-hX}R+ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache deleted file mode 100644 index 3151c7d4e558903d6f47a6e6adeaf70a985d79d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6045 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 MhH5w(M&d#AFAN2avH$=8 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta deleted file mode 100644 index 701db1ffe1dd588340d9500aba145a8b33520324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmd<{vr1)v0cI#e1WKppq$cL-7nc-e=B39cm1gFoq!w|Z$mL`fm++&ABxRPwCl(bY ORz`h4w=v2;suuuDoEL!r diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache deleted file mode 100644 index 06aca663cd5452cb96c0b87500658f45d6fd42a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12265 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 F@qaeQOQZk* diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta deleted file mode 100644 index fd97a7e9416a1be0edb048f21be7ab89f3389b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ocmX@|G$oY*1{k3X9w?ojlbV>TpI=atnV)y~=BAkQ+a_%U0Mz0PzyJUM diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache deleted file mode 100644 index df828811e1f6acdb6c0306f160245b2a929b56e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49248 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 NGxJ45Xsuhc{|A38CG!9P diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta deleted file mode 100644 index e0ebbdac5a8ca12ffada134deb381bda9ca0a76d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmX@|G$oY*2H2qtPAHw8lbV>TpP5&}g(8rXS&Sx<l9^n>gQ6zCpd>Rt4^^xvwYW5= rL<B`$aY<2TUV3~|X=YAJY7sw*TvBF9d}2{iV&%$Nhtz({EiVE9yu2zO diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache deleted file mode 100644 index a4f51d1f3e36464c48d164dde89796f858cb31f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11372 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 I=wcW9FKabJtpET3 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta deleted file mode 100644 index 8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache deleted file mode 100644 index eb1d9ed0279aeeb838591b0c87fbcab6dcc82006..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5798 zcmc&&O>7)V6`pE)JoebmxHG#U4hgO#8!|Q%d+l*@7?wC22<+xUnpu>HB-&}u)YwgW zx`+OWJz=9ns~}k%(6ZXYYELUbEJ7R*N3=q)CxrO9fY{>-PK!8kLE;j=dez<YlOD72 zg@fOeUsqLEfA6cW-m8;reC!A8Qcj=0r=Q8`XZ~9JxRBHJZx&ylVMT40J>If~*<NXd znGL5ASgxZSulhlz(6p`1OWKR;nl4TmO*U5iKC9N=U})SQU#h(}j>d1Y)!MJKXnZGk zwYHZ-<J@GmR-Tl7@>gpQ^JuiEFW2m8H2yGCt^IxmjlUeK*8Y454N<5Tm&RGq#IKfP z#oPFOXNu(lv%{D%qm3DREUUA8Cc{`JqfcEoZfRqgj4`Q=F)cHuoGZq0a*jt%4Q@?7 z&N5BcPZ^IG(`WDLkJ#$$cPHf3Pku9h#k?bYZq7U0^tQsbZ~|^RO>T1Ea)1zTg$kW= zo;OU}_Ia>v28oyNSi!b(#l!P7-V;ISIZ^NU5w{#a5N4CREsW{S%~fxH*R(^ioabNn zMJu#<%k{VyIt~`X{jSs4_FTseeXOi0xM;ORBk(aL*4nW;!nPcY&1baAN3+w1HX5Pl zb=M*+KN`StCBjm|7J>VG4_x2}4A~gjaaigy05x?<aVKN40A8=w{>dl+Mf|SLE}e+h zG&%_W5U%yLdJ+|%mrNNWE9gr2@My6-gtS12@YR-Ra`COu0-A^>AmR0vQ!>kZbCI9B z$QyOODH?7YQ71n+(II{+2b@05uk4!bjxBurxAaAcC8Dsz8=f!&$rtX3o!)AR6BdHe z#2YQ}ga<A~c+0vgoTOi#i`|Ck1cQX}c{}t2?zlTx827_Y$CjVqI)ZQFTk+%G6(08m zEM|@g8S!zMzbxkiE%1Ixs*dM2gzpo_%sY}hW-><6weIx6s_2SA&9I?5`v6Zk4ZIdG zqpR8o=Moaf3-FiuSLEkaCBpSO$w{7H<SmD{yRV{G$*S^~ouJJ9Dz60|W+$vwlYg5p zFE8`^G!`@b?ctB*{*p_mEAE!mEQ@u%<A!!K-X!uHpA2)E+twYR=MJxCaIQR7SHha& zpg*y!csX&%C90v?jyu~3W!DY)jtP-KfIFraSXgtHn}`|gAkKNLrY-siEOiB|cQ6p~ zu>yLISv~A#+ZScp@Ivu!_%p0_$MpiPG~2fPKq7660Nk+yOTPUJgi3d<gfHAJ^X?)L z-sMZY%kMA7ottjB2~MN0oMO3cc1kx_%Y3cOE4RzZRHd~=jJOH!dYNCi4M+<0I+TS~ z9*;klEwpSa*680pjjm)#Q6|XdVqLjz^h=L=s5+tx$;gs%OUd{xh{)k_di`h#DfD7M zn=&AI4|d$4IK=v#vXS#V8U&*GCL%a68Zr_FQguDKAARf+uPMCcJdP?>`QG%erj^Q7 zl=9X%8-l2loLD5F4~#F711BCtcap%FA`2ylXF3LIP=IB}6akhaQ{2f^N|*c3#WyFS z^^S&gz6U9tcJ)f1d<>~_<p8Q&<_+48&3%O#td6@$g{}#~Z$?5<zg;@5w)rA$A(J;n zU|P032X;HQ>6kLTi9+=J#Epr^N~eQvMy3~(ZM-xTroP02%}^v@3BIew3-WZkr@z2f z_5ZN`xkh6+5vLQ0ic*qc@0eXb5;my__;Wg-*IjdiG6Bh{lQW;6Q879naq8V+PQ5+I zsXrMuIi4X-&C==*ku8v&Bde1=44c9jIVi;~XGw9(X;a+tJt^+w#St5kSIR8y4Q%gk z<f1PfjpXrRHl82N#`6bbW0^P0T&N==;UrWL6g1<5LuCsIDbZ-gkK&OBr0Ezb?LQ`u zPCah8$QN<g^k^FFL(^h9+|R(RF+7aedqc7J2H5-4vHn+##(XxFz57b2wdJ@TP8!MS z{WvdA^O*B?SfC7+RX&*cc;*3ew2teG)D-r*u}2h_<$$Evi4}E@&_Cx_jF*xfp|NKP zfFl{rpgMt}1wcNPj+W|-hg3pbHtLF;b&&J*@pwrikqUGiG)aC$>1kuzMAk3Q{Wfxj zErEt7lLsXCZA$Lq?&xCTRPUWV3YM1VVjxgzSst=PDH}2H((8tS6pW~#@R8U$O%M;d zroa86+Dz+_Y~WM+E2<UaQ34X}()WxT<d`GbI7%qZlRZZE(`1jsrfh22J;g1@r?};W zDemMAkuvNl@b>`zzoK($eI)kgu>|=j&0Qa@4C@D02HNE!k%dpD3Zi}xF<6j?mOKLP z=YA3i;{_GV;_o!pR~$#=Cw@y<H71+jfW}UzBYi@-iwHxpDnqeBDeS8HSyMliOPbF9 zZ5$;&$PpU*4A}*;oa{-mr!wfe5^XSax)$xrsll{G4or!=oGHaEr%rL>UFyTGv1~+? zw-iy{0#SY$BQ=^RCx(e~VKh-L9GECLLXgoDUA7XsJoPE!l;SB4z@QCEdnAMW{Ezb2 z7_{<#T&+mB6D`%)bBSo81<=pLmejFoysvP7AGjaOM-&>3``IDfqhcNfE+s>~8<_p? zT6!hb6Ka@f>EMORz>NwNvSIlG6;oVq#-rj)40)p|OMF@1No5_lU+KFW7^-_^HKqzI z4+R!70#snK@RH44s)XZ`Y)zKE7s<%qXi$mDwAU`GYH}4-Se~y_J*rZIcM5+j^kVq) z0Wp6NiMcEzWDHlYD=|mRK1(q>i%8PlS?_;5E73DpT;$=x#t2kA1H|*qY@`LF<N0iA zJgHiem2Q8{^+_Y@58s}Ryd;ZD0Hs^91W+wi0<@8QL{)$vCH_C0`}<rEz7GfBd(Ze; za`Z{~t~@XvMgqD>5G|4Y96(fs+K?AemZ=A9mW>ZV`HKk3%2PwR?V-$3*9O#zZYcf# zADjy|@RW-3fqv+)&d$C#sp+#-efEexzogF}+4!39aUr2+kLlU9v9I1)xZ-)PSGerD Xww_&rukeZ&iiIzmxbM(eZjSvIo{p+3 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta deleted file mode 100644 index 8bfae6dc9ba127cf7714d1689d480cfcf6ebdc98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2Wbbd7QGhmnF;_hmjz=0 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache deleted file mode 100644 index 4f95ac68f6ba84f0c04893d7692c072161d8ec21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18139 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 EUoUbwbN~PV diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta deleted file mode 100644 index 7c99d5d905225ba7c564dd44324b01b038d7953b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache deleted file mode 100644 index 9778e4e4367ebda16503f8b508d1629598257f12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2856 zcmcJR-*4Mg6vut-xK6B9-BqEeXedXmCXy0b;vj^oD%mP+bd_K=u7p@MH4eFL-8#1A zAGBRN@ys+N`oKT17bJM)iT?nJ7ZCgpd*Fd*Udp-mCh6LFlPWcl;v8T5`ked8_k4Xn zI8tvJbb6KEH0aGACx0jzl<rQRl-`~Etz?{T`^@bvc%h;wGTuy5WuohQom=Ydib_9y zVy_czl9ETx8w7(t$g1-f557|$INz%n+|!nw6%B)Gq2tsFJkTwtqGRyRSnR+U1|`FC ziUtN>7N0onBGFE};bs(jK}!5!lf`iuE5yF0YId9Gl$eS_h@#Naf?ZKHMX?KbB($_h zOBO8|EhojP+htMvn!Ge4FBzYC{%~9;gwogs{<BM$@MxZjq?l7Fi>w#c%=4}h{7~}N z?Se}6MOq-OM5I%c#`f6B*syY?)h}EbP2ruK!ZD*_Ags%keOC+4fa4NJQ?F&;KyKr^ z^kY1lWdZtfb$&~JCTDmxKfr%}B$`-0SL!!?O<b<n-wXd11~bWskS=38Ak0<TCiU@0 z!*sIHe$&Div6r$0uDc+03TcRu8+6^c3t^T<Sy}@(idfLarU4fMw(olZ<M*XI3~+qj zG+}lY?i{$i$Y*%cZns5qna~6;obLmw%&d6O%X%|a6BZWW{U*qB6R_*d7N2FB3Tez1 zRtmDw26`P8ppJdan|qZWlREuVKc6%g(^M`d;RT$+y)8HlGuU^7lm~GiAZOKKAUH6j z8i1E35bg&cNG6OyyAMg4LOT!Xi!|kJf@l;*=ZNCDBr1TS8Is0{`m0(N2}VWIvQsIw z6s7h|m&tMozL`r<3hinT=E8ePkFQrFvNMDl>;Fs;sf#n$9~H#d-jQ<LK{-C__rO`& zT%0r)rx4^7we4%9hRr;bn#9%kN&j0fcUdRf?o(R1@J7Bdcq0>4(fC)qW-a@<)X#I& z&wtnC6V5Mqjlb^`uw3}s^)ul=L!T1sg-VikF{;9$$9&;dpYZJoB!@xj9&mB3qhZO} zUIH;ovpB$hbhlC#V}o*k8}w)rVvoXCZonHiOYkl)fXIs&@7N@-J%<VttAANuOG^X) zYc@?7#KJ5uSf+fy{k=-PI<(58aIXgS$0ms3yjfl^3gZ+VB}utcY}9LDJ>=1GQw+}c z+^Dh@R1T_e1PAaQ)ZsBcUR)O$Uw!W!SmIvk+8b648u;Xm4{Pwz!xxPEY4MjLe*w$C zf3xpsquMZB<<6{AdRoE_Yf+`+i*$U7PS4Tlsn+K#$^4Y+Z&TgU?(dcF@Qvogav1tl SpTn_<^*CeYyRM(G>*RkRTfZIv diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta deleted file mode 100644 index 48ca73e0ee43502e40d1b8b70f34ddf19d858229..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache deleted file mode 100644 index a4ac54bf2faa670c4dfcd2bf5663a9eff8c0c3af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37907 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 vNBh4lE# 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 D?@Q*s diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta deleted file mode 100644 index fb52d575e15e87bdb03fca9fb3c0bcfa695274fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache deleted file mode 100644 index 9da2217179c061bd64af462f20aeb7be93945c7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46246 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%0A~q@w1io@;8@DNN$`_S<-%0x&6vGevsYk{{pti7 z6(JHN_fI=rk8kMur^3kpsaRo-ER3}JHKZkLtqlyY<H;ModIRwR_5@*biA1XCiQxE^ zMoUY%zYJ?x()bLj%8I5uku2D(r_n5Q2pU9blg86tit<{%ofJqXbV{~wB4+Hnn0;^2 z5grJ~k`>h&vur&;i*~2WTd?&82|AWnel?L-d|=(Kjdgj#CCUY=wL?;nC^;3YX9<Jl z1eq=;+k~p6Dpy1#2H8W@z84@vh*PRLiG!}LE*1sefQV>iNiO^qD}JTU)c2VKzdAtp zc)FOc)ogcX@xTU7kMfAcMiPTcqs<r3#FE-GG)PeR2fZv{aILDAZ+sY{6sp^JWOxf7 z66SCnW3|h8KVgP5VmXP#m2&L@Iu6{CrZ^pMprD}TN0%N1=`}vq#Cj4W_eyU3^l}2( zjjLHwV)3?)x8GskLCPv0dofm*yN5{c=>JF3^Vu-=5p`2aPdvsfe3l0ODx@b$Vd**K zm7d3x^yD7%kw={HbdMrYXOCR5?8JsKPy*h0EHlQATcKUbfNnp(i`a$XdByJ{-M7y< ziU6fe8u*RR=VK=mQZmQOD31;}Udsm!tpVi`E?NQXw=!%XXpfyCiRCR6Z1VFE=VLUl z*qX<5WYO7Cka?8g^a=~D=*{iKfBGHIDseUV-TLWZKd~Wmzsu%atXmMlMRN5Htl7Oi zw}VBlj^k;pPML=ud+lGnMuG~$m-l&0q&(58!(Y<@>(yC>KkLZg&(eU!Xl^g?uzoIV zlEr5QKnUHM^o3XoLB)I#L9|*dX9;*}fe~}uxYIw{1cR`D_K7!fHttK#W-SH>#3LTw z@N5C7<HyxTJbgZ<;?!8rZV#X5PQxdQj+c0u;g%5-%M7=?wI-}?S~FC9lV!@?WcVBj z??x^}^kJ@?Smn)A00%@@T}%iZ=-nO|76oT(13r$%i6c7n?epK3;c>#YZ_t_RQYftR zQ|LQkSc*`TgA${Ihri%Z=oj36_l3m<L6|3Ph=C7fGW!We%&Ep`;{bB{$(Eb95*`)< z;c6hdvwO7^^rG96klMW{$;CNVU=GajLW6v_Rx@WC-Yrny7p$o|Lj7qquS*nc&QLyY z)&f8qK3kPE9zby`mQQO3_UTAM2NI$yn07!X_zy20R;GXfl1Go1FS<9$D8;*CKpy?` z(O-<xMzi7&g0YE2<HA_h?b0iolwXYLQs1QfB2P+u@}!(lr@TO=GcPshwF-1LS#qjd zEjPG8o_7yqhi!67q@dAe-1M_>x?V;oqMDv@`1$}GEp)^MEt|_ykMa=@+=ZUay2-f5 ziy)|f!%wKyi{S#i=D@dK`kyaR^bZ>v-5$TFsXnVE;+Lq$V+00257(r@y|cMbv8B)a z6o`9dt*DZ(yYI7M*sINK^V{N>rlsIVB$f1p6LCZHV9z}q*)XHQbsgX9+z+dXy_5-6 z@MZX>8!{1yUIkyu%{7EdeZKWut+Yyuwo@8|T4sp-l*THpv<%GQp1GfCqp_5G*2_HG zSj8rDREG?v#n+t~b7$7vsh@uxXKNxgNR5nFBc=P{-rcAi%tn37xxyQ$jV(Cp3upcl z!kGB*Z>HLWLA%XL2?8^)*9R7EXF#1sJ%+e8j=%KpzZBghfYdLAp&8uN`YyVJ=qIA= z2pOZA>+g}j{=)VbNzoz=jjS%-Z5l6Qft#GaL7DinBS~M5VU|hb4_0^zz6o3XkTO<a z(Wd!ogSXaN!*B#+evYQ`7U@IbCG<3VeXB;K>Pyp@rZoMn3Uf6Q<7h0Q{*%3Zg-I>D z524R2le~)oPR(P58SK-&qXM)OOXWlqJxK>0k(dfu0Ua5`arDkt?lcWyfL=VfDQO;D zJa|uVZ?7Dz5@rWY+a?imuyRP=-AVWSivi)<=Tg{rDN9*Z;6fsGHv&QLqsra1Xztu< z_AZ)xH=6tV&HY<>iNe;vi_C^0Faq~B_U#}Kcp!{0EDUkrm|d+GYi7fCvmu*$=<yxw Z1>i$I&4vu_wbG)X9lYM$G#WP<{|{H33E=<$ diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta deleted file mode 100644 index 6587875a9ea9dec90101364c1e7d76d5ef2dffcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmdo0G9#4%23VmCPAHw8lbV>TpP5&}jUteilb?ttlwXvRTEvB-svt2FO(Z2Vxn%E! Lc~|2ZcNPEuC=VMA diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache deleted file mode 100644 index eb3b7c68476e2ba0e42159d0fb641fa4439c5c1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4740 zcmc&%O>7%Q6y7(x?q(f3+rdfGgqFB21+*%P5(^>u;yOwYRE1`}m4Yl#>eQRWjqSDU zb$?JLLscY>zzK1oLLA_VdH``kMd}4{=!qUGAp}xSoO&;BW@k59ckLQS3WpuP_0Eju z``&xsdvgL5`5!o=(wQPXHNEg~8dCQsfYQsUKPMoyp~I7{nq98X*UJ(#J$t?FN_wSM z-6$x8#xkY?iu!iB31FTkGVQF<SaCrsg%_^kCT%<2QE+g#?es-&*Gl!0dof*iDxI30 zt~T1PEte}2P|cuPi6+<dWt<>RP^n7tCD$AyG7t$L0EvX(3d@9kY?!w|PIX|(asiFc zh+%z7(5TBxR!v6ZeI;YPr=amstYqDap+Qx{I;^5`eJp2P8$;t~t!VwCq49S-XZ;mN z!%P^~Y66WPlZN#}5{>UBa;dWbshbL<KF8<gA^gSXYYkH0<C7bQ)Y);+ckJtJ<R(pI z^A5xo0GatOY#>aDYV+m=B1@8~;P`BMkRXBt$&$jET*USIxoX>;<E*ny@GH)V0eadn zkKs?UNRQzd=f~aabBSbsQXVK>*IBRO76Qp12Zco8NMZw!AT3l|lfa7w@E3UCmO|is z5Iy)-zyZBo{lFIBZXXo5LmZsSz-6e0Zc^2^8p2DfM2>O~J7)O!^x@;~cDcQdaklR; zTQj$Lm|>D(m>oCh@e)0;hQTr>k$$<zzTpgQ*F~zn<Ty1i*f<PAX^$hsfx}3$d9p#& zE!z*WM<e^8FOK*C9QX}!j58cL?v1s4(QbEYe%f&5@xJ@sdZ*e0GZTt8hNTDMq`WLY zsh6AUSIV`HB-=t7tTgNc?6*-)W4cigMD+Dtf@4nlN(#X{GBF`MI!K7cf(fQ2=;e}$ zI4CXBb2!FBI72*00ILAF0$whR5t=k;0>x(*NBwHm-A3WAHY6$gs<N)=Zh1!}W^q3p zeG<VD#(2S?g+*GJ@5_+R89Iz{^OS<>!w?j#=L7{}`z9A#hHVI9mKZUcEvGI?-5uL* zRvTLY*@SjR%UA50?fSwsx+?cg7&;(f@EeB7bHlLUPxZni=Vu9LL0}ljLyiXs3zGn` zASC-z{9ODABZt)|34HMwor`%Pg1fags(|*CofPL{au_cBsa}OD`YDs<DYFMih!B#! z3y&a=J(At>AwC{iGP>pso(>7F^9u%DDACuL&QEa|M+P|EpW(F@1GT}Qia=#b1E;^s zLSG;WVHBz$Q+U0QAap82CxK4o_-Np$ZaOUpI3Rkp;X0@iU&_D9dZp#C4ivkr|3xLH zId4a!RAPFVm<ZNKsRY9oMO2S`vg{B^A?V0{6aPJ~Z#uP#M-AP85&O?BUBr4~J{2#| zBW_-3x|HB=UlpC<{LEsV!7VV(*g68izxmB-&9z(DEO_5`4T$mJ33QVO4~G=RNDw+K zT<Fy9=#>?sJ6G%$9+PDmD(HjpR}!lrd*oQB_fuZ(M3fhgnP-*YW1NcPK?(NXgWkQT zof@Y9_xFgDTaW7~`htLBm6#@3+2MtFPto~8y{}Tp<yre;w*&GH?rQS_r)y3mRg^Ll zm=jl<KyvuiMw~eWoMca`D+p+Du5P!s>;R8-bU(pxJ0ciFuTi2aeQ&jp=GaaQP+xz> z5bEns^<rQ#RB}DEAts_*vOrS+e7XHfyQfjes15sSK$rR9$fZbS_clqwj2|YjGn}E5 zIAXQzX}0k|Aw+m_CHF9-bNNoQQg-(^cX@Q@cFkY8bDvVe7ulIu%RO&iV>9|nA)83x z6z02VFz~W*nI`A+=bLWTX$S~TQ_|V1xUA!JzGw))2m41=U5|+nO}$mu6HTw`&Z3M8 z=@caTt$A+z#yAD_OduIKnmj^h3_5c}+?r@?mc|z4^E-1Zt(Mc`cS0I7@IU=Rt7Ff- MQLeRZ+~P3&3(lYD?EnA( diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta deleted file mode 100644 index 0b52486cfc5f05044b9b56a9fe4cd784dca2c15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache deleted file mode 100644 index d989e36ec8ef38c79c74bfdc93342613440fcf1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7258 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 Pj|J8O*Ho0G-yr`36)Isa diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta deleted file mode 100644 index 8b36f47ca8f554f7005ebbf3285be4ae7326420d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache deleted file mode 100644 index 62529545334bdbdf0797dc5ba7779d6eadbcbd7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2702 zcmd5;U2hvj6y4d6Y`kh@uB<ePX~-mPr8L^4i9=LjA<`I(RVh-lbtE3zs$Sbu+pyk^ zcgKl~ic;~2KuEj*PY9mj9q|wNC-A^;D0gPo0b9gTs|r=JN3%0`=FUC$+%vP;)^FRe zP>1Vt@Z{UvpVM;yALo`cw{o9l?B}h3`Q4jQtl3Q#tFK21*Rsu^Q{OXnunL|@%%!_A zP7~tI>ju1IgH?x&GrCsOAya@%9cFB0Jvx1$8~EG1rb9XJeLxKOCGY)AjNAfQsm>G8 z(Xpe8j!~@68`#O1rRubaopmc;buH|CZ<VUwiO!;3tX{E+VU&A#s7t!xxx@nETzm+? z03h#OAp|Iq$1UL|qh~#(<zC+p9F4#aKN=POaxN&kxTaiuikpnOcup%Z^Er#PUCP^j zD180;o89e%sk1LtJQ^XI2APjM1W(hvX>18B7GSXs%Qkiw3L>+M=Rtl>CUD^exw423 zu;LwJ3^R2&BwI7z7~*u}QQTv^ABV{d2El03^@D&VoJNl+KZ$50NR!Z3=a_{eN=|DP zPTxaxvDxRf4acEZuhR0s?;hbg{HoPzl8_D>ptsd>&qc!<4mNVq!4#A2*{OG@?5;m} zU7`8{q4Eb4p$h!C_3DuF2mc^d?kS|O7PjBCO4crq9(BSYhnpj`y6L%+R;HxY1(Xn^ zS&_W4?K>e~l8HiETF4P7dV!)!fK*u<Ivt1LAdZ^-2FoSXr(wU#;!cCc>?mdl3%Sob zQ7EZ{RFc%0%nudUs-(yIRvPpOgHnrf4+*q6!Jr}-CU(fyYK|b7W4Oj?BkCUcF?)?j zR`MPwkOv5I-W;BA9Od`b!Lx}h!kU!s8a?)dKEoj_%aBn&jId&3mmbNKbi$TM2|J;w z`DEx*Xe8-QI=o#}MOslsYB&xd2ZW%6kU4pWtbs|g!jO<{+q`8O`$Imypltt3Q|q|N zc;x#mN!EE=vz4HJ_4R4Yj!}Y!N&I7s{lSp^LzUf>1E{h@*TmntNGD%<p{$yc_f#eH zsYvM5@U-J$-3c)Wp3Gs^RAGp8J?@7MQ86w}B8uuM0>}9}!{lI|Tk3jIgMQc?8F0?b z&K6Eic+g4sMiRw*_5PMicU=1RLzmW{6tQ|GzN@G(8!0PpU@_enCNAB2D60+$fkoA@ zf3kN&*1}sat*Q1{I$ltWCcic$z(wzw0{9sM{P|Ss{v3Q4&hY(TFjY_}{Yoom>;_CN zq<)>r`iR2)=N=k@{X6-KsOKBD>J{Lj%ENW>Xt+S=Z|i%PbeJu|>}6Ok!17zLvj#ht zcki*JA8@ep_$V~)ezH`K<0w{pLng0&Sd{pj!skx56h#48YiOH2jQecqLqAB^8{}`- CaHa16 diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta deleted file mode 100644 index 2395015401100f34736675fe98225d853098d534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache deleted file mode 100644 index a00ce91d6e967cccbc3fb06b812213d5f34dd21a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1882 zcmb`IPiqrF7{>RV&ARQ{5XWF?1<8v+Ok-_LqL)Ce3Q7?{HxUW}ao6rNS>0|zcGE`G zd%u9-!GjkM9tA&vAHky_c+iUnPoBK!JF{s_Y*Z8vozCq1eSXg~6J!@mKHuOcOn#!7 zePNoM-_1TZPiEhl=C@`b+^yw~tLc6>Y21!tE#n3LoeS*Z9OI{}_9E!nX(-pHfGQv1 zc>RN{7<#du(y4MJRjbdXsPfWi)L$8(uSQ~{9eM!v4Abox3=Wp20caYZUbfemu4#6P z(Ny_iT?2cH8cd@<8pD#(0N}i8uhGABgRem;{fQ0M9X~VHMBM9!k%e(fV6rocKx~OH zMn6OsJFeedvMkK!@p9kY>I5R9mg6`|yM^ZmvkLh_X%Wi{3l^5CKjS!-r9tHsT!Y-E z-;LtG6hxAw7+sZASCY!3lHRgp;om7zJO8a9HEBdoN$J(49^QLwhGJ)+Wp~V+b^DAm zNBIFMb#Q~qaie~87{E9`Zub+D`ef1@LoPm9&n$UCoyrf~@#B_qtm$uya8F;fgg0A$ zgc~jy7esBmBhYJy0(+4kHr04fc>abP3(vynei*xbGC7Kc>s8UA)e{SGWd#RrI!hKx z?_WO~nosRf_lL7+STbGpTS%#eif8N^nP|uD42V4&Blhb!!vTfQ+>cLwVzOHWqG;bp z@ZBJMS9P`3WPURf`3<5Tp*&+pcz;Mb4I0TszEEDo5(S=kP&ioSGo;zKEw^)9CP;(5 z$iE*Gy>9OgV<Mw*jP9_y-RJgjBmtUILZ>yRZaagdP22n&DEWy24OD@u*@3+L4gLg5 z{A+6TIFrE~o(N|A;<VgtnV^>Ip(C^BAkhkZ;bGji(2swQZIBCmcpmrQ#D&eU5H8>Y z46%r1d_)u#&hmn_n(zc5Yw3!>$%|8rr;qX(dd!Mc>g`QU%gAE@RKBp1t~AQGOVfw% z=D#sNs8G%fnNy9>ruQ>X22zJ&-mod(lKE3&ZW&|enG8KU5&BQ>?|-G9tUVDsz1wGp zDW))vahJps`UB(&e<hc?m7<?G=}eWUXZd`Q&(E&bMAQpnZXD%CS-*ZSce&ebcQcpT V?SLCa`j)xb?TOqKdYr@|_ztuamw*5O diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta deleted file mode 100644 index a2089a5966a154b5dd61585b9e0a71668b274981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2a#5L@9-R#`vm|lvIQ^z diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache deleted file mode 100644 index 4d6134cf4e68169d226aceadc5fdefbd5f41adf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7021 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 W-%Mz(0#i!(lf#_&1p(}yApZfAnRP4x diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta deleted file mode 100644 index 6ec02d279a3395e477453db0c144ac488b739524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache deleted file mode 100644 index 282e43017750880bf511116eb8b996a120881481..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6600 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 Neknf1VWdo=e*-)qppF0l diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta deleted file mode 100644 index d6129ae46ca64f4056698206dc7d3f0de91184f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd<{vr1)v0Y)f;2TG^sq$cL-=NFV@=I0$1IkMi{#QhNfhQkTV diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache deleted file mode 100644 index eb16341caefa07a4c1de8fb33938ecf99628822a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10378 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 b(1okBVgj+XrwtcyZi3J}D{zV_CfWZ04`O&F diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta deleted file mode 100644 index f4e887486561f8be3945fd8b61344d52d6d64401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmZ4IWtGYR1B_4x7nDxVNlnbv&&ez<xplPfLd0zE)c}_f3VHwl diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache deleted file mode 100644 index 7288ab8ea66c60f3bcc197fd340bcd4f26588a9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6383 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 P+%5{hElSW}%?0v5M-3Z= diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta deleted file mode 100644 index e4e832bc82346f74985f18beddf6b6e9edaf3e83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache deleted file mode 100644 index 803b10a07332be0a84317d77acfedc7e16097fe4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21827 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 YH29;}<h~SI7$ToB%;P7#_D<=40L?3M5dZ)H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta deleted file mode 100644 index 7c72b25579dddf57ca0f1d52e021b5c2d8247d4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache deleted file mode 100644 index 8621e14afe1d360db5a53e513ea69d7e2ca45e60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10568 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 W@@*iRn844H!uq4K?}B#x0QoPNKzVuq diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta deleted file mode 100644 index b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache deleted file mode 100644 index 6854436ee19d2eb620c05cf18f373ecb1659021c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7764 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 Hu#5Z;9viuX diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta deleted file mode 100644 index 2ae412bccfd7739434a236925520c9652e93ff84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<<f}##0 V7N1m_nUj)Q<er!*%^>nW832Uh9(Di# diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache deleted file mode 100644 index eba4407d83485e5a7ee4f182cdc6fdb2fb69ed59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3252 zcmbVOO>7fa5Z<?Id$U%88M#3TBF%!J&{fq?n@WvUWb8JSSS@5(C?yhd*7kF<us_l6 z8f2s@aA*%!FO{g&LsfC<0jUQLtwg!^)=E@W)pF(5Q_nrQ^WLtBH`p{FMb0>RZ|0kM z-+VL2%hD+sW@~WdQvP4^XMT242B_tyCvW5*Ps;suo6?SJg@Paq+m%;DIMUPKASviR z)NkRhUu*g!lFH8#&6pu*Tp<l(4UPVJy6O4hM;>W)Y<kvos6g}?QG$vL=^7~6A-57J zJq!-h@`ziB_$#7>Km8A4bY#W%)_ocT<#U^%<++0JoDdJ=5aTWn0TSXkOK#I^S?;<J zV?Q|(dkv;)0CIo(^a#wkO6WN;zQvJlG*Hl!%ny#j!kz=u6y)thN8@P>@C@I0)??*_ z2(+NLhy=e?@e!r`Nqoe236YBT$bMoxKr4S+)Qnpq8naT>n32%<N-7z5m~k(4-uOO+ z#*b;u_#utP&zYX_O9qW4dDS>0qj7nnYJ4(*22q|ElM0dM&w3ZaF4kdEl=R~y4J0dw zpzH=RAbFsmA0Px&!fTa{ybYx$6|cw*dFx~9H@twpe3)t?%)nnFkRh+ixr<@@ooAx_ zKOaCO09qmjca;cmDDzsT-!k2G>U$k2u)Fo9=U%6NSPw!UNm&oQx*1BGRjis{MAZ}s z5d=^!>BwP(Hi4f6=1MSEfH@h>=^E?$Ik{|bFZ0;xro)<QJbm$&@*H-ii3o6$X9FcT zKwv7{Z&<GBck7{0W*|MMOnn<u5yav~=DSR8!?aOaI0@Dguov`W9CnJsRt|wu07aIU z-S8<;hGy{hvzGnz?`b3k78O+prb;k_r?NcGcIYotcT-y}ukM%@lL}U}Q;Fy@FBj|n zaY0y&h#c7SJk^22#M=ep=VCchz&Oxfi9ieb*Ml?(z7jqcDop%TJvdT>*V$7Y)ZkzN z4le9M6>}e2L0lp|uH6gj9m{w(Z8(i;08mPhH%>KC0xEwi_x+ArXLCd#gXeyfsKX`w z4zEL;y2e?$fKV1SSS-Ne!ic<{!^9D%casuJy$Xtt>bv!R*EJoh$x<<$g;rOX=iiYM zoaQmV3NgPzidByWrC9t!&P?POw+MM@ZfW{`#@`y;CvQ#NRJgmLvI>3mwB@!`(>>f$ zvAC*f+bRR0wmWW<jle){d%hZOP_^0ded>nlrte*)%~0(GC>rV#@57^kx^xleNjARh z<9xp1`PbgeX4Q(@jZdlQ38$s$JoT<xF8960Vy>wz%SX?i-&Jo|;f89eSSza1mKCy4 zmYY@A>d{FnP*J@Ct3`c^@ROJ^ofdk)R2r0J#ZWA_ndLG+o~zc(>!#84t<8|%42Dk+ zVmCVh3Qgo0ua;fvqa%S7Pm@*h?8<-*#{}R+#7CS#yI(=LeE0Oj_)^DE4{&kGj_^Oc z1W3ilnZGmrHojfGZP|iEgIE{t?&yaz!~HO%+9jAS;DWSMwRe7JRK^BD(Hzw}rASV9 zUgFGN)m0{LS78M|vk9o%1kBajZ40*{vO)-|J~>*M5E)zd;+_5Y*>}vaxq**{XC&4L z#c$HTr?=koY!BZ(PT5YRyhHIL@N%x|dE3&?vU))|LzzNMJLY(dV>=%~D$dCoUw2Ih z2dY?)=2YGB*xFimWwyBPVo;5#ECW8~Uwm9W(T^caoX5zcS-ujFhmk=2Q|h18DY0@u zgtvQeat|zPu)Gg0HsJEB;FQ4G2VD)i8R$HOPxrv>8ho~A)D!{I8^v5+eMoDNF61uw z9Xfy7v;*2-8eS;5WFpT>gY76<#^O<czk-e(LV7>?kj`D3U-Es=k9ON}3pkMKfGNYv L2oQ}gM|;VC-XAjg diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta deleted file mode 100644 index 35823f819643250ce036eb3ade6a8b4cfeac4a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0<IM LSG~Z5x<GpX@`M<b diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache deleted file mode 100644 index a3585a7b2363d00cd2098856aa13f726f10532f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1132 zcmb`GL5tH+5Xaxl>uZ`~i9>azQphS>T;ri@)yrP21^3W{`nJO2#oDr|?QU$aZ4hBa z=+TRxz@y;Bi{HYlXZ;#p>%26{ZlMc;9x@qT!u$W`KQlXBXj)X6Q_Z5<n{rKAMD6l5 zb))=DS&Nr}??>a&4C~Wj7zKwSJrJUa52{G_8u~6s`qk1uL6+abe&+-@xrtt98#(!m z?amjI__Ey@N>1!tqf^L%bp6*+F96UNQ0gHlf}#)rLXdr+cTftU3n&4Fc@){#$!?Hs zS&v46%M`s=Pf#jAq9eTtz%Sb5SX?YYyS{MD{aFRV=?(@Xfp_-cIlS-t-Pt7a6ZID> z>UF&xtLHcZ+1^suX@%jbu=%hah#6YC%0Q(#RXG+@t&9XxFB#@z{#$-A4rg6shJe4Y zgB?OZj=A#)*pd%=iwQ0t(H6(dk})Jgfe;x@=F3<34$h!AN*S6frdXyKLa^uOm2P_A ztyCW0mI<9L`-*kTT5u2i$t0Wz)Ao1@PF5uA+NcSg^kFyd!@>Q1e;NfdHy!~4#b#h^ ziA<w1DD$;b(Z^IY9prQ@-r*-SNP}K5^-q!h^Juh}RP$t3&*-i7=|}!|-sPXd<9~E0 z7ki`P$a(D0`n~B3$LM7^*?e5W+sHd#Kq~E0X@e>rRW_1tkh)5$As-*R4^2noT_NT1 One&v_%-u7lUW7mHN#Q#H diff --git a/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glerm/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta deleted file mode 100644 index 401fd74cd1e9eb44559765e4eac26450d3f34537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md deleted file mode 100644 index 90ab0d56c57..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# gleam-community/ansi - -Format text with ANSI escape sequences. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_ansi)](https://hex.pm/packages/gleam_community_ansi) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_ansi/) - -✨ This project is written in _pure Gleam_ so you can use it anywhere Gleam runs: -Erlang, Elixir, Node, Deno, even [some browsers](https://bit.ly/devtools-console-ansi-support)! - ---- - -## Quickstart - -```gleam -import gleam/io -import gleam_community/ansi - -pub fn main() { - let greeting = "Hello, " <> ansi.pink("world") <> "!" - - greeting - |> ansi.bg_white - |> io.println -} - -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_ansi) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_ansi -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_ansi). - -## ANSI-what? - -ANSI escape sequences date back to the 70s as a standard way to format text on -various video text terminals. Since then they have been adopted by many software -terminal emulators and platforms, including some Web browsers, and are a simple -way to format text without platform-specific APIs. - -The point of this package is to abstract the specific codes away and give you an -easy-to-understand API for formatting and colouring terminal text. Still, here is -a quick couple of examples of what's happening under the hood. - -You can copy these examples straight into your terminal to see them in action! - -- Colour text yellow: - - ```shell - $ echo "\e[33mhello" - ``` - -- Colour the background pink: - - ```shell - $ echo "\e[45mhello" - ``` - -- Render text italic: - - ```shell - $ echo "\e[3mhello\e[23m" - ``` - -As you can see, the escape sequences are a bit obscure. Sure, you could hard code -them, or you could use this package! diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml deleted file mode 100644 index 5da1f7ec075..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "gleam_community_ansi" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "ANSI colours, formatting, and control codes" -repository = { type = "github", user = "gleam-community", repo = "ansi" } -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_community_colour = "~> 1.2" - -[dev-dependencies] -gleeunit = "~> 0.11" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam deleted file mode 100644 index a542ddac7ec..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam +++ /dev/null @@ -1,2317 +0,0 @@ -//// -//// - **Text style** -//// - [`bold`](#bold) -//// - [`italic`](#italic) -//// - [`underline`](#underline) -//// - [`strikethrough`](#strikethrough) -//// - [`inverse`](#inverse) -//// - [`dim`](#dim) -//// - [`hidden`](#hidden) -//// - [`reset`](#reset) -//// - **Text colour** -//// - [`black`](#black) -//// - [`red`](#red) -//// - [`green`](#green) -//// - [`yellow`](#yellow) -//// - [`blue`](#blue) -//// - [`magenta`](#magenta) -//// - [`cyan`](#cyan) -//// - [`white`](#white) -//// - [`pink`](#pink) -//// - [`grey`](#grey) -//// - [`gray`](#gray) -//// - [`bright_black`](#bright_black) -//// - [`bright_red`](#bright_red) -//// - [`bright_green`](#bright_green) -//// - [`bright_yellow`](#bright_yellow) -//// - [`bright_blue`](#bright_blue) -//// - [`bright_magenta`](#bright_magenta) -//// - [`bright_cyan`](#bright_cyan) -//// - [`bright_white`](#bright_white) -//// - [`hex`](#hex) -//// - [`colour`](#colour) -//// - [`color`](#color) -//// - **Background colour** -//// - [`bg_black`](#bg_black) -//// - [`bg_red`](#bg_red) -//// - [`bg_green`](#bg_green) -//// - [`bg_yellow`](#bg_yellow) -//// - [`bg_blue`](#bg_blue) -//// - [`bg_magenta`](#bg_magenta) -//// - [`bg_cyan`](#bg_cyan) -//// - [`bg_white`](#bg_white) -//// - [`bg_pink`](#bg_pink) -//// - [`bg_bright_black`](#bg_bright_black) -//// - [`bg_bright_red`](#bg_bright_red) -//// - [`bg_bright_green`](#bg_bright_green) -//// - [`bg_bright_yellow`](#bg_bright_yellow) -//// - [`bg_bright_blue`](#bg_bright_blue) -//// - [`bg_bright_magenta`](#bg_bright_magenta) -//// - [`bg_bright_cyan`](#bg_bright_cyan) -//// - [`bg_bright_white`](#bg_bright_white) -//// - [`bg_hex`](#bg_hex) -//// - [`bg_colour`](#bg_colour) -//// - [`bg_color`](#bg_color) -//// -//// --- -//// -//// This package was heavily inspired by the `colours` module in the Deno standard -//// library. The original source code can be found -//// <a href="https://deno.land/std@0.167.0/fmt/colours.ts">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018-2022 the Deno authors. -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the Deno `colours` module: -// -// https://deno.land/std@0.167.0/fmt/colours.ts -// - -// This seems like a really handy reference if/when we want to expand this beyond -// formatting escape sequences: -// -// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/list -import gleam/string -import gleam_community/colour.{type Colour} as gc_colour - -// CONSTS --------------------------------------------------------------------- - -const asci_escape_character = "" - -// TYPES ---------------------------------------------------------------------- - -type Code { - Code(open: String, close: String, regexp: String) -} - -// UTILITY -------------------------------------------------------------------- - -/// Builds colour code -fn code(open: List(Int), close: Int) -> Code { - let close_str = int.to_string(close) - let open_strs = list.map(open, int.to_string) - - Code( - open: asci_escape_character <> "[" <> string.join(open_strs, ";") <> "m", - close: asci_escape_character <> "[" <> close_str <> "m", - regexp: asci_escape_character <> "[" <> close_str <> "m", - ) -} - -/// Applies colour and background based on colour code and its associated text -fn run(text: String, code: Code) -> String { - code.open <> string.replace(text, code.regexp, code.open) <> code.close -} - -// STYLES --------------------------------------------------------------------- - -/// Reset the text modified -pub fn reset(text: String) -> String { - run(text, code([0], 0)) -} - -/// Style the given text bold. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bold("lucy") -/// // => "\x1B[1mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bold(text: String) -> String { - run(text, code([1], 22)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("lucy") -/// // => "\x1B[2mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn dim(text: String) -> String { - run(text, code([2], 22)) -} - -/// Style the given text italic. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.italic("lucy") -/// // => "\x1B[3mlucy\x1B[23m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[23m"` added to the string. This is the escape code -/// for the "default" italic style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be underlined but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn italic(text: String) -> String { - run(text, code([3], 23)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("lucy") -/// // => "\x1B[4mlucy\x1B[24m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[24m"` added to the string. This is the escape code -/// for the "default" underline style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn underline(text: String) -> String { - run(text, code([4], 24)) -} - -/// Inverse the given text's colour, and background colour. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.inverse("lucy") -/// // => "\x1B[7mlucy\x1B[27m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[27m"` added to the string. This is the escape code -/// for the "default" inverse style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn inverse(text: String) -> String { - run(text, code([7], 27)) -} - -/// Style the given text to be hidden. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hidden("lucy") -/// // => "\x1B[8mlucy\x1B[28m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[28m"` added to the string. This is the escape code -/// for the "default" hidden style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hidden(text: String) -> String { - run(text, code([8], 28)) -} - -/// Style the given text to be striked through. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.strikethrough("lucy") -/// // => "\x1B[9mlucy\x1B[29m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[29m"` added to the string. This is the escape code -/// for the "default" strikethrough style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn strikethrough(text: String) -> String { - run(text, code([9], 29)) -} - -// FOREGROUND ----------------------------------------------------------------- - -/// Colour the given text black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.black("lucy") -/// // => "\x1B[30mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn black(text: String) -> String { - run(text, code([30], 39)) -} - -/// Colour the given text red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.red("lucy") -/// // => "\x1B[31mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn red(text: String) -> String { - run(text, code([31], 39)) -} - -/// Colour the given text green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.green("lucy") -/// // => "\x1B[32mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn green(text: String) -> String { - run(text, code([32], 39)) -} - -/// Colour the given text yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("lucy") -/// // => "\x1B[33mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn yellow(text: String) -> String { - run(text, code([33], 39)) -} - -/// Colour the given text blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.blue("lucy") -/// // => "\x1B[34mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn blue(text: String) -> String { - run(text, code([34], 39)) -} - -/// Colour the given text magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.magenta("lucy") -/// // => "\x1B[35mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn magenta(text: String) -> String { - run(text, code([35], 39)) -} - -/// Colour the given text cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.cyan("lucy") -/// // => "\x1B[36mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cyan(text: String) -> String { - run(text, code([36], 39)) -} - -/// Colour the given text white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.white("lucy") -/// // => "\x1B[37mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn white(text: String) -> String { - run(text, code([37], 39)) -} - -/// Colour the given text gray. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.gray("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn grey(text: String) -> String { - bright_black(text) -} - -/// This is an alias for [`grey`](#grey) for those who prefer the American English -/// spelling. -/// -pub fn gray(text: String) -> String { - bright_black(text) -} - -/// Colour the given text bright black. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_black("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_black(text: String) -> String { - run(text, code([90], 39)) -} - -/// Colour the given text bright red. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_red("lucy") -/// // => "\x1B[91mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_red(text: String) -> String { - run(text, code([91], 39)) -} - -/// Colour the given text bright green. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_green("lucy") -/// // => "\x1B[92mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_green(text: String) -> String { - run(text, code([92], 39)) -} - -/// Colour the given text bright yellow. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_yellow("lucy") -/// // => "\x1B[93mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_yellow(text: String) -> String { - run(text, code([93], 39)) -} - -/// Colour the given text bright blue. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_blue("lucy") -/// // => "\x1B[94mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_blue(text: String) -> String { - run(text, code([94], 39)) -} - -/// Colour the given text bright gremagentaen. This should increase the luminosity -/// of the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_magenta("lucy") -/// // => "\x1B[95mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_magenta(text: String) -> String { - run(text, code([95], 39)) -} - -/// Colour the given text bright cyan. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_cyan("lucy") -/// // => "\x1B[96mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_cyan(text: String) -> String { - run(text, code([96], 39)) -} - -/// Colour the given text bright white. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_white("lucy") -/// // => "\x1B[97mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_white(text: String) -> String { - run(text, code([97], 39)) -} - -/// Colour the given text pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.pink("lucy") -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn pink(text: String) -> String { - hex(text, 0xffaff3) -} - -/// Colour the given text the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hex(text: String, colour: Int) -> String { - let colour = int.clamp(colour, max: 0xffffff, min: 0x0) - run( - text, - code( - [ - 38, - 2, - int.bitwise_shift_right(colour, 16) - |> int.bitwise_and(0xff), - int.bitwise_shift_right(colour, 8) - |> int.bitwise_and(0xff), - int.bitwise_and(colour, 0xff), - ], - 39, - ), - ) -} - -/// Colour the given text the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - hex(text, hex_colour) -} - -/// This is an alias for [`colour`](#colour) for those who prefer the American English -/// spelling. -/// -pub fn color(text: String, color: Colour) -> String { - colour(text, color) -} - -// BACKGROUND ----------------------------------------------------------------- - -/// Colour the given text's background black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_black("lucy") -/// // => "\x1B[40mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_black(text: String) -> String { - run(text, code([40], 49)) -} - -/// Colour the given text's background red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_red("lucy") -/// // => "\x1B[41mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_red(text: String) -> String { - run(text, code([41], 49)) -} - -/// Colour the given text's background green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_green("lucy") -/// // => "\x1B[42mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_green(text: String) -> String { - run(text, code([42], 49)) -} - -/// Colour the given text's background yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_yellow("lucy") -/// // => "\x1B[43mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_yellow(text: String) -> String { - run(text, code([43], 49)) -} - -/// Colour the given text's background blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_blue("lucy") -/// // => "\x1B[44mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_blue(text: String) -> String { - run(text, code([44], 49)) -} - -/// Colour the given text's background magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_magenta("lucy") -/// // => "\x1B[45mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_magenta(text: String) -> String { - run(text, code([45], 49)) -} - -/// Colour the given text's background cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_cyan("lucy") -/// // => "\x1B[46mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_cyan(text: String) -> String { - run(text, code([46], 49)) -} - -/// Colour the given text's background white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_white("lucy") -/// // => "\x1B[47mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_white(text: String) -> String { - run(text, code([47], 49)) -} - -/// Colour the given text's background bright black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_black("lucy") -/// // => "\x1B[100mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_black(text: String) -> String { - run(text, code([100], 49)) -} - -/// Colour the given text's background bright red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_red("lucy") -/// // => "\x1B[101mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_red(text: String) -> String { - run(text, code([101], 49)) -} - -/// Colour the given text's background bright green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_green("lucy") -/// // => "\x1B[102mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_green(text: String) -> String { - run(text, code([102], 49)) -} - -/// Colour the given text's background bright yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_yellow("lucy") -/// // => "\x1B[103mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_yellow(text: String) -> String { - run(text, code([103], 49)) -} - -/// Colour the given text's background bright blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_blue("lucy") -/// // => "\x1B[104mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_blue(text: String) -> String { - run(text, code([104], 49)) -} - -/// Colour the given text's background bright magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_magenta("lucy") -/// // => "\x1B[105mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_magenta(text: String) -> String { - run(text, code([105], 49)) -} - -/// Colour the given text's background bright cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_cyan("lucy") -/// // => "\x1B[106mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_cyan(text: String) -> String { - run(text, code([106], 49)) -} - -/// Colour the given text's background bright white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_white("lucy") -/// // => "\x1B[107mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_white(text: String) -> String { - run(text, code([107], 49)) -} - -/// Colour the given text's background pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_pink("lucy") -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_pink(text: String) -> String { - bg_hex(text, 0xffaff3) -} - -/// Colour the given text's background the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_hex(text: String, colour: Int) -> String { - run( - text, - code( - [ - 48, - 2, - int.bitwise_shift_right(colour, 16) - |> int.bitwise_and(0xff), - int.bitwise_shift_right(colour, 8) - |> int.bitwise_and(0xff), - int.bitwise_and(colour, 0xff), - ], - 49, - ), - ) -} - -/// Colour the given text's background with the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.bg_colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - bg_hex(text, hex_colour) -} - -/// This is an alias for [`bg_colour`](#bg_colour) for those who prefer the American English -/// spelling. -/// -pub fn bg_color(text: String, colour: Colour) -> String { - bg_colour(text, colour) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl deleted file mode 100644 index 8b7a4c9e72f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_community@ansi). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([reset/1, bold/1, dim/1, italic/1, underline/1, inverse/1, hidden/1, strikethrough/1, black/1, red/1, green/1, yellow/1, blue/1, magenta/1, cyan/1, white/1, bright_black/1, grey/1, gray/1, bright_red/1, bright_green/1, bright_yellow/1, bright_blue/1, bright_magenta/1, bright_cyan/1, bright_white/1, hex/2, pink/1, colour/2, color/2, bg_black/1, bg_red/1, bg_green/1, bg_yellow/1, bg_blue/1, bg_magenta/1, bg_cyan/1, bg_white/1, bg_bright_black/1, bg_bright_red/1, bg_bright_green/1, bg_bright_yellow/1, bg_bright_blue/1, bg_bright_magenta/1, bg_bright_cyan/1, bg_bright_white/1, bg_hex/2, bg_pink/1, bg_colour/2, bg_color/2]). --export_type([code/0]). - --type code() :: {code, binary(), binary(), binary()}. - --spec code(list(integer()), integer()) -> code(). -code(Open, Close) -> - Close_str = gleam@int:to_string(Close), - Open_strs = gleam@list:map(Open, fun gleam@int:to_string/1), - {code, - <<<<<<""/utf8, "["/utf8>>/binary, - (gleam@string:join(Open_strs, <<";"/utf8>>))/binary>>/binary, - "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>}. - --spec run(binary(), code()) -> binary(). -run(Text, Code) -> - <<<<(erlang:element(2, Code))/binary, - (gleam@string:replace( - Text, - erlang:element(4, Code), - erlang:element(2, Code) - ))/binary>>/binary, - (erlang:element(3, Code))/binary>>. - --spec reset(binary()) -> binary(). -reset(Text) -> - run(Text, code([0], 0)). - --spec bold(binary()) -> binary(). -bold(Text) -> - run(Text, code([1], 22)). - --spec dim(binary()) -> binary(). -dim(Text) -> - run(Text, code([2], 22)). - --spec italic(binary()) -> binary(). -italic(Text) -> - run(Text, code([3], 23)). - --spec underline(binary()) -> binary(). -underline(Text) -> - run(Text, code([4], 24)). - --spec inverse(binary()) -> binary(). -inverse(Text) -> - run(Text, code([7], 27)). - --spec hidden(binary()) -> binary(). -hidden(Text) -> - run(Text, code([8], 28)). - --spec strikethrough(binary()) -> binary(). -strikethrough(Text) -> - run(Text, code([9], 29)). - --spec black(binary()) -> binary(). -black(Text) -> - run(Text, code([30], 39)). - --spec red(binary()) -> binary(). -red(Text) -> - run(Text, code([31], 39)). - --spec green(binary()) -> binary(). -green(Text) -> - run(Text, code([32], 39)). - --spec yellow(binary()) -> binary(). -yellow(Text) -> - run(Text, code([33], 39)). - --spec blue(binary()) -> binary(). -blue(Text) -> - run(Text, code([34], 39)). - --spec magenta(binary()) -> binary(). -magenta(Text) -> - run(Text, code([35], 39)). - --spec cyan(binary()) -> binary(). -cyan(Text) -> - run(Text, code([36], 39)). - --spec white(binary()) -> binary(). -white(Text) -> - run(Text, code([37], 39)). - --spec bright_black(binary()) -> binary(). -bright_black(Text) -> - run(Text, code([90], 39)). - --spec grey(binary()) -> binary(). -grey(Text) -> - bright_black(Text). - --spec gray(binary()) -> binary(). -gray(Text) -> - bright_black(Text). - --spec bright_red(binary()) -> binary(). -bright_red(Text) -> - run(Text, code([91], 39)). - --spec bright_green(binary()) -> binary(). -bright_green(Text) -> - run(Text, code([92], 39)). - --spec bright_yellow(binary()) -> binary(). -bright_yellow(Text) -> - run(Text, code([93], 39)). - --spec bright_blue(binary()) -> binary(). -bright_blue(Text) -> - run(Text, code([94], 39)). - --spec bright_magenta(binary()) -> binary(). -bright_magenta(Text) -> - run(Text, code([95], 39)). - --spec bright_cyan(binary()) -> binary(). -bright_cyan(Text) -> - run(Text, code([96], 39)). - --spec bright_white(binary()) -> binary(). -bright_white(Text) -> - run(Text, code([97], 39)). - --spec hex(binary(), integer()) -> binary(). -hex(Text, Colour) -> - Colour@1 = gleam@int:clamp(Colour, 16#0, 16#ffffff), - run( - Text, - code( - [38, - 2, - begin - _pipe = erlang:'bsr'(Colour@1, 16), - erlang:'band'(_pipe, 16#ff) - end, - begin - _pipe@1 = erlang:'bsr'(Colour@1, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - erlang:'band'(Colour@1, 16#ff)], - 39 - ) - ). - --spec pink(binary()) -> binary(). -pink(Text) -> - hex(Text, 16#ffaff3). - --spec colour(binary(), gleam_community@colour:colour()) -> binary(). -colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - hex(Text, Hex_colour). - --spec color(binary(), gleam_community@colour:colour()) -> binary(). -color(Text, Color) -> - colour(Text, Color). - --spec bg_black(binary()) -> binary(). -bg_black(Text) -> - run(Text, code([40], 49)). - --spec bg_red(binary()) -> binary(). -bg_red(Text) -> - run(Text, code([41], 49)). - --spec bg_green(binary()) -> binary(). -bg_green(Text) -> - run(Text, code([42], 49)). - --spec bg_yellow(binary()) -> binary(). -bg_yellow(Text) -> - run(Text, code([43], 49)). - --spec bg_blue(binary()) -> binary(). -bg_blue(Text) -> - run(Text, code([44], 49)). - --spec bg_magenta(binary()) -> binary(). -bg_magenta(Text) -> - run(Text, code([45], 49)). - --spec bg_cyan(binary()) -> binary(). -bg_cyan(Text) -> - run(Text, code([46], 49)). - --spec bg_white(binary()) -> binary(). -bg_white(Text) -> - run(Text, code([47], 49)). - --spec bg_bright_black(binary()) -> binary(). -bg_bright_black(Text) -> - run(Text, code([100], 49)). - --spec bg_bright_red(binary()) -> binary(). -bg_bright_red(Text) -> - run(Text, code([101], 49)). - --spec bg_bright_green(binary()) -> binary(). -bg_bright_green(Text) -> - run(Text, code([102], 49)). - --spec bg_bright_yellow(binary()) -> binary(). -bg_bright_yellow(Text) -> - run(Text, code([103], 49)). - --spec bg_bright_blue(binary()) -> binary(). -bg_bright_blue(Text) -> - run(Text, code([104], 49)). - --spec bg_bright_magenta(binary()) -> binary(). -bg_bright_magenta(Text) -> - run(Text, code([105], 49)). - --spec bg_bright_cyan(binary()) -> binary(). -bg_bright_cyan(Text) -> - run(Text, code([106], 49)). - --spec bg_bright_white(binary()) -> binary(). -bg_bright_white(Text) -> - run(Text, code([107], 49)). - --spec bg_hex(binary(), integer()) -> binary(). -bg_hex(Text, Colour) -> - run( - Text, - code( - [48, - 2, - begin - _pipe = erlang:'bsr'(Colour, 16), - erlang:'band'(_pipe, 16#ff) - end, - begin - _pipe@1 = erlang:'bsr'(Colour, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - erlang:'band'(Colour, 16#ff)], - 49 - ) - ). - --spec bg_pink(binary()) -> binary(). -bg_pink(Text) -> - bg_hex(Text, 16#ffaff3). - --spec bg_colour(binary(), gleam_community@colour:colour()) -> binary(). -bg_colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - bg_hex(Text, Hex_colour). - --spec bg_color(binary(), gleam_community@colour:colour()) -> binary(). -bg_color(Text, Colour) -> - bg_colour(Text, Colour). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src deleted file mode 100644 index dfcfdc39497..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_community_ansi, [ - {vsn, "1.2.0"}, - {applications, [gleam_community_colour, - gleam_stdlib, - gleeunit]}, - {description, "ANSI colours, formatting, and control codes"}, - {modules, [gleam_community@ansi]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE deleted file mode 100644 index a84f0ec1d35..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md deleted file mode 100644 index 0eccdd7dd50..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# gleam-community/colour - -A package for a standard Colour type, conversions, and other utilities. - -[![Package Version](https://img.shields.io/hexpm/v/gleam_community_colour)](https://hex.pm/packages/gleam_community_colour) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleam_community_colour/) - -✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! - ---- - -## Quickstart - -```gleam -import gleam_community/colour -import gleam_community/colour/accessibility - -pub fn main() { - let foreground = colour.from_hsl(h: 0.858, s: 1.0, l: 0.843) - - let background_options = [colour.light_grey, colour.dark_grey] - - let background = accessibility.maximum_contrast(foreground, background_options) -} -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_colour) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_colour -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_colour). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml deleted file mode 100644 index 07a81bf3b42..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/gleam.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "gleam_community_colour" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "Colour types, conversions, and other utilities" -repository = { type = "github", user = "gleam-community", repo = "colour" } - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 0.11" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl deleted file mode 100644 index 06116dfe288..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl +++ /dev/null @@ -1 +0,0 @@ --record(hsla, {h :: float(), s :: float(), l :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl deleted file mode 100644 index fff139e06ac..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl +++ /dev/null @@ -1 +0,0 @@ --record(rgba, {r :: float(), g :: float(), b :: float(), a :: float()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam deleted file mode 100644 index 1f5872faffa..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour.gleam +++ /dev/null @@ -1,1126 +0,0 @@ -//// -//// - **Types** -//// - [`Colour`](#Colour) -//// - [`Color`](#Color) -//// - **Constructors** -//// - [`from_rgb255`](#from_rgb255) -//// - [`from_rgb`](#from_rgb) -//// - [`from_rgba`](#from_rgba) -//// - [`from_hsl`](#from_hsl) -//// - [`from_hsla`](#from_hsla) -//// - [`from_rgb_hex`](#from_rgb_hex) -//// - [`from_rgba_hex`](#from_rgba_hex) -//// - [`from_rgb_hex_string`](#from_rgb_hex_string) -//// - [`from_rgba_hex_string`](#from_rgba_hex_string) -//// - **Conversions** -//// - [`to_rgba`](#to_rgba) -//// - [`to_hsla`](#hsla) -//// - [`to_css_rgba_string`](#to_css_rgba_string) -//// - [`to_rgba_hex_string`](#to_rgba_hex_string) -//// - [`to_rgb_hex_string`](#to_rgb_hex_string) -//// - [`to_rgba_hex`](#to_rgba_hex) -//// - [`to_rgb_hex`](#to_rgb_hex) -//// - **Colours** -//// - [`light_red`](#light_red) -//// - [`red`](#red) -//// - [`dark_red`](#dark_red) -//// - [`light_orange`](#light_orange) -//// - [`orange`](#orange) -//// - [`dark_orange`](#dark_orange) -//// - [`light_yellow`](#light_yellow) -//// - [`yellow`](#yellow) -//// - [`dark_yellow`](#dark_yellow) -//// - [`light_green`](#light_green) -//// - [`green`](#green) -//// - [`dark_green`](#dark_green) -//// - [`light_blue`](#light_blue) -//// - [`blue`](#blue) -//// - [`dark_blue`](#dark_blue) -//// - [`light_purple`](#light_purple) -//// - [`purple`](#purple) -//// - [`dark_purple`](#dark_purple) -//// - [`light_brown`](#light_brown) -//// - [`brown`](#brown) -//// - [`dark_brown`](#dark_brown) -//// - [`black`](#black) -//// - [`white`](#white) -//// - [`light_grey`](#light_grey) -//// - [`grey`](#grey) -//// - [`dark_grey`](#dark_grey) -//// - [`light_gray`](#light_gray) -//// - [`gray`](#gray) -//// - [`dark_gray`](#dark_gray) -//// - [`light_charcoal`](#light_charcoal) -//// - [`charcoal`](#charcoal) -//// - [`dark_charcoal`](#dark_charcoal) -//// - [`pink`](#pink) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color` module. -//// The original source code can be found -//// <a href="https://github.com/avh4/elm-color/">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018 Aaron VonderHaar -//// -//// > Redistribution and use in source and binary forms, with or without modification, -//// are permitted provided that the following conditions are met: -//// -//// 1. Redistributions of source code must retain the above copyright notice, -//// this list of conditions and the following disclaimer. -//// -//// 2. Redistributions in binary form must reproduce the above copyright notice, -//// this list of conditions and the following disclaimer in the documentation -//// and/or other materials provided with the distribution. -//// -//// 3. Neither the name of the copyright holder nor the names of its contributors -//// may be used to endorse or promote products derived from this software without -//// specific prior written permission. -//// -//// > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -//// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -//// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -//// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -//// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -//// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color` module: -// -// https://github.com/avh4/elm-color/ -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/float -import gleam/result -import gleam/string -import gleam/list - -// TYPES ---------------------------------------------------------------------- - -/// A representation of a colour that can be converted to RGBA or HSLA format. -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub opaque type Colour { - Rgba(r: Float, g: Float, b: Float, a: Float) - Hsla(h: Float, s: Float, l: Float, a: Float) -} - -/// Type alias for `Colour` -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub type Color = - Colour - -// UTILITY -------------------------------------------------------------------- - -fn valid_colour_value(c: Float) -> Result(Float, Nil) { - case c >. 1.0 || c <. 0.0 { - True -> Error(Nil) - False -> Ok(c) - } -} - -fn hue_to_rgb(hue: Float, m1: Float, m2: Float) -> Float { - let h = case hue { - _ if hue <. 0.0 -> hue +. 1.0 - _ if hue >. 1.0 -> hue -. 1.0 - _ -> hue - } - - let h_t_6 = h *. 6.0 - let h_t_2 = h *. 2.0 - let h_t_3 = h *. 3.0 - - case h { - _ if h_t_6 <. 1.0 -> m1 +. { m2 -. m1 } *. h *. 6.0 - _ if h_t_2 <. 1.0 -> m2 - _ if h_t_3 <. 2.0 -> m1 +. { m2 -. m1 } *. { 2.0 /. 3.0 -. h } *. 6.0 - _ -> m1 - } -} - -fn hex_string_to_int(hex_string: String) -> Result(Int, Nil) { - let hex = case hex_string { - "#" <> hex_number -> hex_number - "0x" <> hex_number -> hex_number - _ -> hex_string - } - - hex - |> string.lowercase() - |> string.to_graphemes() - |> list.reverse() - |> list.index_fold( - Ok(0), - fn(total, char, index) { - case total { - Error(Nil) -> Error(Nil) - Ok(v) -> { - use num <- result.then(case char { - "a" -> Ok(10) - "b" -> Ok(11) - "c" -> Ok(12) - "d" -> Ok(13) - "e" -> Ok(14) - "f" -> Ok(15) - _ -> int.parse(char) - }) - use base <- result.then(int.power(16, int.to_float(index))) - Ok(v + float.round(int.to_float(num) *. base)) - } - } - }, - ) -} - -fn hsla_to_rgba( - h: Float, - s: Float, - l: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let m2 = case l <=. 0.5 { - True -> l *. { s +. 1.0 } - False -> l +. s -. l *. s - } - - let m1 = l *. 2.0 -. m2 - - let r = hue_to_rgb(h +. 1.0 /. 3.0, m1, m2) - let g = hue_to_rgb(h, m1, m2) - let b = hue_to_rgb(h -. 1.0 /. 3.0, m1, m2) - - #(r, g, b, a) -} - -fn rgba_to_hsla( - r: Float, - g: Float, - b: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let min_colour = float.min(r, float.min(g, b)) - - let max_colour = float.max(r, float.max(g, b)) - - let h1 = case True { - _ if max_colour == r -> float.divide(g -. b, max_colour -. min_colour) - _ if max_colour == g -> - float.divide(b -. r, max_colour -. min_colour) - |> result.then(fn(d) { Ok(2.0 +. d) }) - _ -> - float.divide(r -. g, max_colour -. min_colour) - |> result.then(fn(d) { Ok(4.0 +. d) }) - } - - let h2 = case h1 { - Ok(v) -> Ok(v *. { 1.0 /. 6.0 }) - _ -> h1 - } - - let h3 = case h2 { - Ok(v) if v <. 0.0 -> v +. 1.0 - Ok(v) -> v - _ -> 0.0 - } - - let l = { min_colour +. max_colour } /. 2.0 - - let s = case True { - _ if min_colour == max_colour -> 0.0 - _ if l <. 0.5 -> - { max_colour -. min_colour } /. { max_colour +. min_colour } - _ -> { max_colour -. min_colour } /. { 2.0 -. max_colour -. min_colour } - } - - #(h3, s, l, a) -} - -// CONSTRUCTORS --------------------------------------------------------------- - -/// Returns a `Result(Colour)` created from the given 8 bit RGB values. -/// -/// Returns `Error(Nil)` if the supplied RGB values are greater than 255 or less than 0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb255(r red: Int, g green: Int, b blue: Int) -> Result(Colour, Nil) { - use r <- result.then( - red - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use g <- result.then( - green - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use b <- result.then( - blue - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGB values. -/// -/// If the supplied RGB values are greater than 1.0 or less than 0.0 returns `Error(Nil)` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb(1.0, 0.0, 0.0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb( - r red: Float, - g green: Float, - b blue: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGBA values. -/// -/// Returns `Error(Nil)` if the supplied RGBA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rbga(1.0, 0.0, 0.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba( - r red: Float, - g green: Float, - b blue: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Rgba(r: r, g: g, b: b, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSLA values. -/// -/// Returns `Error(Nil)`f the supplied HSLA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_hsla(0.0, 1.0, 0.5, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsla( - h hue: Float, - s saturation: Float, - l lightness: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use h <- result.then(valid_colour_value(hue)) - use s <- result.then(valid_colour_value(saturation)) - use l <- result.then(valid_colour_value(lightness)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Hsla(h: h, s: s, l: l, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSL values. -/// -/// Returns `Error(Nil)` if the supplied HSL values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_hsla(0.0, 1.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsl( - h hue: Float, - s saturation: Float, - l lightness: Float, -) -> Result(Colour, Nil) { - from_hsla(hue, saturation, lightness, 1.0) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex(0xff0000) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffff || hex < 0 { - True -> Error(Nil) - False -> { - let r = - int.bitwise_shift_right(hex, 16) - |> int.bitwise_and(0xff) - let g = - int.bitwise_shift_right(hex, 8) - |> int.bitwise_and(0xff) - let b = int.bitwise_and(hex, 0xff) - from_rgb255(r, g, b) - } - } -} - -/// Returns a `Result(Colour)` created from the given RGB hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex_string("#ff0000") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgb_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given RGBA hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex_string("#ff00007f") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgba_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex(0xff00007f) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffffff || hex < 0 { - True -> Error(Nil) - False -> { - // This won't fail because we are always dividing by 255.0 - let assert Ok(r) = - int.bitwise_shift_right(hex, 24) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(g) = - int.bitwise_shift_right(hex, 16) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(b) = - int.bitwise_shift_right(hex, 8) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(a) = - int.bitwise_and(hex, 0xff) - |> int.to_float() - |> float.divide(255.0) - from_rgba(r, g, b, a) - } - } -} - -// CONVERSIONS ---------------------------------------------------------------- - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// R, G, B, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(r, g, b, a) = to_rgba(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Rgba(r, g, b, a) -> #(r, g, b, a) - Hsla(h, s, l, a) -> hsla_to_rgba(h, s, l, a) - } -} - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// H, S, L, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(h, s, l, a) = to_hsla(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_hsla(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Hsla(h, s, l, a) -> #(h, s, l, a) - Rgba(r, g, b, a) -> rgba_to_hsla(r, g, b, a) - } -} - -/// Returns an rgba formatted CSS `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let css_red = to_css_rgba_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_css_rgba_string(colour: Colour) -> String { - let #(r, g, b, a) = to_rgba(colour) - - let percent = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 100.0 - let assert Ok(p) = - x - |> float.multiply(10_000.0) - |> float.round() - |> int.to_float() - |> float.divide(100.0) - - p - } - - let round_to = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 1000.0 - let assert Ok(r) = - x - |> float.multiply(1000.0) - |> float.round() - |> int.to_float() - |> float.divide(1000.0) - - r - } - - string.join( - [ - "rgba(", - float.to_string(percent(r)) <> "%,", - float.to_string(percent(g)) <> "%,", - float.to_string(percent(b)) <> "%,", - float.to_string(round_to(a)), - ")", - ], - "", - ) -} - -/// Returns an rgba hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex = to_rgba_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex_string(colour: Colour) -> String { - to_rgba_hex(colour) - |> int.to_base16() -} - -/// Returns an rgb hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex = to_rgb_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex_string(colour: Colour) -> String { - to_rgb_hex(colour) - |> int.to_base16() -} - -/// Returns an hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex_int = to_rgba_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex(colour: Colour) -> Int { - let #(r, g, b, a) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> int.bitwise_shift_left(24) - - let green = - g *. 255.0 - |> float.round() - |> int.bitwise_shift_left(16) - - let blue = - b *. 255.0 - |> float.round() - |> int.bitwise_shift_left(8) - - let alpha = - a *. 255.0 - |> float.round() - - red + green + blue + alpha -} - -/// Returns a rgb hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex_int = to_rgb_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex(colour: Colour) -> Int { - let #(r, g, b, _) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> int.bitwise_shift_left(16) - - let green = - g *. 255.0 - |> float.round() - |> int.bitwise_shift_left(8) - - let blue = - b *. 255.0 - |> float.round() - - red + green + blue -} - -// COLOURS -------------------------------------------------------------------- - -/// A `Colour` reprsenting the colour RGBA(239, 41, 41, 1.0) -pub const light_red = Rgba( - r: 0.9372549019607843, - g: 0.1607843137254902, - b: 0.1607843137254902, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(204, 0, 0, 1.0) -pub const red = Rgba(r: 0.8, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(164, 0, 0, 1.0) -pub const dark_red = Rgba(r: 0.6431372549019608, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(252, 175, 62, 1.0) -pub const light_orange = Rgba( - r: 0.9882352941176471, - g: 0.6862745098039216, - b: 0.24313725490196078, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(245, 121, 0, 1.0) -pub const orange = Rgba( - r: 0.9607843137254902, - g: 0.4745098039215686, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(206, 92, 0, 1.0) -pub const dark_orange = Rgba( - r: 0.807843137254902, - g: 0.3607843137254902, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 233, 79, 1.0) -pub const light_yellow = Rgba( - r: 1.0, - g: 0.9137254901960784, - b: 0.30980392156862746, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(237, 212, 0, 1.0) -pub const yellow = Rgba( - r: 0.9294117647058824, - g: 0.8313725490196079, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(196, 160, 0, 1.0) -pub const dark_yellow = Rgba( - r: 0.7686274509803922, - g: 0.6274509803921569, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(138, 226, 52, 1.0) -pub const light_green = Rgba( - r: 0.5411764705882353, - g: 0.8862745098039215, - b: 0.20392156862745098, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(115, 210, 22, 1.0) -pub const green = Rgba( - r: 0.45098039215686275, - g: 0.8235294117647058, - b: 0.08627450980392157, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(78, 154, 6, 1.0) -pub const dark_green = Rgba( - r: 0.3058823529411765, - g: 0.6039215686274509, - b: 0.023529411764705882, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(114, 159, 207, 1.0) -pub const light_blue = Rgba( - r: 0.4470588235294118, - g: 0.6235294117647059, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(52, 101, 164, 1.0) -pub const blue = Rgba( - r: 0.20392156862745098, - g: 0.396078431372549, - b: 0.6431372549019608, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(32, 74, 135, 1.0) -pub const dark_blue = Rgba( - r: 0.12549019607843137, - g: 0.2901960784313726, - b: 0.5294117647058824, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(173, 127, 168, 1.0) -pub const light_purple = Rgba( - r: 0.6784313725490196, - g: 0.4980392156862745, - b: 0.6588235294117647, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(117, 80, 123, 1.0) -pub const purple = Rgba( - r: 0.4588235294117647, - g: 0.3137254901960784, - b: 0.4823529411764706, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(92, 53, 102, 1.0) -pub const dark_purple = Rgba( - r: 0.3607843137254902, - g: 0.20784313725490197, - b: 0.4, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(233, 185, 110, 1.0) -pub const light_brown = Rgba( - r: 0.9137254901960784, - g: 0.7254901960784313, - b: 0.43137254901960786, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(193, 125, 17, 1.0) -pub const brown = Rgba( - r: 0.7568627450980392, - g: 0.49019607843137253, - b: 0.06666666666666667, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(143, 89, 2, 1.0) -pub const dark_brown = Rgba( - r: 0.5607843137254902, - g: 0.34901960784313724, - b: 0.00784313725490196, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(0, 0, 0, 1.0) -pub const black = Rgba(r: 0.0, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(255, 255, 255, 1.0) -pub const white = Rgba(r: 1.0, g: 1.0, b: 1.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_grey = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const grey = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_grey = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_gray = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const gray = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_gray = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(136, 138, 133, 1.0) -pub const light_charcoal = Rgba( - r: 0.5333333333333333, - g: 0.5411764705882353, - b: 0.5215686274509804, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(85, 87, 83, 1.0) -pub const charcoal = Rgba( - r: 0.3333333333333333, - g: 0.3411764705882353, - b: 0.3254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(46, 52, 54, 1.0) -pub const dark_charcoal = Rgba( - r: 0.1803921568627451, - g: 0.20392156862745098, - b: 0.21176470588235294, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 175, 243, 1.0) -pub const pink = Rgba( - r: 1.0, - g: 0.6862745098039216, - b: 0.9529411764705882, - a: 1.0, -) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam deleted file mode 100644 index 54f75e4d469..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam +++ /dev/null @@ -1,173 +0,0 @@ -//// -//// - **Accessibility** -//// - [`luminance`](#luminance) -//// - [`contrast_ratio`](#contrast_ratio) -//// - [`maximum_contrast`](#maximum_contrast) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color-extra` module. -//// The original source code can be found -//// <a href="https://github.com/noahzgordon/elm-color-extra">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright (c) 2016 Andreas Köberle -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// -//// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -//// SOFTWARE. -//// -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color-extra` module: -// -// https://github.com/noahzgordon/elm-color-extra -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/float -import gleam/list -import gleam_community/colour.{type Colour} - -// UTILITIES ------------------------------------------------------------------ - -fn intensity(colour_value: Float) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - case True { - _ if colour_value <=. 0.03928 -> colour_value /. 12.92 - _ -> { - // Is this guaranteed to be `OK`? - let assert Ok(i) = float.power({ colour_value +. 0.055 } /. 1.055, 2.4) - i - } - } -} - -// ACCESSIBILITY -------------------------------------------------------------- - -/// Returns the relative brightness of the given `Colour` as a `Float` between -/// 0.0, and 1.0 with 0.0 being the darkest possible colour and 1.0 being the lightest. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// luminance(colour.white) // 1.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn luminance(colour: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - let #(r, g, b, _) = colour.to_rgba(colour) - - let r_intensity = intensity(r) - let g_intensity = intensity(g) - let b_intensity = intensity(b) - - 0.2126 *. r_intensity +. 0.7152 *. g_intensity +. 0.0722 *. b_intensity -} - -/// Returns the contrast between two `Colour` values as a `Float` between 1.0, -/// and 21.0 with 1.0 being no contrast and, 21.0 being the highest possible contrast. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// contrast_ratio(between: colour.white, and: colour.black) // 21.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn contrast_ratio(between colour_a: Colour, and colour_b: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#contrast-ratiodef - let luminance_a = luminance(colour_a) +. 0.05 - let luminance_b = luminance(colour_b) +. 0.05 - - case luminance_a >. luminance_b { - True -> luminance_a /. luminance_b - False -> luminance_b /. luminance_a - } -} - -/// Returns the `Colour` with the highest contrast between the base `Colour`, -/// and and the other provided `Colour` values. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// maximum_contrast( -/// colour.yellow, -/// [colour.white, colour.dark_blue, colour.green], -/// ) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn maximum_contrast( - base: Colour, - colours: List(Colour), -) -> Result(Colour, Nil) { - colours - |> list.sort(fn(colour_a, colour_b) { - let contrast_a = contrast_ratio(base, colour_a) - let contrast_b = contrast_ratio(base, colour_b) - - float.compare(contrast_b, contrast_a) - }) - |> list.first() -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl deleted file mode 100644 index 21e4c819749..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour.erl +++ /dev/null @@ -1,511 +0,0 @@ --module(gleam_community@colour). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_rgb255/3, from_rgb/3, from_rgba/4, from_hsla/4, from_hsl/3, from_rgb_hex/1, from_rgb_hex_string/1, from_rgba_hex/1, from_rgba_hex_string/1, to_rgba/1, to_hsla/1, to_css_rgba_string/1, to_rgba_hex/1, to_rgba_hex_string/1, to_rgb_hex/1, to_rgb_hex_string/1]). --export_type([colour/0]). - --opaque colour() :: {rgba, float(), float(), float(), float()} | - {hsla, float(), float(), float(), float()}. - --spec valid_colour_value(float()) -> {ok, float()} | {error, nil}. -valid_colour_value(C) -> - case (C > 1.0) orelse (C < +0.0) of - true -> - {error, nil}; - - false -> - {ok, C} - end. - --spec hue_to_rgb(float(), float(), float()) -> float(). -hue_to_rgb(Hue, M1, M2) -> - H = case Hue of - _ when Hue < +0.0 -> - Hue + 1.0; - - _ when Hue > 1.0 -> - Hue - 1.0; - - _ -> - Hue - end, - H_t_6 = H * 6.0, - H_t_2 = H * 2.0, - H_t_3 = H * 3.0, - case H of - _ when H_t_6 < 1.0 -> - M1 + (((M2 - M1) * H) * 6.0); - - _ when H_t_2 < 1.0 -> - M2; - - _ when H_t_3 < 2.0 -> - M1 + (((M2 - M1) * ((2.0 / 3.0) - H)) * 6.0); - - _ -> - M1 - end. - --spec hex_string_to_int(binary()) -> {ok, integer()} | {error, nil}. -hex_string_to_int(Hex_string) -> - Hex = case Hex_string of - <<"#"/utf8, Hex_number/binary>> -> - Hex_number; - - <<"0x"/utf8, Hex_number@1/binary>> -> - Hex_number@1; - - _ -> - Hex_string - end, - _pipe = Hex, - _pipe@1 = gleam@string:lowercase(_pipe), - _pipe@2 = gleam@string:to_graphemes(_pipe@1), - _pipe@3 = gleam@list:reverse(_pipe@2), - gleam@list:index_fold( - _pipe@3, - {ok, 0}, - fun(Total, Char, Index) -> case Total of - {error, nil} -> - {error, nil}; - - {ok, V} -> - gleam@result:then(case Char of - <<"a"/utf8>> -> - {ok, 10}; - - <<"b"/utf8>> -> - {ok, 11}; - - <<"c"/utf8>> -> - {ok, 12}; - - <<"d"/utf8>> -> - {ok, 13}; - - <<"e"/utf8>> -> - {ok, 14}; - - <<"f"/utf8>> -> - {ok, 15}; - - _ -> - gleam@int:parse(Char) - end, fun(Num) -> - gleam@result:then( - gleam@int:power(16, gleam@int:to_float(Index)), - fun(Base) -> - {ok, - V + gleam@float:round( - gleam@int:to_float(Num) * Base - )} - end - ) - end) - end end - ). - --spec hsla_to_rgba(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -hsla_to_rgba(H, S, L, A) -> - M2 = case L =< 0.5 of - true -> - L * (S + 1.0); - - false -> - (L + S) - (L * S) - end, - M1 = (L * 2.0) - M2, - R = hue_to_rgb(H + (1.0 / 3.0), M1, M2), - G = hue_to_rgb(H, M1, M2), - B = hue_to_rgb(H - (1.0 / 3.0), M1, M2), - {R, G, B, A}. - --spec rgba_to_hsla(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -rgba_to_hsla(R, G, B, A) -> - Min_colour = gleam@float:min(R, gleam@float:min(G, B)), - Max_colour = gleam@float:max(R, gleam@float:max(G, B)), - H1 = case true of - _ when Max_colour =:= R -> - gleam@float:divide(G - B, Max_colour - Min_colour); - - _ when Max_colour =:= G -> - _pipe = gleam@float:divide(B - R, Max_colour - Min_colour), - gleam@result:then(_pipe, fun(D) -> {ok, 2.0 + D} end); - - _ -> - _pipe@1 = gleam@float:divide(R - G, Max_colour - Min_colour), - gleam@result:then(_pipe@1, fun(D@1) -> {ok, 4.0 + D@1} end) - end, - H2 = case H1 of - {ok, V} -> - {ok, V * (1.0 / 6.0)}; - - _ -> - H1 - end, - H3 = case H2 of - {ok, V@1} when V@1 < +0.0 -> - V@1 + 1.0; - - {ok, V@2} -> - V@2; - - _ -> - +0.0 - end, - L = (Min_colour + Max_colour) / 2.0, - S = case true of - _ when Min_colour =:= Max_colour -> - +0.0; - - _ when L < 0.5 -> - case (Max_colour + Min_colour) of - 0.0 -> 0.0; - Gleam@denominator -> (Max_colour - Min_colour) / Gleam@denominator - end; - - _ -> - case ((2.0 - Max_colour) - Min_colour) of - 0.0 -> 0.0; - Gleam@denominator@1 -> (Max_colour - Min_colour) / Gleam@denominator@1 - end - end, - {H3, S, L, A}. - --spec from_rgb255(integer(), integer(), integer()) -> {ok, colour()} | - {error, nil}. -from_rgb255(Red, Green, Blue) -> - gleam@result:then( - begin - _pipe = Red, - _pipe@1 = gleam@int:to_float(_pipe), - _pipe@2 = gleam@float:divide(_pipe@1, 255.0), - gleam@result:then(_pipe@2, fun valid_colour_value/1) - end, - fun(R) -> - gleam@result:then( - begin - _pipe@3 = Green, - _pipe@4 = gleam@int:to_float(_pipe@3), - _pipe@5 = gleam@float:divide(_pipe@4, 255.0), - gleam@result:then(_pipe@5, fun valid_colour_value/1) - end, - fun(G) -> - gleam@result:then( - begin - _pipe@6 = Blue, - _pipe@7 = gleam@int:to_float(_pipe@6), - _pipe@8 = gleam@float:divide(_pipe@7, 255.0), - gleam@result:then(_pipe@8, fun valid_colour_value/1) - end, - fun(B) -> {ok, {rgba, R, G, B, 1.0}} end - ) - end - ) - end - ). - --spec from_rgb(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_rgb(Red, Green, Blue) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> {ok, {rgba, R, G, B, 1.0}} end - ) - end - ) - end - ). - --spec from_rgba(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_rgba(Red, Green, Blue, Alpha) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> {ok, {rgba, R, G, B, A}} end - ) - end - ) - end - ) - end - ). - --spec from_hsla(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_hsla(Hue, Saturation, Lightness, Alpha) -> - gleam@result:then( - valid_colour_value(Hue), - fun(H) -> - gleam@result:then( - valid_colour_value(Saturation), - fun(S) -> - gleam@result:then( - valid_colour_value(Lightness), - fun(L) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> {ok, {hsla, H, S, L, A}} end - ) - end - ) - end - ) - end - ). - --spec from_hsl(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_hsl(Hue, Saturation, Lightness) -> - from_hsla(Hue, Saturation, Lightness, 1.0). - --spec from_rgb_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgb_hex(Hex) -> - case (Hex > 16#ffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - R = begin - _pipe = erlang:'bsr'(Hex, 16), - erlang:'band'(_pipe, 16#ff) - end, - G = begin - _pipe@1 = erlang:'bsr'(Hex, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - B = erlang:'band'(Hex, 16#ff), - from_rgb255(R, G, B) - end. - --spec from_rgb_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgb_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> from_rgb_hex(Hex_int) end - ). - --spec from_rgba_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgba_hex(Hex) -> - case (Hex > 16#ffffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - _assert_subject = begin - _pipe = erlang:'bsr'(Hex, 24), - _pipe@1 = erlang:'band'(_pipe, 16#ff), - _pipe@2 = gleam@int:to_float(_pipe@1), - gleam@float:divide(_pipe@2, 255.0) - end, - {ok, R} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 588}) - end, - _assert_subject@1 = begin - _pipe@3 = erlang:'bsr'(Hex, 16), - _pipe@4 = erlang:'band'(_pipe@3, 16#ff), - _pipe@5 = gleam@int:to_float(_pipe@4), - gleam@float:divide(_pipe@5, 255.0) - end, - {ok, G} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 594}) - end, - _assert_subject@2 = begin - _pipe@6 = erlang:'bsr'(Hex, 8), - _pipe@7 = erlang:'band'(_pipe@6, 16#ff), - _pipe@8 = gleam@int:to_float(_pipe@7), - gleam@float:divide(_pipe@8, 255.0) - end, - {ok, B} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 600}) - end, - _assert_subject@3 = begin - _pipe@9 = erlang:'band'(Hex, 16#ff), - _pipe@10 = gleam@int:to_float(_pipe@9), - gleam@float:divide(_pipe@10, 255.0) - end, - {ok, A} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 606}) - end, - from_rgba(R, G, B, A) - end. - --spec from_rgba_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgba_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> from_rgba_hex(Hex_int) end - ). - --spec to_rgba(colour()) -> {float(), float(), float(), float()}. -to_rgba(Colour) -> - case Colour of - {rgba, R, G, B, A} -> - {R, G, B, A}; - - {hsla, H, S, L, A@1} -> - hsla_to_rgba(H, S, L, A@1) - end. - --spec to_hsla(colour()) -> {float(), float(), float(), float()}. -to_hsla(Colour) -> - case Colour of - {hsla, H, S, L, A} -> - {H, S, L, A}; - - {rgba, R, G, B, A@1} -> - rgba_to_hsla(R, G, B, A@1) - end. - --spec to_css_rgba_string(colour()) -> binary(). -to_css_rgba_string(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Percent = fun(X) -> - _assert_subject = begin - _pipe = X, - _pipe@1 = gleam@float:multiply(_pipe, 10000.0), - _pipe@2 = gleam@float:round(_pipe@1), - _pipe@3 = gleam@int:to_float(_pipe@2), - gleam@float:divide(_pipe@3, 100.0) - end, - {ok, P} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 704}) - end, - P - end, - Round_to = fun(X@1) -> - _assert_subject@1 = begin - _pipe@4 = X@1, - _pipe@5 = gleam@float:multiply(_pipe@4, 1000.0), - _pipe@6 = gleam@float:round(_pipe@5), - _pipe@7 = gleam@int:to_float(_pipe@6), - gleam@float:divide(_pipe@7, 1000.0) - end, - {ok, R@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 716}) - end, - R@1 - end, - gleam@string:join( - [<<"rgba("/utf8>>, - <<(gleam@float:to_string(Percent(R)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(G)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(B)))/binary, "%,"/utf8>>, - gleam@float:to_string(Round_to(A)), - <<")"/utf8>>], - <<""/utf8>> - ). - --spec to_rgba_hex(colour()) -> integer(). -to_rgba_hex(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - erlang:'bsl'(_pipe@1, 24) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - erlang:'bsl'(_pipe@3, 16) - end, - Blue = begin - _pipe@4 = B * 255.0, - _pipe@5 = gleam@float:round(_pipe@4), - erlang:'bsl'(_pipe@5, 8) - end, - Alpha = begin - _pipe@6 = A * 255.0, - gleam@float:round(_pipe@6) - end, - ((Red + Green) + Blue) + Alpha. - --spec to_rgba_hex_string(colour()) -> binary(). -to_rgba_hex_string(Colour) -> - _pipe = to_rgba_hex(Colour), - gleam@int:to_base16(_pipe). - --spec to_rgb_hex(colour()) -> integer(). -to_rgb_hex(Colour) -> - {R, G, B, _} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - erlang:'bsl'(_pipe@1, 16) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - erlang:'bsl'(_pipe@3, 8) - end, - Blue = begin - _pipe@4 = B * 255.0, - gleam@float:round(_pipe@4) - end, - (Red + Green) + Blue. - --spec to_rgb_hex_string(colour()) -> binary(). -to_rgb_hex_string(Colour) -> - _pipe = to_rgb_hex(Colour), - gleam@int:to_base16(_pipe). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl deleted file mode 100644 index 64d37bf2eb3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl +++ /dev/null @@ -1,73 +0,0 @@ --module(gleam_community@colour@accessibility). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([luminance/1, contrast_ratio/2, maximum_contrast/2]). - --spec intensity(float()) -> float(). -intensity(Colour_value) -> - case true of - _ when Colour_value =< 0.03928 -> - Colour_value / 12.92; - - _ -> - _assert_subject = gleam@float:power( - (Colour_value + 0.055) / 1.055, - 2.4 - ), - {ok, I} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour/accessibility"/utf8>>, - function => <<"intensity"/utf8>>, - line => 62}) - end, - I - end. - --spec luminance(gleam_community@colour:colour()) -> float(). -luminance(Colour) -> - {R, G, B, _} = gleam_community@colour:to_rgba(Colour), - R_intensity = intensity(R), - G_intensity = intensity(G), - B_intensity = intensity(B), - ((0.2126 * R_intensity) + (0.7152 * G_intensity)) + (0.0722 * B_intensity). - --spec contrast_ratio( - gleam_community@colour:colour(), - gleam_community@colour:colour() -) -> float(). -contrast_ratio(Colour_a, Colour_b) -> - Luminance_a = luminance(Colour_a) + 0.05, - Luminance_b = luminance(Colour_b) + 0.05, - case Luminance_a > Luminance_b of - true -> - case Luminance_b of - 0.0 -> 0.0; - Gleam@denominator -> Luminance_a / Gleam@denominator - end; - - false -> - case Luminance_a of - 0.0 -> 0.0; - Gleam@denominator@1 -> Luminance_b / Gleam@denominator@1 - end - end. - --spec maximum_contrast( - gleam_community@colour:colour(), - list(gleam_community@colour:colour()) -) -> {ok, gleam_community@colour:colour()} | {error, nil}. -maximum_contrast(Base, Colours) -> - _pipe = Colours, - _pipe@1 = gleam@list:sort( - _pipe, - fun(Colour_a, Colour_b) -> - Contrast_a = contrast_ratio(Base, Colour_a), - Contrast_b = contrast_ratio(Base, Colour_b), - gleam@float:compare(Contrast_b, Contrast_a) - end - ), - gleam@list:first(_pipe@1). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src deleted file mode 100644 index a32765072fc..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_community_colour/src/gleam_community_colour.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_community_colour, [ - {vsn, "1.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Colour types, conversions, and other utilities"}, - {modules, [gleam_community@colour, - gleam_community@colour@accessibility]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE deleted file mode 100644 index 59e1345ab47..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md deleted file mode 100644 index ffee4cd751f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Gleam Erlang 🐙 - -A library for making use of Erlang specific code! - -## Features - -- Typed Erlang processes and message sending. -- Erlang binary format (de)serialisation. -- Functions for working with Erlang's charlists. -- Reading, writing, and deletion of files. -- Basic distributed Erlang support and working with nodes. -- Reading and writing of environment variables. -- Functions for working with atoms. - -## Usage - -Add this library to your Gleam project - -```shell -gleam add gleam_erlang -``` - -And then use it in your code - -```gleam -import gleam/io -import gleam/erlang/file - -pub fn main() { - assert Ok(contents) = file.read("pokedex.txt") - io.println(contents) -} -``` - -Documentation can be found at <https://hexdocs.pm/gleam_erlang/>. - -This library requires OTP 23.0 or higher. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml deleted file mode 100644 index 8d626035c25..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/gleam.toml +++ /dev/null @@ -1,18 +0,0 @@ -name = "gleam_erlang" - -version = "0.23.1" -licences = ["Apache-2.0"] -description = "A Gleam library for working with Erlang" - -repository = { type = "github", user = "gleam-lang", repo = "erlang" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl deleted file mode 100644 index b38d11e0f65..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl +++ /dev/null @@ -1,15 +0,0 @@ --record(file_info, { - size :: integer(), - file_type :: gleam@erlang@file:file_type(), - access :: gleam@erlang@file:access(), - atime :: integer(), - mtime :: integer(), - ctime :: integer(), - mode :: integer(), - links :: integer(), - major_device :: integer(), - minor_device :: integer(), - inode :: integer(), - user_id :: integer(), - group_id :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl deleted file mode 100644 index 4cd04529eb4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl +++ /dev/null @@ -1 +0,0 @@ --record(abnormal, {reason :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl deleted file mode 100644 index 5dd504715a5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl +++ /dev/null @@ -1 +0,0 @@ --record(callee_down, {reason :: gleam@dynamic:dynamic_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl deleted file mode 100644 index b82b49fc597..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl +++ /dev/null @@ -1 +0,0 @@ --record(cancelled, {time_remaining :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl deleted file mode 100644 index c476308c591..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(exit_message, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@erlang@process:exit_reason() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl deleted file mode 100644 index df0b6b7793b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(process_down, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@dynamic:dynamic_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl deleted file mode 100644 index ce552e209e6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl +++ /dev/null @@ -1 +0,0 @@ --record(process_monitor, {tag :: gleam@erlang:reference_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl deleted file mode 100644 index abc46b2ecd4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(subject, { - owner :: gleam@erlang@process:pid_(), - tag :: gleam@erlang:reference_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl deleted file mode 100644 index 52c9896ede4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(application_failed_to_start, { - name :: gleam@erlang@atom:atom_(), - reason :: gleam@dynamic:dynamic_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl deleted file mode 100644 index fde3c61706e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unknown_application, {name :: gleam@erlang@atom:atom_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam deleted file mode 100644 index 783cd537232..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang.gleam +++ /dev/null @@ -1,158 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/list -import gleam/erlang/atom.{type Atom} -import gleam/erlang/charlist.{type Charlist} - -@external(erlang, "io_lib", "format") -fn erl_format(a: String, b: List(a)) -> Charlist - -/// Return a string representation of any term -pub fn format(term: any) -> String { - charlist.to_string(erl_format("~p", [term])) -} - -@external(erlang, "erlang", "term_to_binary") -pub fn term_to_binary(a: a) -> BitArray - -type Safe { - Safe -} - -@external(erlang, "erlang", "binary_to_term") -fn erl_binary_to_term(a: BitArray, b: List(Safe)) -> Dynamic - -pub fn binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, [Safe]) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -pub fn unsafe_binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, []) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -/// Error value returned by `get_line` function -/// -pub type GetLineError { - Eof - NoData -} - -/// Reads a line from standard input with the given prompt. -/// -/// # Example -/// -/// > get_line("Language: ") -/// // -> Language: <- gleam -/// Ok("gleam\n") -/// -@external(erlang, "gleam_erlang_ffi", "get_line") -pub fn get_line(prompt prompt: String) -> Result(String, GetLineError) - -pub type TimeUnit { - Second - Millisecond - Microsecond - Nanosecond -} - -/// Returns the current OS system time. -/// -/// <https://erlang.org/doc/apps/erts/time_correction.html#OS_System_Time> -@external(erlang, "os", "system_time") -pub fn system_time(a: TimeUnit) -> Int - -/// Returns the current OS system time as a tuple of Ints -/// -/// http://erlang.org/doc/man/os.html#timestamp-0 -@external(erlang, "os", "timestamp") -pub fn erlang_timestamp() -> #(Int, Int, Int) - -/// Gleam doesn't offer any way to raise exceptions, but they may still occur -/// due to bugs when working with unsafe code, such as when calling Erlang -/// function. -/// -/// This function will catch any error thrown and convert it into a result -/// rather than crashing the process. -/// -@external(erlang, "gleam_erlang_ffi", "rescue") -pub fn rescue(a: fn() -> a) -> Result(a, Crash) - -pub type Crash { - Exited(Dynamic) - Thrown(Dynamic) - Errored(Dynamic) -} - -@external(erlang, "init", "get_plain_arguments") -fn get_start_arguments() -> List(Charlist) - -/// Get the arguments given to the program when it was started. -/// -/// This is sometimes called `argv` in other languages. -pub fn start_arguments() -> List(String) { - get_start_arguments() - |> list.map(charlist.to_string) -} - -/// Starts an OTP application's process tree in the background, as well as -/// the trees of any applications that the given application depends upon. An -/// OTP application typically maps onto a Gleam or Hex package. -/// -/// Returns a list of the applications that were started. Calling this function -/// for application that have already been started is a no-op so you do not need -/// to check the application state beforehand. -/// -/// In Gleam we prefer to not use these implicit background process trees, but -/// you will likely still need to start the trees of OTP applications written in -/// other BEAM languages such as Erlang or Elixir, including those included by -/// default with Erlang/OTP. -/// -/// For more information see the OTP documentation. -/// - <https://www.erlang.org/doc/man/application.html#ensure_all_started-1> -/// - <https://www.erlang.org/doc/man/application.html#start-1> -/// -@external(erlang, "gleam_erlang_ffi", "ensure_all_started") -pub fn ensure_all_started( - application application: Atom, -) -> Result(List(Atom), EnsureAllStartedError) - -pub type EnsureAllStartedError { - UnknownApplication(name: Atom) - ApplicationFailedToStart(name: Atom, reason: Dynamic) -} - -/// A unique reference value. -/// -/// It holds no particular meaning or value, but unique values are often useful -/// in programs are used heavily within both Gleam and Erlang's OTP frameworks. -/// -/// More can be read about references in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/efficiency_guide/advanced.html#unique_references -/// -pub type Reference - -/// Create a new unique reference. -/// -@external(erlang, "erlang", "make_ref") -pub fn make_reference() -> Reference - -/// Returns the path of a package's `priv` directory, where extra non-Gleam -/// or Erlang files are typically kept. -/// -/// Returns an error if no package was found with the given name. -/// -/// # Example -/// -/// ```gleam -/// > erlang.priv_directory("my_app") -/// // -> Ok("/some/location/my_app/priv") -/// ``` -/// -@external(erlang, "gleam_erlang_ffi", "priv_directory") -pub fn priv_directory(name: String) -> Result(String, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam deleted file mode 100644 index a27289c112c..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam +++ /dev/null @@ -1,79 +0,0 @@ -import gleam/dynamic.{type DecodeErrors, type Dynamic} - -/// Atom is a special string-like data-type that is most commonly used for -/// interfacing with code written in other BEAM languages such as Erlang and -/// Elixir. It is preferable to define your own custom types to use instead of -/// atoms where possible. -/// -/// Atoms are not used much in typical Gleam code! -/// -/// ## Creating atoms -/// -/// We can create atoms with the the [`create_from_string`](#create_from_string) -/// function, though we must be careful when doing so as atoms are never -/// garbage collected. If we create too many atoms (for example, if we convert -/// user input into atoms) we may hit the max limit of atoms and cause the -/// virtual machine to crash. -/// -pub type Atom - -/// An error returned when no atom is found in the virtual machine's atom table -/// for a given string when calling the [`from_string`](#from_string) function. -pub type FromStringError { - AtomNotLoaded -} - -/// Finds an existing Atom for the given String. -/// -/// If no atom is found in the virtual machine's atom table for the String then -/// an error is returned. -/// -/// ## Examples -/// -/// > from_string("ok") -/// Ok(create_from_string("ok")) -/// -/// > from_string("some_new_atom") -/// Error(AtomNotLoaded) -/// -@external(erlang, "gleam_erlang_ffi", "atom_from_string") -pub fn from_string(a: String) -> Result(Atom, FromStringError) - -/// Creates an atom from a string, inserting a new value into the virtual -/// machine's atom table if an atom does not already exist for the given -/// string. -/// -/// We must be careful when using this function as there is a limit to the -/// number of atom that can fit in the virtual machine's atom table. Never -/// convert user input into atoms as filling the atom table will cause the -/// virtual machine to crash! -/// -@external(erlang, "erlang", "binary_to_atom") -pub fn create_from_string(a: String) -> Atom - -/// Returns a `String` corresponding to the text representation of the given -/// `Atom`. -/// -/// ## Examples -/// -/// > let ok_atom = create_from_string("ok") -/// > to_string(ok_atom) -/// "ok" -/// -@external(erlang, "erlang", "atom_to_binary") -pub fn to_string(a: Atom) -> String - -/// Checks to see whether a `Dynamic` value is an atom, and return the atom if -/// it is. -/// -/// ## Examples -/// -/// > import gleam/dynamic -/// > from_dynamic(dynamic.from(create_from_string("hello"))) -/// Ok(create_from_string("hello")) -/// -/// > from_dynamic(dynamic.from(123)) -/// Error([DecodeError(expected: "Atom", found: "Int", path: [])]) -/// -@external(erlang, "gleam_erlang_ffi", "atom_from_dynamic") -pub fn from_dynamic(from from: Dynamic) -> Result(Atom, DecodeErrors) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam deleted file mode 100644 index e5b6d65f6b2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam +++ /dev/null @@ -1,25 +0,0 @@ -//// A charlist is a list of integers where all the integers are valid code -//// points. -//// -//// In practice, you will not come across them often, except perhaps when -//// interfacing with Erlang, in particular when using older libraries that do -//// not accept binaries as arguments. - -/// A list of characters represented as ints. Commonly used by older Erlang -/// modules. -pub type Charlist - -/// Transform a charlist to a string -@external(erlang, "unicode", "characters_to_binary") -pub fn to_string(a: Charlist) -> String - -// Calls `unicode:characters_to_binary(Data, unicode, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_binary-1> - -/// Transform a string to a charlist -@external(erlang, "unicode", "characters_to_list") -pub fn from_string(a: String) -> Charlist -// Calls `unicode:characters_to_list(Data, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_list-1> diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam deleted file mode 100644 index 48e11a7ad80..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/file.gleam +++ /dev/null @@ -1,737 +0,0 @@ -//// Working with files on the filesystem. -//// -//// The functions included in this module are for high-level concepts such as -//// reading and writing. - -import gleam/bit_array -import gleam/result - -/// Reason represents all of the reasons that Erlang surfaces of why a file -/// system operation could fail. Most of these reasons are POSIX errors, which -/// come from the operating system and start with `E`. Others have been added to -/// represent other issues that may arise. -pub type Reason { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 -} - -/// The type of file found by `file_info` or `link_info`. -/// -pub type FileType { - Device - Directory - Other - Regular - Symlink -} - -/// The read/write permissions a user can have for a file. -/// -pub type Access { - NoAccess - Read - ReadWrite - Write -} - -/// Meta information for a file. -/// -/// Timestamps are in seconds before or after the Unix time epoch, -/// `1970-01-01 00:00:00 UTC`. -/// -pub type FileInfo { - FileInfo( - /// File size in bytes. - /// - size: Int, - /// `Regular`, `Directory`, `Symlink`, `Device`, or `Other`. - /// - file_type: FileType, - /// `ReadWrite`, `Read`, `Write`, or `NoAccess`. - /// - access: Access, - /// Timestamp of most recent access. - /// - atime: Int, - /// Timestamp of most recent modification. - /// - mtime: Int, - /// Timestamp of most recent change (or file creation, depending on - /// operating system). - /// - ctime: Int, - /// File permissions encoded as a sum of bit values, including but not - /// limited to: - /// - /// Owner read, write, execute. - /// - /// `0o400`, `0o200`, `0o100` - /// - /// Group read, write, execute. - /// - /// `0o40`, `0o20`, `0o10` - /// - /// Other read, write, execute. - /// - /// `0o4`, `0o2`, `0o1` - /// - /// Set user ID, group ID on execution. - /// - /// `0x800`, `0x400` - /// - mode: Int, - /// Total links to a file (always `1` for file systems without links). - /// - links: Int, - /// The file system where a file is located (`0` for drive `A:` on Windows, - /// `1` for `B:`, etc.). - /// - major_device: Int, - /// Character device (or `0` on non-Unix systems). - /// - minor_device: Int, - /// The `inode` number for a file (always `0` on non-Unix file systems). - /// - inode: Int, - /// The owner of a file (always `0` on non-Unix file systems). - /// - user_id: Int, - /// The group id of a file (always `0` on non-Unix file systems). - /// - group_id: Int, - ) -} - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To get `FileInfo` about a symlink itself, use `link_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > file_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 140, -/// file_type: Directory, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/does_not_exist") -/// Error(Enoent) -/// -/// > file_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn file_info(a: String) -> Result(FileInfo, Reason) { - do_file_info(a) -} - -@external(erlang, "gleam_erlang_ffi", "file_info") -fn do_file_info(a: String) -> Result(FileInfo, Reason) - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To get `FileInfo` about a symlink's target, use `file_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > link_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 41, -/// file_type: Symlink, -/// access: ReadWrite, -/// atime: 1680581150, -/// mtime: 1680581150, -/// ctime: 1680581150, -/// mode: 41471, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 471587, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/does_not_exist") -/// Error(Enoent) -/// -/// > link_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn link_info(a: String) -> Result(FileInfo, Reason) { - do_link_info(a) -} - -@external(erlang, "gleam_erlang_ffi", "link_info") -fn do_link_info(a: String) -> Result(FileInfo, Reason) - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Directory` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_directory("/tmp") -/// Ok(True) -/// -/// > is_directory("resume.pdf") -/// Ok(False) -/// -/// > is_directory("/does_not_exist") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn is_directory(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) - file_type == Directory -} - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Regular` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_regular("resume.pdf") -/// Ok(True) -/// -/// > is_regular("/tmp") -/// Ok(False) -/// -/// > is_regular("/does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn is_regular(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) - file_type == Regular -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To find whether a symlink itself exists, use `link_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_exists("resume.pdf") -/// Ok(True) -/// -/// > file_exists("/tmp") -/// Ok(True) -/// -/// > file_exists("/does_not_exist") -/// Ok(False) -/// -/// > file_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn file_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> do_file_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To find whether a symlink's target exists, use `file_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_exists("resume.pdf") -/// Ok(True) -/// -/// > link_exists("/tmp") -/// Ok(True) -/// -/// > link_exists("/does_not_exist") -/// Ok(False) -/// -/// > link_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn link_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> do_link_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Tries to create a directory. Missing parent directories are not created. -/// -/// Returns a Result of nil if the directory is created or Reason if the -/// operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > make_directory("/tmp/foo") -/// Ok(Nil) -/// -/// > make_directory("relative_directory") -/// Ok(Nil) -/// -/// > make_directory("/tmp/missing_intermediate_directory/foo") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "make_directory") -pub fn make_directory(a: String) -> Result(Nil, Reason) - -/// Lists all files in a directory, except files with -/// [raw filenames](https://www.erlang.org/doc/apps/stdlib/unicode_usage.html#notes-about-raw-filenames). -/// -/// Returns a Result containing the list of filenames in the directory, or Reason -/// if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > list_directory("/tmp") -/// Ok(["FB01293B-8597-4359-80D5-130140A0C0DE","AlTest2.out"]) -/// -/// > list_directory("resume.docx") -/// Error(Enotdir) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "list_directory") -pub fn list_directory(a: String) -> Result(List(String), Reason) - -/// Deletes a directory. -/// -/// The directory must be empty before it can be deleted. Returns a nil Success -/// or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > delete_directory("foo") -/// Ok(Nil) -/// -/// > delete_directory("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "delete_directory") -pub fn delete_directory(a: String) -> Result(Nil, Reason) - -/// Deletes a file or directory recursively. -/// -/// Returns a nil Success or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > recursive_delete("foo") -/// Ok(Nil) -/// -/// > recursive_delete("/bar") -/// Ok(Nil) -/// -/// > recursive_delete("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "recursive_delete") -pub fn recursive_delete(a: String) -> Result(Nil, Reason) - -/// Read the contents of the given file as a String -/// -/// Assumes the file is UTF-8 encoded. Returns a Result containing the file's -/// contents as a String if the operation was successful, or Reason if the file -/// operation failed. If the file is not UTF-8 encoded, the `NotUTF8` variant -/// will be returned. -/// -/// ## Examples -/// -/// ```gleam -/// > read("example.txt") -/// Ok("Hello, World!") -/// -/// > read(from: "example.txt") -/// Ok("Hello, World!") -/// -/// > read("does_not_exist.txt") -/// Error(Enoent) -/// -/// > read("cat.gif") -/// Error(NotUTF8) -/// ``` -/// -@deprecated("Use the simplifile package instead?") -pub fn read(from path: String) -> Result(String, Reason) { - path - |> do_read_bits() - |> result.then(fn(content) { - case bit_array.to_string(content) { - Ok(string) -> Ok(string) - Error(Nil) -> Error(NotUtf8) - } - }) -} - -/// Read the contents of the given file as a BitString -/// -/// Returns a Result containing the file's contents as a BitString if the -/// operation was successful, or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > read_bits("example.txt") -/// Ok(<<"Hello, World!">>) -/// -/// > read_bits(from: "cat.gif") -/// Ok(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// -/// > read_bits("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn read_bits(from path: String) -> Result(BitArray, Reason) { - do_read_bits(path) -} - -@external(erlang, "gleam_erlang_ffi", "read_file") -fn do_read_bits(a: path) -> Result(BitArray, Reason) - -/// Write the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > write(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > write("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn write(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_array.from_string - |> do_write_bits(path) -} - -/// Write the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > write_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn write_bits( - contents contents: BitArray, - to path: String, -) -> Result(Nil, Reason) { - do_write_bits(contents, path) -} - -@external(erlang, "gleam_erlang_ffi", "write_file") -fn do_write_bits(a: BitArray, b: String) -> Result(Nil, Reason) - -/// Append the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > append(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > append("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn append(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_array.from_string - |> do_append_bits(path) -} - -/// Append the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > append_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -pub fn append_bits( - contents contents: BitArray, - to path: String, -) -> Result(Nil, Reason) { - do_append_bits(contents, path) -} - -@external(erlang, "gleam_erlang_ffi", "append_file") -fn do_append_bits( - contents contents: BitArray, - path path: String, -) -> Result(Nil, Reason) - -/// Delete the given file. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > delete("file.txt") -/// Ok(Nil) -/// -/// > delete("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "delete_file") -pub fn delete(a: String) -> Result(Nil, Reason) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam deleted file mode 100644 index 339415c9a1a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/node.gleam +++ /dev/null @@ -1,62 +0,0 @@ -import gleam/erlang/atom.{type Atom} - -pub type Node - -type DoNotLeak - -/// Return the current node. -/// -@external(erlang, "erlang", "node") -pub fn self() -> Node - -/// Return a list of all visible nodes in the cluster, not including the current -/// node. -/// -/// The current node can be included by calling `self()` and prepending the -/// result. -/// -/// ```gleam -/// let all_nodes = [node.self(), ..node.visible()] -/// ``` -/// -@external(erlang, "erlang", "nodes") -pub fn visible() -> List(Node) - -pub type ConnectError { - /// Was unable to connect to the node. - FailedToConnect - /// The local node is not alive, so it is not possible to connect to the other - /// node. - LocalNodeIsNotAlive -} - -// TODO: test unknown node -// TODO: test successfully connecting -/// Establish a connection to a node, so the nodes can send messages to each -/// other and any other connected nodes. -/// -/// Returns `Error(FailedToConnect)` if the node is not reachable. -/// -/// Returns `Error(LocalNodeIsNotAlive)` if the local node is not alive, meaning -/// it is not running in distributed mode. -/// -@external(erlang, "gleam_erlang_ffi", "connect_node") -pub fn connect(node: Atom) -> Result(Node, ConnectError) - -// TODO: test -/// Send a message to a named process on a given node. -/// -/// These messages are untyped, like regular Erlang messages. -/// -pub fn send(node: Node, name: Atom, message: message) -> Nil { - raw_send(#(name, node), message) - Nil -} - -@external(erlang, "erlang", "send") -fn raw_send(receiver: #(Atom, Node), message: message) -> DoNotLeak - -/// Convert a node to the atom of its name. -/// -@external(erlang, "gleam_erlang_ffi", "identity") -pub fn to_atom(node: Node) -> Atom diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam deleted file mode 100644 index e13597404bf..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/os.gleam +++ /dev/null @@ -1,95 +0,0 @@ -//// Access to the shell's environment variables - -import gleam/map.{type Map} - -/// Returns the list of all available environment variables as a list of key, -/// tuples. -/// -/// ## Examples -/// -/// > get_all_env() -/// map.from_list([ -/// #("SHELL", "/bin/bash"), -/// #("PWD", "/home/j3rn"), -/// ... -/// ]) -/// -@external(erlang, "gleam_erlang_ffi", "get_all_env") -pub fn get_all_env() -> Map(String, String) - -/// Returns the value associated with the given environment variable name. -/// -/// ## Examples -/// -/// > get_env("SHELL") -/// "/bin/bash" -/// -/// > get_env(name: "PWD") -/// "/home/j3rn" -/// -@external(erlang, "gleam_erlang_ffi", "get_env") -pub fn get_env(name name: String) -> Result(String, Nil) - -/// Associates the given value with the given environment variable name. -/// -/// ## Examples -/// -/// > set_env("MYVAR", "MYVALUE") -/// Nil -/// > get_env("MYVAR") -/// "MYVALUE" -/// -/// > set_env(value: "MYVALUE", name: "MYVAR") -/// Nil -/// -@external(erlang, "gleam_erlang_ffi", "set_env") -pub fn set_env(name name: String, value value: String) -> Nil - -/// Removes the environment variable with the given name. -/// -/// Returns Nil regardless of whether the variable ever existed. -/// -/// ## Examples -/// -/// > get_env("MYVAR") -/// Ok("MYVALUE") -/// > unset_env("MYVAR") -/// Nil -/// > get_env("MYVAR") -/// Error(Nil) -/// -/// > unset_env(name: "MYVAR") -/// Nil -/// -@external(erlang, "gleam_erlang_ffi", "unset_env") -pub fn unset_env(name name: String) -> Nil - -/// Represents operating system kernels -pub type OsFamily { - // The family which includes modern versions of the Windows operating system. - WindowsNt - // The family of operating systems based on the open source Linux kernel. - Linux - // The family of Apple operating systems such as macOS and iOS. - Darwin - // The family of operating systems based on the FreeBSD kernel. - FreeBsd - // An operating system kernel other than Linux, Darwin, FreeBSD, or NT. - Other(String) -} - -/// Returns the kernel of the host operating system. -/// -/// Unknown kernels are reported as `Other(String)`; e.g. `Other("sunos")`. -/// -/// ## Examples -/// -/// > family() -/// Linux -/// > family() -/// Darwin -/// > family() -/// Other("sunos") -/// -@external(erlang, "gleam_erlang_ffi", "os_family") -pub fn family() -> OsFamily diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam deleted file mode 100644 index f66030612a5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam/erlang/process.gleam +++ /dev/null @@ -1,744 +0,0 @@ -import gleam/string -import gleam/dynamic.{type Dynamic} -import gleam/erlang.{type Reference} -import gleam/erlang/atom.{type Atom} - -/// A `Pid` (or Process identifier) is a reference to an Erlang process. Each -/// process has a `Pid` and it is one of the lowest level building blocks of -/// inter-process communication in the Erlang and Gleam OTP frameworks. -/// -pub type Pid - -/// Get the `Pid` for the current process. -@external(erlang, "erlang", "self") -pub fn self() -> Pid - -/// Create a new Erlang process that runs concurrently to the creator. In other -/// languages this might be called a fibre, a green thread, or a coroutine. -/// -/// If `linked` is `True` then the created process is linked to the creator -/// process. When a process terminates an exit signal is sent to all other -/// processes that are linked to it, causing the process to either terminate or -/// have to handle the signal. -/// -/// More can be read about processes and links in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/reference_manual/processes.html -/// -pub fn start(running implementation: fn() -> anything, linked link: Bool) -> Pid { - case link { - True -> spawn_link(implementation) - False -> spawn(implementation) - } -} - -@external(erlang, "erlang", "spawn") -fn spawn(a: fn() -> anything) -> Pid - -@external(erlang, "erlang", "spawn_link") -fn spawn_link(a: fn() -> anything) -> Pid - -/// A `Subject` is a value that processes can use to send and receive messages -/// to and from each other in a well typed way. -/// -/// Each subject is "owned" by the process that created it. Any process can use -/// the `send` function to sent a message of the correct type to the process -/// that owns the subject, and the owner can use the `receive` function or the -/// `Selector` type to receive these messages. -/// -/// The `Subject` type is similar to the "channel" types found in other -/// languages and the "topic" concept found in some pub-sub systems. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// -/// // Send a message with the subject -/// send(subject, "Hello, Joe!") -/// -/// // Receive the message -/// receive(subject, within: 10) -/// ``` -/// -pub opaque type Subject(message) { - Subject(owner: Pid, tag: Reference) -} - -/// Create a new `Subject` owned by the current process. -/// -pub fn new_subject() -> Subject(message) { - Subject(owner: self(), tag: erlang.make_reference()) -} - -/// Get the owner process for a `Subject`. This is the process that created the -/// `Subject` and will receive messages sent with it. -/// -pub fn subject_owner(subject: Subject(message)) -> Pid { - subject.owner -} - -type DoNotLeak - -@external(erlang, "erlang", "send") -fn raw_send(a: Pid, b: message) -> DoNotLeak - -/// Send a message to a process using a `Subject`. The message must be of the -/// type that the `Subject` accepts. -/// -/// This function does not wait for the `Subject` owner process to call the -/// `receive` function, instead it returns once the message has been placed in -/// the process' mailbox. -/// -/// # Ordering -/// -/// If process P1 sends two messages to process P2 it is guaranteed that process -/// P1 will receive the messages in the order they were sent. -/// -/// If you wish to receive the messages in a different order you can send them -/// on two different subjects and the receiver function can call the `receive` -/// function for each subject in the desired order, or you can write some Erlang -/// code to perform a selective receive. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// send(subject, "Hello, Joe!") -/// ``` -/// -pub fn send(subject: Subject(message), message: message) -> Nil { - raw_send(subject.owner, #(subject.tag, message)) - Nil -} - -/// Receive a message that has been sent to current process using the `Subject`. -/// -/// If there is not an existing message for the `Subject` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject` can receive a message using -/// it. If a process that does not own the `Subject` attempts to receive with it -/// then it will not receive a message. -/// -/// To wait for messages from multiple `Subject`s at the same time see the -/// `Selector` type. -/// -pub fn receive( - from subject: Subject(message), - within milliseconds: Int, -) -> Result(message, Nil) { - new_selector() - |> selecting(subject, fn(x) { x }) - |> select(within: milliseconds) -} - -/// A type that enables a process to wait for messages from multiple `Subject`s -/// at the same time, returning whichever message arrives first. -/// -/// Used with the `new_selector`, `selecting`, and `select` functions. -/// -/// # Examples -/// -/// ```gleam -/// > let int_subject = new_subject() -/// > let float_subject = new_subject() -/// > send(int_subject, 1) -/// > -/// > let selector = -/// > new_selector() -/// > |> selecting(int_subject, int.to_string) -/// > |> selecting(float_subject, float.to_string) -/// > -/// > select(selector, 10) -/// Ok("1") -/// ``` -/// -pub type Selector(payload) - -/// Create a new `Selector` which can be used to receive messages on multiple -/// `Subject`s at once. -/// -@external(erlang, "gleam_erlang_ffi", "new_selector") -pub fn new_selector() -> Selector(payload) - -/// Receive a message that has been sent to current process using any of the -/// `Subject`s that have been added to the `Selector` with the `selecting` -/// function. -/// -/// If there is not an existing message for the `Selector` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject`s can receive a message using -/// them. If a process that does not own the a `Subject` attempts to receive -/// with it then it will not receive a message. -/// -/// To wait forever for the next message rather than for a limited amount of -/// time see the `select_forever` function. -/// -@external(erlang, "gleam_erlang_ffi", "select") -pub fn select( - from from: Selector(payload), - within within: Int, -) -> Result(payload, Nil) - -/// Similar to the `select` function but will wait forever for a message to -/// arrive rather than timing out after a specified amount of time. -/// -@external(erlang, "gleam_erlang_ffi", "select") -pub fn select_forever(from from: Selector(payload)) -> payload - -/// Add a transformation function to a selector. When a message is received -/// using this selector the transformation function is applied to the message. -/// -/// This function can be used to change the type of messages received and may -/// be useful when combined with the `merge_selector` function. -/// -@external(erlang, "gleam_erlang_ffi", "map_selector") -pub fn map_selector(a: Selector(a), b: fn(a) -> b) -> Selector(b) - -/// Merge one selector into another, producing a selector that contains the -/// message handlers of both. -/// -/// If a subject is handled by both selectors the handler function of the -/// second selector is used. -/// -@external(erlang, "gleam_erlang_ffi", "merge_selector") -pub fn merge_selector(a: Selector(a), b: Selector(a)) -> Selector(a) - -pub type ExitMessage { - ExitMessage(pid: Pid, reason: ExitReason) -} - -pub type ExitReason { - Normal - Killed - Abnormal(reason: String) -} - -/// Add a handler for trapped exit messages. In order for these messages to be -/// sent to the process when a linked process exits the process must call the -/// `trap_exit` beforehand. -/// -pub fn selecting_trapped_exits( - selector: Selector(a), - handler: fn(ExitMessage) -> a, -) -> Selector(a) { - let tag = atom.create_from_string("EXIT") - let handler = fn(message: #(Atom, Pid, Dynamic)) -> a { - let reason = message.2 - let normal = dynamic.from(Normal) - let killed = dynamic.from(Killed) - let reason = case dynamic.string(reason) { - _ if reason == normal -> Normal - _ if reason == killed -> Killed - Ok(reason) -> Abnormal(reason) - Error(_) -> Abnormal(string.inspect(reason)) - } - handler(ExitMessage(message.1, reason)) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -// TODO: implement in Gleam -/// Discard all messages in the current process' mailbox. -/// -/// Warning: This function may cause other processes to crash if they sent a -/// message to the current process and are waiting for a response, so use with -/// caution. -/// -@external(erlang, "gleam_erlang_ffi", "flush_messages") -pub fn flush_messages() -> Nil - -/// Add a new `Subject` to the `Selector` to that it's messages can be received. -/// -/// The `mapping` function provided with the `Subject` can be used to convert -/// the type of messages received using this `Subject`. This is useful for when -/// you wish to add multiple `Subject`s to a `Seletor` when they have differing -/// message types. If you do not wish to transform the incoming messages in any -/// way then the `identity` function can be given. -/// -pub fn selecting( - selector: Selector(payload), - for subject: Subject(message), - mapping transform: fn(message) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(Reference, message)) { transform(message.1) } - insert_selector_handler(selector, #(subject.tag, 2), handler) -} - -/// Add a handler to a selector for 2 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record2( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic)) { transform(message.1) } - insert_selector_handler(selector, #(tag, 2), handler) -} - -/// Add a handler to a selector for 3 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record3( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic)) { - transform(message.1, message.2) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -/// Add a handler to a selector for 4 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record4( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3) - } - insert_selector_handler(selector, #(tag, 4), handler) -} - -/// Add a handler to a selector for 5 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record5( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4) - } - insert_selector_handler(selector, #(tag, 5), handler) -} - -/// Add a handler to a selector for 6 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record6( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4, message.5) - } - insert_selector_handler(selector, #(tag, 6), handler) -} - -/// Add a handler to a selector for 7 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record7( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - ) { - transform(message.1, message.2, message.3, message.4, message.5, message.6) - } - insert_selector_handler(selector, #(tag, 7), handler) -} - -/// Add a handler to a selector for 8 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record8( - selector: Selector(payload), - tag: tag, - mapping transform: fn( - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #( - tag, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ), - ) { - transform( - message.1, - message.2, - message.3, - message.4, - message.5, - message.6, - message.7, - ) - } - insert_selector_handler(selector, #(tag, 8), handler) -} - -type AnythingSelectorTag { - Anything -} - -/// Add a catch-all handler to a selector that will be used when no other -/// handler in a selector is suitable for a given message. -/// -/// This may be useful for when you want to ensure that any message in the inbox -/// is handled, or when you need to handle messages from other BEAM languages -/// which do not use subjects or record format messages. -/// -pub fn selecting_anything( - selector: Selector(payload), - mapping handler: fn(Dynamic) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, Anything, handler) -} - -@external(erlang, "gleam_erlang_ffi", "insert_selector_handler") -fn insert_selector_handler( - a: Selector(payload), - for for: tag, - mapping mapping: fn(message) -> payload, -) -> Selector(payload) - -/// Suspends the process calling this function for the specified number of -/// milliseconds. -/// -@external(erlang, "gleam_erlang_ffi", "sleep") -pub fn sleep(a: Int) -> Nil - -/// Suspends the process forever! This may be useful for suspending the main -/// process in a Gleam program when it has no more work to do but we want other -/// processes to continue to work. -/// -@external(erlang, "gleam_erlang_ffi", "sleep_forever") -pub fn sleep_forever() -> Nil - -/// Check to see whether the process for a given `Pid` is alive. -/// -/// See the [Erlang documentation][1] for more information. -/// -/// [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1 -/// -@external(erlang, "erlang", "is_process_alive") -pub fn is_alive(a: Pid) -> Bool - -type ProcessMonitorFlag { - Process -} - -@external(erlang, "erlang", "monitor") -fn erlang_monitor_process(a: ProcessMonitorFlag, b: Pid) -> Reference - -pub opaque type ProcessMonitor { - ProcessMonitor(tag: Reference) -} - -/// A message received when a monitored process exits. -/// -pub type ProcessDown { - ProcessDown(pid: Pid, reason: Dynamic) -} - -/// Start monitoring a process so that when the monitored process exits a -/// message is sent to the monitoring process. -/// -/// The message is only sent once, when the target process exits. If the -/// process was not alive when this function is called the message will never -/// be received. -/// -/// The down message can be received with a `Selector` and the -/// `selecting_process_down` function. -/// -/// The process can be demonitored with the `demonitor_process` function. -/// -pub fn monitor_process(pid: Pid) -> ProcessMonitor { - Process - |> erlang_monitor_process(pid) - |> ProcessMonitor -} - -/// Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can -/// be received using the `Selector` and the `select` function. -/// -pub fn selecting_process_down( - selector: Selector(payload), - monitor: ProcessMonitor, - mapping: fn(ProcessDown) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, monitor.tag, mapping) -} - -/// Remove the monitor for a process so that when the monitor process exits a -/// `ProcessDown` message is not sent to the monitoring process. -/// -/// If the message has already been sent it is removed from the monitoring -/// process' mailbox. -/// -@external(erlang, "gleam_erlang_ffi", "demonitor") -pub fn demonitor_process(monitor monitor: ProcessMonitor) -> Nil - -/// An error returned when making a call to a process. -/// -pub type CallError(msg) { - /// The process being called exited before it sent a response. - /// - CalleeDown(reason: Dynamic) - - /// The process being called did not response within the permitted amount of - /// time. - /// - CallTimeout -} - -// This function is based off of Erlang's gen:do_call/4. -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time then an error is returned. -/// -pub fn try_call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> Result(response, CallError(response)) { - let reply_subject = new_subject() - - // Monitor the callee process so we can tell if it goes down (meaning we - // won't get a reply) - let monitor = monitor_process(subject_owner(subject)) - - // Send the request to the process over the channel - send(subject, make_request(reply_subject)) - - // Await a reply or handle failure modes (timeout, process down, etc) - let result = - new_selector() - |> selecting(reply_subject, Ok) - |> selecting_process_down( - monitor, - fn(down: ProcessDown) { Error(CalleeDown(reason: down.reason)) }, - ) - |> select(timeout) - - // Demonitor the process and close the channels as we're done - demonitor_process(monitor) - - // Prepare an appropriate error (if present) for the caller - case result { - Error(Nil) -> Error(CallTimeout) - Ok(res) -> res - } -} - -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time the calling process crashes. If you wish an error to be returned -/// instead see the `try_call` function. -/// -pub fn call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> response { - let assert Ok(resp) = try_call(subject, make_request, timeout) - resp -} - -/// Creates a link between the calling process and another process. -/// -/// When a process crashes any linked processes will also crash. This is useful -/// to ensure that groups of processes that depend on each other all either -/// succeed or fail together. -/// -/// Returns `True` if the link was created successfully, returns `False` if the -/// process was not alive and as such could not be linked. -/// -@external(erlang, "gleam_erlang_ffi", "link") -pub fn link(pid pid: Pid) -> Bool - -@external(erlang, "erlang", "unlink") -fn erlang_unlink(pid pid: Pid) -> Bool - -/// Removes any existing link between the caller process and the target process. -/// -pub fn unlink(pid: Pid) -> Nil { - erlang_unlink(pid) - Nil -} - -pub type Timer - -@external(erlang, "erlang", "send_after") -fn erlang_send_after(a: Int, b: Pid, c: msg) -> Timer - -/// Send a message over a channel after a specified number of milliseconds. -/// -pub fn send_after(subject: Subject(msg), delay: Int, message: msg) -> Timer { - erlang_send_after(delay, subject.owner, #(subject.tag, message)) -} - -@external(erlang, "erlang", "cancel_timer") -fn erlang_cancel_timer(a: Timer) -> Dynamic - -/// Values returned when a timer is cancelled. -/// -pub type Cancelled { - /// The timer could not be found. It likely has already triggered. - /// - TimerNotFound - - /// The timer was found and cancelled before it triggered. - /// - /// The amount of remaining time before the timer was due to be triggered is - /// returned in milliseconds. - /// - Cancelled(time_remaining: Int) -} - -/// Cancel a given timer, causing it not to trigger if it has not done already. -/// -pub fn cancel_timer(timer: Timer) -> Cancelled { - case dynamic.int(erlang_cancel_timer(timer)) { - Ok(i) -> Cancelled(i) - Error(_) -> TimerNotFound - } -} - -type KillFlag { - Kill -} - -@external(erlang, "erlang", "exit") -fn erlang_kill(to to: Pid, because because: KillFlag) -> Bool - -// Go, my pretties. Kill! Kill! -// - Bart Simpson -// -/// Send an untrappable `kill` exit signal to the target process. -/// -/// See the documentation for the Erlang [`erlang:exit`][1] function for more -/// information. -/// -/// [1]: https://erlang.org/doc/man/erlang.html#exit-1 -/// -pub fn kill(pid: Pid) -> Nil { - erlang_kill(pid, Kill) - Nil -} - -@external(erlang, "erlang", "exit") -fn erlang_send_exit(to to: Pid, because because: whatever) -> Bool - -// TODO: test -/// Sends an exit signal to a process, indicating that the process is to shut -/// down. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_exit(to pid: Pid) -> Nil { - erlang_send_exit(pid, Normal) - Nil -} - -/// Sends an exit signal to a process, indicating that the process is to shut -/// down due to an abnormal reason such as a failure. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_abnormal_exit(pid: Pid, reason: String) -> Nil { - erlang_send_exit(pid, Abnormal(reason)) - Nil -} - -/// Set whether the current process is to trap exit signals or not. -/// -/// When not trapping exits if a linked process crashes the exit signal -/// propagates to the process which will also crash. -/// This is the normal behaviour before this function is called. -/// -/// When trapping exits (after this function is called) if a linked process -/// crashes an exit message is sent to the process instead. These messages can -/// be handled with the `selecting_trapped_exits` function. -/// -@external(erlang, "gleam_erlang_ffi", "trap_exits") -pub fn trap_exits(a: Bool) -> Nil - -/// Register a process under a given name, allowing it to be looked up using -/// the `named` function. -/// -/// This function will return an error under the following conditions: -/// - The process for the pid no longer exists. -/// - The name has already been registered. -/// - The process already has a name. -/// - The name is the atom `undefined`, which is reserved by Erlang. -/// -@external(erlang, "gleam_erlang_ffi", "register_process") -pub fn register(pid: Pid, name: Atom) -> Result(Nil, Nil) - -/// Un-register a process name, after which the process can no longer be looked -/// up by that name, and both the name and the process can be re-used in other -/// registrations. -/// -/// It is possible to un-register process that are not from your application, -/// including those from Erlang/OTP itself. This is not recommended and will -/// likely result in undesirable behaviour and crashes. -/// -@external(erlang, "gleam_erlang_ffi", "unregister_process") -pub fn unregister(name: Atom) -> Result(Nil, Nil) - -/// Look up a process by name, returning the pid if it exists. -/// -@external(erlang, "gleam_erlang_ffi", "process_named") -pub fn named(name: Atom) -> Result(Pid, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl deleted file mode 100644 index 14a55381864..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(gleam@erlang). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0, priv_directory/1]). --export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]). - --type safe() :: safe. - --type get_line_error() :: eof | no_data. - --type time_unit() :: second | millisecond | microsecond | nanosecond. - --type crash() :: {exited, gleam@dynamic:dynamic_()} | - {thrown, gleam@dynamic:dynamic_()} | - {errored, gleam@dynamic:dynamic_()}. - --type ensure_all_started_error() :: {unknown_application, - gleam@erlang@atom:atom_()} | - {application_failed_to_start, - gleam@erlang@atom:atom_(), - gleam@dynamic:dynamic_()}. - --type reference_() :: any(). - --spec format(any()) -> binary(). -format(Term) -> - unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])). - --spec term_to_binary(any()) -> bitstring(). -term_to_binary(A) -> - erlang:term_to_binary(A). - --spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. -get_line(Prompt) -> - gleam_erlang_ffi:get_line(Prompt). - --spec system_time(time_unit()) -> integer(). -system_time(A) -> - os:system_time(A). - --spec erlang_timestamp() -> {integer(), integer(), integer()}. -erlang_timestamp() -> - os:timestamp(). - --spec rescue(fun(() -> FHH)) -> {ok, FHH} | {error, crash()}. -rescue(A) -> - gleam_erlang_ffi:rescue(A). - --spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | - {error, nil}. -binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue( - fun() -> erlang:binary_to_term(Binary, [safe]) end - ) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | - {error, nil}. -unsafe_binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec start_arguments() -> list(binary()). -start_arguments() -> - _pipe = init:get_plain_arguments(), - gleam@list:map(_pipe, fun unicode:characters_to_binary/1). - --spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok, - list(gleam@erlang@atom:atom_())} | - {error, ensure_all_started_error()}. -ensure_all_started(Application) -> - gleam_erlang_ffi:ensure_all_started(Application). - --spec make_reference() -> reference_(). -make_reference() -> - erlang:make_ref(). - --spec priv_directory(binary()) -> {ok, binary()} | {error, nil}. -priv_directory(Name) -> - gleam_erlang_ffi:priv_directory(Name). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl deleted file mode 100644 index e9ad5300ce5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@atom.erl +++ /dev/null @@ -1,26 +0,0 @@ --module(gleam@erlang@atom). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]). --export_type([atom_/0, from_string_error/0]). - --type atom_() :: any(). - --type from_string_error() :: atom_not_loaded. - --spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}. -from_string(A) -> - gleam_erlang_ffi:atom_from_string(A). - --spec create_from_string(binary()) -> atom_(). -create_from_string(A) -> - erlang:binary_to_atom(A). - --spec to_string(atom_()) -> binary(). -to_string(A) -> - erlang:atom_to_binary(A). - --spec from_dynamic(gleam@dynamic:dynamic_()) -> {ok, atom_()} | - {error, list(gleam@dynamic:decode_error())}. -from_dynamic(From) -> - gleam_erlang_ffi:atom_from_dynamic(From). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl deleted file mode 100644 index 9f9c0fa1c55..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl +++ /dev/null @@ -1,15 +0,0 @@ --module(gleam@erlang@charlist). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([to_string/1, from_string/1]). --export_type([charlist/0]). - --type charlist() :: any(). - --spec to_string(charlist()) -> binary(). -to_string(A) -> - unicode:characters_to_binary(A). - --spec from_string(binary()) -> charlist(). -from_string(A) -> - unicode:characters_to_list(A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl deleted file mode 100644 index 1fe6628add7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@file.erl +++ /dev/null @@ -1,190 +0,0 @@ --module(gleam@erlang@file). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([file_info/1, link_info/1, is_directory/1, is_regular/1, file_exists/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]). --export_type([reason/0, file_type/0, access/0, file_info/0]). - --type reason() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8. - --type file_type() :: device | directory | other | regular | symlink. - --type access() :: no_access | read | read_write | write. - --type file_info() :: {file_info, - integer(), - file_type(), - access(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec file_info(binary()) -> {ok, file_info()} | {error, reason()}. -file_info(A) -> - gleam_erlang_ffi:file_info(A). - --spec link_info(binary()) -> {ok, file_info()} | {error, reason()}. -link_info(A) -> - gleam_erlang_ffi:link_info(A). - --spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}. -is_directory(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= directory - end - ). - --spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}. -is_regular(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= regular - end - ). - --spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}. -file_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:file_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}. -link_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:link_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec make_directory(binary()) -> {ok, nil} | {error, reason()}. -make_directory(A) -> - gleam_erlang_ffi:make_directory(A). - --spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}. -list_directory(A) -> - gleam_erlang_ffi:list_directory(A). - --spec delete_directory(binary()) -> {ok, nil} | {error, reason()}. -delete_directory(A) -> - gleam_erlang_ffi:delete_directory(A). - --spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}. -recursive_delete(A) -> - gleam_erlang_ffi:recursive_delete(A). - --spec read(binary()) -> {ok, binary()} | {error, reason()}. -read(Path) -> - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:read_file(_pipe), - gleam@result:then( - _pipe@1, - fun(Content) -> case gleam@bit_array:to_string(Content) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, not_utf8} - end end - ). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}. -read_bits(Path) -> - gleam_erlang_ffi:read_file(Path). - --spec write(binary(), binary()) -> {ok, nil} | {error, reason()}. -write(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam_stdlib:identity(_pipe), - gleam_erlang_ffi:write_file(_pipe@1, Path). - --spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -write_bits(Contents, Path) -> - gleam_erlang_ffi:write_file(Contents, Path). - --spec append(binary(), binary()) -> {ok, nil} | {error, reason()}. -append(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam_stdlib:identity(_pipe), - gleam_erlang_ffi:append_file(_pipe@1, Path). - --spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -append_bits(Contents, Path) -> - gleam_erlang_ffi:append_file(Contents, Path). - --spec delete(binary()) -> {ok, nil} | {error, reason()}. -delete(A) -> - gleam_erlang_ffi:delete_file(A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl deleted file mode 100644 index f57d029ba1a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@node.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@erlang@node). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([self/0, visible/0, connect/1, send/3, to_atom/1]). --export_type([node_/0, do_not_leak/0, connect_error/0]). - --type node_() :: any(). - --type do_not_leak() :: any(). - --type connect_error() :: failed_to_connect | local_node_is_not_alive. - --spec self() -> node_(). -self() -> - erlang:node(). - --spec visible() -> list(node_()). -visible() -> - erlang:nodes(). - --spec connect(gleam@erlang@atom:atom_()) -> {ok, node_()} | - {error, connect_error()}. -connect(Node) -> - gleam_erlang_ffi:connect_node(Node). - --spec send(node_(), gleam@erlang@atom:atom_(), any()) -> nil. -send(Node, Name, Message) -> - erlang:send({Name, Node}, Message), - nil. - --spec to_atom(node_()) -> gleam@erlang@atom:atom_(). -to_atom(Node) -> - gleam_erlang_ffi:identity(Node). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl deleted file mode 100644 index 6604255b55f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@os.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@erlang@os). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]). --export_type([os_family/0]). - --type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}. - --spec get_all_env() -> gleam@map:map_(binary(), binary()). -get_all_env() -> - gleam_erlang_ffi:get_all_env(). - --spec get_env(binary()) -> {ok, binary()} | {error, nil}. -get_env(Name) -> - gleam_erlang_ffi:get_env(Name). - --spec set_env(binary(), binary()) -> nil. -set_env(Name, Value) -> - gleam_erlang_ffi:set_env(Name, Value). - --spec unset_env(binary()) -> nil. -unset_env(Name) -> - gleam_erlang_ffi:unset_env(Name). - --spec family() -> os_family(). -family() -> - gleam_erlang_ffi:os_family(). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl deleted file mode 100644 index fc8e0ffe15f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam@erlang@process.erl +++ /dev/null @@ -1,374 +0,0 @@ --module(gleam@erlang@process). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([self/0, start/2, new_subject/0, subject_owner/1, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, selecting_process_down/3, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1, register/2, unregister/1, named/1]). --export_type([pid_/0, subject/1, do_not_leak/0, selector/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, timer/0, cancelled/0, kill_flag/0]). - --type pid_() :: any(). - --opaque subject(FJD) :: {subject, pid_(), gleam@erlang:reference_()} | - {gleam_phantom, FJD}. - --type do_not_leak() :: any(). - --type selector(FJE) :: any() | {gleam_phantom, FJE}. - --type exit_message() :: {exit_message, pid_(), exit_reason()}. - --type exit_reason() :: normal | killed | {abnormal, binary()}. - --type anything_selector_tag() :: anything. - --type process_monitor_flag() :: process. - --opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}. - --type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic_()}. - --type call_error(FJF) :: {callee_down, gleam@dynamic:dynamic_()} | - call_timeout | - {gleam_phantom, FJF}. - --type timer() :: any(). - --type cancelled() :: timer_not_found | {cancelled, integer()}. - --type kill_flag() :: kill. - --spec self() -> pid_(). -self() -> - erlang:self(). - --spec start(fun(() -> any()), boolean()) -> pid_(). -start(Implementation, Link) -> - case Link of - true -> - erlang:spawn_link(Implementation); - - false -> - erlang:spawn(Implementation) - end. - --spec new_subject() -> subject(any()). -new_subject() -> - {subject, erlang:self(), erlang:make_ref()}. - --spec subject_owner(subject(any())) -> pid_(). -subject_owner(Subject) -> - erlang:element(2, Subject). - --spec send(subject(FJO), FJO) -> nil. -send(Subject, Message) -> - erlang:send( - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ), - nil. - --spec new_selector() -> selector(any()). -new_selector() -> - gleam_erlang_ffi:new_selector(). - --spec select(selector(FJW), integer()) -> {ok, FJW} | {error, nil}. -select(From, Within) -> - gleam_erlang_ffi:select(From, Within). - --spec select_forever(selector(FKA)) -> FKA. -select_forever(From) -> - gleam_erlang_ffi:select(From). - --spec map_selector(selector(FKC), fun((FKC) -> FKE)) -> selector(FKE). -map_selector(A, B) -> - gleam_erlang_ffi:map_selector(A, B). - --spec merge_selector(selector(FKG), selector(FKG)) -> selector(FKG). -merge_selector(A, B) -> - gleam_erlang_ffi:merge_selector(A, B). - --spec flush_messages() -> nil. -flush_messages() -> - gleam_erlang_ffi:flush_messages(). - --spec selecting_trapped_exits(selector(FKK), fun((exit_message()) -> FKK)) -> selector(FKK). -selecting_trapped_exits(Selector, Handler) -> - Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>), - Handler@1 = fun(Message) -> - Reason = erlang:element(3, Message), - Normal = gleam@dynamic:from(normal), - Killed = gleam@dynamic:from(killed), - Reason@2 = case gleam@dynamic:string(Reason) of - _ when Reason =:= Normal -> - normal; - - _ when Reason =:= Killed -> - killed; - - {ok, Reason@1} -> - {abnormal, Reason@1}; - - {error, _} -> - {abnormal, gleam@string:inspect(Reason)} - end, - Handler({exit_message, erlang:element(2, Message), Reason@2}) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1). - --spec selecting(selector(FKN), subject(FKP), fun((FKP) -> FKN)) -> selector(FKN). -selecting(Selector, Subject, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler( - Selector, - {erlang:element(3, Subject), 2}, - Handler - ). - --spec 'receive'(subject(FJQ), integer()) -> {ok, FJQ} | {error, nil}. -'receive'(Subject, Milliseconds) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end), - gleam_erlang_ffi:select(_pipe@1, Milliseconds). - --spec selecting_record2( - selector(FKS), - any(), - fun((gleam@dynamic:dynamic_()) -> FKS) -) -> selector(FKS). -selecting_record2(Selector, Tag, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler). - --spec selecting_record3( - selector(FKW), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FKW) -) -> selector(FKW). -selecting_record3(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform(erlang:element(2, Message), erlang:element(3, Message)) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler). - --spec selecting_record4( - selector(FLA), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLA) -) -> selector(FLA). -selecting_record4(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler). - --spec selecting_record5( - selector(FLE), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLE) -) -> selector(FLE). -selecting_record5(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler). - --spec selecting_record6( - selector(FLI), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLI) -) -> selector(FLI). -selecting_record6(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler). - --spec selecting_record7( - selector(FLM), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLM) -) -> selector(FLM). -selecting_record7(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler). - --spec selecting_record8( - selector(FLQ), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLQ) -) -> selector(FLQ). -selecting_record8(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message), - erlang:element(8, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler). - --spec selecting_anything(selector(FLU), fun((gleam@dynamic:dynamic_()) -> FLU)) -> selector(FLU). -selecting_anything(Selector, Handler) -> - gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler). - --spec sleep(integer()) -> nil. -sleep(A) -> - gleam_erlang_ffi:sleep(A). - --spec sleep_forever() -> nil. -sleep_forever() -> - gleam_erlang_ffi:sleep_forever(). - --spec is_alive(pid_()) -> boolean(). -is_alive(A) -> - erlang:is_process_alive(A). - --spec monitor_process(pid_()) -> process_monitor(). -monitor_process(Pid) -> - _pipe = process, - _pipe@1 = erlang:monitor(_pipe, Pid), - {process_monitor, _pipe@1}. - --spec selecting_process_down( - selector(FMC), - process_monitor(), - fun((process_down()) -> FMC) -) -> selector(FMC). -selecting_process_down(Selector, Monitor, Mapping) -> - gleam_erlang_ffi:insert_selector_handler( - Selector, - erlang:element(2, Monitor), - Mapping - ). - --spec demonitor_process(process_monitor()) -> nil. -demonitor_process(Monitor) -> - gleam_erlang_ffi:demonitor(Monitor). - --spec try_call(subject(FMF), fun((subject(FMH)) -> FMF), integer()) -> {ok, FMH} | - {error, call_error(FMH)}. -try_call(Subject, Make_request, Timeout) -> - Reply_subject = new_subject(), - Monitor = monitor_process(subject_owner(Subject)), - send(Subject, Make_request(Reply_subject)), - Result = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting( - _pipe, - Reply_subject, - fun(Field@0) -> {ok, Field@0} end - ), - _pipe@2 = selecting_process_down( - _pipe@1, - Monitor, - fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end - ), - gleam_erlang_ffi:select(_pipe@2, Timeout) - end, - gleam_erlang_ffi:demonitor(Monitor), - case Result of - {error, nil} -> - {error, call_timeout}; - - {ok, Res} -> - Res - end. - --spec call(subject(FMM), fun((subject(FMO)) -> FMM), integer()) -> FMO. -call(Subject, Make_request, Timeout) -> - _assert_subject = try_call(Subject, Make_request, Timeout), - {ok, Resp} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/erlang/process"/utf8>>, - function => <<"call"/utf8>>, - line => 593}) - end, - Resp. - --spec link(pid_()) -> boolean(). -link(Pid) -> - gleam_erlang_ffi:link(Pid). - --spec unlink(pid_()) -> nil. -unlink(Pid) -> - erlang:unlink(Pid), - nil. - --spec send_after(subject(FMR), integer(), FMR) -> timer(). -send_after(Subject, Delay, Message) -> - erlang:send_after( - Delay, - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ). - --spec cancel_timer(timer()) -> cancelled(). -cancel_timer(Timer) -> - case gleam@dynamic:int(erlang:cancel_timer(Timer)) of - {ok, I} -> - {cancelled, I}; - - {error, _} -> - timer_not_found - end. - --spec kill(pid_()) -> nil. -kill(Pid) -> - erlang:exit(Pid, kill), - nil. - --spec send_exit(pid_()) -> nil. -send_exit(Pid) -> - erlang:exit(Pid, normal), - nil. - --spec send_abnormal_exit(pid_(), binary()) -> nil. -send_abnormal_exit(Pid, Reason) -> - erlang:exit(Pid, {abnormal, Reason}), - nil. - --spec trap_exits(boolean()) -> nil. -trap_exits(A) -> - gleam_erlang_ffi:trap_exits(A). - --spec register(pid_(), gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. -register(Pid, Name) -> - gleam_erlang_ffi:register_process(Pid, Name). - --spec unregister(gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. -unregister(Name) -> - gleam_erlang_ffi:unregister_process(Name). - --spec named(gleam@erlang@atom:atom_()) -> {ok, pid_()} | {error, nil}. -named(Name) -> - gleam_erlang_ffi:process_named(Name). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src deleted file mode 100644 index bb1b8e635ed..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang.app.src +++ /dev/null @@ -1,14 +0,0 @@ -{application, gleam_erlang, [ - {vsn, "0.23.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A Gleam library for working with Erlang"}, - {modules, [gleam@erlang, - gleam@erlang@atom, - gleam@erlang@charlist, - gleam@erlang@file, - gleam@erlang@node, - gleam@erlang@os, - gleam@erlang@process]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl deleted file mode 100644 index 872126fec75..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_erlang_ffi). --export([ - atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, - ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, - append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, - set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, - list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, - insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, - merge_selector/2, flush_messages/0, file_info/1, link_info/1, - priv_directory/1, connect_node/1, register_process/2, unregister_process/1, - process_named/1, identity/1 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - --spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. -atom_from_string(S) -> - try {ok, binary_to_existing_atom(S)} - catch error:badarg -> {error, atom_not_loaded} - end. - -atom_from_dynamic(Data) when is_atom(Data) -> - {ok, Data}; -atom_from_dynamic(Data) -> - {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. - -rescue(F) -> - try {ok, F()} - catch - throw:X -> {error, {thrown, X}}; - error:X -> {error, {errored, X}}; - exit:X -> {error, {exited, X}} - end. - -ensure_all_started(Application) -> - case application:ensure_all_started(Application) of - {ok, _} = Ok -> Ok; - - {error, {ProblemApp, {"no such file or directory", _}}} -> - {error, {unknown_application, ProblemApp}} - end. - -sleep(Microseconds) -> - timer:sleep(Microseconds), - nil. - -sleep_forever() -> - timer:sleep(infinity), - nil. - -file_info_result(Result) -> - case Result of - {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> - {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; - {ok, _} -> - Result; - {error, Reason} when ?is_posix_error(Reason) -> - Result - end. - -file_info(Filename) -> - file_info_result(file:read_file_info(Filename, [{time, posix}])). - -link_info(Filename) -> - file_info_result(file:read_link_info(Filename, [{time, posix}])). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -get_all_env() -> - BinVars = lists:map(fun(VarString) -> - [VarName, VarVal] = string:split(VarString, "="), - {list_to_binary(VarName), list_to_binary(VarVal)} - end, os:getenv()), - maps:from_list(BinVars). - -get_env(Name) -> - case os:getenv(binary_to_list(Name)) of - false -> {error, nil}; - Value -> {ok, list_to_binary(Value)} - end. - -set_env(Name, Value) -> - os:putenv(binary_to_list(Name), binary_to_list(Value)), - nil. - -unset_env(Name) -> - os:unsetenv(binary_to_list(Name)), - nil. - -os_family() -> - case os:type() of - {win32, nt} -> - windows_nt; - {unix, linux} -> - linux; - {unix, darwin} -> - darwin; - {unix, freebsd} -> - free_bsd; - {_, Other} -> - {other, atom_to_binary(Other, utf8)} - end. - -new_selector() -> - {selector, #{}}. - -map_selector({selector, Handlers}, Fn) -> - MappedHandlers = maps:map(fun(_Tag, Handler) -> - fun(Message) -> Fn(Handler(Message)) end - end, Handlers), - {selector, MappedHandlers}. - -merge_selector({selector, HandlersA}, {selector, HandlersB}) -> - {selector, maps:merge(HandlersA, HandlersB)}. - -insert_selector_handler({selector, Handlers}, Tag, Fn) -> - {selector, Handlers#{Tag => Fn}}. - -select(Selector) -> - {ok, Message} = select(Selector, infinity), - Message. - -select({selector, Handlers}, Timeout) -> - AnythingHandler = maps:get(anything, Handlers, undefined), - receive - % Monitored process down messages. - % This is special cased so we can selectively receive based on the - % reference as well as the record tag. - {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> - Fn = maps:get(Ref, Handlers), - {ok, Fn({process_down, Pid, Reason})}; - - Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> - Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), - {ok, Fn(Msg)}; - - Msg when AnythingHandler =/= undefined -> - {ok, AnythingHandler(Msg)} - after Timeout -> - {error, nil} - end. - -demonitor({_, Reference}) -> - erlang:demonitor(Reference, [flush]). - -link(Pid) -> - try - erlang:link(Pid) - catch - error:_ -> false - end. - -trap_exits(ShouldTrap) -> - erlang:process_flag(trap_exit, ShouldTrap), - nil. - -flush_messages() -> - receive _Message -> flush_messages() - after 0 -> nil - end. - -priv_directory(Name) -> - try erlang:binary_to_existing_atom(Name) of - Atom -> - case code:priv_dir(Atom) of - {error, _} -> {error, nil}; - Path -> {ok, unicode:characters_to_binary(Path)} - end - catch - error:badarg -> {error, nil} - end. - -connect_node(Node) -> - case net_kernel:connect_node(Node) of - true -> {ok, Node}; - false -> {error, failed_to_connect}; - ignored -> {error, local_node_is_not_alive} - end. - -register_process(Pid, Name) -> - try - true = erlang:register(Name, Pid), - {ok, nil} - catch - error:badarg -> {error, nil} - end. - -unregister_process(Name) -> - try - true = erlang:unregister(Name), - {ok, nil} - catch - error:badarg -> {error, nil} - end. - -process_named(Name) -> - case erlang:whereis(Name) of - Pid when is_pid(Pid) -> {ok, Pid}; - _ -> {error, nil} - end. - -identity(X) -> - X. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE deleted file mode 100644 index 619ec77e6e1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md deleted file mode 100644 index 3c313a1c8c9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Gleam OTP - -<a href="https://github.com/gleam-lang/otp/releases"><img src="https://img.shields.io/github/release/gleam-lang/otp" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/otp/workflows/test/badge.svg?branch=main) - -A Gleam library for building fault tolerant multi-core programs using the -actor model. It is compatible with Erlang's OTP framework. - -This library is experimental and will likely have many breaking changes in the -future! - -Gleam’s actor system is built with a few primary goals: - -- Full type safety of actors and messages. -- Be compatible with Erlang’s OTP actor framework. -- Provide fault tolerance and self-healing through supervisors. -- Have equivalent performance to Erlang’s OTP. - -This library documents its abstractions and functionality, but you may also wish -to read the documentation or other material on Erlang’s OTP framework to get a -fuller understanding of OTP, the problems it solves, and and the motivations for -its design. - -## Usage - -Add this library to your Gleam project. - -```shell -gleam add gleam_otp -``` - -## Actor hierarchy - -This library provides several different types of actor that can be used in -Gleam programs. - -### Process - -The process is the lowest level building block of OTP, all other actors are -built on top of processes either directly or indirectly. Typically this -abstraction would be not be used very often in Gleam applications, favour -other actor types that provide more functionality. - -Gleam's process module is defined in the `gleam_erlang` library. - -[[Documentation]](https://hexdocs.pm/gleam_erlang/gleam/erlang/process.html) - -### Actor - -The `actor` is the most commonly used process type in Gleam and serves as a good -building block for other abstractions. Like Erlang's `gen_server` it handles -OTP's system messages automatically to enable OTP's debugging and tracing -functionality. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/actor.html) - -### Task - -A task is a kind of process that performs a single task and then shuts down. -Commonly tasks are used to convert sequential code into concurrent code by -performing computation in another process. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/task.html) - -### Supervisor - -Supervisors is a process that starts and then supervises a group of processes, -restarting them if they crash. Supervisors can start other supervisors, -resulting in a hierarchical process structure called a supervision tree, -providing fault tolerance to a Gleam application. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/supervisor.html) - -## Limitations and known issues - -This library is experimental there are some limitations that not yet been resolved. - -- There is no support for named processes. They are untyped global mutable - variables which may be uninitialized, more research is needed to find a - suitable type safe alternative. -- There are relatively few actor abstractions provided by this library. More - will be added in the future. -- Actors do not yet support all OTP system messages. Unsupported messages are - dropped. -- Supervisors do not yet support different shutdown periods per child. In - practice this means that children that are supervisors do not get an - unlimited amount of time to shut down, as is expected in Erlang or Elixir. -- This library has not seen much testing compared to the Erlang OTP - libraries, both in terms of unit tests and real world testing in - applications. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml deleted file mode 100644 index 26e451baecf..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/gleam.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "gleam_otp" -version = "0.8.0" -licences = ["Apache-2.0"] -description = "Fault tolerant multicore Gleam programs with OTP" - -gleam = ">= 0.32.0" - -repository = { type = "github", user = "gleam-lang", repo = "otp" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_erlang = "~> 0.22" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl deleted file mode 100644 index 85677d1b257..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(continue, { - state :: any(), - selector :: gleam@option:option(gleam@erlang@process:selector(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl deleted file mode 100644 index 75faa95149f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ready, {state :: any(), selector :: gleam@erlang@process:selector(any())}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl deleted file mode 100644 index 52874392c18..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(spec, { - init :: fun(() -> gleam@otp@actor:init_result(any(), any())), - init_timeout :: integer(), - loop :: fun((any(), any()) -> gleam@otp@actor:next(any(), any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl deleted file mode 100644 index 3ed0b0122d4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(intensity_tracker, { - limit :: integer(), - period :: integer(), - events :: list(integer()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl deleted file mode 100644 index 7afd07f0319..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(child_spec, { - start :: fun((any()) -> {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()}), - returning :: fun((any(), gleam@erlang@process:subject(any())) -> any()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl deleted file mode 100644 index b10bd9fa3f7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(spec, { - argument :: any(), - max_frequency :: integer(), - frequency_period :: integer(), - init :: fun((gleam@otp@supervisor:children(any())) -> gleam@otp@supervisor:children(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl deleted file mode 100644 index 99ab4cb7299..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(status_info, { - module :: gleam@erlang@atom:atom_(), - parent :: gleam@erlang@process:pid_(), - mode :: gleam@otp@system:mode(), - debug_state :: gleam@otp@system:debug_state(), - state :: gleam@dynamic:dynamic_() -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl deleted file mode 100644 index 7c83874c276..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl +++ /dev/null @@ -1 +0,0 @@ --record(exit, {reason :: gleam@dynamic:dynamic_()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl deleted file mode 100644 index 959bea8e9b9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(task, { - owner :: gleam@erlang@process:pid_(), - pid :: gleam@erlang@process:pid_(), - monitor :: gleam@erlang@process:process_monitor(), - selector :: gleam@erlang@process:selector(gleam@otp@task:message(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam deleted file mode 100644 index 9f6a6c41b06..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/actor.gleam +++ /dev/null @@ -1,504 +0,0 @@ -//// This module provides the _Actor_ abstraction, one of the most common -//// building blocks of Gleam OTP programs. -//// -//// An Actor is a process like any other BEAM process and can be be used to hold -//// state, execute code, and communicate with other processes by sending and -//// receiving messages. The advantage of using the actor abstraction over a bare -//// process is that it provides a single interface for commonly needed -//// functionality, including support for the [tracing and debugging -//// features in OTP](erlang-sys). -//// -//// Gleam's Actor is similar to Erlang's `gen_server` and Elixir's `GenServer` -//// but differs in that it offers a fully typed interface. This different API is -//// why Gleam uses the name Actor rather than some variation of generic-server. -//// -//// [erlang-sys]: https://www.erlang.org/doc/man/sys.html -//// -//// ## Example -//// -//// An Actor can be used to create a client-server interaction between an Actor -//// (the server) and other processes (the clients). In this example we have an -//// Actor that works as a stack, allowing clients to push and pop elements. -//// -//// ```gleam -//// pub fn main() { -//// // Start the actor with initial state of an empty list, and the -//// // `handle_message` callback function (defined below). -//// // We assert that it starts successfully. -//// // -//// // In real-world Gleam OTP programs we would likely write a wrapper functions -//// // called `start`, `push` `pop`, `shutdown` to start and interact with the -//// // Actor. We are not doing that here for the sake of showing how the Actor -//// // API works. -//// let assert Ok(actor) = actor.start([], handle_message) -//// -//// // We can send a message to the actor to push elements onto the stack. -//// process.send(actor, Push("Joe")) -//// process.send(actor, Push("Mike")) -//// process.send(actor, Push("Robert")) -//// -//// // The `Push` message expects no response, these messages are sent purely for -//// // the side effect of mutating the state held by the actor. -//// // -//// // We can also send the `Pop` message to take a value off of the actor's -//// // stack. This message expects a response, so we use `process.call` to send a -//// // message and wait until a reply is received. -//// // -//// // In this instance we are giving the actor 10 milliseconds to reply, if the -//// // `call` function doesn't get a reply within this time it will panic and -//// // crash the client process. -//// let assert Ok("Robert") = process.call(actor, Pop, 10) -//// let assert Ok("Mike") = process.call(actor, Pop, 10) -//// let assert Ok("Joe") = process.call(actor, Pop, 10) -//// -//// // The stack is now empty, so if we pop again the actor replies with an error. -//// let assert Error(Nil) = process.call(actor, Pop, 10) -//// -//// // Lastly, we can send a message to the actor asking it to shut down. -//// process.send(actor, Shutdown) -//// } -//// ``` -//// -//// Here is the code that is used to implement this actor: -//// -//// ```gleam -//// // First step of implementing the stack Actor is to define the message type that -//// // it can receive. -//// // -//// // The type of the elements in the stack is no fixed so a type parameter is used -//// // for it instead of a concrete type such as `String` or `Int`. -//// pub type Message(element) { -//// // The `Shutdown` message is used to tell the actor to stop. -//// // It is the simplest message type, it contains no data. -//// Shutdown -//// -//// // The `Push` message is used to add a new element to the stack. -//// // It contains the item to add, the type of which is the `element` -//// // parameterised type. -//// Push(push: element) -//// -//// // The `Pop` message is used to remove an element from the stack. -//// // It contains a `Subject`, which is used to send the response back to the -//// // message sender. In this case the reply is of type `Result(element, Nil)`. -//// Pop(reply_with: Subject(Result(element, Nil))) -//// } -//// -//// // The last part is to implement the `handle_message` callback function. -//// // -//// // This function is called by the Actor each for each message it receives. -//// // Actor is single threaded only does one thing at a time, so it handles -//// // messages sequentially and one at a time, in the order they are received. -//// // -//// // The function takes the message and the current state, and returns a data -//// // structure that indicates what to do next, along with the new state. -//// fn handle_message( -//// message: Message(e), -//// stack: List(e), -//// ) -> actor.Next(Message(e), List(e)) { -//// case message { -//// // For the `Shutdown` message we return the `actor.Stop` value, which causes -//// // the actor to discard any remaining messages and stop. -//// Shutdown -> actor.Stop(process.Normal) -//// -//// // For the `Push` message we add the new element to the stack and return -//// // `actor.continue` with this new stack, causing the actor to process any -//// // queued messages or wait for more. -//// Push(value) -> { -//// let new_state = [value, ..stack] -//// actor.continue(new_state) -//// } -//// -//// // For the `Pop` message we attempt to remove an element from the stack, -//// // sending it or an error back to the caller, before continuing. -//// Pop(client) -> -//// case stack { -//// [] -> { -//// // When the stack is empty we can't pop an element, so we send an -//// // error back. -//// process.send(client, Error(Nil)) -//// actor.continue([]) -//// } -//// -//// [first, ..rest] -> { -//// // Otherwise we send the first element back and use the remaining -//// // elements as the new state. -//// process.send(client, Ok(first)) -//// actor.continue(rest) -//// } -//// } -//// } -//// } -//// ``` - -import gleam/erlang/process.{ - type ExitReason, type Pid, type Selector, type Subject, Abnormal, -} -import gleam/erlang/charlist.{type Charlist} -import gleam/otp/system.{ - type DebugState, type Mode, type StatusInfo, type SystemMessage, GetState, - GetStatus, Resume, Running, StatusInfo, Suspend, Suspended, -} -import gleam/string -import gleam/dynamic.{type Dynamic} -import gleam/erlang/atom -import gleam/option.{type Option, None, Some} - -type Message(message) { - /// A regular message excepted by the process - Message(message) - - /// An OTP system message, for debugging or maintenance - System(SystemMessage) - - /// An unexpected message - Unexpected(Dynamic) -} - -/// The type used to indicate what to do after handling a message. -/// -pub type Next(message, state) { - /// Continue handling messages. - /// - Continue(state: state, selector: Option(Selector(message))) - - /// Stop handling messages and shut down. - /// - Stop(ExitReason) -} - -pub fn continue(state: state) -> Next(message, state) { - Continue(state, None) -} - -pub fn with_selector( - value: Next(message, state), - selector: Selector(message), -) -> Next(message, state) { - case value { - Continue(state, _) -> Continue(state, Some(selector)) - _ -> value - } -} - -/// The type used to indicate whether an actor has started successfully or not. -/// -pub type InitResult(state, message) { - /// The actor has successfully initialised. The actor can start handling - /// messages and actor's channel sender can be returned to the parent - /// process. - /// - Ready(state: state, selector: Selector(message)) - - /// The actor has failed to initialise. The actor shuts down and an error is - /// returned to the parent process. - /// - Failed(String) -} - -type Self(state, msg) { - Self( - mode: Mode, - parent: Pid, - state: state, - subject: Subject(msg), - selector: Selector(Message(msg)), - debug_state: DebugState, - message_handler: fn(msg, state) -> Next(msg, state), - ) -} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an actor. -/// -/// If you do not need to configure the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub type Spec(state, msg) { - Spec( - /// The initialisation functionality for the actor. This function is called - /// just after the actor starts but before the channel sender is returned - /// to the parent. - /// - /// This function is used to ensure that any required data or state is - /// correct. If this function returns an error it means that the actor has - /// failed to start and an error is returned to the parent. - /// - init: fn() -> InitResult(state, msg), - /// How many milliseconds the `init` function has to return before it is - /// considered to have taken too long and failed. - /// - init_timeout: Int, - /// This function is called to handle each message that the actor receives. - /// - loop: fn(msg, state) -> Next(msg, state), - ) -} - -// TODO: Check needed functionality here to be OTP compatible -fn exit_process(reason: ExitReason) -> ExitReason { - // TODO - reason -} - -fn receive_message(self: Self(state, msg)) -> Message(msg) { - let selector = case self.mode { - // When suspended we only respond to system messages - Suspended -> - process.new_selector() - |> selecting_system_messages - - // When running we respond to all messages - Running -> - // We add the handler for unexpected messages first so that the user - // supplied selector can override it if desired - process.new_selector() - |> process.selecting_anything(Unexpected) - |> process.merge_selector(self.selector) - |> selecting_system_messages - } - - process.select_forever(selector) -} - -fn selecting_system_messages( - selector: Selector(Message(msg)), -) -> Selector(Message(msg)) { - selector - |> process.selecting_record3( - atom.create_from_string("system"), - convert_system_message, - ) -} - -@external(erlang, "gleam_otp_external", "convert_system_message") -fn convert_system_message(a: Dynamic, b: Dynamic) -> Message(msg) - -fn process_status_info(self: Self(state, msg)) -> StatusInfo { - StatusInfo( - module: atom.create_from_string("gleam@otp@actor"), - parent: self.parent, - mode: self.mode, - debug_state: self.debug_state, - state: dynamic.from(self.state), - ) -} - -fn loop(self: Self(state, msg)) -> ExitReason { - case receive_message(self) { - System(system) -> - case system { - GetState(callback) -> { - callback(dynamic.from(self.state)) - loop(self) - } - Resume(callback) -> { - callback() - loop(Self(..self, mode: Running)) - } - Suspend(callback) -> { - callback() - loop(Self(..self, mode: Suspended)) - } - GetStatus(callback) -> { - callback(process_status_info(self)) - loop(self) - } - } - - Unexpected(message) -> { - log_warning( - charlist.from_string("Actor discarding unexpected message: ~s"), - [charlist.from_string(string.inspect(message))], - ) - loop(self) - } - - Message(msg) -> - case self.message_handler(msg, self.state) { - Stop(reason) -> exit_process(reason) - Continue(state: state, selector: new_selector) -> { - let selector = - new_selector - |> option.map(init_selector(self.subject, _)) - |> option.unwrap(self.selector) - loop(Self(..self, state: state, selector: selector)) - } - } - } -} - -// TODO: replace this when we have Gleam bindings to the logger -@external(erlang, "logger", "warning") -fn log_warning(a: Charlist, b: List(Charlist)) -> Nil - -fn initialise_actor( - spec: Spec(state, msg), - ack: Subject(Result(Subject(msg), ExitReason)), -) { - let subject = process.new_subject() - case spec.init() { - Ready(state, selector) -> { - let selector = init_selector(subject, selector) - // Signal to parent that the process has initialised successfully - process.send(ack, Ok(subject)) - // Start message receive loop - let self = - Self( - state: state, - parent: process.subject_owner(ack), - subject: subject, - selector: selector, - message_handler: spec.loop, - debug_state: system.debug_state([]), - mode: Running, - ) - loop(self) - } - - Failed(reason) -> { - process.send(ack, Error(Abnormal(reason))) - exit_process(Abnormal(reason)) - } - } -} - -fn init_selector(subject, selector) { - process.new_selector() - |> process.selecting(subject, Message) - |> process.merge_selector(process.map_selector(selector, Message)) -} - -pub type StartError { - InitTimeout - InitFailed(ExitReason) - InitCrashed(Dynamic) -} - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - Result(Subject(msg), StartError) - -/// An Erlang supervisor compatible process start result. -/// -/// If you wish to convert this into a `StartResult` compatible with Gleam -/// supervisors see the `from_erlang_start_result` and `wrap_erlang_starter` -/// functions. -/// -pub type ErlangStartResult = - Result(Pid, Dynamic) - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - case res { - Ok(x) -> Ok(process.subject_owner(x)) - Error(x) -> Error(dynamic.from(x)) - } -} - -type StartInitMessage(msg) { - Ack(Result(Subject(msg), ExitReason)) - Mon(process.ProcessDown) -} - -// TODO: test init_timeout. Currently if we test it eunit prints an error from -// the process death. How do we avoid this? -// -/// Start an actor from a given specification. If the actor's `init` function -/// returns an error or does not return within `init_timeout` then an error is -/// returned. -/// -/// If you do not need to specify the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub fn start_spec(spec: Spec(state, msg)) -> Result(Subject(msg), StartError) { - let ack_subject = process.new_subject() - - let child = - process.start( - linked: True, - running: fn() { initialise_actor(spec, ack_subject) }, - ) - - let monitor = process.monitor_process(child) - let selector = - process.new_selector() - |> process.selecting(ack_subject, Ack) - |> process.selecting_process_down(monitor, Mon) - - let result = case process.select(selector, spec.init_timeout) { - // Child started OK - Ok(Ack(Ok(channel))) -> Ok(channel) - - // Child initialiser returned an error - Ok(Ack(Error(reason))) -> Error(InitFailed(reason)) - - // Child went down while initialising - Ok(Mon(down)) -> Error(InitCrashed(down.reason)) - - // Child did not finish initialising in time - Error(Nil) -> { - process.kill(child) - Error(InitTimeout) - } - } - - // Remove the monitor used for the starting of the actor as to avoid an extra - // message arriving at the parent if the child dies later. - process.demonitor_process(monitor) - - result -} - -/// Start an actor with a given initial state and message handling loop -/// function. -/// -/// This function returns a `Result` but it will always be `Ok` so it is safe -/// to use with `assert` if you are not starting this actor as part of a -/// supervision tree. -/// -/// If you wish to configure the initialisation behaviour of a new actor see -/// the `Spec` record and the `start_spec` function. -/// -pub fn start( - state: state, - loop: fn(msg, state) -> Next(msg, state), -) -> Result(Subject(msg), StartError) { - start_spec(Spec( - init: fn() { Ready(state, process.new_selector()) }, - loop: loop, - init_timeout: 5000, - )) -} - -/// Send a message over a given channel. -/// -/// This is a re-export of `process.send`, for the sake of convenience. -/// -pub fn send(subject: Subject(msg), msg: msg) -> Nil { - process.send(subject, msg) -} - -// TODO: test -/// Send a synchronous message and wait for a response from the receiving -/// process. -/// -/// If a reply is not received within the given timeout then the sender process -/// crashes. If you wish receive a `Result` rather than crashing see the -/// `process.try_call` function. -/// -/// This is a re-export of `process.call`, for the sake of convenience. -/// -pub fn call( - selector: Subject(message), - make_message: fn(Subject(reply)) -> message, - timeout: Int, -) -> reply { - process.call(selector, make_message, timeout) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam deleted file mode 100644 index 2044be09787..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam +++ /dev/null @@ -1,46 +0,0 @@ -//// The intensity tracker is used to monitor how frequently an event happens, -//// erroring if it happens too many times within a period of time. - -import gleam/list - -// TODO: test -pub opaque type IntensityTracker { - IntensityTracker(limit: Int, period: Int, events: List(Int)) -} - -pub type TooIntense { - TooIntense -} - -pub fn new(limit limit: Int, period period: Int) -> IntensityTracker { - IntensityTracker(limit: limit, period: period, events: []) -} - -@external(erlang, "erlang", "monotonic_time") -fn monotonic_time(a: Int) -> Int - -fn now_seconds() -> Int { - monotonic_time(1) -} - -pub fn trim_window(events: List(Int), now: Int, period: Int) -> List(Int) { - case events { - [] -> [] - [event, ..events] -> - case now >= event + period { - True -> [event, ..trim_window(events, now, period)] - False -> [] - } - } -} - -pub fn add_event( - tracker: IntensityTracker, -) -> Result(IntensityTracker, TooIntense) { - let now = now_seconds() - let events = trim_window([now, ..tracker.events], now, tracker.period) - case list.length(events) >= tracker.limit { - True -> Error(TooIntense) - False -> Ok(IntensityTracker(..tracker, events: events)) - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam deleted file mode 100644 index 4e1b4d81285..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/port.gleam +++ /dev/null @@ -1,9 +0,0 @@ -/// Ports are how code running on the Erlang virtual machine interacts with -/// the outside world. Bytes of data can be sent to and read from ports, -/// providing a form of message passing to an external program or resource. -/// -/// For more information on ports see the [Erlang ports documentation][1]. -/// -/// [1]: https://erlang.org/doc/reference_manual/ports.html -/// -pub type Port diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam deleted file mode 100644 index b99ad8efb82..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam +++ /dev/null @@ -1,410 +0,0 @@ -// TODO: specify amount of time permitted for shut-down -import gleam/result -import gleam/string -import gleam/option.{type Option, None, Some} -import gleam/erlang/process.{type Pid, type Subject} -import gleam/otp/actor.{type StartError} -import gleam/otp/intensity_tracker.{type IntensityTracker} -import gleam/erlang/node.{type Node} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an supervisor. -/// -/// If you do not need to configure the behaviour of your supervisor consider -/// using the `start` function. -/// -pub type Spec(argument, return) { - Spec( - argument: argument, - max_frequency: Int, - frequency_period: Int, - init: fn(Children(argument)) -> Children(return), - ) -} - -/// This type represents the starting children of a supervisor within the -/// `init` function. -/// -pub opaque type Children(argument) { - Ready(Starter(argument)) - Failed(ChildStartError) -} - -/// This type contains all the information required to start a new child and -/// add it to the `Children`. -/// -/// This is typically created with the `worker` function. -/// -pub opaque type ChildSpec(msg, argument, returning) { - ChildSpec( - // TODO: merge this into one field - start: fn(argument) -> Result(Subject(msg), StartError), - returning: fn(argument, Subject(msg)) -> returning, - ) -} - -type ChildStartError { - ChildStartError(previous_pid: Option(Pid), error: StartError) -} - -pub opaque type Message { - Exit(process.ExitMessage) - RetryRestart(Pid) -} - -type Instruction { - StartAll - StartFrom(Pid) -} - -type State(a) { - State( - restarts: IntensityTracker, - starter: Starter(a), - retry_restarts: Subject(Pid), - ) -} - -type Starter(argument) { - Starter( - argument: argument, - exec: Option( - fn(Instruction) -> - Result(#(Starter(argument), Instruction), ChildStartError), - ), - ) -} - -type Child(argument) { - Child(pid: Pid, argument: argument) -} - -fn start_child( - child_spec: ChildSpec(msg, argument_in, argument_out), - argument: argument_in, -) -> Result(Child(argument_out), ChildStartError) { - use subject <- result.then( - child_spec.start(argument) - |> result.map_error(ChildStartError(None, _)), - ) - - Ok(Child( - pid: process.subject_owner(subject), - // Merge the new child's pid into the argument to produce the new argument - // used to start any remaining children. - argument: child_spec.returning(argument, subject), - )) -} - -// TODO: more sophsiticated stopping of processes. i.e. give supervisors -// more time to shut down. -fn shutdown_child(pid: Pid, _spec: ChildSpec(msg, arg_1, arg_2)) -> Nil { - process.send_exit(pid) -} - -fn perform_instruction_for_child( - argument: argument_in, - instruction: Instruction, - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Result(#(Child(argument_out), Instruction), ChildStartError) { - let current = child.pid - case instruction { - // This child is older than the StartFrom target, we don't need to - // restart it - StartFrom(target) if target != current -> Ok(#(child, instruction)) - - // This pid either is the cause of the problem, or we have the StartAll - // instruction. Either way it and its younger siblings need to be restarted. - _ -> { - shutdown_child(current, child_spec) - use child <- result.then(start_child(child_spec, argument)) - Ok(#(child, StartAll)) - } - } -} - -fn add_child_to_starter( - starter: Starter(argument_in), - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Starter(argument_out) { - let starter = fn(instruction) { - // Restart the older children. We use `try` to return early if the older - // children failed to start - use #(starter, instruction) <- result.then(case starter.exec { - Some(start) -> start(instruction) - None -> Ok(#(starter, instruction)) - }) - - // Perform the instruction, restarting the child as required - use #(child, instruction) <- result.then(perform_instruction_for_child( - starter.argument, - instruction, - child_spec, - child, - )) - - // Create a new starter for the next time the supervisor needs to restart - let starter = add_child_to_starter(starter, child_spec, child) - - Ok(#(starter, instruction)) - } - - Starter(exec: Some(starter), argument: child.argument) -} - -fn start_and_add_child( - state: Starter(argument_0), - child_spec: ChildSpec(msg, argument_0, argument_1), -) -> Children(argument_1) { - case start_child(child_spec, state.argument) { - Ok(child) -> Ready(add_child_to_starter(state, child_spec, child)) - Error(reason) -> Failed(reason) - } -} - -/// Add a child to the collection of children of the supervisor -/// -/// This function starts the child from the child spec. -/// -pub fn add( - children: Children(argument), - child_spec: ChildSpec(msg, argument, new_argument), -) -> Children(new_argument) { - case children { - // If one of the previous children has failed then we cannot continue - Failed(fail) -> Failed(fail) - - // If everything is OK so far then we can add the child - Ready(state) -> start_and_add_child(state, child_spec) - } -} - -// TODO: test -// TODO: unlimitd shut down duration -/// Prepare a new supervisor type child. -/// -/// If you wish to prepare a new non-supervisor type child see the `worker` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -/// Note: Gleam supervisors do not yet support different shutdown periods per -/// child so this function is currently identical in behaviour to `worker`. It is -/// recommended to use this function for supervisor children nevertheless so the -/// correct shut down behaviour is used in later releases of this library. -/// -pub fn supervisor( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -/// Prepare a new worker type child. -/// -/// If you wish to prepare a new supervisor type child see the `supervisor` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -pub fn worker( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -// TODO: test -/// As each child is added to a supervisors children a new argument is prepared -/// with which to start the next child. By default argument is the same as the -/// previous argument, but this function can be used to change it to something -/// else by passing a function that takes the previous argument and the sender -/// of the previous child. -/// -pub fn returning( - child: ChildSpec(msg, argument_a, argument_b), - updater: fn(argument_a, Subject(msg)) -> argument_c, -) -> ChildSpec(msg, argument_a, argument_c) { - ChildSpec(start: child.start, returning: updater) -} - -fn init( - spec: Spec(argument, return), -) -> actor.InitResult(State(return), Message) { - // Create a subject so that we can asynchronously retry restarting when we - // fail to bring an exited child - let retry = process.new_subject() - - // Trap exits so that we get a message when a child crashes - process.trap_exits(True) - - // Combine selectors - let selector = - process.new_selector() - |> process.selecting(retry, RetryRestart) - |> process.selecting_trapped_exits(Exit) - - // Start any children - let result = - Starter(argument: spec.argument, exec: None) - |> Ready - |> spec.init - - // Pass back up the result - case result { - Ready(starter) -> { - let restarts = - intensity_tracker.new( - limit: spec.max_frequency, - period: spec.frequency_period, - ) - let state = - State(starter: starter, restarts: restarts, retry_restarts: retry) - actor.Ready(state, selector) - } - - Failed(error) -> - actor.Failed(case error.error { - actor.InitTimeout -> "Child initialisation timed out" - actor.InitCrashed(reason) -> - string.append( - "Child crashed during initialisation: ", - string.inspect(reason), - ) - actor.InitFailed(reason) -> - string.append( - "Child failed to start during initialisation: ", - string.inspect(reason), - ) - }) - } -} - -type HandleExitError { - RestartFailed(pid: Pid, restarts: IntensityTracker) - TooManyRestarts -} - -fn handle_exit(pid: Pid, state: State(a)) -> actor.Next(Message, State(a)) { - let outcome = { - // If we are handling an exit then we must have some children - let assert Some(start) = state.starter.exec - - // Check to see if there has been too many restarts in this period - use restarts <- result.then( - state.restarts - |> intensity_tracker.add_event - |> result.map_error(fn(_) { TooManyRestarts }), - ) - - // Restart the exited child and any following children - use #(starter, _) <- result.then( - start(StartFrom(pid)) - |> result.map_error(fn(e: ChildStartError) { - RestartFailed(option.unwrap(e.previous_pid, pid), restarts) - }), - ) - - Ok(State(..state, starter: starter, restarts: restarts)) - } - - case outcome { - Ok(state) -> actor.continue(state) - Error(RestartFailed(failed_child, restarts)) -> { - // Asynchronously enqueue the restarting of this child again as we were - // unable to restart them this time. We do this asynchronously as we want - // to have a chance to handle any system messages that have come in. - process.send(state.retry_restarts, failed_child) - let state = State(..state, restarts: restarts) - actor.continue(state) - } - Error(TooManyRestarts) -> - actor.Stop(process.Abnormal( - "Child processes restarted too many times within allowed period", - )) - } -} - -fn loop( - message: Message, - state: State(argument), -) -> actor.Next(Message, State(argument)) { - case message { - Exit(exit_message) -> handle_exit(exit_message.pid, state) - RetryRestart(pid) -> handle_exit(pid, state) - } -} - -/// Start a supervisor from a given specification. -/// -pub fn start_spec(spec: Spec(a, b)) -> Result(Subject(Message), StartError) { - actor.start_spec(actor.Spec( - init: fn() { init(spec) }, - loop: loop, - init_timeout: 60_000, - )) -} - -/// Start a supervisor from a given `init` function. -/// -/// The init argument passed to children will be `Nil` and the maximum restart -/// intensity will be 1 restart per 5 seconds (the same as the default for -/// [Erlang supervisors][erl-sup]). If you wish to specify these values, see -/// the `start_spec` function and the `Spec` type. -/// -/// [erl-sup]: https://www.erlang.org/doc/design_principles/sup_princ.html#maximum-restart-intensity -/// -pub fn start( - init: fn(Children(Nil)) -> Children(a), -) -> Result(Subject(Message), StartError) { - start_spec(Spec( - init: init, - argument: Nil, - max_frequency: 1, - frequency_period: 5, - )) -} - -/// A type used to describe the situation in which an Erlang based application -/// is starting. -/// -/// For more information see the [Erlang distributed application -/// documentation][1] and the Learn Your Some Erlang chapter on [distributed -/// applications][2]. -/// -/// [1]: https://erlang.org/doc/design_principles/distributed_applications.html -/// [2]: https://learnyousomeerlang.com/distributed-otp-applications -/// -pub type ApplicationStartMode { - Normal - Takeover(Node) - Failover(Node) -} - -pub type ApplicationStop - -@external(erlang, "gleam_otp_external", "application_stopped") -pub fn application_stopped() -> ApplicationStop - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - actor.StartResult(msg) - -/// An Erlang supervisor compatible process start result. -/// -pub type ErlangStartResult = - actor.ErlangStartResult - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - actor.to_erlang_start_result(res) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam deleted file mode 100644 index c05646baa26..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/system.gleam +++ /dev/null @@ -1,89 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/erlang/atom.{type Atom} -import gleam/erlang/process.{type Pid} - -pub type Mode { - Running - Suspended -} - -pub type DebugOption { - NoDebug -} - -pub type DebugState - -@external(erlang, "sys", "debug_options") -pub fn debug_state(a: List(DebugOption)) -> DebugState - -pub type StatusInfo { - StatusInfo( - module: Atom, - parent: Pid, - mode: Mode, - debug_state: DebugState, - state: Dynamic, - ) -} - -// TODO: document -// TODO: implement remaining messages -pub type SystemMessage { - // {replace_state, StateFn} - // {change_code, Mod, Vsn, Extra} - // {terminate, Reason} - // {debug, {log, Flag}} - // {debug, {trace, Flag}} - // {debug, {log_to_file, FileName}} - // {debug, {statistics, Flag}} - // {debug, no_debug} - // {debug, {install, {Func, FuncState}}} - // {debug, {install, {FuncId, Func, FuncState}}} - // {debug, {remove, FuncOrId}} - Resume(fn() -> Nil) - Suspend(fn() -> Nil) - GetState(fn(Dynamic) -> Nil) - GetStatus(fn(StatusInfo) -> Nil) -} - -type DoNotLeak - -/// Get the state of a given OTP compatible process. This function is only -/// intended for debugging. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#get_state-1 -/// -@external(erlang, "sys", "get_state") -pub fn get_state(from from: Pid) -> Dynamic - -@external(erlang, "sys", "suspend") -fn erl_suspend(a: Pid) -> DoNotLeak - -/// Request an OTP compatible process to suspend, causing it to only handle -/// system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#suspend-1 -/// -pub fn suspend(pid: Pid) -> Nil { - erl_suspend(pid) - Nil -} - -@external(erlang, "sys", "resume") -fn erl_resume(from from: Pid) -> DoNotLeak - -/// Request a suspended OTP compatible process to result, causing it to handle -/// all messages rather than only system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#resume-1 -/// -pub fn resume(pid: Pid) -> Nil { - erl_resume(pid) - Nil -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam deleted file mode 100644 index b2b2c5c968e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam/otp/task.gleam +++ /dev/null @@ -1,151 +0,0 @@ -//// A task is a kind of process that performs a single task and then shuts -//// down. Commonly tasks are used to convert sequential code into concurrent -//// code by performing computation in another process. -//// -//// let task = task.async(fn() { do_some_work() }) -//// let value = do_some_other_work() -//// value + task.await(task, 100) -//// -//// Tasks spawned with async can be awaited on by their caller process (and -//// only their caller) as shown in the example above. They are implemented by -//// spawning a process that sends a message to the caller once the given -//// computation is performed. -//// -//// There are two important things to consider when using `async`: -//// -//// 1. If you are using async tasks, you must await a reply as they are always -//// sent. -//// -//// 2. async tasks link the caller and the spawned process. This means that, -//// if the caller crashes, the task will crash too and vice-versa. This is -//// on purpose: if the process meant to receive the result no longer -//// exists, there is no purpose in completing the computation. -//// -//// This module is inspired by Elixir's [Task module][1]. -//// -//// [1]: https://hexdocs.pm/elixir/master/Task.html -//// - -// TODO: await_many -import gleam/erlang/process.{type Pid, type ProcessMonitor, type Selector} -import gleam/dynamic.{type Dynamic} - -pub opaque type Task(value) { - Task( - owner: Pid, - pid: Pid, - monitor: ProcessMonitor, - selector: Selector(Message(value)), - ) -} - -// TODO: test -/// Spawn a task process that calls a given function in order to perform some -/// work. The result of this function is send back to the parent and can be -/// received using the `await` function. -/// -/// See the top level module documentation for more information on async/await. -/// -pub fn async(work: fn() -> value) -> Task(value) { - let owner = process.self() - let subject = process.new_subject() - let pid = - process.start(linked: True, running: fn() { process.send(subject, work()) }) - let monitor = process.monitor_process(pid) - let selector = - process.new_selector() - |> process.selecting_process_down(monitor, FromMonitor) - |> process.selecting(subject, FromSubject) - Task(owner: owner, pid: pid, monitor: monitor, selector: selector) -} - -pub type AwaitError { - Timeout - Exit(reason: Dynamic) -} - -// We can only wait on a task if we are the owner of it so crash if we are -// waiting on a task we don't own. -fn assert_owner(task: Task(a)) -> Nil { - let self = process.self() - case task.owner == self { - True -> Nil - False -> - process.send_abnormal_exit( - self, - "awaited on a task that does not belong to this process", - ) - } -} - -type Message(value) { - FromMonitor(process.ProcessDown) - FromSubject(value) -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then an error is returned. -/// -pub fn try_await(task: Task(value), timeout: Int) -> Result(value, AwaitError) { - assert_owner(task) - case process.select(task.selector, timeout) { - // The task process has sent back a value - Ok(FromSubject(x)) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) -> - Error(Exit(reason)) - - // The task process is alive but has not sent a value yet - Error(Nil) -> Error(Timeout) - } -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then this function crashes. -/// -pub fn await(task: Task(value), timeout: Int) -> value { - let assert Ok(value) = try_await(task, timeout) - value -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! This function does not return until there is a value to -/// receive. If a value is not received then the process will be stuck waiting -/// forever. -/// -pub fn try_await_forever(task: Task(value)) -> Result(value, AwaitError) { - assert_owner(task) - case process.select_forever(task.selector) { - // The task process has sent back a value - FromSubject(x) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - FromMonitor(process.ProcessDown(reason: reason, ..)) -> Error(Exit(reason)) - } -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! Like `try_await_forever`, this function does not return until there is a value to -/// receive. -/// -/// If the task process crashes then this function crashes. -/// -pub fn await_forever(task: Task(value)) -> value { - let assert Ok(value) = try_await_forever(task) - value -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl deleted file mode 100644 index 0606147ca13..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@actor.erl +++ /dev/null @@ -1,273 +0,0 @@ --module(gleam@otp@actor). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([continue/1, with_selector/2, to_erlang_start_result/1, start_spec/1, start/2, send/2, call/3]). --export_type([message/1, next/2, init_result/2, self/2, spec/2, start_error/0, start_init_message/1]). - --type message(GAS) :: {message, GAS} | - {system, gleam@otp@system:system_message()} | - {unexpected, gleam@dynamic:dynamic_()}. - --type next(GAT, GAU) :: {continue, - GAU, - gleam@option:option(gleam@erlang@process:selector(GAT))} | - {stop, gleam@erlang@process:exit_reason()}. - --type init_result(GAV, GAW) :: {ready, GAV, gleam@erlang@process:selector(GAW)} | - {failed, binary()}. - --type self(GAX, GAY) :: {self, - gleam@otp@system:mode(), - gleam@erlang@process:pid_(), - GAX, - gleam@erlang@process:subject(GAY), - gleam@erlang@process:selector(message(GAY)), - gleam@otp@system:debug_state(), - fun((GAY, GAX) -> next(GAY, GAX))}. - --type spec(GAZ, GBA) :: {spec, - fun(() -> init_result(GAZ, GBA)), - integer(), - fun((GBA, GAZ) -> next(GBA, GAZ))}. - --type start_error() :: init_timeout | - {init_failed, gleam@erlang@process:exit_reason()} | - {init_crashed, gleam@dynamic:dynamic_()}. - --type start_init_message(GBB) :: {ack, - {ok, gleam@erlang@process:subject(GBB)} | - {error, gleam@erlang@process:exit_reason()}} | - {mon, gleam@erlang@process:process_down()}. - --spec continue(GBI) -> next(any(), GBI). -continue(State) -> - {continue, State, none}. - --spec with_selector(next(GBM, GBN), gleam@erlang@process:selector(GBM)) -> next(GBM, GBN). -with_selector(Value, Selector) -> - case Value of - {continue, State, _} -> - {continue, State, {some, Selector}}; - - _ -> - Value - end. - --spec exit_process(gleam@erlang@process:exit_reason()) -> gleam@erlang@process:exit_reason(). -exit_process(Reason) -> - Reason. - --spec selecting_system_messages(gleam@erlang@process:selector(message(GBY))) -> gleam@erlang@process:selector(message(GBY)). -selecting_system_messages(Selector) -> - _pipe = Selector, - gleam@erlang@process:selecting_record3( - _pipe, - erlang:binary_to_atom(<<"system"/utf8>>), - fun gleam_otp_external:convert_system_message/2 - ). - --spec receive_message(self(any(), GBU)) -> message(GBU). -receive_message(Self) -> - Selector = case erlang:element(2, Self) of - suspended -> - _pipe = gleam_erlang_ffi:new_selector(), - selecting_system_messages(_pipe); - - running -> - _pipe@1 = gleam_erlang_ffi:new_selector(), - _pipe@2 = gleam@erlang@process:selecting_anything( - _pipe@1, - fun(Field@0) -> {unexpected, Field@0} end - ), - _pipe@3 = gleam_erlang_ffi:merge_selector( - _pipe@2, - erlang:element(6, Self) - ), - selecting_system_messages(_pipe@3) - end, - gleam_erlang_ffi:select(Selector). - --spec process_status_info(self(any(), any())) -> gleam@otp@system:status_info(). -process_status_info(Self) -> - {status_info, - erlang:binary_to_atom(<<"gleam@otp@actor"/utf8>>), - erlang:element(3, Self), - erlang:element(2, Self), - erlang:element(7, Self), - gleam@dynamic:from(erlang:element(4, Self))}. - --spec init_selector( - gleam@erlang@process:subject(GGN), - gleam@erlang@process:selector(GGN) -) -> gleam@erlang@process:selector(message(GGN)). -init_selector(Subject, Selector) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun(Field@0) -> {message, Field@0} end - ), - gleam_erlang_ffi:merge_selector( - _pipe@1, - gleam_erlang_ffi:map_selector( - Selector, - fun(Field@0) -> {message, Field@0} end - ) - ). - --spec loop(self(any(), any())) -> gleam@erlang@process:exit_reason(). -loop(Self) -> - case receive_message(Self) of - {system, System} -> - case System of - {get_state, Callback} -> - Callback(gleam@dynamic:from(erlang:element(4, Self))), - loop(Self); - - {resume, Callback@1} -> - Callback@1(), - loop(erlang:setelement(2, Self, running)); - - {suspend, Callback@2} -> - Callback@2(), - loop(erlang:setelement(2, Self, suspended)); - - {get_status, Callback@3} -> - Callback@3(process_status_info(Self)), - loop(Self) - end; - - {unexpected, Message} -> - logger:warning( - unicode:characters_to_list( - <<"Actor discarding unexpected message: ~s"/utf8>> - ), - [unicode:characters_to_list(gleam@string:inspect(Message))] - ), - loop(Self); - - {message, Msg} -> - case (erlang:element(8, Self))(Msg, erlang:element(4, Self)) of - {stop, Reason} -> - exit_process(Reason); - - {continue, State, New_selector} -> - Selector = begin - _pipe = New_selector, - _pipe@1 = gleam@option:map( - _pipe, - fun(_capture) -> - init_selector(erlang:element(5, Self), _capture) - end - ), - gleam@option:unwrap(_pipe@1, erlang:element(6, Self)) - end, - loop( - erlang:setelement( - 6, - erlang:setelement(4, Self, State), - Selector - ) - ) - end - end. - --spec initialise_actor( - spec(any(), GCP), - gleam@erlang@process:subject({ok, gleam@erlang@process:subject(GCP)} | - {error, gleam@erlang@process:exit_reason()}) -) -> gleam@erlang@process:exit_reason(). -initialise_actor(Spec, Ack) -> - Subject = gleam@erlang@process:new_subject(), - case (erlang:element(2, Spec))() of - {ready, State, Selector} -> - Selector@1 = init_selector(Subject, Selector), - gleam@erlang@process:send(Ack, {ok, Subject}), - Self = {self, - running, - gleam@erlang@process:subject_owner(Ack), - State, - Subject, - Selector@1, - sys:debug_options([]), - erlang:element(4, Spec)}, - loop(Self); - - {failed, Reason} -> - gleam@erlang@process:send(Ack, {error, {abnormal, Reason}}), - exit_process({abnormal, Reason}) - end. - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | {error, start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. -to_erlang_start_result(Res) -> - case Res of - {ok, X} -> - {ok, gleam@erlang@process:subject_owner(X)}; - - {error, X@1} -> - {error, gleam@dynamic:from(X@1)} - end. - --spec start_spec(spec(any(), GDD)) -> {ok, gleam@erlang@process:subject(GDD)} | - {error, start_error()}. -start_spec(Spec) -> - Ack_subject = gleam@erlang@process:new_subject(), - Child = gleam@erlang@process:start( - fun() -> initialise_actor(Spec, Ack_subject) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Child), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Ack_subject, - fun(Field@0) -> {ack, Field@0} end - ), - gleam@erlang@process:selecting_process_down( - _pipe@1, - Monitor, - fun(Field@0) -> {mon, Field@0} end - ) - end, - Result = case gleam_erlang_ffi:select(Selector, erlang:element(3, Spec)) of - {ok, {ack, {ok, Channel}}} -> - {ok, Channel}; - - {ok, {ack, {error, Reason}}} -> - {error, {init_failed, Reason}}; - - {ok, {mon, Down}} -> - {error, {init_crashed, erlang:element(3, Down)}}; - - {error, nil} -> - gleam@erlang@process:kill(Child), - {error, init_timeout} - end, - gleam_erlang_ffi:demonitor(Monitor), - Result. - --spec start(GDJ, fun((GDK, GDJ) -> next(GDK, GDJ))) -> {ok, - gleam@erlang@process:subject(GDK)} | - {error, start_error()}. -start(State, Loop) -> - start_spec( - {spec, - fun() -> {ready, State, gleam_erlang_ffi:new_selector()} end, - 5000, - Loop} - ). - --spec send(gleam@erlang@process:subject(GDQ), GDQ) -> nil. -send(Subject, Msg) -> - gleam@erlang@process:send(Subject, Msg). - --spec call( - gleam@erlang@process:subject(GDS), - fun((gleam@erlang@process:subject(GDU)) -> GDS), - integer() -) -> GDU. -call(Selector, Make_message, Timeout) -> - gleam@erlang@process:call(Selector, Make_message, Timeout). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl deleted file mode 100644 index 8792f143c9a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(gleam@otp@intensity_tracker). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/2, trim_window/3, add_event/1]). --export_type([intensity_tracker/0, too_intense/0]). - --opaque intensity_tracker() :: {intensity_tracker, - integer(), - integer(), - list(integer())}. - --type too_intense() :: too_intense. - --spec new(integer(), integer()) -> intensity_tracker(). -new(Limit, Period) -> - {intensity_tracker, Limit, Period, []}. - --spec now_seconds() -> integer(). -now_seconds() -> - erlang:monotonic_time(1). - --spec trim_window(list(integer()), integer(), integer()) -> list(integer()). -trim_window(Events, Now, Period) -> - case Events of - [] -> - []; - - [Event | Events@1] -> - case Now >= (Event + Period) of - true -> - [Event | trim_window(Events@1, Now, Period)]; - - false -> - [] - end - end. - --spec add_event(intensity_tracker()) -> {ok, intensity_tracker()} | - {error, too_intense()}. -add_event(Tracker) -> - Now = now_seconds(), - Events = trim_window( - [Now | erlang:element(4, Tracker)], - Now, - erlang:element(3, Tracker) - ), - case gleam@list:length(Events) >= erlang:element(2, Tracker) of - true -> - {error, too_intense}; - - false -> - {ok, erlang:setelement(4, Tracker, Events)} - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl deleted file mode 100644 index b2057392ae4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@port.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gleam@otp@port). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([port_/0]). - --type port_() :: any(). - - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl deleted file mode 100644 index 39118f1a5ae..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@supervisor.erl +++ /dev/null @@ -1,322 +0,0 @@ --module(gleam@otp@supervisor). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([add/2, supervisor/1, worker/1, returning/2, start_spec/1, start/1, application_stopped/0, to_erlang_start_result/1]). --export_type([spec/2, children/1, child_spec/3, child_start_error/0, message/0, instruction/0, state/1, starter/1, child/1, handle_exit_error/0, application_start_mode/0, application_stop/0]). - --type spec(GLS, GLT) :: {spec, - GLS, - integer(), - integer(), - fun((children(GLS)) -> children(GLT))}. - --opaque children(GLU) :: {ready, starter(GLU)} | {failed, child_start_error()}. - --opaque child_spec(GLV, GLW, GLX) :: {child_spec, - fun((GLW) -> {ok, gleam@erlang@process:subject(GLV)} | - {error, gleam@otp@actor:start_error()}), - fun((GLW, gleam@erlang@process:subject(GLV)) -> GLX)}. - --type child_start_error() :: {child_start_error, - gleam@option:option(gleam@erlang@process:pid_()), - gleam@otp@actor:start_error()}. - --opaque message() :: {exit, gleam@erlang@process:exit_message()} | - {retry_restart, gleam@erlang@process:pid_()}. - --type instruction() :: start_all | {start_from, gleam@erlang@process:pid_()}. - --type state(GLY) :: {state, - gleam@otp@intensity_tracker:intensity_tracker(), - starter(GLY), - gleam@erlang@process:subject(gleam@erlang@process:pid_())}. - --type starter(GLZ) :: {starter, - GLZ, - gleam@option:option(fun((instruction()) -> {ok, - {starter(GLZ), instruction()}} | - {error, child_start_error()}))}. - --type child(GMA) :: {child, gleam@erlang@process:pid_(), GMA}. - --type handle_exit_error() :: {restart_failed, - gleam@erlang@process:pid_(), - gleam@otp@intensity_tracker:intensity_tracker()} | - too_many_restarts. - --type application_start_mode() :: normal | - {takeover, gleam@erlang@node:node_()} | - {failover, gleam@erlang@node:node_()}. - --type application_stop() :: any(). - --spec start_child(child_spec(any(), GME, GMF), GME) -> {ok, child(GMF)} | - {error, child_start_error()}. -start_child(Child_spec, Argument) -> - gleam@result:then( - begin - _pipe = (erlang:element(2, Child_spec))(Argument), - gleam@result:map_error( - _pipe, - fun(_capture) -> {child_start_error, none, _capture} end - ) - end, - fun(Subject) -> - {ok, - {child, - gleam@erlang@process:subject_owner(Subject), - (erlang:element(3, Child_spec))(Argument, Subject)}} - end - ). - --spec shutdown_child( - gleam@erlang@process:pid_(), - child_spec(any(), any(), any()) -) -> nil. -shutdown_child(Pid, _) -> - gleam@erlang@process:send_exit(Pid). - --spec perform_instruction_for_child( - GMS, - instruction(), - child_spec(any(), GMS, GMU), - child(GMU) -) -> {ok, {child(GMU), instruction()}} | {error, child_start_error()}. -perform_instruction_for_child(Argument, Instruction, Child_spec, Child) -> - Current = erlang:element(2, Child), - case Instruction of - {start_from, Target} when Target =/= Current -> - {ok, {Child, Instruction}}; - - _ -> - shutdown_child(Current, Child_spec), - gleam@result:then( - start_child(Child_spec, Argument), - fun(Child@1) -> {ok, {Child@1, start_all}} end - ) - end. - --spec add_child_to_starter( - starter(GNC), - child_spec(any(), GNC, GNF), - child(GNF) -) -> starter(GNF). -add_child_to_starter(Starter, Child_spec, Child) -> - Starter@3 = fun(Instruction) -> - gleam@result:then(case erlang:element(3, Starter) of - {some, Start} -> - Start(Instruction); - - none -> - {ok, {Starter, Instruction}} - end, fun(_use0) -> - {Starter@1, Instruction@1} = _use0, - gleam@result:then( - perform_instruction_for_child( - erlang:element(2, Starter@1), - Instruction@1, - Child_spec, - Child - ), - fun(_use0@1) -> - {Child@1, Instruction@2} = _use0@1, - Starter@2 = add_child_to_starter( - Starter@1, - Child_spec, - Child@1 - ), - {ok, {Starter@2, Instruction@2}} - end - ) - end) - end, - {starter, erlang:element(3, Child), {some, Starter@3}}. - --spec start_and_add_child(starter(GNL), child_spec(any(), GNL, GNO)) -> children(GNO). -start_and_add_child(State, Child_spec) -> - case start_child(Child_spec, erlang:element(2, State)) of - {ok, Child} -> - {ready, add_child_to_starter(State, Child_spec, Child)}; - - {error, Reason} -> - {failed, Reason} - end. - --spec add(children(GNT), child_spec(any(), GNT, GNW)) -> children(GNW). -add(Children, Child_spec) -> - case Children of - {failed, Fail} -> - {failed, Fail}; - - {ready, State} -> - start_and_add_child(State, Child_spec) - end. - --spec supervisor( - fun((GOB) -> {ok, gleam@erlang@process:subject(GOC)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(GOC, GOB, GOB). -supervisor(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec worker( - fun((GOJ) -> {ok, gleam@erlang@process:subject(GOK)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(GOK, GOJ, GOJ). -worker(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec returning( - child_spec(GOR, GOS, any()), - fun((GOS, gleam@erlang@process:subject(GOR)) -> GOY) -) -> child_spec(GOR, GOS, GOY). -returning(Child, Updater) -> - {child_spec, erlang:element(2, Child), Updater}. - --spec init(spec(any(), GPD)) -> gleam@otp@actor:init_result(state(GPD), message()). -init(Spec) -> - Retry = gleam@erlang@process:new_subject(), - gleam_erlang_ffi:trap_exits(true), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Retry, - fun(Field@0) -> {retry_restart, Field@0} end - ), - gleam@erlang@process:selecting_trapped_exits( - _pipe@1, - fun(Field@0) -> {exit, Field@0} end - ) - end, - Result = begin - _pipe@2 = {starter, erlang:element(2, Spec), none}, - _pipe@3 = {ready, _pipe@2}, - (erlang:element(5, Spec))(_pipe@3) - end, - case Result of - {ready, Starter} -> - Restarts = gleam@otp@intensity_tracker:new( - erlang:element(3, Spec), - erlang:element(4, Spec) - ), - State = {state, Restarts, Starter, Retry}, - {ready, State, Selector}; - - {failed, Error} -> - {failed, case erlang:element(3, Error) of - init_timeout -> - <<"Child initialisation timed out"/utf8>>; - - {init_crashed, Reason} -> - gleam@string:append( - <<"Child crashed during initialisation: "/utf8>>, - gleam@string:inspect(Reason) - ); - - {init_failed, Reason@1} -> - gleam@string:append( - <<"Child failed to start during initialisation: "/utf8>>, - gleam@string:inspect(Reason@1) - ) - end} - end. - --spec handle_exit(gleam@erlang@process:pid_(), state(GPJ)) -> gleam@otp@actor:next(message(), state(GPJ)). -handle_exit(Pid, State) -> - Outcome = begin - _assert_subject = erlang:element(3, erlang:element(3, State)), - {some, Start} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/supervisor"/utf8>>, - function => <<"handle_exit"/utf8>>, - line => 293}) - end, - gleam@result:then( - begin - _pipe = erlang:element(2, State), - _pipe@1 = gleam@otp@intensity_tracker:add_event(_pipe), - gleam@result:map_error(_pipe@1, fun(_) -> too_many_restarts end) - end, - fun(Restarts) -> - gleam@result:then( - begin - _pipe@2 = Start({start_from, Pid}), - gleam@result:map_error( - _pipe@2, - fun(E) -> - {restart_failed, - gleam@option:unwrap( - erlang:element(2, E), - Pid - ), - Restarts} - end - ) - end, - fun(_use0) -> - {Starter, _} = _use0, - {ok, - erlang:setelement( - 2, - erlang:setelement(3, State, Starter), - Restarts - )} - end - ) - end - ) - end, - case Outcome of - {ok, State@1} -> - gleam@otp@actor:continue(State@1); - - {error, {restart_failed, Failed_child, Restarts@1}} -> - gleam@erlang@process:send(erlang:element(4, State), Failed_child), - State@2 = erlang:setelement(2, State, Restarts@1), - gleam@otp@actor:continue(State@2); - - {error, too_many_restarts} -> - {stop, - {abnormal, - <<"Child processes restarted too many times within allowed period"/utf8>>}} - end. - --spec loop(message(), state(GPO)) -> gleam@otp@actor:next(message(), state(GPO)). -loop(Message, State) -> - case Message of - {exit, Exit_message} -> - handle_exit(erlang:element(2, Exit_message), State); - - {retry_restart, Pid} -> - handle_exit(Pid, State) - end. - --spec start_spec(spec(any(), any())) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start_spec(Spec) -> - gleam@otp@actor:start_spec( - {spec, fun() -> init(Spec) end, 60000, fun loop/2} - ). - --spec start(fun((children(nil)) -> children(any()))) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start(Init) -> - start_spec({spec, nil, 1, 5, Init}). - --spec application_stopped() -> application_stop(). -application_stopped() -> - gleam_otp_external:application_stopped(). - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. -to_erlang_start_result(Res) -> - gleam@otp@actor:to_erlang_start_result(Res). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl deleted file mode 100644 index 622e5ea10bf..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@system.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam@otp@system). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([debug_state/1, get_state/1, suspend/1, resume/1]). --export_type([mode/0, debug_option/0, debug_state/0, status_info/0, system_message/0, do_not_leak/0]). - --type mode() :: running | suspended. - --type debug_option() :: no_debug. - --type debug_state() :: any(). - --type status_info() :: {status_info, - gleam@erlang@atom:atom_(), - gleam@erlang@process:pid_(), - mode(), - debug_state(), - gleam@dynamic:dynamic_()}. - --type system_message() :: {resume, fun(() -> nil)} | - {suspend, fun(() -> nil)} | - {get_state, fun((gleam@dynamic:dynamic_()) -> nil)} | - {get_status, fun((status_info()) -> nil)}. - --type do_not_leak() :: any(). - --spec debug_state(list(debug_option())) -> debug_state(). -debug_state(A) -> - sys:debug_options(A). - --spec get_state(gleam@erlang@process:pid_()) -> gleam@dynamic:dynamic_(). -get_state(From) -> - sys:get_state(From). - --spec suspend(gleam@erlang@process:pid_()) -> nil. -suspend(Pid) -> - sys:suspend(Pid), - nil. - --spec resume(gleam@erlang@process:pid_()) -> nil. -resume(Pid) -> - sys:resume(Pid), - nil. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl deleted file mode 100644 index e00428491f4..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam@otp@task.erl +++ /dev/null @@ -1,111 +0,0 @@ --module(gleam@otp@task). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([async/1, try_await/2, await/2, try_await_forever/1, await_forever/1]). --export_type([task/1, await_error/0, message/1]). - --opaque task(FWJ) :: {task, - gleam@erlang@process:pid_(), - gleam@erlang@process:pid_(), - gleam@erlang@process:process_monitor(), - gleam@erlang@process:selector(message(FWJ))}. - --type await_error() :: timeout | {exit, gleam@dynamic:dynamic_()}. - --type message(FWK) :: {from_monitor, gleam@erlang@process:process_down()} | - {from_subject, FWK}. - --spec async(fun(() -> FWL)) -> task(FWL). -async(Work) -> - Owner = erlang:self(), - Subject = gleam@erlang@process:new_subject(), - Pid = gleam@erlang@process:start( - fun() -> gleam@erlang@process:send(Subject, Work()) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Pid), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting_process_down( - _pipe, - Monitor, - fun(Field@0) -> {from_monitor, Field@0} end - ), - gleam@erlang@process:selecting( - _pipe@1, - Subject, - fun(Field@0) -> {from_subject, Field@0} end - ) - end, - {task, Owner, Pid, Monitor, Selector}. - --spec assert_owner(task(any())) -> nil. -assert_owner(Task) -> - Self = erlang:self(), - case erlang:element(2, Task) =:= Self of - true -> - nil; - - false -> - gleam@erlang@process:send_abnormal_exit( - Self, - <<"awaited on a task that does not belong to this process"/utf8>> - ) - end. - --spec try_await(task(FWP), integer()) -> {ok, FWP} | {error, await_error()}. -try_await(Task, Timeout) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task), Timeout) of - {ok, {from_subject, X}} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {ok, {from_monitor, {process_down, _, Reason}}} -> - {error, {exit, Reason}}; - - {error, nil} -> - {error, timeout} - end. - --spec await(task(FWT), integer()) -> FWT. -await(Task, Timeout) -> - _assert_subject = try_await(Task, Timeout), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await"/utf8>>, - line => 117}) - end, - Value. - --spec try_await_forever(task(FWV)) -> {ok, FWV} | {error, await_error()}. -try_await_forever(Task) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task)) of - {from_subject, X} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {from_monitor, {process_down, _, Reason}} -> - {error, {exit, Reason}} - end. - --spec await_forever(task(FWZ)) -> FWZ. -await_forever(Task) -> - _assert_subject = try_await_forever(Task), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await_forever"/utf8>>, - line => 149}) - end, - Value. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src deleted file mode 100644 index 5c52295ceb9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.app.src +++ /dev/null @@ -1,15 +0,0 @@ -{application, gleam_otp, [ - {vsn, "0.8.0"}, - {applications, [gleam_erlang, - gleam_stdlib, - gleeunit]}, - {description, "Fault tolerant multicore Gleam programs with OTP"}, - {modules, [gleam@otp@actor, - gleam@otp@intensity_tracker, - gleam@otp@port, - gleam@otp@supervisor, - gleam@otp@system, - gleam@otp@task, - gleam_otp]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl deleted file mode 100644 index 9381ad2ac22..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(gleam_otp). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec spawn_task(integer()) -> gleam@otp@task:task(nil). -spawn_task(I) -> - gleam@otp@task:async(fun() -> case (I rem 500) =:= 0 of - true -> - gleam@io:println( - <<"Hello from "/utf8, (gleam@int:to_string(I))/binary>> - ); - - false -> - nil - end end). - --spec main() -> integer(). -main() -> - gleam@io:debug( - gleam_otp_test_external:get_message_queue_length(erlang:self()) - ), - _pipe = gleam@list:range(0, 1000000), - _pipe@1 = gleam@list:map(_pipe, fun spawn_task/1), - gleam@list:each(_pipe@1, fun gleam@otp@task:await_forever/1), - gleam@io:debug( - gleam_otp_test_external:get_message_queue_length(erlang:self()) - ). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam deleted file mode 100644 index 69cdd5bb1e6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp.gleam +++ /dev/null @@ -1,27 +0,0 @@ -import gleam/io -import gleam/int -import gleam/list -import gleam/otp/task -import gleam/erlang/process.{type Pid} - -@external(erlang, "gleam_otp_test_external", "get_message_queue_length") -fn get_message_queue_length(pid pid: Pid) -> Int - -fn spawn_task(i) { - task.async(fn() { - case i % 500 == 0 { - True -> io.println("Hello from " <> int.to_string(i)) - False -> Nil - } - }) -} - -pub fn main() { - io.debug(get_message_queue_length(process.self())) - - list.range(0, 1_000_000) - |> list.map(spawn_task) - |> list.each(task.await_forever) - - io.debug(get_message_queue_length(process.self())) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl deleted file mode 100644 index 8910a67d7e2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_otp/src/gleam_otp_external.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam_otp_external). - --export([application_stopped/0, convert_system_message/2]). - -% TODO: support other system messages -% {replace_state, StateFn} -% {change_code, Mod, Vsn, Extra} -% {terminate, Reason} -% {debug, {log, Flag}} -% {debug, {trace, Flag}} -% {debug, {log_to_file, FileName}} -% {debug, {statistics, Flag}} -% {debug, no_debug} -% {debug, {install, {Func, FuncState}}} -% {debug, {install, {FuncId, Func, FuncState}}} -% {debug, {remove, FuncOrId}} -% GetStatus(Subject(StatusInfo)) -convert_system_message({From, Ref}, Request) when is_pid(From) -> - Reply = fun(Msg) -> - erlang:send(From, {Ref, Msg}), - nil - end, - System = fun(Callback) -> - {system, {Request, Callback}} - end, - case Request of - get_status -> System(fun(Status) -> Reply(process_status(Status)) end); - get_state -> System(Reply); - suspend -> System(fun() -> Reply(ok) end); - resume -> System(fun() -> Reply(ok) end); - Other -> {unexpeceted, Other} - end. - -process_status({status_info, Module, Parent, Mode, DebugState, State}) -> - Data = [ - get(), Mode, Parent, DebugState, - [{header, "Status for Gleam process " ++ pid_to_list(self())}, - {data, [{'Status', Mode}, {'Parent', Parent}, {'State', State}]}] - ], - {status, self(), {module, Module}, Data}. - -application_stopped() -> - ok. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index a978a7ff425..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_stdlib" -version = "0.33.1" -gleam = ">= 0.32.0" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 6e1e2261268..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs deleted file mode 100644 index a8309e0cdbd..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/dict.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of Dict size and clean up the API - * @template K,V - */ -export default class Dict { - /** - * @template V - * @param {Record<string,V>} o - * @returns {Dict<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type Dict<string,V> */ - let m = Dict.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {Dict<K,V>} - */ - static fromMap(o) { - /** @type Dict<K,V> */ - let m = Dict.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new Dict(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {Dict<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {Dict<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return Dict.new(); - } - return new Dict(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof Dict) || this.size !== o.size) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index eab2f0b3fec..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam deleted file mode 100644 index 79860e964ef..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_array.gleam +++ /dev/null @@ -1,157 +0,0 @@ -//// BitArrays are a sequence of binary data of any length. - -import gleam/string - -/// Converts a UTF-8 `String` type into a `BitArray`. -/// -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") -pub fn from_string(x: String) -> BitArray - -/// Returns an integer which is the number of bytes in the bit array. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -pub fn byte_size(x: BitArray) -> Int - -/// Creates a new bit array by joining two bit arrays. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - concat([first, second]) -} - -/// Extracts a sub-section of a bit array. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit array. -/// -/// This function runs in constant time. -/// -@external(erlang, "gleam_stdlib", "bit_array_slice") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) - -/// Tests to see whether a bit array is valid UTF-8. -/// -pub fn is_utf8(bits: BitArray) -> Bool { - do_is_utf8(bits) -} - -@target(erlang) -fn do_is_utf8(bits: BitArray) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:bytes>> -> do_is_utf8(rest) - _ -> False - } -} - -@target(javascript) -fn do_is_utf8(bits: BitArray) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } -} - -/// Converts a bit array to a string. -/// -/// Returns an error if the bit array is invalid UTF-8 data. -/// -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - do_to_string(bits) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "identity") -fn unsafe_to_string(a: BitArray) -> String - -@target(erlang) -fn do_to_string(bits: BitArray) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") -fn do_to_string(a: BitArray) -> Result(String, Nil) - -/// Creates a new bit array by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -@external(erlang, "gleam_stdlib", "bit_array_concat") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") -pub fn concat(bit_arrays: List(BitArray)) -> BitArray - -/// Encodes a BitArray into a base 64 encoded string. -/// -pub fn base64_encode(input: BitArray, padding: Bool) -> String { - let encoded = encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -@external(erlang, "base64", "encode") -@external(javascript, "../gleam_stdlib.mjs", "encode64") -fn encode64(a: BitArray) -> String - -/// Decodes a base 64 encoded string into a `BitArray`. -/// -pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { - let padded = case byte_size(from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - decode64(padded) -} - -@external(erlang, "gleam_stdlib", "base_decode64") -@external(javascript, "../gleam_stdlib.mjs", "decode64") -fn decode64(a: String) -> Result(BitArray, Nil) - -/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { - base64_encode(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. -/// -pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> base64_decode() -} - -@external(erlang, "binary", "encode_hex") -@external(javascript, "../gleam_stdlib.mjs", "base16_encode") -pub fn base16_encode(input: BitArray) -> String - -@external(erlang, "gleam_stdlib", "base16_decode") -@external(javascript, "../gleam_stdlib.mjs", "base16_decode") -pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52ec1b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0930d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 91bd6b76129..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,428 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{type Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} - -/// Runs a callback function if the given bool is `True`, otherwise runs an -/// alternative callback function. -/// -/// Useful when further computation should be delayed regardless of the given -/// bool's value. -/// -/// See [`guard`](#guard) for more info. -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "Kamaka" -/// > let inquiry = fn() { "How may we address you?" } -/// > use <- lazy_guard(when: name == "", return: inquiry) -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -/// ```gleam -/// > import gleam/int -/// > let name = "" -/// > let greeting = fn() { "Hello, " <> name } -/// > use <- lazy_guard(when: name == "", otherwise: greeting) -/// > let number = int.random(1, 99) -/// > let name = "User " <> int.to_string(number) -/// > "Welcome, " <> name -/// "Welcome, User 54" -/// ``` -/// -pub fn lazy_guard( - when requirement: Bool, - return consequence: fn() -> a, - otherwise alternative: fn() -> a, -) -> a { - case requirement { - True -> consequence() - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam deleted file mode 100644 index 20c145d93aa..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam +++ /dev/null @@ -1,197 +0,0 @@ -//// BytesBuilder is a type used for efficiently concatenating bytes together -//// without copying. -//// -//// If we append one bit array to another the bit arrays must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit arrays together. -//// -//// BytesBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit array using the `to_bit_array` function. -//// -//// Byte builders are always byte aligned, so that a number of bits that is not -//// divisible by 8 will be padded with 0s. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -// TODO: pad bit arrays to byte boundaries when adding to a builder. -import gleam/string_builder.{type StringBuilder} -import gleam/list -import gleam/bit_array - -pub opaque type BytesBuilder { - Bytes(BitArray) - Text(StringBuilder) - Many(List(BytesBuilder)) -} - -/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> BytesBuilder { - concat([]) -} - -/// Prepends a bit array to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { - append_builder(from_bit_array(first), second) -} - -/// Appends a bit array to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { - append_builder(first, from_bit_array(second)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to second: BytesBuilder, - prefix first: BytesBuilder, -) -> BytesBuilder { - append_builder(first, second) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "iodata_append") -pub fn append_builder( - to first: BytesBuilder, - suffix second: BytesBuilder, -) -> BytesBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string( - to second: BytesBuilder, - prefix first: String, -) -> BytesBuilder { - append_builder(from_string(first), second) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string( - to first: BytesBuilder, - suffix second: String, -) -> BytesBuilder { - append_builder(first, from_string(second)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { - Many(builders) -} - -/// Joins a list of bit arrays into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { - bits - |> list.map(fn(b) { from_bit_array(b) }) - |> concat() -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string(string: String) -> BytesBuilder { - Text(string_builder.from_string(string)) -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { - Text(builder) -} - -/// Creates a new builder from a bit array. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_bit_array(bits: BitArray) -> BytesBuilder { - Bytes(bits) -} - -/// Turns an builder into a bit array. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -@external(erlang, "erlang", "list_to_bitstring") -pub fn to_bit_array(builder: BytesBuilder) -> BitArray { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_array.concat -} - -fn to_list( - stack: List(List(BytesBuilder)), - acc: List(BitArray), -) -> List(BitArray) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bytes(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_array.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -@external(erlang, "erlang", "iolist_size") -pub fn byte_size(builder: BytesBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam deleted file mode 100644 index 280bf9d1d98..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dict.gleam +++ /dev/null @@ -1,544 +0,0 @@ -import gleam/option.{type Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a dict, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a dict once. -/// -/// Dicts are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub type Dict(key, value) - -/// Determines the number of key-value pairs in the dict. -/// This function runs in constant time and does not need to iterate the dict. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(dict: Dict(k, v)) -> Int { - do_size(dict) -} - -@external(erlang, "maps", "size") -@external(javascript, "../gleam_stdlib.mjs", "map_size") -fn do_size(a: Dict(k, v)) -> Int - -/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the dict. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { - do_to_list(dict) -} - -@external(erlang, "maps", "to_list") -@external(javascript, "../gleam_stdlib.mjs", "map_to_list") -fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) - -/// Converts a list of 2-element tuples `#(key, value)` to a dict. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the dict. -/// -pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { - do_from_list(list) -} - -@target(erlang) -@external(erlang, "maps", "from_list") -fn do_from_list(a: List(#(key, value))) -> Dict(key, value) - -@target(javascript) -fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Dict(k, v), -) -> Dict(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } -} - -@target(javascript) -fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { - fold_list_of_pair(list, new()) -} - -/// Determines whether or not a value present in the dict for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(dict: Dict(k, v), key: k) -> Bool { - do_has_key(key, dict) -} - -@target(erlang) -@external(erlang, "maps", "is_key") -fn do_has_key(a: key, b: Dict(key, v)) -> Bool - -@target(javascript) -fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { - get(dict, key) != Error(Nil) -} - -/// Creates a fresh dict that contains no values. -/// -pub fn new() -> Dict(key, value) { - do_new() -} - -@external(erlang, "maps", "new") -@external(javascript, "../gleam_stdlib.mjs", "new_map") -fn do_new() -> Dict(key, value) - -/// Fetches a value from a dict for a given key. -/// -/// The dict may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -@external(erlang, "gleam_stdlib", "map_get") -@external(javascript, "../gleam_stdlib.mjs", "map_get") -fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) - -/// Inserts a value into the dict with the given key. -/// -/// If the dict already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { - do_insert(key, value, dict) -} - -@external(erlang, "maps", "put") -@external(javascript, "../gleam_stdlib.mjs", "map_insert") -fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) - -/// Updates all values in a given dict by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { - do_map_values(fun, dict) -} - -@target(erlang) -@external(erlang, "maps", "map") -fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) - -@target(javascript) -fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { - let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } - dict - |> fold(from: new(), with: f) -} - -/// Gets a list of all keys in a given dict. -/// -/// Dicts are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(dict: Dict(keys, v)) -> List(keys) { - do_keys(dict) -} - -@target(erlang) -@external(erlang, "maps", "keys") -fn do_keys(a: Dict(keys, v)) -> List(keys) - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(dict: Dict(k, v)) -> List(k) { - let list_of_pairs = to_list(dict) - do_keys_acc(list_of_pairs, []) -} - -/// Gets a list of all values in a given dict. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(dict: Dict(k, values)) -> List(values) { - do_values(dict) -} - -@target(erlang) -@external(erlang, "maps", "values") -fn do_values(a: Dict(k, values)) -> List(values) - -@target(javascript) -fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } -} - -@target(javascript) -fn do_values(dict: Dict(k, v)) -> List(v) { - let list_of_pairs = to_list(dict) - do_values_acc(list_of_pairs, []) -} - -/// Creates a new dict from a given dict, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter( - in dict: Dict(k, v), - keeping predicate: fn(k, v) -> Bool, -) -> Dict(k, v) { - do_filter(predicate, dict) -} - -@target(erlang) -@external(erlang, "maps", "filter") -fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) - -@target(javascript) -fn do_filter( - f: fn(key, value) -> Bool, - dict: Dict(key, value), -) -> Dict(key, value) { - let insert = fn(dict, k, v) { - case f(k, v) { - True -> insert(dict, k, v) - _ -> dict - } - } - dict - |> fold(from: new(), with: insert) -} - -/// Creates a new dict from a given dict, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { - do_take(desired_keys, dict) -} - -@target(erlang) -@external(erlang, "maps", "with") -fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_taken( - dict: Dict(k, v), - desired_keys: List(k), - acc: Dict(k, v), -) -> Dict(k, v) { - let insert = fn(taken, key) { - case get(dict, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) - } -} - -@target(javascript) -fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { - insert_taken(dict, desired_keys, new()) -} - -/// Creates a new dict from a pair of given dicts by combining their entries. -/// -/// If there are entries with the same keys in both dicts the entry from the -/// second dict takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { - do_merge(dict, new_entries) -} - -@target(erlang) -@external(erlang, "maps", "merge") -fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { - insert(dict, pair.0, pair.1) -} - -@target(javascript) -fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { - case new_entries { - [] -> dict - [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) - } -} - -@target(javascript) -fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { - new_entries - |> to_list - |> fold_inserts(dict) -} - -/// Creates a new dict from a given dict with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { - do_delete(key, dict) -} - -@external(erlang, "maps", "remove") -@external(javascript, "../gleam_stdlib.mjs", "map_remove") -fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) - -/// Creates a new dict from a given dict with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { - case disallowed_keys { - [] -> dict - [x, ..xs] -> drop(delete(dict, x), xs) - } -} - -/// Creates a new dict with one entry updated using a given function. -/// -/// If there was not an entry in the dict for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let dict = from_list([#("a", 0)]) -/// > -/// > update(dict, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(dict, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in dict: Dict(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Dict(k, v) { - dict - |> get(key) - |> option.from_result - |> fun - |> insert(dict, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over dict: Dict(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - dict - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index c71c6f342ad..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1508 +0,0 @@ -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option} -import gleam/result -import gleam/string_builder -@target(erlang) -import gleam/bit_array - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from(a: anything) -> Dynamic - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_unsafe_coerce(a: Dynamic) -> a - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit -/// array if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_array(from("Hello")) == bit_array.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_array(from(123)) -/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - decode_bit_array(data) -} - -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - -@external(erlang, "gleam_stdlib", "decode_bit_array") -@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") -fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -@target(erlang) -fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_array(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_array.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitArray", path: [])]) - } - }) -} - -@target(erlang) -fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "decode_string") -fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -@external(erlang, "gleam_stdlib", "classify_dynamic") -@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") -fn do_classify(a: Dynamic) -> String - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -@external(erlang, "gleam_stdlib", "decode_int") -@external(javascript, "../gleam_stdlib.mjs", "decode_int") -fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -@external(erlang, "gleam_stdlib", "decode_float") -@external(javascript, "../gleam_stdlib.mjs", "decode_float") -fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -@external(erlang, "gleam_stdlib", "decode_bool") -@external(javascript, "../gleam_stdlib.mjs", "decode_bool") -fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -@external(erlang, "gleam_stdlib", "decode_list") -@external(javascript, "../gleam_stdlib.mjs", "decode_list") -fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_result") -@external(javascript, "../gleam_stdlib.mjs", "decode_result") -fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -@external(erlang, "gleam_stdlib", "decode_option") -@external(javascript, "../gleam_stdlib.mjs", "decode_option") -fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -@external(erlang, "gleam_stdlib", "decode_field") -@external(javascript, "../gleam_stdlib.mjs", "decode_field") -fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -type UnknownTuple - -@external(erlang, "gleam_stdlib", "decode_tuple") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") -fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple2") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") -fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple3") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") -fn decode_tuple3( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple4") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") -fn decode_tuple4( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple5") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") -fn decode_tuple5( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple6") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") -fn decode_tuple6( - a: Dynamic, -) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, -) - -@external(erlang, "gleam_stdlib", "tuple_get") -@external(javascript, "../gleam_stdlib.mjs", "tuple_get") -fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) - -@external(erlang, "gleam_stdlib", "size_of_tuple") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn tuple_size(a: UnknownTuple) -> Int - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a dict. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() |> from |> map(string, int) -/// Ok(dict.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn dict( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> dict.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(dict.from_list(pairs)) - } -} - -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - -@external(erlang, "gleam_stdlib", "decode_map") -@external(javascript, "../gleam_stdlib.mjs", "decode_map") -fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.concat([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 5d62419fd0d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,546 +0,0 @@ -//// Functions for working with floats. -//// -//// ## Division by zero -//// -//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE -//// 754 standard for floating point arithmetic and does not have an `Infinity` -//// value. In Erlang division by zero results in a crash, however Gleam does -//// not have partial functions and operators in core so instead division by zero -//// returns zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/order.{type Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_float") -@external(javascript, "../gleam_stdlib.mjs", "parse_float") -fn do_parse(a: String) -> Result(Float, Nil) - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -@external(erlang, "gleam_stdlib", "float_to_string") -@external(javascript, "../gleam_stdlib.mjs", "float_to_string") -fn do_to_string(a: Float) -> String - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -@external(erlang, "math", "ceil") -@external(javascript, "../gleam_stdlib.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -@external(erlang, "math", "floor") -@external(javascript, "../gleam_stdlib.mjs", "floor") -fn do_floor(a: Float) -> Float - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -@target(erlang) -@external(erlang, "erlang", "round") -fn do_round(a: Float) -> Int - -@target(javascript) -fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "round") -fn js_round(a: Float) -> Int - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../gleam_stdlib.mjs", "truncate") -fn do_truncate(a: Float) -> Int - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../gleam_stdlib.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Generates a random float between the given minimum and maximum values. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(min: Float, max: Float) -> Float { - do_random_uniform() *. { max -. min } +. min -} - -/// Returns a random float uniformly distributed in the value range -/// 0.0 =< X < 1.0 and updates the state in the process dictionary. -/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> -/// -@external(erlang, "rand", "uniform") -@external(javascript, "../gleam_stdlib.mjs", "random_uniform") -fn do_random_uniform() -> Float - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index d93c16afaf6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,874 +0,0 @@ -//// Functions for working with integers. -//// -//// ## Division by zero -//// -//// In Erlang division by zero results in a crash, however Gleam does not have -//// partial functions and operators in core so instead division by zero returns -//// zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/float -import gleam/order.{type Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_int") -@external(javascript, "../gleam_stdlib.mjs", "parse_int") -fn do_parse(a: String) -> Result(Int, Nil) - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -@external(erlang, "gleam_stdlib", "int_from_base_string") -@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") -fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "to_string") -fn do_to_string(a: Int) -> String - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") -fn do_to_base_string(a: Int, b: Int) -> String - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -@external(erlang, "erlang", "float") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_float(a: Int) -> Float - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Generates a random int between the given minimum and maximum values. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(min: Int, max: Int) -> Int { - float.random(to_float(min), to_float(max)) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} - -/// Calculates the bitwise AND of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "band") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") -pub fn bitwise_and(x: Int, y: Int) -> Int - -/// Calculates the bitwise NOT of its argument. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bnot") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") -pub fn bitwise_not(x: Int) -> Int - -/// Calculates the bitwise OR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") -pub fn bitwise_or(x: Int, y: Int) -> Int - -/// Calculates the bitwise XOR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bxor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") -pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic left bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsl") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") -pub fn bitwise_shift_left(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic right bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsr") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") -pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index 0c0a3eeffe0..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,117 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -@external(erlang, "gleam_stdlib", "print") -@external(javascript, "../gleam_stdlib.mjs", "print") -fn do_print(string string: String) -> Nil - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -@external(erlang, "gleam_stdlib", "print_error") -@external(javascript, "../gleam_stdlib.mjs", "print_error") -fn do_print_error(string string: String) -> Nil - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -@external(erlang, "gleam_stdlib", "println") -@external(javascript, "../gleam_stdlib.mjs", "console_log") -fn do_println(string string: String) -> Nil - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "console_error") -fn do_println_error(string string: String) -> Nil - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "print_debug") -fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index c57e7fd9473..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1530 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option, None, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_map2( - continuation1: fn() -> Action(a), - continuation2: fn() -> Action(b), - with fun: fn(a, b) -> c, -) -> fn() -> Action(c) { - fn() { - case continuation1() { - Stop -> Stop - Continue(a, next_a) -> - case continuation2() { - Stop -> Stop - Continue(b, next_b) -> - Continue(fun(a, b), do_map2(next_a, next_b, fun)) - } - } - } -} - -/// Combines two interators into a single one using the given function. -/// -/// If an iterator is longer than the other the extra elements are dropped. -/// -/// This function does not evaluate the elements of the two iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// let first = from_list([1, 2, 3]) -/// let second = from_list([4, 5, 6]) -/// map2(first, second, fn(x, y) { x + y }) |> to_list -/// // -> [5, 7, 9] -/// ``` -/// -/// ```gleam -/// let first = from_list([1, 2]) -/// let second = from_list(["a", "b", "c"]) -/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list -/// // -> [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2( - iterator1: Iterator(a), - iterator2: Iterator(b), - with fun: fn(a, b) -> c, -) -> Iterator(c) { - do_map2(iterator1.continuation, iterator2.continuation, fun) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Joins a list of iterators into a single iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [[1, 2], [3, 4]] -/// > |> map(from_list) -/// > |> concat -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { - flatten(from_list(iterators)) -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - keeping predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - groups - |> dict.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Dict(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Dict(key, List(element)) { - iterator - |> fold(dict.new(), group_updater(key)) - |> dict.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} - -/// Add a new element to the start of an iterator. -/// -/// This function is for use with `use` expressions, to replicate the behaviour -/// of the `yield` keyword found in other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > use <- iterator.yield(1) -/// > use <- iterator.yield(2) -/// > use <- iterator.yield(3) -/// > iterator.empty() -/// iterator.from_list([1, 2, 3]) -/// ``` -/// -pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { - Iterator(fn() { Continue(element, next().continuation) }) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index a5cffa9b951..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2154 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{type Order} -import gleam/pair -import gleam/dict.{type Dict} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -@target(erlang) -@external(erlang, "erlang", "length") -fn do_length(a: List(a)) -> Int - -@target(javascript) -fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) -} - -@target(javascript) -fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -@target(erlang) -@external(erlang, "lists", "reverse") -fn do_reverse(a: List(a)) -> List(a) - -@target(javascript) -fn do_reverse(list) { - do_reverse_acc(list, []) -} - -@target(javascript) -fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - case dict.get(groups, f(elem)) { - Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> dict.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> dict.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) -/// |> dict.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { - fold(list, dict.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Combines two lists into a single list using the given function. -/// -/// If a list is longer than the other the extra elements are dropped. -/// -/// ## Examples -/// -/// ```gleam -/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) -/// [5, 7, 9] -/// ``` -/// -/// ```gleam -/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) -/// [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { - do_map2(list1, list2, fun, []) -} - -fn do_map2( - list1: List(a), - list2: List(b), - fun: fn(a, b) -> c, - acc: List(c), -) -> List(c) { - case list1, list2 { - [], _ | _, [] -> reverse(acc) - [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) - } -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -@target(erlang) -@external(erlang, "lists", "append") -fn do_append(a: List(a), b: List(a)) -> List(a) - -@target(javascript) -fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) -} - -@target(javascript) -fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Joins a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn concat(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// This is the same as `concat`: it joins a list of lists into a single -/// list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// Maps the list with the given function into a list of lists, and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> concat -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> [stop, ..acc] - order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) - order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, finds all tuples that have a given -/// key as the first element and returns the second element. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") -/// [0, 2] -/// ``` -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1)], "c") -/// [] -/// ``` -/// -pub fn key_filter( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> List(v) { - filter_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> concat - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> concat -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> concat -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> concat - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [elem_pair, ..enumerable] -> - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calculate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 1f8b228eb90..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,127 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(map) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@target(javascript) -fn do_filter(f: fn(key, value) -> Bool, map) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 12ce01136ca..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,133 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > negate(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -pub fn negate(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} - -/// Inverts an ordering function, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > list.sort([1, 5, 4], by: reverse(int.compare)) -/// [5, 4, 1] -/// ``` -/// -pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { - fn(a, b) { orderer(b, a) } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index 9ffda789f6a..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,214 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{type Option} - -pub type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -@external(erlang, "gleam_stdlib", "compile_regex") -@external(javascript, "../gleam_stdlib.mjs", "compile_regex") -fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -@external(erlang, "gleam_stdlib", "regex_check") -@external(javascript, "../gleam_stdlib.mjs", "regex_check") -fn do_check(a: Regex, b: String) -> Bool - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "regex_split") -fn do_split(a: Regex, b: String) -> List(String) - -@target(javascript) -fn do_split(regex, string) -> List(String) { - js_split(string, regex) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn js_split(a: String, b: Regex) -> List(String) - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -@external(erlang, "gleam_stdlib", "regex_scan") -@external(javascript, "../gleam_stdlib.mjs", "regex_scan") -fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index fb6dddb3110..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,482 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// "Updates" an `Ok` result by passing its value to a function that yields a result, -/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) -/// -/// If the input is an `Error` rather than an `Ok`, the function is not called and -/// the original `Error` is returned. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), Error("a"), Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index df8d500e804..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/dict.{type Dict} -import gleam/result - -// A list is used as the map value as an empty list has the smallest -// representation in Erlang's binary format -@target(erlang) -type Token = - List(Nil) - -@target(erlang) -const token = [] - -@target(javascript) -type Token = - Nil - -@target(javascript) -const token = Nil - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Dict(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(dict.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - dict.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: dict.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> dict.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: dict.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - dict.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: dict.new(), - with: fn(m, k) { dict.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - keeping predicate: fn(member) -> Bool, -) -> Set(member) { - Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(dict.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case dict.size(first.map) > dict.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index 7254fd9fd1c..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,913 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{type Iterator} -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/order -import gleam/string_builder.{type StringBuilder} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -@external(erlang, "string", "length") -@external(javascript, "../gleam_stdlib.mjs", "string_length") -fn do_length(a: String) -> Int - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -@target(erlang) -fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string -} - -@target(javascript) -fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: String) -> String - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: String) -> String - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -@external(erlang, "gleam_stdlib", "less_than") -@external(javascript, "../gleam_stdlib.mjs", "less_than") -fn less_than(a: String, b: String) -> Bool - -/// Takes a substring given a start grapheme index and a length. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -@target(erlang) -@external(erlang, "string", "slice") -fn do_slice(a: String, b: Int, c: Int) -> String - -@target(javascript) -fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -@external(erlang, "gleam_stdlib", "crop_string") -@external(javascript, "../gleam_stdlib.mjs", "crop_string") -pub fn crop(from string: String, before substring: String) -> String - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -@external(erlang, "gleam_stdlib", "contains_string") -@external(javascript, "../gleam_stdlib.mjs", "contains_string") -pub fn contains(does haystack: String, contain needle: String) -> Bool - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -@external(erlang, "gleam_stdlib", "string_starts_with") -@external(javascript, "../gleam_stdlib.mjs", "starts_with") -fn do_starts_with(a: String, b: String) -> Bool - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -@external(erlang, "gleam_stdlib", "string_ends_with") -@external(javascript, "../gleam_stdlib.mjs", "ends_with") -fn do_ends_with(a: String, b: String) -> Bool - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: String, b: String) -> List(String) - -@target(erlang) -fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split_once") -fn do_split_once( - x x: String, - substring substring: String, -) -> Result(#(String, String), Nil) - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - do_join(strings, separator) -} - -@target(erlang) -fn do_join(strings: List(String), separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "join") -fn do_join(strings strings: List(String), string string: String) -> String - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -@target(erlang) -fn do_trim(string: String) -> String { - erl_trim(string, Both) -} - -@target(erlang) -type Direction { - Leading - Trailing - Both -} - -@target(erlang) -@external(erlang, "string", "trim") -fn erl_trim(a: String, b: Direction) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim") -fn do_trim(string string: String) -> String - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -@target(erlang) -fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_left") -fn do_trim_left(string string: String) -> String - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -@target(erlang) -fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_right") -fn do_trim_right(string string: String) -> String - -/// Splits a non-empty `String` into its first element (head) and rest (tail). -/// This lets you pattern match on `String`s exactly as you would with lists. -/// -/// Note on JavaScript using the function to iterate over a string will likely -/// be slower than using `to_graphemes` due to string slicing being more -/// expensive on JavaScript than Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -@external(erlang, "gleam_stdlib", "string_pop_grapheme") -@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") -fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "codepoint") -fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -@target(erlang) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(<<string:utf8>>, []) - |> list.reverse -} - -@target(erlang) -fn do_to_utf_codepoints_impl( - bit_array: BitArray, - acc: List(UtfCodepoint), -) -> List(UtfCodepoint) { - case bit_array { - <<first:utf8_codepoint, rest:bytes>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - _ -> acc - } -} - -@target(javascript) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") -fn string_to_codepoint_integer_list(a: String) -> List(Int) - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") -/// > utf_codepoint_to_int(utf_codepoint) -/// 128156 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") -fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -@external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam_stdlib.mjs", "inspect") -fn do_inspect(term term: anything) -> StringBuilder - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -/// ## Examples -/// -/// ```gleam -/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") -/// 58 -/// ``` -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "byte_size") -pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 5792ca8699d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,298 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -@external(erlang, "gleam_stdlib", "iodata_append") -@external(javascript, "../gleam_stdlib.mjs", "add") -fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_from_strings(a: List(String)) -> StringBuilder - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_concat(a: List(StringBuilder)) -> StringBuilder - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from_string(a: String) -> StringBuilder - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -@external(erlang, "unicode", "characters_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_string(a: StringBuilder) -> String - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -@external(erlang, "erlang", "iolist_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn do_byte_size(a: StringBuilder) -> Int - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -@target(erlang) -@external(erlang, "string", "reverse") -fn do_reverse(a: StringBuilder) -> StringBuilder - -@target(javascript) -fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -fn do_to_graphemes(string string: String) -> List(String) - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -@target(erlang) -type Direction { - All -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) - -@target(erlang) -fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn do_split( - builder builder: StringBuilder, - pattern pattern: String, -) -> List(StringBuilder) - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -@target(erlang) -fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, -) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) -} - -@target(erlang) -@external(erlang, "string", "replace") -fn erl_replace( - a: StringBuilder, - b: String, - c: String, - d: Direction, -) -> StringBuilder - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_replace") -fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -@external(erlang, "string", "equal") -@external(javascript, "../gleam_stdlib.mjs", "equal") -fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -@target(erlang) -@external(erlang, "string", "is_empty") -fn do_is_empty(a: StringBuilder) -> Bool - -@target(javascript) -fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 11f6ea68cd2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,462 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/string -import gleam/string_builder.{type StringBuilder} -@target(javascript) -import gleam/pair -@target(javascript) -import gleam/regex -@target(javascript) -import gleam/result - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "uri_parse") -fn do_parse(a: String) -> Result(Uri, Nil) - -@target(javascript) -fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) -} - -@target(javascript) -fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) -} - -@target(javascript) -fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } -} - -@target(javascript) -fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } -} - -// Split an authority into its userinfo, host and port parts. -@target(javascript) -fn split_authority( - authority: Option(String), -) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } -} - -@target(javascript) -fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) -} - -@target(javascript) -fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -@external(erlang, "gleam_stdlib", "parse_query") -@external(javascript, "../gleam_stdlib.mjs", "parse_query") -fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -@external(erlang, "gleam_stdlib", "percent_encode") -@external(javascript, "../gleam_stdlib.mjs", "percent_encode") -fn do_percent_encode(a: String) -> String - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -@external(erlang, "gleam_stdlib", "percent_decode") -@external(javascript, "../gleam_stdlib.mjs", "percent_decode") -fn do_percent_decode(a: String) -> Result(String, Nil) - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - _, _, _ -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - _ -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65bc3f63e4d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - gleam@bit_array:base64_encode(Input, Padding). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - gleam@bit_array:base64_decode(Encoded). - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - gleam@bit_array:base64_url_encode(Input, Padding). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl deleted file mode 100644 index ba18dfaabdd..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_array.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(gleam@bit_array). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_arrays) -> - gleam_stdlib:bit_array_concat(Bit_arrays). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam_stdlib:bit_array_concat([First, Second]). - --spec base64_encode(bitstring(), boolean()) -> binary(). -base64_encode(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_decode(Encoded) -> - Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec base64_url_encode(bitstring(), boolean()) -> binary(). -base64_url_encode(Input, Padding) -> - _pipe = base64_encode(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_url_decode(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - base64_decode(_pipe@2). - --spec base16_encode(bitstring()) -> binary(). -base16_encode(Input) -> - binary:encode_hex(Input). - --spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base16_decode(Input) -> - gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 284c6d46cc3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,66 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). - --spec new() -> gleam@bytes_builder:bytes_builder(). -new() -> - gleam@bytes_builder:new(). - --spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -prepend(To, Prefix) -> - gleam@bytes_builder:prepend(To, Prefix). - --spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -append(To, Suffix) -> - gleam@bytes_builder:append(To, Suffix). - --spec prepend_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -prepend_builder(To, Prefix) -> - gleam@bytes_builder:prepend_builder(To, Prefix). - --spec append_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -prepend_string(To, Prefix) -> - gleam@bytes_builder:prepend_string(To, Prefix). - --spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -append_string(To, Suffix) -> - gleam@bytes_builder:append_string(To, Suffix). - --spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 7dabaa3bbc1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam@bit_array:append(First, Second). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - gleam@bit_array:is_utf8(Bits). - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - gleam@bit_array:to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 5f95f4d8314..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,162 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. - --spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. -lazy_guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence(); - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl deleted file mode 100644 index 2f6dd93a9f3..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl +++ /dev/null @@ -1,87 +0,0 @@ --module(gleam@bytes_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). --export_type([bytes_builder/0]). - --opaque bytes_builder() :: {bytes, bitstring()} | - {text, gleam@string_builder:string_builder()} | - {many, list(bytes_builder())}. - --spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -prepend_builder(Second, First) -> - gleam_stdlib:iodata_append(First, Second). - --spec concat(list(bytes_builder())) -> bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec new() -> bytes_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_string(binary()) -> bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). -prepend_string(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append_string(bytes_builder(), binary()) -> bytes_builder(). -append_string(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_array(bitstring()) -> bytes_builder(). -from_bit_array(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). -prepend(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append(bytes_builder(), bitstring()) -> bytes_builder(). -append(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). -concat_bit_arrays(Bits) -> - gleam_stdlib:identity(Bits). - --spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). -to_list(Stack, Acc) -> - case Stack of - [] -> - Acc; - - [[] | Remaining_stack] -> - to_list(Remaining_stack, Acc); - - [[{bytes, Bits} | Rest] | Remaining_stack@1] -> - to_list([Rest | Remaining_stack@1], [Bits | Acc]); - - [[{text, Builder} | Rest@1] | Remaining_stack@2] -> - Bits@1 = gleam_stdlib:identity( - gleam@string_builder:to_string(Builder) - ), - to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); - - [[{many, Builders} | Rest@2] | Remaining_stack@3] -> - to_list([Builders, Rest@2 | Remaining_stack@3], Acc) - end. - --spec to_bit_array(bytes_builder()) -> bitstring(). -to_bit_array(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl deleted file mode 100644 index 99c231e18cc..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dict.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@dict). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). --export_type([dict/2]). - --type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. - --spec size(dict(any(), any())) -> integer(). -size(Dict) -> - maps:size(Dict). - --spec to_list(dict(NZ, OA)) -> list({NZ, OA}). -to_list(Dict) -> - maps:to_list(Dict). - --spec from_list(list({OJ, OK})) -> dict(OJ, OK). -from_list(List) -> - maps:from_list(List). - --spec has_key(dict(OT, any()), OT) -> boolean(). -has_key(Dict, Key) -> - maps:is_key(Key, Dict). - --spec new() -> dict(any(), any()). -new() -> - maps:new(). - --spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). -insert(Dict, Key, Value) -> - maps:put(Key, Value, Dict). - --spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). -map_values(Dict, Fun) -> - maps:map(Fun, Dict). - --spec keys(dict(QV, any())) -> list(QV). -keys(Dict) -> - maps:keys(Dict). - --spec values(dict(any(), RG)) -> list(RG). -values(Dict) -> - maps:values(Dict). - --spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). -filter(Dict, Predicate) -> - maps:filter(Predicate, Dict). - --spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). -take(Dict, Desired_keys) -> - maps:with(Desired_keys, Dict). - --spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). -merge(Dict, New_entries) -> - maps:merge(Dict, New_entries). - --spec delete(dict(TF, TG), TF) -> dict(TF, TG). -delete(Dict, Key) -> - maps:remove(Key, Dict). - --spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). -drop(Dict, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Dict; - - [X | Xs] -> - drop(delete(Dict, X), Xs) - end. - --spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). -update(Dict, Key, Fun) -> - _pipe = Dict, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Dict, Key, _pipe@3). - --spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. -fold(Dict, Initial, Fun) -> - _pipe = Dict, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 2c6016f4222..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,808 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). - --type dynamic_() :: any(). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type unknown_tuple() :: any(). - --spec from(any()) -> dynamic_(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic_()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_array(Data) -> - gleam_stdlib:decode_bit_array(Data). - --spec bit_string(dynamic_()) -> {ok, bitstring()} | - {error, list(decode_error())}. -bit_string(Data) -> - bit_array(Data). - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec classify(dynamic_()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - gleam@option:option(DGM)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, - DKT} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((DKX) -> DKY), - fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec result( - fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - list(DGH)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec map_errors( - {ok, DEV} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, DEV} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec decode_string(dynamic_()) -> {ok, binary()} | - {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_array(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_array:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitArray"/utf8>>, - []}]} - end end - ). - --spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec field( - any(), - fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec dict( - fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | - {error, list(decode_error())}). -dict(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@dict:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end - ) - end - ) - end. - --spec map( - fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - dict(Key_type, Value_type). - --spec decode2( - fun((DLB, DLC) -> DLD), - fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((DLH, DLI, DLJ) -> DLK), - fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((DLP, DLQ, DLR, DLS) -> DLT), - fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((DLZ, DMA, DMB, DMC, DMD) -> DME), - fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), - fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), - fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), - fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), - fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index 33b3d4a3e3f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,181 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= +0.0 of - true -> - X; - - _ -> - +0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > +0.0, - case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent - < +0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, +0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. - --spec random(float(), float()) -> float(). -random(Min, Max) -> - (rand:uniform() * (Max - Min)) + Min. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - +0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - +0.0 -> +0.0; - -0.0 -> -0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index c58c0fe151b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(AS) -> AS. -identity(X) -> - X. - --spec constant(AT) -> fun((any()) -> AT). -constant(Value) -> - fun(_) -> Value end. - --spec tap(AV, fun((AV) -> any())) -> AV. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((AX) -> AY), AX) -> AY. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 2a5dd2c8a1d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,332 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. - --spec random(integer(), integer()) -> integer(). -random(Min, Max) -> - _pipe = gleam@float:random(to_float(Min), to_float(Max)), - _pipe@1 = gleam@float:floor(_pipe), - gleam@float:round(_pipe@1). - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec bitwise_and(integer(), integer()) -> integer(). -bitwise_and(X, Y) -> - erlang:'band'(X, Y). - --spec bitwise_not(integer()) -> integer(). -bitwise_not(X) -> - erlang:'bnot'(X). - --spec bitwise_or(integer(), integer()) -> integer(). -bitwise_or(X, Y) -> - erlang:'bor'(X, Y). - --spec bitwise_exclusive_or(integer(), integer()) -> integer(). -bitwise_exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec bitwise_shift_left(integer(), integer()) -> integer(). -bitwise_shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec bitwise_shift_right(integer(), integer()) -> integer(). -bitwise_shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 82865bbafa6..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ENH) -> ENH. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index a667ae1ac4b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,744 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. - --opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. - --type step(BSE, BSF) :: {next, BSE, BSF} | done. - --type chunk(BSG, BSH) :: {another_by, - list(BSG), - BSH, - BSG, - fun(() -> action(BSG))} | - {last_by, list(BSG)}. - --type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | - {last, list(BSI)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BSV)) -> iterator(BSV). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BSX) -> iterator(BSX). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BSZ)) -> iterator(BSZ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec do_transform( - fun(() -> action(BTC)), - BTE, - fun((BTE, BTC) -> step(BTF, BTE)) -) -> fun(() -> action(BTF)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BTY)) -> list(BTY). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BUJ), integer()) -> iterator(BUJ). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BUP), integer()) -> iterator(BUP). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec do_map2( - fun(() -> action(BVA)), - fun(() -> action(BVC)), - fun((BVA, BVC) -> BVE) -) -> fun(() -> action(BVE)). -do_map2(Continuation1, Continuation2, Fun) -> - fun() -> case Continuation1() of - stop -> - stop; - - {continue, A, Next_a} -> - case Continuation2() of - stop -> - stop; - - {continue, B, Next_b} -> - {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} - end - end end. - --spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). -map2(Iterator1, Iterator2, Fun) -> - _pipe = do_map2( - erlang:element(2, Iterator1), - erlang:element(2, Iterator2), - Fun - ), - {iterator, _pipe}. - --spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BVY))) -> iterator(BVY). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec concat(list(iterator(BWC))) -> iterator(BWC). -concat(Iterators) -> - flatten(from_list(Iterators)). - --spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec cycle(iterator(BWR)) -> iterator(BWR). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), - BXD})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BXG)) -> iterator({integer(), BXG}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, - BYH})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BZU), BZU) -> iterator(BZU). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), - gleam@dict:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> CBH)) -> iterator(CBH). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec single(CBJ) -> iterator(CBJ). -single(Elem) -> - once(fun() -> Elem end). - --spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(CBT)), - fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), - CBV -) -> CBV. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(CBX), - CBZ, - fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) -) -> CBZ. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(CCB)), - fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), - CCD -) -> {ok, CCD} | {error, CCE}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, - CCL} | - {error, CCM}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). - --spec each(iterator(CDD), fun((CDD) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). -yield(Element, Next) -> - {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index cb6c9e44af2..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1136 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(XF)) -> list(XF). -reverse(Xs) -> - lists:reverse(Xs). - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec contains(list(XN), XN) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec first(list(XP)) -> {ok, XP} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@dict:insert(Groups, F(Elem), [Elem]) - end end. - --spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). -map(List, Fun) -> - do_map(List, Fun, []). - --spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). -do_map2(List1, List2, Fun, Acc) -> - case {List1, List2} of - {[], _} -> - reverse(Acc); - - {_, []} -> - reverse(Acc); - - {[A | As_], [B | Bs]} -> - do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) - end. - --spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). -map2(List1, List2, Fun) -> - do_map2(List1, List2, Fun, []). - --spec do_index_map( - list(ABJ), - fun((integer(), ABJ) -> ABL), - integer(), - list(ABL) -) -> list(ABL). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, - list(ABU)} | - {error, ABV}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, - list(ACE)} | - {error, ACF}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(ACL), integer()) -> list(ACL). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(ACS), integer()) -> list(ACS). -take(List, N) -> - do_take(List, N, []). - --spec new() -> list(any()). -new() -> - []. - --spec append(list(ACX), list(ACX)) -> list(ACX). -append(First, Second) -> - lists:append(First, Second). - --spec prepend(list(ADF), ADF) -> list(ADF). -prepend(List, Item) -> - [Item | List]. - --spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). -do_concat(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_concat(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec concat(list(list(ADR))) -> list(ADR). -concat(Lists) -> - do_concat(Lists, []). - --spec flatten(list(list(ADV))) -> list(ADV). -flatten(Lists) -> - do_concat(Lists, []). - --spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - concat(_pipe). - --spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). -group(List, Key) -> - fold(List, gleam@dict:new(), update_group(Key)). - --spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, - list(ABH)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold( - list(AEK), - AEM, - fun((AEM, AEK, integer()) -> AEM), - integer() -) -> AEM. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, - AES} | - {error, AET}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(AGX), AGX) -> list(AGX). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec unique(list(AHE)) -> list(AHE). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(AHH), - list(AHH), - list(AHH), - fun((AHH, AHH) -> gleam@order:order()) -) -> list(AHH). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_down( - integer(), - integer(), - list(AHM), - list(AHM), - list(AHM), - fun((AHM, AHM) -> gleam@order:order()) -) -> list(AHM). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_sort( - list(AHR), - integer(), - fun((AHR, AHR) -> gleam@order:order()), - boolean() -) -> list(AHR). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - [Stop | Acc]; - - gt -> - tail_recursive_range(Start, Stop + 1, [Stop | Acc]); - - lt -> - tail_recursive_range(Start, Stop - 1, [Stop | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(AID, integer()) -> list(AID). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), - list(AIO)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). -key_filter(Keyword_list, Desired_key) -> - filter_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, - {AZQ, list(AZQ)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, - {BAR, list(BAE)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, - {AJV, list(AJT)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AKM), fun((AKM) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | - {error, AKS}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), - list(BBY)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(ALG)) -> list(list(ALG)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - concat(_pipe@5) - end. - --spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(ALQ), integer()) -> list(list(ALQ)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec window_by_2(list(ALU)) -> list({ALU, ALU}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AMU), - integer(), - integer(), - list(AMU), - list(list(AMU)) -) -> list(list(AMU)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec last(list(ANS)) -> {ok, ANS} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec combinations(list(ANW), integer()) -> list(list(ANW)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AOE)) -> list({AOE, AOE}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - concat(_pipe). - --spec transpose(list(list(AOL))) -> list(list(AOL)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - concat(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AOH))) -> list(AOH). -interleave(List) -> - _pipe = transpose(List), - concat(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - [Elem_pair | Enumerable] -> - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec shuffle(list(AOX)) -> list(AOX). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index 9f45b107384..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). - --spec size(gleam@dict:dict(any(), any())) -> integer(). -size(Map) -> - gleam@dict:size(Map). - --spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). -to_list(Map) -> - gleam@dict:to_list(Map). - --spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). -from_list(List) -> - gleam@dict:from_list(List). - --spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). -has_key(Map, Key) -> - gleam@dict:has_key(Map, Key). - --spec new() -> gleam@dict:dict(any(), any()). -new() -> - gleam@dict:new(). - --spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. -get(From, Get) -> - gleam@dict:get(From, Get). - --spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). -insert(Map, Key, Value) -> - gleam@dict:insert(Map, Key, Value). - --spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). -map_values(Map, Fun) -> - gleam@dict:map_values(Map, Fun). - --spec keys(gleam@dict:dict(FED, any())) -> list(FED). -keys(Map) -> - gleam@dict:keys(Map). - --spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). -values(Map) -> - gleam@dict:values(Map). - --spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). -filter(Map, Predicate) -> - gleam@dict:filter(Map, Predicate). - --spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). -take(Map, Desired_keys) -> - gleam@dict:take(Map, Desired_keys). - --spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). -merge(Map, New_entries) -> - gleam@dict:merge(Map, New_entries). - --spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). -delete(Map, Key) -> - gleam@dict:delete(Map, Key). - --spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). -drop(Map, Disallowed_keys) -> - gleam@dict:drop(Map, Disallowed_keys). - --spec update( - gleam@dict:dict(FFB, FFC), - FFB, - fun((gleam@option:option(FFC)) -> FFC) -) -> gleam@dict:dict(FFB, FFC). -update(Map, Key, Fun) -> - gleam@dict:update(Map, Key, Fun). - --spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. -fold(Map, Initial, Fun) -> - gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 812aa1fe854..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). --export_type([option/1]). - --type option(IY) :: {some, IY} | none. - --spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(JF))) -> option(list(JF)). -all(List) -> - do_all(List, []). - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, JU} | {error, any()}) -> option(JU). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(JZ), JZ) -> JZ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(KD), fun((KD) -> KF)) -> option(KF). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(KH))) -> option(KH). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(KQ), option(KQ)) -> option(KQ). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_values(list(option(KY)), list(KY)) -> list(KY). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(LD))) -> list(LD). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index a9eed8f39c1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec negate(order()) -> order(). -negate(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. - --spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). -reverse(Orderer) -> - fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2452a9817e1..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({IJ, any()}) -> IJ. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), IM}) -> IM. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({IN, IO}) -> {IO, IN}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(IV, IW) -> {IV, IW}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index faec6923a14..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(EYN)) -> queue(EYN). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(EYQ)) -> list(EYQ). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EYX), EYX) -> queue(EYX). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EZA), EZA) -> queue(EZA). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec reverse(queue(EZN)) -> queue(EZN). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec check_equal( - list(EZQ), - list(EZQ), - list(EZQ), - list(EZQ), - fun((EZQ, EZQ) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EZY), queue(EZY)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index 2d1c5fc870e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([regex/0, match/0, compile_error/0, options/0]). - --type regex() :: any(). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index c80a7048303..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | - {error, BIK}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | - {error, BIU}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | - {error, BIY}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, - BJJ} | - {error, BJG}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, - BJS} | - {error, BJP}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | - {error, BKT}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, - BLA} | - {error, BLB}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), - list(BLY)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. -partition(Results) -> - do_partition(Results, [], []). - --spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BMT} | {error, any()})) -> list(BMT). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BMZ} | {error, BNA}, - fun((BNA) -> {ok, BMZ} | {error, BND}) -) -> {ok, BMZ} | {error, BND}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index 3374ebc293f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@dict:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@dict:size(erlang:element(2, Set)). - --spec insert(set(EOQ), EOQ) -> set(EOQ). -insert(Set, Member) -> - {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOT), EOT) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@dict:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EOV), EOV) -> set(EOV). -delete(Set, Member) -> - {set, gleam@dict:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOY)) -> list(EOY). -to_list(Set) -> - gleam@dict:keys(erlang:element(2, Set)). - --spec from_list(list(EPB)) -> set(EPB). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@dict:new(), - fun(M, K) -> gleam@dict:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. -fold(Set, Initial, Reducer) -> - gleam@dict:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). -filter(Set, Predicate) -> - {set, - gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. - --spec drop(set(EPK), list(EPK)) -> set(EPK). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPO), list(EPO)) -> set(EPO). -take(Set, Desired) -> - {set, gleam@dict:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. -order(First, Second) -> - case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPX), set(EPX)) -> set(EPX). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EQB), set(EQB)) -> set(EQB). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 6cba31d1895..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,352 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - gleam_stdlib:crop_string(String, Substring). - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - gleam_stdlib:contains_string(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_join(list(binary()), binary()) -> binary(). -do_join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - do_join(Strings, Separator). - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_array, Acc) -> - case Bit_array of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - _ -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 693e840f370..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([string_builder/0, direction/0]). - --type string_builder() :: any(). - --type direction() :: all. - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index a36df375281..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,252 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {_, _, _} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(ETW)) -> list(ETW). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - _ -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index 76aa1ea673c..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,31 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.33.1"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_array, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@bytes_builder, - gleam@dict, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index c6ea1257110..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,529 +0,0 @@ --module(gleam_stdlib). - --export([ - map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, - parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, - wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, - bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, - println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, - int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1 -]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - --define(is_lowercase_char(X), (X > 96 andalso X < 123)). --define(is_underscore_char(X), (X == 95)). --define(is_digit_char(X), (X > 47 andalso X < 58)). - -uppercase(X) -> X - 32. - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_array_concat(BitArrays) -> - list_to_bitstring(BitArrays). - -bit_array_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_array_int_to_u32(_) -> - {error, nil}. - -bit_array_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_array_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:_ -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(nil) -> - "Nil"; -inspect(Data) when is_map(Data) -> - Fields = [ - [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] - || {Key, Value} <- maps:to_list(Data) - ], - ["dict.from_list([", lists:join(", ", Fields), "])"]; -inspect(Atom) when is_atom(Atom) -> - Binary = erlang:atom_to_binary(Atom), - case inspect_maybe_gleam_atom(Binary, none, <<>>) of - {ok, Inspected} -> Inspected; - {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] - end; -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(Bits) when is_bitstring(Bits) -> - inspect_bit_array(Bits); -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - - -inspect_maybe_gleam_atom(<<>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc) - when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, $_, Acc); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); -inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> - {ok, Acc}; -inspect_maybe_gleam_atom(A, B, C) -> - erlang:display({A, B, C}), - throw({gleam_error, A, B, C}). - -inspect_list([]) -> - {proper, []}; -inspect_list([First]) -> - {proper, [inspect(First)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_bit_array(Bits) -> - Text = inspect_bit_array(Bits, <<"<<">>), - <<Text/binary, ">>">>. - -inspect_bit_array(<<>>, Acc) -> - Acc; -inspect_bit_array(<<X, Rest/bitstring>>, Acc) -> - inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); -inspect_bit_array(Rest, Acc) -> - Size = bit_size(Rest), - <<X:Size>> = Rest, - X1 = erlang:integer_to_binary(X), - Size1 = erlang:integer_to_binary(Size), - Segment = <<X1/binary, ":size(", Size1/binary, ")">>, - inspect_bit_array(<<>>, append_segment(Acc, Segment)). - -append_segment(<<"<<">>, Segment) -> - <<"<<", Segment/binary>>; -append_segment(Acc, Segment) -> - <<Acc/binary, ", ", Segment/binary>>. - - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<First/utf8, Rest/binary>> -> - Escaped = case First of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). - -utf_codepoint_list_to_string(List) -> - case unicode:characters_to_binary(List) of - {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); - Binary -> Binary - end. - -crop_string(String, Prefix) -> - case string:find(String, Prefix) of - nomatch -> String; - New -> New - end. - -contains_string(String, Substring) -> - is_bitstring(string:find(String, Substring)). - -base16_decode(String) -> - try - {ok, binary:decode_hex(String)} - catch - _:_ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 45c28cfc87b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,878 +0,0 @@ -import { - BitArray, - Error, - List, - Ok, - Result, - UtfCodepoint, - stringBits, - toBitArray, - NonEmpty, - CustomType, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import Dict from "./dict.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - const iterator = graphemes_iterator(string); - if (iterator) { - return List.fromArray(Array.from(iterator).map((item) => item.segment)); - } else { - return List.fromArray(string.match(/./gsu)); - } -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs, separator) { - const iterator = xs[Symbol.iterator](); - let result = iterator.next().value || ""; - let current = iterator.next(); - while (!current.done) { - result = result + separator + current.value; - current = iterator.next(); - } - return result; -} - -export function concat(xs) { - let result = ""; - for (const x of xs) { - result = result + x; - } - return result; -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function contains_string(haystack, needle) { - return haystack.indexOf(needle) >= 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_array_from_string(string) { - return toBitArray([stringBits(string)]); -} - -export function bit_array_concat(bit_arrays) { - return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_array_to_string(bit_array) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_array.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_array_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitArray(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return Dict.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_array) { - const aBytes = bit_array.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitArray(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (data instanceof Result) { - return "Result"; - } else if (data instanceof List) { - return "List"; - } else if (data instanceof BitArray) { - return "BitArray"; - } else if (data instanceof Dict) { - return "Map"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_array(data) { - if (data instanceof BitArray) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitArray(data)); - } - return decoder_error("BitArray", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - const list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!(data instanceof List)) return; - - const elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (!(current instanceof NonEmpty)) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && !(current instanceof NonEmpty)) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return data instanceof List ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return data instanceof Result ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof Dict) { - return new Ok(Dict.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(Dict.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof Dict || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} - -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function bitwise_and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function bitwise_not(x) { - return Number(~BigInt(x)); -} - -export function bitwise_or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function bitwise_exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function bitwise_shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function bitwise_shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} - -export function inspect(v) { - const t = typeof v; - if (v === true) return "True"; - if (v === false) return "False"; - if (v === null) return "//js(null)"; - if (v === undefined) return "Nil"; - if (t === "string") return JSON.stringify(v); - if (t === "bigint" || t === "number") return v.toString(); - if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; - if (v instanceof List) return inspectList(v); - if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); - if (v instanceof BitArray) return inspectBitArray(v); - if (v instanceof CustomType) return inspectCustomType(v); - if (v instanceof Dict) return inspectDict(v); - if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; - if (v instanceof RegExp) return `//js(${v})`; - if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; - if (v instanceof Function) { - const args = []; - for (const i of Array(v.length).keys()) - args.push(String.fromCharCode(i + 97)); - return `//fn(${args.join(", ")}) { ... }`; - } - return inspectObject(v); -} - -function inspectDict(map) { - let body = "dict.from_list(["; - let first = true; - map.forEach((value, key) => { - if (!first) body = body + ", "; - body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; - first = false; - }); - return body + "])"; -} - -function inspectObject(v) { - const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; - const props = []; - for (const k of Object.keys(v)) { - props.push(`${inspect(k)}: ${inspect(v[k])}`); - } - const body = props.length ? " " + props.join(", ") + " " : ""; - const head = name === "Object" ? "" : name + " "; - return `//js(${head}{${body}})`; -} - -function inspectCustomType(record) { - const props = Object.keys(record) - .map((label) => { - const value = inspect(record[label]); - return isNaN(parseInt(label)) ? `${label}: ${value}` : value; - }) - .join(", "); - return props - ? `${record.constructor.name}(${props})` - : record.constructor.name; -} - -export function inspectList(list) { - return `[${list.toArray().map(inspect).join(", ")}]`; -} - -export function inspectBitArray(bits) { - return `<<${Array.from(bits.buffer).join(", ")}>>`; -} - -export function inspectUtfCodepoint(codepoint) { - return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; -} - -export function base16_encode(bit_array) { - let result = ""; - for (const byte of bit_array.buffer) { - result += byte.toString(16).padStart(2, "0").toUpperCase(); - } - return result; -} - -export function base16_decode(string) { - const bytes = new Uint8Array(string.length / 2); - for (let i = 0; i < string.length; i += 2) { - const a = parseInt(string[i], 16); - const b = parseInt(string[i + 1], 16); - if (isNaN(a) || isNaN(b)) return new Error(Nil); - bytes[i / 2] = a * 16 + b; - } - return new Ok(new BitArray(bytes)); -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE deleted file mode 100644 index c7967c32d6f..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2021, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md deleted file mode 100644 index 3ca1c63e98d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# gleeunit - -Gleam bindings to the Erlang EUnit test framework. - -A custom test runner is included for when compiled to JavaScript running on -either NodeJS or Deno. - -Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). - -## Usage - -Add this package to your Gleam project. - -```sh -gleam add gleeunit --dev -``` - -And then call the `gleeunit.main` function from your test main function. - -```gleam -// In test/yourapp_test.gleam -import gleeunit - -pub fn main() { - gleeunit.main() -} -``` - -Now any public function with a name ending in `_test` in the `test` directory -will be found and run as a test. - -```gleam -pub fn the_universe_test() { - let assert 1 = 1 -} -``` - -Run the tests by entering `gleam test` in the command line. - -### Deno - -If using the Deno JavaScript runtime, you will need to add the following to your -`gleam.toml`. - -```toml -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] -``` diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml deleted file mode 100644 index 74b7e202e47..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleeunit" -version = "0.11.0" -licences = ["Apache-2.0"] -description = "Gleam bindings to Erlang's EUnit test framework" - -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] - -[dependencies] -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src deleted file mode 100644 index 2f98842c95e..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleeunit, [ - {vsn, "0.11.0"}, - {applications, [gleam_stdlib]}, - {description, "Gleam bindings to Erlang's EUnit test framework"}, - {modules, [gleeunit, - gleeunit@should]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl deleted file mode 100644 index 32e1a833d01..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gleeunit). --compile([no_auto_import, nowarn_unused_vars]). - --export([main/0]). --export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). - --type atom_() :: any(). - --type encoding() :: utf8. - --type report_module_name() :: gleeunit_progress. - --type gleeunit_progress_option() :: {colored, boolean()}. - --type eunit_option() :: verbose | - no_tty | - {report, {report_module_name(), list(gleeunit_progress_option())}}. - --spec gleam_to_erlang_module_name(binary()) -> binary(). -gleam_to_erlang_module_name(Path) -> - _pipe = Path, - _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), - gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). - --spec do_main() -> nil. -do_main() -> - Options = [verbose, - no_tty, - {report, {gleeunit_progress, [{colored, true}]}}], - Result = begin - _pipe = gleeunit_ffi:find_files( - <<"**/*.{erl,gleam}"/utf8>>, - <<"test"/utf8>> - ), - _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end - ), - _pipe@3 = eunit:test(_pipe@2, Options), - _pipe@4 = (gleam@dynamic:result( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ))(_pipe@3), - gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) - end, - Code = case Result of - {ok, _} -> - 0; - - {error, _} -> - 1 - end, - erlang:halt(Code). - --spec main() -> nil. -main() -> - do_main(). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam deleted file mode 100644 index e5d4b460cad..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit.gleam +++ /dev/null @@ -1,92 +0,0 @@ -/// Find and run all test functions for the current project using Erlang's EUnit -/// test framework. -/// -/// Any Erlang or Gleam function in the `test` directory with a name editing in -/// `_test` is considered a test function and will be run. -/// -/// If running on JavaScript tests will be run with a custom test runner. -/// -pub fn main() -> Nil { - do_main() -} - -@target(javascript) -@external(javascript, "./gleeunit_ffi.mjs", "main") -fn do_main() -> Nil - -@target(erlang) -import gleam/list -@target(erlang) -import gleam/result -@target(erlang) -import gleam/string -@target(erlang) -import gleam/dynamic.{Dynamic} - -@target(erlang) -fn do_main() -> Nil { - let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] - - let result = - find_files(matching: "**/*.{erl,gleam}", in: "test") - |> list.map(gleam_to_erlang_module_name) - |> list.map(dangerously_convert_string_to_atom(_, Utf8)) - |> run_eunit(options) - |> dynamic.result(dynamic.dynamic, dynamic.dynamic) - |> result.unwrap(Error(dynamic.from(Nil))) - - let code = case result { - Ok(_) -> 0 - Error(_) -> 1 - } - halt(code) -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil - -@target(erlang) -fn gleam_to_erlang_module_name(path: String) -> String { - path - |> string.replace(".gleam", "") - |> string.replace(".erl", "") - |> string.replace("/", "@") -} - -@target(erlang) -@external(erlang, "gleeunit_ffi", "find_files") -fn find_files(matching matching: String, in in: String) -> List(String) - -@target(erlang) -type Atom - -@target(erlang) -type Encoding { - Utf8 -} - -@target(erlang) -@external(erlang, "erlang", "binary_to_atom") -fn dangerously_convert_string_to_atom(a: String, b: Encoding) -> Atom - -@target(erlang) -type ReportModuleName { - GleeunitProgress -} - -@target(erlang) -type GleeunitProgressOption { - Colored(Bool) -} - -@target(erlang) -type EunitOption { - Verbose - NoTty - Report(#(ReportModuleName, List(GleeunitProgressOption))) -} - -@target(erlang) -@external(erlang, "eunit", "test") -fn run_eunit(a: List(Atom), b: List(EunitOption)) -> Dynamic diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam deleted file mode 100644 index c393c232724..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit/should.gleam +++ /dev/null @@ -1,90 +0,0 @@ -//// A module for testing your Gleam code. The functions found here are -//// compatible with the Erlang eunit test framework. -//// -//// More information on running eunit can be found in [the rebar3 -//// documentation](https://rebar3.org/docs/testing/eunit/). - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_equal") -pub fn equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_not_equal") -pub fn not_equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_ok") -pub fn be_ok(a: Result(a, b)) -> a - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_error") -pub fn be_error(a: Result(a, b)) -> b - -@target(javascript) -import gleam/string - -@target(javascript) -@external(javascript, "../gleam.mjs", "inspect") -fn stringify(a: anything) -> String - -@target(javascript) -@external(javascript, "../gleeunit_ffi.mjs", "crash") -fn crash(a: String) -> anything - -@target(javascript) -pub fn equal(a, b) { - case a == b { - True -> Nil - _ -> - crash(string.concat([ - "\n\t", - stringify(a), - "\n\tshould equal \n\t", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn not_equal(a, b) { - case a != b { - True -> Nil - _ -> - crash(string.concat([ - "\n", - stringify(a), - "\nshould not equal \n", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn be_ok(a) { - case a { - Ok(value) -> value - _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) - } -} - -@target(javascript) -pub fn be_error(a) { - case a { - Error(error) -> error - _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) - } -} - -pub fn be_true(actual: Bool) -> Nil { - actual - |> equal(True) -} - -pub fn be_false(actual: Bool) -> Nil { - actual - |> equal(False) -} - -pub fn fail() -> Nil { - be_true(False) -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl deleted file mode 100644 index acf032e1e7d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit@should.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(gleeunit@should). --compile([no_auto_import, nowarn_unused_vars]). - --export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). - --spec equal(EYG, EYG) -> nil. -equal(A, B) -> - gleeunit_ffi:should_equal(A, B). - --spec not_equal(EYH, EYH) -> nil. -not_equal(A, B) -> - gleeunit_ffi:should_not_equal(A, B). - --spec be_ok({ok, EYI} | {error, any()}) -> EYI. -be_ok(A) -> - gleeunit_ffi:should_be_ok(A). - --spec be_error({ok, any()} | {error, EYN}) -> EYN. -be_error(A) -> - gleeunit_ffi:should_be_error(A). - --spec be_true(boolean()) -> nil. -be_true(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, true). - --spec be_false(boolean()) -> nil. -be_false(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, false). - --spec fail() -> nil. -fail() -> - be_true(false). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl deleted file mode 100644 index 31f9ef9e2c9..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(gleeunit_ffi). - --export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, - should_be_error/1]). - --include_lib("eunit/include/eunit.hrl"). - -find_files(Pattern, In) -> - Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), - lists:map(fun list_to_binary/1, Results). - - -should_equal(Actual, Expected) -> - ?assertEqual(Expected, Actual), - nil. -should_not_equal(Actual, Expected) -> - ?assertNotEqual(Expected, Actual), - nil. -should_be_ok(A) -> - ?assertMatch({ok, _}, A), - element(2, A). -should_be_error(A) -> - ?assertMatch({error, _}, A), - element(2, A). diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs deleted file mode 100644 index 339a843e5c5..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_ffi.mjs +++ /dev/null @@ -1,101 +0,0 @@ -async function* gleamFiles(directory) { - for (let entry of await read_dir(directory)) { - let path = join_path(directory, entry); - if (path.endsWith(".gleam")) { - yield path; - } else { - try { - yield* gleamFiles(path); - } catch (error) { - // Could not read directory, assume it's a file - } - } - } -} - -async function readRootPackageName() { - let toml = await read_file("gleam.toml", "utf-8"); - for (let line of toml.split("\n")) { - let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() - if (matches) return matches[1]; - } - throw new Error("Could not determine package name from gleam.toml"); -} - -export async function main() { - let passes = 0; - let failures = 0; - - let packageName = await readRootPackageName(); - let dist = `../${packageName}/`; - - for await (let path of await gleamFiles("test")) { - let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); - let module = await import(join_path(dist, js_path)); - for (let fnName of Object.keys(module)) { - if (!fnName.endsWith("_test")) continue; - try { - await module[fnName](); - write(`\u001b[32m.\u001b[0m`); - passes++; - } catch (error) { - let moduleName = "\n" + js_path.slice(0, -4); - let line = error.line ? `:${error.line}` : ""; - write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); - failures++; - } - } - } - - console.log(` -${passes + failures} tests, ${failures} failures`); - exit(failures ? 1 : 0); -} - -export function crash(message) { - throw new Error(message); -} - -function write(message) { - if (globalThis.Deno) { - Deno.stdout.writeSync(new TextEncoder().encode(message)); - } else { - process.stdout.write(message); - } -} - -function exit(code) { - if (globalThis.Deno) { - Deno.exit(code); - } else { - process.exit(code); - } -} - -async function read_dir(path) { - if (globalThis.Deno) { - let items = []; - for await (let item of Deno.readDir(path, { withFileTypes: true })) { - items.push(item.name); - } - return items; - } else { - let { readdir } = await import("fs/promises"); - return readdir(path); - } -} - -function join_path(a, b) { - if (a.endsWith("/")) return a + b; - return a + "/" + b; -} - -async function read_file(path) { - if (globalThis.Deno) { - return Deno.readTextFile(path); - } else { - let { readFile } = await import("fs/promises"); - let contents = await readFile(path); - return contents.toString(); - } -} diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl deleted file mode 100644 index 1f68eb95e58..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/gleeunit/src/gleeunit_progress.erl +++ /dev/null @@ -1,607 +0,0 @@ -%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters - -%% @doc A listener/reporter for eunit that prints '.' for each -%% success, 'F' for each failure, and 'E' for each error. It can also -%% optionally summarize the failures at the end. --compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). --module(gleeunit_progress). --behaviour(eunit_listener). --define(NOTEST, true). --include_lib("eunit/include/eunit.hrl"). - --define(RED, "\e[0;31m"). --define(GREEN, "\e[0;32m"). --define(YELLOW, "\e[0;33m"). --define(WHITE, "\e[0;37m"). --define(CYAN, "\e[0;36m"). --define(RESET, "\e[0m"). - --record(node,{ - rank = 0 :: non_neg_integer(), - key :: term(), - value :: term(), - children = new() :: binomial_heap() - }). - --export_type([binomial_heap/0, heap_node/0]). --type binomial_heap() :: [ heap_node() ]. --type heap_node() :: #node{}. - -%% eunit_listener callbacks --export([ - init/1, - handle_begin/3, - handle_end/3, - handle_cancel/3, - terminate/2, - start/0, - start/1 - ]). - -%% -- binomial_heap.erl content start -- - --record(state, { - status = dict:new() :: euf_dict(), - failures = [] :: [[pos_integer()]], - skips = [] :: [[pos_integer()]], - timings = new() :: binomial_heap(), - colored = true :: boolean(), - profile = false :: boolean() - }). - --type euf_dict() :: dict:dict(). - --spec new() -> binomial_heap(). -new() -> - []. - -% Inserts a new pair into the heap (or creates a new heap) --spec insert(term(), term()) -> binomial_heap(). -insert(Key,Value) -> - insert(Key,Value,[]). - --spec insert(term(), term(), binomial_heap()) -> binomial_heap(). -insert(Key,Value,Forest) -> - insTree(#node{key=Key,value=Value},Forest). - -% Merges two heaps --spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). -merge(TS1,[]) when is_list(TS1) -> TS1; -merge([],TS2) when is_list(TS2) -> TS2; -merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> - if - R1 < R2 -> - [T1 | merge(TS1,F2)]; - R2 < R1 -> - [T2 | merge(F1, TS2)]; - true -> - insTree(link(T1,T2),merge(TS1,TS2)) - end. - -% Deletes the top entry from the heap and returns it --spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. -delete(TS) -> - {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), - {{Key,Value},merge(lists:reverse(TS1),TS2)}. - -% Turns the heap into list in heap order --spec to_list(binomial_heap()) -> [{term(), term()}]. -to_list([]) -> []; -to_list(List) when is_list(List) -> - to_list([],List). -to_list(Acc, []) -> - lists:reverse(Acc); -to_list(Acc,Forest) -> - {Next, Trees} = delete(Forest), - to_list([Next|Acc], Trees). - -% Take N elements from the top of the heap --spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. -take(N,Trees) when is_integer(N), is_list(Trees) -> - take(N,Trees,[]). -take(0,_Trees,Acc) -> - lists:reverse(Acc); -take(_N,[],Acc)-> - lists:reverse(Acc); -take(N,Trees,Acc) -> - {Top,T2} = delete(Trees), - take(N-1,T2,[Top|Acc]). - -% Get an estimate of the size based on the binomial property --spec size(binomial_heap()) -> non_neg_integer(). -size(Forest) -> - erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). - -%% Private API --spec link(heap_node(), heap_node()) -> heap_node(). -link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> - case X1 < X2 of - true -> - T1#node{rank=R+1,children=[T2|C1]}; - _ -> - T2#node{rank=R+1,children=[T1|C2]} - end. - -insTree(Tree, []) -> - [Tree]; -insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> - case R1 < R2 of - true -> - [T1|TS]; - _ -> - insTree(link(T1,T2),Rest) - end. - -getMin([T]) -> - {T,[]}; -getMin([#node{key=K} = T|TS]) -> - {#node{key=K1} = T1,TS1} = getMin(TS), - case K < K1 of - true -> {T,TS}; - _ -> {T1,[T|TS1]} - end. - -%% -- binomial_heap.erl content end -- - -%% Startup -start() -> - start([]). - -start(Options) -> - eunit_listener:start(?MODULE, Options). - -%%------------------------------------------ -%% eunit_listener callbacks -%%------------------------------------------ -init(Options) -> - #state{colored=proplists:get_bool(colored, Options), - profile=proplists:get_bool(profile, Options)}. - -handle_begin(group, Data, St) -> - GID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; -handle_begin(test, Data, St) -> - TID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. - -handle_end(group, Data, St) -> - St#state{status=merge_on_end(Data, St#state.status)}; -handle_end(test, Data, St) -> - NewStatus = merge_on_end(Data, St#state.status), - St1 = print_progress(Data, St), - St2 = record_timing(Data, St1), - St2#state{status=NewStatus}. - -handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> - Status1 = merge_on_end(Data, Status), - ID = proplists:get_value(id, Data), - St#state{status=Status1, skips=[ID|Skips]}. - -terminate({ok, Data}, St) -> - print_failures(St), - print_pending(St), - print_profile(St), - print_timing(St), - print_results(Data, St); -terminate({error, Reason}, St) -> - io:nl(), io:nl(), - print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), - sync_end(error). - -sync_end(Result) -> - receive - {stop, Reference, ReplyTo} -> - ReplyTo ! {result, Reference, Result}, - ok - end. - -%%------------------------------------------ -%% Print and collect information during run -%%------------------------------------------ -print_progress(Data, St) -> - TID = proplists:get_value(id, Data), - case proplists:get_value(status, Data) of - ok -> - print_progress_success(St), - St; - {skipped, _Reason} -> - print_progress_skipped(St), - St#state{skips=[TID|St#state.skips]}; - {error, Exception} -> - print_progress_failed(Exception, St), - St#state{failures=[TID|St#state.failures]} - end. - -record_timing(Data, State=#state{timings=T, profile=true}) -> - TID = proplists:get_value(id, Data), - case lists:keyfind(time, 1, Data) of - {time, Int} -> - %% It's a min-heap, so we insert negative numbers instead - %% of the actuals and normalize when we report on them. - T1 = insert(-Int, TID, T), - State#state{timings=T1}; - false -> - State - end; -record_timing(_Data, State) -> - State. - -print_progress_success(St) -> - print_colored(".", ?GREEN, St). - -print_progress_skipped(St) -> - print_colored("*", ?YELLOW, St). - -print_progress_failed(_Exc, St) -> - print_colored("F", ?RED, St). - -merge_on_end(Data, Dict) -> - ID = proplists:get_value(id, Data), - dict:update(ID, - fun(Old) -> - orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) - end, Dict). - -merge_data(_K, undefined, X) -> X; -merge_data(_K, X, undefined) -> X; -merge_data(_K, _, X) -> X. - -%%------------------------------------------ -%% Print information at end of run -%%------------------------------------------ -print_failures(#state{failures=[]}) -> - ok; -print_failures(#state{failures=Fails}=State) -> - io:nl(), - io:fwrite("Failures:~n",[]), - lists:foldr(print_failure_fun(State), 1, Fails), - ok. - -print_failure_fun(#state{status=Status}=State) -> - fun(Key, Count) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:fwrite("~n ~p) ~ts~n", [Count, TestId]), - print_failure_reason(proplists:get_value(status, TestData), - proplists:get_value(output, TestData), - State), - io:nl(), - Count + 1 - end. - -print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> - X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), - print_colored(X, ?CYAN, State); -print_gleam_location(_, _) -> - ok. - -inspect(X) -> - gleam@string:inspect(X). - -print_gleam_failure_reason( - #{gleam_error := assert, message := Message, value := Value}, - State -) -> - print_colored(indent(5, "~s~n", [Message]), ?RED, State), - print_colored(indent(5, " value: ", []), ?RED, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); -print_gleam_failure_reason( - #{gleam_error := todo, message := Message}, - State -) -> - print_colored(indent(5, "todo expression run~n", []), ?RED, State), - print_colored(indent(5, " message: ", []), ?RED, State), - print_colored(indent(0, "~s~n", [Message]), ?RESET, State); -print_gleam_failure_reason(Error, State) -> - print_colored(indent(5, "~p~n", [Error]), ?RED, State). - -% New Gleeunit specific formatters -print_failure_reason( - {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State -) when is_list(Stack) -> - print_gleam_failure_reason(Error, State), - print_gleam_location(Error, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "No case clause matched~n", []), ?RED, State), - print_colored(indent(5, "Value: ", []), ?CYAN, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -% From the original Erlang version -print_failure_reason({skipped, Reason}, _Output, State) -> - print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), - ?RED, State); -print_failure_reason({error, {_Class, Term, _}}, Output, State) when - is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> - print_assertion_failure(Term, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, Reason}, Output, State) -> - print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), - print_failure_output(5, Output, State). - -gleam_format_module_name(Module) -> - string:replace(atom_to_list(Module), "@", "/", all). - -print_stack(Stack, State) -> - print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), - print_stackframes(Stack, State). -print_stackframes([{eunit_test, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> - GleamModule = gleam_format_module_name(Module), - print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), - print_stackframes(Stack, State); -print_stackframes([], _State) -> - ok. - - -print_failure_output(_, <<>>, _) -> ok; -print_failure_output(_, undefined, _) -> ok; -print_failure_output(Indent, Output, State) -> - print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). - -print_assertion_failure({Type, Props}, State) -> - FailureDesc = format_assertion_failure(Type, Props, 5), - print_colored(FailureDesc, ?RED, State), - io:nl(). - -print_pending(#state{skips=[]}) -> - ok; -print_pending(#state{status=Status, skips=Skips}=State) -> - io:nl(), - io:fwrite("Pending:~n", []), - lists:foreach(fun(ID) -> - Info = dict:fetch(ID, Status), - case proplists:get_value(reason, Info) of - undefined -> - ok; - Reason -> - print_pending_reason(Reason, Info, State) - end - end, lists:reverse(Skips)), - io:nl(). - -print_pending_reason(Reason0, Data, State) -> - Text = case proplists:get_value(type, Data) of - group -> - io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); - test -> - io_lib:format(" ~ts~n", [format_test_identifier(Data)]) - end, - Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), - print_colored(Text, ?YELLOW, State), - print_colored(Reason, ?CYAN, State). - -print_profile(#state{timings=T, status=Status, profile=true}=State) -> - TopN = take(10, T), - TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), - TLG = dict:fetch([], Status), - TotalTime = proplists:get_value(time, TLG), - if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> - TopNPct = (TopNTime / TotalTime) * 100, - io:nl(), io:nl(), - io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), - lists:foreach(print_timing_fun(State), TopN), - io:nl(); - true -> ok - end; -print_profile(#state{profile=false}) -> - ok. - -print_timing(#state{status=Status}) -> - TLG = dict:fetch([], Status), - Time = proplists:get_value(time, TLG), - io:nl(), - io:fwrite("Finished in ~ts~n", [format_time(Time)]), - ok. - -print_results(Data, State) -> - Pass = proplists:get_value(pass, Data, 0), - Fail = proplists:get_value(fail, Data, 0), - Skip = proplists:get_value(skip, Data, 0), - Cancel = proplists:get_value(cancel, Data, 0), - Total = Pass + Fail + Skip + Cancel, - {Color, Result} = if Fail > 0 -> {?RED, error}; - Skip > 0; Cancel > 0 -> {?YELLOW, error}; - Pass =:= 0 -> {?YELLOW, ok}; - true -> {?GREEN, ok} - end, - print_results(Color, Total, Fail, Skip, Cancel, State), - sync_end(Result). - -print_results(Color, 0, _, _, _, State) -> - print_colored(Color, "0 tests\n", State); -print_results(Color, Total, Fail, Skip, Cancel, State) -> - SkipText = format_optional_result(Skip, "skipped"), - CancelText = format_optional_result(Cancel, "cancelled"), - Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), - print_colored(Text, Color, State). - -print_timing_fun(#state{status=Status}=State) -> - fun({Time, Key}) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:nl(), - io:fwrite(" ~ts~n", [TestId]), - print_colored([" "|format_time(abs(Time))], ?CYAN, State) - end. - -%%------------------------------------------ -%% Print to the console with the given color -%% if enabled. -%%------------------------------------------ -print_colored(Text, Color, #state{colored=true}) -> - io:fwrite("~s~ts~s", [Color, Text, ?RESET]); -print_colored(Text, _Color, #state{colored=false}) -> - io:fwrite("~ts", [Text]). - -%%------------------------------------------ -%% Generic data formatters -%%------------------------------------------ -format_function_name(M, F) -> - M1 = gleam_format_module_name(M), - io_lib:format("~ts.~ts", [M1, F]). - -format_optional_result(0, _) -> - []; -format_optional_result(Count, Text) -> - io_lib:format(", ~p ~ts", [Count, Text]). - -format_test_identifier(Data) -> - {Mod, Fun, _} = proplists:get_value(source, Data), - Line = case proplists:get_value(line, Data) of - 0 -> ""; - L -> io_lib:format(":~p", [L]) - end, - Desc = case proplists:get_value(desc, Data) of - undefined -> ""; - DescText -> io_lib:format(": ~ts", [DescText]) - end, - io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). - -format_time(undefined) -> - "? seconds"; -format_time(Time) -> - io_lib:format("~.3f seconds", [Time / 1000]). - -format_pending_reason({module_not_found, M}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Module '~ts' missing", [M1]); -format_pending_reason({no_such_function, {M,F,_}}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); -format_pending_reason({exit, Reason}) -> - io_lib:format("Related process exited with reason: ~p", [Reason]); -format_pending_reason(Reason) -> - io_lib:format("Unknown error: ~p", [Reason]). - -%% @doc Formats all the known eunit assertions, you're on your own if -%% you make an assertion yourself. -format_assertion_failure(Type, Props, I) when Type =:= assertion_failed - ; Type =:= assert -> - Keys = proplists:get_keys(Props), - HasEUnitProps = ([expression, value] -- Keys) =:= [], - HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], - if - HasEUnitProps -> - [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), - indent(I, " expected: true~n", []), - case proplists:get_value(value, Props) of - false -> - indent(I, " got: false", []); - {not_a_boolean, V} -> - indent(I, " got: ~p", [V]) - end]; - HasHamcrestProps -> - [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), - indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), - indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; - true -> - [indent(I, "Failure: unknown assert: ~p", [Props])] - end; - -format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed - ; Type =:= assertMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed - ; Type =:= assertNotMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected not: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed - ; Type =:= assertEqual -> - Expected = inspect(proplists:get_value(expected, Props)), - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were not equal~n", []), - indent(I, "expected: ~ts~n", [Expected]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed - ; Type =:= assertNotEqual -> - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were equal~n", []), - indent(I, "expected: not ~ts~n,", [Value]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertException_failed - ; Type =:= assertException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA - [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - case proplists:is_defined(unexpected_success, Props) of - true -> - [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), - indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; - false -> - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, " expected: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])] - end]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed - ; Type =:= assertNotException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - indent(I, " expected not: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])]; - -format_assertion_failure(Type, Props, I) when Type =:= command_failed - ; Type =:= command -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed - ; Type =:= assertCmd -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed - ; Type =:= assertCmdOutput -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_output, Props), - Output = proplists:get_value(output, Props), - [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: ~p~n", [Expected]), - indent(I, " got: ~p", [Output])]; - -format_assertion_failure(Type, Props, I) -> - indent(I, "~p", [{Type, Props}]). - -indent(I, Fmt, Args) -> - io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). - -extract_exception_pattern(Str) -> - ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), - {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml deleted file mode 100644 index 9e8e814435b..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/build/packages/packages.toml +++ /dev/null @@ -1,7 +0,0 @@ -[packages] -gleam_community_ansi = "1.2.0" -gleam_otp = "0.8.0" -gleam_erlang = "0.23.1" -gleam_community_colour = "1.2.0" -gleam_stdlib = "0.33.1" -gleeunit = "0.11.0" diff --git a/test-community-packages-javascript/build/packages/glerm/gleam.toml b/test-community-packages-javascript/build/packages/glerm/gleam.toml deleted file mode 100644 index bcd667357ad..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "glerm" -version = "0.1.0" -description = "A terminal wrapper for Gleam" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -licences = ["Apache-2.0"] -repository = { type = "github", user = "rawhat", repo = "glerm" } - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_erlang = "~> 0.19" -gleam_otp = "~> 0.5" -gleam_community_ansi = "~> 1.1" - -[dev-dependencies] -gleeunit = "~> 0.7" diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl deleted file mode 100644 index b2b3067fe7d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Drag.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(drag, { - button :: glerm:mouse_button(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl deleted file mode 100644 index 9342c911a37..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Focus.hrl +++ /dev/null @@ -1 +0,0 @@ --record(focus, {event :: glerm:focus_event()}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl deleted file mode 100644 index 293b9c94bc7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Key.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(key, { - key :: glerm:key_code(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl deleted file mode 100644 index f7ab57fb003..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_ListenerSpec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(listener_spec, { - init :: fun(() -> {any(), - gleam@option:option(gleam@erlang@process:selector(any()))}), - loop :: fun((glerm:listener_message(any()), any()) -> gleam@otp@actor:next(any())) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl deleted file mode 100644 index 4d1e4b707da..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Mouse.hrl +++ /dev/null @@ -1 +0,0 @@ --record(mouse, {event :: glerm:mouse_event()}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl deleted file mode 100644 index 858e2ae852d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseDown.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(mouse_down, { - button :: glerm:mouse_button(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl deleted file mode 100644 index 62eefb79d0d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_MouseUp.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(mouse_up, { - button :: glerm:mouse_button(), - modifier :: gleam@option:option(glerm:modifier()) -}). diff --git a/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl b/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl deleted file mode 100644 index b54f205f739..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/include/glerm_Unknown.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unknown, {tag :: binary(), message :: gleam@dynamic:dynamic()}). diff --git a/test-community-packages-javascript/build/packages/glerm/manifest.toml b/test-community-packages-javascript/build/packages/glerm/manifest.toml deleted file mode 100644 index c6a2c505615..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/manifest.toml +++ /dev/null @@ -1,18 +0,0 @@ -# This file was generated by Gleam -# You typically do not need to edit this file - -packages = [ - { name = "gleam_community_ansi", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_colour"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8B5A9677BC5A2738712BBAF2BA289B1D8195FDF962BBC769569976AD5E9794E1" }, - { name = "gleam_community_colour", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "036C206886AFB9F153C552700A7A0B4D2864E3BC96A20C77E5F34A013C051BE3" }, - { name = "gleam_erlang", version = "0.23.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "C21CFB816C114784E669FFF4BBF433535EEA9960FA2F216209B8691E87156B96" }, - { name = "gleam_otp", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "18EF8242A5E54BA92F717C7222F03B3228AEE00D1F286D4C56C3E8C18AA2588E" }, - { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, - { name = "gleeunit", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "1397E5C4AC4108769EE979939AC39BF7870659C5AFB714630DEEEE16B8272AD5" }, -] - -[requirements] -gleam_community_ansi = { version = "~> 1.1" } -gleam_erlang = { version = "~> 0.19" } -gleam_otp = { version = "~> 0.5" } -gleam_stdlib = { version = "~> 0.28" } -gleeunit = { version = "~> 0.7" } diff --git a/test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so b/test-community-packages-javascript/build/packages/glerm/priv/linux/libglerm.so deleted file mode 100755 index 3a0e947838344eaf03b47dc7a9b0f7baa8fd0a94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4550752 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%0AR97K*PPR&ES6o#1ZAkNG| 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 *o3+j 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�@H&Q?GaSzN;F8X}9QZ|7pW9Gz&Cx@GUc=3d< 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%0DQP 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�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%0Dpu~D_sc~ydv<C-<pF>#KeNM%Yh^!E- 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 (U!@7ioPAh+$oGvUA`cn(q{KmDs$l0Fd5_JgF}3 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 asa^m2<rI6KK5Ka`Jhs31yp#cCpYFd1Pu;}; diff --git a/test-community-packages-javascript/build/packages/glerm/priv/windows/libglerm.dll b/test-community-packages-javascript/build/packages/glerm/priv/windows/libglerm.dll deleted file mode 100644 index 2e8fd10cffc798d1a6145a9733ba4505af1454a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 352768 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 z�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꽼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�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 AN&o-= diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src b/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src deleted file mode 100644 index e3f22c0f0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src +++ /dev/null @@ -1,11 +0,0 @@ -{application, glerm, [ - {vsn, "0.1.0"}, - {applications, [gleam_community_ansi, - gleam_erlang, - gleam_otp, - gleam_stdlib, - gleeunit]}, - {description, "A terminal wrapper for Gleam"}, - {modules, [glerm]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.erl b/test-community-packages-javascript/build/packages/glerm/src/glerm.erl deleted file mode 100644 index 09ab08df23d..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm.erl +++ /dev/null @@ -1,397 +0,0 @@ --module(glerm). --compile([no_auto_import, nowarn_unused_vars]). - --export([selector/0, clear/0, draw/1, start_listener_spec/1, start_listener/2, print/1, size/0, move_to/2, enable_raw_mode/0, disable_raw_mode/0, enter_alternate_screen/0, leave_alternate_screen/0, enable_mouse_capture/0, disable_mouse_capture/0]). --export_type([modifier/0, key_code/0, mouse_button/0, mouse_event/0, focus_event/0, event/0, listener_message/1, listener_spec/2]). - --type modifier() :: shift | alt | control. - --type key_code() :: {character, binary()} | - enter | - backspace | - left | - right | - down | - up | - unsupported. - --type mouse_button() :: mouse_left | mouse_right | mouse_middle. - --type mouse_event() :: {mouse_down, - mouse_button(), - gleam@option:option(modifier())} | - {mouse_up, mouse_button(), gleam@option:option(modifier())} | - {drag, mouse_button(), gleam@option:option(modifier())} | - moved | - scroll_down | - scroll_up. - --type focus_event() :: lost | gained. - --type event() :: {focus, focus_event()} | - {key, key_code(), gleam@option:option(modifier())} | - {mouse, mouse_event()} | - {resize, integer(), integer()} | - {unknown, binary(), gleam@dynamic:dynamic()}. - --type listener_message(GUP) :: {term, event()} | {user, GUP}. - --type listener_spec(GUQ, GUR) :: {listener_spec, - fun(() -> {GUQ, gleam@option:option(gleam@erlang@process:selector(GUR))}), - fun((listener_message(GUR), GUQ) -> gleam@otp@actor:next(GUQ))}. - --spec decode_atom(binary(), GUW) -> fun((gleam@dynamic:dynamic()) -> {ok, GUW} | - {error, list(gleam@dynamic:decode_error())}). -decode_atom(Val, Actual) -> - Real_atom = erlang:binary_to_atom(Val), - Decode = gleam@function:compose( - fun gleam@erlang@atom:from_dynamic/1, - fun(Maybe_atom) -> _pipe = Maybe_atom, - gleam@result:then( - _pipe, - fun(Decoded) -> case Decoded =:= Real_atom of - true -> - {ok, Real_atom}; - - false -> - {error, - [{decode_error, - Val, - erlang:atom_to_binary(Decoded), - []}]} - end end - ) end - ), - fun(Msg) -> _pipe@1 = Decode(Msg), - gleam@result:replace(_pipe@1, Actual) end. - --spec modifier_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, - gleam@option:option(modifier())} | - {error, list(gleam@dynamic:decode_error())}). -modifier_decoder() -> - Decode_some = decode_atom( - <<"some"/utf8>>, - fun(Field@0) -> {some, Field@0} end - ), - gleam@dynamic:any( - [decode_atom(<<"none"/utf8>>, none), - gleam@function:compose( - gleam@dynamic:tuple2( - Decode_some, - decode_atom(<<"shift"/utf8>>, shift) - ), - fun(_capture) -> - gleam@result:replace(_capture, {some, shift}) - end - ), - gleam@function:compose( - gleam@dynamic:tuple2( - Decode_some, - decode_atom(<<"alt"/utf8>>, alt) - ), - fun(_capture@1) -> - gleam@result:replace(_capture@1, {some, alt}) - end - ), - gleam@function:compose( - gleam@dynamic:tuple2( - Decode_some, - decode_atom(<<"control"/utf8>>, control) - ), - fun(_capture@2) -> - gleam@result:replace(_capture@2, {some, control}) - end - )] - ). - --spec keycode_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, key_code()} | - {error, list(gleam@dynamic:decode_error())}). -keycode_decoder() -> - gleam@dynamic:any( - [begin - _pipe = gleam@dynamic:tuple2( - decode_atom( - <<"character"/utf8>>, - fun(Field@0) -> {character, Field@0} end - ), - fun gleam@dynamic:string/1 - ), - gleam@function:compose( - _pipe, - fun(Maybe_pair) -> case Maybe_pair of - {ok, {_, Value}} -> - {ok, {character, Value}}; - - {error, Err} -> - {error, Err} - end end - ) - end, - decode_atom(<<"enter"/utf8>>, enter), - decode_atom(<<"backspace"/utf8>>, backspace), - decode_atom(<<"left"/utf8>>, left), - decode_atom(<<"right"/utf8>>, right), - decode_atom(<<"down"/utf8>>, down), - decode_atom(<<"up"/utf8>>, up), - decode_atom(<<"unsupported"/utf8>>, unsupported)] - ). - --spec mouse_button_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, - mouse_button()} | - {error, list(gleam@dynamic:decode_error())}). -mouse_button_decoder() -> - gleam@dynamic:any( - [decode_atom(<<"mouse_left"/utf8>>, mouse_left), - decode_atom(<<"mouse_right"/utf8>>, mouse_right), - decode_atom(<<"mouse_middle"/utf8>>, mouse_middle)] - ). - --spec mouse_event_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, - mouse_event()} | - {error, list(gleam@dynamic:decode_error())}). -mouse_event_decoder() -> - gleam@dynamic:any( - [begin - _pipe = gleam@dynamic:tuple3( - decode_atom( - <<"mouse_down"/utf8>>, - fun(Field@0, Field@1) -> {mouse_down, Field@0, Field@1} end - ), - mouse_button_decoder(), - modifier_decoder() - ), - gleam@function:compose( - _pipe, - fun(Maybe_triple) -> case Maybe_triple of - {ok, {_, Button, Modifier}} -> - {ok, {mouse_down, Button, Modifier}}; - - {error, Err} -> - {error, Err} - end end - ) - end, - begin - _pipe@1 = gleam@dynamic:tuple3( - decode_atom( - <<"mouse_up"/utf8>>, - fun(Field@0, Field@1) -> {mouse_up, Field@0, Field@1} end - ), - mouse_button_decoder(), - modifier_decoder() - ), - gleam@function:compose( - _pipe@1, - fun(Maybe_triple@1) -> case Maybe_triple@1 of - {ok, {_, Button@1, Modifier@1}} -> - {ok, {mouse_up, Button@1, Modifier@1}}; - - {error, Err@1} -> - {error, Err@1} - end end - ) - end, - begin - _pipe@2 = gleam@dynamic:tuple3( - decode_atom( - <<"drag"/utf8>>, - fun(Field@0, Field@1) -> {drag, Field@0, Field@1} end - ), - mouse_button_decoder(), - modifier_decoder() - ), - gleam@function:compose( - _pipe@2, - fun(Maybe_triple@2) -> case Maybe_triple@2 of - {ok, {_, Button@2, Modifier@2}} -> - {ok, {drag, Button@2, Modifier@2}}; - - {error, Err@2} -> - {error, Err@2} - end end - ) - end, - decode_atom(<<"moved"/utf8>>, moved), - decode_atom(<<"scroll_down"/utf8>>, scroll_down), - decode_atom(<<"scroll_up"/utf8>>, scroll_up)] - ). - --spec selector() -> gleam@erlang@process:selector(event()). -selector() -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@4 = gleam@erlang@process:selecting_record2( - _pipe, - erlang:binary_to_atom(<<"focus"/utf8>>), - fun(Inner) -> _pipe@1 = Inner, - _pipe@2 = (gleam@dynamic:any( - [decode_atom(<<"gained"/utf8>>, gained), - decode_atom(<<"lost"/utf8>>, lost)] - ))(_pipe@1), - _pipe@3 = gleam@result:map( - _pipe@2, - fun(Field@0) -> {focus, Field@0} end - ), - gleam@result:unwrap(_pipe@3, {unknown, <<"focus"/utf8>>, Inner}) end - ), - _pipe@5 = gleam@erlang@process:selecting_record3( - _pipe@4, - erlang:binary_to_atom(<<"key"/utf8>>), - fun(First, Second) -> - Key_code = (keycode_decoder())(First), - Modifier = (modifier_decoder())(Second), - case {Key_code, Modifier} of - {{ok, Code}, {ok, Mod}} -> - {key, Code, Mod}; - - {_, _} -> - {unknown, - <<"key"/utf8>>, - gleam@dynamic:from([First, Second])} - end - end - ), - _pipe@9 = gleam@erlang@process:selecting_record2( - _pipe@5, - erlang:binary_to_atom(<<"mouse"/utf8>>), - fun(Inner@1) -> _pipe@6 = Inner@1, - _pipe@7 = (mouse_event_decoder())(_pipe@6), - _pipe@8 = gleam@result:map( - _pipe@7, - fun(Field@0) -> {mouse, Field@0} end - ), - gleam@result:lazy_unwrap( - _pipe@8, - fun() -> {unknown, <<"mouse"/utf8>>, Inner@1} end - ) end - ), - gleam@erlang@process:selecting_record3( - _pipe@9, - erlang:binary_to_atom(<<"resize"/utf8>>), - fun(First@1, Second@1) -> - Columns = gleam@dynamic:int(First@1), - Rows = gleam@dynamic:int(Second@1), - case {Columns, Rows} of - {{ok, Col}, {ok, Rows@1}} -> - {resize, Col, Rows@1}; - - {_, _} -> - {unknown, - <<"resize"/utf8>>, - gleam@dynamic:from([First@1, Second@1])} - end - end - ). - --spec clear() -> nil. -clear() -> - glerm_ffi:clear(). - --spec draw(list({integer(), integer(), binary()})) -> {ok, nil} | {error, nil}. -draw(Field@0) -> - glerm_ffi:draw(Field@0). - --spec start_listener_spec(listener_spec(any(), GVF)) -> {ok, - gleam@erlang@process:subject(listener_message(GVF))} | - {error, gleam@otp@actor:start_error()}. -start_listener_spec(Spec) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Pid = erlang:self(), - _assert_subject = (erlang:element(2, Spec))(), - {State, User_selector} = case _assert_subject of - {_, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glerm"/utf8>>, - function => <<"start_listener_spec"/utf8>>, - line => 314}) - end, - Term_selector = begin - _pipe = selector(), - gleam_erlang_ffi:map_selector( - _pipe, - fun(Field@0) -> {term, Field@0} end - ) - end, - Selector = begin - _pipe@1 = User_selector, - _pipe@4 = gleam@option:map( - _pipe@1, - fun(User) -> _pipe@2 = User, - _pipe@3 = gleam_erlang_ffi:map_selector( - _pipe@2, - fun(Field@0) -> {user, Field@0} end - ), - gleam_erlang_ffi:merge_selector( - Term_selector, - _pipe@3 - ) end - ), - gleam@option:unwrap(_pipe@4, Term_selector) - end, - gleam@erlang@process:start( - fun() -> glerm_ffi:listen(Pid) end, - true - ), - {ready, State, Selector} - end, - 500, - erlang:element(3, Spec)} - ). - --spec start_listener(GVL, fun((event(), GVL) -> gleam@otp@actor:next(GVL))) -> {ok, - gleam@erlang@process:subject(event())} | - {error, gleam@otp@actor:start_error()}. -start_listener(Initial_state, Loop) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Pid = erlang:self(), - gleam@erlang@process:start( - fun() -> glerm_ffi:listen(Pid) end, - true - ), - {ready, Initial_state, selector()} - end, - 500, - Loop} - ). - --spec print(bitstring()) -> {ok, nil} | {error, nil}. -print(Field@0) -> - glerm_ffi:print(Field@0). - --spec size() -> {ok, {integer(), integer()}} | {error, nil}. -size() -> - glerm_ffi:size(). - --spec move_to(integer(), integer()) -> nil. -move_to(Field@0, Field@1) -> - glerm_ffi:move_to(Field@0, Field@1). - --spec enable_raw_mode() -> {ok, nil} | {error, nil}. -enable_raw_mode() -> - glerm_ffi:enable_raw_mode(). - --spec disable_raw_mode() -> {ok, nil} | {error, nil}. -disable_raw_mode() -> - glerm_ffi:disable_raw_mode(). - --spec enter_alternate_screen() -> {ok, nil} | {error, nil}. -enter_alternate_screen() -> - glerm_ffi:enter_alternate_screen(). - --spec leave_alternate_screen() -> {ok, nil} | {error, nil}. -leave_alternate_screen() -> - glerm_ffi:leave_alternate_screen(). - --spec enable_mouse_capture() -> {ok, nil} | {error, nil}. -enable_mouse_capture() -> - glerm_ffi:enable_mouse_capture(). - --spec disable_mouse_capture() -> {ok, nil} | {error, nil}. -disable_mouse_capture() -> - glerm_ffi:disable_mouse_capture(). diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam b/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam deleted file mode 100644 index dc0f1394352..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam +++ /dev/null @@ -1,354 +0,0 @@ -import gleam/dynamic.{DecodeError, Decoder, Dynamic} -import gleam/function -import gleam/option.{None, Option, Some} -import gleam/result -import gleam/erlang/atom -import gleam/erlang/process.{Pid, Selector, Subject} -import gleam/otp/actor - -/// These represent the noted keys being held down when another action is taken, -/// like pressing another key or mouse button. For certain keys, things like -/// `Shift` will not be set, but instead return something like `A`. -pub type Modifier { - Shift - Alt - Control -} - -/// A particular keyboard key that was pressed. Either a character with its -/// value, or a special key. The `Unsupported` is for things like `PageUp`, etc -/// that I'm just not handling yet. -pub type KeyCode { - Character(String) - Enter - Backspace - Left - Right - Down - Up - Unsupported -} - -/// Which mouse button was pressed. These are prefixed with `Mouse` in order to -/// avoid conflicting with the arrow keys defined in `KeyCode`. -pub type MouseButton { - MouseLeft - MouseRight - MouseMiddle -} - -/// The possible types of mouse events. I think most of these will also -/// have the mouse cursor position attached. That is not supported at the moment. -pub type MouseEvent { - MouseDown(button: MouseButton, modifier: Option(Modifier)) - MouseUp(button: MouseButton, modifier: Option(Modifier)) - Drag(button: MouseButton, modifier: Option(Modifier)) - Moved - ScrollDown - ScrollUp -} - -/// When the terminal window is focused or un-focused. -pub type FocusEvent { - Lost - Gained -} - -/// The possible events coming back from the terminal. `Unknown` should -/// realistically never happen, since this library controls both ends of the -/// message passing. -pub type Event { - Focus(event: FocusEvent) - Key(key: KeyCode, modifier: Option(Modifier)) - Mouse(event: MouseEvent) - Resize(Int, Int) - Unknown(tag: String, message: Dynamic) -} - -fn decode_atom(val: String, actual: a) -> Decoder(a) { - let real_atom = atom.create_from_string(val) - let decode = - function.compose( - atom.from_dynamic, - fn(maybe_atom) { - maybe_atom - |> result.then(fn(decoded) { - case decoded == real_atom { - True -> Ok(real_atom) - False -> Error([DecodeError(val, atom.to_string(decoded), [])]) - } - }) - }, - ) - fn(msg) { - decode(msg) - |> result.replace(actual) - } -} - -fn modifier_decoder() -> Decoder(Option(Modifier)) { - let decode_some = decode_atom("some", Some) - dynamic.any([ - decode_atom("none", None), - function.compose( - dynamic.tuple2(decode_some, decode_atom("shift", Shift)), - result.replace(_, Some(Shift)), - ), - function.compose( - dynamic.tuple2(decode_some, decode_atom("alt", Alt)), - result.replace(_, Some(Alt)), - ), - function.compose( - dynamic.tuple2(decode_some, decode_atom("control", Control)), - result.replace(_, Some(Control)), - ), - ]) -} - -fn keycode_decoder() -> Decoder(KeyCode) { - dynamic.any([ - dynamic.tuple2(decode_atom("character", Character), dynamic.string) - |> function.compose(fn(maybe_pair) { - case maybe_pair { - Ok(#(_character, value)) -> Ok(Character(value)) - Error(err) -> Error(err) - } - }), - decode_atom("enter", Enter), - decode_atom("backspace", Backspace), - decode_atom("left", Left), - decode_atom("right", Right), - decode_atom("down", Down), - decode_atom("up", Up), - decode_atom("unsupported", Unsupported), - ]) -} - -fn mouse_button_decoder() -> Decoder(MouseButton) { - dynamic.any([ - decode_atom("mouse_left", MouseLeft), - decode_atom("mouse_right", MouseRight), - decode_atom("mouse_middle", MouseMiddle), - ]) -} - -fn mouse_event_decoder() -> Decoder(MouseEvent) { - dynamic.any([ - dynamic.tuple3( - decode_atom("mouse_down", MouseDown), - mouse_button_decoder(), - modifier_decoder(), - ) - |> function.compose(fn(maybe_triple) { - case maybe_triple { - Ok(#(_mouse_down, button, modifier)) -> Ok(MouseDown(button, modifier)) - Error(err) -> Error(err) - } - }), - dynamic.tuple3( - decode_atom("mouse_up", MouseUp), - mouse_button_decoder(), - modifier_decoder(), - ) - |> function.compose(fn(maybe_triple) { - case maybe_triple { - Ok(#(_mouse_up, button, modifier)) -> Ok(MouseUp(button, modifier)) - Error(err) -> Error(err) - } - }), - dynamic.tuple3( - decode_atom("drag", Drag), - mouse_button_decoder(), - modifier_decoder(), - ) - |> function.compose(fn(maybe_triple) { - case maybe_triple { - Ok(#(_drag, button, modifier)) -> Ok(Drag(button, modifier)) - Error(err) -> Error(err) - } - }), - decode_atom("moved", Moved), - decode_atom("scroll_down", ScrollDown), - decode_atom("scroll_up", ScrollUp), - ]) -} - -/// The events from the NIF are sent as messages to the calling process. These -/// do not go through a `process.Subject`, so they need to be explicitly -/// extracted from the mailbox. This selector will grab the given `Event`s for -/// each message that comes in. -pub fn selector() -> Selector(Event) { - process.new_selector() - |> process.selecting_record2( - atom.create_from_string("focus"), - fn(inner) { - inner - |> dynamic.any([decode_atom("gained", Gained), decode_atom("lost", Lost)]) - |> result.map(Focus) - |> result.unwrap(Unknown("focus", inner)) - }, - ) - |> process.selecting_record3( - atom.create_from_string("key"), - fn(first, second) { - let key_code = keycode_decoder()(first) - let modifier = modifier_decoder()(second) - case key_code, modifier { - Ok(code), Ok(mod) -> Key(code, mod) - _, _ -> Unknown("key", dynamic.from([first, second])) - } - }, - ) - |> process.selecting_record2( - atom.create_from_string("mouse"), - fn(inner) { - inner - |> mouse_event_decoder() - |> result.map(Mouse) - |> result.lazy_unwrap(fn() { Unknown("mouse", inner) }) - }, - ) - |> process.selecting_record3( - atom.create_from_string("resize"), - fn(first, second) { - let columns = dynamic.int(first) - let rows = dynamic.int(second) - case columns, rows { - Ok(col), Ok(rows) -> Resize(col, rows) - _, _ -> Unknown("resize", dynamic.from([first, second])) - } - }, - ) -} - -/// Fully clears the terminal window -pub external fn clear() -> Nil = - "glerm_ffi" "clear" - -/// Write some string to the screen at the given #(column, row) coordinate -pub external fn draw(commands: List(#(Int, Int, String))) -> Result(Nil, Nil) = - "glerm_ffi" "draw" - -/// This is the "meat" of the library. This will fire up the NIF, which spawns -/// a thread to read for terminal events. The `Pid` provided here is where the -/// messages will be sent. -external fn listen(pid: Pid) -> Result(Nil, Nil) = - "glerm_ffi" "listen" - -/// Writes the given text wherever the cursor is -pub external fn print(data: BitString) -> Result(Nil, Nil) = - "glerm_ffi" "print" - -/// Gives back the #(column, row) count of the current terminal. This can be -/// called to get the initial size, and then updated when `Resize` events -/// come in. -pub external fn size() -> Result(#(Int, Int), Nil) = - "glerm_ffi" "size" - -/// Moves the cursor to the given location -pub external fn move_to(column: Int, row: Int) -> Nil = - "glerm_ffi" "move_to" - -/// Enables "raw mode" for the terminal. This will do a better job than I can -/// at explaining what all that entails: -/// -/// https://docs.rs/crossterm/latest/crossterm/terminal/index.html#raw-mode -/// -/// If you want to control the entire screen, capture all input events, and -/// place the cursor anywhere, this is what you want. -pub external fn enable_raw_mode() -> Result(Nil, Nil) = - "glerm_ffi" "enable_raw_mode" - -/// Turns off raw mode. This will disable the features described in -/// `enable_raw_mode`. -pub external fn disable_raw_mode() -> Result(Nil, Nil) = - "glerm_ffi" "disable_raw_mode" - -/// This will create a new terminal "window" that you can interact with. This -/// will preserve the user's existing terminal when exiting the program, or -/// calling `leave_alternate_screen`. -pub external fn enter_alternate_screen() -> Result(Nil, Nil) = - "glerm_ffi" "enter_alternate_screen" - -/// See: `enter_alternate_screen` -pub external fn leave_alternate_screen() -> Result(Nil, Nil) = - "glerm_ffi" "leave_alternate_screen" - -/// This enables the capturing of mouse events. Without this, those event types -/// will not be emitted by the NIF. -pub external fn enable_mouse_capture() -> Result(Nil, Nil) = - "glerm_ffi" "enable_mouse_capture" - -/// This will stop the capture of mouse events in the terminal. -pub external fn disable_mouse_capture() -> Result(Nil, Nil) = - "glerm_ffi" "disable_mouse_capture" - -pub type ListenerMessage(user_message) { - Term(Event) - User(user_message) -} - -pub type ListenerSubject(user_message) = - Subject(ListenerMessage(user_message)) - -pub type EventSubject = - Subject(Event) - -pub type ListenerSpec(state, user_message) { - ListenerSpec( - init: fn() -> #(state, Option(Selector(user_message))), - loop: fn(ListenerMessage(user_message), state) -> actor.Next(state), - ) -} - -/// This will start the NIF listener and set up the `Event` selector. The spec -/// argument allows for behavior during the initialization of the actor. That -/// function returns the initial state, and an optional user selector. This -/// allows this actor to also receive any user-defined messages. -pub fn start_listener_spec( - spec: ListenerSpec(state, user_message), -) -> Result(ListenerSubject(user_message), actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let pid = process.self() - let assert #(state, user_selector) = spec.init() - let term_selector = - selector() - |> process.map_selector(Term) - let selector = - user_selector - |> option.map(fn(user) { - user - |> process.map_selector(User) - |> process.merge_selector(term_selector, _) - }) - |> option.unwrap(term_selector) - process.start(fn() { listen(pid) }, True) - actor.Ready(state, selector) - }, - init_timeout: 500, - loop: spec.loop, - )) -} - -/// If you are not planning on sending custom messages to the terminal listener, -/// this method is the simplest. Give an initial state for the actor, and the -/// loop will receive only `Event`s and your provided state. To allow this -/// actor to receive additional user-defined messages, see `start_listener_spec` -pub fn start_listener( - initial_state: state, - loop: fn(Event, state) -> actor.Next(state), -) -> Result(EventSubject, actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let pid = process.self() - process.start(fn() { listen(pid) }, True) - actor.Ready(initial_state, selector()) - }, - init_timeout: 500, - loop: loop, - )) -} -// TODO: -// - test? -// - docs diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl b/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl deleted file mode 100644 index 021fbde4915..00000000000 --- a/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(glerm_ffi). - --export([listen/1, print/1, size/0, clear/0, move_to/2, draw/1, enable_raw_mode/0, - disable_raw_mode/0, enter_alternate_screen/0, leave_alternate_screen/0, enable_mouse_capture/0, disable_mouse_capture/0]). - --nifs([{listen, 1}, - {print, 1}, - {size, 0}, - {clear, 0}, - {move_to, 2}, - {draw, 1}, - {enable_raw_mode, 0}, - {disable_raw_mode, 0}, - {enter_alternate_screen, 0}, - {leave_alternate_screen, 0}, - {enable_mouse_capture, 0}, - {disable_mouse_capture, 0}]). - --on_load init/0. - -init() -> - Arch = erlang:system_info(system_architecture), - Priv = code:priv_dir(glerm), - ArchPath = - case Arch of - "x86_64-pc-linux" ++ _ -> - filename:join(Priv, "linux"); - "win32" -> - filename:join(Priv, "windows"); - "x86_64-apple-drawin" ++ _ -> - filename:join(Priv, "macos") - end, - Path = filename:join(ArchPath, libglerm), - erlang:load_nif(Path, 0). - -listen(_Pid) -> - exit(nif_library_not_loaded). - -print(_Data) -> - exit(nif_library_not_loaded). - -size() -> - exit(nif_library_not_loaded). - -clear() -> - exit(nif_library_not_loaded). - -move_to(_Column, _Row) -> - exit(nif_library_not_loaded). - -draw(_Commands) -> - exit(nif_library_not_loaded). - -enable_raw_mode() -> - exit(nif_library_not_loaded). - -disable_raw_mode() -> - exit(nif_library_not_loaded). - -enter_alternate_screen() -> - exit(nif_library_not_loaded). -leave_alternate_screen() -> - exit(nif_library_not_loaded). -enable_mouse_capture() -> - exit(nif_library_not_loaded). -disable_mouse_capture() -> - exit(nif_library_not_loaded). diff --git a/test-community-packages-javascript/build/packages/gliew/README.md b/test-community-packages-javascript/build/packages/gliew/README.md deleted file mode 100644 index 4120dfe33af..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/README.md +++ /dev/null @@ -1,393 +0,0 @@ -# gliew - -[![Package Version](https://img.shields.io/hexpm/v/gliew)](https://hex.pm/packages/gliew) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gliew/) - -An **experimental** web framework with server-side rendering and optional live updating UI (à la Phoenix's LiveView) for gleam. - -## Quick start - -Usage is similar to [mist](https://hexdocs.pm/mist/) except the handler function should return a [nakai](https://hexdocs.pm/nakai/) node tree. - -```gleam -import gleam/erlang/process -import gleam/http.{Get} -import gleam/http/request -import nakai/html -import gliew - -pub fn main() { - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - Get, ["hello"] -> - html.div_text([], "Hello gleam!") - |> gliew.view(200) - _, _ -> - html.div_text([], "Hello world!") - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} -``` - -### Live mounts - -In order to have some elements of the HTML live updating you will need to use live mounts. - -They can be either used by calling the `gliew.live_mount` function directly: - -```gleam -import gleam/int -import gleam/option.{Option} -import gleam/erlang/process.{Subject} -import gleam/http/request -import nakai/html -import gliew - -pub fn main() { - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - _, _ -> - html.div( - [], - [ - html.div_text([], "counter is at:"), - gliew.live_mount( - mount: mount_counter, - with: Nil, - render: render_counter, - ), - ], - ) - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} - -// The render function is called with `None` on -// initial render but `Some(a)` every time there -// is a new value on the subject returned by the -// mount function. -fn render_counter(assign: Option(Int)) { - html.div_text( - [], - assign - |> option.unwrap(0) - |> int.to_string, - ) -} - -// This is the mount function. -fn mount_counter(_ctx) { - let subject = process.new_subject() - - let _ = process.start(fn() { loop(subject, 0) }, True) - - subject -} - -// Counter loop for demonstration purposes. -fn loop(subject: Subject(Int), current: Int) { - process.send(subject, current) - process.sleep(1000) - loop(subject, current + 1) -} -``` - -But a nicer way (IMO) is to use the `use` syntax to turn a function into a live mount by default. - -```gleam -import gleam/int -import gleam/option -import gleam/erlang/process.{Subject} -import gleam/http/request -import nakai/html -import gliew - -pub fn main() { - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - _, _ -> - html.div([], [html.div_text([], "counter is at:"), counter()]) - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} - -// This becomes the render function. -fn counter() { - // Here we use the `use` syntax as kind of a decorator - // to turn this function into a live mount. - use assign <- gliew.live_mount(mount_counter, with: Nil) - - html.div_text( - [], - assign - |> option.unwrap(0) - |> int.to_string, - ) -} - -// This is still the mount function. -fn mount_counter(_ctx) { - let subject = process.new_subject() - - let _ = process.start(fn() { loop(subject, 0) }, True) - - subject -} - -// Counter loop for demonstartion purposes. -fn loop(subject: Subject(Int), current: Int) { - process.send(subject, current) - process.sleep(1000) - loop(subject, current + 1) -} -``` - -## Example - -The following example has a random string generator and a global counter so that every browser session remains in sync when navigating to `http://localhost:8080/mounts`. - -```gleam -import gleam/int -import gleam/string -import gleam/base -import gleam/option.{None, Some} -import gleam/http.{Get, Post} -import gleam/http/request -import gleam/erlang/process.{Subject} -import gleam/crypto.{strong_random_bytes} -import nakai/html -import nakai/html/attrs -import gliew -// This is only here for this example. -// It implements an actor that keeps an -// incrementing counter and can be -// subscribed to. -import gliew/integration/counter.{ - CounterMessage, reset, start_counter, subscribe, -} - -pub fn main() { - // Start anything that will be needed by the handlers. - // In this case we start an actor that simply increments - // a counter (starting at 0). - // You can subscribe to the counter to be notified every - // time it increments. - let assert Ok(count_actor) = start_counter() - - // Start the gliew server. - // This is a thin wrapper around mist which handles - // rendering your views and starting workers for - // live connections. - let assert Ok(_) = - gliew.new( - 8080, - fn(req) { - case req.method, request.path_segments(req) { - Get, ["mounts"] -> - mounts_page(count_actor) - |> gliew.view(200) - Post, ["counter", "reset"] -> reset_counter(count_actor) - _, _ -> - home_page() - |> gliew.view(200) - } - }, - ) - |> gliew.serve - - process.sleep_forever() -} - -// You can just return a simple nakai node tree for -// a static page. -fn home_page() { - html.div_text([], "Hello gleam!") -} - -fn reset_counter(count_actor: Subject(CounterMessage)) { - reset(count_actor) - - gliew.response(204) -} - -fn mounts_page(count_actor: Subject(CounterMessage)) { - // Return the HTML for the page. - html.div( - [ - attrs.style( - [ - "display: flex", "flex-direction: column", "justify-content: center", - "align-items: center", "row-gap: 1em", "height: 100vh", - ] - |> string.join(";"), - ), - ], - [ - // Random text - html.div_text([attrs.style("font-size: x-large")], "Random text for you"), - random_text(), - // Counter - html.div_text([attrs.style("font-size: x-large")], "Counter is at"), - counter(count_actor), - html.div( - [], - [ - html.button_text([], "Reset") - |> gliew.on_click(do: Post, to: "/counter/reset"), - ], - ), - // Explanation text - html.div( - [ - attrs.style( - [ - "background-color: #d0ebf4", "padding: 1em", "color: #222", - "border-radius: 1em", "width: 21em", "margin-top: 0.5em", - ] - |> string.join(";"), - ), - ], - [ - html.div_text( - [attrs.style("font-size: x-large; margin-bottom: 0.5em;")], - "This page is live rendered.", - ), - html.div_text( - [attrs.style("font-size: large")], - "Once the browser has made a connection to the server a new random text is generated every 5 seconds and the counter above should auto-increment.", - ), - ], - ), - ], - ) -} - -// // -// Global counter live mount // -// // - -// A live mount that shows a live updating counter. -fn counter(count_actor: Subject(CounterMessage)) { - // Makes the function a live mount. - // The second parameter passed to `gliew.live_mount` will - // be passed to the mount function (first parameter) - // when the mount is mounted (i.e. the client connects - // back to the server to get live updates). - // - // The returned value is of type `Option(a)` where - // `a` is the type in the Subject returned by mount. - use assign <- gliew.live_mount(counter_mount, with: count_actor) - - let text = case assign { - // View has been mounted and we want to use the - // "live" value that was setup in the mount function. - Some(counter) -> - counter - |> int.to_string - // View is being rendered on the server before - // the client has made a connection back to the server. - // Here we contact the count_actor to get the current - // value. - None -> "Loading.." - } - - // Return the HTML of the view. - html.div_text([attrs.style("font-size: xx-large")], text) -} - -// A mount function that runs once the client connects through -// a websocket. -// This should be used to subscribe to whatever data that should -// be returned to the render function and return the subject. -fn counter_mount(count_actor: Subject(CounterMessage)) { - // Create a new subject. - let subject = process.new_subject() - - // Subscribe to counter. - subscribe(count_actor, subject) - - // Return the subject. - subject -} - -// // -// Random text live mount // -// // - -// A live mount that renders random text on an interval. -fn random_text() { - use assign <- gliew.live_mount(text_mount, with: Nil) - - html.div_text( - [attrs.style("font-size: xx-large")], - assign - |> option.unwrap(random_string()), - ) -} - -// The mount function used for the random_text mount. -// It will generate random text on an interval and -// send it on the returned subject. -fn text_mount(_) { - let subject = process.new_subject() - - let _ = process.start(fn() { loop(subject) }, True) - - subject -} - -// Random text loop. -fn loop(subject: Subject(String)) { - process.send(subject, random_string()) - process.sleep(5000) - loop(subject) -} - -// Helper function to generate random string. -fn random_string() { - strong_random_bytes(10) - |> base.encode64(False) -} -```` - -The above example implementation can be found in `test/integration/live_mounts.gleam` and quickly run with: - -```sh -gleam run -m gliew/integration/live_mounts -``` - -And then navigate to `http://localhost:8080/mounts` to see in action. - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gliew -``` - -and its documentation can be found at <https://hexdocs.pm/gliew>. diff --git a/test-community-packages-javascript/build/packages/gliew/gleam.toml b/test-community-packages-javascript/build/packages/gliew/gleam.toml deleted file mode 100644 index 391330c4572..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gliew" -version = "0.3.0" -description = "A gleam server-side rendered web framework with live updating UI" -repository = { type = "github", user = "arnarg", repo = "gliew" } -licences = ["MIT"] - -[dependencies] -gleam_stdlib = "~> 0.29" -nakai = "~> 0.8" -mist = "~> 0.11" -gleam_erlang = "~> 0.19" -gleam_otp = "~> 0.5" -gleam_crypto = "~> 0.3" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl deleted file mode 100644 index b4e74b38aa5..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(live_mount, { - selecting :: fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl deleted file mode 100644 index 8d99ff6efa5..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(get_worker, { - from :: gleam@erlang@process:subject({ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}), - id :: binary(), - csrf :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl deleted file mode 100644 index 8589100c87b..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(process_tree, { - from :: gleam@erlang@process:subject(nakai@html:node_(gliew@internal@event:event())), - request :: gleam@http@request:request(mist@internal@http:body()), - tree :: nakai@html:node_(gliew@internal@event:event()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl deleted file mode 100644 index 89ac76e9dd3..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(connect_socket, { - socket :: gleam@erlang@process:subject(glisten@handler:handler_message()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl deleted file mode 100644 index a89d582fa33..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(disconnect_socket, { - socket :: gleam@erlang@process:subject(glisten@handler:handler_message()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl deleted file mode 100644 index 2e4eb60f892..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl +++ /dev/null @@ -1 +0,0 @@ --record(live_update, {markup :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl deleted file mode 100644 index be1a4225b8f..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(response, { - status :: integer(), - headers :: list({binary(), binary()}), - body :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl deleted file mode 100644 index 5a9075101ce..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(server, { - port :: integer(), - layout :: fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), - handler :: fun((gleam@http@request:request(mist@internal@http:body())) -> gliew:response()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl deleted file mode 100644 index 96a8047b829..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(view, { - status :: integer(), - headers :: list({binary(), binary()}), - node :: nakai@html:node_(gliew@internal@event:event()) -}). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src b/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src deleted file mode 100644 index 91aa7179e93..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src +++ /dev/null @@ -1,17 +0,0 @@ -{application, gliew, [ - {vsn, "0.3.0"}, - {applications, [gleam_crypto, - gleam_erlang, - gleam_otp, - gleam_stdlib, - gleeunit, - mist, - nakai]}, - {description, "A gleam server-side rendered web framework with live updating UI"}, - {modules, [gliew, - gliew@internal@event, - gliew@internal@manager, - gliew@internal@util, - gliew@internal@worker]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew.erl deleted file mode 100644 index 1cf3336b7ff..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew.erl +++ /dev/null @@ -1,495 +0,0 @@ --module(gliew). --compile([no_auto_import, nowarn_unused_vars]). - --export([view/2, response/1, with_header/3, with_body/2, morph/0, append/0, on_click/3, live_mount/3, script/0, new/2, serve/1]). --export_type([response/0, server/0]). - --opaque response() :: {view, - integer(), - list({binary(), binary()}), - nakai@html:node_(gliew@internal@event:event())} | - {response, - integer(), - list({binary(), binary()}), - gleam@option:option(binary())}. - --type server() :: {server, - integer(), - fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), - fun((gleam@http@request:request(mist@internal@http:body())) -> response())}. - --spec view(nakai@html:node_(gliew@internal@event:event()), integer()) -> response(). -view(Node, Status) -> - {view, Status, [], Node}. - --spec response(integer()) -> response(). -response(Status) -> - {response, Status, [], none}. - --spec with_header(response(), binary(), binary()) -> response(). -with_header(Response, Key, Value) -> - case Response of - {view, Status, Headers, Node} -> - _pipe = Headers, - _pipe@1 = gleam@list:prepend(_pipe, {Key, Value}), - {view, Status, _pipe@1, Node}; - - {response, Status@1, Headers@1, Body} -> - _pipe@2 = Headers@1, - _pipe@3 = gleam@list:prepend(_pipe@2, {Key, Value}), - {response, Status@1, _pipe@3, Body} - end. - --spec with_body(response(), binary()) -> response(). -with_body(Response, Body) -> - case Response of - {response, Status, Headers, _} -> - {response, Status, Headers, {some, Body}}; - - _ -> - Response - end. - --spec morph() -> nakai@html@attrs:attr(gliew@internal@event:event()). -morph() -> - {event, <<"gliew-event"/utf8>>, morph}. - --spec append() -> nakai@html@attrs:attr(gliew@internal@event:event()). -append() -> - {event, <<"gliew-event"/utf8>>, append}. - --spec add_attr( - nakai@html:node_(gliew@internal@event:event()), - nakai@html@attrs:attr(gliew@internal@event:event()) -) -> nakai@html:node_(gliew@internal@event:event()). -add_attr(Node, Attr) -> - case Node of - {element, Tag, Attrs, Children} -> - _pipe = Attrs, - _pipe@1 = gleam@list:prepend(_pipe, Attr), - {element, Tag, _pipe@1, Children}; - - {leaf_element, Tag@1, Attrs@1} -> - _pipe@2 = Attrs@1, - _pipe@3 = gleam@list:prepend(_pipe@2, Attr), - {leaf_element, Tag@1, _pipe@3}; - - {html, Attrs@2, Children@1} -> - _pipe@4 = Attrs@2, - _pipe@5 = gleam@list:prepend(_pipe@4, Attr), - {html, _pipe@5, Children@1}; - - {body, Attrs@3, Children@2} -> - _pipe@6 = Attrs@3, - _pipe@7 = gleam@list:prepend(_pipe@6, Attr), - {body, _pipe@7, Children@2}; - - Other -> - Other - end. - --spec on_click( - nakai@html:node_(gliew@internal@event:event()), - gleam@http:method(), - binary() -) -> nakai@html:node_(gliew@internal@event:event()). -on_click(Node, Method, Path) -> - case Method of - get -> - _pipe = Node, - _pipe@1 = add_attr(_pipe, {attr, <<"hx-get"/utf8>>, Path}), - add_attr(_pipe@1, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - post -> - _pipe@2 = Node, - _pipe@3 = add_attr(_pipe@2, {attr, <<"hx-post"/utf8>>, Path}), - add_attr(_pipe@3, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - put -> - _pipe@4 = Node, - _pipe@5 = add_attr(_pipe@4, {attr, <<"hx-put"/utf8>>, Path}), - add_attr(_pipe@5, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - patch -> - _pipe@6 = Node, - _pipe@7 = add_attr(_pipe@6, {attr, <<"hx-patch"/utf8>>, Path}), - add_attr(_pipe@7, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - delete -> - _pipe@8 = Node, - _pipe@9 = add_attr(_pipe@8, {attr, <<"hx-delete"/utf8>>, Path}), - add_attr(_pipe@9, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); - - _ -> - Node - end. - --spec insert_event( - gliew@internal@event:event(), - nakai@html:node_(gliew@internal@event:event()) -) -> nakai@html:node_(gliew@internal@event:event()). -insert_event(Event, Node) -> - _pipe = Node, - add_attr(_pipe, {event, <<"gliew-event"/utf8>>, Event}). - --spec map_events( - list(nakai@html@attrs:attr(gliew@internal@event:event())), - boolean() -) -> list(nakai@html@attrs:attr(gliew@internal@event:event())). -map_events(Attrs, Render_events) -> - case Render_events of - true -> - gleam@list:map(Attrs, fun(Attr) -> case Attr of - {event, <<"gliew-event"/utf8>>, morph} -> - {attr, <<"hx-swap-oob"/utf8>>, <<"morph"/utf8>>}; - - {event, <<"gliew-event"/utf8>>, append} -> - {attr, <<"hx-swap-oob"/utf8>>, <<"beforeend"/utf8>>}; - - Other -> - Other - end end); - - false -> - Attrs - end. - --spec find_id(list(nakai@html@attrs:attr(gliew@internal@event:event()))) -> {ok, - binary()} | - {error, nil}. -find_id(Attrs) -> - _pipe = Attrs, - gleam@list:find_map(_pipe, fun(Attr) -> case Attr of - {attr, <<"id"/utf8>>, Id} -> - {ok, Id}; - - _ -> - {error, nil} - end end). - --spec random_id() -> binary(). -random_id() -> - <<"g-"/utf8, (gliew@internal@util:random_hex_string(3))/binary>>. - --spec extract_id(nakai@html:node_(gliew@internal@event:event())) -> binary(). -extract_id(Node) -> - _pipe = case Node of - {element, _, Attrs, _} -> - find_id(Attrs); - - {leaf_element, _, Attrs@1} -> - find_id(Attrs@1); - - _ -> - {error, nil} - end, - gleam@result:unwrap(_pipe, random_id()). - --spec has_id(list(nakai@html@attrs:attr(any()))) -> boolean(). -has_id(Attrs) -> - _pipe = Attrs, - gleam@list:any(_pipe, fun(A) -> case A of - {attr, <<"id"/utf8>>, _} -> - true; - - _ -> - false - end end). - --spec ensure_id( - list(nakai@html@attrs:attr(gliew@internal@event:event())), - gleam@option:option(binary()) -) -> list(nakai@html@attrs:attr(gliew@internal@event:event())). -ensure_id(Attrs, Id) -> - case has_id(Attrs) of - true -> - case Id of - {some, Id@1} -> - gleam@list:map(Attrs, fun(Attr) -> case Attr of - {attr, <<"id"/utf8>>, _} -> - nakai@html@attrs:id(Id@1); - - Other -> - Other - end end); - - none -> - Attrs - end; - - false -> - _pipe = Attrs, - gleam@list:prepend( - _pipe, - nakai@html@attrs:id( - begin - _pipe@1 = Id, - gleam@option:unwrap(_pipe@1, random_id()) - end - ) - ) - end. - --spec process_tree( - nakai@html:node_(gliew@internal@event:event()), - gleam@option:option(binary()), - boolean() -) -> nakai@html:node_(gliew@internal@event:event()). -process_tree(Node, Id, Render_events) -> - case Node of - {element, Tag, Attrs, Children} -> - _pipe = Attrs, - _pipe@1 = ensure_id(_pipe, Id), - _pipe@2 = map_events(_pipe@1, Render_events), - {element, Tag, _pipe@2, Children}; - - {leaf_element, Tag@1, Attrs@1} -> - _pipe@3 = Attrs@1, - _pipe@4 = ensure_id(_pipe@3, Id), - _pipe@5 = map_events(_pipe@4, Render_events), - {leaf_element, Tag@1, _pipe@5}; - - Other -> - Other - end. - --spec live_mount( - fun((MEC) -> gleam@erlang@process:subject(MED)), - MEC, - fun((gleam@option:option(MED)) -> nakai@html:node_(gliew@internal@event:event())) -) -> nakai@html:node_(gliew@internal@event:event()). -live_mount(Mount, Context, Render) -> - Tree = begin - _pipe = Render(none), - process_tree(_pipe, none, false) - end, - Id = extract_id(Tree), - _pipe@5 = fun(Selector) -> - Subject = Mount(Context), - _pipe@1 = Selector, - gleam@erlang@process:selecting( - _pipe@1, - Subject, - fun(Val) -> _pipe@2 = Render({some, Val}), - _pipe@3 = process_tree(_pipe@2, {some, Id}, true), - _pipe@4 = nakai:to_inline_string(_pipe@3), - {live_update, _pipe@4} end - ) - end, - _pipe@6 = {live_mount, _pipe@5}, - insert_event(_pipe@6, Tree). - --spec script() -> nakai@html:node_(any()). -script() -> - {fragment, - [{element, - <<"script"/utf8>>, - [nakai@html@attrs:src( - <<"https://unpkg.com/htmx.org@1.9.2/dist/htmx.min.js"/utf8>> - )], - []}, - {element, - <<"script"/utf8>>, - [nakai@html@attrs:src( - <<"https://unpkg.com/htmx.org@1.9.2/dist/ext/ws.js"/utf8>> - )], - []}, - {element, - <<"script"/utf8>>, - [nakai@html@attrs:src( - <<"https://unpkg.com/idiomorph@0.0.8/dist/idiomorph-ext.min.js"/utf8>> - )], - []}]}. - --spec default_layout(nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event()). -default_layout(Content) -> - {html, [], [{head, [script()]}, {body, [], [Content]}]}. - --spec new( - integer(), - fun((gleam@http@request:request(mist@internal@http:body())) -> response()) -) -> server(). -new(Port, Handler) -> - {server, Port, fun default_layout/1, Handler}. - --spec add_headers(gleam@http@response:response(MFW), list({binary(), binary()})) -> gleam@http@response:response(MFW). -add_headers(Response, Headers) -> - _pipe = Headers, - gleam@list:fold(_pipe, Response, fun(Res, Pair) -> _pipe@1 = Res, - gleam@http@response:prepend_header( - _pipe@1, - erlang:element(1, Pair), - erlang:element(2, Pair) - ) end). - --spec to_mist_response( - gleam@http@response:response(any()), - gleam@option:option(binary()) -) -> mist@internal@handler:handler_response(). -to_mist_response(Response, Body) -> - case Body of - {some, Body@1} -> - _pipe = Response, - mist:bit_builder_response( - _pipe, - gleam@bit_builder:from_string(Body@1) - ); - - none -> - _pipe@1 = Response, - mist:empty_response(_pipe@1) - end. - --spec upgrade_connection( - gleam@erlang@process:subject(gliew@internal@manager:message()), - binary(), - binary() -) -> mist@internal@handler:handler_response(). -upgrade_connection(Manager, Session, Csrf) -> - case gliew@internal@manager:get_worker(Manager, Session, Csrf) of - {ok, Worker} -> - _pipe = fun(_, _) -> {ok, nil} end, - _pipe@1 = mist@websocket:with_handler(_pipe), - _pipe@2 = mist@websocket:on_init( - _pipe@1, - fun(Socket) -> gliew@internal@worker:connect(Worker, Socket) end - ), - _pipe@3 = mist@websocket:on_close( - _pipe@2, - fun(Socket@1) -> - gliew@internal@worker:disconnect(Worker, Socket@1) - end - ), - mist:upgrade(_pipe@3); - - {error, nil} -> - _pipe@4 = gleam@http@response:new(401), - mist:empty_response(_pipe@4) - end. - --spec get_params(list({binary(), binary()})) -> {ok, {binary(), binary()}} | - {error, nil}. -get_params(Params) -> - Pmap = gleam@map:from_list(Params), - gleam@result:then( - gleam@map:get(Pmap, <<"session"/utf8>>), - fun(Session) -> - gleam@result:then( - gleam@map:get(Pmap, <<"csrf"/utf8>>), - fun(Csrf) -> {ok, {Session, Csrf}} end - ) - end - ). - --spec parse_params(gleam@http@request:request(mist@internal@http:body())) -> {ok, - {binary(), binary()}} | - {error, nil}. -parse_params(Req) -> - case erlang:element(9, Req) of - {some, Params} -> - case gleam@uri:parse_query(Params) of - {ok, Params@1} -> - _pipe@1 = gleam@list:map( - Params@1, - fun(P) -> - {erlang:element(1, P), - begin - _pipe = erlang:element(2, P), - gleam@string:replace( - _pipe, - <<" "/utf8>>, - <<"+"/utf8>> - ) - end} - end - ), - get_params(_pipe@1); - - {error, nil} -> - {error, nil} - end; - - none -> - {error, nil} - end. - --spec handle_ws_connect( - gleam@erlang@process:subject(gliew@internal@manager:message()), - gleam@http@request:request(mist@internal@http:body()) -) -> mist@internal@handler:handler_response(). -handle_ws_connect(Manager, Req) -> - case parse_params(Req) of - {ok, {Id, Csrf}} -> - upgrade_connection(Manager, Id, Csrf); - - {error, nil} -> - _pipe = gleam@http@response:new(401), - mist:empty_response(_pipe) - end. - --spec handler_func( - gleam@erlang@process:subject(gliew@internal@manager:message()), - fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), - fun((gleam@http@request:request(mist@internal@http:body())) -> response()) -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))). -handler_func(Manager, Layout, Handler) -> - _pipe@7 = fun(Req) -> - case {erlang:element(2, Req), erlang:element(8, Req)} of - {get, <<"/connect"/utf8>>} -> - handle_ws_connect(Manager, Req); - - {_, _} -> - case Handler(Req) of - {response, Status, Headers, Body} -> - _pipe = gleam@http@response:new(Status), - _pipe@1 = add_headers(_pipe, Headers), - to_mist_response(_pipe@1, Body); - - {view, Status@1, Headers@1, Node} -> - _pipe@2 = gleam@http@response:new(Status@1), - _pipe@3 = add_headers(_pipe@2, Headers@1), - mist:bit_builder_response( - _pipe@3, - begin - _pipe@4 = gliew@internal@manager:process_tree( - Manager, - Req, - Node - ), - _pipe@5 = Layout(_pipe@4), - _pipe@6 = nakai:to_string_builder(_pipe@5), - gleam@bit_builder:from_string_builder(_pipe@6) - end - ) - end - end - end, - mist:handler_func(_pipe@7). - --spec serve(server()) -> {ok, nil} | {error, glisten:start_error()}. -serve(Server) -> - gleam@result:'try'( - begin - _pipe = gliew@internal@manager:start_manager(), - gleam@result:map_error(_pipe, fun(Err) -> case Err of - init_timeout -> - acceptor_timeout; - - {init_failed, Reason} -> - {acceptor_failed, Reason}; - - {init_crashed, Any} -> - {acceptor_crashed, Any} - end end) - end, - fun(Manager) -> - mist:serve( - erlang:element(2, Server), - handler_func( - Manager, - erlang:element(3, Server), - erlang:element(4, Server) - ) - ) - end - ). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam deleted file mode 100644 index 884bdbf69ac..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam +++ /dev/null @@ -1,477 +0,0 @@ -import gleam/string -import gleam/list -import gleam/map -import gleam/result -import gleam/option.{None, Option, Some} -import gleam/uri -import gleam/bit_builder -import gleam/otp/actor -import gleam/erlang/process.{Selector, Subject} -import gleam/http.{Get} -import gleam/http/request.{Request} -import gleam/http/response.{Response as HttpResponse} -import mist.{Body} -import mist/websocket -import glisten -import glisten/handler.{HandlerMessage} -import nakai -import nakai/html -import nakai/html/attrs -import gliew/internal/event.{Event, LiveMount} -import gliew/internal/worker.{LiveUpdate, WorkerMessage} -import gliew/internal/manager.{Message as ManagerMessage} -import gliew/internal/util.{random_hex_string} - -const elem_id_prefix = "g-" - -// Response is the final response that should be returned from a -// handler. -// -pub opaque type Response { - View(status: Int, headers: List(#(String, String)), node: html.Node(Event)) - Response(status: Int, headers: List(#(String, String)), body: Option(String)) -} - -/// Creates a view response. -/// -pub fn view(node: html.Node(Event), status: Int) { - View(status, [], node) -} - -/// Creates an empty response without a body. -/// -pub fn response(status: Int) { - Response(status, [], None) -} - -/// Adds a header to a response. -/// -pub fn with_header(response: Response, key key: String, value value: String) { - case response { - View(status, headers, node) -> - headers - |> list.prepend(#(key, value)) - |> View(status, _, node) - Response(status, headers, body) -> - headers - |> list.prepend(#(key, value)) - |> Response(status, _, body) - } -} - -/// Sets body of a response. -/// -pub fn with_body(response: Response, body: String) { - case response { - Response(status, headers, _) -> Response(status, headers, Some(body)) - _ -> response - } -} - -/// Creates a HTML node tree that will be `mounted` -/// and receive live updates with data on `Subject(a)` -/// returned by the mount function. -/// -pub fn live_mount( - mount mount: fn(b) -> Subject(a), - with context: b, - render render: fn(Option(a)) -> html.Node(Event), -) { - // Render initial node tree - let tree = - render(None) - |> process_tree(None, False) - - // Get id from root element - let id = extract_id(tree) - - // Add mount event to root of tree - fn(selector: Selector(WorkerMessage)) { - // Mount component to get subject - let subject = mount(context) - - // Select and map subject - selector - |> process.selecting( - subject, - fn(val) { - render(Some(val)) - |> process_tree(Some(id), True) - |> nakai.to_inline_string - |> LiveUpdate - }, - ) - } - |> LiveMount - |> insert_event(tree) -} - -/// Attaches an on-click handler to a node by specifying -/// the HTTP method and path to make a request to when -/// clicked. -/// -pub fn on_click(node: html.Node(Event), do method: http.Method, to path: String) { - case method { - http.Get -> - node - |> add_attr(attrs.Attr("hx-get", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Post -> - node - |> add_attr(attrs.Attr("hx-post", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Put -> - node - |> add_attr(attrs.Attr("hx-put", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Patch -> - node - |> add_attr(attrs.Attr("hx-patch", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - http.Delete -> - node - |> add_attr(attrs.Attr("hx-delete", path)) - |> add_attr(attrs.Attr("hx-swap", "none")) - _ -> node - } -} - -/// Makes the live mount morph the diff of the innerHTML -/// instead of replacing the whole thing. -/// -pub fn morph() { - attrs.Event("gliew-event", event.Morph) -} - -/// Append the innerHTML of the live mount instead of -/// replacing it. -/// -pub fn append() { - attrs.Event("gliew-event", event.Append) -} - -// Add an attribute to the provided node. -// -fn add_attr(node: html.Node(Event), attr: attrs.Attr(Event)) { - case node { - html.Element(tag, attrs, children) -> - attrs - |> list.prepend(attr) - |> html.Element(tag, _, children) - html.LeafElement(tag, attrs) -> - attrs - |> list.prepend(attr) - |> html.LeafElement(tag, _) - html.Html(attrs, children) -> - attrs - |> list.prepend(attr) - |> html.Html(children) - html.Body(attrs, children) -> - attrs - |> list.prepend(attr) - |> html.Body(children) - // Other nodes don't accept attributes - // we return them unchanged - other -> other - } -} - -// Insert the event to the node. -// -fn insert_event(event: Event, node: html.Node(Event)) { - node - |> add_attr(attrs.Event("gliew-event", event)) -} - -// Adds the id attribute to the node if provided, otherwise -// generates it. -// -fn process_tree(node: html.Node(Event), id: Option(String), render_events: Bool) { - case node { - html.Element(tag, attrs, children) -> - attrs - |> ensure_id(id) - |> map_events(render_events) - |> html.Element(tag, _, children) - html.LeafElement(tag, attrs) -> - attrs - |> ensure_id(id) - |> map_events(render_events) - |> html.LeafElement(tag, _) - other -> other - } -} - -// Transforms event attributes into actual htmx attributes. -// -fn map_events(attrs: List(attrs.Attr(Event)), render_events: Bool) { - case render_events { - True -> - list.map( - attrs, - fn(attr) { - case attr { - attrs.Event("gliew-event", event.Morph) -> - attrs.Attr("hx-swap-oob", "morph") - attrs.Event("gliew-event", event.Append) -> - attrs.Attr("hx-swap-oob", "beforeend") - other -> other - } - }, - ) - False -> attrs - } -} - -// Make sure there is an id attribute in the list of attributes. -// If id is `None` it will generate one if there isn't one. -// If id is `Some(id)` it will replace any id if there is one or -// otherwise add it. -// -fn ensure_id(attrs: List(attrs.Attr(Event)), id: Option(String)) { - case has_id(attrs) { - True -> - case id { - Some(id) -> - list.map( - attrs, - fn(attr) { - case attr { - attrs.Attr("id", _) -> attrs.id(id) - other -> other - } - }, - ) - None -> attrs - } - False -> - attrs - |> list.prepend(attrs.id( - id - |> option.unwrap(random_id()), - )) - } -} - -// Extract the ID value from a HTML node. -// -fn extract_id(node: html.Node(Event)) { - case node { - html.Element(_, attrs, _) -> find_id(attrs) - html.LeafElement(_, attrs) -> find_id(attrs) - _ -> Error(Nil) - } - |> result.unwrap(random_id()) -} - -// Find id attribute in a list of attrs. -// -fn find_id(attrs: List(attrs.Attr(Event))) { - attrs - |> list.find_map(fn(attr) { - case attr { - attrs.Attr("id", id) -> Ok(id) - _ -> Error(Nil) - } - }) -} - -// Generates a random ID for a HTML id attribute. -// -fn random_id() { - elem_id_prefix <> random_hex_string(3) -} - -// Check if list of attrs has id. -// -fn has_id(attrs: List(attrs.Attr(a))) { - attrs - |> list.any(fn(a) { - case a { - attrs.Attr("id", _) -> True - _ -> False - } - }) -} - -// Server ------------------------------------------------ - -/// Returns script tags to put into your own layout in order -/// for live mounts to work. -/// -pub fn script() { - html.Fragment([ - html.Element( - tag: "script", - attrs: [attrs.src("https://unpkg.com/htmx.org@1.9.2/dist/htmx.min.js")], - children: [], - ), - html.Element( - tag: "script", - attrs: [attrs.src("https://unpkg.com/htmx.org@1.9.2/dist/ext/ws.js")], - children: [], - ), - html.Element( - tag: "script", - attrs: [ - attrs.src("https://unpkg.com/idiomorph@0.0.8/dist/idiomorph-ext.min.js"), - ], - children: [], - ), - ]) -} - -fn default_layout(content: html.Node(Event)) { - html.Html( - [], - [html.Head([script()]), html.Body(attrs: [], children: [content])], - ) -} - -/// Configuration for a server. -/// -pub type Server { - Server( - port: Int, - layout: fn(html.Node(Event)) -> html.Node(Event), - handler: fn(Request(Body)) -> Response, - ) -} - -/// Creates a configuration for a server with default -/// layout. -/// -pub fn new(port: Int, handler: fn(Request(Body)) -> Response) { - Server(port, default_layout, handler) -} - -/// Start server. -/// -pub fn serve(server: Server) { - use manager <- result.try( - manager.start_manager() - |> result.map_error(fn(err) { - case err { - actor.InitTimeout -> glisten.AcceptorTimeout - actor.InitFailed(reason) -> glisten.AcceptorFailed(reason) - actor.InitCrashed(any) -> glisten.AcceptorCrashed(any) - } - }), - ) - - mist.serve(server.port, handler_func(manager, server.layout, server.handler)) -} - -fn handler_func( - manager: Subject(ManagerMessage), - layout: fn(html.Node(Event)) -> html.Node(Event), - handler: fn(Request(Body)) -> Response, -) { - // Return actual handler func - fn(req: Request(Body)) { - case req.method, req.path { - Get, "/connect" -> handle_ws_connect(manager, req) - _, _ -> - case handler(req) { - Response(status, headers, body) -> - response.new(status) - |> add_headers(headers) - |> to_mist_response(body) - View(status, headers, node) -> - response.new(status) - |> add_headers(headers) - |> mist.bit_builder_response( - manager.process_tree(manager, req, node) - |> layout - |> nakai.to_string_builder - |> bit_builder.from_string_builder, - ) - } - } - } - |> mist.handler_func -} - -fn add_headers(response: HttpResponse(a), headers: List(#(String, String))) { - headers - |> list.fold( - response, - fn(res, pair) { - res - |> response.prepend_header(pair.0, pair.1) - }, - ) -} - -fn to_mist_response(response, body: Option(String)) { - case body { - Some(body) -> - response - |> mist.bit_builder_response(bit_builder.from_string(body)) - None -> - response - |> mist.empty_response - } -} - -fn handle_ws_connect(manager: Subject(ManagerMessage), req: Request(Body)) { - case parse_params(req) { - Ok(#(id, csrf)) -> upgrade_connection(manager, id, csrf) - Error(Nil) -> - response.new(401) - |> mist.empty_response - } -} - -fn upgrade_connection( - manager: Subject(ManagerMessage), - session: String, - csrf: String, -) { - case manager.get_worker(manager, session, csrf) { - Ok(worker) -> - fn(_msg, _subject: Subject(HandlerMessage)) { Ok(Nil) } - |> websocket.with_handler - |> websocket.on_init(fn(socket: Subject(HandlerMessage)) { - worker.connect(worker, socket) - }) - |> websocket.on_close(fn(socket: Subject(HandlerMessage)) { - worker.disconnect(worker, socket) - }) - |> mist.upgrade - Error(Nil) -> - response.new(401) - |> mist.empty_response - } -} - -fn parse_params(req: Request(Body)) { - case req.query { - Some(params) -> - case uri.parse_query(params) { - Ok(params) -> - list.map( - params, - fn(p) { - #( - p.0, - p.1 - |> string.replace(" ", "+"), - ) - }, - ) - |> get_params - Error(Nil) -> Error(Nil) - } - None -> Error(Nil) - } -} - -fn get_params(params: List(#(String, String))) { - let pmap = map.from_list(params) - - use session <- result.then(map.get(pmap, "session")) - use csrf <- result.then(map.get(pmap, "csrf")) - - Ok(#(session, csrf)) -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam deleted file mode 100644 index 87e56938353..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam +++ /dev/null @@ -1,20 +0,0 @@ -import gleam/erlang/process.{Selector} -import gliew/internal/worker.{WorkerMessage} - -// Event is a special type that can be added to attributes -// in HTML tree elements. -// That way we can just return a HTML tree of `html.Node(Event)` -// and later walk the tree to extract various data from it. -// -pub type Event { - // Instructs that the HTML node is the root of a mount - // and contains the selector function for the worker - // to know how to process updates. - LiveMount(selecting: fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)) - // Instructs us to add a `hx-swap-oob="morph"` to the - // mount. - Morph - // Instruct us to add `hx-swap-oob="beforeend"` to the - // mount. - Append -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam deleted file mode 100644 index 44f711a7286..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam +++ /dev/null @@ -1,222 +0,0 @@ -import gleam/map.{Map} -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/result -import gleam/otp/actor -import gleam/erlang/process.{Selector, Subject} -import gleam/http/request.{Request} -import nakai -import nakai/html -import nakai/html/attrs -import mist.{Body} -import gliew/internal/event.{Event, LiveMount} -import gliew/internal/worker.{WorkerMessage} -import gliew/internal/util.{random_hex_string} - -const sess_id_prefix = "gliew-" - -const csrf_prefix = "g-" - -type LoopState { - LoopState(sessions: Map(String, Session)) -} - -type Session { - Session( - id: String, - csrf: String, - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), - tree: html.Node(Event), - worker: Option(Subject(WorkerMessage)), - ) -} - -pub type Message { - ProcessTree( - from: Subject(html.Node(Event)), - request: Request(Body), - tree: html.Node(Event), - ) - GetWorker( - from: Subject(Result(Subject(WorkerMessage), Nil)), - id: String, - csrf: String, - ) -} - -pub fn start_manager() { - actor.start(LoopState(sessions: map.new()), loop) -} - -fn loop(message: Message, state: LoopState) -> actor.Next(LoopState) { - case message { - // Process tree - ProcessTree(from, _, tree) -> - case extract_selects([], tree) { - // Regular static view - [] -> { - process.send(from, tree) - - actor.Continue(state) - } - selects -> { - // Create a session ID - let sess_id = sess_id_prefix <> random_hex_string(10) - // Create a CSRF token - let csrf = csrf_prefix <> random_hex_string(24) - - process.send( - from, - tree - |> wrap_live_view(sess_id, csrf), - ) - - actor.Continue(LoopState( - sessions: state.sessions - |> map.insert(sess_id, Session(sess_id, csrf, selects, tree, None)), - )) - } - } - - // Get worker for session - GetWorker(from, id, csrf) -> { - case - state.sessions - |> map.get(id) - { - // Found session - Ok(sess) -> - case - sess - |> validate_session(csrf, _) - |> result.map(get_worker_from_sess) - |> result.flatten - { - // We got a worker - Ok(worker) -> { - process.send(from, Ok(worker)) - - state.sessions - |> map.insert(id, Session(..sess, worker: Some(worker))) - |> LoopState - |> actor.Continue - } - - // We failed to get a worker - Error(Nil) -> { - process.send(from, Error(Nil)) - actor.Continue(state) - } - } - - // Sessions does not exist - Error(Nil) -> { - process.send(from, Error(Nil)) - actor.Continue(state) - } - } - } - } -} - -// Validates that the provided csrf token matches -// the session's csrf. -// -fn validate_session(csrf: String, sess: Session) { - case sess { - Session(csrf: token, ..) if csrf == token -> Ok(sess) - _ -> Error(Nil) - } -} - -// Get a worker by either extracting it from the -// session or starting a new one. -// -fn get_worker_from_sess(sess: Session) { - case sess.worker { - // There's already a running worker we can - // return. - Some(worker) -> Ok(worker) - // There isn't a runnig worker so we need - // to start one. - None -> - case worker.start_worker(sess.selects) { - // Worker started successfully - Ok(worker) -> Ok(worker) - // Worker failed starting - Error(_) -> Error(Nil) - } - } -} - -// Walks the node tree until it finds a `LiveMount` event and adds -// its select function to the list of of all select functions -// in the tree. -// -fn extract_selects( - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), - node: html.Node(Event), -) { - case node { - html.Element(_, attrs, children) -> - case extract_event(attrs) { - Ok(LiveMount(selector)) -> - selects - |> list.prepend(selector) - Error(Nil) -> - children - |> list.fold(selects, extract_selects) - } - html.LeafElement(_, attrs) -> - case extract_event(attrs) { - Ok(LiveMount(selector)) -> - selects - |> list.prepend(selector) - Error(Nil) -> selects - } - _ -> selects - } -} - -// Extract a single gliew event attribute. -// -fn extract_event(attrs: List(attrs.Attr(Event))) { - attrs - |> list.find_map(fn(attr) { - case attr { - attrs.Event("gliew-event", event) -> Ok(event) - _ -> Error(Nil) - } - }) -} - -// Wrap a container around a node tree containing any -// live mounts inside. -// This instructs htmx to make a websocket connection back -// to the server. -// -fn wrap_live_view(markup: html.Node(Event), session_id: String, csrf: String) { - html.div( - [ - attrs.Attr("hx-ext", "ws"), - attrs.Attr( - "ws-connect", - "/connect?session=" <> session_id <> "&csrf=" <> csrf, - ), - attrs.Attr("hx-ext", "morph"), - ], - [markup], - ) -} - -pub fn process_tree( - subject: Subject(Message), - request: Request(Body), - tree: html.Node(Event), -) { - process.call(subject, ProcessTree(_, request, tree), 1000) -} - -pub fn get_worker(manager: Subject(Message), id: String, csrf: String) { - process.call(manager, GetWorker(_, id, csrf), 1000) -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam deleted file mode 100644 index 3eb23e4a052..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam +++ /dev/null @@ -1,18 +0,0 @@ -import gleam/int -import gleam/string -import gleam/crypto - -pub fn random_hex_string(len: Int) { - crypto.strong_random_bytes(len) - |> to_hex_string -} - -fn to_hex_string(bstr: BitString) { - case bstr { - <<>> -> "" - <<a:8, rest:bit_string>> -> { - int.to_base16(a) - |> string.lowercase <> to_hex_string(rest) - } - } -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam deleted file mode 100644 index 36b0f78e703..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam +++ /dev/null @@ -1,128 +0,0 @@ -import gleam/io -import gleam/string -import gleam/list -import gleam/option.{None, Option, Some} -import gleam/function -import gleam/otp/actor -import gleam/erlang/process.{Selector, Subject, Timer} -import glisten/handler.{HandlerMessage} -import mist/websocket -import mist/internal/websocket.{TextMessage} as iws - -// inactivity timeout of 10 minutes -const timeout = 600_000 - -type State { - State( - self: Subject(WorkerMessage), - socket: Option(Subject(HandlerMessage)), - timer: Option(Timer), - ) -} - -pub type WorkerMessage { - LiveUpdate(markup: String) - ConnectSocket(socket: Subject(HandlerMessage)) - DisconnectSocket(socket: Subject(HandlerMessage)) - Shutdown -} - -pub fn start_worker( - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), -) { - actor.start_spec(actor.Spec( - init: fn() { - let subject = process.new_subject() - - // Apply selectors from live mounts. - let selector = - process.new_selector() - |> process.selecting(subject, function.identity) - |> apply_selects(selects) - - // Send ourselves a shutdown timer that we will wait - // for a socket for. - let timer = process.send_after(subject, timeout, Shutdown) - - actor.Ready(State(subject, None, Some(timer)), selector) - }, - init_timeout: 1000, - loop: worker_loop, - )) -} - -fn worker_loop(msg: WorkerMessage, state: State) { - case msg { - // We got a new live mount update. - LiveUpdate(markup) -> - case state.socket { - // We have a socket to send data to. - Some(sock) -> { - // Send updated markup to websocket. - websocket.send(sock, TextMessage(markup)) - - actor.Continue(state) - } - // No socket is connected to the worker. - None -> actor.Continue(state) - } - // We got a socket to join. - ConnectSocket(sock) -> { - // Cancel timer - case state.timer { - Some(timer) -> { - process.cancel_timer(timer) - Nil - } - None -> Nil - } - - // Update state - actor.Continue(State(..state, socket: Some(sock), timer: None)) - } - // We should disconnect from socket. - DisconnectSocket(sock) -> - case state.socket { - // We have a socket and the socket matches - // the one we should disconnect from. - Some(socket) if sock == socket -> - // Send ourselves a Shutdown message after timeout. - process.send_after(state.self, timeout, Shutdown) - |> Some - |> State(state.self, None, _) - |> actor.Continue - // Either we don't have a socket or the - // one provided doesn't match so we - // ignore the message. - _ -> actor.Continue(state) - } - // We got a shutdown message. - Shutdown -> { - io.println( - "shutting down worker " <> string.inspect(process.subject_owner( - state.self, - )), - ) - actor.Stop(process.Normal) - } - } -} - -fn apply_selects( - selector: Selector(WorkerMessage), - selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), -) { - selector - |> list.fold(selects, _, fn(selector, selecting) { selecting(selector) }) -} - -pub fn connect(worker: Subject(WorkerMessage), socket: Subject(HandlerMessage)) { - process.send(worker, ConnectSocket(socket)) -} - -pub fn disconnect( - worker: Subject(WorkerMessage), - socket: Subject(HandlerMessage), -) { - process.send(worker, DisconnectSocket(socket)) -} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl deleted file mode 100644 index 24d4dcdf4fa..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl +++ /dev/null @@ -1,11 +0,0 @@ --module(gliew@internal@event). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([event/0]). - --type event() :: {live_mount, - fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))} | - morph | - append. - - diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl deleted file mode 100644 index 4686ce82cde..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl +++ /dev/null @@ -1,216 +0,0 @@ --module(gliew@internal@manager). --compile([no_auto_import, nowarn_unused_vars]). - --export([process_tree/3, get_worker/3, start_manager/0]). --export_type([loop_state/0, session/0, message/0]). - --type loop_state() :: {loop_state, gleam@map:map_(binary(), session())}. - --type session() :: {session, - binary(), - binary(), - list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))), - nakai@html:node_(gliew@internal@event:event()), - gleam@option:option(gleam@erlang@process:subject(gliew@internal@worker:worker_message()))}. - --type message() :: {process_tree, - gleam@erlang@process:subject(nakai@html:node_(gliew@internal@event:event())), - gleam@http@request:request(mist@internal@http:body()), - nakai@html:node_(gliew@internal@event:event())} | - {get_worker, - gleam@erlang@process:subject({ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}), - binary(), - binary()}. - --spec validate_session(binary(), session()) -> {ok, session()} | {error, nil}. -validate_session(Csrf, Sess) -> - case Sess of - {session, _, Token, _, _, _} when Csrf =:= Token -> - {ok, Sess}; - - _ -> - {error, nil} - end. - --spec get_worker_from_sess(session()) -> {ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}. -get_worker_from_sess(Sess) -> - case erlang:element(6, Sess) of - {some, Worker} -> - {ok, Worker}; - - none -> - case gliew@internal@worker:start_worker(erlang:element(4, Sess)) of - {ok, Worker@1} -> - {ok, Worker@1}; - - {error, _} -> - {error, nil} - end - end. - --spec extract_event(list(nakai@html@attrs:attr(gliew@internal@event:event()))) -> {ok, - gliew@internal@event:event()} | - {error, nil}. -extract_event(Attrs) -> - _pipe = Attrs, - gleam@list:find_map(_pipe, fun(Attr) -> case Attr of - {event, <<"gliew-event"/utf8>>, Event} -> - {ok, Event}; - - _ -> - {error, nil} - end end). - --spec wrap_live_view( - nakai@html:node_(gliew@internal@event:event()), - binary(), - binary() -) -> nakai@html:node_(gliew@internal@event:event()). -wrap_live_view(Markup, Session_id, Csrf) -> - nakai@html:'div'( - [{attr, <<"hx-ext"/utf8>>, <<"ws"/utf8>>}, - {attr, - <<"ws-connect"/utf8>>, - <<<<<<"/connect?session="/utf8, Session_id/binary>>/binary, - "&csrf="/utf8>>/binary, - Csrf/binary>>}, - {attr, <<"hx-ext"/utf8>>, <<"morph"/utf8>>}], - [Markup] - ). - --spec process_tree( - gleam@erlang@process:subject(message()), - gleam@http@request:request(mist@internal@http:body()), - nakai@html:node_(gliew@internal@event:event()) -) -> nakai@html:node_(gliew@internal@event:event()). -process_tree(Subject, Request, Tree) -> - gleam@erlang@process:call( - Subject, - fun(_capture) -> {process_tree, _capture, Request, Tree} end, - 1000 - ). - --spec get_worker(gleam@erlang@process:subject(message()), binary(), binary()) -> {ok, - gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | - {error, nil}. -get_worker(Manager, Id, Csrf) -> - gleam@erlang@process:call( - Manager, - fun(_capture) -> {get_worker, _capture, Id, Csrf} end, - 1000 - ). - --spec extract_selects( - list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))), - nakai@html:node_(gliew@internal@event:event()) -) -> list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))). -extract_selects(Selects, Node) -> - case Node of - {element, _, Attrs, Children} -> - case extract_event(Attrs) of - {ok, {live_mount, Selector}} -> - _pipe = Selects, - gleam@list:prepend(_pipe, Selector); - - {error, nil} -> - _pipe@1 = Children, - gleam@list:fold(_pipe@1, Selects, fun extract_selects/2) - end; - - {leaf_element, _, Attrs@1} -> - case extract_event(Attrs@1) of - {ok, {live_mount, Selector@1}} -> - _pipe@2 = Selects, - gleam@list:prepend(_pipe@2, Selector@1); - - {error, nil} -> - Selects - end; - - _ -> - Selects - end. - --spec loop(message(), loop_state()) -> gleam@otp@actor:next(loop_state()). -loop(Message, State) -> - case Message of - {process_tree, From, _, Tree} -> - case extract_selects([], Tree) of - [] -> - gleam@erlang@process:send(From, Tree), - {continue, State}; - - Selects -> - Sess_id = <<"gliew-"/utf8, - (gliew@internal@util:random_hex_string(10))/binary>>, - Csrf = <<"g-"/utf8, - (gliew@internal@util:random_hex_string(24))/binary>>, - gleam@erlang@process:send( - From, - begin - _pipe = Tree, - wrap_live_view(_pipe, Sess_id, Csrf) - end - ), - {continue, - {loop_state, - begin - _pipe@1 = erlang:element(2, State), - gleam@map:insert( - _pipe@1, - Sess_id, - {session, - Sess_id, - Csrf, - Selects, - Tree, - none} - ) - end}} - end; - - {get_worker, From@1, Id, Csrf@1} -> - case begin - _pipe@2 = erlang:element(2, State), - gleam@map:get(_pipe@2, Id) - end of - {ok, Sess} -> - case begin - _pipe@3 = Sess, - _pipe@4 = validate_session(Csrf@1, _pipe@3), - _pipe@5 = gleam@result:map( - _pipe@4, - fun get_worker_from_sess/1 - ), - gleam@result:flatten(_pipe@5) - end of - {ok, Worker} -> - gleam@erlang@process:send(From@1, {ok, Worker}), - _pipe@6 = erlang:element(2, State), - _pipe@7 = gleam@map:insert( - _pipe@6, - Id, - erlang:setelement(6, Sess, {some, Worker}) - ), - _pipe@8 = {loop_state, _pipe@7}, - {continue, _pipe@8}; - - {error, nil} -> - gleam@erlang@process:send(From@1, {error, nil}), - {continue, State} - end; - - {error, nil} -> - gleam@erlang@process:send(From@1, {error, nil}), - {continue, State} - end - end. - --spec start_manager() -> {ok, gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start_manager() -> - gleam@otp@actor:start({loop_state, gleam@map:new()}, fun loop/2). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl deleted file mode 100644 index d5e9e805dbb..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl +++ /dev/null @@ -1,23 +0,0 @@ --module(gliew@internal@util). --compile([no_auto_import, nowarn_unused_vars]). - --export([random_hex_string/1]). - --spec to_hex_string(bitstring()) -> binary(). -to_hex_string(Bstr) -> - case Bstr of - <<>> -> - <<""/utf8>>; - - <<A:8, Rest/bitstring>> -> - <<(begin - _pipe = gleam@int:to_base16(A), - gleam@string:lowercase(_pipe) - end)/binary, - (to_hex_string(Rest))/binary>> - end. - --spec random_hex_string(integer()) -> binary(). -random_hex_string(Len) -> - _pipe = crypto:strong_rand_bytes(Len), - to_hex_string(_pipe). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl deleted file mode 100644 index 090e6b398c1..00000000000 --- a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl +++ /dev/null @@ -1,129 +0,0 @@ --module(gliew@internal@worker). --compile([no_auto_import, nowarn_unused_vars]). - --export([start_worker/1, connect/2, disconnect/2]). --export_type([state/0, worker_message/0]). - --type state() :: {state, - gleam@erlang@process:subject(worker_message()), - gleam@option:option(gleam@erlang@process:subject(glisten@handler:handler_message())), - gleam@option:option(gleam@erlang@process:timer())}. - --type worker_message() :: {live_update, binary()} | - {connect_socket, - gleam@erlang@process:subject(glisten@handler:handler_message())} | - {disconnect_socket, - gleam@erlang@process:subject(glisten@handler:handler_message())} | - shutdown. - --spec worker_loop(worker_message(), state()) -> gleam@otp@actor:next(state()). -worker_loop(Msg, State) -> - case Msg of - {live_update, Markup} -> - case erlang:element(3, State) of - {some, Sock} -> - mist@websocket:send(Sock, {text_message, Markup}), - {continue, State}; - - none -> - {continue, State} - end; - - {connect_socket, Sock@1} -> - case erlang:element(4, State) of - {some, Timer} -> - gleam@erlang@process:cancel_timer(Timer), - nil; - - none -> - nil - end, - {continue, - erlang:setelement( - 4, - erlang:setelement(3, State, {some, Sock@1}), - none - )}; - - {disconnect_socket, Sock@2} -> - case erlang:element(3, State) of - {some, Socket} when Sock@2 =:= Socket -> - _pipe = gleam@erlang@process:send_after( - erlang:element(2, State), - 600000, - shutdown - ), - _pipe@1 = {some, _pipe}, - _pipe@2 = {state, erlang:element(2, State), none, _pipe@1}, - {continue, _pipe@2}; - - _ -> - {continue, State} - end; - - shutdown -> - gleam@io:println( - <<"shutting down worker "/utf8, - (gleam@string:inspect( - gleam@erlang@process:subject_owner( - erlang:element(2, State) - ) - ))/binary>> - ), - {stop, normal} - end. - --spec apply_selects( - gleam@erlang@process:selector(worker_message()), - list(fun((gleam@erlang@process:selector(worker_message())) -> gleam@erlang@process:selector(worker_message()))) -) -> gleam@erlang@process:selector(worker_message()). -apply_selects(Selector, Selects) -> - _pipe = Selector, - gleam@list:fold( - Selects, - _pipe, - fun(Selector@1, Selecting) -> Selecting(Selector@1) end - ). - --spec start_worker( - list(fun((gleam@erlang@process:selector(worker_message())) -> gleam@erlang@process:selector(worker_message()))) -) -> {ok, gleam@erlang@process:subject(worker_message())} | - {error, gleam@otp@actor:start_error()}. -start_worker(Selects) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun gleam@function:identity/1 - ), - apply_selects(_pipe@1, Selects) - end, - Timer = gleam@erlang@process:send_after( - Subject, - 600000, - shutdown - ), - {ready, {state, Subject, none, {some, Timer}}, Selector} - end, - 1000, - fun worker_loop/2} - ). - --spec connect( - gleam@erlang@process:subject(worker_message()), - gleam@erlang@process:subject(glisten@handler:handler_message()) -) -> nil. -connect(Worker, Socket) -> - gleam@erlang@process:send(Worker, {connect_socket, Socket}). - --spec disconnect( - gleam@erlang@process:subject(worker_message()), - gleam@erlang@process:subject(glisten@handler:handler_message()) -) -> nil. -disconnect(Worker, Socket) -> - gleam@erlang@process:send(Worker, {disconnect_socket, Socket}). diff --git a/test-community-packages-javascript/build/packages/glisten/README.md b/test-community-packages-javascript/build/packages/glisten/README.md deleted file mode 100644 index 2a9db26bb3a..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/README.md +++ /dev/null @@ -1,132 +0,0 @@ -# glisten - -See the docs [here](https://hexdocs.pm/glisten/). - -It uses the `gleam_otp` library to handle the supervisor and child processes. - -`glisten` provides a supervisor which manages a pool of acceptors. Each acceptor -will block on `accept` until a connection is opened. The acceptor will then -spawn a handler process and then block again on `accept`. - -The most obvious entrypoint is `glisten.{serve}` which listens for TCP -connections on a given port. It also takes a handler function wrapper -`handler.{func}` which you can provide functionality to, and the state which -each TCP connection process will hold. This takes the shape of: - -```gleam -type HandlerFunc(data) = - fn(BitString, LoopState(data)) -> actor.Next(LoopState(data)) -``` - -SSL is also handled using the `glisten.{serve_ssl}` method. This requires a -certificate and key file path. The rest of the handler flow remains unchanged. - -`glisten` doesn't provide a public API for connected clients. In order to hook -into the socket lifecyle, you can establish some functions which are called -for the opening and closing of the socket. An example is provided below. - -## Examples - -Here is a basic echo server: - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/otp/actor -import gleam/result -import glisten/acceptor -import glisten/handler -import glisten/tcp -import glisten - -pub fn main() { - handler.func(fn(msg, state) { - assert Ok(_) = tcp.send(state.socket, bit_builder.from_bit_string(msg)) - actor.Continue(state) - }) - |> acceptor.new_pool - |> glisten.serve(8080, _) - |> result.map(fn(_) { process.sleep_forever() }) -} -``` - -To serve over SSL: - -```gleam -// ... -import glisten/ssl - -pub fn main() { - handler.func(fn(msg, state) { - assert Ok(_) = ssl.send(state.socket, bit_builder.from_bit_string(msg)) - actor.Continue(state) - }) - |> acceptor.new_pool - |> glisten.serve_ssl( - // Passing labeled arguments for clarity - port: 8080, - certfile: "/path/to/server.crt", - keyfile: "/path/to/server.key", - with_pool: _, - ) - |> result.map(fn(_) { process.sleep_forever() }) -} -``` - -Managing connected clients can be handled similarly to this simple example. -The `with_init` callback will be called after the SSL handshake, if the -underlying socket is set up to use it. - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import glisten/handler -import glisten/tcp -import glisten - -pub fn main() { - // This function is omitted for brevity. It simply manages a - // `gleam/set.{Set}` of `Sender(HandlerMessage)`s that "broadcast" the - // connect/disconnect events to all clients. - assert Ok(connections) = start_connection_actor() - - handler.func(fn(msg, state) { - assert Ok(_) = tcp.send(state.socket, bit_builder.from_bit_string(msg)) - actor.Continue(state) - }) - |> acceptor.new_pool - |> acceptor.with_init(fn(sender) { - process.send(connections, Connected(sender)) - - Nil - }) - |> acceptor.with_close(fn(sender) { - process.send(connections, Disconnected(sender)) - - Nil - }) - |> glisten.serve(8080, _) - |> result.map(fn(_) { process.sleep_forever() }) -} -``` - -But you can also drop down to the lower level listen/accept flow if you'd prefer -to manage connections yourself, or only handle a small number at a time. - -```gleam -import gleam/io -import glisten/socket/options.{ActiveMode, Passive} -import glisten/tcp - -pub fn main() { - try listener = tcp.listen(8000, [ActiveMode(Passive)]) - try socket = tcp.accept(listener) - try msg = tcp.receive(socket, 0) - io.debug(#("got a msg", msg)) - - Ok(Nil) -} -``` - -See [mist](https://github.com/rawhat/mist) for HTTP support built on top of -this library. diff --git a/test-community-packages-javascript/build/packages/glisten/gleam.toml b/test-community-packages-javascript/build/packages/glisten/gleam.toml deleted file mode 100644 index f6cdc2792bf..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "glisten" -version = "0.7.0" -description = "a shiny Gleam TCP/SSL server" -licences = ["Apache-2.0"] -repository = { type = "github", user = "rawhat", repo = "glisten" } - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_otp = "~> 0.5" -gleam_erlang = "~> 0.18" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl deleted file mode 100644 index 0dd99accb49..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(acceptor_state, { - sender :: gleam@erlang@process:subject(glisten@acceptor:acceptor_message()), - socket :: gleam@option:option(glisten@socket:socket()), - transport :: glisten@socket@transport:transport() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl deleted file mode 100644 index 71796ee3ea4..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(pool, { - listener_socket :: glisten@socket:listen_socket(), - handler :: fun((glisten@handler:handler_message(), glisten@handler:loop_state(any())) -> gleam@otp@actor:next(glisten@handler:loop_state(any()))), - initial_data :: any(), - pool_count :: integer(), - on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - transport :: glisten@socket@transport:transport() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl deleted file mode 100644 index 4f553b84c48..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl +++ /dev/null @@ -1,8 +0,0 @@ --record(handler, { - socket :: glisten@socket:socket(), - initial_data :: any(), - loop :: fun((glisten@handler:handler_message(), glisten@handler:loop_state(any())) -> gleam@otp@actor:next(glisten@handler:loop_state(any()))), - on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - transport :: glisten@socket@transport:transport() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl deleted file mode 100644 index 8ba0b7f5452..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(loop_state, { - socket :: glisten@socket:socket(), - sender :: gleam@erlang@process:subject(glisten@handler:handler_message()), - transport :: glisten@socket@transport:transport(), - data :: any() -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl deleted file mode 100644 index 858335aa80c..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ssl, {socket :: gleam@otp@port:port_(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl deleted file mode 100644 index 2c0ad76b188..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl +++ /dev/null @@ -1 +0,0 @@ --record(tcp, {socket :: gleam@otp@port:port_(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl deleted file mode 100644 index c97154c6447..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl +++ /dev/null @@ -1,34 +0,0 @@ --record(ssl, { - accept :: fun((glisten@socket:listen_socket()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - accept_timeout :: fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - close :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - controlling_process :: fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}), - handshake :: fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - listen :: fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - negotiated_protocol :: fun((glisten@socket:socket()) -> {ok, binary()} | - {error, binary()}), - 'receive' :: fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - receive_timeout :: fun((glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}), - send :: fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - set_opts :: fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - shutdown :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - socket_info :: fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic())) -}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl deleted file mode 100644 index 3d655dfb48f..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl +++ /dev/null @@ -1,34 +0,0 @@ --record(tcp, { - accept :: fun((glisten@socket:listen_socket()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - accept_timeout :: fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - close :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - controlling_process :: fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}), - handshake :: fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - listen :: fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - negotiated_protocol :: fun((glisten@socket:socket()) -> {ok, binary()} | - {error, binary()}), - 'receive' :: fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - receive_timeout :: fun((glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}), - send :: fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - set_opts :: fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - shutdown :: fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - socket_info :: fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic())) -}). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src b/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src deleted file mode 100644 index c89d29a854d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src +++ /dev/null @@ -1,18 +0,0 @@ -{application, glisten, [ - {vsn, "0.7.0"}, - {applications, [gleam_erlang, - gleam_otp, - gleam_stdlib, - gleeunit]}, - {description, "a shiny Gleam TCP/SSL server"}, - {modules, [glisten, - glisten@acceptor, - glisten@handler, - glisten@logger, - glisten@socket, - glisten@socket@options, - glisten@socket@transport, - glisten@ssl, - glisten@tcp]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten.erl deleted file mode 100644 index b29f20f1fff..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(glisten). --compile([no_auto_import, nowarn_unused_vars]). - --export([serve/2, serve_ssl/4]). --export_type([start_error/0]). - --type start_error() :: listener_closed | - listener_timeout | - acceptor_timeout | - {acceptor_failed, gleam@erlang@process:exit_reason()} | - {acceptor_crashed, gleam@dynamic:dynamic()} | - {system_error, glisten@socket:socket_reason()}. - --spec serve( - integer(), - fun((glisten@socket:listen_socket()) -> glisten@acceptor:pool(any())) -) -> {ok, nil} | {error, start_error()}. -serve(Port, With_pool) -> - _pipe = Port, - _pipe@1 = glisten@tcp:listen(_pipe, []), - _pipe@2 = gleam@result:map_error(_pipe@1, fun(Err) -> case Err of - closed -> - listener_closed; - - timeout -> - listener_timeout; - - Err@1 -> - {system_error, Err@1} - end end), - _pipe@6 = gleam@result:then( - _pipe@2, - fun(Socket) -> - _pipe@3 = Socket, - _pipe@4 = With_pool(_pipe@3), - _pipe@5 = glisten@acceptor:start_pool(_pipe@4), - gleam@result:map_error(_pipe@5, fun(Err@2) -> case Err@2 of - init_timeout -> - acceptor_timeout; - - {init_failed, Reason} -> - {acceptor_failed, Reason}; - - {init_crashed, Reason@1} -> - {acceptor_crashed, Reason@1} - end end) - end - ), - gleam@result:replace(_pipe@6, nil). - --spec serve_ssl( - integer(), - binary(), - binary(), - fun((glisten@socket:listen_socket()) -> glisten@acceptor:pool(any())) -) -> {ok, nil} | {error, start_error()}. -serve_ssl(Port, Certfile, Keyfile, With_pool) -> - _assert_subject = ssl_ffi:start_ssl(), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten"/utf8>>, - function => <<"serve_ssl"/utf8>>, - line => 62}) - end, - _pipe = Port, - _pipe@1 = glisten@ssl:listen( - _pipe, - [{certfile, Certfile}, {keyfile, Keyfile}] - ), - _pipe@2 = gleam@result:map_error(_pipe@1, fun(Err) -> case Err of - closed -> - listener_closed; - - timeout -> - listener_timeout; - - Err@1 -> - {system_error, Err@1} - end end), - _pipe@6 = gleam@result:then( - _pipe@2, - fun(Socket) -> - _pipe@3 = Socket, - _pipe@4 = (glisten@acceptor:over_ssl(With_pool))(_pipe@3), - _pipe@5 = glisten@acceptor:start_pool(_pipe@4), - gleam@result:map_error(_pipe@5, fun(Err@2) -> case Err@2 of - init_timeout -> - acceptor_timeout; - - {init_failed, Reason} -> - {acceptor_failed, Reason}; - - {init_crashed, Reason@1} -> - {acceptor_crashed, Reason@1} - end end) - end - ), - gleam@result:replace(_pipe@6, nil). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam deleted file mode 100644 index 74a51ee3e9c..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam +++ /dev/null @@ -1,85 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/erlang/process -import gleam/result -import glisten/acceptor.{Pool, over_ssl} -import glisten/socket.{Closed, ListenSocket, SocketReason, Timeout} -import glisten/tcp -import glisten/ssl -import gleam/otp/actor -import glisten/socket/options.{Certfile, Keyfile} - -/// Reasons that `serve` might fail -pub type StartError { - ListenerClosed - ListenerTimeout - AcceptorTimeout - AcceptorFailed(process.ExitReason) - AcceptorCrashed(Dynamic) - SystemError(SocketReason) -} - -/// Sets up a TCP listener with the given acceptor pool. The second argument -/// can be obtained from the `glisten/acceptor.{acceptor_pool}` function. -pub fn serve( - port: Int, - with_pool: fn(ListenSocket) -> Pool(data), -) -> Result(Nil, StartError) { - port - |> tcp.listen([]) - |> result.map_error(fn(err) { - case err { - Closed -> ListenerClosed - Timeout -> ListenerTimeout - err -> SystemError(err) - } - }) - |> result.then(fn(socket) { - socket - |> with_pool - |> acceptor.start_pool - |> result.map_error(fn(err) { - case err { - actor.InitTimeout -> AcceptorTimeout - actor.InitFailed(reason) -> AcceptorFailed(reason) - actor.InitCrashed(reason) -> AcceptorCrashed(reason) - } - }) - }) - |> result.replace(Nil) -} - -external fn start_ssl() -> Result(Nil, Dynamic) = - "ssl_ffi" "start_ssl" - -/// Sets up a SSL listener with the given acceptor pool. The second argument -/// can be obtained from the `glisten/acceptor.{acceptor_pool}` function. -pub fn serve_ssl( - port port: Int, - certfile certfile: String, - keyfile keyfile: String, - with_pool with_pool: fn(ListenSocket) -> Pool(data), -) -> Result(Nil, StartError) { - let assert Ok(_nil) = start_ssl() - port - |> ssl.listen([Certfile(certfile), Keyfile(keyfile)]) - |> result.map_error(fn(err) { - case err { - Closed -> ListenerClosed - Timeout -> ListenerTimeout - err -> SystemError(err) - } - }) - |> result.then(fn(socket) { - socket - |> over_ssl(with_pool) - |> acceptor.start_pool - |> result.map_error(fn(err) { - case err { - actor.InitTimeout -> AcceptorTimeout - actor.InitFailed(reason) -> AcceptorFailed(reason) - actor.InitCrashed(reason) -> AcceptorCrashed(reason) - } - }) - }) - |> result.replace(Nil) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam deleted file mode 100644 index 3237bf0c82d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam +++ /dev/null @@ -1,204 +0,0 @@ -import gleam/erlang/process.{Abnormal, Subject} -import gleam/function -import gleam/iterator -import gleam/option.{None, Option, Some} -import gleam/otp/actor -import gleam/otp/supervisor -import gleam/result -import glisten/handler.{Handler, HandlerMessage, LoopFn, Ready} -import glisten/logger -import glisten/socket.{ListenSocket, Socket} -import glisten/socket/transport.{Transport} - -pub type AcceptorMessage { - AcceptConnection(ListenSocket) -} - -pub type AcceptorError { - AcceptError - HandlerError - ControlError -} - -pub type AcceptorState { - AcceptorState( - sender: Subject(AcceptorMessage), - socket: Option(Socket), - transport: Transport, - ) -} - -/// Worker process that handles `accept`ing connections and starts a new process -/// which receives the messages from the socket -pub fn start( - pool: Pool(data), -) -> Result(Subject(AcceptorMessage), actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let subject = process.new_subject() - let selector = - process.new_selector() - |> process.selecting(subject, function.identity) - - process.send(subject, AcceptConnection(pool.listener_socket)) - - actor.Ready(AcceptorState(subject, None, pool.transport), selector) - }, - // TODO: rethink this value, probably... - init_timeout: 1000, - loop: fn(msg, state) { - let AcceptorState(sender, ..) = state - case msg { - AcceptConnection(listener) -> { - let res = { - use sock <- result.then( - state.transport.accept(listener) - |> result.replace_error(AcceptError), - ) - use start <- result.then( - Handler( - sock, - pool.initial_data, - pool.handler, - pool.on_init, - pool.on_close, - pool.transport, - ) - |> handler.start - |> result.replace_error(HandlerError), - ) - sock - |> state.transport.controlling_process(process.subject_owner(start)) - |> result.replace_error(ControlError) - |> result.map(fn(_) { process.send(start, Ready) }) - } - case res { - Error(reason) -> { - logger.error(#("Failed to accept/start handler", reason)) - actor.Stop(Abnormal("Failed to accept/start handler")) - } - _val -> { - actor.send(sender, AcceptConnection(listener)) - actor.Continue(state) - } - } - } - msg -> { - logger.error(#("Unknown message type", msg)) - actor.Stop(process.Abnormal("Unknown message type")) - } - } - }, - )) -} - -pub type Pool(data) { - Pool( - listener_socket: ListenSocket, - handler: LoopFn(data), - initial_data: data, - pool_count: Int, - on_init: Option(fn(Subject(HandlerMessage)) -> Nil), - on_close: Option(fn(Subject(HandlerMessage)) -> Nil), - transport: Transport, - ) -} - -/// Initialize acceptor pool where each handler has no state -pub fn new_pool(handler: LoopFn(Nil)) -> fn(ListenSocket) -> Pool(Nil) { - fn(listener_socket) { - Pool( - listener_socket: listener_socket, - handler: handler, - initial_data: Nil, - pool_count: 10, - on_init: None, - on_close: None, - transport: transport.tcp(), - ) - } -} - -/// Initialize an acceptor pool where each handler holds some state -pub fn new_pool_with_data( - handler: LoopFn(data), - initial_data: data, -) -> fn(ListenSocket) -> Pool(data) { - fn(listener_socket) { - Pool( - listener_socket: listener_socket, - handler: handler, - initial_data: initial_data, - pool_count: 10, - on_init: None, - on_close: None, - transport: transport.tcp(), - ) - } -} - -/// Add an `on_init` handler to the acceptor pool -pub fn with_init( - make_pool: fn(ListenSocket) -> Pool(data), - func: fn(Subject(HandlerMessage)) -> Nil, -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, on_init: Some(func)) - } -} - -/// Add an `on_close` handler to the acceptor pool -pub fn with_close( - make_pool: fn(ListenSocket) -> Pool(data), - func: fn(Subject(HandlerMessage)) -> Nil, -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, on_close: Some(func)) - } -} - -/// Adjust the number of TCP acceptors in the pool -pub fn with_pool_size( - make_pool: fn(ListenSocket) -> Pool(data), - pool_count: Int, -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, pool_count: pool_count) - } -} - -/// Use SSL for the underlying socket. -pub fn over_ssl( - make_pool: fn(ListenSocket) -> Pool(data), -) -> fn(ListenSocket) -> Pool(data) { - fn(socket) { - let pool = make_pool(socket) - Pool(..pool, transport: transport.ssl()) - } -} - -/// Starts a pool of acceptors of size `pool_count`. -/// -/// Runs `loop_fn` on ever message received -pub fn start_pool( - pool: Pool(data), -) -> Result(Subject(supervisor.Message), actor.StartError) { - supervisor.start_spec(supervisor.Spec( - argument: Nil, - // TODO: i think these might need some tweaking - max_frequency: 100, - frequency_period: 1, - init: fn(children) { - iterator.range(from: 0, to: pool.pool_count) - |> iterator.fold( - children, - fn(children, _index) { - supervisor.add(children, supervisor.worker(fn(_arg) { start(pool) })) - }, - ) - }, - )) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam deleted file mode 100644 index d5e8d9348e5..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam +++ /dev/null @@ -1,160 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic -import gleam/erlang/process.{Subject} -import gleam/function -import gleam/option.{Option, Some} -import gleam/otp/actor -import gleam/otp/port.{Port} -import gleam/result -import gleam/string -import glisten/logger -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} -import glisten/socket/options - -/// All message types that the handler will receive, or that you can -/// send to the handler process -pub type HandlerMessage { - Close - Ready - ReceiveMessage(BitString) - SendMessage(BitBuilder) - Ssl(socket: Port, data: BitString) - SslClosed(Nil) - Tcp(socket: Port, data: BitString) - TcpClosed(Nil) -} - -pub type LoopState(data) { - LoopState( - socket: Socket, - sender: Subject(HandlerMessage), - transport: Transport, - data: data, - ) -} - -pub type LoopFn(data) = - fn(HandlerMessage, LoopState(data)) -> actor.Next(LoopState(data)) - -pub type Handler(data) { - Handler( - socket: Socket, - initial_data: data, - loop: LoopFn(data), - on_init: Option(fn(Subject(HandlerMessage)) -> Nil), - on_close: Option(fn(Subject(HandlerMessage)) -> Nil), - transport: Transport, - ) -} - -/// Starts an actor for the TCP connection -pub fn start( - handler: Handler(data), -) -> Result(Subject(HandlerMessage), actor.StartError) { - actor.start_spec(actor.Spec( - init: fn() { - let subject = process.new_subject() - let selector = - process.new_selector() - |> process.selecting(subject, function.identity) - |> process.selecting_anything(fn(msg) { - case dynamic.unsafe_coerce(msg) { - Tcp(_sock, data) | Ssl(_sock, data) -> ReceiveMessage(data) - msg -> msg - } - }) - actor.Ready( - LoopState( - handler.socket, - subject, - handler.transport, - data: handler.initial_data, - ), - selector, - ) - }, - init_timeout: 1000, - loop: fn(msg, state) { - case msg { - TcpClosed(_) | SslClosed(_) | Close -> - case state.transport.close(state.socket) { - Ok(Nil) -> { - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - actor.Stop(process.Normal) - } - Error(err) -> actor.Stop(process.Abnormal(string.inspect(err))) - } - Ready -> - state.socket - |> state.transport.handshake - |> result.replace_error("Failed to handshake socket") - |> result.map(fn(_ok) { - let _ = case handler.on_init { - Some(func) -> func(state.sender) - _ -> Nil - } - }) - |> result.then(fn(_ok) { - state.transport.set_opts( - state.socket, - [options.ActiveMode(options.Once)], - ) - |> result.replace_error("Failed to set socket active") - }) - |> result.replace(actor.Continue(state)) - |> result.map_error(fn(reason) { - actor.Stop(process.Abnormal(reason)) - }) - |> result.unwrap_both - msg -> - case handler.loop(msg, state) { - actor.Continue(next_state) -> { - let assert Ok(Nil) = - state.transport.set_opts( - state.socket, - [options.ActiveMode(options.Once)], - ) - actor.Continue(next_state) - } - msg -> msg - } - } - }, - )) -} - -pub type HandlerFunc(data) = - fn(BitString, LoopState(data)) -> actor.Next(LoopState(data)) - -/// This helper will generate a TCP handler that will call your handler function -/// with the BitString data in the packet as well as the LoopState, with any -/// associated state data you are maintaining -pub fn func(handler func: HandlerFunc(data)) -> LoopFn(data) { - fn(msg, state: LoopState(data)) { - case msg { - Tcp(_, _) | Ready -> { - logger.error(#("Received an unexpected TCP message", msg)) - actor.Continue(state) - } - ReceiveMessage(data) -> func(data, state) - SendMessage(data) -> - case state.transport.send(state.socket, data) { - Ok(_nil) -> actor.Continue(state) - Error(reason) -> { - logger.error(#("Failed to send data", reason)) - actor.Stop(process.Abnormal("Failed to send data")) - } - } - // NOTE: this should never happen. This function is only called _after_ - // the other message types are handled - msg -> { - logger.error(#("Unhandled TCP message", msg)) - actor.Stop(process.Abnormal("Unhandled TCP message")) - } - } - } -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam deleted file mode 100644 index 14a31a6ce54..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam +++ /dev/null @@ -1,8 +0,0 @@ -import gleam/erlang/charlist.{Charlist} - -external fn log_error(format: Charlist, data: any) -> Nil = - "logger" "error" - -pub fn error(data: any) -> Nil { - log_error(charlist.from_string("~tp"), [data]) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam deleted file mode 100644 index 95aca833ceb..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam +++ /dev/null @@ -1,93 +0,0 @@ -pub type SocketReason { - Closed - Timeout - Badarg - Terminated - - // inet:posix() errors. - Eaddrinuse - Eaddrnotavail - Eafnosupport - Ealready - Econnaborted - Econnrefused - Econnreset - Edestaddrreq - Ehostdown - Ehostunreach - Einprogress - Eisconn - Emsgsize - Enetdown - Enetunreach - Enopkg - Enoprotoopt - Enotconn - Enotty - Enotsock - Eproto - Eprotonosupport - Eprototype - Esocktnosupport - Etimedout - Ewouldblock - Exbadport - Exbadseq - - // file:posix() errors. - Eacces - Eagain - Ebadf - Ebadmsg - Ebusy - Edeadlk - Edeadlock - Edquot - Eexist - Efault - Efbig - Eftype - Eintr - Einval - Eio - Eisdir - Eloop - Emfile - Emlink - Emultihop - Enametoolong - Enfile - Enobufs - Enodev - Enolck - Enolink - Enoent - Enomem - Enospc - Enosr - Enostr - Enosys - Enotblk - Enotdir - Enotsup - Enxio - Eopnotsupp - Eoverflow - Eperm - Epipe - Erange - Erofs - Espipe - Esrch - Estale - Etxtbsy - Exdev -} - -pub opaque type ListenSocket { - ListenSocket -} - -pub opaque type Socket { - Socket -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam deleted file mode 100644 index 86766c2296a..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam +++ /dev/null @@ -1,83 +0,0 @@ -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom -import gleam/list -import gleam/map.{Map} -import gleam/pair - -/// Mode for the socket. Currently `list` is not supported -pub type SocketMode { - Binary -} - -/// Mapping to the {active, _} option -pub type ActiveState { - Once - Passive - Count(Int) - // This is dumb and annoying. I'd much prefer `True` or `Active`, but both - // of those make this a lot more annoying to work with - Active -} - -/// Options for the TCP socket -pub type TcpOption { - Backlog(Int) - Nodelay(Bool) - Linger(#(Bool, Int)) - SendTimeout(Int) - SendTimeoutClose(Bool) - Reuseaddr(Bool) - ActiveMode(ActiveState) - Mode(SocketMode) - // TODO: Probably should adjust the type here to only allow this for SSL - Certfile(String) - Keyfile(String) - AlpnPreferredProtocols(List(String)) -} - -pub fn to_map(options: List(TcpOption)) -> Map(atom.Atom, Dynamic) { - let opt_decoder = dynamic.tuple2(dynamic.dynamic, dynamic.dynamic) - - options - |> list.map(fn(opt) { - case opt { - ActiveMode(Passive) -> - dynamic.from(#(atom.create_from_string("active"), False)) - ActiveMode(Active) -> - dynamic.from(#(atom.create_from_string("active"), True)) - ActiveMode(Count(n)) -> - dynamic.from(#(atom.create_from_string("active"), n)) - ActiveMode(Once) -> - dynamic.from(#( - atom.create_from_string("active"), - atom.create_from_string("once"), - )) - other -> dynamic.from(other) - } - }) - |> list.filter_map(opt_decoder) - |> list.map(pair.map_first(_, dynamic.unsafe_coerce)) - |> map.from_list -} - -const default_options = [ - Backlog(1024), - Nodelay(True), - Linger(#(True, 30)), - SendTimeout(30_000), - SendTimeoutClose(True), - Reuseaddr(True), - Mode(Binary), - ActiveMode(Passive), -] - -pub fn merge_with_defaults(options: List(TcpOption)) -> List(TcpOption) { - let overrides = to_map(options) - - default_options - |> to_map - |> map.merge(overrides) - |> map.to_list - |> list.map(dynamic.from) - |> list.map(dynamic.unsafe_coerce) -} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam deleted file mode 100644 index 4e64c806241..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam +++ /dev/null @@ -1,122 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} -import gleam/map.{Map} -import glisten/socket/options -import glisten/socket.{ListenSocket, Socket, SocketReason} -import glisten/ssl -import glisten/tcp - -type ControllingProcess = - fn(Socket, Pid) -> Result(Nil, Atom) - -type Listen = - fn(Int, List(options.TcpOption)) -> Result(ListenSocket, SocketReason) - -type AcceptTimeout = - fn(ListenSocket, Int) -> Result(Socket, SocketReason) - -type Accept = - fn(ListenSocket) -> Result(Socket, SocketReason) - -type ReceiveTimeout = - fn(Socket, Int, Int) -> Result(BitString, SocketReason) - -type Receive = - fn(Socket, Int) -> Result(BitString, SocketReason) - -type Send = - fn(Socket, BitBuilder) -> Result(Nil, SocketReason) - -type SocketInfo = - fn(Socket) -> Map(Atom, Dynamic) - -type Close = - fn(Socket) -> Result(Nil, SocketReason) - -type Shutdown = - fn(Socket) -> Result(Nil, SocketReason) - -type SetOpts = - fn(Socket, List(options.TcpOption)) -> Result(Nil, Nil) - -type Handshake = - fn(Socket) -> Result(Socket, Nil) - -type NegotiatedProtocol = - fn(Socket) -> Result(String, String) - -pub type Transport { - Ssl( - accept: Accept, - accept_timeout: AcceptTimeout, - close: Close, - controlling_process: ControllingProcess, - handshake: Handshake, - listen: Listen, - negotiated_protocol: NegotiatedProtocol, - receive: Receive, - receive_timeout: ReceiveTimeout, - send: Send, - set_opts: SetOpts, - shutdown: Shutdown, - socket_info: SocketInfo, - ) - Tcp( - accept: Accept, - accept_timeout: AcceptTimeout, - close: Close, - controlling_process: ControllingProcess, - handshake: Handshake, - listen: Listen, - negotiated_protocol: NegotiatedProtocol, - receive: Receive, - receive_timeout: ReceiveTimeout, - send: Send, - set_opts: SetOpts, - shutdown: Shutdown, - socket_info: SocketInfo, - ) -} - -pub fn tcp() -> Transport { - Tcp( - accept: tcp.accept, - accept_timeout: tcp.accept_timeout, - close: tcp.close, - controlling_process: tcp.controlling_process, - handshake: tcp.handshake, - listen: tcp.listen, - negotiated_protocol: fn(_socket) { - Error("Can't negotiate protocol on tcp") - }, - receive: tcp.receive, - receive_timeout: tcp.receive_timeout, - send: tcp.send, - set_opts: tcp.set_opts, - shutdown: tcp.shutdown, - socket_info: socket_info, - ) -} - -pub fn ssl() -> Transport { - Ssl( - accept: ssl.accept, - accept_timeout: ssl.accept_timeout, - close: ssl.close, - controlling_process: ssl.controlling_process, - handshake: ssl.handshake, - listen: ssl.listen, - negotiated_protocol: ssl.negotiated_protocol, - receive: ssl.receive, - receive_timeout: ssl.receive_timeout, - send: ssl.send, - set_opts: ssl.set_opts, - shutdown: ssl.shutdown, - socket_info: socket_info, - ) -} - -pub external fn socket_info(socket: Socket) -> Map(a, b) = - "socket" "info" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam deleted file mode 100644 index a3cd828f3df..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam +++ /dev/null @@ -1,93 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} -import gleam/list -import gleam/map -import glisten/socket.{ListenSocket, Socket, SocketReason} -import glisten/socket/options - -pub external fn controlling_process( - socket: Socket, - pid: Pid, -) -> Result(Nil, Atom) = - "ssl_ffi" "controlling_process" - -external fn do_listen( - port: Int, - options: List(options.TcpOption), -) -> Result(ListenSocket, SocketReason) = - "ssl" "listen" - -pub external fn accept_timeout( - socket: ListenSocket, - timeout: Int, -) -> Result(Socket, SocketReason) = - "ssl" "transport_accept" - -pub external fn accept(socket: ListenSocket) -> Result(Socket, SocketReason) = - "ssl" "transport_accept" - -pub external fn receive_timeout( - socket: Socket, - length: Int, - timeout: Int, -) -> Result(BitString, SocketReason) = - "ssl" "recv" - -pub external fn receive( - socket: Socket, - length: Int, -) -> Result(BitString, SocketReason) = - "ssl" "recv" - -pub external fn send( - socket: Socket, - packet: BitBuilder, -) -> Result(Nil, SocketReason) = - "ssl_ffi" "send" - -pub external fn close(socket: Socket) -> Result(Nil, SocketReason) = - "ssl_ffi" "close" - -pub external fn do_shutdown( - socket: Socket, - write: Atom, -) -> Result(Nil, SocketReason) = - "ssl_ffi" "shutdown" - -pub fn shutdown(socket: Socket) -> Result(Nil, SocketReason) { - let assert Ok(write) = atom.from_string("write") - do_shutdown(socket, write) -} - -external fn do_set_opts(socket: Socket, opts: List(Dynamic)) -> Result(Nil, Nil) = - "ssl_ffi" "set_opts" - -/// Update the optons for a socket (mutates the socket) -pub fn set_opts( - socket: Socket, - opts: List(options.TcpOption), -) -> Result(Nil, Nil) { - opts - |> options.to_map - |> map.to_list - |> list.map(dynamic.from) - |> do_set_opts(socket, _) -} - -pub external fn handshake(socket: Socket) -> Result(Socket, Nil) = - "ssl" "handshake" - -/// Start listening over SSL on a port with the given options -pub fn listen( - port: Int, - options: List(options.TcpOption), -) -> Result(ListenSocket, SocketReason) { - options - |> options.merge_with_defaults - |> do_listen(port, _) -} - -pub external fn negotiated_protocol(socket: Socket) -> Result(String, String) = - "ssl_ffi" "negotiated_protocol" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam deleted file mode 100644 index 55c15372879..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam +++ /dev/null @@ -1,94 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/process.{Pid} -import gleam/list -import gleam/map.{Map} -import glisten/socket.{ListenSocket, Socket, SocketReason} -import glisten/socket/options.{TcpOption} - -pub external fn controlling_process( - socket: Socket, - pid: Pid, -) -> Result(Nil, Atom) = - "tcp_ffi" "controlling_process" - -external fn do_listen_tcp( - port: Int, - options: List(TcpOption), -) -> Result(ListenSocket, SocketReason) = - "gen_tcp" "listen" - -pub external fn accept_timeout( - socket: ListenSocket, - timeout: Int, -) -> Result(Socket, SocketReason) = - "gen_tcp" "accept" - -pub external fn accept(socket: ListenSocket) -> Result(Socket, SocketReason) = - "gen_tcp" "accept" - -pub external fn receive_timeout( - socket: Socket, - length: Int, - timeout: Int, -) -> Result(BitString, SocketReason) = - "gen_tcp" "recv" - -pub external fn receive( - socket: Socket, - length: Int, -) -> Result(BitString, SocketReason) = - "gen_tcp" "recv" - -pub external fn send( - socket: Socket, - packet: BitBuilder, -) -> Result(Nil, SocketReason) = - "tcp_ffi" "send" - -pub external fn socket_info(socket: Socket) -> Map(a, b) = - "socket" "info" - -pub external fn close(socket: a) -> Result(Nil, SocketReason) = - "tcp_ffi" "close" - -pub external fn do_shutdown( - socket: Socket, - write: Atom, -) -> Result(Nil, SocketReason) = - "tcp_ffi" "shutdown" - -pub fn shutdown(socket: Socket) -> Result(Nil, SocketReason) { - let assert Ok(write) = atom.from_string("write") - do_shutdown(socket, write) -} - -external fn do_set_opts(socket: Socket, opts: List(Dynamic)) -> Result(Nil, Nil) = - "tcp_ffi" "set_opts" - -/// Update the optons for a socket (mutates the socket) -pub fn set_opts(socket: Socket, opts: List(TcpOption)) -> Result(Nil, Nil) { - opts - |> options.to_map - |> map.to_list - |> list.map(dynamic.from) - |> do_set_opts(socket, _) -} - -/// Start listening over TCP on a port with the given options -pub fn listen( - port: Int, - options: List(TcpOption), -) -> Result(ListenSocket, SocketReason) { - options - |> options.merge_with_defaults - |> do_listen_tcp(port, _) -} - -pub fn handshake(socket: Socket) -> Result(Socket, Nil) { - Ok(socket) -} - -pub external fn negotiated_protocol(socket: Socket) -> a = - "tcp" "negotiated_protocol" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl deleted file mode 100644 index 1b5c360d729..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl +++ /dev/null @@ -1,232 +0,0 @@ --module(glisten@acceptor). --compile([no_auto_import, nowarn_unused_vars]). - --export([start/1, new_pool/1, new_pool_with_data/2, with_init/2, with_close/2, with_pool_size/2, over_ssl/1, start_pool/1]). --export_type([acceptor_message/0, acceptor_error/0, acceptor_state/0, pool/1]). - --type acceptor_message() :: {accept_connection, glisten@socket:listen_socket()}. - --type acceptor_error() :: accept_error | handler_error | control_error. - --type acceptor_state() :: {acceptor_state, - gleam@erlang@process:subject(acceptor_message()), - gleam@option:option(glisten@socket:socket()), - glisten@socket@transport:transport()}. - --type pool(GRD) :: {pool, - glisten@socket:listen_socket(), - fun((glisten@handler:handler_message(), glisten@handler:loop_state(GRD)) -> gleam@otp@actor:next(glisten@handler:loop_state(GRD))), - GRD, - integer(), - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - glisten@socket@transport:transport()}. - --spec start(pool(any())) -> {ok, - gleam@erlang@process:subject(acceptor_message())} | - {error, gleam@otp@actor:start_error()}. -start(Pool) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - gleam@erlang@process:selecting( - _pipe, - Subject, - fun gleam@function:identity/1 - ) - end, - gleam@erlang@process:send( - Subject, - {accept_connection, erlang:element(2, Pool)} - ), - {ready, - {acceptor_state, Subject, none, erlang:element(8, Pool)}, - Selector} - end, - 1000, - fun(Msg, State) -> - {acceptor_state, Sender, _, _} = State, - case Msg of - {accept_connection, Listener} -> - Res = begin - gleam@result:then( - begin - _pipe@1 = (erlang:element( - 2, - erlang:element(4, State) - ))(Listener), - gleam@result:replace_error( - _pipe@1, - accept_error - ) - end, - fun(Sock) -> - gleam@result:then( - begin - _pipe@2 = {handler, - Sock, - erlang:element(4, Pool), - erlang:element(3, Pool), - erlang:element(6, Pool), - erlang:element(7, Pool), - erlang:element(8, Pool)}, - _pipe@3 = glisten@handler:start( - _pipe@2 - ), - gleam@result:replace_error( - _pipe@3, - handler_error - ) - end, - fun(Start) -> - _pipe@4 = Sock, - _pipe@5 = (erlang:element( - 5, - erlang:element(4, State) - ))( - _pipe@4, - gleam@erlang@process:subject_owner( - Start - ) - ), - _pipe@6 = gleam@result:replace_error( - _pipe@5, - control_error - ), - gleam@result:map( - _pipe@6, - fun(_) -> - gleam@erlang@process:send( - Start, - ready - ) - end - ) - end - ) - end - ) - end, - case Res of - {error, Reason} -> - glisten@logger:error( - {<<"Failed to accept/start handler"/utf8>>, - Reason} - ), - {stop, - {abnormal, - <<"Failed to accept/start handler"/utf8>>}}; - - _ -> - gleam@otp@actor:send( - Sender, - {accept_connection, Listener} - ), - {continue, State} - end; - - Msg@1 -> - glisten@logger:error( - {<<"Unknown message type"/utf8>>, Msg@1} - ), - {stop, {abnormal, <<"Unknown message type"/utf8>>}} - end - end} - ). - --spec new_pool( - fun((glisten@handler:handler_message(), glisten@handler:loop_state(nil)) -> gleam@otp@actor:next(glisten@handler:loop_state(nil))) -) -> fun((glisten@socket:listen_socket()) -> pool(nil)). -new_pool(Handler) -> - fun(Listener_socket) -> - {pool, - Listener_socket, - Handler, - nil, - 10, - none, - none, - glisten@socket@transport:tcp()} - end. - --spec new_pool_with_data( - fun((glisten@handler:handler_message(), glisten@handler:loop_state(GRL)) -> gleam@otp@actor:next(glisten@handler:loop_state(GRL))), - GRL -) -> fun((glisten@socket:listen_socket()) -> pool(GRL)). -new_pool_with_data(Handler, Initial_data) -> - fun(Listener_socket) -> - {pool, - Listener_socket, - Handler, - Initial_data, - 10, - none, - none, - glisten@socket@transport:tcp()} - end. - --spec with_init( - fun((glisten@socket:listen_socket()) -> pool(GRO)), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> fun((glisten@socket:listen_socket()) -> pool(GRO)). -with_init(Make_pool, Func) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(6, Pool, {some, Func}) - end. - --spec with_close( - fun((glisten@socket:listen_socket()) -> pool(GRS)), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> fun((glisten@socket:listen_socket()) -> pool(GRS)). -with_close(Make_pool, Func) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(7, Pool, {some, Func}) - end. - --spec with_pool_size( - fun((glisten@socket:listen_socket()) -> pool(GRW)), - integer() -) -> fun((glisten@socket:listen_socket()) -> pool(GRW)). -with_pool_size(Make_pool, Pool_count) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(5, Pool, Pool_count) - end. - --spec over_ssl(fun((glisten@socket:listen_socket()) -> pool(GRZ))) -> fun((glisten@socket:listen_socket()) -> pool(GRZ)). -over_ssl(Make_pool) -> - fun(Socket) -> - Pool = Make_pool(Socket), - erlang:setelement(8, Pool, glisten@socket@transport:ssl()) - end. - --spec start_pool(pool(any())) -> {ok, - gleam@erlang@process:subject(gleam@otp@supervisor:message())} | - {error, gleam@otp@actor:start_error()}. -start_pool(Pool) -> - gleam@otp@supervisor:start_spec( - {spec, - nil, - 100, - 1, - fun(Children) -> - _pipe = gleam@iterator:range(0, erlang:element(5, Pool)), - gleam@iterator:fold( - _pipe, - Children, - fun(Children@1, _) -> - gleam@otp@supervisor:add( - Children@1, - gleam@otp@supervisor:worker( - fun(_) -> start(Pool) end - ) - ) - end - ) - end} - ). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl deleted file mode 100644 index d4bd37df499..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl +++ /dev/null @@ -1,234 +0,0 @@ --module(glisten@handler). --compile([no_auto_import, nowarn_unused_vars]). - --export([start/1, func/1]). --export_type([handler_message/0, loop_state/1, handler/1]). - --type handler_message() :: close | - ready | - {receive_message, bitstring()} | - {send_message, gleam@bit_builder:bit_builder()} | - {ssl, gleam@otp@port:port_(), bitstring()} | - {ssl_closed, nil} | - {tcp, gleam@otp@port:port_(), bitstring()} | - {tcp_closed, nil}. - --type loop_state(GMF) :: {loop_state, - glisten@socket:socket(), - gleam@erlang@process:subject(handler_message()), - glisten@socket@transport:transport(), - GMF}. - --type handler(GMG) :: {handler, - glisten@socket:socket(), - GMG, - fun((handler_message(), loop_state(GMG)) -> gleam@otp@actor:next(loop_state(GMG))), - gleam@option:option(fun((gleam@erlang@process:subject(handler_message())) -> nil)), - gleam@option:option(fun((gleam@erlang@process:subject(handler_message())) -> nil)), - glisten@socket@transport:transport()}. - --spec start(handler(any())) -> {ok, - gleam@erlang@process:subject(handler_message())} | - {error, gleam@otp@actor:start_error()}. -start(Handler) -> - gleam@otp@actor:start_spec( - {spec, - fun() -> - Subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun gleam@function:identity/1 - ), - gleam@erlang@process:selecting_anything( - _pipe@1, - fun(Msg) -> case gleam@dynamic:unsafe_coerce(Msg) of - {tcp, _, Data} -> - {receive_message, Data}; - - {ssl, _, Data} -> - {receive_message, Data}; - - Msg@1 -> - Msg@1 - end end - ) - end, - {ready, - {loop_state, - erlang:element(2, Handler), - Subject, - erlang:element(7, Handler), - erlang:element(3, Handler)}, - Selector} - end, - 1000, - fun(Msg@2, State) -> case Msg@2 of - {tcp_closed, _} -> - case (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ) of - {ok, nil} -> - _ = case erlang:element(6, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {error, Err} -> - {stop, {abnormal, gleam@string:inspect(Err)}} - end; - - {ssl_closed, _} -> - case (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ) of - {ok, nil} -> - _ = case erlang:element(6, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {error, Err} -> - {stop, {abnormal, gleam@string:inspect(Err)}} - end; - - close -> - case (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ) of - {ok, nil} -> - _ = case erlang:element(6, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {error, Err} -> - {stop, {abnormal, gleam@string:inspect(Err)}} - end; - - ready -> - _pipe@2 = erlang:element(2, State), - _pipe@3 = (erlang:element(6, erlang:element(4, State)))( - _pipe@2 - ), - _pipe@4 = gleam@result:replace_error( - _pipe@3, - <<"Failed to handshake socket"/utf8>> - ), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(_) -> _ = case erlang:element(5, Handler) of - {some, Func@1} -> - Func@1(erlang:element(3, State)); - - _ -> - nil - end end - ), - _pipe@7 = gleam@result:then( - _pipe@5, - fun(_) -> - _pipe@6 = (erlang:element( - 12, - erlang:element(4, State) - ))( - erlang:element(2, State), - [{active_mode, once}] - ), - gleam@result:replace_error( - _pipe@6, - <<"Failed to set socket active"/utf8>> - ) - end - ), - _pipe@8 = gleam@result:replace( - _pipe@7, - {continue, State} - ), - _pipe@9 = gleam@result:map_error( - _pipe@8, - fun(Reason) -> {stop, {abnormal, Reason}} end - ), - gleam@result:unwrap_both(_pipe@9); - - Msg@3 -> - case (erlang:element(4, Handler))(Msg@3, State) of - {continue, Next_state} -> - _assert_subject = (erlang:element( - 12, - erlang:element(4, State) - ))( - erlang:element(2, State), - [{active_mode, once}] - ), - {ok, nil} = case _assert_subject of - {ok, nil} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten/handler"/utf8>>, - function => <<"start"/utf8>>, - line => 116}) - end, - {continue, Next_state}; - - Msg@4 -> - Msg@4 - end - end end} - ). - --spec func( - fun((bitstring(), loop_state(GMU)) -> gleam@otp@actor:next(loop_state(GMU))) -) -> fun((handler_message(), loop_state(GMU)) -> gleam@otp@actor:next(loop_state(GMU))). -func(Func) -> - fun(Msg, State) -> case Msg of - {tcp, _, _} -> - glisten@logger:error( - {<<"Received an unexpected TCP message"/utf8>>, Msg} - ), - {continue, State}; - - ready -> - glisten@logger:error( - {<<"Received an unexpected TCP message"/utf8>>, Msg} - ), - {continue, State}; - - {receive_message, Data} -> - Func(Data, State); - - {send_message, Data@1} -> - case (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - Data@1 - ) of - {ok, _} -> - {continue, State}; - - {error, Reason} -> - glisten@logger:error( - {<<"Failed to send data"/utf8>>, Reason} - ), - {stop, {abnormal, <<"Failed to send data"/utf8>>}} - end; - - Msg@1 -> - glisten@logger:error({<<"Unhandled TCP message"/utf8>>, Msg@1}), - {stop, {abnormal, <<"Unhandled TCP message"/utf8>>}} - end end. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl deleted file mode 100644 index f2c2a3d103d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(glisten@logger). --compile([no_auto_import, nowarn_unused_vars]). - --export([error/1]). - --spec error(any()) -> nil. -error(Data) -> - logger:error(unicode:characters_to_list(<<"~tp"/utf8>>), [Data]). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl deleted file mode 100644 index bf277dbeb4d..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(glisten@socket). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([socket_reason/0, listen_socket/0, socket/0]). - --type socket_reason() :: closed | - timeout | - badarg | - terminated | - eaddrinuse | - eaddrnotavail | - eafnosupport | - ealready | - econnaborted | - econnrefused | - econnreset | - edestaddrreq | - ehostdown | - ehostunreach | - einprogress | - eisconn | - emsgsize | - enetdown | - enetunreach | - enopkg | - enoprotoopt | - enotconn | - enotty | - enotsock | - eproto | - eprotonosupport | - eprototype | - esocktnosupport | - etimedout | - ewouldblock | - exbadport | - exbadseq | - eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev. - --opaque listen_socket() :: listen_socket. - --opaque socket() :: socket. - - diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl deleted file mode 100644 index ba8da56d523..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(glisten@socket@options). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_map/1, merge_with_defaults/1]). --export_type([socket_mode/0, active_state/0, tcp_option/0]). - --type socket_mode() :: binary. - --type active_state() :: once | passive | {count, integer()} | active. - --type tcp_option() :: {backlog, integer()} | - {nodelay, boolean()} | - {linger, {boolean(), integer()}} | - {send_timeout, integer()} | - {send_timeout_close, boolean()} | - {reuseaddr, boolean()} | - {active_mode, active_state()} | - {mode, socket_mode()} | - {certfile, binary()} | - {keyfile, binary()} | - {alpn_preferred_protocols, list(binary())}. - --spec to_map(list(tcp_option())) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()). -to_map(Options) -> - Opt_decoder = gleam@dynamic:tuple2( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ), - _pipe = Options, - _pipe@1 = gleam@list:map(_pipe, fun(Opt) -> case Opt of - {active_mode, passive} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), false} - ); - - {active_mode, active} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), true} - ); - - {active_mode, {count, N}} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), N} - ); - - {active_mode, once} -> - gleam@dynamic:from( - {erlang:binary_to_atom(<<"active"/utf8>>), - erlang:binary_to_atom(<<"once"/utf8>>)} - ); - - Other -> - gleam@dynamic:from(Other) - end end), - _pipe@2 = gleam@list:filter_map(_pipe@1, Opt_decoder), - _pipe@3 = gleam@list:map( - _pipe@2, - fun(_capture) -> - gleam@pair:map_first(_capture, fun gleam@dynamic:unsafe_coerce/1) - end - ), - gleam@map:from_list(_pipe@3). - --spec merge_with_defaults(list(tcp_option())) -> list(tcp_option()). -merge_with_defaults(Options) -> - Overrides = to_map(Options), - _pipe = [{backlog, 1024}, - {nodelay, true}, - {linger, {true, 30}}, - {send_timeout, 30000}, - {send_timeout_close, true}, - {reuseaddr, true}, - {mode, binary}, - {active_mode, passive}], - _pipe@1 = to_map(_pipe), - _pipe@2 = gleam@map:merge(_pipe@1, Overrides), - _pipe@3 = gleam@map:to_list(_pipe@2), - _pipe@4 = gleam@list:map(_pipe@3, fun gleam@dynamic:from/1), - gleam@list:map(_pipe@4, fun gleam@dynamic:unsafe_coerce/1). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl deleted file mode 100644 index 10ebf6c34c4..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(glisten@socket@transport). --compile([no_auto_import, nowarn_unused_vars]). - --export([socket_info/1, tcp/0, ssl/0]). --export_type([transport/0]). - --type transport() :: {ssl, - fun((glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, nil} | - {error, gleam@erlang@atom:atom_()}), - fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, binary()} | {error, binary()}), - fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), integer(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()))} | - {tcp, - fun((glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, nil} | - {error, gleam@erlang@atom:atom_()}), - fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}), - fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> {ok, binary()} | {error, binary()}), - fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), integer(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, - nil} | - {error, nil}), - fun((glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}), - fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()))}. - --spec socket_info(glisten@socket:socket()) -> gleam@map:map_(any(), any()). -socket_info(Field@0) -> - socket:info(Field@0). - --spec tcp() -> transport(). -tcp() -> - {tcp, - fun glisten@tcp:accept/1, - fun glisten@tcp:accept_timeout/2, - fun glisten@tcp:close/1, - fun glisten@tcp:controlling_process/2, - fun glisten@tcp:handshake/1, - fun glisten@tcp:listen/2, - fun(_) -> {error, <<"Can't negotiate protocol on tcp"/utf8>>} end, - fun glisten@tcp:'receive'/2, - fun glisten@tcp:receive_timeout/3, - fun glisten@tcp:send/2, - fun glisten@tcp:set_opts/2, - fun glisten@tcp:shutdown/1, - fun socket:info/1}. - --spec ssl() -> transport(). -ssl() -> - {ssl, - fun glisten@ssl:accept/1, - fun glisten@ssl:accept_timeout/2, - fun glisten@ssl:close/1, - fun glisten@ssl:controlling_process/2, - fun glisten@ssl:handshake/1, - fun glisten@ssl:listen/2, - fun glisten@ssl:negotiated_protocol/1, - fun glisten@ssl:'receive'/2, - fun glisten@ssl:receive_timeout/3, - fun glisten@ssl:send/2, - fun glisten@ssl:set_opts/2, - fun glisten@ssl:shutdown/1, - fun socket:info/1}. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl deleted file mode 100644 index 28d69867a46..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl +++ /dev/null @@ -1,94 +0,0 @@ --module(glisten@ssl). --compile([no_auto_import, nowarn_unused_vars]). - --export([controlling_process/2, listen/2, accept_timeout/2, accept/1, receive_timeout/3, 'receive'/2, send/2, close/1, do_shutdown/2, shutdown/1, set_opts/2, handshake/1, negotiated_protocol/1]). - --spec controlling_process(glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}. -controlling_process(Field@0, Field@1) -> - ssl_ffi:controlling_process(Field@0, Field@1). - --spec listen(integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}. -listen(Port, Options) -> - _pipe = Options, - _pipe@1 = glisten@socket@options:merge_with_defaults(_pipe), - ssl:listen(Port, _pipe@1). - --spec accept_timeout(glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept_timeout(Field@0, Field@1) -> - ssl:transport_accept(Field@0, Field@1). - --spec accept(glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept(Field@0) -> - ssl:transport_accept(Field@0). - --spec receive_timeout(glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}. -receive_timeout(Field@0, Field@1, Field@2) -> - ssl:recv(Field@0, Field@1, Field@2). - --spec 'receive'(glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}. -'receive'(Field@0, Field@1) -> - ssl:recv(Field@0, Field@1). - --spec send(glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -send(Field@0, Field@1) -> - ssl_ffi:send(Field@0, Field@1). - --spec close(glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}. -close(Field@0) -> - ssl_ffi:close(Field@0). - --spec do_shutdown(glisten@socket:socket(), gleam@erlang@atom:atom_()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -do_shutdown(Field@0, Field@1) -> - ssl_ffi:shutdown(Field@0, Field@1). - --spec shutdown(glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}. -shutdown(Socket) -> - _assert_subject = gleam_erlang_ffi:atom_from_string(<<"write"/utf8>>), - {ok, Write} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten/ssl"/utf8>>, - function => <<"shutdown"/utf8>>, - line => 60}) - end, - ssl_ffi:shutdown(Socket, Write). - --spec set_opts( - glisten@socket:socket(), - list(glisten@socket@options:tcp_option()) -) -> {ok, nil} | {error, nil}. -set_opts(Socket, Opts) -> - _pipe = Opts, - _pipe@1 = glisten@socket@options:to_map(_pipe), - _pipe@2 = gleam@map:to_list(_pipe@1), - _pipe@3 = gleam@list:map(_pipe@2, fun gleam@dynamic:from/1), - ssl_ffi:set_opts(Socket, _pipe@3). - --spec handshake(glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}. -handshake(Field@0) -> - ssl:handshake(Field@0). - --spec negotiated_protocol(glisten@socket:socket()) -> {ok, binary()} | - {error, binary()}. -negotiated_protocol(Field@0) -> - ssl_ffi:negotiated_protocol(Field@0). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl deleted file mode 100644 index 09d0bfe4e49..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl +++ /dev/null @@ -1,96 +0,0 @@ --module(glisten@tcp). --compile([no_auto_import, nowarn_unused_vars]). - --export([handshake/1, controlling_process/2, listen/2, accept_timeout/2, accept/1, receive_timeout/3, 'receive'/2, send/2, socket_info/1, close/1, do_shutdown/2, shutdown/1, set_opts/2, negotiated_protocol/1]). - --spec handshake(glisten@socket:socket()) -> {ok, glisten@socket:socket()} | - {error, nil}. -handshake(Socket) -> - {ok, Socket}. - --spec controlling_process(glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, - nil} | - {error, gleam@erlang@atom:atom_()}. -controlling_process(Field@0, Field@1) -> - tcp_ffi:controlling_process(Field@0, Field@1). - --spec listen(integer(), list(glisten@socket@options:tcp_option())) -> {ok, - glisten@socket:listen_socket()} | - {error, glisten@socket:socket_reason()}. -listen(Port, Options) -> - _pipe = Options, - _pipe@1 = glisten@socket@options:merge_with_defaults(_pipe), - gen_tcp:listen(Port, _pipe@1). - --spec accept_timeout(glisten@socket:listen_socket(), integer()) -> {ok, - glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept_timeout(Field@0, Field@1) -> - gen_tcp:accept(Field@0, Field@1). - --spec accept(glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | - {error, glisten@socket:socket_reason()}. -accept(Field@0) -> - gen_tcp:accept(Field@0). - --spec receive_timeout(glisten@socket:socket(), integer(), integer()) -> {ok, - bitstring()} | - {error, glisten@socket:socket_reason()}. -receive_timeout(Field@0, Field@1, Field@2) -> - gen_tcp:recv(Field@0, Field@1, Field@2). - --spec 'receive'(glisten@socket:socket(), integer()) -> {ok, bitstring()} | - {error, glisten@socket:socket_reason()}. -'receive'(Field@0, Field@1) -> - gen_tcp:recv(Field@0, Field@1). - --spec send(glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -send(Field@0, Field@1) -> - tcp_ffi:send(Field@0, Field@1). - --spec socket_info(glisten@socket:socket()) -> gleam@map:map_(any(), any()). -socket_info(Field@0) -> - socket:info(Field@0). - --spec close(any()) -> {ok, nil} | {error, glisten@socket:socket_reason()}. -close(Field@0) -> - tcp_ffi:close(Field@0). - --spec do_shutdown(glisten@socket:socket(), gleam@erlang@atom:atom_()) -> {ok, - nil} | - {error, glisten@socket:socket_reason()}. -do_shutdown(Field@0, Field@1) -> - tcp_ffi:shutdown(Field@0, Field@1). - --spec shutdown(glisten@socket:socket()) -> {ok, nil} | - {error, glisten@socket:socket_reason()}. -shutdown(Socket) -> - _assert_subject = gleam_erlang_ffi:atom_from_string(<<"write"/utf8>>), - {ok, Write} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glisten/tcp"/utf8>>, - function => <<"shutdown"/utf8>>, - line => 63}) - end, - tcp_ffi:shutdown(Socket, Write). - --spec set_opts( - glisten@socket:socket(), - list(glisten@socket@options:tcp_option()) -) -> {ok, nil} | {error, nil}. -set_opts(Socket, Opts) -> - _pipe = Opts, - _pipe@1 = glisten@socket@options:to_map(_pipe), - _pipe@2 = gleam@map:to_list(_pipe@1), - _pipe@3 = gleam@list:map(_pipe@2, fun gleam@dynamic:from/1), - tcp_ffi:set_opts(Socket, _pipe@3). - --spec negotiated_protocol(glisten@socket:socket()) -> any(). -negotiated_protocol(Field@0) -> - tcp:negotiated_protocol(Field@0). diff --git a/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl b/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl deleted file mode 100644 index fd05f369c20..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl +++ /dev/null @@ -1,60 +0,0 @@ --module(ssl_ffi). - --export([controlling_process/2, send/2, set_opts/2, start_ssl/0, shutdown/2, close/1, - negotiated_protocol/1]). - -send(Socket, Packet) -> - case ssl:send(Socket, Packet) of - ok -> - {ok, nil}; - Res -> - Res - end. - -set_opts(Socket, Options) -> - case ssl:setopts(Socket, Options) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -controlling_process(Socket, Pid) -> - case ssl:controlling_process(Socket, Pid) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -start_ssl() -> - case application:ensure_all_started(ssl) of - {ok, _} -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -shutdown(Socket, How) -> - case ssl:shutdown(Socket, How) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -close(Socket) -> - case ssl:close(Socket) of - ok -> - {ok, nil}; - {error, Reason} -> - {error, Reason} - end. - -negotiated_protocol(Socket) -> - case ssl:negotiated_protocol(Socket) of - {error, _} -> - {error, "Socket not negotiated"}; - Protocol -> - Protocol - end. diff --git a/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl b/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl deleted file mode 100644 index 955b881d4c7..00000000000 --- a/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl +++ /dev/null @@ -1,32 +0,0 @@ --module(tcp_ffi). --export([controlling_process/2, send/2, set_opts/2, shutdown/2, close/1]). - -send(Socket, Packet) -> - case gen_tcp:send(Socket, Packet) of - ok -> {ok, nil}; - Res -> Res - end. - -set_opts(Socket, Options) -> - case inet:setopts(Socket, Options) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. - -controlling_process(Socket, Pid) -> - case gen_tcp:controlling_process(Socket, Pid) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. - -shutdown(Socket, How) -> - case gen_tcp:shutdown(Socket, How) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. - -close(Socket) -> - case gen_tcp:close(Socket) of - ok -> {ok, nil}; - {error, Reason} -> {error, Reason} - end. diff --git a/test-community-packages-javascript/build/packages/globe/LICENSE b/test-community-packages-javascript/build/packages/globe/LICENSE deleted file mode 100644 index 37eec8b87f9..00000000000 --- a/test-community-packages-javascript/build/packages/globe/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Willyboar - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/globe/README.md b/test-community-packages-javascript/build/packages/globe/README.md deleted file mode 100644 index 3b7011fd631..00000000000 --- a/test-community-packages-javascript/build/packages/globe/README.md +++ /dev/null @@ -1,26 +0,0 @@ -![Globe](https://github.com/Willyboar/globe/assets/22755228/54162ccb-8f4e-4e6f-a732-e1e21453b213) - -[![Package Version](https://img.shields.io/hexpm/v/globe)](https://hex.pm/packages/globe) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/globe/) - -## WIP: Not Usable - -Globe is a lightweight and efficient compiler backend developed in the Gleam programming language. It provides an Intermediate Language (IL) and Intermediate Representation (IR) to facilitate code transformation and optimization. Globe is designed to generate C99 code, making it compatible with a wide range of platforms and toolchains. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add globe -``` - -and its documentation can be found at <https://hexdocs.pm/globe>. diff --git a/test-community-packages-javascript/build/packages/globe/gleam.toml b/test-community-packages-javascript/build/packages/globe/gleam.toml deleted file mode 100644 index d37f3ad1638..00000000000 --- a/test-community-packages-javascript/build/packages/globe/gleam.toml +++ /dev/null @@ -1,12 +0,0 @@ -name = "globe" -version = "0.1.0" -description = "Gleam Compiler Backend" - -licences = ["MIT"] -repository = { type = "github", user = "Willyboar", repo = "globe" } - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.app.src b/test-community-packages-javascript/build/packages/globe/src/globe.app.src deleted file mode 100644 index 7c9133d1a43..00000000000 --- a/test-community-packages-javascript/build/packages/globe/src/globe.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, globe, [ - {vsn, "0.1.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Gleam Compiler Backend"}, - {modules, [globe]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.erl b/test-community-packages-javascript/build/packages/globe/src/globe.erl deleted file mode 100644 index 2bf599597f2..00000000000 --- a/test-community-packages-javascript/build/packages/globe/src/globe.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(globe). --compile([no_auto_import, nowarn_unused_vars]). - --export([main/0]). - --spec main() -> nil. -main() -> - gleam@io:println(<<"Hello from globe!"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.gleam b/test-community-packages-javascript/build/packages/globe/src/globe.gleam deleted file mode 100644 index c19cb826afa..00000000000 --- a/test-community-packages-javascript/build/packages/globe/src/globe.gleam +++ /dev/null @@ -1,5 +0,0 @@ -import gleam/io - -pub fn main() { - io.println("Hello from globe!") -} diff --git a/test-community-packages-javascript/build/packages/gloml/README.md b/test-community-packages-javascript/build/packages/gloml/README.md deleted file mode 100644 index 16757b25e97..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# gloml - -[![Package Version](https://img.shields.io/hexpm/v/gloml)](https://hex.pm/packages/gloml) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gloml/) - -A toml parsing library for gleam ✨ All gleam targets and runtimes are supported by gloml. - -*Timestamps are not currently supported.* - -```gleam -import gleam/io - -pub fn main() { - decode( - " -[my-project] -version = \"1.2.3\" -", - d.field("my-project", d.field("version", d.string)), - ) - |> io.println() -} -``` - -## Quick start - -```sh -cd priv; npm install; cd .. # install dependencies for js -gleam test # Run the tests -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gloml -``` - -and its documentation can be found at <https://hexdocs.pm/gloml>. diff --git a/test-community-packages-javascript/build/packages/gloml/gleam.toml b/test-community-packages-javascript/build/packages/gloml/gleam.toml deleted file mode 100644 index c7f482deb7b..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gloml" -version = "0.1.2" -description = "A gleam library for parsing toml." -licences = ["MIT"] -repository = { type = "github", user = "lunarmagpie", repo = "gloml" } -links = [{ title = "Website", href = "https://github.com/lunarmagpie.gloml" }] - -[dependencies] -gleam_stdlib = "~> 0.27" -toml = "~> 0.7" - -[dev-dependencies] -gleeunit = "~> 0.10" - -[javascript.deno] -allow_read = ["gleam.toml", "test"] diff --git a/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json b/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json deleted file mode 100644 index ec78ad53f3c..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "priv", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@ltd/j-toml": "^1.38.0" - } - }, - "node_modules/@ltd/j-toml": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@ltd/j-toml/-/j-toml-1.38.0.tgz", - "integrity": "sha512-lYtBcmvHustHQtg4X7TXUu1Xa/tbLC3p2wLvgQI+fWVySguVZJF60Snxijw5EiohumxZbR10kWYFFebh1zotiw==" - } - } -} diff --git a/test-community-packages-javascript/build/packages/gloml/priv/package.json b/test-community-packages-javascript/build/packages/gloml/priv/package.json deleted file mode 100644 index 8f6b7a45402..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/priv/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@ltd/j-toml": "^1.38.0" - } -} diff --git a/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex b/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex deleted file mode 100644 index e021469b55e..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex +++ /dev/null @@ -1,5 +0,0 @@ -defmodule TomlFFI do - def get_reason({:invalid_toml, reason}) do - reason - end -end diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src b/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src deleted file mode 100644 index f654c6d7087..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gloml, [ - {vsn, "0.1.2"}, - {applications, [gleam_stdlib, - gleeunit, - toml]}, - {description, "A gleam library for parsing toml."}, - {modules, [gloml]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.erl b/test-community-packages-javascript/build/packages/gloml/src/gloml.erl deleted file mode 100644 index 0f25cc2bd74..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/gloml.erl +++ /dev/null @@ -1,44 +0,0 @@ --module(gloml). --compile([no_auto_import, nowarn_unused_vars]). - --export([decode/2, decode_dynamic/1]). --export_type([decode_error/0, elx_invalid_toml_error/0]). - --type decode_error() :: {invalid_toml_error, binary()} | - {unexpected_format, list(gleam@dynamic:decode_error())}. - --type elx_invalid_toml_error() :: any(). - --spec decode_inner(binary()) -> {ok, gleam@dynamic:dynamic()} | - {error, decode_error()}. -decode_inner(Toml_string) -> - case 'Elixir.Toml':decode(Toml_string) of - {ok, Value} -> - {ok, Value}; - - {error, Err} -> - {error, {invalid_toml_error, 'Elixir.TomlFFI':get_reason(Err)}} - end. - --spec decode( - binary(), - fun((gleam@dynamic:dynamic()) -> {ok, EUG} | - {error, list(gleam@dynamic:decode_error())}) -) -> {ok, EUG} | {error, decode_error()}. -decode(Toml_string, Decoder) -> - gleam@result:then( - decode_inner(Toml_string), - fun(Dyn) -> - _pipe = Dyn, - _pipe@1 = Decoder(_pipe), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {unexpected_format, Field@0} end - ) - end - ). - --spec decode_dynamic(binary()) -> {ok, gleam@dynamic:dynamic()} | - {error, decode_error()}. -decode_dynamic(Toml_string) -> - decode_inner(Toml_string). diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam b/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam deleted file mode 100644 index 073a087bc63..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam +++ /dev/null @@ -1,77 +0,0 @@ -import gleam/dynamic as dyn -import gleam/result - -pub type DecodeError { - InvalidTomlError(String) - UnexpectedFormat(List(dyn.DecodeError)) -} - -/// Parse a toml file with a decoder. -/// -/// ```gleam -/// pub fn decode_toml() { -/// let version = -/// gloml.decode(" -/// [my-project] -/// version = \"1.2.3\" -/// ", -/// d.field("my-project", d.field("version", d.string)), -/// ) -/// should.equal(version, Ok("1.2.3")) -/// } -/// ``` -/// -pub fn decode( - from toml_string: String, - using decoder: dyn.Decoder(t), -) -> Result(t, DecodeError) { - use dyn <- result.then(decode_inner(toml_string)) - dyn - |> decoder - |> result.map_error(UnexpectedFormat) -} - -/// Parse a toml file into a `gleam/dynamic.Dynamic`. -/// -/// ```gleam -/// pub fn decode_toml() { -/// let dynamic = -/// gloml.decode(" -/// [my-project] -/// version = \"1.2.3\" -/// ") -/// } -/// ``` -/// -pub fn decode_dynamic(toml_string: String) { - decode_inner(toml_string) -} - -if erlang { - external type ElxInvalidTomlError - - external fn decode_ex( - toml_string: String, - ) -> Result(dyn.Dynamic, ElxInvalidTomlError) = - "Elixir.Toml" "decode" - - external fn get_reason(err: ElxInvalidTomlError) -> String = - "Elixir.TomlFFI" "get_reason" - - fn decode_inner(toml_string: String) -> Result(dyn.Dynamic, DecodeError) { - case decode_ex(toml_string) { - Ok(value) -> Ok(value) - Error(err) -> Error(InvalidTomlError(get_reason(err))) - } - } -} - -if javascript { - external fn decode_js(toml_string: String) -> Result(dyn.Dynamic, String) = - "./toml_ffi.mjs" "parse_toml" - - fn decode_inner(toml_string: String) -> Result(dyn.Dynamic, DecodeError) { - decode_js(toml_string) - |> result.map_error(InvalidTomlError) - } -} diff --git a/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs b/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs deleted file mode 100644 index 0623dcb1ad6..00000000000 --- a/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import * as TOML from "./priv/node_modules/@ltd/j-toml/index.mjs"; - -import { - Error, - Ok, -} from "./gleam.mjs"; - -export function parse_toml(string) { - try { - return new Ok(TOML.parse(string)); - } catch (e) { - return new Error(e.message) - } -} diff --git a/test-community-packages-javascript/build/packages/glove/LICENSE b/test-community-packages-javascript/build/packages/glove/LICENSE deleted file mode 100644 index 37eec8b87f9..00000000000 --- a/test-community-packages-javascript/build/packages/glove/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Willyboar - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glove/README.md b/test-community-packages-javascript/build/packages/glove/README.md deleted file mode 100644 index f7bdb08e6de..00000000000 --- a/test-community-packages-javascript/build/packages/glove/README.md +++ /dev/null @@ -1,40 +0,0 @@ - -<img src="https://github.com/Willyboar/glove/assets/22755228/bfd9673f-a105-4083-82d8-84bf4b0ff071"> - - -[![Package Version](https://img.shields.io/hexpm/v/glove)](https://hex.pm/packages/glove) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glove/) - - -## About -Glove is a library for working with QBE intermediate representation (IR) in Gleam. Provides utilities and functions to generate QBE code using the Gleam programming language. - -## Requirements - -To use Glove, you need to have the following dependencies installed: - -Gleam programming language - Install instructions can be found [here](https://gleam.run/getting-started/installing/) - -QBE Backend can be found [here](https://c9x.me/compile/) - - -## Quick start - -You can find a working example [here](https://github.com/Willyboar/glove_example) - -QBE IL Documentation can be found [here](https://c9x.me/compile/doc/il.html) - -## Run the tests -```sh -gleam test # Run the tests -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add glove -``` - -and its documentation can be found at <https://hexdocs.pm/glove>. diff --git a/test-community-packages-javascript/build/packages/glove/gleam.toml b/test-community-packages-javascript/build/packages/glove/gleam.toml deleted file mode 100644 index a66d650c5f5..00000000000 --- a/test-community-packages-javascript/build/packages/glove/gleam.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "glove" -version = "0.2.0" -description = "Gleam QBE IR Generator" -licences = ["MIT"] -repository = { type = "github", user = "Willyboar", repo = "glove" } - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl deleted file mode 100644 index 517a9ced453..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl +++ /dev/null @@ -1 +0,0 @@ --record(block, {label :: binary(), statements :: list(glove:statement())}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl deleted file mode 100644 index 706288b1ee8..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl +++ /dev/null @@ -1 +0,0 @@ --record(const, {value :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl deleted file mode 100644 index acaeff560d1..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(data_def, { - linkage :: glove:linkage(), - name :: binary(), - align :: gleam@option:option(integer()), - items :: list({glove:type(), glove:data_item()}) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl deleted file mode 100644 index 1ff1cdff09b..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(function, { - linkage :: glove:linkage(), - name :: binary(), - arguments :: list({glove:type(), glove:value()}), - return_ty :: gleam@option:option(glove:type()), - blocks :: list(glove:block()) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl deleted file mode 100644 index 9b6ea546aa5..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl +++ /dev/null @@ -1 +0,0 @@ --record(global, {name :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl deleted file mode 100644 index 6e1b0685acd..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(linkage, { - exported :: boolean(), - section :: gleam@option:option(binary()), - secflags :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl deleted file mode 100644 index b97efd9675c..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(module, { - functions :: list(glove:function_()), - types :: list(glove:type_def()), - data :: list(glove:data_def()) -}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl deleted file mode 100644 index add43ebc8d9..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl +++ /dev/null @@ -1 +0,0 @@ --record(temporary, {name :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl deleted file mode 100644 index c83a3e1e7e8..00000000000 --- a/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(type_def, { - name :: binary(), - align :: gleam@option:option(integer()), - items :: list({glove:type(), integer()}) -}). diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.app.src b/test-community-packages-javascript/build/packages/glove/src/glove.app.src deleted file mode 100644 index d7cc4ba9821..00000000000 --- a/test-community-packages-javascript/build/packages/glove/src/glove.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, glove, [ - {vsn, "0.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Gleam QBE IR Generator"}, - {modules, [glove]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.erl b/test-community-packages-javascript/build/packages/glove/src/glove.erl deleted file mode 100644 index cde846d73e2..00000000000 --- a/test-community-packages-javascript/build/packages/glove/src/glove.erl +++ /dev/null @@ -1,640 +0,0 @@ --module(glove). --compile([no_auto_import, nowarn_unused_vars]). - --export([display_value/1, into_abi/1, into_base/1, size/1, display_data_item/1, add_inst/2, assign_inst/4, jumps/1, add_block/1, last_block/1, display_linkage/1, private/0, new_datadef/0, new_function/0, private_with_section/1, public/0, public_with_section/1, new_module/0, add_function/2, add_type/2, add_data/2, display_type_def/1, display_type/1, display_inst/1, display_data_def/1, display_statement/1, display_block/1, display_arguments/1, display_blocks/1, display_function/1, display_module/1]). --export_type([comp/0, inst/0, value/0, type/0, data_def/0, type_def/0, data_item/0, statement/0, block/0, function_/0, linkage/0, module_/0]). - --type comp() :: slt | sle | sgt | sge | eq | ne. - --type inst() :: {add, value(), value()} | - {sub, value(), value()} | - {mul, value(), value()} | - {'div', value(), value()} | - {'rem', value(), value()} | - {comp, type(), comp(), value(), value()} | - {'and', value(), value()} | - {'or', value(), value()} | - {copy, value()} | - {ret, gleam@option:option(value())} | - {jnz, value(), binary(), binary()} | - {jmp, binary()} | - {call, value(), list({type(), value()})} | - {alloc4, integer()} | - {alloc8, integer()} | - {alloc16, integer()} | - {store, type(), value(), value()} | - {load, type(), value()} | - {blit, value(), value(), integer()}. - --type value() :: {temporary, binary()} | {global, binary()} | {const, integer()}. - --type type() :: word | - long | - single | - double | - byte | - halfword | - {aggregate, type_def()}. - --type data_def() :: {data_def, - linkage(), - binary(), - gleam@option:option(integer()), - list({type(), data_item()})}. - --type type_def() :: {type_def, - binary(), - gleam@option:option(integer()), - list({type(), integer()})}. - --type data_item() :: {symbol, binary(), gleam@option:option(integer())} | - {str, binary()} | - {constant, integer()}. - --type statement() :: {assign, value(), type(), inst()} | {volatile, inst()}. - --type block() :: {block, binary(), list(statement())}. - --type function_() :: {function, - linkage(), - binary(), - list({type(), value()}), - gleam@option:option(type()), - list(block())}. - --type linkage() :: {linkage, - boolean(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --type module_() :: {module, - list(function_()), - list(type_def()), - list(data_def())}. - --spec display_value(value()) -> binary(). -display_value(Value) -> - case Value of - {temporary, Name} -> - <<"%"/utf8, Name/binary>>; - - {global, Name@1} -> - <<"$"/utf8, Name@1/binary>>; - - {const, Value@1} -> - gleam@int:to_string(Value@1) - end. - --spec into_abi(type()) -> type(). -into_abi(Self) -> - case Self of - byte -> - word; - - halfword -> - word; - - Other -> - Other - end. - --spec into_base(type()) -> type(). -into_base(Self) -> - case Self of - byte -> - word; - - halfword -> - word; - - {aggregate, _} -> - long; - - Other -> - Other - end. - --spec size(type()) -> integer(). -size(Self) -> - case Self of - byte -> - 1; - - halfword -> - 2; - - word -> - 4; - - single -> - 4; - - long -> - 8; - - double -> - 8; - - {aggregate, Td} -> - case erlang:element(4, Td) of - [] -> - 0 - end - end. - --spec display_data_item(data_item()) -> binary(). -display_data_item(Item) -> - case Item of - {symbol, Name, Offset} -> - case Offset of - {some, Off} -> - <<<<<<"$"/utf8, Name/binary>>/binary, " +"/utf8>>/binary, - (gleam@int:to_string(Off))/binary>>; - - none -> - <<"$"/utf8, Name/binary>> - end; - - {str, String} -> - <<<<"\""/utf8, String/binary>>/binary, "\""/utf8>>; - - {constant, Val} -> - gleam@int:to_string(Val) - end. - --spec add_inst(block(), inst()) -> block(). -add_inst(Block, Inst) -> - {block, - erlang:element(2, Block), - gleam@list:append(erlang:element(3, Block), [{volatile, Inst}])}. - --spec assign_inst(block(), value(), type(), inst()) -> block(). -assign_inst(Block, Val, Typ, Inst) -> - {block, - erlang:element(2, Block), - gleam@list:append(erlang:element(3, Block), [{assign, Val, Typ, Inst}])}. - --spec jumps(block()) -> boolean(). -jumps(Block) -> - case gleam@list:last(erlang:element(3, Block)) of - {ok, Statement} -> - case Statement of - {volatile, Instr} -> - case Instr of - {ret, _} -> - true; - - {jmp, _} -> - true; - - {jnz, _, _, _} -> - true; - - _ -> - false - end; - - _ -> - false - end; - - {error, _} -> - false - end. - --spec add_block(binary()) -> block(). -add_block(Label) -> - {block, Label, []}. - --spec last_block(list(block())) -> gleam@option:option(block()). -last_block(Blocks) -> - case gleam@list:last(Blocks) of - {ok, Block} -> - {some, Block}; - - {error, _} -> - none - end. - --spec display_linkage(linkage()) -> binary(). -display_linkage(Linkage) -> - Exported_str = case erlang:element(2, Linkage) of - true -> - <<"export "/utf8>>; - - false -> - <<""/utf8>> - end, - Section_str = case erlang:element(3, Linkage) of - {some, Section} -> - <<<<<<<<"section \""/utf8, Section/binary>>/binary, "\""/utf8>>/binary, - (case erlang:element(4, Linkage) of - {some, Secflags} -> - <<<<" \""/utf8, Secflags/binary>>/binary, - "\""/utf8>>; - - none -> - <<""/utf8>> - end)/binary>>/binary, - " "/utf8>>; - - none -> - <<""/utf8>> - end, - <<Exported_str/binary, Section_str/binary>>. - --spec private() -> linkage(). -private() -> - {linkage, false, none, none}. - --spec new_datadef() -> data_def(). -new_datadef() -> - {data_def, private(), <<""/utf8>>, none, []}. - --spec new_function() -> function_(). -new_function() -> - {function, private(), <<""/utf8>>, [], none, []}. - --spec private_with_section(binary()) -> linkage(). -private_with_section(Section) -> - {linkage, false, {some, Section}, none}. - --spec public() -> linkage(). -public() -> - {linkage, true, none, none}. - --spec public_with_section(binary()) -> linkage(). -public_with_section(Section) -> - {linkage, true, {some, Section}, none}. - --spec new_module() -> module_(). -new_module() -> - {module, [], [], []}. - --spec add_function(module_(), function_()) -> module_(). -add_function(Module, Function) -> - {module, - gleam@list:append(erlang:element(2, Module), [Function]), - erlang:element(3, Module), - erlang:element(4, Module)}. - --spec add_type(module_(), type_def()) -> module_(). -add_type(Module, Type_def) -> - {module, - erlang:element(2, Module), - gleam@list:append(erlang:element(3, Module), [Type_def]), - erlang:element(4, Module)}. - --spec add_data(module_(), data_def()) -> module_(). -add_data(Module, Data_def) -> - {module, - erlang:element(2, Module), - erlang:element(3, Module), - gleam@list:append(erlang:element(4, Module), [Data_def])}. - --spec display_type_def(type_def()) -> binary(). -display_type_def(Def) -> - Align_str = case erlang:element(3, Def) of - {some, Align} -> - <<<<"align "/utf8, (gleam@int:to_string(Align))/binary>>/binary, - " "/utf8>>; - - none -> - <<""/utf8>> - end, - Items_str = begin - _pipe = erlang:element(4, Def), - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Item) -> case Item of - {Ty, Count} -> - case Count > 1 of - false -> - display_type(Ty); - - true -> - <<<<(display_type(Ty))/binary, " "/utf8>>/binary, - (gleam@int:to_string(Count))/binary>> - end - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end, - <<<<<<<<<<<<"type :"/utf8, (erlang:element(2, Def))/binary>>/binary, - " = "/utf8>>/binary, - Align_str/binary>>/binary, - "{ "/utf8>>/binary, - Items_str/binary>>/binary, - " }"/utf8>>. - --spec display_type(type()) -> binary(). -display_type(Ty) -> - case Ty of - byte -> - <<"b"/utf8>>; - - halfword -> - <<"h"/utf8>>; - - word -> - <<"w"/utf8>>; - - long -> - <<"l"/utf8>>; - - single -> - <<"s"/utf8>>; - - double -> - <<"d"/utf8>>; - - {aggregate, Ty@1} -> - display_type_def(Ty@1) - end. - --spec display_inst(inst()) -> binary(). -display_inst(Inst) -> - case Inst of - {add, A, B} -> - <<<<<<"add "/utf8, (display_value(A))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B))/binary>>; - - {sub, A@1, B@1} -> - <<<<<<"sub "/utf8, (display_value(A@1))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@1))/binary>>; - - {mul, A@2, B@2} -> - <<<<<<"mul "/utf8, (display_value(A@2))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@2))/binary>>; - - {'div', A@3, B@3} -> - <<<<<<"div "/utf8, (display_value(A@3))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@3))/binary>>; - - {'rem', A@4, B@4} -> - <<<<<<"rem "/utf8, (display_value(A@4))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@4))/binary>>; - - {comp, Ty, Cmp, A@5, B@5} -> - case Ty of - {aggregate, _} -> - <<"Cannot Compare aggregate types"/utf8>>; - - _ -> - case Cmp of - slt -> - <<<<<<<<<<<<<<"c"/utf8, "slt"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - sle -> - <<<<<<<<<<<<<<"c"/utf8, "sle"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - sgt -> - <<<<<<<<<<<<<<"c"/utf8, "sgt"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - sge -> - <<<<<<<<<<<<<<"c"/utf8, "sge"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - eq -> - <<<<<<<<<<<<<<"c"/utf8, "eq"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>>; - - ne -> - <<<<<<<<<<<<<<"c"/utf8, "ne"/utf8>>/binary, - " "/utf8>>/binary, - (display_type(Ty))/binary>>/binary, - " "/utf8>>/binary, - (display_value(A@5))/binary>>/binary, - " "/utf8>>/binary, - (display_value(B@5))/binary>> - end - end; - - {'and', A@6, B@6} -> - <<<<<<"and "/utf8, (display_value(A@6))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@6))/binary>>; - - {'or', A@7, B@7} -> - <<<<<<"or "/utf8, (display_value(A@7))/binary>>/binary, ", "/utf8>>/binary, - (display_value(B@7))/binary>>; - - {copy, Val} -> - <<"copy "/utf8, (display_value(Val))/binary>>; - - {ret, Val@1} -> - case Val@1 of - {some, Val@2} -> - <<<<"ret "/utf8, (display_value(Val@2))/binary>>/binary, - "\n"/utf8>>; - - none -> - <<"ret\n"/utf8>> - end; - - {jnz, Val@3, If_nonzero, If_zero} -> - <<<<<<<<<<"jnz "/utf8, (display_value(Val@3))/binary>>/binary, - ", @"/utf8>>/binary, - If_nonzero/binary>>/binary, - ", @"/utf8>>/binary, - If_zero/binary>>; - - {jmp, Str} -> - <<"jmp @"/utf8, Str/binary>>; - - {call, Name, Args} -> - Arg_str = begin - _pipe = Args, - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Arg) -> case Arg of - {Ty@1, Val@4} -> - <<<<(display_type(Ty@1))/binary, " "/utf8>>/binary, - (display_value(Val@4))/binary>> - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end, - <<<<<<<<"call "/utf8, (display_value(Name))/binary>>/binary, - "("/utf8>>/binary, - Arg_str/binary>>/binary, - ")"/utf8>>; - - {alloc4, Int} -> - <<"alloc4 "/utf8, (gleam@int:to_string(Int))/binary>>; - - {alloc8, Int@1} -> - <<"alloc8 "/utf8, (gleam@int:to_string(Int@1))/binary>>; - - {alloc16, Int@2} -> - <<"alloc16 "/utf8, (gleam@int:to_string(Int@2))/binary>>; - - {store, Typ, Value, Dest} -> - case Typ of - {aggregate, _} -> - <<"Store to an aggregate type"/utf8>>; - - _ -> - <<<<<<<<<<"store"/utf8, (display_type(Typ))/binary>>/binary, - " "/utf8>>/binary, - (display_value(Value))/binary>>/binary, - " "/utf8>>/binary, - (display_value(Dest))/binary>> - end; - - {load, Typ@1, Val@5} -> - case Typ@1 of - {aggregate, _} -> - <<"Load aggregate type"/utf8>>; - - _ -> - <<<<<<"load"/utf8, (display_type(Typ@1))/binary>>/binary, - " "/utf8>>/binary, - (display_value(Val@5))/binary>> - end; - - {blit, Src, Dest@1, N} -> - <<<<<<<<<<"blit "/utf8, (display_value(Src))/binary>>/binary, - ", "/utf8>>/binary, - (display_value(Dest@1))/binary>>/binary, - ", "/utf8>>/binary, - (gleam@int:to_string(N))/binary>> - end. - --spec display_data_def(data_def()) -> binary(). -display_data_def(Def) -> - Linkage_str = display_linkage(erlang:element(2, Def)), - Align_str = case erlang:element(4, Def) of - {some, Align} -> - <<" align "/utf8, (gleam@int:to_string(Align))/binary>>; - - none -> - <<""/utf8>> - end, - Items_str = begin - _pipe = erlang:element(5, Def), - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Item) -> case Item of - {Ty, Di} -> - <<<<(display_type(Ty))/binary, " "/utf8>>/binary, - (display_data_item(Di))/binary>> - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end, - <<<<<<<<<<<<<<Linkage_str/binary, "data $"/utf8>>/binary, - (erlang:element(3, Def))/binary>>/binary, - " ="/utf8>>/binary, - Align_str/binary>>/binary, - " { "/utf8>>/binary, - Items_str/binary>>/binary, - " }"/utf8>>. - --spec display_statement(statement()) -> binary(). -display_statement(Stmt) -> - case Stmt of - {assign, Val, Typ, Inst} -> - <<<<<<<<(display_value(Val))/binary, " ="/utf8>>/binary, - (display_type(Typ))/binary>>/binary, - " "/utf8>>/binary, - (display_inst(Inst))/binary>>; - - {volatile, Inst@1} -> - display_inst(Inst@1) - end. - --spec display_block(block()) -> binary(). -display_block(Block) -> - Label = erlang:element(2, Block), - Statements = begin - _pipe = erlang:element(3, Block), - _pipe@1 = gleam@list:map(_pipe, fun display_statement/1), - gleam@string:join(_pipe@1, <<"\n"/utf8>>) - end, - <<<<Label/binary, "\n"/utf8>>/binary, Statements/binary>>. - --spec display_arguments(list({type(), value()})) -> binary(). -display_arguments(Arguments) -> - case Arguments of - [] -> - <<""/utf8>>; - - _ -> - _pipe = Arguments, - _pipe@1 = gleam@list:index_map(_pipe, fun(_, Arg) -> case Arg of - {Ty, Val} -> - <<<<(display_type(Ty))/binary, " "/utf8>>/binary, - (display_value(Val))/binary>> - end end), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end. - --spec display_blocks(list(block())) -> binary(). -display_blocks(Blocks) -> - _pipe = Blocks, - _pipe@1 = gleam@list:map(_pipe, fun(Block) -> display_block(Block) end), - gleam@string:join(_pipe@1, <<"\n"/utf8>>). - --spec display_function(function_()) -> binary(). -display_function(Func) -> - Linkage_str = display_linkage(erlang:element(2, Func)), - Name_str = erlang:element(3, Func), - Return_str = case erlang:element(5, Func) of - {some, Ty} -> - <<" "/utf8, (display_type(Ty))/binary>>; - - none -> - <<""/utf8>> - end, - Args_str = display_arguments(erlang:element(4, Func)), - Blocks_str = display_blocks(erlang:element(6, Func)), - <<<<<<<<<<<<<<<<<<<<<<Linkage_str/binary, "function"/utf8>>/binary, - Return_str/binary>>/binary, - " "/utf8>>/binary, - "$"/utf8>>/binary, - Name_str/binary>>/binary, - "("/utf8>>/binary, - Args_str/binary>>/binary, - ")"/utf8>>/binary, - " {\n"/utf8>>/binary, - Blocks_str/binary>>/binary, - "}"/utf8>>. - --spec display_module(module_()) -> binary(). -display_module(Module) -> - Functions_str = begin - _pipe = erlang:element(2, Module), - _pipe@1 = gleam@list:map(_pipe, fun display_function/1), - gleam@string:join(_pipe@1, <<"\n"/utf8>>) - end, - Types_str = begin - _pipe@2 = erlang:element(3, Module), - _pipe@3 = gleam@list:map(_pipe@2, fun display_type_def/1), - gleam@string:join(_pipe@3, <<"\n"/utf8>>) - end, - Data_str = begin - _pipe@4 = erlang:element(4, Module), - _pipe@5 = gleam@list:map(_pipe@4, fun display_data_def/1), - gleam@string:join(_pipe@5, <<"\n"/utf8>>) - end, - <<<<<<Functions_str/binary, Types_str/binary>>/binary, "\n"/utf8>>/binary, - Data_str/binary>>. diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.gleam b/test-community-packages-javascript/build/packages/glove/src/glove.gleam deleted file mode 100644 index 3dd73dfa7b3..00000000000 --- a/test-community-packages-javascript/build/packages/glove/src/glove.gleam +++ /dev/null @@ -1,563 +0,0 @@ -import gleam/int -import gleam/string -import gleam/option.{None, Option, Some} -import gleam/list - -/// QBE Comparison Operators -pub type Comp { - /// Less Than - Slt - /// Less or Equal - Sle - /// Greater than - Sgt - /// Greater or equal - Sge - /// Equal - Eq - /// Not equal - Ne -} - -/// QBE instruction -pub type Inst { - /// Adds values - Add(Value, Value) - /// Substracts value(b) from value(a) - Sub(Value, Value) - /// Multiplies values - Mul(Value, Value) - /// Divides value(a) by value(b) - Div(Value, Value) - /// Returns a remaider from division - Rem(Value, Value) - /// Perform a Comparison - Comp(Type, Comp, Value, Value) - /// Bitwise AND - And(Value, Value) - /// Bitwise OR - Or(Value, Value) - /// Copies either temporary or literal value - Copy(Value) - /// Return from a function, optionally with a value - Ret(Option(Value)) - /// Jumps to first label if a value is nonzero or to the second one otherwise - Jnz(Value, String, String) - /// Unconditionally jumps to a label - Jmp(String) - /// Calls a function - Call(Value, List(#(Type, Value))) - /// Allocates a 4-byte aligned area on the stack - Alloc4(Int) - /// Allocates a 8-byte aligned area on the stack - Alloc8(Int) - /// Allocates a 16-byte aligned area on the stack - Alloc16(Int) - /// Stores a value into memory pointed to by destination. - /// (type, destination, value) - Store(Type, Value, Value) - /// Loads a value from memory pointed to by source - /// (type, source) - Load(Type, Value) - /// (source, destination, n) - /// - /// Copy `n` bytes from the source address to the destination address. - /// - /// n must be a constant value. - /// - /// Minimum supported QBE version 1.1 - Blit(Value, Value, Int) -} - -/// Display function for Instructions -pub fn display_inst(inst: Inst) -> String { - case inst { - Add(a, b) -> "add " <> display_value(a) <> ", " <> display_value(b) - Sub(a, b) -> "sub " <> display_value(a) <> ", " <> display_value(b) - Mul(a, b) -> "mul " <> display_value(a) <> ", " <> display_value(b) - Div(a, b) -> "div " <> display_value(a) <> ", " <> display_value(b) - Rem(a, b) -> "rem " <> display_value(a) <> ", " <> display_value(b) - Comp(ty, cmp, a, b) -> { - case ty { - Aggregate(_) -> "Cannot Compare aggregate types" - _ -> - case cmp { - Slt -> - "c" <> "slt" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Sle -> - "c" <> "sle" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Sgt -> - "c" <> "sgt" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Sge -> - "c" <> "sge" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Eq -> - "c" <> "eq" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - Ne -> - "c" <> "ne" <> " " <> display_type(ty) <> " " <> display_value(a) <> " " <> display_value( - b, - ) - } - } - } - And(a, b) -> "and " <> display_value(a) <> ", " <> display_value(b) - Or(a, b) -> "or " <> display_value(a) <> ", " <> display_value(b) - Copy(val) -> "copy " <> display_value(val) - Ret(val) -> { - case val { - Some(val) -> "ret " <> display_value(val) <> "\n" - None -> "ret\n" - } - } - Jnz(val, if_nonzero, if_zero) -> - "jnz " <> display_value(val) <> ", @" <> if_nonzero <> ", @" <> if_zero - Jmp(str) -> "jmp @" <> str - Call(name, args) -> { - let arg_str = - args - |> list.index_map(fn(_, arg) { - case arg { - #(ty, val) -> display_type(ty) <> " " <> display_value(val) - } - }) - |> string.join(", ") - - "call " <> display_value(name) <> "(" <> arg_str <> ")" - } - - Alloc4(int) -> "alloc4 " <> int.to_string(int) - Alloc8(int) -> "alloc8 " <> int.to_string(int) - Alloc16(int) -> "alloc16 " <> int.to_string(int) - Store(typ, value, dest) -> - case typ { - Aggregate(_) -> "Store to an aggregate type" - _ -> - "store" <> display_type(typ) <> " " <> display_value(value) <> " " <> display_value( - dest, - ) - } - - Load(typ, val) -> - case typ { - Aggregate(_) -> "Load aggregate type" - _ -> "load" <> display_type(typ) <> " " <> display_value(val) - } - Blit(src, dest, n) -> - "blit " <> display_value(src) <> ", " <> display_value(dest) <> ", " <> int.to_string( - n, - ) - } -} - -/// QBE Value for instructions -pub type Value { - /// `%`-temporary - Temporary(name: String) - /// `$`-global - Global(name: String) - /// Constant - Const(value: Int) -} - -/// Display Value function -pub fn display_value(value: Value) -> String { - case value { - Temporary(name) -> "%" <> name - Global(name) -> "$" <> name - Const(value) -> int.to_string(value) - } -} - -/// QBE Types -pub type Type { - /// Base Types - Word - Long - Single - Double - /// Extended Types - Byte - Halfword - Aggregate(TypeDef) -} - -/// Display Type function -pub fn display_type(ty: Type) -> String { - case ty { - Byte -> "b" - Halfword -> "h" - Word -> "w" - Long -> "l" - Single -> "s" - Double -> "d" - Aggregate(ty) -> display_type_def(ty) - } -} - -/// Aggregate type with a specified name -/// Returns a C ABI type. Extended types are converted to closest base -/// types -pub fn into_abi(self) -> Type { - case self { - Byte | Halfword -> Word - other -> other - } -} - -/// Returns the closest base type -pub fn into_base(self) -> Type { - case self { - Byte | Halfword -> Word - Aggregate(_) -> Long - other -> other - } -} - -/// Returns byte size for values of the type -pub fn size(self) -> Int { - case self { - Byte -> 1 - Halfword -> 2 - Word | Single -> 4 - Long | Double -> 8 - // This not working - Aggregate(td) -> - case td.items { - [] -> 0 - } - } -} - -/// QBE data definition -pub type DataDef { - DataDef( - linkage: Linkage, - name: String, - align: Option(Int), - items: List(#(Type, DataItem)), - ) -} - -pub fn new_datadef() -> DataDef { - DataDef(linkage: private(), name: "", align: None, items: []) -} - -/// Display function for Datadef -pub fn display_data_def(def: DataDef) -> String { - let linkage_str = display_linkage(def.linkage) - let align_str = case def.align { - Some(align) -> " align " <> int.to_string(align) - None -> "" - } - - let items_str = - def.items - |> list.index_map(fn(_, item) { - case item { - #(ty, di) -> display_type(ty) <> " " <> display_data_item(di) - } - }) - |> string.join(", ") - - linkage_str <> "data $" <> def.name <> " =" <> align_str <> " { " <> items_str <> " }" -} - -/// QBE aggregate type definition -pub type TypeDef { - TypeDef(name: String, align: Option(Int), items: List(#(Type, Int))) -} - -/// Display function for TypeDef -pub fn display_type_def(def: TypeDef) -> String { - let align_str = case def.align { - Some(align) -> "align " <> int.to_string(align) <> " " - None -> "" - } - - let items_str = - def.items - |> list.index_map(fn(_, item) { - case item { - #(ty, count) -> - case count > 1 { - False -> display_type(ty) - True -> display_type(ty) <> " " <> int.to_string(count) - } - } - }) - |> string.join(", ") - - "type :" <> def.name <> " = " <> align_str <> "{ " <> items_str <> " }" -} - -/// QBE Data definition item -pub type DataItem { - /// Symbol and offset - Symbol(String, Option(Int)) - /// String - Str(String) - /// Integer - Constant(Int) -} - -/// Display function for DataItem -pub fn display_data_item(item: DataItem) -> String { - case item { - Symbol(name, offset) -> { - case offset { - Some(off) -> "$" <> name <> " +" <> int.to_string(off) - None -> "$" <> name - } - } - Str(string) -> "\"" <> string <> "\"" - Constant(val) -> int.to_string(val) - } -} - -/// IR Statement -pub type Statement { - Assign(Value, Type, Inst) - Volatile(Inst) -} - -/// Display function for Statement -pub fn display_statement(stmt: Statement) -> String { - case stmt { - Assign(val, typ, inst) -> - display_value(val) <> " =" <> display_type(typ) <> " " <> display_inst( - inst, - ) - Volatile(inst) -> display_inst(inst) - } -} - -/// Function block with a label -pub type Block { - Block(label: String, statements: List(Statement)) -} - -/// Display function for block -pub fn display_block(block: Block) -> String { - let label = block.label - let statements = - block.statements - |> list.map(display_statement) - |> string.join("\n") - - label <> "\n" <> statements -} - -/// Adds a new instruction to the block -pub fn add_inst(block: Block, inst: Inst) -> Block { - Block( - label: block.label, - statements: list.append(block.statements, [Volatile(inst)]), - ) -} - -/// Adds a new instruction assigned to a temporary -pub fn assign_inst(block: Block, val: Value, typ: Type, inst: Inst) -> Block { - Block( - label: block.label, - statements: list.append(block.statements, [Assign(val, typ, inst)]), - ) -} - -/// Returns true if the block's last instruction is a jump -pub fn jumps(block: Block) -> Bool { - case list.last(block.statements) { - Ok(statement) -> - case statement { - Volatile(instr) -> - case instr { - Ret(_) -> True - Jmp(_) -> True - Jnz(_, _, _) -> True - _ -> False - } - _ -> False - } - Error(_) -> False - } -} - -/// QBE Function -pub type Function { - Function( - linkage: Linkage, - name: String, - arguments: List(#(Type, Value)), - return_ty: Option(Type), - blocks: List(Block), - ) -} - -/// Display function for functions -pub fn display_function(func: Function) -> String { - let linkage_str = display_linkage(func.linkage) - let name_str = func.name - let return_str = case func.return_ty { - Some(ty) -> " " <> display_type(ty) - None -> "" - } - let args_str = display_arguments(func.arguments) - let blocks_str = display_blocks(func.blocks) - - linkage_str <> "function" <> return_str <> " " <> "$" <> name_str <> "(" <> args_str <> ")" <> " {\n" <> blocks_str <> "}" -} - -/// Display functions Arguments -pub fn display_arguments(arguments: List(#(Type, Value))) -> String { - case arguments { - [] -> "" - _ -> - arguments - |> list.index_map(fn(_, arg) { - case arg { - #(ty, val) -> display_type(ty) <> " " <> display_value(val) - } - }) - |> string.join(", ") - } -} - -/// Display blocks -pub fn display_blocks(blocks: List(Block)) -> String { - blocks - |> list.map(fn(block) { display_block(block) }) - |> string.join("\n") -} - -/// Instantiates an empty function and returns it -pub fn new_function() -> Function { - Function( - linkage: private(), - name: "", - arguments: [], - return_ty: None, - blocks: [], - ) -} - -/// Adds a new empty block with a specified label and returns -/// a reference to it -pub fn add_block(label: String) -> Block { - Block(label: label, statements: []) -} - -/// Returns a reference to the last block -pub fn last_block(blocks: List(Block)) -> Option(Block) { - case list.last(blocks) { - Ok(block) -> Some(block) - Error(_) -> None - } -} - -/// Linkage of a function or data defintion (e.g. section and -/// private/public status) -pub type Linkage { - Linkage(exported: Bool, section: Option(String), secflags: Option(String)) -} - -/// Display function for Linkage -pub fn display_linkage(linkage: Linkage) -> String { - let exported_str = case linkage.exported { - True -> "export " - False -> "" - } - let section_str = case linkage.section { - Some(section) -> - "section \"" <> section <> "\"" <> case linkage.secflags { - Some(secflags) -> " \"" <> secflags <> "\"" - None -> "" - } <> " " - None -> "" - } - exported_str <> section_str -} - -/// Returns the default configuration for private linkage -pub fn private() -> Linkage { - Linkage(exported: False, section: None, secflags: None) -} - -/// Returns the configuration for private linkage with a provided section -pub fn private_with_section(section: String) -> Linkage { - Linkage(exported: False, section: Some(section), secflags: None) -} - -/// Returns the default configuration for public linkage -pub fn public() -> Linkage { - Linkage(exported: True, section: None, secflags: None) -} - -/// Returns the configuration for public linkage with a provided section -pub fn public_with_section(section: String) -> Linkage { - Linkage(exported: True, section: Some(section), secflags: None) -} - -/// A complete IL file -pub type Module { - Module(functions: List(Function), types: List(TypeDef), data: List(DataDef)) -} - -/// Creates a new module -pub fn new_module() -> Module { - Module(functions: [], types: [], data: []) -} - -/// Display function for Module -pub fn display_module(module: Module) -> String { - let functions_str = - module.functions - |> list.map(display_function) - |> string.join("\n") - - let types_str = - module.types - |> list.map(display_type_def) - |> string.join("\n") - - let data_str = - module.data - |> list.map(display_data_def) - |> string.join("\n") - - functions_str <> types_str <> "\n" <> data_str -} - -/// Add function to module -pub fn add_function(module: Module, function: Function) -> Module { - Module( - functions: list.append(module.functions, [function]), - types: module.types, - data: module.data, - ) -} - -/// Add type to module -pub fn add_type(module: Module, type_def: TypeDef) -> Module { - Module( - functions: module.functions, - types: list.append(module.types, [type_def]), - data: module.data, - ) -} - -/// Add Data to module -pub fn add_data(module: Module, data_def: DataDef) -> Module { - Module( - functions: module.functions, - types: module.types, - data: list.append(module.data, [data_def]), - ) -} diff --git a/test-community-packages-javascript/build/packages/glx/LICENSE b/test-community-packages-javascript/build/packages/glx/LICENSE deleted file mode 100644 index b96ba24ed35..00000000000 --- a/test-community-packages-javascript/build/packages/glx/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Marshall Bowers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glx/README.md b/test-community-packages-javascript/build/packages/glx/README.md deleted file mode 100644 index 5b21e3f0858..00000000000 --- a/test-community-packages-javascript/build/packages/glx/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# glx - -[![Package Version](https://img.shields.io/hexpm/v/glx)](https://hex.pm/packages/glx) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glx/) - -⚒️ Extensions to the Gleam standard library. - -## Installation - -```sh -gleam add glx -``` diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache deleted file mode 100644 index fcd403038e374849ea1940a32415eb039772e52f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1223 zcmc(f&r0h+6vpRF8m1LWdngnllt!Ucis-e93pd(=3PtWURuJ5@>CK?2v4Q+q_&zRt z5Ff;ik09J#?nzQ@te0}#=w@<e&g5i%-+U)Ons6XcyTpdT#&P8^ClJS#POe$G%Zcd9 zk>>5@$YhEy)5*XOSjlqi(E;z2Io5iH4oal~z5W_dP~_u&nN#pW!5<1DOa68(xx2#{ z12ERPVmyMn1*<$drQ*KSLqWrEMB(nvAl*IG?TH>-)AIBHb}%qK&%7Jzx2_dBlJb5a zg=uX7FouOqV~s0}895pO3wu~-V?pfq1J9mZ)srHp+0@1Une;;^NK-~W$<=ze(#91* z6|_~<+Ng=BYX_b9!*u$$GUBK0yiHU9#8?D+T%u0nQWiPND#-YD6NV7U$-E@@3nWQ* ze_E0Y<0O&fBU@_$TdC{1Gq?p>s=z;RXSn9L@#a1XJ!cT_Ap6iwPrZ<UcV}M6XT0$G zf+hbGp6oy#i~aBw@Z<NF{(9OJZ;pTa32Ho1AU60r1(I%9pund(Vy3`1cf>!$nUT+n z^T3}u{Z8^6i!CfxQQJeUnm7^F7OL&ixfja%k?Hty+PA1K)4KBOrhe#ou2+V?5~wsM diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta deleted file mode 100644 index d03bd4e27eedf3cf7c1040715866556930eeee16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache deleted file mode 100644 index fa977bc7ae1a82bbfd8e047c1690b7bb21d879b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4959 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 bp_k3NM}4~D*e+O)yn12i1h<>;6@BP0`pL`( diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta deleted file mode 100644 index 09e2f8acc9336bce7885613638b9b2af3ff95002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd;&v`S@w0Y)f;2TG^sq$cL-7nc-e=B0~Ie!%wp&?033h=d8> diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache deleted file mode 100644 index 978ec12631881a81b9ff3202568af472548a6143..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 zcmd^?-)kdP6vywG$z(FwPP2!Sl`JkvOG|&CMpFd|NZLRJmx`Ir$}S?Lna#9LOp`J* z!EIlZvJd(oNFEpVB~P*-Ea<}u`s|DT0luhj{tNpyp81vS#Ei6Yd|4q3hnr;XJ)isi zo_p@A5BV(-3qxFg0l)ln;l{j(`OZRNesw{a7oEed-a0C42G~t)V07C$nEqJPvRSU( zHMH#%hr$O+22xJlu<P!R7_XZE%8MM2J0c20l(W-b#5j~XD335NI`tD<x9HC-M{@*I zl(iF}QEy_AMjISYpY1m}JgO>P;1^nOrnZ3sovW&Cj)M33Q}qr{!MiC_ZKNpJ5gw?! z0tIiS&(y6n1+sXmUKQPujHYg7D3Bymos%f|RT`;(xWV_?y80wb!8cd-)W=sSIGI~g z@67>UYaJi!J(^Wn=6K~h5MF~v;4}!6rI!W*J?xM4(tg0r%_;zA?w5}G?Lk*B89mF+ z>8<uF0F0q@Te-vWj42s<0^aE0;t1D83KwtUN(EOg49DfaZJMnU##qr?0O6wdTo$qb z9AZ@|0iZm@5+G)Stf%kd<{O;JImf2%f@y-U6O#pqen<q-ehi`xu8i>IOCY+K&Ss@{ zrYsXR9O5!yK09W@hfG2{J#!P|Hh<?<`P$un?{3Qum_1H_Sy{Q|F-!Rx*g&a*QaQJ4 zShg<?CHUr&7MuwUF_{pQpKpwyeiQQPF+5hYY}4o+CdlS?z~=9ktKwn>7cZ=*n(8g> zU%Tyex^BYMV=x`3zD+rPJ!)F4_}o)6qm(8xkAbu%bOgs&TT=tWrh|*r#2;FLp1w}R zYr7Zo+D()zD3iRBs?=nx2g(}Nocs{i01Mfvsm7rBEd68JIWYT2P0g^u2Xh$K?ave8 z^3r)O|3&r_6*tU=53`wCaqnlIWJ2R;tmZW~ZpY#t>Hn+qYFu|3-gy-`YK&y6Zb%>v z0O}E7bvwhMd>!YgQK-_BxBHAr*5Kg4xCgNLkblbi@*>MI@mUGKpNO>9&P%K69dBYH z^_V=RMJtV`sxXPEP`J&q*c2VR?^<cH7$;+;*U#rW!=e38?i1XuWum-J<Pwwis`Q~W z-ejOX9=Gd(pT0_Dvm?oyC_i#94gTR<AF!f(GYM}EmJM#Z;I6~FOw8H@6OmE0w1zT> zq#48I7g5f98uY{giRbsSP>);|!n9+^d;vd!qfsB;w2V^*dO#<cq7c!^3?^Cf>xlSH zFX)m<J)SxCq7~uX`eV}kS$ZmoJ^hm)y><dN5WPDhn@!NJ!<Qoa<gPAe@i|zBEzT?N z8z^7HLKO?wa`k?{i^2v9mE0|Jpcmh6buGQNr(1)rjly*r=imFdxMP}q^D6uWa)-J` diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta deleted file mode 100644 index b59a80e2912f11ad19fd2dd2d30e22bb976c9293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmX^5A|sUn2AH4>VJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache deleted file mode 100644 index 31e6666ca904e587ffb1f6607631444d4299af50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1934 zcmchY%}x_h6vywG>2M37sVAi*C6bng253ZND$&fQw23BERHkFXMpLHk6bFV5&P<~i z6XLc{!NON?=gKFLr5mG5pQ7IRD7G>*!5SC6J$F9O|98&$&z+yJNio&M6^bjb6OSpy z<UwMKE+yVm+S@lY^=PfGgHy8|OK<NJ;vZvM5^oxMeUmHQ<Zwfh?*gAlLRpys7Mz2m zd~t&xoTz-~SnwiJRrVq*P=%_}6j+d(s4L48z!w{4yP-M&@*>B}XCSOY7kWGF&9;{5 z2yAg)YMH%$Do#zcEcIkBb7VF<hL+LWwxg-d+k^lRf|G0VHpdepN7xEDna4?y9gJ`5 zwv+ar(LYncn20gjE9*|leIg;mzhK9|bJTeO08x@N>@U{E4BJcvGD48?g@edh<W#q7 z9jA3a(D`nBowo*cj>`5o2O2M%rg0(DlTjX$(N8l}$0Pm~UsR8ewRSU*@nKvUyRwU$ z$Wagad<7RoT%auDR0ZcnoDZ+hUlxrUDB8AHG+#`JSOC~zKMrB36y-1`;WVrD99xTa zr`6Kmu<mwDLJFTD%B5{XZ)iS}DvXQdR5m;$(;kxb3T}wF;UZbh;;M+NZkWqrPQ+X| z9lF&HdY!Qy+PIw{c@wc)tZH`0=+DGu{8>zin7ZNxPxQei;t|Du6Fqma`aG_t$|Kw> zO>>yc;|%oIITptq^-u#Y-m=UiLU`8|3dh`6uIHG(0TI{_I`7lCnAhZM4bUiTlHaO~ zZZeBW5tFp2cy@U)X>^zvgH)9lT@&fzBD-s9P+$l*zHrV*Bfa{Gqt$HvErFof<o|6W zS+9BMP*Zs>@`s#(Ohe@qp#eR&%5GT+WnY$m=ZnkU^aTFzm+ewL+(8&+nVzQlaEXS} z4O4|5zp>Au>lS&8&0<Qz)U0Q?DCAKP<Ik*)mVT%jwiXN@3Ull@|MW2Zz_Lv12K)jj C<lXoH diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta deleted file mode 100644 index e7f013d77b779ab53ac19ad95a796aa2567c499e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache deleted file mode 100644 index 2d192fdbf5deb01503da4f3f8a8348295bc64521..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7081 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 F{{TP;oZSEb diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta deleted file mode 100644 index e616ec00377dd7ef4a8bfede2ea0cd223bda2c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmaz!7?a8X1B_4xH<V7#Nlnbv&o4?zEix6=4Ak0}oeTh-hX}R+ diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache deleted file mode 100644 index 03665a3d2a03e0ca4e37561ce9071b154ed67fa4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6045 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta deleted file mode 100644 index 701db1ffe1dd588340d9500aba145a8b33520324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmd<{vr1)v0cI#e1WKppq$cL-7nc-e=B39cm1gFoq!w|Z$mL`fm++&ABxRPwCl(bY ORz`h4w=v2;suuuDoEL!r diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache deleted file mode 100644 index 5e054b65c30aa33414ac81f462ef08ee174352d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12276 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 U4xYmE#4C5s@DW8RlE=jV0UN+j7ytkO diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta deleted file mode 100644 index fd97a7e9416a1be0edb048f21be7ab89f3389b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ocmX@|G$oY*1{k3X9w?ojlbV>TpI=atnV)y~=BAkQ+a_%U0Mz0PzyJUM diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache deleted file mode 100644 index 5215251bb4c69636ebbdb2b0b05ccb7dfdaf9912..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49265 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%0DhsW4Z=7xvoKFad3NDx_6!A&WzAH<bjhhMPD0$&U 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 YBJLaOh~m~>3h>s?<GUel(FW!J19^uaasU7T diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta deleted file mode 100644 index e0ebbdac5a8ca12ffada134deb381bda9ca0a76d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmX@|G$oY*2H2qtPAHw8lbV>TpP5&}g(8rXS&Sx<l9^n>gQ6zCpd>Rt4^^xvwYW5= rL<B`$aY<2TUV3~|X=YAJY7sw*TvBF9d}2{iV&%$Nhtz({EiVE9yu2zO diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache deleted file mode 100644 index e6515db0ce1b9bb9bd46523539c10ecd31e3f400..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11362 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 TLkAS$bm)bv1Hu<!h;8hD2FO3Z diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta deleted file mode 100644 index 8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache deleted file mode 100644 index 01022dfbb3f019f439694598af80efcd06e9154b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5793 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 MuDY({!WOgaKaT{dbN~PV diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta deleted file mode 100644 index 8bfae6dc9ba127cf7714d1689d480cfcf6ebdc98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2Wbbd7QGhmnF;_hmjz=0 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache deleted file mode 100644 index d87d203823b36c987b8d2307e3e1777db89ebcfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18155 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta deleted file mode 100644 index 7c99d5d905225ba7c564dd44324b01b038d7953b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache deleted file mode 100644 index 61485ce0044715aa244f337e1bb695ca69369d15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2856 zcmcImL2ukd6!zHbc-Lx_i~>PHmG&u7#U`Xl*FgwH(QX^5B}9V8I1+-W%6i#J;>2rP z_LwA1D$Z2B<iH=Ogg|iR#6Ljdgv1T*Md|@0PF%v9ne3*UECob2Qf8mWGw;3m=6m1s zjU)Z0MJHD2HH%*Ra_sYxMd|L?N$It*?@QL{cF6qpd=P7zrtHm(Ya^{NXx`LsRdo99 zLwB7RW0W+#mxwU*Wp7kR<99vv{t(75hU5KgpmE*&$h%>p@vFJ&Jr%|mL-)O}hR|S^ z<Fza_J}f@;8bxB9w&Kks4I)m$Xp^OBoNC0qq8o05n3UL>Mu?`-(!5*I4NY?kI1*Y~ zq$P)zth&c>>vmb@zNTJHs#n%~LD-!)386G~LHz8}B^>Qj85Cn`Wf}FtnMK?+f`62} za;u<IbCDKEJ(J-yZDD)pWJr0yoHYxxCIia4=^l%$SLrdS(jU#<pepIJOM?&6fU^w7 zeNcG<kJ0j@mY=pj9&*mM;hilwjC0ucBQA^-;+!Wr7mJ$=Br2>0aRdR+Al{E43?c>@ zW6<b8CVe%8v#BY#ec-o~kl{n4(XgQgK|CiHs@tqgt^|<8$>g*R^Yd`M2I|=cydbp) zZ<#Ed=-=s|o&^{bmdi*gLWfsrgH(s_7dqkkqBz<YMTONY_({T|7E%v<h}gb_2m$0f z3~;_5GLoXt!V^Xkns(mqfd-!yG<AumfM%+&Qc(APPS-&}l)5{LZaYY~$CtwPg^Kot zN|NLSA@v+8b@4*DtcES{`r7=-EVo!Q-#$ZW<${!4?MMmHHADPMeQ?|-iXBgo9e-X? z9(oVFCWI;j$A?e+FlUzw3@RCK;mN1rFkqo1$lF3!Av=t?e;|mljvP_DgA7u}^EASG z^S3xlu>b|7WEJ3C7Gn*<$9^OVGtY1)h#(0PCg_$umt^wvm-)4{B&tzRu2!?5W2-8Z zW0$4M!QH(|b-G))NAcb)R3F$Nr~B;++DV*pRE&%Zs&7<h!MP`_<C>hDYx_xME2<n! z!x0?7>rjOU=w7~;5&wSe3^;PF(vS^j78cO+#v8Nn<~{qoRvs0<Ep}UqW`q&;jDd8M zW%sIJ%PxHjN4r-_x}EbMy2uZO-wNl+4yx}tJ(-pzyA-YeZJwWzZ^(I`byban0=C(w zO?R5?e@pw05gF>ZgHlV!<w`O*O2%XJS!^#f<(K<vq-rOklK+2K?%R*M_1tO7mo-5N zLbn|&4Xr*MkvFbXbn~n)4~n5L^2@AQdQ`#>)}l^_XXx-aomiw3<0H#)98z<Jn$F02 enzQm9Kg?MDeU{}Rr{=3TZ`|E0-xi;rqvS8qHNxTm diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta deleted file mode 100644 index 48ca73e0ee43502e40d1b8b70f34ddf19d858229..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache deleted file mode 100644 index d650561ceec9c2756d443e974284f903aa79cf5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37897 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta deleted file mode 100644 index fb52d575e15e87bdb03fca9fb3c0bcfa695274fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache deleted file mode 100644 index 3df3b89f7a0e8991141a83ee6ea85df10fc246c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46265 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%0A# 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 F{vRyk5itM& diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta deleted file mode 100644 index 6587875a9ea9dec90101364c1e7d76d5ef2dffcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmdo0G9#4%23VmCPAHw8lbV>TpP5&}jUteilb?ttlwXvRTEvB-svt2FO(Z2Vxn%E! Lc~|2ZcNPEuC=VMA diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache deleted file mode 100644 index 44187b1f3e10bfbd421efb27189f53ea669cc799..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4750 zcmc&%O>Y}j6rKCV&SV_BlZ%_SNfY8a6p&RE#a0FK#<i6okP6LsD!F)*xb-BN#_?G8 zxP_`x5CW-eSs^xb!Ga&qT{j>W-5`WmwNfjwtk@xS#irc%=EEP@uInIJ%$qkeZ$|H& zd+xb+&Ok{16D}w?U&ON~*Pfh&_#ejr@p}BPV-UZk!SmgkSvgoes7TOo=UXjD(yBG< zYCgm;oYX@QQa-3O0Q7TA#&!wA#Wl6u`{E{jq-7@BAsU=LGqLS{wQ5~+wi5?-wOun4 zR=wqza-}K(swq^<7%OS(w7}az)sp0Ejy}y~U=kew66?LnuQU82rGE}`yaHKc8)&j5 zXN^UfCSQh9#+?vNa4KocPSNDNQZ(LCX!6l?%D6I3lONTB@q<c}Cy|u#I6{++Xx3Pd z(&SOBU_6Y0j0M0l#6OcE{uLeRDTo*7NKez5j^Yf&uhLPB(K!ZM%erL}F$pH?cOkq6 zM9a%iK^P@eSM|$GmLxqy<BPc=b{MfEOCeN~sHRa>l=th-vS56Z$zh=Iru0QR#frE{ zV?=DTJJ1rtC(m;2Mz!L2+c(x>;{6}$Ka2fG#s1e)xK_sVCE8<%cFGavSM`tiiecdv z3mJqd;2sBARIg)fHFv4uSa#jpy4{d8e#sZn*J-&JiH8@+sq_6XMHsU_IafG29t}P8 zNC2Ba@<Mn!A7wbVfX4ynvSLipC|h+&3i#7*TFxG@Om^n>Opa7;HXTnB&yK+9?ZKQ* z3Dk<jhLY*87=ssoDI3I#i)17($$$};9c9OE0%%s<v56m#3YPgs{zcYy>{`{O#h5*c z)_xt#OT^dOp)QykO3$<)P$jLAUP(awMFzp$;11mvtOThf)FNPv<b>-3=Q^Xd)3gtW z6jvmgeZy=@Qs&Xjn^9%g^o8<tVxg4uJwXWhCYi@l3YW@wh9}?52#L@$S`p<ILYYPu zQpy$0R=ei8h-<s<bKhb<v}(&8i(!aKKZ}ILa4bEvu*`9JU4G8NZ`G`p1U}T?Cx*J} zLGAb??R-_cXtn%(b7LT%Av_XzAYuaQF%I=bF5xewxRZqz^@KQKf-WN6K>Be01W!S$ zHf>%ZsSp$=7k5d&Ga!}})_e-{X|mCwqSge;Sqga{8w|8@pa<`VfkGQd{ykAWIJO?l zo;@;zH}caAV=0W%LOyyt2+fnqzl%JK96B}^z`qgxmnxGeD0#(0KZa8L7u@g{dgSec z=%ImSHoykWsqA}2^nVF`T;M!DDD?4hLLa<8DD)g#59a>R7lP0q?we-As_&B3@ua8d zN7V~zZpW%QCKUyq8pgS!<i@=Lx#6}Ko(B%ijyXZm39@|AU4nn@dIImDw1RDS{B4{r z%>M?dg)$~+DMZG2pvNF?f#~ZHC)$e4*UE3o;a;V+wQqjn^%3_b_ROK>;pB+&K+mW= zoa&@bA3p+e0T%!nU>YzS@%KyK3&n2S)J91#3z;0dN_J6xeo$#_-Kf;sl5Dm%LH2Y( zPCIGyT++XvSQqmG=R%;1;F{2%9w&F)7f$m|fkaUDE5=1pF}k64QzG@}5Ep@KpF#j` zrvRC^LR%q(Y_4k7Oven!(kCyVL&dN-LJahb=vW$u4u9#uoN!@`B*LvDSzbq63-Pc6 zWL}S4j3A^m%88C{^vUz$CI7iz6(lToGU6X?2LoC&=--R)xCb@M+z&mX$flPM%;s(< zu*RvQWWn75S>SaJW!xD0rws{#?92!O_$$Wfp!}t-0MdR56{hH-?O~!n5xV*auW5Gw zBr@Ns4^*BC+&Q{@<G+i4Qn0i#GX5)G{DWE`8e?zIJ-AtBMcGggl1kmY*-7kACpJNa z7dA<vzyEPc*J}dISsKZw`r3HfP~TSXvj^nd%7w0OFLnawvp9c3R80)0Fr3ydH{0g& byOmnY^nN8Uyg>KmOZ&?k&8FR?Pt3yK*o5XT diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta deleted file mode 100644 index 0b52486cfc5f05044b9b56a9fe4cd784dca2c15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache deleted file mode 100644 index 537182b25f7b45440690c47eab0d251232bcc2d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7259 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta deleted file mode 100644 index 8b36f47ca8f554f7005ebbf3285be4ae7326420d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache deleted file mode 100644 index e1808b4e0d35fa0566e4b02f6c7b4b1e562911be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2704 zcmd5;U2hvj6y4bmZ@p?{Mpl}}5Hd|$DTy{|;t*9>g*2v%RVh-lbtE22Rj=)-y|CVm zXUB<)ic;~2KuEmsh~T+M@K*Q-{1bTKH?((W)`7K%tyTzCvRAV+cV_NA=iak-qpRLD z@q80sox_j5EB<+I4&zUXm-5$(pXbfzoq&41YY|h-Hf8edLClpxJMf#kx{8gmt0R5! z4ufTc+>5G)-!-w(#Ca>bS5a}kjPp%AV@m7n^1iCUZ}*CdohA1c(uxi$)o&pf{DhY3 zPsKnj)t{;`Gp|+a7d05Xr&sDXbQr7|)w*rK;Fnyb{&NlnznZ1`GZSfM&kw<`^Qz{4 zg$#@=ML|eWaQ-6~?o$-^96S+TDC31DzGT91zMO!uaF&;6I1d}Agl8ZX<0bb1Aw1K> z2WWHVTj5<6hv(!j<pUPRGlX|3iF;lU(3q3xA>qdni4vS+((#XI2nHS}jT$HK6Q>W4 zJ>FQiEOPlWafV*+5ca`aqtOr?T3`TJEIWN03|B08h(!w^L0hxA8#&GCr%2fnsi}-% zU>ld*w;&_}@dLM2I3yd;3HUbf0=NW!|AX1{hOa9dUjiH6Fzfsn8-d3<{~a0L@NY7l zz9hp^)U7v-s-f-iSL1>J7gr<~O*mvcoIM)HYrLzNUYIcQ^*1N2sCVcw`WmrPbw8Fh zGK3l_=_3!vL-{~DUWi3uG=u^*$dMNeC`>`Agp_z;1XaXra>%0gpyh`h;*pRZlhk~2 zxunntmX3Yit;oWu$->br3!#04psdlHkiu20qe5bc(3YuR*LQgIzz;`6wlnf`&9#O6 z=t6#`NJk<rOF~~v^LEG=ML~mn8GsY6xPgQ#0Jv6-^wM#(_5}d67$*P>dX)Js!ssER zF%7xL{U{U?1Ck>oW->4`u4N%3Yny52W|StiaQYxL8xss_i4r9z6dDaH5h6>owG&2< zK;=d``NtS=!3emKkZ*_y5OSm{$={eJ#jm_k0A6(;OTZr|`I#GeJC6A65Q5<G93-K{ zG|9e)gRqr=ZId`6AkaxM!g`ZJu0h&%81*=1a?%UinF;IE>~!N~ngT!O>v6>R^1V%) zY}@3W`!;DlssQl<-(^V7^)$&>fQNgDiA^@|3&J43fsdB?qq!5(4!D&{M0bpim(1hI zJwTe#Pb9!k0N^ij>GfyeJAaDr|AMK6LZ*Hy1Y;lB)Iy~GsjO#;<6qB!zGUln^cT`< zBf)sdukb&V|1&sb9Il#7EoCQZ8-(~j`%N}*@RUuB3u1(?COyy;J-Vsxo>%c~8PC3r zS61=L1-xCs+ZW_1IA4-K`20XO0In3OQ50Zf6`IAu0UOZ854|9!J9lY32sk!MFt6SD LbkSifVsD@q4wtD{ diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta deleted file mode 100644 index 2395015401100f34736675fe98225d853098d534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache deleted file mode 100644 index 3a2037f8bfbede0d447b1c3e951f8488d545e9de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1879 zcmcJQPiqrF6u@_8v)y)0h-0AGg5=Rsn#9_gL@$B<6Dma%yNOT;NVDxulhw^8WH)U@ zz4r?U6+HCf!LQ**@F)nLMLl^Eq`sL=V$+6F5f3|g^CvI!e)-KT&=s9cl-Z2VW~zyI zy3W{>#9Mtf@k!T@t1h?d3r$N=omSY{@&hGqyUz9sUA;=#jVW`EsEG%pT-qQQe50At zSBk+ewOEYc=W8ujI@B;|j}%J52vK#9?-OE1scIe&jS)jp2vHO^wrSp^s-l>qR3%iw z2Zu3}oKnc(utq3jQ)Y({7Avz3$;LitBJtpcp~!=F%k#&<0-S`V<+Nbm32G43I8>cI z?g4jsoqK^l507e&4?C6zmg_fQn}gl(IJAAotIG8@x1Aj;;I;w&GcT|@;COz(ExP~} z%$~~5K`sr8i!dFAm3adUn4W%rwAQieO_%$kU#V0iR0Ed8p2DTLtQX+C0SJZUZS6oi zu3OD5pYJpj)w8?QKA)m?(5EI?UE4&Qg6Hi8bG<)9ktjY$lbR91S47xG&JgY{#0kl` zY&MZGE3-Ew%Z$PO42PW<3R~3R**)4&v-Skmnq@;p{2>*vnoZZ?HUtd=oM7G%<e(33 zkXsiPyjX%BAJ0zhdMPgr&%uKX<ltqx3-uNT0;=>39Yu4<?CL0Gu}Kz1eKOdpja@~F zi;WPHPevX`;{Lvcg-c7126*?V3W|en5=|l<Ig3;bQ8BFvmKhUwA++5<ZSSe_r-q}9 z4n^5B7Q`N#+&-U`Sd{7llSp!NknJO(`R^n~rDeNL%U4M7Pm<}f(9ynRVSnr_5ivvw zE|iiLO*fS65GDH=Ik}zTV6F@WBPs~~k76?QP{R;sE^RD_iV-p(m{2R!tm~HaEdPUM z)uhbWg&kbfFhgRyBwLK7PC0Wu)M*`c`bfjX!?79i9vj5u;C&}A#`84_0sQeOD-V^5 zr;4!ltL5-`|7|%@SxBtc%5n-P%lSgPna``|)YWpqg2Hc|I2k#tC@${_lD|&w6MVmk zOCrN!<7}e9CdT7;8V#3e8K&jpk6LY>yo)aizFg#f+YOjDiR0?Sr^&TetI@hlegl8` BnTh}a diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta deleted file mode 100644 index a2089a5966a154b5dd61585b9e0a71668b274981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2a#5L@9-R#`vm|lvIQ^z diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache deleted file mode 100644 index 4af2a984fabae78b73642b949e602a8ebffc5152..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7006 zcmd^EO>7&-72eq;MR84unlMT%Cx*tdg-V1RiByWDLL6I8-K0XAc*PW|EEv*~9Eoc! zcd6Z_WwkX7<kq5xptt6f0zu>Uk|4;nKo30>&7r8#Lkbi{Q549jK#N`rsPE0}Qe6It zu1`e|l4fUTW@qNT_kG`cx<C@zzsR)|ohsAWXX#JB%sm<>l-|kxb)4jWm?g)1HaF{w z2Tdi#n_NC^`+<_J+E#frq0(g0NRY&|(S+B87-v<Deru5?%QUUW=PD{q7iqdo#}?)2 z_-iAfYD87E=<n*wDy^>>4Wi|Kt`<uVRcQQPTQB`VgT{sATIo^}8h;#FFa2o*8edD7 zORuD%@ppZ#^bZ{xmoqb^g$$0#tdzdM#_ag@(xq`6GyZ<=4k5WaBP91O{H&x&ZVi6a z49T6#kmH8i*e;uueMM2=NEuZ#{!NmU==i88G`(nCQ#D1wttw=QQ^BkRO|OWN8&}u4 z-?W2iak0iIoEny*=Qk9MZqCrnBHc`hURBOI^~zwFntIE!<$^a=ElI$DYwHC6lylD$ zQlK;A?PrQ#{4sl-2R;jGFL7p@e!#fR>)Z+0uIJXFo3jJ7?E>?7(DWS3*~3n~HOzFX z%w!Hfl;hZ;71Z2j0E5idS}*82d#7gkY`5uD0?Tz+aMZ9WrfnZFuj%;Aa#+Q6{J@0o z238%uR)!@GE!$>prDFOpB^nH4b!J-*H$5>F*S^SZ+%xM9oBQyvv$G@aR%fr`w&v!s z@%>j>qv_X#S?89zy9%wY(Dpd(?ftonbA<&t6RyJv=EQ;vY-xTT-ouwp`<|S2^1;s4 zmlot6hghy{>J86xy*V(t*hC6;LC8%oIHBZO5tMnFAXzk^qAY)V{3qiw;=pCmnST{? z<_)7EoEbb3ocVm7o-fk#i_o0U)A=HuU(CK~`H{PZLE7Dw93l)9ZBkXiDT@X;C4Cbj z2f#q@1qK*scpjCKudI%$bnG0>5IQykzctHIloU7^A<KVJGuknpa@)3ig+P}$-;ZMF zTQpv257xZcX!oH2dmu(nk2Y0NMS!gvABX^>A3%H+N87j28DFot&Ry;W(>}xrY&2l* zZWKM}`GE`lBF69q2Apr!dHaY~r_Nlj%DopLm^j<DytZhC2*Rmi{W7n(b&fF&qtI=m z#W2pWQ+%yED0_zD!1&sN=qN6*<=YrwktG6ru(`7r)O5D2vuP103R(Ur@hEX@`P=-U zY1${?`bo@Q8^*nMe*|YN(+lX2my7grnHC1H2Oz21%bg^rz+14ew0|ml-F4d`Qw7L0 zej_dVH?ZiZdizGZEL!80eV@%A);L@z;LxEf@6=~C^Db}ME4p_9aCq^;veJfKkO=VD z^!aYnW~MY9xCZwC_W*et9`^y0O@W<t^N5u>t6ICe+!ILcdV2dF5Q2x<1FP}|cd7{K z0LeA?5GNh!>=2ffc<ePR0k1AF-xcc#!&$)*a~s?<1J`3aSFY?Z+>m4k<~O~DXZf(C z4qZreet$n}q4;#2!>CrwOAI>)7^Vd-#QFE0`}jFQVCc*zasGs)ocOOuS<E^eCKA0! zdA)QgWaVqf%HN%6KUAlWg{*w7Gte>0gfaeyX<6b=J2}f9LD2%S=30c@^`=Fp;TzyZ zIVECj;MBHBDCFkkb4cEWKIGjtD3lDH%MAZ%@u}XV-uE-T3I3{-83PDD{nT4e9aj*N z09lokz*Z!}QiH^h^>?M0iGbFp1=Vlnh1x`D<$21Blw<QCPY;Up0Gs#o^nQ`vUlgME z2OGvGIJt}ZNm5aturt)Vun<vUxqc`OTj~ejNszh*lkm+zV(9Vvh{u+qF26DP%Si$7 z^+s@X!bJCC_x0E^f28l$r6xB%lso(og1<c4{{8p{kJ;BbK!4o=ZRoRzWB_d)7j<>W z-wX(Y<No^tY)n%NBJZn|x4J1DnHtvz?d~-}@psGJt-_#L-!N^z&oodCL(N2K3&P>g zsgcnXgj6W-z7sQ(NS71^G9Pr1)1f&9ZU!zgW4s7|#>(_XQW*O&!R0%x@S4ZXfcr_% zXS+aVwNRyr%m%JDFfB-39GBfS?Is7FgA9=@zpia-SEc$1xBG-%HHuy}BTkk|ebWi0 zc$Da^7@x^wd<Mt(MLPU)*Gb%_14-U2I*-$=mqD|{MJOC`&$`Q<e$udpngm3E2lB@A zrNR+FhP_qkt&Z&OUVlMH0bvELT(3p^g7?|QzFsNsaSk~THGVL+bsIr-sh2Z$k1dG7 zg&_x{PvYW57@x(=4vhJ;^yldZ9v5d0t@&Qe`5qf1(rC@ooirV$8P|=o(!6I0RY|m! zxOrip|9tv+foHb6XH^KM$|$lm(=L!l`Y{U~IS*C_HxJ!d2#J{4QS+fwhdF*c50NQ3 zCg12pZlmG)Rsao=kaUUJ{;5P?TlYYq@a8d}2wdR+I@`M4%bvZEsORiLpXogjspkri z??j6b{U*_*Uz8@|Wc$GQLU1kcFu+owNDF29Rb<uGB3&)h8<JIxFxwfBwdezL8h9JB zC$xY)^}ZB@;Mgbm(I|bt1b#;7WI6W+NYlx8v&c?e-W2yc@GF@IU5O~FGY=B^!hj@b z0m%(=4e%%^C}CD8l8g5A*grv+Dk~qgaH=(02p{y=sJ7HihyTZ!6%-Qckc3$c+v4K> zFnF=T#sYI6;2v&NUVd2g8+ff@RYr?fW!C6~%+sXi0#l%%QkOTTKA)oG)^Q~270n4+ z;Q~^qy`s8dyd$C|EJB4zKlt;Rf!=>+I534pl2A*cw~Q+II4#rnK!Dvz#CF!{+BczE z2;ytPbRz$S92pr9?oXr}QL#qKc>uuvzy=A)Qn%cR?ggrfh50zdK~+V}iI}LB8Ov%| zUR1;IcQ$~kDj`|i8kG8eeI}Wq<obgUEKhE`vn2MI_3O+Ds`RLwWm;VIP;%8nkRrbw zjdsy_vtc=G2FqbmLd2zrsE0*$GQ92~%VB*BT~I7(tB3WgnsviQ#9^IkWni%x4Jj-u z@=j^kljmZ$p^FhAL0YmnvN=M@x^zrfKq31lHXJfy#s)^r*l-a8i-?F>Z;zN;VZ_Ld zb((chz~EgxM!aBAu}{2+TV3vPi&%sd!a!>)B%Km2AL(D}l%%dfnfayFj7leqbaI?d z<>}NjbasW#J|k(FlA>&gq9IM@;h$bvOo^sNh7<lnhbGTKzxMY2w5ZO*x)bC-h!Jyc diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta deleted file mode 100644 index 6ec02d279a3395e477453db0c144ac488b739524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache deleted file mode 100644 index e32b59e08b9e8e8e66bccc8e832b8b974625ca48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6599 zcmds5&u`n-9p@vZ&}QT~Z;HF5Yo-@vMI=SG6FMDcp@}19Uelsm!l*zyTdqyY&o&*3 zG)TI3ixdHh9fn|sb{KXjb}Dw*q1#_D3>gY^1A1wJop#)M9njsjU9|6ek90&@Ka6Au ziU9)kM7{TY-=ClFk8>!a{1RPP@fiz0|5E;4^r!q^vk2qu{Cmey{-Ye~ZaUQL%=%PP zH|f6kwHk!d<ho;9^^-C_yKNAZ!M1K}!Pjqf<74>xXT$gkWx6-K&W`QSMQPIaJs%<C zw5;H(D$ZJXTuV}xWIVo&CoGKB)Uo8g+p+?m!Vk@`y%iChA4pKg;})J!#qPdz?og2G z$aMJbesu2N+6isX4MtLG2#(_Y{b<!M$#|t<w2+ctM2+V65iDL%^yU=>7IwyJIvH5} zJF7SUm4(HR)kgCT6&A+WE6vx&U@<>lX?|}U79ZqZY5pR|_DpOyTN6mZ?;!khl>d*6 z@|uF~uY0RO+jJ$#$jOTF8<fRJlO%*B36H;Syecd3&lo%rKC9!i7CxuK@=Oh%(eW9z z&|et~&Cs{q%>s8DuoRpaui$a8#O&m&b`Xj`jEwkaxPh`r#&`+bi#a4F@YK3KGZ?Tf zDW)s5ci@eZJok@$?$rIZ@H(&s6YKL~V%4~0OsuH}p0Yr!H2(uF#RRKy!CqguLxWu> z7VWUcwuSNrXl#_bb1gKCFF^|v);AEkJn>O3mNDr+U2?;xW=Mm}#3XCnK5Jyp4!20) zbto~{*KOvdrb9g8t}~iO&YvfX`(|gyp#l6_TU+Cn)5taA&@kReu9C>ZOKmfttF{|Z zHvnpH(Hi-I=>)V&I-ml3)v;Z8^_ss+%P|cz2&f;DTX#!7Ed!;<KBeND%a^9-SBh26 zV=campKEW?Hrrn%Mbm1x+{^l05&mFwIg^jcDm$O#lruk?)#dv1(or}~@u{w98bY@b z0#8QYtY>7Lt>6rrWJW<~?r+&^#}1&3IqRQO&ib?780>M@3ZByO)NI;W`$QPHD8TCM zf-qm?FW!zc$vhzrL*d7Ve4n}a@CcofWr#}Mcn+NNHtYtp)%u|=LzPGi7wTg&o>;;s z;a~%v-C)=1Ff^AG3it`0?S|A1C28&tD3rS!zSn^W_azljB?{?}6Iz-zN?c13qzsYe zDTONtW*H9|Xj%9nx{ROIl2Qx^+6xf0F5Qa*cXVu~<0@7aD5_Kxq17jrQXUEpnh5%2 z;O)Qt4huUTB>m#<(3NcWB1`rqjSv#&|AQBVP`0j-V#f{wV3dT^@7S&xvh@nt@O;wV zGJUfR?@8MM5sOtui4g1Ukm1fc-LH`=>=oPu9{?;x(<C(ayRomv3c-$Jhmn{3I^iWx zC!Y;)J`Ul!vBM!8{|X@7$_if7zR+X>1mu)Sz~@0HPv`}tQY95;lWT;lro@1!Mi{O} zaR#Q?@Vx4rUL{wmWS)@fCANQ=y#-`0>xVg+1ok<5F>jDLnyfBBUEQ2N|jY&p3vW z06GZeZ{@69oJk||{3K<bo4rt1d6bt0)TxsV&vOcKRgwI~aB5UxC6KDYk?M^IsbY?j zMmU635AZ3d50>z0)QyuLinE`Dx^do<6qf>~f2mAmx~#HdmIPY72>H7CqSd#k+L2V? zS!koTs`@1N_uM3_6eH7pO)JGpb6w^UmVaM{5c}{uoadx*p+xc=hql8H0%AH2;hBd9 z#M>a@7KOmr+;vQ!(ES~s0zi5069(Y2XRo*b?4?#~?_xQMM9^g4Kzx~)9pbU=mS={< zW-G_MOJ{gQGR)&`4~JIL6Tk;YVyui)Dh+C6xe2vjsmLf6%MiN&oE%a6lRCI_2r0%= zOiCjh4$@hKm5%B3#4GoiM8+sBU%c09O|O&}KtJmj%R);FBh)lK_uUZ+VLPI<(MJ{2 z#d4JhtuRVLCrl6ylY@*i^3nl!{>XCyZTnrva#t$*9#L;^nSQGkRD`<t%67whB4d;n z*o&+D?M!8q%K;@~Zc?bq0q7a-5B9Re*1_5ZYD~Wgv4Qj>EkC~4Oglnm;8!e0xC+<j z(Zow^9VuR9&xBw@-3QWb05Q?ai-;VkUQ)I3utfUpd^^vw3op~+?2=BU|Le{@m3(<M z(>H@a5wAkub~uBSj^8|<>T{!9^3!2uKu^b0<Q>nU7Dav8jr#6r)^Nlbk|+nZF|;qw zvA&v(7UF7EOskT418SI0<<At>!z3FSomV}qohk6rR+74Lr3wuVjFvE3;s#?w2}yD2 zZKOm4m;aB+gddj@FG9nkb))8fRVr}2PrJgSKJZXCeEu)TRE+cjcWuzpfI9JMIJa)R zFG}^_Lmly+Dp*Q7M3>y5;jZrnXL-8zU`pyj#$LDEqL<m*qEJxytg7%S*)yTs5XA<8 z7RU9%C#);p+?erZqC_cLwgHtr1IR&BlfefqDE{GKZ{PRGa-+-rCGA5EqnE^ZxK3pJ zg<k($&i@fLZahSC{#{wWaZi?00mp_BxO{;X^G6I~F-b5^!f>Uo8`qJX3O!Eo+!CW$ z<dY0F0T+qgarBBaIy*C<nG-w3l!Nbnp7T6>P{LVl7&%~de#v+d$#IVaSis~y*BEkR zyf-x};Rh)fZ}5Z_gm~=vPvX9~S?UpaRL|9Gp9jWGuurmA5|Z}_kV-U(?frT$LEr&X zozOs<z~O#P5>r?q1snVxOt|>GG#TWOQ?A3{ZnJ(`#?v~UK8DLRTz&?>u#M+W;Cchs zPvFH0UVH`{IyO!S($O>+XP?DcUAc9)z~><;XUAwe^(NLYMvZvMyIeLg%<7XYh6_9% Ph37G(<Rv^t>Phrp01=-8 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta deleted file mode 100644 index d6129ae46ca64f4056698206dc7d3f0de91184f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd<{vr1)v0Y)f;2TG^sq$cL-=NFV@=I0$1IkMi{#QhNfhQkTV diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache deleted file mode 100644 index c9328b3e01d12cd9f0c43099a54e78e9b65c0fb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10381 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta deleted file mode 100644 index f4e887486561f8be3945fd8b61344d52d6d64401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmZ4IWtGYR1B_4x7nDxVNlnbv&&ez<xplPfLd0zE)c}_f3VHwl diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache deleted file mode 100644 index f8b70c2b5b9f3ebd1291629fef5f1c30e9ae5735..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6395 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 C4H$L+ diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta deleted file mode 100644 index e4e832bc82346f74985f18beddf6b6e9edaf3e83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache deleted file mode 100644 index c54e05a7b73d4c922761a7bd63b2e2e860e6c593..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21839 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 A#{d8T diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta deleted file mode 100644 index 7c72b25579dddf57ca0f1d52e021b5c2d8247d4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache deleted file mode 100644 index 46563080f8b9fb45648765a455f9a47a30df605a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10571 zcmdT~U1%HG6`nh?GPYtxzLA|cKd!HpKgZ+;%Sqda%{q3HZDInAq=ao#w)V)njwdV6 zC^MrZb_)qh3uWok(q+>?AuLT>^so<wLRcs)fkOMzhkYotTUsbBY|Fkh(3f_p`rSJ- z`g6vK9j8ek*SV5r?wot>Ip6utIWt5$BAMt3jc%*b{rg7$xlc{zh6(Mvl6*K!k`MNi z+T{}07Y;ivu?_R`bfID-N=0saUr#%(k|>sp!bGP^<GE}P>7cruEs~DfDZ}Qou3;&} zRFv#aH9}8oG+L$cSjdWsO1pA2UZs6n^UWbwpI0OJSIfIXs>zBnXb7nYdD17@{*&4k zSn+8S-&2!ulFRoH5=s7@T*`kYCu%1Dsfus<Ituyz4or?lujIcR#pG|%T>euriE2~% zP7RY^cINUQbz*X_E0_OS7bZW9W%9RUn7q3&o&Ui`On%i}$p5+<ldJK`d^t`c)F$+8 zk{nS<GJ}zhkmMA`haDvOF-AtiXN*`ENv1HW8*y+Lcj6@ZbBscQB$qH!6xU*mBuR1- z<NaQ&f$`23+=H>XAHQLIyp1IPfl=5&k~YR421xQD#=i&g42J86a6LwPH`c*;uou_t zCAFe8J!_e>x<Xu>c()qK-X>8>Vv0hDqR_6x*$Zj}zjWX)p<N@iD~&G`=M2Xkltvc( zvg)%D%dPsRC?S+iWtsTz3T5~ks~JUZx`w-`D2itZbpuz_vAwaWnAoJv%Ozcj%yNI1 z_gi*(GwaG-V*e0p)TT$P^tguU(F{GBrbor}V1^z{(}P;O`G#BHxM!!Ho?!UxpRwp# zG!UWmQg*k{K$Y%>*SGF3L>#E%;@10H$MtfVn?<<X@}qv;Kk81YgaMll0bRt-hca|1 zO^2Rh=WE=lN@*s020I17xMY-8RbT#)P1e|i+@90LbT;E@e}-A6YcY48Gi;n$bIh?8 zc<}3FMMBWbp;(ONDyG8>lffSxS2tbe8Vd=IUkEu*2vI57ClPZy?S@1d{EfJlqKrG0 zxjEwoA!EPk*cPpEyCjWG(e%2p{k6r|eww{2jjc!O`Ls>XR%uq~`D})sP1CbtI+39h zX*waM$8z*|6*#<pcK2jRy~Z=^pmZ|ZFU~AO`(fa*o6_}W`M4utABMQ6-|ZJZ=~~iL zMKJKavecre!`UNJQ9kyp8Z5*PG7_+~cGr_QQk6K;H|gWZ?7VL4vo0sLBSb402~)Qh zZ&plW)+%yE-Sy}0xIA8`TrwJX*?PD)v$v$oD<Vmbj#lZhr#R6kKf!ebY{W!L(=BH^ zC{*D#PWE@b@xGejO!KQ1y#zcC!I>GUqUAVa(>>KyA?%a;gs=rq7g}P{vPyMOj>54K zQ9k$Z^m8)WcPHMwg;1zDX)Tm>n;&(Ud);E7Sc1#ogT;#6<@SPMa%Rj4;8|qz`ZX>g z$kBm4F2CVIKLTi6gf4+S-ePbBxtL)UbysH<M}7h1nmK+PI9BGi?piim&=;A_-HL6p znb-7^!)F-3#?9bqv9`zgk6}856T*nwr9cIao21|Z_KL>b9Je74yRI)f2LO|?x&(&9 z<|?LOhIont5QW^VY;)XT^P<?mu3hZ(4Sk_p;toE|%*;q~5M!^hIon!*p9?Q{hQE>0 zQwLb8ka}Z3JAS<Rx8amtNbQd?xgohi+d6?+4TmjwVEJ-b?}A<7a=Az>rjW7Nj?+5? z_Q*J>kfIMfKW+h@*R#*bLRSrO(t7PSJ|wMYT2}^TF!T&qBCR0(z~Ap`ztCzDd~qlW zx$JxC{}+67NH`>gDZ=GOI-2DPb-4>Ld57r<*u59rgYXUeh2J$|K1}Dre4Ei4!Z;UT z-@M37-8HW9(jqG?O1Hdb*wP~x^x1jgw>p>tZl5<U&zBZs@H|if!{G^G>M)|A?tJ&S zq|NRl5$;7K&6(^ek4T*Ykt(RZ_@SzvvJ9c>PF4cb7p$ocaK5SqHkEkrwSa&}@h7f% z8k_IB*X0EZUtz8M`x#Tubq#_D7wPOPo-V%zU8<_Lu~1d!MT~TqrU%LbBZaMAh6Msd zbr-<`sOlMTySAnF0{XdiqC=(8?G)*%WrA;Ny%&20mI-8BP_(j0fh4bAe@_kxop9i( z>`vjw8M+gc56PI2MM?r<91y+_27Wsb(7;EY|I3ztO=eGc25<%jkWquZg_=N4WS_HK zgGZH0IBSt#%yJP(VF-Z<TsPeLx?Om>V@{>uAh#W_xQ#?4LRB*M{+8aYlzeHTTcv&5 zX)n^ik^0{VP+duIU>P9^v8u>ja<#&u%cmV<Ng@0^i99pVPkD@6J8SwC0%X3DZs(-e zAZdLCh+iem@~ogZL35m_N1lu&E>tFRx#a->Snl$K<KfL~@k*SMlr~W+VXwYh9Pxtu zYD-p7H>D{VW07umRZ(*g>xRgT_<E=JN4=C>^2!d^xUEDSp>bb|8!c30J#w5ium<dC zS(XM#ou({}Z~o3^N~W4U`dOOIN(ggTAWW6sh28u`YZfTv3~KDG>6B5)`~n=Vj=Js4 z+;ByVN2+36(@TQ)3JPH|317_fKM~fRh}jOOtT$8p*|%TCk{$rAz+{^U>~O06t~y_B zqrXizfkuNqw>&GjOPi4dWn|#%1C&exm*k-~&h5o9J|93&06@130F{D<p65x+#09PZ z(B|{hnaQu$zmNbbz`@UW9Arsy+2SFO{C`3>!=&G;A#)K`uxa9x8l|D2mpT!6D|^oK zlp6wJ)%rdo!9IhwfJnv~T>*C9(?^%{$l6$=fQGPTOERdN7W8Zj_jnZRdy=Y|$R1_Y z?1O0E1`(c0)^%>r>P|~|dQt2(7ijhzH2b#NEbQZK7Fu1&W}!x}G*CC%dTt(Lflg$O zjmYxN#Cr)!3IXZ6s%WSqG(yYmmeBItve*zPm&CcbGB_y9L=Bqw;f~LCh}{KHr)V(K zhHJL7+TrHnU`U;BjYUj^n}Vcxh&n*1zK5h$sK=f8265&-h4Y!c?}8yNGq@o59a77m z#C{*6<Vxdl2~js`DB=4pM|?PYrdbK$dCt14=ZZ`xp&q1@eHpb)-pA=j;&_njczP10 zcbUVlsHkxxP}KI$i=9GI$bTfURT7}KO*E_BTAsd?97=2pZ7Gl?b~f$6e3$q*`T;uX z+v?cA;#)QeoU5QJ^U~m4ldz9F)2G3?;4uNt-Rt>N4<$?Da3vT7xnu+C+K>0yg28G! zj?){zwNa3aKz8EWw;&mQ3h<&h@oKj9N#}n9f0I#3Ng!4?`P+*Vsaxt1K?DV>Xat)6 zo?|et$(ue8Y@lm<0QGv`%NrHXu^~Fy+z@@B273tgPM_PwL_}KN60I}3)ig!DP!&|A zyr!sVhtjxcjgAM*PIgDf{unvZA<{^=gKQR|E7Wj=`z_JzC948XEo;ID8w@!N1c5L1 z-Rcu{38XCzt2@`C1uZM=O+nRUP2@!+0I4h*)}m>C9@$kYBAyl^QjMLox$bhdv7Y(1 zRaOqMiw>Wwl>GJ)SWS=vu(DA`t~IY4CO8V(N+wF>e)JZ7u*+QJ2z~+hMC6T#Ky>f@ zgXw}Y?lsIBT6n25ucaVA5SiCI>auNys=xli!lN9pk$L&AE<7ghf@6~Qw-uTkGk8(K zbIf-){0Dj0Na6}A{f$#-_ek%(7#{&g=s=nd9EM#6?<cIsi$LwY`8AonY=n&jJ&qaJ z{gNuT7OHu#!{K(KUf`AD>!#}y(dN>E!_n)7pA=cW$l%@NxZ@(3ZhA??tJ064O7GQP z$(Xb0BQQTnRVC4RNkV5p%34C_G`&SB@%Curb(r=Jym%c9E&Mf|;R%$fzcSII(t#Wu z+C=wc=$<X|WvmT!bcBv>X@2X$FYb=#xKk;)qAL<jN51;z;Az{o>~^7K$Dc+=a7{u~ N$_8bVnG&ss{0~7TdsYAd diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta deleted file mode 100644 index b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache deleted file mode 100644 index 00887a7dc8161207703959ccd973b9e5454d4c13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7769 zcmds6O>7&-72a8jV#!)&CakO<TjiLFYD#fPi;|Lf5nHtr8?|7>BI&?}Q-fTJD{5(y zOYbhNSSQ<v0Urw^1)LxO($oghA}EksVxT|p*+o&bKJ+I*&|84^;9CzZ*!O03$t6We zmhBcs0dY0EJ3ISk=6m1!-rK#T&o}1#et?c-=)}<U<yT1L=JSNoawIiOB7Ytx%~C~E ztI38b5nZ%%mMw*g6}@nzPp1A@x{ve)-ZFJU(!;Wk9t==_h6Y34=Omd1V>Fnd0|D&m zy|pO&;P1#unf`b!eT(=apOc%}F9<Z=mowQ9WoT%=Om@WwjYi)>_MJXxocE`)KlDT6 ztNvK_ul>+?Ke(3tFbIvSp+ffE5H#j?q_VR+pz-g4o7ujd(73bH%zg?DdXLb*k%;0W zkqrE%{3LP|e)j?}U-(@Mk;n(|J2yZgYw*j2Nu&@a&AMhTX*D}1%@?&Lqo~1rcgVi< z$HY%bNRkMVBpOVn<FZeZ(tU6wG^o&EiUtGoS=-cWr6^xYm~Q*lnfZ)nH7d5amHrmL zH>S|B6demdx4{@4Owqx0BLv>mE3M)D1U76feHQ;^=vgvN@A}r6>s|CFdxKBG8el4O z=Ebxc&Z@{PZfhbGV&miN*gI;qUePQ#%jfgl{t!FtK9dtG5sytDI53f#d$D9{svVmQ zu~QesHRfKK$Hzk<iOiHo?~FE!MvlLhz<TmAhz5)HY%M3l<t$SM$Iu3=+42NQo;kSt z?CxgKH0rsEYDvU)=5wP99<O=fF~#AL44>337XbhqB1?W6-0+@{Z+9lm?aMg!d0y<@ zXt3*N`~I-6X&YcFKu{tj2e!p7yY_qS+Spgy$Xy3X$E+Iyg*O0&_ximr_S)5C$2i)o zQ2<~bC?U@-sg;JtR0}S=l{w)-;pr8P8TGnh={7brQ?+%Y#&nD28>XJ9tEQ#pH-~FQ zvl;YdhZwvno;9jkJho!n_1NTo_NGzO_A_x!6KGE?8CATMNF)Huhnc&2r8o=%SNO9^ zGU@Hk{R03F2)EfS#u1K|!3B=%+g<DZG-x75$1-#;(!@xNj-=>FFLqte6b^J;Xv3Ux zxQG(b#1?r`{b~QN`lD6NEV*=dzhfR}(#U3#%UhiWWq`tZ(0z|fZB+H<!_ILZZK5)z zsq}jQ#(@ldk4z8T42XGj!VuWks9e&<T-dGZ_6jpKtFA5Cu<y(U@RjsST8$M{OG9KL z(h!pFIjc4-n-u`MHKrC|v<AQw5p0<7G@x|3QCs4OUDYcU7~5``(6h!g(=^P47)-5{ z3=>{mWy|mwt~Z1Wgsg=)FKX73sTY8o^;(F%ojLwGn>qOE%je^WVGDq08%D)S=$gHp zFw9bN#jaM8=JFDD8n<93;4d%DB~p`#5JW06vpV_tq!Y1$a<l&;o;{roMoIQJgzxGe zI1+kQp;ycFdJ>u+DfFW<{RuX|ROpvw`b%s+Q0Rj){S!7HD)eEBK14`<qtI{4^dE3F z;wK9H%8?*R&Y!BIHO?j&bt#OeTZGGJ<sqO&jOKw8HHWPM{N17be`hPK@g|~bP!2%g zilz5}2i%69puIxfo`<4kkq{D~WcA1%na(ZHR|!3+@Z*%{nBwgP`Wm5!rr_9YSQ<o= zWkbRt=B=d_tqM#RUNJ12$l<zbuaLgz#fD~HCjREKsg|msoUn6$xNev>@y)#MBYmEz zD#V8qoAMq!ZeLRM4oqw5q6kby2u$bJzq*qaoapo%1S27b!1I6&){7-ms{>oW<akip zJPNr2Qp~kWATdWnO{5M8&BOzWk4vV%508#Cd7R5#Y)AoIRS{JF`9urVn`@`I_C#l{ z#%MJ~tATEL0)$V4XCSVvSF1{Iwc70@>tj*@v_Ds`w@^0(I%nItH;WinE%sfY(1uwN zi&<nGY+ajG0a?Y2Wp+Wk?8u9{s+$&YZicfkkiJ91oObmZXb`<9gfQ^0%k-Ow5B}C% zOCM|@L)<Nd4UEUsL(|_Y97;KA`R#GI659_bK;Z!=1w4Vf=Rt1>=?ujEyYCDSM)@cX z0G=ULk;?V~l|ZzOz<&t0JB6V=_wJy|Kw{M^x>~b6YEL*BhFl>DPhYNUuvsUTc^Gyb z(PA~j23HiD)z*sGsU27`Zi-l|6(3<Ex3z^rJYwMWC_rU8H8Y!3lZAN>ibJ;9(8gWr zb9Onz7+0Y9pD{t3ilaSwEQie(_gsQiggzA)kzU>Io;SB1LTYvHqcQGSNXH6`p=~i| zcy6LQRNLOxNUq&(7xx_J!5ADIRB|~n+<&saBctO!*~;ktJ8Zr|b|&aRfX=I9e=+jg zk!IP@YdK3RNuUI4wk0w&x<I`7JCz}iclAi`91H{R28n$~Zoe)NEfPOZlFZKBt;;O0 z$3Xrz6h9HC<Ss6-sa1_jM9UQo8>TVOgQ~SifRA~K@pVTuIFr8NmF8_)pPQm{DLU7k zb#5}Nt^lw}PrSA5Me`HT>UYyG0DBB(=nHTRZ8+Pm#ksiq_q!=M*AzTlS0$frwil$E z9rJuaFvEWG5QZ}~>A=sSHq*@VipkN26xAz5&2(%8DTGCzT%n<d@iJh8@BX>Y-S?W_ zHM`qGe;J}=jr$hQCFddjL-1(N@c&5wbb2(-*Ht@WS-kH2)4^X4QeuKkuva`D4GZH0 z#w#7Z@aR>!#{e(L7Bl^sP%oc>dXa<OW_h=@$+8glY>SO!oJ0GWlcAwf5w#DlHFbNR z1yQnQ*}B~Tx`J-P;W3(JkO@EpY1O)YxpfEROc9e;%xEENH0+n$XRxk<Ijz2|yIG|B zR>%w6iR9|)YCDaD4ARXa6PQwVq>^YY&H$3pEmW_wMVxZuu_Q(|D+w|OGT9hEiLw14 zd(L}w&hybXqLf^7+}bvXs9u$%_6C2^wZT_h-`<#lo|4yZK>ggeucfaDAY1_;jP|!C zAiEQAi|J5HcS~SHu<IKr)pj|I`~5bHVuCET(4>NXTJk5psSs_6R!?$rf7cEmsZW|b zI6-V8JU9VV0}x`{O!aZse*IwU{d)Rw23+-%&N$Q4YOlXS1TK%=8KXp*hYAgpW!ezz z4lmm-q4rL|9;f)Pr0;X>P49#Bp8B?9s&^huc3iU|Pq$v=ZY$=}q8z~~Sedfc-G(X@ z;;^VK>ou1=umtt;?A&adIW{OkVW&x_VrDg<ifh_11{dwTXaFgg334CBZ=TZ^Z(0Ca z=ycLzSdTLrDEEb0h70W?TK*W8(6#_L)_zqBNXN#n5?H{6GBD4fgpBW0@kwOl`DMcx zFQ_JR)M2RO;kG-aU;MCv#&$l19rI!514m)vM-!9`iH~D&#HtGlN;<KMh~Bui&Py;# zdKTo+^@a2e`1jR9`fDOb=EzibmO$e=G~UI=18Dpa8$?cJWFogpF#JWw6vuVSbl@>7 zZeq1N>pWuYg(n@`J7{NZ=xM#c%~qh`<dmeu$Wu>hIv>rcU~PBEUd2N`lv6I_<Lz}# z?Df@<cZ_nvCVuhy)RWFg3`fZ;M|Q~kW8+RbGDSyr(Fui4>_X^L62pJtqfld}{weBD ig-=6j8$GU8AP0f^IefjO{!zH@J9Qz-J(7~ZbL2lBrMO}M diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta deleted file mode 100644 index 2ae412bccfd7739434a236925520c9652e93ff84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<<f}##0 V7N1m_nUj)Q<er!*%^>nW832Uh9(Di# diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache deleted file mode 100644 index e2a24f1b35167bc143baa6286b81cdb86116470b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3252 zcmbVOPi)g>6!&K*aTB$Kr>=-1x*7z7S<?y$NNXe%(yfd}Td8pwQnku;;xDbiu`AmF z1r7B!P0=oscG!VUTy~tqapS%llQvD$;L2^MUADtc+50{_ByN*ZkfQh{{=WBq@4esq zbFM61mSMUIr*BUFNB*3g9+v^ClT+h&C!dYW-A#wmmTQNCAPmZtH$*u7SbK-0pk32G z!^h7Z?FmUuP7_r>N>ErQReb}6?uW4kvf_K2J`IBMwe8UMTtU!|iV{?0NLL}78_+I6 z_Az3BDS71Ofz!f@DB-8O$Y7#sLGCNRG*o#FCaM5(^2QL2*Xg$BhaY>yYB_Y-Y*K;j z1Gy7J-g_$%xd?5(5_-)z0`o&bs*tV1gv<{P!M5nuJ<E1Cg&5OtPf<hU>5J1tuv9LH zKnt2hB>1hPJtfklM%MIIf&vvwx+M~+*p`kF{R@e`OI_DjQz)#bRsGX63jd}T^naM} zZAR4}WKj4)ey;y0qhO9L=o@1w{DQ(0CM;!D{c4s-v&-IU*v1Hqi;{MZq=DoF5wZtK z4IpcvpdBX!6vCsFi?j`dNh+?(wITGuXfcBqUKl)h)<7fx9qkmFJ&O|3Gq;zXi7Jtb z&oX~yx((a4jE3z95)ER9A4c{CLIeS_H?^yxgm1?1o4`y7W(qJPqc~N9sREWkSr2{8 z^(+>n*+c^E{*6bo$d>|S=kg!fK^Ps>Qe0oQ#NX^uk|rX+nx>#Xa0^!OJC}gkk7nLz zG;AaqSs?^3ku#Ms5hjkoIAQcUOeEVSq}w#Z`c}lq;)C?>>2g#EvBysn9?xmtaE}oo zLC-M+n3&l84xFyS+syqFDx4_5iMj5}OKOPQuh>FZ3=hJ-DJ%zoQi6W5tNn-xQjyBv z$z98IH>vNnq`+w#b<e#+{m=+_GL6tP%uwQ8fKl?xM1XE;nC79BsIp!?vnQL~enZ$@ z;xRi$bra5md)yx=!EwxKu3NKR({CH0P-Y;#W|{g9x*~|ht<3kCuHSMEHWdVdbAcDs zue;EHJ&0cAgq}kj^D4|2V15`&_vv>-l6#O$F~1ie>th$)`JnBZO}oxAWH#rlwlK?o zW01M~s)jQQCJJyA@8t3!#Ttsno>=@t&Wz=^OsD7SM#9xO?QD<9%-+eU*5oBOE<%>Z zf&Z6nCn`>E8EY=KT#79-JN;mPm3o-kdEaw9pIULCo&BswJwVPccwXNOGyjUUfE-6? z3ki<*a3n}RBdc=0X|np~G`O5VC-ahK^LbPVm>E@j#A08CN96p(y)0KZU_|IDSFnL9 zrhCd#ka&veI0{RU(rCGLwnzj@!}FDJiz@Y&?^8Eawtepwt%pi0z<#7Ga_*i9l*Jpk zA>`uAKF;&Io`3t@Tu!OD?f8^}ns8w;n=iC0w##*IFq<2SW&5bv^V`Z@JKR!C1$jgj zYS|$(WxF|L!-!7Wfr1qu*cQd?;lTuEbjLys=t_+;uNaD@29sQ-$8(jcdB@c2zP%mt zo5A4ep6z-oz~YQF<JGcDeN-fn;uW$+BCcbb5sj#Nji$#I8N-#?DihW1zGNOTI9M`A zyh^i#KG)9T1G^NC$!WgVnaxo!1`;h5e@gwG+WCa~H81GldyUOt7j0vG2}8QPChu6D z!I&Ed;&qrCSwiOWrrA@NuoQ@&i}@R2<Gt8S-=CMSW_;mL6Gg~XB@CR*yp_2uR*s8s zQH6^cIR6;t55XlBE**iT4rqs9y$a?bpf#}Hg!?79e<WHdN3G>R7J8-5`v{~}NEh;} zev8gtF`a-8o5nyoLwBKpp#(&Y&?okE-l1`CDfRLmZF2EI#YfO`LP#G&2-3CNvx~m( H`G?8>b;>hi diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta deleted file mode 100644 index 35823f819643250ce036eb3ade6a8b4cfeac4a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0<IM LSG~Z5x<GpX@`M<b diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache deleted file mode 100644 index 5759b2b763316da81f66679300bffb7f8bb46279..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1132 zcmb`G!D<sx6o${acP7&W!+3~RB7tcoK^YgVQ8(Qf19lNmdpkmL<CxNkO*>{V$)JKF zWa-8y@DT*{E!_Ghg1A!Rxs#b`A~hRb<mSvBlK=bv``=9;TNYI()Uc@WywWf&qE2Pq zyj*!`TGJ<C5X6K2SZs_Aqc}W(Yy+SrZr23eY^ob5>03vAM_KuVZSN!Ua98YlJA#K_ z!u5XY;iYVPFC-7^M#rlgD4qSlkB$-586njxGzm)phyYaFP&+~bD1%p|;uaN~RNT9@ z8;s&`>@Y(2sag>d1@MP|BJ^Y;5*?|v<crq$p){RA`}<&Pt=tXRey`UDas8aQCZ^00 z42RJWwEVx&Fa?vK%+`cxaypU7M6*CMq}SrTc*98JVH~75kN*hg%6vF(5{_lJqbQt3 zqqF1GF3nz8_xdOM2~k_sIHU4}YP^;*tvnpej+*m%SNL3*4x+IiJd3-4VG4A(0JNtz z6QJZo&`8`HVEm0h5WQ7(COCgYbzbvR8el3E0^~ILQGLKKX!pAPjG?u_VCg;pEU~U@ z;Vw8&{w)`pw|&97YB}0+CbrD5nHV;g8a}<20oYn2N65Wy<0I6y>~+IYa8k?v+=I@n znUnOc%<1Js^Pzk#{3!69UlCMxsk}<nEvl|2wIkCdvuQuz#yZ;?IlZZ5UgUjw|Jb>s I@7G!U4Me2lCjbBd diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta deleted file mode 100644 index 401fd74cd1e9eb44559765e4eac26450d3f34537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache deleted file mode 100644 index f005a617477a85e6a547a334a7ebb0b84cbae461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 552 zcmah`!A`<J5bd-ymBt1pBpAG~mV-!)M7((rG|_`G(W*BwX^~B7EL+@Nl%t>G#jF40 z*XXo8c`zJy-^{$(w{J3aIdZTy!5s&8wi++sAo`6t>^45Z`H9n2Uul^bj)+$dWh3*n zVxm0=DqywKL~sQVY?@Z^4mN^o7yyQW)qc=5EyD;ZbOTn8u{yx2GrS`y5x3)%NAsJK z>J?PKc9key5^EmW0EmO&gTR~M2ON5r8>N%KZhzP<*GnlBV|vC};gvmQLPz9!$`VnO z<K&eKmX9dn1J`AD%f%v-TCqu{XDl3xkVRrjfy~2PgmE#YW|en$I_!KE%@-+Gl!akf zOy;ta^1H5|2|gD3EgK7hndFrDdoFv(34fpYL=})z{$nBWzYtl-r3ms<%2BXZ&@hj_ z;2UUl8zy?k=rys`!&Y;6%hfW~Xm8U(t?TFZxs;i#on={yc8_Ycd%5K8izrpR4!`T% BlYjsK diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache_meta deleted file mode 100644 index e09e4b1bdc7ab6767e4a4ab5ad8829ce2691f3eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104 zcmYc{FH2#70Tw8O3reTwq$cL-C*|kopo-*V7MF0Ns3}TKPp#lV5h^Yz%FIh&s=wyB IUERhi0Bl7T<NyEw diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index a978a7ff425..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_stdlib" -version = "0.33.1" -gleam = ">= 0.32.0" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 6e1e2261268..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs deleted file mode 100644 index a8309e0cdbd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of Dict size and clean up the API - * @template K,V - */ -export default class Dict { - /** - * @template V - * @param {Record<string,V>} o - * @returns {Dict<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type Dict<string,V> */ - let m = Dict.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {Dict<K,V>} - */ - static fromMap(o) { - /** @type Dict<K,V> */ - let m = Dict.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new Dict(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {Dict<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {Dict<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return Dict.new(); - } - return new Dict(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof Dict) || this.size !== o.size) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index eab2f0b3fec..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam deleted file mode 100644 index 79860e964ef..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam +++ /dev/null @@ -1,157 +0,0 @@ -//// BitArrays are a sequence of binary data of any length. - -import gleam/string - -/// Converts a UTF-8 `String` type into a `BitArray`. -/// -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") -pub fn from_string(x: String) -> BitArray - -/// Returns an integer which is the number of bytes in the bit array. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -pub fn byte_size(x: BitArray) -> Int - -/// Creates a new bit array by joining two bit arrays. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - concat([first, second]) -} - -/// Extracts a sub-section of a bit array. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit array. -/// -/// This function runs in constant time. -/// -@external(erlang, "gleam_stdlib", "bit_array_slice") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) - -/// Tests to see whether a bit array is valid UTF-8. -/// -pub fn is_utf8(bits: BitArray) -> Bool { - do_is_utf8(bits) -} - -@target(erlang) -fn do_is_utf8(bits: BitArray) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:bytes>> -> do_is_utf8(rest) - _ -> False - } -} - -@target(javascript) -fn do_is_utf8(bits: BitArray) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } -} - -/// Converts a bit array to a string. -/// -/// Returns an error if the bit array is invalid UTF-8 data. -/// -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - do_to_string(bits) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "identity") -fn unsafe_to_string(a: BitArray) -> String - -@target(erlang) -fn do_to_string(bits: BitArray) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") -fn do_to_string(a: BitArray) -> Result(String, Nil) - -/// Creates a new bit array by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -@external(erlang, "gleam_stdlib", "bit_array_concat") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") -pub fn concat(bit_arrays: List(BitArray)) -> BitArray - -/// Encodes a BitArray into a base 64 encoded string. -/// -pub fn base64_encode(input: BitArray, padding: Bool) -> String { - let encoded = encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -@external(erlang, "base64", "encode") -@external(javascript, "../gleam_stdlib.mjs", "encode64") -fn encode64(a: BitArray) -> String - -/// Decodes a base 64 encoded string into a `BitArray`. -/// -pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { - let padded = case byte_size(from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - decode64(padded) -} - -@external(erlang, "gleam_stdlib", "base_decode64") -@external(javascript, "../gleam_stdlib.mjs", "decode64") -fn decode64(a: String) -> Result(BitArray, Nil) - -/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { - base64_encode(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. -/// -pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> base64_decode() -} - -@external(erlang, "binary", "encode_hex") -@external(javascript, "../gleam_stdlib.mjs", "base16_encode") -pub fn base16_encode(input: BitArray) -> String - -@external(erlang, "gleam_stdlib", "base16_decode") -@external(javascript, "../gleam_stdlib.mjs", "base16_decode") -pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52ec1b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0930d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 91bd6b76129..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,428 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{type Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} - -/// Runs a callback function if the given bool is `True`, otherwise runs an -/// alternative callback function. -/// -/// Useful when further computation should be delayed regardless of the given -/// bool's value. -/// -/// See [`guard`](#guard) for more info. -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "Kamaka" -/// > let inquiry = fn() { "How may we address you?" } -/// > use <- lazy_guard(when: name == "", return: inquiry) -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -/// ```gleam -/// > import gleam/int -/// > let name = "" -/// > let greeting = fn() { "Hello, " <> name } -/// > use <- lazy_guard(when: name == "", otherwise: greeting) -/// > let number = int.random(1, 99) -/// > let name = "User " <> int.to_string(number) -/// > "Welcome, " <> name -/// "Welcome, User 54" -/// ``` -/// -pub fn lazy_guard( - when requirement: Bool, - return consequence: fn() -> a, - otherwise alternative: fn() -> a, -) -> a { - case requirement { - True -> consequence() - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam deleted file mode 100644 index 20c145d93aa..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam +++ /dev/null @@ -1,197 +0,0 @@ -//// BytesBuilder is a type used for efficiently concatenating bytes together -//// without copying. -//// -//// If we append one bit array to another the bit arrays must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit arrays together. -//// -//// BytesBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit array using the `to_bit_array` function. -//// -//// Byte builders are always byte aligned, so that a number of bits that is not -//// divisible by 8 will be padded with 0s. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -// TODO: pad bit arrays to byte boundaries when adding to a builder. -import gleam/string_builder.{type StringBuilder} -import gleam/list -import gleam/bit_array - -pub opaque type BytesBuilder { - Bytes(BitArray) - Text(StringBuilder) - Many(List(BytesBuilder)) -} - -/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> BytesBuilder { - concat([]) -} - -/// Prepends a bit array to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { - append_builder(from_bit_array(first), second) -} - -/// Appends a bit array to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { - append_builder(first, from_bit_array(second)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to second: BytesBuilder, - prefix first: BytesBuilder, -) -> BytesBuilder { - append_builder(first, second) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "iodata_append") -pub fn append_builder( - to first: BytesBuilder, - suffix second: BytesBuilder, -) -> BytesBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string( - to second: BytesBuilder, - prefix first: String, -) -> BytesBuilder { - append_builder(from_string(first), second) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string( - to first: BytesBuilder, - suffix second: String, -) -> BytesBuilder { - append_builder(first, from_string(second)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { - Many(builders) -} - -/// Joins a list of bit arrays into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { - bits - |> list.map(fn(b) { from_bit_array(b) }) - |> concat() -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string(string: String) -> BytesBuilder { - Text(string_builder.from_string(string)) -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { - Text(builder) -} - -/// Creates a new builder from a bit array. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_bit_array(bits: BitArray) -> BytesBuilder { - Bytes(bits) -} - -/// Turns an builder into a bit array. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -@external(erlang, "erlang", "list_to_bitstring") -pub fn to_bit_array(builder: BytesBuilder) -> BitArray { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_array.concat -} - -fn to_list( - stack: List(List(BytesBuilder)), - acc: List(BitArray), -) -> List(BitArray) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bytes(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_array.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -@external(erlang, "erlang", "iolist_size") -pub fn byte_size(builder: BytesBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam deleted file mode 100644 index 280bf9d1d98..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam +++ /dev/null @@ -1,544 +0,0 @@ -import gleam/option.{type Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a dict, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a dict once. -/// -/// Dicts are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub type Dict(key, value) - -/// Determines the number of key-value pairs in the dict. -/// This function runs in constant time and does not need to iterate the dict. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(dict: Dict(k, v)) -> Int { - do_size(dict) -} - -@external(erlang, "maps", "size") -@external(javascript, "../gleam_stdlib.mjs", "map_size") -fn do_size(a: Dict(k, v)) -> Int - -/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the dict. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { - do_to_list(dict) -} - -@external(erlang, "maps", "to_list") -@external(javascript, "../gleam_stdlib.mjs", "map_to_list") -fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) - -/// Converts a list of 2-element tuples `#(key, value)` to a dict. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the dict. -/// -pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { - do_from_list(list) -} - -@target(erlang) -@external(erlang, "maps", "from_list") -fn do_from_list(a: List(#(key, value))) -> Dict(key, value) - -@target(javascript) -fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Dict(k, v), -) -> Dict(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } -} - -@target(javascript) -fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { - fold_list_of_pair(list, new()) -} - -/// Determines whether or not a value present in the dict for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(dict: Dict(k, v), key: k) -> Bool { - do_has_key(key, dict) -} - -@target(erlang) -@external(erlang, "maps", "is_key") -fn do_has_key(a: key, b: Dict(key, v)) -> Bool - -@target(javascript) -fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { - get(dict, key) != Error(Nil) -} - -/// Creates a fresh dict that contains no values. -/// -pub fn new() -> Dict(key, value) { - do_new() -} - -@external(erlang, "maps", "new") -@external(javascript, "../gleam_stdlib.mjs", "new_map") -fn do_new() -> Dict(key, value) - -/// Fetches a value from a dict for a given key. -/// -/// The dict may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -@external(erlang, "gleam_stdlib", "map_get") -@external(javascript, "../gleam_stdlib.mjs", "map_get") -fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) - -/// Inserts a value into the dict with the given key. -/// -/// If the dict already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { - do_insert(key, value, dict) -} - -@external(erlang, "maps", "put") -@external(javascript, "../gleam_stdlib.mjs", "map_insert") -fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) - -/// Updates all values in a given dict by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { - do_map_values(fun, dict) -} - -@target(erlang) -@external(erlang, "maps", "map") -fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) - -@target(javascript) -fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { - let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } - dict - |> fold(from: new(), with: f) -} - -/// Gets a list of all keys in a given dict. -/// -/// Dicts are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(dict: Dict(keys, v)) -> List(keys) { - do_keys(dict) -} - -@target(erlang) -@external(erlang, "maps", "keys") -fn do_keys(a: Dict(keys, v)) -> List(keys) - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(dict: Dict(k, v)) -> List(k) { - let list_of_pairs = to_list(dict) - do_keys_acc(list_of_pairs, []) -} - -/// Gets a list of all values in a given dict. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(dict: Dict(k, values)) -> List(values) { - do_values(dict) -} - -@target(erlang) -@external(erlang, "maps", "values") -fn do_values(a: Dict(k, values)) -> List(values) - -@target(javascript) -fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } -} - -@target(javascript) -fn do_values(dict: Dict(k, v)) -> List(v) { - let list_of_pairs = to_list(dict) - do_values_acc(list_of_pairs, []) -} - -/// Creates a new dict from a given dict, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter( - in dict: Dict(k, v), - keeping predicate: fn(k, v) -> Bool, -) -> Dict(k, v) { - do_filter(predicate, dict) -} - -@target(erlang) -@external(erlang, "maps", "filter") -fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) - -@target(javascript) -fn do_filter( - f: fn(key, value) -> Bool, - dict: Dict(key, value), -) -> Dict(key, value) { - let insert = fn(dict, k, v) { - case f(k, v) { - True -> insert(dict, k, v) - _ -> dict - } - } - dict - |> fold(from: new(), with: insert) -} - -/// Creates a new dict from a given dict, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { - do_take(desired_keys, dict) -} - -@target(erlang) -@external(erlang, "maps", "with") -fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_taken( - dict: Dict(k, v), - desired_keys: List(k), - acc: Dict(k, v), -) -> Dict(k, v) { - let insert = fn(taken, key) { - case get(dict, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) - } -} - -@target(javascript) -fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { - insert_taken(dict, desired_keys, new()) -} - -/// Creates a new dict from a pair of given dicts by combining their entries. -/// -/// If there are entries with the same keys in both dicts the entry from the -/// second dict takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { - do_merge(dict, new_entries) -} - -@target(erlang) -@external(erlang, "maps", "merge") -fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { - insert(dict, pair.0, pair.1) -} - -@target(javascript) -fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { - case new_entries { - [] -> dict - [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) - } -} - -@target(javascript) -fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { - new_entries - |> to_list - |> fold_inserts(dict) -} - -/// Creates a new dict from a given dict with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { - do_delete(key, dict) -} - -@external(erlang, "maps", "remove") -@external(javascript, "../gleam_stdlib.mjs", "map_remove") -fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) - -/// Creates a new dict from a given dict with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { - case disallowed_keys { - [] -> dict - [x, ..xs] -> drop(delete(dict, x), xs) - } -} - -/// Creates a new dict with one entry updated using a given function. -/// -/// If there was not an entry in the dict for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let dict = from_list([#("a", 0)]) -/// > -/// > update(dict, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(dict, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in dict: Dict(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Dict(k, v) { - dict - |> get(key) - |> option.from_result - |> fun - |> insert(dict, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over dict: Dict(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - dict - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index c71c6f342ad..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1508 +0,0 @@ -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option} -import gleam/result -import gleam/string_builder -@target(erlang) -import gleam/bit_array - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from(a: anything) -> Dynamic - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_unsafe_coerce(a: Dynamic) -> a - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit -/// array if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_array(from("Hello")) == bit_array.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_array(from(123)) -/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - decode_bit_array(data) -} - -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - -@external(erlang, "gleam_stdlib", "decode_bit_array") -@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") -fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -@target(erlang) -fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_array(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_array.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitArray", path: [])]) - } - }) -} - -@target(erlang) -fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "decode_string") -fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -@external(erlang, "gleam_stdlib", "classify_dynamic") -@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") -fn do_classify(a: Dynamic) -> String - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -@external(erlang, "gleam_stdlib", "decode_int") -@external(javascript, "../gleam_stdlib.mjs", "decode_int") -fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -@external(erlang, "gleam_stdlib", "decode_float") -@external(javascript, "../gleam_stdlib.mjs", "decode_float") -fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -@external(erlang, "gleam_stdlib", "decode_bool") -@external(javascript, "../gleam_stdlib.mjs", "decode_bool") -fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -@external(erlang, "gleam_stdlib", "decode_list") -@external(javascript, "../gleam_stdlib.mjs", "decode_list") -fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_result") -@external(javascript, "../gleam_stdlib.mjs", "decode_result") -fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -@external(erlang, "gleam_stdlib", "decode_option") -@external(javascript, "../gleam_stdlib.mjs", "decode_option") -fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -@external(erlang, "gleam_stdlib", "decode_field") -@external(javascript, "../gleam_stdlib.mjs", "decode_field") -fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -type UnknownTuple - -@external(erlang, "gleam_stdlib", "decode_tuple") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") -fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple2") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") -fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple3") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") -fn decode_tuple3( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple4") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") -fn decode_tuple4( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple5") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") -fn decode_tuple5( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple6") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") -fn decode_tuple6( - a: Dynamic, -) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, -) - -@external(erlang, "gleam_stdlib", "tuple_get") -@external(javascript, "../gleam_stdlib.mjs", "tuple_get") -fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) - -@external(erlang, "gleam_stdlib", "size_of_tuple") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn tuple_size(a: UnknownTuple) -> Int - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a dict. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() |> from |> map(string, int) -/// Ok(dict.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn dict( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> dict.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(dict.from_list(pairs)) - } -} - -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - -@external(erlang, "gleam_stdlib", "decode_map") -@external(javascript, "../gleam_stdlib.mjs", "decode_map") -fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.concat([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 5d62419fd0d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,546 +0,0 @@ -//// Functions for working with floats. -//// -//// ## Division by zero -//// -//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE -//// 754 standard for floating point arithmetic and does not have an `Infinity` -//// value. In Erlang division by zero results in a crash, however Gleam does -//// not have partial functions and operators in core so instead division by zero -//// returns zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/order.{type Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_float") -@external(javascript, "../gleam_stdlib.mjs", "parse_float") -fn do_parse(a: String) -> Result(Float, Nil) - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -@external(erlang, "gleam_stdlib", "float_to_string") -@external(javascript, "../gleam_stdlib.mjs", "float_to_string") -fn do_to_string(a: Float) -> String - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -@external(erlang, "math", "ceil") -@external(javascript, "../gleam_stdlib.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -@external(erlang, "math", "floor") -@external(javascript, "../gleam_stdlib.mjs", "floor") -fn do_floor(a: Float) -> Float - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -@target(erlang) -@external(erlang, "erlang", "round") -fn do_round(a: Float) -> Int - -@target(javascript) -fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "round") -fn js_round(a: Float) -> Int - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../gleam_stdlib.mjs", "truncate") -fn do_truncate(a: Float) -> Int - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../gleam_stdlib.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Generates a random float between the given minimum and maximum values. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(min: Float, max: Float) -> Float { - do_random_uniform() *. { max -. min } +. min -} - -/// Returns a random float uniformly distributed in the value range -/// 0.0 =< X < 1.0 and updates the state in the process dictionary. -/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> -/// -@external(erlang, "rand", "uniform") -@external(javascript, "../gleam_stdlib.mjs", "random_uniform") -fn do_random_uniform() -> Float - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index d93c16afaf6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,874 +0,0 @@ -//// Functions for working with integers. -//// -//// ## Division by zero -//// -//// In Erlang division by zero results in a crash, however Gleam does not have -//// partial functions and operators in core so instead division by zero returns -//// zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/float -import gleam/order.{type Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_int") -@external(javascript, "../gleam_stdlib.mjs", "parse_int") -fn do_parse(a: String) -> Result(Int, Nil) - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -@external(erlang, "gleam_stdlib", "int_from_base_string") -@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") -fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "to_string") -fn do_to_string(a: Int) -> String - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") -fn do_to_base_string(a: Int, b: Int) -> String - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -@external(erlang, "erlang", "float") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_float(a: Int) -> Float - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Generates a random int between the given minimum and maximum values. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(min: Int, max: Int) -> Int { - float.random(to_float(min), to_float(max)) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} - -/// Calculates the bitwise AND of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "band") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") -pub fn bitwise_and(x: Int, y: Int) -> Int - -/// Calculates the bitwise NOT of its argument. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bnot") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") -pub fn bitwise_not(x: Int) -> Int - -/// Calculates the bitwise OR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") -pub fn bitwise_or(x: Int, y: Int) -> Int - -/// Calculates the bitwise XOR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bxor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") -pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic left bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsl") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") -pub fn bitwise_shift_left(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic right bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsr") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") -pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index 0c0a3eeffe0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,117 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -@external(erlang, "gleam_stdlib", "print") -@external(javascript, "../gleam_stdlib.mjs", "print") -fn do_print(string string: String) -> Nil - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -@external(erlang, "gleam_stdlib", "print_error") -@external(javascript, "../gleam_stdlib.mjs", "print_error") -fn do_print_error(string string: String) -> Nil - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -@external(erlang, "gleam_stdlib", "println") -@external(javascript, "../gleam_stdlib.mjs", "console_log") -fn do_println(string string: String) -> Nil - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "console_error") -fn do_println_error(string string: String) -> Nil - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "print_debug") -fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index c57e7fd9473..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1530 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option, None, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_map2( - continuation1: fn() -> Action(a), - continuation2: fn() -> Action(b), - with fun: fn(a, b) -> c, -) -> fn() -> Action(c) { - fn() { - case continuation1() { - Stop -> Stop - Continue(a, next_a) -> - case continuation2() { - Stop -> Stop - Continue(b, next_b) -> - Continue(fun(a, b), do_map2(next_a, next_b, fun)) - } - } - } -} - -/// Combines two interators into a single one using the given function. -/// -/// If an iterator is longer than the other the extra elements are dropped. -/// -/// This function does not evaluate the elements of the two iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// let first = from_list([1, 2, 3]) -/// let second = from_list([4, 5, 6]) -/// map2(first, second, fn(x, y) { x + y }) |> to_list -/// // -> [5, 7, 9] -/// ``` -/// -/// ```gleam -/// let first = from_list([1, 2]) -/// let second = from_list(["a", "b", "c"]) -/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list -/// // -> [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2( - iterator1: Iterator(a), - iterator2: Iterator(b), - with fun: fn(a, b) -> c, -) -> Iterator(c) { - do_map2(iterator1.continuation, iterator2.continuation, fun) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Joins a list of iterators into a single iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [[1, 2], [3, 4]] -/// > |> map(from_list) -/// > |> concat -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { - flatten(from_list(iterators)) -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - keeping predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - groups - |> dict.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Dict(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Dict(key, List(element)) { - iterator - |> fold(dict.new(), group_updater(key)) - |> dict.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} - -/// Add a new element to the start of an iterator. -/// -/// This function is for use with `use` expressions, to replicate the behaviour -/// of the `yield` keyword found in other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > use <- iterator.yield(1) -/// > use <- iterator.yield(2) -/// > use <- iterator.yield(3) -/// > iterator.empty() -/// iterator.from_list([1, 2, 3]) -/// ``` -/// -pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { - Iterator(fn() { Continue(element, next().continuation) }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index a5cffa9b951..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2154 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{type Order} -import gleam/pair -import gleam/dict.{type Dict} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -@target(erlang) -@external(erlang, "erlang", "length") -fn do_length(a: List(a)) -> Int - -@target(javascript) -fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) -} - -@target(javascript) -fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -@target(erlang) -@external(erlang, "lists", "reverse") -fn do_reverse(a: List(a)) -> List(a) - -@target(javascript) -fn do_reverse(list) { - do_reverse_acc(list, []) -} - -@target(javascript) -fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - case dict.get(groups, f(elem)) { - Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> dict.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> dict.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) -/// |> dict.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { - fold(list, dict.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Combines two lists into a single list using the given function. -/// -/// If a list is longer than the other the extra elements are dropped. -/// -/// ## Examples -/// -/// ```gleam -/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) -/// [5, 7, 9] -/// ``` -/// -/// ```gleam -/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) -/// [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { - do_map2(list1, list2, fun, []) -} - -fn do_map2( - list1: List(a), - list2: List(b), - fun: fn(a, b) -> c, - acc: List(c), -) -> List(c) { - case list1, list2 { - [], _ | _, [] -> reverse(acc) - [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) - } -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -@target(erlang) -@external(erlang, "lists", "append") -fn do_append(a: List(a), b: List(a)) -> List(a) - -@target(javascript) -fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) -} - -@target(javascript) -fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Joins a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn concat(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// This is the same as `concat`: it joins a list of lists into a single -/// list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// Maps the list with the given function into a list of lists, and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> concat -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> [stop, ..acc] - order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) - order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, finds all tuples that have a given -/// key as the first element and returns the second element. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") -/// [0, 2] -/// ``` -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1)], "c") -/// [] -/// ``` -/// -pub fn key_filter( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> List(v) { - filter_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> concat - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> concat -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> concat -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> concat - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [elem_pair, ..enumerable] -> - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calculate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 1f8b228eb90..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,127 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(map) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@target(javascript) -fn do_filter(f: fn(key, value) -> Bool, map) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 12ce01136ca..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,133 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > negate(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -pub fn negate(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} - -/// Inverts an ordering function, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > list.sort([1, 5, 4], by: reverse(int.compare)) -/// [5, 4, 1] -/// ``` -/// -pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { - fn(a, b) { orderer(b, a) } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index 9ffda789f6a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,214 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{type Option} - -pub type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -@external(erlang, "gleam_stdlib", "compile_regex") -@external(javascript, "../gleam_stdlib.mjs", "compile_regex") -fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -@external(erlang, "gleam_stdlib", "regex_check") -@external(javascript, "../gleam_stdlib.mjs", "regex_check") -fn do_check(a: Regex, b: String) -> Bool - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "regex_split") -fn do_split(a: Regex, b: String) -> List(String) - -@target(javascript) -fn do_split(regex, string) -> List(String) { - js_split(string, regex) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn js_split(a: String, b: Regex) -> List(String) - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -@external(erlang, "gleam_stdlib", "regex_scan") -@external(javascript, "../gleam_stdlib.mjs", "regex_scan") -fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index fb6dddb3110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,482 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// "Updates" an `Ok` result by passing its value to a function that yields a result, -/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) -/// -/// If the input is an `Error` rather than an `Ok`, the function is not called and -/// the original `Error` is returned. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), Error("a"), Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index df8d500e804..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/dict.{type Dict} -import gleam/result - -// A list is used as the map value as an empty list has the smallest -// representation in Erlang's binary format -@target(erlang) -type Token = - List(Nil) - -@target(erlang) -const token = [] - -@target(javascript) -type Token = - Nil - -@target(javascript) -const token = Nil - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Dict(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(dict.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - dict.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: dict.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> dict.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: dict.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - dict.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: dict.new(), - with: fn(m, k) { dict.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - keeping predicate: fn(member) -> Bool, -) -> Set(member) { - Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(dict.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case dict.size(first.map) > dict.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index 7254fd9fd1c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,913 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{type Iterator} -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/order -import gleam/string_builder.{type StringBuilder} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -@external(erlang, "string", "length") -@external(javascript, "../gleam_stdlib.mjs", "string_length") -fn do_length(a: String) -> Int - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -@target(erlang) -fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string -} - -@target(javascript) -fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: String) -> String - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: String) -> String - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -@external(erlang, "gleam_stdlib", "less_than") -@external(javascript, "../gleam_stdlib.mjs", "less_than") -fn less_than(a: String, b: String) -> Bool - -/// Takes a substring given a start grapheme index and a length. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -@target(erlang) -@external(erlang, "string", "slice") -fn do_slice(a: String, b: Int, c: Int) -> String - -@target(javascript) -fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -@external(erlang, "gleam_stdlib", "crop_string") -@external(javascript, "../gleam_stdlib.mjs", "crop_string") -pub fn crop(from string: String, before substring: String) -> String - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -@external(erlang, "gleam_stdlib", "contains_string") -@external(javascript, "../gleam_stdlib.mjs", "contains_string") -pub fn contains(does haystack: String, contain needle: String) -> Bool - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -@external(erlang, "gleam_stdlib", "string_starts_with") -@external(javascript, "../gleam_stdlib.mjs", "starts_with") -fn do_starts_with(a: String, b: String) -> Bool - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -@external(erlang, "gleam_stdlib", "string_ends_with") -@external(javascript, "../gleam_stdlib.mjs", "ends_with") -fn do_ends_with(a: String, b: String) -> Bool - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: String, b: String) -> List(String) - -@target(erlang) -fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split_once") -fn do_split_once( - x x: String, - substring substring: String, -) -> Result(#(String, String), Nil) - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - do_join(strings, separator) -} - -@target(erlang) -fn do_join(strings: List(String), separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "join") -fn do_join(strings strings: List(String), string string: String) -> String - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -@target(erlang) -fn do_trim(string: String) -> String { - erl_trim(string, Both) -} - -@target(erlang) -type Direction { - Leading - Trailing - Both -} - -@target(erlang) -@external(erlang, "string", "trim") -fn erl_trim(a: String, b: Direction) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim") -fn do_trim(string string: String) -> String - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -@target(erlang) -fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_left") -fn do_trim_left(string string: String) -> String - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -@target(erlang) -fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_right") -fn do_trim_right(string string: String) -> String - -/// Splits a non-empty `String` into its first element (head) and rest (tail). -/// This lets you pattern match on `String`s exactly as you would with lists. -/// -/// Note on JavaScript using the function to iterate over a string will likely -/// be slower than using `to_graphemes` due to string slicing being more -/// expensive on JavaScript than Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -@external(erlang, "gleam_stdlib", "string_pop_grapheme") -@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") -fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "codepoint") -fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -@target(erlang) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(<<string:utf8>>, []) - |> list.reverse -} - -@target(erlang) -fn do_to_utf_codepoints_impl( - bit_array: BitArray, - acc: List(UtfCodepoint), -) -> List(UtfCodepoint) { - case bit_array { - <<first:utf8_codepoint, rest:bytes>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - _ -> acc - } -} - -@target(javascript) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") -fn string_to_codepoint_integer_list(a: String) -> List(Int) - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") -/// > utf_codepoint_to_int(utf_codepoint) -/// 128156 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") -fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -@external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam_stdlib.mjs", "inspect") -fn do_inspect(term term: anything) -> StringBuilder - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -/// ## Examples -/// -/// ```gleam -/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") -/// 58 -/// ``` -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "byte_size") -pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 5792ca8699d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,298 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -@external(erlang, "gleam_stdlib", "iodata_append") -@external(javascript, "../gleam_stdlib.mjs", "add") -fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_from_strings(a: List(String)) -> StringBuilder - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_concat(a: List(StringBuilder)) -> StringBuilder - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from_string(a: String) -> StringBuilder - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -@external(erlang, "unicode", "characters_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_string(a: StringBuilder) -> String - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -@external(erlang, "erlang", "iolist_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn do_byte_size(a: StringBuilder) -> Int - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -@target(erlang) -@external(erlang, "string", "reverse") -fn do_reverse(a: StringBuilder) -> StringBuilder - -@target(javascript) -fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -fn do_to_graphemes(string string: String) -> List(String) - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -@target(erlang) -type Direction { - All -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) - -@target(erlang) -fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn do_split( - builder builder: StringBuilder, - pattern pattern: String, -) -> List(StringBuilder) - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -@target(erlang) -fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, -) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) -} - -@target(erlang) -@external(erlang, "string", "replace") -fn erl_replace( - a: StringBuilder, - b: String, - c: String, - d: Direction, -) -> StringBuilder - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_replace") -fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -@external(erlang, "string", "equal") -@external(javascript, "../gleam_stdlib.mjs", "equal") -fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -@target(erlang) -@external(erlang, "string", "is_empty") -fn do_is_empty(a: StringBuilder) -> Bool - -@target(javascript) -fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 11f6ea68cd2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,462 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/string -import gleam/string_builder.{type StringBuilder} -@target(javascript) -import gleam/pair -@target(javascript) -import gleam/regex -@target(javascript) -import gleam/result - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "uri_parse") -fn do_parse(a: String) -> Result(Uri, Nil) - -@target(javascript) -fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) -} - -@target(javascript) -fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) -} - -@target(javascript) -fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } -} - -@target(javascript) -fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } -} - -// Split an authority into its userinfo, host and port parts. -@target(javascript) -fn split_authority( - authority: Option(String), -) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } -} - -@target(javascript) -fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) -} - -@target(javascript) -fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -@external(erlang, "gleam_stdlib", "parse_query") -@external(javascript, "../gleam_stdlib.mjs", "parse_query") -fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -@external(erlang, "gleam_stdlib", "percent_encode") -@external(javascript, "../gleam_stdlib.mjs", "percent_encode") -fn do_percent_encode(a: String) -> String - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -@external(erlang, "gleam_stdlib", "percent_decode") -@external(javascript, "../gleam_stdlib.mjs", "percent_decode") -fn do_percent_decode(a: String) -> Result(String, Nil) - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - _, _, _ -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - _ -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65bc3f63e4d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - gleam@bit_array:base64_encode(Input, Padding). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - gleam@bit_array:base64_decode(Encoded). - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - gleam@bit_array:base64_url_encode(Input, Padding). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl deleted file mode 100644 index ba18dfaabdd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(gleam@bit_array). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_arrays) -> - gleam_stdlib:bit_array_concat(Bit_arrays). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam_stdlib:bit_array_concat([First, Second]). - --spec base64_encode(bitstring(), boolean()) -> binary(). -base64_encode(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_decode(Encoded) -> - Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec base64_url_encode(bitstring(), boolean()) -> binary(). -base64_url_encode(Input, Padding) -> - _pipe = base64_encode(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_url_decode(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - base64_decode(_pipe@2). - --spec base16_encode(bitstring()) -> binary(). -base16_encode(Input) -> - binary:encode_hex(Input). - --spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base16_decode(Input) -> - gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 284c6d46cc3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,66 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). - --spec new() -> gleam@bytes_builder:bytes_builder(). -new() -> - gleam@bytes_builder:new(). - --spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -prepend(To, Prefix) -> - gleam@bytes_builder:prepend(To, Prefix). - --spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -append(To, Suffix) -> - gleam@bytes_builder:append(To, Suffix). - --spec prepend_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -prepend_builder(To, Prefix) -> - gleam@bytes_builder:prepend_builder(To, Prefix). - --spec append_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -prepend_string(To, Prefix) -> - gleam@bytes_builder:prepend_string(To, Prefix). - --spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -append_string(To, Suffix) -> - gleam@bytes_builder:append_string(To, Suffix). - --spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 7dabaa3bbc1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam@bit_array:append(First, Second). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - gleam@bit_array:is_utf8(Bits). - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - gleam@bit_array:to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 5f95f4d8314..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,162 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. - --spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. -lazy_guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence(); - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl deleted file mode 100644 index 2f6dd93a9f3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl +++ /dev/null @@ -1,87 +0,0 @@ --module(gleam@bytes_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). --export_type([bytes_builder/0]). - --opaque bytes_builder() :: {bytes, bitstring()} | - {text, gleam@string_builder:string_builder()} | - {many, list(bytes_builder())}. - --spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -prepend_builder(Second, First) -> - gleam_stdlib:iodata_append(First, Second). - --spec concat(list(bytes_builder())) -> bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec new() -> bytes_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_string(binary()) -> bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). -prepend_string(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append_string(bytes_builder(), binary()) -> bytes_builder(). -append_string(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_array(bitstring()) -> bytes_builder(). -from_bit_array(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). -prepend(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append(bytes_builder(), bitstring()) -> bytes_builder(). -append(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). -concat_bit_arrays(Bits) -> - gleam_stdlib:identity(Bits). - --spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). -to_list(Stack, Acc) -> - case Stack of - [] -> - Acc; - - [[] | Remaining_stack] -> - to_list(Remaining_stack, Acc); - - [[{bytes, Bits} | Rest] | Remaining_stack@1] -> - to_list([Rest | Remaining_stack@1], [Bits | Acc]); - - [[{text, Builder} | Rest@1] | Remaining_stack@2] -> - Bits@1 = gleam_stdlib:identity( - gleam@string_builder:to_string(Builder) - ), - to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); - - [[{many, Builders} | Rest@2] | Remaining_stack@3] -> - to_list([Builders, Rest@2 | Remaining_stack@3], Acc) - end. - --spec to_bit_array(bytes_builder()) -> bitstring(). -to_bit_array(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl deleted file mode 100644 index 99c231e18cc..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@dict). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). --export_type([dict/2]). - --type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. - --spec size(dict(any(), any())) -> integer(). -size(Dict) -> - maps:size(Dict). - --spec to_list(dict(NZ, OA)) -> list({NZ, OA}). -to_list(Dict) -> - maps:to_list(Dict). - --spec from_list(list({OJ, OK})) -> dict(OJ, OK). -from_list(List) -> - maps:from_list(List). - --spec has_key(dict(OT, any()), OT) -> boolean(). -has_key(Dict, Key) -> - maps:is_key(Key, Dict). - --spec new() -> dict(any(), any()). -new() -> - maps:new(). - --spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). -insert(Dict, Key, Value) -> - maps:put(Key, Value, Dict). - --spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). -map_values(Dict, Fun) -> - maps:map(Fun, Dict). - --spec keys(dict(QV, any())) -> list(QV). -keys(Dict) -> - maps:keys(Dict). - --spec values(dict(any(), RG)) -> list(RG). -values(Dict) -> - maps:values(Dict). - --spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). -filter(Dict, Predicate) -> - maps:filter(Predicate, Dict). - --spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). -take(Dict, Desired_keys) -> - maps:with(Desired_keys, Dict). - --spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). -merge(Dict, New_entries) -> - maps:merge(Dict, New_entries). - --spec delete(dict(TF, TG), TF) -> dict(TF, TG). -delete(Dict, Key) -> - maps:remove(Key, Dict). - --spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). -drop(Dict, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Dict; - - [X | Xs] -> - drop(delete(Dict, X), Xs) - end. - --spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). -update(Dict, Key, Fun) -> - _pipe = Dict, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Dict, Key, _pipe@3). - --spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. -fold(Dict, Initial, Fun) -> - _pipe = Dict, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 2c6016f4222..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,808 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). - --type dynamic_() :: any(). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type unknown_tuple() :: any(). - --spec from(any()) -> dynamic_(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic_()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_array(Data) -> - gleam_stdlib:decode_bit_array(Data). - --spec bit_string(dynamic_()) -> {ok, bitstring()} | - {error, list(decode_error())}. -bit_string(Data) -> - bit_array(Data). - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec classify(dynamic_()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - gleam@option:option(DGM)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, - DKT} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((DKX) -> DKY), - fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec result( - fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - list(DGH)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec map_errors( - {ok, DEV} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, DEV} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec decode_string(dynamic_()) -> {ok, binary()} | - {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_array(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_array:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitArray"/utf8>>, - []}]} - end end - ). - --spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec field( - any(), - fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec dict( - fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | - {error, list(decode_error())}). -dict(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@dict:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end - ) - end - ) - end. - --spec map( - fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - dict(Key_type, Value_type). - --spec decode2( - fun((DLB, DLC) -> DLD), - fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((DLH, DLI, DLJ) -> DLK), - fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((DLP, DLQ, DLR, DLS) -> DLT), - fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((DLZ, DMA, DMB, DMC, DMD) -> DME), - fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), - fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), - fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), - fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), - fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index 33b3d4a3e3f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,181 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= +0.0 of - true -> - X; - - _ -> - +0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > +0.0, - case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent - < +0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, +0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. - --spec random(float(), float()) -> float(). -random(Min, Max) -> - (rand:uniform() * (Max - Min)) + Min. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - +0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - +0.0 -> +0.0; - -0.0 -> -0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index c58c0fe151b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(AS) -> AS. -identity(X) -> - X. - --spec constant(AT) -> fun((any()) -> AT). -constant(Value) -> - fun(_) -> Value end. - --spec tap(AV, fun((AV) -> any())) -> AV. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((AX) -> AY), AX) -> AY. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 2a5dd2c8a1d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,332 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. - --spec random(integer(), integer()) -> integer(). -random(Min, Max) -> - _pipe = gleam@float:random(to_float(Min), to_float(Max)), - _pipe@1 = gleam@float:floor(_pipe), - gleam@float:round(_pipe@1). - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec bitwise_and(integer(), integer()) -> integer(). -bitwise_and(X, Y) -> - erlang:'band'(X, Y). - --spec bitwise_not(integer()) -> integer(). -bitwise_not(X) -> - erlang:'bnot'(X). - --spec bitwise_or(integer(), integer()) -> integer(). -bitwise_or(X, Y) -> - erlang:'bor'(X, Y). - --spec bitwise_exclusive_or(integer(), integer()) -> integer(). -bitwise_exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec bitwise_shift_left(integer(), integer()) -> integer(). -bitwise_shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec bitwise_shift_right(integer(), integer()) -> integer(). -bitwise_shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 82865bbafa6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ENH) -> ENH. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index a667ae1ac4b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,744 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. - --opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. - --type step(BSE, BSF) :: {next, BSE, BSF} | done. - --type chunk(BSG, BSH) :: {another_by, - list(BSG), - BSH, - BSG, - fun(() -> action(BSG))} | - {last_by, list(BSG)}. - --type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | - {last, list(BSI)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BSV)) -> iterator(BSV). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BSX) -> iterator(BSX). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BSZ)) -> iterator(BSZ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec do_transform( - fun(() -> action(BTC)), - BTE, - fun((BTE, BTC) -> step(BTF, BTE)) -) -> fun(() -> action(BTF)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BTY)) -> list(BTY). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BUJ), integer()) -> iterator(BUJ). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BUP), integer()) -> iterator(BUP). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec do_map2( - fun(() -> action(BVA)), - fun(() -> action(BVC)), - fun((BVA, BVC) -> BVE) -) -> fun(() -> action(BVE)). -do_map2(Continuation1, Continuation2, Fun) -> - fun() -> case Continuation1() of - stop -> - stop; - - {continue, A, Next_a} -> - case Continuation2() of - stop -> - stop; - - {continue, B, Next_b} -> - {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} - end - end end. - --spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). -map2(Iterator1, Iterator2, Fun) -> - _pipe = do_map2( - erlang:element(2, Iterator1), - erlang:element(2, Iterator2), - Fun - ), - {iterator, _pipe}. - --spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BVY))) -> iterator(BVY). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec concat(list(iterator(BWC))) -> iterator(BWC). -concat(Iterators) -> - flatten(from_list(Iterators)). - --spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec cycle(iterator(BWR)) -> iterator(BWR). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), - BXD})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BXG)) -> iterator({integer(), BXG}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, - BYH})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BZU), BZU) -> iterator(BZU). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), - gleam@dict:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> CBH)) -> iterator(CBH). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec single(CBJ) -> iterator(CBJ). -single(Elem) -> - once(fun() -> Elem end). - --spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(CBT)), - fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), - CBV -) -> CBV. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(CBX), - CBZ, - fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) -) -> CBZ. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(CCB)), - fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), - CCD -) -> {ok, CCD} | {error, CCE}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, - CCL} | - {error, CCM}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). - --spec each(iterator(CDD), fun((CDD) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). -yield(Element, Next) -> - {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index cb6c9e44af2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1136 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(XF)) -> list(XF). -reverse(Xs) -> - lists:reverse(Xs). - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec contains(list(XN), XN) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec first(list(XP)) -> {ok, XP} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@dict:insert(Groups, F(Elem), [Elem]) - end end. - --spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). -map(List, Fun) -> - do_map(List, Fun, []). - --spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). -do_map2(List1, List2, Fun, Acc) -> - case {List1, List2} of - {[], _} -> - reverse(Acc); - - {_, []} -> - reverse(Acc); - - {[A | As_], [B | Bs]} -> - do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) - end. - --spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). -map2(List1, List2, Fun) -> - do_map2(List1, List2, Fun, []). - --spec do_index_map( - list(ABJ), - fun((integer(), ABJ) -> ABL), - integer(), - list(ABL) -) -> list(ABL). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, - list(ABU)} | - {error, ABV}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, - list(ACE)} | - {error, ACF}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(ACL), integer()) -> list(ACL). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(ACS), integer()) -> list(ACS). -take(List, N) -> - do_take(List, N, []). - --spec new() -> list(any()). -new() -> - []. - --spec append(list(ACX), list(ACX)) -> list(ACX). -append(First, Second) -> - lists:append(First, Second). - --spec prepend(list(ADF), ADF) -> list(ADF). -prepend(List, Item) -> - [Item | List]. - --spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). -do_concat(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_concat(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec concat(list(list(ADR))) -> list(ADR). -concat(Lists) -> - do_concat(Lists, []). - --spec flatten(list(list(ADV))) -> list(ADV). -flatten(Lists) -> - do_concat(Lists, []). - --spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - concat(_pipe). - --spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). -group(List, Key) -> - fold(List, gleam@dict:new(), update_group(Key)). - --spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, - list(ABH)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold( - list(AEK), - AEM, - fun((AEM, AEK, integer()) -> AEM), - integer() -) -> AEM. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, - AES} | - {error, AET}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(AGX), AGX) -> list(AGX). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec unique(list(AHE)) -> list(AHE). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(AHH), - list(AHH), - list(AHH), - fun((AHH, AHH) -> gleam@order:order()) -) -> list(AHH). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_down( - integer(), - integer(), - list(AHM), - list(AHM), - list(AHM), - fun((AHM, AHM) -> gleam@order:order()) -) -> list(AHM). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_sort( - list(AHR), - integer(), - fun((AHR, AHR) -> gleam@order:order()), - boolean() -) -> list(AHR). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - [Stop | Acc]; - - gt -> - tail_recursive_range(Start, Stop + 1, [Stop | Acc]); - - lt -> - tail_recursive_range(Start, Stop - 1, [Stop | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(AID, integer()) -> list(AID). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), - list(AIO)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). -key_filter(Keyword_list, Desired_key) -> - filter_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, - {AZQ, list(AZQ)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, - {BAR, list(BAE)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, - {AJV, list(AJT)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AKM), fun((AKM) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | - {error, AKS}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), - list(BBY)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(ALG)) -> list(list(ALG)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - concat(_pipe@5) - end. - --spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(ALQ), integer()) -> list(list(ALQ)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec window_by_2(list(ALU)) -> list({ALU, ALU}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AMU), - integer(), - integer(), - list(AMU), - list(list(AMU)) -) -> list(list(AMU)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec last(list(ANS)) -> {ok, ANS} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec combinations(list(ANW), integer()) -> list(list(ANW)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AOE)) -> list({AOE, AOE}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - concat(_pipe). - --spec transpose(list(list(AOL))) -> list(list(AOL)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - concat(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AOH))) -> list(AOH). -interleave(List) -> - _pipe = transpose(List), - concat(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - [Elem_pair | Enumerable] -> - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec shuffle(list(AOX)) -> list(AOX). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index 9f45b107384..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). - --spec size(gleam@dict:dict(any(), any())) -> integer(). -size(Map) -> - gleam@dict:size(Map). - --spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). -to_list(Map) -> - gleam@dict:to_list(Map). - --spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). -from_list(List) -> - gleam@dict:from_list(List). - --spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). -has_key(Map, Key) -> - gleam@dict:has_key(Map, Key). - --spec new() -> gleam@dict:dict(any(), any()). -new() -> - gleam@dict:new(). - --spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. -get(From, Get) -> - gleam@dict:get(From, Get). - --spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). -insert(Map, Key, Value) -> - gleam@dict:insert(Map, Key, Value). - --spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). -map_values(Map, Fun) -> - gleam@dict:map_values(Map, Fun). - --spec keys(gleam@dict:dict(FED, any())) -> list(FED). -keys(Map) -> - gleam@dict:keys(Map). - --spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). -values(Map) -> - gleam@dict:values(Map). - --spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). -filter(Map, Predicate) -> - gleam@dict:filter(Map, Predicate). - --spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). -take(Map, Desired_keys) -> - gleam@dict:take(Map, Desired_keys). - --spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). -merge(Map, New_entries) -> - gleam@dict:merge(Map, New_entries). - --spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). -delete(Map, Key) -> - gleam@dict:delete(Map, Key). - --spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). -drop(Map, Disallowed_keys) -> - gleam@dict:drop(Map, Disallowed_keys). - --spec update( - gleam@dict:dict(FFB, FFC), - FFB, - fun((gleam@option:option(FFC)) -> FFC) -) -> gleam@dict:dict(FFB, FFC). -update(Map, Key, Fun) -> - gleam@dict:update(Map, Key, Fun). - --spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. -fold(Map, Initial, Fun) -> - gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 812aa1fe854..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). --export_type([option/1]). - --type option(IY) :: {some, IY} | none. - --spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(JF))) -> option(list(JF)). -all(List) -> - do_all(List, []). - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, JU} | {error, any()}) -> option(JU). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(JZ), JZ) -> JZ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(KD), fun((KD) -> KF)) -> option(KF). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(KH))) -> option(KH). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(KQ), option(KQ)) -> option(KQ). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_values(list(option(KY)), list(KY)) -> list(KY). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(LD))) -> list(LD). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index a9eed8f39c1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec negate(order()) -> order(). -negate(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. - --spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). -reverse(Orderer) -> - fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2452a9817e1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({IJ, any()}) -> IJ. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), IM}) -> IM. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({IN, IO}) -> {IO, IN}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(IV, IW) -> {IV, IW}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index faec6923a14..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(EYN)) -> queue(EYN). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(EYQ)) -> list(EYQ). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EYX), EYX) -> queue(EYX). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EZA), EZA) -> queue(EZA). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec reverse(queue(EZN)) -> queue(EZN). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec check_equal( - list(EZQ), - list(EZQ), - list(EZQ), - list(EZQ), - fun((EZQ, EZQ) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EZY), queue(EZY)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index 2d1c5fc870e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([regex/0, match/0, compile_error/0, options/0]). - --type regex() :: any(). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index c80a7048303..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | - {error, BIK}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | - {error, BIU}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | - {error, BIY}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, - BJJ} | - {error, BJG}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, - BJS} | - {error, BJP}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | - {error, BKT}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, - BLA} | - {error, BLB}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), - list(BLY)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. -partition(Results) -> - do_partition(Results, [], []). - --spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BMT} | {error, any()})) -> list(BMT). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BMZ} | {error, BNA}, - fun((BNA) -> {ok, BMZ} | {error, BND}) -) -> {ok, BMZ} | {error, BND}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index 3374ebc293f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@dict:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@dict:size(erlang:element(2, Set)). - --spec insert(set(EOQ), EOQ) -> set(EOQ). -insert(Set, Member) -> - {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOT), EOT) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@dict:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EOV), EOV) -> set(EOV). -delete(Set, Member) -> - {set, gleam@dict:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOY)) -> list(EOY). -to_list(Set) -> - gleam@dict:keys(erlang:element(2, Set)). - --spec from_list(list(EPB)) -> set(EPB). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@dict:new(), - fun(M, K) -> gleam@dict:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. -fold(Set, Initial, Reducer) -> - gleam@dict:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). -filter(Set, Predicate) -> - {set, - gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. - --spec drop(set(EPK), list(EPK)) -> set(EPK). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPO), list(EPO)) -> set(EPO). -take(Set, Desired) -> - {set, gleam@dict:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. -order(First, Second) -> - case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPX), set(EPX)) -> set(EPX). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EQB), set(EQB)) -> set(EQB). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 6cba31d1895..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,352 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - gleam_stdlib:crop_string(String, Substring). - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - gleam_stdlib:contains_string(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_join(list(binary()), binary()) -> binary(). -do_join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - do_join(Strings, Separator). - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_array, Acc) -> - case Bit_array of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - _ -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 693e840f370..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([string_builder/0, direction/0]). - --type string_builder() :: any(). - --type direction() :: all. - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index a36df375281..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,252 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {_, _, _} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(ETW)) -> list(ETW). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - _ -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index 76aa1ea673c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,31 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.33.1"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_array, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@bytes_builder, - gleam@dict, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index c6ea1257110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,529 +0,0 @@ --module(gleam_stdlib). - --export([ - map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, - parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, - wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, - bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, - println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, - int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1 -]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - --define(is_lowercase_char(X), (X > 96 andalso X < 123)). --define(is_underscore_char(X), (X == 95)). --define(is_digit_char(X), (X > 47 andalso X < 58)). - -uppercase(X) -> X - 32. - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_array_concat(BitArrays) -> - list_to_bitstring(BitArrays). - -bit_array_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_array_int_to_u32(_) -> - {error, nil}. - -bit_array_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_array_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:_ -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(nil) -> - "Nil"; -inspect(Data) when is_map(Data) -> - Fields = [ - [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] - || {Key, Value} <- maps:to_list(Data) - ], - ["dict.from_list([", lists:join(", ", Fields), "])"]; -inspect(Atom) when is_atom(Atom) -> - Binary = erlang:atom_to_binary(Atom), - case inspect_maybe_gleam_atom(Binary, none, <<>>) of - {ok, Inspected} -> Inspected; - {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] - end; -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(Bits) when is_bitstring(Bits) -> - inspect_bit_array(Bits); -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - - -inspect_maybe_gleam_atom(<<>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc) - when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, $_, Acc); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); -inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> - {ok, Acc}; -inspect_maybe_gleam_atom(A, B, C) -> - erlang:display({A, B, C}), - throw({gleam_error, A, B, C}). - -inspect_list([]) -> - {proper, []}; -inspect_list([First]) -> - {proper, [inspect(First)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_bit_array(Bits) -> - Text = inspect_bit_array(Bits, <<"<<">>), - <<Text/binary, ">>">>. - -inspect_bit_array(<<>>, Acc) -> - Acc; -inspect_bit_array(<<X, Rest/bitstring>>, Acc) -> - inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); -inspect_bit_array(Rest, Acc) -> - Size = bit_size(Rest), - <<X:Size>> = Rest, - X1 = erlang:integer_to_binary(X), - Size1 = erlang:integer_to_binary(Size), - Segment = <<X1/binary, ":size(", Size1/binary, ")">>, - inspect_bit_array(<<>>, append_segment(Acc, Segment)). - -append_segment(<<"<<">>, Segment) -> - <<"<<", Segment/binary>>; -append_segment(Acc, Segment) -> - <<Acc/binary, ", ", Segment/binary>>. - - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<First/utf8, Rest/binary>> -> - Escaped = case First of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). - -utf_codepoint_list_to_string(List) -> - case unicode:characters_to_binary(List) of - {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); - Binary -> Binary - end. - -crop_string(String, Prefix) -> - case string:find(String, Prefix) of - nomatch -> String; - New -> New - end. - -contains_string(String, Substring) -> - is_bitstring(string:find(String, Substring)). - -base16_decode(String) -> - try - {ok, binary:decode_hex(String)} - catch - _:_ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 45c28cfc87b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,878 +0,0 @@ -import { - BitArray, - Error, - List, - Ok, - Result, - UtfCodepoint, - stringBits, - toBitArray, - NonEmpty, - CustomType, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import Dict from "./dict.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - const iterator = graphemes_iterator(string); - if (iterator) { - return List.fromArray(Array.from(iterator).map((item) => item.segment)); - } else { - return List.fromArray(string.match(/./gsu)); - } -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs, separator) { - const iterator = xs[Symbol.iterator](); - let result = iterator.next().value || ""; - let current = iterator.next(); - while (!current.done) { - result = result + separator + current.value; - current = iterator.next(); - } - return result; -} - -export function concat(xs) { - let result = ""; - for (const x of xs) { - result = result + x; - } - return result; -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function contains_string(haystack, needle) { - return haystack.indexOf(needle) >= 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_array_from_string(string) { - return toBitArray([stringBits(string)]); -} - -export function bit_array_concat(bit_arrays) { - return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_array_to_string(bit_array) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_array.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_array_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitArray(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return Dict.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_array) { - const aBytes = bit_array.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitArray(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (data instanceof Result) { - return "Result"; - } else if (data instanceof List) { - return "List"; - } else if (data instanceof BitArray) { - return "BitArray"; - } else if (data instanceof Dict) { - return "Map"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_array(data) { - if (data instanceof BitArray) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitArray(data)); - } - return decoder_error("BitArray", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - const list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!(data instanceof List)) return; - - const elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (!(current instanceof NonEmpty)) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && !(current instanceof NonEmpty)) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return data instanceof List ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return data instanceof Result ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof Dict) { - return new Ok(Dict.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(Dict.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof Dict || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} - -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function bitwise_and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function bitwise_not(x) { - return Number(~BigInt(x)); -} - -export function bitwise_or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function bitwise_exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function bitwise_shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function bitwise_shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} - -export function inspect(v) { - const t = typeof v; - if (v === true) return "True"; - if (v === false) return "False"; - if (v === null) return "//js(null)"; - if (v === undefined) return "Nil"; - if (t === "string") return JSON.stringify(v); - if (t === "bigint" || t === "number") return v.toString(); - if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; - if (v instanceof List) return inspectList(v); - if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); - if (v instanceof BitArray) return inspectBitArray(v); - if (v instanceof CustomType) return inspectCustomType(v); - if (v instanceof Dict) return inspectDict(v); - if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; - if (v instanceof RegExp) return `//js(${v})`; - if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; - if (v instanceof Function) { - const args = []; - for (const i of Array(v.length).keys()) - args.push(String.fromCharCode(i + 97)); - return `//fn(${args.join(", ")}) { ... }`; - } - return inspectObject(v); -} - -function inspectDict(map) { - let body = "dict.from_list(["; - let first = true; - map.forEach((value, key) => { - if (!first) body = body + ", "; - body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; - first = false; - }); - return body + "])"; -} - -function inspectObject(v) { - const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; - const props = []; - for (const k of Object.keys(v)) { - props.push(`${inspect(k)}: ${inspect(v[k])}`); - } - const body = props.length ? " " + props.join(", ") + " " : ""; - const head = name === "Object" ? "" : name + " "; - return `//js(${head}{${body}})`; -} - -function inspectCustomType(record) { - const props = Object.keys(record) - .map((label) => { - const value = inspect(record[label]); - return isNaN(parseInt(label)) ? `${label}: ${value}` : value; - }) - .join(", "); - return props - ? `${record.constructor.name}(${props})` - : record.constructor.name; -} - -export function inspectList(list) { - return `[${list.toArray().map(inspect).join(", ")}]`; -} - -export function inspectBitArray(bits) { - return `<<${Array.from(bits.buffer).join(", ")}>>`; -} - -export function inspectUtfCodepoint(codepoint) { - return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; -} - -export function base16_encode(bit_array) { - let result = ""; - for (const byte of bit_array.buffer) { - result += byte.toString(16).padStart(2, "0").toUpperCase(); - } - return result; -} - -export function base16_decode(string) { - const bytes = new Uint8Array(string.length / 2); - for (let i = 0; i < string.length; i += 2) { - const a = parseInt(string[i], 16); - const b = parseInt(string[i + 1], 16); - if (isNaN(a) || isNaN(b)) return new Error(Nil); - bytes[i / 2] = a * 16 + b; - } - return new Ok(new BitArray(bytes)); -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE deleted file mode 100644 index c7967c32d6f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2021, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md deleted file mode 100644 index 3ca1c63e98d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# gleeunit - -Gleam bindings to the Erlang EUnit test framework. - -A custom test runner is included for when compiled to JavaScript running on -either NodeJS or Deno. - -Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). - -## Usage - -Add this package to your Gleam project. - -```sh -gleam add gleeunit --dev -``` - -And then call the `gleeunit.main` function from your test main function. - -```gleam -// In test/yourapp_test.gleam -import gleeunit - -pub fn main() { - gleeunit.main() -} -``` - -Now any public function with a name ending in `_test` in the `test` directory -will be found and run as a test. - -```gleam -pub fn the_universe_test() { - let assert 1 = 1 -} -``` - -Run the tests by entering `gleam test` in the command line. - -### Deno - -If using the Deno JavaScript runtime, you will need to add the following to your -`gleam.toml`. - -```toml -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] -``` diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache deleted file mode 100644 index 586f1012e4134ddac35bb64f7e3e8fb5b2db969d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1223 zcmc(f-%8^^6vpSwG)%it+Cy0}3(_b^m$Il^ix=K#3+{p}uCapPO`DoQQ_}|W=fd~# z!Uyp|_GX_Wdy-UBgO>GX_hvXVb8<M}Z@!bA792{{FL6`i=J&=?Ng_@fy;7@jSCa9y ztE}nv*kU43*=87otY*8;_>lMN9M_Ib14KiE<3SlHsPf66&MEjPCWBQ0B3832&sKX~ z#u$M4g$wf@w6Czi<5MagC?k@zjK&o1b%$B@$Z%#xctgkY2Aptc`Mz~GGNzs#xr*+C zP)W<)0$>a)7v>Kx7&FVX0yTx}9bA_b>TT3JsLQzTguSE!wb4wAo^ny^d!GBeqwLB) zRytUb2ZPXeX4lVG8gRr!DIi{=LF<P_T^X4<CdTphKDJd+_2UxNS@yeCZ=0V})umMR zTg~UXE)LFA5V>Kd>lIiVOJK<pCugN4Bnm(lBo~0}wqOKt<h#QphwMWyJ@-ONrJsAD zyx@hW4{Y_9WXKNWvBVGmnat#+Ri1=o%8PIw_-~%VNxc68PC6({;Jj;Cayb8DSY9EJ z%PSK21#6ssCuNS+Hda?q-$#8V9ZuBRsC8=Rex#b;EH_Yd2c!0h&c)B$=8^AvejWY* DT17G` diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache_meta deleted file mode 100644 index d03bd4e27eedf3cf7c1040715866556930eeee16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache deleted file mode 100644 index 9c2b842a84992053ebb351c077d0fcde43d77669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4962 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 Ic*Fqu7vZABoB#j- diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta deleted file mode 100644 index 09e2f8acc9336bce7885613638b9b2af3ff95002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd;&v`S@w0Y)f;2TG^sq$cL-7nc-e=B0~Ie!%wp&?033h=d8> diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache deleted file mode 100644 index 6c81f153248d383a02df47ba397294ba9f23d5dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4184 zcmd^CO=}xh6n%F_qtPfHs~6)Gg#^jQ#vim*E4NTYi(-Kb35I$+E-s}YYof6`sw}B* zMzr>(#bnVg3PsC6HiAM36jGW+7wx*6_Aj&)0{IKsP49d;mLdgPnN<T~bb0!icg{Wc zoOy5F6|c*f?cvI+`2FLVYtu5$HfFNZOEcQE>>f1D+F`-4z^NKtt64XJ2WwT^VVQc< zGS(9UN}p&cNVpZtsd!&vqR9cYtAdCdGD<yE)1&@~38*ws?c=QMR*oFgrXRBm-6On3 z!8ih1^=~ZG>XsnVYyDjT4@+7T#F-jY^gW>BBcY`42vlr{cl1q>iuV)q`g;i~{!MWG zkyrdI9qSJzZzZ{{KT1;ZlYFc{kg51FW$5=(RD7Xu-BGBp(tW*?rsBq>6Mgd%71^m1 z{pu8m<yxm>w(10LK@hcvAiV|m!QCR7Y%|}L=;C~4=J!J0JX9fZd@q04u6LVe-fG!S z#;n!f0ALK2UF~B*WK2uZ74TXE=lZxJQ#p4N7mK)fZgM>S*Ez2pF~)NK28b^DpNo<# zfq+=j@&KszFb|075cTLTuDv60;p+}JUkYL>1H?qI$1w99`~l@#?bfZD6DsCG42mge zJHBEPL3>wGDWX!yY+AMx^j!--x!`n7q!p6KkX8b`V;K2cnoYXFH>w6$4*3YTTH=8n z@^dd1em2j?&rMW|sM3JNH8@1Z9c`HgXSRpSfZ6m&sAH)4Ci#0(Zkb<(Ow?mwLiSyS zP38jx1Lp_S?(J^O<}<JYuG6j>UQ1cdYwAG=<l7j46tuU`wsZnvKd;x42bF6J-dhhB zsD0^SEMs6VDW58C5D8U-mHmkHvd;^L-(tYMtL^!?pAClwF81;D3xvb@5_TdFpu9Ma z*xT~i8>VC=eGFg=fYJt*)>8tiC7hzjxkA^n-QC}}zM^b*+KjE;6`zQ%K>(_@b<DsF z3BDZz!7nbXdEb6z`9>>rUz#>wP}>nDfuPRpe<T~i+Mmi3#SL?`%F4boMne=wZtRA+ z@vN9iI9J5EbBn30`}3W9(T9vv(F6<)Lmxv^C-F<d-RJE?FFTn0)M(<-!}3|9DFw}q z1u&V5F(`=v5M$65<f<Gw%#gAEFEue_!=aHx$j6YhEH$K4NdPJ0^w1Dm#SigY1xNM1 zcXSD6q0(hJ?|c-UU2F%u2=w;hA896wVBbgjgHIHZXa-=8;pHz`O$EGAE<^CFbwIZ3 z=Tkhn{My-Zd0xm)lq@teCnIKt(1;P5=!p9Cgvx}q+o@kur&bEV(UnKQU#egpqA&7T zG2&z-eg6nc;&s6f<yBNKW446Z%b7~M-9%{>rDA4>cg@@fwWe*Bw@tg-bWplN>*9x> L=QcQR^H<<MKB2tC diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache_meta deleted file mode 100644 index b59a80e2912f11ad19fd2dd2d30e22bb976c9293..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84 zcmX^5A|sUn2AH4>VJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache deleted file mode 100644 index 3657f591620fbb1984bcdfb66fd54bb8557a179c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1934 zcmb`IUvJV-7>Cb$N>f-y@C~wr#f6SQ=7<wlTr|C55N9%+x`N4WOjv<3yLEK7B|2lW zc+02Qg<rutulxpHdgGnR_9^i64+~^<b72>pye&EHd4A`4PamDbx`62cE(^H)A^B1e zFtwlD6qb@-1Yx*mXzF3HrGwM79ZT=+5#rxtmn6|K^wv79+@rWAE02LoZh+i)2CT@_ zR^vWp#W|H4XKtZIs*O&B6^nemk>gqMhZSe6D62<DTCW43<S3_n1%4F<Fx+Nuwl%TO zv%z_%iMykvI8D{E)Z<<8(CqXLP1Jj~qp6*Tga8nNu^nZba)c;RHUcixa8bfVftBeR zE=af_46C|RaUVel$#_p?6GCsYNwFHnC5(qp;(;Q{iU@%50d4`}OaK!S8~|*yA4OQI zL@CDSah6S!*~mF2A!WPY?dl%^N<Sb<%WbpQR-GV|(`hp)DqCJA5igTi0b>%ziis`V zcKigC;Ge5#uTO&oaFK@SrQu_Qq`{T;Bd3vJ*D?=Xvxval3TQu1PkVoyR`zIxa>En& zV#ogrr={fB=HdWzfT@|u<%Ut=x8E7t(A%2NQio|-P87pqne}#VwT5dFuDLd^WN}5p z6}QZ1F)v|0+)-h(7wj>!eB#0lz|Ur<T-WTrF>>K@=VUQ0Vfr60c%>T`p|W;Hltvx# z)^)(oBP6V#AvlC5m060Z0^VgI`{O*T6RsSDBpmfX1IoGGP&%T&=!tGO`%d@i?dkGh zT$k%wz;7NQQ8mqRZiZSNaf>eZXqh48T<Hb(o*TA~9j$5Wp9loHD7T>gjaagNYfNat zyTaEey&qd?C{7vLFmz1+8$n>y$=|27zo^^@=PH|J|L|whr?QxmFm>rb5GF;woWdAj zXbL~MXoP(Z-NU_r@i|P(n4a@ILB4>zlz3zHwajzXu(hD!ke_Gwxz`7o4a+jEJMb4j C2;Lw7 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta deleted file mode 100644 index e7f013d77b779ab53ac19ad95a796aa2567c499e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache deleted file mode 100644 index 5ae07b5b49a7571a716a53505f89508a787320ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7078 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 E4S%Gc*8l(j diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache_meta deleted file mode 100644 index e616ec00377dd7ef4a8bfede2ea0cd223bda2c84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmaz!7?a8X1B_4xH<V7#Nlnbv&o4?zEix6=4Ak0}oeTh-hX}R+ diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache deleted file mode 100644 index c8419964e1483f0ea86901e93565d41bd7fe4fcb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6050 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta deleted file mode 100644 index 701db1ffe1dd588340d9500aba145a8b33520324..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98 zcmd<{vr1)v0cI#e1WKppq$cL-7nc-e=B39cm1gFoq!w|Z$mL`fm++&ABxRPwCl(bY ORz`h4w=v2;suuuDoEL!r diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache deleted file mode 100644 index 1cff4b455788b7653d5f4a93ecb7c07c9ab1a00e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12268 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 RPu)7n6=Po95~(BNe*q9&PX7P^ diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache_meta deleted file mode 100644 index fd97a7e9416a1be0edb048f21be7ab89f3389b23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ocmX@|G$oY*1{k3X9w?ojlbV>TpI=atnV)y~=BAkQ+a_%U0Mz0PzyJUM diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache deleted file mode 100644 index b0e4f1fe8d576f972851f3c8c264f7658c3c7d3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49216 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 B8~FeL diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache_meta deleted file mode 100644 index e0ebbdac5a8ca12ffada134deb381bda9ca0a76d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173 zcmX@|G$oY*2H2qtPAHw8lbV>TpP5&}g(8rXS&Sx<l9^n>gQ6zCpd>Rt4^^xvwYW5= rL<B`$aY<2TUV3~|X=YAJY7sw*TvBF9d}2{iV&%$Nhtz({EiVE9yu2zO diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache deleted file mode 100644 index 0be48509bfa9c8884cb6f5099e056a343fab22be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11377 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta deleted file mode 100644 index 8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache deleted file mode 100644 index 62d17d5507a4009f069cda23c024a55a73932d0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5806 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache_meta deleted file mode 100644 index 8bfae6dc9ba127cf7714d1689d480cfcf6ebdc98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2Wbbd7QGhmnF;_hmjz=0 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache deleted file mode 100644 index 2eb1d05be650276fe78373129226fd3527494c45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18138 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta deleted file mode 100644 index 7c99d5d905225ba7c564dd44324b01b038d7953b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache deleted file mode 100644 index a9d1867658d08f494777bb0f35f85d4e32891791..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2856 zcmcIm&ube;6yDh%mbAn;gQ<&4Ko6Tx*;VXlRZ41%lo*n_rft04K%pi`tL|7{d$qgl zu4+5BNv{pL_|RK(357y??WzAkp{GKRg&uS0q32$lH?u3nN)?lUB+%;V&CHuO-}k<G zd;LhhnWM8C^lFY?{c-xcLXOhi>C?iy)4vsRXKjz!on<$WBq_BUaUxAQp4+-9-zv%U zQ^Wj(DAP~Kn)N+F<3!%DzLC-RP%*3<3L4kc$hxkgF{?eYKttm%?Sb_-H=ay9vVNFA z!_KuVC&!KamzI+!O3`7hZkrJElB}5PM59EPBtj&K7M9H`vLZ>QDl0^m#8)GPQp0?P zKa(5u8L3SEcPWi9kUwljuAjtU*zmRObr~c9#EI=YcH{tyq9B4&oH%GLz@f`L$MxIr z5eER`LqD+(mUJEN?XYaM8$-mBZsaou?Cpd_&|-W=$ag_s9Dtj^SGJFS=*H-AeF)u< zd9Kf59&3IcZXej4&|~<g*=!21b*O<jeQ9ppg-*9Kx1huFGF+>{>T1tbtLf0Q#nPbx z?(UT;3;oqc!Co0ECprlCuvKm+459=)H%@pKTa_{x_qlak6V9cM9hSEJ(!l~8!2!Gn z6*$50VqB#B>bZ+xh`H%Owu~}VG4j^?W%%H}Ugw9`b%|6T=YPpR6aadD#(wi9_DenX zB|-};v|!Leu5Kj=db=n9+{6huG?xzLK6AakUlhuk*-Q(iiG}h&?QJ($Dqloy!eY2= zV}<b01GN%#ldzkV!45;_iz>0fXZxI2J}<!%LH~seyTMX+%>UDz(yjw$eh!*>bzMDk zf`(XzVi3|8IXH%Sg@dz8Z{Sleip^4F`oiZz+$8v+<n3FkOtlrNl6nf0Bvrp9Ka+Ib zxCk`NBqcCG0-tK<lgw@^$mo0P0{S>TA8*59(1m^5Pq-05$}A@lH7gE}vJHF`aty(~ zk19ZlW5%GFvDbVpmM`WQt3M~ozw*x%Im-e!q@uWz#sy+z?jVSCgYJ+DeX72^?NBw) zp>T>cM<j-Z2qxePgYd=8cU}^GxT-&Ce`;J3X|rf#$c;-HkqI2JUAl@-eK=sRE0R{> zap8rS>*=wvsquC<a!t2}B#t{uIqZ0ErtLe5uk_O<o}cACrn_jAfVU@3CsN9KCm)xv zTIO*otYZ|`AKKuiLuEDdYFUlul1gbBdR6g`-Rni^w4vfdF{b@UbZUGVBh^#+SGivc zlH&Q}D&Mt%mh>=F`I{B)@9MuQzOd$HI=M(EXXxw-ot>Fl3j&X7i&QhF?nPZzykmPY YtAEbou9r~l9rP=A_lmdqo8e{h9N?G1z5oCK diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta deleted file mode 100644 index 48ca73e0ee43502e40d1b8b70f34ddf19d858229..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache deleted file mode 100644 index 15bdf1d6fc3e94574986445cf04af8d55763504a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37904 zcmd6QeQX@(ncvPVX-aF!)Oan$maS+^+3|{|L~>WME!q|>TJl+pEO|*ev?=?zOL9oA zwA`ilLlSv$<T%N}Fk&<{f;Q(1id>N*sp}R&8nk!56flgmaE&YOPEGF$_fWWQuFd&+ zxWvsLMlLP;d!F}WK6kl8%S8;&YL_$f&inCv{GN~ZncI_HeOq=UXL=s$v2Izj?wrc~ z++6HVPu!QZtn=yqBgym!Bgyr}vQu0hEHx6NPOaFe*2EuX>WxJ2e7Q7x>?YH?b2^_f zx~$(B&wtbCN^du^liLh@`8{J~@>}#}yV*av%{02!CrfM2{KHGlM6z-rk;va{CawIS z)xBnIO@*G5Fs-fA*7h~a8uZ;4x-j2mCJi%@RR6A@Y>1vF5(&fD_#xx+A)eb>Ji{;& zrg#c{+lztdVHBs@3?pl8U9+}Ni5tRgZ=wEU1UQT&o)GvwdTg#ys#fHDJ=Si%M)*O4 z@{aJ6c&3alJqmp5ooqNOa+=x>qF)SxuMf8@`rOT9xK58j|9<#M!%Y8kb7b;$3^Co^ z)j!$Qg)cj=8=Ji8I(!-K8JisH!Iyu(r8fCTTj-k9^yHQlzWlfA$0pyq-bh*>7}hV1 z^!rI8{UMI?Ta5G?ju*BX=~r=lu+2#S635sMBR!2{_C}n?adjuo;h4A;f1~5mM!JS$ z#Kzxnr1lx<-8g3N!ryUxf4`A_2glXB@hlv_Jcw%sjr40-BmEYR8}BpH{W#veAMN7k zJBqe&ygO>7&7_(B0RO&potfUf)lB!}cz2tb{t!oPhnao>$E#^G{Thymoo0F#$JJZR z^!qqoxYbO*g5&C5w1H!`&rGl3c<T<F$I*Y6nI6M2-EXGP;}|=DHgNP0;X4j9XQpq& z(Rav9XK~CP#{D?@j^H<r*$43($A_b4I`t5qHHLoR$UbVO$8n@Si$3F+J%j6Typ}i9 zZ{XPd1fGH8l_$;gKgRLKw3&Vf#|yuSztJ&=zvKA6gTCT;^*rvSql{~Dj8)N39Ba?w zS{(1zF+LpQ7x63{FI~p{IBL(KO&on!%=8G3{$w&ej^jgof4@7K?%R?~XL0mjpG=S7 znC(rbYdAi<DVa{~Os36GCDS+J7{4`{p2qRko@Dwej*;7w=?NTTci`_hQki6WH;&nU z+>c}AAnw8O!eBD}3XXSj$@Kd;X79oIdy=DNr?S{s0)uQblljjZ-IkFev64twTL<&U z%_P_oT$M1atuf?CPom4(+GlNrVCd;NS!wKLA^W(Q>^2O`8p%Uyl2H1gF}(f!7TJXm z&#l`JSDTea-L@M`j$LUk&pI``x?nqHXW5~@mnwW_v2@X?*d-|x52jM~*`-q5UT9WW zuGmY(y4|SSjau=dQ>#0C5AHA39DNg=pQDH2FLnKZfs|dZ;xBfsS>dOZOBJVBvm2#l zhaR(UpMBzTae1Ze)bXoODDWs#_EFneUTLgm_S>I7YK!?z*+YCq;JSrcb$O;-sy8y{ zh6n8IfSnt#4?W|%?-1_mEfi8I!+6}lf0ps7V_l}z-EVany;Y1Tk;wIZW#TKn^R+6; zIa<cw_bua8ex8>RA`Hv8XWY6Sx^NI*hx@GItTo)@RVblVkosUt!t^a<OoG7e-G*sd z(33QV?Q7}#3@m<sFLyii&~^L7#bUWxY~1hE?P6u#o-ftsinVzxBuHVQRI4}a(|VnV z5Q;7Z4A?cN(X3TUl|{Q~SDZ^Jz0S01Cl|O8MKAVz70;+t8=#Ymj_p*c&BZ0RX|&6W zshhA%^^|;oGan{4-I^l?AjwUUEXbEepdLOzzfvH*<&|cmNLmoh+bd3Op;}vZ=Iu*M zplt6Abh=ywsS{1Mr$G-z4cLdDA+iKHYKoJ;iE1*<m6=9$#Ln%Pe{58lC{y;iL*iD@ zc7SrZ^-VU4+q@)gTE<<+wwTuTerp>@Ba6>o>SiLbmpf({xu5MFv9HWmXBx!|4g?a> z_<I2wzpQASW!Ijb{B8JyX`Se^PGqeUJ&-*_vYi2ltpQ>e;;@H+OCk}sC8qna{B1(y z-G&jS)KEfnpD=TcTi&|m$^zE7;Z!6$zv&z5V7|;ljVYC5GHi+@cnpc3A_j+SAA|5= z+5Y=r?{~JUk%UINZa*T%_!(kw%@8Et6?4=F?75l)u26ie&-^;Goo2AiIl&_X_Bod7 z&nWI%F0N$sRqBs&#X}6}Q43OmfJXkyfm;r)gB?m0NP@&(7%&$VTYTiBm8tx9nN|qB zl1i6sA@uu+9--f35%l#5Gv@W6qt3VvO*605@-|V@nq}iN6&z=Xk}w}V^;&(MCj(QF zNM3X#<NP=<8PBW905f>?;J9^o%{nsJi5}dRFgv>}9{ZqK9{Y6uZ87$r7{k^ZDc_(% zBL_et{&4F1eJs>iDmLt58KhC6llH9Bxa3GZ(zsN${dfu547jIMwr8u2C7}bMTI_1G z(O$i13JyaTwGtN{m(Fn&NO>3#XBgZt43NVp$JI1+RuDT~MAs14@TD=4Q;WwB4Mje4 zXvhU#sZm043Ti<wd7##%5~1YW^Uc3(lK5UIRpx~zvetmfG-jU4e_Ih*1jh~LpQN*~ zIB2`JX19|}hM7vJx_7KvE$>yZTB^3JWg4RsPQ6){h}$xzq_xfWDnx#|<lg$Y(cMBr z(GWv42X4D~|G&N8GRCe5Iqf`dK(??-{$7CHp4KyA8aKdlmPQ3BW;QC|4xm5NXFP7f zU9!(WyktmxlMIP&)uT|SHKW`VW|UH;gn?o#<yE`5vQjP);&hD%7zRa~pxg$CUrt5_ zB)m|`RQB7yWmoKeJ7+&9=p4W$b2v=$pz$N1zk3Jl`-a=YA_7Off(Ru#%B99Gj9Es1 z??Saa@2<js_N~H|{Odg3fJ`8gVJYb_=R4$r3{MG~>_n>dYR3oNZ5sG3TjKV*4LH{N zCnUgsfB^p54cxnk6`646n{!V6KHrM?tvjCkI@EvJ5ldjtuG(|OGR!bS_AJLz?ot6f zJH<JT-Pt^Z89-tTn4j(gqQ*r*xKR=7FD*5K+l0Bj7UZQ;xeP-B#+HKqveDIQ6ZQjJ z4=_(0yEqHE$$;H~(ZXbd$I(+kU6)GrB{DR<mVs-U*ns?Yy)+LKWMRRXgBdzkt<dk9 z-K06-Rtpf#1$V@yO1<F}*$QcGi+b#UR(PEVh(+~?4QWV3HbPWfoSPd^mJkuNG`#J* zZJYsNr|jV&zsO8l#=Xb3nbyvJ>n6kdDJ@l|Ttm{anfq$`=V>C~$wqYr1T2yLLxO<e z9_<V_z{zKsWLq-E252B>WQrRN(H+Fse&YZH_Ibh;a0yiE2~cQlSwDWVU<4TGBgH^0 zz=nJBL-Yp_{*97_PD}|%9!soSnwO{<)3Bs)Cr4^qA7q*@SI^$M8LI?MFt45uAuZ30 zM9tmZ+rGVx7L54Jl{i22P1sca%RFIzcY~Na=~3!L*4(7k9=>6IcGCPrDKORq{rRs8 zP4Fg!&Ko`4!O#HK?X$uMv<IB(+8i)5v`o=Xqku4JkA*z$9-5g<sd{jw1{hMVfJdNg zHvlkwXRFJ719snI#d5W_O5aXZo27c6a0G>092~R{9JO&%$`)V6jp`TQES?+0GhREJ z6^d{mNxhQ$XTSY7zik=g>kn6f2rEt46ba22`QR!GE0in?L_Q=ZY>FDYXk|NQ^_?d1 z`Z!bW9jyFeBX~L-T6M7ekTDIGM`Wi~g-4;elGr;>J`_E+$$3A|59S|b5{8K#1zL77 zL4Hb&c`E;+m*D%YJ=50hQ<xQ8*L%D)*N|PBFC~(54T;A-CD|QVZm{<hJb-%{%SmtB zE_oL5p{Y$b0Un0|6|klPQxG*<g{41TA}VOqR%b{v2r3X5Z}K7kOkK&p$72t{i(BOE z#DNz#YmrEIo5szOFfd0`K3FT~P+YaU!>feI8=u@k_{3UEp8`IycK3RR8JdlC`xvx% ztyH`pu3>-^nhq#p*jLM?#ifS5P%M>6G@K=`B+ikZ)*__7RBhsN;f%Bk0+*9gZ7w(A z`>58STx+#zZGYjQ_DYJ2fl~x_00=3Zx!}ELe*uncu`W>5fF=0F(4gX6Zm7HbKEt-H zpP(LOWIqB;*P)gfzQ`f)!1>bl;xGbnD4)(j*KAat4>g<&poan-CBO}Gh1d|y@Yt8^ z2Y{sIUu;P6rb7}?%naa2iQB@}_9MkIuE#ksF34Va>N#qTAdB||jJ>3?_BMnrjJ-{X zU~<(jeE0>+7#RhMSSz{UWfG{@8$!AE4wzeGI$&;7Vk$mR0LlU9B@D@Kcrut0?Xkuk z@p&}mJcJks!uQ;%KR87*b*flzjIC;!ix`l1q6YI1D3MFXtgvz;B%?{(4uKFO-n<jt zrl1pfU==!)y@~4YU!D2CXGmF)kq?%hfft(mBf8_0H~E+NO8%!x1hTTw0Flhyr>64k zbi%}aI_ARd(b5oi;{H7}atwQ#5(c!w8$DAa^ehKbhKi{-q!JOg;ghjmKo0~)7c~(_ zF8=F_meJP(e<cPlZG69Vd5y5%UJR9Vt!dyJK5ZIm4Ck{gX|gZ>5u?EL9b|jHvz@vg z8ku$m+~Wm-92lWLIG3S}NscR##S*Yc;loOuECms!QBs~H;fbKtN#RQ8lG_3c>RAyA zs<C^9l!-!}6yJ%kW$DjxL!G~V(Wh1>Cp*C_nagBXUWTJ2%fgvMRIX1DjzD+-?;*zs zx#cJ>O)=0wz{u+vkpa=u`~KlRDV+iBHS6a8!Y6aCy|3<eO~|(s3AgmsMV@FORxyAO z4MVJcIG3Ndj5QKd?C?yC))6<XlRHk@(X9cyFBD)JeK93dAC0Xuz>cPQSZg6m)7R;! z0ggWXPoAbVgd1e8*l;C~Ke#<8gWC`vt@Q?-i6Kt*#S}mLXpq2^Bl*`^{8+C;`t05+ zdmb9wx;<Wn=f*DXvnllN3wgn5<@I_g86+^K*Cq99#OZ-BmkeP=M!CdVZW!bOC`%Z* ze>(Wz2g%t$LEl!(e@${5?g)f?W0DJQmp+IeiRJ$pmjBfh_d8<oTgPnJOSoEc%Dy~@ z!n{*QuF8BtYXhQ&m{|-k6rgdSQkHG<Q}RPZ`a(yJ!!`*7v^s4P2t-IHr$jgja-Ah3 z2uD(bHVhPXY}~GBR3mt;7AS*2WD}?a0_8D3c-!UMEMt0|fgNC7BFVr`U>i8Dy@>Qm z{>KW}fgn7d^Up{`9mll2Q-e9W+cfSZ5fcZ@iQDkWU~YQyxU^!QCo6X1M&F1ci0)MB zf@2pJ9tEH+4B!g^TZXj-*r)7>_kp2L!Vf=S&%!s}tRucsAh~x?VOW7+Vb@mec?WKp zWn@{UDD?&8iiEEkyVr5@g5#`6Oa*)<nc!o)^_l6su6?^CaJlLox%HKA=7?Cr9@ zO3N$NTEk{KAEcoYNtYeC3+xBAiR<`HT*ozUXQ&4bOx{Ce$oi%#;|S-wws&XrCDbo+ z6!`32JeZyxVUP#e&7}w#2w>;G3<aRgdjtkEWExs)Ynd8`hu`a1G;<HFy}4!?vjkSy z+)wm?05wvXJR9V^UntINYf)ul;+DHK6XH%V;aw8PwDK>BtM+$zmEg=-1$3TP$qVj) zLwu<KZR^?ePNT?*GR)lnS$p}nNHGE!c@*P|KIt`>Kg4sWU6`)<kCFGsL^%Bt;q>Rr zLdBJ#;!@q*gV3n7ftB{j6!soT?dDuA&NUDct5&p)W3SYz7ZL87_Xhd2X{5bs?KzKT zBm*ZBSrx-7^s1BDIKs+?gqi!pXaDwDqR2XB?9a?CC3=wSu2F_H0%hWf>Cf|A!q*K= z;7uHfkwAI(#{d}wNZ4dBO^>gbV(?%n0IjSv1b8rsQ49xzv5Y}!RO8Vq%0D{^F9^Fo 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta deleted file mode 100644 index fb52d575e15e87bdb03fca9fb3c0bcfa695274fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache deleted file mode 100644 index 3b60c9cc8ecef600ef12d93823c7681a0177ed00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46259 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache_meta deleted file mode 100644 index 6587875a9ea9dec90101364c1e7d76d5ef2dffcf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120 zcmdo0G9#4%23VmCPAHw8lbV>TpP5&}jUteilb?ttlwXvRTEvB-svt2FO(Z2Vxn%E! Lc~|2ZcNPEuC=VMA diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache deleted file mode 100644 index cc21458a0295aa759f1cded53fa46236b5d63ded..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4737 zcmb_fPi)&%829(=;5tp>y}8}ive7hSfUKdYjSx~US*jKR8mx{d1?AFZi`#ll<0x@9 zm?o72NL-Pa1W1S-IE*XWfj>tMlhA|^64G{<#BmZJfwbeM@%j1LsnaB+DTls3$Dg0x z@Atm%_j}(wNa7!GMy4|*dg|!HgQK8*p8`rRYd@txdsBs{8+EI?o!zbq(DdhPZC6lh zb^BsbA~cpUB#`8{s!agnG!bd1Ok<@5r4s#c6&Gn+>5hbhyJ@8__^a0JOYVjAwo~iW zt+d@}yOvn32|yK{DixY6tIHU`cTlqh@sevy5D|!ge*glBJ{6Y<{ZKbP08vYlB{M;A z@`UK-V{h`8m@)qpaq_j4H*ZNe`6re!|Bm5gT3$4#WSrcX(9KUKaPmaSn~xQod^fpd zemjYi-x3w`UIHgpN;hjMoP3eWYu5;9pQUu|Vhpq!_^ivIeT@HS70^lv&@LxHU3cm= z<R(o-^AJF60g#&g(1ADws_YoQ5K$0}1dc!#bh=QXuauDmN${8uXmQ85?nMlu3`rvx zE+T2T2LBL$34RTK!3B{NN_FEn08N(YJ2=J}jNQ2)2mq@97zwWy6NFCdbP9Hl>UzuB z22h<VRtvXv)pj?5<nB+tl-Sv<w%4|-_k322+hdbbHZ~b4m=j3K37wv((0PxPm_P>d zfbTHk89`!Mwn!COU2>fI9Lva6BF2DFx)gvv?tu?B9Kla=1#*$7h@*XAAX(!)10pdX z|CRk9GYAu12wC;4-FAHl1}=gCF(!uR*F8ptgl)G6#t+hcNp4tIIg0nkJ`UL{M?pXi zM<`)X7>GEIxXVn0Z*Mofn<RHgp=Q-B*W&y9ee8V>Oq<CeX@l>O)dc5!m^eWYiU)wH zln<c2?xhmP5JAT)iBNd4I6-JqrwI(r<H%}A5JKR&7vg8*@`mMd4j%sh93+QufbWol zl*d7yDp)$@Ldj}(>Otl)ZT8=1*n3%i+wQ5Xo|8r_5iUq>N?aD_wyo9%KWOvV_^Mep zZnC<H3It|nQK!WUT^VRFpfae3hL90N_&PE)A%ajpAr>PE;X{pZ&_5r%tOzvKZn%yh z<i1qyC~B?cc;1WtQaT7x9}OmIkruN9<&-j_4kJ-}B#4euEaCU8SVGfb#lo<SN{!D0 zubA9d@q6(?r&+58dSNb)&(4l<m$9?Qd^H5m%r|Si>qQJ?$qOVfh33m89_!~aO=b({ zny&3MI7X)_sNN%&a13W3jgVpC`pmjR$zj&bY3RpeXx_8Tyz`-ji*^HLC*UtI@BHNT z$sN~OtE1T*ScUiLdDD!HBSSn7`A0<(z`qni@PTiGJ%-LfL^vV26>#9`cD1>7rCRR@ zqQ#BfOpl*BW#d+#!t#@b`_RCoIm#d(!=&+rHGIabm>H$E{10Zln*bV7#XuaCmgrd= z;}M(@9(v_xmf4XfKP)T!WPseu(wd~Y)h#a5+BX2>-EHv>eb^(UfDM4va@Dqd%_?{& zV6_YDcHOmF6w2&s(Y@nw2_LFVvy8rH`zaH?8u6AAF0u--ehTFgFqFNekiDHP%WB$< z4ZIV3S7X%ggmOk%1(BE1qp{7LU;Xzs2gex&Cx*CK5HW(r1fiHs*dFv~jDL3hm<Tnd zt1fgpgG$5C8;I)LnY`|_0CJy;KZ{*bZjMdLKK11}M%A2GR>9rnjRwEiu&!Y5UD`|3 z2x3AXJnC+J{Jv(NTTipC&kvDC0`t5b2#<}m1H8<lAaW<=6*+`qo<4~9-5y)~G7Qwo zQ2c^tKT-F#ZKJdt!5Y3EhE(_$b6;vARP<LuucDa}b_+W9sr;)<q4d-%Y|kDAa6<-- z@jI0)Z*aSPAp+mi?DZJm^NhJuqZmXG>U(4<Fo-lWh+SABtdQJ~@DM1-XLfZg$s=?o rPiKy>UYf>q8e3G)w>s9`Yt?$&;%x$r&EoIkxvjaCR?9(Imk+_eGLq}A diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta deleted file mode 100644 index 0b52486cfc5f05044b9b56a9fe4cd784dca2c15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache deleted file mode 100644 index c6e2cffcfb0cfe07a04e05fe48d595584a3bab4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7261 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 NB%?)ubC!OM{SS_5Wpn@l diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta deleted file mode 100644 index 8b36f47ca8f554f7005ebbf3285be4ae7326420d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache deleted file mode 100644 index 35d8d06fca9acd52e4037705e4606d9f169c2f46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2704 zcmd6p-*4Mg6vuu2BVMdk;VSC721;+cP3kJQYm=dE5u$5Yh$dB9y;S01OpBA;B?iY% zu5a274RzuXfslCN5y4-95c~m1@E^cCJnU~6$M-q~TdYB4nkFUI_4T>;9)Hd`-{XzG zdeg-7ZG34CKl-}(=b1T-KP)cguN6PZo6mYabq7~MrkGvI<lTdaD}}D_wYPN@8)ZjF z`r;i1j}dats~WyxVxx`oR(h?X;(QtB+jz#5*6GK)ss_L9iz==!JGYQltfN}<7J`AN zR-1hl1|zN19BMH5U8^>KiwD2zrRFa>3~m_9&Fe-y$km$Hb1?YHEH!^Lk!B9uL-6aY zsyUw{10zdO5K<JJf8T-g6va6MSA-YJc%hA#Oc>6WV;Bq1^YS^)!@?=AXCM{hWoHi| zJk!Q|XmjQ>;a!@;Gjf;mF$<y@!uyo?F6+^Vlkg$o2O$Y#%n|8%`!s;(E+?%9C-0E@ z2rfIkwQgDD!Ua-4bO%G9MsU|^wL}OlFaQ)Q^^pyRmn~Q#9$J>7R$e!1#!)963|&TF zAy_r%0}1O8V3qWVhgo3nO2-S4K-3bc*dqI`Kc+AR&;m-_AOxJuCPNl>#~m-|5tjt? zfF$N8gG<l|cn2QuS0%y*7YH@WLTDEuh%cHGHL;3yREP}`s+jsUeJh|nmrv04Q+asB zu|*#0A`hqJ(0|D?gmKk*BEdZYaG&Oq<Fnju2m6%qXdd9m#Ii{g5=fh94N@y0Z3^!V z2z!iz^Gr^<K{qvF9h)65Jej3Lu_AIX0hmeC#G*d>XO^ZC`Cs>d!mj*`o+53BCpm0O z&{Ks6gJ|KBLx9;uC}WVQHf)l`wIjhOrW;rghcCX|;^6}?m>kyqe^Ff)@?n~{1HLE< z7SzcAhai@|jHM5;Ts4wIv(D{`w5G)<PV4c2GOt4z9WolxfV<oaA;cgdpeRB@P7aZL zFBzh>%|s?r0Z1%Fh&E0zXv9hr?@(y9Kxt6L(ris@OqiWMKp(><Sq2T6r^;5Wj3P$g z|6mTh;1yD|l>C1M^6v%Nw@Ar<G;n>Ws~4sJUhud6??~~opd+HnZ0_yc5u>07(L|;G z$mFv>QK?D$+z=DcK9Q=#e`8t$JoQ3R2Q}xhtb@mKGdT7(i!Twixnog_rT*bK=)^Vf zQUuQTBEBAljIZ3=w8>jGxq9Cw?MGFpN5OXmG-EyKD3_r;?!_iH*}Ok#CJ>K~`JJiN zN2k-VH-Hn7I#z>C(u9tn@sC|UR<Lirl^<|$l^-<@^dNjG{sx-ThHk3cXH`7Aif7N^ zr7B)Jhu6w@?ae|h41H{@!bf3YkB#Z#d#)eRt-CZD`y3l3nAh%nv{+{>Wb#CuFUcS1 LEw~Cr{TliUU~H-r diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta deleted file mode 100644 index 2395015401100f34736675fe98225d853098d534..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache deleted file mode 100644 index a4cfdb824fecc15d2d2a334101ddf6014065c30a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1880 zcmb`I&ubGw6vy|?X1jH5h-0AGg7nc+nntZA(M!R$3Q7^dZc`8fV%F}oUEOX%c4I5* zz5jsV!9y<|{5L!)=*63&;91m@ColEQ>?TdxMO3^@=I5JvpZ&gXkS&;eq{b&rKDnNM zVVa!Z%|AD%@}Ep|Z`~Kp=GmsB>0T=y+zulx=lb5A1$OBK<7aC2IneWOVZ8bVsPm1L zt6v#)UhBo`E1f#;Gt1SF8S1nLW~<Qv=zE(^^L8j!8=4-t0QL~m?ayFvurv)o)A*5_ z_72lE%^qYFfF@4fqy@Qh;jF#bU16FIjHa2Lp?#`HEz{_B6+{CSAl^pP1~ATRb`yYp z_%kSR%jkPcf3~<RqIN3?^XOn8wy^1VE!^^=4U9Gf%J&B@3SVrBAi@pjz89?1kBfD= zr;bju>3hP(s9~WO%~%#rOyHGmXS3;xkVf@-UBR_*4krqw(^#IyM|0R=6S#%7pb$*s zLkzHpWqdqM5#+w})S<(cqP0X^7>B7#gN$d3d<b}Ul-itp1AUIhnx<98GPg1&WssoW zIe_}yK2QQj03mY-;r@bxIBstf#B7akLn-^tkipa04X3hO_wI|JgD#xGl?^Y%RVP5l z4;y$#pxX!pwnIr&vUY{*tvZo#Eesz7k+Y3n5JtjrXR%IKC-5#_>~O5lSSWG7-0kwF zaWC-hsf1}cVTz<dsJO<CF}CKl!YDx&^&#tMP^zw9X<#UR1FEIIA*EKf7h_n91nUEf z1E=G%RJ!Ws4jxLC7)tH^UP9_nArTT~Q&I`*q!QrmC%JITA>FG|+x^pIOqIsqVKK-l z2DGg5E7~MNDTXD=@0zZzN>6VnRSiiAg(%<H6z=cyl$(0eoG6q}W2svatnwYQOck{R zqCw{i{*%AJ5tXRbb(na3^e_=Q#Yj7`$1K~v{O~pYlsx8VruRANV2-DP>DR%3b(mN! zX$C_$sTk&ChXLsG7wIgq%P3<>Os4XKmGt@85C67ah7`AKr&W5I?X8zDEQy>BE-sh@ zUi^m@6QAnQQkhC7r;HUUr{Fr!A6)FJ*<n61%SVQDmm3YA8%1uEb1SX37`sY_CFYk! W*!ClCjMBV*<KEbnR;$rE2EPEr$(yAB diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta deleted file mode 100644 index a2089a5966a154b5dd61585b9e0a71668b274981..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 Wcmb15HB4nd2a#5L@9-R#`vm|lvIQ^z diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache deleted file mode 100644 index 60ddb1de5c626c4ccff9d271c0dfc4241b6a110f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7006 zcmd^EO>7&-72eq;MRE1#F{31QVrVQkC`B-qNTx_&)UoB%O(LX;D5g+l!;qHLNZe?- zOYJT#tBqlxw*ox`0Rpr+C56!hy)-Ct3Q(Yj9)jjjAjckx7Dy4GK!FxWZvoWzW_HP4 zE-BMcFGUZchO;xXGw*%#z3)AqCn@bKay3KG)ag@?(f7a1{b`y|`bO^W(<Jxy3_04h zxY1hN?<g7G;qu$2=PNVYmRVm;sWe@#rbue8+JVP}R3BG0`n^S(uG6d@pR1@eTc+7M zom!Nm<BzK;RU@jRh5whIQ)#PQwTPB`hpg3pMxgNzb*1)C6&efaYqfkD8h6L8)!rO~ z#=kT3wXZVJcz=AQc7Gfif6dlwUu2>2&IC-Kz%f(r*1n#C#%Yb@3h?)fF_QZP{{A+7 zDOb;uoIXi%^OHnwPf@Cqs#g6SNmHUL3L%O@v+LEis=<?S_$2gPfu1YVbBoYiDA0v6 zU09rX#q|6+VYKih$*%NBmY7vl@I<-#Bq8(_A}ps5vK;Phl@Ov*^3COOl}??dlY~yq z!>4B2ijr|UJ|UIAsFT`JyW=%C>qbK%d*CcQ-~GPxy&gRu9Ij5!FA^0_uMT>*JR>|! zjc_DfBn{i7Yt?Ny6Rp#?NQvG^MRyek#SvSD4Rep3GHk{z-r}~;9NTx8-{cI=vB#Vp z(cVY=UDS1UfnC32wAvQ;;LFz5mT-m6o@X~pMOMDW-h7_zxK3-+0zcuG&?0;J$^w4( z9q~w)<BP0vODv=5dY_dG!pitL<2Ox@kQv;VqEtT6ztoS~P8;pKr=WL)p}&q9da-&{ z7#dIy=y~wPfU5x}z9dGjUs>Z`#|mKvSR{Z+dTw3O=*B$VDASD$A{5*vW<BuM!7w%R zs%c5wuBuuZ-LtX=paL)D0DvVrKOH?&znfm<z6XAImNUx$yN0epOZVJUWG?qRu5H@8 z*r|7i8TK|an9UEEa3eb~{U(4G1{vM8(6_IHo!L&uZuq8SGykw{HVn%;WNydym}#?y zV|%^<5b@0xFS0r;abQ{&a~ci9gDK%)7^^eOw7KDmp~vC|wv}H%0L8$vl<X>Xy8_?i zwAc3X7xI8S0W&a%?dQdUMYgoC0M7xTeK<|LPtNMSuz&TXBAPBg%5ssZ*In0f^Wb!` zi45#Q;+s(NnBesSO_3RNAVB*2(?6fS7u<{h&ObdFoHc}VLBKi5nE+=X3c%jA>WA=e zs!l&7rKvxRhg;}J-wTd?o4fwJ2Pl#V0#*nxh`<28Fu>mc%z!OCqs5~G1V*t_XO6qg z-HQM<jywTa3b73MLei1z*LlNf0WV?Cj_F1q9}L5{B_SIE^`WpA2VP0ARFAdF16WH^ zmaZ#mWpQj{?4HZPJRXK;Wc;^I=DE~pT%YQ?@Kfo+Pr-$s>)~D!E_Au!bFUEN0Yo2k z?3%Z^9T*<2xNn#tg|L_-<&DR?jc#$;ZO1cxXb6uc=p*z+j5Guj3=bj6@DZ3c9yvn$ z_r;$PXP1Ud9~iy{zQ0^#;UXYiNabITJUN>IjtBtogBSors8AGO{m}wZS^+gc>3sDW z>DOn#uWu7veuz)g;KCi3d(FUwg4F{*ddzm%ZNutt@1idD`l7a}9hu%HZ?*lyUi7>Z z+w((5&#@leWM-~8PJgHa8HAyZ-iJt6ACJDj|4`rIK6hItP_D-gnjDbk0>a=J7_LHk zfG{QYKb!$hhPu!`5E9)EkXAB^+$<&0)|>TR!}5kq8;G(2GcjTSwEmnK8$W6^d1G&r z?<<*(VM*OwYm=DA{#bjC2*LA+z}ZGY$P`r0yg+%Ga%}Dw=zf{*WAko--YwI+i$Zq) zWWD+kPEIIkl2OzXb_PNT76Q4H8444;8!}ua@RJ7MRGGvN0~G0Td&B_*l>E}{Z)b&; z!uX;P(B}UQeK?L=e`tLuW<6LRjt|m@Yqf6#0`V#e#2=oD9x8t7BNhn6tNr0pP<;2| z{BJ5mnR`Tao9u~bzOFV*Jn8DX;0Z`Hp*y<b5#(KD66O?n`CYsan0|=xiwp|XYyUE% zzgoO%uv{Jbn!#H0isY(ev}X47tEZ8GEoawk5R~k|EFI0T<UOG)pisN{_&usZUXJ$% zE@-JtOLh7!q>tq?U9QvXl0K^I)jLQZ$0V@XW7AuB8qfr^fF`m-Y2u2-?Onea1k-_p zu}acVxuEpj+T(bAX6w0^;QGw|cxK?C`|r^UNVOij9EKkMz>)CqSkt%-qIMrBIMl2n zDZ<MoWRlQ9MGRUl$5;jV7Y;W4LzKlmx$LoR8RKle&FY6;0oENY=pK`}FcnLNIS7Cq zkMDFWW=N3?BAmOBfI$k_1}y-2ydjdfmT}1HoNb#sJFqQ~+dGa6`mJ{=%mqbcjY&Ps z_TmSFO}DwdjoX6Uu<0D&^Fy5-;Aus)bvq58Zx@*-s|VfVIBo74KE&{?%a^wpZb+u7 z%<H&q*YsdX9l9{%29eUAg@!URBI#KRhMH~5l=j1YVnWJ%V-IvJSX3H6C}(u{G03bz zX-A8fc2?*qqWKOXGSa{XQ7EaE^)sKHp=3qK7j!N3t`aSXFCWF?ad0KVLRL`dft&Mm znLb^orDJMzaQlv{1?fXChp7FmR52d_sr3cKjNj<dy$-?p!Z56N0no#4KPr;``aeeI zTnj5?-7=O;^Up$>FR)bk(G$OZf|9i(49Qpn18LGjPk*}qZ6s8z{sCl$=kXJWg$K)v zi6B>8tG*|(@g88KJRaRi0vj^rpTm?t%<LmD5E;J+O%Iv!56k6&q#_yr(853xZy`S< z1^=;yN-R8LQW-i!)GB3g(OE@jb3*ci0RJHMd8+586Q)U%=&yO<vP|Y>JE$;*1;I<z zkHI}qjrkZ-zF%d7SeNun$A)6yQ+PY=POFajQ8c{R-GCycLxNG87&3sPU5IB;wGccn zT?xJ2&?LH(>lbz8chm3I1S7nR&bcr&xtGSxcMYDuc?%WK(xB`rIkqGQmqr|nNfs_% zhVe640R%_>GW%JUk{hxZ4!ck^J97U<EYnXNOU+ZGT}N0%Q1y*ynf{HSOdss5-|MT# z)ahXgmhDF_)Pv$(N`gP8rsMS%sIQ7Sp*6b{Cw~u#RO(?PP@)eC_LbjHq$erKT!mjw zo?V_)>1=_{K1$DDqURqKad29c3TV0jzjDoBradPT=b-#f(`TVydu?w{)KaCoq@)}+ IGN;IY0K=$vTL1t6 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta deleted file mode 100644 index 6ec02d279a3395e477453db0c144ac488b739524..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache deleted file mode 100644 index 343c2a25e00043bb30d972f6b9f5560a0ea10a7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6607 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta deleted file mode 100644 index d6129ae46ca64f4056698206dc7d3f0de91184f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 ncmd<{vr1)v0Y)f;2TG^sq$cL-=NFV@=I0$1IkMi{#QhNfhQkTV diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache deleted file mode 100644 index fc865bb561816657dfeba17ced130ae43f4dfbef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10388 zcmcIqOKcn073HHSQ=+9vW5%+r*w!;0J0h*hCbemVI<}R#AGfJJq5}nS192#gtdaTi z3}suX4W~iSAG+`|EwTs-1PFqnDY__9qv#^YqR6Vqs+$5q8=ydd0%_4j5u{Mhz3<I% z_?J_6L2`z3-<vn*{?5H`j)>U6HwVwgjRPCTv3T~_l1Sc93&Yq*evlT)3mLI}wPai6 zldc^Z^EOL$b-L`;BV(&2r+7Ac?sC+4^Md)77)btBr1I|y9Q-uq=3kHD;2(nv`A-LN z@MJub|8g7$e;z94KN`Zpe}?DtpAX~U{O*PPGrMu{+~{Kd`B5C$W5xXX7!E#(iez*^ zB;8#i`3gRXVUe7~CpU_v;gd^><N`i_nGng(@Ok@yNWO>93kOAV1D_us7RjICbN`4) zeu&R!$1ulnvF&)vw(C~iNF*YJIT9T(e<%hGk)YE^#27wlUWyJxB4!NV!Wf=6hI7X7 z(wRk@5SU^>%poi+8o>ucV#aWWW#VHC)oMveV2VKjBrllj^s`~Ci>&cpEPV4;Y~|DI z_R2L+?zy>c*Vk=V;!C=GSLt}ts>s55T6aO-uu7ZuY$73#9+l^BS>;;E_Hb4x6nJ$B z`4k4Ihn&86Z91DyC*)VHl4r9_H%Xp+`rA&4#4o#>zBF)|`%&~a(Rkh6Qh?<j7fpyQ zneQ`VKm~{$nl}#Rj6+L|=4p*)2lxPB6aWrHq69ULq6B4kxJ69M?@TH>D58du%D*h2 zfYFWQ>q2BlFHF!=v>~5*uC{8`?dQD|!+h~t!3Vy$C2N-FIhCu@se1}}S+7b<u5DIU z>Q1!+HCc7J<=CZFC`pf-NnoN?oYXhn3JoS*vW!jtk|oW`>C5ZTYuVb8Dc7!*tQ9-O zas|5oO{cyd()nx}YWv0-Uw10C&3cPTxRy2<m<d@5rkG*jV41j8rCOIOR;h$FV08(; zUUi+TPQ@w(#sxXGY<rbVjMo^Rgr3B{zUjaS?Mhu%*LX^L#zNVu735mARI1*@EdX6% ztz^~fb_HwU8#=t~P0wE2EJ4tfE9;h{@Tp!^MqdUr4h%ZL*TXUaFu}BDIi=oa59KP0 zpOI^o>04>}T?q%cB~Qp~THb+O<1B|CxJru~bRKzhI%TD1<gIitTK~g7)o+$%y1#O( z)WvncpHkB_|J7|Z4S($RFbxSk2ZgXpu=l7T_MMAGjlrA|6H`{LR)Xiw9U8eYvaKy` zIWlEaFwqh4{T6>-?c~o<5sySWIr1Po=B_^OtE4amJEm*aRA8(jFisA(uB**O7nO%3 z*=Tv`>>>`#T{{#M+C3inkIf^e6>!<~jHGav&^l7b?MiJP%K_CN$R`Z`Kq7%SDdgAX zT`m7$&?Y)VJH*fq_kk9J5kH4Dv<v1chdg5y5$}G?Ur#qk4Th9+$`^su_cw(e0O<o` z7x1&`#2Mw5fbq@4e?2^gKvQ|B`DQnxG!o>S-F;9U)$+abjW4ClI%7VgurC1nx1;<J zZNQ&{(Uu%**y9*jK<FvV%Dio}B37#_n`J~+i<1ilNsfO(2&R9^Ro9kI1&3u48>=8H z_VWCFqt{2bH!C+?tF~N>#H)3X5@tTPoBV#q%tt)J&;;L1b&4iZEm579;n90`HQ%od zgY&oQuC-F%N8z2Gr2@jEY;eu3mIJ4rl?zyH$U-TtD)%pMdUaW}k%3eu^Q<xu+^Y3q zMm`LfHZVnmfNZBQ9G2zG0l}OS1YZ<$f8R5iJfnm(p!b>pT{61_(y`9oj=$l@<NS?d z4wUoeZDmof!J_u;(zok_CsT+HaL$A%i6vL<H4Euh<L)SSq1Z{HnP2qIx(We55S;3b zrUpHgLi8okQ$C(820V$>H9!e!?$#skJaV^Wy|lIL=d1j9D*^pgr-Vgx{&d{@3SH}z zw+se)Pb5l&zbDlfzG&}Q;7cjZEtnrE&3y#Ty)xoILYwLqnI(Ezw(>Q{g;^`rK_iMW zDLMy>wcVSJ2mVFZL0FaZTy<{Pm4GjCOaVOw&nsFh*VI(K^{27*6$s{}iBm41JqXV# zI@5PhWpo~>vTKTeWKMIQMy6~bUj7_Sqq1Zjoz~Hry!D-<X>xx_t$*q#q<ZIt{lDJ7 z4LZw3R7ChR>C+bPzSq_2dXzm$wz@|ne%XT~IQ`x}$w-abtAoO#`9~FNKS!+1?G7)s z&Ae1?<DEcERc5u0QpL~o6ny=%5>(#jQbgXVQXpDy$z}sfNEAIzolHs>B#k1K<4(91 z@#m)d1Szbo6d}t`Xc{NIy0xVYn<9E|%k@>{PFHW(?z|>)MC_=3nh%Nqt^l|IP)hG? zMy<24&32zkoAeYsB9wlgI5!kEMl;3;s!sYIqm>9TMhlEY=HA^k9^YnrMbwPMk&&Uu zJ?L8CCn~rNfoP;U5liOnt_Id4tWB^%?c=Zp%TlNKz9a@YqZG}1%6NVO<4Luwrp<hG zqJB)Nq<dn~G087>{oK+}`WH?wK3c%4B}AQKm3B<s;X&HbLor1S<kS-nD^FETLF&nk zKQnHKjqTOya?Nt<PGpQo*(LNWB1E6^&|SE5bl3b7>kF5VPO=#zn=`T}ad<srT+bQT z>F`d*xRW#PoE-a><N4hrv_JZ!pZ%=T1CeOUFsK)o+W&+kEfRgJh@fT_razS7whXNy zoiWlmBi*`&9+RPq2WDqVWj7KuFVO-@i`_(`bALOSJ7kFYGaPh0fTk(Z@0u_>Y1SAs zje+W<wXUoWI+KjfV-!I<kH?cihFR*oS-?Y#ZWsk5<&BtLUCZjX<<~f;TH~?=HBpm8 z#W>F=P#%I{X{*6YJy2NBSw%2K=cRYdQg}>X(a}X4r$yF@zvj{}BGq2W&d9kJk&wnH zwjd!rd8Bg05UDsqR0GL}l8z2Cc!z>?q|OibNk@nMQL4*k{y~BIFM#@Cf>zmvs7^x} z<dZIGh}vEcAqRyTrA?WLrvLw?A)SEwr;M(t=K)ig&&Wih^6Qg&eh~XGW{Bc8>dj@> zUa3anNJ)V;J*1}Y6dQ&N%t`h!Bqe`jhf<1I7xO=%rY^QA-a=E?_~%6PBXu*q7rL7s zJK=*`AD96MxvJWmDH6(iuc}L}MpJke%~VL=q$|_`#uXQ|2R2!eW!t@qo@w20gE|#7 znX46l1E3?>(tTdpWaauv{s%*s9h$y9Ted6JG8)p{uON~TYSyYQIP8sC0X_E$(ICks zeyxhWdJ&yon;MZ`@1V(kC2v0^edEP6(*ef|H(IGl%t-oo>sNrN0F3@{x7m4px+3D^ z9ki2oKB<ySbz64#%L&=SJQaD#pl;TjbMAx3Gsh@vfXN4bZZ>C)hmn6%?DI!^`EZDU zAQ>O+#91&4XXuoPZA8k@?;@FeGE9qa^XR9m<)TxukCSt?WN0K}-k+g88yJ^zwOOuJ zFq5=PHg(r1UvoC#(eOh~+{zc#_6Md``zUg~T3YpKt$#C>#Pzh5Eq_|-nuJQ83T{t3 zK#Du7(w;4-x3OcL0X=}>=a>@UfLK9}=mA$8^c_^<;UU^&>=ch{oQ3Gb%H$i9L~M0~ z3){QogAE(G*Tm7fwy}<NZeu;p_JE5}HNKf5Y?!Zd$Tr?U#CC)3puTgPf_2rgUsoOc z5PIWNMGwDH^$8g%XlEU*z68w&g&+x9gsNH9vD9dihnm8zt&T1l)E9H#Gk$LvVsX3T zl>AmhLkX=!nYvUv*p?Q@8Tco9xg!*FoUW(T#&sM$`zf|1+=HEPF}!bmKNenKo31Xq zR>fPZ8g7|<2EIVRDK}KUz*_=+Sh0^l198~7vfXYQ3XLJ09U#xYp?!qCk3RdTA#zjL z4X<8n0Q&{^`^7W^n<n78@A&7!1;$G;b?-LJ^j`mX_q~3is~lx|#|nNlRTcw)(6)V3 zcu-OeI3cQD2x#oNd`EmA?T3ZCdds$f*2hh;;H3HLPRx+vz5gCSRGjD>Co+uZi9Uwv zOR4Ozz;OiG;Z<aZpYQUQ+XnEnM5sJ@z>*c)tAh{}7MXMvTJl55+Opl=5NkvTWMyc9 zr4hz0?aYv{f*a9*UZ@C8Iz?}PP?LfhCp3iG6sQBML%$rNfWhquG$SH{+7YU<&JQ)W zBOXR-pJ5e!3Ezl458O_`==R<OCetD2W0es;Mn-sPB>YHi+SKLvsn%rgM}Oi0HOp~B zj9h11mF{^rg9oE~i8d#Q05N2h#bFUa=}zw{@FfpamA0B%$8%%RpCHjX1M3W%c|`Ps z$z_qYu!uQenYEg2QE&t^0EI;_zv`}n5fhc=4rt9@snZK4SRNh+9NFQ0K+RTyw>5ko zqAQ76*>m^Xx0XskE3`Rs*Fhf_bq7Mxjib|7ax*gf;*7kKD&iFgyaxg1(FhlJ4!(2H z5R=%U3GC1OcT=QTGGF6J(fn2r0>kNf<8;nA-RYGoG0XOLvU9xfFZSMq@ud{+m<+SY z&xWzyHsjL!FUMK$JKBE<vpQ`kI|$Wa6C6Ld&y%B|pz>9RDAEws%Hbc{OzAVKNt}04 za1Z}pom&q9$<aGDJgR9Pb=%gzLdNj<-m?>ih@ZuKCw>oNbiz0=ZycE5cjAn}4BkZ< bqwF-rc}MTY8H1Dff8gS^DV`itjEnyQt>}2n diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta deleted file mode 100644 index f4e887486561f8be3945fd8b61344d52d6d64401..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmZ4IWtGYR1B_4x7nDxVNlnbv&&ez<xplPfLd0zE)c}_f3VHwl diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache deleted file mode 100644 index ac3aab69cfd99c5e7fc4f4cfec259c9525d7469b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6402 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 M;-{F>vE~f>KiVD_EdT%j diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta deleted file mode 100644 index e4e832bc82346f74985f18beddf6b6e9edaf3e83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache deleted file mode 100644 index 56a8556be6c6c82cc50b9ad602ee216107ebe941..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21832 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 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta deleted file mode 100644 index 7c72b25579dddf57ca0f1d52e021b5c2d8247d4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache deleted file mode 100644 index 75483550b0448e42f84a11e245d390d4d392040f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10562 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 VZ@w{j!88rCUh;6IMM{(|@_!|WeGLEr diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta deleted file mode 100644 index b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache deleted file mode 100644 index 8a0b42a87ebe04e602200039906fd11ffcdc4611..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7759 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 K=;oBj`1fDVAGuZl diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta deleted file mode 100644 index 2ae412bccfd7739434a236925520c9652e93ff84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<<f}##0 V7N1m_nUj)Q<er!*%^>nW832Uh9(Di# diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version deleted file mode 100644 index 7dd8dc5809e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_version +++ /dev/null @@ -1 +0,0 @@ -0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache deleted file mode 100644 index b7d93046a52ede28e212fe16157739a5771ad13c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3254 zcmbVO!Ef7S6!&K*aUHeGo=T@}YN<DEY*>PhWJqfylqJx?BDU4@O0|l~b&@ZwH^(lY zolTiQy&;IWAaUS;&^U18unPyK{SinA!LGY;;<8EX6y9e$ZQP_KL#pDJ)bD-2_rBlz zy?3r8U6kQi6;7{CzaW21ADff`s?#%*_okmr%DoMT(za^{f*=gq<yS;FUDMB!6nvuT zTlo07t3M{GX@yjcNrJ`-d1QQyMsJC`U)u@<+4fvP(2t4|ydy)p3QBe$qy$P0rm6sP z(qrHiVOf;$FINt{Rvc(?WFQTcDon}Yi^KlC>vYRw!4;1*+77*HwWvTsROOMux>ydF zkw<tXDiUGqExC2CVY?eb9CLK0h%U->=j~Ck-j8cfmYKJ~sPC7sjJrh~4fjzDcR%Oh zdX&$LKsCKVr0F*48lMt0o|B^Sj2nuyW=u+G%%v*EYzmDpQ=0JwH=d{R#xrhMY0X$q zqwykLG5+Dk51FUNPZ=T=R^;QvXvp}}8xz-!a}#JRDiz~`LZn>FvRy*-Nm0@-k~EMk z){F=OD6&2wN&>%afq-%nlsx_>U$vciWTVx>-w6TG^oRJsIzA+CP2E?*aD&P9)JwM8 zP%ZaVLuGAOwH!wcs2`}!wp-_A^wp-v)L@gU^)_SF4b&~>-KO<GZTonG>JoD-cjJt& zF0CMgv#~QnzTETJoj0>twd{7{w^WRT6}MVD(N)_GW3Tfw*VTs2FtW!w>ODKyR4vuT zI4W(}0YA!iv+BATy=nVu9l_ZR$|%B5V#ahD7y(nMQJxh?ak<GYm&fs3wQAk9j5@Qo zg3!|+e7k>kz3pQQMUm09<Wh!#1X8#})<|!NIY?!GN#~<W5<wZiB|yZR>guQPrp}^; zjg%b`e~|oA;YsGNOeyM7>~encp9y*_=-+aB=qcm@K0#SUfSfS|=DKjY3a`s(p3vY# z9!@Nb(YLt|Z9j;(#e;Ivy<``0mvPi<MkEqIQJ=+nsOW<_kd0FvpsrM)^7nGDiS#v_ zwj)T?j|=f2QHWLjgRl^B?nRi(!yM0jrU)~6)U1*bFr>v!+wA?$VWU=Jdo7HpK{0B) zy-sN&0<7sO@4?%!jGx&A)ZIjKX0vJYrd}oloyeK;gvcBAF!~(F&tA(4>YE4<-;uZ$ z6uwLUmfrq|vYO}9IOTIYtQ)7mfWrkUiTd{A?cx%of+4TTxs{-KVd#|qmgbPtTH=f_ zRN{b>nb$J&SG^lSXXu2n^T;R8h@vG9xh2=++@|H=bPoGuJwcBJ{cOKa_(k`1^s*as z{Q!MU^UKxrqxhIA!cp|jhUb)MsELAD_&W6<wf(N=cqmfw>CQo?M>Laj70=t1aSrPx zI}JMsq3yZh7)PQubFvn0FILM8JkgARn=OyeeAAWr)E}d0`}6<@zR$nH(mln^i14Kf zMekU+<?Ih5f%=!!->F^$#|~v)Tk@TbiL>A?Wr693t&F*tRv?A@4_C&o5;b4d`JD=V zF&q$tDhD$+BnSiR%Af}KNACf9RHy>?LxMsPW|1e^Ud?tb)-eO2#6fzkUAAmye$4c6 z(wKag6iA=1zwSZ*%^-R$l(Pja^`Zugc~~5!Q3oI#p=jfD9>3ZOC=B<<?e{u3rR_Su zA*;2}=m_)ScPw(4e%v7WxIy^%o{yGgvGBW`nb>Z4CSP)5qWzyGCn7p(W?12VzyxJ{ z@pJK_Se_N(?HVk;3Rg6^as+N_a5DodkKooJu&O{0fn5aq2(-KK*`efy9p;NOpx9T+ zNNM7^6m~46HAv@kH&~m_U$PvZMyvJErVuZvKq`H07-Sd_Efh+O?6;i&(#J8VbnVXk R5@Q}4HK>7fN39Eo$-gpIGF1Qo diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta deleted file mode 100644 index 35823f819643250ce036eb3ade6a8b4cfeac4a68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0<IM LSG~Z5x<GpX@`M<b diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache deleted file mode 100644 index f19571aa4e63b4c2d3a0fccb0e0d9224a015daeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1134 zcmb`GO=}Zj5XWbpXE)mf!#YGOk;qnQsH}(9h#<X~2JImS_2~-5i!sHGO}b_=$>K#3 za`YmCS3y637r%v9KZAY)^&02dw<c0^(L*M)&%VrW{_~%$4mK^SPN{BD{duKsT14&2 zMRTL_z_eyh0^g5@{fXEdABIuz7_tL^rr4<oy53edP}0wq`hl|Y7Wce&$jOdqd$$B9 z-$ldwrjw7-^*%^WE*K53W}uuM_#J;V3P%8ds7?u~UZ6=>(w6{K+*J331W*P?q~bOe z8&urCx#y3gVB#=H_o-SD5(V&&UlB<(5s9X1P5%vOjbmw+z;_NrRx)eD?(}+n5Z7Lc z_u>@;O-7NQ!aVu|=JGs@8^c(3D-44KMYA&HrR0Wnr+<7N6SY*0iON%|aV%xEa)B`u zm|@-&J{M-gaMJOgMP0xk1v*>++E-gKP^<uJpt~1f{Ea{my;kc?aCSiJ9CJ;Em=+2E zavI2V`Gj9k531J<#{Ti3{<AjiWLnd7T66VsqIrG37Jd~RekeTpH{YO)RWstqc|51V z$<6^=*UNEofzF7l!tQnZ*^rtGL$b6%0hV|}yVPB<M*OwB(0t$LtSgqIJ&_e#<_I(H z%3SJ*lY8~S)-`g3yw_cPh`jYHg32zHSE;&9)zx?f$aKkU*!OvRoLy~|bW6!R&*$>) Lk#k#b`f2<P?Pucd diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta deleted file mode 100644 index 401fd74cd1e9eb44559765e4eac26450d3f34537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd08e3d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca9075..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> -![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index a978a7ff425..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_stdlib" -version = "0.33.1" -gleam = ">= 0.32.0" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2dea0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc71a3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922beda..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25ed0a7..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511eb103..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 42166198699..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603b961..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 6e1e2261268..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f476b1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs deleted file mode 100644 index a8309e0cdbd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/dict.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of Dict size and clean up the API - * @template K,V - */ -export default class Dict { - /** - * @template V - * @param {Record<string,V>} o - * @returns {Dict<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type Dict<string,V> */ - let m = Dict.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {Dict<K,V>} - */ - static fromMap(o) { - /** @type Dict<K,V> */ - let m = Dict.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new Dict(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {Dict<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {Dict<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return Dict.new(); - } - return new Dict(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof Dict) || this.size !== o.size) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index eab2f0b3fec..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam deleted file mode 100644 index 79860e964ef..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_array.gleam +++ /dev/null @@ -1,157 +0,0 @@ -//// BitArrays are a sequence of binary data of any length. - -import gleam/string - -/// Converts a UTF-8 `String` type into a `BitArray`. -/// -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") -pub fn from_string(x: String) -> BitArray - -/// Returns an integer which is the number of bytes in the bit array. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -pub fn byte_size(x: BitArray) -> Int - -/// Creates a new bit array by joining two bit arrays. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - concat([first, second]) -} - -/// Extracts a sub-section of a bit array. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit array. -/// -/// This function runs in constant time. -/// -@external(erlang, "gleam_stdlib", "bit_array_slice") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) - -/// Tests to see whether a bit array is valid UTF-8. -/// -pub fn is_utf8(bits: BitArray) -> Bool { - do_is_utf8(bits) -} - -@target(erlang) -fn do_is_utf8(bits: BitArray) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:bytes>> -> do_is_utf8(rest) - _ -> False - } -} - -@target(javascript) -fn do_is_utf8(bits: BitArray) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } -} - -/// Converts a bit array to a string. -/// -/// Returns an error if the bit array is invalid UTF-8 data. -/// -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - do_to_string(bits) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "identity") -fn unsafe_to_string(a: BitArray) -> String - -@target(erlang) -fn do_to_string(bits: BitArray) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") -fn do_to_string(a: BitArray) -> Result(String, Nil) - -/// Creates a new bit array by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -@external(erlang, "gleam_stdlib", "bit_array_concat") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") -pub fn concat(bit_arrays: List(BitArray)) -> BitArray - -/// Encodes a BitArray into a base 64 encoded string. -/// -pub fn base64_encode(input: BitArray, padding: Bool) -> String { - let encoded = encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -@external(erlang, "base64", "encode") -@external(javascript, "../gleam_stdlib.mjs", "encode64") -fn encode64(a: BitArray) -> String - -/// Decodes a base 64 encoded string into a `BitArray`. -/// -pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { - let padded = case byte_size(from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - decode64(padded) -} - -@external(erlang, "gleam_stdlib", "base_decode64") -@external(javascript, "../gleam_stdlib.mjs", "decode64") -fn decode64(a: String) -> Result(BitArray, Nil) - -/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { - base64_encode(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. -/// -pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> base64_decode() -} - -@external(erlang, "binary", "encode_hex") -@external(javascript, "../gleam_stdlib.mjs", "base16_encode") -pub fn base16_encode(input: BitArray) -> String - -@external(erlang, "gleam_stdlib", "base16_decode") -@external(javascript, "../gleam_stdlib.mjs", "base16_decode") -pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52ec1b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0930d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 91bd6b76129..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,428 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{type Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} - -/// Runs a callback function if the given bool is `True`, otherwise runs an -/// alternative callback function. -/// -/// Useful when further computation should be delayed regardless of the given -/// bool's value. -/// -/// See [`guard`](#guard) for more info. -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "Kamaka" -/// > let inquiry = fn() { "How may we address you?" } -/// > use <- lazy_guard(when: name == "", return: inquiry) -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -/// ```gleam -/// > import gleam/int -/// > let name = "" -/// > let greeting = fn() { "Hello, " <> name } -/// > use <- lazy_guard(when: name == "", otherwise: greeting) -/// > let number = int.random(1, 99) -/// > let name = "User " <> int.to_string(number) -/// > "Welcome, " <> name -/// "Welcome, User 54" -/// ``` -/// -pub fn lazy_guard( - when requirement: Bool, - return consequence: fn() -> a, - otherwise alternative: fn() -> a, -) -> a { - case requirement { - True -> consequence() - False -> alternative() - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam deleted file mode 100644 index 20c145d93aa..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam +++ /dev/null @@ -1,197 +0,0 @@ -//// BytesBuilder is a type used for efficiently concatenating bytes together -//// without copying. -//// -//// If we append one bit array to another the bit arrays must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit arrays together. -//// -//// BytesBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit array using the `to_bit_array` function. -//// -//// Byte builders are always byte aligned, so that a number of bits that is not -//// divisible by 8 will be padded with 0s. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -// TODO: pad bit arrays to byte boundaries when adding to a builder. -import gleam/string_builder.{type StringBuilder} -import gleam/list -import gleam/bit_array - -pub opaque type BytesBuilder { - Bytes(BitArray) - Text(StringBuilder) - Many(List(BytesBuilder)) -} - -/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> BytesBuilder { - concat([]) -} - -/// Prepends a bit array to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { - append_builder(from_bit_array(first), second) -} - -/// Appends a bit array to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { - append_builder(first, from_bit_array(second)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to second: BytesBuilder, - prefix first: BytesBuilder, -) -> BytesBuilder { - append_builder(first, second) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "iodata_append") -pub fn append_builder( - to first: BytesBuilder, - suffix second: BytesBuilder, -) -> BytesBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string( - to second: BytesBuilder, - prefix first: String, -) -> BytesBuilder { - append_builder(from_string(first), second) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string( - to first: BytesBuilder, - suffix second: String, -) -> BytesBuilder { - append_builder(first, from_string(second)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { - Many(builders) -} - -/// Joins a list of bit arrays into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { - bits - |> list.map(fn(b) { from_bit_array(b) }) - |> concat() -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string(string: String) -> BytesBuilder { - Text(string_builder.from_string(string)) -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { - Text(builder) -} - -/// Creates a new builder from a bit array. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_bit_array(bits: BitArray) -> BytesBuilder { - Bytes(bits) -} - -/// Turns an builder into a bit array. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -@external(erlang, "erlang", "list_to_bitstring") -pub fn to_bit_array(builder: BytesBuilder) -> BitArray { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_array.concat -} - -fn to_list( - stack: List(List(BytesBuilder)), - acc: List(BitArray), -) -> List(BitArray) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bytes(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_array.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -@external(erlang, "erlang", "iolist_size") -pub fn byte_size(builder: BytesBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam deleted file mode 100644 index 280bf9d1d98..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dict.gleam +++ /dev/null @@ -1,544 +0,0 @@ -import gleam/option.{type Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a dict, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a dict once. -/// -/// Dicts are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub type Dict(key, value) - -/// Determines the number of key-value pairs in the dict. -/// This function runs in constant time and does not need to iterate the dict. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(dict: Dict(k, v)) -> Int { - do_size(dict) -} - -@external(erlang, "maps", "size") -@external(javascript, "../gleam_stdlib.mjs", "map_size") -fn do_size(a: Dict(k, v)) -> Int - -/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the dict. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { - do_to_list(dict) -} - -@external(erlang, "maps", "to_list") -@external(javascript, "../gleam_stdlib.mjs", "map_to_list") -fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) - -/// Converts a list of 2-element tuples `#(key, value)` to a dict. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the dict. -/// -pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { - do_from_list(list) -} - -@target(erlang) -@external(erlang, "maps", "from_list") -fn do_from_list(a: List(#(key, value))) -> Dict(key, value) - -@target(javascript) -fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Dict(k, v), -) -> Dict(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } -} - -@target(javascript) -fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { - fold_list_of_pair(list, new()) -} - -/// Determines whether or not a value present in the dict for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(dict: Dict(k, v), key: k) -> Bool { - do_has_key(key, dict) -} - -@target(erlang) -@external(erlang, "maps", "is_key") -fn do_has_key(a: key, b: Dict(key, v)) -> Bool - -@target(javascript) -fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { - get(dict, key) != Error(Nil) -} - -/// Creates a fresh dict that contains no values. -/// -pub fn new() -> Dict(key, value) { - do_new() -} - -@external(erlang, "maps", "new") -@external(javascript, "../gleam_stdlib.mjs", "new_map") -fn do_new() -> Dict(key, value) - -/// Fetches a value from a dict for a given key. -/// -/// The dict may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -@external(erlang, "gleam_stdlib", "map_get") -@external(javascript, "../gleam_stdlib.mjs", "map_get") -fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) - -/// Inserts a value into the dict with the given key. -/// -/// If the dict already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { - do_insert(key, value, dict) -} - -@external(erlang, "maps", "put") -@external(javascript, "../gleam_stdlib.mjs", "map_insert") -fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) - -/// Updates all values in a given dict by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { - do_map_values(fun, dict) -} - -@target(erlang) -@external(erlang, "maps", "map") -fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) - -@target(javascript) -fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { - let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } - dict - |> fold(from: new(), with: f) -} - -/// Gets a list of all keys in a given dict. -/// -/// Dicts are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(dict: Dict(keys, v)) -> List(keys) { - do_keys(dict) -} - -@target(erlang) -@external(erlang, "maps", "keys") -fn do_keys(a: Dict(keys, v)) -> List(keys) - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(dict: Dict(k, v)) -> List(k) { - let list_of_pairs = to_list(dict) - do_keys_acc(list_of_pairs, []) -} - -/// Gets a list of all values in a given dict. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(dict: Dict(k, values)) -> List(values) { - do_values(dict) -} - -@target(erlang) -@external(erlang, "maps", "values") -fn do_values(a: Dict(k, values)) -> List(values) - -@target(javascript) -fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } -} - -@target(javascript) -fn do_values(dict: Dict(k, v)) -> List(v) { - let list_of_pairs = to_list(dict) - do_values_acc(list_of_pairs, []) -} - -/// Creates a new dict from a given dict, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter( - in dict: Dict(k, v), - keeping predicate: fn(k, v) -> Bool, -) -> Dict(k, v) { - do_filter(predicate, dict) -} - -@target(erlang) -@external(erlang, "maps", "filter") -fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) - -@target(javascript) -fn do_filter( - f: fn(key, value) -> Bool, - dict: Dict(key, value), -) -> Dict(key, value) { - let insert = fn(dict, k, v) { - case f(k, v) { - True -> insert(dict, k, v) - _ -> dict - } - } - dict - |> fold(from: new(), with: insert) -} - -/// Creates a new dict from a given dict, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { - do_take(desired_keys, dict) -} - -@target(erlang) -@external(erlang, "maps", "with") -fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_taken( - dict: Dict(k, v), - desired_keys: List(k), - acc: Dict(k, v), -) -> Dict(k, v) { - let insert = fn(taken, key) { - case get(dict, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) - } -} - -@target(javascript) -fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { - insert_taken(dict, desired_keys, new()) -} - -/// Creates a new dict from a pair of given dicts by combining their entries. -/// -/// If there are entries with the same keys in both dicts the entry from the -/// second dict takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { - do_merge(dict, new_entries) -} - -@target(erlang) -@external(erlang, "maps", "merge") -fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { - insert(dict, pair.0, pair.1) -} - -@target(javascript) -fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { - case new_entries { - [] -> dict - [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) - } -} - -@target(javascript) -fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { - new_entries - |> to_list - |> fold_inserts(dict) -} - -/// Creates a new dict from a given dict with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { - do_delete(key, dict) -} - -@external(erlang, "maps", "remove") -@external(javascript, "../gleam_stdlib.mjs", "map_remove") -fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) - -/// Creates a new dict from a given dict with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { - case disallowed_keys { - [] -> dict - [x, ..xs] -> drop(delete(dict, x), xs) - } -} - -/// Creates a new dict with one entry updated using a given function. -/// -/// If there was not an entry in the dict for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let dict = from_list([#("a", 0)]) -/// > -/// > update(dict, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(dict, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in dict: Dict(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Dict(k, v) { - dict - |> get(key) - |> option.from_result - |> fun - |> insert(dict, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over dict: Dict(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - dict - |> to_list - |> do_fold(initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index c71c6f342ad..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1508 +0,0 @@ -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option} -import gleam/result -import gleam/string_builder -@target(erlang) -import gleam/bit_array - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from(a: anything) -> Dynamic - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_unsafe_coerce(a: Dynamic) -> a - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit -/// array if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_array(from("Hello")) == bit_array.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_array(from(123)) -/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - decode_bit_array(data) -} - -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - -@external(erlang, "gleam_stdlib", "decode_bit_array") -@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") -fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -@target(erlang) -fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_array(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_array.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitArray", path: [])]) - } - }) -} - -@target(erlang) -fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "decode_string") -fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -@external(erlang, "gleam_stdlib", "classify_dynamic") -@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") -fn do_classify(a: Dynamic) -> String - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -@external(erlang, "gleam_stdlib", "decode_int") -@external(javascript, "../gleam_stdlib.mjs", "decode_int") -fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -@external(erlang, "gleam_stdlib", "decode_float") -@external(javascript, "../gleam_stdlib.mjs", "decode_float") -fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -@external(erlang, "gleam_stdlib", "decode_bool") -@external(javascript, "../gleam_stdlib.mjs", "decode_bool") -fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -@external(erlang, "gleam_stdlib", "decode_list") -@external(javascript, "../gleam_stdlib.mjs", "decode_list") -fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_result") -@external(javascript, "../gleam_stdlib.mjs", "decode_result") -fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -@external(erlang, "gleam_stdlib", "decode_option") -@external(javascript, "../gleam_stdlib.mjs", "decode_option") -fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -@external(erlang, "gleam_stdlib", "decode_field") -@external(javascript, "../gleam_stdlib.mjs", "decode_field") -fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -type UnknownTuple - -@external(erlang, "gleam_stdlib", "decode_tuple") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") -fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple2") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") -fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple3") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") -fn decode_tuple3( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple4") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") -fn decode_tuple4( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple5") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") -fn decode_tuple5( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple6") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") -fn decode_tuple6( - a: Dynamic, -) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, -) - -@external(erlang, "gleam_stdlib", "tuple_get") -@external(javascript, "../gleam_stdlib.mjs", "tuple_get") -fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) - -@external(erlang, "gleam_stdlib", "size_of_tuple") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn tuple_size(a: UnknownTuple) -> Int - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a dict. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() |> from |> map(string, int) -/// Ok(dict.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn dict( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> dict.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(dict.from_list(pairs)) - } -} - -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - -@external(erlang, "gleam_stdlib", "decode_map") -@external(javascript, "../gleam_stdlib.mjs", "decode_map") -fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.concat([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 5d62419fd0d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,546 +0,0 @@ -//// Functions for working with floats. -//// -//// ## Division by zero -//// -//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE -//// 754 standard for floating point arithmetic and does not have an `Infinity` -//// value. In Erlang division by zero results in a crash, however Gleam does -//// not have partial functions and operators in core so instead division by zero -//// returns zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/order.{type Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_float") -@external(javascript, "../gleam_stdlib.mjs", "parse_float") -fn do_parse(a: String) -> Result(Float, Nil) - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -@external(erlang, "gleam_stdlib", "float_to_string") -@external(javascript, "../gleam_stdlib.mjs", "float_to_string") -fn do_to_string(a: Float) -> String - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -@external(erlang, "math", "ceil") -@external(javascript, "../gleam_stdlib.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -@external(erlang, "math", "floor") -@external(javascript, "../gleam_stdlib.mjs", "floor") -fn do_floor(a: Float) -> Float - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -@target(erlang) -@external(erlang, "erlang", "round") -fn do_round(a: Float) -> Int - -@target(javascript) -fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "round") -fn js_round(a: Float) -> Int - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../gleam_stdlib.mjs", "truncate") -fn do_truncate(a: Float) -> Int - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../gleam_stdlib.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Generates a random float between the given minimum and maximum values. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(min: Float, max: Float) -> Float { - do_random_uniform() *. { max -. min } +. min -} - -/// Returns a random float uniformly distributed in the value range -/// 0.0 =< X < 1.0 and updates the state in the process dictionary. -/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> -/// -@external(erlang, "rand", "uniform") -@external(javascript, "../gleam_stdlib.mjs", "random_uniform") -fn do_random_uniform() -> Float - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997de92a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index d93c16afaf6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,874 +0,0 @@ -//// Functions for working with integers. -//// -//// ## Division by zero -//// -//// In Erlang division by zero results in a crash, however Gleam does not have -//// partial functions and operators in core so instead division by zero returns -//// zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/float -import gleam/order.{type Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_int") -@external(javascript, "../gleam_stdlib.mjs", "parse_int") -fn do_parse(a: String) -> Result(Int, Nil) - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -@external(erlang, "gleam_stdlib", "int_from_base_string") -@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") -fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "to_string") -fn do_to_string(a: Int) -> String - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") -fn do_to_base_string(a: Int, b: Int) -> String - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -@external(erlang, "erlang", "float") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_float(a: Int) -> Float - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Generates a random int between the given minimum and maximum values. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(min: Int, max: Int) -> Int { - float.random(to_float(min), to_float(max)) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} - -/// Calculates the bitwise AND of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "band") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") -pub fn bitwise_and(x: Int, y: Int) -> Int - -/// Calculates the bitwise NOT of its argument. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bnot") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") -pub fn bitwise_not(x: Int) -> Int - -/// Calculates the bitwise OR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") -pub fn bitwise_or(x: Int, y: Int) -> Int - -/// Calculates the bitwise XOR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bxor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") -pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic left bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsl") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") -pub fn bitwise_shift_left(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic right bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsr") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") -pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index 0c0a3eeffe0..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,117 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -@external(erlang, "gleam_stdlib", "print") -@external(javascript, "../gleam_stdlib.mjs", "print") -fn do_print(string string: String) -> Nil - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -@external(erlang, "gleam_stdlib", "print_error") -@external(javascript, "../gleam_stdlib.mjs", "print_error") -fn do_print_error(string string: String) -> Nil - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -@external(erlang, "gleam_stdlib", "println") -@external(javascript, "../gleam_stdlib.mjs", "console_log") -fn do_println(string string: String) -> Nil - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "console_error") -fn do_println_error(string string: String) -> Nil - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "print_debug") -fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index c57e7fd9473..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1530 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option, None, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_map2( - continuation1: fn() -> Action(a), - continuation2: fn() -> Action(b), - with fun: fn(a, b) -> c, -) -> fn() -> Action(c) { - fn() { - case continuation1() { - Stop -> Stop - Continue(a, next_a) -> - case continuation2() { - Stop -> Stop - Continue(b, next_b) -> - Continue(fun(a, b), do_map2(next_a, next_b, fun)) - } - } - } -} - -/// Combines two interators into a single one using the given function. -/// -/// If an iterator is longer than the other the extra elements are dropped. -/// -/// This function does not evaluate the elements of the two iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// let first = from_list([1, 2, 3]) -/// let second = from_list([4, 5, 6]) -/// map2(first, second, fn(x, y) { x + y }) |> to_list -/// // -> [5, 7, 9] -/// ``` -/// -/// ```gleam -/// let first = from_list([1, 2]) -/// let second = from_list(["a", "b", "c"]) -/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list -/// // -> [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2( - iterator1: Iterator(a), - iterator2: Iterator(b), - with fun: fn(a, b) -> c, -) -> Iterator(c) { - do_map2(iterator1.continuation, iterator2.continuation, fun) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Joins a list of iterators into a single iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [[1, 2], [3, 4]] -/// > |> map(from_list) -/// > |> concat -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { - flatten(from_list(iterators)) -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - keeping predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - groups - |> dict.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Dict(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Dict(key, List(element)) { - iterator - |> fold(dict.new(), group_updater(key)) - |> dict.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} - -/// Add a new element to the start of an iterator. -/// -/// This function is for use with `use` expressions, to replicate the behaviour -/// of the `yield` keyword found in other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > use <- iterator.yield(1) -/// > use <- iterator.yield(2) -/// > use <- iterator.yield(3) -/// > iterator.empty() -/// iterator.from_list([1, 2, 3]) -/// ``` -/// -pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { - Iterator(fn() { Continue(element, next().continuation) }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index a5cffa9b951..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2154 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{type Order} -import gleam/pair -import gleam/dict.{type Dict} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -@target(erlang) -@external(erlang, "erlang", "length") -fn do_length(a: List(a)) -> Int - -@target(javascript) -fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) -} - -@target(javascript) -fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -@target(erlang) -@external(erlang, "lists", "reverse") -fn do_reverse(a: List(a)) -> List(a) - -@target(javascript) -fn do_reverse(list) { - do_reverse_acc(list, []) -} - -@target(javascript) -fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - case dict.get(groups, f(elem)) { - Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> dict.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> dict.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) -/// |> dict.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { - fold(list, dict.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Combines two lists into a single list using the given function. -/// -/// If a list is longer than the other the extra elements are dropped. -/// -/// ## Examples -/// -/// ```gleam -/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) -/// [5, 7, 9] -/// ``` -/// -/// ```gleam -/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) -/// [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { - do_map2(list1, list2, fun, []) -} - -fn do_map2( - list1: List(a), - list2: List(b), - fun: fn(a, b) -> c, - acc: List(c), -) -> List(c) { - case list1, list2 { - [], _ | _, [] -> reverse(acc) - [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) - } -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -@target(erlang) -@external(erlang, "lists", "append") -fn do_append(a: List(a), b: List(a)) -> List(a) - -@target(javascript) -fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) -} - -@target(javascript) -fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Joins a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn concat(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// This is the same as `concat`: it joins a list of lists into a single -/// list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// Maps the list with the given function into a list of lists, and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> concat -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> [stop, ..acc] - order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) - order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, finds all tuples that have a given -/// key as the first element and returns the second element. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") -/// [0, 2] -/// ``` -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1)], "c") -/// [] -/// ``` -/// -pub fn key_filter( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> List(v) { - filter_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> concat - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> concat -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> concat -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> concat - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [elem_pair, ..enumerable] -> - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calculate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 1f8b228eb90..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,127 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(map) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@target(javascript) -fn do_filter(f: fn(key, value) -> Bool, map) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0fff8f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 12ce01136ca..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,133 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > negate(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -pub fn negate(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} - -/// Inverts an ordering function, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > list.sort([1, 5, 4], by: reverse(int.compare)) -/// [5, 4, 1] -/// ``` -/// -pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { - fn(a, b) { orderer(b, a) } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8d9f1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8a529..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index 9ffda789f6a..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,214 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{type Option} - -pub type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -@external(erlang, "gleam_stdlib", "compile_regex") -@external(javascript, "../gleam_stdlib.mjs", "compile_regex") -fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -@external(erlang, "gleam_stdlib", "regex_check") -@external(javascript, "../gleam_stdlib.mjs", "regex_check") -fn do_check(a: Regex, b: String) -> Bool - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "regex_split") -fn do_split(a: Regex, b: String) -> List(String) - -@target(javascript) -fn do_split(regex, string) -> List(String) { - js_split(string, regex) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn js_split(a: String, b: Regex) -> List(String) - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -@external(erlang, "gleam_stdlib", "regex_scan") -@external(javascript, "../gleam_stdlib.mjs", "regex_scan") -fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index fb6dddb3110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,482 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// "Updates" an `Ok` result by passing its value to a function that yields a result, -/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) -/// -/// If the input is an `Error` rather than an `Ok`, the function is not called and -/// the original `Error` is returned. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), Error("a"), Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index df8d500e804..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/dict.{type Dict} -import gleam/result - -// A list is used as the map value as an empty list has the smallest -// representation in Erlang's binary format -@target(erlang) -type Token = - List(Nil) - -@target(erlang) -const token = [] - -@target(javascript) -type Token = - Nil - -@target(javascript) -const token = Nil - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Dict(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(dict.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - dict.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: dict.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> dict.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: dict.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - dict.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: dict.new(), - with: fn(m, k) { dict.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - keeping predicate: fn(member) -> Bool, -) -> Set(member) { - Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(dict.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case dict.size(first.map) > dict.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index 7254fd9fd1c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,913 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{type Iterator} -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/order -import gleam/string_builder.{type StringBuilder} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -@external(erlang, "string", "length") -@external(javascript, "../gleam_stdlib.mjs", "string_length") -fn do_length(a: String) -> Int - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -@target(erlang) -fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string -} - -@target(javascript) -fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: String) -> String - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: String) -> String - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -@external(erlang, "gleam_stdlib", "less_than") -@external(javascript, "../gleam_stdlib.mjs", "less_than") -fn less_than(a: String, b: String) -> Bool - -/// Takes a substring given a start grapheme index and a length. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -@target(erlang) -@external(erlang, "string", "slice") -fn do_slice(a: String, b: Int, c: Int) -> String - -@target(javascript) -fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -@external(erlang, "gleam_stdlib", "crop_string") -@external(javascript, "../gleam_stdlib.mjs", "crop_string") -pub fn crop(from string: String, before substring: String) -> String - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -@external(erlang, "gleam_stdlib", "contains_string") -@external(javascript, "../gleam_stdlib.mjs", "contains_string") -pub fn contains(does haystack: String, contain needle: String) -> Bool - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -@external(erlang, "gleam_stdlib", "string_starts_with") -@external(javascript, "../gleam_stdlib.mjs", "starts_with") -fn do_starts_with(a: String, b: String) -> Bool - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -@external(erlang, "gleam_stdlib", "string_ends_with") -@external(javascript, "../gleam_stdlib.mjs", "ends_with") -fn do_ends_with(a: String, b: String) -> Bool - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: String, b: String) -> List(String) - -@target(erlang) -fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split_once") -fn do_split_once( - x x: String, - substring substring: String, -) -> Result(#(String, String), Nil) - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - do_join(strings, separator) -} - -@target(erlang) -fn do_join(strings: List(String), separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "join") -fn do_join(strings strings: List(String), string string: String) -> String - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -@target(erlang) -fn do_trim(string: String) -> String { - erl_trim(string, Both) -} - -@target(erlang) -type Direction { - Leading - Trailing - Both -} - -@target(erlang) -@external(erlang, "string", "trim") -fn erl_trim(a: String, b: Direction) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim") -fn do_trim(string string: String) -> String - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -@target(erlang) -fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_left") -fn do_trim_left(string string: String) -> String - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -@target(erlang) -fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_right") -fn do_trim_right(string string: String) -> String - -/// Splits a non-empty `String` into its first element (head) and rest (tail). -/// This lets you pattern match on `String`s exactly as you would with lists. -/// -/// Note on JavaScript using the function to iterate over a string will likely -/// be slower than using `to_graphemes` due to string slicing being more -/// expensive on JavaScript than Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -@external(erlang, "gleam_stdlib", "string_pop_grapheme") -@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") -fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "codepoint") -fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "‍", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️‍🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -@target(erlang) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(<<string:utf8>>, []) - |> list.reverse -} - -@target(erlang) -fn do_to_utf_codepoints_impl( - bit_array: BitArray, - acc: List(UtfCodepoint), -) -> List(UtfCodepoint) { - case bit_array { - <<first:utf8_codepoint, rest:bytes>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - _ -> acc - } -} - -@target(javascript) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") -fn string_to_codepoint_integer_list(a: String) -> List(Int) - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") -/// > utf_codepoint_to_int(utf_codepoint) -/// 128156 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") -fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -@external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam_stdlib.mjs", "inspect") -fn do_inspect(term term: anything) -> StringBuilder - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -/// ## Examples -/// -/// ```gleam -/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") -/// 58 -/// ``` -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "byte_size") -pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 5792ca8699d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,298 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -@external(erlang, "gleam_stdlib", "iodata_append") -@external(javascript, "../gleam_stdlib.mjs", "add") -fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_from_strings(a: List(String)) -> StringBuilder - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_concat(a: List(StringBuilder)) -> StringBuilder - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from_string(a: String) -> StringBuilder - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -@external(erlang, "unicode", "characters_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_string(a: StringBuilder) -> String - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -@external(erlang, "erlang", "iolist_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn do_byte_size(a: StringBuilder) -> Int - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -@target(erlang) -@external(erlang, "string", "reverse") -fn do_reverse(a: StringBuilder) -> StringBuilder - -@target(javascript) -fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -fn do_to_graphemes(string string: String) -> List(String) - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -@target(erlang) -type Direction { - All -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) - -@target(erlang) -fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn do_split( - builder builder: StringBuilder, - pattern pattern: String, -) -> List(StringBuilder) - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -@target(erlang) -fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, -) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) -} - -@target(erlang) -@external(erlang, "string", "replace") -fn erl_replace( - a: StringBuilder, - b: String, - c: String, - d: Direction, -) -> StringBuilder - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_replace") -fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -@external(erlang, "string", "equal") -@external(javascript, "../gleam_stdlib.mjs", "equal") -fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -@target(erlang) -@external(erlang, "string", "is_empty") -fn do_is_empty(a: StringBuilder) -> Bool - -@target(javascript) -fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 11f6ea68cd2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,462 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/string -import gleam/string_builder.{type StringBuilder} -@target(javascript) -import gleam/pair -@target(javascript) -import gleam/regex -@target(javascript) -import gleam/result - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "uri_parse") -fn do_parse(a: String) -> Result(Uri, Nil) - -@target(javascript) -fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) -} - -@target(javascript) -fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) -} - -@target(javascript) -fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } -} - -@target(javascript) -fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } -} - -// Split an authority into its userinfo, host and port parts. -@target(javascript) -fn split_authority( - authority: Option(String), -) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } -} - -@target(javascript) -fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) -} - -@target(javascript) -fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -@external(erlang, "gleam_stdlib", "parse_query") -@external(javascript, "../gleam_stdlib.mjs", "parse_query") -fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -@external(erlang, "gleam_stdlib", "percent_encode") -@external(javascript, "../gleam_stdlib.mjs", "percent_encode") -fn do_percent_encode(a: String) -> String - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -@external(erlang, "gleam_stdlib", "percent_decode") -@external(javascript, "../gleam_stdlib.mjs", "percent_decode") -fn do_percent_decode(a: String) -> Result(String, Nil) - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - _, _, _ -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - _ -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65bc3f63e4d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - gleam@bit_array:base64_encode(Input, Padding). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - gleam@bit_array:base64_decode(Encoded). - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - gleam@bit_array:base64_url_encode(Input, Padding). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl deleted file mode 100644 index ba18dfaabdd..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_array.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(gleam@bit_array). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_arrays) -> - gleam_stdlib:bit_array_concat(Bit_arrays). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam_stdlib:bit_array_concat([First, Second]). - --spec base64_encode(bitstring(), boolean()) -> binary(). -base64_encode(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_decode(Encoded) -> - Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec base64_url_encode(bitstring(), boolean()) -> binary(). -base64_url_encode(Input, Padding) -> - _pipe = base64_encode(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_url_decode(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - base64_decode(_pipe@2). - --spec base16_encode(bitstring()) -> binary(). -base16_encode(Input) -> - binary:encode_hex(Input). - --spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base16_decode(Input) -> - gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 284c6d46cc3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,66 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). - --spec new() -> gleam@bytes_builder:bytes_builder(). -new() -> - gleam@bytes_builder:new(). - --spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -prepend(To, Prefix) -> - gleam@bytes_builder:prepend(To, Prefix). - --spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -append(To, Suffix) -> - gleam@bytes_builder:append(To, Suffix). - --spec prepend_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -prepend_builder(To, Prefix) -> - gleam@bytes_builder:prepend_builder(To, Prefix). - --spec append_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -prepend_string(To, Prefix) -> - gleam@bytes_builder:prepend_string(To, Prefix). - --spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -append_string(To, Suffix) -> - gleam@bytes_builder:append_string(To, Suffix). - --spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 7dabaa3bbc1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam@bit_array:append(First, Second). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - gleam@bit_array:is_utf8(Bits). - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - gleam@bit_array:to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index 5f95f4d8314..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,162 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. - --spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. -lazy_guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence(); - - false -> - Alternative() - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl deleted file mode 100644 index 2f6dd93a9f3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl +++ /dev/null @@ -1,87 +0,0 @@ --module(gleam@bytes_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). --export_type([bytes_builder/0]). - --opaque bytes_builder() :: {bytes, bitstring()} | - {text, gleam@string_builder:string_builder()} | - {many, list(bytes_builder())}. - --spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -prepend_builder(Second, First) -> - gleam_stdlib:iodata_append(First, Second). - --spec concat(list(bytes_builder())) -> bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec new() -> bytes_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_string(binary()) -> bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). -prepend_string(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append_string(bytes_builder(), binary()) -> bytes_builder(). -append_string(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_array(bitstring()) -> bytes_builder(). -from_bit_array(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). -prepend(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append(bytes_builder(), bitstring()) -> bytes_builder(). -append(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). -concat_bit_arrays(Bits) -> - gleam_stdlib:identity(Bits). - --spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). -to_list(Stack, Acc) -> - case Stack of - [] -> - Acc; - - [[] | Remaining_stack] -> - to_list(Remaining_stack, Acc); - - [[{bytes, Bits} | Rest] | Remaining_stack@1] -> - to_list([Rest | Remaining_stack@1], [Bits | Acc]); - - [[{text, Builder} | Rest@1] | Remaining_stack@2] -> - Bits@1 = gleam_stdlib:identity( - gleam@string_builder:to_string(Builder) - ), - to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); - - [[{many, Builders} | Rest@2] | Remaining_stack@3] -> - to_list([Builders, Rest@2 | Remaining_stack@3], Acc) - end. - --spec to_bit_array(bytes_builder()) -> bitstring(). -to_bit_array(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl deleted file mode 100644 index 99c231e18cc..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dict.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@dict). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). --export_type([dict/2]). - --type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. - --spec size(dict(any(), any())) -> integer(). -size(Dict) -> - maps:size(Dict). - --spec to_list(dict(NZ, OA)) -> list({NZ, OA}). -to_list(Dict) -> - maps:to_list(Dict). - --spec from_list(list({OJ, OK})) -> dict(OJ, OK). -from_list(List) -> - maps:from_list(List). - --spec has_key(dict(OT, any()), OT) -> boolean(). -has_key(Dict, Key) -> - maps:is_key(Key, Dict). - --spec new() -> dict(any(), any()). -new() -> - maps:new(). - --spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). -insert(Dict, Key, Value) -> - maps:put(Key, Value, Dict). - --spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). -map_values(Dict, Fun) -> - maps:map(Fun, Dict). - --spec keys(dict(QV, any())) -> list(QV). -keys(Dict) -> - maps:keys(Dict). - --spec values(dict(any(), RG)) -> list(RG). -values(Dict) -> - maps:values(Dict). - --spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). -filter(Dict, Predicate) -> - maps:filter(Predicate, Dict). - --spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). -take(Dict, Desired_keys) -> - maps:with(Desired_keys, Dict). - --spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). -merge(Dict, New_entries) -> - maps:merge(Dict, New_entries). - --spec delete(dict(TF, TG), TF) -> dict(TF, TG). -delete(Dict, Key) -> - maps:remove(Key, Dict). - --spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). -drop(Dict, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Dict; - - [X | Xs] -> - drop(delete(Dict, X), Xs) - end. - --spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). -update(Dict, Key, Fun) -> - _pipe = Dict, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Dict, Key, _pipe@3). - --spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. -fold(Dict, Initial, Fun) -> - _pipe = Dict, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 2c6016f4222..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,808 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). - --type dynamic_() :: any(). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type unknown_tuple() :: any(). - --spec from(any()) -> dynamic_(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic_()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_array(Data) -> - gleam_stdlib:decode_bit_array(Data). - --spec bit_string(dynamic_()) -> {ok, bitstring()} | - {error, list(decode_error())}. -bit_string(Data) -> - bit_array(Data). - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec classify(dynamic_()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - gleam@option:option(DGM)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, - DKT} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((DKX) -> DKY), - fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec result( - fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - list(DGH)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec map_errors( - {ok, DEV} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, DEV} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec decode_string(dynamic_()) -> {ok, binary()} | - {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_array(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_array:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitArray"/utf8>>, - []}]} - end end - ). - --spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec field( - any(), - fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec dict( - fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | - {error, list(decode_error())}). -dict(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@dict:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end - ) - end - ) - end. - --spec map( - fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - dict(Key_type, Value_type). - --spec decode2( - fun((DLB, DLC) -> DLD), - fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((DLH, DLI, DLJ) -> DLK), - fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((DLP, DLQ, DLR, DLS) -> DLT), - fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((DLZ, DMA, DMB, DMC, DMD) -> DME), - fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), - fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), - fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), - fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), - fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index 33b3d4a3e3f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,181 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= +0.0 of - true -> - X; - - _ -> - +0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > +0.0, - case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent - < +0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, +0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. - --spec random(float(), float()) -> float(). -random(Min, Max) -> - (rand:uniform() * (Max - Min)) + Min. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - +0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - +0.0 -> +0.0; - -0.0 -> -0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index c58c0fe151b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(AS) -> AS. -identity(X) -> - X. - --spec constant(AT) -> fun((any()) -> AT). -constant(Value) -> - fun(_) -> Value end. - --spec tap(AV, fun((AV) -> any())) -> AV. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((AX) -> AY), AX) -> AY. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 2a5dd2c8a1d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,332 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. - --spec random(integer(), integer()) -> integer(). -random(Min, Max) -> - _pipe = gleam@float:random(to_float(Min), to_float(Max)), - _pipe@1 = gleam@float:floor(_pipe), - gleam@float:round(_pipe@1). - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec bitwise_and(integer(), integer()) -> integer(). -bitwise_and(X, Y) -> - erlang:'band'(X, Y). - --spec bitwise_not(integer()) -> integer(). -bitwise_not(X) -> - erlang:'bnot'(X). - --spec bitwise_or(integer(), integer()) -> integer(). -bitwise_or(X, Y) -> - erlang:'bor'(X, Y). - --spec bitwise_exclusive_or(integer(), integer()) -> integer(). -bitwise_exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec bitwise_shift_left(integer(), integer()) -> integer(). -bitwise_shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec bitwise_shift_right(integer(), integer()) -> integer(). -bitwise_shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index 82865bbafa6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(ENH) -> ENH. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index a667ae1ac4b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,744 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. - --opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. - --type step(BSE, BSF) :: {next, BSE, BSF} | done. - --type chunk(BSG, BSH) :: {another_by, - list(BSG), - BSH, - BSG, - fun(() -> action(BSG))} | - {last_by, list(BSG)}. - --type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | - {last, list(BSI)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BSV)) -> iterator(BSV). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BSX) -> iterator(BSX). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BSZ)) -> iterator(BSZ). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec do_transform( - fun(() -> action(BTC)), - BTE, - fun((BTE, BTC) -> step(BTF, BTE)) -) -> fun(() -> action(BTF)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BTY)) -> list(BTY). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BUJ), integer()) -> iterator(BUJ). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BUP), integer()) -> iterator(BUP). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec do_map2( - fun(() -> action(BVA)), - fun(() -> action(BVC)), - fun((BVA, BVC) -> BVE) -) -> fun(() -> action(BVE)). -do_map2(Continuation1, Continuation2, Fun) -> - fun() -> case Continuation1() of - stop -> - stop; - - {continue, A, Next_a} -> - case Continuation2() of - stop -> - stop; - - {continue, B, Next_b} -> - {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} - end - end end. - --spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). -map2(Iterator1, Iterator2, Fun) -> - _pipe = do_map2( - erlang:element(2, Iterator1), - erlang:element(2, Iterator2), - Fun - ), - {iterator, _pipe}. - --spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BVY))) -> iterator(BVY). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec concat(list(iterator(BWC))) -> iterator(BWC). -concat(Iterators) -> - flatten(from_list(Iterators)). - --spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec cycle(iterator(BWR)) -> iterator(BWR). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), - BXD})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BXG)) -> iterator({integer(), BXG}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, - BYH})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BZU), BZU) -> iterator(BZU). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), - gleam@dict:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> CBH)) -> iterator(CBH). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec single(CBJ) -> iterator(CBJ). -single(Elem) -> - once(fun() -> Elem end). - --spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(CBT)), - fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), - CBV -) -> CBV. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(CBX), - CBZ, - fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) -) -> CBZ. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(CCB)), - fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), - CCD -) -> {ok, CCD} | {error, CCE}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, - CCL} | - {error, CCM}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). - --spec each(iterator(CDD), fun((CDD) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). -yield(Element, Next) -> - {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index cb6c9e44af2..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1136 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(XF)) -> list(XF). -reverse(Xs) -> - lists:reverse(Xs). - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec contains(list(XN), XN) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec first(list(XP)) -> {ok, XP} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@dict:insert(Groups, F(Elem), [Elem]) - end end. - --spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). -map(List, Fun) -> - do_map(List, Fun, []). - --spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). -do_map2(List1, List2, Fun, Acc) -> - case {List1, List2} of - {[], _} -> - reverse(Acc); - - {_, []} -> - reverse(Acc); - - {[A | As_], [B | Bs]} -> - do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) - end. - --spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). -map2(List1, List2, Fun) -> - do_map2(List1, List2, Fun, []). - --spec do_index_map( - list(ABJ), - fun((integer(), ABJ) -> ABL), - integer(), - list(ABL) -) -> list(ABL). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, - list(ABU)} | - {error, ABV}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, - list(ACE)} | - {error, ACF}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(ACL), integer()) -> list(ACL). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(ACS), integer()) -> list(ACS). -take(List, N) -> - do_take(List, N, []). - --spec new() -> list(any()). -new() -> - []. - --spec append(list(ACX), list(ACX)) -> list(ACX). -append(First, Second) -> - lists:append(First, Second). - --spec prepend(list(ADF), ADF) -> list(ADF). -prepend(List, Item) -> - [Item | List]. - --spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). -do_concat(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_concat(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec concat(list(list(ADR))) -> list(ADR). -concat(Lists) -> - do_concat(Lists, []). - --spec flatten(list(list(ADV))) -> list(ADV). -flatten(Lists) -> - do_concat(Lists, []). - --spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - concat(_pipe). - --spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). -group(List, Key) -> - fold(List, gleam@dict:new(), update_group(Key)). - --spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, - list(ABH)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold( - list(AEK), - AEM, - fun((AEM, AEK, integer()) -> AEM), - integer() -) -> AEM. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, - AES} | - {error, AET}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(AGX), AGX) -> list(AGX). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec unique(list(AHE)) -> list(AHE). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(AHH), - list(AHH), - list(AHH), - fun((AHH, AHH) -> gleam@order:order()) -) -> list(AHH). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_down( - integer(), - integer(), - list(AHM), - list(AHM), - list(AHM), - fun((AHM, AHM) -> gleam@order:order()) -) -> list(AHM). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_sort( - list(AHR), - integer(), - fun((AHR, AHR) -> gleam@order:order()), - boolean() -) -> list(AHR). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - [Stop | Acc]; - - gt -> - tail_recursive_range(Start, Stop + 1, [Stop | Acc]); - - lt -> - tail_recursive_range(Start, Stop - 1, [Stop | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(AID, integer()) -> list(AID). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), - list(AIO)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). -key_filter(Keyword_list, Desired_key) -> - filter_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, - {AZQ, list(AZQ)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, - {BAR, list(BAE)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, - {AJV, list(AJT)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AKM), fun((AKM) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | - {error, AKS}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), - list(BBY)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(ALG)) -> list(list(ALG)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - concat(_pipe@5) - end. - --spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(ALQ), integer()) -> list(list(ALQ)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec window_by_2(list(ALU)) -> list({ALU, ALU}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AMU), - integer(), - integer(), - list(AMU), - list(list(AMU)) -) -> list(list(AMU)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec last(list(ANS)) -> {ok, ANS} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec combinations(list(ANW), integer()) -> list(list(ANW)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(AOE)) -> list({AOE, AOE}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - concat(_pipe). - --spec transpose(list(list(AOL))) -> list(list(AOL)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - concat(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(AOH))) -> list(AOH). -interleave(List) -> - _pipe = transpose(List), - concat(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - [Elem_pair | Enumerable] -> - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec shuffle(list(AOX)) -> list(AOX). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index 9f45b107384..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). - --spec size(gleam@dict:dict(any(), any())) -> integer(). -size(Map) -> - gleam@dict:size(Map). - --spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). -to_list(Map) -> - gleam@dict:to_list(Map). - --spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). -from_list(List) -> - gleam@dict:from_list(List). - --spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). -has_key(Map, Key) -> - gleam@dict:has_key(Map, Key). - --spec new() -> gleam@dict:dict(any(), any()). -new() -> - gleam@dict:new(). - --spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. -get(From, Get) -> - gleam@dict:get(From, Get). - --spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). -insert(Map, Key, Value) -> - gleam@dict:insert(Map, Key, Value). - --spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). -map_values(Map, Fun) -> - gleam@dict:map_values(Map, Fun). - --spec keys(gleam@dict:dict(FED, any())) -> list(FED). -keys(Map) -> - gleam@dict:keys(Map). - --spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). -values(Map) -> - gleam@dict:values(Map). - --spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). -filter(Map, Predicate) -> - gleam@dict:filter(Map, Predicate). - --spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). -take(Map, Desired_keys) -> - gleam@dict:take(Map, Desired_keys). - --spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). -merge(Map, New_entries) -> - gleam@dict:merge(Map, New_entries). - --spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). -delete(Map, Key) -> - gleam@dict:delete(Map, Key). - --spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). -drop(Map, Disallowed_keys) -> - gleam@dict:drop(Map, Disallowed_keys). - --spec update( - gleam@dict:dict(FFB, FFC), - FFB, - fun((gleam@option:option(FFC)) -> FFC) -) -> gleam@dict:dict(FFB, FFC). -update(Map, Key, Fun) -> - gleam@dict:update(Map, Key, Fun). - --spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. -fold(Map, Initial, Fun) -> - gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 812aa1fe854..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). --export_type([option/1]). - --type option(IY) :: {some, IY} | none. - --spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(JF))) -> option(list(JF)). -all(List) -> - do_all(List, []). - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, JU} | {error, any()}) -> option(JU). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(JZ), JZ) -> JZ. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(KD), fun((KD) -> KF)) -> option(KF). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(KH))) -> option(KH). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(KQ), option(KQ)) -> option(KQ). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_values(list(option(KY)), list(KY)) -> list(KY). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(LD))) -> list(LD). -values(Options) -> - do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index a9eed8f39c1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec negate(order()) -> order(). -negate(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. - --spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). -reverse(Orderer) -> - fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index 2452a9817e1..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({IJ, any()}) -> IJ. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), IM}) -> IM. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({IN, IO}) -> {IO, IN}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(IV, IW) -> {IV, IW}. -new(First, Second) -> - {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index faec6923a14..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(EYN)) -> queue(EYN). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(EYQ)) -> list(EYQ). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(EYX), EYX) -> queue(EYX). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(EZA), EZA) -> queue(EZA). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec reverse(queue(EZN)) -> queue(EZN). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec check_equal( - list(EZQ), - list(EZQ), - list(EZQ), - list(EZQ), - fun((EZQ, EZQ) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(EZY), queue(EZY)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index 2d1c5fc870e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([regex/0, match/0, compile_error/0, options/0]). - --type regex() :: any(). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index c80a7048303..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | - {error, BIK}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | - {error, BIU}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | - {error, BIY}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, - BJJ} | - {error, BJG}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, - BJS} | - {error, BJP}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | - {error, BKT}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, - BLA} | - {error, BLB}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), - list(BLY)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. -partition(Results) -> - do_partition(Results, [], []). - --spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BMT} | {error, any()})) -> list(BMT). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BMZ} | {error, BNA}, - fun((BNA) -> {ok, BMZ} | {error, BND}) -) -> {ok, BMZ} | {error, BND}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index 3374ebc293f..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@dict:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@dict:size(erlang:element(2, Set)). - --spec insert(set(EOQ), EOQ) -> set(EOQ). -insert(Set, Member) -> - {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(EOT), EOT) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@dict:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(EOV), EOV) -> set(EOV). -delete(Set, Member) -> - {set, gleam@dict:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(EOY)) -> list(EOY). -to_list(Set) -> - gleam@dict:keys(erlang:element(2, Set)). - --spec from_list(list(EPB)) -> set(EPB). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@dict:new(), - fun(M, K) -> gleam@dict:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. -fold(Set, Initial, Reducer) -> - gleam@dict:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). -filter(Set, Predicate) -> - {set, - gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. - --spec drop(set(EPK), list(EPK)) -> set(EPK). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(EPO), list(EPO)) -> set(EPO). -take(Set, Desired) -> - {set, gleam@dict:take(erlang:element(2, Set), Desired)}. - --spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. -order(First, Second) -> - case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(EPX), set(EPX)) -> set(EPX). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(EQB), set(EQB)) -> set(EQB). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 6cba31d1895..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,352 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - gleam_stdlib:crop_string(String, Substring). - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - gleam_stdlib:contains_string(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_join(list(binary()), binary()) -> binary(). -do_join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - do_join(Strings, Separator). - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_array, Acc) -> - case Bit_array of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - _ -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 693e840f370..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([string_builder/0, direction/0]). - --type string_builder() :: any(). - --type direction() :: all. - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index a36df375281..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,252 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {_, _, _} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(ETW)) -> list(ETW). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - _ -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index 76aa1ea673c..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,31 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.33.1"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_array, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@bytes_builder, - gleam@dict, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index c6ea1257110..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,529 +0,0 @@ --module(gleam_stdlib). - --export([ - map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, - parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, - wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, - bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, - println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, - int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1 -]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - --define(is_lowercase_char(X), (X > 96 andalso X < 123)). --define(is_underscore_char(X), (X == 95)). --define(is_digit_char(X), (X > 47 andalso X < 58)). - -uppercase(X) -> X - 32. - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_array_concat(BitArrays) -> - list_to_bitstring(BitArrays). - -bit_array_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_array_int_to_u32(_) -> - {error, nil}. - -bit_array_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_array_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:_ -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(nil) -> - "Nil"; -inspect(Data) when is_map(Data) -> - Fields = [ - [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] - || {Key, Value} <- maps:to_list(Data) - ], - ["dict.from_list([", lists:join(", ", Fields), "])"]; -inspect(Atom) when is_atom(Atom) -> - Binary = erlang:atom_to_binary(Atom), - case inspect_maybe_gleam_atom(Binary, none, <<>>) of - {ok, Inspected} -> Inspected; - {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] - end; -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(Bits) when is_bitstring(Bits) -> - inspect_bit_array(Bits); -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - - -inspect_maybe_gleam_atom(<<>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc) - when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, $_, Acc); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); -inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> - {ok, Acc}; -inspect_maybe_gleam_atom(A, B, C) -> - erlang:display({A, B, C}), - throw({gleam_error, A, B, C}). - -inspect_list([]) -> - {proper, []}; -inspect_list([First]) -> - {proper, [inspect(First)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_bit_array(Bits) -> - Text = inspect_bit_array(Bits, <<"<<">>), - <<Text/binary, ">>">>. - -inspect_bit_array(<<>>, Acc) -> - Acc; -inspect_bit_array(<<X, Rest/bitstring>>, Acc) -> - inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); -inspect_bit_array(Rest, Acc) -> - Size = bit_size(Rest), - <<X:Size>> = Rest, - X1 = erlang:integer_to_binary(X), - Size1 = erlang:integer_to_binary(Size), - Segment = <<X1/binary, ":size(", Size1/binary, ")">>, - inspect_bit_array(<<>>, append_segment(Acc, Segment)). - -append_segment(<<"<<">>, Segment) -> - <<"<<", Segment/binary>>; -append_segment(Acc, Segment) -> - <<Acc/binary, ", ", Segment/binary>>. - - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<First/utf8, Rest/binary>> -> - Escaped = case First of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). - -utf_codepoint_list_to_string(List) -> - case unicode:characters_to_binary(List) of - {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); - Binary -> Binary - end. - -crop_string(String, Prefix) -> - case string:find(String, Prefix) of - nomatch -> String; - New -> New - end. - -contains_string(String, Substring) -> - is_bitstring(string:find(String, Substring)). - -base16_decode(String) -> - try - {ok, binary:decode_hex(String)} - catch - _:_ -> {error, nil} - end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index 45c28cfc87b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,878 +0,0 @@ -import { - BitArray, - Error, - List, - Ok, - Result, - UtfCodepoint, - stringBits, - toBitArray, - NonEmpty, - CustomType, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import Dict from "./dict.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - const iterator = graphemes_iterator(string); - if (iterator) { - return List.fromArray(Array.from(iterator).map((item) => item.segment)); - } else { - return List.fromArray(string.match(/./gsu)); - } -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs, separator) { - const iterator = xs[Symbol.iterator](); - let result = iterator.next().value || ""; - let current = iterator.next(); - while (!current.done) { - result = result + separator + current.value; - current = iterator.next(); - } - return result; -} - -export function concat(xs) { - let result = ""; - for (const x of xs) { - result = result + x; - } - return result; -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function contains_string(haystack, needle) { - return haystack.indexOf(needle) >= 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_array_from_string(string) { - return toBitArray([stringBits(string)]); -} - -export function bit_array_concat(bit_arrays) { - return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_array_to_string(bit_array) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_array.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_array_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitArray(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return Dict.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_array) { - const aBytes = bit_array.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitArray(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (data instanceof Result) { - return "Result"; - } else if (data instanceof List) { - return "List"; - } else if (data instanceof BitArray) { - return "BitArray"; - } else if (data instanceof Dict) { - return "Map"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_array(data) { - if (data instanceof BitArray) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitArray(data)); - } - return decoder_error("BitArray", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - const list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!(data instanceof List)) return; - - const elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (!(current instanceof NonEmpty)) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && !(current instanceof NonEmpty)) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return data instanceof List ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return data instanceof Result ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof Dict) { - return new Ok(Dict.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(Dict.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof Dict || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} - -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function bitwise_and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function bitwise_not(x) { - return Number(~BigInt(x)); -} - -export function bitwise_or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function bitwise_exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function bitwise_shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function bitwise_shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} - -export function inspect(v) { - const t = typeof v; - if (v === true) return "True"; - if (v === false) return "False"; - if (v === null) return "//js(null)"; - if (v === undefined) return "Nil"; - if (t === "string") return JSON.stringify(v); - if (t === "bigint" || t === "number") return v.toString(); - if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; - if (v instanceof List) return inspectList(v); - if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); - if (v instanceof BitArray) return inspectBitArray(v); - if (v instanceof CustomType) return inspectCustomType(v); - if (v instanceof Dict) return inspectDict(v); - if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; - if (v instanceof RegExp) return `//js(${v})`; - if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; - if (v instanceof Function) { - const args = []; - for (const i of Array(v.length).keys()) - args.push(String.fromCharCode(i + 97)); - return `//fn(${args.join(", ")}) { ... }`; - } - return inspectObject(v); -} - -function inspectDict(map) { - let body = "dict.from_list(["; - let first = true; - map.forEach((value, key) => { - if (!first) body = body + ", "; - body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; - first = false; - }); - return body + "])"; -} - -function inspectObject(v) { - const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; - const props = []; - for (const k of Object.keys(v)) { - props.push(`${inspect(k)}: ${inspect(v[k])}`); - } - const body = props.length ? " " + props.join(", ") + " " : ""; - const head = name === "Object" ? "" : name + " "; - return `//js(${head}{${body}})`; -} - -function inspectCustomType(record) { - const props = Object.keys(record) - .map((label) => { - const value = inspect(record[label]); - return isNaN(parseInt(label)) ? `${label}: ${value}` : value; - }) - .join(", "); - return props - ? `${record.constructor.name}(${props})` - : record.constructor.name; -} - -export function inspectList(list) { - return `[${list.toArray().map(inspect).join(", ")}]`; -} - -export function inspectBitArray(bits) { - return `<<${Array.from(bits.buffer).join(", ")}>>`; -} - -export function inspectUtfCodepoint(codepoint) { - return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; -} - -export function base16_encode(bit_array) { - let result = ""; - for (const byte of bit_array.buffer) { - result += byte.toString(16).padStart(2, "0").toUpperCase(); - } - return result; -} - -export function base16_decode(string) { - const bytes = new Uint8Array(string.length / 2); - for (let i = 0; i < string.length; i += 2) { - const a = parseInt(string[i], 16); - const b = parseInt(string[i + 1], 16); - if (isNaN(a) || isNaN(b)) return new Error(Nil); - bytes[i / 2] = a * 16 + b; - } - return new Ok(new BitArray(bytes)); -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml deleted file mode 100644 index 08c866301c6..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/packages/packages.toml +++ /dev/null @@ -1,2 +0,0 @@ -[packages] -gleam_stdlib = "0.33.1" diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml deleted file mode 100644 index 74b7e202e47..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleeunit" -version = "0.11.0" -licences = ["Apache-2.0"] -description = "Gleam bindings to Erlang's EUnit test framework" - -[javascript.deno] -allow_read = [ - "gleam.toml", - "test", - "build", -] - -[dependencies] -gleam_stdlib = "~> 0.27" - -[dev-dependencies] -# some_test_package = "~> 1.0.0" diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml deleted file mode 100644 index 913de938d95..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/manifest.toml +++ /dev/null @@ -1,9 +0,0 @@ -# This file was generated by Gleam -# You typically do not need to edit this file - -packages = [ - { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, -] - -[requirements] -gleam_stdlib = { version = "~> 0.27" } diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src deleted file mode 100644 index 2f98842c95e..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, gleeunit, [ - {vsn, "0.11.0"}, - {applications, [gleam_stdlib]}, - {description, "Gleam bindings to Erlang's EUnit test framework"}, - {modules, [gleeunit, - gleeunit@should]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl deleted file mode 100644 index 32e1a833d01..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gleeunit). --compile([no_auto_import, nowarn_unused_vars]). - --export([main/0]). --export_type([atom_/0, encoding/0, report_module_name/0, gleeunit_progress_option/0, eunit_option/0]). - --type atom_() :: any(). - --type encoding() :: utf8. - --type report_module_name() :: gleeunit_progress. - --type gleeunit_progress_option() :: {colored, boolean()}. - --type eunit_option() :: verbose | - no_tty | - {report, {report_module_name(), list(gleeunit_progress_option())}}. - --spec gleam_to_erlang_module_name(binary()) -> binary(). -gleam_to_erlang_module_name(Path) -> - _pipe = Path, - _pipe@1 = gleam@string:replace(_pipe, <<".gleam"/utf8>>, <<""/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<".erl"/utf8>>, <<""/utf8>>), - gleam@string:replace(_pipe@2, <<"/"/utf8>>, <<"@"/utf8>>). - --spec do_main() -> nil. -do_main() -> - Options = [verbose, - no_tty, - {report, {gleeunit_progress, [{colored, true}]}}], - Result = begin - _pipe = gleeunit_ffi:find_files( - <<"**/*.{erl,gleam}"/utf8>>, - <<"test"/utf8>> - ), - _pipe@1 = gleam@list:map(_pipe, fun gleam_to_erlang_module_name/1), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(_capture) -> erlang:binary_to_atom(_capture, utf8) end - ), - _pipe@3 = eunit:test(_pipe@2, Options), - _pipe@4 = (gleam@dynamic:result( - fun gleam@dynamic:dynamic/1, - fun gleam@dynamic:dynamic/1 - ))(_pipe@3), - gleam@result:unwrap(_pipe@4, {error, gleam@dynamic:from(nil)}) - end, - Code = case Result of - {ok, _} -> - 0; - - {error, _} -> - 1 - end, - erlang:halt(Code). - --spec main() -> nil. -main() -> - do_main(). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam deleted file mode 100644 index e5d4b460cad..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit.gleam +++ /dev/null @@ -1,92 +0,0 @@ -/// Find and run all test functions for the current project using Erlang's EUnit -/// test framework. -/// -/// Any Erlang or Gleam function in the `test` directory with a name editing in -/// `_test` is considered a test function and will be run. -/// -/// If running on JavaScript tests will be run with a custom test runner. -/// -pub fn main() -> Nil { - do_main() -} - -@target(javascript) -@external(javascript, "./gleeunit_ffi.mjs", "main") -fn do_main() -> Nil - -@target(erlang) -import gleam/list -@target(erlang) -import gleam/result -@target(erlang) -import gleam/string -@target(erlang) -import gleam/dynamic.{Dynamic} - -@target(erlang) -fn do_main() -> Nil { - let options = [Verbose, NoTty, Report(#(GleeunitProgress, [Colored(True)]))] - - let result = - find_files(matching: "**/*.{erl,gleam}", in: "test") - |> list.map(gleam_to_erlang_module_name) - |> list.map(dangerously_convert_string_to_atom(_, Utf8)) - |> run_eunit(options) - |> dynamic.result(dynamic.dynamic, dynamic.dynamic) - |> result.unwrap(Error(dynamic.from(Nil))) - - let code = case result { - Ok(_) -> 0 - Error(_) -> 1 - } - halt(code) -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil - -@target(erlang) -fn gleam_to_erlang_module_name(path: String) -> String { - path - |> string.replace(".gleam", "") - |> string.replace(".erl", "") - |> string.replace("/", "@") -} - -@target(erlang) -@external(erlang, "gleeunit_ffi", "find_files") -fn find_files(matching matching: String, in in: String) -> List(String) - -@target(erlang) -type Atom - -@target(erlang) -type Encoding { - Utf8 -} - -@target(erlang) -@external(erlang, "erlang", "binary_to_atom") -fn dangerously_convert_string_to_atom(a: String, b: Encoding) -> Atom - -@target(erlang) -type ReportModuleName { - GleeunitProgress -} - -@target(erlang) -type GleeunitProgressOption { - Colored(Bool) -} - -@target(erlang) -type EunitOption { - Verbose - NoTty - Report(#(ReportModuleName, List(GleeunitProgressOption))) -} - -@target(erlang) -@external(erlang, "eunit", "test") -fn run_eunit(a: List(Atom), b: List(EunitOption)) -> Dynamic diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam deleted file mode 100644 index c393c232724..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit/should.gleam +++ /dev/null @@ -1,90 +0,0 @@ -//// A module for testing your Gleam code. The functions found here are -//// compatible with the Erlang eunit test framework. -//// -//// More information on running eunit can be found in [the rebar3 -//// documentation](https://rebar3.org/docs/testing/eunit/). - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_equal") -pub fn equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_not_equal") -pub fn not_equal(a: a, b: a) -> Nil - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_ok") -pub fn be_ok(a: Result(a, b)) -> a - -@target(erlang) -@external(erlang, "gleeunit_ffi", "should_be_error") -pub fn be_error(a: Result(a, b)) -> b - -@target(javascript) -import gleam/string - -@target(javascript) -@external(javascript, "../gleam.mjs", "inspect") -fn stringify(a: anything) -> String - -@target(javascript) -@external(javascript, "../gleeunit_ffi.mjs", "crash") -fn crash(a: String) -> anything - -@target(javascript) -pub fn equal(a, b) { - case a == b { - True -> Nil - _ -> - crash(string.concat([ - "\n\t", - stringify(a), - "\n\tshould equal \n\t", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn not_equal(a, b) { - case a != b { - True -> Nil - _ -> - crash(string.concat([ - "\n", - stringify(a), - "\nshould not equal \n", - stringify(b), - ])) - } -} - -@target(javascript) -pub fn be_ok(a) { - case a { - Ok(value) -> value - _ -> crash(string.concat(["\n", stringify(a), "\nshould be ok"])) - } -} - -@target(javascript) -pub fn be_error(a) { - case a { - Error(error) -> error - _ -> crash(string.concat(["\n", stringify(a), "\nshould be error"])) - } -} - -pub fn be_true(actual: Bool) -> Nil { - actual - |> equal(True) -} - -pub fn be_false(actual: Bool) -> Nil { - actual - |> equal(False) -} - -pub fn fail() -> Nil { - be_true(False) -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl deleted file mode 100644 index acf032e1e7d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit@should.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(gleeunit@should). --compile([no_auto_import, nowarn_unused_vars]). - --export([equal/2, not_equal/2, be_ok/1, be_error/1, be_true/1, be_false/1, fail/0]). - --spec equal(EYG, EYG) -> nil. -equal(A, B) -> - gleeunit_ffi:should_equal(A, B). - --spec not_equal(EYH, EYH) -> nil. -not_equal(A, B) -> - gleeunit_ffi:should_not_equal(A, B). - --spec be_ok({ok, EYI} | {error, any()}) -> EYI. -be_ok(A) -> - gleeunit_ffi:should_be_ok(A). - --spec be_error({ok, any()} | {error, EYN}) -> EYN. -be_error(A) -> - gleeunit_ffi:should_be_error(A). - --spec be_true(boolean()) -> nil. -be_true(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, true). - --spec be_false(boolean()) -> nil. -be_false(Actual) -> - _pipe = Actual, - gleeunit_ffi:should_equal(_pipe, false). - --spec fail() -> nil. -fail() -> - be_true(false). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl deleted file mode 100644 index 31f9ef9e2c9..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(gleeunit_ffi). - --export([find_files/2, should_equal/2, should_not_equal/2, should_be_ok/1, - should_be_error/1]). - --include_lib("eunit/include/eunit.hrl"). - -find_files(Pattern, In) -> - Results = filelib:wildcard(binary_to_list(Pattern), binary_to_list(In)), - lists:map(fun list_to_binary/1, Results). - - -should_equal(Actual, Expected) -> - ?assertEqual(Expected, Actual), - nil. -should_not_equal(Actual, Expected) -> - ?assertNotEqual(Expected, Actual), - nil. -should_be_ok(A) -> - ?assertMatch({ok, _}, A), - element(2, A). -should_be_error(A) -> - ?assertMatch({error, _}, A), - element(2, A). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs deleted file mode 100644 index 339a843e5c5..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_ffi.mjs +++ /dev/null @@ -1,101 +0,0 @@ -async function* gleamFiles(directory) { - for (let entry of await read_dir(directory)) { - let path = join_path(directory, entry); - if (path.endsWith(".gleam")) { - yield path; - } else { - try { - yield* gleamFiles(path); - } catch (error) { - // Could not read directory, assume it's a file - } - } - } -} - -async function readRootPackageName() { - let toml = await read_file("gleam.toml", "utf-8"); - for (let line of toml.split("\n")) { - let matches = line.match(/\s*name\s*=\s*"([a-z][a-z0-9_]*)"/); // Match regexp in compiler-cli/src/new.rs in validate_name() - if (matches) return matches[1]; - } - throw new Error("Could not determine package name from gleam.toml"); -} - -export async function main() { - let passes = 0; - let failures = 0; - - let packageName = await readRootPackageName(); - let dist = `../${packageName}/`; - - for await (let path of await gleamFiles("test")) { - let js_path = path.slice("test/".length).replace(".gleam", ".mjs"); - let module = await import(join_path(dist, js_path)); - for (let fnName of Object.keys(module)) { - if (!fnName.endsWith("_test")) continue; - try { - await module[fnName](); - write(`\u001b[32m.\u001b[0m`); - passes++; - } catch (error) { - let moduleName = "\n" + js_path.slice(0, -4); - let line = error.line ? `:${error.line}` : ""; - write(`\n❌ ${moduleName}.${fnName}${line}: ${error}\n`); - failures++; - } - } - } - - console.log(` -${passes + failures} tests, ${failures} failures`); - exit(failures ? 1 : 0); -} - -export function crash(message) { - throw new Error(message); -} - -function write(message) { - if (globalThis.Deno) { - Deno.stdout.writeSync(new TextEncoder().encode(message)); - } else { - process.stdout.write(message); - } -} - -function exit(code) { - if (globalThis.Deno) { - Deno.exit(code); - } else { - process.exit(code); - } -} - -async function read_dir(path) { - if (globalThis.Deno) { - let items = []; - for await (let item of Deno.readDir(path, { withFileTypes: true })) { - items.push(item.name); - } - return items; - } else { - let { readdir } = await import("fs/promises"); - return readdir(path); - } -} - -function join_path(a, b) { - if (a.endsWith("/")) return a + b; - return a + "/" + b; -} - -async function read_file(path) { - if (globalThis.Deno) { - return Deno.readTextFile(path); - } else { - let { readFile } = await import("fs/promises"); - let contents = await readFile(path); - return contents.toString(); - } -} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl deleted file mode 100644 index 1f68eb95e58..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/src/gleeunit_progress.erl +++ /dev/null @@ -1,607 +0,0 @@ -%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters - -%% @doc A listener/reporter for eunit that prints '.' for each -%% success, 'F' for each failure, and 'E' for each error. It can also -%% optionally summarize the failures at the end. --compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). --module(gleeunit_progress). --behaviour(eunit_listener). --define(NOTEST, true). --include_lib("eunit/include/eunit.hrl"). - --define(RED, "\e[0;31m"). --define(GREEN, "\e[0;32m"). --define(YELLOW, "\e[0;33m"). --define(WHITE, "\e[0;37m"). --define(CYAN, "\e[0;36m"). --define(RESET, "\e[0m"). - --record(node,{ - rank = 0 :: non_neg_integer(), - key :: term(), - value :: term(), - children = new() :: binomial_heap() - }). - --export_type([binomial_heap/0, heap_node/0]). --type binomial_heap() :: [ heap_node() ]. --type heap_node() :: #node{}. - -%% eunit_listener callbacks --export([ - init/1, - handle_begin/3, - handle_end/3, - handle_cancel/3, - terminate/2, - start/0, - start/1 - ]). - -%% -- binomial_heap.erl content start -- - --record(state, { - status = dict:new() :: euf_dict(), - failures = [] :: [[pos_integer()]], - skips = [] :: [[pos_integer()]], - timings = new() :: binomial_heap(), - colored = true :: boolean(), - profile = false :: boolean() - }). - --type euf_dict() :: dict:dict(). - --spec new() -> binomial_heap(). -new() -> - []. - -% Inserts a new pair into the heap (or creates a new heap) --spec insert(term(), term()) -> binomial_heap(). -insert(Key,Value) -> - insert(Key,Value,[]). - --spec insert(term(), term(), binomial_heap()) -> binomial_heap(). -insert(Key,Value,Forest) -> - insTree(#node{key=Key,value=Value},Forest). - -% Merges two heaps --spec merge(binomial_heap(), binomial_heap()) -> binomial_heap(). -merge(TS1,[]) when is_list(TS1) -> TS1; -merge([],TS2) when is_list(TS2) -> TS2; -merge([#node{rank=R1}=T1|TS1]=F1,[#node{rank=R2}=T2|TS2]=F2) -> - if - R1 < R2 -> - [T1 | merge(TS1,F2)]; - R2 < R1 -> - [T2 | merge(F1, TS2)]; - true -> - insTree(link(T1,T2),merge(TS1,TS2)) - end. - -% Deletes the top entry from the heap and returns it --spec delete(binomial_heap()) -> {{term(), term()}, binomial_heap()}. -delete(TS) -> - {#node{key=Key,value=Value,children=TS1},TS2} = getMin(TS), - {{Key,Value},merge(lists:reverse(TS1),TS2)}. - -% Turns the heap into list in heap order --spec to_list(binomial_heap()) -> [{term(), term()}]. -to_list([]) -> []; -to_list(List) when is_list(List) -> - to_list([],List). -to_list(Acc, []) -> - lists:reverse(Acc); -to_list(Acc,Forest) -> - {Next, Trees} = delete(Forest), - to_list([Next|Acc], Trees). - -% Take N elements from the top of the heap --spec take(non_neg_integer(), binomial_heap()) -> [{term(), term()}]. -take(N,Trees) when is_integer(N), is_list(Trees) -> - take(N,Trees,[]). -take(0,_Trees,Acc) -> - lists:reverse(Acc); -take(_N,[],Acc)-> - lists:reverse(Acc); -take(N,Trees,Acc) -> - {Top,T2} = delete(Trees), - take(N-1,T2,[Top|Acc]). - -% Get an estimate of the size based on the binomial property --spec size(binomial_heap()) -> non_neg_integer(). -size(Forest) -> - erlang:trunc(lists:sum([math:pow(2,R) || #node{rank=R} <- Forest])). - -%% Private API --spec link(heap_node(), heap_node()) -> heap_node(). -link(#node{rank=R,key=X1,children=C1}=T1,#node{key=X2,children=C2}=T2) -> - case X1 < X2 of - true -> - T1#node{rank=R+1,children=[T2|C1]}; - _ -> - T2#node{rank=R+1,children=[T1|C2]} - end. - -insTree(Tree, []) -> - [Tree]; -insTree(#node{rank=R1}=T1, [#node{rank=R2}=T2|Rest] = TS) -> - case R1 < R2 of - true -> - [T1|TS]; - _ -> - insTree(link(T1,T2),Rest) - end. - -getMin([T]) -> - {T,[]}; -getMin([#node{key=K} = T|TS]) -> - {#node{key=K1} = T1,TS1} = getMin(TS), - case K < K1 of - true -> {T,TS}; - _ -> {T1,[T|TS1]} - end. - -%% -- binomial_heap.erl content end -- - -%% Startup -start() -> - start([]). - -start(Options) -> - eunit_listener:start(?MODULE, Options). - -%%------------------------------------------ -%% eunit_listener callbacks -%%------------------------------------------ -init(Options) -> - #state{colored=proplists:get_bool(colored, Options), - profile=proplists:get_bool(profile, Options)}. - -handle_begin(group, Data, St) -> - GID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(GID, orddict:from_list([{type, group}|Data]), Dict)}; -handle_begin(test, Data, St) -> - TID = proplists:get_value(id, Data), - Dict = St#state.status, - St#state{status=dict:store(TID, orddict:from_list([{type, test}|Data]), Dict)}. - -handle_end(group, Data, St) -> - St#state{status=merge_on_end(Data, St#state.status)}; -handle_end(test, Data, St) -> - NewStatus = merge_on_end(Data, St#state.status), - St1 = print_progress(Data, St), - St2 = record_timing(Data, St1), - St2#state{status=NewStatus}. - -handle_cancel(_, Data, #state{status=Status, skips=Skips}=St) -> - Status1 = merge_on_end(Data, Status), - ID = proplists:get_value(id, Data), - St#state{status=Status1, skips=[ID|Skips]}. - -terminate({ok, Data}, St) -> - print_failures(St), - print_pending(St), - print_profile(St), - print_timing(St), - print_results(Data, St); -terminate({error, Reason}, St) -> - io:nl(), io:nl(), - print_colored(io_lib:format("Eunit failed: ~25p~n", [Reason]), ?RED, St), - sync_end(error). - -sync_end(Result) -> - receive - {stop, Reference, ReplyTo} -> - ReplyTo ! {result, Reference, Result}, - ok - end. - -%%------------------------------------------ -%% Print and collect information during run -%%------------------------------------------ -print_progress(Data, St) -> - TID = proplists:get_value(id, Data), - case proplists:get_value(status, Data) of - ok -> - print_progress_success(St), - St; - {skipped, _Reason} -> - print_progress_skipped(St), - St#state{skips=[TID|St#state.skips]}; - {error, Exception} -> - print_progress_failed(Exception, St), - St#state{failures=[TID|St#state.failures]} - end. - -record_timing(Data, State=#state{timings=T, profile=true}) -> - TID = proplists:get_value(id, Data), - case lists:keyfind(time, 1, Data) of - {time, Int} -> - %% It's a min-heap, so we insert negative numbers instead - %% of the actuals and normalize when we report on them. - T1 = insert(-Int, TID, T), - State#state{timings=T1}; - false -> - State - end; -record_timing(_Data, State) -> - State. - -print_progress_success(St) -> - print_colored(".", ?GREEN, St). - -print_progress_skipped(St) -> - print_colored("*", ?YELLOW, St). - -print_progress_failed(_Exc, St) -> - print_colored("F", ?RED, St). - -merge_on_end(Data, Dict) -> - ID = proplists:get_value(id, Data), - dict:update(ID, - fun(Old) -> - orddict:merge(fun merge_data/3, Old, orddict:from_list(Data)) - end, Dict). - -merge_data(_K, undefined, X) -> X; -merge_data(_K, X, undefined) -> X; -merge_data(_K, _, X) -> X. - -%%------------------------------------------ -%% Print information at end of run -%%------------------------------------------ -print_failures(#state{failures=[]}) -> - ok; -print_failures(#state{failures=Fails}=State) -> - io:nl(), - io:fwrite("Failures:~n",[]), - lists:foldr(print_failure_fun(State), 1, Fails), - ok. - -print_failure_fun(#state{status=Status}=State) -> - fun(Key, Count) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:fwrite("~n ~p) ~ts~n", [Count, TestId]), - print_failure_reason(proplists:get_value(status, TestData), - proplists:get_value(output, TestData), - State), - io:nl(), - Count + 1 - end. - -print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> - X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), - print_colored(X, ?CYAN, State); -print_gleam_location(_, _) -> - ok. - -inspect(X) -> - gleam@string:inspect(X). - -print_gleam_failure_reason( - #{gleam_error := assert, message := Message, value := Value}, - State -) -> - print_colored(indent(5, "~s~n", [Message]), ?RED, State), - print_colored(indent(5, " value: ", []), ?RED, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State); -print_gleam_failure_reason( - #{gleam_error := todo, message := Message}, - State -) -> - print_colored(indent(5, "todo expression run~n", []), ?RED, State), - print_colored(indent(5, " message: ", []), ?RED, State), - print_colored(indent(0, "~s~n", [Message]), ?RESET, State); -print_gleam_failure_reason(Error, State) -> - print_colored(indent(5, "~p~n", [Error]), ?RED, State). - -% New Gleeunit specific formatters -print_failure_reason( - {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State -) when is_list(Stack) -> - print_gleam_failure_reason(Error, State), - print_gleam_location(Error, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "No case clause matched~n", []), ?RED, State), - print_colored(indent(5, "Value: ", []), ?CYAN, State), - print_colored(indent(0, "~ts~n", [inspect(Value)]), ?RESET, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -% From the original Erlang version -print_failure_reason({skipped, Reason}, _Output, State) -> - print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), - ?RED, State); -print_failure_reason({error, {_Class, Term, _}}, Output, State) when - is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> - print_assertion_failure(Term, State), - print_failure_output(5, Output, State); -print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> - print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), - print_stack(Stack, State), - print_failure_output(5, Output, State); -print_failure_reason({error, Reason}, Output, State) -> - print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), - print_failure_output(5, Output, State). - -gleam_format_module_name(Module) -> - string:replace(atom_to_list(Module), "@", "/", all). - -print_stack(Stack, State) -> - print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), - print_stackframes(Stack, State). -print_stackframes([{eunit_test, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> - print_stackframes(Stack, State); -print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> - GleamModule = gleam_format_module_name(Module), - print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), - print_stackframes(Stack, State); -print_stackframes([], _State) -> - ok. - - -print_failure_output(_, <<>>, _) -> ok; -print_failure_output(_, undefined, _) -> ok; -print_failure_output(Indent, Output, State) -> - print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). - -print_assertion_failure({Type, Props}, State) -> - FailureDesc = format_assertion_failure(Type, Props, 5), - print_colored(FailureDesc, ?RED, State), - io:nl(). - -print_pending(#state{skips=[]}) -> - ok; -print_pending(#state{status=Status, skips=Skips}=State) -> - io:nl(), - io:fwrite("Pending:~n", []), - lists:foreach(fun(ID) -> - Info = dict:fetch(ID, Status), - case proplists:get_value(reason, Info) of - undefined -> - ok; - Reason -> - print_pending_reason(Reason, Info, State) - end - end, lists:reverse(Skips)), - io:nl(). - -print_pending_reason(Reason0, Data, State) -> - Text = case proplists:get_value(type, Data) of - group -> - io_lib:format(" ~ts~n", [proplists:get_value(desc, Data)]); - test -> - io_lib:format(" ~ts~n", [format_test_identifier(Data)]) - end, - Reason = io_lib:format(" %% ~ts~n", [format_pending_reason(Reason0)]), - print_colored(Text, ?YELLOW, State), - print_colored(Reason, ?CYAN, State). - -print_profile(#state{timings=T, status=Status, profile=true}=State) -> - TopN = take(10, T), - TopNTime = abs(lists:sum([ Time || {Time, _} <- TopN ])), - TLG = dict:fetch([], Status), - TotalTime = proplists:get_value(time, TLG), - if TotalTime =/= undefined andalso TotalTime > 0 andalso TopN =/= [] -> - TopNPct = (TopNTime / TotalTime) * 100, - io:nl(), io:nl(), - io:fwrite("Top ~p slowest tests (~ts, ~.1f% of total time):", [length(TopN), format_time(TopNTime), TopNPct]), - lists:foreach(print_timing_fun(State), TopN), - io:nl(); - true -> ok - end; -print_profile(#state{profile=false}) -> - ok. - -print_timing(#state{status=Status}) -> - TLG = dict:fetch([], Status), - Time = proplists:get_value(time, TLG), - io:nl(), - io:fwrite("Finished in ~ts~n", [format_time(Time)]), - ok. - -print_results(Data, State) -> - Pass = proplists:get_value(pass, Data, 0), - Fail = proplists:get_value(fail, Data, 0), - Skip = proplists:get_value(skip, Data, 0), - Cancel = proplists:get_value(cancel, Data, 0), - Total = Pass + Fail + Skip + Cancel, - {Color, Result} = if Fail > 0 -> {?RED, error}; - Skip > 0; Cancel > 0 -> {?YELLOW, error}; - Pass =:= 0 -> {?YELLOW, ok}; - true -> {?GREEN, ok} - end, - print_results(Color, Total, Fail, Skip, Cancel, State), - sync_end(Result). - -print_results(Color, 0, _, _, _, State) -> - print_colored(Color, "0 tests\n", State); -print_results(Color, Total, Fail, Skip, Cancel, State) -> - SkipText = format_optional_result(Skip, "skipped"), - CancelText = format_optional_result(Cancel, "cancelled"), - Text = io_lib:format("~p tests, ~p failures~ts~ts~n", [Total, Fail, SkipText, CancelText]), - print_colored(Text, Color, State). - -print_timing_fun(#state{status=Status}=State) -> - fun({Time, Key}) -> - TestData = dict:fetch(Key, Status), - TestId = format_test_identifier(TestData), - io:nl(), - io:fwrite(" ~ts~n", [TestId]), - print_colored([" "|format_time(abs(Time))], ?CYAN, State) - end. - -%%------------------------------------------ -%% Print to the console with the given color -%% if enabled. -%%------------------------------------------ -print_colored(Text, Color, #state{colored=true}) -> - io:fwrite("~s~ts~s", [Color, Text, ?RESET]); -print_colored(Text, _Color, #state{colored=false}) -> - io:fwrite("~ts", [Text]). - -%%------------------------------------------ -%% Generic data formatters -%%------------------------------------------ -format_function_name(M, F) -> - M1 = gleam_format_module_name(M), - io_lib:format("~ts.~ts", [M1, F]). - -format_optional_result(0, _) -> - []; -format_optional_result(Count, Text) -> - io_lib:format(", ~p ~ts", [Count, Text]). - -format_test_identifier(Data) -> - {Mod, Fun, _} = proplists:get_value(source, Data), - Line = case proplists:get_value(line, Data) of - 0 -> ""; - L -> io_lib:format(":~p", [L]) - end, - Desc = case proplists:get_value(desc, Data) of - undefined -> ""; - DescText -> io_lib:format(": ~ts", [DescText]) - end, - io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). - -format_time(undefined) -> - "? seconds"; -format_time(Time) -> - io_lib:format("~.3f seconds", [Time / 1000]). - -format_pending_reason({module_not_found, M}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Module '~ts' missing", [M1]); -format_pending_reason({no_such_function, {M,F,_}}) -> - M1 = gleam_format_module_name(M), - io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); -format_pending_reason({exit, Reason}) -> - io_lib:format("Related process exited with reason: ~p", [Reason]); -format_pending_reason(Reason) -> - io_lib:format("Unknown error: ~p", [Reason]). - -%% @doc Formats all the known eunit assertions, you're on your own if -%% you make an assertion yourself. -format_assertion_failure(Type, Props, I) when Type =:= assertion_failed - ; Type =:= assert -> - Keys = proplists:get_keys(Props), - HasEUnitProps = ([expression, value] -- Keys) =:= [], - HasHamcrestProps = ([expected, actual, matcher] -- Keys) =:= [], - if - HasEUnitProps -> - [indent(I, "Failure: ?assert(~ts)~n", [proplists:get_value(expression, Props)]), - indent(I, " expected: true~n", []), - case proplists:get_value(value, Props) of - false -> - indent(I, " got: false", []); - {not_a_boolean, V} -> - indent(I, " got: ~p", [V]) - end]; - HasHamcrestProps -> - [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), - indent(I, " expected: ~ts~n", [inspect(proplists:get_value(expected, Props))]), - indent(I, " got: ~ts", [inspect(proplists:get_value(actual, Props))])]; - true -> - [indent(I, "Failure: unknown assert: ~p", [Props])] - end; - -format_assertion_failure(Type, Props, I) when Type =:= assertMatch_failed - ; Type =:= assertMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed - ; Type =:= assertNotMatch -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertNotMatch(~ts, ~ts)~n", [Pattern, Expr]), - indent(I, " expected not: = ~ts~n", [Pattern]), - indent(I, " got: ~p", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed - ; Type =:= assertEqual -> - Expected = inspect(proplists:get_value(expected, Props)), - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were not equal~n", []), - indent(I, "expected: ~ts~n", [Expected]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed - ; Type =:= assertNotEqual -> - Value = inspect(proplists:get_value(value, Props)), - [indent(I, "Values were equal~n", []), - indent(I, "expected: not ~ts~n,", [Value]), - indent(I, " got: ~ts", [Value])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertException_failed - ; Type =:= assertException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DATA - [indent(I, "Failure: ?assertException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - case proplists:is_defined(unexpected_success, Props) of - true -> - [indent(I, " expected: exception ~ts but nothing was raised~n", [Pattern]), - indent(I, " got: value ~p", [proplists:get_value(unexpected_success, Props)])]; - false -> - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, " expected: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])] - end]; - -format_assertion_failure(Type, Props, I) when Type =:= assertNotException_failed - ; Type =:= assertNotException -> - Expr = proplists:get_value(expression, Props), - Pattern = proplists:get_value(pattern, Props), - {Class, Term} = extract_exception_pattern(Pattern), % I hate that we have to do this, why not just give DAT - Ex = proplists:get_value(unexpected_exception, Props), - [indent(I, "Failure: ?assertNotException(~ts, ~ts, ~ts)~n", [Class, Term, Expr]), - indent(I, " expected not: exception ~ts~n", [Pattern]), - indent(I, " got: exception ~p", [Ex])]; - -format_assertion_failure(Type, Props, I) when Type =:= command_failed - ; Type =:= command -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?cmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmd_failed - ; Type =:= assertCmd -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_status, Props), - Status = proplists:get_value(status, Props), - [indent(I, "Failure: ?assertCmdStatus(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: status ~p~n", [Expected]), - indent(I, " got: status ~p", [Status])]; - -format_assertion_failure(Type, Props, I) when Type =:= assertCmdOutput_failed - ; Type =:= assertCmdOutput -> - Cmd = proplists:get_value(command, Props), - Expected = proplists:get_value(expected_output, Props), - Output = proplists:get_value(output, Props), - [indent(I, "Failure: ?assertCmdOutput(~p, ~p)~n", [Expected, Cmd]), - indent(I, " expected: ~p~n", [Expected]), - indent(I, " got: ~p", [Output])]; - -format_assertion_failure(Type, Props, I) -> - indent(I, "~p", [{Type, Props}]). - -indent(I, Fmt, Args) -> - io_lib:format("~" ++ integer_to_list(I) ++ "s" ++ Fmt, [" "|Args]). - -extract_exception_pattern(Str) -> - ["{", Class, Term|_] = re:split(Str, "[, ]{1,2}", [unicode,{return,list}]), - {Class, Term}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml b/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml deleted file mode 100644 index 44f92f58c1d..00000000000 --- a/test-community-packages-javascript/build/packages/glx/build/packages/packages.toml +++ /dev/null @@ -1,3 +0,0 @@ -[packages] -gleam_stdlib = "0.33.1" -gleeunit = "0.11.0" diff --git a/test-community-packages-javascript/build/packages/glx/gleam.toml b/test-community-packages-javascript/build/packages/glx/gleam.toml deleted file mode 100644 index bbbca2306be..00000000000 --- a/test-community-packages-javascript/build/packages/glx/gleam.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "glx" -version = "0.2.0" -description = "Extensions to the Gleam standard library." -licences = ["MIT"] -repository = { type = "github", user = "maxdeviant", repo = "glx" } - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glx/manifest.toml b/test-community-packages-javascript/build/packages/glx/manifest.toml deleted file mode 100644 index b605eaf19d3..00000000000 --- a/test-community-packages-javascript/build/packages/glx/manifest.toml +++ /dev/null @@ -1,11 +0,0 @@ -# This file was generated by Gleam -# You typically do not need to edit this file - -packages = [ - { name = "gleam_stdlib", version = "0.33.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "3CEAD7B153D896499C78390B22CC968620C27500C922AED3A5DD7B536F922B25" }, - { name = "gleeunit", version = "0.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "1397E5C4AC4108769EE979939AC39BF7870659C5AFB714630DEEEE16B8272AD5" }, -] - -[requirements] -gleam_stdlib = { version = "~> 0.29" } -gleeunit = { version = "~> 0.10" } diff --git a/test-community-packages-javascript/build/packages/glx/src/glx.app.src b/test-community-packages-javascript/build/packages/glx/src/glx.app.src deleted file mode 100644 index c6fc08eca4b..00000000000 --- a/test-community-packages-javascript/build/packages/glx/src/glx.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, glx, [ - {vsn, "0.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Extensions to the Gleam standard library."}, - {modules, [glx@stringx]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam b/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam deleted file mode 100644 index ba8bfd24805..00000000000 --- a/test-community-packages-javascript/build/packages/glx/src/glx/stringx.gleam +++ /dev/null @@ -1,31 +0,0 @@ -//// Extensions to `gleam/string`. - -import gleam/bool.{negate} -import gleam/list -import gleam/regex -import gleam/string - -/// Returns the lines contained in the given string. -/// -/// Supports both `\n` and `\r\n` line endings. -/// -/// ## Examples -/// -/// ```gleam -/// > lines("one\ntwo\n\nthree\n") -/// ["one", "two", "three"] -/// ``` -/// -/// ```gleam -/// > lines("one\r\ntwo\r\n\r\nthree\r\n") -/// ["one", "two", "three"] -/// ``` -pub fn lines(value: String) -> List(String) { - let assert Ok(newline_regex) = regex.from_string("\r?\n") - - let is_not_empty = fn(line) { negate(string.is_empty(line)) } - - value - |> regex.split(with: newline_regex) - |> list.filter(is_not_empty) -} diff --git a/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl b/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl deleted file mode 100644 index 442e47bcd68..00000000000 --- a/test-community-packages-javascript/build/packages/glx/src/glx@stringx.erl +++ /dev/null @@ -1,24 +0,0 @@ --module(glx@stringx). --compile([no_auto_import, nowarn_unused_vars]). - --export([lines/1]). - --spec lines(binary()) -> list(binary()). -lines(Value) -> - _assert_subject = gleam@regex:from_string(<<"\r?\n"/utf8>>), - {ok, Newline_regex} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glx/stringx"/utf8>>, - function => <<"lines"/utf8>>, - line => 24}) - end, - Is_not_empty = fun(Line) -> - gleam@bool:negate(gleam@string:is_empty(Line)) - end, - _pipe = Value, - _pipe@1 = gleam@regex:split(Newline_regex, _pipe), - gleam@list:filter(_pipe@1, Is_not_empty). diff --git a/test-community-packages-javascript/build/packages/gsv/README.md b/test-community-packages-javascript/build/packages/gsv/README.md deleted file mode 100644 index f9e1f0e4d20..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# gsv - -[![Package Version](https://img.shields.io/hexpm/v/csv)](https://hex.pm/packages/csv) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/csv/) - -This is a simple csv parser and writer for gleam. It will get more performant in the future, -but if you're looking for high performance now, I'd recommend doing ffi to an existing parser -in your target runtime. - -We are using the grammar from [rfc 4180](https://datatracker.ietf.org/doc/html/rfc4180#section-2) - -#### Example - -```gleam -import gsv.{Unix, Windows} - -pub fn main() { - let csv_str = "Hello, World\nGoodbye, Mars" - - // Parse a CSV string to a List(List(String)) - let assert Ok(records) = gsv.to_lists(csv_str) - - // Write a List(List(String)) to a CSV string - let csv_str = records - |> gsv.from_lists(separator: ",", line_ending: Windows) -} -``` - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add csv -``` - -and its documentation can be found at <https://hexdocs.pm/csv>. diff --git a/test-community-packages-javascript/build/packages/gsv/gleam.toml b/test-community-packages-javascript/build/packages/gsv/gleam.toml deleted file mode 100644 index 5531f8f1ada..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/gleam.toml +++ /dev/null @@ -1,20 +0,0 @@ -name = "gsv" -version = "0.1.0" -description = "A simple csv parser and generator written in gleam " - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -licences = ["Apache-2.0"] -repository = { type = "github", user = "bcpeinhardt", repo = "gsv" } - -internal_modules = [ - "gsv/internal", - "gsv/internal/*", -] - -[dependencies] -gleam_stdlib = "~> 0.28" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl b/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl deleted file mode 100644 index 6f89ba03f95..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/include/gsv@internal@token_Textdata.hrl +++ /dev/null @@ -1 +0,0 @@ --record(textdata, {inner :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src b/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src deleted file mode 100644 index 357abfbd8a2..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, gsv, [ - {vsn, "0.1.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A simple csv parser and generator written in gleam "}, - {modules, [gsv, - gsv@internal@ast, - gsv@internal@token]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv.erl deleted file mode 100644 index a5751d0d9a4..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv.erl +++ /dev/null @@ -1,58 +0,0 @@ --module(gsv). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_lists/1, from_lists/3]). --export_type([line_ending/0]). - --type line_ending() :: windows | unix. - --spec to_lists(binary()) -> {ok, list(list(binary()))} | {error, nil}. -to_lists(Input) -> - _pipe = Input, - _pipe@1 = gsv@internal@token:scan(_pipe), - gsv@internal@ast:parse(_pipe@1). - --spec le_to_string(line_ending()) -> binary(). -le_to_string(Le) -> - case Le of - windows -> - <<"\r\n"/utf8>>; - - unix -> - <<"\n"/utf8>> - end. - --spec from_lists(list(list(binary())), binary(), line_ending()) -> binary(). -from_lists(Input, Separator, Line_ending) -> - _pipe = Input, - _pipe@1 = gleam@list:map( - _pipe, - fun(Row) -> - gleam@list:map( - Row, - fun(Entry) -> - Entry@1 = gleam@string:replace( - Entry, - <<"\""/utf8>>, - <<"\"\""/utf8>> - ), - case (gleam@string:contains(Entry@1, Separator) orelse gleam@string:contains( - Entry@1, - <<"\n"/utf8>> - )) - orelse gleam@string:contains(Entry@1, <<"\""/utf8>>) of - true -> - <<<<"\""/utf8, Entry@1/binary>>/binary, "\""/utf8>>; - - false -> - Entry@1 - end - end - ) - end - ), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(Row@1) -> gleam@string:join(Row@1, Separator) end - ), - gleam@string:join(_pipe@2, le_to_string(Line_ending)). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam deleted file mode 100644 index 3feff3f6228..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv.gleam +++ /dev/null @@ -1,62 +0,0 @@ -import gsv/internal/ast -import gsv/internal/token -import gleam/list -import gleam/string - -/// Parses a csv string to a list of lists of strings. -/// Automatically handles Windows and Unix line endings. -pub fn to_lists(input: String) -> Result(List(List(String)), Nil) { - input - |> token.scan - |> ast.parse -} - -/// Option for using "\n = LF = Unix" or "\r\n = CRLF = Windows" -/// line endings. Use with the `from_lists` function when -/// writing to a csv string. -pub type LineEnding { - Windows - Unix -} - -fn le_to_string(le: LineEnding) -> String { - case le { - Windows -> "\r\n" - Unix -> "\n" - } -} - -/// Takes a list of lists of strings and writes it to a csv string. -/// Will automatically escape strings that contain double quotes or -/// line endings with double quotes (in csv, double quotes get escaped by doing -/// a double doublequote) -/// The string `he"llo\n` becomes `"he""llo\n"` -pub fn from_lists( - input: List(List(String)), - separator separator: String, - line_ending line_ending: LineEnding, -) -> String { - input - |> list.map(fn(row) { - list.map( - row, - fn(entry) { - // Double quotes need to be escaped with an extra doublequote - let entry = string.replace(entry, "\"", "\"\"") - - // If the string contains a , \n \r\n or " it needs to be escaped by wrapping in double quotes - case - string.contains(entry, separator) || string.contains(entry, "\n") || string.contains( - entry, - "\"", - ) - { - True -> "\"" <> entry <> "\"" - False -> entry - } - }, - ) - }) - |> list.map(fn(row) { string.join(row, separator) }) - |> string.join(le_to_string(line_ending)) -} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam deleted file mode 100644 index f991b826f7d..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/ast.gleam +++ /dev/null @@ -1,140 +0,0 @@ -//// We are using the following grammar for CSV from rfc4180 -//// -//// file = [header CRLF] record *(CRLF record) [CRLF] -//// header = name *(COMMA name) -//// record = field *(COMMA field) -//// name = field -//// field = (escaped / non-escaped) -//// escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE -//// non-escaped = *TEXTDATA - -import gleam/list -import gleam/result -import gsv/internal/token.{CR, Comma, CsvToken, Doublequote, LF, Textdata} - -type ParseState { - Beginning - JustParsedField - JustParsedComma - JustParsedNewline - JustParsedCR - InsideEscapedString -} - -pub fn parse(input: List(CsvToken)) -> Result(List(List(String)), Nil) { - let inner_rev = { - use llf <- result.try(parse_p(input, Beginning, [])) - use lf <- list.try_map(llf) - Ok(list.reverse(lf)) - } - use ir <- result.try(inner_rev) - Ok(list.reverse(ir)) -} - -fn parse_p( - input: List(CsvToken), - parse_state: ParseState, - llf: List(List(String)), -) -> Result(List(List(String)), Nil) { - case input, parse_state, llf { - // Error Case: An empty list should produce an Error - [], Beginning, _ -> Error(Nil) - - // BASE CASE: We are done parsing tokens - [], _, llf -> Ok(llf) - - // File should begin with either Escaped or Nonescaped string - [Textdata(str), ..remaining_tokens], Beginning, [] -> - parse_p(remaining_tokens, JustParsedField, [[str]]) - - [Doublequote, ..remaining_tokens], Beginning, [] -> - parse_p(remaining_tokens, InsideEscapedString, [[""]]) - - _, Beginning, _ -> Error(Nil) - - // If we just parsed a field, we're expecting either a comma or a CRLF - [Comma, ..remaining_tokens], JustParsedField, llf -> - parse_p(remaining_tokens, JustParsedComma, llf) - - [LF, ..remaining_tokens], JustParsedField, llf -> - parse_p(remaining_tokens, JustParsedNewline, llf) - - [CR, ..remaining_tokens], JustParsedField, llf -> - parse_p(remaining_tokens, JustParsedCR, llf) - - _, JustParsedField, _ -> Error(Nil) - - // If we just parsed a CR, we're expecting an LF - [LF, ..remaining_tokens], JustParsedCR, llf -> - parse_p(remaining_tokens, JustParsedNewline, llf) - - _, JustParsedCR, _ -> Error(Nil) - - // If we just parsed a comma, we're expecting an Escaped or Non-Escaped string - [Textdata(str), ..remaining_tokens], JustParsedComma, [ - curr_line, - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - JustParsedField, - [[str, ..curr_line], ..previously_parsed_lines], - ) - - [Doublequote, ..remaining_tokens], JustParsedComma, [ - curr_line, - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [["", ..curr_line], ..previously_parsed_lines], - ) - - _, JustParsedComma, _ -> Error(Nil) - - // If we just parsed a new line, we're expecting an escaped or non-escaped string - [Textdata(str), ..remaining_tokens], JustParsedNewline, llf -> - parse_p(remaining_tokens, JustParsedField, [[str], ..llf]) - - [Doublequote, ..remaining_tokens], JustParsedNewline, [ - curr_line, - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [["", ..curr_line], ..previously_parsed_lines], - ) - - _, JustParsedNewline, _ -> Error(Nil) - - // If we're inside an escaped string, we can take anything until we get a double quote, - // but a double double quote "" escapes the double quote and we keep parsing - [Doublequote, Doublequote, ..remaining_tokens], InsideEscapedString, [ - [str, ..rest_curr_line], - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [[str <> "\"", ..rest_curr_line], ..previously_parsed_lines], - ) - - [Doublequote, ..remaining_tokens], InsideEscapedString, llf -> - parse_p(remaining_tokens, JustParsedField, llf) - - [other_token, ..remaining_tokens], InsideEscapedString, [ - [str, ..rest_curr_line], - ..previously_parsed_lines - ] -> - parse_p( - remaining_tokens, - InsideEscapedString, - [ - [str <> token.to_lexeme(other_token), ..rest_curr_line], - ..previously_parsed_lines - ], - ) - } -} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam b/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam deleted file mode 100644 index ff70536f4f1..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv/internal/token.gleam +++ /dev/null @@ -1,54 +0,0 @@ -//// We are using the following grammar for CSV from rfc4180 -//// -//// file = [header CRLF] record *(CRLF record) [CRLF] -//// header = name *(COMMA name) -//// record = field *(COMMA field) -//// name = field -//// field = (escaped / non-escaped) -//// escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE -//// non-escaped = *TEXTDATA - -import gleam/string -import gleam/list - -pub type CsvToken { - Comma - LF - CR - Doublequote - Textdata(inner: String) -} - -pub fn to_lexeme(token: CsvToken) -> String { - case token { - Comma -> "," - LF -> "\n" - CR -> "\r" - Doublequote -> "\"" - Textdata(str) -> str - } -} - -pub fn scan(input: String) -> List(CsvToken) { - input - |> string.to_utf_codepoints - |> list.fold( - [], - fn(acc, x) { - case string.utf_codepoint_to_int(x) { - 0x2c -> [Comma, ..acc] - 0x22 -> [Doublequote, ..acc] - 0x0a -> [LF, ..acc] - 0x0D -> [CR, ..acc] - _ -> { - let cp = string.from_utf_codepoints([x]) - case acc { - [Textdata(str), ..rest] -> [Textdata(str <> cp), ..rest] - _ -> [Textdata(cp), ..acc] - } - } - } - }, - ) - |> list.reverse -} diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl deleted file mode 100644 index ac107202ac0..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@ast.erl +++ /dev/null @@ -1,125 +0,0 @@ --module(gsv@internal@ast). --compile([no_auto_import, nowarn_unused_vars]). - --export([parse/1]). --export_type([parse_state/0]). - --type parse_state() :: beginning | - just_parsed_field | - just_parsed_comma | - just_parsed_newline | - just_parsed_cr | - inside_escaped_string. - --spec parse_p( - list(gsv@internal@token:csv_token()), - parse_state(), - list(list(binary())) -) -> {ok, list(list(binary()))} | {error, nil}. -parse_p(Input, Parse_state, Llf) -> - case {Input, Parse_state, Llf} of - {[], beginning, _} -> - {error, nil}; - - {[], _, Llf@1} -> - {ok, Llf@1}; - - {[{textdata, Str} | Remaining_tokens], beginning, []} -> - parse_p(Remaining_tokens, just_parsed_field, [[Str]]); - - {[doublequote | Remaining_tokens@1], beginning, []} -> - parse_p(Remaining_tokens@1, inside_escaped_string, [[<<""/utf8>>]]); - - {_, beginning, _} -> - {error, nil}; - - {[comma | Remaining_tokens@2], just_parsed_field, Llf@2} -> - parse_p(Remaining_tokens@2, just_parsed_comma, Llf@2); - - {[lf | Remaining_tokens@3], just_parsed_field, Llf@3} -> - parse_p(Remaining_tokens@3, just_parsed_newline, Llf@3); - - {[cr | Remaining_tokens@4], just_parsed_field, Llf@4} -> - parse_p(Remaining_tokens@4, just_parsed_cr, Llf@4); - - {_, just_parsed_field, _} -> - {error, nil}; - - {[lf | Remaining_tokens@5], just_parsed_cr, Llf@5} -> - parse_p(Remaining_tokens@5, just_parsed_newline, Llf@5); - - {_, just_parsed_cr, _} -> - {error, nil}; - - {[{textdata, Str@1} | Remaining_tokens@6], - just_parsed_comma, - [Curr_line | Previously_parsed_lines]} -> - parse_p( - Remaining_tokens@6, - just_parsed_field, - [[Str@1 | Curr_line] | Previously_parsed_lines] - ); - - {[doublequote | Remaining_tokens@7], - just_parsed_comma, - [Curr_line@1 | Previously_parsed_lines@1]} -> - parse_p( - Remaining_tokens@7, - inside_escaped_string, - [[<<""/utf8>> | Curr_line@1] | Previously_parsed_lines@1] - ); - - {_, just_parsed_comma, _} -> - {error, nil}; - - {[{textdata, Str@2} | Remaining_tokens@8], just_parsed_newline, Llf@6} -> - parse_p(Remaining_tokens@8, just_parsed_field, [[Str@2] | Llf@6]); - - {[doublequote | Remaining_tokens@9], - just_parsed_newline, - [Curr_line@2 | Previously_parsed_lines@2]} -> - parse_p( - Remaining_tokens@9, - inside_escaped_string, - [[<<""/utf8>> | Curr_line@2] | Previously_parsed_lines@2] - ); - - {_, just_parsed_newline, _} -> - {error, nil}; - - {[doublequote, doublequote | Remaining_tokens@10], - inside_escaped_string, - [[Str@3 | Rest_curr_line] | Previously_parsed_lines@3]} -> - parse_p( - Remaining_tokens@10, - inside_escaped_string, - [[<<Str@3/binary, "\""/utf8>> | Rest_curr_line] | - Previously_parsed_lines@3] - ); - - {[doublequote | Remaining_tokens@11], inside_escaped_string, Llf@7} -> - parse_p(Remaining_tokens@11, just_parsed_field, Llf@7); - - {[Other_token | Remaining_tokens@12], - inside_escaped_string, - [[Str@4 | Rest_curr_line@1] | Previously_parsed_lines@4]} -> - parse_p( - Remaining_tokens@12, - inside_escaped_string, - [[<<Str@4/binary, - (gsv@internal@token:to_lexeme(Other_token))/binary>> | - Rest_curr_line@1] | - Previously_parsed_lines@4] - ) - end. - --spec parse(list(gsv@internal@token:csv_token())) -> {ok, list(list(binary()))} | - {error, nil}. -parse(Input) -> - Inner_rev = (gleam@result:'try'( - parse_p(Input, beginning, []), - fun(Llf) -> - gleam@list:try_map(Llf, fun(Lf) -> {ok, gleam@list:reverse(Lf)} end) - end - )), - gleam@result:'try'(Inner_rev, fun(Ir) -> {ok, gleam@list:reverse(Ir)} end). diff --git a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl b/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl deleted file mode 100644 index 63647f465f1..00000000000 --- a/test-community-packages-javascript/build/packages/gsv/src/gsv@internal@token.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(gsv@internal@token). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_lexeme/1, scan/1]). --export_type([csv_token/0]). - --type csv_token() :: comma | lf | cr | doublequote | {textdata, binary()}. - --spec to_lexeme(csv_token()) -> binary(). -to_lexeme(Token) -> - case Token of - comma -> - <<","/utf8>>; - - lf -> - <<"\n"/utf8>>; - - cr -> - <<"\r"/utf8>>; - - doublequote -> - <<"\""/utf8>>; - - {textdata, Str} -> - Str - end. - --spec scan(binary()) -> list(csv_token()). -scan(Input) -> - _pipe = Input, - _pipe@1 = gleam@string:to_utf_codepoints(_pipe), - _pipe@2 = gleam@list:fold( - _pipe@1, - [], - fun(Acc, X) -> case gleam@string:utf_codepoint_to_int(X) of - 16#2c -> - [comma | Acc]; - - 16#22 -> - [doublequote | Acc]; - - 16#0a -> - [lf | Acc]; - - 16#0D -> - [cr | Acc]; - - _ -> - Cp = gleam@string:from_utf_codepoints([X]), - case Acc of - [{textdata, Str} | Rest] -> - [{textdata, <<Str/binary, Cp/binary>>} | Rest]; - - _ -> - [{textdata, Cp} | Acc] - end - end end - ), - gleam@list:reverse(_pipe@2). diff --git a/test-community-packages-javascript/build/packages/hug/README.md b/test-community-packages-javascript/build/packages/hug/README.md deleted file mode 100644 index a55808a6eb5..00000000000 --- a/test-community-packages-javascript/build/packages/hug/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# hug - -A package for creating helpful, and pretty CLI messages. - -[![Package Version](https://img.shields.io/hexpm/v/hug)](https://hex.pm/packages/hug) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/hug/) - -✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! - ---- - -## Quick start - -```gleam -import gleam/io -import hug - -pub fn main() { - let source = "let six = 5 + 1.0" - - source - |> hug.error( - in: "example.gleam", - from: #(1, 10), - to: #(1, 17), - message: "invalid type", - hint: "can not add an `Int` to a `Float`" - ) - |> io.println() - ) -} -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add hug -``` - -and its documentation can be found at <https://hexdocs.pm/hug>. - - -## Why `hug`? - -The name `hug` is inspired by Mark Rendle's talk [The Worst Programming Language Ever](https://youtu.be/vcFBwt1nu2U?t=2229) where he refers error messages in Rust as "a hug from the compiler". diff --git a/test-community-packages-javascript/build/packages/hug/gleam.toml b/test-community-packages-javascript/build/packages/hug/gleam.toml deleted file mode 100644 index 3aedf38c6fa..00000000000 --- a/test-community-packages-javascript/build/packages/hug/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "hug" -version = "0.1.0" -licences = ["Apache-2.0"] -description = "Helpful and pretty CLI messages" -repository = { type = "github", user = "brettkolodny", repo = "gleam-hug" } - -[javascript.deno] -allow_read = ["./gleam.toml", "./test/"] - -[dependencies] -gleam_stdlib = "~> 0.26" -gleam_community_ansi = "~> 1.0" - -[dev-dependencies] -gleeunit = "~> 0.9" -gleam_erlang = "~> 0.17" diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.app.src b/test-community-packages-javascript/build/packages/hug/src/hug.app.src deleted file mode 100644 index dfed29a1cf7..00000000000 --- a/test-community-packages-javascript/build/packages/hug/src/hug.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, hug, [ - {vsn, "0.1.0"}, - {applications, [gleam_community_ansi, - gleam_erlang, - gleam_stdlib, - gleeunit]}, - {description, "Helpful and pretty CLI messages"}, - {modules, [hug]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.erl b/test-community-packages-javascript/build/packages/hug/src/hug.erl deleted file mode 100644 index 21d3a159505..00000000000 --- a/test-community-packages-javascript/build/packages/hug/src/hug.erl +++ /dev/null @@ -1,303 +0,0 @@ --module(hug). --compile(no_auto_import). - --export([error/6, warning/6, info/6]). --export_type([location/0, output/0]). - --type location() :: {location, integer(), integer()}. - --type output() :: error | warning | info. - --spec error( - binary(), - binary(), - {integer(), integer()}, - {integer(), integer()}, - binary(), - binary() -) -> binary(). -error(File_name, Source, Start, End, Msg, Hint) -> - output( - File_name, - Source, - {location, erlang:element(1, Start), erlang:element(2, Start)}, - {location, erlang:element(1, End), erlang:element(2, End)}, - Msg, - Hint, - error - ). - --spec warning( - binary(), - binary(), - {integer(), integer()}, - {integer(), integer()}, - binary(), - binary() -) -> binary(). -warning(File_name, Source, Start, End, Msg, Hint) -> - output( - File_name, - Source, - {location, erlang:element(1, Start), erlang:element(2, Start)}, - {location, erlang:element(1, End), erlang:element(2, End)}, - Msg, - Hint, - warning - ). - --spec info( - binary(), - binary(), - {integer(), integer()}, - {integer(), integer()}, - binary(), - binary() -) -> binary(). -info(File_name, Source, Start, End, Msg, Hint) -> - output( - File_name, - Source, - {location, erlang:element(1, Start), erlang:element(2, Start)}, - {location, erlang:element(1, End), erlang:element(2, End)}, - Msg, - Hint, - info - ). - --spec output( - binary(), - binary(), - location(), - location(), - binary(), - binary(), - output() -) -> binary(). -output(File_name, Source, Start, End, Err, Hint, Output) -> - Header = construct_header(Err, Output), - Body = construct_body(File_name, Source, Start, End, Output), - gleam@string:join([Header, Body, <<""/utf8>>, Hint], <<"\n"/utf8>>). - --spec get_relevant_lines(list(binary()), location(), location()) -> list(binary()). -get_relevant_lines(Source_lines, Start, End) -> - gleam@list:index_fold( - Source_lines, - [], - fun(Lines, Line, Index) -> - case ((Index - + 1) - >= erlang:element(2, Start)) - andalso ((Index - + 1) - =< erlang:element(2, End)) of - true -> - gleam@list:append(Lines, [Line]); - - false -> - Lines - end - end - ). - --spec underline_source(list(binary()), location(), location(), output()) -> list(binary()). -underline_source(Source_lines, Start, End, Output) -> - Colour = case Output of - error -> - fun gleam_community@ansi:red/1; - - warning -> - fun gleam_community@ansi:yellow/1; - - info -> - fun gleam_community@ansi:blue/1 - end, - gleam@list:index_map( - Source_lines, - fun(Index, Line) -> - case gleam@string:trim(Line) of - <<""/utf8>> -> - <<""/utf8>>; - - _@1 -> - case Index =:= 0 of - true -> - White_space = gleam@string:repeat( - <<" "/utf8>>, - erlang:element(3, Start) - - 1 - ), - Underline_end = case erlang:element(2, End) - =:= erlang:element(2, Start) of - true -> - erlang:element(3, End) - erlang:element( - 3, - Start - ); - - false -> - gleam@string:length(Line) - gleam@string:length( - White_space - ) - end, - <<White_space/binary, - (Colour( - gleam@string:repeat( - <<"~"/utf8>>, - Underline_end - ) - ))/binary>>; - - false -> - Line_length = gleam@string:length(Line), - Line_length_post_trim = gleam@string:length( - gleam@string:trim_left(Line) - ), - Num_white_space = Line_length - - Line_length_post_trim, - White_space@1 = gleam@string:repeat( - <<" "/utf8>>, - Num_white_space - ), - <<White_space@1/binary, - (Colour( - gleam@string:repeat( - <<"~"/utf8>>, - Line_length_post_trim - ) - ))/binary>> - end - end - end - ). - --spec construct_header(binary(), output()) -> binary(). -construct_header(Message, Output) -> - case Output of - error -> - <<(gleam_community@ansi:red(<<"error: "/utf8>>))/binary, - Message/binary>>; - - warning -> - <<(gleam_community@ansi:yellow(<<"warning: "/utf8>>))/binary, - Message/binary>>; - - info -> - <<(gleam_community@ansi:blue(<<"info: "/utf8>>))/binary, - Message/binary>> - end. - --spec construct_body(binary(), binary(), location(), location(), output()) -> binary(). -construct_body(File_name, Source, Start, End, Output) -> - Left_padding = gleam@int:max( - gleam@string:length(gleam@int:to_string(erlang:element(2, Start))), - gleam@string:length(gleam@int:to_string(erlang:element(2, End))) - ) - - 1, - Body_start = <<<<<<<<<<<<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, - " ┌─ "/utf8>>/binary, - File_name/binary>>/binary, - ":"/utf8>>/binary, - (gleam@int:to_string(erlang:element(2, Start)))/binary>>/binary, - ":"/utf8>>/binary, - (gleam@int:to_string(erlang:element(3, Start)))/binary>>, - Relevant_lines = get_relevant_lines( - gleam@string:split(Source, <<"\n"/utf8>>), - Start, - End - ), - Underlines = underline_source(Relevant_lines, Start, End, Output), - Trim_left_amount = get_trim_left_amount(Relevant_lines), - Body = begin - _pipe = gleam@list:zip(Relevant_lines, Underlines), - _pipe@1 = gleam@list:index_map( - _pipe, - fun(Index, Input) -> - construct_output_line( - Input, - Index - + erlang:element(2, Start), - Trim_left_amount, - Left_padding - ) - end - ), - gleam@string:join(_pipe@1, <<"\n"/utf8>>) - end, - gleam@string:join( - [Body_start, - <<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, - " │"/utf8>>, - Body, - <<(gleam@string:repeat(<<" "/utf8>>, Left_padding))/binary, - " │"/utf8>>], - <<"\n"/utf8>> - ). - --spec construct_output_line( - {binary(), binary()}, - integer(), - integer(), - integer() -) -> binary(). -construct_output_line(Input, Row, Trim_left_amount, Left_padding) -> - {Source_line, Underline} = Input, - Line_number_padding = (Left_padding - - gleam@string:length(gleam@int:to_string(Row))) - + 1, - Source_line@1 = <<<<<<(gleam_community@ansi:green(gleam@int:to_string(Row)))/binary, - (gleam@string:repeat(<<" "/utf8>>, Line_number_padding))/binary>>/binary, - " │ "/utf8>>/binary, - (trim_left(Source_line, Trim_left_amount))/binary>>, - case gleam@string:length(Underline) of - 0 -> - Source_line@1; - - _@1 -> - Underline_line = <<<<(gleam@string:repeat( - <<" "/utf8>>, - Left_padding - ))/binary, - " │ "/utf8>>/binary, - (trim_left(Underline, Trim_left_amount))/binary>>, - gleam@string:join([Source_line@1, Underline_line], <<"\n"/utf8>>) - end. - --spec get_trim_left_amount(list(binary())) -> integer(). -get_trim_left_amount(Lines) -> - Get_left_white_space = fun(Line) -> - gleam@string:length(Line) - - begin - _pipe = Line, - _pipe@1 = gleam@string:trim_left(_pipe), - gleam@string:length(_pipe@1) - end - end, - First_line = begin - _pipe@2 = gleam@list:first(Lines), - gleam@result:unwrap(_pipe@2, <<""/utf8>>) - end, - gleam@list:fold( - Lines, - Get_left_white_space(First_line), - fun(Min_white_space, Line@1) -> - case gleam@string:trim(Line@1) of - <<""/utf8>> -> - Min_white_space; - - _@1 -> - White_space = gleam@string:length(Line@1) - - begin - _pipe@3 = Line@1, - _pipe@4 = gleam@string:trim_left(_pipe@3), - gleam@string:length(_pipe@4) - end, - gleam@int:min(Min_white_space, White_space) - end - end - ). - --spec trim_left(binary(), integer()) -> binary(). -trim_left(Str, Num_white_space) -> - String_length = gleam@string:length(Str), - gleam@string:slice(Str, Num_white_space, String_length). diff --git a/test-community-packages-javascript/build/packages/hug/src/hug.gleam b/test-community-packages-javascript/build/packages/hug/src/hug.gleam deleted file mode 100644 index 5c81514446d..00000000000 --- a/test-community-packages-javascript/build/packages/hug/src/hug.gleam +++ /dev/null @@ -1,405 +0,0 @@ -//// -//// - **Outputs** -//// - [`error`](#error) -//// - [`warning`](#error) -//// - [`info`](#info) -//// -//// --- -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/list -import gleam/result -import gleam/string -import gleam_community/ansi - -// TYPES ---------------------------------------------------------------------- - -type Location { - Location(row: Int, col: Int) -} - -type Output { - Error - Warning - Info -} - -// OUTPUTS -------------------------------------------------------------------- - -/// Returns a `String` displaying the provided error and relevant code. -/// -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// let source = "let five = 4 + 1.0" -/// -/// source -/// |> hug.error( -/// in: "example.gleam", -/// from: #(1, 11), -/// to: #(1, 18), -/// message: "invalid type", -/// hint: "can not add an `Int` to a `Float`" -/// ) -/// |> io.println() -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/brettkolodny/hug/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn error( - in file_name: String, - containing source: String, - from start: #(Int, Int), - to end: #(Int, Int), - message msg: String, - hint hint: String, -) -> String { - output( - file_name, - source, - Location(row: start.0, col: start.1), - Location(row: end.0, col: end.1), - msg, - hint, - Error, - ) -} - -/// Returns a `String` displaying the provided warning and relevant code. -/// -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// let source = "let five = 4 + 1.0" -/// -/// source -/// |> hug.warning( -/// in: "example.gleam", -/// from: #(1, 5), -/// to: #(1, 9), -/// message: "unused variable", -/// hint: "the variable `five` is declared but never used" -/// ) -/// |> io.println() -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/brettkolodny/hug/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn warning( - in file_name: String, - containing source: String, - from start: #(Int, Int), - to end: #(Int, Int), - message msg: String, - hint hint: String, -) -> String { - output( - file_name, - source, - Location(row: start.0, col: start.1), - Location(row: end.0, col: end.1), - msg, - hint, - Warning, - ) -} - -/// Returns a `String` displaying the provided info and relevant code. -/// -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// let source = "try five = int.parse("4") |> result.then(fn(v) { v + 1})" -/// -/// source -/// |> hug.info( -/// in: "example.gleam", -/// from: #(1, 1), -/// to: #(1, 4), -/// message: "use of deprecated code", -/// hint: "`try` is marked as deprecated, check out `use`!" -/// ) -/// |> io.println() -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/brettkolodny/hug/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn info( - in file_name: String, - containing source: String, - from start: #(Int, Int), - to end: #(Int, Int), - message msg: String, - hint hint: String, -) -> String { - output( - file_name, - source, - Location(row: start.0, col: start.1), - Location(row: end.0, col: end.1), - msg, - hint, - Info, - ) -} - -// ---------------------------------------------------------------------------- - -fn output( - file_name: String, - source: String, - start: Location, - end: Location, - err: String, - hint: String, - output: Output, -) { - let header = construct_header(err, output) - - let body = construct_body(file_name, source, start, end, output) - - string.join([header, body, "", hint], "\n") -} - -// -fn get_relevant_lines( - source_lines: List(String), - start: Location, - end: Location, -) -> List(String) { - use lines, line, index <- list.index_fold(source_lines, []) - - case index + 1 >= start.row && index + 1 <= end.row { - True -> list.append(lines, [line]) - False -> lines - } -} - -// -fn underline_source( - source_lines: List(String), - start: Location, - end: Location, - output: Output, -) -> List(String) { - let colour = case output { - Error -> ansi.red - Warning -> ansi.yellow - Info -> ansi.blue - } - - use index, line <- list.index_map(source_lines) - - case string.trim(line) { - "" -> "" - _ -> - case index == 0 { - True -> { - let white_space = string.repeat(" ", start.col - 1) - - let underline_end = case end.row == start.row { - True -> end.col - start.col - False -> string.length(line) - string.length(white_space) - } - - white_space <> colour(string.repeat("~", underline_end)) - } - - False -> { - let line_length = string.length(line) - let line_length_post_trim = string.length(string.trim_left(line)) - - let num_white_space = line_length - line_length_post_trim - - let white_space = string.repeat(" ", num_white_space) - - white_space <> colour(string.repeat("~", line_length_post_trim)) - } - } - } -} - -fn construct_header(message: String, output: Output) -> String { - case output { - Error -> ansi.red("error: ") <> message - Warning -> ansi.yellow("warning: ") <> message - Info -> ansi.blue("info: ") <> message - } -} - -// -fn construct_body( - file_name: String, - source: String, - start: Location, - end: Location, - output: Output, -) -> String { - let left_padding = - int.max( - string.length(int.to_string(start.row)), - string.length(int.to_string(end.row)), - ) - 1 - - let body_start = - string.repeat(" ", left_padding) <> " ┌─ " <> file_name <> ":" <> int.to_string( - start.row, - ) <> ":" <> int.to_string(start.col) - - let relevant_lines = - get_relevant_lines(string.split(source, on: "\n"), start, end) - - let underlines = underline_source(relevant_lines, start, end, output) - - let trim_left_amount = get_trim_left_amount(relevant_lines) - - let body = - list.zip(relevant_lines, underlines) - |> list.index_map(fn(index, input) { - construct_output_line( - input, - index + start.row, - trim_left_amount, - left_padding, - ) - }) - |> string.join("\n") - - string.join( - [ - body_start, - string.repeat(" ", left_padding) <> " │", - body, - string.repeat(" ", left_padding) <> " │", - ], - "\n", - ) -} - -// -fn construct_output_line( - input: #(String, String), - row: Int, - trim_left_amount: Int, - left_padding: Int, -) -> String { - let #(source_line, underline) = input - - let line_number_padding = left_padding - string.length(int.to_string(row)) + 1 - - let source_line = - ansi.green(int.to_string(row)) <> string.repeat(" ", line_number_padding) <> " │ " <> trim_left( - source_line, - by: trim_left_amount, - ) - - case string.length(underline) { - 0 -> source_line - _ -> { - let underline_line = - string.repeat(" ", left_padding) <> " │ " <> trim_left( - underline, - by: trim_left_amount, - ) - - string.join([source_line, underline_line], "\n") - } - } -} - -// -fn get_trim_left_amount(lines: List(String)) -> Int { - let get_left_white_space = fn(line) { - string.length(line) - { - line - |> string.trim_left() - |> string.length() - } - } - - let first_line = - list.first(lines) - |> result.unwrap("") - - use min_white_space, line <- list.fold( - lines, - get_left_white_space(first_line), - ) - - case string.trim(line) { - "" -> min_white_space - _ -> { - let white_space = - string.length(line) - { - line - |> string.trim_left() - |> string.length() - } - - int.min(min_white_space, white_space) - } - } -} - -// -fn trim_left(str: String, by num_white_space: Int) -> String { - let string_length = string.length(str) - - string.slice(from: str, at_index: num_white_space, length: string_length) -} diff --git a/test-community-packages-javascript/build/packages/mist/README.md b/test-community-packages-javascript/build/packages/mist/README.md deleted file mode 100644 index fedef427160..00000000000 --- a/test-community-packages-javascript/build/packages/mist/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# mist - -A glistening Gleam web server. - -## Installation - -This package can be added to your Gleam project: - -```sh -gleam add mist -``` - -and its documentation can be found at <https://hexdocs.pm/mist>. - -## Usage - -Right now there are a few options. Let's say you want a "simple" HTTP server -that you can customize to your heart's content. In that case, you want: - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http/response -import mist - -pub fn main() { - let assert Ok(_) = - mist.run_service( - 8080, - fn(_req) { - response.new(200) - |> response.set_body(bit_builder.from_string("hello, world!")) - }, - max_body_limit: 4_000_000 - ) - process.sleep_forever() -} -``` - -Maybe you also want to work with websockets. Maybe those should only be -upgradable at a certain endpoint. For that, you can use `mist.handler_func`. -The websocket methods help you build a handler with connect/disconnect handlers. -You can use these to track connected clients, for example. - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http.{Get, Post} -import gleam/http/request.{Request} -import gleam/http/response -import gleam/result -import mist -import mist/websocket - -pub fn main() { - let assert Ok(_) = - mist.serve( - 8080, - mist.handler_func(fn(req) { - case req.method, request.path_segments(req) { - Get, ["echo", "test"] -> websocket_echo() - Post, ["echo", "body"] -> echo_body(req) - Get, ["home"] -> - response.new(200) - |> mist.bit_builder_response( - bit_builder.from_string("sup home boy") - ) - _, _ -> - response.new(200) - |> mist.bit_builder_response( - bit_builder.from_string("Hello, world!") - ) - } - }), - ) - process.sleep_forever() -} - -fn websocket_echo() { - websocket.echo_handler - |> websocket.with_handler - // Here you can gain access to the `Subject` to send message to - // with: - // |> websocket.on_init(fn(subj) { ... }) - // |> websocket.on_close(fn(subj) { ... }) - |> mist.upgrade -} - -fn echo_body(req: Request(mist.Body)) { - req - |> mist.read_body - |> result.map(fn(req) { - response.new(200) - |> response.prepend_header( - "content-type", - request.get_header(req, "content-type") - |> result.unwrap("application/octet-stream"), - ) - |> mist.bit_builder_response(bit_builder.from_bit_string(req.body)) - }) - |> result.unwrap( - response.new(400) - |> mist.empty_response, - ) -} -``` - -You might also want to use SSL. You can do that with the following options. - -With `run_service_ssl`: - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http/response -import mist - -pub fn main() { - let assert Ok(_) = - mist.run_service_ssl( - port: 8080, - certfile: "/path/to/server.crt", - keyfile: "/path/to/server.key", - handler: fn(_req) { - response.new(200) - |> response.set_body(bit_builder.from_bit_string(<< - "hello, world!":utf8, - >>)) - }, - max_body_limit: 4_000_000 - ) - process.sleep_forever() -} -``` - -With `serve_ssl`: - -```gleam -pub fn main() { - let assert Ok(_) = - mist.serve_ssl( - port: 8080, - certfile: "...", - keyfile: "...", - mist.handler_func(fn(req) { - todo - } - ) - // ... -} -``` - -There is support for sending files as well. This uses the `file:sendfile` erlang -method under the hood. - -```gleam -import gleam/bit_builder -import gleam/erlang/process -import gleam/http/request.{Request} -import gleam/http/response -import gleam/string -import mist - -pub fn main() { - let asset_root = "..." - let assert Ok(_) = - mist.serve( - 8080, - mist.handler_func(fn(req: Request(Body)) { - let not_found = - response.new(404) - |> mist.empty_response - case request.path_segments(req) { - ["static", ..path] -> { - // verify, validate, etc - let file_path = - path - |> string.join("/") - |> string.append("/", _) - response.new(200) - |> mist.file_response(asset_root <> file_path) - |> result.unwrap(not_found) - } - _ -> not_found - } - }), - ) - process.sleep_forever() -} -``` - -You can return chunked responses using the `mist.{chunked_response}` method. -This takes an `Iterator(BitBuilder)` and handles sending the initial -response, and subsequent chunks in the proper format as they are emitted from -the iterator. The iterator must be finite. - -If you need something a little more complex or custom, you can always use the -helpers exported by the various `glisten`/`mist` modules. - -## Benchmarks - -These are currently located [here](https://github.com/rawhat/http-benchmarks) diff --git a/test-community-packages-javascript/build/packages/mist/gleam.toml b/test-community-packages-javascript/build/packages/mist/gleam.toml deleted file mode 100644 index 91c326f0ca4..00000000000 --- a/test-community-packages-javascript/build/packages/mist/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "mist" -version = "0.11.0" - -licences = ["Apache-2.0"] -description = "a misty Gleam web server" -repository = { type = "github", user = "rawhat", repo = "mist" } - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_erlang = "~> 0.18" -gleam_http = "~> 3.2" -gleam_otp = "~> 0.5" -glisten = "~> 0.7" - -[dev-dependencies] -gleeunit = "~> 0.10" -gleam_hackney = "~> 1.0" diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl deleted file mode 100644 index c49d5eace0b..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_Response.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(response, { - response :: gleam@http@response:response(mist@internal@http:http_response_body()) -}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl deleted file mode 100644 index 4dc61ad70a9..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@handler_State.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(state, { - idle_timer :: gleam@option:option(gleam@erlang@process:timer()), - upgraded_handler :: gleam@option:option(mist@internal@websocket:websocket_handler()) -}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl deleted file mode 100644 index 95dd5e515b9..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Buffer.hrl +++ /dev/null @@ -1 +0,0 @@ --record(buffer, {remaining :: integer(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl deleted file mode 100644 index ce21939a44f..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_FileBody.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(file_body, { - file_descriptor :: mist@internal@file:file_descriptor(), - content_type :: binary(), - offset :: integer(), - length :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl deleted file mode 100644 index b58f506cc3a..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Read.hrl +++ /dev/null @@ -1 +0,0 @@ --record(read, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl deleted file mode 100644 index 204cebd84f7..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@http_Unread.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unread, {rest :: bitstring(), socket :: glisten@socket:socket()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl deleted file mode 100644 index 4d0a2f59f4a..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(binary_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl deleted file mode 100644 index f44c5b4e905..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_BinaryMessage.hrl +++ /dev/null @@ -1 +0,0 @@ --record(binary_message, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl deleted file mode 100644 index ec07ce26727..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_CloseFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(close_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl deleted file mode 100644 index eb73aeab1f8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PingFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ping_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl deleted file mode 100644 index c55a2aa1fc9..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_PongFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(pong_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl deleted file mode 100644 index 25def5fbb71..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextFrame.hrl +++ /dev/null @@ -1 +0,0 @@ --record(text_frame, {payload_length :: integer(), payload :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl deleted file mode 100644 index c4cf5176528..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_TextMessage.hrl +++ /dev/null @@ -1 +0,0 @@ --record(text_message, {data :: binary()}). diff --git a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl b/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl deleted file mode 100644 index 00dd595dba4..00000000000 --- a/test-community-packages-javascript/build/packages/mist/include/mist@internal@websocket_WebsocketHandler.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(websocket_handler, { - on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - handler :: fun((mist@internal@websocket:message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, - nil} | - {error, nil}) -}). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.app.src b/test-community-packages-javascript/build/packages/mist/src/mist.app.src deleted file mode 100644 index 9cd4bf452a0..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist.app.src +++ /dev/null @@ -1,20 +0,0 @@ -{application, mist, [ - {vsn, "0.11.0"}, - {applications, [gleam_erlang, - gleam_hackney, - gleam_http, - gleam_otp, - gleam_stdlib, - gleeunit, - glisten]}, - {description, "a misty Gleam web server"}, - {modules, [mist, - mist@internal@encoder, - mist@internal@file, - mist@internal@handler, - mist@internal@http, - mist@internal@logger, - mist@internal@websocket, - mist@websocket]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.erl b/test-community-packages-javascript/build/packages/mist/src/mist.erl deleted file mode 100644 index c5e34db8e56..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist.erl +++ /dev/null @@ -1,116 +0,0 @@ --module(mist). --compile([no_auto_import, nowarn_unused_vars]). - --export([run_service/3, run_service_ssl/5, serve/2, serve_ssl/4, handler_func/1, read_body/1, upgrade/1, empty_response/1, bit_builder_response/2, file_response/3, chunked_response/2]). - --spec run_service( - integer(), - fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - integer() -) -> {ok, nil} | {error, glisten:start_error()}. -run_service(Port, Handler, Max_body_limit) -> - _pipe = Handler, - _pipe@1 = mist@internal@handler:with(_pipe, Max_body_limit), - _pipe@2 = glisten@acceptor:new_pool_with_data( - _pipe@1, - mist@internal@handler:new_state() - ), - glisten:serve(Port, _pipe@2). - --spec run_service_ssl( - integer(), - binary(), - binary(), - fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - integer() -) -> {ok, nil} | {error, glisten:start_error()}. -run_service_ssl(Port, Certfile, Keyfile, Handler, Max_body_limit) -> - _pipe = Handler, - _pipe@1 = mist@internal@handler:with(_pipe, Max_body_limit), - _pipe@2 = glisten@acceptor:new_pool_with_data( - _pipe@1, - mist@internal@handler:new_state() - ), - glisten:serve_ssl(Port, Certfile, Keyfile, _pipe@2). - --spec serve( - integer(), - fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))) -) -> {ok, nil} | {error, glisten:start_error()}. -serve(Port, Handler) -> - _pipe = Handler, - _pipe@1 = glisten@acceptor:new_pool_with_data( - _pipe, - mist@internal@handler:new_state() - ), - glisten:serve(Port, _pipe@1). - --spec serve_ssl( - integer(), - binary(), - binary(), - fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))) -) -> {ok, nil} | {error, glisten:start_error()}. -serve_ssl(Port, Certfile, Keyfile, Handler) -> - _pipe = Handler, - _pipe@1 = glisten@acceptor:new_pool_with_data( - _pipe, - mist@internal@handler:new_state() - ), - glisten:serve_ssl(Port, Certfile, Keyfile, _pipe@1). - --spec handler_func( - fun((gleam@http@request:request(mist@internal@http:body())) -> mist@internal@handler:handler_response()) -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))). -handler_func(Handler) -> - mist@internal@handler:with_func(Handler). - --spec read_body(gleam@http@request:request(mist@internal@http:body())) -> {ok, - gleam@http@request:request(bitstring())} | - {error, mist@internal@http:decode_error()}. -read_body(Req) -> - mist@internal@http:read_body(Req). - --spec upgrade(mist@internal@websocket:websocket_handler()) -> mist@internal@handler:handler_response(). -upgrade(Websocket_handler) -> - {upgrade, Websocket_handler}. - --spec empty_response(gleam@http@response:response(any())) -> mist@internal@handler:handler_response(). -empty_response(Resp) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body( - _pipe, - {bit_builder_body, gleam@bit_builder:new()} - ), - {response, _pipe@1}. - --spec bit_builder_response( - gleam@http@response:response(any()), - gleam@bit_builder:bit_builder() -) -> mist@internal@handler:handler_response(). -bit_builder_response(Resp, Data) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body(_pipe, {bit_builder_body, Data}), - {response, _pipe@1}. - --spec file_response(gleam@http@response:response(any()), binary(), binary()) -> {ok, - mist@internal@handler:handler_response()} | - {error, mist@internal@file:file_error()}. -file_response(Resp, Path, Content_type) -> - File_path = gleam@bit_string:from_string(Path), - Size = filelib:file_size(File_path), - gleam@result:map(mist_ffi:file_open(File_path), fun(Fd) -> _pipe = Resp, - _pipe@1 = gleam@http@response:set_body( - _pipe, - {file_body, Fd, Content_type, 0, Size} - ), - {response, _pipe@1} end). - --spec chunked_response( - gleam@http@response:response(any()), - gleam@iterator:iterator(gleam@bit_builder:bit_builder()) -) -> mist@internal@handler:handler_response(). -chunked_response(Resp, Iter) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body(_pipe, {chunked, Iter}), - {response, _pipe@1}. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist.gleam b/test-community-packages-javascript/build/packages/mist/src/mist.gleam deleted file mode 100644 index 62dd7e18ec8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist.gleam +++ /dev/null @@ -1,165 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/http/request.{Request} -import gleam/http/response.{Response as HttpResponse} -import gleam/iterator.{Iterator} -import gleam/result -import glisten -import glisten/acceptor -import glisten/handler.{LoopFn} as glisten_handler -import mist/internal/handler.{ - HandlerResponse, Response as MistResponse, State, Upgrade, -} -import mist/internal/http.{BitBuilderBody, Body as HTTPBody, Chunked, FileBody} -import mist/internal/file.{FileError} -import mist/internal/websocket.{WebsocketHandler} - -/// This type reflects whether the body has been read from the socket yet. -pub type Body = - HTTPBody - -/// Mist supports `BitBuilder`, `FileBody`, and `Chunked` response types. The -/// helper methods provided can generate these from a `gleam/http/response` -/// Response. This type is re-exported for pulling specific handlers out into -/// separate functions. -pub type Response = - HandlerResponse - -/// Runs an HTTP Request->Response server at the given port, with your defined -/// handler. This will automatically read the full body contents up to the -/// specified `max_body_limit` in bytes. If you'd prefer to have finer-grain -/// control over this behavior, consider using `mist.serve`. -pub fn run_service( - port: Int, - handler: handler.Handler, - max_body_limit max_body_limit: Int, -) -> Result(Nil, glisten.StartError) { - handler - |> handler.with(max_body_limit) - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve(port, _) -} - -/// Similar setup and behavior to `run_service`, but instead takes in the SSL -/// certificate/key and serves over HTTPS. -pub fn run_service_ssl( - port port: Int, - certfile certfile: String, - keyfile keyfile: String, - handler handler: handler.Handler, - max_body_limit max_body_limit: Int, -) -> Result(Nil, glisten.StartError) { - handler - |> handler.with(max_body_limit) - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve_ssl( - port: port, - certfile: certfile, - keyfile: keyfile, - with_pool: _, - ) -} - -/// Slightly more flexible alternative to `run_service`. This allows hooking -/// into the `mist.handler_func` method. Note that the request body -/// will not be automatically read. You will need to call `mist.read_body`. -/// Ensure that this is only called _once_ per request. -pub fn serve( - port port: Int, - handler handler: LoopFn(State), -) -> Result(Nil, glisten.StartError) { - handler - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve(port, _) -} - -/// Similar to the `run_service` method, `serve` also has a similar SSL method. -pub fn serve_ssl( - port port: Int, - certfile certfile: String, - keyfile keyfile: String, - handler handler: LoopFn(State), -) -> Result(Nil, glisten.StartError) { - handler - |> acceptor.new_pool_with_data(handler.new_state()) - |> glisten.serve_ssl( - port: port, - certfile: certfile, - keyfile: keyfile, - with_pool: _, - ) -} - -/// Handles converting the mist `Response` type into a gleam HTTP Response. Use -/// this when calling `mist.serve` to start your application. -pub fn handler_func( - handler: handler.HandlerFunc, -) -> glisten_handler.LoopFn(handler.State) { - handler.with_func(handler) -} - -/// When using `mist.serve`, the body is not automatically read. You can -/// inspect content headers to determine whether to read the body or not. -/// This function will pull the content from the sender. It gives back a -/// `Request(BitString)` containing the body. This return value should be -/// treated as replacing the initial request. Do not attempt to call this -/// method multiple times on the same request. -pub fn read_body( - req: Request(Body), -) -> Result(Request(BitString), http.DecodeError) { - http.read_body(req) -} - -/// A websocket handler is created using the `websocket.with_handler` -/// method. This function enables the mist HTTP layer to build the properly -/// formatted websocket upgrade response. -pub fn upgrade(websocket_handler: WebsocketHandler) -> Response { - Upgrade(websocket_handler) -} - -/// `mist.serve` expects the mist Response type, rather than the `gleam/http` -/// Response. When returning a response with no body, this will convert the -/// type. Note that any previously set response body will be removed before -/// sending. -pub fn empty_response(resp: HttpResponse(a)) -> Response { - resp - |> response.set_body(BitBuilderBody(bit_builder.new())) - |> MistResponse -} - -/// The mist runtime only supports sending BitBuilder types, or files (see -/// below). This method will erase any pre-existing response body. -pub fn bit_builder_response(resp: HttpResponse(a), data: BitBuilder) -> Response { - resp - |> response.set_body(BitBuilderBody(data)) - |> MistResponse -} - -/// This is a more generally optimized method for returning files to a client. -/// It's a light wrapper around Erlang's `file:sendfile/5` method. The error -/// can be matched on with `mist/file.{FileError}` if custom behavior is desired -/// for various cases. The size of the file will be added to the -/// `content-length` header field. -pub fn file_response( - resp: HttpResponse(a), - path: String, - content_type: String, -) -> Result(Response, FileError) { - let file_path = bit_string.from_string(path) - let size = file.size(file_path) - use fd <- result.map(file.open(file_path)) - resp - |> response.set_body(FileBody(fd, content_type, 0, size)) - |> MistResponse -} - -/// You can send chunks of responses from an iterator. The iterator must -/// complete. -pub fn chunked_response( - resp: HttpResponse(a), - iter: Iterator(BitBuilder), -) -> Response { - resp - |> response.set_body(Chunked(iter)) - |> MistResponse -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam deleted file mode 100644 index 95e529ee6fc..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/encoder.gleam +++ /dev/null @@ -1,104 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/http.{Header} -import gleam/http/response.{Response} -import gleam/int -import gleam/list - -/// Turns an HTTP response into a TCP message -pub fn to_bit_builder(resp: Response(BitBuilder)) -> BitBuilder { - resp.status - |> response_builder(resp.headers) - |> bit_builder.append_builder(resp.body) -} - -pub fn response_builder(status: Int, headers: List(Header)) -> BitBuilder { - let status_string = - status - |> int.to_string - |> bit_builder.from_string - |> bit_builder.append(<<" ":utf8>>) - |> bit_builder.append(status_to_bit_string(status)) - - bit_builder.new() - |> bit_builder.append(<<"HTTP/1.1 ":utf8>>) - |> bit_builder.append_builder(status_string) - |> bit_builder.append(<<"\r\n":utf8>>) - |> bit_builder.append_builder(encode_headers(headers)) - |> bit_builder.append(<<"\r\n":utf8>>) -} - -pub fn status_to_bit_string(status: Int) -> BitString { - // Obviously nowhere near exhaustive... - case status { - 100 -> <<"Continue":utf8>> - 101 -> <<"Switching Protocols":utf8>> - 103 -> <<"Early Hints":utf8>> - 200 -> <<"OK":utf8>> - 201 -> <<"Created":utf8>> - 202 -> <<"Accepted":utf8>> - 203 -> <<"Non-Authoritative Information":utf8>> - 204 -> <<"No Content":utf8>> - 205 -> <<"Reset Content":utf8>> - 206 -> <<"Partial Content":utf8>> - 300 -> <<"Multiple Choices":utf8>> - 301 -> <<"Moved Permanently":utf8>> - 302 -> <<"Found":utf8>> - 303 -> <<"See Other":utf8>> - 304 -> <<"Not Modified":utf8>> - 307 -> <<"Temporary Redirect":utf8>> - 308 -> <<"Permanent Redirect":utf8>> - 400 -> <<"Bad Request":utf8>> - 401 -> <<"Unauthorized":utf8>> - 402 -> <<"Payment Required":utf8>> - 403 -> <<"Forbidden":utf8>> - 404 -> <<"Not Found":utf8>> - 405 -> <<"Method Not Allowed":utf8>> - 406 -> <<"Not Acceptable":utf8>> - 407 -> <<"Proxy Authentication Required":utf8>> - 408 -> <<"Request Timeout":utf8>> - 409 -> <<"Conflict":utf8>> - 410 -> <<"Gone":utf8>> - 411 -> <<"Length Required":utf8>> - 412 -> <<"Precondition Failed":utf8>> - 413 -> <<"Payload Too Large":utf8>> - 414 -> <<"URI Too Long":utf8>> - 415 -> <<"Unsupported Media Type":utf8>> - 416 -> <<"Range Not Satisfiable":utf8>> - 417 -> <<"Expectation Failed":utf8>> - 418 -> <<"I'm a teapot":utf8>> - 422 -> <<"Unprocessable Entity":utf8>> - 425 -> <<"Too Early":utf8>> - 426 -> <<"Upgrade Required":utf8>> - 428 -> <<"Precondition Required":utf8>> - 429 -> <<"Too Many Requests":utf8>> - 431 -> <<"Request Header Fields Too Large":utf8>> - 451 -> <<"Unavailable For Legal Reasons":utf8>> - 500 -> <<"Internal Server Error":utf8>> - 501 -> <<"Not Implemented":utf8>> - 502 -> <<"Bad Gateway":utf8>> - 503 -> <<"Service Unavailable":utf8>> - 504 -> <<"Gateway Timeout":utf8>> - 505 -> <<"HTTP Version Not Supported":utf8>> - 506 -> <<"Variant Also Negotiates":utf8>> - 507 -> <<"Insufficient Storage":utf8>> - 508 -> <<"Loop Detected":utf8>> - 510 -> <<"Not Extended":utf8>> - 511 -> <<"Network Authentication Required":utf8>> - } -} - -pub fn encode_headers(headers: List(Header)) -> BitBuilder { - list.fold( - headers, - bit_builder.new(), - fn(builder, tup) { - let #(header, value) = tup - - builder - |> bit_builder.append_string(header) - |> bit_builder.append(<<": ":utf8>>) - |> bit_builder.append_string(value) - |> bit_builder.append(<<"\r\n":utf8>>) - }, - ) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam deleted file mode 100644 index 9783db1b2d0..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/file.gleam +++ /dev/null @@ -1,26 +0,0 @@ -import gleam/erlang/atom.{Atom} -import glisten/socket.{Socket} - -pub external type FileDescriptor - -pub external fn size(path: BitString) -> Int = - "filelib" "file_size" - -pub external fn sendfile( - file_descriptor: FileDescriptor, - socket: Socket, - offset: Int, - bytes: Int, - options: List(a), -) -> Result(Int, Atom) = - "file" "sendfile" - -pub type FileError { - IsDir - NoAccess - NoEntry - UnknownFileError -} - -pub external fn open(file: BitString) -> Result(FileDescriptor, FileError) = - "mist_ffi" "file_open" diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam deleted file mode 100644 index 1f5ea1bbc78..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/handler.gleam +++ /dev/null @@ -1,350 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/dynamic -import gleam/erlang.{Errored, Exited, Thrown, rescue} -import gleam/erlang/process -import gleam/http/request.{Request} -import gleam/http/response -import gleam/int -import gleam/iterator.{Iterator} -import gleam/option.{None, Option, Some} -import gleam/otp/actor -import gleam/result -import glisten/handler.{Close, LoopFn, LoopState} -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} -import mist/internal/encoder -import mist/internal/file -import mist/internal/http.{ - BitBuilderBody, Body, Chunked, DecodeError, DiscardPacket, FileBody, - HttpResponseBody, -} -import mist/internal/logger -import mist/internal/websocket - -pub type Handler = - fn(request.Request(BitString)) -> response.Response(BitBuilder) - -pub type HandlerResponse { - Response(response: response.Response(HttpResponseBody)) - Upgrade(websocket.WebsocketHandler) -} - -pub type HandlerFunc = - fn(Request(Body)) -> HandlerResponse - -pub type HandlerError { - InvalidRequest(DecodeError) - NotFound -} - -const stop_normal = actor.Stop(process.Normal) - -pub type State { - State( - idle_timer: Option(process.Timer), - upgraded_handler: Option(websocket.WebsocketHandler), - ) -} - -pub fn new_state() -> State { - State(None, None) -} - -/// This is a more flexible handler. It will allow you to upgrade a connection -/// to a websocket connection, or deal with a regular HTTP req->resp workflow. -pub fn with_func(handler: HandlerFunc) -> LoopFn(State) { - handler.func(fn(msg, socket_state: LoopState(State)) { - let LoopState(socket, transport: transport, data: state, ..) = socket_state - case state.upgraded_handler { - Some(ws_handler) -> - handle_websocket_message(socket_state, ws_handler, msg) - None -> - { - let _ = case state.idle_timer { - Some(t) -> process.cancel_timer(t) - _ -> process.TimerNotFound - } - msg - |> http.parse_request(socket, transport) - |> result.map_error(fn(err) { - case err { - DiscardPacket -> Nil - _ -> { - logger.error(err) - let _ = transport.close(socket) - Nil - } - } - }) - |> result.replace_error(stop_normal) - |> result.then(fn(req) { - rescue(fn() { handler(req) }) - |> result.map(fn(resp) { #(req, resp) }) - |> result.map_error(log_and_error( - _, - socket_state.socket, - socket_state.transport, - )) - }) - |> result.map(fn(req_resp) { - let #(req, response) = req_resp - case response { - Response( - response: response.Response(body: BitBuilderBody(body), ..) as resp, - ) -> handle_bit_builder_body(resp, body, socket_state) - Response( - response: response.Response(body: Chunked(body), ..) as resp, - ) -> handle_chunked_body(resp, body, socket_state) - Response( - response: response.Response(body: FileBody(..), ..) as resp, - ) -> handle_file_body(resp, socket_state) - Upgrade(with_handler) -> - handle_upgrade(req, with_handler, socket_state) - } - }) - } - |> result.unwrap_both - } - }) -} - -fn handle_websocket_message( - state: LoopState(State), - handler: websocket.WebsocketHandler, - msg: BitString, -) -> actor.Next(LoopState(State)) { - case websocket.frame_from_message(state.socket, state.transport, msg) { - Ok(websocket.PingFrame(_, _)) -> { - let assert Ok(_) = - state.transport.send( - state.socket, - websocket.frame_to_bit_builder(websocket.PongFrame(0, <<>>)), - ) - actor.Continue(state) - } - Ok(websocket.CloseFrame(..) as frame) -> { - let assert Ok(_) = - state.transport.send( - state.socket, - websocket.frame_to_bit_builder(frame), - ) - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - actor.Stop(process.Normal) - } - Ok(websocket.PongFrame(..)) -> stop_normal - Ok(frame) -> - case frame { - websocket.TextFrame(_length, payload) -> { - let assert Ok(msg) = bit_string.to_string(payload) - websocket.TextMessage(msg) - } - // NOTE: this doesn't need to be exhaustive since we already - // cover the cases above - _frame -> websocket.BinaryMessage(frame.payload) - } - |> fn(ws_msg) { rescue(fn() { handler.handler(ws_msg, state.sender) }) } - |> result.replace(actor.Continue(state)) - |> result.map_error(fn(err) { - logger.error(err) - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - err - }) - |> result.replace_error(stop_normal) - |> result.unwrap_both - Error(_) -> { - let _ = case handler.on_close { - Some(func) -> func(state.sender) - _ -> Nil - } - // TODO: not normal - stop_normal - } - } -} - -fn log_and_error( - error: erlang.Crash, - socket: Socket, - transport: Transport, -) -> actor.Next(LoopState(State)) { - case error { - Exited(msg) | Thrown(msg) | Errored(msg) -> { - logger.error(error) - response.new(500) - |> response.set_body(bit_builder.from_bit_string(<< - "Internal Server Error":utf8, - >>)) - |> response.prepend_header("content-length", "21") - |> http.add_default_headers - |> encoder.to_bit_builder - |> transport.send(socket, _) - let _ = transport.close(socket) - actor.Stop(process.Abnormal(dynamic.unsafe_coerce(msg))) - } - } -} - -fn handle_bit_builder_body( - resp: response.Response(HttpResponseBody), - body: BitBuilder, - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - resp - |> response.set_body(body) - |> http.add_default_headers - |> encoder.to_bit_builder - |> state.transport.send(state.socket, _) - |> result.map(fn(_sent) { - // If the handler explicitly says to close the connection, we should - // probably listen to them - case response.get_header(resp, "connection") { - Ok("close") -> { - let _ = state.transport.close(state.socket) - stop_normal - } - _ -> { - // TODO: this should be a configuration - let timer = process.send_after(state.sender, 10_000, Close) - actor.Continue( - LoopState(..state, data: State(..state.data, idle_timer: Some(timer))), - ) - } - } - }) - |> result.replace_error(stop_normal) - |> result.unwrap_both -} - -external fn integer_to_list(int: Int, base: Int) -> String = - "erlang" "integer_to_list" - -fn int_to_hex(int: Int) -> String { - integer_to_list(int, 16) -} - -fn handle_chunked_body( - resp: response.Response(HttpResponseBody), - body: Iterator(BitBuilder), - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - let headers = [#("transfer-encoding", "chunked"), ..resp.headers] - let initial_payload = encoder.response_builder(resp.status, headers) - - state.transport.send(state.socket, initial_payload) - |> result.then(fn(_ok) { - body - |> iterator.append(iterator.from_list([bit_builder.new()])) - |> iterator.try_fold( - Nil, - fn(_prev, chunk) { - let size = bit_builder.byte_size(chunk) - let encoded = - size - |> int_to_hex - |> bit_builder.from_string - |> bit_builder.append_string("\r\n") - |> bit_builder.append_builder(chunk) - |> bit_builder.append_string("\r\n") - - state.transport.send(state.socket, encoded) - }, - ) - }) - |> result.replace(actor.Continue(state)) - |> result.unwrap(stop_normal) -} - -fn handle_file_body( - resp: response.Response(HttpResponseBody), - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - let assert FileBody(file_descriptor, content_type, offset, length) = resp.body - resp - |> response.prepend_header("content-length", int.to_string(length - offset)) - |> response.prepend_header("content-type", content_type) - |> response.set_body(bit_builder.new()) - |> fn(r: response.Response(BitBuilder)) { - encoder.response_builder(resp.status, r.headers) - } - |> state.transport.send(state.socket, _) - |> result.map(fn(_) { - file.sendfile(file_descriptor, state.socket, offset, length, []) - }) - |> result.replace(actor.Continue(state)) - // TODO: not normal - |> result.replace_error(stop_normal) - |> result.unwrap_both -} - -fn handle_upgrade( - req: Request(Body), - handler: websocket.WebsocketHandler, - state: LoopState(State), -) -> actor.Next(LoopState(State)) { - req - |> http.upgrade(state.socket, state.transport, _) - |> result.map(fn(_nil) { - let _ = case handler.on_init { - Some(func) -> func(state.sender) - _ -> Nil - } - }) - |> result.replace(actor.Continue( - LoopState( - ..state, - data: State(..state.data, upgraded_handler: Some(handler)), - ), - )) - // TODO: not normal - |> result.replace_error(stop_normal) - |> result.unwrap_both -} - -/// Creates a standard HTTP handler service to pass to `mist.serve` -pub fn with(handler: Handler, max_body_limit: Int) -> LoopFn(State) { - let bad_request = - response.new(400) - |> response.set_body(bit_builder.new()) - with_func(fn(req) { - case - request.get_header(req, "content-length"), - request.get_header(req, "transfer-encoding") - { - Ok("0"), _ | Error(Nil), Error(Nil) -> - req - |> request.set_body(<<>>) - |> handler - _, Ok("chunked") -> - req - |> http.read_body - |> result.map(handler) - |> result.unwrap(bad_request) - Ok(size), _ -> - size - |> int.parse - |> result.map(fn(size) { - case size > max_body_limit { - True -> - response.new(413) - |> response.set_body(bit_builder.new()) - |> response.prepend_header("connection", "close") - False -> - req - |> http.read_body - |> result.map(handler) - |> result.unwrap(bad_request) - } - }) - |> result.unwrap(bad_request) - } - |> response.map(BitBuilderBody) - |> Response - }) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam deleted file mode 100644 index c845487a3a8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/http.gleam +++ /dev/null @@ -1,393 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/dynamic.{Dynamic} -import gleam/erlang/atom.{Atom} -import gleam/erlang/charlist.{Charlist} -import gleam/http/request.{Request} -import gleam/http/response.{Response} -import gleam/http -import gleam/int -import gleam/iterator.{Iterator} -import gleam/list -import gleam/map.{Map} -import gleam/option.{Option} -import gleam/pair -import gleam/result -import gleam/string -import gleam/uri -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} -import mist/internal/encoder -import mist/internal/file -import mist/internal/websocket - -pub type PacketType { - Http - HttphBin - HttpBin -} - -pub type HttpUri { - AbsPath(BitString) -} - -pub type HttpPacket { - HttpRequest(Dynamic, HttpUri, #(Int, Int)) - HttpHeader(Int, Atom, BitString, BitString) -} - -pub type DecodedPacket { - BinaryData(HttpPacket, BitString) - EndOfHeaders(BitString) - MoreData(Option(Int)) -} - -pub type DecodeError { - MalformedRequest - InvalidMethod - InvalidPath - UnknownHeader - UnknownMethod - // TODO: better name? - InvalidBody - DiscardPacket -} - -external fn decode_packet( - packet_type: PacketType, - packet: BitString, - options: List(a), -) -> Result(DecodedPacket, DecodeError) = - "mist_ffi" "decode_packet" - -pub fn from_header(value: BitString) -> String { - let assert Ok(value) = bit_string.to_string(value) - - string.lowercase(value) -} - -pub type Buffer { - Buffer(remaining: Int, data: BitString) -} - -pub fn parse_headers( - bs: BitString, - socket: Socket, - transport: Transport, - headers: Map(String, String), -) -> Result(#(Map(String, String), BitString), DecodeError) { - case decode_packet(HttphBin, bs, []) { - Ok(BinaryData(HttpHeader(_, _field, field, value), rest)) -> { - let field = from_header(field) - let assert Ok(value) = bit_string.to_string(value) - headers - |> map.insert(field, value) - |> parse_headers(rest, socket, transport, _) - } - Ok(EndOfHeaders(rest)) -> Ok(#(headers, rest)) - Ok(MoreData(size)) -> { - let amount_to_read = option.unwrap(size, 0) - use next <- result.then(read_data( - socket, - transport, - Buffer(amount_to_read, bs), - UnknownHeader, - )) - parse_headers(next, socket, transport, headers) - } - _other -> Error(UnknownHeader) - } -} - -pub fn read_data( - socket: Socket, - transport: Transport, - buffer: Buffer, - error: DecodeError, -) -> Result(BitString, DecodeError) { - // TODO: don't hard-code these, probably - let to_read = int.min(buffer.remaining, 1_000_000) - let timeout = 15_000 - use data <- result.then( - socket - |> transport.receive_timeout(to_read, timeout) - |> result.replace_error(error), - ) - let next_buffer = - Buffer( - remaining: buffer.remaining - to_read, - data: <<buffer.data:bit_string, data:bit_string>>, - ) - - case next_buffer.remaining > 0 { - True -> read_data(socket, transport, next_buffer, error) - False -> Ok(next_buffer.data) - } -} - -external fn binary_match( - source: BitString, - pattern: BitString, -) -> Result(#(Int, Int), Nil) = - "mist_ffi" "binary_match" - -external fn string_to_int(string: Charlist, base: Int) -> Result(Int, Nil) = - "mist_ffi" "string_to_int" - -const crnl = <<13:int, 10:int>> - -fn read_chunk( - socket: Socket, - transport: Transport, - buffer: Buffer, - body: BitBuilder, -) -> Result(BitBuilder, DecodeError) { - case buffer.data, binary_match(buffer.data, crnl) { - _, Ok(#(offset, _)) -> { - let assert << - chunk:binary-size(offset), - _return:int, - _newline:int, - rest:binary, - >> = buffer.data - use chunk_size <- result.then( - chunk - |> bit_string.to_string - |> result.map(charlist.from_string) - |> result.replace_error(InvalidBody), - ) - use size <- result.then( - string_to_int(chunk_size, 16) - |> result.replace_error(InvalidBody), - ) - case size { - 0 -> Ok(body) - size -> - case rest { - <<next_chunk:binary-size(size), 13:int, 10:int, rest:binary>> -> - read_chunk( - socket, - transport, - Buffer(0, rest), - bit_builder.append(body, next_chunk), - ) - _ -> { - use next <- result.then(read_data( - socket, - transport, - Buffer(0, buffer.data), - InvalidBody, - )) - read_chunk(socket, transport, Buffer(0, next), body) - } - } - } - } - <<>>, _ -> { - use next <- result.then(read_data( - socket, - transport, - Buffer(0, buffer.data), - InvalidBody, - )) - read_chunk(socket, transport, Buffer(0, next), body) - } - _, Error(Nil) -> Error(InvalidBody) - } -} - -/// Turns the TCP message into an HTTP request -pub fn parse_request( - bs: BitString, - socket: Socket, - transport: Transport, -) -> Result(request.Request(Body), DecodeError) { - case decode_packet(HttpBin, bs, []) { - Ok(BinaryData(HttpRequest(http_method, AbsPath(path), _version), rest)) -> { - use method <- result.then( - http_method - |> atom.from_dynamic - |> result.map(atom.to_string) - |> result.or(dynamic.string(http_method)) - |> result.nil_error - |> result.then(http.parse_method) - |> result.replace_error(UnknownMethod), - ) - use #(headers, rest) <- result.then(parse_headers( - rest, - socket, - transport, - map.new(), - )) - use path <- result.then( - path - |> bit_string.to_string - |> result.replace_error(InvalidPath), - ) - let #(path, query) = case string.split(path, "?") { - [path] -> #(path, []) - [path, query_string] -> { - let query = - query_string - |> uri.parse_query - |> result.unwrap([]) - #(path, query) - } - } - let req = - request.new() - |> request.set_scheme(case transport { - transport.Ssl(..) -> http.Https - transport.Tcp(..) -> http.Http - }) - |> request.set_body(Unread(rest, socket)) - |> request.set_method(method) - |> request.set_path(path) - |> request.set_query(query) - Ok(request.Request(..req, headers: map.to_list(headers))) - } - _ -> Error(DiscardPacket) - } -} - -pub opaque type Body { - Unread(rest: BitString, socket: Socket) - Read(data: BitString) -} - -pub fn read_body(req: Request(Body)) -> Result(Request(BitString), DecodeError) { - let transport = case req.scheme { - http.Https -> transport.ssl() - http.Http -> transport.tcp() - } - case request.get_header(req, "transfer-encoding"), req.body { - Ok("chunked"), Unread(rest, socket) -> { - use chunk <- result.then(read_chunk( - socket, - transport, - Buffer(remaining: 0, data: rest), - bit_builder.new(), - )) - Ok(request.set_body(req, bit_builder.to_bit_string(chunk))) - } - _, Unread(rest, socket) -> { - let _continue = case is_continue(req) { - True -> { - let assert Ok(Nil) = - response.new(100) - |> response.set_body(bit_builder.new()) - |> encoder.to_bit_builder - |> transport.send(socket, _) - Nil - } - False -> Nil - } - let body_size = - req.headers - |> list.find(fn(tup) { pair.first(tup) == "content-length" }) - |> result.map(pair.second) - |> result.then(int.parse) - |> result.unwrap(0) - let remaining = body_size - bit_string.byte_size(rest) - case body_size, remaining { - 0, 0 -> Ok(<<>>) - 0, _n -> Ok(rest) - // is this pipelining? check for GET? - _n, 0 -> Ok(rest) - _size, _rem -> - read_data(socket, transport, Buffer(remaining, rest), InvalidBody) - } - |> result.map(request.set_body(req, _)) - |> result.replace_error(InvalidBody) - } - _, Read(_data) -> Error(InvalidBody) - } -} - -pub type HttpResponseBody { - BitBuilderBody(BitBuilder) - Chunked(Iterator(BitBuilder)) - FileBody( - file_descriptor: file.FileDescriptor, - content_type: String, - offset: Int, - length: Int, - ) -} - -pub fn upgrade_socket( - req: Request(Body), -) -> Result(Response(BitBuilder), Request(Body)) { - use _upgrade <- result.then( - request.get_header(req, "upgrade") - |> result.replace_error(req), - ) - use key <- result.then( - request.get_header(req, "sec-websocket-key") - |> result.replace_error(req), - ) - use _version <- result.then( - request.get_header(req, "sec-websocket-version") - |> result.replace_error(req), - ) - - let accept_key = websocket.parse_key(key) - - response.new(101) - |> response.set_body(bit_builder.new()) - |> response.prepend_header("Upgrade", "websocket") - |> response.prepend_header("Connection", "Upgrade") - |> response.prepend_header("Sec-WebSocket-Accept", accept_key) - |> Ok -} - -// TODO: improve this error type -pub fn upgrade( - socket: Socket, - transport: Transport, - req: Request(Body), -) -> Result(Nil, Nil) { - use resp <- result.then( - upgrade_socket(req) - |> result.nil_error, - ) - - use _sent <- result.then( - resp - |> add_default_headers - |> encoder.to_bit_builder - |> transport.send(socket, _) - |> result.nil_error, - ) - - Ok(Nil) -} - -pub fn add_default_headers(resp: Response(BitBuilder)) -> Response(BitBuilder) { - let body_size = bit_builder.byte_size(resp.body) - - let headers = - map.from_list([ - #("content-length", int.to_string(body_size)), - #("connection", "keep-alive"), - ]) - |> list.fold( - resp.headers, - _, - fn(defaults, tup) { - let #(key, value) = tup - map.insert(defaults, key, value) - }, - ) - |> map.to_list - - Response(..resp, headers: headers) -} - -fn is_continue(req: Request(Body)) -> Bool { - req.headers - |> list.find(fn(tup) { - pair.first(tup) == "expect" && pair.second(tup) == "100-continue" - }) - |> result.is_ok -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam deleted file mode 100644 index 14a31a6ce54..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/logger.gleam +++ /dev/null @@ -1,8 +0,0 @@ -import gleam/erlang/charlist.{Charlist} - -external fn log_error(format: Charlist, data: any) -> Nil = - "logger" "error" - -pub fn error(data: any) -> Nil { - log_error(charlist.from_string("~tp"), [data]) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam deleted file mode 100644 index 50318f2c6fe..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/internal/websocket.gleam +++ /dev/null @@ -1,167 +0,0 @@ -import gleam/bit_builder.{BitBuilder} -import gleam/bit_string -import gleam/erlang/process.{Subject} -import gleam/list -import gleam/option.{Option} -import gleam/string -import glisten/handler.{HandlerMessage} -import glisten/socket.{Socket} -import glisten/socket/transport.{Transport} - -pub type Message { - BinaryMessage(data: BitString) - TextMessage(data: String) -} - -pub type Handler = - fn(Message, Subject(HandlerMessage)) -> Result(Nil, Nil) - -// TODO: there are other message types, AND ALSO will need to buffer across -// multiple frames, potentially -pub type Frame { - // TODO: should this include data? - CloseFrame(payload_length: Int, payload: BitString) - TextFrame(payload_length: Int, payload: BitString) - BinaryFrame(payload_length: Int, payload: BitString) - // We don't care about basicaly everything else for now - PingFrame(payload_length: Int, payload: BitString) - PongFrame(payload_length: Int, payload: BitString) -} - -external fn crypto_exor(a: BitString, b: BitString) -> BitString = - "crypto" "exor" - -fn unmask_data( - data: BitString, - masks: List(BitString), - index: Int, - resp: BitString, -) -> BitString { - case data { - <<>> -> resp - <<masked:bit_string-size(8), rest:bit_string>> -> { - let assert Ok(mask_value) = list.at(masks, index % 4) - let unmasked = crypto_exor(mask_value, masked) - unmask_data( - rest, - masks, - index + 1, - <<resp:bit_string, unmasked:bit_string>>, - ) - } - } -} - -pub fn frame_from_message( - socket: Socket, - transport: Transport, - message: BitString, -) -> Result(Frame, Nil) { - let assert <<_fin:1, rest:bit_string>> = message - let assert <<_reserved:3, rest:bit_string>> = rest - let assert <<opcode:int-size(4), rest:bit_string>> = rest - case opcode { - 1 | 2 -> { - // mask - let assert <<1:1, rest:bit_string>> = rest - let assert <<payload_length:int-size(7), rest:bit_string>> = rest - let #(payload_length, rest) = case payload_length { - 126 -> { - let assert <<length:int-size(16), rest:bit_string>> = rest - #(length, rest) - } - 127 -> { - let assert <<length:int-size(64), rest:bit_string>> = rest - #(length, rest) - } - _ -> #(payload_length, rest) - } - let assert << - mask1:bit_string-size(8), - mask2:bit_string-size(8), - mask3:bit_string-size(8), - mask4:bit_string-size(8), - rest:bit_string, - >> = rest - let data = case payload_length - bit_string.byte_size(rest) { - 0 -> unmask_data(rest, [mask1, mask2, mask3, mask4], 0, <<>>) - need -> { - let assert Ok(needed) = transport.receive(socket, need) - rest - |> bit_string.append(needed) - |> unmask_data([mask1, mask2, mask3, mask4], 0, <<>>) - } - } - case opcode { - 1 -> TextFrame(payload_length, data) - 2 -> BinaryFrame(payload_length, data) - } - |> Ok - } - 8 -> Ok(CloseFrame(payload_length: 0, payload: <<>>)) - } -} - -pub fn frame_to_bit_builder(frame: Frame) -> BitBuilder { - case frame { - TextFrame(payload_length, payload) -> make_frame(1, payload_length, payload) - CloseFrame(payload_length, payload) -> - make_frame(8, payload_length, payload) - BinaryFrame(payload_length, payload) -> - make_frame(2, payload_length, payload) - PongFrame(payload_length, payload) -> - make_frame(10, payload_length, payload) - PingFrame(..) -> bit_builder.from_bit_string(<<>>) - } -} - -fn make_frame(opcode: Int, length: Int, payload: BitString) -> BitBuilder { - let length_section = case length { - length if length > 65_535 -> <<127:7, length:int-size(64)>> - length if length >= 126 -> <<126:7, length:int-size(16)>> - _length -> <<length:7>> - } - - <<1:1, 0:3, opcode:4, 0:1, length_section:bit_string, payload:bit_string>> - |> bit_builder.from_bit_string -} - -pub fn to_text_frame(data: BitString) -> BitBuilder { - let size = bit_string.byte_size(data) - frame_to_bit_builder(TextFrame(size, data)) -} - -pub fn to_binary_frame(data: BitString) -> BitBuilder { - let size = bit_string.byte_size(data) - frame_to_bit_builder(BinaryFrame(size, data)) -} - -const websocket_key = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - -pub type ShaHash { - Sha -} - -pub external fn crypto_hash(hash: ShaHash, data: String) -> String = - "crypto" "hash" - -pub external fn base64_encode(data: String) -> String = - "base64" "encode" - -pub fn parse_key(key: String) -> String { - key - |> string.append(websocket_key) - |> crypto_hash(Sha, _) - |> base64_encode -} - -pub type EventHandler = - fn(Subject(HandlerMessage)) -> Nil - -pub type WebsocketHandler { - WebsocketHandler( - on_close: Option(EventHandler), - on_init: Option(EventHandler), - handler: Handler, - ) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam b/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam deleted file mode 100644 index 4205bfe793d..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist/websocket.gleam +++ /dev/null @@ -1,51 +0,0 @@ -import gleam/bit_string -import gleam/erlang/process.{Subject} -import gleam/option.{None, Some} -import glisten/handler.{HandlerMessage, SendMessage} -import mist/internal/websocket.{ - BinaryMessage, EventHandler, Handler, Message, TextMessage, WebsocketHandler, - to_binary_frame, to_text_frame, -} - -/// Helper to encapsulate the logic to send a provided message over the -/// WebSocket -pub fn send(sender: Subject(HandlerMessage), message: Message) -> Nil { - case message { - TextMessage(data) -> - data - |> bit_string.from_string - |> to_text_frame - BinaryMessage(data) -> to_binary_frame(data) - } - |> SendMessage - |> process.send(sender, _) - - Nil -} - -pub fn echo_handler( - message: Message, - sender: Subject(HandlerMessage), -) -> Result(Nil, Nil) { - let _ = send(sender, message) - - Ok(Nil) -} - -pub fn with_handler(func: Handler) -> WebsocketHandler { - WebsocketHandler(on_close: None, on_init: None, handler: func) -} - -pub fn on_init( - handler: WebsocketHandler, - func: EventHandler, -) -> WebsocketHandler { - WebsocketHandler(..handler, on_init: Some(func)) -} - -pub fn on_close( - handler: WebsocketHandler, - func: EventHandler, -) -> WebsocketHandler { - WebsocketHandler(..handler, on_close: Some(func)) -} diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl deleted file mode 100644 index 78d65345b19..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@encoder.erl +++ /dev/null @@ -1,209 +0,0 @@ --module(mist@internal@encoder). --compile([no_auto_import, nowarn_unused_vars]). - --export([status_to_bit_string/1, encode_headers/1, response_builder/2, to_bit_builder/1]). - --spec status_to_bit_string(integer()) -> bitstring(). -status_to_bit_string(Status) -> - case Status of - 100 -> - <<"Continue"/utf8>>; - - 101 -> - <<"Switching Protocols"/utf8>>; - - 103 -> - <<"Early Hints"/utf8>>; - - 200 -> - <<"OK"/utf8>>; - - 201 -> - <<"Created"/utf8>>; - - 202 -> - <<"Accepted"/utf8>>; - - 203 -> - <<"Non-Authoritative Information"/utf8>>; - - 204 -> - <<"No Content"/utf8>>; - - 205 -> - <<"Reset Content"/utf8>>; - - 206 -> - <<"Partial Content"/utf8>>; - - 300 -> - <<"Multiple Choices"/utf8>>; - - 301 -> - <<"Moved Permanently"/utf8>>; - - 302 -> - <<"Found"/utf8>>; - - 303 -> - <<"See Other"/utf8>>; - - 304 -> - <<"Not Modified"/utf8>>; - - 307 -> - <<"Temporary Redirect"/utf8>>; - - 308 -> - <<"Permanent Redirect"/utf8>>; - - 400 -> - <<"Bad Request"/utf8>>; - - 401 -> - <<"Unauthorized"/utf8>>; - - 402 -> - <<"Payment Required"/utf8>>; - - 403 -> - <<"Forbidden"/utf8>>; - - 404 -> - <<"Not Found"/utf8>>; - - 405 -> - <<"Method Not Allowed"/utf8>>; - - 406 -> - <<"Not Acceptable"/utf8>>; - - 407 -> - <<"Proxy Authentication Required"/utf8>>; - - 408 -> - <<"Request Timeout"/utf8>>; - - 409 -> - <<"Conflict"/utf8>>; - - 410 -> - <<"Gone"/utf8>>; - - 411 -> - <<"Length Required"/utf8>>; - - 412 -> - <<"Precondition Failed"/utf8>>; - - 413 -> - <<"Payload Too Large"/utf8>>; - - 414 -> - <<"URI Too Long"/utf8>>; - - 415 -> - <<"Unsupported Media Type"/utf8>>; - - 416 -> - <<"Range Not Satisfiable"/utf8>>; - - 417 -> - <<"Expectation Failed"/utf8>>; - - 418 -> - <<"I'm a teapot"/utf8>>; - - 422 -> - <<"Unprocessable Entity"/utf8>>; - - 425 -> - <<"Too Early"/utf8>>; - - 426 -> - <<"Upgrade Required"/utf8>>; - - 428 -> - <<"Precondition Required"/utf8>>; - - 429 -> - <<"Too Many Requests"/utf8>>; - - 431 -> - <<"Request Header Fields Too Large"/utf8>>; - - 451 -> - <<"Unavailable For Legal Reasons"/utf8>>; - - 500 -> - <<"Internal Server Error"/utf8>>; - - 501 -> - <<"Not Implemented"/utf8>>; - - 502 -> - <<"Bad Gateway"/utf8>>; - - 503 -> - <<"Service Unavailable"/utf8>>; - - 504 -> - <<"Gateway Timeout"/utf8>>; - - 505 -> - <<"HTTP Version Not Supported"/utf8>>; - - 506 -> - <<"Variant Also Negotiates"/utf8>>; - - 507 -> - <<"Insufficient Storage"/utf8>>; - - 508 -> - <<"Loop Detected"/utf8>>; - - 510 -> - <<"Not Extended"/utf8>>; - - 511 -> - <<"Network Authentication Required"/utf8>> - end. - --spec encode_headers(list({binary(), binary()})) -> gleam@bit_builder:bit_builder(). -encode_headers(Headers) -> - gleam@list:fold( - Headers, - gleam@bit_builder:new(), - fun(Builder, Tup) -> - {Header, Value} = Tup, - _pipe = Builder, - _pipe@1 = gleam@bit_builder:append_string(_pipe, Header), - _pipe@2 = gleam@bit_builder:append(_pipe@1, <<": "/utf8>>), - _pipe@3 = gleam@bit_builder:append_string(_pipe@2, Value), - gleam@bit_builder:append(_pipe@3, <<"\r\n"/utf8>>) - end - ). - --spec response_builder(integer(), list({binary(), binary()})) -> gleam@bit_builder:bit_builder(). -response_builder(Status, Headers) -> - Status_string = begin - _pipe = Status, - _pipe@1 = gleam@int:to_string(_pipe), - _pipe@2 = gleam@bit_builder:from_string(_pipe@1), - _pipe@3 = gleam@bit_builder:append(_pipe@2, <<" "/utf8>>), - gleam@bit_builder:append(_pipe@3, status_to_bit_string(Status)) - end, - _pipe@4 = gleam@bit_builder:new(), - _pipe@5 = gleam@bit_builder:append(_pipe@4, <<"HTTP/1.1 "/utf8>>), - _pipe@6 = gleam@bit_builder:append_builder(_pipe@5, Status_string), - _pipe@7 = gleam@bit_builder:append(_pipe@6, <<"\r\n"/utf8>>), - _pipe@8 = gleam@bit_builder:append_builder(_pipe@7, encode_headers(Headers)), - gleam@bit_builder:append(_pipe@8, <<"\r\n"/utf8>>). - --spec to_bit_builder( - gleam@http@response:response(gleam@bit_builder:bit_builder()) -) -> gleam@bit_builder:bit_builder(). -to_bit_builder(Resp) -> - _pipe = erlang:element(2, Resp), - _pipe@1 = response_builder(_pipe, erlang:element(3, Resp)), - gleam@bit_builder:append_builder(_pipe@1, erlang:element(4, Resp)). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl deleted file mode 100644 index 51bd02b0819..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@file.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(mist@internal@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([size/1, sendfile/5, open/1]). --export_type([file_error/0, file_descriptor/0]). - --type file_error() :: is_dir | no_access | no_entry | unknown_file_error. - --type file_descriptor() :: any(). - --spec size(bitstring()) -> integer(). -size(Field@0) -> - filelib:file_size(Field@0). - --spec sendfile( - file_descriptor(), - glisten@socket:socket(), - integer(), - integer(), - list(any()) -) -> {ok, integer()} | {error, gleam@erlang@atom:atom_()}. -sendfile(Field@0, Field@1, Field@2, Field@3, Field@4) -> - file:sendfile(Field@0, Field@1, Field@2, Field@3, Field@4). - --spec open(bitstring()) -> {ok, file_descriptor()} | {error, file_error()}. -open(Field@0) -> - mist_ffi:file_open(Field@0). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl deleted file mode 100644 index 7b0afe0b615..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@handler.erl +++ /dev/null @@ -1,577 +0,0 @@ --module(mist@internal@handler). --compile([no_auto_import, nowarn_unused_vars]). - --export([new_state/0, with_func/1, with/2]). --export_type([handler_response/0, handler_error/0, state/0]). - --type handler_response() :: {response, - gleam@http@response:response(mist@internal@http:http_response_body())} | - {upgrade, mist@internal@websocket:websocket_handler()}. - --type handler_error() :: {invalid_request, mist@internal@http:decode_error()} | - not_found. - --type state() :: {state, - gleam@option:option(gleam@erlang@process:timer()), - gleam@option:option(mist@internal@websocket:websocket_handler())}. - --spec new_state() -> state(). -new_state() -> - {state, none, none}. - --spec handle_websocket_message( - glisten@handler:loop_state(state()), - mist@internal@websocket:websocket_handler(), - bitstring() -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_websocket_message(State, Handler, Msg) -> - case mist@internal@websocket:frame_from_message( - erlang:element(2, State), - erlang:element(4, State), - Msg - ) of - {ok, {ping_frame, _, _}} -> - _assert_subject = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - mist@internal@websocket:frame_to_bit_builder( - {pong_frame, 0, <<>>} - ) - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_websocket_message"/utf8>>, - line => 119}) - end, - {continue, State}; - - {ok, {close_frame, _, _} = Frame} -> - _assert_subject@1 = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - mist@internal@websocket:frame_to_bit_builder(Frame) - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_websocket_message"/utf8>>, - line => 127}) - end, - _ = case erlang:element(2, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal}; - - {ok, {pong_frame, _, _}} -> - {stop, normal}; - - {ok, Frame@1} -> - _pipe = case Frame@1 of - {text_frame, _, Payload} -> - _assert_subject@2 = gleam@bit_string:to_string(Payload), - {ok, Msg@1} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_websocket_message"/utf8>>, - line => 142}) - end, - {text_message, Msg@1}; - - _ -> - {binary_message, erlang:element(3, Frame@1)} - end, - _pipe@1 = (fun(Ws_msg) -> - gleam_erlang_ffi:rescue( - fun() -> - (erlang:element(4, Handler))( - Ws_msg, - erlang:element(3, State) - ) - end - ) - end)(_pipe), - _pipe@2 = gleam@result:replace(_pipe@1, {continue, State}), - _pipe@3 = gleam@result:map_error( - _pipe@2, - fun(Err) -> - mist@internal@logger:error(Err), - _ = case erlang:element(2, Handler) of - {some, Func@1} -> - Func@1(erlang:element(3, State)); - - _ -> - nil - end, - Err - end - ), - _pipe@4 = gleam@result:replace_error(_pipe@3, {stop, normal}), - gleam@result:unwrap_both(_pipe@4); - - {error, _} -> - _ = case erlang:element(2, Handler) of - {some, Func@2} -> - Func@2(erlang:element(3, State)); - - _ -> - nil - end, - {stop, normal} - end. - --spec log_and_error( - gleam@erlang:crash(), - glisten@socket:socket(), - glisten@socket@transport:transport() -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -log_and_error(Error, Socket, Transport) -> - case Error of - {exited, Msg} -> - mist@internal@logger:error(Error), - _pipe = gleam@http@response:new(500), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:from_bit_string( - <<"Internal Server Error"/utf8>> - ) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-length"/utf8>>, - <<"21"/utf8>> - ), - _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), - _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), - (erlang:element(11, Transport))(Socket, _pipe@4), - _ = (erlang:element(4, Transport))(Socket), - {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}}; - - {thrown, Msg} -> - mist@internal@logger:error(Error), - _pipe = gleam@http@response:new(500), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:from_bit_string( - <<"Internal Server Error"/utf8>> - ) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-length"/utf8>>, - <<"21"/utf8>> - ), - _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), - _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), - (erlang:element(11, Transport))(Socket, _pipe@4), - _ = (erlang:element(4, Transport))(Socket), - {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}}; - - {errored, Msg} -> - mist@internal@logger:error(Error), - _pipe = gleam@http@response:new(500), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:from_bit_string( - <<"Internal Server Error"/utf8>> - ) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-length"/utf8>>, - <<"21"/utf8>> - ), - _pipe@3 = mist@internal@http:add_default_headers(_pipe@2), - _pipe@4 = mist@internal@encoder:to_bit_builder(_pipe@3), - (erlang:element(11, Transport))(Socket, _pipe@4), - _ = (erlang:element(4, Transport))(Socket), - {stop, {abnormal, gleam@dynamic:unsafe_coerce(Msg)}} - end. - --spec handle_bit_builder_body( - gleam@http@response:response(mist@internal@http:http_response_body()), - gleam@bit_builder:bit_builder(), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_bit_builder_body(Resp, Body, State) -> - _pipe = Resp, - _pipe@1 = gleam@http@response:set_body(_pipe, Body), - _pipe@2 = mist@internal@http:add_default_headers(_pipe@1), - _pipe@3 = mist@internal@encoder:to_bit_builder(_pipe@2), - _pipe@4 = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - _pipe@3 - ), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(_) -> - case gleam@http@response:get_header(Resp, <<"connection"/utf8>>) of - {ok, <<"close"/utf8>>} -> - _ = (erlang:element(4, erlang:element(4, State)))( - erlang:element(2, State) - ), - {stop, normal}; - - _ -> - Timer = gleam@erlang@process:send_after( - erlang:element(3, State), - 10000, - close - ), - {continue, - erlang:setelement( - 5, - State, - erlang:setelement( - 2, - erlang:element(5, State), - {some, Timer} - ) - )} - end - end - ), - _pipe@6 = gleam@result:replace_error(_pipe@5, {stop, normal}), - gleam@result:unwrap_both(_pipe@6). - --spec handle_file_body( - gleam@http@response:response(mist@internal@http:http_response_body()), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_file_body(Resp, State) -> - _assert_subject = erlang:element(4, Resp), - {file_body, File_descriptor, Content_type, Offset, Length} = case _assert_subject of - {file_body, _, _, _, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/handler"/utf8>>, - function => <<"handle_file_body"/utf8>>, - line => 268}) - end, - _pipe = Resp, - _pipe@1 = gleam@http@response:prepend_header( - _pipe, - <<"content-length"/utf8>>, - gleam@int:to_string(Length - Offset) - ), - _pipe@2 = gleam@http@response:prepend_header( - _pipe@1, - <<"content-type"/utf8>>, - Content_type - ), - _pipe@3 = gleam@http@response:set_body(_pipe@2, gleam@bit_builder:new()), - _pipe@4 = (fun(R) -> - mist@internal@encoder:response_builder( - erlang:element(2, Resp), - erlang:element(3, R) - ) - end)(_pipe@3), - _pipe@5 = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - _pipe@4 - ), - _pipe@6 = gleam@result:map( - _pipe@5, - fun(_) -> - file:sendfile( - File_descriptor, - erlang:element(2, State), - Offset, - Length, - [] - ) - end - ), - _pipe@7 = gleam@result:replace(_pipe@6, {continue, State}), - _pipe@8 = gleam@result:replace_error(_pipe@7, {stop, normal}), - gleam@result:unwrap_both(_pipe@8). - --spec handle_upgrade( - gleam@http@request:request(mist@internal@http:body()), - mist@internal@websocket:websocket_handler(), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_upgrade(Req, Handler, State) -> - _pipe = Req, - _pipe@1 = mist@internal@http:upgrade( - erlang:element(2, State), - erlang:element(4, State), - _pipe - ), - _pipe@2 = gleam@result:map( - _pipe@1, - fun(_) -> _ = case erlang:element(3, Handler) of - {some, Func} -> - Func(erlang:element(3, State)); - - _ -> - nil - end end - ), - _pipe@3 = gleam@result:replace( - _pipe@2, - {continue, - erlang:setelement( - 5, - State, - erlang:setelement(3, erlang:element(5, State), {some, Handler}) - )} - ), - _pipe@4 = gleam@result:replace_error(_pipe@3, {stop, normal}), - gleam@result:unwrap_both(_pipe@4). - --spec int_to_hex(integer()) -> binary(). -int_to_hex(Int) -> - erlang:integer_to_list(Int, 16). - --spec handle_chunked_body( - gleam@http@response:response(mist@internal@http:http_response_body()), - gleam@iterator:iterator(gleam@bit_builder:bit_builder()), - glisten@handler:loop_state(state()) -) -> gleam@otp@actor:next(glisten@handler:loop_state(state())). -handle_chunked_body(Resp, Body, State) -> - Headers = [{<<"transfer-encoding"/utf8>>, <<"chunked"/utf8>>} | - erlang:element(3, Resp)], - Initial_payload = mist@internal@encoder:response_builder( - erlang:element(2, Resp), - Headers - ), - _pipe = (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - Initial_payload - ), - _pipe@8 = gleam@result:then(_pipe, fun(_) -> _pipe@1 = Body, - _pipe@2 = gleam@iterator:append( - _pipe@1, - gleam@iterator:from_list([gleam@bit_builder:new()]) - ), - gleam@iterator:try_fold( - _pipe@2, - nil, - fun(_, Chunk) -> - Size = gleam@bit_builder:byte_size(Chunk), - Encoded = begin - _pipe@3 = Size, - _pipe@4 = int_to_hex(_pipe@3), - _pipe@5 = gleam@bit_builder:from_string(_pipe@4), - _pipe@6 = gleam@bit_builder:append_string( - _pipe@5, - <<"\r\n"/utf8>> - ), - _pipe@7 = gleam@bit_builder:append_builder( - _pipe@6, - Chunk - ), - gleam@bit_builder:append_string( - _pipe@7, - <<"\r\n"/utf8>> - ) - end, - (erlang:element(11, erlang:element(4, State)))( - erlang:element(2, State), - Encoded - ) - end - ) end), - _pipe@9 = gleam@result:replace(_pipe@8, {continue, State}), - gleam@result:unwrap(_pipe@9, {stop, normal}). - --spec with_func( - fun((gleam@http@request:request(mist@internal@http:body())) -> handler_response()) -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(state())) -> gleam@otp@actor:next(glisten@handler:loop_state(state()))). -with_func(Handler) -> - glisten@handler:func( - fun(Msg, Socket_state) -> - {loop_state, Socket, _, Transport, State} = Socket_state, - case erlang:element(3, State) of - {some, Ws_handler} -> - handle_websocket_message(Socket_state, Ws_handler, Msg); - - none -> - _pipe@7 = begin - _ = case erlang:element(2, State) of - {some, T} -> - gleam@erlang@process:cancel_timer(T); - - _ -> - timer_not_found - end, - _pipe = Msg, - _pipe@1 = mist@internal@http:parse_request( - _pipe, - Socket, - Transport - ), - _pipe@2 = gleam@result:map_error( - _pipe@1, - fun(Err) -> case Err of - discard_packet -> - nil; - - _ -> - mist@internal@logger:error(Err), - _ = (erlang:element(4, Transport))( - Socket - ), - nil - end end - ), - _pipe@3 = gleam@result:replace_error( - _pipe@2, - {stop, normal} - ), - _pipe@6 = gleam@result:then( - _pipe@3, - fun(Req) -> - _pipe@4 = gleam_erlang_ffi:rescue( - fun() -> Handler(Req) end - ), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(Resp) -> {Req, Resp} end - ), - gleam@result:map_error( - _pipe@5, - fun(_capture) -> - log_and_error( - _capture, - erlang:element(2, Socket_state), - erlang:element(4, Socket_state) - ) - end - ) - end - ), - gleam@result:map( - _pipe@6, - fun(Req_resp) -> - {Req@1, Response} = Req_resp, - case Response of - {response, - {response, - _, - _, - {bit_builder_body, Body}} = Resp@1} -> - handle_bit_builder_body( - Resp@1, - Body, - Socket_state - ); - - {response, - {response, _, _, {chunked, Body@1}} = Resp@2} -> - handle_chunked_body( - Resp@2, - Body@1, - Socket_state - ); - - {response, - {response, - _, - _, - {file_body, _, _, _, _}} = Resp@3} -> - handle_file_body(Resp@3, Socket_state); - - {upgrade, With_handler} -> - handle_upgrade( - Req@1, - With_handler, - Socket_state - ) - end - end - ) - end, - gleam@result:unwrap_both(_pipe@7) - end - end - ). - --spec with( - fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder())), - integer() -) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(state())) -> gleam@otp@actor:next(glisten@handler:loop_state(state()))). -with(Handler, Max_body_limit) -> - Bad_request = begin - _pipe = gleam@http@response:new(400), - gleam@http@response:set_body(_pipe, gleam@bit_builder:new()) - end, - with_func( - fun(Req) -> - _pipe@14 = case {gleam@http@request:get_header( - Req, - <<"content-length"/utf8>> - ), - gleam@http@request:get_header(Req, <<"transfer-encoding"/utf8>>)} of - {{ok, <<"0"/utf8>>}, _} -> - _pipe@1 = Req, - _pipe@2 = gleam@http@request:set_body(_pipe@1, <<>>), - Handler(_pipe@2); - - {{error, nil}, {error, nil}} -> - _pipe@1 = Req, - _pipe@2 = gleam@http@request:set_body(_pipe@1, <<>>), - Handler(_pipe@2); - - {_, {ok, <<"chunked"/utf8>>}} -> - _pipe@3 = Req, - _pipe@4 = mist@internal@http:read_body(_pipe@3), - _pipe@5 = gleam@result:map(_pipe@4, Handler), - gleam@result:unwrap(_pipe@5, Bad_request); - - {{ok, Size}, _} -> - _pipe@6 = Size, - _pipe@7 = gleam@int:parse(_pipe@6), - _pipe@13 = gleam@result:map( - _pipe@7, - fun(Size@1) -> case Size@1 > Max_body_limit of - true -> - _pipe@8 = gleam@http@response:new(413), - _pipe@9 = gleam@http@response:set_body( - _pipe@8, - gleam@bit_builder:new() - ), - gleam@http@response:prepend_header( - _pipe@9, - <<"connection"/utf8>>, - <<"close"/utf8>> - ); - - false -> - _pipe@10 = Req, - _pipe@11 = mist@internal@http:read_body( - _pipe@10 - ), - _pipe@12 = gleam@result:map( - _pipe@11, - Handler - ), - gleam@result:unwrap(_pipe@12, Bad_request) - end end - ), - gleam@result:unwrap(_pipe@13, Bad_request) - end, - _pipe@15 = gleam@http@response:map( - _pipe@14, - fun(Field@0) -> {bit_builder_body, Field@0} end - ), - {response, _pipe@15} - end - ). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl deleted file mode 100644 index aad9e7db5c8..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@http.erl +++ /dev/null @@ -1,591 +0,0 @@ --module(mist@internal@http). --compile([no_auto_import, nowarn_unused_vars]). - --export([from_header/1, upgrade_socket/1, add_default_headers/1, upgrade/3, parse_headers/4, parse_request/3, read_data/4, read_body/1]). --export_type([packet_type/0, http_uri/0, http_packet/0, decoded_packet/0, decode_error/0, buffer/0, body/0, http_response_body/0]). - --type packet_type() :: http | httph_bin | http_bin. - --type http_uri() :: {abs_path, bitstring()}. - --type http_packet() :: {http_request, - gleam@dynamic:dynamic(), - http_uri(), - {integer(), integer()}} | - {http_header, - integer(), - gleam@erlang@atom:atom_(), - bitstring(), - bitstring()}. - --type decoded_packet() :: {binary_data, http_packet(), bitstring()} | - {end_of_headers, bitstring()} | - {more_data, gleam@option:option(integer())}. - --type decode_error() :: malformed_request | - invalid_method | - invalid_path | - unknown_header | - unknown_method | - invalid_body | - discard_packet. - --type buffer() :: {buffer, integer(), bitstring()}. - --opaque body() :: {unread, bitstring(), glisten@socket:socket()} | - {read, bitstring()}. - --type http_response_body() :: {bit_builder_body, - gleam@bit_builder:bit_builder()} | - {chunked, gleam@iterator:iterator(gleam@bit_builder:bit_builder())} | - {file_body, - mist@internal@file:file_descriptor(), - binary(), - integer(), - integer()}. - --spec from_header(bitstring()) -> binary(). -from_header(Value) -> - _assert_subject = gleam@bit_string:to_string(Value), - {ok, Value@1} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"from_header"/utf8>>, - line => 64}) - end, - gleam@string:lowercase(Value@1). - --spec upgrade_socket(gleam@http@request:request(body())) -> {ok, - gleam@http@response:response(gleam@bit_builder:bit_builder())} | - {error, gleam@http@request:request(body())}. -upgrade_socket(Req) -> - gleam@result:then( - begin - _pipe = gleam@http@request:get_header(Req, <<"upgrade"/utf8>>), - gleam@result:replace_error(_pipe, Req) - end, - fun(_) -> - gleam@result:then( - begin - _pipe@1 = gleam@http@request:get_header( - Req, - <<"sec-websocket-key"/utf8>> - ), - gleam@result:replace_error(_pipe@1, Req) - end, - fun(Key) -> - gleam@result:then( - begin - _pipe@2 = gleam@http@request:get_header( - Req, - <<"sec-websocket-version"/utf8>> - ), - gleam@result:replace_error(_pipe@2, Req) - end, - fun(_) -> - Accept_key = mist@internal@websocket:parse_key(Key), - _pipe@3 = gleam@http@response:new(101), - _pipe@4 = gleam@http@response:set_body( - _pipe@3, - gleam@bit_builder:new() - ), - _pipe@5 = gleam@http@response:prepend_header( - _pipe@4, - <<"Upgrade"/utf8>>, - <<"websocket"/utf8>> - ), - _pipe@6 = gleam@http@response:prepend_header( - _pipe@5, - <<"Connection"/utf8>>, - <<"Upgrade"/utf8>> - ), - _pipe@7 = gleam@http@response:prepend_header( - _pipe@6, - <<"Sec-WebSocket-Accept"/utf8>>, - Accept_key - ), - {ok, _pipe@7} - end - ) - end - ) - end - ). - --spec add_default_headers( - gleam@http@response:response(gleam@bit_builder:bit_builder()) -) -> gleam@http@response:response(gleam@bit_builder:bit_builder()). -add_default_headers(Resp) -> - Body_size = gleam@bit_builder:byte_size(erlang:element(4, Resp)), - Headers = begin - _pipe = gleam@map:from_list( - [{<<"content-length"/utf8>>, gleam@int:to_string(Body_size)}, - {<<"connection"/utf8>>, <<"keep-alive"/utf8>>}] - ), - _pipe@1 = gleam@list:fold( - erlang:element(3, Resp), - _pipe, - fun(Defaults, Tup) -> - {Key, Value} = Tup, - gleam@map:insert(Defaults, Key, Value) - end - ), - gleam@map:to_list(_pipe@1) - end, - erlang:setelement(3, Resp, Headers). - --spec upgrade( - glisten@socket:socket(), - glisten@socket@transport:transport(), - gleam@http@request:request(body()) -) -> {ok, nil} | {error, nil}. -upgrade(Socket, Transport, Req) -> - gleam@result:then( - begin - _pipe = upgrade_socket(Req), - gleam@result:nil_error(_pipe) - end, - fun(Resp) -> - gleam@result:then( - begin - _pipe@1 = Resp, - _pipe@2 = add_default_headers(_pipe@1), - _pipe@3 = mist@internal@encoder:to_bit_builder(_pipe@2), - _pipe@4 = (erlang:element(11, Transport))(Socket, _pipe@3), - gleam@result:nil_error(_pipe@4) - end, - fun(_) -> {ok, nil} end - ) - end - ). - --spec is_continue(gleam@http@request:request(body())) -> boolean(). -is_continue(Req) -> - _pipe = erlang:element(3, Req), - _pipe@1 = gleam@list:find( - _pipe, - fun(Tup) -> - (gleam@pair:first(Tup) =:= <<"expect"/utf8>>) andalso (gleam@pair:second( - Tup - ) - =:= <<"100-continue"/utf8>>) - end - ), - gleam@result:is_ok(_pipe@1). - --spec parse_headers( - bitstring(), - glisten@socket:socket(), - glisten@socket@transport:transport(), - gleam@map:map_(binary(), binary()) -) -> {ok, {gleam@map:map_(binary(), binary()), bitstring()}} | - {error, decode_error()}. -parse_headers(Bs, Socket, Transport, Headers) -> - case mist_ffi:decode_packet(httph_bin, Bs, []) of - {ok, {binary_data, {http_header, _, _, Field, Value}, Rest}} -> - Field@1 = from_header(Field), - _assert_subject = gleam@bit_string:to_string(Value), - {ok, Value@1} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"parse_headers"/utf8>>, - line => 82}) - end, - _pipe = Headers, - _pipe@1 = gleam@map:insert(_pipe, Field@1, Value@1), - parse_headers(Rest, Socket, Transport, _pipe@1); - - {ok, {end_of_headers, Rest@1}} -> - {ok, {Headers, Rest@1}}; - - {ok, {more_data, Size}} -> - Amount_to_read = gleam@option:unwrap(Size, 0), - gleam@result:then( - read_data( - Socket, - Transport, - {buffer, Amount_to_read, Bs}, - unknown_header - ), - fun(Next) -> parse_headers(Next, Socket, Transport, Headers) end - ); - - _ -> - {error, unknown_header} - end. - --spec parse_request( - bitstring(), - glisten@socket:socket(), - glisten@socket@transport:transport() -) -> {ok, gleam@http@request:request(body())} | {error, decode_error()}. -parse_request(Bs, Socket, Transport) -> - case mist_ffi:decode_packet(http_bin, Bs, []) of - {ok, - {binary_data, - {http_request, Http_method, {abs_path, Path}, _}, - Rest}} -> - gleam@result:then( - begin - _pipe = Http_method, - _pipe@1 = gleam_erlang_ffi:atom_from_dynamic(_pipe), - _pipe@2 = gleam@result:map( - _pipe@1, - fun gleam@erlang@atom:to_string/1 - ), - _pipe@3 = gleam@result:'or'( - _pipe@2, - gleam@dynamic:string(Http_method) - ), - _pipe@4 = gleam@result:nil_error(_pipe@3), - _pipe@5 = gleam@result:then( - _pipe@4, - fun gleam@http:parse_method/1 - ), - gleam@result:replace_error(_pipe@5, unknown_method) - end, - fun(Method) -> - gleam@result:then( - parse_headers(Rest, Socket, Transport, gleam@map:new()), - fun(_use0) -> - {Headers, Rest@1} = _use0, - gleam@result:then( - begin - _pipe@6 = Path, - _pipe@7 = gleam@bit_string:to_string( - _pipe@6 - ), - gleam@result:replace_error( - _pipe@7, - invalid_path - ) - end, - fun(Path@1) -> - {Path@4, Query@1} = case gleam@string:split( - Path@1, - <<"?"/utf8>> - ) of - [Path@2] -> - {Path@2, []}; - - [Path@3, Query_string] -> - Query = begin - _pipe@8 = Query_string, - _pipe@9 = gleam@uri:parse_query( - _pipe@8 - ), - gleam@result:unwrap(_pipe@9, []) - end, - {Path@3, Query} - end, - Req = begin - _pipe@10 = gleam@http@request:new(), - _pipe@11 = gleam@http@request:set_scheme( - _pipe@10, - case Transport of - {ssl, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _} -> - https; - - {tcp, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _, - _} -> - http - end - ), - _pipe@12 = gleam@http@request:set_body( - _pipe@11, - {unread, Rest@1, Socket} - ), - _pipe@13 = gleam@http@request:set_method( - _pipe@12, - Method - ), - _pipe@14 = gleam@http@request:set_path( - _pipe@13, - Path@4 - ), - gleam@http@request:set_query( - _pipe@14, - Query@1 - ) - end, - {ok, - erlang:setelement( - 3, - Req, - gleam@map:to_list(Headers) - )} - end - ) - end - ) - end - ); - - _ -> - {error, discard_packet} - end. - --spec read_data( - glisten@socket:socket(), - glisten@socket@transport:transport(), - buffer(), - decode_error() -) -> {ok, bitstring()} | {error, decode_error()}. -read_data(Socket, Transport, Buffer, Error) -> - To_read = gleam@int:min(erlang:element(2, Buffer), 1000000), - Timeout = 15000, - gleam@result:then( - begin - _pipe = Socket, - _pipe@1 = (erlang:element(10, Transport))(_pipe, To_read, Timeout), - gleam@result:replace_error(_pipe@1, Error) - end, - fun(Data) -> - Next_buffer = {buffer, - erlang:element(2, Buffer) - To_read, - <<(erlang:element(3, Buffer))/bitstring, Data/bitstring>>}, - case erlang:element(2, Next_buffer) > 0 of - true -> - read_data(Socket, Transport, Next_buffer, Error); - - false -> - {ok, erlang:element(3, Next_buffer)} - end - end - ). - --spec read_chunk( - glisten@socket:socket(), - glisten@socket@transport:transport(), - buffer(), - gleam@bit_builder:bit_builder() -) -> {ok, gleam@bit_builder:bit_builder()} | {error, decode_error()}. -read_chunk(Socket, Transport, Buffer, Body) -> - case {erlang:element(3, Buffer), - mist_ffi:binary_match( - erlang:element(3, Buffer), - <<13/integer, 10/integer>> - )} of - {_, {ok, {Offset, _}}} -> - _assert_subject = erlang:element(3, Buffer), - <<Chunk:Offset/binary, _/integer, _/integer, Rest/binary>> = case _assert_subject of - <<_:Offset/binary, _/integer, _/integer, _/binary>> -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"read_chunk"/utf8>>, - line => 147}) - end, - gleam@result:then( - begin - _pipe = Chunk, - _pipe@1 = gleam@bit_string:to_string(_pipe), - _pipe@2 = gleam@result:map( - _pipe@1, - fun gleam@erlang@charlist:from_string/1 - ), - gleam@result:replace_error(_pipe@2, invalid_body) - end, - fun(Chunk_size) -> - gleam@result:then( - begin - _pipe@3 = mist_ffi:string_to_int(Chunk_size, 16), - gleam@result:replace_error(_pipe@3, invalid_body) - end, - fun(Size) -> case Size of - 0 -> - {ok, Body}; - - Size@1 -> - case Rest of - <<Next_chunk:Size@1/binary, - 13/integer, - 10/integer, - Rest@1/binary>> -> - read_chunk( - Socket, - Transport, - {buffer, 0, Rest@1}, - gleam@bit_builder:append( - Body, - Next_chunk - ) - ); - - _ -> - gleam@result:then( - read_data( - Socket, - Transport, - {buffer, - 0, - erlang:element( - 3, - Buffer - )}, - invalid_body - ), - fun(Next) -> - read_chunk( - Socket, - Transport, - {buffer, 0, Next}, - Body - ) - end - ) - end - end end - ) - end - ); - - {<<>>, _} -> - gleam@result:then( - read_data( - Socket, - Transport, - {buffer, 0, erlang:element(3, Buffer)}, - invalid_body - ), - fun(Next@1) -> - read_chunk(Socket, Transport, {buffer, 0, Next@1}, Body) - end - ); - - {_, {error, nil}} -> - {error, invalid_body} - end. - --spec read_body(gleam@http@request:request(body())) -> {ok, - gleam@http@request:request(bitstring())} | - {error, decode_error()}. -read_body(Req) -> - Transport = case erlang:element(5, Req) of - https -> - glisten@socket@transport:ssl(); - - http -> - glisten@socket@transport:tcp() - end, - case {gleam@http@request:get_header(Req, <<"transfer-encoding"/utf8>>), - erlang:element(4, Req)} of - {{ok, <<"chunked"/utf8>>}, {unread, Rest, Socket}} -> - gleam@result:then( - read_chunk( - Socket, - Transport, - {buffer, 0, Rest}, - gleam@bit_builder:new() - ), - fun(Chunk) -> - {ok, - gleam@http@request:set_body( - Req, - gleam@bit_builder:to_bit_string(Chunk) - )} - end - ); - - {_, {unread, Rest@1, Socket@1}} -> - _ = case is_continue(Req) of - true -> - _assert_subject = begin - _pipe = gleam@http@response:new(100), - _pipe@1 = gleam@http@response:set_body( - _pipe, - gleam@bit_builder:new() - ), - _pipe@2 = mist@internal@encoder:to_bit_builder(_pipe@1), - (erlang:element(11, Transport))(Socket@1, _pipe@2) - end, - {ok, nil} = case _assert_subject of - {ok, nil} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/http"/utf8>>, - function => <<"read_body"/utf8>>, - line => 276}) - end, - nil; - - false -> - nil - end, - Body_size = begin - _pipe@3 = erlang:element(3, Req), - _pipe@4 = gleam@list:find( - _pipe@3, - fun(Tup) -> - gleam@pair:first(Tup) =:= <<"content-length"/utf8>> - end - ), - _pipe@5 = gleam@result:map(_pipe@4, fun gleam@pair:second/1), - _pipe@6 = gleam@result:then(_pipe@5, fun gleam@int:parse/1), - gleam@result:unwrap(_pipe@6, 0) - end, - Remaining = Body_size - gleam@bit_string:byte_size(Rest@1), - _pipe@7 = case {Body_size, Remaining} of - {0, 0} -> - {ok, <<>>}; - - {0, _} -> - {ok, Rest@1}; - - {_, 0} -> - {ok, Rest@1}; - - {_, _} -> - read_data( - Socket@1, - Transport, - {buffer, Remaining, Rest@1}, - invalid_body - ) - end, - _pipe@8 = gleam@result:map( - _pipe@7, - fun(_capture) -> gleam@http@request:set_body(Req, _capture) end - ), - gleam@result:replace_error(_pipe@8, invalid_body); - - {_, {read, _}} -> - {error, invalid_body} - end. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl deleted file mode 100644 index 214e0870e63..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@logger.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(mist@internal@logger). --compile([no_auto_import, nowarn_unused_vars]). - --export([error/1]). - --spec error(any()) -> nil. -error(Data) -> - logger:error(unicode:characters_to_list(<<"~tp"/utf8>>), [Data]). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl b/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl deleted file mode 100644 index c361892ff13..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@internal@websocket.erl +++ /dev/null @@ -1,359 +0,0 @@ --module(mist@internal@websocket). --compile([no_auto_import, nowarn_unused_vars]). - --export([frame_to_bit_builder/1, to_text_frame/1, to_binary_frame/1, crypto_hash/2, base64_encode/1, parse_key/1, frame_from_message/3]). --export_type([message/0, frame/0, sha_hash/0, websocket_handler/0]). - --type message() :: {binary_message, bitstring()} | {text_message, binary()}. - --type frame() :: {close_frame, integer(), bitstring()} | - {text_frame, integer(), bitstring()} | - {binary_frame, integer(), bitstring()} | - {ping_frame, integer(), bitstring()} | - {pong_frame, integer(), bitstring()}. - --type sha_hash() :: sha. - --type websocket_handler() :: {websocket_handler, - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), - fun((message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, - nil} | - {error, nil})}. - --spec make_frame(integer(), integer(), bitstring()) -> gleam@bit_builder:bit_builder(). -make_frame(Opcode, Length, Payload) -> - Length_section = case Length of - Length@1 when Length@1 > 65535 -> - <<127:7, Length@1:64/integer>>; - - Length@2 when Length@2 >= 126 -> - <<126:7, Length@2:16/integer>>; - - _ -> - <<Length:7>> - end, - _pipe = <<1:1, - 0:3, - Opcode:4, - 0:1, - Length_section/bitstring, - Payload/bitstring>>, - gleam@bit_builder:from_bit_string(_pipe). - --spec frame_to_bit_builder(frame()) -> gleam@bit_builder:bit_builder(). -frame_to_bit_builder(Frame) -> - case Frame of - {text_frame, Payload_length, Payload} -> - make_frame(1, Payload_length, Payload); - - {close_frame, Payload_length@1, Payload@1} -> - make_frame(8, Payload_length@1, Payload@1); - - {binary_frame, Payload_length@2, Payload@2} -> - make_frame(2, Payload_length@2, Payload@2); - - {pong_frame, Payload_length@3, Payload@3} -> - make_frame(10, Payload_length@3, Payload@3); - - {ping_frame, _, _} -> - gleam@bit_builder:from_bit_string(<<>>) - end. - --spec to_text_frame(bitstring()) -> gleam@bit_builder:bit_builder(). -to_text_frame(Data) -> - Size = gleam@bit_string:byte_size(Data), - frame_to_bit_builder({text_frame, Size, Data}). - --spec to_binary_frame(bitstring()) -> gleam@bit_builder:bit_builder(). -to_binary_frame(Data) -> - Size = gleam@bit_string:byte_size(Data), - frame_to_bit_builder({binary_frame, Size, Data}). - --spec crypto_hash(sha_hash(), binary()) -> binary(). -crypto_hash(Field@0, Field@1) -> - crypto:hash(Field@0, Field@1). - --spec base64_encode(binary()) -> binary(). -base64_encode(Field@0) -> - base64:encode(Field@0). - --spec parse_key(binary()) -> binary(). -parse_key(Key) -> - _pipe = Key, - _pipe@1 = gleam@string:append( - _pipe, - <<"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"/utf8>> - ), - _pipe@2 = crypto:hash(sha, _pipe@1), - base64:encode(_pipe@2). - --spec unmask_data(bitstring(), list(bitstring()), integer(), bitstring()) -> bitstring(). -unmask_data(Data, Masks, Index, Resp) -> - case Data of - <<>> -> - Resp; - - <<Masked:8/bitstring, Rest/bitstring>> -> - _assert_subject = gleam@list:at(Masks, Index rem 4), - {ok, Mask_value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"unmask_data"/utf8>>, - line => 43}) - end, - Unmasked = crypto:exor(Mask_value, Masked), - unmask_data( - Rest, - Masks, - Index + 1, - <<Resp/bitstring, Unmasked/bitstring>> - ) - end. - --spec frame_from_message( - glisten@socket:socket(), - glisten@socket@transport:transport(), - bitstring() -) -> {ok, frame()} | {error, nil}. -frame_from_message(Socket, Transport, Message) -> - <<_:1, Rest/bitstring>> = case Message of - <<_:1, _/bitstring>> -> Message; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 60}) - end, - <<_:3, Rest@1/bitstring>> = case Rest of - <<_:3, _/bitstring>> -> Rest; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 61}) - end, - <<Opcode:4/integer, Rest@2/bitstring>> = case Rest@1 of - <<_:4/integer, _/bitstring>> -> Rest@1; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 62}) - end, - case Opcode of - 1 -> - <<1:1, Rest@3/bitstring>> = case Rest@2 of - <<1:1, _/bitstring>> -> Rest@2; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 66}) - end, - <<Payload_length:7/integer, Rest@4/bitstring>> = case Rest@3 of - <<_:7/integer, _/bitstring>> -> Rest@3; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 67}) - end, - {Payload_length@1, Rest@7} = case Payload_length of - 126 -> - <<Length:16/integer, Rest@5/bitstring>> = case Rest@4 of - <<_:16/integer, _/bitstring>> -> Rest@4; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 70}) - end, - {Length, Rest@5}; - - 127 -> - <<Length@1:64/integer, Rest@6/bitstring>> = case Rest@4 of - <<_:64/integer, _/bitstring>> -> Rest@4; - _assert_fail@6 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@6, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 74}) - end, - {Length@1, Rest@6}; - - _ -> - {Payload_length, Rest@4} - end, - <<Mask1:8/bitstring, - Mask2:8/bitstring, - Mask3:8/bitstring, - Mask4:8/bitstring, - Rest@8/bitstring>> = case Rest@7 of - <<_:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _/bitstring>> -> Rest@7; - _assert_fail@7 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@7, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 79}) - end, - Data = case Payload_length@1 - gleam@bit_string:byte_size(Rest@8) of - 0 -> - unmask_data(Rest@8, [Mask1, Mask2, Mask3, Mask4], 0, <<>>); - - Need -> - _assert_subject = (erlang:element(9, Transport))( - Socket, - Need - ), - {ok, Needed} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail@8 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@8, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 89}) - end, - _pipe = Rest@8, - _pipe@1 = gleam@bit_string:append(_pipe, Needed), - unmask_data(_pipe@1, [Mask1, Mask2, Mask3, Mask4], 0, <<>>) - end, - _pipe@2 = case Opcode of - 1 -> - {text_frame, Payload_length@1, Data}; - - 2 -> - {binary_frame, Payload_length@1, Data} - end, - {ok, _pipe@2}; - - 2 -> - <<1:1, Rest@3/bitstring>> = case Rest@2 of - <<1:1, _/bitstring>> -> Rest@2; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 66}) - end, - <<Payload_length:7/integer, Rest@4/bitstring>> = case Rest@3 of - <<_:7/integer, _/bitstring>> -> Rest@3; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 67}) - end, - {Payload_length@1, Rest@7} = case Payload_length of - 126 -> - <<Length:16/integer, Rest@5/bitstring>> = case Rest@4 of - <<_:16/integer, _/bitstring>> -> Rest@4; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 70}) - end, - {Length, Rest@5}; - - 127 -> - <<Length@1:64/integer, Rest@6/bitstring>> = case Rest@4 of - <<_:64/integer, _/bitstring>> -> Rest@4; - _assert_fail@6 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@6, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 74}) - end, - {Length@1, Rest@6}; - - _ -> - {Payload_length, Rest@4} - end, - <<Mask1:8/bitstring, - Mask2:8/bitstring, - Mask3:8/bitstring, - Mask4:8/bitstring, - Rest@8/bitstring>> = case Rest@7 of - <<_:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _:8/bitstring, - _/bitstring>> -> Rest@7; - _assert_fail@7 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@7, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 79}) - end, - Data = case Payload_length@1 - gleam@bit_string:byte_size(Rest@8) of - 0 -> - unmask_data(Rest@8, [Mask1, Mask2, Mask3, Mask4], 0, <<>>); - - Need -> - _assert_subject = (erlang:element(9, Transport))( - Socket, - Need - ), - {ok, Needed} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail@8 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@8, - module => <<"mist/internal/websocket"/utf8>>, - function => <<"frame_from_message"/utf8>>, - line => 89}) - end, - _pipe = Rest@8, - _pipe@1 = gleam@bit_string:append(_pipe, Needed), - unmask_data(_pipe@1, [Mask1, Mask2, Mask3, Mask4], 0, <<>>) - end, - _pipe@2 = case Opcode of - 1 -> - {text_frame, Payload_length@1, Data}; - - 2 -> - {binary_frame, Payload_length@1, Data} - end, - {ok, _pipe@2}; - - 8 -> - {ok, {close_frame, 0, <<>>}} - end. diff --git a/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl b/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl deleted file mode 100644 index 8e5110f7274..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist@websocket.erl +++ /dev/null @@ -1,52 +0,0 @@ --module(mist@websocket). --compile([no_auto_import, nowarn_unused_vars]). - --export([send/2, echo_handler/2, with_handler/1, on_init/2, on_close/2]). - --spec send( - gleam@erlang@process:subject(glisten@handler:handler_message()), - mist@internal@websocket:message() -) -> nil. -send(Sender, Message) -> - _pipe@2 = case Message of - {text_message, Data} -> - _pipe = Data, - _pipe@1 = gleam@bit_string:from_string(_pipe), - mist@internal@websocket:to_text_frame(_pipe@1); - - {binary_message, Data@1} -> - mist@internal@websocket:to_binary_frame(Data@1) - end, - _pipe@3 = {send_message, _pipe@2}, - gleam@erlang@process:send(Sender, _pipe@3), - nil. - --spec echo_handler( - mist@internal@websocket:message(), - gleam@erlang@process:subject(glisten@handler:handler_message()) -) -> {ok, nil} | {error, nil}. -echo_handler(Message, Sender) -> - _ = send(Sender, Message), - {ok, nil}. - --spec with_handler( - fun((mist@internal@websocket:message(), gleam@erlang@process:subject(glisten@handler:handler_message())) -> {ok, - nil} | - {error, nil}) -) -> mist@internal@websocket:websocket_handler(). -with_handler(Func) -> - {websocket_handler, none, none, Func}. - --spec on_init( - mist@internal@websocket:websocket_handler(), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> mist@internal@websocket:websocket_handler(). -on_init(Handler, Func) -> - erlang:setelement(3, Handler, {some, Func}). - --spec on_close( - mist@internal@websocket:websocket_handler(), - fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) -) -> mist@internal@websocket:websocket_handler(). -on_close(Handler, Func) -> - erlang:setelement(2, Handler, {some, Func}). diff --git a/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl b/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl deleted file mode 100644 index f83e08f5c27..00000000000 --- a/test-community-packages-javascript/build/packages/mist/src/mist_ffi.erl +++ /dev/null @@ -1,47 +0,0 @@ --module(mist_ffi). - --export([binary_match/2, decode_packet/3, file_open/1, string_to_int/2]). - -decode_packet(Type, Packet, Opts) -> - case erlang:decode_packet(Type, Packet, Opts) of - {ok, http_eoh, Rest} -> - {ok, {end_of_headers, Rest}}; - {ok, Binary, Rest} -> - {ok, {binary_data, Binary, Rest}}; - {more, Length} when Length =:= undefined -> - {ok, {more_data, none}}; - {more, Length} -> - {ok, {more_data, {some, Length}}}; - {error, Reason} -> - {error, Reason} - end. - -binary_match(Source, Pattern) -> - case binary:match(Source, Pattern) of - {Before, After} -> - {ok, {Before, After}}; - nomatch -> - {error, nil} - end. - -string_to_int(String, Base) -> - try - {ok, erlang:list_to_integer(String, Base)} - catch - badarg -> - {error, nil} - end. - -file_open(Path) -> - case file:open(Path, [raw]) of - {ok, fd} -> - {ok, fd}; - {error, enoent} -> - {error, no_entry}; - {error, eacces} -> - {error, no_access}; - {error, eisdir} -> - {error, is_dir}; - _ -> - {error, unknown_file_error} - end. diff --git a/test-community-packages-javascript/build/packages/nakai/LICENSE b/test-community-packages-javascript/build/packages/nakai/LICENSE deleted file mode 100644 index 2f3b8c6484c..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2022 McKayla Washburn -Copyright (c) 2022 Nakai Contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/nakai/README.md b/test-community-packages-javascript/build/packages/nakai/README.md deleted file mode 100644 index 49bcf2f50cb..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/README.md +++ /dev/null @@ -1,46 +0,0 @@ -![Nakai](https://cdn.mckayla.cloud/-/2d8051c1ce2f4fbd91eaf07df5661e25/Nakai-Banner.svg) - -[![Documentation](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/nakai/) - -## Getting started - -```sh -gleam add nakai -``` - -```gleam -import nakai -import nakai/html.{Node} -import nakai/html/attrs.{Attr} - -const header_style = " - color: #331f26; - font-family: 'Neuton', serif; - font-size: 128px; - font-weight: 400; -" - -pub fn header(attrs: List(Attr(a)), text: String) -> Node(a) { - let attrs = [attrs.style(header_style), ..attrs] - html.h1_text(attrs, text) -} - -pub fn app() -> String { - html.div( - [], - [ - html.Head([html.title("Hello!")]), - header([], "Hello, from Nakai!") - ], - ) - |> nakai.to_string() -} -``` - -## Development - -While Nakai itself is pure Gleam, the benchmarks require having [Elixir] installed, -and some of its dependencies require [Rebar3] to compile. - -[elixir]: https://elixir-lang.org/ -[rebar3]: https://rebar3.org/ diff --git a/test-community-packages-javascript/build/packages/nakai/gleam.toml b/test-community-packages-javascript/build/packages/nakai/gleam.toml deleted file mode 100644 index 6a59fb50e38..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/gleam.toml +++ /dev/null @@ -1,20 +0,0 @@ -name = "nakai" -version = "0.8.0" -licences = ["MIT"] -description = "HTML generation for Gleam, on the server or anywhere else" -repository = { type = "github", user = "nakaixo", repo = "nakai" } -links = [ - { title = "Website", href = "https://nakaixo.github.io" }, - { title = "Sponsor", href = "https://github.com/sponsors/aslilac" }, -] - -internal_modules = ["nakai/internal/*", "nakai/experimental/*"] - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleam_erlang = "~> 0.19" -gleam_json = "~> 0.5" -gleeunit = "~> 0.10" -glychee = "~> 0.2" diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl deleted file mode 100644 index a1e6394f178..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Attr.hrl +++ /dev/null @@ -1 +0,0 @@ --record(attr, {name :: binary(), value :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl deleted file mode 100644 index ff64a0a76cc..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html@attrs_Event.hrl +++ /dev/null @@ -1 +0,0 @@ --record(event, {name :: binary(), action :: any()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl deleted file mode 100644 index 1536616600a..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Body.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(body, { - attrs :: list(nakai@html@attrs:attr(any())), - children :: list(nakai@html:node_(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl deleted file mode 100644 index 7ca4cf0259f..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Comment.hrl +++ /dev/null @@ -1 +0,0 @@ --record(comment, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl deleted file mode 100644 index d1e743c6e74..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Doctype.hrl +++ /dev/null @@ -1 +0,0 @@ --record(doctype, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl deleted file mode 100644 index 498ade5cb56..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Element.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(element, { - tag :: binary(), - attrs :: list(nakai@html@attrs:attr(any())), - children :: list(nakai@html:node_(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl deleted file mode 100644 index 1753ea5e619..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Fragment.hrl +++ /dev/null @@ -1 +0,0 @@ --record(fragment, {children :: list(nakai@html:node_(any()))}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl deleted file mode 100644 index db9f893f8ce..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Head.hrl +++ /dev/null @@ -1 +0,0 @@ --record(head, {children :: list(nakai@html:node_(any()))}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl deleted file mode 100644 index 474196a71bb..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Html.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(html, { - attrs :: list(nakai@html@attrs:attr(any())), - children :: list(nakai@html:node_(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl deleted file mode 100644 index bd76321701c..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_LeafElement.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(leaf_element, { - tag :: binary(), - attrs :: list(nakai@html@attrs:attr(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl deleted file mode 100644 index e95a602c375..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Script.hrl +++ /dev/null @@ -1 +0,0 @@ --record(script, {script :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl deleted file mode 100644 index 174e44494d9..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_Text.hrl +++ /dev/null @@ -1 +0,0 @@ --record(text, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl deleted file mode 100644 index 05a9922f2a5..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@html_UnsafeText.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unsafe_text, {content :: binary()}). diff --git a/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl b/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl deleted file mode 100644 index 67f0288ec89..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/include/nakai@internal@document_Document.hrl +++ /dev/null @@ -1,8 +0,0 @@ --record(document, { - doctype :: gleam@option:option(binary()), - html_attrs :: gleam@string_builder:string_builder(), - body_attrs :: gleam@string_builder:string_builder(), - head :: gleam@string_builder:string_builder(), - body :: gleam@string_builder:string_builder(), - scripts :: list(binary()) -}). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src b/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src deleted file mode 100644 index 3c3ace613f4..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai.app.src +++ /dev/null @@ -1,18 +0,0 @@ -{application, nakai, [ - {vsn, "0.8.0"}, - {applications, [gleam_erlang, - gleam_json, - gleam_stdlib, - gleeunit, - glychee]}, - {description, "HTML generation for Gleam, on the server or anywhere else"}, - {modules, [nakai, - nakai@experimental@head, - nakai@experimental@on, - nakai@experimental@web_components, - nakai@html, - nakai@html@attrs, - nakai@internal@document, - nakai@internal@render]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai.erl deleted file mode 100644 index ce38b1f6f17..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai.erl +++ /dev/null @@ -1,22 +0,0 @@ --module(nakai). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_string_builder/1, to_string/1, to_inline_string_builder/1, to_inline_string/1]). - --spec to_string_builder(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -to_string_builder(Tree) -> - nakai@internal@render:render_document(Tree). - --spec to_string(nakai@html:node_(any())) -> binary(). -to_string(Tree) -> - _pipe = nakai@internal@render:render_document(Tree), - gleam@string_builder:to_string(_pipe). - --spec to_inline_string_builder(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -to_inline_string_builder(Tree) -> - nakai@internal@render:render_inline(Tree). - --spec to_inline_string(nakai@html:node_(any())) -> binary(). -to_inline_string(Tree) -> - _pipe = nakai@internal@render:render_inline(Tree), - gleam@string_builder:to_string(_pipe). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam deleted file mode 100644 index 18c83efcade..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai.gleam +++ /dev/null @@ -1,60 +0,0 @@ -//// Nakai has several "builders" that can be used. -//// - A `document` builder (the recommend one) that renders a full HTML document, -//// does a little magic to dedepulicate `<head>` elements, and some other things -//// that generally fit the theme of "rendering a full, valid, HTML document" -//// - An `inline` builder that should mostly be used for snippets, and partial bits of -//// HTML that will be inlined into a full document; hence the name. It renders things -//// much more literally. If you tell it to give you a `<head>` element inside a -//// `<p>`, it will, as an example. -//// - A future experimental DOM renderer (meant for use in the browser) that isn't -//// actually done yet. - -import gleam/string_builder.{StringBuilder} -import nakai/html.{Node} -import nakai/internal/render - -/// Renders a full HTML document from the given tree, into a `StringBuilder`. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_string_builder() -/// ``` -pub fn to_string_builder(tree: Node(a)) -> StringBuilder { - render.render_document(tree) -} - -/// Renders a full HTML document from the given tree, into a `String`. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_string() -/// ``` -pub fn to_string(tree: Node(a)) -> String { - render.render_document(tree) - |> string_builder.to_string() -} - -/// Renders only the provided HTML, exactly as provided (disables `<head>` -/// deduplication, etc.), into a `StringBuilder`. Useful for generating snippets -/// instead of whole pages. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_inline_string_builder() -/// ``` -pub fn to_inline_string_builder(tree: Node(a)) -> StringBuilder { - render.render_inline(tree) -} - -/// Renders only the provided HTML, exactly as provided (disables `<head>` -/// deduplication, etc.), into a `String`. Useful for generating snippets instead -/// of whole pages. -/// ## Examples -/// ```gleam -/// html.div_text([], "hello, lucy!") -/// |> nakai.to_inline_string() -/// ``` -pub fn to_inline_string(tree: Node(a)) -> String { - render.render_inline(tree) - |> string_builder.to_string() -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam deleted file mode 100644 index 466c0c259aa..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/head.gleam +++ /dev/null @@ -1,22 +0,0 @@ -import nakai/html -import nakai/html/attrs - -pub fn title(title: String) { - html.Head([html.title(title)]) -} - -pub fn link(rel rel: String, href href: String) { - html.Head([html.link([attrs.rel(rel), attrs.href(href)])]) -} - -pub fn meta(name name: String, content content: String) { - html.Head([html.meta([attrs.name(name), attrs.content(content)])]) -} - -pub fn http_equiv(header: String, content content: String) { - html.Head([html.meta([attrs.http_equiv(header), attrs.content(content)])]) -} - -pub fn charset(charset: String) { - html.Head([html.meta([attrs.charset(charset)])]) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam deleted file mode 100644 index 07f43f0a398..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/on.gleam +++ /dev/null @@ -1,5 +0,0 @@ -import nakai/html/attrs.{Attr} - -pub fn click(script: String) -> Attr(a) { - Attr(name: "onclick", value: script) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam deleted file mode 100644 index 9041dd78bdc..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/experimental/web_components.gleam +++ /dev/null @@ -1,10 +0,0 @@ -import nakai/html.{Element, LeafElement, Node} -import nakai/html/attrs.{Attr} - -pub fn slot(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "slot", attrs: attrs) -} - -pub fn template(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "template", attrs: attrs, children: children) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam deleted file mode 100644 index d1b07418fe7..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/html.gleam +++ /dev/null @@ -1,1164 +0,0 @@ - - - - - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// * THIS FILE IS GENERATED. DO NOT EDIT IT. * -// * You're probably looking for ./codegen/html_prelude.gleam, or ./codegen/html.json. * -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - - - - -import nakai/html/attrs.{Attr} - -pub type Node(a) { - /// Can be used anywhere in the document, and will set the doctype of the document - /// being rendered. Usually not necessary, as documents have a default of `<!DOCTYPE html>`. - /// ## Example - /// ```gleam - /// html.Doctype("html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"") - /// ``` - Doctype(content: String) - /// Used for setting attributes on the root `<html>` element of the document. Children - /// will be rendered in-place, equivalent to using `html.Fragment(children)`. - /// ## Example - /// ```gleam - /// html.Html([attrs.lang("en-US")], [ - /// ... - /// ]) - /// ``` - Html(attrs: List(Attr(a)), children: List(Node(a))) - /// Used for placing content in the `<head>` of the document. Useful for elements like - /// `<meta>`, `<title>`, `<link>`, etc. - /// ## Example - /// ```gleam - /// html.Fragment([ - /// html.Head([ - /// html.title("List of puppies") - /// ]), - /// html.div([], [ - /// ... - /// ]) - /// ]) - /// ``` - Head(children: List(Node(a))) - /// Used for setting attributes on the `<body>` element of the document. Children - /// will be rendered in-place, equivalent to using `html.Fragment(children)`. - /// ## Example - /// ```gleam - /// html.Body([attrs.class("dark-mode")], [ - /// ... - /// ]) - /// ``` - Body(attrs: List(Attr(a)), children: List(Node(a))) - /// An "transparent" container that will render it's children, but does not add anything - /// itself to the document. If you've ever used `React.Fragment` or `<>` and `</>` in - /// JSX/React, this is that. - /// ## Example - /// ```gleam - /// html.ul([], [ - /// // some puppies are hard-coded - /// html.li_text([], "August"), - /// // some are loaded from a server - /// html.Fragment(puppies_fetched_from_api |> list.map(html.li_text([], _))) - /// ]) - /// // <ul> - /// // <li>August</li> - /// // <li>Dot</li> - /// // <li>Mody</li> - /// // <li>Spot</li> - /// // <li>Toby</li> - /// // </ul> - /// ``` - Fragment(children: List(Node(a))) - /// An HTML element. You shouldn't need to reach for this very often, but it can be a - /// handy escape hatch if there isn't a shorthand function for the element type you need. - /// ## Example - /// ```gleam - /// // bad example, pls use `html.div` - /// html.Element("div", [], [html.Text("hello, lucy!")]) - /// ``` - Element(tag: String, attrs: List(Attr(a)), children: List(Node(a))) - /// An HTML element, but that does not have any children, and should be self closing. - /// Similarly to `Element`, you shouldn't really need this, except as an escape hatch - /// if there isn't a shorthand function for the element type you need. - /// ## Example - /// ```gleam - /// // bad example, pls use `html.link` - /// html.LeafElement("link", [attrs.rel("stylesheet"), attrs.href(...)]) - /// ``` - LeafElement(tag: String, attrs: List(Attr(a))) - /// An HTML comment, which will be included in the document. - /// ## Example - /// ```gleam - /// html.Comment("You've uncovered my secrets!") - /// // <!-- You've uncovered my secrets! --> - /// ``` - Comment(content: String) - /// Some plain text to include in the document. The provided text will be escaped, to - /// make it safe to include in the document. - /// ## Example - /// ```gleam - /// html.Text("hello, lucy!") - /// // hello, lucy! - /// ``` - /// ```gleam - /// // Time to trust some unvalidated user input! :^) - /// html.div_text([], "<script>alert('pwned');</script>") - /// // <div><script>alert('pwned');</script></div> - /// ``` - Text(content: String) - /// The dangerous cousin of `Text`. This will render the provided text as-is, without - /// any santization. Good for things like including some HTML you just generated from - /// a Markdown file. Bad for things like `$_GET['search']`. - /// ## Example - /// ```gleam - /// html.Text("hello, lucy!") - /// // hello, lucy! - /// ``` - /// ```gleam - /// // Time to trust some unvalidated user input! :^) - /// html.div([], [html.UnsafeText("<script>alert('pwned');</script>")]) - /// // <div><script>alert('pwned');</script></div> - /// // Oh no, we just got got! D: - /// ``` - UnsafeText(content: String) - /// Add some JavaScript to your page! Scripts will always be inserted at the end of the - /// page, regardless of where in the document the `Script` node is, so that your content - /// loads first. - /// ## Example - /// ```gleam - /// html.Script("alert('hello, lucy!')") - /// ``` - Script(script: String) - /// Renders absolutely nothing. For when you may or may not have something to render, - /// and need a way to say "I've got nothing." - /// ## Example - /// ```gleam - /// html.div([], [ - /// case my_cool_feature { - /// Enabled -> super_cool_stuff() - /// Disabled -> html.Nothing - /// } - /// ]) - Nothing -} - -/// The HTML [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title) element -pub fn title(text: String) -> Node(a) { - Element("title", [], [Text(text)]) -} - -/// The [HTML `<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) -pub fn a(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "a", attrs: attrs, children: children) -} - -/// Shorthand for `html.a(attrs, children: [html.Text(text)])` -pub fn a_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "a", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<abbr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr) -pub fn abbr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "abbr", attrs: attrs, children: children) -} - -/// Shorthand for `html.abbr(attrs, children: [html.Text(text)])` -pub fn abbr_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "abbr", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<address>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address) -pub fn address(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "address", attrs: attrs, children: children) -} - -/// Shorthand for `html.address(attrs, children: [html.Text(text)])` -pub fn address_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "address", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<area />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area) -pub fn area(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "area", attrs: attrs) -} - -/// The [HTML `<article>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article) -pub fn article(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "article", attrs: attrs, children: children) -} - -/// Shorthand for `html.article(attrs, children: [html.Text(text)])` -pub fn article_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "article", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<aside>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside) -pub fn aside(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "aside", attrs: attrs, children: children) -} - -/// Shorthand for `html.aside(attrs, children: [html.Text(text)])` -pub fn aside_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "aside", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<audio>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio) -pub fn audio(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "audio", attrs: attrs, children: children) -} - -/// Shorthand for `html.audio(attrs, children: [html.Text(text)])` -pub fn audio_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "audio", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<b>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b) -pub fn b(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "b", attrs: attrs, children: children) -} - -/// Shorthand for `html.b(attrs, children: [html.Text(text)])` -pub fn b_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "b", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<base />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base) -pub fn base(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "base", attrs: attrs) -} - -/// The [HTML `<bdi>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi) -pub fn bdi(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "bdi", attrs: attrs, children: children) -} - -/// Shorthand for `html.bdi(attrs, children: [html.Text(text)])` -pub fn bdi_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "bdi", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<bdo>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo) -pub fn bdo(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "bdo", attrs: attrs, children: children) -} - -/// Shorthand for `html.bdo(attrs, children: [html.Text(text)])` -pub fn bdo_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "bdo", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<blockquote>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote) -pub fn blockquote(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "blockquote", attrs: attrs, children: children) -} - -/// Shorthand for `html.blockquote(attrs, children: [html.Text(text)])` -pub fn blockquote_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "blockquote", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<br />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br) -pub fn br(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "br", attrs: attrs) -} - -/// The [HTML `<button>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) -pub fn button(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "button", attrs: attrs, children: children) -} - -/// Shorthand for `html.button(attrs, children: [html.Text(text)])` -pub fn button_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "button", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<canvas>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) -pub fn canvas(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "canvas", attrs: attrs, children: children) -} - -/// Shorthand for `html.canvas(attrs, children: [html.Text(text)])` -pub fn canvas_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "canvas", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<caption>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption) -pub fn caption(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "caption", attrs: attrs, children: children) -} - -/// Shorthand for `html.caption(attrs, children: [html.Text(text)])` -pub fn caption_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "caption", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<cite>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite) -pub fn cite(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "cite", attrs: attrs, children: children) -} - -/// Shorthand for `html.cite(attrs, children: [html.Text(text)])` -pub fn cite_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "cite", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<code>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code) -pub fn code(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "code", attrs: attrs, children: children) -} - -/// Shorthand for `html.code(attrs, children: [html.Text(text)])` -pub fn code_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "code", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<col>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col) -pub fn col(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "col", attrs: attrs, children: children) -} - -/// Shorthand for `html.col(attrs, children: [html.Text(text)])` -pub fn col_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "col", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<colgroup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup) -pub fn colgroup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "colgroup", attrs: attrs, children: children) -} - -/// Shorthand for `html.colgroup(attrs, children: [html.Text(text)])` -pub fn colgroup_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "colgroup", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<data>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data) -pub fn data(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "data", attrs: attrs, children: children) -} - -/// Shorthand for `html.data(attrs, children: [html.Text(text)])` -pub fn data_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "data", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<datalist>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) -pub fn datalist(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "datalist", attrs: attrs, children: children) -} - -/// Shorthand for `html.datalist(attrs, children: [html.Text(text)])` -pub fn datalist_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "datalist", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dd>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd) -pub fn dd(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dd", attrs: attrs, children: children) -} - -/// Shorthand for `html.dd(attrs, children: [html.Text(text)])` -pub fn dd_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dd", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<del>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del) -pub fn del(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "del", attrs: attrs, children: children) -} - -/// Shorthand for `html.del(attrs, children: [html.Text(text)])` -pub fn del_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "del", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<details>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details) -pub fn details(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "details", attrs: attrs, children: children) -} - -/// Shorthand for `html.details(attrs, children: [html.Text(text)])` -pub fn details_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "details", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dfn>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dfn) -pub fn dfn(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dfn", attrs: attrs, children: children) -} - -/// Shorthand for `html.dfn(attrs, children: [html.Text(text)])` -pub fn dfn_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dfn", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dialog>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) -pub fn dialog(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dialog", attrs: attrs, children: children) -} - -/// Shorthand for `html.dialog(attrs, children: [html.Text(text)])` -pub fn dialog_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dialog", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<div>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div) -pub fn div(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "div", attrs: attrs, children: children) -} - -/// Shorthand for `html.div(attrs, children: [html.Text(text)])` -pub fn div_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "div", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dl>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl) -pub fn dl(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dl", attrs: attrs, children: children) -} - -/// Shorthand for `html.dl(attrs, children: [html.Text(text)])` -pub fn dl_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dl", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<dt>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt) -pub fn dt(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "dt", attrs: attrs, children: children) -} - -/// Shorthand for `html.dt(attrs, children: [html.Text(text)])` -pub fn dt_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "dt", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<em>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em) -pub fn em(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "em", attrs: attrs, children: children) -} - -/// Shorthand for `html.em(attrs, children: [html.Text(text)])` -pub fn em_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "em", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<embed>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed) -pub fn embed(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "embed", attrs: attrs, children: children) -} - -/// Shorthand for `html.embed(attrs, children: [html.Text(text)])` -pub fn embed_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "embed", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<fieldset>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset) -pub fn fieldset(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "fieldset", attrs: attrs, children: children) -} - -/// Shorthand for `html.fieldset(attrs, children: [html.Text(text)])` -pub fn fieldset_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "fieldset", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<figcaption>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption) -pub fn figcaption(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "figcaption", attrs: attrs, children: children) -} - -/// Shorthand for `html.figcaption(attrs, children: [html.Text(text)])` -pub fn figcaption_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "figcaption", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<figure>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure) -pub fn figure(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "figure", attrs: attrs, children: children) -} - -/// Shorthand for `html.figure(attrs, children: [html.Text(text)])` -pub fn figure_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "figure", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<footer>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer) -pub fn footer(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "footer", attrs: attrs, children: children) -} - -/// Shorthand for `html.footer(attrs, children: [html.Text(text)])` -pub fn footer_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "footer", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<form>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) -pub fn form(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "form", attrs: attrs, children: children) -} - -/// Shorthand for `html.form(attrs, children: [html.Text(text)])` -pub fn form_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "form", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h1>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1) -pub fn h1(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h1", attrs: attrs, children: children) -} - -/// Shorthand for `html.h1(attrs, children: [html.Text(text)])` -pub fn h1_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h1", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h2>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2) -pub fn h2(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h2", attrs: attrs, children: children) -} - -/// Shorthand for `html.h2(attrs, children: [html.Text(text)])` -pub fn h2_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h2", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h3>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3) -pub fn h3(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h3", attrs: attrs, children: children) -} - -/// Shorthand for `html.h3(attrs, children: [html.Text(text)])` -pub fn h3_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h3", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h4>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4) -pub fn h4(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h4", attrs: attrs, children: children) -} - -/// Shorthand for `html.h4(attrs, children: [html.Text(text)])` -pub fn h4_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h4", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h5>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5) -pub fn h5(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h5", attrs: attrs, children: children) -} - -/// Shorthand for `html.h5(attrs, children: [html.Text(text)])` -pub fn h5_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h5", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<h6>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6) -pub fn h6(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "h6", attrs: attrs, children: children) -} - -/// Shorthand for `html.h6(attrs, children: [html.Text(text)])` -pub fn h6_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "h6", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<header>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header) -pub fn header(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "header", attrs: attrs, children: children) -} - -/// Shorthand for `html.header(attrs, children: [html.Text(text)])` -pub fn header_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "header", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<hr />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr) -pub fn hr(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "hr", attrs: attrs) -} - -/// The [HTML `<i>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i) -pub fn i(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "i", attrs: attrs, children: children) -} - -/// Shorthand for `html.i(attrs, children: [html.Text(text)])` -pub fn i_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "i", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<iframe>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) -pub fn iframe(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "iframe", attrs: attrs, children: children) -} - -/// Shorthand for `html.iframe(attrs, children: [html.Text(text)])` -pub fn iframe_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "iframe", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<img />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img) -pub fn img(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "img", attrs: attrs) -} - -/// The [HTML `<input />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) -pub fn input(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "input", attrs: attrs) -} - -/// The [HTML `<ins>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins) -pub fn ins(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ins", attrs: attrs, children: children) -} - -/// Shorthand for `html.ins(attrs, children: [html.Text(text)])` -pub fn ins_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ins", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<kbd>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd) -pub fn kbd(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "kbd", attrs: attrs, children: children) -} - -/// Shorthand for `html.kbd(attrs, children: [html.Text(text)])` -pub fn kbd_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "kbd", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<label>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) -pub fn label(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "label", attrs: attrs, children: children) -} - -/// Shorthand for `html.label(attrs, children: [html.Text(text)])` -pub fn label_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "label", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<legend>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend) -pub fn legend(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "legend", attrs: attrs, children: children) -} - -/// Shorthand for `html.legend(attrs, children: [html.Text(text)])` -pub fn legend_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "legend", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<li>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li) -pub fn li(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "li", attrs: attrs, children: children) -} - -/// Shorthand for `html.li(attrs, children: [html.Text(text)])` -pub fn li_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "li", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<link />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link) -pub fn link(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "link", attrs: attrs) -} - -/// The [HTML `<main>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main) -pub fn main(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "main", attrs: attrs, children: children) -} - -/// Shorthand for `html.main(attrs, children: [html.Text(text)])` -pub fn main_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "main", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<map>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map) -pub fn map(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "map", attrs: attrs, children: children) -} - -/// Shorthand for `html.map(attrs, children: [html.Text(text)])` -pub fn map_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "map", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<mark>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark) -pub fn mark(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "mark", attrs: attrs, children: children) -} - -/// Shorthand for `html.mark(attrs, children: [html.Text(text)])` -pub fn mark_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "mark", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<math>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/math) -pub fn math(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "math", attrs: attrs, children: children) -} - -/// Shorthand for `html.math(attrs, children: [html.Text(text)])` -pub fn math_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "math", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<menu>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu) -pub fn menu(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "menu", attrs: attrs, children: children) -} - -/// Shorthand for `html.menu(attrs, children: [html.Text(text)])` -pub fn menu_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "menu", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<menuitem>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menuitem) -pub fn menuitem(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "menuitem", attrs: attrs, children: children) -} - -/// Shorthand for `html.menuitem(attrs, children: [html.Text(text)])` -pub fn menuitem_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "menuitem", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<meta />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) -pub fn meta(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "meta", attrs: attrs) -} - -/// The [HTML `<meter>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter) -pub fn meter(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "meter", attrs: attrs, children: children) -} - -/// Shorthand for `html.meter(attrs, children: [html.Text(text)])` -pub fn meter_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "meter", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<nav>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav) -pub fn nav(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "nav", attrs: attrs, children: children) -} - -/// Shorthand for `html.nav(attrs, children: [html.Text(text)])` -pub fn nav_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "nav", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<noscript>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript) -pub fn noscript(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "noscript", attrs: attrs, children: children) -} - -/// Shorthand for `html.noscript(attrs, children: [html.Text(text)])` -pub fn noscript_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "noscript", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<object>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object) -pub fn object(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "object", attrs: attrs, children: children) -} - -/// Shorthand for `html.object(attrs, children: [html.Text(text)])` -pub fn object_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "object", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<ol>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol) -pub fn ol(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ol", attrs: attrs, children: children) -} - -/// Shorthand for `html.ol(attrs, children: [html.Text(text)])` -pub fn ol_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ol", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<optgroup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup) -pub fn optgroup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "optgroup", attrs: attrs, children: children) -} - -/// Shorthand for `html.optgroup(attrs, children: [html.Text(text)])` -pub fn optgroup_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "optgroup", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<option>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option) -pub fn option(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "option", attrs: attrs, children: children) -} - -/// Shorthand for `html.option(attrs, children: [html.Text(text)])` -pub fn option_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "option", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<output>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output) -pub fn output(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "output", attrs: attrs, children: children) -} - -/// Shorthand for `html.output(attrs, children: [html.Text(text)])` -pub fn output_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "output", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<p>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p) -pub fn p(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "p", attrs: attrs, children: children) -} - -/// Shorthand for `html.p(attrs, children: [html.Text(text)])` -pub fn p_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "p", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<param>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param) -pub fn param(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "param", attrs: attrs, children: children) -} - -/// Shorthand for `html.param(attrs, children: [html.Text(text)])` -pub fn param_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "param", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<picture>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) -pub fn picture(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "picture", attrs: attrs, children: children) -} - -/// Shorthand for `html.picture(attrs, children: [html.Text(text)])` -pub fn picture_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "picture", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<pre>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre) -pub fn pre(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "pre", attrs: attrs, children: children) -} - -/// Shorthand for `html.pre(attrs, children: [html.Text(text)])` -pub fn pre_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "pre", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<progress>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress) -pub fn progress(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "progress", attrs: attrs, children: children) -} - -/// Shorthand for `html.progress(attrs, children: [html.Text(text)])` -pub fn progress_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "progress", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<q>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q) -pub fn q(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "q", attrs: attrs, children: children) -} - -/// Shorthand for `html.q(attrs, children: [html.Text(text)])` -pub fn q_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "q", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<rp>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp) -pub fn rp(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "rp", attrs: attrs, children: children) -} - -/// Shorthand for `html.rp(attrs, children: [html.Text(text)])` -pub fn rp_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "rp", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<rt>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rt) -pub fn rt(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "rt", attrs: attrs, children: children) -} - -/// Shorthand for `html.rt(attrs, children: [html.Text(text)])` -pub fn rt_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "rt", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<ruby>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby) -pub fn ruby(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ruby", attrs: attrs, children: children) -} - -/// Shorthand for `html.ruby(attrs, children: [html.Text(text)])` -pub fn ruby_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ruby", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<s>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s) -pub fn s(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "s", attrs: attrs, children: children) -} - -/// Shorthand for `html.s(attrs, children: [html.Text(text)])` -pub fn s_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "s", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<samp>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/samp) -pub fn samp(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "samp", attrs: attrs, children: children) -} - -/// Shorthand for `html.samp(attrs, children: [html.Text(text)])` -pub fn samp_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "samp", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<section>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section) -pub fn section(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "section", attrs: attrs, children: children) -} - -/// Shorthand for `html.section(attrs, children: [html.Text(text)])` -pub fn section_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "section", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<select>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) -pub fn select(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "select", attrs: attrs, children: children) -} - -/// Shorthand for `html.select(attrs, children: [html.Text(text)])` -pub fn select_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "select", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<small>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small) -pub fn small(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "small", attrs: attrs, children: children) -} - -/// Shorthand for `html.small(attrs, children: [html.Text(text)])` -pub fn small_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "small", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<source />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source) -pub fn source(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "source", attrs: attrs) -} - -/// The [HTML `<span>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span) -pub fn span(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "span", attrs: attrs, children: children) -} - -/// Shorthand for `html.span(attrs, children: [html.Text(text)])` -pub fn span_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "span", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<strong>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong) -pub fn strong(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "strong", attrs: attrs, children: children) -} - -/// Shorthand for `html.strong(attrs, children: [html.Text(text)])` -pub fn strong_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "strong", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<sub>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub) -pub fn sub(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "sub", attrs: attrs, children: children) -} - -/// Shorthand for `html.sub(attrs, children: [html.Text(text)])` -pub fn sub_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "sub", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<summary>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary) -pub fn summary(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "summary", attrs: attrs, children: children) -} - -/// Shorthand for `html.summary(attrs, children: [html.Text(text)])` -pub fn summary_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "summary", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<sup>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup) -pub fn sup(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "sup", attrs: attrs, children: children) -} - -/// Shorthand for `html.sup(attrs, children: [html.Text(text)])` -pub fn sup_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "sup", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<svg>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/svg) -pub fn svg(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "svg", attrs: attrs, children: children) -} - -/// Shorthand for `html.svg(attrs, children: [html.Text(text)])` -pub fn svg_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "svg", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<table>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table) -pub fn table(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "table", attrs: attrs, children: children) -} - -/// Shorthand for `html.table(attrs, children: [html.Text(text)])` -pub fn table_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "table", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<tbody>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody) -pub fn tbody(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "tbody", attrs: attrs, children: children) -} - -/// Shorthand for `html.tbody(attrs, children: [html.Text(text)])` -pub fn tbody_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "tbody", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<td>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) -pub fn td(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "td", attrs: attrs, children: children) -} - -/// Shorthand for `html.td(attrs, children: [html.Text(text)])` -pub fn td_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "td", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<textarea>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) -pub fn textarea(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "textarea", attrs: attrs, children: children) -} - -/// Shorthand for `html.textarea(attrs, children: [html.Text(text)])` -pub fn textarea_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "textarea", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<tfoot>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot) -pub fn tfoot(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "tfoot", attrs: attrs, children: children) -} - -/// Shorthand for `html.tfoot(attrs, children: [html.Text(text)])` -pub fn tfoot_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "tfoot", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<th>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th) -pub fn th(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "th", attrs: attrs, children: children) -} - -/// Shorthand for `html.th(attrs, children: [html.Text(text)])` -pub fn th_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "th", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<thead>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead) -pub fn thead(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "thead", attrs: attrs, children: children) -} - -/// Shorthand for `html.thead(attrs, children: [html.Text(text)])` -pub fn thead_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "thead", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<time>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time) -pub fn time(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "time", attrs: attrs, children: children) -} - -/// Shorthand for `html.time(attrs, children: [html.Text(text)])` -pub fn time_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "time", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<tr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr) -pub fn tr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "tr", attrs: attrs, children: children) -} - -/// Shorthand for `html.tr(attrs, children: [html.Text(text)])` -pub fn tr_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "tr", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<track />` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track) -pub fn track(attrs: List(Attr(a))) -> Node(a) { - LeafElement(tag: "track", attrs: attrs) -} - -/// The [HTML `<u>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u) -pub fn u(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "u", attrs: attrs, children: children) -} - -/// Shorthand for `html.u(attrs, children: [html.Text(text)])` -pub fn u_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "u", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<ul>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul) -pub fn ul(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "ul", attrs: attrs, children: children) -} - -/// Shorthand for `html.ul(attrs, children: [html.Text(text)])` -pub fn ul_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "ul", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<var>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var) -pub fn var(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "var", attrs: attrs, children: children) -} - -/// Shorthand for `html.var(attrs, children: [html.Text(text)])` -pub fn var_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "var", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<video>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) -pub fn video(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "video", attrs: attrs, children: children) -} - -/// Shorthand for `html.video(attrs, children: [html.Text(text)])` -pub fn video_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "video", attrs: attrs, children: [Text(text)]) -} - -/// The [HTML `<wbr>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr) -pub fn wbr(attrs: List(Attr(a)), children: List(Node(a))) -> Node(a) { - Element(tag: "wbr", attrs: attrs, children: children) -} - -/// Shorthand for `html.wbr(attrs, children: [html.Text(text)])` -pub fn wbr_text(attrs: List(Attr(a)), text: String) -> Node(a) { - Element(tag: "wbr", attrs: attrs, children: [Text(text)]) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam deleted file mode 100644 index a8fda0fb25a..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/html/attrs.gleam +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -// * THIS FILE IS GENERATED. DO NOT EDIT IT. * -// * You're probably looking for ./codegen/attrs_prelude.gleam, or ./codegen/attrs.json. * -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - - - - -pub type Attr(a) { - Attr(name: String, value: String) - Event(name: String, action: a) -} - -pub fn data(name: String, value: String) -> Attr(a) { - Attr(name: "data-" <> name, value: value) -} - -pub fn accept(value: String) -> Attr(a) { - Attr(name: "accept", value: value) -} - -pub fn accept_charset(value: String) -> Attr(a) { - Attr(name: "accept-charset", value: value) -} - -pub fn action(value: String) -> Attr(a) { - Attr(name: "action", value: value) -} - -pub fn alt(value: String) -> Attr(a) { - Attr(name: "alt", value: value) -} - -pub fn async() -> Attr(a) { - Attr(name: "async", value: "true") -} - -pub fn autocapitalize(value: String) -> Attr(a) { - Attr(name: "autocapitalize", value: value) -} - -pub fn autocomplete(value: String) -> Attr(a) { - Attr(name: "autocomplete", value: value) -} - -pub fn autofocus() -> Attr(a) { - Attr(name: "autofocus", value: "true") -} - -pub fn autoplay() -> Attr(a) { - Attr(name: "autoplay", value: "true") -} - -pub fn capture(value: String) -> Attr(a) { - Attr(name: "capture", value: value) -} - -pub fn charset(value: String) -> Attr(a) { - Attr(name: "charset", value: value) -} - -pub fn checked() -> Attr(a) { - Attr(name: "checked", value: "true") -} - -pub fn cite(value: String) -> Attr(a) { - Attr(name: "cite", value: value) -} - -pub fn class(value: String) -> Attr(a) { - Attr(name: "class", value: value) -} - -pub fn content(value: String) -> Attr(a) { - Attr(name: "content", value: value) -} - -pub fn contenteditable() -> Attr(a) { - Attr(name: "contenteditable", value: "true") -} - -pub fn crossorigin() -> Attr(a) { - Attr(name: "crossorigin", value: "true") -} - -pub fn defer() -> Attr(a) { - Attr(name: "defer", value: "true") -} - -pub fn disabled() -> Attr(a) { - Attr(name: "disabled", value: "true") -} - -pub fn draggable() -> Attr(a) { - Attr(name: "draggable", value: "true") -} - -pub fn for(value: String) -> Attr(a) { - Attr(name: "for", value: value) -} - -pub fn formaction(value: String) -> Attr(a) { - Attr(name: "formaction", value: value) -} - -pub fn height(value: String) -> Attr(a) { - Attr(name: "height", value: value) -} - -pub fn href(value: String) -> Attr(a) { - Attr(name: "href", value: value) -} - -pub fn http_equiv(value: String) -> Attr(a) { - Attr(name: "http-equiv", value: value) -} - -pub fn id(value: String) -> Attr(a) { - Attr(name: "id", value: value) -} - -pub fn integrity(value: String) -> Attr(a) { - Attr(name: "integrity", value: value) -} - -pub fn lang(value: String) -> Attr(a) { - Attr(name: "lang", value: value) -} - -pub fn loop() -> Attr(a) { - Attr(name: "loop", value: "true") -} - -pub fn method(value: String) -> Attr(a) { - Attr(name: "method", value: value) -} - -pub fn name(value: String) -> Attr(a) { - Attr(name: "name", value: value) -} - -pub fn placeholder(value: String) -> Attr(a) { - Attr(name: "placeholder", value: value) -} - -pub fn preload() -> Attr(a) { - Attr(name: "preload", value: "true") -} - -pub fn property(value: String) -> Attr(a) { - Attr(name: "property", value: value) -} - -pub fn readonly() -> Attr(a) { - Attr(name: "readonly", value: "true") -} - -pub fn rel(value: String) -> Attr(a) { - Attr(name: "rel", value: value) -} - -pub fn selected() -> Attr(a) { - Attr(name: "selected", value: "true") -} - -pub fn src(value: String) -> Attr(a) { - Attr(name: "src", value: value) -} - -pub fn style(value: String) -> Attr(a) { - Attr(name: "style", value: value) -} - -pub fn tabindex(value: String) -> Attr(a) { - Attr(name: "tabindex", value: value) -} - -pub fn target(value: String) -> Attr(a) { - Attr(name: "target", value: value) -} - -pub fn title(value: String) -> Attr(a) { - Attr(name: "title", value: value) -} - -pub fn type_(value: String) -> Attr(a) { - Attr(name: "type", value: value) -} - -pub fn value(value: String) -> Attr(a) { - Attr(name: "value", value: value) -} - -pub fn width(value: String) -> Attr(a) { - Attr(name: "width", value: value) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam deleted file mode 100644 index 8fe56a47f23..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/document.gleam +++ /dev/null @@ -1,97 +0,0 @@ -import gleam/option.{Option} -import gleam/list -import gleam/string_builder.{StringBuilder} - -pub const encoding = " -<meta charset=\"utf-8\" /> -<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /> -" - -pub type Document { - Document( - doctype: Option(String), - html_attrs: StringBuilder, - body_attrs: StringBuilder, - head: StringBuilder, - body: StringBuilder, - scripts: List(String), - ) -} - -pub fn new() { - Document( - doctype: option.None, - html_attrs: string_builder.new(), - body_attrs: string_builder.new(), - head: string_builder.new(), - body: string_builder.new(), - scripts: [], - ) -} - -pub fn merge(self: Document, new: Document) -> Document { - Document( - // Overwrite the doctype with a newer one, unless the newer one is `None` - doctype: option.or(new.doctype, self.doctype), - html_attrs: string_builder.append_builder(self.html_attrs, new.html_attrs), - body_attrs: string_builder.append_builder(self.body_attrs, new.body_attrs), - head: string_builder.append_builder(self.head, new.head), - body: string_builder.append_builder(self.body, new.body), - scripts: list.append(self.scripts, new.scripts), - ) -} - -pub fn concat(docs: List(Document)) -> Document { - docs - |> list.fold(new(), merge) -} - -pub fn from_doctype(doctype: String) -> Document { - Document(..new(), doctype: option.Some(doctype)) -} - -pub fn append_html_attrs(self: Document, html_attrs: StringBuilder) -> Document { - Document( - ..self, - html_attrs: string_builder.append_builder(self.html_attrs, html_attrs), - ) -} - -pub fn append_body_attrs(self: Document, body_attrs: StringBuilder) -> Document { - Document( - ..self, - body_attrs: string_builder.append_builder(self.body_attrs, body_attrs), - ) -} - -pub fn from_head(head: StringBuilder) -> Document { - Document(..new(), head: head) -} - -pub fn append_head(self: Document, head: StringBuilder) -> Document { - Document(..self, head: string_builder.append_builder(self.head, head)) -} - -pub fn from_body(body: StringBuilder) -> Document { - Document(..new(), body: body) -} - -pub fn append_body(self: Document, body: StringBuilder) -> Document { - Document(..self, body: string_builder.append_builder(self.body, body)) -} - -pub fn replace_body(self: Document, body: StringBuilder) -> Document { - Document(..self, body: body) -} - -pub fn from_script(script: String) -> Document { - Document(..new(), scripts: [script]) -} - -pub fn into_head(state: Document) -> Document { - Document( - ..state, - head: string_builder.append_builder(state.head, state.body), - body: string_builder.new(), - ) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam b/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam deleted file mode 100644 index 780a9715f79..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai/internal/render.gleam +++ /dev/null @@ -1,211 +0,0 @@ -import gleam/list -import gleam/option -import gleam/string_builder.{StringBuilder} -import gleam/string -import nakai/html.{Node} -import nakai/html/attrs.{Attr, Event} -import nakai/internal/document.{Document} - -type Builder(a, output) { - Builder(map: fn(Node(a)) -> output, fold: fn(List(output)) -> output) -} - -const document_builder = Builder( - map: render_document_node, - fold: document.concat, -) - -const inline_builder = Builder( - map: render_inline_node, - fold: string_builder.concat, -) - -fn render_doctype(doctype: String) -> StringBuilder { - string_builder.from_strings(["<!DOCTYPE ", doctype, ">\n"]) -} - -fn render_children( - children: List(Node(a)), - builder: Builder(a, output), -) -> output { - children - |> list.map(builder.map) - |> builder.fold() -} - -fn render_attrs(attrs: List(Attr(a))) -> StringBuilder { - attrs - |> list.map(render_attr) - |> list.fold(string_builder.new(), string_builder.append_builder) -} - -fn render_attr(attr: Attr(a)) -> StringBuilder { - case attr { - Attr(name, value) -> { - let sanitized_value = - value - |> string.replace("\"", """) - |> string.replace(">", ">") - string_builder.from_strings([" ", name, "=\"", sanitized_value, "\""]) - } - Event(_name, _action) -> { - string_builder.new() - } - } -} - -fn render_document_node(tree: Node(a)) -> Document { - case tree { - html.Doctype(doctype) -> document.from_doctype(doctype) - - html.Html(attrs, children) -> - render_children(children, document_builder) - |> document.append_html_attrs(render_attrs(attrs)) - - html.Head(children) -> - render_children(children, document_builder) - |> document.into_head() - - html.Body(attrs, children) -> - render_children(children, document_builder) - |> document.append_body_attrs(render_attrs(attrs)) - - html.Fragment(children) -> render_children(children, document_builder) - - html.Element(tag, attrs, children) -> { - let child_document = render_children(children, document_builder) - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(">"), - child_document.body, - string_builder.from_strings(["</", tag, ">"]), - ]) - |> document.replace_body(child_document, _) - } - - html.LeafElement(tag, attrs) -> - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(" />"), - ]) - |> document.from_body() - - html.Comment(content) -> { - let content = - content - |> string.replace("-->", "") - string_builder.from_strings(["<!-- ", content, " -->"]) - |> document.from_body() - } - - html.Text(content) -> - string_builder.from_string(content) - |> string_builder.replace("&", "&") - |> string_builder.replace("<", "<") - |> string_builder.replace(">", ">") - |> document.from_body() - - html.UnsafeText(content) -> - string_builder.from_string(content) - |> document.from_body() - - html.Script(script) -> document.from_script(script) - - html.Nothing -> document.new() - } -} - -fn render_inline_node(tree: Node(a)) -> StringBuilder { - case tree { - html.Doctype(doctype) -> render_doctype(doctype) - - html.Html(attrs, children) -> - render_inline_node(html.Element("html", attrs, children)) - - html.Head(children) -> - render_inline_node(html.Element("head", [], children)) - - html.Body(attrs, children) -> - render_inline_node(html.Element("body", attrs, children)) - - html.Fragment(children) -> render_children(children, inline_builder) - - html.Element(tag, attrs, children) -> { - let child_document = render_children(children, inline_builder) - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(">"), - child_document, - string_builder.from_strings(["</", tag, ">"]), - ]) - } - - html.LeafElement(tag, attrs) -> - string_builder.concat([ - string_builder.from_strings(["<", tag]), - render_attrs(attrs), - string_builder.from_string(" />"), - ]) - - html.Comment(content) -> { - let content = - content - |> string.replace("-->", "") - string_builder.from_strings(["<!-- ", content, " -->"]) - } - - html.Text(content) -> - string_builder.from_string(content) - |> string_builder.replace("&", "&") - |> string_builder.replace("<", "<") - |> string_builder.replace(">", ">") - - html.UnsafeText(content) -> string_builder.from_string(content) - - html.Script(script) -> - render_inline_node(html.Element("script", [], [html.Text(script)])) - - html.Nothing -> string_builder.new() - } -} - -fn render_script(script: String) -> StringBuilder { - string_builder.concat([ - string_builder.from_string("<script>"), - string_builder.from_string(script), - string_builder.from_string("</script>\n"), - ]) -} - -fn render_scripts(scripts: List(String)) -> StringBuilder { - scripts - |> list.map(render_script) - |> string_builder.concat() -} - -pub fn render_document(tree: Node(a)) -> StringBuilder { - let result = render_document_node(tree) - string_builder.concat([ - render_doctype( - result.doctype - |> option.unwrap("html"), - ), - string_builder.from_string("<html"), - result.html_attrs, - string_builder.from_string(">\n<head>" <> document.encoding), - result.head, - string_builder.from_string("</head>\n<body"), - result.body_attrs, - string_builder.from_string(">"), - result.body, - render_scripts(result.scripts), - string_builder.from_string("</body>\n</html>\n"), - ]) -} - -pub fn render_inline(tree: Node(a)) -> StringBuilder { - render_inline_node(tree) -} diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl deleted file mode 100644 index ee2b3a30198..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@head.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(nakai@experimental@head). --compile([no_auto_import, nowarn_unused_vars]). - --export([title/1, link/2, meta/2, http_equiv/2, charset/1]). - --spec title(binary()) -> nakai@html:node_(any()). -title(Title) -> - {head, [nakai@html:title(Title)]}. - --spec link(binary(), binary()) -> nakai@html:node_(any()). -link(Rel, Href) -> - {head, - [nakai@html:link( - [nakai@html@attrs:rel(Rel), nakai@html@attrs:href(Href)] - )]}. - --spec meta(binary(), binary()) -> nakai@html:node_(any()). -meta(Name, Content) -> - {head, - [nakai@html:meta( - [nakai@html@attrs:name(Name), nakai@html@attrs:content(Content)] - )]}. - --spec http_equiv(binary(), binary()) -> nakai@html:node_(any()). -http_equiv(Header, Content) -> - {head, - [nakai@html:meta( - [nakai@html@attrs:http_equiv(Header), - nakai@html@attrs:content(Content)] - )]}. - --spec charset(binary()) -> nakai@html:node_(any()). -charset(Charset) -> - {head, [nakai@html:meta([nakai@html@attrs:charset(Charset)])]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl deleted file mode 100644 index 447491b17a6..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@on.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(nakai@experimental@on). --compile([no_auto_import, nowarn_unused_vars]). - --export([click/1]). - --spec click(binary()) -> nakai@html@attrs:attr(any()). -click(Script) -> - {attr, <<"onclick"/utf8>>, Script}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl deleted file mode 100644 index d1a7ff36142..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@experimental@web_components.erl +++ /dev/null @@ -1,12 +0,0 @@ --module(nakai@experimental@web_components). --compile([no_auto_import, nowarn_unused_vars]). - --export([slot/1, template/2]). - --spec slot(list(nakai@html@attrs:attr(ICF))) -> nakai@html:node_(ICF). -slot(Attrs) -> - {leaf_element, <<"slot"/utf8>>, Attrs}. - --spec template(list(nakai@html@attrs:attr(ICJ)), list(nakai@html:node_(ICJ))) -> nakai@html:node_(ICJ). -template(Attrs, Children) -> - {element, <<"template"/utf8>>, Attrs, Children}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl deleted file mode 100644 index 52c46d513f4..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@html.erl +++ /dev/null @@ -1,830 +0,0 @@ --module(nakai@html). --compile([no_auto_import, nowarn_unused_vars]). - --export([title/1, a/2, a_text/2, abbr/2, abbr_text/2, address/2, address_text/2, area/1, article/2, article_text/2, aside/2, aside_text/2, audio/2, audio_text/2, b/2, b_text/2, base/1, bdi/2, bdi_text/2, bdo/2, bdo_text/2, blockquote/2, blockquote_text/2, br/1, button/2, button_text/2, canvas/2, canvas_text/2, caption/2, caption_text/2, cite/2, cite_text/2, code/2, code_text/2, col/2, col_text/2, colgroup/2, colgroup_text/2, data/2, data_text/2, datalist/2, datalist_text/2, dd/2, dd_text/2, del/2, del_text/2, details/2, details_text/2, dfn/2, dfn_text/2, dialog/2, dialog_text/2, 'div'/2, div_text/2, dl/2, dl_text/2, dt/2, dt_text/2, em/2, em_text/2, embed/2, embed_text/2, fieldset/2, fieldset_text/2, figcaption/2, figcaption_text/2, figure/2, figure_text/2, footer/2, footer_text/2, form/2, form_text/2, h1/2, h1_text/2, h2/2, h2_text/2, h3/2, h3_text/2, h4/2, h4_text/2, h5/2, h5_text/2, h6/2, h6_text/2, header/2, header_text/2, hr/1, i/2, i_text/2, iframe/2, iframe_text/2, img/1, input/1, ins/2, ins_text/2, kbd/2, kbd_text/2, label/2, label_text/2, legend/2, legend_text/2, li/2, li_text/2, link/1, main/2, main_text/2, map/2, map_text/2, mark/2, mark_text/2, math/2, math_text/2, menu/2, menu_text/2, menuitem/2, menuitem_text/2, meta/1, meter/2, meter_text/2, nav/2, nav_text/2, noscript/2, noscript_text/2, object/2, object_text/2, ol/2, ol_text/2, optgroup/2, optgroup_text/2, option/2, option_text/2, output/2, output_text/2, p/2, p_text/2, param/2, param_text/2, picture/2, picture_text/2, pre/2, pre_text/2, progress/2, progress_text/2, q/2, q_text/2, rp/2, rp_text/2, rt/2, rt_text/2, ruby/2, ruby_text/2, s/2, s_text/2, samp/2, samp_text/2, section/2, section_text/2, select/2, select_text/2, small/2, small_text/2, source/1, span/2, span_text/2, strong/2, strong_text/2, sub/2, sub_text/2, summary/2, summary_text/2, sup/2, sup_text/2, svg/2, svg_text/2, table/2, table_text/2, tbody/2, tbody_text/2, td/2, td_text/2, textarea/2, textarea_text/2, tfoot/2, tfoot_text/2, th/2, th_text/2, thead/2, thead_text/2, time/2, time_text/2, tr/2, tr_text/2, track/1, u/2, u_text/2, ul/2, ul_text/2, var/2, var_text/2, video/2, video_text/2, wbr/2, wbr_text/2]). --export_type([node_/1]). - --type node_(FSS) :: {doctype, binary()} | - {html, list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | - {head, list(node_(FSS))} | - {body, list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | - {fragment, list(node_(FSS))} | - {element, binary(), list(nakai@html@attrs:attr(FSS)), list(node_(FSS))} | - {leaf_element, binary(), list(nakai@html@attrs:attr(FSS))} | - {comment, binary()} | - {text, binary()} | - {unsafe_text, binary()} | - {script, binary()} | - nothing. - --spec title(binary()) -> node_(any()). -title(Text) -> - {element, <<"title"/utf8>>, [], [{text, Text}]}. - --spec a(list(nakai@html@attrs:attr(FSV)), list(node_(FSV))) -> node_(FSV). -a(Attrs, Children) -> - {element, <<"a"/utf8>>, Attrs, Children}. - --spec a_text(list(nakai@html@attrs:attr(FTB)), binary()) -> node_(FTB). -a_text(Attrs, Text) -> - {element, <<"a"/utf8>>, Attrs, [{text, Text}]}. - --spec abbr(list(nakai@html@attrs:attr(FTF)), list(node_(FTF))) -> node_(FTF). -abbr(Attrs, Children) -> - {element, <<"abbr"/utf8>>, Attrs, Children}. - --spec abbr_text(list(nakai@html@attrs:attr(FTL)), binary()) -> node_(FTL). -abbr_text(Attrs, Text) -> - {element, <<"abbr"/utf8>>, Attrs, [{text, Text}]}. - --spec address(list(nakai@html@attrs:attr(FTP)), list(node_(FTP))) -> node_(FTP). -address(Attrs, Children) -> - {element, <<"address"/utf8>>, Attrs, Children}. - --spec address_text(list(nakai@html@attrs:attr(FTV)), binary()) -> node_(FTV). -address_text(Attrs, Text) -> - {element, <<"address"/utf8>>, Attrs, [{text, Text}]}. - --spec area(list(nakai@html@attrs:attr(FTZ))) -> node_(FTZ). -area(Attrs) -> - {leaf_element, <<"area"/utf8>>, Attrs}. - --spec article(list(nakai@html@attrs:attr(FUD)), list(node_(FUD))) -> node_(FUD). -article(Attrs, Children) -> - {element, <<"article"/utf8>>, Attrs, Children}. - --spec article_text(list(nakai@html@attrs:attr(FUJ)), binary()) -> node_(FUJ). -article_text(Attrs, Text) -> - {element, <<"article"/utf8>>, Attrs, [{text, Text}]}. - --spec aside(list(nakai@html@attrs:attr(FUN)), list(node_(FUN))) -> node_(FUN). -aside(Attrs, Children) -> - {element, <<"aside"/utf8>>, Attrs, Children}. - --spec aside_text(list(nakai@html@attrs:attr(FUT)), binary()) -> node_(FUT). -aside_text(Attrs, Text) -> - {element, <<"aside"/utf8>>, Attrs, [{text, Text}]}. - --spec audio(list(nakai@html@attrs:attr(FUX)), list(node_(FUX))) -> node_(FUX). -audio(Attrs, Children) -> - {element, <<"audio"/utf8>>, Attrs, Children}. - --spec audio_text(list(nakai@html@attrs:attr(FVD)), binary()) -> node_(FVD). -audio_text(Attrs, Text) -> - {element, <<"audio"/utf8>>, Attrs, [{text, Text}]}. - --spec b(list(nakai@html@attrs:attr(FVH)), list(node_(FVH))) -> node_(FVH). -b(Attrs, Children) -> - {element, <<"b"/utf8>>, Attrs, Children}. - --spec b_text(list(nakai@html@attrs:attr(FVN)), binary()) -> node_(FVN). -b_text(Attrs, Text) -> - {element, <<"b"/utf8>>, Attrs, [{text, Text}]}. - --spec base(list(nakai@html@attrs:attr(FVR))) -> node_(FVR). -base(Attrs) -> - {leaf_element, <<"base"/utf8>>, Attrs}. - --spec bdi(list(nakai@html@attrs:attr(FVV)), list(node_(FVV))) -> node_(FVV). -bdi(Attrs, Children) -> - {element, <<"bdi"/utf8>>, Attrs, Children}. - --spec bdi_text(list(nakai@html@attrs:attr(FWB)), binary()) -> node_(FWB). -bdi_text(Attrs, Text) -> - {element, <<"bdi"/utf8>>, Attrs, [{text, Text}]}. - --spec bdo(list(nakai@html@attrs:attr(FWF)), list(node_(FWF))) -> node_(FWF). -bdo(Attrs, Children) -> - {element, <<"bdo"/utf8>>, Attrs, Children}. - --spec bdo_text(list(nakai@html@attrs:attr(FWL)), binary()) -> node_(FWL). -bdo_text(Attrs, Text) -> - {element, <<"bdo"/utf8>>, Attrs, [{text, Text}]}. - --spec blockquote(list(nakai@html@attrs:attr(FWP)), list(node_(FWP))) -> node_(FWP). -blockquote(Attrs, Children) -> - {element, <<"blockquote"/utf8>>, Attrs, Children}. - --spec blockquote_text(list(nakai@html@attrs:attr(FWV)), binary()) -> node_(FWV). -blockquote_text(Attrs, Text) -> - {element, <<"blockquote"/utf8>>, Attrs, [{text, Text}]}. - --spec br(list(nakai@html@attrs:attr(FWZ))) -> node_(FWZ). -br(Attrs) -> - {leaf_element, <<"br"/utf8>>, Attrs}. - --spec button(list(nakai@html@attrs:attr(FXD)), list(node_(FXD))) -> node_(FXD). -button(Attrs, Children) -> - {element, <<"button"/utf8>>, Attrs, Children}. - --spec button_text(list(nakai@html@attrs:attr(FXJ)), binary()) -> node_(FXJ). -button_text(Attrs, Text) -> - {element, <<"button"/utf8>>, Attrs, [{text, Text}]}. - --spec canvas(list(nakai@html@attrs:attr(FXN)), list(node_(FXN))) -> node_(FXN). -canvas(Attrs, Children) -> - {element, <<"canvas"/utf8>>, Attrs, Children}. - --spec canvas_text(list(nakai@html@attrs:attr(FXT)), binary()) -> node_(FXT). -canvas_text(Attrs, Text) -> - {element, <<"canvas"/utf8>>, Attrs, [{text, Text}]}. - --spec caption(list(nakai@html@attrs:attr(FXX)), list(node_(FXX))) -> node_(FXX). -caption(Attrs, Children) -> - {element, <<"caption"/utf8>>, Attrs, Children}. - --spec caption_text(list(nakai@html@attrs:attr(FYD)), binary()) -> node_(FYD). -caption_text(Attrs, Text) -> - {element, <<"caption"/utf8>>, Attrs, [{text, Text}]}. - --spec cite(list(nakai@html@attrs:attr(FYH)), list(node_(FYH))) -> node_(FYH). -cite(Attrs, Children) -> - {element, <<"cite"/utf8>>, Attrs, Children}. - --spec cite_text(list(nakai@html@attrs:attr(FYN)), binary()) -> node_(FYN). -cite_text(Attrs, Text) -> - {element, <<"cite"/utf8>>, Attrs, [{text, Text}]}. - --spec code(list(nakai@html@attrs:attr(FYR)), list(node_(FYR))) -> node_(FYR). -code(Attrs, Children) -> - {element, <<"code"/utf8>>, Attrs, Children}. - --spec code_text(list(nakai@html@attrs:attr(FYX)), binary()) -> node_(FYX). -code_text(Attrs, Text) -> - {element, <<"code"/utf8>>, Attrs, [{text, Text}]}. - --spec col(list(nakai@html@attrs:attr(FZB)), list(node_(FZB))) -> node_(FZB). -col(Attrs, Children) -> - {element, <<"col"/utf8>>, Attrs, Children}. - --spec col_text(list(nakai@html@attrs:attr(FZH)), binary()) -> node_(FZH). -col_text(Attrs, Text) -> - {element, <<"col"/utf8>>, Attrs, [{text, Text}]}. - --spec colgroup(list(nakai@html@attrs:attr(FZL)), list(node_(FZL))) -> node_(FZL). -colgroup(Attrs, Children) -> - {element, <<"colgroup"/utf8>>, Attrs, Children}. - --spec colgroup_text(list(nakai@html@attrs:attr(FZR)), binary()) -> node_(FZR). -colgroup_text(Attrs, Text) -> - {element, <<"colgroup"/utf8>>, Attrs, [{text, Text}]}. - --spec data(list(nakai@html@attrs:attr(FZV)), list(node_(FZV))) -> node_(FZV). -data(Attrs, Children) -> - {element, <<"data"/utf8>>, Attrs, Children}. - --spec data_text(list(nakai@html@attrs:attr(GAB)), binary()) -> node_(GAB). -data_text(Attrs, Text) -> - {element, <<"data"/utf8>>, Attrs, [{text, Text}]}. - --spec datalist(list(nakai@html@attrs:attr(GAF)), list(node_(GAF))) -> node_(GAF). -datalist(Attrs, Children) -> - {element, <<"datalist"/utf8>>, Attrs, Children}. - --spec datalist_text(list(nakai@html@attrs:attr(GAL)), binary()) -> node_(GAL). -datalist_text(Attrs, Text) -> - {element, <<"datalist"/utf8>>, Attrs, [{text, Text}]}. - --spec dd(list(nakai@html@attrs:attr(GAP)), list(node_(GAP))) -> node_(GAP). -dd(Attrs, Children) -> - {element, <<"dd"/utf8>>, Attrs, Children}. - --spec dd_text(list(nakai@html@attrs:attr(GAV)), binary()) -> node_(GAV). -dd_text(Attrs, Text) -> - {element, <<"dd"/utf8>>, Attrs, [{text, Text}]}. - --spec del(list(nakai@html@attrs:attr(GAZ)), list(node_(GAZ))) -> node_(GAZ). -del(Attrs, Children) -> - {element, <<"del"/utf8>>, Attrs, Children}. - --spec del_text(list(nakai@html@attrs:attr(GBF)), binary()) -> node_(GBF). -del_text(Attrs, Text) -> - {element, <<"del"/utf8>>, Attrs, [{text, Text}]}. - --spec details(list(nakai@html@attrs:attr(GBJ)), list(node_(GBJ))) -> node_(GBJ). -details(Attrs, Children) -> - {element, <<"details"/utf8>>, Attrs, Children}. - --spec details_text(list(nakai@html@attrs:attr(GBP)), binary()) -> node_(GBP). -details_text(Attrs, Text) -> - {element, <<"details"/utf8>>, Attrs, [{text, Text}]}. - --spec dfn(list(nakai@html@attrs:attr(GBT)), list(node_(GBT))) -> node_(GBT). -dfn(Attrs, Children) -> - {element, <<"dfn"/utf8>>, Attrs, Children}. - --spec dfn_text(list(nakai@html@attrs:attr(GBZ)), binary()) -> node_(GBZ). -dfn_text(Attrs, Text) -> - {element, <<"dfn"/utf8>>, Attrs, [{text, Text}]}. - --spec dialog(list(nakai@html@attrs:attr(GCD)), list(node_(GCD))) -> node_(GCD). -dialog(Attrs, Children) -> - {element, <<"dialog"/utf8>>, Attrs, Children}. - --spec dialog_text(list(nakai@html@attrs:attr(GCJ)), binary()) -> node_(GCJ). -dialog_text(Attrs, Text) -> - {element, <<"dialog"/utf8>>, Attrs, [{text, Text}]}. - --spec 'div'(list(nakai@html@attrs:attr(GCN)), list(node_(GCN))) -> node_(GCN). -'div'(Attrs, Children) -> - {element, <<"div"/utf8>>, Attrs, Children}. - --spec div_text(list(nakai@html@attrs:attr(GCT)), binary()) -> node_(GCT). -div_text(Attrs, Text) -> - {element, <<"div"/utf8>>, Attrs, [{text, Text}]}. - --spec dl(list(nakai@html@attrs:attr(GCX)), list(node_(GCX))) -> node_(GCX). -dl(Attrs, Children) -> - {element, <<"dl"/utf8>>, Attrs, Children}. - --spec dl_text(list(nakai@html@attrs:attr(GDD)), binary()) -> node_(GDD). -dl_text(Attrs, Text) -> - {element, <<"dl"/utf8>>, Attrs, [{text, Text}]}. - --spec dt(list(nakai@html@attrs:attr(GDH)), list(node_(GDH))) -> node_(GDH). -dt(Attrs, Children) -> - {element, <<"dt"/utf8>>, Attrs, Children}. - --spec dt_text(list(nakai@html@attrs:attr(GDN)), binary()) -> node_(GDN). -dt_text(Attrs, Text) -> - {element, <<"dt"/utf8>>, Attrs, [{text, Text}]}. - --spec em(list(nakai@html@attrs:attr(GDR)), list(node_(GDR))) -> node_(GDR). -em(Attrs, Children) -> - {element, <<"em"/utf8>>, Attrs, Children}. - --spec em_text(list(nakai@html@attrs:attr(GDX)), binary()) -> node_(GDX). -em_text(Attrs, Text) -> - {element, <<"em"/utf8>>, Attrs, [{text, Text}]}. - --spec embed(list(nakai@html@attrs:attr(GEB)), list(node_(GEB))) -> node_(GEB). -embed(Attrs, Children) -> - {element, <<"embed"/utf8>>, Attrs, Children}. - --spec embed_text(list(nakai@html@attrs:attr(GEH)), binary()) -> node_(GEH). -embed_text(Attrs, Text) -> - {element, <<"embed"/utf8>>, Attrs, [{text, Text}]}. - --spec fieldset(list(nakai@html@attrs:attr(GEL)), list(node_(GEL))) -> node_(GEL). -fieldset(Attrs, Children) -> - {element, <<"fieldset"/utf8>>, Attrs, Children}. - --spec fieldset_text(list(nakai@html@attrs:attr(GER)), binary()) -> node_(GER). -fieldset_text(Attrs, Text) -> - {element, <<"fieldset"/utf8>>, Attrs, [{text, Text}]}. - --spec figcaption(list(nakai@html@attrs:attr(GEV)), list(node_(GEV))) -> node_(GEV). -figcaption(Attrs, Children) -> - {element, <<"figcaption"/utf8>>, Attrs, Children}. - --spec figcaption_text(list(nakai@html@attrs:attr(GFB)), binary()) -> node_(GFB). -figcaption_text(Attrs, Text) -> - {element, <<"figcaption"/utf8>>, Attrs, [{text, Text}]}. - --spec figure(list(nakai@html@attrs:attr(GFF)), list(node_(GFF))) -> node_(GFF). -figure(Attrs, Children) -> - {element, <<"figure"/utf8>>, Attrs, Children}. - --spec figure_text(list(nakai@html@attrs:attr(GFL)), binary()) -> node_(GFL). -figure_text(Attrs, Text) -> - {element, <<"figure"/utf8>>, Attrs, [{text, Text}]}. - --spec footer(list(nakai@html@attrs:attr(GFP)), list(node_(GFP))) -> node_(GFP). -footer(Attrs, Children) -> - {element, <<"footer"/utf8>>, Attrs, Children}. - --spec footer_text(list(nakai@html@attrs:attr(GFV)), binary()) -> node_(GFV). -footer_text(Attrs, Text) -> - {element, <<"footer"/utf8>>, Attrs, [{text, Text}]}. - --spec form(list(nakai@html@attrs:attr(GFZ)), list(node_(GFZ))) -> node_(GFZ). -form(Attrs, Children) -> - {element, <<"form"/utf8>>, Attrs, Children}. - --spec form_text(list(nakai@html@attrs:attr(GGF)), binary()) -> node_(GGF). -form_text(Attrs, Text) -> - {element, <<"form"/utf8>>, Attrs, [{text, Text}]}. - --spec h1(list(nakai@html@attrs:attr(GGJ)), list(node_(GGJ))) -> node_(GGJ). -h1(Attrs, Children) -> - {element, <<"h1"/utf8>>, Attrs, Children}. - --spec h1_text(list(nakai@html@attrs:attr(GGP)), binary()) -> node_(GGP). -h1_text(Attrs, Text) -> - {element, <<"h1"/utf8>>, Attrs, [{text, Text}]}. - --spec h2(list(nakai@html@attrs:attr(GGT)), list(node_(GGT))) -> node_(GGT). -h2(Attrs, Children) -> - {element, <<"h2"/utf8>>, Attrs, Children}. - --spec h2_text(list(nakai@html@attrs:attr(GGZ)), binary()) -> node_(GGZ). -h2_text(Attrs, Text) -> - {element, <<"h2"/utf8>>, Attrs, [{text, Text}]}. - --spec h3(list(nakai@html@attrs:attr(GHD)), list(node_(GHD))) -> node_(GHD). -h3(Attrs, Children) -> - {element, <<"h3"/utf8>>, Attrs, Children}. - --spec h3_text(list(nakai@html@attrs:attr(GHJ)), binary()) -> node_(GHJ). -h3_text(Attrs, Text) -> - {element, <<"h3"/utf8>>, Attrs, [{text, Text}]}. - --spec h4(list(nakai@html@attrs:attr(GHN)), list(node_(GHN))) -> node_(GHN). -h4(Attrs, Children) -> - {element, <<"h4"/utf8>>, Attrs, Children}. - --spec h4_text(list(nakai@html@attrs:attr(GHT)), binary()) -> node_(GHT). -h4_text(Attrs, Text) -> - {element, <<"h4"/utf8>>, Attrs, [{text, Text}]}. - --spec h5(list(nakai@html@attrs:attr(GHX)), list(node_(GHX))) -> node_(GHX). -h5(Attrs, Children) -> - {element, <<"h5"/utf8>>, Attrs, Children}. - --spec h5_text(list(nakai@html@attrs:attr(GID)), binary()) -> node_(GID). -h5_text(Attrs, Text) -> - {element, <<"h5"/utf8>>, Attrs, [{text, Text}]}. - --spec h6(list(nakai@html@attrs:attr(GIH)), list(node_(GIH))) -> node_(GIH). -h6(Attrs, Children) -> - {element, <<"h6"/utf8>>, Attrs, Children}. - --spec h6_text(list(nakai@html@attrs:attr(GIN)), binary()) -> node_(GIN). -h6_text(Attrs, Text) -> - {element, <<"h6"/utf8>>, Attrs, [{text, Text}]}. - --spec header(list(nakai@html@attrs:attr(GIR)), list(node_(GIR))) -> node_(GIR). -header(Attrs, Children) -> - {element, <<"header"/utf8>>, Attrs, Children}. - --spec header_text(list(nakai@html@attrs:attr(GIX)), binary()) -> node_(GIX). -header_text(Attrs, Text) -> - {element, <<"header"/utf8>>, Attrs, [{text, Text}]}. - --spec hr(list(nakai@html@attrs:attr(GJB))) -> node_(GJB). -hr(Attrs) -> - {leaf_element, <<"hr"/utf8>>, Attrs}. - --spec i(list(nakai@html@attrs:attr(GJF)), list(node_(GJF))) -> node_(GJF). -i(Attrs, Children) -> - {element, <<"i"/utf8>>, Attrs, Children}. - --spec i_text(list(nakai@html@attrs:attr(GJL)), binary()) -> node_(GJL). -i_text(Attrs, Text) -> - {element, <<"i"/utf8>>, Attrs, [{text, Text}]}. - --spec iframe(list(nakai@html@attrs:attr(GJP)), list(node_(GJP))) -> node_(GJP). -iframe(Attrs, Children) -> - {element, <<"iframe"/utf8>>, Attrs, Children}. - --spec iframe_text(list(nakai@html@attrs:attr(GJV)), binary()) -> node_(GJV). -iframe_text(Attrs, Text) -> - {element, <<"iframe"/utf8>>, Attrs, [{text, Text}]}. - --spec img(list(nakai@html@attrs:attr(GJZ))) -> node_(GJZ). -img(Attrs) -> - {leaf_element, <<"img"/utf8>>, Attrs}. - --spec input(list(nakai@html@attrs:attr(GKD))) -> node_(GKD). -input(Attrs) -> - {leaf_element, <<"input"/utf8>>, Attrs}. - --spec ins(list(nakai@html@attrs:attr(GKH)), list(node_(GKH))) -> node_(GKH). -ins(Attrs, Children) -> - {element, <<"ins"/utf8>>, Attrs, Children}. - --spec ins_text(list(nakai@html@attrs:attr(GKN)), binary()) -> node_(GKN). -ins_text(Attrs, Text) -> - {element, <<"ins"/utf8>>, Attrs, [{text, Text}]}. - --spec kbd(list(nakai@html@attrs:attr(GKR)), list(node_(GKR))) -> node_(GKR). -kbd(Attrs, Children) -> - {element, <<"kbd"/utf8>>, Attrs, Children}. - --spec kbd_text(list(nakai@html@attrs:attr(GKX)), binary()) -> node_(GKX). -kbd_text(Attrs, Text) -> - {element, <<"kbd"/utf8>>, Attrs, [{text, Text}]}. - --spec label(list(nakai@html@attrs:attr(GLB)), list(node_(GLB))) -> node_(GLB). -label(Attrs, Children) -> - {element, <<"label"/utf8>>, Attrs, Children}. - --spec label_text(list(nakai@html@attrs:attr(GLH)), binary()) -> node_(GLH). -label_text(Attrs, Text) -> - {element, <<"label"/utf8>>, Attrs, [{text, Text}]}. - --spec legend(list(nakai@html@attrs:attr(GLL)), list(node_(GLL))) -> node_(GLL). -legend(Attrs, Children) -> - {element, <<"legend"/utf8>>, Attrs, Children}. - --spec legend_text(list(nakai@html@attrs:attr(GLR)), binary()) -> node_(GLR). -legend_text(Attrs, Text) -> - {element, <<"legend"/utf8>>, Attrs, [{text, Text}]}. - --spec li(list(nakai@html@attrs:attr(GLV)), list(node_(GLV))) -> node_(GLV). -li(Attrs, Children) -> - {element, <<"li"/utf8>>, Attrs, Children}. - --spec li_text(list(nakai@html@attrs:attr(GMB)), binary()) -> node_(GMB). -li_text(Attrs, Text) -> - {element, <<"li"/utf8>>, Attrs, [{text, Text}]}. - --spec link(list(nakai@html@attrs:attr(GMF))) -> node_(GMF). -link(Attrs) -> - {leaf_element, <<"link"/utf8>>, Attrs}. - --spec main(list(nakai@html@attrs:attr(GMJ)), list(node_(GMJ))) -> node_(GMJ). -main(Attrs, Children) -> - {element, <<"main"/utf8>>, Attrs, Children}. - --spec main_text(list(nakai@html@attrs:attr(GMP)), binary()) -> node_(GMP). -main_text(Attrs, Text) -> - {element, <<"main"/utf8>>, Attrs, [{text, Text}]}. - --spec map(list(nakai@html@attrs:attr(GMT)), list(node_(GMT))) -> node_(GMT). -map(Attrs, Children) -> - {element, <<"map"/utf8>>, Attrs, Children}. - --spec map_text(list(nakai@html@attrs:attr(GMZ)), binary()) -> node_(GMZ). -map_text(Attrs, Text) -> - {element, <<"map"/utf8>>, Attrs, [{text, Text}]}. - --spec mark(list(nakai@html@attrs:attr(GND)), list(node_(GND))) -> node_(GND). -mark(Attrs, Children) -> - {element, <<"mark"/utf8>>, Attrs, Children}. - --spec mark_text(list(nakai@html@attrs:attr(GNJ)), binary()) -> node_(GNJ). -mark_text(Attrs, Text) -> - {element, <<"mark"/utf8>>, Attrs, [{text, Text}]}. - --spec math(list(nakai@html@attrs:attr(GNN)), list(node_(GNN))) -> node_(GNN). -math(Attrs, Children) -> - {element, <<"math"/utf8>>, Attrs, Children}. - --spec math_text(list(nakai@html@attrs:attr(GNT)), binary()) -> node_(GNT). -math_text(Attrs, Text) -> - {element, <<"math"/utf8>>, Attrs, [{text, Text}]}. - --spec menu(list(nakai@html@attrs:attr(GNX)), list(node_(GNX))) -> node_(GNX). -menu(Attrs, Children) -> - {element, <<"menu"/utf8>>, Attrs, Children}. - --spec menu_text(list(nakai@html@attrs:attr(GOD)), binary()) -> node_(GOD). -menu_text(Attrs, Text) -> - {element, <<"menu"/utf8>>, Attrs, [{text, Text}]}. - --spec menuitem(list(nakai@html@attrs:attr(GOH)), list(node_(GOH))) -> node_(GOH). -menuitem(Attrs, Children) -> - {element, <<"menuitem"/utf8>>, Attrs, Children}. - --spec menuitem_text(list(nakai@html@attrs:attr(GON)), binary()) -> node_(GON). -menuitem_text(Attrs, Text) -> - {element, <<"menuitem"/utf8>>, Attrs, [{text, Text}]}. - --spec meta(list(nakai@html@attrs:attr(GOR))) -> node_(GOR). -meta(Attrs) -> - {leaf_element, <<"meta"/utf8>>, Attrs}. - --spec meter(list(nakai@html@attrs:attr(GOV)), list(node_(GOV))) -> node_(GOV). -meter(Attrs, Children) -> - {element, <<"meter"/utf8>>, Attrs, Children}. - --spec meter_text(list(nakai@html@attrs:attr(GPB)), binary()) -> node_(GPB). -meter_text(Attrs, Text) -> - {element, <<"meter"/utf8>>, Attrs, [{text, Text}]}. - --spec nav(list(nakai@html@attrs:attr(GPF)), list(node_(GPF))) -> node_(GPF). -nav(Attrs, Children) -> - {element, <<"nav"/utf8>>, Attrs, Children}. - --spec nav_text(list(nakai@html@attrs:attr(GPL)), binary()) -> node_(GPL). -nav_text(Attrs, Text) -> - {element, <<"nav"/utf8>>, Attrs, [{text, Text}]}. - --spec noscript(list(nakai@html@attrs:attr(GPP)), list(node_(GPP))) -> node_(GPP). -noscript(Attrs, Children) -> - {element, <<"noscript"/utf8>>, Attrs, Children}. - --spec noscript_text(list(nakai@html@attrs:attr(GPV)), binary()) -> node_(GPV). -noscript_text(Attrs, Text) -> - {element, <<"noscript"/utf8>>, Attrs, [{text, Text}]}. - --spec object(list(nakai@html@attrs:attr(GPZ)), list(node_(GPZ))) -> node_(GPZ). -object(Attrs, Children) -> - {element, <<"object"/utf8>>, Attrs, Children}. - --spec object_text(list(nakai@html@attrs:attr(GQF)), binary()) -> node_(GQF). -object_text(Attrs, Text) -> - {element, <<"object"/utf8>>, Attrs, [{text, Text}]}. - --spec ol(list(nakai@html@attrs:attr(GQJ)), list(node_(GQJ))) -> node_(GQJ). -ol(Attrs, Children) -> - {element, <<"ol"/utf8>>, Attrs, Children}. - --spec ol_text(list(nakai@html@attrs:attr(GQP)), binary()) -> node_(GQP). -ol_text(Attrs, Text) -> - {element, <<"ol"/utf8>>, Attrs, [{text, Text}]}. - --spec optgroup(list(nakai@html@attrs:attr(GQT)), list(node_(GQT))) -> node_(GQT). -optgroup(Attrs, Children) -> - {element, <<"optgroup"/utf8>>, Attrs, Children}. - --spec optgroup_text(list(nakai@html@attrs:attr(GQZ)), binary()) -> node_(GQZ). -optgroup_text(Attrs, Text) -> - {element, <<"optgroup"/utf8>>, Attrs, [{text, Text}]}. - --spec option(list(nakai@html@attrs:attr(GRD)), list(node_(GRD))) -> node_(GRD). -option(Attrs, Children) -> - {element, <<"option"/utf8>>, Attrs, Children}. - --spec option_text(list(nakai@html@attrs:attr(GRJ)), binary()) -> node_(GRJ). -option_text(Attrs, Text) -> - {element, <<"option"/utf8>>, Attrs, [{text, Text}]}. - --spec output(list(nakai@html@attrs:attr(GRN)), list(node_(GRN))) -> node_(GRN). -output(Attrs, Children) -> - {element, <<"output"/utf8>>, Attrs, Children}. - --spec output_text(list(nakai@html@attrs:attr(GRT)), binary()) -> node_(GRT). -output_text(Attrs, Text) -> - {element, <<"output"/utf8>>, Attrs, [{text, Text}]}. - --spec p(list(nakai@html@attrs:attr(GRX)), list(node_(GRX))) -> node_(GRX). -p(Attrs, Children) -> - {element, <<"p"/utf8>>, Attrs, Children}. - --spec p_text(list(nakai@html@attrs:attr(GSD)), binary()) -> node_(GSD). -p_text(Attrs, Text) -> - {element, <<"p"/utf8>>, Attrs, [{text, Text}]}. - --spec param(list(nakai@html@attrs:attr(GSH)), list(node_(GSH))) -> node_(GSH). -param(Attrs, Children) -> - {element, <<"param"/utf8>>, Attrs, Children}. - --spec param_text(list(nakai@html@attrs:attr(GSN)), binary()) -> node_(GSN). -param_text(Attrs, Text) -> - {element, <<"param"/utf8>>, Attrs, [{text, Text}]}. - --spec picture(list(nakai@html@attrs:attr(GSR)), list(node_(GSR))) -> node_(GSR). -picture(Attrs, Children) -> - {element, <<"picture"/utf8>>, Attrs, Children}. - --spec picture_text(list(nakai@html@attrs:attr(GSX)), binary()) -> node_(GSX). -picture_text(Attrs, Text) -> - {element, <<"picture"/utf8>>, Attrs, [{text, Text}]}. - --spec pre(list(nakai@html@attrs:attr(GTB)), list(node_(GTB))) -> node_(GTB). -pre(Attrs, Children) -> - {element, <<"pre"/utf8>>, Attrs, Children}. - --spec pre_text(list(nakai@html@attrs:attr(GTH)), binary()) -> node_(GTH). -pre_text(Attrs, Text) -> - {element, <<"pre"/utf8>>, Attrs, [{text, Text}]}. - --spec progress(list(nakai@html@attrs:attr(GTL)), list(node_(GTL))) -> node_(GTL). -progress(Attrs, Children) -> - {element, <<"progress"/utf8>>, Attrs, Children}. - --spec progress_text(list(nakai@html@attrs:attr(GTR)), binary()) -> node_(GTR). -progress_text(Attrs, Text) -> - {element, <<"progress"/utf8>>, Attrs, [{text, Text}]}. - --spec q(list(nakai@html@attrs:attr(GTV)), list(node_(GTV))) -> node_(GTV). -q(Attrs, Children) -> - {element, <<"q"/utf8>>, Attrs, Children}. - --spec q_text(list(nakai@html@attrs:attr(GUB)), binary()) -> node_(GUB). -q_text(Attrs, Text) -> - {element, <<"q"/utf8>>, Attrs, [{text, Text}]}. - --spec rp(list(nakai@html@attrs:attr(GUF)), list(node_(GUF))) -> node_(GUF). -rp(Attrs, Children) -> - {element, <<"rp"/utf8>>, Attrs, Children}. - --spec rp_text(list(nakai@html@attrs:attr(GUL)), binary()) -> node_(GUL). -rp_text(Attrs, Text) -> - {element, <<"rp"/utf8>>, Attrs, [{text, Text}]}. - --spec rt(list(nakai@html@attrs:attr(GUP)), list(node_(GUP))) -> node_(GUP). -rt(Attrs, Children) -> - {element, <<"rt"/utf8>>, Attrs, Children}. - --spec rt_text(list(nakai@html@attrs:attr(GUV)), binary()) -> node_(GUV). -rt_text(Attrs, Text) -> - {element, <<"rt"/utf8>>, Attrs, [{text, Text}]}. - --spec ruby(list(nakai@html@attrs:attr(GUZ)), list(node_(GUZ))) -> node_(GUZ). -ruby(Attrs, Children) -> - {element, <<"ruby"/utf8>>, Attrs, Children}. - --spec ruby_text(list(nakai@html@attrs:attr(GVF)), binary()) -> node_(GVF). -ruby_text(Attrs, Text) -> - {element, <<"ruby"/utf8>>, Attrs, [{text, Text}]}. - --spec s(list(nakai@html@attrs:attr(GVJ)), list(node_(GVJ))) -> node_(GVJ). -s(Attrs, Children) -> - {element, <<"s"/utf8>>, Attrs, Children}. - --spec s_text(list(nakai@html@attrs:attr(GVP)), binary()) -> node_(GVP). -s_text(Attrs, Text) -> - {element, <<"s"/utf8>>, Attrs, [{text, Text}]}. - --spec samp(list(nakai@html@attrs:attr(GVT)), list(node_(GVT))) -> node_(GVT). -samp(Attrs, Children) -> - {element, <<"samp"/utf8>>, Attrs, Children}. - --spec samp_text(list(nakai@html@attrs:attr(GVZ)), binary()) -> node_(GVZ). -samp_text(Attrs, Text) -> - {element, <<"samp"/utf8>>, Attrs, [{text, Text}]}. - --spec section(list(nakai@html@attrs:attr(GWD)), list(node_(GWD))) -> node_(GWD). -section(Attrs, Children) -> - {element, <<"section"/utf8>>, Attrs, Children}. - --spec section_text(list(nakai@html@attrs:attr(GWJ)), binary()) -> node_(GWJ). -section_text(Attrs, Text) -> - {element, <<"section"/utf8>>, Attrs, [{text, Text}]}. - --spec select(list(nakai@html@attrs:attr(GWN)), list(node_(GWN))) -> node_(GWN). -select(Attrs, Children) -> - {element, <<"select"/utf8>>, Attrs, Children}. - --spec select_text(list(nakai@html@attrs:attr(GWT)), binary()) -> node_(GWT). -select_text(Attrs, Text) -> - {element, <<"select"/utf8>>, Attrs, [{text, Text}]}. - --spec small(list(nakai@html@attrs:attr(GWX)), list(node_(GWX))) -> node_(GWX). -small(Attrs, Children) -> - {element, <<"small"/utf8>>, Attrs, Children}. - --spec small_text(list(nakai@html@attrs:attr(GXD)), binary()) -> node_(GXD). -small_text(Attrs, Text) -> - {element, <<"small"/utf8>>, Attrs, [{text, Text}]}. - --spec source(list(nakai@html@attrs:attr(GXH))) -> node_(GXH). -source(Attrs) -> - {leaf_element, <<"source"/utf8>>, Attrs}. - --spec span(list(nakai@html@attrs:attr(GXL)), list(node_(GXL))) -> node_(GXL). -span(Attrs, Children) -> - {element, <<"span"/utf8>>, Attrs, Children}. - --spec span_text(list(nakai@html@attrs:attr(GXR)), binary()) -> node_(GXR). -span_text(Attrs, Text) -> - {element, <<"span"/utf8>>, Attrs, [{text, Text}]}. - --spec strong(list(nakai@html@attrs:attr(GXV)), list(node_(GXV))) -> node_(GXV). -strong(Attrs, Children) -> - {element, <<"strong"/utf8>>, Attrs, Children}. - --spec strong_text(list(nakai@html@attrs:attr(GYB)), binary()) -> node_(GYB). -strong_text(Attrs, Text) -> - {element, <<"strong"/utf8>>, Attrs, [{text, Text}]}. - --spec sub(list(nakai@html@attrs:attr(GYF)), list(node_(GYF))) -> node_(GYF). -sub(Attrs, Children) -> - {element, <<"sub"/utf8>>, Attrs, Children}. - --spec sub_text(list(nakai@html@attrs:attr(GYL)), binary()) -> node_(GYL). -sub_text(Attrs, Text) -> - {element, <<"sub"/utf8>>, Attrs, [{text, Text}]}. - --spec summary(list(nakai@html@attrs:attr(GYP)), list(node_(GYP))) -> node_(GYP). -summary(Attrs, Children) -> - {element, <<"summary"/utf8>>, Attrs, Children}. - --spec summary_text(list(nakai@html@attrs:attr(GYV)), binary()) -> node_(GYV). -summary_text(Attrs, Text) -> - {element, <<"summary"/utf8>>, Attrs, [{text, Text}]}. - --spec sup(list(nakai@html@attrs:attr(GYZ)), list(node_(GYZ))) -> node_(GYZ). -sup(Attrs, Children) -> - {element, <<"sup"/utf8>>, Attrs, Children}. - --spec sup_text(list(nakai@html@attrs:attr(GZF)), binary()) -> node_(GZF). -sup_text(Attrs, Text) -> - {element, <<"sup"/utf8>>, Attrs, [{text, Text}]}. - --spec svg(list(nakai@html@attrs:attr(GZJ)), list(node_(GZJ))) -> node_(GZJ). -svg(Attrs, Children) -> - {element, <<"svg"/utf8>>, Attrs, Children}. - --spec svg_text(list(nakai@html@attrs:attr(GZP)), binary()) -> node_(GZP). -svg_text(Attrs, Text) -> - {element, <<"svg"/utf8>>, Attrs, [{text, Text}]}. - --spec table(list(nakai@html@attrs:attr(GZT)), list(node_(GZT))) -> node_(GZT). -table(Attrs, Children) -> - {element, <<"table"/utf8>>, Attrs, Children}. - --spec table_text(list(nakai@html@attrs:attr(GZZ)), binary()) -> node_(GZZ). -table_text(Attrs, Text) -> - {element, <<"table"/utf8>>, Attrs, [{text, Text}]}. - --spec tbody(list(nakai@html@attrs:attr(HAD)), list(node_(HAD))) -> node_(HAD). -tbody(Attrs, Children) -> - {element, <<"tbody"/utf8>>, Attrs, Children}. - --spec tbody_text(list(nakai@html@attrs:attr(HAJ)), binary()) -> node_(HAJ). -tbody_text(Attrs, Text) -> - {element, <<"tbody"/utf8>>, Attrs, [{text, Text}]}. - --spec td(list(nakai@html@attrs:attr(HAN)), list(node_(HAN))) -> node_(HAN). -td(Attrs, Children) -> - {element, <<"td"/utf8>>, Attrs, Children}. - --spec td_text(list(nakai@html@attrs:attr(HAT)), binary()) -> node_(HAT). -td_text(Attrs, Text) -> - {element, <<"td"/utf8>>, Attrs, [{text, Text}]}. - --spec textarea(list(nakai@html@attrs:attr(HAX)), list(node_(HAX))) -> node_(HAX). -textarea(Attrs, Children) -> - {element, <<"textarea"/utf8>>, Attrs, Children}. - --spec textarea_text(list(nakai@html@attrs:attr(HBD)), binary()) -> node_(HBD). -textarea_text(Attrs, Text) -> - {element, <<"textarea"/utf8>>, Attrs, [{text, Text}]}. - --spec tfoot(list(nakai@html@attrs:attr(HBH)), list(node_(HBH))) -> node_(HBH). -tfoot(Attrs, Children) -> - {element, <<"tfoot"/utf8>>, Attrs, Children}. - --spec tfoot_text(list(nakai@html@attrs:attr(HBN)), binary()) -> node_(HBN). -tfoot_text(Attrs, Text) -> - {element, <<"tfoot"/utf8>>, Attrs, [{text, Text}]}. - --spec th(list(nakai@html@attrs:attr(HBR)), list(node_(HBR))) -> node_(HBR). -th(Attrs, Children) -> - {element, <<"th"/utf8>>, Attrs, Children}. - --spec th_text(list(nakai@html@attrs:attr(HBX)), binary()) -> node_(HBX). -th_text(Attrs, Text) -> - {element, <<"th"/utf8>>, Attrs, [{text, Text}]}. - --spec thead(list(nakai@html@attrs:attr(HCB)), list(node_(HCB))) -> node_(HCB). -thead(Attrs, Children) -> - {element, <<"thead"/utf8>>, Attrs, Children}. - --spec thead_text(list(nakai@html@attrs:attr(HCH)), binary()) -> node_(HCH). -thead_text(Attrs, Text) -> - {element, <<"thead"/utf8>>, Attrs, [{text, Text}]}. - --spec time(list(nakai@html@attrs:attr(HCL)), list(node_(HCL))) -> node_(HCL). -time(Attrs, Children) -> - {element, <<"time"/utf8>>, Attrs, Children}. - --spec time_text(list(nakai@html@attrs:attr(HCR)), binary()) -> node_(HCR). -time_text(Attrs, Text) -> - {element, <<"time"/utf8>>, Attrs, [{text, Text}]}. - --spec tr(list(nakai@html@attrs:attr(HCV)), list(node_(HCV))) -> node_(HCV). -tr(Attrs, Children) -> - {element, <<"tr"/utf8>>, Attrs, Children}. - --spec tr_text(list(nakai@html@attrs:attr(HDB)), binary()) -> node_(HDB). -tr_text(Attrs, Text) -> - {element, <<"tr"/utf8>>, Attrs, [{text, Text}]}. - --spec track(list(nakai@html@attrs:attr(HDF))) -> node_(HDF). -track(Attrs) -> - {leaf_element, <<"track"/utf8>>, Attrs}. - --spec u(list(nakai@html@attrs:attr(HDJ)), list(node_(HDJ))) -> node_(HDJ). -u(Attrs, Children) -> - {element, <<"u"/utf8>>, Attrs, Children}. - --spec u_text(list(nakai@html@attrs:attr(HDP)), binary()) -> node_(HDP). -u_text(Attrs, Text) -> - {element, <<"u"/utf8>>, Attrs, [{text, Text}]}. - --spec ul(list(nakai@html@attrs:attr(HDT)), list(node_(HDT))) -> node_(HDT). -ul(Attrs, Children) -> - {element, <<"ul"/utf8>>, Attrs, Children}. - --spec ul_text(list(nakai@html@attrs:attr(HDZ)), binary()) -> node_(HDZ). -ul_text(Attrs, Text) -> - {element, <<"ul"/utf8>>, Attrs, [{text, Text}]}. - --spec var(list(nakai@html@attrs:attr(HED)), list(node_(HED))) -> node_(HED). -var(Attrs, Children) -> - {element, <<"var"/utf8>>, Attrs, Children}. - --spec var_text(list(nakai@html@attrs:attr(HEJ)), binary()) -> node_(HEJ). -var_text(Attrs, Text) -> - {element, <<"var"/utf8>>, Attrs, [{text, Text}]}. - --spec video(list(nakai@html@attrs:attr(HEN)), list(node_(HEN))) -> node_(HEN). -video(Attrs, Children) -> - {element, <<"video"/utf8>>, Attrs, Children}. - --spec video_text(list(nakai@html@attrs:attr(HET)), binary()) -> node_(HET). -video_text(Attrs, Text) -> - {element, <<"video"/utf8>>, Attrs, [{text, Text}]}. - --spec wbr(list(nakai@html@attrs:attr(HEX)), list(node_(HEX))) -> node_(HEX). -wbr(Attrs, Children) -> - {element, <<"wbr"/utf8>>, Attrs, Children}. - --spec wbr_text(list(nakai@html@attrs:attr(HFD)), binary()) -> node_(HFD). -wbr_text(Attrs, Text) -> - {element, <<"wbr"/utf8>>, Attrs, [{text, Text}]}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl deleted file mode 100644 index a75887648d0..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@html@attrs.erl +++ /dev/null @@ -1,191 +0,0 @@ --module(nakai@html@attrs). --compile([no_auto_import, nowarn_unused_vars]). - --export([data/2, accept/1, accept_charset/1, action/1, alt/1, async/0, autocapitalize/1, autocomplete/1, autofocus/0, autoplay/0, capture/1, charset/1, checked/0, cite/1, class/1, content/1, contenteditable/0, crossorigin/0, defer/0, disabled/0, draggable/0, for/1, formaction/1, height/1, href/1, http_equiv/1, id/1, integrity/1, lang/1, loop/0, method/1, name/1, placeholder/1, preload/0, property/1, readonly/0, rel/1, selected/0, src/1, style/1, tabindex/1, target/1, title/1, type_/1, value/1, width/1]). --export_type([attr/1]). - --type attr(FNI) :: {attr, binary(), binary()} | {event, binary(), FNI}. - --spec data(binary(), binary()) -> attr(any()). -data(Name, Value) -> - {attr, <<"data-"/utf8, Name/binary>>, Value}. - --spec accept(binary()) -> attr(any()). -accept(Value) -> - {attr, <<"accept"/utf8>>, Value}. - --spec accept_charset(binary()) -> attr(any()). -accept_charset(Value) -> - {attr, <<"accept-charset"/utf8>>, Value}. - --spec action(binary()) -> attr(any()). -action(Value) -> - {attr, <<"action"/utf8>>, Value}. - --spec alt(binary()) -> attr(any()). -alt(Value) -> - {attr, <<"alt"/utf8>>, Value}. - --spec async() -> attr(any()). -async() -> - {attr, <<"async"/utf8>>, <<"true"/utf8>>}. - --spec autocapitalize(binary()) -> attr(any()). -autocapitalize(Value) -> - {attr, <<"autocapitalize"/utf8>>, Value}. - --spec autocomplete(binary()) -> attr(any()). -autocomplete(Value) -> - {attr, <<"autocomplete"/utf8>>, Value}. - --spec autofocus() -> attr(any()). -autofocus() -> - {attr, <<"autofocus"/utf8>>, <<"true"/utf8>>}. - --spec autoplay() -> attr(any()). -autoplay() -> - {attr, <<"autoplay"/utf8>>, <<"true"/utf8>>}. - --spec capture(binary()) -> attr(any()). -capture(Value) -> - {attr, <<"capture"/utf8>>, Value}. - --spec charset(binary()) -> attr(any()). -charset(Value) -> - {attr, <<"charset"/utf8>>, Value}. - --spec checked() -> attr(any()). -checked() -> - {attr, <<"checked"/utf8>>, <<"true"/utf8>>}. - --spec cite(binary()) -> attr(any()). -cite(Value) -> - {attr, <<"cite"/utf8>>, Value}. - --spec class(binary()) -> attr(any()). -class(Value) -> - {attr, <<"class"/utf8>>, Value}. - --spec content(binary()) -> attr(any()). -content(Value) -> - {attr, <<"content"/utf8>>, Value}. - --spec contenteditable() -> attr(any()). -contenteditable() -> - {attr, <<"contenteditable"/utf8>>, <<"true"/utf8>>}. - --spec crossorigin() -> attr(any()). -crossorigin() -> - {attr, <<"crossorigin"/utf8>>, <<"true"/utf8>>}. - --spec defer() -> attr(any()). -defer() -> - {attr, <<"defer"/utf8>>, <<"true"/utf8>>}. - --spec disabled() -> attr(any()). -disabled() -> - {attr, <<"disabled"/utf8>>, <<"true"/utf8>>}. - --spec draggable() -> attr(any()). -draggable() -> - {attr, <<"draggable"/utf8>>, <<"true"/utf8>>}. - --spec for(binary()) -> attr(any()). -for(Value) -> - {attr, <<"for"/utf8>>, Value}. - --spec formaction(binary()) -> attr(any()). -formaction(Value) -> - {attr, <<"formaction"/utf8>>, Value}. - --spec height(binary()) -> attr(any()). -height(Value) -> - {attr, <<"height"/utf8>>, Value}. - --spec href(binary()) -> attr(any()). -href(Value) -> - {attr, <<"href"/utf8>>, Value}. - --spec http_equiv(binary()) -> attr(any()). -http_equiv(Value) -> - {attr, <<"http-equiv"/utf8>>, Value}. - --spec id(binary()) -> attr(any()). -id(Value) -> - {attr, <<"id"/utf8>>, Value}. - --spec integrity(binary()) -> attr(any()). -integrity(Value) -> - {attr, <<"integrity"/utf8>>, Value}. - --spec lang(binary()) -> attr(any()). -lang(Value) -> - {attr, <<"lang"/utf8>>, Value}. - --spec loop() -> attr(any()). -loop() -> - {attr, <<"loop"/utf8>>, <<"true"/utf8>>}. - --spec method(binary()) -> attr(any()). -method(Value) -> - {attr, <<"method"/utf8>>, Value}. - --spec name(binary()) -> attr(any()). -name(Value) -> - {attr, <<"name"/utf8>>, Value}. - --spec placeholder(binary()) -> attr(any()). -placeholder(Value) -> - {attr, <<"placeholder"/utf8>>, Value}. - --spec preload() -> attr(any()). -preload() -> - {attr, <<"preload"/utf8>>, <<"true"/utf8>>}. - --spec property(binary()) -> attr(any()). -property(Value) -> - {attr, <<"property"/utf8>>, Value}. - --spec readonly() -> attr(any()). -readonly() -> - {attr, <<"readonly"/utf8>>, <<"true"/utf8>>}. - --spec rel(binary()) -> attr(any()). -rel(Value) -> - {attr, <<"rel"/utf8>>, Value}. - --spec selected() -> attr(any()). -selected() -> - {attr, <<"selected"/utf8>>, <<"true"/utf8>>}. - --spec src(binary()) -> attr(any()). -src(Value) -> - {attr, <<"src"/utf8>>, Value}. - --spec style(binary()) -> attr(any()). -style(Value) -> - {attr, <<"style"/utf8>>, Value}. - --spec tabindex(binary()) -> attr(any()). -tabindex(Value) -> - {attr, <<"tabindex"/utf8>>, Value}. - --spec target(binary()) -> attr(any()). -target(Value) -> - {attr, <<"target"/utf8>>, Value}. - --spec title(binary()) -> attr(any()). -title(Value) -> - {attr, <<"title"/utf8>>, Value}. - --spec type_(binary()) -> attr(any()). -type_(Value) -> - {attr, <<"type"/utf8>>, Value}. - --spec value(binary()) -> attr(any()). -value(Value) -> - {attr, <<"value"/utf8>>, Value}. - --spec width(binary()) -> attr(any()). -width(Value) -> - {attr, <<"width"/utf8>>, Value}. diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl deleted file mode 100644 index 2b544c8d6f6..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@document.erl +++ /dev/null @@ -1,117 +0,0 @@ --module(nakai@internal@document). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/0, merge/2, concat/1, from_doctype/1, append_html_attrs/2, append_body_attrs/2, from_head/1, append_head/2, from_body/1, append_body/2, replace_body/2, from_script/1, into_head/1]). --export_type([document/0]). - --type document() :: {document, - gleam@option:option(binary()), - gleam@string_builder:string_builder(), - gleam@string_builder:string_builder(), - gleam@string_builder:string_builder(), - gleam@string_builder:string_builder(), - list(binary())}. - --spec new() -> document(). -new() -> - {document, - none, - gleam@string_builder:new(), - gleam@string_builder:new(), - gleam@string_builder:new(), - gleam@string_builder:new(), - []}. - --spec merge(document(), document()) -> document(). -merge(Self, New) -> - {document, - gleam@option:'or'(erlang:element(2, New), erlang:element(2, Self)), - gleam@string_builder:append_builder( - erlang:element(3, Self), - erlang:element(3, New) - ), - gleam@string_builder:append_builder( - erlang:element(4, Self), - erlang:element(4, New) - ), - gleam@string_builder:append_builder( - erlang:element(5, Self), - erlang:element(5, New) - ), - gleam@string_builder:append_builder( - erlang:element(6, Self), - erlang:element(6, New) - ), - gleam@list:append(erlang:element(7, Self), erlang:element(7, New))}. - --spec concat(list(document())) -> document(). -concat(Docs) -> - _pipe = Docs, - gleam@list:fold(_pipe, new(), fun merge/2). - --spec from_doctype(binary()) -> document(). -from_doctype(Doctype) -> - erlang:setelement(2, new(), {some, Doctype}). - --spec append_html_attrs(document(), gleam@string_builder:string_builder()) -> document(). -append_html_attrs(Self, Html_attrs) -> - erlang:setelement( - 3, - Self, - gleam@string_builder:append_builder(erlang:element(3, Self), Html_attrs) - ). - --spec append_body_attrs(document(), gleam@string_builder:string_builder()) -> document(). -append_body_attrs(Self, Body_attrs) -> - erlang:setelement( - 4, - Self, - gleam@string_builder:append_builder(erlang:element(4, Self), Body_attrs) - ). - --spec from_head(gleam@string_builder:string_builder()) -> document(). -from_head(Head) -> - erlang:setelement(5, new(), Head). - --spec append_head(document(), gleam@string_builder:string_builder()) -> document(). -append_head(Self, Head) -> - erlang:setelement( - 5, - Self, - gleam@string_builder:append_builder(erlang:element(5, Self), Head) - ). - --spec from_body(gleam@string_builder:string_builder()) -> document(). -from_body(Body) -> - erlang:setelement(6, new(), Body). - --spec append_body(document(), gleam@string_builder:string_builder()) -> document(). -append_body(Self, Body) -> - erlang:setelement( - 6, - Self, - gleam@string_builder:append_builder(erlang:element(6, Self), Body) - ). - --spec replace_body(document(), gleam@string_builder:string_builder()) -> document(). -replace_body(Self, Body) -> - erlang:setelement(6, Self, Body). - --spec from_script(binary()) -> document(). -from_script(Script) -> - erlang:setelement(7, new(), [Script]). - --spec into_head(document()) -> document(). -into_head(State) -> - erlang:setelement( - 6, - erlang:setelement( - 5, - State, - gleam@string_builder:append_builder( - erlang:element(5, State), - erlang:element(6, State) - ) - ), - gleam@string_builder:new() - ). diff --git a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl b/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl deleted file mode 100644 index ad00173bdd4..00000000000 --- a/test-community-packages-javascript/build/packages/nakai/src/nakai@internal@render.erl +++ /dev/null @@ -1,297 +0,0 @@ --module(nakai@internal@render). --compile([no_auto_import, nowarn_unused_vars]). - --export([render_document/1, render_inline/1]). --export_type([builder/2]). - --type builder(HVS, HVT) :: {builder, - fun((nakai@html:node_(HVS)) -> HVT), - fun((list(HVT)) -> HVT)}. - --spec render_doctype(binary()) -> gleam@string_builder:string_builder(). -render_doctype(Doctype) -> - gleam@string_builder:from_strings( - [<<"<!DOCTYPE "/utf8>>, Doctype, <<">\n"/utf8>>] - ). - --spec render_children(list(nakai@html:node_(HVU)), builder(HVU, HVX)) -> HVX. -render_children(Children, Builder) -> - _pipe = Children, - _pipe@1 = gleam@list:map(_pipe, erlang:element(2, Builder)), - (erlang:element(3, Builder))(_pipe@1). - --spec render_attr(nakai@html@attrs:attr(any())) -> gleam@string_builder:string_builder(). -render_attr(Attr) -> - case Attr of - {attr, Name, Value} -> - Sanitized_value = begin - _pipe = Value, - _pipe@1 = gleam@string:replace( - _pipe, - <<"\""/utf8>>, - <<"""/utf8>> - ), - gleam@string:replace(_pipe@1, <<">"/utf8>>, <<">"/utf8>>) - end, - gleam@string_builder:from_strings( - [<<" "/utf8>>, - Name, - <<"=\""/utf8>>, - Sanitized_value, - <<"\""/utf8>>] - ); - - {event, _, _} -> - gleam@string_builder:new() - end. - --spec render_attrs(list(nakai@html@attrs:attr(any()))) -> gleam@string_builder:string_builder(). -render_attrs(Attrs) -> - _pipe = Attrs, - _pipe@1 = gleam@list:map(_pipe, fun render_attr/1), - gleam@list:fold( - _pipe@1, - gleam@string_builder:new(), - fun gleam@string_builder:append_builder/2 - ). - --spec render_document_node(nakai@html:node_(any())) -> nakai@internal@document:document(). -render_document_node(Tree) -> - case Tree of - {doctype, Doctype} -> - nakai@internal@document:from_doctype(Doctype); - - {html, Attrs, Children} -> - _pipe = render_children( - Children, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - nakai@internal@document:append_html_attrs( - _pipe, - render_attrs(Attrs) - ); - - {head, Children@1} -> - _pipe@1 = render_children( - Children@1, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - nakai@internal@document:into_head(_pipe@1); - - {body, Attrs@1, Children@2} -> - _pipe@2 = render_children( - Children@2, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - nakai@internal@document:append_body_attrs( - _pipe@2, - render_attrs(Attrs@1) - ); - - {fragment, Children@3} -> - render_children( - Children@3, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ); - - {element, Tag, Attrs@2, Children@4} -> - Child_document = render_children( - Children@4, - {builder, - fun render_document_node/1, - fun nakai@internal@document:concat/1} - ), - _pipe@3 = gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag]), - render_attrs(Attrs@2), - gleam@string_builder:from_string(<<">"/utf8>>), - erlang:element(6, Child_document), - gleam@string_builder:from_strings( - [<<"</"/utf8>>, Tag, <<">"/utf8>>] - )] - ), - nakai@internal@document:replace_body(Child_document, _pipe@3); - - {leaf_element, Tag@1, Attrs@3} -> - _pipe@4 = gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag@1]), - render_attrs(Attrs@3), - gleam@string_builder:from_string(<<" />"/utf8>>)] - ), - nakai@internal@document:from_body(_pipe@4); - - {comment, Content} -> - Content@1 = begin - _pipe@5 = Content, - gleam@string:replace(_pipe@5, <<"-->"/utf8>>, <<""/utf8>>) - end, - _pipe@6 = gleam@string_builder:from_strings( - [<<"<!-- "/utf8>>, Content@1, <<" -->"/utf8>>] - ), - nakai@internal@document:from_body(_pipe@6); - - {text, Content@2} -> - _pipe@7 = gleam@string_builder:from_string(Content@2), - _pipe@8 = gleam@string_builder:replace( - _pipe@7, - <<"&"/utf8>>, - <<"&"/utf8>> - ), - _pipe@9 = gleam@string_builder:replace( - _pipe@8, - <<"<"/utf8>>, - <<"<"/utf8>> - ), - _pipe@10 = gleam@string_builder:replace( - _pipe@9, - <<">"/utf8>>, - <<">"/utf8>> - ), - nakai@internal@document:from_body(_pipe@10); - - {unsafe_text, Content@3} -> - _pipe@11 = gleam@string_builder:from_string(Content@3), - nakai@internal@document:from_body(_pipe@11); - - {script, Script} -> - nakai@internal@document:from_script(Script); - - nothing -> - nakai@internal@document:new() - end. - --spec render_script(binary()) -> gleam@string_builder:string_builder(). -render_script(Script) -> - gleam@string_builder:concat( - [gleam@string_builder:from_string(<<"<script>"/utf8>>), - gleam@string_builder:from_string(Script), - gleam@string_builder:from_string(<<"</script>\n"/utf8>>)] - ). - --spec render_scripts(list(binary())) -> gleam@string_builder:string_builder(). -render_scripts(Scripts) -> - _pipe = Scripts, - _pipe@1 = gleam@list:map(_pipe, fun render_script/1), - gleam@string_builder:concat(_pipe@1). - --spec render_document(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -render_document(Tree) -> - Result = render_document_node(Tree), - gleam@string_builder:concat( - [render_doctype( - begin - _pipe = erlang:element(2, Result), - gleam@option:unwrap(_pipe, <<"html"/utf8>>) - end - ), - gleam@string_builder:from_string(<<"<html"/utf8>>), - erlang:element(3, Result), - gleam@string_builder:from_string( - <<">\n<head>"/utf8, - (<<" -<meta charset=\"utf-8\" /> -<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /> -"/utf8>>)/binary>> - ), - erlang:element(5, Result), - gleam@string_builder:from_string(<<"</head>\n<body"/utf8>>), - erlang:element(4, Result), - gleam@string_builder:from_string(<<">"/utf8>>), - erlang:element(6, Result), - render_scripts(erlang:element(7, Result)), - gleam@string_builder:from_string(<<"</body>\n</html>\n"/utf8>>)] - ). - --spec render_inline_node(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -render_inline_node(Tree) -> - case Tree of - {doctype, Doctype} -> - render_doctype(Doctype); - - {html, Attrs, Children} -> - render_inline_node({element, <<"html"/utf8>>, Attrs, Children}); - - {head, Children@1} -> - render_inline_node({element, <<"head"/utf8>>, [], Children@1}); - - {body, Attrs@1, Children@2} -> - render_inline_node({element, <<"body"/utf8>>, Attrs@1, Children@2}); - - {fragment, Children@3} -> - render_children( - Children@3, - {builder, - fun render_inline_node/1, - fun gleam@string_builder:concat/1} - ); - - {element, Tag, Attrs@2, Children@4} -> - Child_document = render_children( - Children@4, - {builder, - fun render_inline_node/1, - fun gleam@string_builder:concat/1} - ), - gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag]), - render_attrs(Attrs@2), - gleam@string_builder:from_string(<<">"/utf8>>), - Child_document, - gleam@string_builder:from_strings( - [<<"</"/utf8>>, Tag, <<">"/utf8>>] - )] - ); - - {leaf_element, Tag@1, Attrs@3} -> - gleam@string_builder:concat( - [gleam@string_builder:from_strings([<<"<"/utf8>>, Tag@1]), - render_attrs(Attrs@3), - gleam@string_builder:from_string(<<" />"/utf8>>)] - ); - - {comment, Content} -> - Content@1 = begin - _pipe = Content, - gleam@string:replace(_pipe, <<"-->"/utf8>>, <<""/utf8>>) - end, - gleam@string_builder:from_strings( - [<<"<!-- "/utf8>>, Content@1, <<" -->"/utf8>>] - ); - - {text, Content@2} -> - _pipe@1 = gleam@string_builder:from_string(Content@2), - _pipe@2 = gleam@string_builder:replace( - _pipe@1, - <<"&"/utf8>>, - <<"&"/utf8>> - ), - _pipe@3 = gleam@string_builder:replace( - _pipe@2, - <<"<"/utf8>>, - <<"<"/utf8>> - ), - gleam@string_builder:replace(_pipe@3, <<">"/utf8>>, <<">"/utf8>>); - - {unsafe_text, Content@3} -> - gleam@string_builder:from_string(Content@3); - - {script, Script} -> - render_inline_node( - {element, <<"script"/utf8>>, [], [{text, Script}]} - ); - - nothing -> - gleam@string_builder:new() - end. - --spec render_inline(nakai@html:node_(any())) -> gleam@string_builder:string_builder(). -render_inline(Tree) -> - render_inline_node(Tree). diff --git a/test-community-packages-javascript/build/packages/nibble/LICENSE b/test-community-packages-javascript/build/packages/nibble/LICENSE deleted file mode 100644 index b8320fd29e4..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/LICENSE +++ /dev/null @@ -1,18 +0,0 @@ -Copyright 2022 Hayleigh Thompson - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in the -Software without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/nibble/README.md b/test-community-packages-javascript/build/packages/nibble/README.md deleted file mode 100644 index b6cba15088f..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# nibble - -[![Package Version](https://img.shields.io/hexpm/v/nibble)](https://hex.pm/packages/nibble) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/nibble/) - -A string parsing library heavily inspired by [`elm/parser`](https://github.com/elm/parser). - -## Quick start - -```gleam -import gleam/function -import nibble.{ Parser } - -type Point { - Point(x: Int, y: Int) -} - -pub fn main () { - let parser = - nibble.succeed(function.curry2(Point)) - |> nibble.drop(nibble.grapheme("(")) - |> nibble.drop(nibble.spaces()) - |> nibble.keep(nibble.int()) - |> nibble.drop(nibble.spaces()) - |> nibble.drop(nibble.grapheme(",")) - |> nibble.drop(nibble.spaces()) - |> nibble.keep(nibble.int()) - |> nibble.drop(nibble.spaces()) - |> nibble.drop(nibble.grapheme(")")) - - assert Ok(point) = nibble.run("(1, 2)", parser) - - point.x //=> 1 - point.y //=> 2 -} -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add nibble -``` - -and its documentation can be found at <https://hexdocs.pm/nibble>. diff --git a/test-community-packages-javascript/build/packages/nibble/gleam.toml b/test-community-packages-javascript/build/packages/nibble/gleam.toml deleted file mode 100644 index 2f6286a1f38..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/gleam.toml +++ /dev/null @@ -1,15 +0,0 @@ -name = "nibble" -version = "0.2.3" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -licences = ["MIT"] -description = "A string parsing library heavily inspired by elm/parser." -repository = { type = "github", user = "hayleigh-dot-dev", repo = "gleam-nibble" } - -[dependencies] -gleam_stdlib = "~> 0.28" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl deleted file mode 100644 index 4980405448d..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/include/nibble@pratt_Config.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(config, { - one_of :: list(fun((nibble@pratt:config(any(), any())) -> nibble:parser(any(), any()))), - and_then_one_of :: list(nibble@pratt:operator(any(), any())), - spaces :: nibble:parser(nil, any()) -}). diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl deleted file mode 100644 index 3e3e338638d..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/include/nibble_DeadEnd.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(dead_end, { - row :: integer(), - col :: integer(), - problem :: nibble:error(), - context :: list(nibble:located(any())) -}). diff --git a/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl b/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl deleted file mode 100644 index b987412c2cb..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/include/nibble_Located.hrl +++ /dev/null @@ -1 +0,0 @@ --record(located, {row :: integer(), col :: integer(), context :: any()}). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src b/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src deleted file mode 100644 index f499dc88532..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble.app.src +++ /dev/null @@ -1,10 +0,0 @@ -{application, nibble, [ - {vsn, "0.2.3"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A string parsing library heavily inspired by elm/parser."}, - {modules, [nibble, - nibble@pratt, - nibble@predicates]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble.erl deleted file mode 100644 index da1bce811f8..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble.erl +++ /dev/null @@ -1,517 +0,0 @@ --module(nibble). --compile([no_auto_import, nowarn_unused_vars]). - --export([succeed/1, lazy/1, backtrackable/1, commit/1, then/2, map/2, replace/2, keep/2, drop/2, fail/1, eof/0, take_if/2, any/0, grapheme/1, one_of/1, in/2, inspect/2, string/1, run/2, int/0, float/0, take_while/1, spaces/0, whitespace/0, take_if_and_while/2, take_until/1, loop/2, many/2]). --export_type([parser/2, state/1, step/2, located/1, backtrackable/0, loop/2, error/0, dead_end/1, bag/1]). - --opaque parser(EVD, EVE) :: {parser, fun((state(EVE)) -> step(EVD, EVE))}. - --type state(EVF) :: {state, - gleam@map:map_(integer(), binary()), - integer(), - list(located(EVF)), - integer(), - integer()}. - --type step(EVG, EVH) :: {cont, backtrackable(), EVG, state(EVH)} | - {fail, backtrackable(), bag(EVH)}. - --type located(EVI) :: {located, integer(), integer(), EVI}. - --type backtrackable() :: commit | backtrack. - --type loop(EVJ, EVK) :: {continue, EVK} | {break, EVJ}. - --type error() :: {bad_parser, binary()} | - {custom, binary()} | - end_of_input | - {expected, binary(), binary()} | - {unexpected, binary()}. - --type dead_end(EVL) :: {dead_end, - integer(), - integer(), - error(), - list(located(EVL))}. - --type bag(EVM) :: empty | - {cons, bag(EVM), dead_end(EVM)} | - {append, bag(EVM), bag(EVM)}. - --spec runwrap(state(EVV), parser(EVX, EVV)) -> step(EVX, EVV). -runwrap(State, Parser) -> - {parser, Parse} = Parser, - Parse(State). - --spec succeed(EWG) -> parser(EWG, any()). -succeed(A) -> - {parser, fun(State) -> {cont, backtrack, A, State} end}. - --spec lazy(fun(() -> parser(EWO, EWP))) -> parser(EWO, EWP). -lazy(Parser) -> - {parser, fun(State) -> runwrap(State, Parser()) end}. - --spec backtrackable(parser(EWU, EWV)) -> parser(EWU, EWV). -backtrackable(Parser) -> - {parser, fun(State) -> case runwrap(State, Parser) of - {cont, _, A, State@1} -> - {cont, backtrack, A, State@1}; - - {fail, _, Bag} -> - {fail, backtrack, Bag} - end end}. - --spec commit(EXA) -> parser(EXA, any()). -commit(A) -> - {parser, fun(State) -> {cont, commit, A, State} end}. - --spec should_commit(backtrackable(), backtrackable()) -> backtrackable(). -should_commit(To_x, To_y) -> - case {To_x, To_y} of - {commit, _} -> - commit; - - {_, commit} -> - commit; - - {_, _} -> - backtrack - end. - --spec then(parser(EXE, EXF), fun((EXE) -> parser(EXI, EXF))) -> parser(EXI, EXF). -then(Parser, F) -> - {parser, fun(State) -> case runwrap(State, Parser) of - {cont, To_a, A, State@1} -> - case runwrap(State@1, F(A)) of - {cont, To_b, B, State@2} -> - {cont, should_commit(To_a, To_b), B, State@2}; - - {fail, To_b@1, Bag} -> - {fail, should_commit(To_a, To_b@1), Bag} - end; - - {fail, Can_backtrack, Bag@1} -> - {fail, Can_backtrack, Bag@1} - end end}. - --spec map(parser(EXN, EXO), fun((EXN) -> EXR)) -> parser(EXR, EXO). -map(Parser, F) -> - then(Parser, fun(A) -> succeed(F(A)) end). - --spec next(state(EWC)) -> {gleam@option:option(binary()), state(EWC)}. -next(State) -> - case gleam@map:get(erlang:element(2, State), erlang:element(3, State)) of - {ok, <<"\n"/utf8>>} -> - {{some, <<"\n"/utf8>>}, - erlang:setelement( - 5, - erlang:setelement( - 6, - erlang:setelement( - 3, - State, - erlang:element(3, State) + 1 - ), - 1 - ), - erlang:element(5, State) + 1 - )}; - - {ok, G} -> - {{some, G}, - erlang:setelement( - 6, - erlang:setelement(3, State, erlang:element(3, State) + 1), - erlang:element(6, State) + 1 - )}; - - {error, _} -> - {none, State} - end. - --spec map2(parser(EXU, EXV), parser(EXY, EXV), fun((EXU, EXY) -> EYB)) -> parser(EYB, EXV). -map2(Parse_a, Parse_b, F) -> - then(Parse_a, fun(A) -> map(Parse_b, fun(B) -> F(A, B) end) end). - --spec replace(parser(any(), EYF), EYI) -> parser(EYI, EYF). -replace(Parser, B) -> - map(Parser, fun(_) -> B end). - --spec keep(parser(fun((EYL) -> EYM), EYN), parser(EYL, EYN)) -> parser(EYM, EYN). -keep(Parse_f, Parse_a) -> - map2(Parse_f, Parse_a, fun(F, A) -> F(A) end). - --spec drop(parser(EYU, EYV), parser(any(), EYV)) -> parser(EYU, EYV). -drop(Parse_a, Parse_x) -> - map2(Parse_a, Parse_x, fun(A, _) -> A end). - --spec bag_from_state(state(FCC), error()) -> bag(FCC). -bag_from_state(State, Problem) -> - {cons, - empty, - {dead_end, - erlang:element(5, State), - erlang:element(6, State), - Problem, - erlang:element(4, State)}}. - --spec fail(binary()) -> parser(any(), any()). -fail(Message) -> - {parser, - fun(State) -> - {fail, backtrack, bag_from_state(State, {custom, Message})} - end}. - --spec eof() -> parser(nil, any()). -eof() -> - {parser, fun(State) -> case next(State) of - {{some, Str}, _} -> - {fail, backtrack, bag_from_state(State, {unexpected, Str})}; - - {none, _} -> - {cont, backtrack, nil, State} - end end}. - --spec take_if(fun((binary()) -> boolean()), binary()) -> parser(binary(), any()). -take_if(Predicate, Expecting) -> - {parser, - fun(State) -> - {Str, Next_state} = next(State), - Should_take = begin - _pipe = Str, - _pipe@1 = gleam@option:map(_pipe, Predicate), - gleam@option:unwrap(_pipe@1, false) - end, - Str@1 = gleam@option:unwrap(Str, <<""/utf8>>), - case Should_take of - true -> - {cont, commit, Str@1, Next_state}; - - false -> - {fail, - backtrack, - bag_from_state(State, {expected, Expecting, Str@1})} - end - end}. - --spec any() -> parser(binary(), any()). -any() -> - take_if(gleam@function:constant(true), <<"a single grapheme"/utf8>>). - --spec grapheme(binary()) -> parser(nil, any()). -grapheme(Str) -> - _pipe = take_if(fun(G) -> G =:= Str end, Str), - map(_pipe, gleam@function:constant(nil)). - --spec add_bag_to_step(step(FCL, FCM), bag(FCM)) -> step(FCL, FCM). -add_bag_to_step(Step, Left) -> - case Step of - {cont, Can_backtrack, A, State} -> - {cont, Can_backtrack, A, State}; - - {fail, Can_backtrack@1, Right} -> - {fail, Can_backtrack@1, {append, Left, Right}} - end. - --spec one_of(list(parser(FAB, FAC))) -> parser(FAB, FAC). -one_of(Parsers) -> - {parser, - fun(State) -> - Init = {fail, backtrack, empty}, - gleam@list:fold_until( - Parsers, - Init, - fun(Result, Next) -> case Result of - {cont, _, _, _} -> - {stop, Result}; - - {fail, commit, _} -> - {stop, Result}; - - {fail, _, Bag} -> - _pipe = runwrap(State, Next), - _pipe@1 = add_bag_to_step(_pipe, Bag), - {continue, _pipe@1} - end end - ) - end}. - --spec push_context(state(FCY), FCY) -> state(FCY). -push_context(State, Context) -> - Located = {located, - erlang:element(5, State), - erlang:element(6, State), - Context}, - erlang:setelement(4, State, [Located | erlang:element(4, State)]). - --spec pop_context(state(FDB)) -> state(FDB). -pop_context(State) -> - case erlang:element(4, State) of - [] -> - State; - - [_ | Context] -> - erlang:setelement(4, State, Context) - end. - --spec in(parser(FCS, FCT), FCT) -> parser(FCS, FCT). -in(Parser, Context) -> - {parser, fun(State) -> case runwrap(push_context(State, Context), Parser) of - {cont, Can_backtrack, A, State@1} -> - {cont, Can_backtrack, A, pop_context(State@1)}; - - {fail, Can_backtrack@1, Bag} -> - {fail, Can_backtrack@1, Bag} - end end}. - --spec inspect(parser(FDE, FDF), binary()) -> parser(FDE, FDF). -inspect(Parser, Message) -> - {parser, - fun(State) -> - gleam@io:print(Message), - gleam@io:println(<<": "/utf8>>), - _pipe = runwrap(State, Parser), - gleam@io:debug(_pipe) - end}. - --spec string(binary()) -> parser(nil, any()). -string(Str) -> - Graphemes = gleam@string:to_graphemes(Str), - {parser, fun(State) -> case Graphemes of - [] -> - {fail, - backtrack, - bag_from_state( - State, - {bad_parser, <<"empty string"/utf8>>} - )}; - - [Head | Tail] -> - Parse_each = gleam@list:fold( - Tail, - grapheme(Head), - fun(Parse, Next) -> _pipe = Parse, - drop(_pipe, grapheme(Next)) end - ), - case runwrap(State, Parse_each) of - {cont, _, _, State@1} -> - {cont, commit, nil, State@1}; - - {fail, _, Bag} -> - {fail, backtrack, Bag} - end - end end}. - --spec to_deadends(bag(FCF), list(dead_end(FCF))) -> list(dead_end(FCF)). -to_deadends(Bag, Acc) -> - case Bag of - empty -> - Acc; - - {cons, empty, Deadend} -> - [Deadend | Acc]; - - {cons, Bag@1, Deadend@1} -> - to_deadends(Bag@1, [Deadend@1 | Acc]); - - {append, Left, Right} -> - to_deadends(Left, to_deadends(Right, Acc)) - end. - --spec run(binary(), parser(EVN, EVO)) -> {ok, EVN} | - {error, list(dead_end(EVO))}. -run(Src, Parser) -> - Graphemes = begin - _pipe = gleam@string:to_graphemes(Src), - _pipe@1 = gleam@list:index_map( - _pipe, - fun(I, Grapheme) -> {I, Grapheme} end - ), - gleam@map:from_list(_pipe@1) - end, - Init = {state, Graphemes, 0, [], 1, 1}, - case runwrap(Init, Parser) of - {cont, _, A, _} -> - {ok, A}; - - {fail, _, Bag} -> - {error, to_deadends(Bag, [])} - end. - --spec int() -> parser(integer(), any()). -int() -> - _pipe = take_if_and_while( - fun nibble@predicates:is_digit/1, - <<"a digit"/utf8>> - ), - map( - _pipe, - fun(Digits) -> - _assert_subject = gleam@int:parse(Digits), - {ok, Int} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"nibble"/utf8>>, - function => <<"int"/utf8>>, - line => 254}) - end, - Int - end - ). - --spec float() -> parser(float(), any()). -float() -> - Make_float_string = gleam@function:curry2( - fun(X, Y) -> gleam@string:concat([X, <<"."/utf8>>, Y]) end - ), - _pipe = succeed(Make_float_string), - _pipe@1 = keep( - _pipe, - take_if_and_while(fun nibble@predicates:is_digit/1, <<"a digit"/utf8>>) - ), - _pipe@2 = drop(_pipe@1, grapheme(<<"."/utf8>>)), - _pipe@3 = keep( - _pipe@2, - take_if_and_while(fun nibble@predicates:is_digit/1, <<"a digit"/utf8>>) - ), - map( - _pipe@3, - fun(Digits) -> - _assert_subject = gleam@float:parse(Digits), - {ok, Float} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"nibble"/utf8>>, - function => <<"float"/utf8>>, - line => 271}) - end, - Float - end - ). - --spec take_while(fun((binary()) -> boolean())) -> parser(binary(), any()). -take_while(Predicate) -> - {parser, - fun(State) -> - {Str, Next_state} = next(State), - Should_take = begin - _pipe = Str, - _pipe@1 = gleam@option:map(_pipe, Predicate), - gleam@option:unwrap(_pipe@1, false) - end, - Str@1 = gleam@option:unwrap(Str, <<""/utf8>>), - case Should_take of - true -> - runwrap( - Next_state, - map( - take_while(Predicate), - fun(_capture) -> - gleam@string:append(Str@1, _capture) - end - ) - ); - - false -> - {cont, backtrack, <<""/utf8>>, State} - end - end}. - --spec spaces() -> parser(nil, any()). -spaces() -> - _pipe = take_while(fun(G) -> G =:= <<" "/utf8>> end), - map(_pipe, gleam@function:constant(nil)). - --spec whitespace() -> parser(nil, any()). -whitespace() -> - _pipe = take_while(fun nibble@predicates:is_whitespace/1), - map(_pipe, gleam@function:constant(nil)). - --spec take_if_and_while(fun((binary()) -> boolean()), binary()) -> parser(binary(), any()). -take_if_and_while(Predicate, Expecting) -> - map2( - take_if(Predicate, Expecting), - take_while(Predicate), - fun gleam@string:append/2 - ). - --spec take_until(fun((binary()) -> boolean())) -> parser(binary(), any()). -take_until(Predicate) -> - take_while(gleam@function:compose(Predicate, fun gleam@bool:negate/1)). - --spec loop_help( - fun((FBC) -> parser(loop(FBD, FBC), FBG)), - backtrackable(), - FBC, - state(FBG) -) -> step(FBD, FBG). -loop_help(F, Commit, Loop_state, State) -> - case runwrap(State, F(Loop_state)) of - {cont, Can_backtrack, {continue, Next_loop_state}, Next_state} -> - loop_help( - F, - should_commit(Commit, Can_backtrack), - Next_loop_state, - Next_state - ); - - {cont, Can_backtrack@1, {break, Result}, Next_state@1} -> - {cont, should_commit(Commit, Can_backtrack@1), Result, Next_state@1}; - - {fail, Can_backtrack@2, Bag} -> - {fail, should_commit(Commit, Can_backtrack@2), Bag} - end. - --spec loop(FBC, fun((FBC) -> parser(loop(FBD, FBC), FBG))) -> parser(FBD, FBG). -loop(Init, Step) -> - {parser, fun(State) -> loop_help(Step, backtrack, Init, State) end}. - --spec more(FAS, parser(FAS, FAT), parser(any(), FAT)) -> parser(list(FAS), FAT). -more(X, Parser, Separator) -> - loop( - [X], - fun(Xs) -> - one_of( - [begin - _pipe = succeed( - fun(_capture) -> - gleam@list:prepend(Xs, _capture) - end - ), - _pipe@1 = drop(_pipe, Separator), - _pipe@2 = keep(_pipe@1, Parser), - map(_pipe@2, fun(Field@0) -> {continue, Field@0} end) - end, - begin - _pipe@3 = succeed(Xs), - _pipe@4 = drop(_pipe@3, eof()), - _pipe@5 = map(_pipe@4, fun gleam@list:reverse/1), - map(_pipe@5, fun(Field@0) -> {break, Field@0} end) - end, - begin - _pipe@6 = succeed(Xs), - _pipe@7 = map(_pipe@6, fun gleam@list:reverse/1), - map(_pipe@7, fun(Field@0) -> {break, Field@0} end) - end] - ) - end - ). - --spec many(parser(FAI, FAJ), parser(any(), FAJ)) -> parser(list(FAI), FAJ). -many(Parser, Separator) -> - one_of( - [begin - _pipe = Parser, - then( - _pipe, - fun(_capture) -> more(_capture, Parser, Separator) end - ) - end, - succeed([])] - ). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam deleted file mode 100644 index 3292d85d810..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble.gleam +++ /dev/null @@ -1,519 +0,0 @@ -//// - -// IMPORTS --------------------------------------------------------------------- - -import gleam/bool -import gleam/float -import gleam/function -import gleam/int -import gleam/io -import gleam/list -import gleam/map.{Map} -import gleam/option.{Option} -import gleam/string -import nibble/predicates - -// TYPES ----------------------------------------------------------------------- - -/// -pub opaque type Parser(a, ctx) { - Parser(fn(State(ctx)) -> Step(a, ctx)) -} - -type State(ctx) { - State( - // The Gleam stdlib doesn't seem to have an `Array` type, so we'll just - // use a `Map` instead. We only need something for indexed access, to it's - // not a huge deal. - // - // TODO: Louis says making an `Array` backed by tuples in Erlang will - // be way better for performance. In JavaScript we could just use normal - // arrays - someone should look into this. - src: Map(Int, String), - offset: Int, - context: List(Located(ctx)), - row: Int, - col: Int, - ) -} - -type Step(a, ctx) { - Cont(Backtrackable, a, State(ctx)) - Fail(Backtrackable, Bag(ctx)) -} - -/// -pub type Located(ctx) { - Located(row: Int, col: Int, context: ctx) -} - -type Backtrackable { - Commit - Backtrack -} - -// RUNNING PARSERS ------------------------------------------------------------- - -/// -pub fn run(src: String, parser: Parser(a, ctx)) -> Result(a, List(DeadEnd(ctx))) { - let graphemes = - string.to_graphemes(src) - |> list.index_map(fn(i, grapheme) { #(i, grapheme) }) - |> map.from_list - - let init = State(graphemes, 0, [], 1, 1) - - case runwrap(init, parser) { - Cont(_, a, _) -> Ok(a) - - Fail(_, bag) -> Error(to_deadends(bag, [])) - } -} - -fn runwrap(state: State(ctx), parser: Parser(a, ctx)) -> Step(a, ctx) { - let Parser(parse) = parser - parse(state) -} - -fn next(state: State(ctx)) -> #(Option(String), State(ctx)) { - case map.get(state.src, state.offset) { - Ok("\n") -> #( - option.Some("\n"), - State(..state, offset: state.offset + 1, col: 1, row: state.row + 1), - ) - - Ok(g) -> #( - option.Some(g), - State(..state, offset: state.offset + 1, col: state.col + 1), - ) - - Error(_) -> #(option.None, state) - } -} - -// CONSTRUCTORS ---------------------------------------------------------------- - -/// -pub fn succeed(a: a) -> Parser(a, ctx) { - Parser(fn(state) { Cont(Backtrack, a, state) }) -} - -/// -pub fn fail(message: String) -> Parser(a, ctx) { - Parser(fn(state) { Fail(Backtrack, bag_from_state(state, Custom(message))) }) -} - -/// -pub fn lazy(parser: fn() -> Parser(a, ctx)) -> Parser(a, ctx) { - Parser(fn(state) { runwrap(state, parser()) }) -} - -// BACKTRACKING ---------------------------------------------------------------- - -/// -pub fn backtrackable(parser: Parser(a, ctx)) -> Parser(a, ctx) { - Parser(fn(state) { - case runwrap(state, parser) { - Cont(_, a, state) -> Cont(Backtrack, a, state) - - Fail(_, bag) -> Fail(Backtrack, bag) - } - }) -} - -/// -pub fn commit(to a: a) -> Parser(a, ctx) { - Parser(fn(state) { Cont(Commit, a, state) }) -} - -fn should_commit(to_x: Backtrackable, or to_y: Backtrackable) -> Backtrackable { - case to_x, to_y { - Commit, _ -> Commit - - _, Commit -> Commit - - _, _ -> Backtrack - } -} - -// MANIPULATING PARSERS -------------------------------------------------------- - -/// -pub fn then( - parser: Parser(a, ctx), - f: fn(a) -> Parser(b, ctx), -) -> Parser(b, ctx) { - Parser(fn(state) { - case runwrap(state, parser) { - Cont(to_a, a, state) -> - case runwrap(state, f(a)) { - Cont(to_b, b, state) -> Cont(should_commit(to_a, or: to_b), b, state) - Fail(to_b, bag) -> Fail(should_commit(to_a, or: to_b), bag) - } - - Fail(can_backtrack, bag) -> Fail(can_backtrack, bag) - } - }) -} - -/// -pub fn map(parser: Parser(a, ctx), f: fn(a) -> b) -> Parser(b, ctx) { - then(parser, fn(a) { succeed(f(a)) }) -} - -fn map2( - parse_a: Parser(a, ctx), - parse_b: Parser(b, ctx), - f: fn(a, b) -> c, -) -> Parser(c, ctx) { - then(parse_a, fn(a) { map(parse_b, fn(b) { f(a, b) }) }) -} - -/// -pub fn replace(parser: Parser(a, ctx), with b: b) -> Parser(b, ctx) { - map(parser, fn(_) { b }) -} - -// PIPE-FRIENDLY HELPERS ------------------------------------------------------- - -/// -pub fn keep( - parse_f: Parser(fn(a) -> b, ctx), - parse_a: Parser(a, ctx), -) -> Parser(b, ctx) { - map2(parse_f, parse_a, fn(f, a) { f(a) }) -} - -/// -pub fn drop(parse_a: Parser(a, ctx), parse_x: Parser(x, ctx)) -> Parser(a, ctx) { - map2(parse_a, parse_x, fn(a, _) { a }) -} - -// SIMPLE PARSERS -------------------------------------------------------------- - -/// -pub fn any() -> Parser(String, ctx) { - take_if(function.constant(True), "a single grapheme") -} - -/// -pub fn eof() -> Parser(Nil, ctx) { - Parser(fn(state) { - case next(state) { - #(option.Some(str), _) -> - Fail(Backtrack, bag_from_state(state, Unexpected(str))) - - #(option.None, _) -> Cont(Backtrack, Nil, state) - } - }) -} - -// GRAPHEMES AND STRINGS ------------------------------------------------------- - -/// -pub fn grapheme(str: String) -> Parser(Nil, ctx) { - take_if(fn(g) { g == str }, str) - |> map(function.constant(Nil)) -} - -/// -pub fn string(str: String) -> Parser(Nil, ctx) { - let graphemes = string.to_graphemes(str) - - Parser(fn(state) { - case graphemes { - [] -> Fail(Backtrack, bag_from_state(state, BadParser("empty string"))) - - [head, ..tail] -> { - let parse_each = - list.fold( - tail, - grapheme(head), - fn(parse, next) { - parse - |> drop(grapheme(next)) - }, - ) - case runwrap(state, parse_each) { - Cont(_, _, state) -> Cont(Commit, Nil, state) - Fail(_, bag) -> Fail(Backtrack, bag) - } - } - } - }) -} - -// NUMBERS --------------------------------------------------------------------- - -/// -pub fn int() -> Parser(Int, ctx) { - take_if_and_while(predicates.is_digit, "a digit") - // We can make the following assertion because we know our parser will - // only consume digits, and is guaranteed to have at least one. - |> map(fn(digits) { - let assert Ok(int) = int.parse(digits) - int - }) -} - -/// -pub fn float() -> Parser(Float, ctx) { - let make_float_string = - function.curry2(fn(x, y) { string.concat([x, ".", y]) }) - - succeed(make_float_string) - |> keep(take_if_and_while(predicates.is_digit, "a digit")) - |> drop(grapheme(".")) - |> keep(take_if_and_while(predicates.is_digit, "a digit")) - // We can make the following assertion because we know our parser will - // only consume digits, and is guaranteed to have at least one. - |> map(fn(digits) { - let assert Ok(float) = float.parse(digits) - float - }) -} - -// WHITESPACE ------------------------------------------------------------------ - -/// -pub fn spaces() -> Parser(Nil, ctx) { - take_while(fn(g) { g == " " }) - |> map(function.constant(Nil)) -} - -/// -pub fn whitespace() -> Parser(Nil, ctx) { - take_while(predicates.is_whitespace) - |> map(function.constant(Nil)) -} - -// BRANCHING AND LOOPING ------------------------------------------------------- - -/// -pub fn one_of(parsers: List(Parser(a, ctx))) -> Parser(a, ctx) { - Parser(fn(state) { - let init = Fail(Backtrack, Empty) - - list.fold_until( - parsers, - init, - fn(result, next) { - case result { - Cont(_, _, _) -> list.Stop(result) - - Fail(Commit, _) -> list.Stop(result) - - Fail(_, bag) -> - runwrap(state, next) - |> add_bag_to_step(bag) - |> list.Continue - } - }, - ) - }) -} - -/// -pub fn many( - parser: Parser(a, ctx), - separator: Parser(x, ctx), -) -> Parser(List(a), ctx) { - one_of([ - parser - |> then(more(_, parser, separator)), - succeed([]), - ]) -} - -fn more( - x: a, - parser: Parser(a, ctx), - separator: Parser(x, ctx), -) -> Parser(List(a), ctx) { - loop( - [x], - fn(xs) { - one_of([ - succeed(list.prepend(xs, _)) - |> drop(separator) - |> keep(parser) - |> map(Continue), - succeed(xs) - |> drop(eof()) - |> map(list.reverse) - |> map(Break), - succeed(xs) - |> map(list.reverse) - |> map(Break), - ]) - }, - ) -} - -pub type Loop(a, state) { - Continue(state) - Break(a) -} - -pub fn loop( - init: state, - step: fn(state) -> Parser(Loop(a, state), ctx), -) -> Parser(a, ctx) { - Parser(fn(state) { loop_help(step, Backtrack, init, state) }) -} - -fn loop_help(f, commit, loop_state, state) { - case runwrap(state, f(loop_state)) { - Cont(can_backtrack, Continue(next_loop_state), next_state) -> - loop_help( - f, - should_commit(commit, can_backtrack), - next_loop_state, - next_state, - ) - - Cont(can_backtrack, Break(result), next_state) -> - Cont(should_commit(commit, can_backtrack), result, next_state) - - Fail(can_backtrack, bag) -> Fail(should_commit(commit, can_backtrack), bag) - } -} - -// PREDICATES ------------------------------------------------------------------ - -/// -pub fn take_if( - predicate: fn(String) -> Bool, - expecting: String, -) -> Parser(String, ctx) { - Parser(fn(state) { - let #(str, next_state) = next(state) - let should_take = - str - |> option.map(predicate) - |> option.unwrap(False) - let str = option.unwrap(str, "") - - case should_take { - True -> Cont(Commit, str, next_state) - - False -> - Fail(Backtrack, bag_from_state(state, Expected(expecting, got: str))) - } - }) -} - -/// -pub fn take_while(predicate: fn(String) -> Bool) -> Parser(String, ctx) { - Parser(fn(state) { - let #(str, next_state) = next(state) - let should_take = - str - |> option.map(predicate) - |> option.unwrap(False) - let str = option.unwrap(str, "") - - case should_take { - True -> - runwrap(next_state, map(take_while(predicate), string.append(str, _))) - - False -> Cont(Backtrack, "", state) - } - }) -} - -/// -pub fn take_if_and_while( - predicate: fn(String) -> Bool, - expecting: String, -) -> Parser(String, ctx) { - map2(take_if(predicate, expecting), take_while(predicate), string.append) -} - -/// -pub fn take_until(predicate: fn(String) -> Bool) -> Parser(String, ctx) { - take_while(function.compose(predicate, bool.negate)) -} - -// ERRORS ---------------------------------------------------------------------- - -pub type Error { - BadParser(String) - Custom(String) - EndOfInput - Expected(String, got: String) - Unexpected(String) -} - -/// -pub type DeadEnd(ctx) { - DeadEnd(row: Int, col: Int, problem: Error, context: List(Located(ctx))) -} - -type Bag(ctx) { - Empty - Cons(Bag(ctx), DeadEnd(ctx)) - Append(Bag(ctx), Bag(ctx)) -} - -fn bag_from_state(state: State(ctx), problem: Error) -> Bag(ctx) { - Cons(Empty, DeadEnd(state.row, state.col, problem, state.context)) -} - -fn to_deadends(bag: Bag(ctx), acc: List(DeadEnd(ctx))) -> List(DeadEnd(ctx)) { - case bag { - Empty -> acc - - Cons(Empty, deadend) -> [deadend, ..acc] - - Cons(bag, deadend) -> to_deadends(bag, [deadend, ..acc]) - - Append(left, right) -> to_deadends(left, to_deadends(right, acc)) - } -} - -fn add_bag_to_step(step: Step(a, ctx), left: Bag(ctx)) -> Step(a, ctx) { - case step { - Cont(can_backtrack, a, state) -> Cont(can_backtrack, a, state) - - Fail(can_backtrack, right) -> Fail(can_backtrack, Append(left, right)) - } -} - -// CONTEXT --------------------------------------------------------------------- - -/// -pub fn in(parser: Parser(a, ctx), context: ctx) -> Parser(a, ctx) { - Parser(fn(state) { - case runwrap(push_context(state, context), parser) { - Cont(can_backtrack, a, state) -> - Cont(can_backtrack, a, pop_context(state)) - - Fail(can_backtrack, bag) -> Fail(can_backtrack, bag) - } - }) -} - -fn push_context(state: State(ctx), context: ctx) -> State(ctx) { - let located = Located(state.row, state.col, context) - State(..state, context: [located, ..state.context]) -} - -fn pop_context(state: State(ctx)) -> State(ctx) { - case state.context { - [] -> state - - [_, ..context] -> State(..state, context: context) - } -} - -/// Run the given parser and then inspect it's state. -pub fn inspect(parser: Parser(a, ctx), message: String) -> Parser(a, ctx) { - Parser(fn(state) { - io.print(message) - io.println(": ") - - runwrap(state, parser) - |> io.debug - }) -} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam deleted file mode 100644 index 968e75b128b..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble/pratt.gleam +++ /dev/null @@ -1,113 +0,0 @@ -// IMPORTS --------------------------------------------------------------------- - -import gleam/list -import gleam/function -import nibble.{ Parser } - -// TYPES ----------------------------------------------------------------------- - -pub opaque type Config(a, ctx) { - Config( - one_of: List(fn (Config(a, ctx)) -> Parser(a, ctx)), - and_then_one_of: List(Operator(a, ctx)), - spaces: Parser(Nil, ctx) - ) -} - -pub opaque type Operator(a, ctx) { - Operator( - fn(Config(a, ctx)) -> #(Int, fn (a) -> Parser(a, ctx)) - ) -} - -// - -pub fn expression( - one_of first: List(fn (Config(a, ctx)) -> Parser(a, ctx)), - and_then_one_of then: List(Operator(a, ctx)), - dropping spaces: Parser(Nil, ctx) -) -> Parser(a, ctx) { - let config = Config(first, then, spaces) - sub_expression(config, 0) -} - -pub fn sub_expression (config: Config(a, ctx), precedence: Int) -> Parser(a, ctx) { - let expr = nibble.lazy(fn () { - config.one_of - |> list.map(fn (p) { p(config) }) - |> nibble.one_of - }) - - let go = fn (expr) { - nibble.succeed(function.identity) - |> nibble.drop(config.spaces) - |> nibble.keep( - nibble.one_of([ - nibble.succeed(expr) - |> nibble.then(operation(_, config, precedence)) - |> nibble.map(nibble.Continue), - nibble.succeed(expr) - |> nibble.map(nibble.Break) - ]) - ) - } - - nibble.succeed(function.identity) - |> nibble.drop(config.spaces) - |> nibble.keep(expr) - |> nibble.then(nibble.loop(_, go)) -} - -fn operation (expr: a, config: Config(a, ctx), current_precedence: Int) -> Parser(a, ctx) { - config.and_then_one_of - |> list.filter_map(fn (operator) { - let Operator(op) = operator - case op(config) { - #(precedence, parser) if precedence > current_precedence -> - Ok(parser(expr)) - - _ -> - Error(Nil) - } - - }) - |> nibble.one_of() -} - -// - -pub fn prefix (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a) -> a) -> fn (Config(a, ctx)) -> Parser(a, ctx) { - fn (config) { - nibble.succeed(apply) - |> nibble.drop(operator) - |> nibble.keep(sub_expression(config, precedence)) - } -} - -pub fn infix_left (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { - make_infix(#(precedence, precedence), operator, apply) -} - -pub fn infix_right (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { - make_infix(#(precedence, precedence - 1), operator, apply) -} - -pub fn postfix (precedence: Int, operator: Parser(Nil, ctx), apply: fn (a) -> a) -> Operator(a, ctx) { - Operator(fn (_) { - #(precedence, fn (lhs) { - nibble.succeed(apply(lhs)) - |> nibble.drop(operator) - }) - }) -} - -fn make_infix(precedence: #(Int, Int), operator: Parser(Nil, ctx), apply: fn (a, a) -> a) -> Operator(a, ctx) { - let #(left_precedence, right_precedence) = precedence - Operator(fn (config) { - #(left_precedence, fn (lhs) { - nibble.succeed(apply(lhs, _)) - |> nibble.drop(operator) - |> nibble.keep(sub_expression(config, right_precedence)) - }) - }) -} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam b/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam deleted file mode 100644 index 756ccbd3ba7..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble/predicates.gleam +++ /dev/null @@ -1,59 +0,0 @@ -/// -pub fn is_digit (grapheme: String) -> Bool { - case grapheme { - "0" | "1" | "2" | "3" | "4" | - "5" | "6" | "7" | "8" | "9" -> - True - - _ -> - False - } -} - -/// -pub fn is_whitespace (grapheme: String) -> Bool { - case grapheme { - " " | "\t" | "\n" | "\r" -> - True - - _ -> - False - } -} - -/// -pub fn is_upper (grapheme: String) -> Bool { - case grapheme { - "A" | "B" | "C" | "D" | "E" | - "F" | "G" | "H" | "I" | "J" | - "K" | "L" | "M" | "N" | "O" | - "P" | "Q" | "R" | "S" | "T" | - "U" | "V" | "W" | "X" | "Y" | - "Z" -> - True - - _ -> - False - } -} - -/// -pub fn is_lower (grapheme: String) -> Bool { - case grapheme { - "a" | "b" | "c" | "d" | "e" | - "f" | "g" | "h" | "i" | "j" | - "k" | "l" | "m" | "n" | "o" | - "p" | "q" | "r" | "s" | "t" | - "u" | "v" | "w" | "x" | "y" | - "z" -> - True - - _ -> - False - } -} - -/// -pub fn is_alphanum (grapheme: String) -> Bool { - is_digit(grapheme) || is_upper(grapheme) || is_lower(grapheme) -} diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl deleted file mode 100644 index 36a1260fc3b..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble@pratt.erl +++ /dev/null @@ -1,120 +0,0 @@ --module(nibble@pratt). --compile([no_auto_import, nowarn_unused_vars]). - --export([sub_expression/2, expression/3, prefix/3, postfix/3, infix_left/3, infix_right/3]). --export_type([config/2, operator/2]). - --opaque config(FVQ, FVR) :: {config, - list(fun((config(FVQ, FVR)) -> nibble:parser(FVQ, FVR))), - list(operator(FVQ, FVR)), - nibble:parser(nil, FVR)}. - --opaque operator(FVS, FVT) :: {operator, - fun((config(FVS, FVT)) -> {integer(), - fun((FVS) -> nibble:parser(FVS, FVT))})}. - --spec operation(FWO, config(FWO, FWP), integer()) -> nibble:parser(FWO, FWP). -operation(Expr, Config, Current_precedence) -> - _pipe = erlang:element(3, Config), - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Operator) -> - {operator, Op} = Operator, - case Op(Config) of - {Precedence, Parser} when Precedence > Current_precedence -> - {ok, Parser(Expr)}; - - _ -> - {error, nil} - end - end - ), - nibble:one_of(_pipe@1). - --spec sub_expression(config(FWI, FWJ), integer()) -> nibble:parser(FWI, FWJ). -sub_expression(Config, Precedence) -> - Expr = nibble:lazy(fun() -> _pipe = erlang:element(2, Config), - _pipe@1 = gleam@list:map(_pipe, fun(P) -> P(Config) end), - nibble:one_of(_pipe@1) end), - Go = fun(Expr@1) -> _pipe@2 = nibble:succeed(fun gleam@function:identity/1), - _pipe@3 = nibble:drop(_pipe@2, erlang:element(4, Config)), - nibble:keep( - _pipe@3, - nibble:one_of( - [begin - _pipe@4 = nibble:succeed(Expr@1), - _pipe@5 = nibble:then( - _pipe@4, - fun(_capture) -> - operation(_capture, Config, Precedence) - end - ), - nibble:map( - _pipe@5, - fun(Field@0) -> {continue, Field@0} end - ) - end, - begin - _pipe@6 = nibble:succeed(Expr@1), - nibble:map( - _pipe@6, - fun(Field@0) -> {break, Field@0} end - ) - end] - ) - ) end, - _pipe@7 = nibble:succeed(fun gleam@function:identity/1), - _pipe@8 = nibble:drop(_pipe@7, erlang:element(4, Config)), - _pipe@9 = nibble:keep(_pipe@8, Expr), - nibble:then(_pipe@9, fun(_capture@1) -> nibble:loop(_capture@1, Go) end). - --spec expression( - list(fun((config(FVU, FVV)) -> nibble:parser(FVU, FVV))), - list(operator(FVU, FVV)), - nibble:parser(nil, FVV) -) -> nibble:parser(FVU, FVV). -expression(First, Then, Spaces) -> - Config = {config, First, Then, Spaces}, - sub_expression(Config, 0). - --spec prefix(integer(), nibble:parser(nil, FWU), fun((FWX) -> FWX)) -> fun((config(FWX, FWU)) -> nibble:parser(FWX, FWU)). -prefix(Precedence, Operator, Apply) -> - fun(Config) -> _pipe = nibble:succeed(Apply), - _pipe@1 = nibble:drop(_pipe, Operator), - nibble:keep(_pipe@1, sub_expression(Config, Precedence)) end. - --spec postfix(integer(), nibble:parser(nil, FXO), fun((FXR) -> FXR)) -> operator(FXR, FXO). -postfix(Precedence, Operator, Apply) -> - {operator, - fun(_) -> {Precedence, fun(Lhs) -> _pipe = nibble:succeed(Apply(Lhs)), - nibble:drop(_pipe, Operator) end} end}. - --spec make_infix( - {integer(), integer()}, - nibble:parser(nil, FXU), - fun((FXX, FXX) -> FXX) -) -> operator(FXX, FXU). -make_infix(Precedence, Operator, Apply) -> - {Left_precedence, Right_precedence} = Precedence, - {operator, - fun(Config) -> - {Left_precedence, - fun(Lhs) -> - _pipe = nibble:succeed( - fun(_capture) -> Apply(Lhs, _capture) end - ), - _pipe@1 = nibble:drop(_pipe, Operator), - nibble:keep( - _pipe@1, - sub_expression(Config, Right_precedence) - ) - end} - end}. - --spec infix_left(integer(), nibble:parser(nil, FXC), fun((FXF, FXF) -> FXF)) -> operator(FXF, FXC). -infix_left(Precedence, Operator, Apply) -> - make_infix({Precedence, Precedence}, Operator, Apply). - --spec infix_right(integer(), nibble:parser(nil, FXI), fun((FXL, FXL) -> FXL)) -> operator(FXL, FXI). -infix_right(Precedence, Operator, Apply) -> - make_infix({Precedence, Precedence - 1}, Operator, Apply). diff --git a/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl b/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl deleted file mode 100644 index 153d6223e49..00000000000 --- a/test-community-packages-javascript/build/packages/nibble/src/nibble@predicates.erl +++ /dev/null @@ -1,234 +0,0 @@ --module(nibble@predicates). --compile([no_auto_import, nowarn_unused_vars]). - --export([is_digit/1, is_whitespace/1, is_upper/1, is_lower/1, is_alphanum/1]). - --spec is_digit(binary()) -> boolean(). -is_digit(Grapheme) -> - case Grapheme of - <<"0"/utf8>> -> - true; - - <<"1"/utf8>> -> - true; - - <<"2"/utf8>> -> - true; - - <<"3"/utf8>> -> - true; - - <<"4"/utf8>> -> - true; - - <<"5"/utf8>> -> - true; - - <<"6"/utf8>> -> - true; - - <<"7"/utf8>> -> - true; - - <<"8"/utf8>> -> - true; - - <<"9"/utf8>> -> - true; - - _ -> - false - end. - --spec is_whitespace(binary()) -> boolean(). -is_whitespace(Grapheme) -> - case Grapheme of - <<" "/utf8>> -> - true; - - <<"\t"/utf8>> -> - true; - - <<"\n"/utf8>> -> - true; - - <<"\r"/utf8>> -> - true; - - _ -> - false - end. - --spec is_upper(binary()) -> boolean(). -is_upper(Grapheme) -> - case Grapheme of - <<"A"/utf8>> -> - true; - - <<"B"/utf8>> -> - true; - - <<"C"/utf8>> -> - true; - - <<"D"/utf8>> -> - true; - - <<"E"/utf8>> -> - true; - - <<"F"/utf8>> -> - true; - - <<"G"/utf8>> -> - true; - - <<"H"/utf8>> -> - true; - - <<"I"/utf8>> -> - true; - - <<"J"/utf8>> -> - true; - - <<"K"/utf8>> -> - true; - - <<"L"/utf8>> -> - true; - - <<"M"/utf8>> -> - true; - - <<"N"/utf8>> -> - true; - - <<"O"/utf8>> -> - true; - - <<"P"/utf8>> -> - true; - - <<"Q"/utf8>> -> - true; - - <<"R"/utf8>> -> - true; - - <<"S"/utf8>> -> - true; - - <<"T"/utf8>> -> - true; - - <<"U"/utf8>> -> - true; - - <<"V"/utf8>> -> - true; - - <<"W"/utf8>> -> - true; - - <<"X"/utf8>> -> - true; - - <<"Y"/utf8>> -> - true; - - <<"Z"/utf8>> -> - true; - - _ -> - false - end. - --spec is_lower(binary()) -> boolean(). -is_lower(Grapheme) -> - case Grapheme of - <<"a"/utf8>> -> - true; - - <<"b"/utf8>> -> - true; - - <<"c"/utf8>> -> - true; - - <<"d"/utf8>> -> - true; - - <<"e"/utf8>> -> - true; - - <<"f"/utf8>> -> - true; - - <<"g"/utf8>> -> - true; - - <<"h"/utf8>> -> - true; - - <<"i"/utf8>> -> - true; - - <<"j"/utf8>> -> - true; - - <<"k"/utf8>> -> - true; - - <<"l"/utf8>> -> - true; - - <<"m"/utf8>> -> - true; - - <<"n"/utf8>> -> - true; - - <<"o"/utf8>> -> - true; - - <<"p"/utf8>> -> - true; - - <<"q"/utf8>> -> - true; - - <<"r"/utf8>> -> - true; - - <<"s"/utf8>> -> - true; - - <<"t"/utf8>> -> - true; - - <<"u"/utf8>> -> - true; - - <<"v"/utf8>> -> - true; - - <<"w"/utf8>> -> - true; - - <<"x"/utf8>> -> - true; - - <<"y"/utf8>> -> - true; - - <<"z"/utf8>> -> - true; - - _ -> - false - end. - --spec is_alphanum(binary()) -> boolean(). -is_alphanum(Grapheme) -> - (is_digit(Grapheme) orelse is_upper(Grapheme)) orelse is_lower(Grapheme). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/LICENSE b/test-community-packages-javascript/build/packages/non_empty_list/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/test-community-packages-javascript/build/packages/non_empty_list/README.md b/test-community-packages-javascript/build/packages/non_empty_list/README.md deleted file mode 100644 index 4502421a799..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# non_empty_list - -[![Package Version](https://img.shields.io/hexpm/v/non_empty_list)](https://hex.pm/packages/non_empty_list) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/non_empty_list/) -![CI](https://github.com/giacomocavalieri/non_empty_list/workflows/CI/badge.svg?branch=main) - -Non-empty lists in Gleam ✨ - -> ⚙️ This package supports both the Erlang and JavaScript target! - -## Installation - -To add this package to your Gleam project: - -```sh -gleam add non_empty_list -``` - -## Usage - -Import the `non_empty_list` module and write some code! - -```gleam -import non_empty_list -import gleam/int -import gleam/io - -pub fn main() { - non_empty_list.new(1, [2, 3, 4]) - |> non_empty_list.reduce(with: fn(n, m) { n + m }) - |> int.to_string - |> io.println -} -``` - -## Contributing - -This package exposes most of the same functions you'd find in the `gleam/list` module but it may be missing some useful functions. - -If you think there's a missing function that would fit here, or if you spot a bug don't be afraid to open PRs, issues or requests of any kind! Any contribution is welcome 💜 diff --git a/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml b/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml deleted file mode 100644 index 4ac8d3b865f..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "non_empty_list" -version = "1.0.0" -description = "Non-empty lists in Gleam" - -licences = ["Apache-2.0"] -repository = { type = "github", user = "giacomocavalieri", repo = "non_empty_list" } -links = [] - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -glacier = "~> 0.8" diff --git a/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl b/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl deleted file mode 100644 index d88aaf5f88b..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/include/non_empty_list_NonEmptyList.hrl +++ /dev/null @@ -1 +0,0 @@ --record(non_empty_list, {first :: any(), rest :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src deleted file mode 100644 index ec63d53e799..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, non_empty_list, [ - {vsn, "1.0.0"}, - {applications, [glacier, - gleam_stdlib]}, - {description, "Non-empty lists in Gleam"}, - {modules, [non_empty_list]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl deleted file mode 100644 index efb67411150..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.erl +++ /dev/null @@ -1,304 +0,0 @@ --module(non_empty_list). --compile([no_auto_import, nowarn_unused_vars]). - --export([first/1, last/1, new/2, append_list/2, from_list/1, intersperse/2, map/2, prepend/2, reduce/2, rest/1, single/1, to_list/1, append/2, drop/2, reverse/1, map_fold/3, scan/3, shuffle/1, sort/2, take/2, unique/1, unzip/1, zip/2, strict_zip/2, flatten/1, flat_map/2, index_map/2]). --export_type([non_empty_list/1, list_was_empty/0]). - --type non_empty_list(GJS) :: {non_empty_list, GJS, list(GJS)}. - --type list_was_empty() :: list_was_empty. - --spec first(non_empty_list(GKE)) -> GKE. -first(List) -> - erlang:element(2, List). - --spec last(non_empty_list(GLP)) -> GLP. -last(List) -> - _pipe = gleam@list:last(erlang:element(3, List)), - gleam@result:unwrap(_pipe, erlang:element(2, List)). - --spec new(GMA, list(GMA)) -> non_empty_list(GMA). -new(First, Rest) -> - {non_empty_list, First, Rest}. - --spec append_list(non_empty_list(GJX), list(GJX)) -> non_empty_list(GJX). -append_list(First, Second) -> - new( - erlang:element(2, First), - gleam@list:append(erlang:element(3, First), Second) - ). - --spec from_list(list(GKY)) -> {ok, non_empty_list(GKY)} | - {error, list_was_empty()}. -from_list(List) -> - case List of - [] -> - {error, list_was_empty}; - - [First | Rest] -> - {ok, new(First, Rest)} - end. - --spec intersperse(non_empty_list(GLM), GLM) -> non_empty_list(GLM). -intersperse(List, Elem) -> - new( - erlang:element(2, List), - [Elem | gleam@list:intersperse(erlang:element(3, List), Elem)] - ). - --spec map(non_empty_list(GLR), fun((GLR) -> GLT)) -> non_empty_list(GLT). -map(List, Fun) -> - new( - Fun(erlang:element(2, List)), - gleam@list:map(erlang:element(3, List), Fun) - ). - --spec prepend(non_empty_list(GMD), GMD) -> non_empty_list(GMD). -prepend(List, Item) -> - new(Item, [erlang:element(2, List) | erlang:element(3, List)]). - --spec reduce(non_empty_list(GMG), fun((GMG, GMG) -> GMG)) -> GMG. -reduce(List, Fun) -> - gleam@list:fold(erlang:element(3, List), erlang:element(2, List), Fun). - --spec rest(non_empty_list(GMI)) -> list(GMI). -rest(List) -> - erlang:element(3, List). - --spec single(GMV) -> non_empty_list(GMV). -single(First) -> - new(First, []). - --spec to_list(non_empty_list(GNK)) -> list(GNK). -to_list(Non_empty) -> - [erlang:element(2, Non_empty) | erlang:element(3, Non_empty)]. - --spec append(non_empty_list(GJT), non_empty_list(GJT)) -> non_empty_list(GJT). -append(First, Second) -> - new( - erlang:element(2, First), - gleam@list:append(erlang:element(3, First), to_list(Second)) - ). - --spec drop(non_empty_list(GKB), integer()) -> list(GKB). -drop(List, N) -> - _pipe = List, - _pipe@1 = to_list(_pipe), - gleam@list:drop(_pipe@1, N). - --spec reverse(non_empty_list(GML)) -> non_empty_list(GML). -reverse(List) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:reverse(_pipe@1), - from_list(_pipe@2) - end, - {ok, Reversed} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"reverse"/utf8>>, - line => 378}) - end, - Reversed. - --spec map_fold(non_empty_list(GLV), GLX, fun((GLX, GLV) -> {GLX, GLY})) -> {GLX, - non_empty_list(GLY)}. -map_fold(List, Acc, Fun) -> - {Acc@1, First_elem} = Fun(Acc, erlang:element(2, List)), - _pipe = gleam@list:fold( - erlang:element(3, List), - {Acc@1, single(First_elem)}, - fun(Acc_non_empty, Item) -> - {Acc@2, Non_empty} = Acc_non_empty, - {Acc@3, New_item} = Fun(Acc@2, Item), - {Acc@3, prepend(Non_empty, New_item)} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec scan(non_empty_list(GMO), GMQ, fun((GMQ, GMO) -> GMQ)) -> non_empty_list(GMQ). -scan(List, Initial, Fun) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:scan(_pipe@1, Initial, Fun), - from_list(_pipe@2) - end, - {ok, Scanned} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"scan"/utf8>>, - line => 400}) - end, - Scanned. - --spec shuffle(non_empty_list(GMS)) -> non_empty_list(GMS). -shuffle(List) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:shuffle(_pipe@1), - from_list(_pipe@2) - end, - {ok, Shuffled} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"shuffle"/utf8>>, - line => 423}) - end, - Shuffled. - --spec sort(non_empty_list(GMX), fun((GMX, GMX) -> gleam@order:order())) -> non_empty_list(GMX). -sort(List, Compare) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:sort(_pipe@1, Compare), - from_list(_pipe@2) - end, - {ok, Sorted} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"sort"/utf8>>, - line => 459}) - end, - Sorted. - --spec take(non_empty_list(GNH), integer()) -> list(GNH). -take(List, N) -> - _pipe = List, - _pipe@1 = to_list(_pipe), - gleam@list:take(_pipe@1, N). - --spec unique(non_empty_list(GNN)) -> non_empty_list(GNN). -unique(List) -> - _assert_subject = begin - _pipe = List, - _pipe@1 = to_list(_pipe), - _pipe@2 = gleam@list:unique(_pipe@1), - from_list(_pipe@2) - end, - {ok, Unique} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"non_empty_list"/utf8>>, - function => <<"unique"/utf8>>, - line => 557}) - end, - Unique. - --spec unzip(non_empty_list({GNQ, GNR})) -> {non_empty_list(GNQ), - non_empty_list(GNR)}. -unzip(List) -> - _pipe = gleam@list:unzip(erlang:element(3, List)), - _pipe@1 = gleam@pair:map_first( - _pipe, - fun(_capture) -> - new(erlang:element(1, erlang:element(2, List)), _capture) - end - ), - gleam@pair:map_second( - _pipe@1, - fun(_capture@1) -> - new(erlang:element(2, erlang:element(2, List)), _capture@1) - end - ). - --spec zip(non_empty_list(GNV), non_empty_list(GNX)) -> non_empty_list({GNV, GNX}). -zip(List, Other) -> - new( - {erlang:element(2, List), erlang:element(2, Other)}, - gleam@list:zip(erlang:element(3, List), erlang:element(3, Other)) - ). - --spec strict_zip(non_empty_list(GNA), non_empty_list(GNC)) -> {ok, - non_empty_list({GNA, GNC})} | - {error, gleam@list:length_mismatch()}. -strict_zip(List, Other) -> - case gleam@list:length(to_list(List)) =:= gleam@list:length(to_list(Other)) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_flatten(list(non_empty_list(GKP)), non_empty_list(GKP)) -> non_empty_list(GKP). -do_flatten(Lists, Accumulator) -> - case Lists of - [] -> - reverse(Accumulator); - - [List | Further_lists] -> - do_flatten(Further_lists, reverse_and_prepend(List, Accumulator)) - end. - --spec flatten(non_empty_list(non_empty_list(GKL))) -> non_empty_list(GKL). -flatten(Lists) -> - do_flatten(erlang:element(3, Lists), reverse(erlang:element(2, Lists))). - --spec flat_map(non_empty_list(GKG), fun((GKG) -> non_empty_list(GKI))) -> non_empty_list(GKI). -flat_map(List, Fun) -> - _pipe = List, - _pipe@1 = map(_pipe, Fun), - flatten(_pipe@1). - --spec reverse_and_prepend(non_empty_list(GKU), non_empty_list(GKU)) -> non_empty_list(GKU). -reverse_and_prepend(Prefix, Suffix) -> - case erlang:element(3, Prefix) of - [] -> - new(erlang:element(2, Prefix), to_list(Suffix)); - - [First | Rest] -> - reverse_and_prepend( - new(First, Rest), - new(erlang:element(2, Prefix), to_list(Suffix)) - ) - end. - --spec do_index_map( - list(GLH), - list(GLJ), - integer(), - fun((integer(), GLH) -> GLJ) -) -> list(GLJ). -do_index_map(List, Accumulator, Index, Fun) -> - case List of - [] -> - gleam@list:reverse(Accumulator); - - [First | Rest] -> - do_index_map( - Rest, - [Fun(Index, First) | Accumulator], - Index + 1, - Fun - ) - end. - --spec index_map(non_empty_list(GLD), fun((integer(), GLD) -> GLF)) -> non_empty_list(GLF). -index_map(List, Fun) -> - new( - Fun(0, erlang:element(2, List)), - do_index_map(erlang:element(3, List), [], 1, Fun) - ). diff --git a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam b/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam deleted file mode 100644 index 9ceb47e143e..00000000000 --- a/test-community-packages-javascript/build/packages/non_empty_list/src/non_empty_list.gleam +++ /dev/null @@ -1,607 +0,0 @@ -import gleam/list -import gleam/result -import gleam/pair -import gleam/order.{Order} - -/// A list that is guaranteed to contain at least one item. -pub type NonEmptyList(a) { - NonEmptyList(first: a, rest: List(a)) -} - -/// An error that occurs when trying to convert an empty list into a -/// non empty list. -/// -pub type ListWasEmpty { - ListWasEmpty -} - -/// Joins a non-empty list onto the end of a non-empty list. -/// -/// This function runs in linear time, and it traverses and copies the first non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> append(new(5, [6, 7])) -/// NonEmptyList(1, [2, 3, 4, 5, 6, 7]) -/// ``` -/// -/// ```gleam -/// > single("a") -/// > |> append(new("b", ["c"]) -/// NonEmptyList("a", ["b", "c"]) -/// ```` -/// -pub fn append( - first: NonEmptyList(a), - second: NonEmptyList(a), -) -> NonEmptyList(a) { - new(first.first, list.append(first.rest, to_list(second))) -} - -/// Joins a list onto the end of a non-empty list. -/// -/// This function runs in linear time, and it traverses and copies the first non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> append_list([5, 6, 7]) -/// NonEmptyList(1, [2, 3, 4, 5, 6, 7]) -/// ``` -/// -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> append_list([]) -/// NonEmptyList("a", ["b", "c"]) -/// ``` -/// -pub fn append_list(first: NonEmptyList(a), second: List(a)) -> NonEmptyList(a) { - new(first.first, list.append(first.rest, second)) -} - -/// Returns a list that is the given non-empty list with up to the given -/// number of elements removed from the front of the list. -/// -/// ## Examples -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> drop(up_to: 2) -/// ["c"] -/// ``` -/// -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> drop(up_to: 3) -/// [] -/// ``` -/// -pub fn drop(from list: NonEmptyList(a), up_to n: Int) -> List(a) { - list - |> to_list - |> list.drop(up_to: n) -} - -/// Gets the first element from the start of the non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> first -/// 1 -/// ``` -/// -pub fn first(list: NonEmptyList(a)) -> a { - list.first -} - -/// Maps the non-empty list with the given function and then flattens it. -/// -/// ## Examples -/// ```gleam -/// > new(1, [3, 5]) -/// > |> flat_map(fn(x) { new(x, [x + 1]) }) -/// NonEmptyList(1, [2, 3, 4, 5, 6]) -/// ``` -/// -pub fn flat_map( - over list: NonEmptyList(a), - with fun: fn(a) -> NonEmptyList(b), -) -> NonEmptyList(b) { - list - |> map(fun) - |> flatten -} - -/// Flattens a non-empty list of non-empty lists into a single non-empty list. -/// -/// This function traverses all elements twice. -/// -/// ### Examples -/// -/// ```gleam -/// > new(new(1, [2, 3]), [new(3, [4, 5])]) -/// > |> flatten -/// NonEmptyList(1, [2, 3, 4, 5]) -/// ``` -/// -pub fn flatten(lists: NonEmptyList(NonEmptyList(a))) -> NonEmptyList(a) { - do_flatten(lists.rest, reverse(lists.first)) -} - -fn do_flatten( - lists: List(NonEmptyList(a)), - accumulator: NonEmptyList(a), -) -> NonEmptyList(a) { - case lists { - [] -> reverse(accumulator) - [list, ..further_lists] -> - do_flatten(further_lists, reverse_and_prepend(list, accumulator)) - } -} - -fn reverse_and_prepend( - list prefix: NonEmptyList(a), - to suffix: NonEmptyList(a), -) -> NonEmptyList(a) { - case prefix.rest { - [] -> new(prefix.first, to_list(suffix)) - [first, ..rest] -> - reverse_and_prepend(new(first, rest), new(prefix.first, to_list(suffix))) - } -} - -/// Attempts to turn a list into a non-empty list, fails if the starting -/// list is empty. -/// -/// ## Examples -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// Ok(NonEmptyList(1, [2, 3, 4])) -/// ``` -/// -/// ```gleam -/// > from_list(["a"]) -/// Ok(NonEmptyList("a", [])) -/// ``` -/// -/// ```gleam -/// > from_list([]) -/// Error(ListWasEmpty) -/// ``` -/// -pub fn from_list(list: List(a)) -> Result(NonEmptyList(a), ListWasEmpty) { - case list { - [] -> Error(ListWasEmpty) - [first, ..rest] -> Ok(new(first, rest)) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so on. -/// -/// ## Examples -/// ```gleam -/// > new("a", ["b", "c"]) -/// > |> index_map(fn(index, letter) { #(index, letter) }) -/// NonEmpty(#(0, "a"), [#(1, "b"), #(2, "c")]) -/// ``` -/// -pub fn index_map( - list: NonEmptyList(a), - with fun: fn(Int, a) -> b, -) -> NonEmptyList(b) { - new(fun(0, list.first), do_index_map(list.rest, [], 1, fun)) -} - -fn do_index_map( - list: List(a), - accumulator: List(b), - index: Int, - fun: fn(Int, a) -> b, -) -> List(b) { - case list { - [] -> list.reverse(accumulator) - [first, ..rest] -> - do_index_map(rest, [fun(index, first), ..accumulator], index + 1, fun) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> intersperse(with: 0) -/// NonEmptyList(1, [0, 2, 0, 3, 0, 4]) -/// ``` -/// -/// ```gleam -/// > single("a") -/// > |> intersperse(with: "z") -/// NonEmptyList("a", ["z"]) -/// ``` -/// -pub fn intersperse(list: NonEmptyList(a), with elem: a) -> NonEmptyList(a) { - new(list.first, [elem, ..list.intersperse(list.rest, with: elem)]) -} - -/// Returns the last element in the given list. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// ```gleam -/// > single(1) -/// > |> last -/// 1 -/// ``` -/// -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> last -/// 4 -/// ``` -/// -pub fn last(list: NonEmptyList(a)) -> a { - list.last(list.rest) - |> result.unwrap(list.first) -} - -/// Returns a new non-empty list containing only the elements of the first -/// non-empty list after the function has been applied to each one. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3]) -/// > |> map(fn(x) { x + 1 }) -/// NonEmpty(2, [3, 4]) -/// ``` -/// -pub fn map(over list: NonEmptyList(a), with fun: fn(a) -> b) -> NonEmptyList(b) { - new(fun(list.first), list.map(list.rest, with: fun)) -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3]) -/// > |> map_fold(from: 100, with: fn(memo, n) { #(memo + i, i * 2) }) -/// #(106, NonEmpty(2, [4, 6])) -/// ``` -/// -pub fn map_fold( - over list: NonEmptyList(a), - from acc: b, - with fun: fn(b, a) -> #(b, c), -) -> #(b, NonEmptyList(c)) { - let #(acc, first_elem) = fun(acc, list.first) - list.fold( - over: list.rest, - from: #(acc, single(first_elem)), - with: fn(acc_non_empty, item) { - let #(acc, non_empty) = acc_non_empty - let #(acc, new_item) = fun(acc, item) - #(acc, prepend(to: non_empty, this: new_item)) - }, - ) - |> pair.map_second(reverse) -} - -/// Creates a new non-empty list given its first element and a list -/// for the rest of the elements. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// NonEmptyList(1, [2, 3, 4]) -/// ``` -/// ```gleam -/// > new("a", []) -/// NonEmptyList("a", []) -/// ``` -/// -pub fn new(first: a, rest: List(a)) -> NonEmptyList(a) { - NonEmptyList(first, rest) -} - -/// Prefixes an item to a non-empty list. -/// -/// ## Examples -/// ```gleam -/// > new(2, [3, 4]) -/// > |> prepend(1) -/// NonEmptyList(1, [2, 3, 4]) -/// ``` -/// -pub fn prepend(to list: NonEmptyList(a), this item: a) -> NonEmptyList(a) { - new(item, [list.first, ..list.rest]) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the non-empty list and combines it with each -/// subsequent element in turn using the given function. -/// The function is called as `fun(accumulator, current_element)`. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> reduce(fn(acc, x) { acc + x }) -/// 10 -/// ``` -/// -pub fn reduce(over list: NonEmptyList(a), with fun: fn(a, a) -> a) -> a { - list.fold(over: list.rest, from: list.first, with: fun) -} - -/// Returns the list minus the first element. Since the remaining list could -/// be empty this functions returns a normal list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> rest -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > single(1) -/// > |> rest -/// [] -/// ``` -/// -pub fn rest(list: NonEmptyList(a)) -> List(a) { - list.rest -} - -/// Creates a new non-empty list from a given non-empty list containing the same elements -/// but in the opposite order. -/// -/// This function has to traverse the non-empty list to create the new reversed -/// non-empty list, so it runs in linear time. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> reverse -/// NonEmptyList(4, [3, 2, 1]) -/// ``` -/// -pub fn reverse(list: NonEmptyList(a)) -> NonEmptyList(a) { - let assert Ok(reversed) = - list - |> to_list - |> list.reverse - |> from_list - reversed -} - -/// Similar to fold, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> scan(from: 100, with: fn(acc, i) { acc + i }) -/// NonEmptyList(101 [103, 106, 110]) -/// ``` -/// -pub fn scan( - over list: NonEmptyList(a), - from initial: b, - with fun: fn(b, a) -> b, -) -> NonEmptyList(b) { - let assert Ok(scanned) = - list - |> to_list - |> list.scan(from: initial, with: fun) - |> from_list - scanned -} - -/// Takes a non-empty list, randomly sorts all items and returns the shuffled -/// non-empty list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calcuate the index shuffling. -/// -/// ## Examples -/// -/// ```gleam -/// > new("a", ["b", "c", "d"]) -/// > |> shuffle -/// NonEmptyList("c", ["a", "d", "b"]) -/// ``` -/// -pub fn shuffle(list: NonEmptyList(a)) -> NonEmptyList(a) { - let assert Ok(shuffled) = - list - |> to_list - |> list.shuffle - |> from_list - shuffled -} - -/// Creates a non-empty list with a single element. -/// -/// ## Examples -/// ```gleam -/// > single(1) -/// NonEmptyList(1, []) -/// ``` -/// -pub fn single(first: a) -> NonEmptyList(a) { - new(first, []) -} - -/// Sorts a given non-empty list from smallest to largest based upon the -/// ordering specified by a given function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > new(4, [1, 3, 4, 2, 6, 5]) -/// > sort(by: int.compare) -/// NonEmptyList(1, [2, 3, 4, 4, 5, 6]) -/// ``` -/// -pub fn sort( - list: NonEmptyList(a), - by compare: fn(a, a) -> Order, -) -> NonEmptyList(a) { - let assert Ok(sorted) = - list - |> to_list - |> list.sort(by: compare) - |> from_list - sorted -} - -/// Takes two non-empty lists and returns a single non-empty list of 2-element tuples. -/// -/// If one of the non-empty lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip(single(1), new("a", ["b", "c"])) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip(new(1, [2, 3]), single("a")) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip(new(1, [2, 3]), new("a", ["b", "c"])) -/// Ok(NonEmptyList(#(1, "a"), [#(2, "b"), #(3, "c")])) -/// ``` -/// -pub fn strict_zip( - list: NonEmptyList(a), - with other: NonEmptyList(b), -) -> Result(NonEmptyList(#(a, b)), list.LengthMismatch) { - case list.length(to_list(list)) == list.length(to_list(other)) { - True -> Ok(zip(list, with: other)) - False -> Error(list.LengthMismatch) - } -} - -/// Returns a list containing the first given number of elements from the given -/// non-empty list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > take(2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > take(9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: NonEmptyList(a), up_to n: Int) -> List(a) { - list - |> to_list - |> list.take(n) -} - -/// Turns a non-empty list back into a normal list with the same -/// elements. -/// -/// ## Examples -/// ```gleam -/// > new(1, [2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -/// ```gleam -/// > single("a") -/// > |> to_list -/// ["a"] -/// ``` -/// -pub fn to_list(non_empty: NonEmptyList(a)) -> List(a) { - [non_empty.first, ..non_empty.rest] -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// ```gleam -/// > new(1, [1, 2, 3, 1, 4, 4, 3]) -/// > |> unique -/// NonEmptyList(1, [2, 3, 4]) -/// ``` -/// -pub fn unique(list: NonEmptyList(a)) -> NonEmptyList(a) { - let assert Ok(unique) = - list - |> to_list - |> list.unique - |> from_list - unique -} - -/// Takes a single non-empty list of 2-element tuples and returns two -/// non-empty lists. -/// -/// ## Examples -/// ```gleam -/// > new(#(1, "a"), [#(2, "b"), #(3, "c")]) -/// > |> unzip -/// #(NonEmptyList(1, [2, 3]), NonEmptyList("a", ["b", "c"])) -/// ``` -/// -pub fn unzip(list: NonEmptyList(#(a, b))) -> #(NonEmptyList(a), NonEmptyList(b)) { - list.unzip(list.rest) - |> pair.map_first(new(list.first.0, _)) - |> pair.map_second(new(list.first.1, _)) -} - -/// Takes two non-empty lists and returns a single non-empty list of 2-element tuples. -/// -/// If one of the non-empty lists is longer than the other, the remaining elements from -/// the longer non-empty list are not used. -/// -/// ## Examples -/// ```gleam -/// > zip(new(1, [2, 3]), single("a")) -/// NonEmptyList(#(1, "a"), []) -/// ``` -/// -/// ```gleam -/// > zip(single(1), new("a", ["b", "c"])) -/// NonEmptyList(#(1, "a"), []) -/// ``` -/// -/// ```gleam -/// > zip(new(1, [2, 3]), new("a", ["b", "c"])) -/// NonEmptyList(#(1, "a"), [#(2, "b"), #(3, "c")]) -/// ``` -/// -pub fn zip( - list: NonEmptyList(a), - with other: NonEmptyList(b), -) -> NonEmptyList(#(a, b)) { - new(#(list.first, other.first), list.zip(list.rest, other.rest)) -} diff --git a/test-community-packages-javascript/build/packages/packages.toml b/test-community-packages-javascript/build/packages/packages.toml deleted file mode 100644 index 948d847a082..00000000000 --- a/test-community-packages-javascript/build/packages/packages.toml +++ /dev/null @@ -1,30 +0,0 @@ -[packages] -gliew = "0.3.0" -gleam_community_colour = "1.1.0" -gleam_stdlib = "0.29.2" -simplifile = "0.1.4" -gleam_bitwise = "1.2.0" -nakai = "0.8.0" -gleam_erlang = "0.19.0" -gleeunit = "0.10.1" -gsv = "0.1.0" -gleam_community_ansi = "1.1.0" -trie_again = "1.1.1" -ream = "0.1.0" -gleam_cors = "0.2.0" -gleam_otp = "0.5.3" -glisten = "0.7.0" -nibble = "0.2.3" -gleam_crypto = "0.3.1" -globe = "0.1.0" -glove = "0.2.0" -mist = "0.11.0" -gloml = "0.1.2" -toml = "0.7.0" -gleam_http = "3.2.0" -hug = "0.1.0" -glenvy = "0.4.0" -glx = "0.2.0" -non_empty_list = "1.0.0" -glerm = "0.1.0" -gleamy_structures = "0.3.0" diff --git a/test-community-packages-javascript/build/packages/ream/LICENSE b/test-community-packages-javascript/build/packages/ream/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/test-community-packages-javascript/build/packages/ream/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/test-community-packages-javascript/build/packages/ream/README.md b/test-community-packages-javascript/build/packages/ream/README.md deleted file mode 100644 index f31e5667fb3..00000000000 --- a/test-community-packages-javascript/build/packages/ream/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# ream - -[![Package Version](https://img.shields.io/hexpm/v/ream)](https://hex.pm/packages/ream) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/ream/) - -REAM is an event-sourcing system. - -The REAM server is a simple TCP server that's receiving events from aggregators which are -sending the event and a status update. The idea is: - -- The Aggregator receives a command. -- The aggregator validates the command and generates: - 1. One or more events are generated by the aggregator and published into REAM. - 2. A modification in the state is performed in the aggregator and stored in REAM. -- Subscribers, mainly projectors receive the event. -- These subscribers perform a change in the schema and publish changes into projections. - -Therefore we have three different but related storage: - -- Events. It's getting events in different streams. We can create as many streams as we need. -- Aggregations. It's storing the state for the aggregators based on the last processed event for a specific stream. -- Projections. Stored the projections based on the information provided by the projectors. - -The main idea is to provide an easy way for implementing aggregators and projectors to process the data we need in the way we need it. - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add ream -``` - -and its documentation can be found at <https://hexdocs.pm/ream>. - -## Architecture and Design - -You can check the protocol [here](docs/protocol.md) and how the storage is going to take place [here](docs/storage.md). - -## License - -Apache License Version 2.0, see [LICENSE](LICENSE) - -Copyright 2023 Altenwald - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/test-community-packages-javascript/build/packages/ream/gleam.toml b/test-community-packages-javascript/build/packages/ream/gleam.toml deleted file mode 100644 index 43c839f2fbc..00000000000 --- a/test-community-packages-javascript/build/packages/ream/gleam.toml +++ /dev/null @@ -1,27 +0,0 @@ -name = "ream" -version = "0.1.0" -description = "REAM is an event sourcing system" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. - -licences = ["Apache-2.0"] -repository = { type = "github", user = "altenwald", repo = "ream" } -# links = [{ title = "Website", href = "https://gleam.run" }] - -[dependencies] -gleam_stdlib = "~> 0.28" -gleam_otp = "~> 0.5" -hug = "~> 0.1" -gloml = "~> 0.1" -gleam_erlang = "~> 0.19" - -[dev-dependencies] -glacier = "~> 0.8" - -[documentation] -pages = [ - { title = "LICENSE", path = "license.html", source = "LICENSE" }, - { title = "Protocol", path = "protocol.html", source = "docs/protocol.md" }, - { title = "Storage", path = "storage.html", source = "docs/storage.md" } -] diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl deleted file mode 100644 index 686a9b2f541..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@close_Error.hrl +++ /dev/null @@ -1 +0,0 @@ --record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl deleted file mode 100644 index 686a9b2f541..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Error.hrl +++ /dev/null @@ -1 +0,0 @@ --record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl deleted file mode 100644 index db5abbdf21d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@read_Ok.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ok, {data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl deleted file mode 100644 index 686a9b2f541..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file@write_Error.hrl +++ /dev/null @@ -1 +0,0 @@ --record(error, {reason :: gleam@erlang@file:reason()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl deleted file mode 100644 index eb7e3ac051a..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_DelayedWrite.hrl +++ /dev/null @@ -1 +0,0 @@ --record(delayed_write, {size :: integer(), delay :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl deleted file mode 100644 index 2d13f93ccb9..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_Encoding.hrl +++ /dev/null @@ -1 +0,0 @@ --record(encoding, {encoding :: ream@storage@file:encoding_type()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl deleted file mode 100644 index 963a65ce424..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@file_ReadAhead.hrl +++ /dev/null @@ -1 +0,0 @@ --record(read_ahead, {size :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl deleted file mode 100644 index 0be9823bd17..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTable.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(mem_table, { - entries :: gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry()), - size :: integer(), - max_size :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl deleted file mode 100644 index b342d1a4d84..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@memtable_MemTableEntry.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(mem_table_entry, { - key :: binary(), - value :: ream@storage@kv@value:value() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl deleted file mode 100644 index 1631ca7075a..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_Value.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(value, { - offset :: integer(), - deleted :: boolean(), - data :: gleam@option:option(bitstring()), - file_id :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl deleted file mode 100644 index b8fd91be66a..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFile.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(value_file, { - id :: integer(), - handler :: gleam@erlang@process:pid_(), - size :: integer(), - max_size :: integer(), - file_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl deleted file mode 100644 index 9582b309c40..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv@value_ValueFileInfo.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(value_file_info, { - file_id :: integer(), - size :: integer(), - max_size :: integer(), - entries :: integer(), - deleted :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl deleted file mode 100644 index 75884f81d1d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KV.hrl +++ /dev/null @@ -1,11 +0,0 @@ --record(kv, { - base_path :: binary(), - name :: binary(), - memtable_ranges :: gleam@map:map_(integer(), ream@storage@kv:mem_table_range()), - active_value_file :: gleam@option:option(integer()), - values :: gleam@map:map_(integer(), ream@storage@kv@value:value_file()), - memtables_loaded :: integer(), - max_memtables_loaded :: integer(), - max_memtable_size :: integer(), - max_value_size :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl deleted file mode 100644 index 3bd9ff18d40..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_KVInfo.hrl +++ /dev/null @@ -1,12 +0,0 @@ --record(kv_info, { - base_path :: binary(), - name :: binary(), - values :: integer(), - values_size_bytes :: integer(), - memtables_total :: integer(), - memtables_loaded :: integer(), - memtables_loaded_size_bytes :: integer(), - max_memtables_loaded :: integer(), - max_memtable_size :: integer(), - max_value_size :: integer() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl deleted file mode 100644 index 71ec67b0599..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@kv_MemTableRange.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(mem_table_range, { - lower :: integer(), - upper :: integer(), - memtable :: gleam@option:option(ream@storage@kv@memtable:mem_table()) -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl deleted file mode 100644 index 8eaa99ab752..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_Event.hrl +++ /dev/null @@ -1 +0,0 @@ --record(event, {offset :: integer(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl deleted file mode 100644 index eab4d784cf5..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@event_EventFile.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(event_file, { - id :: integer(), - handler :: gleam@erlang@process:pid_(), - size :: integer(), - file_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl deleted file mode 100644 index eed9e04ebec..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_Index.hrl +++ /dev/null @@ -1 +0,0 @@ --record(index, {offset :: integer(), size :: integer(), file_id :: integer()}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl deleted file mode 100644 index 7a25f9bdfcb..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream@index_IndexFile.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(index_file, { - handler :: gleam@erlang@process:pid_(), - size :: integer(), - file_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl b/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl deleted file mode 100644 index ff7a5576983..00000000000 --- a/test-community-packages-javascript/build/packages/ream/include/ream@storage@stream_Stream.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(stream, { - name :: binary(), - index :: ream@storage@stream@index:index_file(), - active_file :: gleam@option:option(ream@storage@stream@event:event_file()), - files :: gleam@map:map_(integer(), ream@storage@stream@event:event_file()), - base_path :: binary() -}). diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.app.src b/test-community-packages-javascript/build/packages/ream/src/ream.app.src deleted file mode 100644 index ad44dc9c44d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream.app.src +++ /dev/null @@ -1,24 +0,0 @@ -{application, ream, [ - {vsn, "0.1.0"}, - {applications, [glacier, - gleam_erlang, - gleam_otp, - gleam_stdlib, - gloml, - hug]}, - {description, "REAM is an event sourcing system"}, - {modules, [ream, - ream@storage@file, - ream@storage@file@close, - ream@storage@file@read, - ream@storage@file@write, - ream@storage@kv, - ream@storage@kv@memtable, - ream@storage@kv@sstable, - ream@storage@kv@value, - ream@storage@stream, - ream@storage@stream@event, - ream@storage@stream@index, - ream@uuid]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.erl b/test-community-packages-javascript/build/packages/ream/src/ream.erl deleted file mode 100644 index a54ca2a1af2..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream.erl +++ /dev/null @@ -1 +0,0 @@ --module(ream). diff --git a/test-community-packages-javascript/build/packages/ream/src/ream.gleam b/test-community-packages-javascript/build/packages/ream/src/ream.gleam deleted file mode 100644 index 8b137891791..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream.gleam +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam deleted file mode 100644 index 64e87f2e0d3..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file.gleam +++ /dev/null @@ -1,103 +0,0 @@ -import gleam/erlang/process.{Pid} -import gleam/erlang/file -import ream/storage/file/read -import ream/storage/file/close -import ream/storage/file/write - -pub type Endian { - Big - Little -} - -pub type EncodingType { - Unicode - Utf8 - Utf16(Endian) - Utf32(Endian) - Latin1 -} - -pub type Mode { - Read - Write - Append - Exclusive - Raw - Binary - DelayedWrite(size: Int, delay: Int) - ReadAhead(size: Int) - Compressed - CompressedOne - Encoding(encoding: EncodingType) - Ram - Sync - Directory -} - -pub type Location { - Bof(Int) - Cur(Int) - Eof(Int) -} - -pub fn open(filename: String, mode: List(Mode)) -> Result(Pid, file.Reason) { - do_open(filename, [Binary, ..mode]) -} - -pub external fn do_open( - filename: String, - mode: List(Mode), -) -> Result(Pid, file.Reason) = - "file" "open" - -pub external fn read(io_device: Pid, bytes: Int) -> read.Result = - "file" "read" - -pub fn close(io_device: Pid) -> Result(Bool, file.Reason) { - case do_close(io_device) { - close.Ok -> Ok(True) - close.Error(reason) -> Error(reason) - } -} - -external fn do_close(io_device: Pid) -> close.Result = - "file" "close" - -pub fn write(io_device: Pid, data: BitString) -> Result(Bool, file.Reason) { - case do_write(io_device, data) { - write.Ok -> Ok(True) - write.Error(reason) -> Error(reason) - } -} - -external fn do_write(io_device: Pid, data: BitString) -> write.Result = - "file" "write" - -pub external fn dirname(filename: String) -> String = - "filename" "dirname" - -pub external fn basename(filename: String) -> String = - "filename" "basename" - -pub external fn join(parts: List(String)) -> String = - "filename" "join" - -pub external fn position( - io_device: Pid, - location: Location, -) -> Result(Int, file.Reason) = - "file" "position" - -pub fn recursive_make_directory(path: String) -> Result(Bool, file.Reason) { - case file.is_directory(path) { - Error(file.Enoent) -> { - let prev_dir = dirname(path) - let assert Ok(True) = recursive_make_directory(prev_dir) - let assert Ok(_) = file.make_directory(path) - Ok(True) - } - Error(file.Eexist) -> Ok(True) - Ok(True) -> Ok(True) - _ -> Error(file.Einval) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam deleted file mode 100644 index 8d98d62ae47..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/close.gleam +++ /dev/null @@ -1,6 +0,0 @@ -import gleam/erlang/file - -pub type Result { - Ok - Error(reason: file.Reason) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam deleted file mode 100644 index 571e0b0cb92..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/read.gleam +++ /dev/null @@ -1,7 +0,0 @@ -import gleam/erlang/file - -pub type Result { - Ok(data: BitString) - Eof - Error(reason: file.Reason) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam deleted file mode 100644 index 8d98d62ae47..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/file/write.gleam +++ /dev/null @@ -1,6 +0,0 @@ -import gleam/erlang/file - -pub type Result { - Ok - Error(reason: file.Reason) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam deleted file mode 100644 index 81f59437b30..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv.gleam +++ /dev/null @@ -1,430 +0,0 @@ -import gleam/erlang/process.{Pid} -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read -import ream/storage/kv/memtable.{CapacityExceeded, MemTable} -import ream/storage/kv/sstable -import ream/storage/kv/value.{Value, ValueFile} -import ream/uuid - -pub type MemTableRange { - MemTableRange(lower: Int, upper: Int, memtable: Option(MemTable)) -} - -pub type KV { - KV( - base_path: String, - name: String, - memtable_ranges: Map(Int, MemTableRange), - active_value_file: Option(Int), - values: Map(Int, ValueFile), - memtables_loaded: Int, - max_memtables_loaded: Int, - max_memtable_size: Int, - max_value_size: Int, - ) -} - -pub type KVInfo { - KVInfo( - base_path: String, - name: String, - values: Int, - values_size_bytes: Int, - memtables_total: Int, - memtables_loaded: Int, - memtables_loaded_size_bytes: Int, - max_memtables_loaded: Int, - max_memtable_size: Int, - max_value_size: Int, - ) -} - -const min_bound = 0 - -const max_bound = 340_282_366_920_938_463_463_374_607_431_768_211_455 - -pub fn open( - path: String, - name: String, - max_memtables_loaded: Int, - max_memtable_size: Int, - max_value_size: Int, -) -> KV { - let path = fs.join([path, "kv", name]) - - let key_index_file = fs.join([path, "key", "index"]) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(key_index_file)) - let assert Ok(kv) = fs.open(key_index_file, [fs.Read, fs.Write]) - let ranges = - read_memtable_ranges( - kv, - fs.join([path, "key"]), - max_memtable_size, - map.new(), - ) - let #(memtables_loaded, ranges) = case map.size(ranges) == 0 { - True -> { - let memtable = memtable.new(max_memtable_size) - let ranges = - [#(new_id(), MemTableRange(min_bound, max_bound, Some(memtable)))] - |> map.from_list() - #(1, ranges) - } - False -> #(0, ranges) - } - let assert Ok(_) = fs.close(kv) - - let value_index_file = fs.join([path, "value", "index"]) - let assert Ok(True) = - fs.recursive_make_directory(fs.dirname(value_index_file)) - let assert Ok(kv) = fs.open(value_index_file, [fs.Read, fs.Write]) - let #(active_value_file, values) = - read_values(kv, fs.join([path, "value"]), None, max_value_size, map.new()) - let assert Ok(_) = fs.close(kv) - - KV( - path, - name, - ranges, - active_value_file, - values, - memtables_loaded, - max_memtables_loaded, - max_memtable_size, - max_value_size, - ) -} - -fn new_id() -> Int { - uuid.to_int(uuid.new()) -} - -fn read_memtable_ranges( - kv: Pid, - path: String, - max_size: Int, - acc: Map(Int, MemTableRange), -) -> Map(Int, MemTableRange) { - case fs.read(kv, 48) { - read.Ok(<<lower:size(128), upper:size(128), id:size(128)>>) -> { - let range = MemTableRange(lower, upper, None) - read_memtable_ranges(kv, path, max_size, map.insert(acc, id, range)) - } - read.Eof -> acc - read.Error(_err) -> { - let assert Ok(_) = fs.close(kv) - // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed - panic - } - } -} - -fn read_values( - kv: Pid, - path: String, - last_file_id: Option(Int), - max_value_size: Int, - acc: Map(Int, ValueFile), -) -> #(Option(Int), Map(Int, ValueFile)) { - case fs.read(kv, 16) { - read.Ok(<<file_id:size(128)>>) -> { - let assert Ok(value_file) = value.open(path, file_id, max_value_size) - read_values( - kv, - path, - Some(file_id), - max_value_size, - map.insert(acc, file_id, value_file), - ) - } - read.Eof -> #(last_file_id, acc) - read.Error(_err) -> { - let assert Ok(_) = fs.close(kv) - // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed - panic - } - } -} - -fn sstable_path(path: String, id: Int) -> String { - let parts = uuid.parts(uuid.from_int(id)) - fs.join([path, "key", ..parts]) -} - -fn find_range(kv: KV, key_hash: Int, max_size: Int) -> #(Int, KV) { - let max_memtables_loaded = kv.max_memtables_loaded - let assert #(#(loaded, Some(range_id)), range_list) = - kv.memtable_ranges - |> map.to_list() - |> list.map_fold( - #(kv.memtables_loaded, None), - fn(acc, entry) { - let #(id, range) = entry - let #(loaded, range_id) = acc - case - key_hash >= range.lower && key_hash <= range.upper, - range.memtable - { - True, Some(_) -> #(#(loaded, Some(id)), #(id, range)) - True, None -> { - let assert Ok(memtable) = - sstable.load(sstable_path(kv.base_path, id), max_size) - #( - #(loaded + 1, Some(id)), - #(id, MemTableRange(..range, memtable: Some(memtable))), - ) - } - False, Some(memtable) if loaded >= max_memtables_loaded -> { - let assert Ok(_) = - sstable.flush(memtable, sstable_path(kv.base_path, id)) - #( - #(loaded - 1, range_id), - #(id, MemTableRange(..range, memtable: None)), - ) - } - False, _ -> #(acc, #(id, range)) - } - }, - ) - - #( - range_id, - KV( - ..kv, - memtable_ranges: map.from_list(range_list), - memtables_loaded: loaded, - ), - ) -} - -pub fn close(kv: KV) -> Result(Nil, Nil) { - let assert Ok(_) = flush(kv) - - map.values(kv.values) - |> list.each(fn(v) { value.close(v) }) - - Ok(Nil) -} - -pub fn flush(kv: KV) -> Result(Nil, Nil) { - let key_index_file = fs.join([kv.base_path, "key", "index"]) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(key_index_file)) - let assert Ok(kv_file) = fs.open(key_index_file, [fs.Write]) - let memtable_ranges = map.to_list(kv.memtable_ranges) - let assert Ok(_) = - write_memtable_ranges(kv_file, kv.base_path, memtable_ranges) - let assert Ok(_) = fs.close(kv_file) - - let value_index_file = fs.join([kv.base_path, "value", "index"]) - let assert Ok(True) = - fs.recursive_make_directory(fs.dirname(value_index_file)) - let assert Ok(kv_file) = fs.open(value_index_file, [fs.Write]) - let assert Ok(_) = write_values(kv_file, map.keys(kv.values)) - let assert Ok(_) = fs.close(kv_file) - - Ok(Nil) -} - -fn write_memtable_ranges( - kv_file: Pid, - base_path: String, - memtable_ranges: List(#(Int, MemTableRange)), -) -> Result(Nil, Nil) { - case memtable_ranges { - [#(id, MemTableRange(lower, upper, Some(memtable))), ..rest] -> { - let assert Ok(True) = sstable.flush(memtable, sstable_path(base_path, id)) - let assert Ok(_) = fs.write(kv_file, <<lower:128, upper:128, id:128>>) - write_memtable_ranges(kv_file, base_path, rest) - } - [#(id, MemTableRange(lower, upper, None)), ..rest] -> { - let assert Ok(_) = fs.write(kv_file, <<lower:128, upper:128, id:128>>) - write_memtable_ranges(kv_file, base_path, rest) - } - [] -> Ok(Nil) - } -} - -fn write_values(kv: Pid, values: List(Int)) -> Result(Nil, Nil) { - case values { - [id, ..rest] -> { - let assert Ok(_) = fs.write(kv, <<id:128>>) - write_values(kv, rest) - } - [] -> Ok(Nil) - } -} - -pub fn get(kv: KV, key: String) -> #(Result(BitString, Nil), KV) { - let key_hash = memtable.hash(key) - let #(range_id, kv) = find_range(kv, key_hash, kv.max_memtable_size) - let assert Ok(range) = map.get(kv.memtable_ranges, range_id) - let assert Some(memtable) = range.memtable - case memtable.get(memtable, key) { - Ok(value) -> { - let assert Ok(vfile) = map.get(kv.values, value.file_id) - case value.read(vfile, value.offset) { - Ok(Value(deleted: False, file_id: _, offset: _, data: Some(data))) -> #( - Ok(data), - kv, - ) - _ -> #(Error(Nil), kv) - } - } - Error(_err) -> #(Error(Nil), kv) - } -} - -pub fn set(kv: KV, key: String, value: BitString) -> KV { - let key_hash = memtable.hash(key) - let #(range_id, kv) = find_range(kv, key_hash, kv.max_memtable_size) - let assert Ok(range) = map.get(kv.memtable_ranges, range_id) - let assert Some(memtable) = range.memtable - let kv = case kv.active_value_file { - Some(_file_id) -> kv - None -> { - let assert Ok(vfile) = - value.create(fs.join([kv.base_path, "value"]), kv.max_value_size) - KV( - ..kv, - active_value_file: Some(vfile.id), - values: map.insert(kv.values, vfile.id, vfile), - ) - } - } - case memtable.get(memtable, key) { - Ok(old_value) -> { - // key is in the index, we have to replace it - case store_value(kv, key, range_id, range, memtable, value) { - Ok(kv) -> kv - Error(CapacityExceeded) -> { - let kv = split(kv, key_hash, range_id, range, memtable) - set(kv, key, value) - } - } - let assert Ok(kv) = delete_value(kv, old_value) - kv - } - Error(Nil) -> { - // key isn't in the index yet, insert it as a new key - case store_value(kv, key, range_id, range, memtable, value) { - Ok(kv) -> kv - Error(CapacityExceeded) -> { - let kv = split(kv, key_hash, range_id, range, memtable) - set(kv, key, value) - } - } - } - } -} - -fn split( - kv: KV, - key_hash: Int, - range_id: Int, - range: MemTableRange, - memtable: MemTable, -) -> KV { - let #(memtable_low, memtable_high, pivot) = memtable.split(memtable, key_hash) - let assert MemTableRange(lower, upper, _) = range - let #(memtable_range_low, memtable_range_high) = case - memtable_low.size >= memtable_high.size - { - False -> #( - MemTableRange(lower, pivot - 1, Some(memtable_low)), - MemTableRange(pivot, upper, None), - ) - True -> #( - MemTableRange(lower, pivot - 1, None), - MemTableRange(pivot, upper, Some(memtable_high)), - ) - } - let memtable_high_id = new_id() - let memtable_ranges = - kv.memtable_ranges - |> map.insert(range_id, memtable_range_low) - |> map.insert(memtable_high_id, memtable_range_high) - - let assert Ok(True) = - sstable.flush(memtable_high, sstable_path(kv.base_path, memtable_high_id)) - - let assert Ok(True) = - sstable.flush(memtable_low, sstable_path(kv.base_path, range_id)) - - KV(..kv, memtable_ranges: memtable_ranges) -} - -fn store_value( - kv: KV, - key: String, - range_id: Int, - range: MemTableRange, - memtable: MemTable, - value_data: BitString, -) -> Result(KV, memtable.Reason) { - let assert Some(file_id) = kv.active_value_file - let assert Ok(vfile) = map.get(kv.values, file_id) - case value.write(vfile, value_data) { - Ok(#(vfile, value)) -> { - use memtable <- try(memtable.set(memtable, key, value)) - let range = MemTableRange(..range, memtable: Some(memtable)) - Ok( - KV( - ..kv, - active_value_file: Some(vfile.id), - values: map.insert(kv.values, vfile.id, vfile), - memtable_ranges: map.insert(kv.memtable_ranges, range_id, range), - ), - ) - } - Error(value.CapacityExceeded) -> { - let assert Ok(vfile) = - value.create(fs.join([kv.base_path, "value"]), kv.max_value_size) - KV( - ..kv, - active_value_file: Some(vfile.id), - values: map.insert(kv.values, vfile.id, vfile), - ) - |> store_value(key, range_id, range, memtable, value_data) - } - } -} - -fn delete_value(kv: KV, value: Value) -> Result(KV, Nil) { - let file_id = value.file_id - let assert Ok(vfile) = map.get(kv.values, file_id) - let assert Ok(vfile) = value.delete(vfile, value) - let values = map.insert(kv.values, file_id, vfile) - Ok(KV(..kv, values: values)) -} - -pub fn info(kv: KV) -> KVInfo { - KVInfo( - base_path: kv.base_path, - name: kv.name, - values: map.size(kv.values), - values_size_bytes: map.fold( - kv.values, - 0, - fn(acc, _key, value_file) { acc + value_file.size }, - ), - memtables_total: map.size(kv.memtable_ranges), - memtables_loaded: kv.memtables_loaded, - memtables_loaded_size_bytes: map.fold( - kv.memtable_ranges, - 0, - fn(acc, _key, memtable_range) { - case memtable_range.memtable { - Some(memtable) -> acc + memtable.size - None -> acc - } - }, - ), - max_memtables_loaded: kv.max_memtables_loaded, - max_memtable_size: kv.max_memtable_size, - max_value_size: kv.max_value_size, - ) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam deleted file mode 100644 index 1b49010d665..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/memtable.gleam +++ /dev/null @@ -1,287 +0,0 @@ -//// MemTable is an in-memory data structure that holds the latest written -//// records. It is a sorted list of records sorted by the key hash. When the -//// MemTable reaches its capacity, it is flushed to disk as a Table (Sorted -//// String Table or SSTable). See the sstable module for more details. - -import gleam/bit_string -import gleam/list -import gleam/map.{Map} -import gleam/option.{None} -import ream/storage/kv/value.{Value} - -/// MemTable holds a sorted list of the latest written records. Generally, we -/// could implement a sorted list algorithm like skip list, but for simplicity -/// we use a map instead. -/// -/// MemTables have a max capacity and when that is reached, we flush the MemTable -/// to disk as a Table (Sorted String Table or SSTable). See the sstable module -/// for more details. -/// -/// The MemTable structure is as follows: -/// - `entries`: a map of key hash to MemTableEntry. The key hash is the hash of -/// the key string. -/// - `size`: the total size of the MemTable in bytes. -/// - `max_size`: the maximum size of the MemTable in bytes. -pub type MemTable { - MemTable(entries: Map(Int, MemTableEntry), size: Int, max_size: Int) -} - -/// MemTableEntry is a single entry in the MemTable. -pub type MemTableEntry { - MemTableEntry(key: String, value: Value) -} - -/// Reason is the reason why a MemTable operation failed. -pub type Reason { - /// The MemTable is full and cannot accept more entries. - CapacityExceeded -} - -/// The key hash size is 32-bit integer -pub const key_hash_size_bytes = 4 - -/// The key string size data is 16-bit integer -pub const key_size_bytes = 2 - -/// The file ID size is 128-bit integer corresponding to the UUID -/// of the file in binary format. -pub const file_id_size_bytes = 16 - -/// The file offset size is 32-bit integer. -pub const file_offset_size_bytes = 4 - -/// The payload size for the memtable entry, it is the sum of the -/// key hash size, file ID size, file offset size and key size. -pub const payload_size_bytes = 26 - -pub fn new(max_size: Int) -> MemTable { - MemTable(entries: map.new(), size: 0, max_size: max_size) -} - -/// calculate_entries_size calculates the total size of the entries in the -/// MemTable. It is mainly used when we load the MemTable from disk. -pub fn from_entries(entries: Map(Int, MemTableEntry), max_size: Int) -> MemTable { - let size = calculate_entries_size(entries) - MemTable(entries: entries, size: size, max_size: max_size) -} - -/// entry_to_bitstring converts a MemTableEntry to a bitstring. It is mainly used -/// when we need to convert the MemTableEntry to its binary representation. -pub fn entry_to_bitstring(entry: MemTableEntry) -> BitString { - let key_hash = hash(entry.key) - let key_string = bit_string.from_string(entry.key) - let key_size = bit_string.byte_size(key_string) - let file_id = entry.value.file_id - let file_offset = entry.value.offset - << - key_hash:128, - key_size:16, - file_id:128, - file_offset:32, - key_string:bit_string, - >> -} - -/// bitstring_to_entry converts a bitstring to a MemTableEntry. It is mainly used -/// when we need to convert the binary representation of a MemTableEntry to a -/// MemTableEntry. -pub fn bitstring_to_entry(bitstring: BitString) -> #(Int, MemTableEntry) { - let << - key_hash:128, - _key_size:16, - file_id:128, - file_offset:32, - key_string:bit_string, - >> = bitstring - let assert Ok(key) = bit_string.to_string(key_string) - let value = - Value(data: None, deleted: False, file_id: file_id, offset: file_offset) - #(key_hash, MemTableEntry(key: key, value: value)) -} - -/// contains checks if the MemTable contains the given key. -pub fn contains(mem_table: MemTable, key: String) -> Bool { - map.has_key(mem_table.entries, hash(key)) -} - -/// generates a hash for the given key. -pub external fn hash(key: String) -> Int = - "erlang" "phash2" - -/// set sets the given key to the given value in the MemTable. If the MemTable -/// reaches its capacity, it returns an error. Otherwise, it returns the updated -/// MemTable. -pub fn set( - mem_table: MemTable, - key: String, - value: Value, -) -> Result(MemTable, Reason) { - let key_hash = hash(key) - case map.get(mem_table.entries, key_hash) { - Error(Nil) -> { - let entry = MemTableEntry(key, value) - let entry_size = calculate_size(entry) - let current_size = mem_table.size + entry_size - case current_size > mem_table.max_size { - True -> Error(CapacityExceeded) - False -> - Ok( - MemTable( - ..mem_table, - entries: map.insert(mem_table.entries, key_hash, entry), - size: current_size, - ), - ) - } - } - Ok(old_entry) -> { - let old_entry_size = calculate_size(old_entry) - let entry = MemTableEntry(..old_entry, value: value) - let current_entry_size = calculate_size(entry) - let mem_table_size = mem_table.size + current_entry_size - old_entry_size - case mem_table_size > mem_table.max_size { - True -> Error(CapacityExceeded) - False -> - Ok( - MemTable( - ..mem_table, - entries: map.insert(mem_table.entries, key_hash, entry), - size: mem_table_size, - ), - ) - } - } - } -} - -/// deletes the given key from the MemTable. If the key does not exist, it -/// returns the original MemTable. Otherwise, it returns the updated MemTable. -pub fn delete(mem_table: MemTable, key: String) -> MemTable { - let key_hash = hash(key) - case map.get(mem_table.entries, key_hash) { - Error(Nil) -> mem_table - Ok(entry) -> { - MemTable( - ..mem_table, - entries: map.delete(mem_table.entries, key_hash), - size: mem_table.size - calculate_size(entry), - ) - } - } -} - -/// gets the value of the given key from the MemTable. If the key does not -/// exist, it returns an error. -pub fn get(mem_table: MemTable, key: String) -> Result(Value, Nil) { - case map.get(mem_table.entries, hash(key)) { - Ok(MemTableEntry(key: stored_key, value: value)) if key == stored_key -> - Ok(value) - Ok(MemTableEntry(key: _stored_key, value: _)) -> { - // TODO better panic messages when https://github.com/gleam-lang/gleam/issues/2176 is fixed - // let errmsg = - // "collision hash function between " <> key <> " and " <> stored_key - panic - } - Error(Nil) -> Error(Nil) - } -} - -/// search for a pivot in the MemTable. The pivot is the middle key in the -/// MemTable. -pub fn search_pivot(mem_table: MemTable) -> Int { - let entries = mem_table.entries - let keys = map.keys(entries) - let entries_count = map.size(entries) - let #(_, [pivot, ..]) = list.split(keys, at: entries_count / 2) - pivot -} - -/// splits the MemTable into two MemTables. The first MemTable contains -/// MemTableEntries with keys less than the pivot. The second MemTable contains -/// MemTableEntries with keys greater than or equal to the pivot. The pivot is -/// the middle key in the MemTable. -pub fn split(mem_table: MemTable, pivot: Int) -> #(MemTable, MemTable, Int) { - let #(low_entries, high_entries) = - mem_table.entries - |> map.to_list() - |> list.partition(fn(entry) { entry.0 < pivot }) - - let low_entries = map.from_list(low_entries) - - let low = - MemTable( - ..mem_table, - entries: low_entries, - size: calculate_entries_size(low_entries), - ) - - let high_entries = map.from_list(high_entries) - - let high = - MemTable( - ..mem_table, - entries: high_entries, - size: calculate_entries_size(high_entries), - ) - - case low.size >= high.size, map.get(high.entries, pivot) { - True, _ -> #(low, high, pivot) - False, Error(Nil) -> #(low, high, pivot + 1) - False, Ok(entry) -> { - let high = - MemTable( - ..high, - entries: map.delete(high.entries, pivot), - size: high.size - calculate_size(entry), - ) - let low = - MemTable( - ..low, - entries: map.insert(low.entries, pivot, entry), - size: low.size + calculate_size(entry), - ) - #(low, high, pivot + 1) - } - } -} - -fn calculate_entries_size(entries: Map(Int, MemTableEntry)) -> Int { - map.fold(entries, 0, fn(acc, _key, entry) { acc + calculate_size(entry) }) -} - -fn calculate_size(entry: MemTableEntry) -> Int { - bit_string.byte_size(entry_to_bitstring(entry)) -} - -/// get_bounds returns the lower and higher bounds of the MemTable. If the -/// MemTable is empty, it returns `#(0, 0)`. -pub fn get_bounds(mem_table: MemTable) -> #(Int, Int) { - case map.to_list(mem_table.entries) { - [] -> #(0, 0) - [#(k, _), ..entries] -> { - list.fold( - entries, - #(k, k), - fn(acc: #(Int, Int), entry) { - #(get_lower(acc.0, entry.0), get_higher(acc.1, entry.0)) - }, - ) - } - } -} - -fn get_lower(lower_bound: Int, key: Int) -> Int { - case lower_bound { - 0 -> key - lower_bound if key < lower_bound -> key - lower_bound -> lower_bound - } -} - -fn get_higher(higher_bound: Int, key: Int) -> Int { - case higher_bound { - 0 -> key - higher_bound if key > higher_bound -> key - higher_bound -> higher_bound - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam deleted file mode 100644 index ec218baab55..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/sstable.gleam +++ /dev/null @@ -1,54 +0,0 @@ -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/map.{Map} -import ream/storage/file as fs -import ream/storage/file/read -import ream/storage/kv/memtable.{MemTable, MemTableEntry} - -const header_size = 38 - -pub fn flush(mem_table: MemTable, path: String) -> Result(Bool, file.Reason) { - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(path)) - let assert Ok(file) = fs.open(path, [fs.Write]) - // TODO maybe suggest the inclusion of `map.each/2` for gleam/stdlib - map.filter( - mem_table.entries, - fn(_key, entry) { - let content = memtable.entry_to_bitstring(entry) - let assert Ok(_) = fs.write(file, content) - False - }, - ) - let assert Ok(_) = fs.close(file) - Ok(True) -} - -pub fn load(path: String, max_size: Int) -> Result(MemTable, file.Reason) { - let assert Ok(file) = fs.open(path, [fs.Read]) - let assert Ok(entries) = read_entries(file, map.new()) - let assert Ok(_) = fs.close(file) - Ok(memtable.from_entries(entries, max_size)) -} - -fn read_entries( - file: Pid, - entries: Map(Int, MemTableEntry), -) -> Result(Map(Int, MemTableEntry), file.Reason) { - case fs.read(file, header_size) { - read.Ok(<<key_hash:128, key_size:16, file_id:128, offset:32>>) -> { - let assert read.Ok(key_string) = fs.read(file, key_size) - let #(_key, entry) = - memtable.bitstring_to_entry(<< - key_hash:128, - key_size:16, - file_id:128, - offset:32, - key_string:bit_string, - >>) - let entries = map.insert(entries, key_hash, entry) - read_entries(file, entries) - } - read.Eof -> Ok(entries) - read.Error(reason) -> Error(reason) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam deleted file mode 100644 index 8711085f8f6..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/kv/value.gleam +++ /dev/null @@ -1,206 +0,0 @@ -//// Store the information of the values for kv. -//// -//// The events stored in the file are in the following format: -//// - 4 bytes: the size of the event -//// - 1 byte: 0 if the event is not deleted, 1 if it is -//// - n bytes: the event -//// -//// The KV system is split into two parts: the key store and the value store. -//// The file is related to the value store. As we said it's a file with the -//// content marking the size of the value, if it's deleted and the value itself. -//// -//// The file is append only. When a value is written, it's appended to the end -//// of the file. When a value is deleted, it's not deleted from the file, it's -//// marked as deleted. When a value is updated, it's deleted and a new value is -//// appended to the end of the file. - -import gleam/bit_string -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/option.{None, Option, Some} -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read -import ream/uuid - -pub const value_size_bits = 32 - -pub type Reason { - CapacityExceeded -} - -/// The information for a value. The fields are: -/// - `offset`: the offset of the value in the file. -/// - `deleted`: if the value is deleted. -/// - `data`: the value. It can be `None` if we didn't read the value yet. -/// - `file_id`: the id of the file where the value is stored. -pub type Value { - Value(offset: Int, deleted: Bool, data: Option(BitString), file_id: Int) -} - -/// The information for the kv file. The fields are: -/// - `id`: the id of the file. It's intended to be a UUID but it's stored as an Int. -/// - `handler`: the file handler to read and write values. -/// - `size`: the size of the file. -/// - `max_size`: the maximum size of the file. -/// - `file_path`: the path of the file. -pub type ValueFile { - ValueFile(id: Int, handler: Pid, size: Int, max_size: Int, file_path: String) -} - -/// The information for the kv file. The fields are: -/// - `file_id`: the id of the file. It's intended to be a UUID but it's stored as an Int. -/// - `size`: the size of the file. -/// - `entries`: the number of entries in the file. -/// - `deleted`: the number of deleted entries in the file. -pub type ValueFileInfo { - ValueFileInfo( - file_id: Int, - size: Int, - max_size: Int, - entries: Int, - deleted: Int, - ) -} - -/// Create a new kv file. It creates a new file with a random UUID as the -/// path for finding the file. -/// -/// For example, if the UUID is `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, the -/// file will be created in the following path: -/// `base_path/f81d4fae/7dec/11d0/a765/00a0c91e6bf6`. -pub fn create( - base_path: String, - max_size: Int, -) -> Result(ValueFile, file.Reason) { - let file_id = uuid.to_int(uuid.new()) - let file_name = get_file_name(base_path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - use file_pid <- try(fs.open(file_name, [fs.Read, fs.Write])) - Ok(ValueFile(file_id, file_pid, 0, max_size, file_name)) -} - -fn get_file_name(base_path: String, file_id: Int) -> String { - fs.join([base_path, ..uuid.parts(uuid.from_int(file_id))]) -} - -/// Open a kv file. It opens the file with the given file id. -/// If the file doesn't exist, it is creating it. The main difference -/// with `create` is that `open` doesn't generate a new UUID. -/// It returns the kv file with the file handler and the file size. -pub fn open( - path: String, - file_id: Int, - max_size: Int, -) -> Result(ValueFile, file.Reason) { - let file_name = get_file_name(path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - let assert Ok(file_pid) = fs.open(file_name, [fs.Read, fs.Write]) - let assert Ok(file_info) = file.file_info(file_name) - Ok(ValueFile(file_id, file_pid, file_info.size, max_size, file_name)) -} - -/// Close a kv file. It closes the file handler. -pub fn close(vfile: ValueFile) -> Result(Nil, file.Reason) { - let assert Ok(_) = fs.close(vfile.handler) - Ok(Nil) -} - -/// Write a value to the kv file. It writes the value in the following -/// format: -/// - 4 bytes: the size of the value -/// - 1 byte: 0 if the value is not deleted, 1 if it is -/// - n bytes: the value -/// It returns the updated kv file with the new size. -pub fn write_value(vfile: ValueFile, value: Value) -> Result(ValueFile, Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let value_size_bits = value_size_bits - // end FIXME - let value_size_bytes = value_size_bits / 8 - let assert Some(data) = value.data - let data_size = bit_string.byte_size(data) + value_size_bytes + 1 - let deleted = case value.deleted { - True -> 1 - False -> 0 - } - let packed_data = << - data_size:size(value_size_bits), - deleted:8, - data:bit_string, - >> - let assert Ok(offset) = fs.position(vfile.handler, fs.Bof(value.offset)) - case offset + data_size > vfile.max_size { - True -> Error(CapacityExceeded) - False -> { - let assert Ok(_) = fs.write(vfile.handler, packed_data) - case offset + data_size > vfile.size { - True -> Ok(ValueFile(..vfile, size: offset + data_size)) - False -> Ok(vfile) - } - } - } -} - -pub fn write( - vfile: ValueFile, - value: BitString, -) -> Result(#(ValueFile, Value), Reason) { - let value = Value(vfile.size, False, Some(value), vfile.id) - use vfile <- try(write_value(vfile, value)) - Ok(#(vfile, Value(..value, data: None))) -} - -/// Delete a value from the kv file. It marks the value as deleted. -/// It returns the updated kv file with the new size. -pub fn delete(vfile: ValueFile, value: Value) -> Result(ValueFile, Reason) { - use value <- try(read(vfile, value.offset)) - write_value(vfile, Value(..value, deleted: True)) -} - -/// Read a value from the kv file. It reads the value and returns it as -/// a BitString with the following format: -/// - 4 bytes: the size of the value -/// - 1 byte: 0 if the value is not deleted, 1 if it is -/// - n bytes: the value -pub fn read(vfile: ValueFile, offset: Int) -> Result(Value, Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let value_size_bits = value_size_bits - // end FIXME - let value_size_bytes = value_size_bits / 8 - let assert Ok(_) = fs.position(vfile.handler, fs.Bof(offset)) - let assert read.Ok(<<size:size(value_size_bits), deleted:8>>) = - fs.read(vfile.handler, value_size_bytes + 1) - let content_size = size - value_size_bytes - 1 - let assert read.Ok(data) = fs.read(vfile.handler, content_size) - let deleted = case deleted { - 0 -> False - 1 -> True - } - Ok(Value(offset, deleted, Some(data), vfile.id)) -} - -pub fn get_file_info(vfile: ValueFile) -> ValueFileInfo { - let assert Ok(_) = fs.position(vfile.handler, fs.Bof(0)) - let assert Ok(#(entries, deleted)) = - get_entries_and_deleted(vfile.handler, #(0, 0)) - ValueFileInfo(vfile.id, vfile.size, vfile.max_size, entries, deleted) -} - -fn get_entries_and_deleted( - handler: Pid, - acc: #(Int, Int), -) -> Result(#(Int, Int), file.Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let value_size_bits = value_size_bits - // end FIXME - let value_size_bytes = value_size_bits / 8 - case fs.read(handler, value_size_bytes + 1) { - read.Ok(<<size:size(value_size_bits), deleted:8>>) -> { - let payload_size = size - value_size_bytes - 1 - let assert Ok(_) = fs.position(handler, fs.Cur(payload_size)) - get_entries_and_deleted(handler, #(acc.0 + 1, acc.1 + deleted)) - } - read.Eof -> Ok(acc) - read.Error(reason) -> Error(reason) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam deleted file mode 100644 index 7d40439966f..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream.gleam +++ /dev/null @@ -1,139 +0,0 @@ -import gleam/bit_string -import gleam/erlang/file -import gleam/iterator -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/stream/event.{Event, EventFile} -import ream/storage/stream/index.{Index, IndexFile} - -pub type Stream { - Stream( - name: String, - index: IndexFile, - active_file: Option(EventFile), - files: Map(Int, EventFile), - base_path: String, - ) -} - -pub fn get_base_path(path: String, name: String) -> String { - fs.join([path, "stream", name]) -} - -pub fn open(name: String, path path: String) -> Result(Stream, file.Reason) { - let base_path = fs.join([path, "stream", name]) - let assert Ok(index_file) = index.open(base_path) - use files <- try(do_open_files(index_file, base_path, map.new())) - let active_file = less_populated_file(map.values(files)) - Ok(Stream(name, index_file, active_file, files, base_path)) -} - -fn less_populated_file(files: List(EventFile)) -> Option(EventFile) { - files - |> list.fold( - with: fn(acc, file) { - let file_size = file.size - case acc { - Some(EventFile(_id, _handler, size, _file_id)) if file_size >= size -> - acc - _ -> Some(file) - } - }, - from: None, - ) -} - -pub fn close(stream: Stream) -> Result(Nil, file.Reason) { - let assert Ok(_) = index.close(stream.index) - - stream.files - |> map.values() - |> list.each(fn(file) { fs.close(file.handler) }) - - Ok(Nil) -} - -fn do_open_files( - index_file: IndexFile, - path: String, - acc: Map(Int, EventFile), -) -> Result(Map(Int, EventFile), file.Reason) { - case index.count(index_file) { - 0 -> Ok(acc) - num_of_events -> { - let _ = index.set_pos(index_file, 0) - - let files = - num_of_events - 1 - |> iterator.range(0, _) - |> iterator.fold( - from: acc, - with: fn(acc, _idx) { - let assert Ok(Index(_offset, _size, file_id)) = - index.get_next(index_file) - case map.has_key(acc, file_id) { - True -> acc - False -> { - let assert Ok(file) = event.open(path, file_id) - map.insert(acc, file_id, file) - } - } - }, - ) - - Ok(files) - } - } -} - -pub fn add_event( - stream: Stream, - event_content: BitString, -) -> Result(Stream, file.Reason) { - let event_size = bit_string.byte_size(event_content) - let #(stream, index) = case index.count(stream.index) { - 0 -> { - let assert Ok(stream_file) = event.create(stream.base_path) - let #(index, index_file) = - index.add(stream.index, event_size, stream_file.id) - let stream = - Stream( - ..stream, - index: index_file, - active_file: Some(stream_file), - files: map.insert(stream.files, stream_file.id, stream_file), - ) - #(stream, index) - } - _ -> { - let assert Some(active_file) = stream.active_file - let #(index, index_file) = - index.add(stream.index, event_size, active_file.id) - let stream = Stream(..stream, index: index_file) - #(stream, index) - } - } - - let assert Ok(file) = map.get(stream.files, index.file_id) - let event = Event(index.offset, event_content) - let stream_file = event.write(file, event) - - let files = map.insert(stream.files, stream_file.id, stream_file) - Ok(Stream(..stream, files: files)) -} - -pub fn get_event(stream: Stream, index: Int) -> Result(BitString, file.Reason) { - case index.count(stream.index) > index { - True -> { - let assert Ok(Index(offset, _size, file_id)) = - index.get(stream.index, index) - let assert Ok(file) = map.get(stream.files, file_id) - let assert Ok(Event(_offset, data)) = event.read(file, offset) - Ok(data) - } - False -> Error(file.Einval) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam deleted file mode 100644 index 14ab0e946dc..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/event.gleam +++ /dev/null @@ -1,95 +0,0 @@ -//// Store the information of the event that is being streamed. It is used to -//// write and read events from the file. -//// -//// The events stored in the file are in the following format: -//// - 4 bytes: the size of the event -//// - n bytes: the event - -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/bit_string -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read -import ream/storage/stream/index -import ream/uuid - -pub type Event { - Event(offset: Int, data: BitString) -} - -/// The information for the stream file. The fields are: -/// - `id`: the id of the file. It's intended to be a UUID but it's stored as an Int. -/// - `handler`: the file handler to read and write events. -/// - `size`: the size of the file. -/// - `file_path`: the path of the file. -pub type EventFile { - EventFile(id: Int, handler: Pid, size: Int, file_path: String) -} - -/// Create a new stream file. It creates a new file with a random UUID as the -/// path for finding the file. -/// -/// For example, if the UUID is `f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, the -/// file will be created in the following path: -/// `base_path/f81d4fae/7dec/11d0/a765/00a0c91e6bf6`. -pub fn create(base_path: String) -> Result(EventFile, file.Reason) { - let <<file_id:128>> = uuid.new() - let file_name = get_file_name(base_path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - use file_pid <- try(fs.open(file_name, [fs.Read, fs.Append])) - Ok(EventFile(file_id, file_pid, 0, file_name)) -} - -fn get_file_name(base_path: String, file_id: Int) -> String { - fs.join([base_path, ..uuid.parts(<<file_id:128>>)]) -} - -/// Open a stream file. It opens the file with the given file id. -/// If the file doesn't exist, it is creating it. The main difference -/// with `create` is that `open` doesn't generate a new UUID. -/// It returns the stream file with the file handler and the file size. -pub fn open(path: String, file_id: Int) -> Result(EventFile, file.Reason) { - let file_name = get_file_name(path, file_id) - let assert Ok(True) = fs.recursive_make_directory(fs.dirname(file_name)) - let assert Ok(file_pid) = fs.open(file_name, [fs.Read, fs.Append]) - let assert Ok(file_info) = file.file_info(file_name) - Ok(EventFile(file_id, file_pid, file_info.size, file_name)) -} - -/// Close a stream file. It closes the file handler. -pub fn close(stream_file: EventFile) -> Result(Nil, file.Reason) { - let assert Ok(_) = fs.close(stream_file.handler) - Ok(Nil) -} - -/// Write an event to the stream file. It writes the event in the following -/// format: -/// - 4 bytes: the size of the event -/// - n bytes: the event -/// It returns the updated stream file with the new size. -pub fn write(stream_file: EventFile, event: Event) -> EventFile { - let event_size_bits = index.event_size_bits - let event_size_bytes = event_size_bits / 8 - let data_size = bit_string.byte_size(event.data) + event_size_bytes - let data = <<data_size:size(event_size_bits), event.data:bit_string>> - let assert Ok(_) = fs.position(stream_file.handler, fs.Bof(event.offset)) - let assert Ok(_) = fs.write(stream_file.handler, data) - let data_size = bit_string.byte_size(data) - EventFile(..stream_file, size: stream_file.size + data_size) -} - -/// Read an event from the stream file. It reads the event and returns it as -/// a BitString with the following format: -/// - 4 bytes: the size of the event -/// - n bytes: the event -pub fn read(stream_file: EventFile, offset: Int) -> Result(Event, file.Reason) { - let event_size_bits = index.event_size_bits - let event_size_bytes = event_size_bits / 8 - let assert Ok(_) = fs.position(stream_file.handler, fs.Bof(offset)) - let assert read.Ok(<<size:size(event_size_bits)>>) = - fs.read(stream_file.handler, event_size_bytes) - let content_size = size - event_size_bytes - let assert read.Ok(data) = fs.read(stream_file.handler, content_size) - Ok(Event(offset, data)) -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam deleted file mode 100644 index 83f5104c935..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/storage/stream/index.gleam +++ /dev/null @@ -1,153 +0,0 @@ -import gleam/erlang/file -import gleam/erlang/process.{Pid} -import gleam/int -import gleam/result.{try} -import ream/storage/file as fs -import ream/storage/file/read - -/// the size of the offset in bytes, it's 6 bytes or 48 bits -/// letting us store offsets of 2^48 bytes (256TB) of data -pub const offset_size_bits = 48 - -/// event size (in bits) is storing letting us store events -/// of 2^24 bits (16MB) of data -pub const event_size_bits = 24 - -/// the size of the file id in bytes, it's 16 bytes or 128 bits -/// representing a 128 bit integer (UUID) -pub const file_id_size_bits = 128 - -/// the size of the index entry in bytes, it's 25 bytes because -/// we're storing the offset (6 bytes), the event size (3 bytes) -/// and the file id (16 bytes). -pub const index_size_bytes = 25 - -pub type Index { - Index(offset: Int, size: Int, file_id: Int) -} - -pub type IndexFile { - IndexFile(handler: Pid, size: Int, file_path: String) -} - -pub fn open(path: String) -> Result(IndexFile, file.Reason) { - let assert Ok(True) = fs.recursive_make_directory(path) - let index = fs.join([path, "index"]) - use index_pid <- try(fs.open(index, [fs.Read, fs.Append])) - use index_info <- try(file.file_info(index)) - Ok(IndexFile(index_pid, index_info.size, index)) -} - -pub fn close(index_file: IndexFile) -> Result(Nil, file.Reason) { - let assert Ok(_) = fs.close(index_file.handler) - Ok(Nil) -} - -pub fn add( - index_file: IndexFile, - event_size: Int, - file_id: Int, -) -> #(Index, IndexFile) { - let event_size_bytes = event_size_bits / 8 - let #(index_content, index) = case index_file.size { - 0 -> { - let index = Index(0, event_size + event_size_bytes, file_id) - #(index_binary(index), index) - } - _ -> { - let assert Ok(_) = - fs.position(index_file.handler, fs.Eof(-index_size_bytes)) - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - let assert Ok(<< - offset:size(offset_size_bits), - prev_size:size(event_size_bits), - _file_id:size(file_id_size_bits), - >>) = last_entry_for_file(index_file.handler, file_id) - let offset = offset + prev_size - let index = Index(offset, event_size + event_size_bytes, file_id) - #(index_binary(index), index) - } - } - let assert Ok(_) = fs.write(index_file.handler, index_content) - let index_file = - IndexFile(..index_file, size: index_file.size + index_size_bytes) - #(index, index_file) -} - -fn index_binary(index: Index) -> BitString { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - << - index.offset:size(offset_size_bits), - index.size:size(event_size_bits), - index.file_id:size(file_id_size_bits), - >> -} - -fn last_entry_for_file( - index_file: Pid, - file_id: Int, -) -> Result(BitString, file.Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - let assert read.Ok(<< - offset:size(offset_size_bits), - size:size(event_size_bits), - new_file_id:size(file_id_size_bits), - >>) = fs.read(index_file, index_size_bytes) - case new_file_id == file_id { - True -> Ok(index_binary(Index(offset, size, file_id))) - False -> { - case fs.position(index_file, fs.Cur(-2 * index_size_bytes)) { - Ok(_) -> last_entry_for_file(index_file, file_id) - Error(file.Einval) -> Ok(index_binary(Index(0, 0, file_id))) - } - } - } -} - -pub fn count(index_file: IndexFile) -> Int { - let assert Ok(result) = int.divide(index_file.size, index_size_bytes) - result -} - -pub fn set_pos(index_file: IndexFile, index: Int) -> Result(Int, file.Reason) { - fs.position(index_file.handler, fs.Bof(index * index_size_bytes)) -} - -pub fn get_next(index_file: IndexFile) -> Result(Index, file.Reason) { - // FIXME: https://github.com/gleam-lang/gleam/issues/2166 - let offset_size_bits = offset_size_bits - let event_size_bits = event_size_bits - let file_id_size_bits = file_id_size_bits - // end FIXME - case fs.read(index_file.handler, index_size_bytes) { - read.Ok(<< - offset:size(offset_size_bits), - size:size(event_size_bits), - file_id:size(file_id_size_bits), - >>) -> Ok(Index(offset, size, file_id)) - read.Eof -> Error(file.Espipe) - _ -> Error(file.Einval) - } -} - -pub fn get(index_file: IndexFile, index: Int) -> Result(Index, file.Reason) { - case count(index_file) > index { - True -> { - let assert Ok(_) = set_pos(index_file, index) - get_next(index_file) - } - False -> Error(file.Einval) - } -} diff --git a/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam b/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam deleted file mode 100644 index 03a489db8b2..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream/uuid.gleam +++ /dev/null @@ -1,48 +0,0 @@ -//// This module implements the UUID v4 generation algorithm. - -import gleam/int -import gleam/string - -pub fn new() -> BitString { - let <<u0:size(48), _:size(4), u1:size(12), _:size(2), u2:size(62)>> = - crypto_strong_rand_bytes(16) - - <<u0:size(48), 4:size(4), u1:size(12), 2:size(2), u2:size(62)>> -} - -pub fn to_string(uuid: BitString) -> String { - parts(uuid) - |> string.join(with: "-") -} - -pub fn to_int(uuid: BitString) -> Int { - let <<uuid_int:128>> = uuid - uuid_int -} - -pub fn from_int(uuid: Int) -> BitString { - <<uuid:128>> -} - -pub fn from_string(uuid: String) -> BitString { - let assert Ok(uuid_int) = - uuid - |> string.replace(each: "-", with: "") - |> int.base_parse(16) - - from_int(uuid_int) -} - -pub fn parts(uuid: BitString) -> List(String) { - let <<p1:32, p2:16, p3:16, p4:16, p5:48>> = uuid - [to_hex(p1, 8), to_hex(p2, 4), to_hex(p3, 4), to_hex(p4, 4), to_hex(p5, 12)] -} - -fn to_hex(n: Int, size: Int) -> String { - int.to_base16(n) - |> string.lowercase() - |> string.pad_left(to: size, with: "0") -} - -external fn crypto_strong_rand_bytes(Int) -> BitString = - "crypto" "strong_rand_bytes" diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl deleted file mode 100644 index 9120a478ea0..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file.erl +++ /dev/null @@ -1,123 +0,0 @@ --module(ream@storage@file). --compile([no_auto_import, nowarn_unused_vars]). - --export([do_open/2, open/2, read/2, close/1, write/2, dirname/1, basename/1, join/1, position/2, recursive_make_directory/1]). --export_type([endian/0, encoding_type/0, mode/0, location/0]). - --type endian() :: big | little. - --type encoding_type() :: unicode | - utf8 | - {utf16, endian()} | - {utf32, endian()} | - latin1. - --type mode() :: read | - write | - append | - exclusive | - raw | - binary | - {delayed_write, integer(), integer()} | - {read_ahead, integer()} | - compressed | - compressed_one | - {encoding, encoding_type()} | - ram | - sync | - directory. - --type location() :: {bof, integer()} | {cur, integer()} | {eof, integer()}. - --spec do_open(binary(), list(mode())) -> {ok, gleam@erlang@process:pid_()} | - {error, gleam@erlang@file:reason()}. -do_open(Field@0, Field@1) -> - file:open(Field@0, Field@1). - --spec open(binary(), list(mode())) -> {ok, gleam@erlang@process:pid_()} | - {error, gleam@erlang@file:reason()}. -open(Filename, Mode) -> - file:open(Filename, [binary | Mode]). - --spec read(gleam@erlang@process:pid_(), integer()) -> ream@storage@file@read:result(). -read(Field@0, Field@1) -> - file:read(Field@0, Field@1). - --spec close(gleam@erlang@process:pid_()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -close(Io_device) -> - case file:close(Io_device) of - ok -> - {ok, true}; - - {error, Reason} -> - {error, Reason} - end. - --spec write(gleam@erlang@process:pid_(), bitstring()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -write(Io_device, Data) -> - case file:write(Io_device, Data) of - ok -> - {ok, true}; - - {error, Reason} -> - {error, Reason} - end. - --spec dirname(binary()) -> binary(). -dirname(Field@0) -> - filename:dirname(Field@0). - --spec basename(binary()) -> binary(). -basename(Field@0) -> - filename:basename(Field@0). - --spec join(list(binary())) -> binary(). -join(Field@0) -> - filename:join(Field@0). - --spec position(gleam@erlang@process:pid_(), location()) -> {ok, integer()} | - {error, gleam@erlang@file:reason()}. -position(Field@0, Field@1) -> - file:position(Field@0, Field@1). - --spec recursive_make_directory(binary()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -recursive_make_directory(Path) -> - case gleam@erlang@file:is_directory(Path) of - {error, enoent} -> - Prev_dir = filename:dirname(Path), - _assert_subject = recursive_make_directory(Prev_dir), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/file"/utf8>>, - function => <<"recursive_make_directory"/utf8>>, - line => 95}) - end, - _assert_subject@1 = gleam_erlang_ffi:make_directory(Path), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/file"/utf8>>, - function => <<"recursive_make_directory"/utf8>>, - line => 96}) - end, - {ok, true}; - - {error, eexist} -> - {ok, true}; - - {ok, true} -> - {ok, true}; - - _ -> - {error, einval} - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl deleted file mode 100644 index 3cd71df7c31..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@close.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(ream@storage@file@close). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([result/0]). - --type result() :: ok | {error, gleam@erlang@file:reason()}. - - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl deleted file mode 100644 index ab021bd22bd..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@read.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(ream@storage@file@read). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([result/0]). - --type result() :: {ok, bitstring()} | eof | {error, gleam@erlang@file:reason()}. - - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl deleted file mode 100644 index 7bdc59d9767..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@file@write.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(ream@storage@file@write). --compile([no_auto_import, nowarn_unused_vars]). - --export_type([result/0]). - --type result() :: ok | {error, gleam@erlang@file:reason()}. - - diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl deleted file mode 100644 index 00b8caa6701..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv.erl +++ /dev/null @@ -1,901 +0,0 @@ --module(ream@storage@kv). --compile([no_auto_import, nowarn_unused_vars]). - --export([get/2, info/1, open/5, flush/1, close/1, set/3]). --export_type([mem_table_range/0, kv/0, kv_info/0]). - --type mem_table_range() :: {mem_table_range, - integer(), - integer(), - gleam@option:option(ream@storage@kv@memtable:mem_table())}. - --type kv() :: {kv, - binary(), - binary(), - gleam@map:map_(integer(), mem_table_range()), - gleam@option:option(integer()), - gleam@map:map_(integer(), ream@storage@kv@value:value_file()), - integer(), - integer(), - integer(), - integer()}. - --type kv_info() :: {kv_info, - binary(), - binary(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec new_id() -> integer(). -new_id() -> - ream@uuid:to_int(ream@uuid:new()). - --spec sstable_path(binary(), integer()) -> binary(). -sstable_path(Path, Id) -> - Parts = ream@uuid:parts(ream@uuid:from_int(Id)), - filename:join([Path, <<"key"/utf8>> | Parts]). - --spec find_range(kv(), integer(), integer()) -> {integer(), kv()}. -find_range(Kv, Key_hash, Max_size) -> - Max_memtables_loaded = erlang:element(8, Kv), - _assert_subject@2 = begin - _pipe = erlang:element(4, Kv), - _pipe@1 = gleam@map:to_list(_pipe), - gleam@list:map_fold( - _pipe@1, - {erlang:element(7, Kv), none}, - fun(Acc, Entry) -> - {Id, Range} = Entry, - {Loaded, Range_id} = Acc, - case {(Key_hash >= erlang:element(2, Range)) andalso (Key_hash - =< erlang:element(3, Range)), - erlang:element(4, Range)} of - {true, {some, _}} -> - {{Loaded, {some, Id}}, {Id, Range}}; - - {true, none} -> - _assert_subject = ream@storage@kv@sstable:load( - sstable_path(erlang:element(2, Kv), Id), - Max_size - ), - {ok, Memtable} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"find_range"/utf8>>, - line => 174}) - end, - {{Loaded + 1, {some, Id}}, - {Id, erlang:setelement(4, Range, {some, Memtable})}}; - - {false, {some, Memtable@1}} when Loaded >= Max_memtables_loaded -> - _assert_subject@1 = ream@storage@kv@sstable:flush( - Memtable@1, - sstable_path(erlang:element(2, Kv), Id) - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"find_range"/utf8>>, - line => 182}) - end, - {{Loaded - 1, Range_id}, - {Id, erlang:setelement(4, Range, none)}}; - - {false, _} -> - {Acc, {Id, Range}} - end - end - ) - end, - {{Loaded@1, {some, Range_id@1}}, Range_list} = case _assert_subject@2 of - {{_, {some, _}}, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"find_range"/utf8>>, - line => 160}) - end, - {Range_id@1, - erlang:setelement( - 7, - erlang:setelement(4, Kv, gleam@map:from_list(Range_list)), - Loaded@1 - )}. - --spec get(kv(), binary()) -> {{ok, bitstring()} | {error, nil}, kv()}. -get(Kv, Key) -> - Key_hash = erlang:phash2(Key), - {Range_id, Kv@1} = find_range(Kv, Key_hash, erlang:element(9, Kv)), - _assert_subject = gleam@map:get(erlang:element(4, Kv@1), Range_id), - {ok, Range} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"get"/utf8>>, - line => 264}) - end, - _assert_subject@1 = erlang:element(4, Range), - {some, Memtable} = case _assert_subject@1 of - {some, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"get"/utf8>>, - line => 265}) - end, - case ream@storage@kv@memtable:get(Memtable, Key) of - {ok, Value} -> - _assert_subject@2 = gleam@map:get( - erlang:element(6, Kv@1), - erlang:element(5, Value) - ), - {ok, Vfile} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"get"/utf8>>, - line => 268}) - end, - case ream@storage@kv@value:read(Vfile, erlang:element(2, Value)) of - {ok, {value, _, false, {some, Data}, _}} -> - {{ok, Data}, Kv@1}; - - _ -> - {{error, nil}, Kv@1} - end; - - {error, _} -> - {{error, nil}, Kv@1} - end. - --spec split( - kv(), - integer(), - integer(), - mem_table_range(), - ream@storage@kv@memtable:mem_table() -) -> kv(). -split(Kv, Key_hash, Range_id, Range, Memtable) -> - {Memtable_low, Memtable_high, Pivot} = ream@storage@kv@memtable:split( - Memtable, - Key_hash - ), - {mem_table_range, Lower, Upper, _} = case Range of - {mem_table_range, _, _, _} -> Range; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"split"/utf8>>, - line => 332}) - end, - {Memtable_range_low, Memtable_range_high} = case erlang:element( - 3, - Memtable_low - ) - >= erlang:element(3, Memtable_high) of - false -> - {{mem_table_range, Lower, Pivot - 1, {some, Memtable_low}}, - {mem_table_range, Pivot, Upper, none}}; - - true -> - {{mem_table_range, Lower, Pivot - 1, none}, - {mem_table_range, Pivot, Upper, {some, Memtable_high}}} - end, - Memtable_high_id = new_id(), - Memtable_ranges = begin - _pipe = erlang:element(4, Kv), - _pipe@1 = gleam@map:insert(_pipe, Range_id, Memtable_range_low), - gleam@map:insert(_pipe@1, Memtable_high_id, Memtable_range_high) - end, - _assert_subject = ream@storage@kv@sstable:flush( - Memtable_high, - sstable_path(erlang:element(2, Kv), Memtable_high_id) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"split"/utf8>>, - line => 351}) - end, - _assert_subject@1 = ream@storage@kv@sstable:flush( - Memtable_low, - sstable_path(erlang:element(2, Kv), Range_id) - ), - {ok, true} = case _assert_subject@1 of - {ok, true} -> _assert_subject@1; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"split"/utf8>>, - line => 354}) - end, - erlang:setelement(4, Kv, Memtable_ranges). - --spec delete_value(kv(), ream@storage@kv@value:value()) -> {ok, kv()} | - {error, nil}. -delete_value(Kv, Value) -> - File_id = erlang:element(5, Value), - _assert_subject = gleam@map:get(erlang:element(6, Kv), File_id), - {ok, Vfile} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"delete_value"/utf8>>, - line => 398}) - end, - _assert_subject@1 = ream@storage@kv@value:delete(Vfile, Value), - {ok, Vfile@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"delete_value"/utf8>>, - line => 399}) - end, - Values = gleam@map:insert(erlang:element(6, Kv), File_id, Vfile@1), - {ok, erlang:setelement(6, Kv, Values)}. - --spec info(kv()) -> kv_info(). -info(Kv) -> - {kv_info, - erlang:element(2, Kv), - erlang:element(3, Kv), - gleam@map:size(erlang:element(6, Kv)), - gleam@map:fold( - erlang:element(6, Kv), - 0, - fun(Acc, _, Value_file) -> Acc + erlang:element(4, Value_file) end - ), - gleam@map:size(erlang:element(4, Kv)), - erlang:element(7, Kv), - gleam@map:fold( - erlang:element(4, Kv), - 0, - fun(Acc@1, _, Memtable_range) -> - case erlang:element(4, Memtable_range) of - {some, Memtable} -> - Acc@1 + erlang:element(3, Memtable); - - none -> - Acc@1 - end - end - ), - erlang:element(8, Kv), - erlang:element(9, Kv), - erlang:element(10, Kv)}. - --spec read_memtable_ranges( - gleam@erlang@process:pid_(), - binary(), - integer(), - gleam@map:map_(integer(), mem_table_range()) -) -> gleam@map:map_(integer(), mem_table_range()). -read_memtable_ranges(Kv, Path, Max_size, Acc) -> - case file:read(Kv, 48) of - {ok, <<Lower:128, Upper:128, Id:128>>} -> - Range = {mem_table_range, Lower, Upper, none}, - read_memtable_ranges( - Kv, - Path, - Max_size, - gleam@map:insert(Acc, Id, Range) - ); - - eof -> - Acc; - - {error, _} -> - _assert_subject = ream@storage@file:close(Kv), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_memtable_ranges"/utf8>>, - line => 119}) - end, - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_memtable_ranges"/utf8>>, - line => 121}) - end. - --spec read_values( - gleam@erlang@process:pid_(), - binary(), - gleam@option:option(integer()), - integer(), - gleam@map:map_(integer(), ream@storage@kv@value:value_file()) -) -> {gleam@option:option(integer()), - gleam@map:map_(integer(), ream@storage@kv@value:value_file())}. -read_values(Kv, Path, Last_file_id, Max_value_size, Acc) -> - case file:read(Kv, 16) of - {ok, <<File_id:128>>} -> - _assert_subject = ream@storage@kv@value:open( - Path, - File_id, - Max_value_size - ), - {ok, Value_file} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_values"/utf8>>, - line => 135}) - end, - read_values( - Kv, - Path, - {some, File_id}, - Max_value_size, - gleam@map:insert(Acc, File_id, Value_file) - ); - - eof -> - {Last_file_id, Acc}; - - {error, _} -> - _assert_subject@1 = ream@storage@file:close(Kv), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_values"/utf8>>, - line => 146}) - end, - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"ream/storage/kv"/utf8>>, - function => <<"read_values"/utf8>>, - line => 148}) - end. - --spec open(binary(), binary(), integer(), integer(), integer()) -> kv(). -open(Path, Name, Max_memtables_loaded, Max_memtable_size, Max_value_size) -> - Path@1 = filename:join([Path, <<"kv"/utf8>>, Name]), - Key_index_file = filename:join([Path@1, <<"key"/utf8>>, <<"index"/utf8>>]), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(Key_index_file) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 60}) - end, - _assert_subject@1 = ream@storage@file:open(Key_index_file, [read, write]), - {ok, Kv} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 61}) - end, - Ranges = read_memtable_ranges( - Kv, - filename:join([Path@1, <<"key"/utf8>>]), - Max_memtable_size, - gleam@map:new() - ), - {Memtables_loaded, Ranges@2} = case gleam@map:size(Ranges) =:= 0 of - true -> - Memtable = ream@storage@kv@memtable:new(Max_memtable_size), - Ranges@1 = begin - _pipe = [{new_id(), - {mem_table_range, - 0, - 340282366920938463463374607431768211455, - {some, Memtable}}}], - gleam@map:from_list(_pipe) - end, - {1, Ranges@1}; - - false -> - {0, Ranges} - end, - _assert_subject@2 = ream@storage@file:close(Kv), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 79}) - end, - Value_index_file = filename:join( - [Path@1, <<"value"/utf8>>, <<"index"/utf8>>] - ), - _assert_subject@3 = ream@storage@file:recursive_make_directory( - filename:dirname(Value_index_file) - ), - {ok, true} = case _assert_subject@3 of - {ok, true} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 82}) - end, - _assert_subject@4 = ream@storage@file:open(Value_index_file, [read, write]), - {ok, Kv@1} = case _assert_subject@4 of - {ok, _} -> _assert_subject@4; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 84}) - end, - {Active_value_file, Values} = read_values( - Kv@1, - filename:join([Path@1, <<"value"/utf8>>]), - none, - Max_value_size, - gleam@map:new() - ), - _assert_subject@5 = ream@storage@file:close(Kv@1), - {ok, _} = case _assert_subject@5 of - {ok, _} -> _assert_subject@5; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"ream/storage/kv"/utf8>>, - function => <<"open"/utf8>>, - line => 87}) - end, - {kv, - Path@1, - Name, - Ranges@2, - Active_value_file, - Values, - Memtables_loaded, - Max_memtables_loaded, - Max_memtable_size, - Max_value_size}. - --spec write_memtable_ranges( - gleam@erlang@process:pid_(), - binary(), - list({integer(), mem_table_range()}) -) -> {ok, nil} | {error, nil}. -write_memtable_ranges(Kv_file, Base_path, Memtable_ranges) -> - case Memtable_ranges of - [{Id, {mem_table_range, Lower, Upper, {some, Memtable}}} | Rest] -> - _assert_subject = ream@storage@kv@sstable:flush( - Memtable, - sstable_path(Base_path, Id) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_memtable_ranges"/utf8>>, - line => 239}) - end, - _assert_subject@1 = ream@storage@file:write( - Kv_file, - <<Lower:128, Upper:128, Id:128>> - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_memtable_ranges"/utf8>>, - line => 240}) - end, - write_memtable_ranges(Kv_file, Base_path, Rest); - - [{Id@1, {mem_table_range, Lower@1, Upper@1, none}} | Rest@1] -> - _assert_subject@2 = ream@storage@file:write( - Kv_file, - <<Lower@1:128, Upper@1:128, Id@1:128>> - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_memtable_ranges"/utf8>>, - line => 244}) - end, - write_memtable_ranges(Kv_file, Base_path, Rest@1); - - [] -> - {ok, nil} - end. - --spec write_values(gleam@erlang@process:pid_(), list(integer())) -> {ok, nil} | - {error, nil}. -write_values(Kv, Values) -> - case Values of - [Id | Rest] -> - _assert_subject = ream@storage@file:write(Kv, <<Id:128>>), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"write_values"/utf8>>, - line => 254}) - end, - write_values(Kv, Rest); - - [] -> - {ok, nil} - end. - --spec flush(kv()) -> {ok, nil} | {error, nil}. -flush(Kv) -> - Key_index_file = filename:join( - [erlang:element(2, Kv), <<"key"/utf8>>, <<"index"/utf8>>] - ), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(Key_index_file) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 215}) - end, - _assert_subject@1 = ream@storage@file:open(Key_index_file, [write]), - {ok, Kv_file} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 216}) - end, - Memtable_ranges = gleam@map:to_list(erlang:element(4, Kv)), - _assert_subject@2 = write_memtable_ranges( - Kv_file, - erlang:element(2, Kv), - Memtable_ranges - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 218}) - end, - _assert_subject@3 = ream@storage@file:close(Kv_file), - {ok, _} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 220}) - end, - Value_index_file = filename:join( - [erlang:element(2, Kv), <<"value"/utf8>>, <<"index"/utf8>>] - ), - _assert_subject@4 = ream@storage@file:recursive_make_directory( - filename:dirname(Value_index_file) - ), - {ok, true} = case _assert_subject@4 of - {ok, true} -> _assert_subject@4; - _assert_fail@4 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@4, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 223}) - end, - _assert_subject@5 = ream@storage@file:open(Value_index_file, [write]), - {ok, Kv_file@1} = case _assert_subject@5 of - {ok, _} -> _assert_subject@5; - _assert_fail@5 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@5, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 225}) - end, - _assert_subject@6 = write_values( - Kv_file@1, - gleam@map:keys(erlang:element(6, Kv)) - ), - {ok, _} = case _assert_subject@6 of - {ok, _} -> _assert_subject@6; - _assert_fail@6 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@6, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 226}) - end, - _assert_subject@7 = ream@storage@file:close(Kv_file@1), - {ok, _} = case _assert_subject@7 of - {ok, _} -> _assert_subject@7; - _assert_fail@7 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@7, - module => <<"ream/storage/kv"/utf8>>, - function => <<"flush"/utf8>>, - line => 227}) - end, - {ok, nil}. - --spec close(kv()) -> {ok, nil} | {error, nil}. -close(Kv) -> - _assert_subject = flush(Kv), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"close"/utf8>>, - line => 205}) - end, - _pipe = gleam@map:values(erlang:element(6, Kv)), - gleam@list:each(_pipe, fun(V) -> ream@storage@kv@value:close(V) end), - {ok, nil}. - --spec set(kv(), binary(), bitstring()) -> kv(). -set(Kv, Key, Value) -> - Key_hash = erlang:phash2(Key), - {Range_id, Kv@1} = find_range(Kv, Key_hash, erlang:element(9, Kv)), - _assert_subject = gleam@map:get(erlang:element(4, Kv@1), Range_id), - {ok, Range} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 284}) - end, - _assert_subject@1 = erlang:element(4, Range), - {some, Memtable} = case _assert_subject@1 of - {some, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 285}) - end, - Kv@2 = case erlang:element(5, Kv@1) of - {some, _} -> - Kv@1; - - none -> - _assert_subject@2 = ream@storage@kv@value:create( - filename:join([erlang:element(2, Kv@1), <<"value"/utf8>>]), - erlang:element(10, Kv@1) - ), - {ok, Vfile} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 289}) - end, - erlang:setelement( - 6, - erlang:setelement(5, Kv@1, {some, erlang:element(2, Vfile)}), - gleam@map:insert( - erlang:element(6, Kv@1), - erlang:element(2, Vfile), - Vfile - ) - ) - end, - case ream@storage@kv@memtable:get(Memtable, Key) of - {ok, Old_value} -> - case store_value(Kv@2, Key, Range_id, Range, Memtable, Value) of - {ok, Kv@3} -> - Kv@3; - - {error, capacity_exceeded} -> - Kv@4 = split(Kv@2, Key_hash, Range_id, Range, Memtable), - set(Kv@4, Key, Value) - end, - _assert_subject@3 = delete_value(Kv@2, Old_value), - {ok, Kv@5} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv"/utf8>>, - function => <<"set"/utf8>>, - line => 308}) - end, - Kv@5; - - {error, nil} -> - case store_value(Kv@2, Key, Range_id, Range, Memtable, Value) of - {ok, Kv@6} -> - Kv@6; - - {error, capacity_exceeded} -> - Kv@7 = split(Kv@2, Key_hash, Range_id, Range, Memtable), - set(Kv@7, Key, Value) - end - end. - --spec store_value( - kv(), - binary(), - integer(), - mem_table_range(), - ream@storage@kv@memtable:mem_table(), - bitstring() -) -> {ok, kv()} | {error, ream@storage@kv@memtable:reason()}. -store_value(Kv, Key, Range_id, Range, Memtable, Value_data) -> - _assert_subject = erlang:element(5, Kv), - {some, File_id} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv"/utf8>>, - function => <<"store_value"/utf8>>, - line => 368}) - end, - _assert_subject@1 = gleam@map:get(erlang:element(6, Kv), File_id), - {ok, Vfile} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv"/utf8>>, - function => <<"store_value"/utf8>>, - line => 369}) - end, - case ream@storage@kv@value:write(Vfile, Value_data) of - {ok, {Vfile@1, Value}} -> - gleam@result:'try'( - ream@storage@kv@memtable:set(Memtable, Key, Value), - fun(Memtable@1) -> - Range@1 = erlang:setelement(4, Range, {some, Memtable@1}), - {ok, - erlang:setelement( - 4, - erlang:setelement( - 6, - erlang:setelement( - 5, - Kv, - {some, erlang:element(2, Vfile@1)} - ), - gleam@map:insert( - erlang:element(6, Kv), - erlang:element(2, Vfile@1), - Vfile@1 - ) - ), - gleam@map:insert( - erlang:element(4, Kv), - Range_id, - Range@1 - ) - )} - end - ); - - {error, capacity_exceeded} -> - _assert_subject@2 = ream@storage@kv@value:create( - filename:join([erlang:element(2, Kv), <<"value"/utf8>>]), - erlang:element(10, Kv) - ), - {ok, Vfile@2} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv"/utf8>>, - function => <<"store_value"/utf8>>, - line => 384}) - end, - _pipe = erlang:setelement( - 6, - erlang:setelement(5, Kv, {some, erlang:element(2, Vfile@2)}), - gleam@map:insert( - erlang:element(6, Kv), - erlang:element(2, Vfile@2), - Vfile@2 - ) - ), - store_value(_pipe, Key, Range_id, Range, Memtable, Value_data) - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl deleted file mode 100644 index dd2140c0085..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@memtable.erl +++ /dev/null @@ -1,277 +0,0 @@ --module(ream@storage@kv@memtable). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, bitstring_to_entry/1, search_pivot/1, get_bounds/1, hash/1, entry_to_bitstring/1, contains/2, get/2, set/3, delete/2, from_entries/2, split/2]). --export_type([mem_table/0, mem_table_entry/0, reason/0]). - --type mem_table() :: {mem_table, - gleam@map:map_(integer(), mem_table_entry()), - integer(), - integer()}. - --type mem_table_entry() :: {mem_table_entry, - binary(), - ream@storage@kv@value:value()}. - --type reason() :: capacity_exceeded. - --spec new(integer()) -> mem_table(). -new(Max_size) -> - {mem_table, gleam@map:new(), 0, Max_size}. - --spec bitstring_to_entry(bitstring()) -> {integer(), mem_table_entry()}. -bitstring_to_entry(Bitstring) -> - <<Key_hash:128, _:16, File_id:128, File_offset:32, Key_string/bitstring>> = Bitstring, - _assert_subject = gleam@bit_string:to_string(Key_string), - {ok, Key} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/memtable"/utf8>>, - function => <<"bitstring_to_entry"/utf8>>, - line => 96}) - end, - Value = {value, File_offset, false, none, File_id}, - {Key_hash, {mem_table_entry, Key, Value}}. - --spec search_pivot(mem_table()) -> integer(). -search_pivot(Mem_table) -> - Entries = erlang:element(2, Mem_table), - Keys = gleam@map:keys(Entries), - Entries_count = gleam@map:size(Entries), - {_, [Pivot | _]} = gleam@list:split(Keys, Entries_count div 2), - Pivot. - --spec get_lower(integer(), integer()) -> integer(). -get_lower(Lower_bound, Key) -> - case Lower_bound of - 0 -> - Key; - - Lower_bound@1 when Key < Lower_bound@1 -> - Key; - - Lower_bound@2 -> - Lower_bound@2 - end. - --spec get_higher(integer(), integer()) -> integer(). -get_higher(Higher_bound, Key) -> - case Higher_bound of - 0 -> - Key; - - Higher_bound@1 when Key > Higher_bound@1 -> - Key; - - Higher_bound@2 -> - Higher_bound@2 - end. - --spec get_bounds(mem_table()) -> {integer(), integer()}. -get_bounds(Mem_table) -> - case gleam@map:to_list(erlang:element(2, Mem_table)) of - [] -> - {0, 0}; - - [{K, _} | Entries] -> - gleam@list:fold( - Entries, - {K, K}, - fun(Acc, Entry) -> - {get_lower(erlang:element(1, Acc), erlang:element(1, Entry)), - get_higher( - erlang:element(2, Acc), - erlang:element(1, Entry) - )} - end - ) - end. - --spec hash(binary()) -> integer(). -hash(Field@0) -> - erlang:phash2(Field@0). - --spec entry_to_bitstring(mem_table_entry()) -> bitstring(). -entry_to_bitstring(Entry) -> - Key_hash = erlang:phash2(erlang:element(2, Entry)), - Key_string = gleam@bit_string:from_string(erlang:element(2, Entry)), - Key_size = gleam@bit_string:byte_size(Key_string), - File_id = erlang:element(5, erlang:element(3, Entry)), - File_offset = erlang:element(2, erlang:element(3, Entry)), - <<Key_hash:128, - Key_size:16, - File_id:128, - File_offset:32, - Key_string/bitstring>>. - --spec contains(mem_table(), binary()) -> boolean(). -contains(Mem_table, Key) -> - gleam@map:has_key(erlang:element(2, Mem_table), erlang:phash2(Key)). - --spec get(mem_table(), binary()) -> {ok, ream@storage@kv@value:value()} | - {error, nil}. -get(Mem_table, Key) -> - case gleam@map:get(erlang:element(2, Mem_table), erlang:phash2(Key)) of - {ok, {mem_table_entry, Stored_key, Value}} when Key =:= Stored_key -> - {ok, Value}; - - {ok, {mem_table_entry, _, _}} -> - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"ream/storage/kv/memtable"/utf8>>, - function => <<"get"/utf8>>, - line => 183}); - - {error, nil} -> - {error, nil} - end. - --spec calculate_size(mem_table_entry()) -> integer(). -calculate_size(Entry) -> - gleam@bit_string:byte_size(entry_to_bitstring(Entry)). - --spec set(mem_table(), binary(), ream@storage@kv@value:value()) -> {ok, - mem_table()} | - {error, reason()}. -set(Mem_table, Key, Value) -> - Key_hash = erlang:phash2(Key), - case gleam@map:get(erlang:element(2, Mem_table), Key_hash) of - {error, nil} -> - Entry = {mem_table_entry, Key, Value}, - Entry_size = calculate_size(Entry), - Current_size = erlang:element(3, Mem_table) + Entry_size, - case Current_size > erlang:element(4, Mem_table) of - true -> - {error, capacity_exceeded}; - - false -> - {ok, - erlang:setelement( - 3, - erlang:setelement( - 2, - Mem_table, - gleam@map:insert( - erlang:element(2, Mem_table), - Key_hash, - Entry - ) - ), - Current_size - )} - end; - - {ok, Old_entry} -> - Old_entry_size = calculate_size(Old_entry), - Entry@1 = erlang:setelement(3, Old_entry, Value), - Current_entry_size = calculate_size(Entry@1), - Mem_table_size = (erlang:element(3, Mem_table) + Current_entry_size) - - Old_entry_size, - case Mem_table_size > erlang:element(4, Mem_table) of - true -> - {error, capacity_exceeded}; - - false -> - {ok, - erlang:setelement( - 3, - erlang:setelement( - 2, - Mem_table, - gleam@map:insert( - erlang:element(2, Mem_table), - Key_hash, - Entry@1 - ) - ), - Mem_table_size - )} - end - end. - --spec delete(mem_table(), binary()) -> mem_table(). -delete(Mem_table, Key) -> - Key_hash = erlang:phash2(Key), - case gleam@map:get(erlang:element(2, Mem_table), Key_hash) of - {error, nil} -> - Mem_table; - - {ok, Entry} -> - erlang:setelement( - 3, - erlang:setelement( - 2, - Mem_table, - gleam@map:delete(erlang:element(2, Mem_table), Key_hash) - ), - erlang:element(3, Mem_table) - calculate_size(Entry) - ) - end. - --spec calculate_entries_size(gleam@map:map_(integer(), mem_table_entry())) -> integer(). -calculate_entries_size(Entries) -> - gleam@map:fold( - Entries, - 0, - fun(Acc, _, Entry) -> Acc + calculate_size(Entry) end - ). - --spec from_entries(gleam@map:map_(integer(), mem_table_entry()), integer()) -> mem_table(). -from_entries(Entries, Max_size) -> - Size = calculate_entries_size(Entries), - {mem_table, Entries, Size, Max_size}. - --spec split(mem_table(), integer()) -> {mem_table(), mem_table(), integer()}. -split(Mem_table, Pivot) -> - {Low_entries, High_entries} = begin - _pipe = erlang:element(2, Mem_table), - _pipe@1 = gleam@map:to_list(_pipe), - gleam@list:partition( - _pipe@1, - fun(Entry) -> erlang:element(1, Entry) < Pivot end - ) - end, - Low_entries@1 = gleam@map:from_list(Low_entries), - Low = erlang:setelement( - 3, - erlang:setelement(2, Mem_table, Low_entries@1), - calculate_entries_size(Low_entries@1) - ), - High_entries@1 = gleam@map:from_list(High_entries), - High = erlang:setelement( - 3, - erlang:setelement(2, Mem_table, High_entries@1), - calculate_entries_size(High_entries@1) - ), - case {erlang:element(3, Low) >= erlang:element(3, High), - gleam@map:get(erlang:element(2, High), Pivot)} of - {true, _} -> - {Low, High, Pivot}; - - {false, {error, nil}} -> - {Low, High, Pivot + 1}; - - {false, {ok, Entry@1}} -> - High@1 = erlang:setelement( - 3, - erlang:setelement( - 2, - High, - gleam@map:delete(erlang:element(2, High), Pivot) - ), - erlang:element(3, High) - calculate_size(Entry@1) - ), - Low@1 = erlang:setelement( - 3, - erlang:setelement( - 2, - Low, - gleam@map:insert(erlang:element(2, Low), Pivot, Entry@1) - ), - erlang:element(3, Low) + calculate_size(Entry@1) - ), - {Low@1, High@1, Pivot + 1} - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl deleted file mode 100644 index c8800712fc5..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@sstable.erl +++ /dev/null @@ -1,136 +0,0 @@ --module(ream@storage@kv@sstable). --compile([no_auto_import, nowarn_unused_vars]). - --export([flush/2, load/2]). - --spec flush(ream@storage@kv@memtable:mem_table(), binary()) -> {ok, boolean()} | - {error, gleam@erlang@file:reason()}. -flush(Mem_table, Path) -> - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(Path) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 11}) - end, - _assert_subject@1 = ream@storage@file:open(Path, [write]), - {ok, File} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 12}) - end, - gleam@map:filter( - erlang:element(2, Mem_table), - fun(_, Entry) -> - Content = ream@storage@kv@memtable:entry_to_bitstring(Entry), - _assert_subject@2 = ream@storage@file:write(File, Content), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 18}) - end, - false - end - ), - _assert_subject@3 = ream@storage@file:close(File), - {ok, _} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"flush"/utf8>>, - line => 22}) - end, - {ok, true}. - --spec read_entries( - gleam@erlang@process:pid_(), - gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry()) -) -> {ok, gleam@map:map_(integer(), ream@storage@kv@memtable:mem_table_entry())} | - {error, gleam@erlang@file:reason()}. -read_entries(File, Entries) -> - case file:read(File, 38) of - {ok, <<Key_hash:128, Key_size:16, File_id:128, Offset:32>>} -> - _assert_subject = file:read(File, Key_size), - {ok, Key_string} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"read_entries"/utf8>>, - line => 39}) - end, - {_, Entry} = ream@storage@kv@memtable:bitstring_to_entry( - <<Key_hash:128, - Key_size:16, - File_id:128, - Offset:32, - Key_string/bitstring>> - ), - Entries@1 = gleam@map:insert(Entries, Key_hash, Entry), - read_entries(File, Entries@1); - - eof -> - {ok, Entries}; - - {error, Reason} -> - {error, Reason} - end. - --spec load(binary(), integer()) -> {ok, ream@storage@kv@memtable:mem_table()} | - {error, gleam@erlang@file:reason()}. -load(Path, Max_size) -> - _assert_subject = ream@storage@file:open(Path, [read]), - {ok, File} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"load"/utf8>>, - line => 27}) - end, - _assert_subject@1 = read_entries(File, gleam@map:new()), - {ok, Entries} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"load"/utf8>>, - line => 28}) - end, - _assert_subject@2 = ream@storage@file:close(File), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/sstable"/utf8>>, - function => <<"load"/utf8>>, - line => 29}) - end, - {ok, ream@storage@kv@memtable:from_entries(Entries, Max_size)}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl deleted file mode 100644 index 5d11a993bde..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@kv@value.erl +++ /dev/null @@ -1,326 +0,0 @@ --module(ream@storage@kv@value). --compile([no_auto_import, nowarn_unused_vars]). - --export([create/2, open/3, close/1, write_value/2, write/2, read/2, delete/2, get_file_info/1]). --export_type([reason/0, value/0, value_file/0, value_file_info/0]). - --type reason() :: capacity_exceeded. - --type value() :: {value, - integer(), - boolean(), - gleam@option:option(bitstring()), - integer()}. - --type value_file() :: {value_file, - integer(), - gleam@erlang@process:pid_(), - integer(), - integer(), - binary()}. - --type value_file_info() :: {value_file_info, - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec get_file_name(binary(), integer()) -> binary(). -get_file_name(Base_path, File_id) -> - filename:join([Base_path | ream@uuid:parts(ream@uuid:from_int(File_id))]). - --spec create(binary(), integer()) -> {ok, value_file()} | - {error, gleam@erlang@file:reason()}. -create(Base_path, Max_size) -> - File_id = ream@uuid:to_int(ream@uuid:new()), - File_name = get_file_name(Base_path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"create"/utf8>>, - line => 78}) - end, - gleam@result:'try'( - ream@storage@file:open(File_name, [read, write]), - fun(File_pid) -> - {ok, {value_file, File_id, File_pid, 0, Max_size, File_name}} - end - ). - --spec open(binary(), integer(), integer()) -> {ok, value_file()} | - {error, gleam@erlang@file:reason()}. -open(Path, File_id, Max_size) -> - File_name = get_file_name(Path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"open"/utf8>>, - line => 97}) - end, - _assert_subject@1 = ream@storage@file:open(File_name, [read, write]), - {ok, File_pid} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"open"/utf8>>, - line => 98}) - end, - _assert_subject@2 = gleam_erlang_ffi:file_info(File_name), - {ok, File_info} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"open"/utf8>>, - line => 99}) - end, - {ok, - {value_file, - File_id, - File_pid, - erlang:element(2, File_info), - Max_size, - File_name}}. - --spec close(value_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Vfile) -> - _assert_subject = ream@storage@file:close(erlang:element(3, Vfile)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"close"/utf8>>, - line => 105}) - end, - {ok, nil}. - --spec write_value(value_file(), value()) -> {ok, value_file()} | - {error, reason()}. -write_value(Vfile, Value) -> - Value_size_bits = 32, - Value_size_bytes = Value_size_bits div 8, - _assert_subject = erlang:element(4, Value), - {some, Data} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"write_value"/utf8>>, - line => 120}) - end, - Data_size = (gleam@bit_string:byte_size(Data) + Value_size_bytes) + 1, - Deleted = case erlang:element(3, Value) of - true -> - 1; - - false -> - 0 - end, - Packed_data = <<Data_size:(lists:max([(Value_size_bits), 0])), - Deleted:8, - Data/bitstring>>, - _assert_subject@1 = file:position( - erlang:element(3, Vfile), - {bof, erlang:element(2, Value)} - ), - {ok, Offset} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"write_value"/utf8>>, - line => 131}) - end, - case (Offset + Data_size) > erlang:element(5, Vfile) of - true -> - {error, capacity_exceeded}; - - false -> - _assert_subject@2 = ream@storage@file:write( - erlang:element(3, Vfile), - Packed_data - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"write_value"/utf8>>, - line => 135}) - end, - case (Offset + Data_size) > erlang:element(4, Vfile) of - true -> - {ok, erlang:setelement(4, Vfile, Offset + Data_size)}; - - false -> - {ok, Vfile} - end - end. - --spec write(value_file(), bitstring()) -> {ok, {value_file(), value()}} | - {error, reason()}. -write(Vfile, Value) -> - Value@1 = {value, - erlang:element(4, Vfile), - false, - {some, Value}, - erlang:element(2, Vfile)}, - gleam@result:'try'( - write_value(Vfile, Value@1), - fun(Vfile@1) -> {ok, {Vfile@1, erlang:setelement(4, Value@1, none)}} end - ). - --spec read(value_file(), integer()) -> {ok, value()} | {error, reason()}. -read(Vfile, Offset) -> - Value_size_bits = 32, - Value_size_bytes = Value_size_bits div 8, - _assert_subject = file:position(erlang:element(3, Vfile), {bof, Offset}), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"read"/utf8>>, - line => 170}) - end, - _assert_subject@1 = file:read( - erlang:element(3, Vfile), - Value_size_bytes + 1 - ), - {ok, <<Size:Value_size_bits, Deleted:8>>} = case _assert_subject@1 of - {ok, <<_:Value_size_bits, _:8>>} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"read"/utf8>>, - line => 171}) - end, - Content_size = (Size - Value_size_bytes) - 1, - _assert_subject@2 = file:read(erlang:element(3, Vfile), Content_size), - {ok, Data} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"read"/utf8>>, - line => 174}) - end, - Deleted@1 = case Deleted of - 0 -> - false; - - 1 -> - true - end, - {ok, {value, Offset, Deleted@1, {some, Data}, erlang:element(2, Vfile)}}. - --spec delete(value_file(), value()) -> {ok, value_file()} | {error, reason()}. -delete(Vfile, Value) -> - gleam@result:'try'( - read(Vfile, erlang:element(2, Value)), - fun(Value@1) -> - write_value(Vfile, erlang:setelement(3, Value@1, true)) - end - ). - --spec get_entries_and_deleted( - gleam@erlang@process:pid_(), - {integer(), integer()} -) -> {ok, {integer(), integer()}} | {error, gleam@erlang@file:reason()}. -get_entries_and_deleted(Handler, Acc) -> - Value_size_bits = 32, - Value_size_bytes = Value_size_bits div 8, - case file:read(Handler, Value_size_bytes + 1) of - {ok, <<Size:Value_size_bits, Deleted:8>>} -> - Payload_size = (Size - Value_size_bytes) - 1, - _assert_subject = file:position(Handler, {cur, Payload_size}), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"get_entries_and_deleted"/utf8>>, - line => 200}) - end, - get_entries_and_deleted( - Handler, - {erlang:element(1, Acc) + 1, erlang:element(2, Acc) + Deleted} - ); - - eof -> - {ok, Acc}; - - {error, Reason} -> - {error, Reason} - end. - --spec get_file_info(value_file()) -> value_file_info(). -get_file_info(Vfile) -> - _assert_subject = file:position(erlang:element(3, Vfile), {bof, 0}), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"get_file_info"/utf8>>, - line => 183}) - end, - _assert_subject@1 = get_entries_and_deleted( - erlang:element(3, Vfile), - {0, 0} - ), - {ok, {Entries, Deleted}} = case _assert_subject@1 of - {ok, {_, _}} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/kv/value"/utf8>>, - function => <<"get_file_info"/utf8>>, - line => 184}) - end, - {value_file_info, - erlang:element(2, Vfile), - erlang:element(4, Vfile), - erlang:element(5, Vfile), - Entries, - Deleted}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl deleted file mode 100644 index fd978abe885..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream.erl +++ /dev/null @@ -1,272 +0,0 @@ --module(ream@storage@stream). --compile([no_auto_import, nowarn_unused_vars]). - --export([get_base_path/2, close/1, open/2, add_event/2, get_event/2]). --export_type([stream/0]). - --type stream() :: {stream, - binary(), - ream@storage@stream@index:index_file(), - gleam@option:option(ream@storage@stream@event:event_file()), - gleam@map:map_(integer(), ream@storage@stream@event:event_file()), - binary()}. - --spec get_base_path(binary(), binary()) -> binary(). -get_base_path(Path, Name) -> - filename:join([Path, <<"stream"/utf8>>, Name]). - --spec less_populated_file(list(ream@storage@stream@event:event_file())) -> gleam@option:option(ream@storage@stream@event:event_file()). -less_populated_file(Files) -> - _pipe = Files, - gleam@list:fold( - _pipe, - none, - fun(Acc, File) -> - File_size = erlang:element(4, File), - case Acc of - {some, {event_file, _, _, Size, _}} when File_size >= Size -> - Acc; - - _ -> - {some, File} - end - end - ). - --spec close(stream()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Stream) -> - _assert_subject = ream@storage@stream@index:close(erlang:element(3, Stream)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"close"/utf8>>, - line => 50}) - end, - _pipe = erlang:element(5, Stream), - _pipe@1 = gleam@map:values(_pipe), - gleam@list:each( - _pipe@1, - fun(File) -> ream@storage@file:close(erlang:element(3, File)) end - ), - {ok, nil}. - --spec do_open_files( - ream@storage@stream@index:index_file(), - binary(), - gleam@map:map_(integer(), ream@storage@stream@event:event_file()) -) -> {ok, gleam@map:map_(integer(), ream@storage@stream@event:event_file())} | - {error, gleam@erlang@file:reason()}. -do_open_files(Index_file, Path, Acc) -> - case ream@storage@stream@index:count(Index_file) of - 0 -> - {ok, Acc}; - - Num_of_events -> - _ = ream@storage@stream@index:set_pos(Index_file, 0), - Files = begin - _pipe = Num_of_events - 1, - _pipe@1 = gleam@iterator:range(0, _pipe), - gleam@iterator:fold( - _pipe@1, - Acc, - fun(Acc@1, _) -> - _assert_subject = ream@storage@stream@index:get_next( - Index_file - ), - {ok, {index, _, _, File_id}} = case _assert_subject of - {ok, {index, _, _, _}} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"do_open_files"/utf8>>, - line => 75}) - end, - case gleam@map:has_key(Acc@1, File_id) of - true -> - Acc@1; - - false -> - _assert_subject@1 = ream@storage@stream@event:open( - Path, - File_id - ), - {ok, File} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream"/utf8>>, - function => <<"do_open_files"/utf8>>, - line => 80}) - end, - gleam@map:insert(Acc@1, File_id, File) - end - end - ) - end, - {ok, Files} - end. - --spec open(binary(), binary()) -> {ok, stream()} | - {error, gleam@erlang@file:reason()}. -open(Name, Path) -> - Base_path = filename:join([Path, <<"stream"/utf8>>, Name]), - _assert_subject = ream@storage@stream@index:open(Base_path), - {ok, Index_file} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"open"/utf8>>, - line => 28}) - end, - gleam@result:'try'( - do_open_files(Index_file, Base_path, gleam@map:new()), - fun(Files) -> - Active_file = less_populated_file(gleam@map:values(Files)), - {ok, {stream, Name, Index_file, Active_file, Files, Base_path}} - end - ). - --spec add_event(stream(), bitstring()) -> {ok, stream()} | - {error, gleam@erlang@file:reason()}. -add_event(Stream, Event_content) -> - Event_size = gleam@bit_string:byte_size(Event_content), - {Stream@3, Index@2} = case ream@storage@stream@index:count( - erlang:element(3, Stream) - ) of - 0 -> - _assert_subject = ream@storage@stream@event:create( - erlang:element(6, Stream) - ), - {ok, Stream_file} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"add_event"/utf8>>, - line => 99}) - end, - {Index, Index_file} = ream@storage@stream@index:add( - erlang:element(3, Stream), - Event_size, - erlang:element(2, Stream_file) - ), - Stream@1 = erlang:setelement( - 5, - erlang:setelement( - 4, - erlang:setelement(3, Stream, Index_file), - {some, Stream_file} - ), - gleam@map:insert( - erlang:element(5, Stream), - erlang:element(2, Stream_file), - Stream_file - ) - ), - {Stream@1, Index}; - - _ -> - _assert_subject@1 = erlang:element(4, Stream), - {some, Active_file} = case _assert_subject@1 of - {some, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream"/utf8>>, - function => <<"add_event"/utf8>>, - line => 112}) - end, - {Index@1, Index_file@1} = ream@storage@stream@index:add( - erlang:element(3, Stream), - Event_size, - erlang:element(2, Active_file) - ), - Stream@2 = erlang:setelement(3, Stream, Index_file@1), - {Stream@2, Index@1} - end, - _assert_subject@2 = gleam@map:get( - erlang:element(5, Stream@3), - erlang:element(4, Index@2) - ), - {ok, File} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream"/utf8>>, - function => <<"add_event"/utf8>>, - line => 120}) - end, - Event = {event, erlang:element(2, Index@2), Event_content}, - Stream_file@1 = ream@storage@stream@event:write(File, Event), - Files = gleam@map:insert( - erlang:element(5, Stream@3), - erlang:element(2, Stream_file@1), - Stream_file@1 - ), - {ok, erlang:setelement(5, Stream@3, Files)}. - --spec get_event(stream(), integer()) -> {ok, bitstring()} | - {error, gleam@erlang@file:reason()}. -get_event(Stream, Index) -> - case ream@storage@stream@index:count(erlang:element(3, Stream)) > Index of - true -> - _assert_subject = ream@storage@stream@index:get( - erlang:element(3, Stream), - Index - ), - {ok, {index, Offset, _, File_id}} = case _assert_subject of - {ok, {index, _, _, _}} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream"/utf8>>, - function => <<"get_event"/utf8>>, - line => 131}) - end, - _assert_subject@1 = gleam@map:get( - erlang:element(5, Stream), - File_id - ), - {ok, File} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream"/utf8>>, - function => <<"get_event"/utf8>>, - line => 133}) - end, - _assert_subject@2 = ream@storage@stream@event:read(File, Offset), - {ok, {event, _, Data}} = case _assert_subject@2 of - {ok, {event, _, _}} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream"/utf8>>, - function => <<"get_event"/utf8>>, - line => 134}) - end, - {ok, Data}; - - false -> - {error, einval} - end. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl deleted file mode 100644 index f52e4f21270..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@event.erl +++ /dev/null @@ -1,186 +0,0 @@ --module(ream@storage@stream@event). --compile([no_auto_import, nowarn_unused_vars]). - --export([create/1, open/2, close/1, write/2, read/2]). --export_type([event/0, event_file/0]). - --type event() :: {event, integer(), bitstring()}. - --type event_file() :: {event_file, - integer(), - gleam@erlang@process:pid_(), - integer(), - binary()}. - --spec get_file_name(binary(), integer()) -> binary(). -get_file_name(Base_path, File_id) -> - filename:join([Base_path | ream@uuid:parts(<<File_id:128>>)]). - --spec create(binary()) -> {ok, event_file()} | - {error, gleam@erlang@file:reason()}. -create(Base_path) -> - <<File_id:128>> = ream@uuid:new(), - File_name = get_file_name(Base_path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"create"/utf8>>, - line => 39}) - end, - gleam@result:'try'( - ream@storage@file:open(File_name, [read, append]), - fun(File_pid) -> {ok, {event_file, File_id, File_pid, 0, File_name}} end - ). - --spec open(binary(), integer()) -> {ok, event_file()} | - {error, gleam@erlang@file:reason()}. -open(Path, File_id) -> - File_name = get_file_name(Path, File_id), - _assert_subject = ream@storage@file:recursive_make_directory( - filename:dirname(File_name) - ), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"open"/utf8>>, - line => 54}) - end, - _assert_subject@1 = ream@storage@file:open(File_name, [read, append]), - {ok, File_pid} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"open"/utf8>>, - line => 55}) - end, - _assert_subject@2 = gleam_erlang_ffi:file_info(File_name), - {ok, File_info} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"open"/utf8>>, - line => 56}) - end, - {ok, - {event_file, File_id, File_pid, erlang:element(2, File_info), File_name}}. - --spec close(event_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Stream_file) -> - _assert_subject = ream@storage@file:close(erlang:element(3, Stream_file)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"close"/utf8>>, - line => 62}) - end, - {ok, nil}. - --spec write(event_file(), event()) -> event_file(). -write(Stream_file, Event) -> - Event_size_bits = 24, - Event_size_bytes = Event_size_bits div 8, - Data_size = gleam@bit_string:byte_size(erlang:element(3, Event)) + Event_size_bytes, - Data = <<Data_size:(lists:max([(Event_size_bits), 0])), - (erlang:element(3, Event))/bitstring>>, - _assert_subject = file:position( - erlang:element(3, Stream_file), - {bof, erlang:element(2, Event)} - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"write"/utf8>>, - line => 76}) - end, - _assert_subject@1 = ream@storage@file:write( - erlang:element(3, Stream_file), - Data - ), - {ok, _} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"write"/utf8>>, - line => 77}) - end, - Data_size@1 = gleam@bit_string:byte_size(Data), - erlang:setelement( - 4, - Stream_file, - erlang:element(4, Stream_file) + Data_size@1 - ). - --spec read(event_file(), integer()) -> {ok, event()} | - {error, gleam@erlang@file:reason()}. -read(Stream_file, Offset) -> - Event_size_bits = 24, - Event_size_bytes = Event_size_bits div 8, - _assert_subject = file:position( - erlang:element(3, Stream_file), - {bof, Offset} - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"read"/utf8>>, - line => 89}) - end, - _assert_subject@1 = file:read( - erlang:element(3, Stream_file), - Event_size_bytes - ), - {ok, <<Size:Event_size_bits>>} = case _assert_subject@1 of - {ok, <<_:Event_size_bits>>} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"read"/utf8>>, - line => 90}) - end, - Content_size = Size - Event_size_bytes, - _assert_subject@2 = file:read(erlang:element(3, Stream_file), Content_size), - {ok, Data} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream/event"/utf8>>, - function => <<"read"/utf8>>, - line => 93}) - end, - {ok, {event, Offset, Data}}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl b/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl deleted file mode 100644 index 1580dada363..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@storage@stream@index.erl +++ /dev/null @@ -1,234 +0,0 @@ --module(ream@storage@stream@index). --compile([no_auto_import, nowarn_unused_vars]). - --export([open/1, close/1, count/1, set_pos/2, get_next/1, get/2, add/3]). --export_type([index/0, index_file/0]). - --type index() :: {index, integer(), integer(), integer()}. - --type index_file() :: {index_file, - gleam@erlang@process:pid_(), - integer(), - binary()}. - --spec open(binary()) -> {ok, index_file()} | {error, gleam@erlang@file:reason()}. -open(Path) -> - _assert_subject = ream@storage@file:recursive_make_directory(Path), - {ok, true} = case _assert_subject of - {ok, true} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"open"/utf8>>, - line => 34}) - end, - Index = filename:join([Path, <<"index"/utf8>>]), - gleam@result:'try'( - ream@storage@file:open(Index, [read, append]), - fun(Index_pid) -> - gleam@result:'try'( - gleam_erlang_ffi:file_info(Index), - fun(Index_info) -> - {ok, - {index_file, - Index_pid, - erlang:element(2, Index_info), - Index}} - end - ) - end - ). - --spec close(index_file()) -> {ok, nil} | {error, gleam@erlang@file:reason()}. -close(Index_file) -> - _assert_subject = ream@storage@file:close(erlang:element(2, Index_file)), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"close"/utf8>>, - line => 42}) - end, - {ok, nil}. - --spec index_binary(index()) -> bitstring(). -index_binary(Index) -> - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - <<(erlang:element(2, Index)):(lists:max([(Offset_size_bits), 0])), - (erlang:element(3, Index)):(lists:max([(Event_size_bits), 0])), - (erlang:element(4, Index)):(lists:max([(File_id_size_bits), 0]))>>. - --spec count(index_file()) -> integer(). -count(Index_file) -> - _assert_subject = gleam@int:divide(erlang:element(3, Index_file), 25), - {ok, Result} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"count"/utf8>>, - line => 120}) - end, - Result. - --spec set_pos(index_file(), integer()) -> {ok, integer()} | - {error, gleam@erlang@file:reason()}. -set_pos(Index_file, Index) -> - file:position(erlang:element(2, Index_file), {bof, Index * 25}). - --spec get_next(index_file()) -> {ok, index()} | - {error, gleam@erlang@file:reason()}. -get_next(Index_file) -> - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - case file:read(erlang:element(2, Index_file), 25) of - {ok, - <<Offset:Offset_size_bits, - Size:Event_size_bits, - File_id:File_id_size_bits>>} -> - {ok, {index, Offset, Size, File_id}}; - - eof -> - {error, espipe}; - - _ -> - {error, einval} - end. - --spec get(index_file(), integer()) -> {ok, index()} | - {error, gleam@erlang@file:reason()}. -get(Index_file, Index) -> - case count(Index_file) > Index of - true -> - _assert_subject = set_pos(Index_file, Index), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"get"/utf8>>, - line => 148}) - end, - get_next(Index_file); - - false -> - {error, einval} - end. - --spec last_entry_for_file(gleam@erlang@process:pid_(), integer()) -> {ok, - bitstring()} | - {error, gleam@erlang@file:reason()}. -last_entry_for_file(Index_file, File_id) -> - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - _assert_subject = file:read(Index_file, 25), - {ok, - <<Offset:Offset_size_bits, - Size:Event_size_bits, - New_file_id:File_id_size_bits>>} = case _assert_subject of - {ok, <<_:Offset_size_bits, _:Event_size_bits, _:File_id_size_bits>>} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"last_entry_for_file"/utf8>>, - line => 103}) - end, - case New_file_id =:= File_id of - true -> - {ok, index_binary({index, Offset, Size, File_id})}; - - false -> - case file:position(Index_file, {cur, -2 * 25}) of - {ok, _} -> - last_entry_for_file(Index_file, File_id); - - {error, einval} -> - {ok, index_binary({index, 0, 0, File_id})} - end - end. - --spec add(index_file(), integer(), integer()) -> {index(), index_file()}. -add(Index_file, Event_size, File_id) -> - Event_size_bytes = 24 div 8, - {Index_content, Index@2} = case erlang:element(3, Index_file) of - 0 -> - Index = {index, 0, Event_size + Event_size_bytes, File_id}, - {index_binary(Index), Index}; - - _ -> - _assert_subject = file:position( - erlang:element(2, Index_file), - {eof, - 25} - ), - {ok, _} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"add"/utf8>>, - line => 58}) - end, - Offset_size_bits = 48, - Event_size_bits = 24, - File_id_size_bits = 128, - _assert_subject@1 = last_entry_for_file( - erlang:element(2, Index_file), - File_id - ), - {ok, - <<Offset:Offset_size_bits, - Prev_size:Event_size_bits, - _:File_id_size_bits>>} = case _assert_subject@1 of - {ok, - <<_:Offset_size_bits, - _:Event_size_bits, - _:File_id_size_bits>>} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"add"/utf8>>, - line => 65}) - end, - Offset@1 = Offset + Prev_size, - Index@1 = {index, Offset@1, Event_size + Event_size_bytes, File_id}, - {index_binary(Index@1), Index@1} - end, - _assert_subject@2 = ream@storage@file:write( - erlang:element(2, Index_file), - Index_content - ), - {ok, _} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"ream/storage/stream/index"/utf8>>, - function => <<"add"/utf8>>, - line => 75}) - end, - Index_file@1 = erlang:setelement( - 3, - Index_file, - erlang:element(3, Index_file) + 25 - ), - {Index@2, Index_file@1}. diff --git a/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl b/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl deleted file mode 100644 index 67ad2a2773d..00000000000 --- a/test-community-packages-javascript/build/packages/ream/src/ream@uuid.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(ream@uuid). --compile([no_auto_import, nowarn_unused_vars]). - --export([to_int/1, from_int/1, from_string/1, parts/1, to_string/1, new/0]). - --spec to_int(bitstring()) -> integer(). -to_int(Uuid) -> - <<Uuid_int:128>> = Uuid, - Uuid_int. - --spec from_int(integer()) -> bitstring(). -from_int(Uuid) -> - <<Uuid:128>>. - --spec from_string(binary()) -> bitstring(). -from_string(Uuid) -> - _assert_subject = begin - _pipe = Uuid, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<""/utf8>>), - gleam@int:base_parse(_pipe@1, 16) - end, - {ok, Uuid_int} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"ream/uuid"/utf8>>, - function => <<"from_string"/utf8>>, - line => 28}) - end, - from_int(Uuid_int). - --spec to_hex(integer(), integer()) -> binary(). -to_hex(N, Size) -> - _pipe = gleam@int:to_base16(N), - _pipe@1 = gleam@string:lowercase(_pipe), - gleam@string:pad_left(_pipe@1, Size, <<"0"/utf8>>). - --spec parts(bitstring()) -> list(binary()). -parts(Uuid) -> - <<P1:32, P2:16, P3:16, P4:16, P5:48>> = Uuid, - [to_hex(P1, 8), to_hex(P2, 4), to_hex(P3, 4), to_hex(P4, 4), to_hex(P5, 12)]. - --spec to_string(bitstring()) -> binary(). -to_string(Uuid) -> - _pipe = parts(Uuid), - gleam@string:join(_pipe, <<"-"/utf8>>). - --spec new() -> bitstring(). -new() -> - <<U0:48, _:4, U1:12, _:2, U2:62>> = crypto:strong_rand_bytes(16), - <<U0:48, 4:4, U1:12, 2:2, U2:62>>. diff --git a/test-community-packages-javascript/build/packages/simplifile/README.md b/test-community-packages-javascript/build/packages/simplifile/README.md deleted file mode 100644 index 006d5b762a7..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# simplifile - -[![Package Version](https://img.shields.io/hexpm/v/simplifile)](https://hex.pm/packages/simplifile) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/simplifile/) - -Simplifile provides basic file operations (read, write, append, and delete) that work -for all targets (Erlang, Node, and Deno). It also provides functions for working with directories. - -## Example -```gleam -let filepath = "./test/hello.txt" -let assert Ok(_) = "Hello, World" |> write(to: filepath) -let assert Ok(_) = "Goodbye, Mars" |> append(to: filepath) -let assert Ok("Hello, WorldGoodbye, Mars") = read(from: filepath) -let assert Ok(_) = delete(filepath) -let assert Error(_) = read(from: filepath) -``` - -## Quick start - -```sh -gleam run # Run the project -gleam test # Run the tests -gleam shell # Run an Erlang shell -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add simplifile -``` - -and its documentation can be found at <https://hexdocs.pm/simplifile>. diff --git a/test-community-packages-javascript/build/packages/simplifile/gleam.toml b/test-community-packages-javascript/build/packages/simplifile/gleam.toml deleted file mode 100644 index be16a280dd5..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/gleam.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "simplifile" -version = "0.1.4" -description = "Basic file operations that work on all targets" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -licences = ["Apache-2.0"] -repository = { type = "github", user = "bcpeinhardt", repo = "simplifile" } -# links = [{ title = "Website", href = "https://gleam.run" }] - -[javascript.deno] -allow_all = true - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/simplifile/src/file.mjs b/test-community-packages-javascript/build/packages/simplifile/src/file.mjs deleted file mode 100644 index a707f9e5f6d..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/file.mjs +++ /dev/null @@ -1,84 +0,0 @@ -import fs from "node:fs" -import path from "node:path" -import { BitString, Ok, Error as GError, toList} from "./gleam.mjs"; - -export function readFile(filepath) { - try { - const contents = fs.readFileSync(path.normalize(filepath)).toString() - return new Ok(contents) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function readBits(filepath) { - try { - const contents = fs.readFileSync(path.normalize(filepath)) - return new Ok(new BitString(new Uint8Array(contents))) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function writeFile(contents, filepath) { - try { - fs.writeFileSync(path.normalize(filepath), contents) - return new Ok(undefined) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function writeBits(contents, filepath) { - try { - fs.writeFileSync(path.normalize(filepath), contents.buffer) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -export function deleteFile(filepath) { - try { - fs.unlinkSync(path.normalize(filepath)) - return new Ok(undefined) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function appendFile(contents, filepath) { - try { - fs.appendFileSync(path.normalize(filepath), contents) - return new Ok(undefined) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function appendBits(contents, filepath) { - try { - fs.appendFileSync(path.normalize(filepath), contents.buffer) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -function stringifyError(e) { - return e.code -} - -export function isDirectory(filepath) { - let fp = path.normalize(filepath) - return fs.existsSync(fp) && fs.lstatSync(fp).isDirectory(); -} - -export function listContents(filepath) { - try { - const stuff = toList(fs.readdirSync(path.normalize(filepath))) - return new Ok(stuff) - } catch(e) { - return new GError(stringifyError(e)) - } -} \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl b/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl deleted file mode 100644 index b902c92cf1b..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/gleam_erlang_ffi.erl +++ /dev/null @@ -1,218 +0,0 @@ --module(gleam_erlang_ffi). --export([ - atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, - ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, - append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, - set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, - list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, - insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, - merge_selector/2, flush_messages/0, file_info/1, link_info/1 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - --spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. -atom_from_string(S) -> - try {ok, binary_to_existing_atom(S)} - catch error:badarg -> {error, atom_not_loaded} - end. - -atom_from_dynamic(Data) when is_atom(Data) -> - {ok, Data}; -atom_from_dynamic(Data) -> - {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. - -rescue(F) -> - try {ok, F()} - catch - throw:X -> {error, {thrown, X}}; - error:X -> {error, {errored, X}}; - exit:X -> {error, {exited, X}} - end. - -ensure_all_started(Application) -> - case application:ensure_all_started(Application) of - {ok, _} = Ok -> Ok; - - {error, {ProblemApp, {"no such file or directory", _}}} -> - {error, {unknown_application, ProblemApp}} - end. - -sleep(Microseconds) -> - timer:sleep(Microseconds), - nil. - -sleep_forever() -> - timer:sleep(infinity), - nil. - -file_info_result(Result) -> - case Result of - {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> - {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; - {ok, _} -> - Result; - {error, Reason} when ?is_posix_error(Reason) -> - Result - end. - -file_info(Filename) -> - file_info_result(file:read_file_info(Filename, [{time, posix}])). - -link_info(Filename) -> - file_info_result(file:read_link_info(Filename, [{time, posix}])). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -get_all_env() -> - BinVars = lists:map(fun(VarString) -> - [VarName, VarVal] = string:split(VarString, "="), - {list_to_binary(VarName), list_to_binary(VarVal)} - end, os:getenv()), - maps:from_list(BinVars). - -get_env(Name) -> - case os:getenv(binary_to_list(Name)) of - false -> {error, nil}; - Value -> {ok, list_to_binary(Value)} - end. - -set_env(Name, Value) -> - os:putenv(binary_to_list(Name), binary_to_list(Value)), - nil. - -unset_env(Name) -> - os:unsetenv(binary_to_list(Name)), - nil. - -os_family() -> - case os:type() of - {win32, nt} -> - windows_nt; - {unix, linux} -> - linux; - {unix, darwin} -> - darwin; - {unix, freebsd} -> - free_bsd; - {_, Other} -> - {other, atom_to_binary(Other, utf8)} - end. - -new_selector() -> - {selector, #{}}. - -map_selector({selector, Handlers}, Fn) -> - MappedHandlers = maps:map(fun(_Tag, Handler) -> - fun(Message) -> Fn(Handler(Message)) end - end, Handlers), - {selector, MappedHandlers}. - -merge_selector({selector, HandlersA}, {selector, HandlersB}) -> - {selector, maps:merge(HandlersA, HandlersB)}. - -insert_selector_handler({selector, Handlers}, Tag, Fn) -> - {selector, Handlers#{Tag => Fn}}. - -select(Selector) -> - {ok, Message} = select(Selector, infinity), - Message. - -select({selector, Handlers}, Timeout) -> - AnythingHandler = maps:get(anything, Handlers, undefined), - receive - % Monitored process down messages. - % This is special cased so we can selectively receive based on the - % reference as well as the record tag. - {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> - Fn = maps:get(Ref, Handlers), - {ok, Fn({process_down, Pid, Reason})}; - - Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> - Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), - {ok, Fn(Msg)}; - - Msg when AnythingHandler =/= undefined -> - {ok, AnythingHandler(Msg)} - after Timeout -> - {error, nil} - end. - -demonitor({_, Reference}) -> - erlang:demonitor(Reference, [flush]). - -link(Pid) -> - try - erlang:link(Pid) - catch - error:_ -> false - end. - -trap_exits(ShouldTrap) -> - erlang:process_flag(trap_exit, ShouldTrap), - nil. - -flush_messages() -> - receive _Message -> flush_messages() - after 0 -> nil - end. \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src deleted file mode 100644 index 5e1c9b5afca..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, simplifile, [ - {vsn, "0.1.4"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Basic file operations that work on all targets"}, - {modules, [simplifile]}, - {registered, []} -]}. diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl deleted file mode 100644 index e6cacc110b1..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.erl +++ /dev/null @@ -1,131 +0,0 @@ --module(simplifile). --compile([no_auto_import, nowarn_unused_vars]). - --export([append_bits/2, append/2, write_bits/2, write/2, read_bits/1, read/1, delete/1, is_directory/1, list_contents/1]). --export_type([file_error/0]). - --type file_error() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8 | - unknown. - --spec cast_error({ok, EXS} | {error, file_error()}) -> {ok, EXS} | - {error, file_error()}. -cast_error(Input) -> - Input. - --spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, file_error()}. -append_bits(Bits, Filepath) -> - _pipe = gleam_erlang_ffi:append_file(Bits, Filepath), - cast_error(_pipe). - --spec do_append(binary(), binary()) -> {ok, nil} | {error, file_error()}. -do_append(Content, Filepath) -> - _pipe = Content, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:append_file(_pipe@1, Filepath). - --spec append(binary(), binary()) -> {ok, nil} | {error, file_error()}. -append(Contents, Filepath) -> - _pipe = do_append(Contents, Filepath), - cast_error(_pipe). - --spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, file_error()}. -write_bits(Bits, Filepath) -> - _pipe = gleam_erlang_ffi:write_file(Bits, Filepath), - cast_error(_pipe). - --spec do_write(binary(), binary()) -> {ok, nil} | {error, file_error()}. -do_write(Content, Filepath) -> - _pipe = Content, - _pipe@1 = gleam@bit_string:from_string(_pipe), - gleam_erlang_ffi:write_file(_pipe@1, Filepath). - --spec write(binary(), binary()) -> {ok, nil} | {error, file_error()}. -write(Contents, Filepath) -> - _pipe = do_write(Contents, Filepath), - cast_error(_pipe). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, file_error()}. -read_bits(Filepath) -> - _pipe = gleam_erlang_ffi:read_file(Filepath), - cast_error(_pipe). - --spec do_read(binary()) -> {ok, binary()} | {error, file_error()}. -do_read(Filepath) -> - case gleam_erlang_ffi:read_file(Filepath) of - {ok, Bit_str} -> - case gleam@bit_string:to_string(Bit_str) of - {ok, Str} -> - {ok, Str}; - - _ -> - {error, not_utf8} - end; - - {error, E} -> - {error, E} - end. - --spec read(binary()) -> {ok, binary()} | {error, file_error()}. -read(Filepath) -> - _pipe = do_read(Filepath), - cast_error(_pipe). - --spec delete(binary()) -> {ok, nil} | {error, file_error()}. -delete(Filepath) -> - _pipe = gleam_erlang_ffi:delete_file(Filepath), - cast_error(_pipe). - --spec is_directory(binary()) -> boolean(). -is_directory(Filepath) -> - filelib:is_dir(Filepath). - --spec list_contents(binary()) -> {ok, list(binary())} | {error, file_error()}. -list_contents(Directory) -> - gleam_erlang_ffi:list_directory(Directory). diff --git a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam b/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam deleted file mode 100644 index 0a94ea185a6..00000000000 --- a/test-community-packages-javascript/build/packages/simplifile/src/simplifile.gleam +++ /dev/null @@ -1,359 +0,0 @@ -/// This type represents all of the reasons for why a file system operation could fail. -/// -/// Most of these reasons are POSIX errors, which come from the operating system -/// and start with E. Others have been added to represent other issues that may -/// arise specific to this library. -/// -pub type FileError { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 - /// Any error not accounted for by this type - Unknown -} - -/// Read a files contents as a string -/// ## Example -/// ```gleam -/// let assert Ok(records) = read(from: "./users.csv") -/// ``` -/// ### A note about utf8 -/// Currently on the erlang target, this function expects a utf8 string -/// and returns a `NotUtf8` error if it reads a non utf8 string. -/// On the javascript target, it will read any string. -/// This behavior will probably change soon. -/// -pub fn read(from filepath: String) -> Result(String, FileError) { - do_read(filepath) - |> cast_error -} - -/// Write a string to a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = write("Hello, World!", to: "./hello_world.txt") -/// ``` -/// -pub fn write(contents: String, to filepath: String) -> Result(Nil, FileError) { - do_write(contents, to: filepath) - |> cast_error -} - -/// Delete a file at a given filepath -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = delete(file_at: "./delete_me.txt") -/// ``` -/// -pub fn delete(file_at filepath: String) -> Result(Nil, FileError) { - do_delete(filepath) - |> cast_error -} - -/// Append a string to the contents of a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = append("more text", to: "./needs_more_text.txt") -/// ``` -/// -pub fn append(contents: String, to filepath: String) -> Result(Nil, FileError) { - do_append(contents, to: filepath) - |> cast_error -} - -/// Read a files contents as a bitstring -/// ## Example -/// ```gleam -/// let assert Ok(records) = read_bits(from: "./users.csv") -/// ``` -/// -pub fn read_bits(from filepath: String) -> Result(BitString, FileError) { - do_read_bits(filepath) - |> cast_error -} - -/// Write a bitstring to a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = write_bits(<<"Hello, World!":utf8>>, to: "./hello_world.txt") -/// ``` -/// -pub fn write_bits( - bits: BitString, - to filepath: String, -) -> Result(Nil, FileError) { - do_write_bits(bits, filepath) - |> cast_error -} - -/// Append a bitstring to the contents of a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = append_bits(<<"more text":utf8>>, to: "./needs_more_text.txt") -/// ``` -/// -pub fn append_bits( - bits: BitString, - to filepath: String, -) -> Result(Nil, FileError) { - do_append_bits(bits, filepath) - |> cast_error -} - -/// Checks if the provided filepath is a directory -/// ## Example -/// ```gleam -/// let assert True = is_directory("./test") -/// ``` -pub fn is_directory(filepath: String) -> Bool { - do_is_directory(filepath) -} - -/// Lists the contents of a directory. -/// The list contains directory and file names, and is not recursive. -/// -/// ## Example -/// ```gleam -/// let assert Ok(files_and_folders) = list_contents(of: "./Folder1") -/// ``` -/// -pub fn list_contents(of directory: String) -> Result(List(String), FileError) { - do_list_contents(directory) -} - -if javascript { - import gleam/result - - external fn do_read(from: String) -> Result(String, String) = - "./file.mjs" "readFile" - - external fn do_write(String, to: String) -> Result(Nil, String) = - "./file.mjs" "writeFile" - - external fn do_delete(file_at: String) -> Result(Nil, String) = - "./file.mjs" "deleteFile" - - external fn do_append(String, to: String) -> Result(Nil, String) = - "./file.mjs" "appendFile" - - external fn do_read_bits(from: String) -> Result(BitString, String) = - "./file.mjs" "readBits" - - external fn do_write_bits(BitString, to: String) -> Result(Nil, String) = - "./file.mjs" "writeBits" - - external fn do_append_bits(BitString, to: String) -> Result(Nil, String) = - "./file.mjs" "appendBits" - - external fn do_is_directory(String) -> Bool = - "./file.mjs" "isDirectory" - - external fn do_list_contents(String) -> Result(List(String), FileError) = - "./file.mjs" "listContents" - - fn cast_error(input: Result(a, String)) -> Result(a, FileError) { - result.map_error( - input, - fn(e) { - case e { - "EACCES" -> Eacces - "EAGAIN" -> Eagain - "EBADF" -> Ebadf - "EBADMSG" -> Ebadmsg - "EBUSY" -> Ebusy - "EDEADLK" -> Edeadlk - "EDEADLOCK" -> Edeadlock - "EDQUOT" -> Edquot - "EEXIST" -> Eexist - "EFAULT" -> Efault - "EFBIG" -> Efbig - "EFTYPE" -> Eftype - "EINTR" -> Eintr - "EINVAL" -> Einval - "EIO" -> Eio - "EISDIR" -> Eisdir - "ELOOP" -> Eloop - "EMFILE" -> Emfile - "EMLINK" -> Emlink - "EMULTIHOP" -> Emultihop - "ENAMETOOLONG" -> Enametoolong - "ENFILE" -> Enfile - "ENOBUFS" -> Enobufs - "ENODEV" -> Enodev - "ENOLCK" -> Enolck - "ENOLINK" -> Enolink - "ENOENT" -> Enoent - "ENOMEM" -> Enomem - "ENOSPC" -> Enospc - "ENOSR" -> Enosr - "ENOSTR" -> Enostr - "ENOSYS" -> Enosys - "ENOBLK" -> Enotblk - "ENODIR" -> Enotdir - "ENOTSUP" -> Enotsup - "ENXIO" -> Enxio - "EOPNOTSUPP" -> Eopnotsupp - "EOVERFLOW" -> Eoverflow - "EPERM" -> Eperm - "EPIPE" -> Epipe - "ERANGE" -> Erange - "EROFS" -> Erofs - "ESPIPE" -> Espipe - "ESRCH" -> Esrch - "ESTALE" -> Estale - "ETXTBSY" -> Etxtbsy - "EXDEV" -> Exdev - "NOTUTF8" -> NotUtf8 - _ -> Unknown - } - }, - ) - } -} - -if erlang { - import gleam/bit_string - - external fn do_append_bits(BitString, to: String) -> Result(Nil, FileError) = - "gleam_erlang_ffi" "append_file" - - external fn do_write_bits(BitString, to: String) -> Result(Nil, FileError) = - "gleam_erlang_ffi" "write_file" - - external fn do_read_bits(from: String) -> Result(BitString, FileError) = - "gleam_erlang_ffi" "read_file" - - external fn do_delete(String) -> Result(Nil, FileError) = - "gleam_erlang_ffi" "delete_file" - - fn do_append(content: String, to filepath: String) -> Result(Nil, FileError) { - content - |> bit_string.from_string - |> do_append_bits(filepath) - } - - fn do_write(content: String, to filepath: String) -> Result(Nil, FileError) { - content - |> bit_string.from_string - |> do_write_bits(filepath) - } - - fn do_read(from filepath: String) -> Result(String, FileError) { - case do_read_bits(filepath) { - Ok(bit_str) -> { - case bit_string.to_string(bit_str) { - Ok(str) -> Ok(str) - _ -> Error(NotUtf8) - } - } - Error(e) -> Error(e) - } - } - - fn cast_error(input: Result(a, FileError)) -> Result(a, FileError) { - input - } - - external fn do_is_directory(String) -> Bool = - "filelib" "is_dir" - - external fn do_list_contents( - directory: String, - ) -> Result(List(String), FileError) = - "gleam_erlang_ffi" "list_directory" -} diff --git a/test-community-packages-javascript/build/packages/toml/LICENSE b/test-community-packages-javascript/build/packages/toml/LICENSE deleted file mode 100644 index e1ebf2e95c4..00000000000 --- a/test-community-packages-javascript/build/packages/toml/LICENSE +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/test-community-packages-javascript/build/packages/toml/README.md b/test-community-packages-javascript/build/packages/toml/README.md deleted file mode 100644 index 8fb93a965d3..00000000000 --- a/test-community-packages-javascript/build/packages/toml/README.md +++ /dev/null @@ -1,338 +0,0 @@ -# TOML for Elixir - -[![Main](https://github.com/bitwalker/toml-elixir/workflows/elixir/badge.svg?branch=main)](https://github.com/bitwalker/toml-elixir/actions?query=workflow%3A%22elixir%22+branch%3Amain) -[![Hex.pm Version](https://img.shields.io/hexpm/v/toml.svg?style=flat)](https://hex.pm/packages/toml) -[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg?style=flat)](https://hexdocs.pm/toml) -[![Total Download](https://img.shields.io/hexpm/dt/toml.svg?style=flat)](https://hex.pm/packages/toml) -[![Last Updated](https://img.shields.io/github/last-commit/bitwalker/toml-elixir.svg?style=flat)](https://github.com/bitwalker/toml-elixir/commits/main) - -This is a TOML library for Elixir projects. - -It is compliant with version 1.0 of the [official TOML specification](https://github.com/toml-lang/toml). You can find a -brief overview of the feature set below, but you are encouraged to read the full spec at the link above (it is short and easy to read!). - -## Features - -- Decode from string, file, or stream -- Fully compliant with the latest version of the TOML spec -- Is tested against [toml-test](https://github.com/BurntSushi/toml-test), a test - suite for spec-compliant TOML encoders/decoders, used by implementations in - multiple languages. The test suite has been integrated into this project to be - run under Mix so that we get better error information and so it can run as - part of the test suite. -- Decoder produces a map with values using the appropriate Elixir data types for - representation -- Supports extension via value transformers (see `Toml.Transform` docs for details) -- Supports use as a configuration provider in Distillery 2.x+ (use TOML - files for configuration!) -- Decoder is written by hand to take advantage of various optimizations. -- Library passes Dialyzer checks - -## Comparison To Other Libraries - -I compared `toml` to four other libraries: - -- `toml_elixir` -- `tomlex` -- `jerry` -- `etoml` - -Of these four, none correctly implement the 0.5.0 specification. Either they are -targeting older versions of the spec (in `etoml`, it is built against pre-0.1), -are not fully implemented (i.e. don't support all features), or have bugs which -prevent them from properly parsing a 0.5.0 example file (the -`test/fixtures/example.toml` file in this repository). - -If you are looking for a TOML library, at present `toml` is the only one which -full implements the spec and correctly decodes `example.toml`. - -## Installation - -This library is available on Hex as `:toml`, and can be added to your deps like so: - -```elixir -def deps do - [ - {:toml, "~> 0.7"} - ] -end -``` - -NOTE: You can determine the latest version on Hex by running `mix hex.info toml`. - -## Type Conversions - -In case you are curious how TOML types are translated to Elixir types, the -following table provides the conversions. - -**NOTE:** The various possible representations of each type, such as -hex/octal/binary integers, quoted/literal strings, etc., are considered to be -the same base type (e.g. integer and string respectively in the examples given). - -| TOML | Elixir | -|-------|-------| -| String | String.t (binary) | -| Integer | integer | -| inf | :infinity | -| +inf | :infinity | -| -inf | :negative_infinity | -| nan | :nan | -| +nan | :nan | -| -nan | :negative_nan | -| Boolean | boolean | -| Offset Date-Time | DateTime.t | -| Local Date-Time | NaiveDateTime.t | -| Local Date | Date.t | -| Local Time | Time.t | -| Array | list | -| Table | map | -| Table Array | list(map) | - -## Implementation-specific Behaviors - -Certain features of TOML have implementation-specific behavior: - -- `-inf`, `inf`, and `+inf` are all valid infinity values in TOML. - In Erlang/Elixir, these don't have exact representations. Instead, by convention, - `:infinity` is used for positive infinity, as atoms are always larger than integers - when using comparison operators, so `:infinity > <any integer>` will always be true. - However, negative infinity cannot be represented, as numbers are always considered smaller - than every other type in term comparisons. Instead, we represent it with `:negative_infinity`, - so that the type information is not lost, but you must be careful to deal with it specifically - in comparisons/sorting/etc. -- `-nan`, `nan`, and `+nan` are all valid NaN (not a number) values in TOML. In Erlang/Elixir, - NaN is traditionally represented with `:nan`, but there is no representation for negative NaN, - and no API actually produces `:nan`, instead invalid numbers typically raise errors, in the typical - spirit of "let it crash" in the face of errors. For purposes of preserving type information though, - we use the `:nan` convention, and `:negative_nan` for -NaN. You will need to take care to deal with - these values manually if the values need to be preserved. -- The maximum precision of times in the various time types is microseconds (i.e. precision to six decimal places), - if you provide higher precision values (i.e. nanoseconds), the extra precision will be lost. -- Hex, octal, and binary numbers are converted to integers, so serializing those values after decoding - them from a TOML document will be in their decimal representation. - -## Example Usage - -The following is a brief overview of how to use this library. First, let's take -a look at an example TOML file, as borrowed from the [TOML -homepage](https://github.com/toml-lang/toml): - -``` toml -# This is a TOML document. - -title = "TOML Example" - -[owner] -name = "Tom Preston-Werner" -dob = 1979-05-27T07:32:00-08:00 # First class dates - -[database] -server = "192.168.1.1" -ports = [ 8001, 8001, 8002 ] -connection_max = 5000 -enabled = true - -[servers] - - # Indentation (tabs and/or spaces) is allowed but not required - [servers.alpha] - ip = "10.0.0.1" - dc = "eqdc10" - - [servers.beta] - ip = "10.0.0.2" - dc = "eqdc10" - -[clients] -data = [ ["gamma", "delta"], [1, 2] ] - -# Line breaks are OK when inside arrays -hosts = [ - "alpha", - "omega" -] -``` - -### Parsing - -```elixir -iex> input = """ -[database] -server = "192.168.1.1" -""" -...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode(input) -...> {:ok, %{database: %{server: "192.168.1.1"}}} = Toml.decode(input, keys: :atoms) -...> stream = File.stream!("example.toml") -...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode_stream(stream) -...> {:ok, %{"database" => %{"server" => "192.168.1.1"}}} = Toml.decode_file("example.toml") -...> invalid = """ -[invalid] -a = 1 b = 2 -""" -...> {:error, {:invalid_toml, reason}} = Toml.decode(invalid); IO.puts(reason) -expected '\n', but got 'b' in nofile on line 2: - - a = 1 b = 2 - ^ - -:ok -``` - -### Transforms - -Support for extending value conversions is provided by the `Toml.Transform` -behavior. An example is shown below: - -Given the following TOML document: - -``` toml -[servers.alpha] -ip = "192.168.1.1" -ports = [8080, 8081] - -[servers.beta] -ip = "192.168.1.2" -ports = [8082, 8083] -``` - -And the following modules: - -``` elixir -defmodule Server do - defstruct [:name, :ip, :ports] -end - -defmodule IPStringToCharlist do - use Toml.Transform - - def transform(:ip, v) when is_binary(v) do - String.to_charlist(v) - end - def transform(_k, v), do: v -end - -defmodule CharlistToIP do - use Toml.Transform - - def transform(:ip, v) when is_list(v) do - case :inet.parse_ipv4_address(v) do - {:ok, address} -> - address - {:error, reason} -> - {:error, {:invalid_ip_address, reason}} - end - end - def transform(:ip, v), do: {:error, {:invalid_ip_address, v}} - def transform(_k, v), do: v -end - -defmodule ServerMapToList do - use Toml.Transform - - def transform(:servers, v) when is_map(v) do - for {name, server} <- v, do: struct(Server, Map.put(server, :name, name)) - end - def transform(_k, v), do: v -end -``` - -You can convert the TOML document to a more strongly-typed version using the -above transforms like so: - -```elixir -iex> transforms = [IPStringToCharlist, CharlistToIP, ServerMapToList] -...> {:ok, result} = Toml.decode("example.toml", keys: :atoms, transforms: transforms) -%{servers: [%Server{name: :alpha, ip: {192,168,1,1}}, ports: [8080, 8081] | _]} -``` - -The transforms given here are intended to show how they can be composed: they -are applied in the order provided, and the document is transformed using a -depth-first, bottom-up traversal. Put another way, you transform the leaves of -the tree before the branches; as shown in the example above, this means the -`:ip` key is converted to an address tuple before the `:servers` key is -transformed into a list of `Server` structs. - -## Using with Elixir Releases (1.9+) - -To use this library as a configuration provider in Elixir, use the following -example of how one might use it in their release configuration, and tailor it -to your needs: - -```elixir -config_providers: [ - {Toml.Provider, [ - path: {:system, "XDG_CONFIG_DIR", "myapp.toml"}, - transforms: [...] - ]} -] -``` - -See the "Using as a Config Provider" section for more info. - -## Using with Distillery - -Like the above, use the following example as a guideline for how you use this -in your own release configuration (i.e. in `rel/config.exs`): - -``` elixir -release :myapp do - # ...snip... - set config_providers: [ - {Toml.Provider, [path: "${XDG_CONFIG_DIR}/myapp.toml", transforms: [...]]} - ] -end -``` - -## Using as a Config Provider - -The usages described above will result in `Toml.Provider` being invoked during boot, at which point it -will evaluate the given path and read the TOML file it finds. If one is not -found, or is not accessible, the provider will raise an error, and the boot -sequence will terminate unsuccessfully. If it succeeds, it persists settings in -the file to the application environment (i.e. you access it via -`Application.get_env/2`). - -You can pass the same options in the arguments list for `Toml.Provider` as you -can to `Toml.decode/2`, but `:path` is required, and `:keys` only supports -`:atoms` and `:atoms!` values. - -The config provider expects a certain format to the TOML file, namely that keys -at the root of the document correspond to applications which need to be configured. -If it encounters keys at the root of the document which are not tables, they are ignored. - -``` toml -# This is an example of something that would be ignored -title = "My config file" - -# We're expecting something like this: -[myapp] -key = "value" - -# To use a bit of Phoenix config, you translate to TOML like so: -[myapp."MyApp.Endpoint"] -cache_static_manifest = "priv/static/cache_manifest.json" - -[myapp."MyApp.Endpoint".http] -port = "4000" - -[myapp."MyApp.Endpoint".force_ssl] -hsts = true - -# Or logger.. -[logger] -level = "info" - -[logger.console] -format = "[$level] $message \n" -``` - -## Roadmap - -- [x] Add benchmarking suite -- [x] Provide options for converting keys to atom, similar to Jason/Poison/etc. -- [ ] Optimize lexer to always send offsets to decoder, rather than only in some cases -- [ ] Try to find pathological TOML files to test - -## License - -This project is licensed Apache 2.0, see the `LICENSE` file in this repo for details. diff --git a/test-community-packages-javascript/build/packages/toml/lib/builder.ex b/test-community-packages-javascript/build/packages/toml/lib/builder.ex deleted file mode 100644 index 8491af59817..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/builder.ex +++ /dev/null @@ -1,413 +0,0 @@ -defmodule Toml.Builder do - @moduledoc false - - @compile inline: [key: 3, keys: 2, comment: 2, open: 2, close: 1, to_result: 1] - - # Builds a Document, performing validation along the way - - alias Toml.Document - - @doc """ - Creates a new empty TOML document to build with. - """ - defdelegate new(opts), to: Document - - @doc """ - Starts a new table and sets the context for subsequent key/values - """ - def push_table(%Document{} = doc, keypath) do - with {:ok, doc} = push_key(%Document{doc | open_table: nil}, keypath, {:table_decl, %{}}) do - # We're explicitly opening a new table - doc |> open(keypath) |> to_result() - end - end - - @doc """ - Starts a new array of tables and sets the context for subsequent key/values - """ - def push_table_array(%Document{} = doc, keypath) do - with {:ok, doc} = push_key(%Document{doc | open_table: nil}, keypath, {:table_array, []}) do - # We're explicitly opening a new table - doc |> open(keypath) |> to_result() - end - end - - @doc """ - Push a comment on a stack containing lines of comments applying to some element. - Comments are collected and assigned to key paths when a key is set, table created, etc. - """ - def push_comment(%Document{comment_stack: cs} = doc, comment) do - %Document{doc | comment_stack: [comment | cs]} - end - - @doc """ - Push a value for a key into the TOML document. - - This operation is used when any key/value pair is set, and table or table array is defined. - - Based on the key the type of the value provided, the behavior of this function varies, as validation - as performed as part of setting the key, to ensure that redefining keys is prohibited, but that setting - child keys of existing tables is allowed. Table arrays considerably complicate this unfortunately. - """ - def push_key(%Document{keys: ks} = doc, [key], value) - when is_map(value) and map_size(value) == 0 - when is_tuple(value) and elem(value, 0) == :table_decl do - # New table - keypath = [key] - - case Map.get(ks, key) do - nil -> - doc - |> key(key, %{}) - |> comment(keypath) - |> open(keypath) - |> to_result() - - exists when is_map(exists) -> - cond do - map_size(exists) == 0 -> - # Redefinition - key_exists!(keypath) - - Enum.all?(exists, fn - {_, v} when is_map(v) -> true - _ -> false - end) -> - # All keys are sub-tables, we'll allow this - doc - |> comment(keypath) - |> open(keypath) - |> to_result() - - :else -> - {k, _} = Enum.find(exists, fn {_, v} -> not is_map(v) end) - key_exists!(keypath ++ [k]) - end - - _exists -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, [key], value) when is_map(value) do - # Pushing an inline table - keypath = - case doc.open_table do - nil -> - [key] - - opened -> - opened ++ [key] - end - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, [key], {:table_array, _} = value) do - keypath = [key] - - case push_key_into_table(ks, [key], value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> close() - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks, open_table: nil} = doc, [key], value) do - # Pushing a key/value pair at the root level of the document - keypath = [key] - - if Map.has_key?(ks, key) do - key_exists!(keypath) - end - - doc - |> key(key, value) - |> comment(keypath) - |> close() - |> to_result() - end - - def push_key(%Document{keys: ks, open_table: opened} = doc, [key], value) do - # Pushing a key/value pair when a table is open - keypath = opened ++ [key] - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, keypath, value) - when is_list(keypath) and is_map(value) - when is_list(keypath) and is_tuple(value) and elem(value, 0) == :table_decl do - # Pushing a multi-part key with a table value - keypath = - case doc.open_table do - nil -> - keypath - - opened -> - opened ++ keypath - end - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - def push_key(%Document{keys: ks} = doc, keypath, value) when is_list(keypath) do - # Pushing a multi-part key with a plain value - keypath = - case doc.open_table do - nil -> - keypath - - opened -> - opened ++ keypath - end - - case push_key_into_table(ks, keypath, value) do - {:ok, ks} -> - doc - |> keys(ks) - |> comment(keypath) - |> to_result() - - {:error, :key_exists} -> - key_exists!(keypath) - end - end - - # Handles pushing a value into a map, arbitrarily deep, and respecting - # the desired behavior of table arrays. Can be used with any map. - # - # NOTE: This is similar to `put_in/3`, but does not raise if a key does - # exist, instead it creates a new table (map) at the level needed, and continues - # pushing the key into this new table - @doc false - def push_key_into_table({:table_array, array}, [key], {:table_array, _} = value) do - case array do - [] -> - {:ok, {:table_array, [Map.put(%{}, key, value)]}} - - [h | t] when is_map(h) -> - case Map.get(h, key) do - nil -> - {:ok, {:table_array, [Map.put(h, key, value) | t]}} - - {:table_array, items} -> - {:ok, {:table_array, [Map.put(h, key, {:table_array, [%{} | items]}) | t]}} - - _ -> - {:error, :key_exists} - end - end - end - - def push_key_into_table({:table_array, array}, keypath, {:table_decl, value}) do - case array do - [] -> - {:ok, {:table_array, [value]}} - - [h | t] when is_map(h) -> - case push_key_into_table(h, keypath, {:table_decl, value}) do - {:ok, h2} -> - {:ok, {:table_array, [h2 | t]}} - - {:error, _} = err -> - err - end - end - end - - def push_key_into_table({:table_array, array}, keypath, value) when is_map(value) do - case array do - [] -> - {:ok, {:table_array, [value]}} - - [h | t] when is_map(h) -> - case push_key_into_table(h, keypath, value) do - {:ok, h2} -> - {:ok, {:table_array, [h2 | t]}} - - {:error, _} = err -> - err - end - end - end - - def push_key_into_table({:table_array, array}, keypath, value) do - # Adding key/value to last table item - case array do - [] -> - case push_key_into_table(%{}, keypath, value) do - {:ok, item} -> - {:ok, {:table_array, [item]}} - - {:error, _} = err -> - err - end - - [h | t] when is_map(h) -> - case push_key_into_table(h, keypath, value) do - {:ok, h2} -> - {:ok, {:table_array, [h2 | t]}} - - {:error, _} = err -> - err - end - end - end - - def push_key_into_table(ts, [key], {:table_decl, value}) do - case Map.get(ts, key) do - nil -> - {:ok, Map.put(ts, key, value)} - - exists when is_map(exists) -> - # We're reopening a table, but we allow it as long as keys - # in that table don't override previously defined keys - {:ok, ts} - - _exists -> - {:error, :key_exists} - end - end - - def push_key_into_table(ts, [key], value) when is_map(ts) do - # Reached final table - case Map.get(ts, key) do - nil -> - {:ok, Map.put(ts, key, value)} - - {:table_array, items} - when is_list(items) and is_tuple(value) and elem(value, 0) == :table_array -> - # Appending to table array - {:ok, Map.put(ts, key, {:table_array, [%{} | items]})} - - {:table_array, items} when is_list(items) and is_map(value) -> - # Pushing into table array - {:ok, Map.put(ts, key, {:table_array, [value | items]})} - - exists when is_map(exists) and is_map(value) and map_size(value) > 0 -> - result = - Enum.reduce(value, exists, fn {k, v}, acc -> - case push_key_into_table(acc, [k], v) do - {:ok, acc2} -> - acc2 - - {:error, _} = err -> - throw(err) - end - end) - - {:ok, result} - - _exists -> - {:error, :key_exists} - end - catch - :throw, {:error, _} = err -> - err - end - - def push_key_into_table(ts, _keypath, _value) when not is_map(ts) do - # The table we're trying to push into is not itself a table, this is redefinition! - {:error, :key_exists} - end - - def push_key_into_table(ts, [table | keypath], value) when is_map(ts) do - result = - case Map.get(ts, table) do - nil -> - push_key_into_table(%{}, keypath, value) - - child -> - push_key_into_table(child, keypath, value) - end - - case result do - {:ok, child} -> - {:ok, Map.put(ts, table, child)} - - {:error, _} = err -> - err - end - end - - # Raised if the given keypath has already been defined - # and the value being set at that keypath is not an inline - # table (effectively extending the keypath and pushing multiple values), - # or table array (resulting in a new table being pushed into that array) - @spec key_exists!([binary]) :: no_return - defp key_exists!(keypath), - do: error!({:key_exists, Enum.join(keypath, ".")}) - - # Raised due to any other document builder error - @spec error!([binary]) :: no_return - defp error!(reason), - do: throw({:error, {:invalid_toml, reason}}) - - # Set a key at the document root - defp key(%Document{keys: keys} = doc, key, value), - do: %Document{doc | keys: Map.put(keys, key, value)} - - # Replace the set of keys in the document - defp keys(%Document{} = doc, keys), - do: %Document{doc | keys: keys} - - # Comment the given key, if comments are available on the stack - defp comment(%Document{comments: cs, comment_stack: stack} = doc, key) do - comment = - stack - |> Enum.reverse() - |> Enum.join("\n") - - if byte_size(comment) > 0 do - %Document{doc | comment_stack: [], comments: Map.put(cs, key, comment)} - else - %Document{doc | comment_stack: []} - end - end - - # Open a table at the given key - defp open(%Document{} = doc, key), - do: %Document{doc | open_table: key} - - # Close any open table - defp close(%Document{} = doc), - do: %Document{doc | open_table: nil} - - # Wrap the document in a ok tuple - defp to_result(%Document{} = doc), - do: {:ok, doc} -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/decoder.ex b/test-community-packages-javascript/build/packages/toml/lib/decoder.ex deleted file mode 100644 index ac0801adab1..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/decoder.ex +++ /dev/null @@ -1,1055 +0,0 @@ -defmodule Toml.Decoder do - @moduledoc false - - alias Toml.Document - alias Toml.Builder - alias Toml.Lexer - - @compile :inline_list_funs - @compile inline: [ - pop_skip: 2, - peek_skip: 2, - iodata_to_str: 1, - iodata_to_integer: 1, - iodata_to_float: 1 - ] - - @doc """ - Decodes a raw binary into a map. - - `Toml.Error` is raised if decoding fails. - """ - @spec decode!(binary, Toml.opts()) :: map | no_return - def decode!(bin, opts) when is_binary(bin) and is_list(opts) do - # Raise if the filename is invalid - filename = - case Keyword.get(opts, :filename, "nofile") do - name when is_binary(name) -> - name - - n -> - raise ArgumentError, "invalid :filename option '#{inspect(n)}', must be a binary!" - end - - # Get our lexer outside the try so that we can stop it if things go south - # This can only fail if the lexer process itself crashes during init - {:ok, lexer} = Lexer.new(bin) - - try do - case do_decode(lexer, bin, Builder.new(opts)) do - {:ok, doc} -> - case Document.to_map(doc) do - {:ok, result} -> - result - - {:error, reason} -> - raise Toml.Error, reason - end - - {:error, reason, skip, lines} -> - raise Toml.Error, format_error(reason, bin, filename, skip, lines) - end - catch - :throw, {:error, {:invalid_toml, reason}} -> - raise Toml.Error, reason - - :throw, {:badarg, {option, value, valid}} -> - raise Toml.Error, {:badarg, option, value, valid} - after - Lexer.stop(lexer) - end - end - - @doc """ - Decodes a raw binary safely, returns `{:ok, map}` or `{:error, reason}` - """ - @spec decode(binary, Toml.opts()) :: {:ok, map} | Toml.error() - def decode(bin, opts) when is_binary(bin) and is_list(opts) do - {:ok, decode!(bin, opts)} - rescue - err in [Toml.Error] -> - {:error, {:invalid_toml, Exception.message(err)}} - - err in [ArgumentError] -> - {:error, err.message} - catch - :error, reason -> - {:error, Toml.Error.format_reason(reason)} - end - - @doc """ - Decodes a stream. - - Raises `Toml.Error` if decoding fails. - """ - @spec decode_stream!(Enumerable.t(), Toml.opts()) :: map | no_return - def decode_stream!(stream, opts) do - decode!(Enum.into(stream, <<>>), opts) - end - - @doc """ - Decodes a stream safely. - - Returns same type as `decode/2` - """ - @spec decode_stream(Enumerable.t(), Toml.opts()) :: {:ok, map} | Toml.error() - def decode_stream(stream, opts) do - decode(Enum.into(stream, <<>>), opts) - end - - @doc """ - Decodes a file. - - Raises `Toml.Error` if decoding fails. - """ - @spec decode_file!(String.t(), Toml.opts()) :: map | no_return - def decode_file!(path, opts) when is_binary(path) do - with {:ok, opts} <- set_filename_opt(opts, path), - bin = File.read!(path) do - decode!(bin, opts) - end - end - - @doc """ - Decodes a file safely. - - Returns same type as `decode/2` - """ - @spec decode_file(String.t(), Toml.opts()) :: {:ok, map} | Toml.error() - def decode_file(path, opts) when is_binary(path) do - with {:ok, opts} <- set_filename_opt(opts, path), - {:ok, bin} <- File.read(path) do - decode(bin, opts) - else - {:error, reason} -> - {:error, "unable to open file '#{Path.relative_to_cwd(path)}': #{inspect(reason)}"} - end - end - - defp set_filename_opt(opts, default) do - case Keyword.get(opts, :filename) do - nil -> - {:ok, Keyword.put(opts, :filename, default)} - - _name -> - {:ok, opts} - end - end - - ## Decoder Implementation - - @spec do_decode(Lexer.t(), binary, Document.t()) :: {:ok, Document.t()} | Lexer.lexer_err() - defp do_decode(lexer, original, %Document{} = doc) do - with {:ok, {type, skip, data, lines}} <- Lexer.pop(lexer) do - handle_token(lexer, original, doc, type, skip, data, lines) - end - end - - # Converts an error into a friendly, printable representation - defp format_error(reason, original, filename, skip, lines) do - msg = - "#{Toml.Error.format_reason(reason)} in #{Path.relative_to_cwd(filename)} on line #{lines}" - - {ctx, pos} = seek_line(original, skip - 1, lines) - - """ - #{msg}: - - #{ctx} - #{String.duplicate(" ", pos)}^ at column #{pos} - """ - end - - # Finds the line of context for display in a formatted error - defp seek_line(original, skip, lines) do - seek_line(original, original, 0, 0, skip, lines - 1) - end - - defp seek_line(original, rest, lastnl, from, len, 0) do - case seek_to_eol(rest, 0) do - 0 -> - {binary_part(original, lastnl, from - lastnl), from - lastnl} - - len_to_eol when len_to_eol > 0 -> - {binary_part(original, from, len_to_eol), len} - end - end - - defp seek_line(original, <<?\r, ?\n, rest::binary>>, lastnl, from, len, 1) when len <= 0 do - # Content occurred on the last line right before the newline - seek_line(original, rest, lastnl, from + 2, 0, 0) - end - - defp seek_line(original, <<?\r, ?\n, rest::binary>>, _, from, len, lines) do - seek_line(original, rest, from + 2, from + 2, len - 2, lines - 1) - end - - defp seek_line(original, <<?\n, rest::binary>>, lastnl, from, len, 1) when len <= 0 do - # Content occurred on the last line right before the newline - seek_line(original, rest, lastnl, from + 1, 0, 0) - end - - defp seek_line(original, <<?\n, rest::binary>>, _, from, len, lines) do - seek_line(original, rest, from + 1, from + 1, len - 1, lines - 1) - end - - defp seek_line(original, <<_::utf8, rest::binary>>, lastnl, from, len, lines) do - seek_line(original, rest, lastnl, from + 1, len - 1, lines) - end - - # Find the number of bytes to the end of the current line in the input - defp seek_to_eol(<<>>, len), do: len - defp seek_to_eol(<<?\r, ?\n, _::binary>>, len), do: len - defp seek_to_eol(<<?\n, _::binary>>, len), do: len - - defp seek_to_eol(<<_::utf8, rest::binary>>, len) do - seek_to_eol(rest, len + 1) - end - - # Handles invalid byte sequences (i.e. invalid unicode) - # Considers the invalid byte as EOL so context can still be shown - defp seek_to_eol(<<_, _rest::binary>>, len), do: len - - # Skip top-level whitespace and newlines - @spec handle_token( - Lexer.t(), - binary, - Document.t(), - Lexer.type(), - Lexer.skip(), - binary | non_neg_integer, - Lexer.lines() - ) :: {:ok, Document.t()} | Lexer.lexer_err() - defp handle_token(lexer, original, doc, :whitespace, _skip, _data, _lines), - do: do_decode(lexer, original, doc) - - defp handle_token(lexer, original, doc, :newline, _skip, _data, _lines), - do: do_decode(lexer, original, doc) - - # Push comments on the comment stack - defp handle_token(lexer, original, doc, :comment, skip, size, _lines) do - comment = binary_part(original, skip - size, size) - do_decode(lexer, original, Builder.push_comment(doc, comment)) - end - - # Handle valid top-level entities - # - array of tables - # - table - # - key/value - defp handle_token(lexer, original, doc, ?\[, skip, data, lines) do - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {?\[, _, _, _}} -> - # Push opening bracket, second was peeked, so no need - Lexer.push(lexer, {?\[, skip, data, lines}) - handle_table_array(lexer, original, doc) - - {:ok, {_, _, _, _}} -> - Lexer.push(lexer, {?\[, skip, data, lines}) - handle_table(lexer, original, doc) - end - end - - defp handle_token(lexer, original, doc, type, skip, data, lines) - when type in [:digits, :alpha, :string] do - Lexer.push(lexer, {type, skip, data, lines}) - - with {:ok, key, _skip, _lines} <- key(lexer) do - handle_key(lexer, original, doc, key) - end - end - - defp handle_token(lexer, original, doc, type, skip, _data, lines) when type in '-_' do - handle_token(lexer, original, doc, :string, skip, <<type::utf8>>, lines) - end - - # We're done - defp handle_token(_lexer, _original, doc, :eof, _skip, _data, _lines) do - {:ok, doc} - end - - # Anything else at top-level is invalid - defp handle_token(_lexer, _original, _doc, type, skip, data, lines) do - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - defp handle_key(lexer, original, doc, key) do - with {:ok, {?=, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, value} <- value(lexer), - {:ok, doc} <- Builder.push_key(doc, key, value) do - # Make sure key/value pairs are separated by a newline - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - # Implies newline - do_decode(lexer, original, doc) - - {:ok, {type, _, _, _}} when type in [:newline, :eof] -> - do_decode(lexer, original, doc) - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, :newline, {type, data}}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, ?=, {type, data}}, skip, lines} - end - end - - defp handle_table(lexer, original, doc) do - # Guaranteed to have an open bracket - with {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, key, _line, _col} <- key(lexer), - {:ok, {?\], _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, doc} <- Builder.push_table(doc, key) do - # Make sure table opening is followed by newline - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - do_decode(lexer, original, doc) - - {:ok, {type, _, _, _}} when type in [:newline, :eof] -> - do_decode(lexer, original, doc) - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, :newline, {type, data}}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp handle_table_array(lexer, original, doc) do - # Guaranteed to have two open brackets - with {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, {?\[, _, _, _}} <- pop_skip(lexer, [:whitespace]), - {:ok, key, _, _} <- key(lexer), - {_, {:ok, {?\], _, _, _}}} <- {:close, pop_skip(lexer, [:whitespace])}, - {_, {:ok, {?\], _, _, _}}} <- {:close, pop_skip(lexer, [:whitespace])}, - {:ok, doc} <- Builder.push_table_array(doc, key) do - # Make sure table opening is followed by newline - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - do_decode(lexer, original, doc) - - {:ok, {type, _, _, _}} when type in [:newline, :eof] -> - do_decode(lexer, original, doc) - - {:ok, {type, skip, data, lines}} -> - {:error, {:expected, :newline, {type, data}}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {_, {:error, _, _, _} = err} -> - err - - {:close, {:ok, {type, skip, data, lines}}} -> - {:error, {:unclosed_table_array_name, {type, data}}, skip, lines} - end - end - - defp maybe_integer(lexer) do - case pop_skip(lexer, [:whitespace]) do - {:ok, {type, _skip, _data, _lines}} when type in '-+' -> - # Can be integer, float - case Lexer.peek(lexer) do - {:error, _, _, _} = err -> - err - - # Handle infinity/nan with leading sign - {:ok, {:alpha, _, "inf", _}} -> - Lexer.advance(lexer) - - if type == ?\+ do - {:ok, :infinity} - else - {:ok, :negative_infinity} - end - - {:ok, {:alpha, _, "nan", _}} -> - Lexer.advance(lexer) - - if type == ?\+ do - {:ok, :nan} - else - {:ok, :negative_nan} - end - - # Must be a signed integer or float - {:ok, {:digits, _, d, _}} -> - Lexer.advance(lexer) - maybe_integer(lexer, [d, type]) - - # Invalid - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - {:ok, {:digits, skip, <<leader::utf8, _::utf8, _::utf8, _::utf8>> = d, lines} = token} -> - # Could be a datetime - case Lexer.peek(lexer) do - {:ok, {?-, _, _, _}} -> - # This is a date or datetime - Lexer.push(lexer, token) - maybe_datetime(lexer) - - {:ok, {?., _, _, _}} -> - # Float - Lexer.advance(lexer) - float(lexer, ?., [?., d]) - - {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' -> - # Float - Lexer.advance(lexer) - float(lexer, ?e, [?e, ?0, ?., d]) - - {:ok, {?_, _, _, _}} -> - # Integer - maybe_integer(lexer, [d]) - - _ -> - # Just an integer - if leader == ?0 do - # Leading zeroes not allowed - {:error, {:invalid_integer, :leading_zero}, skip, lines} - else - {:ok, String.to_integer(d)} - end - end - - {:ok, {:digits, skip, <<leader::utf8, _::utf8>> = d, lines} = token} -> - # Could be a time - case Lexer.peek(lexer) do - {:ok, {?:, _, _, _}} -> - # This is a local time - Lexer.push(lexer, token) - time(lexer) - - _ -> - # It's just an integer - if leader == ?0 do - # Leading zeros not allowed - {:error, {:invalid_integer, :leading_zero}, skip, lines} - else - maybe_integer(lexer, [d]) - end - end - - {:ok, {:digits, _, d, _}} -> - # Just a integer or float - maybe_integer(lexer, [d]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp maybe_integer(lexer, parts) do - case Lexer.pop(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {?., _, _, _}} -> - # Float - float(lexer, ?., [?. | parts]) - - {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' -> - # Float, need to add .0 before e, or String.to_float fails - float(lexer, ?e, [?e, ?0, ?. | parts]) - - {:ok, {?_, _, _, _}} -> - case Lexer.peek(lexer) do - {:ok, {:digits, _, d, _}} -> - # Allowed, just skip the underscore - Lexer.advance(lexer) - maybe_integer(lexer, [d | parts]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - - {:error, _, _, _} = err -> - err - end - - {:ok, {_, skip, _, lines} = token} -> - # Just an integer - Lexer.push(lexer, token) - - with {:ok, _} = result <- iodata_to_integer(parts) do - result - else - {:error, reason} -> - {:error, reason, skip, lines} - end - end - end - - defp float(lexer, signal, [last | _] = parts) do - case Lexer.pop(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {?., skip, _, lines}} -> - # Always an error at this point, as either duplicate or after E - {:error, {:invalid_float, {?., 0}}, skip, lines} - - {:ok, {sign, _, _, _}} when sign in '-+' and last == ?e -> - # +/- are allowed after e/E - float(lexer, signal, [sign | parts]) - - {:ok, {:alpha, _, <<c::utf8>>, _}} when c in 'eE' and signal == ?. -> - # Valid if after a dot - float(lexer, ?e, [?e | parts]) - - {:ok, {?_, skip, _, lines}} when last not in '_e.' -> - # Valid only when surrounded by digits - with {:ok, {:digits, _, d, _}} <- Lexer.peek(lexer), - _ = Lexer.advance(lexer) do - float(lexer, signal, [d | parts]) - else - {:error, _, _, _} = err -> - err - - {:ok, {_, _, _, _}} -> - {:error, {:invalid_float, {?_, 0}}, skip, lines} - end - - {:ok, {:digits, _, d, _}} -> - float(lexer, signal, [d | parts]) - - {:ok, {type, skip, data, lines}} when last in 'e.' -> - # Incomplete float - {:error, {:invalid_float, {type, data}}, skip, lines} - - {:ok, {_type, skip, _data, lines} = token} when last not in '_e.' -> - # Done - Lexer.push(lexer, token) - - with {:ok, _} = result <- iodata_to_float(parts) do - result - else - {:error, reason} -> - {:error, reason, skip, lines} - end - end - end - - defp time(lexer) do - # At this point we know we have at least HH: - with {:ok, {:digits, skip, <<_::utf8, _::utf8>> = hh, lines}} <- Lexer.pop(lexer), - {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer), - {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = ss, _}} <- Lexer.pop(lexer) do - # Check for fractional - parts = [ss, ?:, mm, ?:, hh] - - parts = - case Lexer.peek(lexer) do - {:ok, {?., _, _, _}} -> - Lexer.advance(lexer) - - case Lexer.pop(lexer) do - {:ok, {:digits, _, d, _}} -> - [d, ?. | parts] - - {:ok, {type, skip, data, lines}} -> - # Invalid - throw({:error, {:invalid_token, {type, data}}, skip, lines}) - - {:error, reason, skip, lines} -> - throw({:error, {:invalid_fractional_seconds, reason}, skip, lines}) - end - - {:ok, _} -> - parts - end - - case Time.from_iso8601(iodata_to_str(parts)) do - {:ok, _} = result -> - result - - {:error, :invalid_time} -> - {:error, :invalid_time, skip, lines} - - {:error, reason} -> - {:error, {:invalid_time, reason}, skip, lines} - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - catch - :throw, {:error, _, _, _} = err -> - err - end - - defp maybe_datetime(lexer) do - # At this point we have at least YYYY- - with {:ok, {:digits, _, <<_::utf8, _::utf8, _::utf8, _::utf8>> = yy, _}} <- Lexer.pop(lexer), - {:ok, {?-, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer), - {:ok, {?-, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, skip, <<_::utf8, _::utf8>> = dd, lines}} <- Lexer.pop(lexer) do - # At this point we have a full date, check for time - case Lexer.pop(lexer) do - {:ok, {:alpha, _, "T", _}} -> - # Expecting a time - with {:ok, time} <- time(lexer) do - datetime(lexer, [dd, ?-, mm, ?-, yy], time) - end - - {:ok, {:whitespace, _, _, _}} -> - case Lexer.peek(lexer) do - {:ok, {:digits, _, <<_::utf8, _::utf8>>, _}} -> - # Expecting a time - with {:ok, time} <- time(lexer) do - datetime(lexer, [dd, ?-, mm, ?-, yy], time) - end - - _ -> - # Just a date - case Date.from_iso8601(iodata_to_str([dd, ?-, mm, ?-, yy])) do - {:ok, _} = result -> - result - - {:error, :invalid_date} -> - {:error, :invalid_date, skip, lines} - - {:error, reason} -> - {:error, {:invalid_date, reason}, skip, lines} - end - end - - {:ok, {_type, skip, _data, lines} = token} -> - # Just a date - Lexer.push(lexer, token) - - case Date.from_iso8601(iodata_to_str([dd, ?-, mm, ?-, yy])) do - {:ok, _} = result -> - result - - {:error, :invalid_date} -> - {:error, :invalid_date, skip, lines} - - {:error, reason} -> - {:error, {:invalid_date, reason}, skip, lines} - end - end - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp datetime(lexer, parts, time) do - # Track the current lexer position for errors - {:ok, skip, lines} = Lexer.pos(lexer) - # Convert parts to string - datestr = iodata_to_str(parts) - # At this point we have at least YYYY-mm-dd and a fully decoded time - with {_, {:ok, date}} <- {:date, Date.from_iso8601(datestr)}, - {_, {:ok, naive}} <- {:datetime, NaiveDateTime.new(date, time)} do - # We just need to check for Z or UTC offset - case Lexer.pop(lexer) do - {:ok, {:alpha, _, "Z", _}} -> - DateTime.from_naive(naive, "Etc/UTC") - - {:ok, {sign, _, _, _}} when sign in '-+' -> - # We have an offset - with {:ok, {:digits, _, <<_::utf8, _::utf8>> = hh, _}} <- Lexer.pop(lexer), - {:ok, {?:, _, _, _}} <- Lexer.pop(lexer), - {:ok, {:digits, _, <<_::utf8, _::utf8>> = mm, _}} <- Lexer.pop(lexer) do - # Shift naive to account for offset - hours = String.to_integer(hh) - mins = String.to_integer(mm) - offset = hours * 60 * 60 + mins * 60 - - naive = - case sign do - ?- -> - NaiveDateTime.add(naive, offset * -1, :second) - - ?+ -> - NaiveDateTime.add(naive, offset, :second) - end - - DateTime.from_naive(naive, "Etc/UTC") - else - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_datetime_offset, {type, data}}, skip, lines} - end - - {:ok, {type, _, _, _} = token} when type in [:eof, :whitespace, :newline] -> - # Just a local date/time - Lexer.push(lexer, token) - {:ok, naive} - end - else - {:date, {:error, :invalid_date}} -> - {:error, {:invalid_date, datestr}, skip, lines} - - {:date, {:error, reason}} -> - {:error, {:invalid_date, reason, datestr}, skip, lines} - - {:datetime, {:error, :invalid_date}} -> - {:error, {:invalid_datetime, {datestr, time}}, skip, lines} - - {:datetime, {:error, reason}} -> - {:error, {:invalid_date, reason, {datestr, time}}, skip, lines} - - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - # Allowed values - # - Array - # - Inline table - # - Integer (in all forms) - # - Float - # - String - # - DateTime - defp value(lexer) do - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {:comment, _, _, _}} -> - Lexer.advance(lexer) - value(lexer) - - {:ok, {?\[, _skip, _, _lines}} -> - # Need to embellish some errors with line/col - with {:ok, _} = ok <- array(lexer) do - ok - else - {:error, _, _, _} = err -> - err - end - - {:ok, {?\{, _, _, _}} -> - inline_table(lexer) - - {:ok, {:hex, _, v, _}} -> - Lexer.advance(lexer) - {:ok, String.to_integer(v, 16)} - - {:ok, {:octal, _, v, _}} -> - Lexer.advance(lexer) - {:ok, String.to_integer(v, 8)} - - {:ok, {:binary, _, v, _}} -> - Lexer.advance(lexer) - {:ok, String.to_integer(v, 2)} - - {:ok, {true, _, _, _}} -> - Lexer.advance(lexer) - {:ok, true} - - {:ok, {false, _, _, _}} -> - Lexer.advance(lexer) - {:ok, false} - - {:ok, {:alpha, _, "inf", _}} -> - Lexer.advance(lexer) - {:ok, :infinity} - - {:ok, {:alpha, _, "nan", _}} -> - Lexer.advance(lexer) - {:ok, :nan} - - {:ok, {type, _, v, _}} when type in [:string, :multiline_string] -> - Lexer.advance(lexer) - {:ok, v} - - {:ok, {sign, _, _, _}} when sign in '-+' -> - maybe_integer(lexer) - - {:ok, {:digits, _, _, _}} -> - maybe_integer(lexer) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - end - - defp array(lexer) do - with {:ok, {?\[, skip, _, lines}} <- pop_skip(lexer, [:whitespace]), - {:ok, elements} <- accumulate_array_elements(lexer), - {_, _, {:ok, {?\], _, _, _}}} <- - {:close, {skip, lines}, pop_skip(lexer, [:whitespace, :newline, :comment])} do - {:ok, elements} - else - {:error, _, _, _} = err -> - err - - {:close, {:error, _, _, _} = err} -> - err - - {:close, {_oline, _ocol} = opened, {:ok, {_, eskip, _, elines}}} -> - {:error, {:unclosed_array, opened}, eskip, elines} - - {:valid?, err} -> - err - end - end - - defp inline_table(lexer) do - with {:ok, {?\{, skip, _, lines}} <- pop_skip(lexer, [:whitespace]), - {:ok, elements} <- accumulate_table_elements(lexer), - {_, _, {:ok, {?\}, _, _, _}}} <- {:close, {skip, lines}, pop_skip(lexer, [:whitespace])} do - {:ok, elements} - else - {:error, _, _, _} = err -> - err - - {:close, {:error, _, _, _} = err} -> - err - - {:close, {_oskip, _olines} = opened, {:ok, {_, eskip, _, elines}}} -> - {:error, {:unclosed_inline_table, opened}, eskip, elines} - end - end - - defp accumulate_array_elements(lexer) do - accumulate_array_elements(lexer, []) - end - - defp accumulate_array_elements(lexer, acc) do - with {:ok, {type, _, _, _}} <- peek_skip(lexer, [:whitespace, :newline, :comment]), - {_, false} <- {:trailing_comma, type == ?\]}, - {:ok, value} <- value(lexer), - {:ok, {next, _, _, _}} <- peek_skip(lexer, [:whitespace]) do - if next == ?, do - Lexer.advance(lexer) - accumulate_array_elements(lexer, [value | acc]) - else - {:ok, Enum.reverse([value | acc])} - end - else - {:error, _, _, _} = err -> - err - - {:trailing_comma, true} -> - {:ok, Enum.reverse(acc)} - end - end - - defp accumulate_table_elements(lexer) do - accumulate_table_elements(lexer, %{}) - end - - defp accumulate_table_elements(lexer, acc) do - with {:ok, {type, _, _, _}} <- peek_skip(lexer, [:whitespace, :newline, :comment]), - {_, false} <- {:trailing_comma, type == ?\}}, - {:ok, key, skip, lines} <- key(lexer), - {_, _, false, _, _} <- {:key_exists, key, Map.has_key?(acc, key), skip, lines}, - {:ok, {?=, _, _, _}} <- pop_skip(lexer, [:whitespace, :comments]), - {:ok, value} <- value(lexer), - {_, {:ok, acc2}} <- {key, Builder.push_key_into_table(acc, key, value)}, - {:ok, {next, _, _, _}} <- peek_skip(lexer, [:whitespace, :comments]) do - if next == ?, do - Lexer.advance(lexer) - accumulate_table_elements(lexer, acc2) - else - {:ok, acc2} - end - else - {:error, _, _, _} = err -> - err - - {:key_exists, key, true, line, col} -> - {:error, {:key_exists, key}, line, col} - - {table, {:error, :key_exists}} -> - {:error, {:key_exists_in_table, table}, -1, -1} - - {:trailing_comma, true} -> - {:ok, acc} - - {:ok, {type, skip, data, lines} = token} -> - Lexer.push(lexer, token) - {:error, {:invalid_key_value, {type, data}}, skip, lines} - end - end - - defp key(lexer) do - result = - case pop_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {type, skip, s, lines}} when type in [:digits, :alpha, :string] -> - {key(lexer, s, []), skip, lines} - - {:ok, {type, skip, _, lines}} when type in '-_' -> - {key(lexer, <<type::utf8>>, []), skip, lines} - - {:ok, {type, skip, data, lines} = token} -> - Lexer.push(lexer, token) - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - case result do - {:error, _, _, _} = err -> - err - - {{:ok, key}, skip, lines} -> - {:ok, key, skip, lines} - - {{:error, _, _, _} = err, _, _} -> - err - end - end - - defp key(lexer, word, acc) do - case Lexer.peek(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {:whitespace, _, _, _}} -> - # The only allowed continuation now is a . followed by key char - case peek_skip(lexer, [:whitespace]) do - {:ok, {?., _, _, _}} -> - Lexer.advance(lexer) - - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} when type in [:digits, :alpha, :string] -> - key(lexer, "", [word | acc]) - - {:ok, {type, _, _, _}} when type in '-_' -> - key(lexer, "", [word | acc]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - {:ok, _} -> - {:ok, Enum.reverse([word | acc])} - end - - {:ok, {type, _, s, _}} when type in [:digits, :alpha, :string] -> - Lexer.advance(lexer) - key(lexer, word <> s, acc) - - {:ok, {type, _, _, _}} when type in '-_' -> - Lexer.advance(lexer) - key(lexer, word <> iodata_to_str([type]), acc) - - {:ok, {?., _, _, _}} -> - Lexer.advance(lexer) - - case peek_skip(lexer, [:whitespace]) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} when type in [:digits, :alpha, :string] -> - key(lexer, "", [word | acc]) - - {:ok, {type, _, _, _}} when type in '-_' -> - key(lexer, "", [word | acc]) - - {:ok, {type, skip, data, lines}} -> - {:error, {:invalid_token, {type, data}}, skip, lines} - end - - {:ok, _} -> - {:ok, Enum.reverse([word | acc])} - end - end - - defp iodata_to_integer(data) do - case iodata_to_str(data) do - <<?0, rest::binary>> when byte_size(rest) > 0 -> - {:error, {:invalid_integer, :leading_zero}} - - <<sign::utf8, ?0, rest::binary>> when (sign == ?- or sign == ?+) and byte_size(rest) > 0 -> - {:error, {:invalid_integer, :leading_zero}} - - s -> - {:ok, String.to_integer(s)} - end - end - - defp iodata_to_float(data) do - case iodata_to_str(data) do - <<?0, next::utf8, _::binary>> when next != ?. -> - {:error, {:invalid_float, :leading_zero}} - - <<sign::utf8, ?0, next::utf8, _::binary>> when (sign == ?- or sign == ?+) and next != ?. -> - {:error, {:invalid_float, :leading_zero}} - - s -> - {:ok, String.to_float(s)} - end - end - - defp iodata_to_str(parts) do - parts - |> Enum.reverse() - |> IO.chardata_to_string() - end - - defp pop_skip(lexer, skip) do - case Lexer.pop(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} = result -> - if :lists.member(type, skip) do - pop_skip(lexer, skip) - else - result - end - end - end - - defp peek_skip(lexer, skip) do - case Lexer.peek(lexer) do - {:error, _, _, _} = err -> - err - - {:ok, {type, _, _, _}} = result -> - if :lists.member(type, skip) do - Lexer.advance(lexer) - peek_skip(lexer, skip) - else - result - end - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/document.ex b/test-community-packages-javascript/build/packages/toml/lib/document.ex deleted file mode 100644 index 730abd17f86..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/document.ex +++ /dev/null @@ -1,182 +0,0 @@ -defmodule Toml.Document do - @moduledoc false - - # Represents a TOML document, and handles conversion to a plain map - # See `Toml.Builder` for the actual logic for constructing the document. - - defstruct [:keys, :comments, :open_table, :comment_stack, :keyfun, :transforms] - - # A key is either binary or atom depending on the decoder option value - @type key :: binary | atom | term - - # A value is the fully decoded value from the TOML - @type value :: - %{key => value} - | {:table_array, [%{key => value}]} - | number - | binary - | NaiveDateTime.t() - | DateTime.t() - | Date.t() - | Time.t() - | [value] - - # A keypath is a list of keys, they are all of the same key type - @type keypath :: list(binary) | list(atom) | list(term) - - @type t :: %__MODULE__{ - keys: %{key => value}, - comments: %{keypath => binary}, - open_table: keypath | nil, - comment_stack: [binary], - keyfun: nil | (binary -> term | no_return), - transforms: [Toml.Transform.t()] - } - - @doc """ - Create a new empty TOML document - """ - @spec new(Toml.opts()) :: t - def new(opts) when is_list(opts) do - keyfun = to_key_fun(Keyword.get(opts, :keys, :strings)) - transforms = Keyword.get(opts, :transforms, []) - - %__MODULE__{ - keys: %{}, - comments: %{}, - open_table: nil, - comment_stack: [], - keyfun: keyfun, - transforms: transforms - } - end - - @doc """ - Convert the given TOML document to a plain map. - - During conversion to a plain map, keys are converted according - to the key type defined when the document was created. - - In addition to converting keys, if transforms were defined, they are - applied to values depth-first, bottom-up. Transforms are first composed - into a single function, designed to be executed in the order they appear - in the list provided; if any transform returns an error, conversion is - stopped and an error is returned - otherwise, the value is passed from - transformer to transformer and the final result replaces the value in the - document. - """ - def to_map(%__MODULE__{keys: keys, keyfun: keyfun, transforms: ts}) do - transform = - case ts do - [] -> - nil - - ts when is_list(ts) -> - Toml.Transform.compose(ts) - end - - {:ok, to_map2(keys, keyfun, transform)} - catch - _, {:error, {:keys, {:non_existing_atom, _}}} = err -> - err - end - - # Called when a table is being converted - defp to_map2(m, nil, nil) when is_map(m) do - for {k, v} <- m, into: %{}, do: {k, to_map3(k, v, nil, nil)} - end - - defp to_map2(m, keyfun, nil) when is_map(m) and is_function(keyfun, 1) do - for {k, v} <- m, into: %{} do - k2 = keyfun.(k) - {k2, to_map3(k2, v, keyfun, nil)} - end - end - - defp to_map2(m, nil, transform) when is_map(m) and is_function(transform, 2) do - for {k, v} <- m, into: %{} do - v2 = to_map3(k, v, nil, transform) - {k, v2} - end - end - - defp to_map2(m, keyfun, transform) - when is_map(m) and is_function(keyfun, 1) and is_function(transform, 2) do - for {k, v} <- m, into: %{} do - k2 = keyfun.(k) - v2 = to_map3(k2, v, keyfun, transform) - {k2, v2} - end - end - - # Called when a table value is being converted - defp to_map3(_key, %_{} = s, _keyfun, nil), do: s - defp to_map3(key, %_{} = s, _keyfun, transform), do: transform.(key, s) - - defp to_map3(key, list, keyfun, nil) when is_list(list) do - for v <- list, do: to_map3(key, v, keyfun, nil) - end - - defp to_map3(key, list, _keyfun, transform) when is_list(list) do - transform.(key, list) - end - - defp to_map3(_key, {:table_array, list}, keyfun, nil) do - for v <- Enum.reverse(list) do - to_map2(v, keyfun, nil) - end - end - - defp to_map3(key, {:table_array, list}, keyfun, transform) do - for v <- Enum.reverse(list) do - to_map2(v, keyfun, transform) - end - |> (&transform.(key, &1)).() - end - - defp to_map3(_key, v, keyfun, nil) when is_map(v) do - to_map2(v, keyfun, nil) - end - - defp to_map3(key, v, keyfun, transform) when is_map(v) and is_function(transform) do - transform.(key, to_map2(v, keyfun, transform)) - end - - defp to_map3(_key, v, _keyfun, nil), do: v - defp to_map3(key, v, _keyfun, transform), do: transform.(key, v) - - # Convert the value of `:keys` to a key conversion function (if not already one) - @valid_keys_opts [:atoms, :atoms!, :strings, "(key :: String.t) -> term"] - defp to_key_fun(:atoms), do: &to_atom/1 - defp to_key_fun(:atoms!), do: &to_existing_atom/1 - defp to_key_fun(:strings), do: nil - defp to_key_fun(fun) when is_function(fun, 1), do: fun - defp to_key_fun(invalid), do: throw({:badarg, {:keys, invalid, @valid_keys_opts}}) - - # Convert the given key (as binary) to an atom - # Handle converting uppercase keys to module names rather than plain atoms - defp to_atom(<<c::utf8, _::binary>> = key) when c >= ?A and c <= ?Z do - Module.concat([key]) - end - - defp to_atom(key), do: String.to_atom(key) - - # Convert the given key (as binary) to an existing atom - # Handle converting uppercase keys to module names rather than plain atoms - # - # NOTE: This throws an error if the atom does not exist, and is intended to - # be handled in the decoder - defp to_existing_atom(<<c::utf8, _::binary>> = key) when c >= ?A and c <= ?Z do - Module.concat([String.to_existing_atom(key)]) - rescue - _ -> - throw({:error, {:keys, {:non_existing_atom, key}}}) - end - - defp to_existing_atom(key) do - String.to_existing_atom(key) - rescue - _ -> - throw({:error, {:keys, {:non_existing_atom, key}}}) - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/error.ex b/test-community-packages-javascript/build/packages/toml/lib/error.ex deleted file mode 100644 index c4690b7b333..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/error.ex +++ /dev/null @@ -1,143 +0,0 @@ -defmodule Toml.Error do - @moduledoc false - - defexception [:message, :reason] - - def exception(msg) when is_binary(msg) do - %__MODULE__{message: msg, reason: nil} - end - - def exception({:error, reason}) do - %__MODULE__{message: format_reason(reason), reason: reason} - end - - def exception(reason) when is_tuple(reason) do - %__MODULE__{message: format_reason(reason), reason: reason} - end - - def message(%__MODULE__{message: message}) do - message - end - - @doc """ - Convert internal error reasons into friendly, printable form - """ - def format_reason({:keys, {:non_existing_atom, key}}), - do: "unable to convert '#{key}' to an existing atom" - - def format_reason({:expected, token, other}), - do: "expected #{format_token(token)}, but got #{format_token(other)}" - - def format_reason({:invalid_token, token}), - do: "invalid token #{format_token(token)}" - - def format_reason({:invalid_integer, :leading_zero}), - do: "invalid integer syntax, leading zeros are not allowed" - - def format_reason({:invalid_float, :leading_zero}), - do: "invalid float syntax, leading zeros are not allowed" - - def format_reason({:invalid_float, token}), - do: "invalid float syntax, unexpected token #{format_token(token)}" - - def format_reason({:invalid_datetime, reason}), - do: "invalid datetime syntax, #{inspect(reason)}" - - def format_reason({:invalid_datetime_offset, reason}), - do: "invalid datetime offset syntax, #{inspect(reason)}" - - def format_reason({:invalid_date, reason}), - do: "invalid date syntax, #{inspect(reason)}" - - def format_reason({:invalid_time, reason}), - do: "invalid time syntax, #{inspect(reason)}" - - def format_reason({:invalid_key_value, token}), - do: "invalid key/value syntax, unexpected token #{format_token(token)}" - - def format_reason({:unclosed_table_array_name, token}), - do: "unclosed table array name at #{format_token(token)}" - - def format_reason({:unclosed_array, {oline, ocol}}), - do: "unclosed array started on line #{oline}, column #{ocol}" - - def format_reason({:unclosed_inline_table, {oline, ocol}}), - do: "unclosed inline table started on line #{oline}, column #{ocol}" - - def format_reason(:unclosed_quote), - do: "unclosed quoted string" - - def format_reason(:unexpected_newline), - do: "unexpected newline in single-quoted string" - - def format_reason(:unexpected_eof), - do: "unexpected end of file" - - def format_reason({:invalid_escape, char}), - do: "illegal escape sequence #{char}" - - def format_reason({:invalid_control_char, char}) do - if String.printable?(char) do - "illegal control character #{inspect(char, base: :hex)} ('#{char}')" - else - "illegal control character #{inspect(char, base: :hex)}" - end - end - - def format_reason({:invalid_char, char}) do - if String.printable?(char) do - "illegal character #{inspect(char, base: :hex)} ('#{char}')" - else - "illegal character #{inspect(char, base: :hex)}" - end - end - - def format_reason({:invalid_unicode, char}) do - if String.printable?(char) do - "illegal unicode escape, #{inspect(char, base: :hex)} ('#{char}')" - else - "illegal unicode escape, #{inspect(char, base: :hex)}" - end - end - - def format_reason({:key_exists, key}) do - "cannot redefine key in path '#{key}'" - end - - def format_reason({:badarg, option, value, valid}) when is_list(valid) do - valid = - valid - |> Enum.map(fn - a when is_atom(a) -> - "#{inspect(a)}" - - s when is_binary(s) -> - s - - v -> - "#{inspect(v)}" - end) - |> Enum.join(", ") - - "invalid value `#{inspect(value)}` for option #{inspect(option)}; must be one of [#{valid}]" - end - - def format_reason(reason), do: "#{inspect(reason)}" - - # Format a token in `{type, data}`, or `type` form into printable representation - defp format_token({true, _}), do: "'true'" - defp format_token({false, _}), do: "'false'" - defp format_token(:newline), do: "'\\n'" - - defp format_token({_, data}) when is_binary(data), - do: "'#{data}'" - - defp format_token({token, data}) when is_atom(token), - do: "'#{data}' (#{token})" - - defp format_token({token, _}), - do: "'#{<<token>>}'" - - defp format_token(token), - do: "'#{<<token>>}'" -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer.ex deleted file mode 100644 index 58824f1d3e1..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/lexer.ex +++ /dev/null @@ -1,392 +0,0 @@ -defmodule Toml.Lexer do - @moduledoc false - - import __MODULE__.Guards - - defstruct [:pid] - - @type t :: %__MODULE__{pid: pid} - - # The type of the token - @type type :: - :whitespace - | :newline - | :comment - | :digits - | :hex - | :octal - | :binary - | :alpha - | __MODULE__.String.type() - | boolean - | non_neg_integer - | :eof - # The number of bytes in the input to skip to reach the beginning of the token - @type skip :: non_neg_integer - # The data representation of a token (either size, a character, or string) - @type data :: non_neg_integer | binary - # The line number of the token - @type lines :: non_neg_integer - # The full shape of a token - @type token :: {type, skip, data, lines} - # The shape of errors the lexer produces - @type lexer_err :: {:error, term, skip, lines} - # The shape of the lexer stack - @type stack :: [token] | lexer_err - # The shape of replies which return tokens - @type token_reply :: - {:ok, token} - | lexer_err - - @doc """ - Creates a new Lexer with the given binary content. - - The lexer is a process, which manages the state of the lexer, - and provides the following benefits: - - - Only lexes content as the decoder walks the document, minimizing - the work performed, and resources (i.e. memory) used. - - Allows pushing an arbitrary tokens back on the stack, allowing the - decoder to "rewind" the lexer and try an alternative path. - - Lexing the next token happens concurrently with the decoder handling the last token - - Currently, the lexer will build up strings for most tokens and send them back to - the decoder, since these are running in separate processes, this means all string data - contained in the tokens is copied. For some tokens, like comments, the lexer will send - only the token type (e.g. `:comment`), and indexes into the original input, so that the - content can be extracted only when needed, and in the most efficient manner possible. In - the future, the lexer will do this will all tokens, allowing us to only make copies or store - references into the original input when absolutely needed. We do not do this currently, as - strings in TOML have escapes, which need to be unescaped during parsing. This could be deferred - and done in the decoder, but is not done so right now. - - Returns `{:ok, %#{__MODULE__}{}}`. - """ - @spec new(binary) :: {:ok, t} - def new(content) when is_binary(content) do - {:ok, pid} = :proc_lib.start_link(__MODULE__, :init, [self(), content]) - {:ok, %__MODULE__{pid: pid}} - end - - @doc """ - Pops the next token from the lexer. This advances the lexer to the next token. - """ - @spec pop(t) :: token_reply - def pop(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :pop) - - @doc """ - Advances the lexer to the next token, without returning the current token on the stack, - effectively skipping the current token. - """ - @spec advance(t) :: :ok - def advance(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :advance) - - @doc """ - Peeks at the next token the lexer will return from `pop/1`. - - Always returns the same result until the lexer advances. - """ - @spec peek(t) :: token_reply - def peek(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :peek) - - @doc """ - Pushes a token back on the lexer's stack. - - You may push as many tokens back on the stack as desired. - """ - @spec push(t, token) :: :ok - def push(%__MODULE__{pid: pid}, {_type, _skip, _data, _lines} = token) when is_pid(pid), - do: server_call(pid, {:push, token}) - - @doc """ - Retrieves the position of the lexer in the current input - """ - @spec pos(t) :: {:ok, skip, lines} - def pos(%__MODULE__{pid: pid}) when is_pid(pid), - do: server_call(pid, :pos) - - @doc """ - Terminates the lexer process. - """ - @spec stop(t) :: :ok - def stop(%__MODULE__{pid: pid}) when is_pid(pid) do - if Process.alive?(pid) do - server_call(pid, :stop) - else - :ok - end - end - - @doc """ - Converts the lexer in to a `Stream`. Not currently used. - """ - @spec stream(t) :: Enumerable.t() - def stream(%__MODULE__{} = lexer) do - Stream.resource( - fn -> {lexer, false, false} end, - fn - {_lexer, true, _error?} = acc -> - {:halt, acc} - - {_lexer, _eof?, true} = acc -> - {:halt, acc} - - {lexer, false, false} -> - case pop(lexer) do - {:error, _, _, _} = err -> - {[err], {lexer, false, true}} - - {:ok, {:eof, _, _, _}} = ok -> - {[ok], {lexer, true, false}} - - {:ok, _} = ok -> - {[ok], {lexer, false, false}} - end - end, - fn {lexer, _, _} -> stop(lexer) end - ) - end - - ## Private - - def init(parent, {:stream, stream}) when is_pid(parent) do - init(parent, Enum.into(stream, <<>>)) - end - - def init(parent, data) when is_pid(parent) and is_binary(data) do - Process.flag(:trap_exit, true) - :proc_lib.init_ack(parent, {:ok, self()}) - lex(parent, :sys.debug_options([]), data, 0, 1, []) - end - - # If an error is on the stack keep it there unless we push a valid token back on - @spec lex(pid, term, binary, skip, lines, stack) :: no_return - defp lex(parent, debug, data, skip, lines, {:error, _, eskip, elines} = err) do - receive do - {:EXIT, ^parent, reason} -> - exit(reason) - - {from, :stop} -> - send(from, {self(), :ok}) - exit(:normal) - - {from, {:push, {_type, _tskip, _tsize, _tline} = token}} -> - send(from, {self(), :ok}) - lex(parent, debug, data, skip, lines, [token]) - - {from, op} when op in [:pop, :peek, :advance] -> - send(from, {self(), err}) - lex(parent, debug, data, skip, lines, err) - - {from, :pos} -> - send(from, {self(), {:ok, eskip, elines}}) - lex(parent, debug, data, skip, lines, err) - end - end - - defp lex(parent, debug, data, skip, lines, []) do - case do_lex(data, skip, lines) do - {:error, _, _, _} = err -> - lex(parent, debug, data, skip, lines, err) - - {:ok, data, {_type, skip, _size, lines} = token} -> - lex(parent, debug, data, skip, lines, [token]) - end - end - - defp lex(parent, debug, data, skip, lines, [{_, tskip, _, tlines} = token | stack] = ostack) do - receive do - {:EXIT, ^parent, reason} -> - exit(reason) - - {from, :stop} -> - send(from, {self(), :ok}) - exit(:normal) - - {from, :pop} -> - send(from, {self(), {:ok, token}}) - lex(parent, debug, data, skip, lines, stack) - - {from, :advance} -> - send(from, {self(), :ok}) - lex(parent, debug, data, skip, lines, stack) - - {from, :peek} -> - send(from, {self(), {:ok, token}}) - lex(parent, debug, data, skip, lines, ostack) - - {from, {:push, pushed}} -> - send(from, {self(), :ok}) - lex(parent, debug, data, skip, lines, [pushed | ostack]) - - {from, :pos} -> - send(from, {self(), {:ok, tskip, tlines}}) - lex(parent, debug, data, skip, lines, ostack) - end - end - - @spec do_lex(binary, skip, lines) :: {:ok, binary, token} | {:error, term, skip, lines} - defp do_lex(data, skip, lines) - - defp do_lex(<<>> = data, skip, lines), - do: {:ok, data, {:eof, skip, 0, lines}} - - defp do_lex(<<?\#, rest::binary>>, skip, lines), - do: lex_comment(rest, skip + 1, 0, lines) - - defp do_lex(<<?\r, ?\n, rest::binary>>, skip, lines), - do: {:ok, rest, {:newline, skip + 2, 0, lines + 1}} - - defp do_lex(<<?\n, rest::binary>>, skip, lines), - do: {:ok, rest, {:newline, skip + 1, 0, lines + 1}} - - defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), - do: lex_whitespace(rest, skip + 1, lines) - - defp do_lex(<<"true", rest::binary>>, skip, lines), - do: {:ok, rest, {true, skip + 4, 0, lines}} - - defp do_lex(<<"false", rest::binary>>, skip, lines), - do: {:ok, rest, {false, skip + 5, 0, lines}} - - defp do_lex(<<?=, rest::binary>>, skip, lines), - do: {:ok, rest, {?=, skip + 1, 0, lines}} - - defp do_lex(<<?., rest::binary>>, skip, lines), - do: {:ok, rest, {?., skip + 1, 0, lines}} - - defp do_lex(<<?\[, rest::binary>>, skip, lines), - do: {:ok, rest, {?\[, skip + 1, 0, lines}} - - defp do_lex(<<?\], rest::binary>>, skip, lines), - do: {:ok, rest, {?\], skip + 1, 0, lines}} - - defp do_lex(<<?\{, rest::binary>>, skip, lines), - do: {:ok, rest, {?\{, skip + 1, 0, lines}} - - defp do_lex(<<?\}, rest::binary>>, skip, lines), - do: {:ok, rest, {?\}, skip + 1, 0, lines}} - - defp do_lex(<<?+, rest::binary>>, skip, lines), - do: {:ok, rest, {?+, skip + 1, 0, lines}} - - defp do_lex(<<?-, rest::binary>>, skip, lines), - do: {:ok, rest, {?-, skip + 1, 0, lines}} - - defp do_lex(<<?:, rest::binary>>, skip, lines), - do: {:ok, rest, {?:, skip + 1, 0, lines}} - - defp do_lex(<<?,, rest::binary>>, skip, lines), - do: {:ok, rest, {?,, skip + 1, 0, lines}} - - defp do_lex(<<?_, rest::binary>>, skip, lines), - do: {:ok, rest, {?_, skip + 1, 0, lines}} - - defp do_lex(<<?0, ?x, c::utf8, rest::binary>>, skip, lines) when is_hex(c), - do: lex_hex(rest, skip + 3, [c], lines) - - defp do_lex(<<?0, ?o, c::utf8, rest::binary>>, skip, lines) when is_octal(c), - do: lex_octal(rest, skip + 3, [c], lines) - - defp do_lex(<<?0, ?b, c::utf8, rest::binary>>, skip, lines) when is_bin(c), - do: lex_binary(rest, skip + 3, [c], lines) - - defp do_lex(<<c::utf8, _::binary>> = data, skip, lines) when is_quote(c), - do: __MODULE__.String.lex(data, skip, lines) - - defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_digit(c), - do: lex_digits(rest, skip + 1, [c], lines) - - defp do_lex(<<c::utf8, rest::binary>>, skip, lines) when is_alpha(c), - do: lex_alpha(rest, skip + 1, [c], lines) - - defp do_lex(<<c::utf8, _::binary>>, skip, lines), - do: {:error, {:invalid_char, <<c::utf8>>}, skip + 1, lines} - - defp lex_whitespace(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), - do: lex_whitespace(rest, skip + 1, lines) - - defp lex_whitespace(rest, skip, lines), - do: {:ok, rest, {:whitespace, skip, 0, lines}} - - defp lex_comment(<<?\r, ?\n, rest::binary>>, skip, size, lines), - do: {:ok, rest, {:comment, skip + 2, size, lines + 1}} - - defp lex_comment(<<?\n, rest::binary>>, skip, size, lines), - do: {:ok, rest, {:comment, skip + 1, size, lines + 1}} - - defp lex_comment(<<_::utf8, rest::binary>>, skip, size, lines), - do: lex_comment(rest, skip + 1, size + 1, lines) - - defp lex_comment(<<>> = rest, skip, size, lines), - do: {:ok, rest, {:comment, skip, size, lines}} - - defp lex_digits(<<c::utf8, rest::binary>>, skip, acc, lines) when is_digit(c), - do: lex_digits(rest, skip + 1, [c | acc], lines) - - defp lex_digits(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:digits, skip, bin, lines}} - end - - defp lex_hex(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) - when is_hex(c) and is_hex(d), - do: lex_hex(rest, skip + 3, [d, c | acc], lines) - - defp lex_hex(<<c::utf8, rest::binary>>, skip, acc, lines) when is_hex(c), - do: lex_hex(rest, skip + 1, [c | acc], lines) - - defp lex_hex(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:hex, skip, bin, lines}} - end - - defp lex_octal(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) - when is_octal(c) and is_octal(d), - do: lex_octal(rest, skip + 3, [d, c | acc], lines) - - defp lex_octal(<<c::utf8, rest::binary>>, skip, acc, lines) when is_octal(c), - do: lex_octal(rest, skip + 1, [c | acc], lines) - - defp lex_octal(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:octal, skip, bin, lines}} - end - - defp lex_binary(<<c::utf8, ?_, d::utf8, rest::binary>>, skip, acc, lines) - when is_bin(c) and is_bin(d), - do: lex_binary(rest, skip + 3, [d, c | acc], lines) - - defp lex_binary(<<c::utf8, rest::binary>>, skip, acc, lines) when is_bin(c), - do: lex_binary(rest, skip + 1, [c | acc], lines) - - defp lex_binary(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:binary, skip, bin, lines}} - end - - defp lex_alpha(<<c::utf8, rest::binary>>, skip, acc, lines) when is_alpha(c), - do: lex_alpha(rest, skip + 1, [c | acc], lines) - - defp lex_alpha(rest, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:alpha, skip, bin, lines}} - end - - defp server_call(pid, msg) do - ref = Process.monitor(pid) - send(pid, {self(), msg}) - - receive do - {:DOWN, ^ref, _type, _pid, info} -> - {:error, info} - - {^pid, reply} -> - Process.demonitor(ref, [:flush]) - reply - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex deleted file mode 100644 index bd3df5f7c27..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/lexer/guards.ex +++ /dev/null @@ -1,21 +0,0 @@ -defmodule Toml.Lexer.Guards do - @moduledoc false - - defguard is_lowercase(c) when c >= ?a and c <= ?z - - defguard is_uppercase(c) when c >= ?A and c <= ?Z - - defguard is_alpha(c) when is_lowercase(c) or is_uppercase(c) - - defguard is_digit(c) when c >= ?0 and c <= ?9 - - defguard is_hex(c) when is_digit(c) or (c >= ?a and c <= ?z) or (c >= ?A and c <= ?Z) - - defguard is_octal(c) when c >= ?0 and c <= ?8 - - defguard is_bin(c) when c == ?0 or c == ?1 - - defguard is_whitespace(c) when c == ?\s or c == ?\t - - defguard is_quote(c) when c == ?\" or c == ?\' -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex b/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex deleted file mode 100644 index dbe7635f699..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/lexer/string.ex +++ /dev/null @@ -1,294 +0,0 @@ -defmodule Toml.Lexer.String do - @moduledoc false - - # This module manages the complexity of lexing quoted and literal - # strings as defined by the TOML spec. - - import Toml.Lexer.Guards - - @type type :: - :string - | :multiline_string - - @type skip :: Toml.Lexer.skip() - @type lines :: Toml.Lexer.lines() - @type lexer_err :: Toml.Lexer.lexer_err() - @type result :: {:ok, binary, {type, skip, binary, lines}} | lexer_err - - @spec lex(binary, skip, lines) :: result - def lex(binary, skip, lines) - - def lex(<<>>, skip, lines), - do: {:error, :unexpected_eof, skip, lines} - - def lex(<<?\', ?\', ?\', rest::binary>>, skip, lines) do - {rest, skip, lines} = trim_newline(rest, skip + 3, lines) - lex_literal(:multi, rest, skip, [], lines) - end - - def lex(<<?\', ?\', rest::binary>>, skip, lines), - do: {:ok, rest, {:string, skip + 2, <<>>, lines}} - - def lex(<<?\', rest::binary>>, skip, lines), - do: lex_literal(:single, rest, skip + 1, [], lines) - - def lex(<<?\", ?\", ?\", rest::binary>>, skip, lines) do - {rest, skip, lines} = trim_newline(rest, skip + 3, lines) - lex_quoted(:multi, rest, skip, [], lines) - end - - def lex(<<?\", ?\", rest::binary>>, skip, lines), - do: {:ok, rest, {:string, skip + 2, <<>>, lines}} - - def lex(<<?\", rest::binary>>, skip, lines), - do: lex_quoted(:single, rest, skip + 1, [], lines) - - defp lex_literal(_type, <<>>, skip, _acc, lines), - do: {:error, :unclosed_quote, skip, lines} - - # Disallow newlines in single-line literals - defp lex_literal(:single, <<?\r, ?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_literal(:single, <<?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_literal(type, <<?\r, ?\n, rest::binary>>, skip, acc, lines), - do: lex_literal(type, rest, skip + 2, [?\n | acc], lines + 1) - - defp lex_literal(type, <<?\n, rest::binary>>, skip, acc, lines), - do: lex_literal(type, rest, skip + 1, [?\n | acc], lines + 1) - - # Closing quotes - defp lex_literal(:single, <<?\', rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:string, skip + 1, bin, lines}} - end - - defp lex_literal(:multi, <<?\', ?\', ?\', rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:multiline_string, skip + 3, bin, lines}} - end - - # Disallow any control chars in single quoted literals - defp lex_literal(:single, <<c::utf8, _::binary>>, skip, _acc, lines) - when (c >= 0 and c <= 31) or c == 127, - do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} - - # Disallow any control chars in single quoted literals, EXCEPT \t in multi-line literals - defp lex_literal(:multi, <<?\t, rest::binary>>, skip, acc, lines), - do: lex_literal(:multi, rest, skip + 1, [?\t | acc], lines) - - defp lex_literal(:multi, <<c::utf8, _::binary>>, skip, _acc, lines) - when (c >= 0 and c <= 31) or c == 127, - do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} - - # Eat next character in string - defp lex_literal(type, <<c::utf8, rest::binary>>, skip, acc, lines), - do: lex_literal(type, rest, skip + 1, [c | acc], lines) - - # Invalid byte sequence (i.e. invalid unicode) - defp lex_literal(_type, <<c, _::binary>>, skip, _acc, lines), - do: {:error, {:invalid_unicode, <<c>>}, skip + 1, lines} - - defp lex_quoted(_type, <<>>, skip, _acc, lines), - do: {:error, :unclosed_quote, skip, lines} - - # Disallow newlines in single-line strings - defp lex_quoted(:single, <<?\r, ?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_quoted(:single, <<?\n, _::binary>>, skip, _acc, lines), - do: {:error, :unexpected_newline, skip + 1, lines} - - defp lex_quoted(type, <<?\r, ?\n, rest::binary>>, skip, acc, lines), - do: lex_quoted(type, rest, skip + 2, [?\n | acc], lines + 1) - - defp lex_quoted(type, <<?\n, rest::binary>>, skip, acc, lines), - do: lex_quoted(type, rest, skip + 1, [?\n | acc], lines + 1) - - # Allow escaping newlines in multi-ine strings - defp lex_quoted(:multi, <<?\\, ?\r, ?\n, rest::binary>>, skip, acc, lines) do - {rest, skip, lines} = trim_whitespace(rest, skip + 3, lines + 1) - lex_quoted(:multi, rest, skip, acc, lines) - end - - defp lex_quoted(:multi, <<?\\, ?\n, rest::binary>>, skip, acc, lines) do - {rest, skip, lines} = trim_whitespace(rest, skip + 2, lines + 1) - lex_quoted(:multi, rest, skip, acc, lines) - end - - # Trim trailing whitespace at end of line - defp lex_quoted(:multi, <<?\\, ?\s, rest::binary>>, skip, acc, lines) do - lex_quoted(:multi, <<?\\, rest::binary>>, skip, acc, lines) - end - - # Allowed escapes - defp lex_quoted(type, <<?\\, ?\\, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\\ | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?b, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\b | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?d, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\d | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?f, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\f | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?n, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\n | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?r, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\r | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?t, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 2, [?\t | acc], lines) - end - - defp lex_quoted(type, <<?\\, ?\", rest::binary>>, skip, acc, lines), - do: lex_quoted(type, rest, skip + 2, [?\" | acc], lines) - - defp lex_quoted(type, <<?\\, ?u, rest::binary>>, skip, acc, lines) do - {char, rest, skip2} = unescape_unicode(?u, rest) - lex_quoted(type, rest, 2 + skip + skip2, [char | acc], lines) - catch - :throw, {:invalid_unicode, _} = reason -> - {:error, reason, skip + 1, lines} - end - - defp lex_quoted(type, <<?\\, ?U, rest::binary>>, skip, acc, lines) do - {char, rest, skip2} = unescape_unicode(?U, rest) - lex_quoted(type, rest, 2 + skip + skip2, [char | acc], lines) - catch - :throw, {:invalid_unicode, _} = reason -> - {:error, reason, skip + 1, lines} - end - - # Bad escape - defp lex_quoted(_type, <<?\\, char::utf8, _::binary>>, skip, _acc, lines) do - {:error, {:invalid_escape, <<?\\, char::utf8>>}, skip + 1, lines} - end - - # Closing quotes - defp lex_quoted(:multi, <<?\", ?\", ?\", rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:multiline_string, skip + 3, bin, lines}} - end - - defp lex_quoted(:single, <<?\", rest::binary>>, skip, acc, lines) do - bin = acc |> Enum.reverse() |> IO.chardata_to_string() - {:ok, rest, {:string, skip + 1, bin, lines}} - end - - # Disallow any unescaped control chars in quoted strings - defp lex_quoted(_type, <<c::utf8, _::binary>>, skip, _acc, lines) - when (c >= 0 and c <= 31) or c == 127, - do: {:error, {:invalid_control_char, <<c::utf8>>}, skip + 1, lines} - - # Eat next character in string - defp lex_quoted(type, <<c::utf8, rest::binary>>, skip, acc, lines) do - lex_quoted(type, rest, skip + 1, [c | acc], lines) - end - - defp lex_quoted(_type, <<c, _::binary>>, skip, _acc, lines), - do: {:error, {:invalid_unicode, <<c>>}, skip + 1, lines} - - defp trim_newline(<<?\r, ?\n, rest::binary>>, skip, lines), do: {rest, skip + 2, lines + 1} - defp trim_newline(<<?\n, rest::binary>>, skip, lines), do: {rest, skip + 1, lines + 1} - defp trim_newline(rest, skip, lines), do: {rest, skip, lines} - - # Trims whitespace (tab, space) up until next non-whitespace character, - # or until closing delimiter. Only allowed with mulit-line quoted strings. - defp trim_whitespace(<<c::utf8, rest::binary>>, skip, lines) when is_whitespace(c), - do: trim_whitespace(rest, skip + 1, lines) - - defp trim_whitespace(<<?\", ?\", ?\", _::binary>> = rest, skip, lines), - do: {rest, skip, lines} - - defp trim_whitespace(rest, skip, lines), - do: {rest, skip, lines} - - def unescape_unicode(?U, <<n::8-binary, bin::binary>>) do - char = - case :erlang.binary_to_integer(n, 16) do - u when u <= 0x007F -> - <<u>> - - u when 0x0080 <= u and u <= 0x07FF -> - u1 = div(u, 64) + 192 - u2 = mod(u, 64) + 128 - <<u1, u2>> - - u when (0x0080 <= u and u <= 0xD7FF) or (0xE000 <= u and u <= 0xFFFF) -> - u1 = div(u, 4096) + 224 - u2 = div(mod(u, 4096), 64) + 128 - u3 = mod(u, 64) + 128 - <<u1, u2, u3>> - - u -> - u1 = div(u, 262_144) + 240 - u2 = div(mod(u, 262_144), 4096) + 128 - u3 = div(mod(u, 4096), 64) + 128 - u4 = mod(u, 64) + 128 - <<u1, u2, u3, u4>> - end - - # Check that we have a valid utf8 encoding - case char do - <<_::utf8>> -> - {char, bin, 8} - - _ -> - bad_unicode!(char) - end - end - - def unescape_unicode(?u, <<n::4-binary, bin::binary>>) do - case :erlang.binary_to_integer(n, 16) do - high when 0xD800 <= high and high <= 0xDBFF -> - # surrogate pair - case bin do - <<?\\, ?u, n2::4-binary, bin2::binary>> -> - case :erlang.binary_to_integer(n2, 16) do - low when 0xDC00 <= low and low <= 0xDFFF -> - <<u::utf16>> = <<high::16, low::16>> - {<<u::utf8>>, bin2, 4 + 6} - - _ -> - bad_unicode!(n) - end - - _ -> - bad_unicode!(n) - end - - # second part of surrogate pair (without first part) - u when (0xDC00 <= u and u <= 0xDFFF) or u < 0 -> - bad_unicode!(n) - - u -> - {<<u::utf8>>, bin, 4} - end - catch - :error, :badarg -> - bad_unicode!(n) - end - - def unescape_unicode(_type, <<c, _::binary>>) do - bad_unicode!(<<c>>) - end - - @spec bad_unicode!(binary) :: no_return - defp bad_unicode!(byte), do: throw({:invalid_unicode, byte}) - - defp mod(x, y) when x > 0, do: rem(x, y) - defp mod(x, y) when x < 0, do: y + rem(x, y) - defp mod(0, _), do: 0 -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/provider.ex b/test-community-packages-javascript/build/packages/toml/lib/provider.ex deleted file mode 100644 index 400d72a3478..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/provider.ex +++ /dev/null @@ -1,227 +0,0 @@ -defmodule Toml.Provider do - @moduledoc """ - This module provides an implementation of both the Distilery and Elixir - config provider behaviours, so that TOML files can be used for configuration - in releases. - - ## Distillery Usage - - Add the following to your `rel/config.exs` - - release :myapp do - # ...snip... - set config_providers: [ - {Toml.Provider, [path: "${XDG_CONFIG_DIR}/myapp.toml", transforms: [...]]} - ] - end - - ## Elixir Usage - - config_providers: [ - {Toml.Provider, [ - path: {:system, "XDG_CONFIG_DIR", "myapp.toml"}, - transforms: [...] - ]} - ] - - This will result in `Toml.Provider` being invoked during boot, at which point it - will evaluate the given path and read the TOML file it finds. If one is not - found, or is not accessible, the provider will raise an error, and the boot - sequence will terminate unsuccessfully. If it succeeds, it persists settings in - the file to the application environment (i.e. you access it via - `Application.get_env/2`). - - The config provider expects a certain format to the TOML file, namely that - keys at the root of the document are tables which correspond to applications - which need to be configured. If it encounters keys at the root of the document - which are not tables, they are ignored. - - ## Options - - The same options that `Toml.parse/2` accepts are able to be provided to `Toml.Provider`, - but there are two main differences: - - * `:path` (required) - sets the path to the TOML file to load config from - * `:keys` - defaults to `:atoms`, but can be set to `:atoms!` if desired, all other - key types are ignored, as it results in an invalid config structure - - """ - has_config_api? = Version.match?(Version.parse!(System.version()), ">= 1.9.0") - - if has_config_api? do - @behaviour Config.Provider - end - - @doc false - def init(opts) when is_list(opts) do - opts = - case Keyword.get(opts, :keys) do - a when a in [:atoms, :atoms!] -> - opts - - _ -> - Keyword.put(opts, :keys, :atoms) - end - - if is_distillery_env?() do - # When running under Distillery, init performs load - load([], opts) - opts - else - # With 1.9 releases, init just preps arguments for `load` - opts - end - end - - @doc false - def load(config, opts) when is_list(opts) do - path = Keyword.fetch!(opts, :path) - # path expansion should happen in load rather than init, otherwise - # in 1.9 releases using a {:system, env_var, path} tuple an error - # will be raised if the env var is not set in the build environment - with {:ok, path} <- expand_path(path) do - map = Toml.decode_file!(path, opts) - persist(config, to_keyword(map)) - else - {:error, reason} -> - exit(reason) - end - end - - @doc false - def get([app | keypath]) do - config = Application.get_all_env(app) - - case get_in(config, keypath) do - nil -> - nil - - val -> - {:ok, val} - end - end - - if has_config_api? do - defp persist(config, keyword) when is_list(keyword) do - config = Config.Reader.merge(config, keyword) - Application.put_all_env(config, persistent: true) - config - end - else - defp persist(config, keyword) when is_list(keyword) do - # For each app - for {app, app_config} <- keyword do - # Get base config - base = Application.get_all_env(app) - base = deep_merge(base, Keyword.get(config, app, [])) - # Merge this app's TOML config over the base config - merged = deep_merge(base, app_config) - # Persist key/value pairs for this app - for {k, v} <- merged do - Application.put_env(app, k, v, persistent: true) - end - - # Return merged config - {app, merged} - end - end - - defp deep_merge(a, b) when is_list(a) and is_list(b) do - if Keyword.keyword?(a) and Keyword.keyword?(b) do - Keyword.merge(a, b, &deep_merge/3) - else - b - end - end - - defp deep_merge(_k, a, b) when is_list(a) and is_list(b) do - if Keyword.keyword?(a) and Keyword.keyword?(b) do - Keyword.merge(a, b, &deep_merge/3) - else - b - end - end - - defp deep_merge(_k, a, b) when is_map(a) and is_map(b) do - Map.merge(a, b, &deep_merge/3) - end - - defp deep_merge(_k, _a, b), do: b - end - - # At the top level, convert the map to a keyword list of keyword lists - # Keys with no children (i.e. keys which are not tables) are dropped - defp to_keyword(map) when is_map(map) do - for {k, v} <- map, v2 = to_keyword2(v), is_list(v2), into: [] do - {k, v2} - end - end - - # For all other values, convert tables to keywords - defp to_keyword2(map) when is_map(map) do - Enum.map(map, fn {k, v} -> {k, to_keyword2(v)} end) - end - - # And leave all other values untouched - defp to_keyword2(term), do: term - - def expand_path(path) when is_binary(path) do - case expand_path(path, <<>>) do - {:ok, p} -> - {:ok, Path.expand(p)} - - {:error, _} = err -> - err - end - end - - if has_config_api? do - def expand_path(path) do - {:ok, Config.Provider.resolve_config_path!(path)} - end - end - - defp expand_path(<<>>, acc), - do: {:ok, acc} - - defp expand_path(<<?$, ?\{, rest::binary>>, acc) do - case expand_var(rest) do - {:ok, var, rest} -> - expand_path(rest, acc <> var) - - {:error, _} = err -> - err - end - end - - defp expand_path(<<c::utf8, rest::binary>>, acc) do - expand_path(rest, <<acc::binary, c::utf8>>) - end - - defp expand_var(bin), - do: expand_var(bin, <<>>) - - defp expand_var(<<>>, _acc), - do: {:error, :unclosed_var_expansion} - - defp expand_var(<<?\}, rest::binary>>, acc), - do: {:ok, System.get_env(acc) || "", rest} - - defp expand_var(<<c::utf8, rest::binary>>, acc) do - expand_var(rest, <<acc::binary, c::utf8>>) - end - - defp is_distillery_env? do - if Version.match?(Version.parse!(System.version()), ">= 1.9.0") do - Code.ensure_loaded?(Distillery.Releases.Config.Provider) - else - true - end - rescue - _ -> - case :erlang.phash2(1, 1) do - 0 -> true - _ -> false - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/toml.ex b/test-community-packages-javascript/build/packages/toml/lib/toml.ex deleted file mode 100644 index c040f5c2944..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/toml.ex +++ /dev/null @@ -1,94 +0,0 @@ -defmodule Toml do - @external_resource "README.md" - - @moduledoc File.read!(Path.join([__DIR__, "..", "README.md"])) - - @type key :: binary | atom | term - @type opt :: - {:keys, :atoms | :atoms! | :string | (key -> term)} - | {:filename, String.t()} - | {:transforms, [Toml.Transform.t()]} - @type opts :: [opt] - - @type reason :: {:invalid_toml, binary} | binary - @type error :: {:error, reason} - - @doc """ - Decode the given binary as TOML content - - ## Options - - You can pass the following options to configure the decoder behavior: - - * `:filename` - pass a filename to use in error messages - * `:keys` - controls how keys in the document are decoded. Possible values are: - * `:strings` (default) - decodes keys as strings - * `:atoms` - converts keys to atoms with `String.to_atom/1` - * `:atoms!` - converts keys to atoms with `String.to_existing_atom/1` - * `(key -> term)` - converts keys using the provided function - * `:transforms` - a list of custom transformations to apply to decoded TOML values, - see `c:Toml.Transform.transform/2` for details. - - ## Decoding keys to atoms - - The `:atoms` option uses the `String.to_atom/1` call that can create atoms at runtime. - Since the atoms are not garbage collected, this can pose a DoS attack vector when used - on user-controlled data. It is recommended that if you either avoid converting to atoms, - by using `keys: :strings`, or require known keys, by using the `keys: :atoms!` option, - which will cause decoding to fail if the key is not an atom already in the atom table. - - ## Transformations - - You should rarely need custom datatype transformations, but in some cases it can be quite - useful. In particular if you want to transform things like IP addresses from their string - form to the Erlang address tuples used in most `:inet` APIs, a custom transform can ensure - that all addresses are usable right away, and that validation of those addresses is done as - part of decoding the document. - - Keep in mind that transforms add additional work to decoding, which may result in reduced - performance, if you don't need the convenience, or the validation, deferring such conversions - until the values are used may be a better approach, rather than incurring the overhead during decoding. - """ - @spec decode(binary) :: {:ok, map} | error - @spec decode(binary, opts) :: {:ok, map} | error - defdelegate decode(bin, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Same as `decode/1`, but returns the document directly, or raises `Toml.Error` if it fails. - """ - @spec decode!(binary) :: map | no_return - @spec decode!(binary, opts) :: map | no_return - defdelegate decode!(bin, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Decode the file at the given path as TOML - - Takes same options as `decode/2` - """ - @spec decode_file(binary) :: {:ok, map} | error - @spec decode_file(binary, opts) :: {:ok, map} | error - defdelegate decode_file(path, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Same as `decode_file/1`, but returns the document directly, or raises `Toml.Error` if it fails. - """ - @spec decode_file!(binary) :: map | no_return - @spec decode_file!(binary, opts) :: map | no_return - defdelegate decode_file!(path, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Decode the given stream as TOML. - - Takes same options as `decode/2` - """ - @spec decode_stream(Enumerable.t()) :: {:ok, map} | error - @spec decode_stream(Enumerable.t(), opts) :: {:ok, map} | error - defdelegate decode_stream(stream, opts \\ []), to: __MODULE__.Decoder - - @doc """ - Same as `decode_stream/1`, but returns the document directly, or raises `Toml.Error` if it fails. - """ - @spec decode_stream!(Enumerable.t()) :: map | no_return - @spec decode_stream!(Enumerable.t(), opts) :: map | no_return - defdelegate decode_stream!(stream, opts \\ []), to: __MODULE__.Decoder -end diff --git a/test-community-packages-javascript/build/packages/toml/lib/transform.ex b/test-community-packages-javascript/build/packages/toml/lib/transform.ex deleted file mode 100644 index 78cd21741b7..00000000000 --- a/test-community-packages-javascript/build/packages/toml/lib/transform.ex +++ /dev/null @@ -1,127 +0,0 @@ -defmodule Toml.Transform do - @moduledoc """ - Defines the behavior for custom transformations of decoded TOML values. - - See the documentation for `c:transform/2` for more details. - """ - - @type t :: module - @type key :: binary | atom | term - @type keypath :: [binary] | [atom] | [term] - @type value :: - %{key => value} - | [value] - | number - | binary - | NaiveDateTime.t() - | DateTime.t() - | Date.t() - | Time.t() - - def __using__(_) do - quote do - @behaviour unquote(__MODULE__) - end - end - - @doc """ - This function is invoked for every key/value pair in the document, in a depth-first, - bottom-up, traversal of the document. - - The transformer must return one of two values: - - * `{:error, term}` - an error occurred in the transformer, and decoding should fail - * `term` - replace the value for the given key with the value returned from the - transformer in the final document - - ## Example - - An example transformation would be the conversion of tables of a certain shape to a known struct value. - - The struct: - - defmodule Server do - defstruct [:name, :ip, :ports] - end - - - TOML which contains a table of this shape: - - [servers.alpha] - ip = "192.168.1.1" - ports = [8080, 8081] - - [servers.beta] - ip = "192.168.1.2" - ports = [8082, 8083] - - - And finally, the transforer implementation: - - defmodule ServerTransform do - use Toml.Transform - - # Transform IP strings to Erlang address tuples - def transform(:ip, ip) when is_binary(ip) do - case :inet.parse_ipv4_address(String.to_charlist(ip)) do - {:ok, result} -> - result - {:error, reason} -> - {:error, {:invalid_ip, ip, reason}} - end - end - - # Non-binary values for IP addresses should return an error - def transform(:ip, ip), do: {:error, {:invalid_ip, ip, :expected_string}} - - # Transform the server objects to Server structs - def transform(:servers, servers) when is_map(servers) do - for {name, server} <- servers do - struct(Server, Map.put(server, :name, name)) - end - end - - # Non-map values for servers should return an error - def transform(:servers, s), do: {:error, {:invalid_server, s}} - - # Ignore all other values - def transform(_key, v), do: v - end - - Assuming we decode with the following options: - - Toml.decode!(content, keys: :atoms, transforms: [ServerTransform]) - - The result would be: - - %{ - servers: [ - %Server{name: :alpha, ip: {192,168,1,1}, ports: [8080, 8081]}, - %Server{name: :beta, ip: {192,168,1,2}, ports: [8082, 8083]} - ] - } - - """ - @callback transform(key, value) :: {:error, term} | term - - # Given a list of transform functions, compose them into a single transformation pass - @doc false - def compose(mods) when is_list(mods) do - Enum.reduce(mods, nil, &compose_transforms/2) - end - - # The first transform in the list does not require composition - defp compose_transforms(mod, nil), do: &mod.transform/2 - # All subsequent transforms are composed with the previous - defp compose_transforms(mod, acc) when is_atom(mod) and is_function(acc) do - fn k, v -> - case acc.(k, v) do - {:error, _} = err -> - throw(err) - - v2 -> - mod.transform(k, v2) - end - end - end -end diff --git a/test-community-packages-javascript/build/packages/toml/mix.exs b/test-community-packages-javascript/build/packages/toml/mix.exs deleted file mode 100644 index cc5511df9f2..00000000000 --- a/test-community-packages-javascript/build/packages/toml/mix.exs +++ /dev/null @@ -1,125 +0,0 @@ -defmodule Toml.MixProject do - use Mix.Project - - @version "0.7.0" - @source_url "https://github.com/bitwalker/toml-elixir" - - def project do - [ - app: :toml, - version: @version, - elixir: "~> 1.9", - start_permanent: Mix.env() == :prod, - consolidate_protocols: Mix.env() != :test, - description: "An implementation of TOML for Elixir projects", - package: package(), - deps: deps(), - aliases: aliases(Mix.env()), - preferred_cli_env: [ - bench: :bench, - "bench.decoder": :bench, - "bench.lexer": :bench, - docs: :docs, - "hex.publish": :docs, - coveralls: :test, - "coveralls.html": :test, - "coveralls.details": :test - ], - dialyzer: dialyzer(), - docs: docs(), - elixirc_paths: elixirc_paths(Mix.env()), - escript: escript(Mix.env()), - test_coverage: [tool: ExCoveralls] - ] - end - - # Run "mix help compile.app" to learn about applications. - def application do - [ - extra_applications: [] - ] - end - - # Run "mix help deps" to learn about dependencies. - defp deps do - [ - {:ex_doc, ">= 0.0.0", only: [:docs]}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, - {:benchee, "~> 1.0", only: [:bench]}, - {:benchee_html, "~> 1.0", only: [:bench]}, - {:jason, "~> 1.0", only: [:test, :bench]}, - {:excoveralls, "~> 0.9", only: [:test]} - # For benchmarking, though none of these libraries work at this point - # {:tomlex, "~> 0.0.5", only: [:bench]}, - # {:toml_elixir, "~> 2.0.1", only: [:bench]}, - # {:jerry, "~> 0.1.4", only: [:bench]}, - # {:etoml, "~> 0.1.0", only: [:bench]}, - ] - end - - defp package do - [ - files: ["lib", "mix.exs", "README.md", "LICENSE"], - maintainers: ["Paul Schoenfelder"], - licenses: ["Apache-2.0"], - links: %{"GitHub" => @source_url} - ] - end - - defp docs do - [ - main: "readme", - source_url: @source_url, - source_ref: @version, - extras: [ - LICENSE: [title: "License"], - "README.md": [title: "Overview"] - ], - formatters: ["html"] - ] - end - - defp escript(:test) do - [ - main_module: Toml.CLI, - name: :toml, - path: Path.join([__DIR__, "bin", "toml"]) - ] - end - - defp escript(_), do: nil - - defp aliases(_env) do - [ - "compile-check": [ - "compile --warnings-as-errors", - "format --check-formatted --dry-run", - "dialyzer --format dialyxir" - ], - clean: ["clean", &clean/1], - bench: ["bench.decoder", "bench.lexer"], - "bench.decoder": ["run bench/bench.decoder.exs"], - "bench.lexer": ["run bench/bench.lexer.exs"] - ] - end - - defp elixirc_paths(:test), do: ["lib", "test/support"] - defp elixirc_paths(:bench), do: ["lib", "bench/support"] - defp elixirc_paths(_), do: ["lib"] - - defp dialyzer do - [ - ignore_warnings: "dialyzer.ignore", - flags: [:error_handling, :underspecs], - plt_core_path: System.get_env("PLT_PATH") || System.get_env("MIX_HOME") - ] - end - - defp clean(_args) do - toml = Path.join([__DIR__, "bin", "toml"]) - - if File.exists?(toml) do - _ = File.rm(toml) - end - end -end diff --git a/test-community-packages-javascript/build/packages/trie_again/LICENSE b/test-community-packages-javascript/build/packages/trie_again/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/test-community-packages-javascript/build/packages/trie_again/README.md b/test-community-packages-javascript/build/packages/trie_again/README.md deleted file mode 100644 index 0dbd9478a04..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# trie_again - -[![Package Version](https://img.shields.io/hexpm/v/trie_again)](https://hex.pm/packages/trie_again) -[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/trie_again/) -![CI](https://github.com/giacomocavalieri/trie_again/workflows/CI/badge.svg?branch=main) - -Tries in Gleam 🌳 - -> ⚙️ This package supports the Erlang and Javascript targets! - -## Why tries? - -A [trie](https://en.wikipedia.org/wiki/Trie) is a data structure that uses lists as keys. By taking advantage of this property it is possible to efficiently perform some queries: for example imagine you want to find all the elements that are associated with a key with the same prefix; with a trie the complexity of the lookup is linear in the size of the prefix you're looking for. - -That is why tries can be used to implement autocompleting text dictionaries, spell checking or prefix matching algorithms. - -In this example a trie is used to store words (as lists of graphemes) as keys associated with a definition. With the `subtrie` function one can look for all the elements sharing a commong prefix in their key: - -```gleam -import trie -import string - -let dictionary = - trie.new() - |> trie.insert(at: string.to_graphemes("gleam"), value: "To produce a small, bright light") - |> trie.insert(at: string.to_graphemes("gleaming"), value: "Bright and shiny") - |> trie.insert(at: string.to_graphemes("beam"), value: "A line of light that shines from a bright object") - -dictionary -|> trie.subtrie(at: ["g", "l"]) -|> trie.to_list -// -> [ -// #(["g", "l", "e", "a", "m"], "To produce a small, bright light"), -// #(["g", "l", "e", "a", "m", "i", "n", "g"], "Bright and shiny"), -// ] -``` - -## Installation - -To add this package to your Gleam project: - -```sh -gleam add trie_again -``` - -## Usage - -Import the `trie` module and write some code! You can find many examples of how the different functions work in the [project documentation](https://hexdocs.pm/trie_again/). - -```gleam -import trie - -trie.new() -|> trie.insert(at: ["c", "a", "r"], value: 1) -|> trie.insert(at: ["c", "a", "t"], value: 10) -|> trie.get(at: ["c", "a", "t"]) -// -> Ok(10) -``` - -## Contributing - -If you think there's any way to improve this package, or if you spot a bug don't be afraid to open PRs, issues or requests of any kind! Any contribution is welcome 💜 diff --git a/test-community-packages-javascript/build/packages/trie_again/gleam.toml b/test-community-packages-javascript/build/packages/trie_again/gleam.toml deleted file mode 100644 index 75fa79b7bcd..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/gleam.toml +++ /dev/null @@ -1,12 +0,0 @@ -name = "trie_again" -version = "1.1.1" -description = "Tries in Gleam" -licences = ["Apache-2.0"] -repository = { type = "github", user = "giacomocavalieri", repo = "trie_again" } -links = [] - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl b/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl deleted file mode 100644 index b5da5c01430..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/include/trie_Trie.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(trie, { - entry :: gleam@option:option(any()), - children_map :: gleam@map:map_(any(), trie:trie(any(), any())) -}). diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie.erl b/test-community-packages-javascript/build/packages/trie_again/src/trie.erl deleted file mode 100644 index 47d83f03ca4..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/src/trie.erl +++ /dev/null @@ -1,232 +0,0 @@ --module(trie). --compile([no_auto_import, nowarn_unused_vars]). - --export([map/2, new/0, delete/2, fold/3, paths/1, size/1, is_empty/1, to_list/1, values/1, insert/3, from_list/1, singleton/2, get/2, has_path/2, subtrie/2, update/3]). --export_type([trie/2]). - --opaque trie(EWX, EWY) :: {trie, - gleam@option:option(EWY), - gleam@map:map_(EWX, trie(EWX, EWY))}. - --spec do_delete(trie(EXG, EXH), list(EXG)) -> gleam@option:option(trie(EXG, EXH)). -do_delete(Trie, Path) -> - case {Path, Trie} of - {[], {trie, _, Children_map}} -> - case gleam@map:size(Children_map) of - 0 -> - none; - - _ -> - {some, {trie, none, Children_map}} - end; - - {[First | Rest], {trie, Entry, Children_map@1}} -> - New_children = case gleam@map:get(Children_map@1, First) of - {error, _} -> - Children_map@1; - - {ok, Child} -> - case do_delete(Child, Rest) of - none -> - gleam@map:delete(Children_map@1, First); - - {some, Trie@1} -> - gleam@map:insert(Children_map@1, First, Trie@1) - end - end, - case {Entry, gleam@map:size(New_children)} of - {none, 0} -> - none; - - {_, _} -> - {some, {trie, Entry, New_children}} - end - end. - --spec map(trie(EYX, EYY), fun((EYY) -> EZB)) -> trie(EYX, EZB). -map(Trie, Fun) -> - {trie, - gleam@option:map(erlang:element(2, Trie), Fun), - gleam@map:map_values( - erlang:element(3, Trie), - fun(_, T) -> map(T, Fun) end - )}. - --spec new() -> trie(any(), any()). -new() -> - {trie, none, gleam@map:new()}. - --spec delete(trie(EWZ, EXA), list(EWZ)) -> trie(EWZ, EXA). -delete(Trie, Path) -> - _pipe = do_delete(Trie, Path), - gleam@option:unwrap(_pipe, new()). - --spec fold(trie(EXO, EXP), EXS, fun((EXS, list(EXO), EXP) -> EXS)) -> EXS. -fold(Trie, Initial, Fun) -> - gleam@map:fold( - erlang:element(3, Trie), - begin - _pipe = erlang:element(2, Trie), - _pipe@1 = gleam@option:map( - _pipe, - fun(_capture) -> Fun(Initial, [], _capture) end - ), - gleam@option:unwrap(_pipe@1, Initial) - end, - fun(Acc, First, Trie@1) -> - fold( - Trie@1, - Acc, - fun(Acc@1, Rest, Value) -> Fun(Acc@1, [First | Rest], Value) end - ) - end - ). - --spec paths(trie(EZI, any())) -> list(list(EZI)). -paths(Trie) -> - fold(Trie, [], fun(Rest, Path, _) -> [Path | Rest] end). - --spec size(trie(any(), any())) -> integer(). -size(Trie) -> - fold(Trie, 0, fun(Acc, _, _) -> Acc + 1 end). - --spec is_empty(trie(any(), any())) -> boolean(). -is_empty(Trie) -> - size(Trie) =:= 0. - --spec to_list(trie(FAG, FAH)) -> list({list(FAG), FAH}). -to_list(Trie) -> - fold(Trie, [], fun(Rest, Path, Value) -> [{Path, Value} | Rest] end). - --spec values(trie(any(), FBG)) -> list(FBG). -values(Trie) -> - fold(Trie, [], fun(Values, _, Value) -> [Value | Values] end). - --spec insert(trie(EYM, EYN), list(EYM), EYN) -> trie(EYM, EYN). -insert(Trie, Path, Value) -> - case {Path, Trie} of - {[], {trie, _, Children_map}} -> - {trie, {some, Value}, Children_map}; - - {[First | Rest], {trie, Entry, Children_map@1}} -> - _pipe = gleam@map:get(Children_map@1, First), - _pipe@1 = gleam@result:unwrap(_pipe, new()), - _pipe@2 = insert(_pipe@1, Rest, Value), - _pipe@3 = gleam@map:insert(Children_map@1, First, _pipe@2), - {trie, Entry, _pipe@3} - end. - --spec from_list(list({list(EXU), EXW})) -> trie(EXU, EXW). -from_list(List) -> - gleam@list:fold( - List, - new(), - fun(Trie, Pair) -> - insert(Trie, erlang:element(1, Pair), erlang:element(2, Pair)) - end - ). - --spec singleton(list(EZO), EZQ) -> trie(EZO, EZQ). -singleton(Path, Value) -> - insert(new(), Path, Value). - --spec get(trie(EYA, EYB), list(EYA)) -> {ok, EYB} | {error, nil}. -get(From, Path) -> - case {Path, From} of - {[], {trie, none, _}} -> - {error, nil}; - - {[], {trie, {some, Value}, _}} -> - {ok, Value}; - - {[First | Rest], {trie, _, Children_map}} -> - _pipe = Children_map, - _pipe@1 = gleam@map:get(_pipe, First), - gleam@result:then(_pipe@1, fun(_capture) -> get(_capture, Rest) end) - end. - --spec has_path(trie(EYH, any()), list(EYH)) -> boolean(). -has_path(Trie, Path) -> - case get(Trie, Path) of - {ok, _} -> - true; - - {error, _} -> - false - end. - --spec subtrie(trie(EZX, EZY), list(EZX)) -> {ok, trie(EZX, EZY)} | {error, nil}. -subtrie(Trie, Prefix) -> - case {Prefix, Trie} of - {[], _} -> - {ok, Trie}; - - {[First | Rest], {trie, _, Children_map}} -> - _pipe = Children_map, - _pipe@1 = gleam@map:get(_pipe, First), - _pipe@2 = gleam@result:'try'( - _pipe@1, - fun(_capture) -> subtrie(_capture, Rest) end - ), - gleam@result:map(_pipe@2, fun(Subtrie) -> _pipe@3 = gleam@map:new(), - _pipe@4 = gleam@map:insert(_pipe@3, First, Subtrie), - {trie, none, _pipe@4} end) - end. - --spec do_update( - trie(FAV, FAW), - list(FAV), - fun((gleam@option:option(FAW)) -> gleam@option:option(FAW)) -) -> gleam@option:option(trie(FAV, FAW)). -do_update(Trie, Path, Fun) -> - case {Path, Trie} of - {[], {trie, Entry, Children_map}} -> - case {Fun(Entry), gleam@map:size(Children_map)} of - {none, 0} -> - none; - - {_ = New_entry, _} -> - {some, {trie, New_entry, Children_map}} - end; - - {[First | Rest], {trie, Entry@1, Children_map@1}} -> - New_children = case gleam@map:get(Children_map@1, First) of - {ok, Child} -> - case do_update(Child, Rest, Fun) of - none -> - gleam@map:delete(Children_map@1, First); - - {some, New_child} -> - gleam@map:insert(Children_map@1, First, New_child) - end; - - {error, _} -> - case Fun(none) of - none -> - Children_map@1; - - {some, Value} -> - gleam@map:insert( - Children_map@1, - First, - singleton(Rest, Value) - ) - end - end, - case {Entry@1, gleam@map:size(New_children)} of - {none, 0} -> - none; - - {_, _} -> - {some, {trie, Entry@1, New_children}} - end - end. - --spec update( - trie(FAM, FAN), - list(FAM), - fun((gleam@option:option(FAN)) -> gleam@option:option(FAN)) -) -> trie(FAM, FAN). -update(Trie, Path, Fun) -> - _pipe = do_update(Trie, Path, Fun), - gleam@option:unwrap(_pipe, new()). diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam b/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam deleted file mode 100644 index 406e483a2dd..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/src/trie.gleam +++ /dev/null @@ -1,466 +0,0 @@ -import gleam/list -import gleam/map.{Map} -import gleam/option.{None, Option, Some} -import gleam/result - -/// A `Trie(k, v)` is a data structure that allows to store values of type `v` indexed by lists -/// of values of type `k`. -/// -pub opaque type Trie(k, v) { - /// The trie constructor, its implementation is based on the one described by Okasaki in - /// Purely Functional Data Structures. - /// - Trie(entry: Option(v), children_map: Map(k, Trie(k, v))) -} - -/// Deletes from a trie the value associated with a given path. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> delete(at: [1, 2]) -/// > |> to_list -/// [#([1], "b")] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> delete(at: [1, 2]) -/// > |> to_list -/// [] -/// ``` -/// -pub fn delete(from trie: Trie(k, v), at path: List(k)) -> Trie(k, v) { - do_delete(from: trie, at: path) - |> option.unwrap(new()) -} - -/// Exactly same behaviour as delete but returns `None` if the tree is empty as a -/// result of the deletion. -/// -fn do_delete(from trie: Trie(k, v), at path: List(k)) -> Option(Trie(k, v)) { - case path, trie { - [], Trie(_, children_map) -> - case map.size(children_map) { - 0 -> None - _ -> Some(Trie(None, children_map)) - } - [first, ..rest], Trie(entry, children_map) -> { - let new_children = case map.get(children_map, first) { - Error(_) -> children_map - Ok(child) -> - case do_delete(from: child, at: rest) { - None -> map.delete(children_map, first) - Some(trie) -> map.insert(children_map, first, trie) - } - } - case entry, map.size(new_children) { - None, 0 -> None - _, _ -> Some(Trie(entry, new_children)) - } - } - } -} - -/// Combines all the trie's values into a single one by calling a given function on each one. -/// -/// The function takes as input the accumulator, the path of a value and the corresponding value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], 10), #([1], 1)] -/// > |> from_list -/// > |> fold(from: 0, with: fn(sum, _, value) { sum + value }) -/// 11 -/// ``` -/// -pub fn fold( - over trie: Trie(k, a), - from initial: b, - with fun: fn(b, List(k), a) -> b, -) -> b { - map.fold( - over: trie.children_map, - from: trie.entry - |> option.map(fun(initial, [], _)) - |> option.unwrap(initial), - with: fn(acc, first, trie) { - fold( - over: trie, - from: acc, - with: fn(acc, rest, value) { fun(acc, [first, ..rest], value) }, - ) - }, - ) -} - -/// Creates a new trie from a list of path-value pairs. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> to_list -/// [#([1, 2], "a"), #([1], "b")] -/// ``` -/// -pub fn from_list(list: List(#(List(k), v))) -> Trie(k, v) { - list.fold( - over: list, - from: new(), - with: fn(trie, pair) { insert(trie, pair.0, pair.1) }, - ) -} - -/// Fetches a value from a trie for a given path. -/// If a value is present at the given path it returns it wrapped in an `Ok`, -/// otherwise it returns `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> get(at: [1, 2]) -/// Result(Nil) -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> get(at: [1, 2]) -/// Ok("a") -/// ``` -/// -pub fn get(from: Trie(k, v), at path: List(k)) -> Result(v, Nil) { - case path, from { - [], Trie(None, _) -> Error(Nil) - [], Trie(Some(value), _) -> Ok(value) - [first, ..rest], Trie(_, children_map) -> - children_map - |> map.get(first) - |> result.then(get(_, rest)) - } -} - -/// Determines wether a trie contains a value associated with the given path. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> has_path([1, 2]) -/// True -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> has_path([1]) -/// False -/// ``` -/// -pub fn has_path(trie: Trie(k, v), path: List(k)) -> Bool { - case get(trie, path) { - Ok(_) -> True - Error(_) -> False - } -} - -/// Inserts a value in a trie at a given path. If there already is a value -/// at the given path it is replaced by the new one. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(at: [1, 2], value: "a") -/// > |> insert(at: [1], value: "b") -/// > |> to_list -/// [#([1, 2], "a"), #([1], "b")] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(at: [1, 2], value: "a") -/// > |> insert(at: [1, 2], value: "b") -/// > |> to_list -/// [#([1, 2], "b")] -/// ``` -/// -pub fn insert( - into trie: Trie(k, v), - at path: List(k), - value value: v, -) -> Trie(k, v) { - case path, trie { - [], Trie(_, children_map) -> Trie(Some(value), children_map) - [first, ..rest], Trie(entry, children_map) -> { - map.get(children_map, first) - |> result.unwrap(new()) - |> insert(rest, value) - |> map.insert(children_map, first, _) - |> Trie(entry, _) - } - } -} - -/// Determines wether or not the trie is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> is_empty -/// False -/// ``` -/// -pub fn is_empty(trie: Trie(k, v)) -> Bool { - size(trie) == 0 -} - -/// Updates all the values in a given trie by calling a function on each value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> map(fn(s) { s <> "!" }) -/// > |> to_list -/// [#([1, 2], "a!"), #([1], "b!")] -/// ``` -/// -pub fn map(over trie: Trie(k, v), with fun: fn(v) -> a) -> Trie(k, a) { - Trie( - option.map(trie.entry, fun), - map.map_values(trie.children_map, fn(_, t) { map(t, fun) }), - ) -} - -/// Creates a new empty trie. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> to_list -/// [] -/// ``` -/// -pub fn new() -> Trie(k, v) { - Trie(None, map.new()) -} - -/// Gets a list of all the valid paths in the trie. That is all the paths associated with a value. -/// -/// Tries are not ordered so the paths are not returned in any specific order. -/// Do not write code that relies on the order paths are returned by this function -/// as it may change in later versions of the library. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> paths -/// [[1, 2], [1]] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> paths -/// [] -/// ``` -pub fn paths(trie: Trie(k, v)) -> List(List(k)) { - fold(over: trie, from: [], with: fn(rest, path, _) { [path, ..rest] }) -} - -/// Creates a new trie with a single value associated to the given path. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> to_list -/// [#([1, 2], "a")] -/// ``` -/// -pub fn singleton(path: List(k), value: v) -> Trie(k, v) { - insert(new(), at: path, value: value) -} - -/// Gets the number of elements in the trie. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> size -/// 2 -/// ``` -/// -pub fn size(trie: Trie(k, v)) -> Int { - fold(trie, from: 0, with: fn(acc, _, _) { acc + 1 }) -} - -/// Gets the subtrie whose elements all share a common given prefix. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2, 3], "a"), #([1, 2, 4, 5], "b"), #([3, 4], "c")] -/// > |> from_list -/// > |> subtrie(at: [1, 2]) -/// > |> to_list -/// [#([1, 2, 3], "a"), #([1, 2, 4, 5], "b")] -/// ``` -/// -pub fn subtrie(trie: Trie(k, v), at prefix: List(k)) -> Result(Trie(k, v), Nil) { - case prefix, trie { - [], _ -> Ok(trie) - [first, ..rest], Trie(_, children_map) -> - children_map - |> map.get(first) - |> result.try(subtrie(_, rest)) - |> result.map(fn(subtrie) { - map.new() - |> map.insert(first, subtrie) - |> Trie(None, _) - }) - } -} - -/// Turns a trie into a list of path-value pairs. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> to_list -/// [#([1, 2], "a")] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> to_list -/// [] -/// ``` -/// -pub fn to_list(trie: Trie(k, v)) -> List(#(List(k), v)) { - fold( - over: trie, - from: [], - with: fn(rest, path, value) { [#(path, value), ..rest] }, - ) -} - -/// Updates the value associated with a path applying it the given function. -/// If there is no value associated with the given path the function is passed `None`. -/// -/// If the function returns `None` any value associated with the path is deleted from the trie. -/// If the function returns `Some(value)` then the new value is associated to the given path. -/// -/// ## Examples -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> update(at: [1, 2], with: fn(n) { n |> option.map(fn(_) { "b" }) }) -/// > |> to_list -/// [#([1, 2], "b")] -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> update(at: [1, 2], with: fn(_) { None }) -/// > |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > singleton([1, 2], "a") -/// > |> update(at: [1], with: fn(_) { Some("b") }) -/// > |> to_list -/// [#([1, 2], "a"), #([1], "b")] -/// ``` -/// -pub fn update( - trie: Trie(k, v), - at path: List(k), - with fun: fn(Option(v)) -> Option(v), -) -> Trie(k, v) { - do_update(trie, at: path, with: fun) - |> option.unwrap(new()) -} - -/// Exactly same behaviour as update but returns `None` if the tree is empty as a -/// result of the (possible) deletion. -/// -fn do_update( - trie: Trie(k, v), - at path: List(k), - with fun: fn(Option(v)) -> Option(v), -) -> Option(Trie(k, v)) { - case path, trie { - [], Trie(entry, children_map) -> { - case fun(entry), map.size(children_map) { - None, 0 -> None - _ as new_entry, _ -> Some(Trie(new_entry, children_map)) - } - } - [first, ..rest], Trie(entry, children_map) -> { - let new_children = case map.get(children_map, first) { - Ok(child) -> - case do_update(child, at: rest, with: fun) { - None -> map.delete(children_map, first) - Some(new_child) -> map.insert(children_map, first, new_child) - } - Error(_) -> { - case fun(None) { - None -> children_map - Some(value) -> - map.insert(children_map, first, singleton(rest, value)) - } - } - } - - case entry, map.size(new_children) { - None, 0 -> None - _, _ -> Some(Trie(entry, new_children)) - } - } - } -} - -/// Gets a list of all the values in a given trie. -/// -/// Tries are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order values are returned by this function -/// as it may change in later versions of the library. -/// -/// ## Examples -/// -/// ```gleam -/// > [#([1, 2], "a"), #([1], "b")] -/// > |> from_list -/// > |> values -/// ["a", "b"] -/// ``` -/// -/// ```gleam -/// > new() -/// > |> values -/// [] -/// ``` -/// -pub fn values(trie: Trie(k, v)) -> List(v) { - fold(trie, from: [], with: fn(values, _, value) { [value, ..values] }) -} diff --git a/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src b/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src deleted file mode 100644 index e48a5f7a864..00000000000 --- a/test-community-packages-javascript/build/packages/trie_again/src/trie_again.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, trie_again, [ - {vsn, "1.1.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Tries in Gleam"}, - {modules, [trie]}, - {registered, []} -]}. From e191012d6f803311ef454b7798d4a912445fe2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Wed, 10 Apr 2024 20:10:55 +0200 Subject: [PATCH 07/11] Remove cov-mark feature + add descriptive comments --- Cargo.lock | 7 ------- compiler-core/Cargo.toml | 2 -- compiler-core/src/ast.rs | 8 ++++++-- compiler-core/src/ast/tests.rs | 5 ----- compiler-core/src/ast/typed.rs | 7 +++++-- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 555ae4a9029..abac62c1948 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,12 +435,6 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" -[[package]] -name = "cov-mark" -version = "2.0.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d48d8f76bd9331f19fe2aaf3821a9f9fb32c3963e1e3d6ce82a8c09cef7444a" - [[package]] name = "cpufeatures" version = "0.2.12" @@ -895,7 +889,6 @@ dependencies = [ "capnp", "capnpc", "codespan-reporting", - "cov-mark", "debug-ignore", "dirs-next", "ecow", diff --git a/compiler-core/Cargo.toml b/compiler-core/Cargo.toml index 79b637c0ff1..cdec2512291 100644 --- a/compiler-core/Cargo.toml +++ b/compiler-core/Cargo.toml @@ -42,8 +42,6 @@ pubgrub = "0.2" pathdiff = { version = "0.2.1", features = ["camino"] } # Memory arena using ids rather than references id-arena = "2.1" -# Assert certain code path executions -cov-mark = "2.0.0-pre.1" async-trait.workspace = true base16.workspace = true bytes.workspace = true diff --git a/compiler-core/src/ast.rs b/compiler-core/src/ast.rs index fd436fbc155..50ac9234fd3 100644 --- a/compiler-core/src/ast.rs +++ b/compiler-core/src/ast.rs @@ -574,6 +574,9 @@ impl TypedDefinition { pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { match self { Definition::Function(function) => { + + // Search for the corresponding node inside the function + // only if the index falls within the function's full location. if function.full_location().contains(byte_index) { if let Some(found) = function.body.iter().find_map(|s| s.find_node(byte_index)) { @@ -604,7 +607,6 @@ impl TypedDefinition { Some(Located::FunctionBody(function)) } else { - cov_mark::hit!(prune_function_definition); None } } @@ -1754,6 +1756,9 @@ impl TypedStatement { } pub fn find_node(&self, byte_index: u32) -> Option<Located<'_>> { + + // Search for the corresponding node inside the statement + // only if the index falls within the statement's location. if self.location().contains(byte_index) { match self { Statement::Use(_) => None, @@ -1769,7 +1774,6 @@ impl TypedStatement { } } } else { - cov_mark::hit!(prune_statement); None } } diff --git a/compiler-core/src/ast/tests.rs b/compiler-core/src/ast/tests.rs index f24e8301d73..78d3585cf94 100644 --- a/compiler-core/src/ast/tests.rs +++ b/compiler-core/src/ast/tests.rs @@ -245,7 +245,6 @@ fn find_node_sequence() { #[test] fn find_node_sequence_early_exit() { let block = compile_expression(r#"{ 1 2 3 }"#); - cov_mark::check!(early_exit_block); assert!(block.find_node(1).is_none()); } @@ -289,7 +288,6 @@ fn find_node_list_early_exit() { let statement = compile_expression(r#"[1, 2, 3]"#); let list = get_bare_expression(&statement); - cov_mark::check!(early_exit_tuple_list); assert_eq!(list.find_node(2), Some(Located::Expression(list))); } @@ -334,7 +332,6 @@ fn find_node_tuple_early_exit() { let statement = compile_expression(r#"#(1, 2, 3)"#); let tuple = get_bare_expression(&statement); - cov_mark::check!(early_exit_tuple_list); assert_eq!(tuple.find_node(3), Some(Located::Expression(tuple))); } @@ -633,7 +630,6 @@ fn i_am_here(){ value: "3".into(), }; - cov_mark::check!(prune_function_definition); //main() and test1() should be pruned assert_eq!(module.find_node(68), Some(Located::Expression(&int3))); } @@ -656,6 +652,5 @@ pub fn main() { value: "3".into(), }; - cov_mark::check!(prune_statement); //let s1 and let s2 should be pruned assert_eq!(module.find_node(60), Some(Located::Expression(&int3))); } diff --git a/compiler-core/src/ast/typed.rs b/compiler-core/src/ast/typed.rs index 05467cb0e5e..5987d91fe60 100644 --- a/compiler-core/src/ast/typed.rs +++ b/compiler-core/src/ast/typed.rs @@ -183,10 +183,11 @@ impl TypedExpr { .find_map(|e| e.find_node(byte_index)) .or_else(|| finally.find_node(byte_index)), + // Exit the search and return None if during iteration a statement + // is found with a start index beyond the index under search. Self::Block { statements, .. } => { for statement in statements { if statement.location().start > byte_index { - cov_mark::hit!(early_exit_block); break; } @@ -198,6 +199,9 @@ impl TypedExpr { None } + // Exit the search and return the encompassing type (e.g., list or tuple) + // if during iteration, an element is encountered with a start index + // beyond the index under search. Self::Tuple { elems: expressions, .. } @@ -207,7 +211,6 @@ impl TypedExpr { } => { for expression in expressions { if expression.location().start > byte_index { - cov_mark::hit!(early_exit_tuple_list); break; } From 9749531a014b692142c62629e27130281e8e65d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Wed, 17 Apr 2024 14:26:14 +0200 Subject: [PATCH 08/11] remove unnecessary tests --- compiler-core/src/ast/tests.rs | 70 ---------------------------------- 1 file changed, 70 deletions(-) diff --git a/compiler-core/src/ast/tests.rs b/compiler-core/src/ast/tests.rs index c3638d3fd4e..fb2763cb338 100644 --- a/compiler-core/src/ast/tests.rs +++ b/compiler-core/src/ast/tests.rs @@ -273,16 +273,6 @@ fn find_node_list() { assert_eq!(list.find_node(9), None); } -// The function exits early when attempting to find the AST node for a specific index, -// if the remaining elements have indices beyond the search index, returning the list itself. -#[test] -fn find_node_list_early_exit() { - let statement = compile_expression(r#"[1, 2, 3]"#); - let list = get_bare_expression(&statement); - - assert_eq!(list.find_node(2), Some(Located::Expression(list))); -} - #[test] fn find_node_tuple() { let statement = compile_expression(r#"#(1, 2, 3)"#); @@ -317,16 +307,6 @@ fn find_node_tuple() { assert_eq!(tuple.find_node(10), None); } -// The function exits early when attempting to find the AST node for a specific index, -// if the remaining elements have indices beyond the search index, returning the tuple itself. -#[test] -fn find_node_tuple_early_exit() { - let statement = compile_expression(r#"#(1, 2, 3)"#); - let tuple = get_bare_expression(&statement); - - assert_eq!(tuple.find_node(3), Some(Located::Expression(tuple))); -} - #[test] fn find_node_binop() { let statement = compile_expression(r#"1 + 2"#); @@ -596,53 +576,3 @@ use x <- fn(f) { f(1) } assert!(use_.find_node(26).is_some()); // The int } - -// Check that the AST tree gets pruned at the definition level. -#[test] -fn find_node_with_pruning_definition() { - let module = compile_module( - r#" -pub fn main() { - 1 -} - -fn test1() { - 2 -} - -fn i_am_here(){ - 3 -} - "#, - ); - - let int3 = TypedExpr::Int { - location: SrcSpan { start: 68, end: 69 }, - typ: type_::int(), - value: "3".into(), - }; - - assert_eq!(module.find_node(68), Some(Located::Expression(&int3))); -} - -// Check that the AST tree gets pruned at the statement level. -#[test] -fn find_node_with_pruning_statement() { - let module = compile_module( - r#" -pub fn main() { - let s1 = 1 - let s2 = 2 - let s3 = 3 -} - "#, - ); - - let int3 = TypedExpr::Int { - location: SrcSpan { start: 60, end: 61 }, - typ: type_::int(), - value: "3".into(), - }; - - assert_eq!(module.find_node(60), Some(Located::Expression(&int3))); -} From 4bb933c8fecc6cd1716ce501f8bf66de6a5ff6c9 Mon Sep 17 00:00:00 2001 From: Milco Kats <milcokats@gmail.com> Date: Wed, 17 Apr 2024 20:31:28 +0200 Subject: [PATCH 09/11] changelog --- CHANGELOG.md | 2189 +------------------------------------------------- 1 file changed, 41 insertions(+), 2148 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db6bd567a4e..9db0e25ff0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2169 +1,62 @@ # Changelog -### Unreleased - -## Formatter - -- Fixed a bug where the first subject of a case expression clause would be - indented more than necessary. - -## v1.1.0-rc3 - 2024-04-12 - -### Formatter - -- Fixed a bug where the `@internal` annotation wouldn't be displayed. -- Fixed a bug where a record update's arguments would be incorrectly split on - multiple lines. - -## v1.1.0-rc2 - 2024-04-10 - -### Compiler - -- Fixed a bug on the JavaScript target where variables named `debugger`, which - is a JavaScript keyword, were not being renamed, leading to runtime errors. - -### Formatter - -- Fixed a bug where comments would be moved out of an empty bit array. -- Fixed a bug where the formatter could add a trailing comma inside empty - bit arrays, generating invalid syntax. -- Revert the warning about internal types being exposed in a package's public - API. - -### Build tool - -- Revert the change that would make the build tool refuse to publish a package - that exposes an internal type in its public API. - -## v1.1.0-rc1 - 2024-04-08 - -### Compiler - -- The `@internal` attribute can now be used to annotate definitions. - This will hide those definitions from the generated documentation, - autocompletions and the exported module interface. -- Prepending to lists in JavaScript (`[x, ..xs]` syntax) has been optimised. -- Function stubs are no longer generated for functions that do not have an - implementation for the current targeting being compiled for. -- Fixed a bug where some functions would not result in a compile error when - compiled for a target that they do not support. -- Fixed a bug where sometimes a warning would not be emitted when a result is - discarded. -- Fixed a bug with JavaScript code generation of pattern matching guards. -- URLs in error messages have been updated for the new language tour. -- Improved error message when erroneously trying to append items to a list using - the spread syntax (like `[..rest, last]`). -- Generate [type references](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) - when compiling to JavaScript with TypeScript definitions enabled. -- Fix a bug where JavaScript code generation would not properly return the - result of nested blocks. -- Fix a bug where JavaScript code generation would not properly handle functions - returned by blocks. -- Fix a bug where Erlang code generation would not properly handle list case - patterns with no head and a spread tail. -- The compiler will now raise a warning if you're pattern matching on tuple - literals and suggest you use multiple subjects instead. -- Fixed a bug where JavaScript code generation would incorrectly parenthesise a - return statement. -- Fixed a bug where `tuple.0.1` was not recognised as a nested tuple access - expression -- Error messages are more clear about expecting values instead of types. -- Fixed a bug where pattern matching on a string would cause the program to - crash on the JavaScript target. -- A warning is now emitted when defining an opaque external type. -- Improve error message when using incorrect quotes (`'`) to define a string -- Fixed a bug where Erlang string prefix patterns could generate invalid Erlang. -- Fixed string prefix matching producing wrong results on the JavaScript target - when the prefix had a Unicode codepoint escape sequence (`\u{...}`). -- Improved error message for wrong patterns using constructors from other - modules. -- Fixed a bug on the JavaScript target where variables bound by patterns, if - used within a bit array literal inside a `case` clause's guard, would be used - before they were defined, leading to a runtime error when evaluating the - `case` expression. -- Improved error messages when failing to parse a series of things. -- A warning is now raised for unused binary operations, records, record access - and record updates. -- Fixed a bug when using constant as the size option parameter - for `BitArray` caused unknown variable exception. -- Improved recommendations on error messages. -- Improved error message for `BitArray` segment sizes. -- A warning is now raised when an internal type is accidentally exposed in a - package's public API. -- Fixed the error message when using `panic` on the JavaScript target: it now - correctly identifies the error variant as a `panic` instead of a `todo`. -- Fixed a bug on the JavaScript target where empty lists with little space - available could compile to a conversion from the array `[ , ]`, causing them - to wrongly have a length of one (the array has a single `undefined` element). - -### Formatter - -- The formatting of case expressions with multiple subjects has been improved. -- Fixed a bug where the formatter would move comments from the end of bounded - expressions like lists, tuples, case expressions or function calls. -- Fixed a bug where a record update's arguments would not be indented correctly. -- Fixed a bug where function call arguments, tuple items and list items would be - needlessly indented if preceded by a comment. -- Line endings other than `\n` are now handled by the formatter, preserving - blank lines and converting them to `\n`. -- The formatter can now format groups of imports alphabetically. -- Fixed a bug where comments would be moved out of an empty list. -- Fixed a bug where pipes and binary operations in function calls would be - nested more than necessary. -- Improved formatting of comments in binary operation chains. - -### Build tool - -- Added support for the [Bun](https://bun.sh/) runtime when compiling to - JavaScript by using `gleam run --target javascript --runtime bun` -- Allow compilation of packages that require `"rebar"` using the rebar3 - compiler. -- A warning is now emitted if there is a `.gleam` file with a path that would be - invalid as a module name. -- The `~> x.y` version constraint syntax has been dropped in favour of - `> x.y.z and <= xx.0.0` syntax in `gleam add` and `gleam new`, for clarity. -- New projects are created with the GitHub `actions/checkout` v4 action. -- Fixed a bug where bit arrays would break syntax highlighting in the generated - HTML documentation. -- Dependencies that use Erlang-only bit options can now compile on JavaScript, - though the functions that use them will not be available for use in the root - package. -- The output format of the command line help messages have been changed - slightly. -- The command line help text now lists valid targets and runtimes. -- Generated documentation no longer exposes the constructors of opaque types, - no longer exposes the values of constants, and indicates which types are - opaque. -- Generated HTML documentation now includes a link to the package on Hex. -- Terminal colors can now be forced by setting the `FORCE_COLOR` environment - variable to any non-empty value. -- Rust's Reqwest's `webpki-roots` are now used for TLS verification. -- Update Deno config to allow passing `--location` runtime flag. -- Fixed a bug with dependency resolution of exact versions of RC releases. -- Fixed a bug where the documentation of a labelled record constructor could be - assigned to the wrong definition in the doc site. -- Fixed a bug where the code blocks in the generated documentation's site would - have a wrong indentation. -- Fixed a bug where the compiler would panic when it cannot get current - directory. -- Improved error message for non-UTF-8 paths encountered during Gleam commands. - Now includes the path that caused the error for better diagnostics. -- Fixed a bug where on windows local packages had absolute paths in the manifest - instead of relative. -- The `gleam publish` command now asks for confirmation if the package - repository URL doesn't return a successful status code. -- `gleam publish` can now optionally use a Hex API key to authorise publishing - and retiring packages, set via the environment variable `HEXPM_API_KEY`. -- `gleam publish` will now refuse to publish placeholder packages, to prevent - name squatting which is against the Hex terms of service. -- If a package leaks an internal type in its public API, then the build tool - will now refuse to publish it to Hex. -- Monospaced links in the generated documentation now have the same color as - common links. -- Fixed a bug where the `export package interface` command would always - recompile the project ignoring the cache. - -### Language Server - -- Update messages from the client are now batched to avoid doing excess - compilation work in the language server, improving performance. This makes a - large difference in low power machines where the language server could - struggle to keep up with the edits from the client. -- The `Compiling Gleam` message is no longer emitted each time code is compiled. - This is to reduce noise in editors that show this message prominently such as - Neovim. -- Fixed a bug where hovering over an expression in the middle of a pipe would - give the wrong node. -- Go to definition now works for values in dependency Gleam modules. -- Completions are now provided for module imports. - -## v1.0.0 - 2024-03-04 - -### Language changes - -- Comments have been added to the JavaScript prelude to indicate which members - are in the public API and which are internal. +## Unreleased ### Build tool -- Fixed a bug where the exported package interface would not have a module's - documentation. - -## v1.0.0-rc2 - 2024-02-14 - -### Bug fixes - -- Fixed a bug where the exhaustiveness checker could crash for some generic - types. - -### Formatter - -- The format used by the formatter has been improved in some niche cases. -- Improved the formatting of long case guards. - -## v1.0.0-rc1 - 2024-02-10 - -### Language changes - -- Using a reserved word is now a compile error, not a warning. -- Inexhaustive matches are now compile errors, not warnings. -- The warning for an unused module alias now shows how to not assign a name to - the module. -- Type aliases with unused type parameters now emit an error. -- Type definitions with duplicate type parameters now emit an error. - -### Formatter - -- Now the formatter will nest pipelines and binary operators that are used as - function arguments, list items or as tuple items. -- The format function literals used as the last argument in a function call - on long lines has been improved. - -### Build tool - -- If a package contains a `todo` expression then the build tool will now refuse - to publish it to Hex. -- `gleam export` now takes a `package-interface` option to export a json file - containing metadata about the root package. -- `gleam docs build` now creates a json file containing metadata about the root - package. -- The order of dependencies in `manifest.toml` is now in alphabetical order. -- The search bar in generated docs now has a darker background color. -- The generated docs no longer shows whether an argument is discarded or - not in a function signature. -- It is now possible to use `gleam run -m` to run a dependency module even if - that dependency uses a compile target that your project does not support. - -### Bug fixes - -- Fixed a bug the build tool could be make to attempt to run a main function - that does not support the current target in some circumstances. -- Fixed a bug where the exhaustiveness checker could crash when checking nested - values inserted into the parent type using type parameters. -- Fixed a bug where `functionname(_name)` would incorrectly parse as a function - capture instead of a syntax error. -- Fixed a bug where external only functions would "successfully" compile for a - target they do not support, leading to a runtime error. - -## v0.34.1 - 2023-01-17 - -### Build tool changes - -- Support has been added for using SourceHut as a repository. - -### Bug fixes - -- Fixed a bug where long function headers with external implementations could - format incorrectly. -- The `@deprecated` attribute can now be used to annotate module constants. - This will cause a warning to be emitted when the constant is used. - -## v0.34.0 - 2023-01-16 - -## v0.34.0-rc3 - 2023-01-12 - -### Language changes - -- "echo" is now a reserved word. -- A warning is no longer emitted when a function has a Gleam implementation as - well as external implementations for both targets. This is because having a - default Gleam implementation means the code is future-proof and continues to - be cross platform even if a new target is added. - -### Bug fixes - -- Fixed a bug where function heads would go over the line limit in the - formatter. - -## v0.34.0-rc2 - 2023-01-11 - -### Bug fixes - -- Fixed a bug where `gleam run` would fail when the current directory is not - the root of the project and using the JavaScript target. -- Fixed a bug where the compiler would in some cases fail to error when an - application uses functions that do not support the current compilation - target. - -## v0.34.0-rc1 - 2024-01-07 - -### Language changes - -- Warn about function body not being used, because it already has external - implementations for all targets. -- It's now possible to compile a project with external functions in dependency - packages that are not supported by the compilation target so long as they are - not used on the current target. -- The error message for when one imports a constructor instead of an homonymous - type has been improved. - -### Language Server Changes - -- Added a `View on HexDocs` link on function hover. - -### Formatter - -- Fixed some quirk with the formatting of binary operators. -- Fixed a bug where the formatter would move a function call's closed - parentheses on a new line instead of splitting the function's arguments. -- Now the formatter will format tuples as if they were functions, trying to - first split just the last element before splitting the whole tuple. -- Improved the formatting of multiline strings in string concatenation. - -### Build tool changes - -- The `gleam new` command now accepts any existing path, as long as there are - no conflicts with already existing files. Examples: `gleam new .`, `gleam new -..`, `gleam new ~/projects/test`. -- The format for the README created by `gleam new` has been altered. -- The `gleam.toml` created by `gleam new` now has a link to the full reference - for its available options. -- The `gleam` binary is now statically linked on Windows. -- New projects are created requiring between versions of v0.34.0 inclusive and - exclusive v2.0.0. -- The `repository` section now supports additional VCS types in the form of - codeberg, forgejo and gitea allowing a `user`, `repo` and additionally a - `host` url. -- TypeScript declaration for the prelude exports previously missing functions - and classes. Additionally, swaps interfaces for classes and adds missing - attributes to classes. -- `gleam` commands now look in parent directories for a `gleam.toml` file. - -### Bug fixes - -- Fixed a bug where `gleam add` would not update `manifest.toml` correctly. -- Fixed a bug where `fn() { Nil }()` could generate invalid JavaScript code. -- Fixed a bug where the build tool would make unnecessary calls to the Hex API - when path dependencies are used. -- Fixed a bug where `gleam new` would generate a gitignore with `build` rather - than `/build`. -- Fixed where the types of generic constants could be incorrecly inferred. -- `Utf8Codepoint` has been renamed to `UtfCodepoint` in `prelude.d.mts`. -- Fixed a bug where `gleam deps list` would look in filesystem root instead of - the current directory. -- Fixed a bug with the `isEqual` function in `prelude.js` where RegExps were - being incorrectly structurally compared and being falsely reported as being - equal. -- JavaScript: export from `prelude.d.mts` in `gleam.d.mts` to fix the error: - "Type 'Result' is not generic". -- Not providing a definition after some attributes is now a parse error. - -## v0.33.0 - 2023-12-18 - -## v0.33.0-rc4 - 2023-12-17 - -- The deprecated bit array options `binary` and `bit_string` have been removed. -- The deprecated ambiguous type import syntax has been removed. -- The deprecated `BitString` type has been removed. -- The deprecated `inspect` functions and `BitString` type has been removed from - the JavaScript prelude. - -## v0.33.0-rc3 - 2023-12-17 - -### Formatter - -- The formatter now tries to split long chains of binary operations around the - operator itself, rather than around other elements like lists or function - calls. - -### Bug fixes - -- Fixed a bug where string prefix aliases defined in alternative case branches - would all be bound to the same constant. +- A helpful error message is now shown if the `manifest.toml` file has been + edited to be invalid in some way. ([zahash](https://github.com/zahash)) + ``` + error: Corrupt manifest.toml -## v0.33.0-rc2 - 2023-12-07 + The `manifest.toml` file is corrupt. -### Language changes + Hint: Please fun `gleam update` to fix it. + ``` -- The `\e` string escape sequence has been removed. Use `\u{001b}` instead. -- Generated Erlang now disabled redundant case clause warnings as these are now - redundant due to exhaustiveness checking. +### Compiler -### Bug fixes +- The compiler will now raise a warning for `let assert` assignments where the + assertion is redundant. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ``` + warning: Redundant assertion + ┌─ /home/lucy/src/app/src/app.gleam:4:7 + │ + 4 │ let assert x = get_name() + │ ^^^^^^ You can remove this -- Fixed a bug where the `\u` string escape sequence would not work with - on Erlang on the right hand side of a string concatenation. + This assertion is redundant since the pattern covers all possibilities. + ``` -## v0.33.0-rc1 - 2023-12-06 +- Empty case expressions are no longer parse errors and will instead be + exhaustiveness errors. ([Race Williams](https://github.com/raquentin)) ### Formatter -- The formatter now tries to keep a function body and its arguments on a single - line by first trying to split only its last argument on multiple lines. -- Fixed a bug where the formatter would move comments out of blocks. -- `gleam format` now ignores the Gleam build directory by default, even when not - in a git repository. - -### Language changes - -- Gleam now has full exhaustiveness checking. Exhaustiveness issues have been - downgraded from errors to warnings so that existing Gleam code can be - upgraded to be exhaustive without breaking existing code. In a future version - they will be upgraded to errors. -- The `!` operator can now be used in clause guards. -- The words `auto`, `delegate`, `derive`, `else`, `implement`, `macro`, and - `test` are now reserved for future use. If used they will emit a warning. In - a future version this may be upgraded to an error. -- The `\u{...}` syntax can be used in strings to specify unicode codepoints via a - hexadecimal number with 1 to 6 digits. -- The `todo as` and `panic as` syntaxes now accept an expression that evaluates - to a string rather than just a string literal. - -### Build tool changes - -- The `gleam run` and `gleam test` commands gain the `-t` flag, which is an - alias of the `--target` flag. -- The `gleam build`, `gleam check`, `gleam run` and `gleam test` commands now - also accept `js` and `erl` as values for the `--target` flag. -- The `gleam new` command now creates packages at version 1.0.0. -- The `gleam publish` command now asks for confirmation if the package being - published is not yet version 1.0.0. -- The `gleam publish` command now asks for confirmation if the package name is - one that implies the package is maintained by the Gleam core team. -- The error messages shown when dependency resolution fails have been improved. - -### Compiler WASM API - -- The WASM API for the compiler has been rewritten to be simpler. -- The WASM API for the compiler now exposes warnings. - -### HTML documentation generator - -- Searching in rendered HTML documentation now also matches words that do not - start with the input but do contain it. - -### Bug fixes - -- Fixed a bug where the JavaScript code generator could generate invalid code - when pretty printing a zero arity function call when the line is over 80 - columns wide. -- Fixed a bug where the build directory could be left in an invalid state if - there is Elixir code to compile and running on Windows without permission to - create symlinks. -- Fixed a bug where numbers with preceeding zeros could generate incorrect - JavaScript. -- The Erlang code generated by the `/.` operator no longer generates a warning - for the upcoming negative zero float change in Erlang OTP 27. -- Fixed a bug where using only types from an aliased import, wouldn't stop the - compiler from emitting an unused alias warning for that import. -- Fixed a bug where the formatter would remove the ` as name` from string prefix - patterns. -- Fixed a bug where the formatter would misplace comments at the start of a - block. -- Fixed a bug where using a string prefix pattern in `let assert` would generate - incorrect JavaScript. - -## v0.32.4 - 2023-11-09 - -### Build tool changes - -- The build tool now supports rebar3 and mix hex packages where the package name - differs from the otp application name. - -### bug fixes - -- Fixed a bug where invalid javascript code could be generated when a module - function calls another function that was passed as an argument and the - argument has the same name as the module function. -- Fixed the `target` property of `gleam.toml` being ignored for local path - dependencies by `gleam run -m module/name` - -## v0.32.3 - 2023-11-07 - -### Language changes - -- Imported modules can now be discarded by giving them an alias starting with `_`. - -### Build tool changes - -- New projects are now generated with the call to `gleam format` coming last in - the GitHub Actions workflow. This is so that feedback from tests is presented - even if formatting is incorrect. -- Added Windows support for the `gleam export erlang-shipment` command. - -### Bug fixes - -- Fixed a bug where some nested pipelines could fail to type check. - -## v0.32.2 - 2023-11-03 - -### Build tool changes - -- New Gleam projects are created with `gleam_stdlib` v0.32 and `gleeunit` v1.0. - -### Bug fixes - -- Fixed a bug where `gleam fix` would not produce correct results for code that - shadowed a prelude name with an import of the same name but a different kind. -- Fixed a bug where documentation would not publish to Hexdocs for packages with - a number in the name. -- Fixed a bug where aliased unqualified types and values of the same name could - produce an incorrect error. - -## v0.32.1 - 2023-11-02 - -### Bug fixes - -- Fixed a bug where `gleam fix` would not produce correct results for code that - shadowed a prelude name with an import of the same name but a different kind. -- Fixed a bug where incorrect JavaScript could be generated due to backwards - compatibility with the deprecated import syntax. - -## v0.32.0 - 2023-11-01 - -### Bug fixes - -- Fixed a bug where running `gleam fix` multiple times could produce incorrect - results. - -## v0.32.0-rc3 - 2023-10-26 - -### Bug fixes - -- Fixed a bug where `gleam fix` would fail to update the deprecated type import - syntax for aliased unqualified types. - -## v0.32.0-rc2 - 2023-10-26 - -### Bug fixes - -- Fixed a bug where the backward compatibility for the deprecated import syntax - could result in an import error with some valid imports. - -## v0.32.0-rc1 - 2023-10-25 - -### Language changes - -- Using `import module.{TypeName}` to import a type has been deprecated, - replaced by `import module.{type TypeName}`. In a future version of Gleam the - old syntax will only import the value of the same name. Run `gleam fix` to - update your code. -- The `BitString` type has been renamed to `BitArray`. Run `gleam fix` to update - your code. -- The `binary` and `bit_string` bit array modifier have been deprecated in favour - of `bytes` and `bits`. -- The error message for when one element in a list doesn't match the others has - been improved. -- The error message for when the elements of a list's tail don't match the - previous ones has been improved. -- The error message for when one tries to access an unknown field has been - improved. -- The `__gleam_prelude_variant__` property has been removed from the classes - defined in the JavaScript prelude. -- The deprecated `todo("...")` syntax has been removed. -- Module access can now be used in case clause guards. -- The JS target now supports bit syntax for module constants. -- The Erlang compiler will no longer emit a duplicate warning for unused - functions. -- The `@deprecated` attribute can now be used with type definitions. -- A warning is now emitted if a module alias is unused. - -### Language server changes - -- The language server now has a code action for removing unused items. -- The language server now shows the type of variables defined using `use` on - hover. - -### Build tool changes - -- The `gleam check` command supports the `target` flag. -- The `gleam fix` command updates code to use `BitArray` rather than `BitString`. -- The `gleam fix` command updates code to use the new import type syntax. -- `gleam fix` sets the `gleam` version constraint in `gleam.toml` to `>= 0.32.0`. -- The `gleam` version constraint field in `gleam.toml` now disregards pre and - build components when checking for compatibility. -- The prelude is no longer rendered once per package when compiling to - JavaScript, instead one copy is rendered for the entire project. If you are - using the `gleam compile-package` API you now need to give a path to the - prelude using the `--javascript-prelude` flag. -- The `gleam export javascript-prelude` and `gleam export typescript-prelude` - commands have been added to export a copy of the prelude. This command may be - useful for build tools that use the compiler via the `gleam compile-package` - API. -- Fixed a bug where some deprecation messages would not be printed. -- The content has been made wider in rendered HTML documentation. -- Dependencies that can be built with both `mix` and `rebar3` are now built - with `mix` if it exists on the system, and with `rebar3` if it doesn't. - -### Bug fixes - -- "Compiling $package" is now only printed when a package has new changes to - compile. -- The main process started with `gleam run` no longer traps exits on Erlang. -- The formatting of code in rendered HTML documentation has been improved. -- The formatter no longer moves trailing comments out of custom type definitions. -- Fixed a bug where some hexidecimal numbers would generate incorrect Erlang. -- Fixed a bug where markdown tables would not render correctly in HTML - documentation. -- The float 0.0 is now rendered in Erlang as `+0.0` to silence warnings in - Erlang/OTP 27. - -## v0.31.0 - 2023-09-25 - -- New Gleam projects are created with `gleam_stdlib` v0.31, `actions/checkout` - v3.\*, and `erlef/setup-beam` v1.\*. -- A note is included in the generated HTML documentation if a function is - deprecated. - -## v0.31.0-rc1 - 2023-09-18 - -- The `@deprecated("...")` attribute can be used to mark a function as - deprecated. This will cause a warning to be emitted when the function is used. -- A warning is now emitted if a module from a transitive dependency is imported. -- Record access can now be used in case clause guards. -- Fixed a bug where `manifest.toml` could contain absolute paths for path - dependencies. -- The `as` keyword can now be used to assign the literal prefix to a variable - when pattern matching on a string. -- The `if` conditional compilation, `external fn`, and `external type` syntaxes - have been removed. -- The `description` flag for the `gleam new` command has been removed. -- The highlight.js grammar included with generated HTML documentation has been - updated for the latest syntax. -- Packages are no longer precompiled to Erlang when publishing to Hex if the - package target is set to JavaScript. -- An exception is now raised if JavaScript code uses the `BitString` class - constructor and passes in the incorrect argument type. -- Fixed a bug where mutually recursive functions could be incorrectly inferred - as having an overly general type. -- Fixed a bug where recursive type constructors could incorrectly infer a type - error. -- Fixed a bug where some mutually recursive functions would be inferred as - having too general a type. -- Fixed a bug where constants where not being correctly inlined when used in the - size option of a bit string pattern match. -- Fixed a bug where anonymous functions could parse successfully when missing a - body. -- Fixed a bug where incorrect unused variable warnings could be emitted for code - that doesn't type check. -- Fixed a bug where packages defaulting to the JavaScript target could have - modules missing from their HTML documentation when published. -- Corrected some outdated links in error messages. -- Hovering over a function definition will now display the function signature, - or the type of the hovered argument. -- Use `import type` for importing types from typescript declarations. -- Use `.d.mts` extension for typescript declarations to match `.mjs`. -- Prefix module names with dollar sign in typescript to avoid name collisions. - -## v0.30.4 - 2023-07-26 - -- External implementations are always referenced directly in generated code, to - avoid the overhead of an extra function call. -- Fixed a bug where the compiler could infer incorrect generic type parameters - when analysing a module without type annotations with self recursive - functions that reference themselves multiple times. - -## v0.30.3 - 2023-07-23 - -- Fixed a bug where JavaScript module path such as `node:fs` would be rejected. -- New Gleam projects are created with `gleam_stdlib` v0.30, Erlang OTP v26.0.2, - Elixir v1.15.4, actions/checkout v3.5.1, and erlef/setup-beam v1.16.0. - -## v0.30.2 - 2023-07-20 - -- Fixed a bug where the compiler could infer incorrect generic type parameters - when analysing a module without type annotations with self recursive - functions. -- Fixed a bug where the formatter would incorrectly format external functions - by breaking the return annotation instead of the function arguments. - -## v0.30.1 - 2023-07-13 - -- Fixed a bug where the language server could fail to import path dependencies - in monorepos. - -## v0.30.0 - 2023-07-12 - -- A warning is now emitted for the deprecated external fn syntax. - -## v0.30.0-rc4 - 2023-07-10 - -- An error is now emitted for invalid JavaScript external implementations. -- Fixed a bug where Erlang external implementations could generate invalid code. - -## v0.30.0-rc3 - 2023-07-05 - -- Fixed a bug where `gleam fix` would fail to parse command line flags. - -## v0.30.0-rc2 - 2023-07-03 - -- Fixed a bug where `gleam fix` would merge external functions of the same name - but incompatible types. -- Fixed a bug where external function arguments would incorrectly be marked as - unused. - -## v0.30.0-rc1 - 2023-06-29 - -- The new `@target(erlang)` and `@target(javascript)` attribute syntax has been - added for conditional compilation. The existing `if` conditional compilation - syntax has been deprecated. Run `gleam fix` to update your code. -- The new `type TypeName` syntax syntax replaces the `external type TypeName` - syntax. The existing external type syntax has been deprecated. Run `gleam format` - to update your code. -- Adding a new dependency now unlocks the target package. This helps avoid - failing to find a suitable version for the package due to already being - locked. -- A custom message can now be specified for `panic` with `panic as "..."`. -- The syntax for specifying a custom message for `todo` is now `todo as "..."`. -- The Erlang error raised by `let assert` is now tagged `let_assert`. -- Types named `Dynamic` are now called `dynamic_` in Erlang to avoid a clash - with the new Erlang `dynamic` type introduced in OTP26. -- Dependencies can now be loaded from paths using the - `packagename = { path = "..." }` syntax in `gleam.toml`. -- The `javascript.deno.unstable` field in `gleam.toml` can now be used to - enable Deno's unstable APIs when targeting JavaScript. -- Blockquotes are now styled in rendered HTML documentation. -- The `gleam` property can be set in `gleam.toml` can be set to a version - requirement to specify the version of Gleam required to build the project. -- Type aliases can now refer to type aliases defined later in the same module. -- Fixed a bug where unapplied record constructors in constant expressions would - generate invalid Erlang. -- Fixed a bug where the prescedence of `<>` and `|>` would clash. -- Fixed a bug where `gleam docs build` would print an incorrect path upon - completion. -- Warnings from dependency packages are no longer surfaced in the language - server. -- A warning is now emitted when a Gleam file is found with an invalid name. -- A warning is now emitted when using `list.length` to check for the empty list, - which is slow compared to checking for equality or pattern matching (#2180). -- The new `gleam remove <package_name>` can be used to remove dependencies - from a Gleam project. -- Fixed a bug where the formatter could crash. -- Fixed a bug where invalid Erlang would be generated when piping into `panic`. -- The `gleam docs build` command gains the `--open` flag to open the docs after - they are generated (#2188). -- Fixed a bug where type annotations for constants could not be written with - type annotations. -- Updated font loading in generated HTML documentation to fix an issue with - fonts not loading properly in some browsers (#2209). - -## v0.29.0 - 2023-05-23 - -- New projects now require `gleam_stdlib` v0.29. - -## v0.29.0-rc2 - 2023-05-22 - -- The `gleam lsp` command is no longer hidden from the help output. -- Fixed a bug where some language server clients would show autocompletion - suggestions too eagerly. - -## v0.29.0-rc1 - 2023-05-16 - -- The language server will now provide autocomplete suggestions for types and - values either imported or defined at the top level of the current module. -- Fixed a bug where record patterns using the spread operator (`..`) to discard - unwanted arguments would not type check correctly when the record had no - labelled fields. -- Add support for using sized binary segments in pattern matches when targeting - JavaScript. -- A warning is now emitted for double unary negation on ints (`--`) and bools - (`!!`) as this does nothing but return the original value. -- Previously the build tool would discard the entire build directory when dependencies - were changed. Now it will only discard the build artefacts for removed - dependencies. -- The errors emitted when a name is reused in a module have been made clearer. -- Fixed an incorrect URL in the error message for failing to parse a let binding - with a type annotation. -- Fixed a bug where shadowing a prelude type name could result in incorrect - errors in exhaustiveness checking. -- Fixed a bug where the language server would in some scenarios not remove an - error diagnostic after it becomes outdated. -- Fixed a bug where the formatter would incorrectly format blocks with a comment - before them that were the only argument to a function call. -- Fixed a bug where the language server would not reset the build directory when - it was created by a different version of Gleam. -- New Gleam projects are created with `erlef/setup-beam@v1.15.4` in their GitHub - actions CI configuration. -- Running a module now uses the dependency's target and runtime in its `gleam.toml`. - -## v0.28.3 - 2023-04-17 - -- Fixed a bug where the language server would show outdated error diagnostics - when a new one was emitted in a different module. -- Fixed a bug where the language server would attempt to analyse Gleam modules - that were outside of the `src` or `test` directories. -- New Gleam projects are created with `actions/checkout@v3.5.1` and - `erlef/setup-beam@1.15.3` in their GitHub actions CI configuration. - -## v0.28.2 - 2023-04-10 - -- Fixed a bug where comments above a `use` expression would be formatted - incorrectly. -- Fixed a bug where the formatter would fail to preserve empty lines after a - block. -- Fixed a bug where the formatter would fail to preserve empty lines after an - anonymous function with a return annotation. - -## v0.28.1 - 2023-04-05 - -- Fixed a bug where the language server would unset too many error diagnostics - when multiple projects are open, more than one have errors, and one of them is - successfully compiled. -- Fixed a bug where the language server would unset error diagnostics when - displaying information on hover. -- Added support for type annotations in use statements. - -## v0.28.0 - 2023-04-03 - -- New projects now require `gleam_stdlib` v0.28. - -## v0.28.0-rc3 - 2023-03-31 - -- Fixed a bug where source links would be incorrect in HTML documentation. - -## v0.28.0-rc2 - 2023-03-27 - -- Fixed a bug where single statement blocks inside binary operators could - generate invalid JavaScript. -- Fixed a bug where the formatter could incorrectly place comments. -- Fixed a bug where the language server would show outdated diagnostics when a - file with an error reverts to the previous valid version, causing the compiler - to use the cached version of the file. - -## v0.28.0-rc1 - 2023-03-26 - -- The language server now analyzes files on edit rather than on save, providing - feedback faster. -- The language server now supports editor sessions that span multiple projects. - This is useful for mono-repos and projects with both a frontend and backend in - Gleam. -- The language server now also shows documentation on hover for expressions. -- The language server now shows types and documentation on hover for patterns. -- Added support for negation of integers with the new `-` unary operator. -- Variable assignments are now only permitted within a function or a block, not - anywhere that an expression is permitted. -- The deprecated `try` expression has been removed. -- The deprecated `assert ... = ...` syntax has been removed. -- Semicolons are no longer whitespace. An error will be emitted if one is - encountered. -- Warnings are now immediately emitted rather than being buffered until the end - of the compilation. -- The `--warnings-as-errors` flag is now supported by `gleam build`. -- Blocks are now preserved by the formatter when they only have a single - expression within them. -- Generated docs now export more meta data to improve the developer experience, - accessibility and search engine discoverability. -- Files are now only recompiled if they have changed since the last compilation, - detected by file hash and modification time. Previously only the modification - time was used. -- Autocompletion of module imports was removed due to a buggy implementation. -- Fixed a bug where the formatter would incorrectly remove `{ ... }` from bit - string segment value expressions. -- Fixed a bug where TypeScript type definitions files could include incorrect - type names. -- Fixed a bug where the compiler used VSCode specific behaviour in the language - server which was incompatible with Helix. -- Fixed a bug where string concatenation patterns on strings with escape - characters would generate javascript code with wrong slice index. -- Fixed a bug where blocks could parse incorrectly. -- Allow modules to be run with the `gleam run --module` command. - -## v0.27.0 - 2023-03-01 - -- Fixed a bug where `panic` could generate incorrect JavaScript code. -- New projects now require `gleam_stdlib` v0.27. - -## v0.27.0-rc1 - 2023-02-26 - -- The new `panic` keyword can be used to crash the program. This may be useful - for situations in which a program has got into an unrecoverable invalid state. -- `try` expressions are now deprecated and will be removed in a future version. -- The new `gleam fix` command can be used to automatically convert `try` - expressions to `use` expressions. -- `let assert ... = ...` is now the syntax for assertion assignments. The - `assert ... = ...` syntax is deprecated and will be removed in a future - version. Run `gleam format` to automatically update your code. -- `gleam export hex-tarball` can be used to create a tarball suitable for - uploading to a Hex compatible package repository. -- The unused private type and constructor detection has been improved. -- The argument `--runtime` now accepts `nodejs` as the name for that runtime. - The previous name `node` is still accepted. -- Patterns can now be used in `use` expressions. -- Fixed a bug where string concatenation patterns could generate javascript - code with wrong slice index due to ut8/ut16 length mismatch. -- The Erlang compiler will no longer emit a duplicate warning for unused - variables. -- Fixed a bug where typescript type definitions for types with unlabelled - arguments where generated with an invalid identifier and unlabelled fields - were generated with a name that didn't match the javascript implementation. -- Fixed a bug in the type inferrer were unannotated functions that were - used before they were defined in a module could in rare cased be inferred - with a more general type than is correct. -- Fixed a bug where the LSP would fail to show type information on hover for - expressions after a use expression. -- Fixed a bug where imported constants could generated incorrect JavaScript - code. -- Fixed a bug where the LSP would perform codegen for dependencies. -- Fixed a bug where the LSP would compile native dependencies needlessly. -- Fixed a bug where integer division with large numbers on JavaScript could - produce incorrect results. -- Fixed a bug where pattern matches on custom types with mixed labelled and - unlabelled arguments could not be compiled when targeting JavaScript. -- Fixed a bug where local variables in case guard constant expressions caused - the compiler to panic. -- The formatter now truncates meaningless zeroes of floats' fractional parts. -- Anonymous functions may now have an empty body. The compiler will emit a - warning for functions without a body, and these functions will crash at - runtime if executed. -- Fixed bug where raised errors on JS would have an extra stack frame recorded - in them. - -## v0.26.2 - 2023-02-03 - -- The formatter now wraps long `|` patterns in case clauses over multiple lines. -- Fixed a bug where unlabelled function arguments could be declared after - labelled ones. -- A broken link was removed from the error messages. -- Fixed a bug where using a qualified imported record constructor function as a - value would produce invalid Erlang code if the name of the record variant was - an Erlang reserved word. - -## v0.26.1 - 2023-01-22 - -- New projects now require `gleeunit` v0.10. -- Rebar3 dependency projects are now compiled in-place. This fixes an issue - where some NIF using projects would fail to boot due to some paths not being - copied to the `build` directory. -- An error is now emitted if a list spread expression is written without a tail - value. -- An error is now emitted when a function is defined with multiple arguments - with the same name. -- The error message emitted when a `let` does not match all possible values has - been improved. -- Fixed a bug where the language server wouldn't analyse test code. -- Fixed a bug where `assert` expressions can generate invalid Erlang. - warning. -- Fixed a bug where arguments would be passed incorrectly to Deno. -- Fixed a bug where defining variables that shadow external functions could - generate invalid JavaScript. - -## v0.26.0 - 2023-01-19 - -[Release blog post](https://gleam.run/news/v0.26-incremental-compilation-and-deno/) - -- New projects require `gleam_stdlib` v0.26 and `gleeunit` v0.9. -- Fixed a bug where JavaScript default projects would fail to publish to Hex. - -## v0.26.0-rc1 - 2023-01-12 - -- Added support for Deno runtime for JavaScript target. -- Scientific notation is now available for float literals. -- The compiler now supports incremental compilation at the module level. If a - module or its dependencies have not been changed then it will not be - recompiled. -- The format used by the formatter has been improved. -- 4 digit integers are now always formatted without underscores. -- Running `gleam new` will skip `git init` if the new project directory is - already part of a git work tree. -- Generated HTML documentation now includes all static assets, including web - fonts, so that it can be accessed offline and in future once CDNs would 404. -- Generated HTML documentation now supports TypeScript syntax highlighting. -- New Gleam projects are created using GitHub actions erlef/setup-beam@v1.15.2. -- Some modules can now be hidden from the docs by specifying a list of glob - patterns in `internal_modules` in `gleam.toml`. The default value for this - list is `["$package_name/internal", "$package_name/internal/*"]`. -- The `gleam new` command gains the `--skip-git` flag to skip creation of - `.git/*`, `.gitignore` and `.github/*` files. -- The `gleam new` command gains the `--skip-github` flag to skip creation of - `.github/*` files. -- Fixed a bug where no error would be emitted if a `src` module imported a - `test` module. -- Fixed a bug where comments in list prepending expressions could be formatted - incorrectly. -- Fixed a bug where comments in record update expressions could be formatted - incorrectly. -- Fixed a bug where long `use` expressions could be formatted incorrectly. -- Fixed a bug integer multiplication would overflow large integers when - compiling to JavaScript. -- Fixed `int` and `float` formatting in `const`s and patterns. -- Fixed a bug where piping into a function capture expression with a pipe as one - of the arguments would produce invalid Erlang code. -- Formatter no longer removes new lines in expression blocks within case branches - -## v0.25.3 - 2022-12-16 - -- 4 digit integers are no longer automatically formatted with underscores. - -## v0.25.2 - 2022-12-16 - -- Updated `actions/checkout` from `actions/checkout@v3.0.0` to `@v3.2.0` for - projects created via `gleam new`. -- Fixed a bug where `gleam new` would set a `Rebar3` version to `25.1` - instead of the latest stable `3`. -- Updated following runtime versions set via `gleam new`: `Erlang/OTP` - to `25.2`, and `Elixir` to `1.14.2`. -- The formatter now inserts underscores into larger `Int`s and the larger - integer parts of `Float`s. -- Added support for top level TypeScript file inclusion in builds. -- The build tool will now favour using rebar3 over Mix for packages that support - both. This fixes an issue where some packages could not be compiled without - Elixir installed even though it is not strictly required. - -## v0.25.1 - 2022-12-11 - -- New Gleam projects are now configured to explicitly install rebar3 using - GitHub actions erlef/setup-beam. -- A better error message is now shown when attempting to use a function within a - constant expression. -- Changed float size limit in bit string expressions to 16, 32 or 64, when static. - Also allowed dynamic size. -- New Gleam projects are created using GitHub actions erlef/setup-beam@v1.15.0. -- Fixed a bug where returning an anonymous function from a pipeline and calling - it immediately without assigning it to a variable would produce invalid Erlang - code. -- Fixed a bug where the formatter would remove the braces from negating boolean - expressions. - -## v0.25.0 - 2022-11-24 - -[Release blog post](https://gleam.run/news/v0.25-introducing-use-expressions/) - -## v0.25.0-rc2 - 2022-11-23 - -- Fixed a bug where Gleam dependency packages with a `priv` directory could fail - to build. -- Fixed a regression where Elixir and Erlang Markdown code blocks in generated - documentation would not be highlighted. - -## v0.25.0-rc1 - 2022-11-19 - -- Generated HTML documentation now includes the `theme-color` HTML meta tag. -- The `use` expression has been introduced. This is a new syntactic sugar that - permits callback using code to be written without indentation. -- Nightly builds are now also published as OCI container images hosted on - GitHub. -- Fixed a bug where the build tool would not hook up stdin for Gleam programs it - starts. -- Fixed a bug where using a record constructor as a value could generate a - warning in Erlang. -- Fixed a bug where the build tool would use precompiled code from Hex packages - rather than the latest version, which could result in incorrect external - function usage in some cases. -- Fixed a bug where the warning for `todo` would not print the type of the code - to complete. -- Fixed a bug where `try` expressions inside blocks could generate incorrect - JavaScript. -- Generated HTML documentation now includes all static assets (but the web - fonts), so that it can be accessed offline or in far future once CDNs would 404. -- New Gleam projects are created using GitHub actions erlef/setup-beam@v1.14.0 -- The `javascript.typescript_declarations` field in `gleam.toml` now applies to - the entire project rather than just the top level package. -- The formatter now adds a `0` to floats ending with `.` (ie `1.` => `1.0`). -- New projects require `gleam_stdlib` v0.25. - -## 0.24.0 - 2022-10-25 - -[Release blog post](https://gleam.run/news/gleam-v0.24-released/) - -## 0.24.0-rc4 - 2022-10-23 - -- Fixed a bug where the string concatenate operator could produce invalid Erlang - code when working with pipe expressions. - -## 0.24.0-rc3 - 2022-10-20 - -- Fixed a bug where the OOP method call error hint would be shown on too many - errors. -- Fixed a bug where the string concatenate operator could produce invalid Erlang - code when working with constant values. - -## 0.24.0-rc2 - 2022-10-18 - -- Fixed a bug where imported and qualified record constructors used in constant - expressions could fail to resolve. - -## 0.24.0-rc1 - 2022-10-15 - -- Gleam can now compile Elixir files within a project's `src` directory. -- The `<>` operator can now be used for string concatenation and for string - prefix pattern matching. -- Fixed a bug where TypeScript definitions may have incorrect type parameters. -- New projects depend on `gleam_stdlib` v0.24. -- New projects' GitHub Actions config specifies Erlang/OTP 25.1 and suggest - Elixir 1.14.1. -- If you attempt to use the method call syntax (`thing.method()`) on a value - without that field the error message will now include a hint explaining that - Gleam is not object oriented and does not have methods. -- Fixed a bug in the formatter where multiple line documentation comments for - custom type constructor fields could be formatted incorrectly. -- Fixed a bug where tail call optimisation could be incorrectly applied when - compiling to JavaScript in some situations. -- Fixed a bug where the remainder operator would return NaN results when the - right hand side was zero when compiling to JavaScript. -- Fixed a bug where Elixir dependencies would fail to compile on Windows. -- Fixed a bug where images added to HTML documentation via documentation - comments would not have a max width. - -## v0.23.0 - 2022-09-15 - -[Release Blog Post](https://gleam.run/news/gleam-v0.23-released/) - -## v0.23.0-rc2 - 2022-09-15 - -- New Gleam projects are created using GitHub actions erlef/setup-beam@v1.13.0 - and actions/checkout@v3.0.0. -- New Gleam projects are created using version v0.23.0 of the stdlib. -- Fixed a bug where LSP hovering would fail to locate the expression. - -## v0.23.0-rc1 - 2022-09-01 - -- Gleam can now build dependency packages that are managed using Mix. -- Compiler performance has been improved by buffering disc writing and by lazily - loading TLS certs. In testing this doubles performance when compiling the - standard library. -- The `gleam publish` command now adds the `priv` directory and any `NOTICE` - file to the tarball. -- The `gleam update` command can now be used to update dependency packages to - their latest versions. -- Module functions with empty bodies are no longer syntax errors. -- The format used by the formatter has been improved. -- OpenSSL swapped out for RustTLS. -- Generated HTML documentation now includes a search bar. -- The LSP will now provide autocompletion for imports. -- A helpful error message is now returned when assignments are missing either a - keyword or a value. -- Qualifiers are now used when multiple types have the same name in an error - message. -- In JavaScript, if an object has defined an `equals` method in its prototype, - Gleam will now use this method when checking for equality. -- Functions can now be defined and referenced in constant expressions. -- An error is now raised if the record update syntax is used with a custom type - that has multiple constructors. -- An error is now raised if a module is imported multiple times. -- Fixed a bug where defining a type named `CustomeType` would product invalid - JavaScript. -- Fixed a bug where defining a variable with the same name as an unqualified - import would produce invalid JavaScript. -- Fixed a bug where piping to `todo` would generate invalid Erlang code. -- Fixed a bug where inspecting a JavaScript object with a null prototype would - crash. -- Fixed a bug where the formatter could crash if source code contained 3 or more - empty lines in a row. -- Fixed a bug where the formatter would remove braces from blocks used as the - subject of a case expression. -- Fixed a bug alternative patterns with a clause containing a pipe with a pipe - after the case expresson could render incorrect Erlang. -- Fixed a bug where formatter would strip curly braces around case guards even - when they are required to specify boolean precedence. -- Fixed a bug where `gleam new` would in some situations not validate the - target directory correctly. -- Fixed a bug where pipes inside record update subjects could generate invalid - Erlang. -- Fixed a bug where pipes inside record access could generate invalid Erlang. - -## v0.22.1 - 2022-06-27 - -- The `gleam publish` confirmation prompt now accepts both "Y" and "y". -- Fixed a bug where `todo` would not emit the correct line number to the LSP while. - -## v0.22.0 - 2022-06-12 - -[Release Blog Post](https://gleam.run/news/gleam-v0.22-released/) - -- New projects are created with `gleam_stdlib` v0.22. - -## v0.22.0-rc1 - 2022-06-12 - -- Fixed a bug where doc comments would dissociate from their statements when - generating html documentation. -- You are now allowed to use named accessors on types with multiple constructors if the - accessor's name, position and type match (among the constructors) (#1610). -- Added the ability to replace a release up to one hour after it is published - using `gleam publish --replace`. -- `gleam publish`, `gleam docs publish`, `gleam docs remove`, `gleam hex retire`, - and `gleam hex unretire` now have access to environment variables for - username (default key `HEXPM_USER`) and password (default key `HEXPM_PASS`) -- The `gleam publish` command gains the `-y/--yes` flag to disable the "are you - sure" prompt. -- Clear outdated files from the build directory after compilation. -- Fixed a bug where immediately calling the value that a case expression - evaluates to could generate invalid JavaScript. -- Fixed a bug where the default project target is set to JavaScript, - but the project would run on target Erlang instead. -- The compiler is now able to generate TypeScript declaration files on target - JavaScript (#1563). To enable this edit `gleam.toml` like so: - - ```toml - [javascript] - typescript_declarations = true +- Redundant alias names for imported modules are now removed. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ```gleam + import gleam/result as result + ``` + is formatted to + ```gleam + import gleam/result ``` -- Fixed a bug where argument labels were allowed for anonymous functions. -- Fixed a bug where JavaScript code could be invalid if a variable is defined - inside an anonymous function with a parameter with the same name as the - variable. -- Fixed a bug where importing a JavaScript function named "then" could produce - invalid code. -- Fixed a bug where constants that reference locally defined custom types could - render invalid JavaScript. -- The project generator will no longer permit use of the reserved `gleam_` - prefix. -- Generated HTML docs easter egg updated. -- `gleam export erlang-shipment` can be used to create a directory of compiled - Erlang bytecode that can be used as a deployment artefact to get your - application live. -- `gleam format` will now preserve (up to one) empty lines between consecutive - comments, as well as between comments and any following expression -- The deprecated rebar3 integration has been removed. -- Fixed a bug where `gleam format` would output an unwanted newline at the top - of documents that only contain simple `//` comments. -- No longer add `dev-dependencies` to generated `.app` Erlang files unless - we're compiling the root project (#1569). -- Fixed a bug where the formatter could render a syntax error with lists on long - unbreakable lines. -- Fixed a bug where JavaScript variable names could be incorrectly reused. -- Fixed a bug where `gleam format` would remove the braces around a tuple index - access when accessing a field of the returned element. -- Fixed a bug case clause guards could render incorrect JavaScript if a variable - name was rebinded in the clause body. -- The `gleam compile-package` command no longer generates a `.app` file. This - should now be done by the build tool that calls this command as it is - responsible for handling dependencies. -- Fixed a bug where piping a list tail would create invalid Erlang code (#1656). - -## v0.21.0 - 2022-04-24 - -[Release Blog Post](https://gleam.run/news/v0.21-introducing-the-gleam-language-server/) - -- New projects are created with `gleam_stdlib` v0.21. - -## v0.21.0-rc2 - 2022-04-20 - -- Added the ability to replace a release up to one hour after it is published - using `gleam publish --replace`. -- The language server will now enter a degraded mode that only performs - formatting if running in a directory that is not a Gleam project with a - `gleam.toml`. - -## v0.21.0-rc1 - 2022-04-16 - -- The Gleam language server is here! This will provide IDE like features for - code editors that support LSP, including but not limited to VSCode, Neovim, - Emacs, Eclipse, Visual Studio, and Atom. This first version includes these - features: - - Project compilation. - - Inline errors and warnings. - - Type information on hover. - - Go-to definition. - - Code formatting. -- Fixed a bug in generated JavaScript code where functions named `then` would - cause errors when dynamically imported. -- Initialize `git` repo when creating a new project. -- Log messages controlled with `GLEAM_LOG` now print to standard error. -- Log message colours can be disabled by setting the `GLEAM_LOG_NOCOLOUR` - environment variable. -- You can now specify multiple packages when using `gleam add`. -- Bools can now be negated with the `!` unary operator. -- If the compiler version changes we now rebuild the project from scratch on - next build command to avoid issues arising from reading metadata in an old - format (#1547). -- Updated the "Unknown label" error message to match other error messages - (#1548). -- Type holes are now permitted in function arguments and return annotations - (#1519). -- Unused module imports now emit a warning (#1553). -- The error message for failing to parse a multiline clauses without curly - braces has been improved with a hint on how to fix the issue (#1555). -- The error messages for when rebar3 or Erlang are missing from the machine has - been improved with a tip on how to install them (#1567). -- Corrected the hint given with certain int and float binary operator type - errors. -- Add support for `int` and `float` bit string type when compiling to JavaScript. -- Add support for specifying size of integers in a bit string. Supports only exact binaries, - i.e. length is a multiple of 8. -- Fixed compilation of rebar3 based dependencies on Windows. - -## v0.20.1 - 2022-02-24 - -- The type checker has been improved to enable use of the record access syntax - (`record.field`) in anonymous functions passed into higher order functions - without additional annotations. - -## v0.20.0 - 2022-02-23 - -[Release Blog Post](https://gleam.run/news/gleam-v0.20-released/) - -- New projects are created with `gleam_stdlib` v0.20. - -## v0.20.0-rc1 - 2022-02-20 - -- Type unification errors involving user annotated types now refer to the names - specified by the user instead of internal rigid-type ids. -- The build tool now validates that listed licenses are valid SPDX expressions. -- A WebAssembly version of the compile is now available for use in JavaScript - and other WebAssembly environments. -- New projects include Hex badges and a link to Hexdocs. -- Enhance type mismatch errors in the presence of try. -- Enhance type mismatch error for an inconsistent try. -- Enhance type mismatch error for pipe expressions to show the whole pipeline - and not only its first line. -- Fixed a bug where sometimes type variable could be reused result in incorrect - non-deterministic type errors. -- Built in support for the Mix build tool has been removed. The `mix_gleam` - plugin is to be used instead. -- Introduce a limited form of exhaustiveness checking for pattern matching - of custom types, which only checks that all constructor tags are covered - at the top level of patterns. -- The `ebin` directory is now copied to the build directory for rebar3 managed - dependencies if present before compilation. -- The format used by the formatter has been improved. -- Package names in `gleam.toml` are validated when the config is read. -- The `priv` directory is linked into the build directory for Gleam projects - managed by the build tool. -- Fixed a bug where type errors from pipes could show incorrect information. -- Fixed a bug where types could not be imported if they had the same name as a - value in the prelude. - -## v0.19.0 - 2022-01-12 - -Dedicated to the memory of Muhammad Shaheer, a good and caring man. - -[Release Blog Post](https://gleam.run/news/gleam-v0.19-released/) - -## v0.19.0-rc4 - 2022-01-10 - -- New projects are created with `gleam_stdlib` v0.19 and `gleeunit` v0.6. -- Fixed a bug where external functions could be specified with the wrong module - name in generated Erlang when imported from a nested module in another - package. -- Fixed a bug where warnings wouldn't get printed. - -## v0.19.0-rc3 - 2022-01-07 - -- Fixed a bug where precompiled packages would fail to compile due to Erlang - files being compiled twice concurrently. - -## v0.19.0-rc2 - 2022-01-06 - -- Erlang modules are now compiled in a multi-core fashion. -- New projects are created with `erlef/setup-beam` v1.9.0 instead of - `gleam-lang/setup-erlang` and `gleam-lang/setup-gleam`. -- Fixed a bug where tail call optimisation could generate incorrect code when - the function has argument names that are JavaScript keywords. -- Fixed a bug where the build would continue when dependency packages failed to - compile. -- Fixed a bug where `include` directories would not be accessible by the Erlang - compiler during Gleam compilation. - -## v0.19.0-rc1 - 2022-01-03 - -- The build tool now supports the JavaScript target. The target can be specified - in either `gleam.toml` or using the `--target` flag. -- The `gleam check` command has been introduced for rapidly verifying the types - of Gleam code without performing codegen. -- `true` and `false` can no longer be used as pattern matching variables, to - avoid accidental uses of incorrect syntax that is popular in other languages. - An error will hint about using Gleam's `True` and `False` values instead. -- You can now remove build artifacts using the new `gleam clean` command. -- The `compile-package` can now generate `package.app` files and compile source - modules to `.beam` bytecode files. -- The flags that `compile-package` accepts have changed. -- Published Hex packages now include precompiled Erlang files. -- Erlang record headers are now written to the `include` directory within the - package build directory. -- The format used by the formatter has been improved. -- Fixed a bug where tail recursion could sometimes generated incorrect - JavaScript code. -- Performance of code generators has been slightly improved. -- Allow the record in a record expansion to be an expression that returns a - record. -- Fixed a bug where external function module names would not be escaped - correctly if they contained special characters and were assigned to a - variable. -- A helpful error message is shown if Erlang is not installed. - -## v0.18.2 - 2021-12-12 - -- Erlang applications are now automatically started when the VM is started by - `gleam run` and `gleam test`. - -## v0.18.1 - 2021-12-12 - -- Fixed a bug where pipe expressions in record updates and operator expressions - could generate incorrect Erlang code. -- The `priv` directory is now copied to the output directory for rebar3 packages - prior to compilation. This is required for some packages to compile. -- Fixed a bug where deps that fail to compile would be skipped when compilation - would next be attempted, resulting the project being in an invalid state. - -## v0.18.0 - 2021-12-06 - -[Release Blog Post](https://gleam.run/news/gleam-v0.18-released/) - -- New projects now include `gleeunit`. - -## v0.18.0-rc3 - 2021-12-05 - -- URL format in gleam.toml is now validated. -- The `gleam deps list` command has been added. -- Fixed a bug where changing requirements in `gleam.toml` would not cause deps - to be re-resolved. -- Fixed a bug where locked deps would cause incompatible package requirements to - be discarded. -- Development dependencies are now included in the applications listed in the - generated OTP `.app` file. -- `gleam.toml` now includes an `erlang.extra_applications` key to specify extra - OTP applications that need to be started. - -## v0.18.0-rc2 - 2021-11-26 - -- Fixed a bug where OTP .app files would be generated with invalid syntax. -- Removed extra whitespace from newly generated projects. - -## v0.18.0-rc1 - 2021-11-25 - -- Gleam can now compile Gleam projects. -- Gleam can now run tests with the `gleam eunit` command. -- Gleam can now run programs with the `gleam run` command. -- Gleam can now run an Erlang shell with the `gleam shell` command. -- Gleam can now resolve package versions for a Gleam project's dependency tree. -- Gleam can now download Hex packages. -- Gleam can now build dependency packages that are managed using Gleam or - rebar3. -- Gleam is now the default build tool for new projects. -- The template names for `gleam new` have been changed. -- Fixed a bug where the error message for a record update with an unknown field - would point to all the fields rather than the unknown one. -- Improved styling for inline code in generated documentation. -- New projects use v0.18 of the stdlib. - -## v0.17.0 - 2021-09-20 - -[Release Blog Post](https://gleam.run/news/gleam-v0.17-released/) - -- Functions now get special handling when being printed from JavaScript. - -## v0.17.0-rc2 - 2021-09-19 - -- Errors thrown when no case clause or assignment pattern matches the subject - value now include more debugging information when targeting JavaScript. -- New projects are generated using `gleam_stdlib` v0.17.1. - -## v0.17.0-rc1 - 2021-09-11 - -- Redesigned the Gleam prelude to be a module of core classes when compiling to - JavaScript. This improves the resulting generated code and makes debugging and - interop easier. -- Projects without rebar3 can be generated using the `gleam-lib` template. -- JavaScript modules are imported using a camel case variable name to avoid name - collisions with variables. -- Pipelines now use assignments in the generated code in order to preserve the - order of any side effects. -- Fixed a bug where the compiler would crash rather than raise an error if a - project contained a single module and attempted to import another. -- Special variable naming has been made more consistent in rendered Erlang and - JavaScript. -- Conditional compilation can now be used to have different code within a module - when compiling to a specific target. -- Fixed a bug where `todo` caused values not to be returned in JavaScript. -- Fixed a bug where multiple discarded function arguments generated invalid - JavaScript. -- Fixed a bug where using JavaScript reserved words as function argument names - caused generated invalid JavaScript. -- Fixed a bug where a case expression of just a catch-all pattern generated - invalid JavaScript. -- Fixed a bug where the formatter would incorrectly render extra newlines below - try expressions. -- Fixed a bug where tail recursive functions with arguments with the same name - as JavaScript reserved words generated the wrong JavaScript. -- Fixed a bug where list equality would be incorrectly reported in JavaScript. -- Multiple subjects are now supported for case expressions in JavaScript. -- Fixed a bug where matching using a Bool or Nil literal as the subject for a - case expression would produce invalid code when compiling to JavaScript. -- Unsupported feature error messages now include file path and line numbers for - debugging. -- Bit string literals with no segment options or just the `bit_string`, `utf8` - or `utf8_codepoint` options can be constructed when compiling to JavaScript. -- The format of generated JavaScript has been improved. -- Fixed a bug where rendered JavaScript incorrectly incremented variables when - reassigned in patterns. -- Added `eval` and `arguments` to JavaScript reserved words. -- Support for the deprecated `tuple(x, y, ...)` syntax has been removed in favor - of the more concise (`#(x, y, ...)`). Use `gleam format` with the previous - version of the compiler to auto-migrate. -- New OTP projects are generated using `gleam_otp` v0.1.6. -- Fixed a bug where the equality operators could return the incorrect value for - records when compiling to JavaScript. -- Fixed a bug where `todo` could sometimes render invalid JavaScript when used - as an expression in the generated code. -- An error is now emitted if the list spread syntax is used with no prepended - elements `[..xs]`. -- Fixed a bug where type errors inside piped expressions would be incorrectly be - reported as being an incorrect usage of the pipe operator. -- Gleam modules with no public exports no longer render private members in - Erlang. -- Fixed a bug where discard variables used in assert assignments would generate - invalid Erlang code. -- Fixed a bug where some expressions as case subjects would generate invalid - JavaScript code. -- Fixed a bug where some assignments as the final expression in a function would - not return the correct value in JavaScript. -- Gleam packages imported in JavaScript now have the path prefix - `gleam-packages`. This can be served from your web server or aliased in your - `package.json` for NodeJS projects. -- Fixed a bug where the type checker would fail to generalise some type - variables, causing module metadata writing to fail. -- Fixed a bug where tail call optimisation when compiling to JavaScript could - result in incorrect code. -- Fixed a bug where variable names could be rendered incorrectly in closures. -- An error is now emitted if alternative patterns fail to define all the - variables defined by the first pattern. -- New projects are generated using `gleam_stdlib` v0.17.0. -- New projects are generated using `gleam_otp` v0.2.0. - -## v0.16.1 - 2021-06-21 - -- Values which are being imported more than once in an unqualified fashion now - cause an error to be reported. -- Argument docs for custom type constructors are now rendered in the HTML - documentation. -- Patterns can be used with `try` expressions when compiling to JavaScript. -- Types and record constructors can now be aliased with an uppercase name when - imported. Aliasing them with a lowercase name is no longer permitted. -- Fixed a bug where nested import paths could be rendered incorrectly in - JavaScript. - -## v0.16.0 - 2021-06-17 - -[Release Blog Post](https://gleam.run/news/gleam-v0.16-released/) - -## v0.16.0-rc4 - 2021-06-17 - -- Fixed a bug where if a JavaScript global function was imported as an external - function with the same name the generated code would diverge. - -## v0.16.0-rc3 - 2021-06-17 - -- New projects are generated using `gleam_stdlib` v0.16.0. - -## v0.16.0-rc2 - 2021-06-08 - -- Gleam now supports alternative patterns in case expressions for the JavaScript target. -- The `gleam` prelude module can now be imported when compiling to JavaScript. -- Fixed a bug where the prelude module could not be imported when using the old - build compiler API. -- Fixed a bug where if a JavaScript global function was imported as an external - function with the same name the generated code would diverge. -- Type error messages coming from pipe usage have been improved. - -## v0.16.0-rc1 - 2021-06-04 - -- Gleam can now compile to JavaScript! Specify the `--target javascript` flag to - `gleam compile-package` to use it today. -- A compile time error is now raised when multiple module level constants with - the same name are defined. -- Fixed a bug where declaring a type constructor using reserved erlang keyword - in its fields results in invalid erlang code being generated. -- Fixed a bug where calling a function with discarded labelled arguments - incorrectly results in a compile error. -- Fixed a bug where assert statements return the wrong value. -- The `gleam new` command requires a root folder param, project name is - optional and if not provided the project name will be inferred from - the folder name. -- Generated Erlang record header files now contain Erlang type information. -- New OTP application projects depend on `gleam_otp` v0.1.5. -- The output of the formatter has been improved. - -## v0.15.1 - 2021-05-07 - -- Fixed a bug where blocks that contained try expressions could be formatted - incorrectly. - -## v0.15.0 - 2021-05-06 - -[Release Blog Post](https://gleam.run/news/gleam-v0.15-released/) - -## v0.15.0-rc1 - 2021-05-05 - -- Syntax highlighting of Gleam code in generated HTML documentation has been - improved. -- Fixed a bug where markdown tables in rendered HTML documentation would have - the incorrect background colour on every other row. -- Tuples now have a new, concise syntax variant: `#(x, y, ...)`. Existing code - can be auto-migrated to the new syntax by running `gleam format`. -- Fixed a bug where customt type constructors with Erlang keywords as names - would generate invalid Erlang code. -- Gleam now supports `\e` string escapes. -- Values and types from the prelude can now be used in a qualified fashion by - importing the `gleam` module. -- Empty lists can now be used in constants. -- Compiler performance has been improved when working with lists. -- Compiler performance has been improved when working with sequences of - expressions. -- Assignments using `let` and `assert` are now expressions and no longer require - a following expression in their containing block. They are now themselves - expressions. -- Fixed a bug where tuple indexing could incorrectly claim a tuple is not of - type tuple in some circumstances. -- Glean `new` command now checks if target folder exists, if so it returns - an error. -- A compile time error is now raised if a module is defined with the name `gleam`. -- A compile time error is now raised if a module is defined with the a keyword - in the name. -- New projects are generated using `gleam_stdlib` v0.15.0. -- New projects are generated at v0.1.0. - -## v0.14.4 - 2021-03-27 - -- The Gleam compiler has been updated to compile with the new Rust v1.51.0. -- New project's `gleam.toml` has a comment that shows how to add a - `repository` field. -- New projects no longer include a licence field in `src/$APP.app.src` by - default. - -## v0.14.3 - 2021-03-20 - -- Added an error hint when joining string using the `+` or `+.` operator. -- New projects are created with `setup-erlang` v1.1.2 and Erlang/OTP v23.2. -- Fixed a bug where the compiler would be unable to locate an imported module - if a value from a nested module is used in a qualified fashion. - -## v0.14.2 - 2021-03-02 - -- Project names can now contain numbers. - -## v0.14.1 - 2021-02-27 - -- The error message for binary operators has been given more detail and - hints. -- Fixed a bug where alternative patterns would incorrectly report unused - variables. -- Fixed a bug where private types shadowed shadowed by values would - incorrectly report unused variables. - -## v0.14.0 - 2021-02-18 - -[Release Blog Post](https://gleam.run/news/gleam-v0.14-released/) - -## v0.14.0-rc2 - 2021-02-18 - -- New projects are created with `gleam_stdlib` v0.14.0. - -## v0.14.0-rc1 - 2021-02-14 - -- Gleam now generates Erlang typespecs. -- New projects no longer include a licence file by default. -- New projects can be created using the new `escript` template to generate a - command line tool style program. -- A warning is emitted when a literal value is constructed but not used. -- Automatically generate a link to repository in docs if available. -- Code in HTML documentation is has highlighted syntax. -- Gleam now only supports `\r`, `\n`, `\t`, `\"`, and `\\` string escapes. -- A set of OCI container images are built automatically for each release. -- New compile time checks for invalid bit string literals and patterns have - been added. -- The error messages for syntax errors in names have been improved. -- Fixed a bug where the repo URL would render incorrectly in HTML docs. -- Fixed a bug where piping a block can render invalid Erlang. -- New compile time warnings on unused types, functions and variables. -- The runtime error emitted by the `todo` keyword now carries additional - information. -- The runtime error emitted by the `assert` keyword now carries additional - information. -- Fixed a bug where bit string patterns would not correctly unify with the - subject being pattern matches on. -- Documentation dark mode. -- Fixed a bug where some app.src properties were incorrectly named. -- `--warnings-as-errors` flag added to `gleam build` command. - -## v0.13.2 - 2021-01-14 - -- `ring` dep upgraded to enable compilation on Apple M1 ARM processors. - -## v0.13.1 - 2021-01-13 - -- Fix off-by-one error in message messages. - -## v0.13.0 - 2021-01-13 - -[Release Blog Post](https://gleam.run/news/gleam-v0.13-released/) - -- New Gleam projects use stdlib v0.13.0. - -## v0.13.0-rc2 - 2021-01-12 - -- The `version` property in `gleam.toml` is now optional again. - -## v0.13.0-rc1 - 2021-01-09 - -- Variable names now only have 1st letter capitalized when converted to erlang. -- Records defined in other modules can now be used in module constants. -- Documentation can link from functions, types & constants to their source - code definitions on popular project hosting sites. -- Documentation hosted on HexDocs now has a version selector. -- Fixed a bug where the `app` project template rendered invalid code. -- Newly generated projects use stdlib v0.12.0. -- Named subexpressions in patterns now render correct Erlang. -- The anonymous function syntax now successfully parses with whitespace - between `fn` and `(`. -- Fixed a bug where the formatter would incorrectly remove blocks around some - binary operators. -- Constants can now be defined after they are used in functions -- The parser has been rewritten from scratch, dramatically improving error - messages and compilation times. -- `1-1` and `a-1` are now parsed as `1 - 1` and `a - 1` -- Further information has been added to the error messages when a function - returns the wrong type. -- Further information has been added to the error messages when case clauses - return different types. -- Fixed a bug where imported record constructors without labels used as an - anonymous function generates incorrect Erlang. - -## v0.12.1 - 2020-11-15 - -- The compiler can now discriminate between record access and module access - for shadowed names -- The `new` command will no longer permit projects to be made with names that - clash with Erlang standard library modules. -- The formatter now correctly treats lines of only whitespace as empty. -- The styling of tables in rendered HTML documentation has been improved. -- Rendered HTML documentation has regained its max-width styling. - -## v0.12.0 - 2020-10-31 - -[Release Blog Post](https://gleam.run/news/gleam-v0.12-and-gleam-otp-v0.1-released/) - -## v0.12.0-rc4 - 2020-10-31 - -- The rendered module documentation sidebar can now scroll independently to - the page. -- Application projects now have the correct `mod` value in the generated - `.app.src`. -- Records without fields can now be used in module constants. -- New application projects are now created used Gleam's type safe OTP pulled - from Hex. - -## v0.12.0-rc3 - 2020-10-24 - -## v0.12.0-rc2 - 2020-10-24 - -## v0.12.0-rc1 - 2020-10-24 - -- The utf8, utf16, and utf32 type specifiers are now only available in bit - string construction, matching must be done with the codepoint versions. -- Functions may now be called before they are defined in a module. This - enabled mutually recursive functions! -- Discarded variable names may now include numbers. -- Fixed a bug where discarded variables might generate incorrect Erlang. -- Added support tuple access in clause guards. -- New projects are created with version 1.0.2 of the setup-gleam GitHub - action. -- New application projects are now created used Gleam's type safe OTP. -- Comments are now correctly handled on platforms that use \r\n line endings, - such as Windows. - -## v0.11.2 - 2020-09-01 - -- Fixed a bug where an imported constructor would emit an unused constructor - warning when only used in pattern matching. - -## v0.11.1 - 2020-08-31 - -- The formatter style has been improved to render function type arguments on - a single line when possible, even if the return type will not fit on a - single line. -- The format for printed types in error messages has been improved. -- Fixed a bug where the formatter would strip a constructor pattern spread - when no fields are given. -- Fixed a bug where assigning the result of a block to a variable would - generate incorrect Erlang. -- The formatter style has been improved for function calls that take a single - block as an argument. -- Reserved words are no longer incorrectly permitted as project names. - -## v0.11.0 - 2020-08-28 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.11-released/) - -## v0.11.0-rc3 - 2020-08-27 - -- Bit strings now support non-literal strings as segment values. -- Fixed a bug where Erlang variables could be generated with incorrect names - when defining an anonymous function. - -## v0.11.0-rc2 - 2020-08-24 - -- The formatter style has been improved to render some single argument calls - in a more compact style. - -## v0.11.0-rc1 - 2020-08-22 - -- Field access now works before the custom type is defined. -- The error message returned by the compiler when the user tries to use unknown - labelled arguments now handles multiple labels at once, and does not suggest - labels they have already supplied. -- The formatter style has been improved to use a trailing comma on imports - broken over multiple lines. -- The formatter style has been improved to wrap lists and bit strings over as - few lines as possible if the elements are Ints, Floats, or Strings. -- The formatter style has been improved to preserve comments on labelled - call arguments. -- The formatter style has been improved to preserve empty lines in assignments. -- The performance of the formatter has been improved. -- Records can be updated using the spread syntax. A warning is emitted if no - fields are updated when using this syntax. -- Fixed a bug where type parameters can leak between different type - definitions in a module. -- Markdown tables, footnotes, strikethroughs, and tasklists are now supported - in documentation. -- Fixed a bug where generic types may be incorrectly unified. -- Ints and floats can now be written with underscores for clarity. -- The warning for a `todo` now includes the required type of the - not-yet-implemented expression. -- Holes can be used in type annotations to specify part of a type, leaving the - rest for inference. -- The incorrect arity error now prints any missing labelled arguments. -- Fixed a bug where Erlang variables could be generated with incorrect names - when directly calling an anonymous function. -- A warning is emitted when a type is imported or created but not used. -- Fixed a bug where Erlang variables names could clash when rebinding - variables while similarly named variables ending in a number are in scope. -- Fixed a bug in the pretty printer which prevented the formatter from - rendering sub-expressions in a single line when later code would not fit on - the same line. -- The formatter style has been improved to render some single argument calls - in a more compact style. -- Gleam now supports hex, octal, and binary literals. -- Rebar3 hex packages now include `gleam.toml` and `gen`. -- Newly generated projects use stdlib v0.11.0. - -## v0.10.1 - 2020-07-15 - -- Fixed a bug where the compiler failed to return an error when type checking - a tuple with the wrong arity in a pattern. -- The error message for a duplicate module member now shows the location of - both definitions. -- Fix compiler bug where labelled arguments were being reordered incorrectly. - -## v0.10.0 - 2020-07-01 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.10-released/) - -- Newly generated projects use stdlib v0.10.1. -- Fixed a bug where discards inside bit string patterns generated invalid - code. - -## v0.10.0-rc2 - 2020-06-30 - -- Fixed a bug where variables names would be incorrectly generated when using - alternative patterns. - -## v0.10.0-rc1 - 2020-06-29 - -- Single letter module names are now permitted. -- Added support for bit string syntax. -- Support for the deprecated list prepend syntax has been removed. -- Added module level constants that are inlined at compile time. -- Public module level constants generate documentation. -- The formatter style has been improved to wrap and sort imports. -- The formatter now permits comments at the end of module function bodies. -- The formatter now skips files that match patterns defined in ignore files - such as .gitignore and .ignore. -- Error message diagnostic code previews for type errors when using the the - pipe operator have been made more accurate. -- Added support for list literals in clause guards. -- Fixed bug when reassigning a variable inside a case clause with alternative - patterns. -- Todos can now take an optional label. - -## v0.9.1 - 2020-06-12 - -- Fixed a bug where binary operators may lose required `{ }`s when formatted. - -## v0.9.0 - 2020-06-01 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.9-released/) - -- Newly generated projects use stdlib v0.9.0. -- Additional information is printed to the console when generating HTML - documentation from Gleam code. -- Fixed a bug where blocks on either side of a binary operator would be - rendered without `{ }`. - -## v0.9.0-rc1 - 2020-05-26 - -- The formatter style has been improved. -- Numbers are now permitted in module names. -- Emitted Erlang code correctly adds parentheses around binary subexpressions - to preserve precedence. -- Record names and fields are now escaped in `.hrl` files if they conflict - with Erlang reserved words -- Annotations are now supported on `let` and `assert` expressions -- Formatter now accepts comments for the fields of a custom type's constructors -- Added opaque custom types, which have constructors that cannot be accessed - from outside their own modules. -- Additional (arbitrary) markdown documentation pages can now be added and - built with `docs build`. -- Fix code generation when calling functions returned through either record - or tuple access -- Add lookup for Gleam source code in Mix's `deps` directory. -- Newly generated Gleam projects use the GitHub action - `gleam-lang/setup-erlang` v1.1.0. -- Added support for custom type record literals in guards. -- Type variables are now correctly preserved within nested scopes. - -## v0.8.1 - 2020-05-19 - -- The formatter now correctly handles unicode comments. - -## v0.8.0 - 2020-05-07 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.8-released/) - -- The `docs build`, `docs publish`, and `docs remove` commands can be used to - compile HTML documentation locally, publish them to HexDocs, and remove them - from HexDocs respectively. -- Type error reporting has been improved when using the pipe operator. -- Newly generated projects use stdlib v0.8.0. -- The compiler can now emit warnings. Currently there are warnings for using - the old '|' syntax in lists and for todos. -- Will give a clearer error when a function given as an argument to another - function doesn't match the type of the parameter. -- Fixed bug where imported type constructors had the incorrect arity. -- Fixed bug where a doing an unqualified import of a type constructor and - giving it an alias would use the wrong name if it contained any values. -- Fixed a bug trying to access an imported constructor which contained values. -- Fixed a compiler crash that occurred when trying to unify a tuple with something - other than another tuple or a variable. -- Added support for tuple literals in guards. - -## v0.8.0-rc1 - 2020-04-28 - -- Strings are now encoded as utf8 binaries in the generated Erlang. -- HTML documentation can now be generated from Gleam code by running `gleam build --doc`. -- Gleam code can be formatted using the `gleam format` command. -- The pipe operator `|>` will now attempt to insert the left hand side as the - first argument to the right hand side if the right hand side is a call, - removing the need for function capture boilerplate. -- A `record.label` syntax can now be used to access the fields of a custom - type that have a single record variant. -- Anonymous functions can now have return type annotations. -- There is a `todo` keyword for type checking functions that have not yet been - implemented. -- Tuples can be indexed into using the `var.1` syntax. -- `>`, `>=`, `<`, and `<=` operators are now supported in case clause guards - and can be used to check the ordering of integers. -- `>.`, `>=.`, `<.`, and `<=.` operators are now supported in case clause - guards and can be used to check the ordering of floats. -- The list prepend syntax is now `[x, ..y]`. The old `[x | y]` syntax is - deprecated but will continue to work for now. The formatter will rewrite the - old syntax to the new. -- Add new assert syntax for binding variables `assert Ok(x) = result`. In the - future this will allow you to use a pattern that does not match all values. -- Added support for int and float literals in guards. -- Color codes are now only emitted in error output for interactive terminal - sessions. -- Added a new `..` syntax for discarding the remaining fields of a record. -- Using the same variable name multiple times in the same pattern will now - raise an error. -- Discard can now be omitted in list tails in patterns, ie `[x, ..]` is the - same as `[x, .._]`. The former is the preferred version and is emitted by the - formatter. - -## v0.7.1 - 2020-03-03 - -- Projects generated with `gleam new` use `stdlib` version 0.7.0. - -## v0.7.0 - 2020-03-01 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.7-released/) - -## v0.7.0-rc1 - 2020-02-28 - -- Type aliases can be defined to give concise names to frequently used types. -- Case expression clauses may have guards which can be used to require - equality between specified variables in order for the clause to match. -- Case expression clauses may have alternative patterns, enabling one clause - to match for multiple different possible patterns. -- Types may now be used before they are defined within their defining module. -- Fixed a bug where import paths would not be correctly resolved on Windows. -- Added job to create precompiled binary for 64-bit Windows when releasing. -- `gleam new` now creates a project that uses `actions/checkout@v2.0.0` in its - GitHub actions workflow. -- Labelled argument in functions may now be discarded by prefixing the name - with an underscore, like unlabelled arguments. -- Sub-patterns can have names assigned to them within a pattern using the `as` - keyword. -- The format of compiler error messages printed to the console has been - improved by upgrading to a newer version of the codespan-reporting library. -- Type variables in the given and expected types will now be printed with the - same name in type error messages if they are equivalent. -- A friendly error message is rendered when a case expression clause has the - incorrect number of patterns for the subjects. -- A friendly error message is rendered when a .gleam file cannot be read. -- A friendly error message is rendered when the `gleam new` command fails to - write the new project to the file system. -- A friendly error message is rendered when there is a cycle formed by module - imports. -- Top level types are now printed in error messages for type parameter mismatches. -- The `gen` directory is now deleted before each compilation. -- `gleam new` now includes installation instructions for Hex packages in the - generated README. -- `gleam new` now accepts a `--description` flag for including a description of - the project in the README and `.app.src` file. -- Fixed a bug where variable names would be incorrectly generated in some - situations when variable names are reused during and after a case - expression. -- Performance of the Erlang code generator has been improved by removing some - vector allocations. -- An error is emitted when multiple types with the same name are defined in or - imported into a module. - -## v0.6.0 - 2019-12-25 🎄 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.6-released/) - -- Function capture syntax now supports labelled arguments. - -## v0.6.0-rc1 - 2019-12-23 - -- Syntax for defining structs and enums have been unified into a singular - custom type definition statement. Instances of these custom types are called - records. -- Anonymous structs have been renamed tuples. -- Values and types can be given a new name when imported in the unqualified - fashion using the `import mod.{value as name}` syntax. -- An error will be emitted if multiple values constructors are defined with - the same name in a module. - -## v0.5.1 - 2019-12-23 - -- Fixed a bug where invalid Erlang would be generated when using a local - private function as a value. - -## v0.5.0 - 2019-12-16 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.5-released/) - -- Enum constructor arguments can now be labelled, allowing arguments to be - given by name at the call site. -- An Erlang header file with a record definition is generated for each Gleam - struct defined. -- `gleam new` creates a project at v1.0.0. -- Function calls are now properly escaped when the function name conflicts - with an Erlang keyword. -- References to unqualified imported functions now generate correct Erlang - code. -- Fixed a bug where variable rebinding would generate incorrect code in some - case expressions. -- Fixed a bug where variable rebinding of function arguments would generate - incorrect code. - -## v0.5.0-rc1 - 2019-11-26 - -- Function arguments can be labelled, allowing arguments to be given by name - at the call site. -- `case` expressions now accept multiple subjects, enabling pattern matching - on multiple values simultaneously. -- Values and types can be imported from modules and references in an - unqualified fashion. -- Named structs now have their name as the first element in the generated - Erlang code. This enabled easier use from Erlang by defining records for - them, as well as slightly clearer printf debugging. -- Anonymous structs have been introduced, serving as a quick and generic - alternative to declared structs and as a format for interop with Erlang - tuples. -- `gleam new` now accepts a `--template` flag to generate different styles of - project. An OTP application template has been added alongside the existing - OTP library template. -- `gleam new` now creates configuration for GitHub Actions, making Gleam - projects ready for continuous integration out of the box. -- The syntax for defining enums, case expressions, and blocks has been changed - to a syntax closer to that found in the C family of languages. -- The source code preview for functions that return a type incompatible with - the functions annotations has been improved to be more precise. -- A helpful error message is rendered if an enum field contains a generic type - that has not been declared. -- A bug has been fixed in which type mismatch errors originating from pattern - matching would sometimes display the incorrect expected type. - -## v0.4.2 - 2019-10-22 - -- Fixed a crash when an incorrect number of labelled struct arguments are - given. -- Fixed a struct labelled argument being incorrect reported as already given. - -## v0.4.1 - 2019-09-29 - -- Struct types with parameterised fields are now registered with the correct - number of type parameters. - -## v0.4.0 - 2019-09-19 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.4-released/) - -- The struct data type has be introduced. Structs are pre-declared user - defined data types with named fields and constant access time. -- The map and tuple data types has been removed, replaced by the struct data - type. -- The generated code no longer contains export statements if no functions are - exported from a module. -- Comparison operators have been specialised to operate only on Ints. -- The `>.` `>=.` `<.` and `<=.` comparison operators have been added for - comparing Floats. -- It is now an error to export an enum which has a constructor that takes a - private type as an argument. -- The error messages for defining multiple modules with the same name and for - importing test modules into application code have been improved. -- Numbers are now permitted in type names and constructors. -- The `Nil` constructor will no longer erroneously be of type `Int`. - -## v0.3.0 - 2019-08-08 - -[Release Blog Post](https://lpil.uk/blog/gleam-v0.3-released/) - -- New project structure can be generated with the `gleam new` command. -- Functions can be annotated with their argument and return types. This may be - used to restrict the function to a less general type than inferred by the - compiler, or purely for documentation purposes. -- External function names and their target functions are now escaped in the - generated code if they collide with Erlang keywords such as `catch` or `or`. -- Type error arising from the arguments of function calls have more accurate - error diagnostics. -- Precompiled Gleam binaries are now available on the GitHub release page. -- Precompiled Docker images containing the Gleam binary are now available on - DockerHub. -- The formatting of the Erlang code rendered by the compiler has been altered - to improve legibility. -- A helpful error message is now rendered if the shorthand anonymous function - syntax is used with too many underscores. -- A helpful error message is now rendered when attempting to import an unknown - module. - -## v0.2.0 - 2019-06-25 - -- Modules can now live within namespaces such as `my_app/user/profile`. -- The name of the variable created can be specified when importing a module - using the `import my_mod as name` syntax. -- Function names and atoms are now escaped in the generated code if they - collide with Erlang keywords such as `catch` or `or`. -- There is a shorthand syntax for prepending multiple elements to a list. - `[1, 2, 3 | my_list]` - -## v0.1.2 - 2019-05-12 - -- Types containing more than 26 type variables will no longer render with - invalid type variable names. -- Types in error messages no longer have extra indentation that increases as - the type gets larger. -- There is a new type `Nil` which is occupied by a single value (`Nil`). This - type is used to represent the absence of a value and is commonly used with - `Result` to model a value that is either present (`Ok(value)`) or absent - (`Error(Nil)`). -- Zero arity enum constructors now generate the correct Erlang when used in - modules other than the one they are defined in. +### Language Server -## v0.1.1 - 2019-04-28 +- When removing unused imports, the entire line is removed if it would otherwise be left blank. -- Error messages now display the path of the file containing the problem. -- Maps and modules with erroneous extra fields now have a custom error - message. -- Rows with tails that are unbound type variables are now correctly unified in - the type system. This fixes a bug in which maps and modules may sometimes - fail to type check when there is no error. +### Bug Fixes -## v0.1.0 - 2019-04-15 +- Fixed [RUSTSEC-2021-0145](https://rustsec.org/advisories/RUSTSEC-2021-0145) by + using Rust's `std::io::IsTerminal` instead of the `atty` library. + ([Pi-Cla](https://github.com/Pi-Cla)) -[Release Blog Post](https://lpil.uk/blog/hello-gleam/) +- Fixed the generated `mod` property in the Erlang application file when using the + `application_start_module` property in `gleam.toml`. + ([Alex Manning](https://github.com/rawhat)) -- Initial release! +- Fixed a bug where using some reserved keywords would result in confusing error + messages. ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) From d41aa60cf773347c239a314be2b3a5c675170d77 Mon Sep 17 00:00:00 2001 From: Milco Kats <milcokats@gmail.com> Date: Wed, 17 Apr 2024 20:37:29 +0200 Subject: [PATCH 10/11] correct changelog --- CHANGELOG.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9db0e25ff0c..5444c4d6f9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,9 @@ - Empty case expressions are no longer parse errors and will instead be exhaustiveness errors. ([Race Williams](https://github.com/raquentin)) +- Introduced some enhancements to the tree traversal algorithm, such that + less work needs to be done in order to find the correct node. + ### Formatter - Redundant alias names for imported modules are now removed. @@ -44,10 +47,6 @@ import gleam/result ``` -### Language Server - -- When removing unused imports, the entire line is removed if it would otherwise be left blank. - ### Bug Fixes - Fixed [RUSTSEC-2021-0145](https://rustsec.org/advisories/RUSTSEC-2021-0145) by From ff303686a9efaf6fedfe404fe004137845b89ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEclismic=E2=80=9D?= <“milcokats”@gmail.com> Date: Sat, 20 Apr 2024 07:34:45 +0200 Subject: [PATCH 11/11] fix vulnerabilities cargo --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20c476e4183..0f222ec8df2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1887,9 +1887,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring 0.17.8",

    (1ky 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꽼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 AN&o-= literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src b/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src new file mode 100644 index 00000000000..e3f22c0f0a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/src/glerm.app.src @@ -0,0 +1,11 @@ +{application, glerm, [ + {vsn, "0.1.0"}, + {applications, [gleam_community_ansi, + gleam_erlang, + gleam_otp, + gleam_stdlib, + gleeunit]}, + {description, "A terminal wrapper for Gleam"}, + {modules, [glerm]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.erl b/test-community-packages-javascript/build/packages/glerm/src/glerm.erl new file mode 100644 index 00000000000..09ab08df23d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/src/glerm.erl @@ -0,0 +1,397 @@ +-module(glerm). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([selector/0, clear/0, draw/1, start_listener_spec/1, start_listener/2, print/1, size/0, move_to/2, enable_raw_mode/0, disable_raw_mode/0, enter_alternate_screen/0, leave_alternate_screen/0, enable_mouse_capture/0, disable_mouse_capture/0]). +-export_type([modifier/0, key_code/0, mouse_button/0, mouse_event/0, focus_event/0, event/0, listener_message/1, listener_spec/2]). + +-type modifier() :: shift | alt | control. + +-type key_code() :: {character, binary()} | + enter | + backspace | + left | + right | + down | + up | + unsupported. + +-type mouse_button() :: mouse_left | mouse_right | mouse_middle. + +-type mouse_event() :: {mouse_down, + mouse_button(), + gleam@option:option(modifier())} | + {mouse_up, mouse_button(), gleam@option:option(modifier())} | + {drag, mouse_button(), gleam@option:option(modifier())} | + moved | + scroll_down | + scroll_up. + +-type focus_event() :: lost | gained. + +-type event() :: {focus, focus_event()} | + {key, key_code(), gleam@option:option(modifier())} | + {mouse, mouse_event()} | + {resize, integer(), integer()} | + {unknown, binary(), gleam@dynamic:dynamic()}. + +-type listener_message(GUP) :: {term, event()} | {user, GUP}. + +-type listener_spec(GUQ, GUR) :: {listener_spec, + fun(() -> {GUQ, gleam@option:option(gleam@erlang@process:selector(GUR))}), + fun((listener_message(GUR), GUQ) -> gleam@otp@actor:next(GUQ))}. + +-spec decode_atom(binary(), GUW) -> fun((gleam@dynamic:dynamic()) -> {ok, GUW} | + {error, list(gleam@dynamic:decode_error())}). +decode_atom(Val, Actual) -> + Real_atom = erlang:binary_to_atom(Val), + Decode = gleam@function:compose( + fun gleam@erlang@atom:from_dynamic/1, + fun(Maybe_atom) -> _pipe = Maybe_atom, + gleam@result:then( + _pipe, + fun(Decoded) -> case Decoded =:= Real_atom of + true -> + {ok, Real_atom}; + + false -> + {error, + [{decode_error, + Val, + erlang:atom_to_binary(Decoded), + []}]} + end end + ) end + ), + fun(Msg) -> _pipe@1 = Decode(Msg), + gleam@result:replace(_pipe@1, Actual) end. + +-spec modifier_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, + gleam@option:option(modifier())} | + {error, list(gleam@dynamic:decode_error())}). +modifier_decoder() -> + Decode_some = decode_atom( + <<"some"/utf8>>, + fun(Field@0) -> {some, Field@0} end + ), + gleam@dynamic:any( + [decode_atom(<<"none"/utf8>>, none), + gleam@function:compose( + gleam@dynamic:tuple2( + Decode_some, + decode_atom(<<"shift"/utf8>>, shift) + ), + fun(_capture) -> + gleam@result:replace(_capture, {some, shift}) + end + ), + gleam@function:compose( + gleam@dynamic:tuple2( + Decode_some, + decode_atom(<<"alt"/utf8>>, alt) + ), + fun(_capture@1) -> + gleam@result:replace(_capture@1, {some, alt}) + end + ), + gleam@function:compose( + gleam@dynamic:tuple2( + Decode_some, + decode_atom(<<"control"/utf8>>, control) + ), + fun(_capture@2) -> + gleam@result:replace(_capture@2, {some, control}) + end + )] + ). + +-spec keycode_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, key_code()} | + {error, list(gleam@dynamic:decode_error())}). +keycode_decoder() -> + gleam@dynamic:any( + [begin + _pipe = gleam@dynamic:tuple2( + decode_atom( + <<"character"/utf8>>, + fun(Field@0) -> {character, Field@0} end + ), + fun gleam@dynamic:string/1 + ), + gleam@function:compose( + _pipe, + fun(Maybe_pair) -> case Maybe_pair of + {ok, {_, Value}} -> + {ok, {character, Value}}; + + {error, Err} -> + {error, Err} + end end + ) + end, + decode_atom(<<"enter"/utf8>>, enter), + decode_atom(<<"backspace"/utf8>>, backspace), + decode_atom(<<"left"/utf8>>, left), + decode_atom(<<"right"/utf8>>, right), + decode_atom(<<"down"/utf8>>, down), + decode_atom(<<"up"/utf8>>, up), + decode_atom(<<"unsupported"/utf8>>, unsupported)] + ). + +-spec mouse_button_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, + mouse_button()} | + {error, list(gleam@dynamic:decode_error())}). +mouse_button_decoder() -> + gleam@dynamic:any( + [decode_atom(<<"mouse_left"/utf8>>, mouse_left), + decode_atom(<<"mouse_right"/utf8>>, mouse_right), + decode_atom(<<"mouse_middle"/utf8>>, mouse_middle)] + ). + +-spec mouse_event_decoder() -> fun((gleam@dynamic:dynamic()) -> {ok, + mouse_event()} | + {error, list(gleam@dynamic:decode_error())}). +mouse_event_decoder() -> + gleam@dynamic:any( + [begin + _pipe = gleam@dynamic:tuple3( + decode_atom( + <<"mouse_down"/utf8>>, + fun(Field@0, Field@1) -> {mouse_down, Field@0, Field@1} end + ), + mouse_button_decoder(), + modifier_decoder() + ), + gleam@function:compose( + _pipe, + fun(Maybe_triple) -> case Maybe_triple of + {ok, {_, Button, Modifier}} -> + {ok, {mouse_down, Button, Modifier}}; + + {error, Err} -> + {error, Err} + end end + ) + end, + begin + _pipe@1 = gleam@dynamic:tuple3( + decode_atom( + <<"mouse_up"/utf8>>, + fun(Field@0, Field@1) -> {mouse_up, Field@0, Field@1} end + ), + mouse_button_decoder(), + modifier_decoder() + ), + gleam@function:compose( + _pipe@1, + fun(Maybe_triple@1) -> case Maybe_triple@1 of + {ok, {_, Button@1, Modifier@1}} -> + {ok, {mouse_up, Button@1, Modifier@1}}; + + {error, Err@1} -> + {error, Err@1} + end end + ) + end, + begin + _pipe@2 = gleam@dynamic:tuple3( + decode_atom( + <<"drag"/utf8>>, + fun(Field@0, Field@1) -> {drag, Field@0, Field@1} end + ), + mouse_button_decoder(), + modifier_decoder() + ), + gleam@function:compose( + _pipe@2, + fun(Maybe_triple@2) -> case Maybe_triple@2 of + {ok, {_, Button@2, Modifier@2}} -> + {ok, {drag, Button@2, Modifier@2}}; + + {error, Err@2} -> + {error, Err@2} + end end + ) + end, + decode_atom(<<"moved"/utf8>>, moved), + decode_atom(<<"scroll_down"/utf8>>, scroll_down), + decode_atom(<<"scroll_up"/utf8>>, scroll_up)] + ). + +-spec selector() -> gleam@erlang@process:selector(event()). +selector() -> + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@4 = gleam@erlang@process:selecting_record2( + _pipe, + erlang:binary_to_atom(<<"focus"/utf8>>), + fun(Inner) -> _pipe@1 = Inner, + _pipe@2 = (gleam@dynamic:any( + [decode_atom(<<"gained"/utf8>>, gained), + decode_atom(<<"lost"/utf8>>, lost)] + ))(_pipe@1), + _pipe@3 = gleam@result:map( + _pipe@2, + fun(Field@0) -> {focus, Field@0} end + ), + gleam@result:unwrap(_pipe@3, {unknown, <<"focus"/utf8>>, Inner}) end + ), + _pipe@5 = gleam@erlang@process:selecting_record3( + _pipe@4, + erlang:binary_to_atom(<<"key"/utf8>>), + fun(First, Second) -> + Key_code = (keycode_decoder())(First), + Modifier = (modifier_decoder())(Second), + case {Key_code, Modifier} of + {{ok, Code}, {ok, Mod}} -> + {key, Code, Mod}; + + {_, _} -> + {unknown, + <<"key"/utf8>>, + gleam@dynamic:from([First, Second])} + end + end + ), + _pipe@9 = gleam@erlang@process:selecting_record2( + _pipe@5, + erlang:binary_to_atom(<<"mouse"/utf8>>), + fun(Inner@1) -> _pipe@6 = Inner@1, + _pipe@7 = (mouse_event_decoder())(_pipe@6), + _pipe@8 = gleam@result:map( + _pipe@7, + fun(Field@0) -> {mouse, Field@0} end + ), + gleam@result:lazy_unwrap( + _pipe@8, + fun() -> {unknown, <<"mouse"/utf8>>, Inner@1} end + ) end + ), + gleam@erlang@process:selecting_record3( + _pipe@9, + erlang:binary_to_atom(<<"resize"/utf8>>), + fun(First@1, Second@1) -> + Columns = gleam@dynamic:int(First@1), + Rows = gleam@dynamic:int(Second@1), + case {Columns, Rows} of + {{ok, Col}, {ok, Rows@1}} -> + {resize, Col, Rows@1}; + + {_, _} -> + {unknown, + <<"resize"/utf8>>, + gleam@dynamic:from([First@1, Second@1])} + end + end + ). + +-spec clear() -> nil. +clear() -> + glerm_ffi:clear(). + +-spec draw(list({integer(), integer(), binary()})) -> {ok, nil} | {error, nil}. +draw(Field@0) -> + glerm_ffi:draw(Field@0). + +-spec start_listener_spec(listener_spec(any(), GVF)) -> {ok, + gleam@erlang@process:subject(listener_message(GVF))} | + {error, gleam@otp@actor:start_error()}. +start_listener_spec(Spec) -> + gleam@otp@actor:start_spec( + {spec, + fun() -> + Pid = erlang:self(), + _assert_subject = (erlang:element(2, Spec))(), + {State, User_selector} = case _assert_subject of + {_, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"glerm"/utf8>>, + function => <<"start_listener_spec"/utf8>>, + line => 314}) + end, + Term_selector = begin + _pipe = selector(), + gleam_erlang_ffi:map_selector( + _pipe, + fun(Field@0) -> {term, Field@0} end + ) + end, + Selector = begin + _pipe@1 = User_selector, + _pipe@4 = gleam@option:map( + _pipe@1, + fun(User) -> _pipe@2 = User, + _pipe@3 = gleam_erlang_ffi:map_selector( + _pipe@2, + fun(Field@0) -> {user, Field@0} end + ), + gleam_erlang_ffi:merge_selector( + Term_selector, + _pipe@3 + ) end + ), + gleam@option:unwrap(_pipe@4, Term_selector) + end, + gleam@erlang@process:start( + fun() -> glerm_ffi:listen(Pid) end, + true + ), + {ready, State, Selector} + end, + 500, + erlang:element(3, Spec)} + ). + +-spec start_listener(GVL, fun((event(), GVL) -> gleam@otp@actor:next(GVL))) -> {ok, + gleam@erlang@process:subject(event())} | + {error, gleam@otp@actor:start_error()}. +start_listener(Initial_state, Loop) -> + gleam@otp@actor:start_spec( + {spec, + fun() -> + Pid = erlang:self(), + gleam@erlang@process:start( + fun() -> glerm_ffi:listen(Pid) end, + true + ), + {ready, Initial_state, selector()} + end, + 500, + Loop} + ). + +-spec print(bitstring()) -> {ok, nil} | {error, nil}. +print(Field@0) -> + glerm_ffi:print(Field@0). + +-spec size() -> {ok, {integer(), integer()}} | {error, nil}. +size() -> + glerm_ffi:size(). + +-spec move_to(integer(), integer()) -> nil. +move_to(Field@0, Field@1) -> + glerm_ffi:move_to(Field@0, Field@1). + +-spec enable_raw_mode() -> {ok, nil} | {error, nil}. +enable_raw_mode() -> + glerm_ffi:enable_raw_mode(). + +-spec disable_raw_mode() -> {ok, nil} | {error, nil}. +disable_raw_mode() -> + glerm_ffi:disable_raw_mode(). + +-spec enter_alternate_screen() -> {ok, nil} | {error, nil}. +enter_alternate_screen() -> + glerm_ffi:enter_alternate_screen(). + +-spec leave_alternate_screen() -> {ok, nil} | {error, nil}. +leave_alternate_screen() -> + glerm_ffi:leave_alternate_screen(). + +-spec enable_mouse_capture() -> {ok, nil} | {error, nil}. +enable_mouse_capture() -> + glerm_ffi:enable_mouse_capture(). + +-spec disable_mouse_capture() -> {ok, nil} | {error, nil}. +disable_mouse_capture() -> + glerm_ffi:disable_mouse_capture(). diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam b/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam new file mode 100644 index 00000000000..dc0f1394352 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/src/glerm.gleam @@ -0,0 +1,354 @@ +import gleam/dynamic.{DecodeError, Decoder, Dynamic} +import gleam/function +import gleam/option.{None, Option, Some} +import gleam/result +import gleam/erlang/atom +import gleam/erlang/process.{Pid, Selector, Subject} +import gleam/otp/actor + +/// These represent the noted keys being held down when another action is taken, +/// like pressing another key or mouse button. For certain keys, things like +/// `Shift` will not be set, but instead return something like `A`. +pub type Modifier { + Shift + Alt + Control +} + +/// A particular keyboard key that was pressed. Either a character with its +/// value, or a special key. The `Unsupported` is for things like `PageUp`, etc +/// that I'm just not handling yet. +pub type KeyCode { + Character(String) + Enter + Backspace + Left + Right + Down + Up + Unsupported +} + +/// Which mouse button was pressed. These are prefixed with `Mouse` in order to +/// avoid conflicting with the arrow keys defined in `KeyCode`. +pub type MouseButton { + MouseLeft + MouseRight + MouseMiddle +} + +/// The possible types of mouse events. I think most of these will also +/// have the mouse cursor position attached. That is not supported at the moment. +pub type MouseEvent { + MouseDown(button: MouseButton, modifier: Option(Modifier)) + MouseUp(button: MouseButton, modifier: Option(Modifier)) + Drag(button: MouseButton, modifier: Option(Modifier)) + Moved + ScrollDown + ScrollUp +} + +/// When the terminal window is focused or un-focused. +pub type FocusEvent { + Lost + Gained +} + +/// The possible events coming back from the terminal. `Unknown` should +/// realistically never happen, since this library controls both ends of the +/// message passing. +pub type Event { + Focus(event: FocusEvent) + Key(key: KeyCode, modifier: Option(Modifier)) + Mouse(event: MouseEvent) + Resize(Int, Int) + Unknown(tag: String, message: Dynamic) +} + +fn decode_atom(val: String, actual: a) -> Decoder(a) { + let real_atom = atom.create_from_string(val) + let decode = + function.compose( + atom.from_dynamic, + fn(maybe_atom) { + maybe_atom + |> result.then(fn(decoded) { + case decoded == real_atom { + True -> Ok(real_atom) + False -> Error([DecodeError(val, atom.to_string(decoded), [])]) + } + }) + }, + ) + fn(msg) { + decode(msg) + |> result.replace(actual) + } +} + +fn modifier_decoder() -> Decoder(Option(Modifier)) { + let decode_some = decode_atom("some", Some) + dynamic.any([ + decode_atom("none", None), + function.compose( + dynamic.tuple2(decode_some, decode_atom("shift", Shift)), + result.replace(_, Some(Shift)), + ), + function.compose( + dynamic.tuple2(decode_some, decode_atom("alt", Alt)), + result.replace(_, Some(Alt)), + ), + function.compose( + dynamic.tuple2(decode_some, decode_atom("control", Control)), + result.replace(_, Some(Control)), + ), + ]) +} + +fn keycode_decoder() -> Decoder(KeyCode) { + dynamic.any([ + dynamic.tuple2(decode_atom("character", Character), dynamic.string) + |> function.compose(fn(maybe_pair) { + case maybe_pair { + Ok(#(_character, value)) -> Ok(Character(value)) + Error(err) -> Error(err) + } + }), + decode_atom("enter", Enter), + decode_atom("backspace", Backspace), + decode_atom("left", Left), + decode_atom("right", Right), + decode_atom("down", Down), + decode_atom("up", Up), + decode_atom("unsupported", Unsupported), + ]) +} + +fn mouse_button_decoder() -> Decoder(MouseButton) { + dynamic.any([ + decode_atom("mouse_left", MouseLeft), + decode_atom("mouse_right", MouseRight), + decode_atom("mouse_middle", MouseMiddle), + ]) +} + +fn mouse_event_decoder() -> Decoder(MouseEvent) { + dynamic.any([ + dynamic.tuple3( + decode_atom("mouse_down", MouseDown), + mouse_button_decoder(), + modifier_decoder(), + ) + |> function.compose(fn(maybe_triple) { + case maybe_triple { + Ok(#(_mouse_down, button, modifier)) -> Ok(MouseDown(button, modifier)) + Error(err) -> Error(err) + } + }), + dynamic.tuple3( + decode_atom("mouse_up", MouseUp), + mouse_button_decoder(), + modifier_decoder(), + ) + |> function.compose(fn(maybe_triple) { + case maybe_triple { + Ok(#(_mouse_up, button, modifier)) -> Ok(MouseUp(button, modifier)) + Error(err) -> Error(err) + } + }), + dynamic.tuple3( + decode_atom("drag", Drag), + mouse_button_decoder(), + modifier_decoder(), + ) + |> function.compose(fn(maybe_triple) { + case maybe_triple { + Ok(#(_drag, button, modifier)) -> Ok(Drag(button, modifier)) + Error(err) -> Error(err) + } + }), + decode_atom("moved", Moved), + decode_atom("scroll_down", ScrollDown), + decode_atom("scroll_up", ScrollUp), + ]) +} + +/// The events from the NIF are sent as messages to the calling process. These +/// do not go through a `process.Subject`, so they need to be explicitly +/// extracted from the mailbox. This selector will grab the given `Event`s for +/// each message that comes in. +pub fn selector() -> Selector(Event) { + process.new_selector() + |> process.selecting_record2( + atom.create_from_string("focus"), + fn(inner) { + inner + |> dynamic.any([decode_atom("gained", Gained), decode_atom("lost", Lost)]) + |> result.map(Focus) + |> result.unwrap(Unknown("focus", inner)) + }, + ) + |> process.selecting_record3( + atom.create_from_string("key"), + fn(first, second) { + let key_code = keycode_decoder()(first) + let modifier = modifier_decoder()(second) + case key_code, modifier { + Ok(code), Ok(mod) -> Key(code, mod) + _, _ -> Unknown("key", dynamic.from([first, second])) + } + }, + ) + |> process.selecting_record2( + atom.create_from_string("mouse"), + fn(inner) { + inner + |> mouse_event_decoder() + |> result.map(Mouse) + |> result.lazy_unwrap(fn() { Unknown("mouse", inner) }) + }, + ) + |> process.selecting_record3( + atom.create_from_string("resize"), + fn(first, second) { + let columns = dynamic.int(first) + let rows = dynamic.int(second) + case columns, rows { + Ok(col), Ok(rows) -> Resize(col, rows) + _, _ -> Unknown("resize", dynamic.from([first, second])) + } + }, + ) +} + +/// Fully clears the terminal window +pub external fn clear() -> Nil = + "glerm_ffi" "clear" + +/// Write some string to the screen at the given #(column, row) coordinate +pub external fn draw(commands: List(#(Int, Int, String))) -> Result(Nil, Nil) = + "glerm_ffi" "draw" + +/// This is the "meat" of the library. This will fire up the NIF, which spawns +/// a thread to read for terminal events. The `Pid` provided here is where the +/// messages will be sent. +external fn listen(pid: Pid) -> Result(Nil, Nil) = + "glerm_ffi" "listen" + +/// Writes the given text wherever the cursor is +pub external fn print(data: BitString) -> Result(Nil, Nil) = + "glerm_ffi" "print" + +/// Gives back the #(column, row) count of the current terminal. This can be +/// called to get the initial size, and then updated when `Resize` events +/// come in. +pub external fn size() -> Result(#(Int, Int), Nil) = + "glerm_ffi" "size" + +/// Moves the cursor to the given location +pub external fn move_to(column: Int, row: Int) -> Nil = + "glerm_ffi" "move_to" + +/// Enables "raw mode" for the terminal. This will do a better job than I can +/// at explaining what all that entails: +/// +/// https://docs.rs/crossterm/latest/crossterm/terminal/index.html#raw-mode +/// +/// If you want to control the entire screen, capture all input events, and +/// place the cursor anywhere, this is what you want. +pub external fn enable_raw_mode() -> Result(Nil, Nil) = + "glerm_ffi" "enable_raw_mode" + +/// Turns off raw mode. This will disable the features described in +/// `enable_raw_mode`. +pub external fn disable_raw_mode() -> Result(Nil, Nil) = + "glerm_ffi" "disable_raw_mode" + +/// This will create a new terminal "window" that you can interact with. This +/// will preserve the user's existing terminal when exiting the program, or +/// calling `leave_alternate_screen`. +pub external fn enter_alternate_screen() -> Result(Nil, Nil) = + "glerm_ffi" "enter_alternate_screen" + +/// See: `enter_alternate_screen` +pub external fn leave_alternate_screen() -> Result(Nil, Nil) = + "glerm_ffi" "leave_alternate_screen" + +/// This enables the capturing of mouse events. Without this, those event types +/// will not be emitted by the NIF. +pub external fn enable_mouse_capture() -> Result(Nil, Nil) = + "glerm_ffi" "enable_mouse_capture" + +/// This will stop the capture of mouse events in the terminal. +pub external fn disable_mouse_capture() -> Result(Nil, Nil) = + "glerm_ffi" "disable_mouse_capture" + +pub type ListenerMessage(user_message) { + Term(Event) + User(user_message) +} + +pub type ListenerSubject(user_message) = + Subject(ListenerMessage(user_message)) + +pub type EventSubject = + Subject(Event) + +pub type ListenerSpec(state, user_message) { + ListenerSpec( + init: fn() -> #(state, Option(Selector(user_message))), + loop: fn(ListenerMessage(user_message), state) -> actor.Next(state), + ) +} + +/// This will start the NIF listener and set up the `Event` selector. The spec +/// argument allows for behavior during the initialization of the actor. That +/// function returns the initial state, and an optional user selector. This +/// allows this actor to also receive any user-defined messages. +pub fn start_listener_spec( + spec: ListenerSpec(state, user_message), +) -> Result(ListenerSubject(user_message), actor.StartError) { + actor.start_spec(actor.Spec( + init: fn() { + let pid = process.self() + let assert #(state, user_selector) = spec.init() + let term_selector = + selector() + |> process.map_selector(Term) + let selector = + user_selector + |> option.map(fn(user) { + user + |> process.map_selector(User) + |> process.merge_selector(term_selector, _) + }) + |> option.unwrap(term_selector) + process.start(fn() { listen(pid) }, True) + actor.Ready(state, selector) + }, + init_timeout: 500, + loop: spec.loop, + )) +} + +/// If you are not planning on sending custom messages to the terminal listener, +/// this method is the simplest. Give an initial state for the actor, and the +/// loop will receive only `Event`s and your provided state. To allow this +/// actor to receive additional user-defined messages, see `start_listener_spec` +pub fn start_listener( + initial_state: state, + loop: fn(Event, state) -> actor.Next(state), +) -> Result(EventSubject, actor.StartError) { + actor.start_spec(actor.Spec( + init: fn() { + let pid = process.self() + process.start(fn() { listen(pid) }, True) + actor.Ready(initial_state, selector()) + }, + init_timeout: 500, + loop: loop, + )) +} +// TODO: +// - test? +// - docs diff --git a/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl b/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl new file mode 100644 index 00000000000..021fbde4915 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glerm/src/glerm_ffi.erl @@ -0,0 +1,67 @@ +-module(glerm_ffi). + +-export([listen/1, print/1, size/0, clear/0, move_to/2, draw/1, enable_raw_mode/0, + disable_raw_mode/0, enter_alternate_screen/0, leave_alternate_screen/0, enable_mouse_capture/0, disable_mouse_capture/0]). + +-nifs([{listen, 1}, + {print, 1}, + {size, 0}, + {clear, 0}, + {move_to, 2}, + {draw, 1}, + {enable_raw_mode, 0}, + {disable_raw_mode, 0}, + {enter_alternate_screen, 0}, + {leave_alternate_screen, 0}, + {enable_mouse_capture, 0}, + {disable_mouse_capture, 0}]). + +-on_load init/0. + +init() -> + Arch = erlang:system_info(system_architecture), + Priv = code:priv_dir(glerm), + ArchPath = + case Arch of + "x86_64-pc-linux" ++ _ -> + filename:join(Priv, "linux"); + "win32" -> + filename:join(Priv, "windows"); + "x86_64-apple-drawin" ++ _ -> + filename:join(Priv, "macos") + end, + Path = filename:join(ArchPath, libglerm), + erlang:load_nif(Path, 0). + +listen(_Pid) -> + exit(nif_library_not_loaded). + +print(_Data) -> + exit(nif_library_not_loaded). + +size() -> + exit(nif_library_not_loaded). + +clear() -> + exit(nif_library_not_loaded). + +move_to(_Column, _Row) -> + exit(nif_library_not_loaded). + +draw(_Commands) -> + exit(nif_library_not_loaded). + +enable_raw_mode() -> + exit(nif_library_not_loaded). + +disable_raw_mode() -> + exit(nif_library_not_loaded). + +enter_alternate_screen() -> + exit(nif_library_not_loaded). +leave_alternate_screen() -> + exit(nif_library_not_loaded). +enable_mouse_capture() -> + exit(nif_library_not_loaded). +disable_mouse_capture() -> + exit(nif_library_not_loaded). diff --git a/test-community-packages-javascript/build/packages/gliew/README.md b/test-community-packages-javascript/build/packages/gliew/README.md new file mode 100644 index 00000000000..4120dfe33af --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/README.md @@ -0,0 +1,393 @@ +# gliew + +[![Package Version](https://img.shields.io/hexpm/v/gliew)](https://hex.pm/packages/gliew) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gliew/) + +An **experimental** web framework with server-side rendering and optional live updating UI (à la Phoenix's LiveView) for gleam. + +## Quick start + +Usage is similar to [mist](https://hexdocs.pm/mist/) except the handler function should return a [nakai](https://hexdocs.pm/nakai/) node tree. + +```gleam +import gleam/erlang/process +import gleam/http.{Get} +import gleam/http/request +import nakai/html +import gliew + +pub fn main() { + let assert Ok(_) = + gliew.new( + 8080, + fn(req) { + case req.method, request.path_segments(req) { + Get, ["hello"] -> + html.div_text([], "Hello gleam!") + |> gliew.view(200) + _, _ -> + html.div_text([], "Hello world!") + |> gliew.view(200) + } + }, + ) + |> gliew.serve + + process.sleep_forever() +} +``` + +### Live mounts + +In order to have some elements of the HTML live updating you will need to use live mounts. + +They can be either used by calling the `gliew.live_mount` function directly: + +```gleam +import gleam/int +import gleam/option.{Option} +import gleam/erlang/process.{Subject} +import gleam/http/request +import nakai/html +import gliew + +pub fn main() { + let assert Ok(_) = + gliew.new( + 8080, + fn(req) { + case req.method, request.path_segments(req) { + _, _ -> + html.div( + [], + [ + html.div_text([], "counter is at:"), + gliew.live_mount( + mount: mount_counter, + with: Nil, + render: render_counter, + ), + ], + ) + |> gliew.view(200) + } + }, + ) + |> gliew.serve + + process.sleep_forever() +} + +// The render function is called with `None` on +// initial render but `Some(a)` every time there +// is a new value on the subject returned by the +// mount function. +fn render_counter(assign: Option(Int)) { + html.div_text( + [], + assign + |> option.unwrap(0) + |> int.to_string, + ) +} + +// This is the mount function. +fn mount_counter(_ctx) { + let subject = process.new_subject() + + let _ = process.start(fn() { loop(subject, 0) }, True) + + subject +} + +// Counter loop for demonstration purposes. +fn loop(subject: Subject(Int), current: Int) { + process.send(subject, current) + process.sleep(1000) + loop(subject, current + 1) +} +``` + +But a nicer way (IMO) is to use the `use` syntax to turn a function into a live mount by default. + +```gleam +import gleam/int +import gleam/option +import gleam/erlang/process.{Subject} +import gleam/http/request +import nakai/html +import gliew + +pub fn main() { + let assert Ok(_) = + gliew.new( + 8080, + fn(req) { + case req.method, request.path_segments(req) { + _, _ -> + html.div([], [html.div_text([], "counter is at:"), counter()]) + |> gliew.view(200) + } + }, + ) + |> gliew.serve + + process.sleep_forever() +} + +// This becomes the render function. +fn counter() { + // Here we use the `use` syntax as kind of a decorator + // to turn this function into a live mount. + use assign <- gliew.live_mount(mount_counter, with: Nil) + + html.div_text( + [], + assign + |> option.unwrap(0) + |> int.to_string, + ) +} + +// This is still the mount function. +fn mount_counter(_ctx) { + let subject = process.new_subject() + + let _ = process.start(fn() { loop(subject, 0) }, True) + + subject +} + +// Counter loop for demonstartion purposes. +fn loop(subject: Subject(Int), current: Int) { + process.send(subject, current) + process.sleep(1000) + loop(subject, current + 1) +} +``` + +## Example + +The following example has a random string generator and a global counter so that every browser session remains in sync when navigating to `http://localhost:8080/mounts`. + +```gleam +import gleam/int +import gleam/string +import gleam/base +import gleam/option.{None, Some} +import gleam/http.{Get, Post} +import gleam/http/request +import gleam/erlang/process.{Subject} +import gleam/crypto.{strong_random_bytes} +import nakai/html +import nakai/html/attrs +import gliew +// This is only here for this example. +// It implements an actor that keeps an +// incrementing counter and can be +// subscribed to. +import gliew/integration/counter.{ + CounterMessage, reset, start_counter, subscribe, +} + +pub fn main() { + // Start anything that will be needed by the handlers. + // In this case we start an actor that simply increments + // a counter (starting at 0). + // You can subscribe to the counter to be notified every + // time it increments. + let assert Ok(count_actor) = start_counter() + + // Start the gliew server. + // This is a thin wrapper around mist which handles + // rendering your views and starting workers for + // live connections. + let assert Ok(_) = + gliew.new( + 8080, + fn(req) { + case req.method, request.path_segments(req) { + Get, ["mounts"] -> + mounts_page(count_actor) + |> gliew.view(200) + Post, ["counter", "reset"] -> reset_counter(count_actor) + _, _ -> + home_page() + |> gliew.view(200) + } + }, + ) + |> gliew.serve + + process.sleep_forever() +} + +// You can just return a simple nakai node tree for +// a static page. +fn home_page() { + html.div_text([], "Hello gleam!") +} + +fn reset_counter(count_actor: Subject(CounterMessage)) { + reset(count_actor) + + gliew.response(204) +} + +fn mounts_page(count_actor: Subject(CounterMessage)) { + // Return the HTML for the page. + html.div( + [ + attrs.style( + [ + "display: flex", "flex-direction: column", "justify-content: center", + "align-items: center", "row-gap: 1em", "height: 100vh", + ] + |> string.join(";"), + ), + ], + [ + // Random text + html.div_text([attrs.style("font-size: x-large")], "Random text for you"), + random_text(), + // Counter + html.div_text([attrs.style("font-size: x-large")], "Counter is at"), + counter(count_actor), + html.div( + [], + [ + html.button_text([], "Reset") + |> gliew.on_click(do: Post, to: "/counter/reset"), + ], + ), + // Explanation text + html.div( + [ + attrs.style( + [ + "background-color: #d0ebf4", "padding: 1em", "color: #222", + "border-radius: 1em", "width: 21em", "margin-top: 0.5em", + ] + |> string.join(";"), + ), + ], + [ + html.div_text( + [attrs.style("font-size: x-large; margin-bottom: 0.5em;")], + "This page is live rendered.", + ), + html.div_text( + [attrs.style("font-size: large")], + "Once the browser has made a connection to the server a new random text is generated every 5 seconds and the counter above should auto-increment.", + ), + ], + ), + ], + ) +} + +// // +// Global counter live mount // +// // + +// A live mount that shows a live updating counter. +fn counter(count_actor: Subject(CounterMessage)) { + // Makes the function a live mount. + // The second parameter passed to `gliew.live_mount` will + // be passed to the mount function (first parameter) + // when the mount is mounted (i.e. the client connects + // back to the server to get live updates). + // + // The returned value is of type `Option(a)` where + // `a` is the type in the Subject returned by mount. + use assign <- gliew.live_mount(counter_mount, with: count_actor) + + let text = case assign { + // View has been mounted and we want to use the + // "live" value that was setup in the mount function. + Some(counter) -> + counter + |> int.to_string + // View is being rendered on the server before + // the client has made a connection back to the server. + // Here we contact the count_actor to get the current + // value. + None -> "Loading.." + } + + // Return the HTML of the view. + html.div_text([attrs.style("font-size: xx-large")], text) +} + +// A mount function that runs once the client connects through +// a websocket. +// This should be used to subscribe to whatever data that should +// be returned to the render function and return the subject. +fn counter_mount(count_actor: Subject(CounterMessage)) { + // Create a new subject. + let subject = process.new_subject() + + // Subscribe to counter. + subscribe(count_actor, subject) + + // Return the subject. + subject +} + +// // +// Random text live mount // +// // + +// A live mount that renders random text on an interval. +fn random_text() { + use assign <- gliew.live_mount(text_mount, with: Nil) + + html.div_text( + [attrs.style("font-size: xx-large")], + assign + |> option.unwrap(random_string()), + ) +} + +// The mount function used for the random_text mount. +// It will generate random text on an interval and +// send it on the returned subject. +fn text_mount(_) { + let subject = process.new_subject() + + let _ = process.start(fn() { loop(subject) }, True) + + subject +} + +// Random text loop. +fn loop(subject: Subject(String)) { + process.send(subject, random_string()) + process.sleep(5000) + loop(subject) +} + +// Helper function to generate random string. +fn random_string() { + strong_random_bytes(10) + |> base.encode64(False) +} +```` + +The above example implementation can be found in `test/integration/live_mounts.gleam` and quickly run with: + +```sh +gleam run -m gliew/integration/live_mounts +``` + +And then navigate to `http://localhost:8080/mounts` to see in action. + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add gliew +``` + +and its documentation can be found at . diff --git a/test-community-packages-javascript/build/packages/gliew/gleam.toml b/test-community-packages-javascript/build/packages/gliew/gleam.toml new file mode 100644 index 00000000000..391330c4572 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/gleam.toml @@ -0,0 +1,16 @@ +name = "gliew" +version = "0.3.0" +description = "A gleam server-side rendered web framework with live updating UI" +repository = { type = "github", user = "arnarg", repo = "gliew" } +licences = ["MIT"] + +[dependencies] +gleam_stdlib = "~> 0.29" +nakai = "~> 0.8" +mist = "~> 0.11" +gleam_erlang = "~> 0.19" +gleam_otp = "~> 0.5" +gleam_crypto = "~> 0.3" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl new file mode 100644 index 00000000000..b4e74b38aa5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@event_LiveMount.hrl @@ -0,0 +1,3 @@ +-record(live_mount, { + selecting :: fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message())) +}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl new file mode 100644 index 00000000000..8d99ff6efa5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_GetWorker.hrl @@ -0,0 +1,7 @@ +-record(get_worker, { + from :: gleam@erlang@process:subject({ok, + gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | + {error, nil}), + id :: binary(), + csrf :: binary() +}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl new file mode 100644 index 00000000000..8589100c87b --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@manager_ProcessTree.hrl @@ -0,0 +1,5 @@ +-record(process_tree, { + from :: gleam@erlang@process:subject(nakai@html:node_(gliew@internal@event:event())), + request :: gleam@http@request:request(mist@internal@http:body()), + tree :: nakai@html:node_(gliew@internal@event:event()) +}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl new file mode 100644 index 00000000000..89ac76e9dd3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_ConnectSocket.hrl @@ -0,0 +1,3 @@ +-record(connect_socket, { + socket :: gleam@erlang@process:subject(glisten@handler:handler_message()) +}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl new file mode 100644 index 00000000000..a89d582fa33 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_DisconnectSocket.hrl @@ -0,0 +1,3 @@ +-record(disconnect_socket, { + socket :: gleam@erlang@process:subject(glisten@handler:handler_message()) +}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl new file mode 100644 index 00000000000..2e4eb60f892 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew@internal@worker_LiveUpdate.hrl @@ -0,0 +1 @@ +-record(live_update, {markup :: binary()}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl new file mode 100644 index 00000000000..be1a4225b8f --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew_Response.hrl @@ -0,0 +1,5 @@ +-record(response, { + status :: integer(), + headers :: list({binary(), binary()}), + body :: gleam@option:option(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl new file mode 100644 index 00000000000..5a9075101ce --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew_Server.hrl @@ -0,0 +1,5 @@ +-record(server, { + port :: integer(), + layout :: fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), + handler :: fun((gleam@http@request:request(mist@internal@http:body())) -> gliew:response()) +}). diff --git a/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl b/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl new file mode 100644 index 00000000000..96a8047b829 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/include/gliew_View.hrl @@ -0,0 +1,5 @@ +-record(view, { + status :: integer(), + headers :: list({binary(), binary()}), + node :: nakai@html:node_(gliew@internal@event:event()) +}). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src b/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src new file mode 100644 index 00000000000..91aa7179e93 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew.app.src @@ -0,0 +1,17 @@ +{application, gliew, [ + {vsn, "0.3.0"}, + {applications, [gleam_crypto, + gleam_erlang, + gleam_otp, + gleam_stdlib, + gleeunit, + mist, + nakai]}, + {description, "A gleam server-side rendered web framework with live updating UI"}, + {modules, [gliew, + gliew@internal@event, + gliew@internal@manager, + gliew@internal@util, + gliew@internal@worker]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew.erl new file mode 100644 index 00000000000..1cf3336b7ff --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew.erl @@ -0,0 +1,495 @@ +-module(gliew). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([view/2, response/1, with_header/3, with_body/2, morph/0, append/0, on_click/3, live_mount/3, script/0, new/2, serve/1]). +-export_type([response/0, server/0]). + +-opaque response() :: {view, + integer(), + list({binary(), binary()}), + nakai@html:node_(gliew@internal@event:event())} | + {response, + integer(), + list({binary(), binary()}), + gleam@option:option(binary())}. + +-type server() :: {server, + integer(), + fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), + fun((gleam@http@request:request(mist@internal@http:body())) -> response())}. + +-spec view(nakai@html:node_(gliew@internal@event:event()), integer()) -> response(). +view(Node, Status) -> + {view, Status, [], Node}. + +-spec response(integer()) -> response(). +response(Status) -> + {response, Status, [], none}. + +-spec with_header(response(), binary(), binary()) -> response(). +with_header(Response, Key, Value) -> + case Response of + {view, Status, Headers, Node} -> + _pipe = Headers, + _pipe@1 = gleam@list:prepend(_pipe, {Key, Value}), + {view, Status, _pipe@1, Node}; + + {response, Status@1, Headers@1, Body} -> + _pipe@2 = Headers@1, + _pipe@3 = gleam@list:prepend(_pipe@2, {Key, Value}), + {response, Status@1, _pipe@3, Body} + end. + +-spec with_body(response(), binary()) -> response(). +with_body(Response, Body) -> + case Response of + {response, Status, Headers, _} -> + {response, Status, Headers, {some, Body}}; + + _ -> + Response + end. + +-spec morph() -> nakai@html@attrs:attr(gliew@internal@event:event()). +morph() -> + {event, <<"gliew-event"/utf8>>, morph}. + +-spec append() -> nakai@html@attrs:attr(gliew@internal@event:event()). +append() -> + {event, <<"gliew-event"/utf8>>, append}. + +-spec add_attr( + nakai@html:node_(gliew@internal@event:event()), + nakai@html@attrs:attr(gliew@internal@event:event()) +) -> nakai@html:node_(gliew@internal@event:event()). +add_attr(Node, Attr) -> + case Node of + {element, Tag, Attrs, Children} -> + _pipe = Attrs, + _pipe@1 = gleam@list:prepend(_pipe, Attr), + {element, Tag, _pipe@1, Children}; + + {leaf_element, Tag@1, Attrs@1} -> + _pipe@2 = Attrs@1, + _pipe@3 = gleam@list:prepend(_pipe@2, Attr), + {leaf_element, Tag@1, _pipe@3}; + + {html, Attrs@2, Children@1} -> + _pipe@4 = Attrs@2, + _pipe@5 = gleam@list:prepend(_pipe@4, Attr), + {html, _pipe@5, Children@1}; + + {body, Attrs@3, Children@2} -> + _pipe@6 = Attrs@3, + _pipe@7 = gleam@list:prepend(_pipe@6, Attr), + {body, _pipe@7, Children@2}; + + Other -> + Other + end. + +-spec on_click( + nakai@html:node_(gliew@internal@event:event()), + gleam@http:method(), + binary() +) -> nakai@html:node_(gliew@internal@event:event()). +on_click(Node, Method, Path) -> + case Method of + get -> + _pipe = Node, + _pipe@1 = add_attr(_pipe, {attr, <<"hx-get"/utf8>>, Path}), + add_attr(_pipe@1, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); + + post -> + _pipe@2 = Node, + _pipe@3 = add_attr(_pipe@2, {attr, <<"hx-post"/utf8>>, Path}), + add_attr(_pipe@3, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); + + put -> + _pipe@4 = Node, + _pipe@5 = add_attr(_pipe@4, {attr, <<"hx-put"/utf8>>, Path}), + add_attr(_pipe@5, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); + + patch -> + _pipe@6 = Node, + _pipe@7 = add_attr(_pipe@6, {attr, <<"hx-patch"/utf8>>, Path}), + add_attr(_pipe@7, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); + + delete -> + _pipe@8 = Node, + _pipe@9 = add_attr(_pipe@8, {attr, <<"hx-delete"/utf8>>, Path}), + add_attr(_pipe@9, {attr, <<"hx-swap"/utf8>>, <<"none"/utf8>>}); + + _ -> + Node + end. + +-spec insert_event( + gliew@internal@event:event(), + nakai@html:node_(gliew@internal@event:event()) +) -> nakai@html:node_(gliew@internal@event:event()). +insert_event(Event, Node) -> + _pipe = Node, + add_attr(_pipe, {event, <<"gliew-event"/utf8>>, Event}). + +-spec map_events( + list(nakai@html@attrs:attr(gliew@internal@event:event())), + boolean() +) -> list(nakai@html@attrs:attr(gliew@internal@event:event())). +map_events(Attrs, Render_events) -> + case Render_events of + true -> + gleam@list:map(Attrs, fun(Attr) -> case Attr of + {event, <<"gliew-event"/utf8>>, morph} -> + {attr, <<"hx-swap-oob"/utf8>>, <<"morph"/utf8>>}; + + {event, <<"gliew-event"/utf8>>, append} -> + {attr, <<"hx-swap-oob"/utf8>>, <<"beforeend"/utf8>>}; + + Other -> + Other + end end); + + false -> + Attrs + end. + +-spec find_id(list(nakai@html@attrs:attr(gliew@internal@event:event()))) -> {ok, + binary()} | + {error, nil}. +find_id(Attrs) -> + _pipe = Attrs, + gleam@list:find_map(_pipe, fun(Attr) -> case Attr of + {attr, <<"id"/utf8>>, Id} -> + {ok, Id}; + + _ -> + {error, nil} + end end). + +-spec random_id() -> binary(). +random_id() -> + <<"g-"/utf8, (gliew@internal@util:random_hex_string(3))/binary>>. + +-spec extract_id(nakai@html:node_(gliew@internal@event:event())) -> binary(). +extract_id(Node) -> + _pipe = case Node of + {element, _, Attrs, _} -> + find_id(Attrs); + + {leaf_element, _, Attrs@1} -> + find_id(Attrs@1); + + _ -> + {error, nil} + end, + gleam@result:unwrap(_pipe, random_id()). + +-spec has_id(list(nakai@html@attrs:attr(any()))) -> boolean(). +has_id(Attrs) -> + _pipe = Attrs, + gleam@list:any(_pipe, fun(A) -> case A of + {attr, <<"id"/utf8>>, _} -> + true; + + _ -> + false + end end). + +-spec ensure_id( + list(nakai@html@attrs:attr(gliew@internal@event:event())), + gleam@option:option(binary()) +) -> list(nakai@html@attrs:attr(gliew@internal@event:event())). +ensure_id(Attrs, Id) -> + case has_id(Attrs) of + true -> + case Id of + {some, Id@1} -> + gleam@list:map(Attrs, fun(Attr) -> case Attr of + {attr, <<"id"/utf8>>, _} -> + nakai@html@attrs:id(Id@1); + + Other -> + Other + end end); + + none -> + Attrs + end; + + false -> + _pipe = Attrs, + gleam@list:prepend( + _pipe, + nakai@html@attrs:id( + begin + _pipe@1 = Id, + gleam@option:unwrap(_pipe@1, random_id()) + end + ) + ) + end. + +-spec process_tree( + nakai@html:node_(gliew@internal@event:event()), + gleam@option:option(binary()), + boolean() +) -> nakai@html:node_(gliew@internal@event:event()). +process_tree(Node, Id, Render_events) -> + case Node of + {element, Tag, Attrs, Children} -> + _pipe = Attrs, + _pipe@1 = ensure_id(_pipe, Id), + _pipe@2 = map_events(_pipe@1, Render_events), + {element, Tag, _pipe@2, Children}; + + {leaf_element, Tag@1, Attrs@1} -> + _pipe@3 = Attrs@1, + _pipe@4 = ensure_id(_pipe@3, Id), + _pipe@5 = map_events(_pipe@4, Render_events), + {leaf_element, Tag@1, _pipe@5}; + + Other -> + Other + end. + +-spec live_mount( + fun((MEC) -> gleam@erlang@process:subject(MED)), + MEC, + fun((gleam@option:option(MED)) -> nakai@html:node_(gliew@internal@event:event())) +) -> nakai@html:node_(gliew@internal@event:event()). +live_mount(Mount, Context, Render) -> + Tree = begin + _pipe = Render(none), + process_tree(_pipe, none, false) + end, + Id = extract_id(Tree), + _pipe@5 = fun(Selector) -> + Subject = Mount(Context), + _pipe@1 = Selector, + gleam@erlang@process:selecting( + _pipe@1, + Subject, + fun(Val) -> _pipe@2 = Render({some, Val}), + _pipe@3 = process_tree(_pipe@2, {some, Id}, true), + _pipe@4 = nakai:to_inline_string(_pipe@3), + {live_update, _pipe@4} end + ) + end, + _pipe@6 = {live_mount, _pipe@5}, + insert_event(_pipe@6, Tree). + +-spec script() -> nakai@html:node_(any()). +script() -> + {fragment, + [{element, + <<"script"/utf8>>, + [nakai@html@attrs:src( + <<"https://unpkg.com/htmx.org@1.9.2/dist/htmx.min.js"/utf8>> + )], + []}, + {element, + <<"script"/utf8>>, + [nakai@html@attrs:src( + <<"https://unpkg.com/htmx.org@1.9.2/dist/ext/ws.js"/utf8>> + )], + []}, + {element, + <<"script"/utf8>>, + [nakai@html@attrs:src( + <<"https://unpkg.com/idiomorph@0.0.8/dist/idiomorph-ext.min.js"/utf8>> + )], + []}]}. + +-spec default_layout(nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event()). +default_layout(Content) -> + {html, [], [{head, [script()]}, {body, [], [Content]}]}. + +-spec new( + integer(), + fun((gleam@http@request:request(mist@internal@http:body())) -> response()) +) -> server(). +new(Port, Handler) -> + {server, Port, fun default_layout/1, Handler}. + +-spec add_headers(gleam@http@response:response(MFW), list({binary(), binary()})) -> gleam@http@response:response(MFW). +add_headers(Response, Headers) -> + _pipe = Headers, + gleam@list:fold(_pipe, Response, fun(Res, Pair) -> _pipe@1 = Res, + gleam@http@response:prepend_header( + _pipe@1, + erlang:element(1, Pair), + erlang:element(2, Pair) + ) end). + +-spec to_mist_response( + gleam@http@response:response(any()), + gleam@option:option(binary()) +) -> mist@internal@handler:handler_response(). +to_mist_response(Response, Body) -> + case Body of + {some, Body@1} -> + _pipe = Response, + mist:bit_builder_response( + _pipe, + gleam@bit_builder:from_string(Body@1) + ); + + none -> + _pipe@1 = Response, + mist:empty_response(_pipe@1) + end. + +-spec upgrade_connection( + gleam@erlang@process:subject(gliew@internal@manager:message()), + binary(), + binary() +) -> mist@internal@handler:handler_response(). +upgrade_connection(Manager, Session, Csrf) -> + case gliew@internal@manager:get_worker(Manager, Session, Csrf) of + {ok, Worker} -> + _pipe = fun(_, _) -> {ok, nil} end, + _pipe@1 = mist@websocket:with_handler(_pipe), + _pipe@2 = mist@websocket:on_init( + _pipe@1, + fun(Socket) -> gliew@internal@worker:connect(Worker, Socket) end + ), + _pipe@3 = mist@websocket:on_close( + _pipe@2, + fun(Socket@1) -> + gliew@internal@worker:disconnect(Worker, Socket@1) + end + ), + mist:upgrade(_pipe@3); + + {error, nil} -> + _pipe@4 = gleam@http@response:new(401), + mist:empty_response(_pipe@4) + end. + +-spec get_params(list({binary(), binary()})) -> {ok, {binary(), binary()}} | + {error, nil}. +get_params(Params) -> + Pmap = gleam@map:from_list(Params), + gleam@result:then( + gleam@map:get(Pmap, <<"session"/utf8>>), + fun(Session) -> + gleam@result:then( + gleam@map:get(Pmap, <<"csrf"/utf8>>), + fun(Csrf) -> {ok, {Session, Csrf}} end + ) + end + ). + +-spec parse_params(gleam@http@request:request(mist@internal@http:body())) -> {ok, + {binary(), binary()}} | + {error, nil}. +parse_params(Req) -> + case erlang:element(9, Req) of + {some, Params} -> + case gleam@uri:parse_query(Params) of + {ok, Params@1} -> + _pipe@1 = gleam@list:map( + Params@1, + fun(P) -> + {erlang:element(1, P), + begin + _pipe = erlang:element(2, P), + gleam@string:replace( + _pipe, + <<" "/utf8>>, + <<"+"/utf8>> + ) + end} + end + ), + get_params(_pipe@1); + + {error, nil} -> + {error, nil} + end; + + none -> + {error, nil} + end. + +-spec handle_ws_connect( + gleam@erlang@process:subject(gliew@internal@manager:message()), + gleam@http@request:request(mist@internal@http:body()) +) -> mist@internal@handler:handler_response(). +handle_ws_connect(Manager, Req) -> + case parse_params(Req) of + {ok, {Id, Csrf}} -> + upgrade_connection(Manager, Id, Csrf); + + {error, nil} -> + _pipe = gleam@http@response:new(401), + mist:empty_response(_pipe) + end. + +-spec handler_func( + gleam@erlang@process:subject(gliew@internal@manager:message()), + fun((nakai@html:node_(gliew@internal@event:event())) -> nakai@html:node_(gliew@internal@event:event())), + fun((gleam@http@request:request(mist@internal@http:body())) -> response()) +) -> fun((glisten@handler:handler_message(), glisten@handler:loop_state(mist@internal@handler:state())) -> gleam@otp@actor:next(glisten@handler:loop_state(mist@internal@handler:state()))). +handler_func(Manager, Layout, Handler) -> + _pipe@7 = fun(Req) -> + case {erlang:element(2, Req), erlang:element(8, Req)} of + {get, <<"/connect"/utf8>>} -> + handle_ws_connect(Manager, Req); + + {_, _} -> + case Handler(Req) of + {response, Status, Headers, Body} -> + _pipe = gleam@http@response:new(Status), + _pipe@1 = add_headers(_pipe, Headers), + to_mist_response(_pipe@1, Body); + + {view, Status@1, Headers@1, Node} -> + _pipe@2 = gleam@http@response:new(Status@1), + _pipe@3 = add_headers(_pipe@2, Headers@1), + mist:bit_builder_response( + _pipe@3, + begin + _pipe@4 = gliew@internal@manager:process_tree( + Manager, + Req, + Node + ), + _pipe@5 = Layout(_pipe@4), + _pipe@6 = nakai:to_string_builder(_pipe@5), + gleam@bit_builder:from_string_builder(_pipe@6) + end + ) + end + end + end, + mist:handler_func(_pipe@7). + +-spec serve(server()) -> {ok, nil} | {error, glisten:start_error()}. +serve(Server) -> + gleam@result:'try'( + begin + _pipe = gliew@internal@manager:start_manager(), + gleam@result:map_error(_pipe, fun(Err) -> case Err of + init_timeout -> + acceptor_timeout; + + {init_failed, Reason} -> + {acceptor_failed, Reason}; + + {init_crashed, Any} -> + {acceptor_crashed, Any} + end end) + end, + fun(Manager) -> + mist:serve( + erlang:element(2, Server), + handler_func( + Manager, + erlang:element(3, Server), + erlang:element(4, Server) + ) + ) + end + ). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam new file mode 100644 index 00000000000..884bdbf69ac --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew.gleam @@ -0,0 +1,477 @@ +import gleam/string +import gleam/list +import gleam/map +import gleam/result +import gleam/option.{None, Option, Some} +import gleam/uri +import gleam/bit_builder +import gleam/otp/actor +import gleam/erlang/process.{Selector, Subject} +import gleam/http.{Get} +import gleam/http/request.{Request} +import gleam/http/response.{Response as HttpResponse} +import mist.{Body} +import mist/websocket +import glisten +import glisten/handler.{HandlerMessage} +import nakai +import nakai/html +import nakai/html/attrs +import gliew/internal/event.{Event, LiveMount} +import gliew/internal/worker.{LiveUpdate, WorkerMessage} +import gliew/internal/manager.{Message as ManagerMessage} +import gliew/internal/util.{random_hex_string} + +const elem_id_prefix = "g-" + +// Response is the final response that should be returned from a +// handler. +// +pub opaque type Response { + View(status: Int, headers: List(#(String, String)), node: html.Node(Event)) + Response(status: Int, headers: List(#(String, String)), body: Option(String)) +} + +/// Creates a view response. +/// +pub fn view(node: html.Node(Event), status: Int) { + View(status, [], node) +} + +/// Creates an empty response without a body. +/// +pub fn response(status: Int) { + Response(status, [], None) +} + +/// Adds a header to a response. +/// +pub fn with_header(response: Response, key key: String, value value: String) { + case response { + View(status, headers, node) -> + headers + |> list.prepend(#(key, value)) + |> View(status, _, node) + Response(status, headers, body) -> + headers + |> list.prepend(#(key, value)) + |> Response(status, _, body) + } +} + +/// Sets body of a response. +/// +pub fn with_body(response: Response, body: String) { + case response { + Response(status, headers, _) -> Response(status, headers, Some(body)) + _ -> response + } +} + +/// Creates a HTML node tree that will be `mounted` +/// and receive live updates with data on `Subject(a)` +/// returned by the mount function. +/// +pub fn live_mount( + mount mount: fn(b) -> Subject(a), + with context: b, + render render: fn(Option(a)) -> html.Node(Event), +) { + // Render initial node tree + let tree = + render(None) + |> process_tree(None, False) + + // Get id from root element + let id = extract_id(tree) + + // Add mount event to root of tree + fn(selector: Selector(WorkerMessage)) { + // Mount component to get subject + let subject = mount(context) + + // Select and map subject + selector + |> process.selecting( + subject, + fn(val) { + render(Some(val)) + |> process_tree(Some(id), True) + |> nakai.to_inline_string + |> LiveUpdate + }, + ) + } + |> LiveMount + |> insert_event(tree) +} + +/// Attaches an on-click handler to a node by specifying +/// the HTTP method and path to make a request to when +/// clicked. +/// +pub fn on_click(node: html.Node(Event), do method: http.Method, to path: String) { + case method { + http.Get -> + node + |> add_attr(attrs.Attr("hx-get", path)) + |> add_attr(attrs.Attr("hx-swap", "none")) + http.Post -> + node + |> add_attr(attrs.Attr("hx-post", path)) + |> add_attr(attrs.Attr("hx-swap", "none")) + http.Put -> + node + |> add_attr(attrs.Attr("hx-put", path)) + |> add_attr(attrs.Attr("hx-swap", "none")) + http.Patch -> + node + |> add_attr(attrs.Attr("hx-patch", path)) + |> add_attr(attrs.Attr("hx-swap", "none")) + http.Delete -> + node + |> add_attr(attrs.Attr("hx-delete", path)) + |> add_attr(attrs.Attr("hx-swap", "none")) + _ -> node + } +} + +/// Makes the live mount morph the diff of the innerHTML +/// instead of replacing the whole thing. +/// +pub fn morph() { + attrs.Event("gliew-event", event.Morph) +} + +/// Append the innerHTML of the live mount instead of +/// replacing it. +/// +pub fn append() { + attrs.Event("gliew-event", event.Append) +} + +// Add an attribute to the provided node. +// +fn add_attr(node: html.Node(Event), attr: attrs.Attr(Event)) { + case node { + html.Element(tag, attrs, children) -> + attrs + |> list.prepend(attr) + |> html.Element(tag, _, children) + html.LeafElement(tag, attrs) -> + attrs + |> list.prepend(attr) + |> html.LeafElement(tag, _) + html.Html(attrs, children) -> + attrs + |> list.prepend(attr) + |> html.Html(children) + html.Body(attrs, children) -> + attrs + |> list.prepend(attr) + |> html.Body(children) + // Other nodes don't accept attributes + // we return them unchanged + other -> other + } +} + +// Insert the event to the node. +// +fn insert_event(event: Event, node: html.Node(Event)) { + node + |> add_attr(attrs.Event("gliew-event", event)) +} + +// Adds the id attribute to the node if provided, otherwise +// generates it. +// +fn process_tree(node: html.Node(Event), id: Option(String), render_events: Bool) { + case node { + html.Element(tag, attrs, children) -> + attrs + |> ensure_id(id) + |> map_events(render_events) + |> html.Element(tag, _, children) + html.LeafElement(tag, attrs) -> + attrs + |> ensure_id(id) + |> map_events(render_events) + |> html.LeafElement(tag, _) + other -> other + } +} + +// Transforms event attributes into actual htmx attributes. +// +fn map_events(attrs: List(attrs.Attr(Event)), render_events: Bool) { + case render_events { + True -> + list.map( + attrs, + fn(attr) { + case attr { + attrs.Event("gliew-event", event.Morph) -> + attrs.Attr("hx-swap-oob", "morph") + attrs.Event("gliew-event", event.Append) -> + attrs.Attr("hx-swap-oob", "beforeend") + other -> other + } + }, + ) + False -> attrs + } +} + +// Make sure there is an id attribute in the list of attributes. +// If id is `None` it will generate one if there isn't one. +// If id is `Some(id)` it will replace any id if there is one or +// otherwise add it. +// +fn ensure_id(attrs: List(attrs.Attr(Event)), id: Option(String)) { + case has_id(attrs) { + True -> + case id { + Some(id) -> + list.map( + attrs, + fn(attr) { + case attr { + attrs.Attr("id", _) -> attrs.id(id) + other -> other + } + }, + ) + None -> attrs + } + False -> + attrs + |> list.prepend(attrs.id( + id + |> option.unwrap(random_id()), + )) + } +} + +// Extract the ID value from a HTML node. +// +fn extract_id(node: html.Node(Event)) { + case node { + html.Element(_, attrs, _) -> find_id(attrs) + html.LeafElement(_, attrs) -> find_id(attrs) + _ -> Error(Nil) + } + |> result.unwrap(random_id()) +} + +// Find id attribute in a list of attrs. +// +fn find_id(attrs: List(attrs.Attr(Event))) { + attrs + |> list.find_map(fn(attr) { + case attr { + attrs.Attr("id", id) -> Ok(id) + _ -> Error(Nil) + } + }) +} + +// Generates a random ID for a HTML id attribute. +// +fn random_id() { + elem_id_prefix <> random_hex_string(3) +} + +// Check if list of attrs has id. +// +fn has_id(attrs: List(attrs.Attr(a))) { + attrs + |> list.any(fn(a) { + case a { + attrs.Attr("id", _) -> True + _ -> False + } + }) +} + +// Server ------------------------------------------------ + +/// Returns script tags to put into your own layout in order +/// for live mounts to work. +/// +pub fn script() { + html.Fragment([ + html.Element( + tag: "script", + attrs: [attrs.src("https://unpkg.com/htmx.org@1.9.2/dist/htmx.min.js")], + children: [], + ), + html.Element( + tag: "script", + attrs: [attrs.src("https://unpkg.com/htmx.org@1.9.2/dist/ext/ws.js")], + children: [], + ), + html.Element( + tag: "script", + attrs: [ + attrs.src("https://unpkg.com/idiomorph@0.0.8/dist/idiomorph-ext.min.js"), + ], + children: [], + ), + ]) +} + +fn default_layout(content: html.Node(Event)) { + html.Html( + [], + [html.Head([script()]), html.Body(attrs: [], children: [content])], + ) +} + +/// Configuration for a server. +/// +pub type Server { + Server( + port: Int, + layout: fn(html.Node(Event)) -> html.Node(Event), + handler: fn(Request(Body)) -> Response, + ) +} + +/// Creates a configuration for a server with default +/// layout. +/// +pub fn new(port: Int, handler: fn(Request(Body)) -> Response) { + Server(port, default_layout, handler) +} + +/// Start server. +/// +pub fn serve(server: Server) { + use manager <- result.try( + manager.start_manager() + |> result.map_error(fn(err) { + case err { + actor.InitTimeout -> glisten.AcceptorTimeout + actor.InitFailed(reason) -> glisten.AcceptorFailed(reason) + actor.InitCrashed(any) -> glisten.AcceptorCrashed(any) + } + }), + ) + + mist.serve(server.port, handler_func(manager, server.layout, server.handler)) +} + +fn handler_func( + manager: Subject(ManagerMessage), + layout: fn(html.Node(Event)) -> html.Node(Event), + handler: fn(Request(Body)) -> Response, +) { + // Return actual handler func + fn(req: Request(Body)) { + case req.method, req.path { + Get, "/connect" -> handle_ws_connect(manager, req) + _, _ -> + case handler(req) { + Response(status, headers, body) -> + response.new(status) + |> add_headers(headers) + |> to_mist_response(body) + View(status, headers, node) -> + response.new(status) + |> add_headers(headers) + |> mist.bit_builder_response( + manager.process_tree(manager, req, node) + |> layout + |> nakai.to_string_builder + |> bit_builder.from_string_builder, + ) + } + } + } + |> mist.handler_func +} + +fn add_headers(response: HttpResponse(a), headers: List(#(String, String))) { + headers + |> list.fold( + response, + fn(res, pair) { + res + |> response.prepend_header(pair.0, pair.1) + }, + ) +} + +fn to_mist_response(response, body: Option(String)) { + case body { + Some(body) -> + response + |> mist.bit_builder_response(bit_builder.from_string(body)) + None -> + response + |> mist.empty_response + } +} + +fn handle_ws_connect(manager: Subject(ManagerMessage), req: Request(Body)) { + case parse_params(req) { + Ok(#(id, csrf)) -> upgrade_connection(manager, id, csrf) + Error(Nil) -> + response.new(401) + |> mist.empty_response + } +} + +fn upgrade_connection( + manager: Subject(ManagerMessage), + session: String, + csrf: String, +) { + case manager.get_worker(manager, session, csrf) { + Ok(worker) -> + fn(_msg, _subject: Subject(HandlerMessage)) { Ok(Nil) } + |> websocket.with_handler + |> websocket.on_init(fn(socket: Subject(HandlerMessage)) { + worker.connect(worker, socket) + }) + |> websocket.on_close(fn(socket: Subject(HandlerMessage)) { + worker.disconnect(worker, socket) + }) + |> mist.upgrade + Error(Nil) -> + response.new(401) + |> mist.empty_response + } +} + +fn parse_params(req: Request(Body)) { + case req.query { + Some(params) -> + case uri.parse_query(params) { + Ok(params) -> + list.map( + params, + fn(p) { + #( + p.0, + p.1 + |> string.replace(" ", "+"), + ) + }, + ) + |> get_params + Error(Nil) -> Error(Nil) + } + None -> Error(Nil) + } +} + +fn get_params(params: List(#(String, String))) { + let pmap = map.from_list(params) + + use session <- result.then(map.get(pmap, "session")) + use csrf <- result.then(map.get(pmap, "csrf")) + + Ok(#(session, csrf)) +} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam new file mode 100644 index 00000000000..87e56938353 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/event.gleam @@ -0,0 +1,20 @@ +import gleam/erlang/process.{Selector} +import gliew/internal/worker.{WorkerMessage} + +// Event is a special type that can be added to attributes +// in HTML tree elements. +// That way we can just return a HTML tree of `html.Node(Event)` +// and later walk the tree to extract various data from it. +// +pub type Event { + // Instructs that the HTML node is the root of a mount + // and contains the selector function for the worker + // to know how to process updates. + LiveMount(selecting: fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)) + // Instructs us to add a `hx-swap-oob="morph"` to the + // mount. + Morph + // Instruct us to add `hx-swap-oob="beforeend"` to the + // mount. + Append +} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam new file mode 100644 index 00000000000..44f711a7286 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/manager.gleam @@ -0,0 +1,222 @@ +import gleam/map.{Map} +import gleam/list +import gleam/option.{None, Option, Some} +import gleam/result +import gleam/otp/actor +import gleam/erlang/process.{Selector, Subject} +import gleam/http/request.{Request} +import nakai +import nakai/html +import nakai/html/attrs +import mist.{Body} +import gliew/internal/event.{Event, LiveMount} +import gliew/internal/worker.{WorkerMessage} +import gliew/internal/util.{random_hex_string} + +const sess_id_prefix = "gliew-" + +const csrf_prefix = "g-" + +type LoopState { + LoopState(sessions: Map(String, Session)) +} + +type Session { + Session( + id: String, + csrf: String, + selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), + tree: html.Node(Event), + worker: Option(Subject(WorkerMessage)), + ) +} + +pub type Message { + ProcessTree( + from: Subject(html.Node(Event)), + request: Request(Body), + tree: html.Node(Event), + ) + GetWorker( + from: Subject(Result(Subject(WorkerMessage), Nil)), + id: String, + csrf: String, + ) +} + +pub fn start_manager() { + actor.start(LoopState(sessions: map.new()), loop) +} + +fn loop(message: Message, state: LoopState) -> actor.Next(LoopState) { + case message { + // Process tree + ProcessTree(from, _, tree) -> + case extract_selects([], tree) { + // Regular static view + [] -> { + process.send(from, tree) + + actor.Continue(state) + } + selects -> { + // Create a session ID + let sess_id = sess_id_prefix <> random_hex_string(10) + // Create a CSRF token + let csrf = csrf_prefix <> random_hex_string(24) + + process.send( + from, + tree + |> wrap_live_view(sess_id, csrf), + ) + + actor.Continue(LoopState( + sessions: state.sessions + |> map.insert(sess_id, Session(sess_id, csrf, selects, tree, None)), + )) + } + } + + // Get worker for session + GetWorker(from, id, csrf) -> { + case + state.sessions + |> map.get(id) + { + // Found session + Ok(sess) -> + case + sess + |> validate_session(csrf, _) + |> result.map(get_worker_from_sess) + |> result.flatten + { + // We got a worker + Ok(worker) -> { + process.send(from, Ok(worker)) + + state.sessions + |> map.insert(id, Session(..sess, worker: Some(worker))) + |> LoopState + |> actor.Continue + } + + // We failed to get a worker + Error(Nil) -> { + process.send(from, Error(Nil)) + actor.Continue(state) + } + } + + // Sessions does not exist + Error(Nil) -> { + process.send(from, Error(Nil)) + actor.Continue(state) + } + } + } + } +} + +// Validates that the provided csrf token matches +// the session's csrf. +// +fn validate_session(csrf: String, sess: Session) { + case sess { + Session(csrf: token, ..) if csrf == token -> Ok(sess) + _ -> Error(Nil) + } +} + +// Get a worker by either extracting it from the +// session or starting a new one. +// +fn get_worker_from_sess(sess: Session) { + case sess.worker { + // There's already a running worker we can + // return. + Some(worker) -> Ok(worker) + // There isn't a runnig worker so we need + // to start one. + None -> + case worker.start_worker(sess.selects) { + // Worker started successfully + Ok(worker) -> Ok(worker) + // Worker failed starting + Error(_) -> Error(Nil) + } + } +} + +// Walks the node tree until it finds a `LiveMount` event and adds +// its select function to the list of of all select functions +// in the tree. +// +fn extract_selects( + selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), + node: html.Node(Event), +) { + case node { + html.Element(_, attrs, children) -> + case extract_event(attrs) { + Ok(LiveMount(selector)) -> + selects + |> list.prepend(selector) + Error(Nil) -> + children + |> list.fold(selects, extract_selects) + } + html.LeafElement(_, attrs) -> + case extract_event(attrs) { + Ok(LiveMount(selector)) -> + selects + |> list.prepend(selector) + Error(Nil) -> selects + } + _ -> selects + } +} + +// Extract a single gliew event attribute. +// +fn extract_event(attrs: List(attrs.Attr(Event))) { + attrs + |> list.find_map(fn(attr) { + case attr { + attrs.Event("gliew-event", event) -> Ok(event) + _ -> Error(Nil) + } + }) +} + +// Wrap a container around a node tree containing any +// live mounts inside. +// This instructs htmx to make a websocket connection back +// to the server. +// +fn wrap_live_view(markup: html.Node(Event), session_id: String, csrf: String) { + html.div( + [ + attrs.Attr("hx-ext", "ws"), + attrs.Attr( + "ws-connect", + "/connect?session=" <> session_id <> "&csrf=" <> csrf, + ), + attrs.Attr("hx-ext", "morph"), + ], + [markup], + ) +} + +pub fn process_tree( + subject: Subject(Message), + request: Request(Body), + tree: html.Node(Event), +) { + process.call(subject, ProcessTree(_, request, tree), 1000) +} + +pub fn get_worker(manager: Subject(Message), id: String, csrf: String) { + process.call(manager, GetWorker(_, id, csrf), 1000) +} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam new file mode 100644 index 00000000000..3eb23e4a052 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/util.gleam @@ -0,0 +1,18 @@ +import gleam/int +import gleam/string +import gleam/crypto + +pub fn random_hex_string(len: Int) { + crypto.strong_random_bytes(len) + |> to_hex_string +} + +fn to_hex_string(bstr: BitString) { + case bstr { + <<>> -> "" + <> -> { + int.to_base16(a) + |> string.lowercase <> to_hex_string(rest) + } + } +} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam new file mode 100644 index 00000000000..36b0f78e703 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew/internal/worker.gleam @@ -0,0 +1,128 @@ +import gleam/io +import gleam/string +import gleam/list +import gleam/option.{None, Option, Some} +import gleam/function +import gleam/otp/actor +import gleam/erlang/process.{Selector, Subject, Timer} +import glisten/handler.{HandlerMessage} +import mist/websocket +import mist/internal/websocket.{TextMessage} as iws + +// inactivity timeout of 10 minutes +const timeout = 600_000 + +type State { + State( + self: Subject(WorkerMessage), + socket: Option(Subject(HandlerMessage)), + timer: Option(Timer), + ) +} + +pub type WorkerMessage { + LiveUpdate(markup: String) + ConnectSocket(socket: Subject(HandlerMessage)) + DisconnectSocket(socket: Subject(HandlerMessage)) + Shutdown +} + +pub fn start_worker( + selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), +) { + actor.start_spec(actor.Spec( + init: fn() { + let subject = process.new_subject() + + // Apply selectors from live mounts. + let selector = + process.new_selector() + |> process.selecting(subject, function.identity) + |> apply_selects(selects) + + // Send ourselves a shutdown timer that we will wait + // for a socket for. + let timer = process.send_after(subject, timeout, Shutdown) + + actor.Ready(State(subject, None, Some(timer)), selector) + }, + init_timeout: 1000, + loop: worker_loop, + )) +} + +fn worker_loop(msg: WorkerMessage, state: State) { + case msg { + // We got a new live mount update. + LiveUpdate(markup) -> + case state.socket { + // We have a socket to send data to. + Some(sock) -> { + // Send updated markup to websocket. + websocket.send(sock, TextMessage(markup)) + + actor.Continue(state) + } + // No socket is connected to the worker. + None -> actor.Continue(state) + } + // We got a socket to join. + ConnectSocket(sock) -> { + // Cancel timer + case state.timer { + Some(timer) -> { + process.cancel_timer(timer) + Nil + } + None -> Nil + } + + // Update state + actor.Continue(State(..state, socket: Some(sock), timer: None)) + } + // We should disconnect from socket. + DisconnectSocket(sock) -> + case state.socket { + // We have a socket and the socket matches + // the one we should disconnect from. + Some(socket) if sock == socket -> + // Send ourselves a Shutdown message after timeout. + process.send_after(state.self, timeout, Shutdown) + |> Some + |> State(state.self, None, _) + |> actor.Continue + // Either we don't have a socket or the + // one provided doesn't match so we + // ignore the message. + _ -> actor.Continue(state) + } + // We got a shutdown message. + Shutdown -> { + io.println( + "shutting down worker " <> string.inspect(process.subject_owner( + state.self, + )), + ) + actor.Stop(process.Normal) + } + } +} + +fn apply_selects( + selector: Selector(WorkerMessage), + selects: List(fn(Selector(WorkerMessage)) -> Selector(WorkerMessage)), +) { + selector + |> list.fold(selects, _, fn(selector, selecting) { selecting(selector) }) +} + +pub fn connect(worker: Subject(WorkerMessage), socket: Subject(HandlerMessage)) { + process.send(worker, ConnectSocket(socket)) +} + +pub fn disconnect( + worker: Subject(WorkerMessage), + socket: Subject(HandlerMessage), +) { + process.send(worker, DisconnectSocket(socket)) +} diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl new file mode 100644 index 00000000000..24d4dcdf4fa --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@event.erl @@ -0,0 +1,11 @@ +-module(gliew@internal@event). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([event/0]). + +-type event() :: {live_mount, + fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))} | + morph | + append. + + diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl new file mode 100644 index 00000000000..4686ce82cde --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@manager.erl @@ -0,0 +1,216 @@ +-module(gliew@internal@manager). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([process_tree/3, get_worker/3, start_manager/0]). +-export_type([loop_state/0, session/0, message/0]). + +-type loop_state() :: {loop_state, gleam@map:map_(binary(), session())}. + +-type session() :: {session, + binary(), + binary(), + list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))), + nakai@html:node_(gliew@internal@event:event()), + gleam@option:option(gleam@erlang@process:subject(gliew@internal@worker:worker_message()))}. + +-type message() :: {process_tree, + gleam@erlang@process:subject(nakai@html:node_(gliew@internal@event:event())), + gleam@http@request:request(mist@internal@http:body()), + nakai@html:node_(gliew@internal@event:event())} | + {get_worker, + gleam@erlang@process:subject({ok, + gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | + {error, nil}), + binary(), + binary()}. + +-spec validate_session(binary(), session()) -> {ok, session()} | {error, nil}. +validate_session(Csrf, Sess) -> + case Sess of + {session, _, Token, _, _, _} when Csrf =:= Token -> + {ok, Sess}; + + _ -> + {error, nil} + end. + +-spec get_worker_from_sess(session()) -> {ok, + gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | + {error, nil}. +get_worker_from_sess(Sess) -> + case erlang:element(6, Sess) of + {some, Worker} -> + {ok, Worker}; + + none -> + case gliew@internal@worker:start_worker(erlang:element(4, Sess)) of + {ok, Worker@1} -> + {ok, Worker@1}; + + {error, _} -> + {error, nil} + end + end. + +-spec extract_event(list(nakai@html@attrs:attr(gliew@internal@event:event()))) -> {ok, + gliew@internal@event:event()} | + {error, nil}. +extract_event(Attrs) -> + _pipe = Attrs, + gleam@list:find_map(_pipe, fun(Attr) -> case Attr of + {event, <<"gliew-event"/utf8>>, Event} -> + {ok, Event}; + + _ -> + {error, nil} + end end). + +-spec wrap_live_view( + nakai@html:node_(gliew@internal@event:event()), + binary(), + binary() +) -> nakai@html:node_(gliew@internal@event:event()). +wrap_live_view(Markup, Session_id, Csrf) -> + nakai@html:'div'( + [{attr, <<"hx-ext"/utf8>>, <<"ws"/utf8>>}, + {attr, + <<"ws-connect"/utf8>>, + <<<<<<"/connect?session="/utf8, Session_id/binary>>/binary, + "&csrf="/utf8>>/binary, + Csrf/binary>>}, + {attr, <<"hx-ext"/utf8>>, <<"morph"/utf8>>}], + [Markup] + ). + +-spec process_tree( + gleam@erlang@process:subject(message()), + gleam@http@request:request(mist@internal@http:body()), + nakai@html:node_(gliew@internal@event:event()) +) -> nakai@html:node_(gliew@internal@event:event()). +process_tree(Subject, Request, Tree) -> + gleam@erlang@process:call( + Subject, + fun(_capture) -> {process_tree, _capture, Request, Tree} end, + 1000 + ). + +-spec get_worker(gleam@erlang@process:subject(message()), binary(), binary()) -> {ok, + gleam@erlang@process:subject(gliew@internal@worker:worker_message())} | + {error, nil}. +get_worker(Manager, Id, Csrf) -> + gleam@erlang@process:call( + Manager, + fun(_capture) -> {get_worker, _capture, Id, Csrf} end, + 1000 + ). + +-spec extract_selects( + list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))), + nakai@html:node_(gliew@internal@event:event()) +) -> list(fun((gleam@erlang@process:selector(gliew@internal@worker:worker_message())) -> gleam@erlang@process:selector(gliew@internal@worker:worker_message()))). +extract_selects(Selects, Node) -> + case Node of + {element, _, Attrs, Children} -> + case extract_event(Attrs) of + {ok, {live_mount, Selector}} -> + _pipe = Selects, + gleam@list:prepend(_pipe, Selector); + + {error, nil} -> + _pipe@1 = Children, + gleam@list:fold(_pipe@1, Selects, fun extract_selects/2) + end; + + {leaf_element, _, Attrs@1} -> + case extract_event(Attrs@1) of + {ok, {live_mount, Selector@1}} -> + _pipe@2 = Selects, + gleam@list:prepend(_pipe@2, Selector@1); + + {error, nil} -> + Selects + end; + + _ -> + Selects + end. + +-spec loop(message(), loop_state()) -> gleam@otp@actor:next(loop_state()). +loop(Message, State) -> + case Message of + {process_tree, From, _, Tree} -> + case extract_selects([], Tree) of + [] -> + gleam@erlang@process:send(From, Tree), + {continue, State}; + + Selects -> + Sess_id = <<"gliew-"/utf8, + (gliew@internal@util:random_hex_string(10))/binary>>, + Csrf = <<"g-"/utf8, + (gliew@internal@util:random_hex_string(24))/binary>>, + gleam@erlang@process:send( + From, + begin + _pipe = Tree, + wrap_live_view(_pipe, Sess_id, Csrf) + end + ), + {continue, + {loop_state, + begin + _pipe@1 = erlang:element(2, State), + gleam@map:insert( + _pipe@1, + Sess_id, + {session, + Sess_id, + Csrf, + Selects, + Tree, + none} + ) + end}} + end; + + {get_worker, From@1, Id, Csrf@1} -> + case begin + _pipe@2 = erlang:element(2, State), + gleam@map:get(_pipe@2, Id) + end of + {ok, Sess} -> + case begin + _pipe@3 = Sess, + _pipe@4 = validate_session(Csrf@1, _pipe@3), + _pipe@5 = gleam@result:map( + _pipe@4, + fun get_worker_from_sess/1 + ), + gleam@result:flatten(_pipe@5) + end of + {ok, Worker} -> + gleam@erlang@process:send(From@1, {ok, Worker}), + _pipe@6 = erlang:element(2, State), + _pipe@7 = gleam@map:insert( + _pipe@6, + Id, + erlang:setelement(6, Sess, {some, Worker}) + ), + _pipe@8 = {loop_state, _pipe@7}, + {continue, _pipe@8}; + + {error, nil} -> + gleam@erlang@process:send(From@1, {error, nil}), + {continue, State} + end; + + {error, nil} -> + gleam@erlang@process:send(From@1, {error, nil}), + {continue, State} + end + end. + +-spec start_manager() -> {ok, gleam@erlang@process:subject(message())} | + {error, gleam@otp@actor:start_error()}. +start_manager() -> + gleam@otp@actor:start({loop_state, gleam@map:new()}, fun loop/2). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl new file mode 100644 index 00000000000..d5e9e805dbb --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@util.erl @@ -0,0 +1,23 @@ +-module(gliew@internal@util). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([random_hex_string/1]). + +-spec to_hex_string(bitstring()) -> binary(). +to_hex_string(Bstr) -> + case Bstr of + <<>> -> + <<""/utf8>>; + + <> -> + <<(begin + _pipe = gleam@int:to_base16(A), + gleam@string:lowercase(_pipe) + end)/binary, + (to_hex_string(Rest))/binary>> + end. + +-spec random_hex_string(integer()) -> binary(). +random_hex_string(Len) -> + _pipe = crypto:strong_rand_bytes(Len), + to_hex_string(_pipe). diff --git a/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl new file mode 100644 index 00000000000..090e6b398c1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gliew/src/gliew@internal@worker.erl @@ -0,0 +1,129 @@ +-module(gliew@internal@worker). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([start_worker/1, connect/2, disconnect/2]). +-export_type([state/0, worker_message/0]). + +-type state() :: {state, + gleam@erlang@process:subject(worker_message()), + gleam@option:option(gleam@erlang@process:subject(glisten@handler:handler_message())), + gleam@option:option(gleam@erlang@process:timer())}. + +-type worker_message() :: {live_update, binary()} | + {connect_socket, + gleam@erlang@process:subject(glisten@handler:handler_message())} | + {disconnect_socket, + gleam@erlang@process:subject(glisten@handler:handler_message())} | + shutdown. + +-spec worker_loop(worker_message(), state()) -> gleam@otp@actor:next(state()). +worker_loop(Msg, State) -> + case Msg of + {live_update, Markup} -> + case erlang:element(3, State) of + {some, Sock} -> + mist@websocket:send(Sock, {text_message, Markup}), + {continue, State}; + + none -> + {continue, State} + end; + + {connect_socket, Sock@1} -> + case erlang:element(4, State) of + {some, Timer} -> + gleam@erlang@process:cancel_timer(Timer), + nil; + + none -> + nil + end, + {continue, + erlang:setelement( + 4, + erlang:setelement(3, State, {some, Sock@1}), + none + )}; + + {disconnect_socket, Sock@2} -> + case erlang:element(3, State) of + {some, Socket} when Sock@2 =:= Socket -> + _pipe = gleam@erlang@process:send_after( + erlang:element(2, State), + 600000, + shutdown + ), + _pipe@1 = {some, _pipe}, + _pipe@2 = {state, erlang:element(2, State), none, _pipe@1}, + {continue, _pipe@2}; + + _ -> + {continue, State} + end; + + shutdown -> + gleam@io:println( + <<"shutting down worker "/utf8, + (gleam@string:inspect( + gleam@erlang@process:subject_owner( + erlang:element(2, State) + ) + ))/binary>> + ), + {stop, normal} + end. + +-spec apply_selects( + gleam@erlang@process:selector(worker_message()), + list(fun((gleam@erlang@process:selector(worker_message())) -> gleam@erlang@process:selector(worker_message()))) +) -> gleam@erlang@process:selector(worker_message()). +apply_selects(Selector, Selects) -> + _pipe = Selector, + gleam@list:fold( + Selects, + _pipe, + fun(Selector@1, Selecting) -> Selecting(Selector@1) end + ). + +-spec start_worker( + list(fun((gleam@erlang@process:selector(worker_message())) -> gleam@erlang@process:selector(worker_message()))) +) -> {ok, gleam@erlang@process:subject(worker_message())} | + {error, gleam@otp@actor:start_error()}. +start_worker(Selects) -> + gleam@otp@actor:start_spec( + {spec, + fun() -> + Subject = gleam@erlang@process:new_subject(), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Subject, + fun gleam@function:identity/1 + ), + apply_selects(_pipe@1, Selects) + end, + Timer = gleam@erlang@process:send_after( + Subject, + 600000, + shutdown + ), + {ready, {state, Subject, none, {some, Timer}}, Selector} + end, + 1000, + fun worker_loop/2} + ). + +-spec connect( + gleam@erlang@process:subject(worker_message()), + gleam@erlang@process:subject(glisten@handler:handler_message()) +) -> nil. +connect(Worker, Socket) -> + gleam@erlang@process:send(Worker, {connect_socket, Socket}). + +-spec disconnect( + gleam@erlang@process:subject(worker_message()), + gleam@erlang@process:subject(glisten@handler:handler_message()) +) -> nil. +disconnect(Worker, Socket) -> + gleam@erlang@process:send(Worker, {disconnect_socket, Socket}). diff --git a/test-community-packages-javascript/build/packages/glisten/README.md b/test-community-packages-javascript/build/packages/glisten/README.md new file mode 100644 index 00000000000..2a9db26bb3a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/README.md @@ -0,0 +1,132 @@ +# glisten + +See the docs [here](https://hexdocs.pm/glisten/). + +It uses the `gleam_otp` library to handle the supervisor and child processes. + +`glisten` provides a supervisor which manages a pool of acceptors. Each acceptor +will block on `accept` until a connection is opened. The acceptor will then +spawn a handler process and then block again on `accept`. + +The most obvious entrypoint is `glisten.{serve}` which listens for TCP +connections on a given port. It also takes a handler function wrapper +`handler.{func}` which you can provide functionality to, and the state which +each TCP connection process will hold. This takes the shape of: + +```gleam +type HandlerFunc(data) = + fn(BitString, LoopState(data)) -> actor.Next(LoopState(data)) +``` + +SSL is also handled using the `glisten.{serve_ssl}` method. This requires a +certificate and key file path. The rest of the handler flow remains unchanged. + +`glisten` doesn't provide a public API for connected clients. In order to hook +into the socket lifecyle, you can establish some functions which are called +for the opening and closing of the socket. An example is provided below. + +## Examples + +Here is a basic echo server: + +```gleam +import gleam/bit_builder +import gleam/erlang/process +import gleam/otp/actor +import gleam/result +import glisten/acceptor +import glisten/handler +import glisten/tcp +import glisten + +pub fn main() { + handler.func(fn(msg, state) { + assert Ok(_) = tcp.send(state.socket, bit_builder.from_bit_string(msg)) + actor.Continue(state) + }) + |> acceptor.new_pool + |> glisten.serve(8080, _) + |> result.map(fn(_) { process.sleep_forever() }) +} +``` + +To serve over SSL: + +```gleam +// ... +import glisten/ssl + +pub fn main() { + handler.func(fn(msg, state) { + assert Ok(_) = ssl.send(state.socket, bit_builder.from_bit_string(msg)) + actor.Continue(state) + }) + |> acceptor.new_pool + |> glisten.serve_ssl( + // Passing labeled arguments for clarity + port: 8080, + certfile: "/path/to/server.crt", + keyfile: "/path/to/server.key", + with_pool: _, + ) + |> result.map(fn(_) { process.sleep_forever() }) +} +``` + +Managing connected clients can be handled similarly to this simple example. +The `with_init` callback will be called after the SSL handshake, if the +underlying socket is set up to use it. + +```gleam +import gleam/bit_builder +import gleam/erlang/process +import glisten/handler +import glisten/tcp +import glisten + +pub fn main() { + // This function is omitted for brevity. It simply manages a + // `gleam/set.{Set}` of `Sender(HandlerMessage)`s that "broadcast" the + // connect/disconnect events to all clients. + assert Ok(connections) = start_connection_actor() + + handler.func(fn(msg, state) { + assert Ok(_) = tcp.send(state.socket, bit_builder.from_bit_string(msg)) + actor.Continue(state) + }) + |> acceptor.new_pool + |> acceptor.with_init(fn(sender) { + process.send(connections, Connected(sender)) + + Nil + }) + |> acceptor.with_close(fn(sender) { + process.send(connections, Disconnected(sender)) + + Nil + }) + |> glisten.serve(8080, _) + |> result.map(fn(_) { process.sleep_forever() }) +} +``` + +But you can also drop down to the lower level listen/accept flow if you'd prefer +to manage connections yourself, or only handle a small number at a time. + +```gleam +import gleam/io +import glisten/socket/options.{ActiveMode, Passive} +import glisten/tcp + +pub fn main() { + try listener = tcp.listen(8000, [ActiveMode(Passive)]) + try socket = tcp.accept(listener) + try msg = tcp.receive(socket, 0) + io.debug(#("got a msg", msg)) + + Ok(Nil) +} +``` + +See [mist](https://github.com/rawhat/mist) for HTTP support built on top of +this library. diff --git a/test-community-packages-javascript/build/packages/glisten/gleam.toml b/test-community-packages-javascript/build/packages/glisten/gleam.toml new file mode 100644 index 00000000000..f6cdc2792bf --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/gleam.toml @@ -0,0 +1,13 @@ +name = "glisten" +version = "0.7.0" +description = "a shiny Gleam TCP/SSL server" +licences = ["Apache-2.0"] +repository = { type = "github", user = "rawhat", repo = "glisten" } + +[dependencies] +gleam_stdlib = "~> 0.28" +gleam_otp = "~> 0.5" +gleam_erlang = "~> 0.18" + +[dev-dependencies] +gleeunit = "~> 0.6" diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl new file mode 100644 index 00000000000..0dd99accb49 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_AcceptorState.hrl @@ -0,0 +1,5 @@ +-record(acceptor_state, { + sender :: gleam@erlang@process:subject(glisten@acceptor:acceptor_message()), + socket :: gleam@option:option(glisten@socket:socket()), + transport :: glisten@socket@transport:transport() +}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl new file mode 100644 index 00000000000..71796ee3ea4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@acceptor_Pool.hrl @@ -0,0 +1,9 @@ +-record(pool, { + listener_socket :: glisten@socket:listen_socket(), + handler :: fun((glisten@handler:handler_message(), glisten@handler:loop_state(any())) -> gleam@otp@actor:next(glisten@handler:loop_state(any()))), + initial_data :: any(), + pool_count :: integer(), + on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + transport :: glisten@socket@transport:transport() +}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl new file mode 100644 index 00000000000..4f553b84c48 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Handler.hrl @@ -0,0 +1,8 @@ +-record(handler, { + socket :: glisten@socket:socket(), + initial_data :: any(), + loop :: fun((glisten@handler:handler_message(), glisten@handler:loop_state(any())) -> gleam@otp@actor:next(glisten@handler:loop_state(any()))), + on_init :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + on_close :: gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + transport :: glisten@socket@transport:transport() +}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl new file mode 100644 index 00000000000..8ba0b7f5452 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_LoopState.hrl @@ -0,0 +1,6 @@ +-record(loop_state, { + socket :: glisten@socket:socket(), + sender :: gleam@erlang@process:subject(glisten@handler:handler_message()), + transport :: glisten@socket@transport:transport(), + data :: any() +}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl new file mode 100644 index 00000000000..858335aa80c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Ssl.hrl @@ -0,0 +1 @@ +-record(ssl, {socket :: gleam@otp@port:port_(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl new file mode 100644 index 00000000000..2c0ad76b188 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@handler_Tcp.hrl @@ -0,0 +1 @@ +-record(tcp, {socket :: gleam@otp@port:port_(), data :: bitstring()}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl new file mode 100644 index 00000000000..c97154c6447 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Ssl.hrl @@ -0,0 +1,34 @@ +-record(ssl, { + accept :: fun((glisten@socket:listen_socket()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + accept_timeout :: fun((glisten@socket:listen_socket(), integer()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + close :: fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + controlling_process :: fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, + nil} | + {error, gleam@erlang@atom:atom_()}), + handshake :: fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | + {error, nil}), + listen :: fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, + glisten@socket:listen_socket()} | + {error, glisten@socket:socket_reason()}), + negotiated_protocol :: fun((glisten@socket:socket()) -> {ok, binary()} | + {error, binary()}), + 'receive' :: fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}), + receive_timeout :: fun((glisten@socket:socket(), integer(), integer()) -> {ok, + bitstring()} | + {error, glisten@socket:socket_reason()}), + send :: fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}), + set_opts :: fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, + nil} | + {error, nil}), + shutdown :: fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + socket_info :: fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic())) +}). diff --git a/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl new file mode 100644 index 00000000000..3d655dfb48f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/include/glisten@socket@transport_Tcp.hrl @@ -0,0 +1,34 @@ +-record(tcp, { + accept :: fun((glisten@socket:listen_socket()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + accept_timeout :: fun((glisten@socket:listen_socket(), integer()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + close :: fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + controlling_process :: fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, + nil} | + {error, gleam@erlang@atom:atom_()}), + handshake :: fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | + {error, nil}), + listen :: fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, + glisten@socket:listen_socket()} | + {error, glisten@socket:socket_reason()}), + negotiated_protocol :: fun((glisten@socket:socket()) -> {ok, binary()} | + {error, binary()}), + 'receive' :: fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}), + receive_timeout :: fun((glisten@socket:socket(), integer(), integer()) -> {ok, + bitstring()} | + {error, glisten@socket:socket_reason()}), + send :: fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}), + set_opts :: fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, + nil} | + {error, nil}), + shutdown :: fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + socket_info :: fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic())) +}). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src b/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src new file mode 100644 index 00000000000..c89d29a854d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten.app.src @@ -0,0 +1,18 @@ +{application, glisten, [ + {vsn, "0.7.0"}, + {applications, [gleam_erlang, + gleam_otp, + gleam_stdlib, + gleeunit]}, + {description, "a shiny Gleam TCP/SSL server"}, + {modules, [glisten, + glisten@acceptor, + glisten@handler, + glisten@logger, + glisten@socket, + glisten@socket@options, + glisten@socket@transport, + glisten@ssl, + glisten@tcp]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten.erl new file mode 100644 index 00000000000..b29f20f1fff --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten.erl @@ -0,0 +1,102 @@ +-module(glisten). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([serve/2, serve_ssl/4]). +-export_type([start_error/0]). + +-type start_error() :: listener_closed | + listener_timeout | + acceptor_timeout | + {acceptor_failed, gleam@erlang@process:exit_reason()} | + {acceptor_crashed, gleam@dynamic:dynamic()} | + {system_error, glisten@socket:socket_reason()}. + +-spec serve( + integer(), + fun((glisten@socket:listen_socket()) -> glisten@acceptor:pool(any())) +) -> {ok, nil} | {error, start_error()}. +serve(Port, With_pool) -> + _pipe = Port, + _pipe@1 = glisten@tcp:listen(_pipe, []), + _pipe@2 = gleam@result:map_error(_pipe@1, fun(Err) -> case Err of + closed -> + listener_closed; + + timeout -> + listener_timeout; + + Err@1 -> + {system_error, Err@1} + end end), + _pipe@6 = gleam@result:then( + _pipe@2, + fun(Socket) -> + _pipe@3 = Socket, + _pipe@4 = With_pool(_pipe@3), + _pipe@5 = glisten@acceptor:start_pool(_pipe@4), + gleam@result:map_error(_pipe@5, fun(Err@2) -> case Err@2 of + init_timeout -> + acceptor_timeout; + + {init_failed, Reason} -> + {acceptor_failed, Reason}; + + {init_crashed, Reason@1} -> + {acceptor_crashed, Reason@1} + end end) + end + ), + gleam@result:replace(_pipe@6, nil). + +-spec serve_ssl( + integer(), + binary(), + binary(), + fun((glisten@socket:listen_socket()) -> glisten@acceptor:pool(any())) +) -> {ok, nil} | {error, start_error()}. +serve_ssl(Port, Certfile, Keyfile, With_pool) -> + _assert_subject = ssl_ffi:start_ssl(), + {ok, _} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"glisten"/utf8>>, + function => <<"serve_ssl"/utf8>>, + line => 62}) + end, + _pipe = Port, + _pipe@1 = glisten@ssl:listen( + _pipe, + [{certfile, Certfile}, {keyfile, Keyfile}] + ), + _pipe@2 = gleam@result:map_error(_pipe@1, fun(Err) -> case Err of + closed -> + listener_closed; + + timeout -> + listener_timeout; + + Err@1 -> + {system_error, Err@1} + end end), + _pipe@6 = gleam@result:then( + _pipe@2, + fun(Socket) -> + _pipe@3 = Socket, + _pipe@4 = (glisten@acceptor:over_ssl(With_pool))(_pipe@3), + _pipe@5 = glisten@acceptor:start_pool(_pipe@4), + gleam@result:map_error(_pipe@5, fun(Err@2) -> case Err@2 of + init_timeout -> + acceptor_timeout; + + {init_failed, Reason} -> + {acceptor_failed, Reason}; + + {init_crashed, Reason@1} -> + {acceptor_crashed, Reason@1} + end end) + end + ), + gleam@result:replace(_pipe@6, nil). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam new file mode 100644 index 00000000000..74a51ee3e9c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten.gleam @@ -0,0 +1,85 @@ +import gleam/dynamic.{Dynamic} +import gleam/erlang/process +import gleam/result +import glisten/acceptor.{Pool, over_ssl} +import glisten/socket.{Closed, ListenSocket, SocketReason, Timeout} +import glisten/tcp +import glisten/ssl +import gleam/otp/actor +import glisten/socket/options.{Certfile, Keyfile} + +/// Reasons that `serve` might fail +pub type StartError { + ListenerClosed + ListenerTimeout + AcceptorTimeout + AcceptorFailed(process.ExitReason) + AcceptorCrashed(Dynamic) + SystemError(SocketReason) +} + +/// Sets up a TCP listener with the given acceptor pool. The second argument +/// can be obtained from the `glisten/acceptor.{acceptor_pool}` function. +pub fn serve( + port: Int, + with_pool: fn(ListenSocket) -> Pool(data), +) -> Result(Nil, StartError) { + port + |> tcp.listen([]) + |> result.map_error(fn(err) { + case err { + Closed -> ListenerClosed + Timeout -> ListenerTimeout + err -> SystemError(err) + } + }) + |> result.then(fn(socket) { + socket + |> with_pool + |> acceptor.start_pool + |> result.map_error(fn(err) { + case err { + actor.InitTimeout -> AcceptorTimeout + actor.InitFailed(reason) -> AcceptorFailed(reason) + actor.InitCrashed(reason) -> AcceptorCrashed(reason) + } + }) + }) + |> result.replace(Nil) +} + +external fn start_ssl() -> Result(Nil, Dynamic) = + "ssl_ffi" "start_ssl" + +/// Sets up a SSL listener with the given acceptor pool. The second argument +/// can be obtained from the `glisten/acceptor.{acceptor_pool}` function. +pub fn serve_ssl( + port port: Int, + certfile certfile: String, + keyfile keyfile: String, + with_pool with_pool: fn(ListenSocket) -> Pool(data), +) -> Result(Nil, StartError) { + let assert Ok(_nil) = start_ssl() + port + |> ssl.listen([Certfile(certfile), Keyfile(keyfile)]) + |> result.map_error(fn(err) { + case err { + Closed -> ListenerClosed + Timeout -> ListenerTimeout + err -> SystemError(err) + } + }) + |> result.then(fn(socket) { + socket + |> over_ssl(with_pool) + |> acceptor.start_pool + |> result.map_error(fn(err) { + case err { + actor.InitTimeout -> AcceptorTimeout + actor.InitFailed(reason) -> AcceptorFailed(reason) + actor.InitCrashed(reason) -> AcceptorCrashed(reason) + } + }) + }) + |> result.replace(Nil) +} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam new file mode 100644 index 00000000000..3237bf0c82d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/acceptor.gleam @@ -0,0 +1,204 @@ +import gleam/erlang/process.{Abnormal, Subject} +import gleam/function +import gleam/iterator +import gleam/option.{None, Option, Some} +import gleam/otp/actor +import gleam/otp/supervisor +import gleam/result +import glisten/handler.{Handler, HandlerMessage, LoopFn, Ready} +import glisten/logger +import glisten/socket.{ListenSocket, Socket} +import glisten/socket/transport.{Transport} + +pub type AcceptorMessage { + AcceptConnection(ListenSocket) +} + +pub type AcceptorError { + AcceptError + HandlerError + ControlError +} + +pub type AcceptorState { + AcceptorState( + sender: Subject(AcceptorMessage), + socket: Option(Socket), + transport: Transport, + ) +} + +/// Worker process that handles `accept`ing connections and starts a new process +/// which receives the messages from the socket +pub fn start( + pool: Pool(data), +) -> Result(Subject(AcceptorMessage), actor.StartError) { + actor.start_spec(actor.Spec( + init: fn() { + let subject = process.new_subject() + let selector = + process.new_selector() + |> process.selecting(subject, function.identity) + + process.send(subject, AcceptConnection(pool.listener_socket)) + + actor.Ready(AcceptorState(subject, None, pool.transport), selector) + }, + // TODO: rethink this value, probably... + init_timeout: 1000, + loop: fn(msg, state) { + let AcceptorState(sender, ..) = state + case msg { + AcceptConnection(listener) -> { + let res = { + use sock <- result.then( + state.transport.accept(listener) + |> result.replace_error(AcceptError), + ) + use start <- result.then( + Handler( + sock, + pool.initial_data, + pool.handler, + pool.on_init, + pool.on_close, + pool.transport, + ) + |> handler.start + |> result.replace_error(HandlerError), + ) + sock + |> state.transport.controlling_process(process.subject_owner(start)) + |> result.replace_error(ControlError) + |> result.map(fn(_) { process.send(start, Ready) }) + } + case res { + Error(reason) -> { + logger.error(#("Failed to accept/start handler", reason)) + actor.Stop(Abnormal("Failed to accept/start handler")) + } + _val -> { + actor.send(sender, AcceptConnection(listener)) + actor.Continue(state) + } + } + } + msg -> { + logger.error(#("Unknown message type", msg)) + actor.Stop(process.Abnormal("Unknown message type")) + } + } + }, + )) +} + +pub type Pool(data) { + Pool( + listener_socket: ListenSocket, + handler: LoopFn(data), + initial_data: data, + pool_count: Int, + on_init: Option(fn(Subject(HandlerMessage)) -> Nil), + on_close: Option(fn(Subject(HandlerMessage)) -> Nil), + transport: Transport, + ) +} + +/// Initialize acceptor pool where each handler has no state +pub fn new_pool(handler: LoopFn(Nil)) -> fn(ListenSocket) -> Pool(Nil) { + fn(listener_socket) { + Pool( + listener_socket: listener_socket, + handler: handler, + initial_data: Nil, + pool_count: 10, + on_init: None, + on_close: None, + transport: transport.tcp(), + ) + } +} + +/// Initialize an acceptor pool where each handler holds some state +pub fn new_pool_with_data( + handler: LoopFn(data), + initial_data: data, +) -> fn(ListenSocket) -> Pool(data) { + fn(listener_socket) { + Pool( + listener_socket: listener_socket, + handler: handler, + initial_data: initial_data, + pool_count: 10, + on_init: None, + on_close: None, + transport: transport.tcp(), + ) + } +} + +/// Add an `on_init` handler to the acceptor pool +pub fn with_init( + make_pool: fn(ListenSocket) -> Pool(data), + func: fn(Subject(HandlerMessage)) -> Nil, +) -> fn(ListenSocket) -> Pool(data) { + fn(socket) { + let pool = make_pool(socket) + Pool(..pool, on_init: Some(func)) + } +} + +/// Add an `on_close` handler to the acceptor pool +pub fn with_close( + make_pool: fn(ListenSocket) -> Pool(data), + func: fn(Subject(HandlerMessage)) -> Nil, +) -> fn(ListenSocket) -> Pool(data) { + fn(socket) { + let pool = make_pool(socket) + Pool(..pool, on_close: Some(func)) + } +} + +/// Adjust the number of TCP acceptors in the pool +pub fn with_pool_size( + make_pool: fn(ListenSocket) -> Pool(data), + pool_count: Int, +) -> fn(ListenSocket) -> Pool(data) { + fn(socket) { + let pool = make_pool(socket) + Pool(..pool, pool_count: pool_count) + } +} + +/// Use SSL for the underlying socket. +pub fn over_ssl( + make_pool: fn(ListenSocket) -> Pool(data), +) -> fn(ListenSocket) -> Pool(data) { + fn(socket) { + let pool = make_pool(socket) + Pool(..pool, transport: transport.ssl()) + } +} + +/// Starts a pool of acceptors of size `pool_count`. +/// +/// Runs `loop_fn` on ever message received +pub fn start_pool( + pool: Pool(data), +) -> Result(Subject(supervisor.Message), actor.StartError) { + supervisor.start_spec(supervisor.Spec( + argument: Nil, + // TODO: i think these might need some tweaking + max_frequency: 100, + frequency_period: 1, + init: fn(children) { + iterator.range(from: 0, to: pool.pool_count) + |> iterator.fold( + children, + fn(children, _index) { + supervisor.add(children, supervisor.worker(fn(_arg) { start(pool) })) + }, + ) + }, + )) +} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam new file mode 100644 index 00000000000..d5e8d9348e5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/handler.gleam @@ -0,0 +1,160 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/dynamic +import gleam/erlang/process.{Subject} +import gleam/function +import gleam/option.{Option, Some} +import gleam/otp/actor +import gleam/otp/port.{Port} +import gleam/result +import gleam/string +import glisten/logger +import glisten/socket.{Socket} +import glisten/socket/transport.{Transport} +import glisten/socket/options + +/// All message types that the handler will receive, or that you can +/// send to the handler process +pub type HandlerMessage { + Close + Ready + ReceiveMessage(BitString) + SendMessage(BitBuilder) + Ssl(socket: Port, data: BitString) + SslClosed(Nil) + Tcp(socket: Port, data: BitString) + TcpClosed(Nil) +} + +pub type LoopState(data) { + LoopState( + socket: Socket, + sender: Subject(HandlerMessage), + transport: Transport, + data: data, + ) +} + +pub type LoopFn(data) = + fn(HandlerMessage, LoopState(data)) -> actor.Next(LoopState(data)) + +pub type Handler(data) { + Handler( + socket: Socket, + initial_data: data, + loop: LoopFn(data), + on_init: Option(fn(Subject(HandlerMessage)) -> Nil), + on_close: Option(fn(Subject(HandlerMessage)) -> Nil), + transport: Transport, + ) +} + +/// Starts an actor for the TCP connection +pub fn start( + handler: Handler(data), +) -> Result(Subject(HandlerMessage), actor.StartError) { + actor.start_spec(actor.Spec( + init: fn() { + let subject = process.new_subject() + let selector = + process.new_selector() + |> process.selecting(subject, function.identity) + |> process.selecting_anything(fn(msg) { + case dynamic.unsafe_coerce(msg) { + Tcp(_sock, data) | Ssl(_sock, data) -> ReceiveMessage(data) + msg -> msg + } + }) + actor.Ready( + LoopState( + handler.socket, + subject, + handler.transport, + data: handler.initial_data, + ), + selector, + ) + }, + init_timeout: 1000, + loop: fn(msg, state) { + case msg { + TcpClosed(_) | SslClosed(_) | Close -> + case state.transport.close(state.socket) { + Ok(Nil) -> { + let _ = case handler.on_close { + Some(func) -> func(state.sender) + _ -> Nil + } + actor.Stop(process.Normal) + } + Error(err) -> actor.Stop(process.Abnormal(string.inspect(err))) + } + Ready -> + state.socket + |> state.transport.handshake + |> result.replace_error("Failed to handshake socket") + |> result.map(fn(_ok) { + let _ = case handler.on_init { + Some(func) -> func(state.sender) + _ -> Nil + } + }) + |> result.then(fn(_ok) { + state.transport.set_opts( + state.socket, + [options.ActiveMode(options.Once)], + ) + |> result.replace_error("Failed to set socket active") + }) + |> result.replace(actor.Continue(state)) + |> result.map_error(fn(reason) { + actor.Stop(process.Abnormal(reason)) + }) + |> result.unwrap_both + msg -> + case handler.loop(msg, state) { + actor.Continue(next_state) -> { + let assert Ok(Nil) = + state.transport.set_opts( + state.socket, + [options.ActiveMode(options.Once)], + ) + actor.Continue(next_state) + } + msg -> msg + } + } + }, + )) +} + +pub type HandlerFunc(data) = + fn(BitString, LoopState(data)) -> actor.Next(LoopState(data)) + +/// This helper will generate a TCP handler that will call your handler function +/// with the BitString data in the packet as well as the LoopState, with any +/// associated state data you are maintaining +pub fn func(handler func: HandlerFunc(data)) -> LoopFn(data) { + fn(msg, state: LoopState(data)) { + case msg { + Tcp(_, _) | Ready -> { + logger.error(#("Received an unexpected TCP message", msg)) + actor.Continue(state) + } + ReceiveMessage(data) -> func(data, state) + SendMessage(data) -> + case state.transport.send(state.socket, data) { + Ok(_nil) -> actor.Continue(state) + Error(reason) -> { + logger.error(#("Failed to send data", reason)) + actor.Stop(process.Abnormal("Failed to send data")) + } + } + // NOTE: this should never happen. This function is only called _after_ + // the other message types are handled + msg -> { + logger.error(#("Unhandled TCP message", msg)) + actor.Stop(process.Abnormal("Unhandled TCP message")) + } + } + } +} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam new file mode 100644 index 00000000000..14a31a6ce54 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/logger.gleam @@ -0,0 +1,8 @@ +import gleam/erlang/charlist.{Charlist} + +external fn log_error(format: Charlist, data: any) -> Nil = + "logger" "error" + +pub fn error(data: any) -> Nil { + log_error(charlist.from_string("~tp"), [data]) +} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam new file mode 100644 index 00000000000..95aca833ceb --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket.gleam @@ -0,0 +1,93 @@ +pub type SocketReason { + Closed + Timeout + Badarg + Terminated + + // inet:posix() errors. + Eaddrinuse + Eaddrnotavail + Eafnosupport + Ealready + Econnaborted + Econnrefused + Econnreset + Edestaddrreq + Ehostdown + Ehostunreach + Einprogress + Eisconn + Emsgsize + Enetdown + Enetunreach + Enopkg + Enoprotoopt + Enotconn + Enotty + Enotsock + Eproto + Eprotonosupport + Eprototype + Esocktnosupport + Etimedout + Ewouldblock + Exbadport + Exbadseq + + // file:posix() errors. + Eacces + Eagain + Ebadf + Ebadmsg + Ebusy + Edeadlk + Edeadlock + Edquot + Eexist + Efault + Efbig + Eftype + Eintr + Einval + Eio + Eisdir + Eloop + Emfile + Emlink + Emultihop + Enametoolong + Enfile + Enobufs + Enodev + Enolck + Enolink + Enoent + Enomem + Enospc + Enosr + Enostr + Enosys + Enotblk + Enotdir + Enotsup + Enxio + Eopnotsupp + Eoverflow + Eperm + Epipe + Erange + Erofs + Espipe + Esrch + Estale + Etxtbsy + Exdev +} + +pub opaque type ListenSocket { + ListenSocket +} + +pub opaque type Socket { + Socket +} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam new file mode 100644 index 00000000000..86766c2296a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/options.gleam @@ -0,0 +1,83 @@ +import gleam/dynamic.{Dynamic} +import gleam/erlang/atom +import gleam/list +import gleam/map.{Map} +import gleam/pair + +/// Mode for the socket. Currently `list` is not supported +pub type SocketMode { + Binary +} + +/// Mapping to the {active, _} option +pub type ActiveState { + Once + Passive + Count(Int) + // This is dumb and annoying. I'd much prefer `True` or `Active`, but both + // of those make this a lot more annoying to work with + Active +} + +/// Options for the TCP socket +pub type TcpOption { + Backlog(Int) + Nodelay(Bool) + Linger(#(Bool, Int)) + SendTimeout(Int) + SendTimeoutClose(Bool) + Reuseaddr(Bool) + ActiveMode(ActiveState) + Mode(SocketMode) + // TODO: Probably should adjust the type here to only allow this for SSL + Certfile(String) + Keyfile(String) + AlpnPreferredProtocols(List(String)) +} + +pub fn to_map(options: List(TcpOption)) -> Map(atom.Atom, Dynamic) { + let opt_decoder = dynamic.tuple2(dynamic.dynamic, dynamic.dynamic) + + options + |> list.map(fn(opt) { + case opt { + ActiveMode(Passive) -> + dynamic.from(#(atom.create_from_string("active"), False)) + ActiveMode(Active) -> + dynamic.from(#(atom.create_from_string("active"), True)) + ActiveMode(Count(n)) -> + dynamic.from(#(atom.create_from_string("active"), n)) + ActiveMode(Once) -> + dynamic.from(#( + atom.create_from_string("active"), + atom.create_from_string("once"), + )) + other -> dynamic.from(other) + } + }) + |> list.filter_map(opt_decoder) + |> list.map(pair.map_first(_, dynamic.unsafe_coerce)) + |> map.from_list +} + +const default_options = [ + Backlog(1024), + Nodelay(True), + Linger(#(True, 30)), + SendTimeout(30_000), + SendTimeoutClose(True), + Reuseaddr(True), + Mode(Binary), + ActiveMode(Passive), +] + +pub fn merge_with_defaults(options: List(TcpOption)) -> List(TcpOption) { + let overrides = to_map(options) + + default_options + |> to_map + |> map.merge(overrides) + |> map.to_list + |> list.map(dynamic.from) + |> list.map(dynamic.unsafe_coerce) +} diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam new file mode 100644 index 00000000000..4e64c806241 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/socket/transport.gleam @@ -0,0 +1,122 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/dynamic.{Dynamic} +import gleam/erlang/atom.{Atom} +import gleam/erlang/process.{Pid} +import gleam/map.{Map} +import glisten/socket/options +import glisten/socket.{ListenSocket, Socket, SocketReason} +import glisten/ssl +import glisten/tcp + +type ControllingProcess = + fn(Socket, Pid) -> Result(Nil, Atom) + +type Listen = + fn(Int, List(options.TcpOption)) -> Result(ListenSocket, SocketReason) + +type AcceptTimeout = + fn(ListenSocket, Int) -> Result(Socket, SocketReason) + +type Accept = + fn(ListenSocket) -> Result(Socket, SocketReason) + +type ReceiveTimeout = + fn(Socket, Int, Int) -> Result(BitString, SocketReason) + +type Receive = + fn(Socket, Int) -> Result(BitString, SocketReason) + +type Send = + fn(Socket, BitBuilder) -> Result(Nil, SocketReason) + +type SocketInfo = + fn(Socket) -> Map(Atom, Dynamic) + +type Close = + fn(Socket) -> Result(Nil, SocketReason) + +type Shutdown = + fn(Socket) -> Result(Nil, SocketReason) + +type SetOpts = + fn(Socket, List(options.TcpOption)) -> Result(Nil, Nil) + +type Handshake = + fn(Socket) -> Result(Socket, Nil) + +type NegotiatedProtocol = + fn(Socket) -> Result(String, String) + +pub type Transport { + Ssl( + accept: Accept, + accept_timeout: AcceptTimeout, + close: Close, + controlling_process: ControllingProcess, + handshake: Handshake, + listen: Listen, + negotiated_protocol: NegotiatedProtocol, + receive: Receive, + receive_timeout: ReceiveTimeout, + send: Send, + set_opts: SetOpts, + shutdown: Shutdown, + socket_info: SocketInfo, + ) + Tcp( + accept: Accept, + accept_timeout: AcceptTimeout, + close: Close, + controlling_process: ControllingProcess, + handshake: Handshake, + listen: Listen, + negotiated_protocol: NegotiatedProtocol, + receive: Receive, + receive_timeout: ReceiveTimeout, + send: Send, + set_opts: SetOpts, + shutdown: Shutdown, + socket_info: SocketInfo, + ) +} + +pub fn tcp() -> Transport { + Tcp( + accept: tcp.accept, + accept_timeout: tcp.accept_timeout, + close: tcp.close, + controlling_process: tcp.controlling_process, + handshake: tcp.handshake, + listen: tcp.listen, + negotiated_protocol: fn(_socket) { + Error("Can't negotiate protocol on tcp") + }, + receive: tcp.receive, + receive_timeout: tcp.receive_timeout, + send: tcp.send, + set_opts: tcp.set_opts, + shutdown: tcp.shutdown, + socket_info: socket_info, + ) +} + +pub fn ssl() -> Transport { + Ssl( + accept: ssl.accept, + accept_timeout: ssl.accept_timeout, + close: ssl.close, + controlling_process: ssl.controlling_process, + handshake: ssl.handshake, + listen: ssl.listen, + negotiated_protocol: ssl.negotiated_protocol, + receive: ssl.receive, + receive_timeout: ssl.receive_timeout, + send: ssl.send, + set_opts: ssl.set_opts, + shutdown: ssl.shutdown, + socket_info: socket_info, + ) +} + +pub external fn socket_info(socket: Socket) -> Map(a, b) = + "socket" "info" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam new file mode 100644 index 00000000000..a3cd828f3df --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/ssl.gleam @@ -0,0 +1,93 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/dynamic.{Dynamic} +import gleam/erlang/atom.{Atom} +import gleam/erlang/process.{Pid} +import gleam/list +import gleam/map +import glisten/socket.{ListenSocket, Socket, SocketReason} +import glisten/socket/options + +pub external fn controlling_process( + socket: Socket, + pid: Pid, +) -> Result(Nil, Atom) = + "ssl_ffi" "controlling_process" + +external fn do_listen( + port: Int, + options: List(options.TcpOption), +) -> Result(ListenSocket, SocketReason) = + "ssl" "listen" + +pub external fn accept_timeout( + socket: ListenSocket, + timeout: Int, +) -> Result(Socket, SocketReason) = + "ssl" "transport_accept" + +pub external fn accept(socket: ListenSocket) -> Result(Socket, SocketReason) = + "ssl" "transport_accept" + +pub external fn receive_timeout( + socket: Socket, + length: Int, + timeout: Int, +) -> Result(BitString, SocketReason) = + "ssl" "recv" + +pub external fn receive( + socket: Socket, + length: Int, +) -> Result(BitString, SocketReason) = + "ssl" "recv" + +pub external fn send( + socket: Socket, + packet: BitBuilder, +) -> Result(Nil, SocketReason) = + "ssl_ffi" "send" + +pub external fn close(socket: Socket) -> Result(Nil, SocketReason) = + "ssl_ffi" "close" + +pub external fn do_shutdown( + socket: Socket, + write: Atom, +) -> Result(Nil, SocketReason) = + "ssl_ffi" "shutdown" + +pub fn shutdown(socket: Socket) -> Result(Nil, SocketReason) { + let assert Ok(write) = atom.from_string("write") + do_shutdown(socket, write) +} + +external fn do_set_opts(socket: Socket, opts: List(Dynamic)) -> Result(Nil, Nil) = + "ssl_ffi" "set_opts" + +/// Update the optons for a socket (mutates the socket) +pub fn set_opts( + socket: Socket, + opts: List(options.TcpOption), +) -> Result(Nil, Nil) { + opts + |> options.to_map + |> map.to_list + |> list.map(dynamic.from) + |> do_set_opts(socket, _) +} + +pub external fn handshake(socket: Socket) -> Result(Socket, Nil) = + "ssl" "handshake" + +/// Start listening over SSL on a port with the given options +pub fn listen( + port: Int, + options: List(options.TcpOption), +) -> Result(ListenSocket, SocketReason) { + options + |> options.merge_with_defaults + |> do_listen(port, _) +} + +pub external fn negotiated_protocol(socket: Socket) -> Result(String, String) = + "ssl_ffi" "negotiated_protocol" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam b/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam new file mode 100644 index 00000000000..55c15372879 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten/tcp.gleam @@ -0,0 +1,94 @@ +import gleam/bit_builder.{BitBuilder} +import gleam/dynamic.{Dynamic} +import gleam/erlang/atom.{Atom} +import gleam/erlang/process.{Pid} +import gleam/list +import gleam/map.{Map} +import glisten/socket.{ListenSocket, Socket, SocketReason} +import glisten/socket/options.{TcpOption} + +pub external fn controlling_process( + socket: Socket, + pid: Pid, +) -> Result(Nil, Atom) = + "tcp_ffi" "controlling_process" + +external fn do_listen_tcp( + port: Int, + options: List(TcpOption), +) -> Result(ListenSocket, SocketReason) = + "gen_tcp" "listen" + +pub external fn accept_timeout( + socket: ListenSocket, + timeout: Int, +) -> Result(Socket, SocketReason) = + "gen_tcp" "accept" + +pub external fn accept(socket: ListenSocket) -> Result(Socket, SocketReason) = + "gen_tcp" "accept" + +pub external fn receive_timeout( + socket: Socket, + length: Int, + timeout: Int, +) -> Result(BitString, SocketReason) = + "gen_tcp" "recv" + +pub external fn receive( + socket: Socket, + length: Int, +) -> Result(BitString, SocketReason) = + "gen_tcp" "recv" + +pub external fn send( + socket: Socket, + packet: BitBuilder, +) -> Result(Nil, SocketReason) = + "tcp_ffi" "send" + +pub external fn socket_info(socket: Socket) -> Map(a, b) = + "socket" "info" + +pub external fn close(socket: a) -> Result(Nil, SocketReason) = + "tcp_ffi" "close" + +pub external fn do_shutdown( + socket: Socket, + write: Atom, +) -> Result(Nil, SocketReason) = + "tcp_ffi" "shutdown" + +pub fn shutdown(socket: Socket) -> Result(Nil, SocketReason) { + let assert Ok(write) = atom.from_string("write") + do_shutdown(socket, write) +} + +external fn do_set_opts(socket: Socket, opts: List(Dynamic)) -> Result(Nil, Nil) = + "tcp_ffi" "set_opts" + +/// Update the optons for a socket (mutates the socket) +pub fn set_opts(socket: Socket, opts: List(TcpOption)) -> Result(Nil, Nil) { + opts + |> options.to_map + |> map.to_list + |> list.map(dynamic.from) + |> do_set_opts(socket, _) +} + +/// Start listening over TCP on a port with the given options +pub fn listen( + port: Int, + options: List(TcpOption), +) -> Result(ListenSocket, SocketReason) { + options + |> options.merge_with_defaults + |> do_listen_tcp(port, _) +} + +pub fn handshake(socket: Socket) -> Result(Socket, Nil) { + Ok(socket) +} + +pub external fn negotiated_protocol(socket: Socket) -> a = + "tcp" "negotiated_protocol" diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl new file mode 100644 index 00000000000..1b5c360d729 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@acceptor.erl @@ -0,0 +1,232 @@ +-module(glisten@acceptor). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([start/1, new_pool/1, new_pool_with_data/2, with_init/2, with_close/2, with_pool_size/2, over_ssl/1, start_pool/1]). +-export_type([acceptor_message/0, acceptor_error/0, acceptor_state/0, pool/1]). + +-type acceptor_message() :: {accept_connection, glisten@socket:listen_socket()}. + +-type acceptor_error() :: accept_error | handler_error | control_error. + +-type acceptor_state() :: {acceptor_state, + gleam@erlang@process:subject(acceptor_message()), + gleam@option:option(glisten@socket:socket()), + glisten@socket@transport:transport()}. + +-type pool(GRD) :: {pool, + glisten@socket:listen_socket(), + fun((glisten@handler:handler_message(), glisten@handler:loop_state(GRD)) -> gleam@otp@actor:next(glisten@handler:loop_state(GRD))), + GRD, + integer(), + gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + gleam@option:option(fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil)), + glisten@socket@transport:transport()}. + +-spec start(pool(any())) -> {ok, + gleam@erlang@process:subject(acceptor_message())} | + {error, gleam@otp@actor:start_error()}. +start(Pool) -> + gleam@otp@actor:start_spec( + {spec, + fun() -> + Subject = gleam@erlang@process:new_subject(), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + gleam@erlang@process:selecting( + _pipe, + Subject, + fun gleam@function:identity/1 + ) + end, + gleam@erlang@process:send( + Subject, + {accept_connection, erlang:element(2, Pool)} + ), + {ready, + {acceptor_state, Subject, none, erlang:element(8, Pool)}, + Selector} + end, + 1000, + fun(Msg, State) -> + {acceptor_state, Sender, _, _} = State, + case Msg of + {accept_connection, Listener} -> + Res = begin + gleam@result:then( + begin + _pipe@1 = (erlang:element( + 2, + erlang:element(4, State) + ))(Listener), + gleam@result:replace_error( + _pipe@1, + accept_error + ) + end, + fun(Sock) -> + gleam@result:then( + begin + _pipe@2 = {handler, + Sock, + erlang:element(4, Pool), + erlang:element(3, Pool), + erlang:element(6, Pool), + erlang:element(7, Pool), + erlang:element(8, Pool)}, + _pipe@3 = glisten@handler:start( + _pipe@2 + ), + gleam@result:replace_error( + _pipe@3, + handler_error + ) + end, + fun(Start) -> + _pipe@4 = Sock, + _pipe@5 = (erlang:element( + 5, + erlang:element(4, State) + ))( + _pipe@4, + gleam@erlang@process:subject_owner( + Start + ) + ), + _pipe@6 = gleam@result:replace_error( + _pipe@5, + control_error + ), + gleam@result:map( + _pipe@6, + fun(_) -> + gleam@erlang@process:send( + Start, + ready + ) + end + ) + end + ) + end + ) + end, + case Res of + {error, Reason} -> + glisten@logger:error( + {<<"Failed to accept/start handler"/utf8>>, + Reason} + ), + {stop, + {abnormal, + <<"Failed to accept/start handler"/utf8>>}}; + + _ -> + gleam@otp@actor:send( + Sender, + {accept_connection, Listener} + ), + {continue, State} + end; + + Msg@1 -> + glisten@logger:error( + {<<"Unknown message type"/utf8>>, Msg@1} + ), + {stop, {abnormal, <<"Unknown message type"/utf8>>}} + end + end} + ). + +-spec new_pool( + fun((glisten@handler:handler_message(), glisten@handler:loop_state(nil)) -> gleam@otp@actor:next(glisten@handler:loop_state(nil))) +) -> fun((glisten@socket:listen_socket()) -> pool(nil)). +new_pool(Handler) -> + fun(Listener_socket) -> + {pool, + Listener_socket, + Handler, + nil, + 10, + none, + none, + glisten@socket@transport:tcp()} + end. + +-spec new_pool_with_data( + fun((glisten@handler:handler_message(), glisten@handler:loop_state(GRL)) -> gleam@otp@actor:next(glisten@handler:loop_state(GRL))), + GRL +) -> fun((glisten@socket:listen_socket()) -> pool(GRL)). +new_pool_with_data(Handler, Initial_data) -> + fun(Listener_socket) -> + {pool, + Listener_socket, + Handler, + Initial_data, + 10, + none, + none, + glisten@socket@transport:tcp()} + end. + +-spec with_init( + fun((glisten@socket:listen_socket()) -> pool(GRO)), + fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) +) -> fun((glisten@socket:listen_socket()) -> pool(GRO)). +with_init(Make_pool, Func) -> + fun(Socket) -> + Pool = Make_pool(Socket), + erlang:setelement(6, Pool, {some, Func}) + end. + +-spec with_close( + fun((glisten@socket:listen_socket()) -> pool(GRS)), + fun((gleam@erlang@process:subject(glisten@handler:handler_message())) -> nil) +) -> fun((glisten@socket:listen_socket()) -> pool(GRS)). +with_close(Make_pool, Func) -> + fun(Socket) -> + Pool = Make_pool(Socket), + erlang:setelement(7, Pool, {some, Func}) + end. + +-spec with_pool_size( + fun((glisten@socket:listen_socket()) -> pool(GRW)), + integer() +) -> fun((glisten@socket:listen_socket()) -> pool(GRW)). +with_pool_size(Make_pool, Pool_count) -> + fun(Socket) -> + Pool = Make_pool(Socket), + erlang:setelement(5, Pool, Pool_count) + end. + +-spec over_ssl(fun((glisten@socket:listen_socket()) -> pool(GRZ))) -> fun((glisten@socket:listen_socket()) -> pool(GRZ)). +over_ssl(Make_pool) -> + fun(Socket) -> + Pool = Make_pool(Socket), + erlang:setelement(8, Pool, glisten@socket@transport:ssl()) + end. + +-spec start_pool(pool(any())) -> {ok, + gleam@erlang@process:subject(gleam@otp@supervisor:message())} | + {error, gleam@otp@actor:start_error()}. +start_pool(Pool) -> + gleam@otp@supervisor:start_spec( + {spec, + nil, + 100, + 1, + fun(Children) -> + _pipe = gleam@iterator:range(0, erlang:element(5, Pool)), + gleam@iterator:fold( + _pipe, + Children, + fun(Children@1, _) -> + gleam@otp@supervisor:add( + Children@1, + gleam@otp@supervisor:worker( + fun(_) -> start(Pool) end + ) + ) + end + ) + end} + ). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl new file mode 100644 index 00000000000..d4bd37df499 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@handler.erl @@ -0,0 +1,234 @@ +-module(glisten@handler). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([start/1, func/1]). +-export_type([handler_message/0, loop_state/1, handler/1]). + +-type handler_message() :: close | + ready | + {receive_message, bitstring()} | + {send_message, gleam@bit_builder:bit_builder()} | + {ssl, gleam@otp@port:port_(), bitstring()} | + {ssl_closed, nil} | + {tcp, gleam@otp@port:port_(), bitstring()} | + {tcp_closed, nil}. + +-type loop_state(GMF) :: {loop_state, + glisten@socket:socket(), + gleam@erlang@process:subject(handler_message()), + glisten@socket@transport:transport(), + GMF}. + +-type handler(GMG) :: {handler, + glisten@socket:socket(), + GMG, + fun((handler_message(), loop_state(GMG)) -> gleam@otp@actor:next(loop_state(GMG))), + gleam@option:option(fun((gleam@erlang@process:subject(handler_message())) -> nil)), + gleam@option:option(fun((gleam@erlang@process:subject(handler_message())) -> nil)), + glisten@socket@transport:transport()}. + +-spec start(handler(any())) -> {ok, + gleam@erlang@process:subject(handler_message())} | + {error, gleam@otp@actor:start_error()}. +start(Handler) -> + gleam@otp@actor:start_spec( + {spec, + fun() -> + Subject = gleam@erlang@process:new_subject(), + Selector = begin + _pipe = gleam_erlang_ffi:new_selector(), + _pipe@1 = gleam@erlang@process:selecting( + _pipe, + Subject, + fun gleam@function:identity/1 + ), + gleam@erlang@process:selecting_anything( + _pipe@1, + fun(Msg) -> case gleam@dynamic:unsafe_coerce(Msg) of + {tcp, _, Data} -> + {receive_message, Data}; + + {ssl, _, Data} -> + {receive_message, Data}; + + Msg@1 -> + Msg@1 + end end + ) + end, + {ready, + {loop_state, + erlang:element(2, Handler), + Subject, + erlang:element(7, Handler), + erlang:element(3, Handler)}, + Selector} + end, + 1000, + fun(Msg@2, State) -> case Msg@2 of + {tcp_closed, _} -> + case (erlang:element(4, erlang:element(4, State)))( + erlang:element(2, State) + ) of + {ok, nil} -> + _ = case erlang:element(6, Handler) of + {some, Func} -> + Func(erlang:element(3, State)); + + _ -> + nil + end, + {stop, normal}; + + {error, Err} -> + {stop, {abnormal, gleam@string:inspect(Err)}} + end; + + {ssl_closed, _} -> + case (erlang:element(4, erlang:element(4, State)))( + erlang:element(2, State) + ) of + {ok, nil} -> + _ = case erlang:element(6, Handler) of + {some, Func} -> + Func(erlang:element(3, State)); + + _ -> + nil + end, + {stop, normal}; + + {error, Err} -> + {stop, {abnormal, gleam@string:inspect(Err)}} + end; + + close -> + case (erlang:element(4, erlang:element(4, State)))( + erlang:element(2, State) + ) of + {ok, nil} -> + _ = case erlang:element(6, Handler) of + {some, Func} -> + Func(erlang:element(3, State)); + + _ -> + nil + end, + {stop, normal}; + + {error, Err} -> + {stop, {abnormal, gleam@string:inspect(Err)}} + end; + + ready -> + _pipe@2 = erlang:element(2, State), + _pipe@3 = (erlang:element(6, erlang:element(4, State)))( + _pipe@2 + ), + _pipe@4 = gleam@result:replace_error( + _pipe@3, + <<"Failed to handshake socket"/utf8>> + ), + _pipe@5 = gleam@result:map( + _pipe@4, + fun(_) -> _ = case erlang:element(5, Handler) of + {some, Func@1} -> + Func@1(erlang:element(3, State)); + + _ -> + nil + end end + ), + _pipe@7 = gleam@result:then( + _pipe@5, + fun(_) -> + _pipe@6 = (erlang:element( + 12, + erlang:element(4, State) + ))( + erlang:element(2, State), + [{active_mode, once}] + ), + gleam@result:replace_error( + _pipe@6, + <<"Failed to set socket active"/utf8>> + ) + end + ), + _pipe@8 = gleam@result:replace( + _pipe@7, + {continue, State} + ), + _pipe@9 = gleam@result:map_error( + _pipe@8, + fun(Reason) -> {stop, {abnormal, Reason}} end + ), + gleam@result:unwrap_both(_pipe@9); + + Msg@3 -> + case (erlang:element(4, Handler))(Msg@3, State) of + {continue, Next_state} -> + _assert_subject = (erlang:element( + 12, + erlang:element(4, State) + ))( + erlang:element(2, State), + [{active_mode, once}] + ), + {ok, nil} = case _assert_subject of + {ok, nil} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"glisten/handler"/utf8>>, + function => <<"start"/utf8>>, + line => 116}) + end, + {continue, Next_state}; + + Msg@4 -> + Msg@4 + end + end end} + ). + +-spec func( + fun((bitstring(), loop_state(GMU)) -> gleam@otp@actor:next(loop_state(GMU))) +) -> fun((handler_message(), loop_state(GMU)) -> gleam@otp@actor:next(loop_state(GMU))). +func(Func) -> + fun(Msg, State) -> case Msg of + {tcp, _, _} -> + glisten@logger:error( + {<<"Received an unexpected TCP message"/utf8>>, Msg} + ), + {continue, State}; + + ready -> + glisten@logger:error( + {<<"Received an unexpected TCP message"/utf8>>, Msg} + ), + {continue, State}; + + {receive_message, Data} -> + Func(Data, State); + + {send_message, Data@1} -> + case (erlang:element(11, erlang:element(4, State)))( + erlang:element(2, State), + Data@1 + ) of + {ok, _} -> + {continue, State}; + + {error, Reason} -> + glisten@logger:error( + {<<"Failed to send data"/utf8>>, Reason} + ), + {stop, {abnormal, <<"Failed to send data"/utf8>>}} + end; + + Msg@1 -> + glisten@logger:error({<<"Unhandled TCP message"/utf8>>, Msg@1}), + {stop, {abnormal, <<"Unhandled TCP message"/utf8>>}} + end end. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl new file mode 100644 index 00000000000..f2c2a3d103d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@logger.erl @@ -0,0 +1,8 @@ +-module(glisten@logger). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([error/1]). + +-spec error(any()) -> nil. +error(Data) -> + logger:error(unicode:characters_to_list(<<"~tp"/utf8>>), [Data]). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl new file mode 100644 index 00000000000..bf277dbeb4d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket.erl @@ -0,0 +1,90 @@ +-module(glisten@socket). +-compile([no_auto_import, nowarn_unused_vars]). + +-export_type([socket_reason/0, listen_socket/0, socket/0]). + +-type socket_reason() :: closed | + timeout | + badarg | + terminated | + eaddrinuse | + eaddrnotavail | + eafnosupport | + ealready | + econnaborted | + econnrefused | + econnreset | + edestaddrreq | + ehostdown | + ehostunreach | + einprogress | + eisconn | + emsgsize | + enetdown | + enetunreach | + enopkg | + enoprotoopt | + enotconn | + enotty | + enotsock | + eproto | + eprotonosupport | + eprototype | + esocktnosupport | + etimedout | + ewouldblock | + exbadport | + exbadseq | + eacces | + eagain | + ebadf | + ebadmsg | + ebusy | + edeadlk | + edeadlock | + edquot | + eexist | + efault | + efbig | + eftype | + eintr | + einval | + eio | + eisdir | + eloop | + emfile | + emlink | + emultihop | + enametoolong | + enfile | + enobufs | + enodev | + enolck | + enolink | + enoent | + enomem | + enospc | + enosr | + enostr | + enosys | + enotblk | + enotdir | + enotsup | + enxio | + eopnotsupp | + eoverflow | + eperm | + epipe | + erange | + erofs | + espipe | + esrch | + estale | + etxtbsy | + exdev. + +-opaque listen_socket() :: listen_socket. + +-opaque socket() :: socket. + + diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl new file mode 100644 index 00000000000..ba8da56d523 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@options.erl @@ -0,0 +1,79 @@ +-module(glisten@socket@options). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([to_map/1, merge_with_defaults/1]). +-export_type([socket_mode/0, active_state/0, tcp_option/0]). + +-type socket_mode() :: binary. + +-type active_state() :: once | passive | {count, integer()} | active. + +-type tcp_option() :: {backlog, integer()} | + {nodelay, boolean()} | + {linger, {boolean(), integer()}} | + {send_timeout, integer()} | + {send_timeout_close, boolean()} | + {reuseaddr, boolean()} | + {active_mode, active_state()} | + {mode, socket_mode()} | + {certfile, binary()} | + {keyfile, binary()} | + {alpn_preferred_protocols, list(binary())}. + +-spec to_map(list(tcp_option())) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()). +to_map(Options) -> + Opt_decoder = gleam@dynamic:tuple2( + fun gleam@dynamic:dynamic/1, + fun gleam@dynamic:dynamic/1 + ), + _pipe = Options, + _pipe@1 = gleam@list:map(_pipe, fun(Opt) -> case Opt of + {active_mode, passive} -> + gleam@dynamic:from( + {erlang:binary_to_atom(<<"active"/utf8>>), false} + ); + + {active_mode, active} -> + gleam@dynamic:from( + {erlang:binary_to_atom(<<"active"/utf8>>), true} + ); + + {active_mode, {count, N}} -> + gleam@dynamic:from( + {erlang:binary_to_atom(<<"active"/utf8>>), N} + ); + + {active_mode, once} -> + gleam@dynamic:from( + {erlang:binary_to_atom(<<"active"/utf8>>), + erlang:binary_to_atom(<<"once"/utf8>>)} + ); + + Other -> + gleam@dynamic:from(Other) + end end), + _pipe@2 = gleam@list:filter_map(_pipe@1, Opt_decoder), + _pipe@3 = gleam@list:map( + _pipe@2, + fun(_capture) -> + gleam@pair:map_first(_capture, fun gleam@dynamic:unsafe_coerce/1) + end + ), + gleam@map:from_list(_pipe@3). + +-spec merge_with_defaults(list(tcp_option())) -> list(tcp_option()). +merge_with_defaults(Options) -> + Overrides = to_map(Options), + _pipe = [{backlog, 1024}, + {nodelay, true}, + {linger, {true, 30}}, + {send_timeout, 30000}, + {send_timeout_close, true}, + {reuseaddr, true}, + {mode, binary}, + {active_mode, passive}], + _pipe@1 = to_map(_pipe), + _pipe@2 = gleam@map:merge(_pipe@1, Overrides), + _pipe@3 = gleam@map:to_list(_pipe@2), + _pipe@4 = gleam@list:map(_pipe@3, fun gleam@dynamic:from/1), + gleam@list:map(_pipe@4, fun gleam@dynamic:unsafe_coerce/1). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl new file mode 100644 index 00000000000..10ebf6c34c4 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@socket@transport.erl @@ -0,0 +1,102 @@ +-module(glisten@socket@transport). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([socket_info/1, tcp/0, ssl/0]). +-export_type([transport/0]). + +-type transport() :: {ssl, + fun((glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:listen_socket(), integer()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, nil} | + {error, gleam@erlang@atom:atom_()}), + fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | + {error, nil}), + fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, + glisten@socket:listen_socket()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket()) -> {ok, binary()} | {error, binary()}), + fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), integer(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, + nil} | + {error, nil}), + fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()))} | + {tcp, + fun((glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:listen_socket(), integer()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, nil} | + {error, gleam@erlang@atom:atom_()}), + fun((glisten@socket:socket()) -> {ok, glisten@socket:socket()} | + {error, nil}), + fun((integer(), list(glisten@socket@options:tcp_option())) -> {ok, + glisten@socket:listen_socket()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket()) -> {ok, binary()} | {error, binary()}), + fun((glisten@socket:socket(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), integer(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket(), list(glisten@socket@options:tcp_option())) -> {ok, + nil} | + {error, nil}), + fun((glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}), + fun((glisten@socket:socket()) -> gleam@map:map_(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic()))}. + +-spec socket_info(glisten@socket:socket()) -> gleam@map:map_(any(), any()). +socket_info(Field@0) -> + socket:info(Field@0). + +-spec tcp() -> transport(). +tcp() -> + {tcp, + fun glisten@tcp:accept/1, + fun glisten@tcp:accept_timeout/2, + fun glisten@tcp:close/1, + fun glisten@tcp:controlling_process/2, + fun glisten@tcp:handshake/1, + fun glisten@tcp:listen/2, + fun(_) -> {error, <<"Can't negotiate protocol on tcp"/utf8>>} end, + fun glisten@tcp:'receive'/2, + fun glisten@tcp:receive_timeout/3, + fun glisten@tcp:send/2, + fun glisten@tcp:set_opts/2, + fun glisten@tcp:shutdown/1, + fun socket:info/1}. + +-spec ssl() -> transport(). +ssl() -> + {ssl, + fun glisten@ssl:accept/1, + fun glisten@ssl:accept_timeout/2, + fun glisten@ssl:close/1, + fun glisten@ssl:controlling_process/2, + fun glisten@ssl:handshake/1, + fun glisten@ssl:listen/2, + fun glisten@ssl:negotiated_protocol/1, + fun glisten@ssl:'receive'/2, + fun glisten@ssl:receive_timeout/3, + fun glisten@ssl:send/2, + fun glisten@ssl:set_opts/2, + fun glisten@ssl:shutdown/1, + fun socket:info/1}. diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl new file mode 100644 index 00000000000..28d69867a46 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@ssl.erl @@ -0,0 +1,94 @@ +-module(glisten@ssl). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([controlling_process/2, listen/2, accept_timeout/2, accept/1, receive_timeout/3, 'receive'/2, send/2, close/1, do_shutdown/2, shutdown/1, set_opts/2, handshake/1, negotiated_protocol/1]). + +-spec controlling_process(glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, + nil} | + {error, gleam@erlang@atom:atom_()}. +controlling_process(Field@0, Field@1) -> + ssl_ffi:controlling_process(Field@0, Field@1). + +-spec listen(integer(), list(glisten@socket@options:tcp_option())) -> {ok, + glisten@socket:listen_socket()} | + {error, glisten@socket:socket_reason()}. +listen(Port, Options) -> + _pipe = Options, + _pipe@1 = glisten@socket@options:merge_with_defaults(_pipe), + ssl:listen(Port, _pipe@1). + +-spec accept_timeout(glisten@socket:listen_socket(), integer()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}. +accept_timeout(Field@0, Field@1) -> + ssl:transport_accept(Field@0, Field@1). + +-spec accept(glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}. +accept(Field@0) -> + ssl:transport_accept(Field@0). + +-spec receive_timeout(glisten@socket:socket(), integer(), integer()) -> {ok, + bitstring()} | + {error, glisten@socket:socket_reason()}. +receive_timeout(Field@0, Field@1, Field@2) -> + ssl:recv(Field@0, Field@1, Field@2). + +-spec 'receive'(glisten@socket:socket(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}. +'receive'(Field@0, Field@1) -> + ssl:recv(Field@0, Field@1). + +-spec send(glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}. +send(Field@0, Field@1) -> + ssl_ffi:send(Field@0, Field@1). + +-spec close(glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}. +close(Field@0) -> + ssl_ffi:close(Field@0). + +-spec do_shutdown(glisten@socket:socket(), gleam@erlang@atom:atom_()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}. +do_shutdown(Field@0, Field@1) -> + ssl_ffi:shutdown(Field@0, Field@1). + +-spec shutdown(glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}. +shutdown(Socket) -> + _assert_subject = gleam_erlang_ffi:atom_from_string(<<"write"/utf8>>), + {ok, Write} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"glisten/ssl"/utf8>>, + function => <<"shutdown"/utf8>>, + line => 60}) + end, + ssl_ffi:shutdown(Socket, Write). + +-spec set_opts( + glisten@socket:socket(), + list(glisten@socket@options:tcp_option()) +) -> {ok, nil} | {error, nil}. +set_opts(Socket, Opts) -> + _pipe = Opts, + _pipe@1 = glisten@socket@options:to_map(_pipe), + _pipe@2 = gleam@map:to_list(_pipe@1), + _pipe@3 = gleam@list:map(_pipe@2, fun gleam@dynamic:from/1), + ssl_ffi:set_opts(Socket, _pipe@3). + +-spec handshake(glisten@socket:socket()) -> {ok, glisten@socket:socket()} | + {error, nil}. +handshake(Field@0) -> + ssl:handshake(Field@0). + +-spec negotiated_protocol(glisten@socket:socket()) -> {ok, binary()} | + {error, binary()}. +negotiated_protocol(Field@0) -> + ssl_ffi:negotiated_protocol(Field@0). diff --git a/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl b/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl new file mode 100644 index 00000000000..09d0bfe4e49 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/glisten@tcp.erl @@ -0,0 +1,96 @@ +-module(glisten@tcp). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([handshake/1, controlling_process/2, listen/2, accept_timeout/2, accept/1, receive_timeout/3, 'receive'/2, send/2, socket_info/1, close/1, do_shutdown/2, shutdown/1, set_opts/2, negotiated_protocol/1]). + +-spec handshake(glisten@socket:socket()) -> {ok, glisten@socket:socket()} | + {error, nil}. +handshake(Socket) -> + {ok, Socket}. + +-spec controlling_process(glisten@socket:socket(), gleam@erlang@process:pid_()) -> {ok, + nil} | + {error, gleam@erlang@atom:atom_()}. +controlling_process(Field@0, Field@1) -> + tcp_ffi:controlling_process(Field@0, Field@1). + +-spec listen(integer(), list(glisten@socket@options:tcp_option())) -> {ok, + glisten@socket:listen_socket()} | + {error, glisten@socket:socket_reason()}. +listen(Port, Options) -> + _pipe = Options, + _pipe@1 = glisten@socket@options:merge_with_defaults(_pipe), + gen_tcp:listen(Port, _pipe@1). + +-spec accept_timeout(glisten@socket:listen_socket(), integer()) -> {ok, + glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}. +accept_timeout(Field@0, Field@1) -> + gen_tcp:accept(Field@0, Field@1). + +-spec accept(glisten@socket:listen_socket()) -> {ok, glisten@socket:socket()} | + {error, glisten@socket:socket_reason()}. +accept(Field@0) -> + gen_tcp:accept(Field@0). + +-spec receive_timeout(glisten@socket:socket(), integer(), integer()) -> {ok, + bitstring()} | + {error, glisten@socket:socket_reason()}. +receive_timeout(Field@0, Field@1, Field@2) -> + gen_tcp:recv(Field@0, Field@1, Field@2). + +-spec 'receive'(glisten@socket:socket(), integer()) -> {ok, bitstring()} | + {error, glisten@socket:socket_reason()}. +'receive'(Field@0, Field@1) -> + gen_tcp:recv(Field@0, Field@1). + +-spec send(glisten@socket:socket(), gleam@bit_builder:bit_builder()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}. +send(Field@0, Field@1) -> + tcp_ffi:send(Field@0, Field@1). + +-spec socket_info(glisten@socket:socket()) -> gleam@map:map_(any(), any()). +socket_info(Field@0) -> + socket:info(Field@0). + +-spec close(any()) -> {ok, nil} | {error, glisten@socket:socket_reason()}. +close(Field@0) -> + tcp_ffi:close(Field@0). + +-spec do_shutdown(glisten@socket:socket(), gleam@erlang@atom:atom_()) -> {ok, + nil} | + {error, glisten@socket:socket_reason()}. +do_shutdown(Field@0, Field@1) -> + tcp_ffi:shutdown(Field@0, Field@1). + +-spec shutdown(glisten@socket:socket()) -> {ok, nil} | + {error, glisten@socket:socket_reason()}. +shutdown(Socket) -> + _assert_subject = gleam_erlang_ffi:atom_from_string(<<"write"/utf8>>), + {ok, Write} = case _assert_subject of + {ok, _} -> _assert_subject; + _assert_fail -> + erlang:error(#{gleam_error => assert, + message => <<"Assertion pattern match failed"/utf8>>, + value => _assert_fail, + module => <<"glisten/tcp"/utf8>>, + function => <<"shutdown"/utf8>>, + line => 63}) + end, + tcp_ffi:shutdown(Socket, Write). + +-spec set_opts( + glisten@socket:socket(), + list(glisten@socket@options:tcp_option()) +) -> {ok, nil} | {error, nil}. +set_opts(Socket, Opts) -> + _pipe = Opts, + _pipe@1 = glisten@socket@options:to_map(_pipe), + _pipe@2 = gleam@map:to_list(_pipe@1), + _pipe@3 = gleam@list:map(_pipe@2, fun gleam@dynamic:from/1), + tcp_ffi:set_opts(Socket, _pipe@3). + +-spec negotiated_protocol(glisten@socket:socket()) -> any(). +negotiated_protocol(Field@0) -> + tcp:negotiated_protocol(Field@0). diff --git a/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl b/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl new file mode 100644 index 00000000000..fd05f369c20 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/ssl_ffi.erl @@ -0,0 +1,60 @@ +-module(ssl_ffi). + +-export([controlling_process/2, send/2, set_opts/2, start_ssl/0, shutdown/2, close/1, + negotiated_protocol/1]). + +send(Socket, Packet) -> + case ssl:send(Socket, Packet) of + ok -> + {ok, nil}; + Res -> + Res + end. + +set_opts(Socket, Options) -> + case ssl:setopts(Socket, Options) of + ok -> + {ok, nil}; + {error, Reason} -> + {error, Reason} + end. + +controlling_process(Socket, Pid) -> + case ssl:controlling_process(Socket, Pid) of + ok -> + {ok, nil}; + {error, Reason} -> + {error, Reason} + end. + +start_ssl() -> + case application:ensure_all_started(ssl) of + {ok, _} -> + {ok, nil}; + {error, Reason} -> + {error, Reason} + end. + +shutdown(Socket, How) -> + case ssl:shutdown(Socket, How) of + ok -> + {ok, nil}; + {error, Reason} -> + {error, Reason} + end. + +close(Socket) -> + case ssl:close(Socket) of + ok -> + {ok, nil}; + {error, Reason} -> + {error, Reason} + end. + +negotiated_protocol(Socket) -> + case ssl:negotiated_protocol(Socket) of + {error, _} -> + {error, "Socket not negotiated"}; + Protocol -> + Protocol + end. diff --git a/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl b/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl new file mode 100644 index 00000000000..955b881d4c7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glisten/src/tcp_ffi.erl @@ -0,0 +1,32 @@ +-module(tcp_ffi). +-export([controlling_process/2, send/2, set_opts/2, shutdown/2, close/1]). + +send(Socket, Packet) -> + case gen_tcp:send(Socket, Packet) of + ok -> {ok, nil}; + Res -> Res + end. + +set_opts(Socket, Options) -> + case inet:setopts(Socket, Options) of + ok -> {ok, nil}; + {error, Reason} -> {error, Reason} + end. + +controlling_process(Socket, Pid) -> + case gen_tcp:controlling_process(Socket, Pid) of + ok -> {ok, nil}; + {error, Reason} -> {error, Reason} + end. + +shutdown(Socket, How) -> + case gen_tcp:shutdown(Socket, How) of + ok -> {ok, nil}; + {error, Reason} -> {error, Reason} + end. + +close(Socket) -> + case gen_tcp:close(Socket) of + ok -> {ok, nil}; + {error, Reason} -> {error, Reason} + end. diff --git a/test-community-packages-javascript/build/packages/globe/LICENSE b/test-community-packages-javascript/build/packages/globe/LICENSE new file mode 100644 index 00000000000..37eec8b87f9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/globe/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Willyboar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/globe/README.md b/test-community-packages-javascript/build/packages/globe/README.md new file mode 100644 index 00000000000..3b7011fd631 --- /dev/null +++ b/test-community-packages-javascript/build/packages/globe/README.md @@ -0,0 +1,26 @@ +![Globe](https://github.com/Willyboar/globe/assets/22755228/54162ccb-8f4e-4e6f-a732-e1e21453b213) + +[![Package Version](https://img.shields.io/hexpm/v/globe)](https://hex.pm/packages/globe) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/globe/) + +## WIP: Not Usable + +Globe is a lightweight and efficient compiler backend developed in the Gleam programming language. It provides an Intermediate Language (IL) and Intermediate Representation (IR) to facilitate code transformation and optimization. Globe is designed to generate C99 code, making it compatible with a wide range of platforms and toolchains. + +## Quick start + +```sh +gleam run # Run the project +gleam test # Run the tests +gleam shell # Run an Erlang shell +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add globe +``` + +and its documentation can be found at . diff --git a/test-community-packages-javascript/build/packages/globe/gleam.toml b/test-community-packages-javascript/build/packages/globe/gleam.toml new file mode 100644 index 00000000000..d37f3ad1638 --- /dev/null +++ b/test-community-packages-javascript/build/packages/globe/gleam.toml @@ -0,0 +1,12 @@ +name = "globe" +version = "0.1.0" +description = "Gleam Compiler Backend" + +licences = ["MIT"] +repository = { type = "github", user = "Willyboar", repo = "globe" } + +[dependencies] +gleam_stdlib = "~> 0.29" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.app.src b/test-community-packages-javascript/build/packages/globe/src/globe.app.src new file mode 100644 index 00000000000..7c9133d1a43 --- /dev/null +++ b/test-community-packages-javascript/build/packages/globe/src/globe.app.src @@ -0,0 +1,8 @@ +{application, globe, [ + {vsn, "0.1.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Gleam Compiler Backend"}, + {modules, [globe]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.erl b/test-community-packages-javascript/build/packages/globe/src/globe.erl new file mode 100644 index 00000000000..2bf599597f2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/globe/src/globe.erl @@ -0,0 +1,8 @@ +-module(globe). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([main/0]). + +-spec main() -> nil. +main() -> + gleam@io:println(<<"Hello from globe!"/utf8>>). diff --git a/test-community-packages-javascript/build/packages/globe/src/globe.gleam b/test-community-packages-javascript/build/packages/globe/src/globe.gleam new file mode 100644 index 00000000000..c19cb826afa --- /dev/null +++ b/test-community-packages-javascript/build/packages/globe/src/globe.gleam @@ -0,0 +1,5 @@ +import gleam/io + +pub fn main() { + io.println("Hello from globe!") +} diff --git a/test-community-packages-javascript/build/packages/gloml/README.md b/test-community-packages-javascript/build/packages/gloml/README.md new file mode 100644 index 00000000000..16757b25e97 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/README.md @@ -0,0 +1,40 @@ +# gloml + +[![Package Version](https://img.shields.io/hexpm/v/gloml)](https://hex.pm/packages/gloml) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gloml/) + +A toml parsing library for gleam ✨ All gleam targets and runtimes are supported by gloml. + +*Timestamps are not currently supported.* + +```gleam +import gleam/io + +pub fn main() { + decode( + " +[my-project] +version = \"1.2.3\" +", + d.field("my-project", d.field("version", d.string)), + ) + |> io.println() +} +``` + +## Quick start + +```sh +cd priv; npm install; cd .. # install dependencies for js +gleam test # Run the tests +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add gloml +``` + +and its documentation can be found at . diff --git a/test-community-packages-javascript/build/packages/gloml/gleam.toml b/test-community-packages-javascript/build/packages/gloml/gleam.toml new file mode 100644 index 00000000000..c7f482deb7b --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/gleam.toml @@ -0,0 +1,16 @@ +name = "gloml" +version = "0.1.2" +description = "A gleam library for parsing toml." +licences = ["MIT"] +repository = { type = "github", user = "lunarmagpie", repo = "gloml" } +links = [{ title = "Website", href = "https://github.com/lunarmagpie.gloml" }] + +[dependencies] +gleam_stdlib = "~> 0.27" +toml = "~> 0.7" + +[dev-dependencies] +gleeunit = "~> 0.10" + +[javascript.deno] +allow_read = ["gleam.toml", "test"] diff --git a/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json b/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json new file mode 100644 index 00000000000..ec78ad53f3c --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/priv/package-lock.json @@ -0,0 +1,18 @@ +{ + "name": "priv", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@ltd/j-toml": "^1.38.0" + } + }, + "node_modules/@ltd/j-toml": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/@ltd/j-toml/-/j-toml-1.38.0.tgz", + "integrity": "sha512-lYtBcmvHustHQtg4X7TXUu1Xa/tbLC3p2wLvgQI+fWVySguVZJF60Snxijw5EiohumxZbR10kWYFFebh1zotiw==" + } + } +} diff --git a/test-community-packages-javascript/build/packages/gloml/priv/package.json b/test-community-packages-javascript/build/packages/gloml/priv/package.json new file mode 100644 index 00000000000..8f6b7a45402 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/priv/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "@ltd/j-toml": "^1.38.0" + } +} diff --git a/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex b/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex new file mode 100644 index 00000000000..e021469b55e --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/src/TomlFFI.ex @@ -0,0 +1,5 @@ +defmodule TomlFFI do + def get_reason({:invalid_toml, reason}) do + reason + end +end diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src b/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src new file mode 100644 index 00000000000..f654c6d7087 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/src/gloml.app.src @@ -0,0 +1,9 @@ +{application, gloml, [ + {vsn, "0.1.2"}, + {applications, [gleam_stdlib, + gleeunit, + toml]}, + {description, "A gleam library for parsing toml."}, + {modules, [gloml]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.erl b/test-community-packages-javascript/build/packages/gloml/src/gloml.erl new file mode 100644 index 00000000000..0f25cc2bd74 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/src/gloml.erl @@ -0,0 +1,44 @@ +-module(gloml). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([decode/2, decode_dynamic/1]). +-export_type([decode_error/0, elx_invalid_toml_error/0]). + +-type decode_error() :: {invalid_toml_error, binary()} | + {unexpected_format, list(gleam@dynamic:decode_error())}. + +-type elx_invalid_toml_error() :: any(). + +-spec decode_inner(binary()) -> {ok, gleam@dynamic:dynamic()} | + {error, decode_error()}. +decode_inner(Toml_string) -> + case 'Elixir.Toml':decode(Toml_string) of + {ok, Value} -> + {ok, Value}; + + {error, Err} -> + {error, {invalid_toml_error, 'Elixir.TomlFFI':get_reason(Err)}} + end. + +-spec decode( + binary(), + fun((gleam@dynamic:dynamic()) -> {ok, EUG} | + {error, list(gleam@dynamic:decode_error())}) +) -> {ok, EUG} | {error, decode_error()}. +decode(Toml_string, Decoder) -> + gleam@result:then( + decode_inner(Toml_string), + fun(Dyn) -> + _pipe = Dyn, + _pipe@1 = Decoder(_pipe), + gleam@result:map_error( + _pipe@1, + fun(Field@0) -> {unexpected_format, Field@0} end + ) + end + ). + +-spec decode_dynamic(binary()) -> {ok, gleam@dynamic:dynamic()} | + {error, decode_error()}. +decode_dynamic(Toml_string) -> + decode_inner(Toml_string). diff --git a/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam b/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam new file mode 100644 index 00000000000..073a087bc63 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/src/gloml.gleam @@ -0,0 +1,77 @@ +import gleam/dynamic as dyn +import gleam/result + +pub type DecodeError { + InvalidTomlError(String) + UnexpectedFormat(List(dyn.DecodeError)) +} + +/// Parse a toml file with a decoder. +/// +/// ```gleam +/// pub fn decode_toml() { +/// let version = +/// gloml.decode(" +/// [my-project] +/// version = \"1.2.3\" +/// ", +/// d.field("my-project", d.field("version", d.string)), +/// ) +/// should.equal(version, Ok("1.2.3")) +/// } +/// ``` +/// +pub fn decode( + from toml_string: String, + using decoder: dyn.Decoder(t), +) -> Result(t, DecodeError) { + use dyn <- result.then(decode_inner(toml_string)) + dyn + |> decoder + |> result.map_error(UnexpectedFormat) +} + +/// Parse a toml file into a `gleam/dynamic.Dynamic`. +/// +/// ```gleam +/// pub fn decode_toml() { +/// let dynamic = +/// gloml.decode(" +/// [my-project] +/// version = \"1.2.3\" +/// ") +/// } +/// ``` +/// +pub fn decode_dynamic(toml_string: String) { + decode_inner(toml_string) +} + +if erlang { + external type ElxInvalidTomlError + + external fn decode_ex( + toml_string: String, + ) -> Result(dyn.Dynamic, ElxInvalidTomlError) = + "Elixir.Toml" "decode" + + external fn get_reason(err: ElxInvalidTomlError) -> String = + "Elixir.TomlFFI" "get_reason" + + fn decode_inner(toml_string: String) -> Result(dyn.Dynamic, DecodeError) { + case decode_ex(toml_string) { + Ok(value) -> Ok(value) + Error(err) -> Error(InvalidTomlError(get_reason(err))) + } + } +} + +if javascript { + external fn decode_js(toml_string: String) -> Result(dyn.Dynamic, String) = + "./toml_ffi.mjs" "parse_toml" + + fn decode_inner(toml_string: String) -> Result(dyn.Dynamic, DecodeError) { + decode_js(toml_string) + |> result.map_error(InvalidTomlError) + } +} diff --git a/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs b/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs new file mode 100644 index 00000000000..0623dcb1ad6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/gloml/src/toml_ffi.mjs @@ -0,0 +1,14 @@ +import * as TOML from "./priv/node_modules/@ltd/j-toml/index.mjs"; + +import { + Error, + Ok, +} from "./gleam.mjs"; + +export function parse_toml(string) { + try { + return new Ok(TOML.parse(string)); + } catch (e) { + return new Error(e.message) + } +} diff --git a/test-community-packages-javascript/build/packages/glove/LICENSE b/test-community-packages-javascript/build/packages/glove/LICENSE new file mode 100644 index 00000000000..37eec8b87f9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Willyboar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/test-community-packages-javascript/build/packages/glove/README.md b/test-community-packages-javascript/build/packages/glove/README.md new file mode 100644 index 00000000000..f7bdb08e6de --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/README.md @@ -0,0 +1,40 @@ + + + + +[![Package Version](https://img.shields.io/hexpm/v/glove)](https://hex.pm/packages/glove) +[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glove/) + + +## About +Glove is a library for working with QBE intermediate representation (IR) in Gleam. Provides utilities and functions to generate QBE code using the Gleam programming language. + +## Requirements + +To use Glove, you need to have the following dependencies installed: + +Gleam programming language - Install instructions can be found [here](https://gleam.run/getting-started/installing/) + +QBE Backend can be found [here](https://c9x.me/compile/) + + +## Quick start + +You can find a working example [here](https://github.com/Willyboar/glove_example) + +QBE IL Documentation can be found [here](https://c9x.me/compile/doc/il.html) + +## Run the tests +```sh +gleam test # Run the tests +``` + +## Installation + +If available on Hex this package can be added to your Gleam project: + +```sh +gleam add glove +``` + +and its documentation can be found at . diff --git a/test-community-packages-javascript/build/packages/glove/gleam.toml b/test-community-packages-javascript/build/packages/glove/gleam.toml new file mode 100644 index 00000000000..a66d650c5f5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/gleam.toml @@ -0,0 +1,11 @@ +name = "glove" +version = "0.2.0" +description = "Gleam QBE IR Generator" +licences = ["MIT"] +repository = { type = "github", user = "Willyboar", repo = "glove" } + +[dependencies] +gleam_stdlib = "~> 0.29" + +[dev-dependencies] +gleeunit = "~> 0.10" diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl new file mode 100644 index 00000000000..517a9ced453 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_Block.hrl @@ -0,0 +1 @@ +-record(block, {label :: binary(), statements :: list(glove:statement())}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl new file mode 100644 index 00000000000..706288b1ee8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_Const.hrl @@ -0,0 +1 @@ +-record(const, {value :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl new file mode 100644 index 00000000000..acaeff560d1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_DataDef.hrl @@ -0,0 +1,6 @@ +-record(data_def, { + linkage :: glove:linkage(), + name :: binary(), + align :: gleam@option:option(integer()), + items :: list({glove:type(), glove:data_item()}) +}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl new file mode 100644 index 00000000000..1ff1cdff09b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_Function.hrl @@ -0,0 +1,7 @@ +-record(function, { + linkage :: glove:linkage(), + name :: binary(), + arguments :: list({glove:type(), glove:value()}), + return_ty :: gleam@option:option(glove:type()), + blocks :: list(glove:block()) +}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl new file mode 100644 index 00000000000..9b6ea546aa5 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_Global.hrl @@ -0,0 +1 @@ +-record(global, {name :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl new file mode 100644 index 00000000000..6e1b0685acd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_Linkage.hrl @@ -0,0 +1,5 @@ +-record(linkage, { + exported :: boolean(), + section :: gleam@option:option(binary()), + secflags :: gleam@option:option(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl new file mode 100644 index 00000000000..b97efd9675c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_Module.hrl @@ -0,0 +1,5 @@ +-record(module, { + functions :: list(glove:function_()), + types :: list(glove:type_def()), + data :: list(glove:data_def()) +}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl new file mode 100644 index 00000000000..add43ebc8d9 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_Temporary.hrl @@ -0,0 +1 @@ +-record(temporary, {name :: binary()}). diff --git a/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl b/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl new file mode 100644 index 00000000000..c83a3e1e7e8 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/include/glove_TypeDef.hrl @@ -0,0 +1,5 @@ +-record(type_def, { + name :: binary(), + align :: gleam@option:option(integer()), + items :: list({glove:type(), integer()}) +}). diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.app.src b/test-community-packages-javascript/build/packages/glove/src/glove.app.src new file mode 100644 index 00000000000..d7cc4ba9821 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/src/glove.app.src @@ -0,0 +1,8 @@ +{application, glove, [ + {vsn, "0.2.0"}, + {applications, [gleam_stdlib, + gleeunit]}, + {description, "Gleam QBE IR Generator"}, + {modules, [glove]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glove/src/glove.erl b/test-community-packages-javascript/build/packages/glove/src/glove.erl new file mode 100644 index 00000000000..cde846d73e2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glove/src/glove.erl @@ -0,0 +1,640 @@ +-module(glove). +-compile([no_auto_import, nowarn_unused_vars]). + +-export([display_value/1, into_abi/1, into_base/1, size/1, display_data_item/1, add_inst/2, assign_inst/4, jumps/1, add_block/1, last_block/1, display_linkage/1, private/0, new_datadef/0, new_function/0, private_with_section/1, public/0, public_with_section/1, new_module/0, add_function/2, add_type/2, add_data/2, display_type_def/1, display_type/1, display_inst/1, display_data_def/1, display_statement/1, display_block/1, display_arguments/1, display_blocks/1, display_function/1, display_module/1]). +-export_type([comp/0, inst/0, value/0, type/0, data_def/0, type_def/0, data_item/0, statement/0, block/0, function_/0, linkage/0, module_/0]). + +-type comp() :: slt | sle | sgt | sge | eq | ne. + +-type inst() :: {add, value(), value()} | + {sub, value(), value()} | + {mul, value(), value()} | + {'div', value(), value()} | + {'rem', value(), value()} | + {comp, type(), comp(), value(), value()} | + {'and', value(), value()} | + {'or', value(), value()} | + {copy, value()} | + {ret, gleam@option:option(value())} | + {jnz, value(), binary(), binary()} | + {jmp, binary()} | + {call, value(), list({type(), value()})} | + {alloc4, integer()} | + {alloc8, integer()} | + {alloc16, integer()} | + {store, type(), value(), value()} | + {load, type(), value()} | + {blit, value(), value(), integer()}. + +-type value() :: {temporary, binary()} | {global, binary()} | {const, integer()}. + +-type type() :: word | + long | + single | + double | + byte | + halfword | + {aggregate, type_def()}. + +-type data_def() :: {data_def, + linkage(), + binary(), + gleam@option:option(integer()), + list({type(), data_item()})}. + +-type type_def() :: {type_def, + binary(), + gleam@option:option(integer()), + list({type(), integer()})}. + +-type data_item() :: {symbol, binary(), gleam@option:option(integer())} | + {str, binary()} | + {constant, integer()}. + +-type statement() :: {assign, value(), type(), inst()} | {volatile, inst()}. + +-type block() :: {block, binary(), list(statement())}. + +-type function_() :: {function, + linkage(), + binary(), + list({type(), value()}), + gleam@option:option(type()), + list(block())}. + +-type linkage() :: {linkage, + boolean(), + gleam@option:option(binary()), + gleam@option:option(binary())}. + +-type module_() :: {module, + list(function_()), + list(type_def()), + list(data_def())}. + +-spec display_value(value()) -> binary(). +display_value(Value) -> + case Value of + {temporary, Name} -> + <<"%"/utf8, Name/binary>>; + + {global, Name@1} -> + <<"$"/utf8, Name@1/binary>>; + + {const, Value@1} -> + gleam@int:to_string(Value@1) + end. + +-spec into_abi(type()) -> type(). +into_abi(Self) -> + case Self of + byte -> + word; + + halfword -> + word; + + Other -> + Other + end. + +-spec into_base(type()) -> type(). +into_base(Self) -> + case Self of + byte -> + word; + + halfword -> + word; + + {aggregate, _} -> + long; + + Other -> + Other + end. + +-spec size(type()) -> integer(). +size(Self) -> + case Self of + byte -> + 1; + + halfword -> + 2; + + word -> + 4; + + single -> + 4; + + long -> + 8; + + double -> + 8; + + {aggregate, Td} -> + case erlang:element(4, Td) of + [] -> + 0 + end + end. + +-spec display_data_item(data_item()) -> binary(). +display_data_item(Item) -> + case Item of + {symbol, Name, Offset} -> + case Offset of + {some, Off} -> + <<<<<<"$"/utf8, Name/binary>>/binary, " +"/utf8>>/binary, + (gleam@int:to_string(Off))/binary>>; + + none -> + <<"$"/utf8, Name/binary>> + end; + + {str, String} -> + <<<<"\""/utf8, String/binary>>/binary, "\""/utf8>>; + + {constant, Val} -> + gleam@int:to_string(Val) + end. + +-spec add_inst(block(), inst()) -> block(). +add_inst(Block, Inst) -> + {block, + erlang:element(2, Block), + gleam@list:append(erlang:element(3, Block), [{volatile, Inst}])}. + +-spec assign_inst(block(), value(), type(), inst()) -> block(). +assign_inst(Block, Val, Typ, Inst) -> + {block, + erlang:element(2, Block), + gleam@list:append(erlang:element(3, Block), [{assign, Val, Typ, Inst}])}. + +-spec jumps(block()) -> boolean(). +jumps(Block) -> + case gleam@list:last(erlang:element(3, Block)) of + {ok, Statement} -> + case Statement of + {volatile, Instr} -> + case Instr of + {ret, _} -> + true; + + {jmp, _} -> + true; + + {jnz, _, _, _} -> + true; + + _ -> + false + end; + + _ -> + false + end; + + {error, _} -> + false + end. + +-spec add_block(binary()) -> block(). +add_block(Label) -> + {block, Label, []}. + +-spec last_block(list(block())) -> gleam@option:option(block()). +last_block(Blocks) -> + case gleam@list:last(Blocks) of + {ok, Block} -> + {some, Block}; + + {error, _} -> + none + end. + +-spec display_linkage(linkage()) -> binary(). +display_linkage(Linkage) -> + Exported_str = case erlang:element(2, Linkage) of + true -> + <<"export "/utf8>>; + + false -> + <<""/utf8>> + end, + Section_str = case erlang:element(3, Linkage) of + {some, Section} -> + <<<<<<<<"section \""/utf8, Section/binary>>/binary, "\""/utf8>>/binary, + (case erlang:element(4, Linkage) of + {some, Secflags} -> + <<<<" \""/utf8, Secflags/binary>>/binary, + "\""/utf8>>; + + none -> + <<""/utf8>> + end)/binary>>/binary, + " "/utf8>>; + + none -> + <<""/utf8>> + end, + <>. + +-spec private() -> linkage(). +private() -> + {linkage, false, none, none}. + +-spec new_datadef() -> data_def(). +new_datadef() -> + {data_def, private(), <<""/utf8>>, none, []}. + +-spec new_function() -> function_(). +new_function() -> + {function, private(), <<""/utf8>>, [], none, []}. + +-spec private_with_section(binary()) -> linkage(). +private_with_section(Section) -> + {linkage, false, {some, Section}, none}. + +-spec public() -> linkage(). +public() -> + {linkage, true, none, none}. + +-spec public_with_section(binary()) -> linkage(). +public_with_section(Section) -> + {linkage, true, {some, Section}, none}. + +-spec new_module() -> module_(). +new_module() -> + {module, [], [], []}. + +-spec add_function(module_(), function_()) -> module_(). +add_function(Module, Function) -> + {module, + gleam@list:append(erlang:element(2, Module), [Function]), + erlang:element(3, Module), + erlang:element(4, Module)}. + +-spec add_type(module_(), type_def()) -> module_(). +add_type(Module, Type_def) -> + {module, + erlang:element(2, Module), + gleam@list:append(erlang:element(3, Module), [Type_def]), + erlang:element(4, Module)}. + +-spec add_data(module_(), data_def()) -> module_(). +add_data(Module, Data_def) -> + {module, + erlang:element(2, Module), + erlang:element(3, Module), + gleam@list:append(erlang:element(4, Module), [Data_def])}. + +-spec display_type_def(type_def()) -> binary(). +display_type_def(Def) -> + Align_str = case erlang:element(3, Def) of + {some, Align} -> + <<<<"align "/utf8, (gleam@int:to_string(Align))/binary>>/binary, + " "/utf8>>; + + none -> + <<""/utf8>> + end, + Items_str = begin + _pipe = erlang:element(4, Def), + _pipe@1 = gleam@list:index_map(_pipe, fun(_, Item) -> case Item of + {Ty, Count} -> + case Count > 1 of + false -> + display_type(Ty); + + true -> + <<<<(display_type(Ty))/binary, " "/utf8>>/binary, + (gleam@int:to_string(Count))/binary>> + end + end end), + gleam@string:join(_pipe@1, <<", "/utf8>>) + end, + <<<<<<<<<<<<"type :"/utf8, (erlang:element(2, Def))/binary>>/binary, + " = "/utf8>>/binary, + Align_str/binary>>/binary, + "{ "/utf8>>/binary, + Items_str/binary>>/binary, + " }"/utf8>>. + +-spec display_type(type()) -> binary(). +display_type(Ty) -> + case Ty of + byte -> + <<"b"/utf8>>; + + halfword -> + <<"h"/utf8>>; + + word -> + <<"w"/utf8>>; + + long -> + <<"l"/utf8>>; + + single -> + <<"s"/utf8>>; + + double -> + <<"d"/utf8>>; + + {aggregate, Ty@1} -> + display_type_def(Ty@1) + end. + +-spec display_inst(inst()) -> binary(). +display_inst(Inst) -> + case Inst of + {add, A, B} -> + <<<<<<"add "/utf8, (display_value(A))/binary>>/binary, ", "/utf8>>/binary, + (display_value(B))/binary>>; + + {sub, A@1, B@1} -> + <<<<<<"sub "/utf8, (display_value(A@1))/binary>>/binary, ", "/utf8>>/binary, + (display_value(B@1))/binary>>; + + {mul, A@2, B@2} -> + <<<<<<"mul "/utf8, (display_value(A@2))/binary>>/binary, ", "/utf8>>/binary, + (display_value(B@2))/binary>>; + + {'div', A@3, B@3} -> + <<<<<<"div "/utf8, (display_value(A@3))/binary>>/binary, ", "/utf8>>/binary, + (display_value(B@3))/binary>>; + + {'rem', A@4, B@4} -> + <<<<<<"rem "/utf8, (display_value(A@4))/binary>>/binary, ", "/utf8>>/binary, + (display_value(B@4))/binary>>; + + {comp, Ty, Cmp, A@5, B@5} -> + case Ty of + {aggregate, _} -> + <<"Cannot Compare aggregate types"/utf8>>; + + _ -> + case Cmp of + slt -> + <<<<<<<<<<<<<<"c"/utf8, "slt"/utf8>>/binary, + " "/utf8>>/binary, + (display_type(Ty))/binary>>/binary, + " "/utf8>>/binary, + (display_value(A@5))/binary>>/binary, + " "/utf8>>/binary, + (display_value(B@5))/binary>>; + + sle -> + <<<<<<<<<<<<<<"c"/utf8, "sle"/utf8>>/binary, + " "/utf8>>/binary, + (display_type(Ty))/binary>>/binary, + " "/utf8>>/binary, + (display_value(A@5))/binary>>/binary, + " "/utf8>>/binary, + (display_value(B@5))/binary>>; + + sgt -> + <<<<<<<<<<<<<<"c"/utf8, "sgt"/utf8>>/binary, + " "/utf8>>/binary, + (display_type(Ty))/binary>>/binary, + " "/utf8>>/binary, + (display_value(A@5))/binary>>/binary, + " "/utf8>>/binary, + (display_value(B@5))/binary>>; + + sge -> + <<<<<<<<<<<<<<"c"/utf8, "sge"/utf8>>/binary, + " "/utf8>>/binary, + (display_type(Ty))/binary>>/binary, + " "/utf8>>/binary, + (display_value(A@5))/binary>>/binary, + " "/utf8>>/binary, + (display_value(B@5))/binary>>; + + eq -> + <<<<<<<<<<<<<<"c"/utf8, "eq"/utf8>>/binary, + " "/utf8>>/binary, + (display_type(Ty))/binary>>/binary, + " "/utf8>>/binary, + (display_value(A@5))/binary>>/binary, + " "/utf8>>/binary, + (display_value(B@5))/binary>>; + + ne -> + <<<<<<<<<<<<<<"c"/utf8, "ne"/utf8>>/binary, + " "/utf8>>/binary, + (display_type(Ty))/binary>>/binary, + " "/utf8>>/binary, + (display_value(A@5))/binary>>/binary, + " "/utf8>>/binary, + (display_value(B@5))/binary>> + end + end; + + {'and', A@6, B@6} -> + <<<<<<"and "/utf8, (display_value(A@6))/binary>>/binary, ", "/utf8>>/binary, + (display_value(B@6))/binary>>; + + {'or', A@7, B@7} -> + <<<<<<"or "/utf8, (display_value(A@7))/binary>>/binary, ", "/utf8>>/binary, + (display_value(B@7))/binary>>; + + {copy, Val} -> + <<"copy "/utf8, (display_value(Val))/binary>>; + + {ret, Val@1} -> + case Val@1 of + {some, Val@2} -> + <<<<"ret "/utf8, (display_value(Val@2))/binary>>/binary, + "\n"/utf8>>; + + none -> + <<"ret\n"/utf8>> + end; + + {jnz, Val@3, If_nonzero, If_zero} -> + <<<<<<<<<<"jnz "/utf8, (display_value(Val@3))/binary>>/binary, + ", @"/utf8>>/binary, + If_nonzero/binary>>/binary, + ", @"/utf8>>/binary, + If_zero/binary>>; + + {jmp, Str} -> + <<"jmp @"/utf8, Str/binary>>; + + {call, Name, Args} -> + Arg_str = begin + _pipe = Args, + _pipe@1 = gleam@list:index_map(_pipe, fun(_, Arg) -> case Arg of + {Ty@1, Val@4} -> + <<<<(display_type(Ty@1))/binary, " "/utf8>>/binary, + (display_value(Val@4))/binary>> + end end), + gleam@string:join(_pipe@1, <<", "/utf8>>) + end, + <<<<<<<<"call "/utf8, (display_value(Name))/binary>>/binary, + "("/utf8>>/binary, + Arg_str/binary>>/binary, + ")"/utf8>>; + + {alloc4, Int} -> + <<"alloc4 "/utf8, (gleam@int:to_string(Int))/binary>>; + + {alloc8, Int@1} -> + <<"alloc8 "/utf8, (gleam@int:to_string(Int@1))/binary>>; + + {alloc16, Int@2} -> + <<"alloc16 "/utf8, (gleam@int:to_string(Int@2))/binary>>; + + {store, Typ, Value, Dest} -> + case Typ of + {aggregate, _} -> + <<"Store to an aggregate type"/utf8>>; + + _ -> + <<<<<<<<<<"store"/utf8, (display_type(Typ))/binary>>/binary, + " "/utf8>>/binary, + (display_value(Value))/binary>>/binary, + " "/utf8>>/binary, + (display_value(Dest))/binary>> + end; + + {load, Typ@1, Val@5} -> + case Typ@1 of + {aggregate, _} -> + <<"Load aggregate type"/utf8>>; + + _ -> + <<<<<<"load"/utf8, (display_type(Typ@1))/binary>>/binary, + " "/utf8>>/binary, + (display_value(Val@5))/binary>> + end; + + {blit, Src, Dest@1, N} -> + <<<<<<<<<<"blit "/utf8, (display_value(Src))/binary>>/binary, + ", "/utf8>>/binary, + (display_value(Dest@1))/binary>>/binary, + ", "/utf8>>/binary, + (gleam@int:to_string(N))/binary>> + end. + +-spec display_data_def(data_def()) -> binary(). +display_data_def(Def) -> + Linkage_str = display_linkage(erlang:element(2, Def)), + Align_str = case erlang:element(4, Def) of + {some, Align} -> + <<" align "/utf8, (gleam@int:to_string(Align))/binary>>; + + none -> + <<""/utf8>> + end, + Items_str = begin + _pipe = erlang:element(5, Def), + _pipe@1 = gleam@list:index_map(_pipe, fun(_, Item) -> case Item of + {Ty, Di} -> + <<<<(display_type(Ty))/binary, " "/utf8>>/binary, + (display_data_item(Di))/binary>> + end end), + gleam@string:join(_pipe@1, <<", "/utf8>>) + end, + <<<<<<<<<<<<<>/binary, + (erlang:element(3, Def))/binary>>/binary, + " ="/utf8>>/binary, + Align_str/binary>>/binary, + " { "/utf8>>/binary, + Items_str/binary>>/binary, + " }"/utf8>>. + +-spec display_statement(statement()) -> binary(). +display_statement(Stmt) -> + case Stmt of + {assign, Val, Typ, Inst} -> + <<<<<<<<(display_value(Val))/binary, " ="/utf8>>/binary, + (display_type(Typ))/binary>>/binary, + " "/utf8>>/binary, + (display_inst(Inst))/binary>>; + + {volatile, Inst@1} -> + display_inst(Inst@1) + end. + +-spec display_block(block()) -> binary(). +display_block(Block) -> + Label = erlang:element(2, Block), + Statements = begin + _pipe = erlang:element(3, Block), + _pipe@1 = gleam@list:map(_pipe, fun display_statement/1), + gleam@string:join(_pipe@1, <<"\n"/utf8>>) + end, + <<<Bn7s8c?r{egB_TaB504u3Umwf`6?yc%jCYU=mqb;DN<;qk3&!sf z9#(Odsq}CTco+q}WzeCW(#UL^te=&vKgB7dV11;F!te9-B!UPfhDGp`)^@bIx=f*z;3Qm-T7fF)x%n;9;W$kh^jV`iF{*2nJ5ZHResV93N2!Uq2<9O zTzlY8A25wq*6Yi2V4>*+qf)K|TrSj%MLi+5KYr&g2Rb5w4-_BgylNJGzhdqfIB{W_ zBGU5F<>gp6eI-n=sV+X^&P#-*#xvQVeZ`+J7%_&ZA-}fp_o!azO(GcWGKqhPllGRt zfcNQj#u+Sz``hHU`)Qm|alQ7hgo;CcB-m{Sbv-mPZCc#t6EAE*K;AS;!(uFlFfWlg zpyUfN-x*4OR=ScxmoU;x&UIIGaS(DwfbAl=fNXgRYmzTOm$TX84~WvA71juDcQ4cJ z(z9hUxXcA_Eh|Df5G^M}s2j+S@T5UBb0n0fz-~g&Nx*lk3}sA9bidEaMxp!g2pF?e zhJMgHZUa#JW^yiJ0|ek8krgDPnLG^+^Y zH+%XUqFbt-rQ`@5^15PfGuFv-L<)Ca$O{C&{wi@(2Whu+`D$&{&26(^3yiuYTfhCR zG-AU5>Lz*;9#4Gurx*S&C!}$`I4KrslKjNiSAW6yQCE(774%Ul2sZ=;jOX>VrI+}qVJ*6X(@9$LdwW!tCAtO0u>K#t%Km}$hrt5N|0ReT+BBs z8^J+pC9)2L*N^ZWlo^#nC@G`)co7ybs&AG6x@#HJ&p}>BB`7usk)~0Je2V3n5^=%q zauJ965h5bsF6gI9Fhexv9RlvbE(OTIqGA#npPm_*=ptWB2v17vR~^RS#3lqPHMO}N zB-Tl$N+3x}XQ5Igg^`Qdd=+wAez8!Qh;%9eGZ4^$U+|ql5joTmi>gZ8Wy5#tphW>~ zT>mV6Mnq=tWQa7xcp%%vmK#)btjc0HD2E;H+xEF_0$3}PPL^SUCw=U)nJC5xF%IFDk3#5~KkN1nE;I{T_Q6LEI&i^gs=#Y#vWR_=>_zNfgzgd%SGR_ZYd>?dWo#vo zQz8J73?!+z5(f?=l{2gSbPkvbPWJ)?fi~#58cvYExp2Y|I)n#kfz%947-}woBJlt> z=abzrMKz$A3_>gjRS?7w@YLA0;=nG13H{4yqsn9R;igTV$$6qErk2fzpG>Gm)RQ5; zWI&mpD+0<#FVpjVHU42?CNuJBV1_aL`AfgLM4W=J$Q)aCVo8xdCXE2UnI=m+0_D;0 z6&`9WkNTlDEi^PMXy5)mlm0D4`IVdfoo!6{RBov4bdZn>T@ZZ>qR){Y(X^b>mC#bX zgm(I=qi_rH22$oqr8Xxx2_VT;RMU(}&Isk_LINs>_|j!Cg9p(EII0PxrTd}Mf(@{$ z6G;tjzE5k7abypQ5{LvEz$a8EJ{zX{c>Dnxp_{#so&LwuWE5i;3| z9*?(4k7!mHptdLe`)ZdQQ3N5L%g5>eY_UuY^U%7VbYF2U2W-w_R_o~YL6=L;*qQ)^|oSpU#Bb}wg0 zt%QjgJ<&f&YoH7UIb-Gbai)FLSN=b6=xX5o<%ATB!iHE#LnK_Y)HXr33V@jZOQ*E`xkn zqf-w{Co>${bM2_WUR;uCy>_)6Kxk!PJf6t?vm7DyR2G0;)M~Lr!QK2OU{&9+qe_yX z5l5wm+)jDGNsLi!Q$TmejgvG|_|j9f!RjehCVt{VWy19dib$-j)@0hExDB723N*&ByGOf zKom>D4@LSb#}C!8#h`h6fjI|)bP0POq^Md5@(vqWRm2txW$UWrEKAJ{@k;V^D{2?G z{=i$mKtU`rBD6`WoPW`4TA&SLT7{)$Y{F&n76b!g`^V#4l{8NUNvbYWxy8UK;TJpF zFSe$s2M%ZC!Xx%gRmMSO5?o?tY;u~X$!X?Gs9#j^DSvvF1Oa`}zX~iQu`LBePuJ|b}Pfj(J zC$0K$U{^FL1&sv2cM&@E&JH=C2!@kNpgj!SO%zweC#;4jxLblpE}zn}3Bu*-IIUZN zsSCVGpgBVGsP<*ripog;phil|Hj3^Ye7_bEZy#4dD78x1w0~rUoV`PZ>NFU=6xND_ zgOeuY^aG6*i4wU{Z2xnEL=R*RoT|S&a`rw#h{%O@>G+Sg$TT@k1luIq#=l2L+ZbN@ zf-q2M7l*GWxsMT~DN_*kF|jZdAZ2~yD2TizkTT#;mm-{iJ)$rXp)`y04-k%VXcL{n z(gtA+mi7W0M{{VTY& zh}xM507)(4*y-X--MR+M*1RhsZH9n%HFU}x3e~U<3jW(1t(`QSPeG4S}W|BJ?8s|FpuS4E;rMeHuyzBO3%OV-! z^K7~psB|P+Y+OF&Av2npOrd;exdKU1BpHFe3X#B{QTqw?UMw%sUYU>Oi{;8Hot-P! z3svl#NkkZKQB>&Srj#X4#f|D4-z=URoqgh2UcdYON5B7fzfa3c!F6|e-}ecnEh@x% zR4?zNO_ggCA;vd0p@<)|5KFU)eQ7%nDuN^)!B~;BF+`RcD?E=73;9=C2eQnIR)JV% zuF4{kX(sQq>eRttVIa!exoU+{r$jbsN-OB*q)1E0mY08{kIUH0#tq{hmtow-DN(Jp zB1*lQXGd{|B!h4trm4=AW{ATsp_@a(Xw2Qa5xJz(gwY{Pta7G~AAjvQkt`Laxg`6| z0Lg9vdVe-T__ksB;dZwC@R|-8m^@0RUtc%(Jc2Iew&D-K&7pYQTmhT2RESbFp`OI=&;%uE@W?HJCgPFcy*8aR{V{YOO!q^(ym}hTgnm{f+9FH&gP>6#rlIHYRsFFRRl-Xw+VhT(Q~x!li9L>M1OgbH`2_^}}x4RPuycYg-_dP54)SZrMd zUSmn@4hX~de8;B|l+5-lP-2!I%EY!{j@p(O5o21*;0%-U+j2Uls3hTZVOC}M%>g2r ztx04>T?F(fB3BCyF(YU3CLTudegZZgNr~}<=17-z-vj6)M^DUL?FWidt!3mC9XNn0 zZ4XSM-7i11m$G=myuo*I!BuBfLkz^-7aFSdex1TFKZlmsPT~HA${uO==@g{bZ0(Tdyv!xuY>nVw?4m+DeZ%A?e!_mP z^bKwl)kGo+fuKgT2_vc>>65D;#WudLUg^9l6Ceq<1aZm0d+?C+#n4x#!!mg1&6(ZS(bF*rWD0g);djl*#wH)L=s6UAG<)!@QfU zLM^#TfhZ}C_#UU*YvWJ-H)BoZo0 zq2D==27ht)8$mW=mEIddJE(0QY~y{NQr6%G$OnZE#ZC$W>kvzmvJU$VWSvUOd#KBu z4thT`{uzqFab?~ApWS0FYQ1pL6^MaAVw(~JO|o{FvVV`{-*_s`+oSC5$iv135~x_7W^dwGXFEYXDN1cMbQ0`Q_>2 z8S;kC3GiGRJue6NxTVZ#C{=JR`~iMN<%H*rlc8Cc5mfA1fShn_S|EHROZiCDnb18D zJAeJeub!aJQeaK%aQk7=*?6nA6L#9h)*PXSdcwT!`$O^21I9rxODoV4&(QZE{b;k^_hDfp+Y8+H6qgs zgRacWUh7qs>oO4ywecpQC-sP*Y&zn|N;V#y|4l+8c#}|RH8dve{rlb|1WZ?9%z<|V zYRxS6)}r@7k%KNAeI3+=hR%K9R|&bhcd5>h8aNpO`$QQO8v^p7&DDh`6oMIP^d2G4 zyL#9{h>D5`+W`0iZ8aU&J4=QpLhC5%aK*15 zl^&3l=hD!OF5_?0ns|z+xefp0DdJT&PG1+s>FY2~_jbviN6_9`bdHKZF6>1l|y+|bbwmCJuP@IMA9Lab^LV+QTOB?Q_8aDT63dc*!P zOEkRL0*me0E&r1A*xN}Dn}S>u>0xwt+?bNm4d6`kEm)rB%P+M_KDdk1$i~G>aZq>w zXky5GX{UGO5mY3TT2A_`R|Y;Q+7R4dU+iv}4{xv!;fQ?gr957VN^dJv?@c3;qmACk zFa@nv7V7kBUZkb~ipI{aNMn(&s1Yrq6LVJ1K?a-mCnce|R}mTA5W;ky2(-X^k_BC| zEQ{)+RCSeVi7ux^UVcx2*mO>ma*-*;S!;`U-4+XcFZ1}L&d3(7lvfHUZiOF5FAt`n ziAq;Ei8+MroE2=sfa){kzwtJBIYop^xe=O}=vUhGM!vC8-%9VsK==^*MT^$}aCsH) zAC2!Q?m#vf_HHMnH(=zq^i~btj*dzuVaqjmM}W)*qt$S;#s63L%uezEO9+ZkWfQ$8 zUR#`$+34l7ui8IkKHDj6&PMw}eiA(JOrQBo)_kVD7s*`KHU-YWd!GcJMnHcLD>rGP zUM3DhV1XF2=M?Q#7-A2}z`7CM8gk0NJ)3vLp$1@5#vgy}aS04Vn$dRo(a_-y`+X&R zgbn3;|7%jbYKwn)e$xILUFtQZPvA3bsaXZ_nefD>RR{uG) z`l~7KcWA`A2rT0Df1J}QxAAe~&bc|K3LI%pm&EYCvTa6{vD>$R7ngXW87VBA+m@`Z z1zgl5pi8UMB%muHCxtxt1fsA9q!81Pq!MZyw<{VAS12@&>mIs&<#sB7Cm?eg6e$Ye zg{2S*bBJx`q2FOBsGW-1c70~Gn3`=<+t0Oqy&%J}38df(k-f{_sxDB7In8GlLcXT24fO0=}?cZFJ`KMe+6*Jtuez38McMhb| zjt1J41=N;GUubi-7HD=_1CG!%t1X?m3TRbiuBu^1&BlMu>_0%Jjtu^|dN~LOZ#Jy6 zNF#{$&awK7)M@l{)c%stwO@j+?c1ih6Y4RxqomT8e65EQyWC)m*PB2(D*FK%#OHEp zF3*4o4^6xEZ`$y?8D1|zX=$W)fTT3EIy-*_oo#>y8{jph{~$kz!wr* z+#0GtX88ZCeeQS2kl>avkzPY$0(#dg6>dmZC))hxku)p&5oo%KFp~$G5Ci8+TQ;s0r|Z7B>Ro&I#Icw=2@G(N zSHWM2RzT(1uv?AB8NVnp6Egz~p}=if_>ZAhDnJwC5^vz8yDqxBJEKmQVDo_jY7GOw>1ej&dTwm=1^U^dL8+PXcDLyAyMMR zam9RTp^lB1;Va@@XI^dNd-d6I?#6=$wO%~L&GPGK8vQ1A-k|P>?-Lolnvi95!jli} zlD5`!pf}K1Dq+zkl&`+{gBJ;7f|g<{K9=AdBN=l3b06i%my0mevpK+`O}KwqN>Ny! z8|B_DOFJb1BzcDwqAl2(U%L0dql8{UA$W~F@8eAaG#{fkE|XofA-1gJ$PXjFfBod` zar4NSdF&(R$*g&Dk7%(A>Zn2lU;VYrM64v|KLoZ`p2=c0DZDOe49|_TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache new file mode 100644 index 0000000000000000000000000000000000000000..3df3b89f7a0e8991141a83ee6ea85df10fc246c1 GIT binary patch literal 46265 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%0A# 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 Lc~|2ZcNPEuC=VMA literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache new file mode 100644 index 0000000000000000000000000000000000000000..44187b1f3e10bfbd421efb27189f53ea669cc799 GIT binary patch literal 4750 zcmc&%O>Y}j6rKCV&SV_BlZ%_SNfY8a6p&RE#a0FK#W-5`WmwNfjwtk@xS#irc%=EEP@uInIJ%$qkeZ$|H& zd+xb+&Ok{16D}w?U&ON~*Pfh&_#ejr@p}BPV-UZk!SmgkSvgoes7TOo=UXjD(yBG< zYCgm;oYX@QQa-3O0Q7TA#&!wA#Wl6u`{E{jq-7@BAsU=LGqLS{wQ5~+wi5?-wOun4 zR=wqza-}K(swq^<7%OS(w7}az)sp0Ejy}y~U=kew66?LnuQU82rGE}`yaHKc8)&j5 zXN^UfCSQh9#+?vNa4KocPSNDNQZ(LCX!6l?%D6I3lONTB@ql=th-vS56Z$zh=Iru0QR#frE{ zV?=DTJJ1rtC(m;2Mz!L2+c(x>;{6}$Ka2fG#s1e)xK_sVCE8<%cFGavSM`tiiecdv z3mJqd;2sBARIg)fHFv4uSa#jpy4{d8e#sZn*J-&JiH8@+sq_6XMHsU_IafG29t}P8 zNC2Ba@Opa7;HXTnB&yK+9?ZKQ* z3Dk{`{O#h5*c z)_xt#OT^dOp)QykO3$<)P$jLAUP(awMFzp$;11mvtOThf)FNPv-3=Q^Xd)3gtW z6jvmgeZy=@Qs&Xjn^9%g^o8Be01W!S$ zHf>%ZsSp$=7k5d&Ga!}})_e-{X|mCwqSge;Sqga{8w|8@pa<`VfkGQd{ykAWIJO?l zo;@;zH}caAV=0W%LOyyt2+fnqzl%JK96B}^z`qgxmnxGeD0#(0KZa8L7u@g{dgSec z=%ImSHoykWsqA}2^nVF`T;M!DDD?4hLLa<8DD)g#59a>R7lP0q?we-As_&B3@ua8d zN7V~zZpW%QCKUyq8pgS!M?dg)$~+DMZG2pvNF?f#~ZHC)$e4*UE3o;a;V+wQqjn^%3_b_ROK>;pB+&K+mW= zoa&@bA3p+e0T%!nU>YzS@%KyK3&n2S)J91#3z;0dN_J6xeo$#_-Kf;sl5Dm%LH2Y( zPCIGyT++XvSQqmG=R%;1;F{2%9w&F)7f$m|fkaUDE5=1pF}k64QzG@}5Ep@KpF#j` zrvRC^LR%q(Y_4k7Oven!(kCyVL&dN-LJahb=vW$u4u9#uoN!@`B*LvDSzbq63-Pc6 zWL}S4j3A^m%88C{^vUz$CI7iz6(lToGU6X?2LoC&=--R)xCb@M+z&mX$flPM%;s(< zu*RvQWWn75S>SaJW!xD0rws{#?92!O_$$Wfp!}t-0MdR56{hH-?O~!n5xV*auW5Gw zBr@Ns4^*BC+&Q{@KmOZ&?k&8FR?Pt3yK*o5XT literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..0b52486cfc5f05044b9b56a9fe4cd784dca2c15b GIT binary patch literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache new file mode 100644 index 0000000000000000000000000000000000000000..537182b25f7b45440690c47eab0d251232bcc2d0 GIT binary patch literal 7259 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 LbkSifVsD@q4wtD{ literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..2395015401100f34736675fe98225d853098d534 GIT binary patch literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache new file mode 100644 index 0000000000000000000000000000000000000000..3a2037f8bfbede0d447b1c3e951f8488d545e9de GIT binary patch literal 1879 zcmcJQPiqrF6u@_8v)y)0h-0AGg5=Rsn#9_gL@$B<6Dma%yNOT;NVDxulhw^8WH)U@ zz4r?U6+HCf!LQ**@F)nLMLl^Eq`sL=V$+6F5f3|g^CvI!e)-KT&=s9cl-Z2VW~zyI zy3W{>#9Mtf@k!T@t1h?d3r$N=omSY{@&hGqyUz9sUA;=#jVW`EsEG%pT-qQQe50At zSBk+ewOEYc=W8ujI@B;|j}%J52vK#9?-OE1scIe&jS)jp2vHO^wrSp^s-l>qR3%iw z2Zu3}oKnc(utq3jQ)Y({7Avz3$;LitBJtpcp~!=F%k#&<0-S`V<+Nbm32G43I8>cI z?g4jsoqK^l507e&4?C6zmg_fQn}gl(IJAAotIG8@x1Aj;;I;w&GcT|@;COz(ExP~} z%$~~5K`sr8i!dFAm3adUn4W%rwAQieO_%$kU#V0iR0Ed8p2DTLtQX+C0SJZUZS6oi zu3OD5pYJpj)w8?QKA)m?(5EI?UE4&Qg6Hi8bG<)9ktjY$lbR91S47xG&JgY{#0kl` zY&MZGE3-Ew%Z$PO42PW<3R~3R**)4&v-Skmnq@;p{2>*vnoZZ?HUtd=oM7G%39Yu4yo)aizFg#f+YOjDiR0?Sr^&TetI@hlegl8` BnTh}a literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..a2089a5966a154b5dd61585b9e0a71668b274981 GIT binary patch literal 29 Wcmb15HB4nd2a#5L@9-R#`vm|lvIQ^z literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache new file mode 100644 index 0000000000000000000000000000000000000000..4af2a984fabae78b73642b949e602a8ebffc5152 GIT binary patch literal 7006 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 Ph37G(Phrp01=-8 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..d6129ae46ca64f4056698206dc7d3f0de91184f9 GIT binary patch literal 49 ncmd<{vr1)v0Y)f;2TG^sq$cL-=NFV@=I0$1IkMi{#QhNfhQkTV literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache new file mode 100644 index 0000000000000000000000000000000000000000..c9328b3e01d12cd9f0c43099a54e78e9b65c0fb8 GIT binary patch literal 10381 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 C4H$L+ literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..e4e832bc82346f74985f18beddf6b6e9edaf3e83 GIT binary patch literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache new file mode 100644 index 0000000000000000000000000000000000000000..c54e05a7b73d4c922761a7bd63b2e2e860e6c593 GIT binary patch literal 21839 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 A#{d8T literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..7c72b25579dddf57ca0f1d52e021b5c2d8247d4f GIT binary patch literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache new file mode 100644 index 0000000000000000000000000000000000000000..46563080f8b9fb45648765a455f9a47a30df605a GIT binary patch literal 10571 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 N$_8bVnG&ss{0~7TdsYAd literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..b367bfd9115d8e2fc3444f02c1f95e0fb2fa654a GIT binary patch literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_T#>Yuzq+sB8vuA}30D9B literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache new file mode 100644 index 0000000000000000000000000000000000000000..00887a7dc8161207703959ccd973b9e5454d4c13 GIT binary patch literal 7769 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@uri.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..2ae412bccfd7739434a236925520c9652e93ff84 GIT binary patch literal 132 zcmX@|G$oY*23VmCPAHw8lbV>TpP5&}g(8rXSzN+{B9dQFl9``}Dpp)ll$n<nW832Uh9(Di# literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version new file mode 100644 index 00000000000..7dd8dc5809e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleam_version @@ -0,0 +1 @@ +0.32.4 \ No newline at end of file diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache new file mode 100644 index 0000000000000000000000000000000000000000..e2a24f1b35167bc143baa6286b81cdb86116470b GIT binary patch literal 3252 zcmbVOPi)g>6!&K*aTB$Kr>=-1x*7z7SN>ErQReb}6?uW4kvf_K2J`IBMwe8UMTtU!|iV{?0NLL}78_+I6 z_Az3BDS71Ofz!f@DB-8O$Y7#sLGCNRG*o#FCaM5(^2QL2*Xg$BhaY>yYB_Y-Y*K;j z1Gy7J-g_$%xd?5(5_-)z0`o&bs*tV1gv<{P!M5nuJ5J1tuv9LH zKnt2hB>1hPJtfklM%MIIf&vvwx+M~+*p`kF{R@e`OI_DjQz)#bRsGX63jd}T^naM} zZAR4}WKj4)ey;y0qhO9L=o@1w{DQ(0CM;!D{c4s-v&-IU*v1Hqi;{MZq=DoF5wZtK z4IpcvpdBX!6vCsFi?j`dNh+?(wITGuXfcBqUKl)h)<7fx9qkmFJ&O|3Gq;zXi7Jtb z&oX~yx((a4jE3z95)ER9A4c{CLIeS_H?^yxgm1?1o4`y7W(qJPqc~N9sREWkSr2{8 z^(+>n*+c^E{*6bo$d>|S=kg!fK^Ps>Qe0oQ#NX^uk|rX+nx>#Xa0^!OJC}gkk7nLz zG;AaqSs?^3ku#Ms5hjkoIAQcUOeEVSq}w#Z`c}lq;)C?>>2g#EvBysn9?xmtaE}oo zLC-M+n3&l84xFyS+syqFDx4_5iMj5}OKOPQuh>FZ3=hJ-DJ%zoQi6W5tNn-xQjyBv z$z98IH>vNnq`+w#b-l6#O$F~1ie>th$)`JnBZO}oxAWH#rlwlK?o zW01M~s)jQQCJJyA@8t3!#Ttsno>=@t&Wz=^OsD7SM#9xO?QD<9%-+eU*5oBOE<%>Z zf&Z6nCn`>E8EY=KT#79-JN;mPm3o-kdEaw9pIULCo&BswJwVPccwXNOGyjUUfE-6? z3ki<*a3n}RBdc=0X|np~G`O5VC-ahK^LbPVm>E@j#A08CN96p(y)0KZU_|IDSFnL9 zrhCd#ka&veI0{RU(rCGLwnzj@!}FDJiz@Y&?^8Eawtepwt%pi0z<#7Ga_*i9l*Jpk zA>`uAKF;&Io`3t@Tu!OD?f8^}ns8w;n=iC0w##*IFq<2SW&5bv^V`Z@JKR!C1$jgj zYS|$(WxF|L!-!7Wfr1qu*cQd?;lTuEbjLys=t_+;uNaD@29sQ-$8(jcdB@c2zP%mt zo5A4ep6z-oz~YQFR7J8-5`v{~}NEh;} zev8gtF`a-8o5nyoLwBKpp#(&Y&?okE-l1`CDfRLmZF2EI#YfO`LP#G&2-3CNvx~m( H`G?8>b;>hi literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..35823f819643250ce036eb3ade6a8b4cfeac4a68 GIT binary patch literal 108 zcmYdhxRAmC11wMm7nDxVNlnbv&&ez<;Xx58N-ZwUK@%%3Day=C=S5MMQkj>So0{V$)JKF zWa-8y@DT*{E!_Ghg1A!Rxs#b`A~hRb03vAM_KuVZSN!Ua98YlJA#K_ z!u5XY;iYVPFC-7^M#rlgD4qSlkB$-586njxGzm)phyYaFP&+~bD1%p|;uaN~RNT9@ z8;s&`>@Y(2sag>d1@MP|BJ^Y;5*?|v~+IYa8k?v+=I@n znUnOc%<1Js^Pzk#{3!69UlCMxsk}s I@7G!U4Me2lCjbBd literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/gleeunit/_gleam_artefacts/gleeunit@should.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..401fd74cd1e9eb44559765e4eac26450d3f34537 GIT binary patch literal 29 VcmYdhxRAnt0g5sw8KyG$0suA|1Lyz% literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache b/test-community-packages-javascript/build/packages/glx/build/lsp/erlang/glx/_gleam_artefacts/glx@stringx.cache new file mode 100644 index 0000000000000000000000000000000000000000..f005a617477a85e6a547a334a7ebb0b84cbae461 GIT binary patch literal 552 zcmah`!A`G#jF40 z*XXo8c`zJy-^{$(w{J3aIdZTy!5s&8wi++sAo`6t>^45Z`H9n2Uul^bj)+$dWh3*n zVxm0=DqywKL~sQVY?@Z^4mN^o7yyQW)qc=5EyD;ZbOTn8u{yx2GrS`y5x3)%NAsJK z>J?PKc9key5^EmW0EmO&gTR~M2ON5r8>N%KZhzP<*GnlBV|vC};gvmQLPz9!$`VnO z. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md new file mode 100644 index 00000000000..05c68ca9075 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/README.md @@ -0,0 +1,39 @@ +# stdlib + +GitHub release +Discord chat +![CI](https://github.com/gleam-lang/stdlib/workflows/CI/badge.svg?branch=main) + +Gleam's standard library! +Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). + +## Installation + +Add `gleam_stdlib` to your Gleam project. + +```sh +gleam add gleam_stdlib +``` + +## Usage + +Import the modules you want to use and write some code! + +```gleam +import gleam/string + +pub fn greet(name: String) -> String { + string.concat(["Hello ", name, "!"]) +} +``` + +## Targets + +Gleam's standard library supports both targets: Erlang and JavaScript. + +### Compatibility + +This library is compatible with all versions of Erlang/OTP, NodeJS, and +major browsers that are currently supported by their maintainers. If you +have a compatibility issue with any platform open an issue and we'll see +what we can do to help. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml new file mode 100644 index 00000000000..a978a7ff425 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/gleam.toml @@ -0,0 +1,16 @@ +name = "gleam_stdlib" +version = "0.33.1" +gleam = ">= 0.32.0" +licences = ["Apache-2.0"] +description = "A standard library for the Gleam programming language" + +repository = { type = "github", user = "gleam-lang", repo = "stdlib" } +links = [ + { title = "Website", href = "https://gleam.run" }, + { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, +] + +[javascript.deno] +allow_read = [ + "./", +] diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl new file mode 100644 index 00000000000..b1135f2dea0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl @@ -0,0 +1,5 @@ +-record(decode_error, { + expected :: binary(), + found :: binary(), + path :: list(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl new file mode 100644 index 00000000000..b0d08dc71a3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl @@ -0,0 +1 @@ +-record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl new file mode 100644 index 00000000000..1f61922beda --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl @@ -0,0 +1 @@ +-record(next, {element :: any(), accumulator :: any()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl new file mode 100644 index 00000000000..88ac25ed0a7 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl @@ -0,0 +1 @@ +-record(queue, {in :: list(any()), out :: list(any())}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl new file mode 100644 index 00000000000..ad5511eb103 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl @@ -0,0 +1 @@ +-record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl new file mode 100644 index 00000000000..42166198699 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl @@ -0,0 +1,4 @@ +-record(match, { + content :: binary(), + submatches :: list(gleam@option:option(binary())) +}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl new file mode 100644 index 00000000000..0074603b961 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl @@ -0,0 +1 @@ +-record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl new file mode 100644 index 00000000000..6e1e2261268 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@set_Set.hrl @@ -0,0 +1 @@ +-record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl new file mode 100644 index 00000000000..50150f476b1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl @@ -0,0 +1,9 @@ +-record(uri, { + scheme :: gleam@option:option(binary()), + userinfo :: gleam@option:option(binary()), + host :: gleam@option:option(binary()), + port :: gleam@option:option(integer()), + path :: binary(), + 'query' :: gleam@option:option(binary()), + fragment :: gleam@option:option(binary()) +}). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs new file mode 100644 index 00000000000..a8309e0cdbd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/dict.mjs @@ -0,0 +1,957 @@ +/** + * This file uses jsdoc to annotate types. + * These types can be checked using the typescript compiler with "checkjs" option. + */ + +import { isEqual } from "./gleam.mjs"; + +const referenceMap = new WeakMap(); +const tempDataView = new DataView(new ArrayBuffer(8)); +let referenceUID = 0; +/** + * hash the object by reference using a weak map and incrementing uid + * @param {any} o + * @returns {number} + */ +function hashByReference(o) { + const known = referenceMap.get(o); + if (known !== undefined) { + return known; + } + const hash = referenceUID++; + if (referenceUID === 0x7fffffff) { + referenceUID = 0; + } + referenceMap.set(o, hash); + return hash; +} +/** + * merge two hashes in an order sensitive way + * @param {number} a + * @param {number} b + * @returns {number} + */ +function hashMerge(a, b) { + return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; +} +/** + * standard string hash popularised by java + * @param {string} s + * @returns {number} + */ +function hashString(s) { + let hash = 0; + const len = s.length; + for (let i = 0; i < len; i++) { + hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; + } + return hash; +} +/** + * hash a number by converting to two integers and do some jumbling + * @param {number} n + * @returns {number} + */ +function hashNumber(n) { + tempDataView.setFloat64(0, n); + const i = tempDataView.getInt32(0); + const j = tempDataView.getInt32(4); + return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; +} +/** + * hash a BigInt by converting it to a string and hashing that + * @param {BigInt} n + * @returns {number} + */ +function hashBigInt(n) { + return hashString(n.toString()); +} +/** + * hash any js object + * @param {any} o + * @returns {number} + */ +function hashObject(o) { + const proto = Object.getPrototypeOf(o); + if (proto !== null && typeof proto.hashCode === "function") { + try { + const code = o.hashCode(o); + if (typeof code === "number") { + return code; + } + } catch {} + } + if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { + return hashByReference(o); + } + if (o instanceof Date) { + return hashNumber(o.getTime()); + } + let h = 0; + if (o instanceof ArrayBuffer) { + o = new Uint8Array(o); + } + if (Array.isArray(o) || o instanceof Uint8Array) { + for (let i = 0; i < o.length; i++) { + h = (Math.imul(31, h) + getHash(o[i])) | 0; + } + } else if (o instanceof Set) { + o.forEach((v) => { + h = (h + getHash(v)) | 0; + }); + } else if (o instanceof Map) { + o.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + } else { + const keys = Object.keys(o); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + const v = o[k]; + h = (h + hashMerge(getHash(v), hashString(k))) | 0; + } + } + return h; +} +/** + * hash any js value + * @param {any} u + * @returns {number} + */ +export function getHash(u) { + if (u === null) return 0x42108422; + if (u === undefined) return 0x42108423; + if (u === true) return 0x42108421; + if (u === false) return 0x42108420; + switch (typeof u) { + case "number": + return hashNumber(u); + case "string": + return hashString(u); + case "bigint": + return hashBigInt(u); + case "object": + return hashObject(u); + case "symbol": + return hashByReference(u); + case "function": + return hashByReference(u); + default: + return 0; // should be unreachable + } +} +/** + * @template K,V + * @typedef {ArrayNode | IndexNode | CollisionNode} Node + */ +/** + * @template K,V + * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry + */ +/** + * @template K,V + * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry | Node)[] }} ArrayNode + */ +/** + * @template K,V + * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry | Node)[] }} IndexNode + */ +/** + * @template K,V + * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry[] }} CollisionNode + */ +/** + * @typedef {{ val: boolean }} Flag + */ +const SHIFT = 5; // number of bits you need to shift by to get the next bucket +const BUCKET_SIZE = Math.pow(2, SHIFT); +const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket +const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node +const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node +const ENTRY = 0; +const ARRAY_NODE = 1; +const INDEX_NODE = 2; +const COLLISION_NODE = 3; +/** @type {IndexNode} */ +const EMPTY = { + type: INDEX_NODE, + bitmap: 0, + array: [], +}; +/** + * Mask the hash to get only the bucket corresponding to shift + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function mask(hash, shift) { + return (hash >>> shift) & MASK; +} +/** + * Set only the Nth bit where N is the masked hash + * @param {number} hash + * @param {number} shift + * @returns {number} + */ +function bitpos(hash, shift) { + return 1 << mask(hash, shift); +} +/** + * Count the number of 1 bits in a number + * @param {number} x + * @returns {number} + */ +function bitcount(x) { + x -= (x >> 1) & 0x55555555; + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x += x >> 8; + x += x >> 16; + return x & 0x7f; +} +/** + * Calculate the array index of an item in a bitmap index node + * @param {number} bitmap + * @param {number} bit + * @returns {number} + */ +function index(bitmap, bit) { + return bitcount(bitmap & (bit - 1)); +} +/** + * Efficiently copy an array and set one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function cloneAndSet(arr, at, val) { + const len = arr.length; + const out = new Array(len); + for (let i = 0; i < len; ++i) { + out[i] = arr[i]; + } + out[at] = val; + return out; +} +/** + * Efficiently copy an array and insert one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @param {T} val + * @returns {T[]} + */ +function spliceIn(arr, at, val) { + const len = arr.length; + const out = new Array(len + 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + out[g++] = val; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Efficiently copy an array and remove one value at an index + * @template T + * @param {T[]} arr + * @param {number} at + * @returns {T[]} + */ +function spliceOut(arr, at) { + const len = arr.length; + const out = new Array(len - 1); + let i = 0; + let g = 0; + while (i < at) { + out[g++] = arr[i++]; + } + ++i; + while (i < len) { + out[g++] = arr[i++]; + } + return out; +} +/** + * Create a new node containing two entries + * @template K,V + * @param {number} shift + * @param {K} key1 + * @param {V} val1 + * @param {number} key2hash + * @param {K} key2 + * @param {V} val2 + * @returns {Node} + */ +function createNode(shift, key1, val1, key2hash, key2, val2) { + const key1hash = getHash(key1); + if (key1hash === key2hash) { + return { + type: COLLISION_NODE, + hash: key1hash, + array: [ + { type: ENTRY, k: key1, v: val1 }, + { type: ENTRY, k: key2, v: val2 }, + ], + }; + } + const addedLeaf = { val: false }; + return assoc( + assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), + shift, + key2hash, + key2, + val2, + addedLeaf + ); +} +/** + * @template T,K,V + * @callback AssocFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @param {V} val + * @param {Flag} addedLeaf + * @returns {Node} + */ +/** + * Associate a node with a new entry, creating a new node + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assoc(root, shift, hash, key, val, addedLeaf) { + switch (root.type) { + case ARRAY_NODE: + return assocArray(root, shift, hash, key, val, addedLeaf); + case INDEX_NODE: + return assocIndex(root, shift, hash, key, val, addedLeaf); + case COLLISION_NODE: + return assocCollision(root, shift, hash, key, val, addedLeaf); + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocArray(root, shift, hash, key, val, addedLeaf) { + const idx = mask(hash, shift); + const node = root.array[idx]; + // if the corresponding index is empty set the index to a newly created node + if (node === undefined) { + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size + 1, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + if (node.type === ENTRY) { + // if keys are equal replace the entry + if (isEqual(key, node.k)) { + if (val === node.v) { + return root; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // otherwise upgrade the entry to a node and insert + addedLeaf.val = true; + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, node.k, node.v, hash, key, val) + ), + }; + } + // otherwise call assoc on the child node + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + // if the child node hasn't changed just return the old root + if (n === node) { + return root; + } + // otherwise set the index to the new node + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocIndex(root, shift, hash, key, val, addedLeaf) { + const bit = bitpos(hash, shift); + const idx = index(root.bitmap, bit); + // if there is already a item at this hash index.. + if ((root.bitmap & bit) !== 0) { + // if there is a node at the index (not an entry), call assoc on the child node + const node = root.array[idx]; + if (node.type !== ENTRY) { + const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); + if (n === node) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise there is an entry at the index + // if the keys are equal replace the entry with the updated value + const nodeKey = node.k; + if (isEqual(key, nodeKey)) { + if (val === node.v) { + return root; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }), + }; + } + // if the keys are not equal, replace the entry with a new child node + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet( + root.array, + idx, + createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) + ), + }; + } else { + // else there is currently no item at the hash index + const n = root.array.length; + // if the number of nodes is at the maximum, expand this node into an array node + if (n >= MAX_INDEX_NODE) { + // create a 32 length array for the new array node (one for each bit in the hash) + const nodes = new Array(32); + // create and insert a node for the new entry + const jdx = mask(hash, shift); + nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); + let j = 0; + let bitmap = root.bitmap; + // place each item in the index node into the correct spot in the array node + // loop through all 32 bits / array positions + for (let i = 0; i < 32; i++) { + if ((bitmap & 1) !== 0) { + const node = root.array[j++]; + nodes[i] = node; + } + // shift the bitmap to process the next bit + bitmap = bitmap >>> 1; + } + return { + type: ARRAY_NODE, + size: n + 1, + array: nodes, + }; + } else { + // else there is still space in this index node + // simply insert a new entry at the hash index + const newArray = spliceIn(root.array, idx, { + type: ENTRY, + k: key, + v: val, + }); + addedLeaf.val = true; + return { + type: INDEX_NODE, + bitmap: root.bitmap | bit, + array: newArray, + }; + } + } +} +/** + * @template T,K,V + * @type {AssocFunction,K,V>} + */ +function assocCollision(root, shift, hash, key, val, addedLeaf) { + // if there is a hash collision + if (hash === root.hash) { + const idx = collisionIndexOf(root, key); + // if this key already exists replace the entry with the new value + if (idx !== -1) { + const entry = root.array[idx]; + if (entry.v === val) { + return root; + } + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), + }; + } + // otherwise insert the entry at the end of the array + const size = root.array.length; + addedLeaf.val = true; + return { + type: COLLISION_NODE, + hash: hash, + array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), + }; + } + // if there is no hash collision, upgrade to an index node + return assoc( + { + type: INDEX_NODE, + bitmap: bitpos(root.hash, shift), + array: [root], + }, + shift, + hash, + key, + val, + addedLeaf + ); +} +/** + * Find the index of a key in the collision node's array + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {number} + */ +function collisionIndexOf(root, key) { + const size = root.array.length; + for (let i = 0; i < size; i++) { + if (isEqual(key, root.array[i].k)) { + return i; + } + } + return -1; +} +/** + * @template T,K,V + * @callback FindFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Entry} + */ +/** + * Return the found entry or undefined if not present in the root + * @template K,V + * @type {FindFunction,K,V>} + */ +function find(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return findArray(root, shift, hash, key); + case INDEX_NODE: + return findIndex(root, shift, hash, key); + case COLLISION_NODE: + return findCollision(root, key); + } +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return undefined; + } + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @type {FindFunction,K,V>} + */ +function findIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return undefined; + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + if (node.type !== ENTRY) { + return find(node, shift + SHIFT, hash, key); + } + if (isEqual(key, node.k)) { + return node; + } + return undefined; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Entry} + */ +function findCollision(root, key) { + const idx = collisionIndexOf(root, key); + if (idx < 0) { + return undefined; + } + return root.array[idx]; +} +/** + * @template T,K,V + * @callback WithoutFunction + * @param {T} root + * @param {number} shift + * @param {number} hash + * @param {K} key + * @returns {undefined | Node} + */ +/** + * Remove an entry from the root, returning the updated root. + * Returns undefined if the node should be removed from the parent. + * @template K,V + * @type {WithoutFunction,K,V>} + * */ +function without(root, shift, hash, key) { + switch (root.type) { + case ARRAY_NODE: + return withoutArray(root, shift, hash, key); + case INDEX_NODE: + return withoutIndex(root, shift, hash, key); + case COLLISION_NODE: + return withoutCollision(root, key); + } +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutArray(root, shift, hash, key) { + const idx = mask(hash, shift); + const node = root.array[idx]; + if (node === undefined) { + return root; // already empty + } + let n = undefined; + // if node is an entry and the keys are not equal there is nothing to remove + // if node is not an entry do a recursive call + if (node.type === ENTRY) { + if (!isEqual(node.k, key)) { + return root; // no changes + } + } else { + n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + } + // if the recursive call returned undefined the node should be removed + if (n === undefined) { + // if the number of child nodes is at the minimum, pack into an index node + if (root.size <= MIN_ARRAY_NODE) { + const arr = root.array; + const out = new Array(root.size - 1); + let i = 0; + let j = 0; + let bitmap = 0; + while (i < idx) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + ++i; // skip copying the removed node + while (i < arr.length) { + const nv = arr[i]; + if (nv !== undefined) { + out[j] = nv; + bitmap |= 1 << i; + ++j; + } + ++i; + } + return { + type: INDEX_NODE, + bitmap: bitmap, + array: out, + }; + } + return { + type: ARRAY_NODE, + size: root.size - 1, + array: cloneAndSet(root.array, idx, n), + }; + } + return { + type: ARRAY_NODE, + size: root.size, + array: cloneAndSet(root.array, idx, n), + }; +} +/** + * @template K,V + * @type {WithoutFunction,K,V>} + */ +function withoutIndex(root, shift, hash, key) { + const bit = bitpos(hash, shift); + if ((root.bitmap & bit) === 0) { + return root; // already empty + } + const idx = index(root.bitmap, bit); + const node = root.array[idx]; + // if the item is not an entry + if (node.type !== ENTRY) { + const n = without(node, shift + SHIFT, hash, key); + if (n === node) { + return root; // no changes + } + // if not undefined, the child node still has items, so update it + if (n !== undefined) { + return { + type: INDEX_NODE, + bitmap: root.bitmap, + array: cloneAndSet(root.array, idx, n), + }; + } + // otherwise the child node should be removed + // if it was the only child node, remove this node from the parent + if (root.bitmap === bit) { + return undefined; + } + // otherwise just remove the child node + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + // otherwise the item is an entry, remove it if the key matches + if (isEqual(key, node.k)) { + if (root.bitmap === bit) { + return undefined; + } + return { + type: INDEX_NODE, + bitmap: root.bitmap ^ bit, + array: spliceOut(root.array, idx), + }; + } + return root; +} +/** + * @template K,V + * @param {CollisionNode} root + * @param {K} key + * @returns {undefined | Node} + */ +function withoutCollision(root, key) { + const idx = collisionIndexOf(root, key); + // if the key not found, no changes + if (idx < 0) { + return root; + } + // otherwise the entry was found, remove it + // if it was the only entry in this node, remove the whole node + if (root.array.length === 1) { + return undefined; + } + // otherwise just remove the entry + return { + type: COLLISION_NODE, + hash: root.hash, + array: spliceOut(root.array, idx), + }; +} +/** + * @template K,V + * @param {undefined | Node} root + * @param {(value:V,key:K)=>void} fn + * @returns {void} + */ +function forEach(root, fn) { + if (root === undefined) { + return; + } + const items = root.array; + const size = items.length; + for (let i = 0; i < size; i++) { + const item = items[i]; + if (item === undefined) { + continue; + } + if (item.type === ENTRY) { + fn(item.v, item.k); + continue; + } + forEach(item, fn); + } +} +/** + * Extra wrapper to keep track of Dict size and clean up the API + * @template K,V + */ +export default class Dict { + /** + * @template V + * @param {Record} o + * @returns {Dict} + */ + static fromObject(o) { + const keys = Object.keys(o); + /** @type Dict */ + let m = Dict.new(); + for (let i = 0; i < keys.length; i++) { + const k = keys[i]; + m = m.set(k, o[k]); + } + return m; + } + /** + * @template K,V + * @param {Map} o + * @returns {Dict} + */ + static fromMap(o) { + /** @type Dict */ + let m = Dict.new(); + o.forEach((v, k) => { + m = m.set(k, v); + }); + return m; + } + static new() { + return new Dict(undefined, 0); + } + /** + * @param {undefined | Node} root + * @param {number} size + */ + constructor(root, size) { + this.root = root; + this.size = size; + } + /** + * @template NotFound + * @param {K} key + * @param {NotFound} notFound + * @returns {NotFound | V} + */ + get(key, notFound) { + if (this.root === undefined) { + return notFound; + } + const found = find(this.root, 0, getHash(key), key); + if (found === undefined) { + return notFound; + } + return found.v; + } + /** + * @param {K} key + * @param {V} val + * @returns {Dict} + */ + set(key, val) { + const addedLeaf = { val: false }; + const root = this.root === undefined ? EMPTY : this.root; + const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); + if (newRoot === this.root) { + return this; + } + return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); + } + /** + * @param {K} key + * @returns {Dict} + */ + delete(key) { + if (this.root === undefined) { + return this; + } + const newRoot = without(this.root, 0, getHash(key), key); + if (newRoot === this.root) { + return this; + } + if (newRoot === undefined) { + return Dict.new(); + } + return new Dict(newRoot, this.size - 1); + } + /** + * @param {K} key + * @returns {boolean} + */ + has(key) { + if (this.root === undefined) { + return false; + } + return find(this.root, 0, getHash(key), key) !== undefined; + } + /** + * @returns {[K,V][]} + */ + entries() { + if (this.root === undefined) { + return []; + } + /** @type [K,V][] */ + const result = []; + this.forEach((v, k) => result.push([k, v])); + return result; + } + /** + * + * @param {(val:V,key:K)=>void} fn + */ + forEach(fn) { + forEach(this.root, fn); + } + hashCode() { + let h = 0; + this.forEach((v, k) => { + h = (h + hashMerge(getHash(v), getHash(k))) | 0; + }); + return h; + } + /** + * @param {unknown} o + * @returns {boolean} + */ + equals(o) { + if (!(o instanceof Dict) || this.size !== o.size) { + return false; + } + let equal = true; + this.forEach((v, k) => { + equal = equal && isEqual(o.get(k, !v), v); + }); + return equal; + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam new file mode 100644 index 00000000000..eab2f0b3fec --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/base.gleam @@ -0,0 +1,21 @@ +import gleam/bit_array + +@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") +pub fn encode64(input: BitArray, padding: Bool) -> String { + bit_array.base64_encode(input, padding) +} + +@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") +pub fn decode64(encoded: String) -> Result(BitArray, Nil) { + bit_array.base64_decode(encoded) +} + +@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") +pub fn url_encode64(input: BitArray, padding: Bool) -> String { + bit_array.base64_url_encode(input, padding) +} + +@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") +pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { + bit_array.base64_url_decode(encoded) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam new file mode 100644 index 00000000000..79860e964ef --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_array.gleam @@ -0,0 +1,157 @@ +//// BitArrays are a sequence of binary data of any length. + +import gleam/string + +/// Converts a UTF-8 `String` type into a `BitArray`. +/// +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") +pub fn from_string(x: String) -> BitArray + +/// Returns an integer which is the number of bytes in the bit array. +/// +@external(erlang, "erlang", "byte_size") +@external(javascript, "../gleam_stdlib.mjs", "length") +pub fn byte_size(x: BitArray) -> Int + +/// Creates a new bit array by joining two bit arrays. +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: from_string("butter"), suffix: from_string("fly")) +/// from_string("butterfly") +/// ``` +/// +pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { + concat([first, second]) +} + +/// Extracts a sub-section of a bit array. +/// +/// The slice will start at given position and continue up to specified +/// length. +/// A negative length can be used to extract bytes at the end of a bit array. +/// +/// This function runs in constant time. +/// +@external(erlang, "gleam_stdlib", "bit_array_slice") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") +pub fn slice( + from string: BitArray, + at position: Int, + take length: Int, +) -> Result(BitArray, Nil) + +/// Tests to see whether a bit array is valid UTF-8. +/// +pub fn is_utf8(bits: BitArray) -> Bool { + do_is_utf8(bits) +} + +@target(erlang) +fn do_is_utf8(bits: BitArray) -> Bool { + case bits { + <<>> -> True + <<_:utf8, rest:bytes>> -> do_is_utf8(rest) + _ -> False + } +} + +@target(javascript) +fn do_is_utf8(bits: BitArray) -> Bool { + case to_string(bits) { + Ok(_) -> True + _ -> False + } +} + +/// Converts a bit array to a string. +/// +/// Returns an error if the bit array is invalid UTF-8 data. +/// +pub fn to_string(bits: BitArray) -> Result(String, Nil) { + do_to_string(bits) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "identity") +fn unsafe_to_string(a: BitArray) -> String + +@target(erlang) +fn do_to_string(bits: BitArray) -> Result(String, Nil) { + case is_utf8(bits) { + True -> Ok(unsafe_to_string(bits)) + False -> Error(Nil) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") +fn do_to_string(a: BitArray) -> Result(String, Nil) + +/// Creates a new bit array by joining multiple binaries. +/// +/// ## Examples +/// +/// ```gleam +/// > concat([from_string("butter"), from_string("fly")]) +/// from_string("butterfly") +/// ``` +/// +@external(erlang, "gleam_stdlib", "bit_array_concat") +@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") +pub fn concat(bit_arrays: List(BitArray)) -> BitArray + +/// Encodes a BitArray into a base 64 encoded string. +/// +pub fn base64_encode(input: BitArray, padding: Bool) -> String { + let encoded = encode64(input) + case padding { + True -> encoded + False -> string.replace(encoded, "=", "") + } +} + +@external(erlang, "base64", "encode") +@external(javascript, "../gleam_stdlib.mjs", "encode64") +fn encode64(a: BitArray) -> String + +/// Decodes a base 64 encoded string into a `BitArray`. +/// +pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { + let padded = case byte_size(from_string(encoded)) % 4 { + 0 -> encoded + n -> string.append(encoded, string.repeat("=", 4 - n)) + } + decode64(padded) +} + +@external(erlang, "gleam_stdlib", "base_decode64") +@external(javascript, "../gleam_stdlib.mjs", "decode64") +fn decode64(a: String) -> Result(BitArray, Nil) + +/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. +/// +pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { + base64_encode(input, padding) + |> string.replace("+", "-") + |> string.replace("/", "_") +} + +/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. +/// +pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { + encoded + |> string.replace("-", "+") + |> string.replace("_", "/") + |> base64_decode() +} + +@external(erlang, "binary", "encode_hex") +@external(javascript, "../gleam_stdlib.mjs", "base16_encode") +pub fn base16_encode(input: BitArray) -> String + +@external(erlang, "gleam_stdlib", "base16_decode") +@external(javascript, "../gleam_stdlib.mjs", "base16_decode") +pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam new file mode 100644 index 00000000000..ce6fe52ec1b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam @@ -0,0 +1,80 @@ +//// This module has been deprecated in favour of `gleam/bytes_builder`. + +import gleam/bytes_builder +import gleam/string_builder.{type StringBuilder} + +pub type BitBuilder = + bytes_builder.BytesBuilder + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn new() -> BitBuilder { + bytes_builder.new() +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { + bytes_builder.prepend(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { + bytes_builder.append(to, suffix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { + bytes_builder.prepend_builder(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append_builder( + to first: BitBuilder, + suffix second: BitBuilder, +) -> BitBuilder { + bytes_builder.append_builder(first, second) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { + bytes_builder.prepend_string(to, prefix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { + bytes_builder.append_string(to, suffix) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn concat(builders: List(BitBuilder)) -> BitBuilder { + bytes_builder.concat(builders) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { + bytes_builder.concat_bit_arrays(bits) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_string(string: String) -> BitBuilder { + bytes_builder.from_string(string) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { + bytes_builder.from_string_builder(builder) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn from_bit_string(bits: BitArray) -> BitBuilder { + bytes_builder.from_bit_array(bits) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn to_bit_string(builder: BitBuilder) -> BitArray { + bytes_builder.to_bit_array(builder) +} + +@deprecated("Please use the `gleam/bytes_builder` module instead.") +pub fn byte_size(builder: BitBuilder) -> Int { + bytes_builder.byte_size(builder) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam new file mode 100644 index 00000000000..b703da0930d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bit_string.gleam @@ -0,0 +1,43 @@ +//// This module has been deprecated. Please use the `gleam/bit_array` module +//// instead. + +import gleam/bit_array + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn from_string(x: String) -> BitArray { + bit_array.from_string(x) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn byte_size(x: BitArray) -> Int { + bit_array.byte_size(x) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { + bit_array.append(first, second) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn slice( + from string: BitArray, + at position: Int, + take length: Int, +) -> Result(BitArray, Nil) { + bit_array.slice(string, position, length) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn is_utf8(bits: BitArray) -> Bool { + bit_array.is_utf8(bits) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn to_string(bits: BitArray) -> Result(String, Nil) { + bit_array.to_string(bits) +} + +@deprecated("Please use the `gleam/bit_array` module instead.") +pub fn concat(bit_strings: List(BitArray)) -> BitArray { + bit_array.concat(bit_strings) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam new file mode 100644 index 00000000000..91bd6b76129 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bool.gleam @@ -0,0 +1,428 @@ +//// A type with two possible values, `True` and `False`. Used to indicate whether +//// things are... true or false! +//// +//// Often is it clearer and offers more type safety to define a custom type +//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` +//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom +//// type that can be either `Student` or `Teacher`. + +import gleam/order.{type Order} + +/// Returns the and of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `&&` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > and(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > and(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > False |> and(True) +/// False +/// ``` +/// +pub fn and(a: Bool, b: Bool) -> Bool { + a && b +} + +/// Returns the or of two bools, but it evaluates both arguments. +/// +/// It's the function equivalent of the `||` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > or(True, True) +/// True +/// ``` +/// +/// ```gleam +/// > or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > False |> or(True) +/// True +/// ``` +/// +pub fn or(a: Bool, b: Bool) -> Bool { + a || b +} + +/// Returns the opposite bool value. +/// +/// This is the same as the `!` or `not` operators in some other languages. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(True) +/// False +/// ``` +/// +/// ```gleam +/// > negate(False) +/// True +/// ``` +/// +pub fn negate(bool: Bool) -> Bool { + case bool { + True -> False + False -> True + } +} + +/// Returns the nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > nor(True, True) +/// False +/// ``` +/// +pub fn nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> False + } +} + +/// Returns the nand of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > nand(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > nand(True, True) +/// False +/// ``` +/// +pub fn nand(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive or of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_or(False, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_or(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_or(True, True) +/// False +/// ``` +/// +pub fn exclusive_or(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> False + False, True -> True + True, False -> True + True, True -> False + } +} + +/// Returns the exclusive nor of two bools. +/// +/// ## Examples +/// +/// ```gleam +/// > exclusive_nor(False, False) +/// True +/// ``` +/// +/// ```gleam +/// > exclusive_nor(False, True) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > exclusive_nor(True, True) +/// True +/// ``` +/// +pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { + case a, b { + False, False -> True + False, True -> False + True, False -> False + True, True -> True + } +} + +/// Compares two bools and returns the first value's `Order` to the second. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/order +/// > compare(True, False) +/// order.Gt +/// ``` +/// +pub fn compare(a: Bool, with b: Bool) -> Order { + case a, b { + True, True -> order.Eq + True, False -> order.Gt + False, False -> order.Eq + False, True -> order.Lt + } +} + +/// Returns `True` if either argument's value is `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > max(True, False) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, True) +/// True +/// ``` +/// +/// ```gleam +/// > max(False, False) +/// False +/// ``` +/// +pub fn max(a: Bool, b: Bool) -> Bool { + case a { + True -> True + False -> b + } +} + +/// Returns `False` if either bool value is `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > min(True, False) +/// False +/// ``` +/// +/// ```gleam +/// > min(False, True) +/// False +/// +/// > min(False, False) +/// False +/// ``` +/// +pub fn min(a: Bool, b: Bool) -> Bool { + case a { + False -> False + True -> b + } +} + +/// Returns a numeric representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(True) +/// 1 +/// +/// > to_int(False) +/// 0 +/// ``` +/// +pub fn to_int(bool: Bool) -> Int { + case bool { + False -> 0 + True -> 1 + } +} + +/// Returns a string representation of the given bool. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(True) +/// "True" +/// ``` +/// +/// ```gleam +/// > to_string(False) +/// "False" +/// ``` +/// +pub fn to_string(bool: Bool) -> String { + case bool { + False -> "False" + True -> "True" + } +} + +/// Run a callback function if the given bool is `False`, otherwise return a +/// default value. +/// +/// With a `use` expression this function can simulate the early-return pattern +/// found in some other programming languages. +/// +/// In a procedural language: +/// +/// ```js +/// if (predicate) return value; +/// // ... +/// ``` +/// +/// In Gleam with a `use` expression: +/// +/// ```gleam +/// use <- guard(when: predicate, return: value) +/// // ... +/// ``` +/// +/// Like everything in Gleam `use` is an expression, so it short circuits the +/// current block, not the entire function. As a result you can assign the value +/// to a variable: +/// +/// ```gleam +/// let x = { +/// use <- guard(when: predicate, return: value) +/// // ... +/// } +/// ``` +/// +/// Note that unlike in procedural languages the `return` value is evaluated +/// even when the predicate is `False`, so it is advisable not to perform +/// expensive computation there. +/// +/// +/// ## Examples +/// +/// ```gleam +/// > let name = "" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Welcome!" +/// ``` +/// +/// ```gleam +/// > let name = "Kamaka" +/// > use <- guard(when: name == "", return: "Welcome!") +/// > "Hello, " <> name +/// "Hello, Kamaka" +/// ``` +/// +pub fn guard( + when requirement: Bool, + return consequence: t, + otherwise alternative: fn() -> t, +) -> t { + case requirement { + True -> consequence + False -> alternative() + } +} + +/// Runs a callback function if the given bool is `True`, otherwise runs an +/// alternative callback function. +/// +/// Useful when further computation should be delayed regardless of the given +/// bool's value. +/// +/// See [`guard`](#guard) for more info. +/// +/// ## Examples +/// +/// ```gleam +/// > let name = "Kamaka" +/// > let inquiry = fn() { "How may we address you?" } +/// > use <- lazy_guard(when: name == "", return: inquiry) +/// > "Hello, " <> name +/// "Hello, Kamaka" +/// ``` +/// +/// ```gleam +/// > import gleam/int +/// > let name = "" +/// > let greeting = fn() { "Hello, " <> name } +/// > use <- lazy_guard(when: name == "", otherwise: greeting) +/// > let number = int.random(1, 99) +/// > let name = "User " <> int.to_string(number) +/// > "Welcome, " <> name +/// "Welcome, User 54" +/// ``` +/// +pub fn lazy_guard( + when requirement: Bool, + return consequence: fn() -> a, + otherwise alternative: fn() -> a, +) -> a { + case requirement { + True -> consequence() + False -> alternative() + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam new file mode 100644 index 00000000000..20c145d93aa --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam @@ -0,0 +1,197 @@ +//// BytesBuilder is a type used for efficiently concatenating bytes together +//// without copying. +//// +//// If we append one bit array to another the bit arrays must be copied to a +//// new location in memory so that they can sit together. This behaviour +//// enables efficient reading of the string but copying can be expensive, +//// especially if we want to join many bit arrays together. +//// +//// BytesBuilder is different in that it can be joined together in constant +//// time using minimal memory, and then can be efficiently converted to a +//// bit array using the `to_bit_array` function. +//// +//// Byte builders are always byte aligned, so that a number of bits that is not +//// divisible by 8 will be padded with 0s. +//// +//// On Erlang this type is compatible with Erlang's iolists. + +// TODO: pad bit arrays to byte boundaries when adding to a builder. +import gleam/string_builder.{type StringBuilder} +import gleam/list +import gleam/bit_array + +pub opaque type BytesBuilder { + Bytes(BitArray) + Text(StringBuilder) + Many(List(BytesBuilder)) +} + +/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many +/// builders together. +/// +pub fn new() -> BytesBuilder { + concat([]) +} + +/// Prepends a bit array to the start of a builder. +/// +/// Runs in constant time. +/// +pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { + append_builder(from_bit_array(first), second) +} + +/// Appends a bit array to the end of a builder. +/// +/// Runs in constant time. +/// +pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { + append_builder(first, from_bit_array(second)) +} + +/// Prepends a builder onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder( + to second: BytesBuilder, + prefix first: BytesBuilder, +) -> BytesBuilder { + append_builder(first, second) +} + +/// Appends a builder onto the end of another. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "iodata_append") +pub fn append_builder( + to first: BytesBuilder, + suffix second: BytesBuilder, +) -> BytesBuilder { + case second { + Many(builders) -> Many([first, ..builders]) + _ -> Many([first, second]) + } +} + +/// Prepends a string onto the start of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn prepend_string( + to second: BytesBuilder, + prefix first: String, +) -> BytesBuilder { + append_builder(from_string(first), second) +} + +/// Appends a string onto the end of a builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time with the length of the string otherwise. +/// +pub fn append_string( + to first: BytesBuilder, + suffix second: String, +) -> BytesBuilder { + append_builder(first, from_string(second)) +} + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "identity") +pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { + Many(builders) +} + +/// Joins a list of bit arrays into a single builder. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "identity") +pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { + bits + |> list.map(fn(b) { from_bit_array(b) }) + |> concat() +} + +/// Creates a new builder from a string. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_string(string: String) -> BytesBuilder { + Text(string_builder.from_string(string)) +} + +/// Creates a new builder from a string builder. +/// +/// Runs in constant time when running on Erlang. +/// Runs in linear time otherwise. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { + Text(builder) +} + +/// Creates a new builder from a bit array. +/// +/// Runs in constant time. +/// +@external(erlang, "gleam_stdlib", "wrap_list") +pub fn from_bit_array(bits: BitArray) -> BytesBuilder { + Bytes(bits) +} + +/// Turns an builder into a bit array. +/// +/// Runs in linear time. +/// +/// When running on Erlang this function is implemented natively by the +/// virtual machine and is highly optimised. +/// +@external(erlang, "erlang", "list_to_bitstring") +pub fn to_bit_array(builder: BytesBuilder) -> BitArray { + [[builder]] + |> to_list([]) + |> list.reverse + |> bit_array.concat +} + +fn to_list( + stack: List(List(BytesBuilder)), + acc: List(BitArray), +) -> List(BitArray) { + case stack { + [] -> acc + + [[], ..remaining_stack] -> to_list(remaining_stack, acc) + + [[Bytes(bits), ..rest], ..remaining_stack] -> + to_list([rest, ..remaining_stack], [bits, ..acc]) + + [[Text(builder), ..rest], ..remaining_stack] -> { + let bits = bit_array.from_string(string_builder.to_string(builder)) + to_list([rest, ..remaining_stack], [bits, ..acc]) + } + + [[Many(builders), ..rest], ..remaining_stack] -> + to_list([builders, rest, ..remaining_stack], acc) + } +} + +/// Returns the size of the builder's content in bytes. +/// +/// Runs in linear time. +/// +@external(erlang, "erlang", "iolist_size") +pub fn byte_size(builder: BytesBuilder) -> Int { + [[builder]] + |> to_list([]) + |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam new file mode 100644 index 00000000000..280bf9d1d98 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dict.gleam @@ -0,0 +1,544 @@ +import gleam/option.{type Option} + +/// A dictionary of keys and values. +/// +/// Any type can be used for the keys and values of a dict, but all the keys +/// must be of the same type and all the values must be of the same type. +/// +/// Each key can only be present in a dict once. +/// +/// Dicts are not ordered in any way, and any unintentional ordering is not to +/// be relied upon in your code as it may change in future versions of Erlang +/// or Gleam. +/// +/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more +/// information. +/// +pub type Dict(key, value) + +/// Determines the number of key-value pairs in the dict. +/// This function runs in constant time and does not need to iterate the dict. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> size() +/// 0 +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", "value") |> size() +/// 1 +/// ``` +/// +pub fn size(dict: Dict(k, v)) -> Int { + do_size(dict) +} + +@external(erlang, "maps", "size") +@external(javascript, "../gleam_stdlib.mjs", "map_size") +fn do_size(a: Dict(k, v)) -> Int + +/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for +/// each key-value pair in the dict. +/// +/// The tuples in the list have no specific order. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> to_list() +/// [] +/// ``` +/// +/// ```gleam +/// > new() |> insert("key", 0) |> to_list() +/// [#("key", 0)] +/// ``` +/// +pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { + do_to_list(dict) +} + +@external(erlang, "maps", "to_list") +@external(javascript, "../gleam_stdlib.mjs", "map_to_list") +fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) + +/// Converts a list of 2-element tuples `#(key, value)` to a dict. +/// +/// If two tuples have the same key the last one in the list will be the one +/// that is present in the dict. +/// +pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { + do_from_list(list) +} + +@target(erlang) +@external(erlang, "maps", "from_list") +fn do_from_list(a: List(#(key, value))) -> Dict(key, value) + +@target(javascript) +fn fold_list_of_pair( + over list: List(#(k, v)), + from initial: Dict(k, v), +) -> Dict(k, v) { + case list { + [] -> initial + [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) + } +} + +@target(javascript) +fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { + fold_list_of_pair(list, new()) +} + +/// Determines whether or not a value present in the dict for a given key. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("a") +/// True +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> has_key("b") +/// False +/// ``` +/// +pub fn has_key(dict: Dict(k, v), key: k) -> Bool { + do_has_key(key, dict) +} + +@target(erlang) +@external(erlang, "maps", "is_key") +fn do_has_key(a: key, b: Dict(key, v)) -> Bool + +@target(javascript) +fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { + get(dict, key) != Error(Nil) +} + +/// Creates a fresh dict that contains no values. +/// +pub fn new() -> Dict(key, value) { + do_new() +} + +@external(erlang, "maps", "new") +@external(javascript, "../gleam_stdlib.mjs", "new_map") +fn do_new() -> Dict(key, value) + +/// Fetches a value from a dict for a given key. +/// +/// The dict may not have a value for the key, so the value is wrapped in a +/// `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> get("b") +/// Error(Nil) +/// ``` +/// +pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { + do_get(from, get) +} + +@external(erlang, "gleam_stdlib", "map_get") +@external(javascript, "../gleam_stdlib.mjs", "map_get") +fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) + +/// Inserts a value into the dict with the given key. +/// +/// If the dict already has a value for the given key then the value is +/// replaced with the new value. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert("a", 0) |> to_list +/// [#("a", 0)] +/// ``` +/// +/// ```gleam +/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list +/// [#("a", 5)] +/// ``` +/// +pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { + do_insert(key, value, dict) +} + +@external(erlang, "maps", "put") +@external(javascript, "../gleam_stdlib.mjs", "map_insert") +fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) + +/// Updates all values in a given dict by calling a given function on each key +/// and value. +/// +/// ## Examples +/// +/// ```gleam +/// > [#(3, 3), #(2, 4)] +/// > |> from_list +/// > |> map_values(fn(key, value) { key * value }) +/// [#(3, 9), #(2, 8)] +/// ``` +/// +pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { + do_map_values(fun, dict) +} + +@target(erlang) +@external(erlang, "maps", "map") +fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) + +@target(javascript) +fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { + let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } + dict + |> fold(from: new(), with: f) +} + +/// Gets a list of all keys in a given dict. +/// +/// Dicts are not ordered so the keys are not returned in any specific order. Do +/// not write code that relies on the order keys are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > keys([#("a", 0), #("b", 1)]) +/// ["a", "b"] +/// ``` +/// +pub fn keys(dict: Dict(keys, v)) -> List(keys) { + do_keys(dict) +} + +@target(erlang) +@external(erlang, "maps", "keys") +fn do_keys(a: Dict(keys, v)) -> List(keys) + +@target(javascript) +fn reverse_and_concat(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) + } +} + +@target(javascript) +fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) + } +} + +@target(javascript) +fn do_keys(dict: Dict(k, v)) -> List(k) { + let list_of_pairs = to_list(dict) + do_keys_acc(list_of_pairs, []) +} + +/// Gets a list of all values in a given dict. +/// +/// Dicts are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order values are returned by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > values(from_list([#("a", 0), #("b", 1)])) +/// [0, 1] +/// ``` +/// +pub fn values(dict: Dict(k, values)) -> List(values) { + do_values(dict) +} + +@target(erlang) +@external(erlang, "maps", "values") +fn do_values(a: Dict(k, values)) -> List(values) + +@target(javascript) +fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) + } +} + +@target(javascript) +fn do_values(dict: Dict(k, v)) -> List(v) { + let list_of_pairs = to_list(dict) + do_values_acc(list_of_pairs, []) +} + +/// Creates a new dict from a given dict, minus any entries that a given function +/// returns `False` for. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { value != 0 }) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> filter(fn(key, value) { True }) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn filter( + in dict: Dict(k, v), + keeping predicate: fn(k, v) -> Bool, +) -> Dict(k, v) { + do_filter(predicate, dict) +} + +@target(erlang) +@external(erlang, "maps", "filter") +fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) + +@target(javascript) +fn do_filter( + f: fn(key, value) -> Bool, + dict: Dict(key, value), +) -> Dict(key, value) { + let insert = fn(dict, k, v) { + case f(k, v) { + True -> insert(dict, k, v) + _ -> dict + } + } + dict + |> fold(from: new(), with: insert) +} + +/// Creates a new dict from a given dict, only including any entries for which the +/// keys are in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["b"]) +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > from_list([#("a", 0), #("b", 1)]) +/// > |> take(["a", "b", "c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { + do_take(desired_keys, dict) +} + +@target(erlang) +@external(erlang, "maps", "with") +fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) + +@target(javascript) +fn insert_taken( + dict: Dict(k, v), + desired_keys: List(k), + acc: Dict(k, v), +) -> Dict(k, v) { + let insert = fn(taken, key) { + case get(dict, key) { + Ok(value) -> insert(taken, key, value) + _ -> taken + } + } + case desired_keys { + [] -> acc + [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) + } +} + +@target(javascript) +fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { + insert_taken(dict, desired_keys, new()) +} + +/// Creates a new dict from a pair of given dicts by combining their entries. +/// +/// If there are entries with the same keys in both dicts the entry from the +/// second dict takes precedence. +/// +/// ## Examples +/// +/// ```gleam +/// > let a = from_list([#("a", 0), #("b", 1)]) +/// > let b = from_list([#("b", 2), #("c", 3)]) +/// > merge(a, b) +/// from_list([#("a", 0), #("b", 2), #("c", 3)]) +/// ``` +/// +pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { + do_merge(dict, new_entries) +} + +@target(erlang) +@external(erlang, "maps", "merge") +fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) + +@target(javascript) +fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { + insert(dict, pair.0, pair.1) +} + +@target(javascript) +fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { + case new_entries { + [] -> dict + [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) + } +} + +@target(javascript) +fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { + new_entries + |> to_list + |> fold_inserts(dict) +} + +/// Creates a new dict from a given dict with all the same entries except for the +/// one with a given key, if it exists. +/// +/// ## Examples +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "a") +/// from_list([#("b", 1)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], "c") +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { + do_delete(key, dict) +} + +@external(erlang, "maps", "remove") +@external(javascript, "../gleam_stdlib.mjs", "map_remove") +fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) + +/// Creates a new dict from a given dict with all the same entries except any with +/// keys found in a given list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a"]) +/// from_list([#("b", 2)]) +/// ``` +/// +/// ```gleam +/// > delete([#("a", 0), #("b", 1)], ["c"]) +/// from_list([#("a", 0), #("b", 1)]) +/// ``` +/// +/// ```gleam +/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) +/// from_list([]) +/// ``` +/// +pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { + case disallowed_keys { + [] -> dict + [x, ..xs] -> drop(delete(dict, x), xs) + } +} + +/// Creates a new dict with one entry updated using a given function. +/// +/// If there was not an entry in the dict for the given key then the function +/// gets `None` as its argument, otherwise it gets `Some(value)`. +/// +/// ## Example +/// +/// ```gleam +/// > let increment = fn(x) { +/// > case x { +/// > Some(i) -> i + 1 +/// > None -> 0 +/// > } +/// > } +/// > let dict = from_list([#("a", 0)]) +/// > +/// > update(dict, "a", increment) +/// from_list([#("a", 1)]) +/// ``` +/// +/// ```gleam +/// > update(dict, "b", increment) +/// from_list([#("a", 0), #("b", 0)]) +/// ``` +/// +pub fn update( + in dict: Dict(k, v), + update key: k, + with fun: fn(Option(v)) -> v, +) -> Dict(k, v) { + dict + |> get(key) + |> option.from_result + |> fun + |> insert(dict, key, _) +} + +fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { + case list { + [] -> initial + [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) + } +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Dicts are not ordered so the values are not returned in any specific order. Do +/// not write code that relies on the order entries are used by this function +/// as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) +/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) +/// 13 +/// ``` +/// +/// ```gleam +/// > import gleam/string.{append} +/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) +/// "abc" +/// ``` +/// +pub fn fold( + over dict: Dict(k, v), + from initial: acc, + with fun: fn(acc, k, v) -> acc, +) -> acc { + dict + |> to_list + |> do_fold(initial, fun) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam new file mode 100644 index 00000000000..c71c6f342ad --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/dynamic.gleam @@ -0,0 +1,1508 @@ +import gleam/int +import gleam/list +import gleam/dict.{type Dict} +import gleam/option.{type Option} +import gleam/result +import gleam/string_builder +@target(erlang) +import gleam/bit_array + +/// `Dynamic` data is data that we don't know the type of yet. +/// We likely get data like this from interop with Erlang, or from +/// IO with the outside world. +/// +pub type Dynamic + +/// Error returned when unexpected data is encountered +/// +pub type DecodeError { + DecodeError(expected: String, found: String, path: List(String)) +} + +pub type DecodeErrors = + List(DecodeError) + +pub type Decoder(t) = + fn(Dynamic) -> Result(t, DecodeErrors) + +/// Converts any Gleam data into `Dynamic` data. +/// +pub fn from(a) -> Dynamic { + do_from(a) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_from(a: anything) -> Dynamic + +/// Unsafely casts a Dynamic value into any other type. +/// +/// This is an escape hatch for the type system that may be useful when wrapping +/// native Erlang APIs. It is to be used as a last measure only! +/// +/// If you can avoid using this function, do! +/// +pub fn unsafe_coerce(a: Dynamic) -> anything { + do_unsafe_coerce(a) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_unsafe_coerce(a: Dynamic) -> a + +/// Decodes a `Dynamic` value from a `Dynamic` value. +/// +/// This function doesn't seem very useful at first, but it can be convenient +/// when you need to give a decoder function but you don't actually care what +/// the to-decode value is. +/// +pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { + Ok(value) +} + +/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit +/// array if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bit_array(from("Hello")) == bit_array.from_string("Hello") +/// True +/// ``` +/// +/// ```gleam +/// > bit_array(from(123)) +/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) +/// ``` +/// +pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { + decode_bit_array(data) +} + +@deprecated("Please use `bit_array` instead") +pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { + bit_array(data) +} + +@external(erlang, "gleam_stdlib", "decode_bit_array") +@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") +fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a string, and returns that string if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > string(from("Hello")) +/// Ok("Hello") +/// ``` +/// +/// ```gleam +/// > string(from(123)) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { + decode_string(data) +} + +fn map_errors( + result: Result(t, DecodeErrors), + f: fn(DecodeError) -> DecodeError, +) -> Result(t, DecodeErrors) { + result.map_error(result, list.map(_, f)) +} + +@target(erlang) +fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { + bit_array(data) + |> map_errors(put_expected(_, "String")) + |> result.try(fn(raw) { + case bit_array.to_string(raw) { + Ok(string) -> Ok(string) + Error(Nil) -> + Error([DecodeError(expected: "String", found: "BitArray", path: [])]) + } + }) +} + +@target(erlang) +fn put_expected(error: DecodeError, expected: String) -> DecodeError { + DecodeError(..error, expected: expected) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "decode_string") +fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) + +/// Return a string indicating the type of the dynamic value. +/// +/// ```gleam +/// > classify(from("Hello")) +/// "String" +/// ``` +/// +pub fn classify(data: Dynamic) -> String { + do_classify(data) +} + +@external(erlang, "gleam_stdlib", "classify_dynamic") +@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") +fn do_classify(a: Dynamic) -> String + +/// Checks to see whether a `Dynamic` value is an int, and returns that int if it +/// is. +/// +/// ## Examples +/// +/// ```gleam +/// > int(from(123)) +/// Ok(123) +/// ``` +/// +/// ```gleam +/// > int(from("Hello")) +/// Error([DecodeError(expected: "Int", found: "String", path: [])]) +/// ``` +/// +pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { + decode_int(data) +} + +@external(erlang, "gleam_stdlib", "decode_int") +@external(javascript, "../gleam_stdlib.mjs", "decode_int") +fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a float, and returns that float if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > float(from(2.0)) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > float(from(123)) +/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) +/// ``` +/// +pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { + decode_float(data) +} + +@external(erlang, "gleam_stdlib", "decode_float") +@external(javascript, "../gleam_stdlib.mjs", "decode_float") +fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if +/// it is. +/// +/// ## Examples +/// +/// ```gleam +/// > bool(from(True)) +/// Ok(True) +/// ``` +/// +/// ```gleam +/// > bool(from(123)) +/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) +/// ``` +/// +pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { + decode_bool(data) +} + +@external(erlang, "gleam_stdlib", "decode_bool") +@external(javascript, "../gleam_stdlib.mjs", "decode_bool") +fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a list, and returns that list if it +/// is. The types of the elements are not checked. +/// +/// If you wish to decode all the elements in the list use the `list` function +/// instead. +/// +/// ## Examples +/// +/// ```gleam +/// > shallow_list(from(["a", "b", "c"])) +/// Ok([from("a"), from("b"), from("c")]) +/// ``` +/// +/// ```gleam +/// > shallow_list(1) +/// Error([DecodeError(expected: "List", found: "Int", path: [])]) +/// ``` +/// +pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { + decode_list(value) +} + +@external(erlang, "gleam_stdlib", "decode_list") +@external(javascript, "../gleam_stdlib.mjs", "decode_list") +fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_result") +@external(javascript, "../gleam_stdlib.mjs", "decode_result") +fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) + +/// Checks to see whether a `Dynamic` value is a result of a particular type, and +/// returns that result if it is. +/// +/// The `ok` and `error` arguments are decoders for decoding the `Ok` and +/// `Error` values of the result. +/// +/// ## Examples +/// +/// ```gleam +/// > from(Ok(1)) +/// > |> result(ok: int, error: string) +/// Ok(Ok(1)) +/// ``` +/// +/// ```gleam +/// > from(Error("boom")) +/// > |> result(ok: int, error: string) +/// Ok(Error("boom")) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> result(ok: int, error: string) +/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) +/// ``` +/// +pub fn result( + ok decode_ok: Decoder(a), + error decode_error: Decoder(e), +) -> Decoder(Result(a, e)) { + fn(value) { + use inner_result <- result.try(decode_result(value)) + + case inner_result { + Ok(raw) -> { + use value <- result.try( + decode_ok(raw) + |> map_errors(push_path(_, "ok")), + ) + Ok(Ok(value)) + } + Error(raw) -> { + use value <- result.try( + decode_error(raw) + |> map_errors(push_path(_, "error")), + ) + Ok(Error(value)) + } + } + } +} + +/// Checks to see whether a `Dynamic` value is a list of a particular type, and +/// returns that list if it is. +/// +/// The second argument is a decoder function used to decode the elements of +/// the list. The list is only decoded if all elements in the list can be +/// successfully decoded using this function. +/// +/// If you do not wish to decode all the elements in the list use the `shallow_list` +/// function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > from(["a", "b", "c"]) +/// > |> list(of: string) +/// Ok(["a", "b", "c"]) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> list(of: string) +/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) +/// ``` +/// +/// ```gleam +/// > from("ok") +/// > |> list(of: string) +/// Error([DecodeError(expected: "List", found: "String", path: [])]) +/// ``` +/// +pub fn list( + of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), +) -> Decoder(List(inner)) { + fn(dynamic) { + use list <- result.try(shallow_list(dynamic)) + list + |> list.try_map(decoder_type) + |> map_errors(push_path(_, "*")) + } +} + +/// Checks to see if a `Dynamic` value is a nullable version of a particular +/// type, and returns a corresponding `Option` if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from("Hello") +/// > |> optional(string) +/// Ok(Some("Hello")) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("null")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("nil")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(atom.from_string("undefined")) +/// > |> optional(string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> optional(string) +/// Error([DecodeError(expected: "String", found: "Int", path: [])]) +/// ``` +/// +pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { + fn(value) { decode_optional(value, decode) } +} + +@external(erlang, "gleam_stdlib", "decode_option") +@external(javascript, "../gleam_stdlib.mjs", "decode_option") +fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) + +/// Checks to see if a `Dynamic` value is a map with a specific field, and returns +/// the value of that field if it is. +/// +/// This will not succeed on a record. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> dict.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok("World") +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { + fn(value) { + let missing_field_error = + DecodeError(expected: "field", found: "nothing", path: []) + + use maybe_inner <- result.try(decode_field(value, name)) + maybe_inner + |> option.to_result([missing_field_error]) + |> result.try(inner_type) + |> map_errors(push_path(_, name)) + } +} + +/// Checks to see if a `Dynamic` value is a map with a specific field. +/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, +/// returns the decoded field wrapped in `Some(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> dict.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(Some("World")) +/// ``` +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn optional_field( + named name: a, + of inner_type: Decoder(t), +) -> Decoder(Option(t)) { + fn(value) { + use maybe_inner <- result.try(decode_field(value, name)) + case maybe_inner { + option.None -> Ok(option.None) + option.Some(dynamic_inner) -> + dynamic_inner + |> decode_optional(inner_type) + |> map_errors(push_path(_, name)) + } + } +} + +@external(erlang, "gleam_stdlib", "decode_field") +@external(javascript, "../gleam_stdlib.mjs", "decode_field") +fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) + +/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain +/// index, and returns the value of that index if it is. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(0, int) +/// Ok(from(1)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> element(2, int) +/// Error([ +/// DecodeError( +/// expected: "Tuple of at least 3 elements", +/// found: "Tuple of 2 elements", +/// path: [], +/// ), +/// ]) +/// ``` +/// +pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { + fn(data: Dynamic) { + use tuple <- result.try(decode_tuple(data)) + let size = tuple_size(tuple) + use data <- result.try(case index >= 0 { + True -> + case index < size { + True -> tuple_get(tuple, index) + False -> at_least_decode_tuple_error(index + 1, data) + } + False -> + case int.absolute_value(index) <= size { + True -> tuple_get(tuple, size + index) + False -> at_least_decode_tuple_error(int.absolute_value(index), data) + } + }) + inner_type(data) + |> map_errors(push_path(_, index)) + } +} + +fn at_least_decode_tuple_error( + size: Int, + data: Dynamic, +) -> Result(a, DecodeErrors) { + let s = case size { + 1 -> "" + _ -> "s" + } + let error = + ["Tuple of at least ", int.to_string(size), " element", s] + |> string_builder.from_strings + |> string_builder.to_string + |> DecodeError(found: classify(data), path: []) + Error([error]) +} + +// A tuple of unknown size +type UnknownTuple + +@external(erlang, "gleam_stdlib", "decode_tuple") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") +fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple2") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") +fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple3") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") +fn decode_tuple3( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple4") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") +fn decode_tuple4( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple5") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") +fn decode_tuple5( + a: Dynamic, +) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) + +@external(erlang, "gleam_stdlib", "decode_tuple6") +@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") +fn decode_tuple6( + a: Dynamic, +) -> Result( + #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), + DecodeErrors, +) + +@external(erlang, "gleam_stdlib", "tuple_get") +@external(javascript, "../gleam_stdlib.mjs", "tuple_get") +fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) + +@external(erlang, "gleam_stdlib", "size_of_tuple") +@external(javascript, "../gleam_stdlib.mjs", "length") +fn tuple_size(a: UnknownTuple) -> Int + +fn tuple_errors( + result: Result(a, List(DecodeError)), + name: String, +) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> list.map(errors, push_path(_, name)) + } +} + +fn push_path(error: DecodeError, name: t) -> DecodeError { + let name = from(name) + let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) + let name = case decoder(name) { + Ok(name) -> name + Error(_) -> + ["<", classify(name), ">"] + |> string_builder.from_strings + |> string_builder.to_string + } + DecodeError(..error, path: [name, ..error.path]) +} + +/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0)) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from([1, 2]) +/// > |> tuple2(int, int) +/// Ok(#(1, 2)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0)]) +/// > |> tuple2(int, float) +/// Ok(#(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple2(int, float) +/// Error([ +/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple2(int, float) +/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple2( + first decode1: Decoder(a), + second decode2: Decoder(b), +) -> Decoder(#(a, b)) { + fn(value) { + use #(a, b) <- result.try(decode_tuple2(value)) + case decode1(a), decode2(b) { + Ok(a), Ok(b) -> Ok(#(a, b)) + a, b -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3)) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3]) +/// > |> tuple3(int, int, int) +/// Ok(#(1, 2, 3)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3")]) +/// > |> tuple3(int, float, string) +/// Ok(#(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple3(int, float, string) +/// Error([ +/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple3( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), +) -> Decoder(#(a, b, c)) { + fn(value) { + use #(a, b, c) <- result.try(decode_tuple3(value)) + case decode1(a), decode2(b), decode3(c) { + Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) + a, b, c -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4)) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4)) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4]) +/// > |> tuple4(int, int, int, int) +/// Ok(#(1, 2, 3, 4)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4)]) +/// > |> tuple4(int, float, string, int) +/// Ok(#(1, 2.0, "3", 4)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple4(int, float, string, int) +/// Error([ +/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), +/// ]) +/// ``` +/// +pub fn tuple4( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), +) -> Decoder(#(a, b, c, d)) { + fn(value) { + use #(a, b, c, d) <- result.try(decode_tuple4(value)) + case decode1(a), decode2(b), decode3(c), decode4(d) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) + a, b, c, d -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5)) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5)) +/// > |> tuple5(int, float, string, int, int) +/// Ok(#(1, 2.0, "3", 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5]) +/// > |> tuple5(int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) +/// > |> tuple5(int, float, string, int, bool) +/// Ok(#(1, 2.0, "3", 4, True)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple5(int, float, string, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple5(int, float, string, int, int) +/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple5( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), +) -> Decoder(#(a, b, c, d, e)) { + fn(value) { + use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) + case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) + a, b, c, d, e -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing +/// specifically typed elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2, 3, 4, 5, 6)) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2.0, "3", 4, 5, 6)) +/// > |> tuple6(int, float, string, int, int, int) +/// Ok(#(1, 2.0, "3", 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([1, 2, 3, 4, 5, 6]) +/// > |> tuple6(int, int, int, int, int, int) +/// Ok(#(1, 2, 3, 4, 5, 6)) +/// ``` +/// +/// ```gleam +/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) +/// > |> tuple6(int, float, string, int, bool, bool) +/// Ok(#(1, 2.0, "3", 4, True, False)) +/// ``` +/// +/// ```gleam +/// > from(#(1, 2)) +/// > |> tuple6(int, float, string, int, int, int) +/// Error([ +/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), +/// ]) +/// ``` +/// +/// ```gleam +/// > from("") +/// > |> tuple6(int, float, string, int, int, int) +/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) +/// ``` +/// +pub fn tuple6( + first decode1: Decoder(a), + second decode2: Decoder(b), + third decode3: Decoder(c), + fourth decode4: Decoder(d), + fifth decode5: Decoder(e), + sixth decode6: Decoder(f), +) -> Decoder(#(a, b, c, d, e, f)) { + fn(value) { + use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) + case + decode1(a), + decode2(b), + decode3(c), + decode4(d), + decode5(e), + decode6(f) + { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) + a, b, c, d, e, f -> + tuple_errors(a, "0") + |> list.append(tuple_errors(b, "1")) + |> list.append(tuple_errors(c, "2")) + |> list.append(tuple_errors(d, "3")) + |> list.append(tuple_errors(e, "4")) + |> list.append(tuple_errors(f, "5")) + |> Error + } + } +} + +/// Checks to see if a `Dynamic` value is a dict. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/dict +/// > dict.new() |> from |> map(string, int) +/// Ok(dict.new()) +/// ``` +/// +/// ```gleam +/// > from(1) |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "Int", path: [])) +/// ``` +/// +/// ```gleam +/// > from("") |> map(string, int) +/// Error(DecodeError(expected: "Map", found: "String", path: [])) +/// ``` +/// +pub fn dict( + of key_type: Decoder(k), + to value_type: Decoder(v), +) -> Decoder(Dict(k, v)) { + fn(value) { + use map <- result.try(decode_map(value)) + use pairs <- result.try( + map + |> dict.to_list + |> list.try_map(fn(pair) { + let #(k, v) = pair + use k <- result.try( + key_type(k) + |> map_errors(push_path(_, "keys")), + ) + use v <- result.try( + value_type(v) + |> map_errors(push_path(_, "values")), + ) + Ok(#(k, v)) + }), + ) + Ok(dict.from_list(pairs)) + } +} + +@deprecated("Use `dict` instead") +pub fn map( + of key_type: Decoder(k), + to value_type: Decoder(v), +) -> Decoder(Dict(k, v)) { + dict(key_type, value_type) +} + +@external(erlang, "gleam_stdlib", "decode_map") +@external(javascript, "../gleam_stdlib.mjs", "decode_map") +fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) + +/// Joins multiple decoders into one. When run they will each be tried in turn +/// until one succeeds, or they all fail. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/result +/// > let bool_or_string = any(of: [ +/// > string, +/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } +/// > ]) +/// > bool_or_string(from("ok")) +/// Ok("ok") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(True)) +/// Ok("a bool") +/// ``` +/// +/// ```gleam +/// > bool_or_string(from(1)) +/// Error(DecodeError(expected: "another type", found: "Int", path: [])) +/// ``` +/// +pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { + fn(data) { + case decoders { + [] -> + Error([ + DecodeError(found: classify(data), expected: "another type", path: []), + ]) + + [decoder, ..decoders] -> + case decoder(data) { + Ok(decoded) -> Ok(decoded) + Error(_) -> any(decoders)(data) + } + } + } +} + +/// Decode 1 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode1(MyRecord, element(0, int)) +/// Ok(MyRecord(1)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode1(MyRecord, element(0, int)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// ]) +/// ``` +/// +pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { + fn(value) { + case t1(value) { + Ok(a) -> Ok(constructor(a)) + a -> Error(all_errors(a)) + } + } +} + +/// Decode 2 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Ok(MyRecord(1, 2.0)) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode2(MyRecord, element(0, int), element(1, float)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode2( + constructor: fn(t1, t2) -> t, + t1: Decoder(t1), + t2: Decoder(t2), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value) { + Ok(a), Ok(b) -> Ok(constructor(a, b)) + a, b -> Error(list.concat([all_errors(a), all_errors(b)])) + } + } +} + +/// Decode 3 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.0, "3")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Ok(MyRecord(1, 2.0, "3")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "")) +/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode3( + constructor: fn(t1, t2, t3) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), +) -> Decoder(t) { + fn(value) { + case t1(value), t2(value), t3(value) { + Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) + a, b, c -> + Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) + } + } +} + +/// Decode 4 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "")) +/// > |> decode4( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode4( + constructor: fn(t1, t2, t3, t4) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x) { + Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) + a, b, c, d -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + ])) + } + } +} + +/// Decode 5 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "")) +/// > |> decode5( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode5( + constructor: fn(t1, t2, t3, t4, t5) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) + a, b, c, d, e -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + ])) + } + } +} + +/// Decode 6 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "")) +/// > |> decode6( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode6( + constructor: fn(t1, t2, t3, t4, t5, t6) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> + Ok(constructor(a, b, c, d, e, f)) + a, b, c, d, e, f -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + ])) + } + } +} + +/// Decode 7 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "")) +/// > |> decode7( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode7( + constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> + Ok(constructor(a, b, c, d, e, f, g)) + a, b, c, d, e, f, g -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + ])) + } + } +} + +/// Decode 8 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "")) +/// > |> decode8( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode8( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> + Ok(constructor(a, b, c, d, e, f, g, h)) + a, b, c, d, e, f, g, h -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + ])) + } + } +} + +/// Decode 9 values from a `Dynamic` value. +/// +/// ## Examples +/// +/// ```gleam +/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) +/// ``` +/// +/// ```gleam +/// > from(#("", "", "", "", "", "", "", "", "")) +/// > |> decode9( +/// > MyRecord, +/// > element(0, int), +/// > element(1, float), +/// > element(2, string), +/// > element(3, string), +/// > element(4, string), +/// > element(5, string), +/// > element(6, string), +/// > element(7, string), +/// > element(8, string), +/// > ) +/// Error([ +/// DecodeError(expected: "Int", found: "String", path: ["0"]), +/// DecodeError(expected: "Float", found: "String", path: ["1"]), +/// ]) +/// ``` +/// +pub fn decode9( + constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, + t1: Decoder(t1), + t2: Decoder(t2), + t3: Decoder(t3), + t4: Decoder(t4), + t5: Decoder(t5), + t6: Decoder(t6), + t7: Decoder(t7), + t8: Decoder(t8), + t9: Decoder(t9), +) -> Decoder(t) { + fn(x: Dynamic) { + case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { + Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> + Ok(constructor(a, b, c, d, e, f, g, h, i)) + a, b, c, d, e, f, g, h, i -> + Error(list.concat([ + all_errors(a), + all_errors(b), + all_errors(c), + all_errors(d), + all_errors(e), + all_errors(f), + all_errors(g), + all_errors(h), + all_errors(i), + ])) + } + } +} + +fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { + case result { + Ok(_) -> [] + Error(errors) -> errors + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam new file mode 100644 index 00000000000..5d62419fd0d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/float.gleam @@ -0,0 +1,546 @@ +//// Functions for working with floats. +//// +//// ## Division by zero +//// +//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE +//// 754 standard for floating point arithmetic and does not have an `Infinity` +//// value. In Erlang division by zero results in a crash, however Gleam does +//// not have partial functions and operators in core so instead division by zero +//// returns zero, a behaviour taken from Pony, Coq, and Lean. +//// +//// This may seem unexpected at first, but it is no less mathematically valid +//// than crashing or returning a special value. Division by zero is undefined +//// in mathematics. + +import gleam/order.{type Order} + +/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was +/// not possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2.3") +/// Ok(2.3) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Float, Nil) { + do_parse(string) +} + +@external(erlang, "gleam_stdlib", "parse_float") +@external(javascript, "../gleam_stdlib.mjs", "parse_float") +fn do_parse(a: String) -> Result(Float, Nil) + +/// Returns the string representation of the provided `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2.3) +/// "2.3" +/// ``` +/// +pub fn to_string(x: Float) -> String { + do_to_string(x) +} + +@external(erlang, "gleam_stdlib", "float_to_string") +@external(javascript, "../gleam_stdlib.mjs", "float_to_string") +fn do_to_string(a: Float) -> String + +/// Restricts a `Float` between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(1.2, min: 1.4, max: 1.6) +/// 1.4 +/// ``` +/// +pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two `Float`s, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2.0, 2.3) +/// Lt +/// ``` +/// +/// To handle +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) +/// you may use [`loosely_compare`](#loosely_compare) instead. +/// +pub fn compare(a: Float, with b: Float) -> Order { + case a == b { + True -> order.Eq + False -> + case a <. b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two `Float`s within a tolerance, returning an `Order`: +/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) +/// Eq +/// ``` +/// +/// If you want to check only for equality you may use +/// [`loosely_equals`](#loosely_equals) instead. +/// +pub fn loosely_compare( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Order { + let difference = absolute_value(a -. b) + case difference <=. tolerance { + True -> order.Eq + False -> compare(a, b) + } +} + +/// Checks for equality of two `Float`s within a tolerance, +/// returning an `Bool`. +/// +/// This function allows Float comparison while handling +/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). +/// +/// Notice: For `Float`s the tolerance won't be exact: +/// `5.3 - 5.0` is not exactly `0.3`. +/// +/// ## Examples +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) +/// True +/// ``` +/// +/// ```gleam +/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) +/// False +/// ``` +/// +pub fn loosely_equals( + a: Float, + with b: Float, + tolerating tolerance: Float, +) -> Bool { + let difference = absolute_value(a -. b) + difference <=. tolerance +} + +/// Compares two `Float`s, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2.0, 2.3) +/// 2.0 +/// ``` +/// +pub fn min(a: Float, b: Float) -> Float { + case a <. b { + True -> a + False -> b + } +} + +/// Compares two `Float`s, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2.0, 2.3) +/// 2.3 +/// ``` +/// +pub fn max(a: Float, b: Float) -> Float { + case a >. b { + True -> a + False -> b + } +} + +/// Rounds the value to the next highest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > ceiling(2.3) +/// 3.0 +/// ``` +/// +pub fn ceiling(x: Float) -> Float { + do_ceiling(x) +} + +@external(erlang, "math", "ceil") +@external(javascript, "../gleam_stdlib.mjs", "ceiling") +fn do_ceiling(a: Float) -> Float + +/// Rounds the value to the next lowest whole number as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor(2.3) +/// 2.0 +/// ``` +/// +pub fn floor(x: Float) -> Float { + do_floor(x) +} + +@external(erlang, "math", "floor") +@external(javascript, "../gleam_stdlib.mjs", "floor") +fn do_floor(a: Float) -> Float + +/// Rounds the value to the nearest whole number as an `Int`. +/// +/// ## Examples +/// +/// ```gleam +/// > round(2.3) +/// 2 +/// ``` +/// +/// ```gleam +/// > round(2.5) +/// 3 +/// ``` +/// +pub fn round(x: Float) -> Int { + do_round(x) +} + +@target(erlang) +@external(erlang, "erlang", "round") +fn do_round(a: Float) -> Int + +@target(javascript) +fn do_round(x: Float) -> Int { + case x >=. 0.0 { + True -> js_round(x) + _ -> 0 - js_round(negate(x)) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "round") +fn js_round(a: Float) -> Int + +/// Returns the value as an `Int`, truncating all decimal digits. +/// +/// ## Examples +/// +/// ```gleam +/// > truncate(2.4343434847383438) +/// 2 +/// ``` +/// +pub fn truncate(x: Float) -> Int { + do_truncate(x) +} + +@external(erlang, "erlang", "trunc") +@external(javascript, "../gleam_stdlib.mjs", "truncate") +fn do_truncate(a: Float) -> Int + +/// Returns the absolute value of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12.5) +/// 12.5 +/// ``` +/// +/// ```gleam +/// > absolute_value(10.2) +/// 10.2 +/// ``` +/// +pub fn absolute_value(x: Float) -> Float { + case x >=. 0.0 { + True -> x + _ -> 0.0 -. x + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2.0, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2.0, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8.0, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4.0 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1.0, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { + let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 + // In the following check: + // 1. If the base is negative and the exponent is fractional then + // return an error as it will otherwise be an imaginary number + // 2. If the base is 0 and the exponent is negative then the expression + // is equivalent to the exponent divided by 0 and an error should be + // returned + case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { + True -> Error(Nil) + False -> Ok(do_power(base, exponent)) + } +} + +@external(erlang, "math", "pow") +@external(javascript, "../gleam_stdlib.mjs", "power") +fn do_power(a: Float, b: Float) -> Float + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4.0) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16.0) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Float) -> Result(Float, Nil) { + power(x, 0.5) +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1.0) +/// -1.0 +/// ``` +/// +pub fn negate(x: Float) -> Float { + -1.0 *. x +} + +/// Sums a list of `Float`s. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1.0, 2.2, 3.3]) +/// 6.5 +/// ``` +/// +pub fn sum(numbers: List(Float)) -> Float { + numbers + |> do_sum(0.0) +} + +fn do_sum(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x +. initial) + } +} + +/// Multiplies a list of `Float`s and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2.5, 3.2, 4.2]) +/// 33.6 +/// ``` +/// +pub fn product(numbers: List(Float)) -> Float { + case numbers { + [] -> 1.0 + _ -> do_product(numbers, 1.0) + } +} + +fn do_product(numbers: List(Float), initial: Float) -> Float { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x *. initial) + } +} + +/// Generates a random float between the given minimum and maximum values. +/// +/// +/// ## Examples +/// +/// ```gleam +/// > random(1.0, 5.0) +/// 2.646355926896028 +/// ``` +/// +pub fn random(min: Float, max: Float) -> Float { + do_random_uniform() *. { max -. min } +. min +} + +/// Returns a random float uniformly distributed in the value range +/// 0.0 =< X < 1.0 and updates the state in the process dictionary. +/// See: +/// +@external(erlang, "rand", "uniform") +@external(javascript, "../gleam_stdlib.mjs", "random_uniform") +fn do_random_uniform() -> Float + +/// Returns division of the inputs as a `Result`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0.0, 1.0) +/// Ok(1.0) +/// ``` +/// +/// ```gleam +/// > divide(1.0, 0.0) +/// Error(Nil) +/// ``` +/// +pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { + case b { + 0.0 -> Error(Nil) + b -> Ok(a /. b) + } +} + +/// Adds two floats together. +/// +/// It's the function equivalent of the `+.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1.0, 2.0) +/// 3.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 0.0, add) +/// 6.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> add(2.0) +/// 5.0 +/// ``` +/// +pub fn add(a: Float, b: Float) -> Float { + a +. b +} + +/// Multiplies two floats together. +/// +/// It's the function equivalent of the `*.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2.0, 4.0) +/// 8.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) +/// 24.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> multiply(2.0) +/// 6.0 +/// ``` +/// +pub fn multiply(a: Float, b: Float) -> Float { + a *. b +} + +/// Subtracts one float from another. +/// +/// It's the function equivalent of the `-.` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3.0, 1.0) +/// 2.0 +/// ``` +/// +/// ```gleam +/// > import gleam/list +/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) +/// 4.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(_, 2.0) +/// 1.0 +/// ``` +/// +/// ```gleam +/// > 3.0 |> subtract(2.0, _) +/// -1.0 +/// ``` +/// +pub fn subtract(a: Float, b: Float) -> Float { + a -. b +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam new file mode 100644 index 00000000000..daa997de92a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/function.gleam @@ -0,0 +1,162 @@ +/// Takes two functions and chains them together to form one function that +/// takes the input from the first and returns the output of the second. +/// +pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { + fn(a) { fun2(fun1(a)) } +} + +/// Takes a function with `2` arguments (an arity of `2`), and returns the +/// curried equivalent. +/// +/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. +/// +/// ## Examples +/// +/// *Currying* creates a new function that is identical to the given function +/// except that arguments must now be supplied one by one over several function +/// calls. It thus is the process of taking a function with `n` arguments +/// and producing a sequence of `n` single-argument functions. Given: +/// +/// ```gleam +/// > fn my_fun(i: Int, s: String) -> String { ... } +/// ``` +/// +/// …calling `curry2(my_fun)` would return the curried equivalent, like so: +/// +/// ```gleam +/// > curry2(my_fun) +/// fn(Int) -> fn(String) -> String +/// ``` +/// +/// Currying is useful when you want to partially apply a function with +/// some arguments and then pass it somewhere else, for example: +/// +/// ```gleam +/// > import gleam/list +/// > let multiply = curry2(fn(x, y) { x * y }) +/// > let doubles = list.map([1, 2, 3], multiply(2)) +/// [2, 4, 6] +/// ``` +/// +pub fn curry2(fun: fn(a, b) -> value) { + fn(a) { fn(b) { fun(a, b) } } +} + +/// Takes a function with `3` arguments (an arity of `3`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry3(fun: fn(a, b, c) -> value) { + fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } +} + +/// Takes a function with `4` arguments (an arity of `4`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry4(fun: fn(a, b, c, d) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } +} + +/// Takes a function with `5` arguments (an arity of `5`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e) -> f` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry5(fun: fn(a, b, c, d, e) -> value) { + fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } +} + +/// Takes a function with `6` arguments (an arity of `6`), and returns the +/// curried equivalent. +/// +/// `fn(a, b, c, d, e, f) -> g` becomes +/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. +/// +/// See [`curry2`](#curry2) for a detailed explanation. +/// +pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { + fn(a) { + fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } + } +} + +/// Takes a function that takes two arguments and returns a new function that +/// takes the same two arguments, but in reverse order. +/// +pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { + fn(b, a) { fun(a, b) } +} + +/// Takes a single argument and always returns its input value. +/// +pub fn identity(x: a) -> a { + x +} + +/// Takes a single argument and returns a new function that +/// ignores its argument and always returns the input value. +/// +pub fn constant(value: a) -> fn(b) -> a { + fn(_) { value } +} + +/// Takes an argument and a single function, +/// calls that function with that argument +/// and returns that argument instead of the function return value. +/// Useful for running synchronous side effects in a pipeline. +/// +pub fn tap(arg: a, effect: fn(a) -> b) -> a { + effect(arg) + arg +} + +/// Takes a function with arity one and an argument, +/// calls that function with the argument and returns the function return value. +/// +/// Useful for concisely calling functions returned as a part of a pipeline. +/// +/// ## Example +/// +/// ```gleam +/// > let doubler = fn() { +/// > fn(x: Int) { x * 2 } +/// > } +/// > +/// > doubler() +/// > |> apply1(2) +/// 4 +/// ``` +/// +pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { + fun(arg1) +} + +/// Takes a function with arity two and two arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { + fun(arg1, arg2) +} + +/// Takes a function with arity three and three arguments, +/// calls that function with the arguments +/// and returns the function return value. +/// +/// See [`apply1`](#apply1) for more details. +/// +pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { + fun(arg1, arg2, arg3) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam new file mode 100644 index 00000000000..d93c16afaf6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/int.gleam @@ -0,0 +1,874 @@ +//// Functions for working with integers. +//// +//// ## Division by zero +//// +//// In Erlang division by zero results in a crash, however Gleam does not have +//// partial functions and operators in core so instead division by zero returns +//// zero, a behaviour taken from Pony, Coq, and Lean. +//// +//// This may seem unexpected at first, but it is no less mathematically valid +//// than crashing or returning a special value. Division by zero is undefined +//// in mathematics. + +import gleam/float +import gleam/order.{type Order} + +/// Returns the absolute value of the input. +/// +/// ## Examples +/// +/// ```gleam +/// > absolute_value(-12) +/// 12 +/// ``` +/// +/// ```gleam +/// > absolute_value(10) +/// 10 +/// ``` +/// +pub fn absolute_value(x: Int) -> Int { + case x >= 0 { + True -> x + False -> x * -1 + } +} + +/// Returns the results of the base being raised to the power of the +/// exponent, as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > power(2, -1.0) +/// Ok(0.5) +/// ``` +/// +/// ```gleam +/// > power(2, 2.0) +/// Ok(4.0) +/// ``` +/// +/// ```gleam +/// > power(8, 1.5) +/// Ok(22.627416997969522) +/// ``` +/// +/// ```gleam +/// > 4 |> power(of: 2.0) +/// Ok(16.0) +/// ``` +/// +/// ```gleam +/// > power(-1, 0.5) +/// Error(Nil) +/// ``` +/// +pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { + base + |> to_float() + |> float.power(exponent) +} + +/// Returns the square root of the input as a `Float`. +/// +/// ## Examples +/// +/// ```gleam +/// > square_root(4) +/// Ok(2.0) +/// ``` +/// +/// ```gleam +/// > square_root(-16) +/// Error(Nil) +/// ``` +/// +pub fn square_root(x: Int) -> Result(Float, Nil) { + x + |> to_float() + |> float.square_root() +} + +/// Parses a given string as an int if possible. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("2") +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > parse("ABC") +/// Error(Nil) +/// ``` +/// +pub fn parse(string: String) -> Result(Int, Nil) { + do_parse(string) +} + +@external(erlang, "gleam_stdlib", "parse_int") +@external(javascript, "../gleam_stdlib.mjs", "parse_int") +fn do_parse(a: String) -> Result(Int, Nil) + +/// Parses a given string as an int in a given base if possible. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > base_parse("10", 2) +/// Ok(2) +/// +/// > base_parse("30", 16) +/// Ok(48) +/// +/// > base_parse("1C", 36) +/// Ok(48) +/// +/// > base_parse("48", 1) +/// Error(Nil) +/// +/// > base_parse("48", 37) +/// Error(Nil) +/// ``` +/// +pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { + case base >= 2 && base <= 36 { + True -> do_base_parse(string, base) + False -> Error(Nil) + } +} + +@external(erlang, "gleam_stdlib", "int_from_base_string") +@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") +fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) + +/// Prints a given int to a string. +/// +/// ## Examples +/// +/// ```gleam +/// > to_string(2) +/// "2" +/// ``` +/// +pub fn to_string(x: Int) { + do_to_string(x) +} + +@external(erlang, "erlang", "integer_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "to_string") +fn do_to_string(a: Int) -> String + +/// Error value when trying to operate with a base out of the allowed range. +/// +pub type InvalidBase { + InvalidBase +} + +/// Prints a given int to a string using the base number provided. +/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. +/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base_string(2, 2) +/// Ok("10") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 16) +/// Ok("30") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 36) +/// Ok("1C") +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > to_base_string(48, 37) +/// Error(InvalidBase) +/// ``` +/// +pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { + case base >= 2 && base <= 36 { + True -> Ok(do_to_base_string(x, base)) + False -> Error(InvalidBase) + } +} + +@external(erlang, "erlang", "integer_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") +fn do_to_base_string(a: Int, b: Int) -> String + +/// Prints a given int to a string using base-2. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base2(2) +/// "10" +/// ``` +/// +pub fn to_base2(x: Int) -> String { + do_to_base_string(x, 2) +} + +/// Prints a given int to a string using base-8. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base8(15) +/// "17" +/// ``` +/// +pub fn to_base8(x: Int) -> String { + do_to_base_string(x, 8) +} + +/// Prints a given int to a string using base-16. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base16(48) +/// "30" +/// ``` +/// +pub fn to_base16(x: Int) -> String { + do_to_base_string(x, 16) +} + +/// Prints a given int to a string using base-36. +/// +/// ## Examples +/// +/// ```gleam +/// > to_base36(48) +/// "1C" +/// ``` +/// +pub fn to_base36(x: Int) -> String { + do_to_base_string(x, 36) +} + +/// Takes an int and returns its value as a float. +/// +/// ## Examples +/// +/// ```gleam +/// > to_float(5) +/// 5.0 +/// ``` +/// +/// ```gleam +/// > to_float(0) +/// 0.0 +/// ``` +/// +/// ```gleam +/// > to_float(-3) +/// -3.0 +/// ``` +/// +pub fn to_float(x: Int) -> Float { + do_to_float(x) +} + +@external(erlang, "erlang", "float") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_to_float(a: Int) -> Float + +/// Restricts an int between a lower and upper bound. +/// +/// ## Examples +/// +/// ```gleam +/// > clamp(40, min: 50, max: 60) +/// 50 +/// ``` +/// +pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { + x + |> min(max_bound) + |> max(min_bound) +} + +/// Compares two ints, returning an order. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(2, 3) +/// Lt +/// ``` +/// +/// ```gleam +/// > compare(4, 3) +/// Gt +/// ``` +/// +/// ```gleam +/// > compare(3, 3) +/// Eq +/// ``` +/// +pub fn compare(a: Int, with b: Int) -> Order { + case a == b { + True -> order.Eq + False -> + case a < b { + True -> order.Lt + False -> order.Gt + } + } +} + +/// Compares two ints, returning the smaller of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > min(2, 3) +/// 2 +/// ``` +/// +pub fn min(a: Int, b: Int) -> Int { + case a < b { + True -> a + False -> b + } +} + +/// Compares two ints, returning the larger of the two. +/// +/// ## Examples +/// +/// ```gleam +/// > max(2, 3) +/// 3 +/// ``` +/// +pub fn max(a: Int, b: Int) -> Int { + case a > b { + True -> a + False -> b + } +} + +/// Returns whether the value provided is even. +/// +/// ## Examples +/// +/// ```gleam +/// > is_even(2) +/// True +/// ``` +/// +/// ```gleam +/// > is_even(3) +/// False +/// ``` +/// +pub fn is_even(x: Int) -> Bool { + x % 2 == 0 +} + +/// Returns whether the value provided is odd. +/// +/// ## Examples +/// +/// ```gleam +/// > is_odd(3) +/// True +/// ``` +/// +/// ```gleam +/// > is_odd(2) +/// False +/// ``` +/// +pub fn is_odd(x: Int) -> Bool { + x % 2 != 0 +} + +/// Returns the negative of the value provided. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(1) +/// -1 +/// ``` +/// +pub fn negate(x: Int) -> Int { + -1 * x +} + +/// Sums a list of ints. +/// +/// ## Example +/// +/// ```gleam +/// > sum([1, 2, 3]) +/// 6 +/// ``` +/// +pub fn sum(numbers: List(Int)) -> Int { + numbers + |> do_sum(0) +} + +fn do_sum(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_sum(rest, x + initial) + } +} + +/// Multiplies a list of ints and returns the product. +/// +/// ## Example +/// +/// ```gleam +/// > product([2, 3, 4]) +/// 24 +/// ``` +/// +pub fn product(numbers: List(Int)) -> Int { + case numbers { + [] -> 1 + _ -> do_product(numbers, 1) + } +} + +fn do_product(numbers: List(Int), initial: Int) -> Int { + case numbers { + [] -> initial + [x, ..rest] -> do_product(rest, x * initial) + } +} + +/// Splits an integer into its digit representation in the specified base +/// +/// ## Examples +/// +/// ```gleam +/// > digits(234, 10) +/// Ok([2,3,4]) +/// ``` +/// +/// ```gleam +/// > digits(234, 1) +/// Error(InvalidBase) +/// ``` +/// +pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> Ok(do_digits(x, base, [])) + } +} + +fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { + case absolute_value(x) < base { + True -> [x, ..acc] + False -> do_digits(x / base, base, [x % base, ..acc]) + } +} + +/// Joins a list of digits into a single value. +/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. +/// +/// ## Examples +/// +/// ```gleam +/// > undigits([2,3,4], 10) +/// Ok(234) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 1) +/// Error(InvalidBase) +/// ``` +/// +/// ```gleam +/// > undigits([2,3,4], 2) +/// Error(InvalidBase) +/// ``` +/// +pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { + case base < 2 { + True -> Error(InvalidBase) + False -> do_undigits(numbers, base, 0) + } +} + +fn do_undigits( + numbers: List(Int), + base: Int, + acc: Int, +) -> Result(Int, InvalidBase) { + case numbers { + [] -> Ok(acc) + [digit, ..] if digit >= base -> Error(InvalidBase) + [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) + } +} + +/// Generates a random int between the given minimum and maximum values. +/// +/// ## Examples +/// +/// ```gleam +/// > random(1, 5) +/// 2 +/// ``` +/// +pub fn random(min: Int, max: Int) -> Int { + float.random(to_float(min), to_float(max)) + |> float.floor() + |> float.round() +} + +/// Performs a truncated integer division. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > divide(0, 1) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > divide(-99, 2) +/// Ok(-49) +/// ``` +/// +pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend / divisor) + } +} + +/// Computes the remainder of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > remainder(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > remainder(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: 3) +/// Ok(-1) +/// ``` +/// +/// ```gleam +/// > remainder(13, by: -3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > remainder(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> Ok(dividend % divisor) + } +} + +/// Computes the modulo of an integer division of inputs as a `Result`. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// Most the time you will want to use the `%` operator instead of this +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > modulo(3, 2) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > modulo(10, -1) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: 3) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: 3) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > modulo(13, by: -3) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > modulo(-13, by: -3) +/// Ok(-1) +/// ``` +/// +pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + _ -> { + let remainder = dividend % divisor + case remainder * divisor < 0 { + True -> Ok(remainder + divisor) + False -> Ok(remainder) + } + } + } +} + +/// Performs a *floored* integer division, which means that the result will +/// always be rounded towards negative infinity. +/// +/// If you want to perform truncated integer division (rounding towards zero), +/// use `int.divide()` or the `/` operator instead. +/// +/// Returns division of the inputs as a `Result`: If the given divisor equals +/// `0`, this function returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > floor_divide(1, 0) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > floor_divide(5, 2) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > floor_divide(6, -4) +/// Ok(-2) +/// ``` +/// +/// ```gleam +/// > floor_divide(-99, 2) +/// Ok(-50) +/// ``` +/// +pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { + case divisor { + 0 -> Error(Nil) + divisor -> + case dividend * divisor < 0 && dividend % divisor != 0 { + True -> Ok(dividend / divisor - 1) + False -> Ok(dividend / divisor) + } + } +} + +/// Adds two integers together. +/// +/// It's the function equivalent of the `+` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > add(1, 2) +/// 3 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 0, add) +/// 6 +/// ``` +/// +/// ```gleam +/// > 3 |> add(2) +/// 5 +/// ``` +/// +pub fn add(a: Int, b: Int) -> Int { + a + b +} + +/// Multiplies two integers together. +/// +/// It's the function equivalent of the `*` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > multiply(2, 4) +/// 8 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([2, 3, 4], 1, multiply) +/// 24 +/// ``` +/// +/// ```gleam +/// > 3 |> multiply(2) +/// 6 +/// ``` +/// +pub fn multiply(a: Int, b: Int) -> Int { + a * b +} + +/// Subtracts one int from another. +/// +/// It's the function equivalent of the `-` operator. +/// This function is useful in higher order functions or pipes. +/// +/// ## Examples +/// +/// ```gleam +/// > subtract(3, 1) +/// 2.0 +/// ``` +/// +/// ```gleam +/// import gleam/list +/// > list.fold([1, 2, 3], 10, subtract) +/// 4 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2) +/// 1 +/// ``` +/// +/// ```gleam +/// > 3 |> subtract(2, _) +/// -1 +/// ``` +/// +pub fn subtract(a: Int, b: Int) -> Int { + a - b +} + +/// Calculates the bitwise AND of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "band") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") +pub fn bitwise_and(x: Int, y: Int) -> Int + +/// Calculates the bitwise NOT of its argument. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bnot") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") +pub fn bitwise_not(x: Int) -> Int + +/// Calculates the bitwise OR of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bor") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") +pub fn bitwise_or(x: Int, y: Int) -> Int + +/// Calculates the bitwise XOR of its arguments. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bxor") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") +pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int + +/// Calculates the result of an arithmetic left bitshift. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bsl") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") +pub fn bitwise_shift_left(x: Int, y: Int) -> Int + +/// Calculates the result of an arithmetic right bitshift. +/// +/// The exact behaviour of this function depends on the target platform. +/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it +/// is equivalent to bitwise operations on big-ints. +/// +@external(erlang, "erlang", "bsr") +@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") +pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam new file mode 100644 index 00000000000..0c0a3eeffe0 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/io.gleam @@ -0,0 +1,117 @@ +import gleam/string + +/// Writes a string to standard output. +/// +/// If you want your output to be printed on its own line see `println`. +/// +/// ## Example +/// +/// ```gleam +/// > io.print("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn print(string: String) -> Nil { + do_print(string) +} + +@external(erlang, "gleam_stdlib", "print") +@external(javascript, "../gleam_stdlib.mjs", "print") +fn do_print(string string: String) -> Nil + +/// Writes a string to standard error. +/// +/// If you want your output to be printed on its own line see `println_error`. +/// +/// ## Example +/// +/// ``` +/// > io.print_error("Hi pop") +/// // -> Hi pop +/// Nil +/// ``` +/// +pub fn print_error(string: String) -> Nil { + do_print_error(string) +} + +@external(erlang, "gleam_stdlib", "print_error") +@external(javascript, "../gleam_stdlib.mjs", "print_error") +fn do_print_error(string string: String) -> Nil + +/// Writes a string to standard output, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println("Hi mum") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println(string: String) -> Nil { + do_println(string) +} + +@external(erlang, "gleam_stdlib", "println") +@external(javascript, "../gleam_stdlib.mjs", "console_log") +fn do_println(string string: String) -> Nil + +/// Writes a string to standard error, appending a newline to the end. +/// +/// ## Example +/// +/// ```gleam +/// > io.println_error("Hi pop") +/// // -> Hi mum +/// Nil +/// ``` +/// +pub fn println_error(string: String) -> Nil { + do_println_error(string) +} + +@external(erlang, "gleam_stdlib", "println_error") +@external(javascript, "../gleam_stdlib.mjs", "console_error") +fn do_println_error(string string: String) -> Nil + +/// Prints a value to standard error (stderr) yielding Gleam syntax. +/// +/// The value is returned after being printed so it can be used in pipelines. +/// +/// ## Example +/// +/// ```gleam +/// > debug("Hi mum") +/// // -> <<"Hi mum">> +/// "Hi mum" +/// ``` +/// +/// ```gleam +/// > debug(Ok(1)) +/// // -> {ok, 1} +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > import list +/// > [1, 2] +/// > |> list.map(fn(x) { x + 1 }) +/// > |> debug +/// > |> list.map(fn(x) { x * 2 }) +/// // -> [2, 3] +/// [4, 6] +/// ``` +/// +pub fn debug(term: anything) -> anything { + term + |> string.inspect + |> do_debug_println + + term +} + +@external(erlang, "gleam_stdlib", "println_error") +@external(javascript, "../gleam_stdlib.mjs", "print_debug") +fn do_debug_println(string string: String) -> Nil diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam new file mode 100644 index 00000000000..c57e7fd9473 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/iterator.gleam @@ -0,0 +1,1530 @@ +import gleam/result +import gleam/int +import gleam/list +import gleam/dict.{type Dict} +import gleam/option.{type Option, None, Some} +import gleam/order + +// Internal private representation of an Iterator +type Action(element) { + // Dedicated to Electric Six + // https://youtu.be/_30t2dzEgiw?t=162 + Stop + Continue(element, fn() -> Action(element)) +} + +/// An iterator is a lazily evaluated sequence of element. +/// +/// Iterators are useful when working with collections that are too large to +/// fit in memory (or those that are infinite in size) as they only require the +/// elements currently being processed to be in memory. +/// +/// As a lazy data structure no work is done when an iterator is filters, +/// mapped, etc, instead a new iterator is returned with these transformations +/// applied to the stream. Once the stream has all the required transformations +/// applied it can be evaluated using functions such as `fold` and `to_list`. +/// +pub opaque type Iterator(element) { + Iterator(continuation: fn() -> Action(element)) +} + +// Public API for iteration +pub type Step(element, accumulator) { + Next(element: element, accumulator: accumulator) + Done +} + +// Shortcut for an empty iterator. +fn stop() -> Action(element) { + Stop +} + +// Creating Iterators +fn do_unfold( + initial: acc, + f: fn(acc) -> Step(element, acc), +) -> fn() -> Action(element) { + fn() { + case f(initial) { + Next(x, acc) -> Continue(x, do_unfold(acc, f)) + Done -> Stop + } + } +} + +/// Creates an iterator from a given function and accumulator. +/// +/// The function is called on the accumulator and returns either `Done`, +/// indicating the iterator has no more elements, or `Next` which contains a +/// new element and accumulator. The element is yielded by the iterator and the +/// new accumulator is used with the function to compute the next element in +/// the sequence. +/// +/// ## Examples +/// +/// ```gleam +/// > unfold(from: 5, with: fn(n) { +/// > case n { +/// > 0 -> Done +/// > n -> Next(element: n, accumulator: n - 1) +/// > } +/// > }) +/// > |> to_list +/// [5, 4, 3, 2, 1] +/// ``` +/// +pub fn unfold( + from initial: acc, + with f: fn(acc) -> Step(element, acc), +) -> Iterator(element) { + initial + |> do_unfold(f) + |> Iterator +} + +// TODO: test +/// Creates an iterator that yields values created by calling a given function +/// repeatedly. +/// +pub fn repeatedly(f: fn() -> element) -> Iterator(element) { + unfold(Nil, fn(_) { Next(f(), Nil) }) +} + +/// Creates an iterator that returns the same value infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat(10) +/// > |> take(4) +/// > |> to_list +/// [10, 10, 10, 10] +/// ``` +/// +pub fn repeat(x: element) -> Iterator(element) { + repeatedly(fn() { x }) +} + +/// Creates an iterator that yields each element from the given list. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn from_list(list: List(element)) -> Iterator(element) { + let yield = fn(acc) { + case acc { + [] -> Done + [head, ..tail] -> Next(head, tail) + } + } + unfold(list, yield) +} + +// Consuming Iterators +fn do_transform( + continuation: fn() -> Action(a), + state: acc, + f: fn(acc, a) -> Step(b, acc), +) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> + case f(state, el) { + Done -> Stop + Next(yield, next_state) -> + Continue(yield, do_transform(next, next_state, f)) + } + } + } +} + +/// Creates an iterator from an existing iterator +/// and a stateful function that may short-circuit. +/// +/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, +/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. +/// +/// ## Examples +/// +/// Approximate implementation of `index` in terms of `transform`: +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) +/// > |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +pub fn transform( + over iterator: Iterator(a), + from initial: acc, + with f: fn(acc, a) -> Step(b, acc), +) -> Iterator(b) { + do_transform(iterator.continuation, initial, f) + |> Iterator +} + +fn do_fold( + continuation: fn() -> Action(e), + f: fn(acc, e) -> acc, + accumulator: acc, +) -> acc { + case continuation() { + Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) + Stop -> accumulator + } +} + +/// Reduces an iterator of elements into a single value by calling a given +/// function on each element in turn. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// If you do not care about the end value and only wish to evaluate the +/// iterator for side effects consider using the `run` function instead. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) +/// 10 +/// ``` +/// +pub fn fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> acc, +) -> acc { + iterator.continuation + |> do_fold(f, initial) +} + +// TODO: test +/// Evaluates all elements emitted by the given iterator. This function is useful for when +/// you wish to trigger any side effects that would occur when evaluating +/// the iterator. +/// +pub fn run(iterator: Iterator(e)) -> Nil { + fold(iterator, Nil, fn(_, _) { Nil }) +} + +/// Evaluates an iterator and returns all the elements as a list. +/// +/// If called on an iterator of infinite length then this function will never +/// return. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn to_list(iterator: Iterator(element)) -> List(element) { + iterator + |> fold([], fn(acc, e) { [e, ..acc] }) + |> list.reverse +} + +/// Eagerly accesses the first value of an iterator, returning a `Next` +/// that contains the first value and the rest of the iterator. +/// +/// If called on an empty iterator, `Done` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Next(first, rest) = [1, 2, 3, 4] +/// > |> from_list +/// > |> step +/// > first +/// 1 +/// ``` +/// +/// ```gleam +/// > rest |> to_list +/// [2, 3, 4] +/// ``` +/// +/// ```gleam +/// > empty() |> step +/// Done +/// ``` +/// +pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { + case iterator.continuation() { + Stop -> Done + Continue(e, a) -> Next(e, Iterator(a)) + } +} + +fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { + fn() { + case desired > 0 { + False -> Stop + True -> + case continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, do_take(next, desired - 1)) + } + } + } +} + +/// Creates an iterator that only yields the first `desired` elements. +/// +/// If the iterator does not have enough elements all of them are yielded. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2, 3] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> take(up_to: 3) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + iterator.continuation + |> do_take(desired) + |> Iterator +} + +fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case desired > 0 { + True -> do_drop(next, desired - 1) + False -> Continue(e, next) + } + } +} + +/// Evaluates and discards the first N elements in an iterator, returning a new +/// iterator. +/// +/// If the iterator does not have enough elements an empty iterator is +/// returned. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [4, 5] +/// ``` +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> drop(up_to: 3) +/// > |> to_list +/// [] +/// ``` +/// +pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { + fn() { do_drop(iterator.continuation, desired) } + |> Iterator +} + +fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) + } + } +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3] +/// > |> from_list +/// > |> map(fn(x) { x * 2 }) +/// > |> to_list +/// [2, 4, 6] +/// ``` +/// +pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { + iterator.continuation + |> do_map(f) + |> Iterator +} + +fn do_map2( + continuation1: fn() -> Action(a), + continuation2: fn() -> Action(b), + with fun: fn(a, b) -> c, +) -> fn() -> Action(c) { + fn() { + case continuation1() { + Stop -> Stop + Continue(a, next_a) -> + case continuation2() { + Stop -> Stop + Continue(b, next_b) -> + Continue(fun(a, b), do_map2(next_a, next_b, fun)) + } + } + } +} + +/// Combines two interators into a single one using the given function. +/// +/// If an iterator is longer than the other the extra elements are dropped. +/// +/// This function does not evaluate the elements of the two iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// let first = from_list([1, 2, 3]) +/// let second = from_list([4, 5, 6]) +/// map2(first, second, fn(x, y) { x + y }) |> to_list +/// // -> [5, 7, 9] +/// ``` +/// +/// ```gleam +/// let first = from_list([1, 2]) +/// let second = from_list(["a", "b", "c"]) +/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list +/// // -> [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2( + iterator1: Iterator(a), + iterator2: Iterator(b), + with fun: fn(a, b) -> c, +) -> Iterator(c) { + do_map2(iterator1.continuation, iterator2.continuation, fun) + |> Iterator +} + +fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { + case first() { + Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) + Stop -> second() + } +} + +/// Appends two iterators, producing a new iterator. +/// +/// This function does not evaluate the elements of the iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> append([3, 4] |> from_list) +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { + fn() { do_append(first.continuation, second.continuation) } + |> Iterator +} + +fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { + case flattened() { + Stop -> Stop + Continue(it, next_iterator) -> + do_append(it.continuation, fn() { do_flatten(next_iterator) }) + } +} + +/// Flattens an iterator of iterators, creating a new iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([[1, 2], [3, 4]]) +/// > |> map(from_list) +/// > |> flatten +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { + fn() { do_flatten(iterator.continuation) } + |> Iterator +} + +/// Joins a list of iterators into a single iterator. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [[1, 2], [3, 4]] +/// > |> map(from_list) +/// > |> concat +/// > |> to_list +/// [1, 2, 3, 4] +/// ``` +/// +pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { + flatten(from_list(iterators)) +} + +/// Creates an iterator from an existing iterator and a transformation function. +/// +/// Each element in the new iterator will be the result of calling the given +/// function on the elements in the given iterator and then flattening the +/// results. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) +/// > |> to_list +/// [1, 2, 2, 3] +/// ``` +/// +pub fn flat_map( + over iterator: Iterator(a), + with f: fn(a) -> Iterator(b), +) -> Iterator(b) { + iterator + |> map(f) + |> flatten +} + +fn do_filter( + continuation: fn() -> Action(e), + predicate: fn(e) -> Bool, +) -> Action(e) { + case continuation() { + Stop -> Stop + Continue(e, iterator) -> + case predicate(e) { + True -> Continue(e, fn() { do_filter(iterator, predicate) }) + False -> do_filter(iterator, predicate) + } + } +} + +/// Creates an iterator from an existing iterator and a predicate function. +/// +/// The new iterator will contain elements from the first iterator for which +/// the given function returns `True`. +/// +/// This function does not evaluate the elements of the iterator, the +/// computation is performed when the iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> filter(int.is_even) +/// > |> to_list +/// [2, 4] +/// ``` +/// +pub fn filter( + iterator: Iterator(a), + keeping predicate: fn(a) -> Bool, +) -> Iterator(a) { + fn() { do_filter(iterator.continuation, predicate) } + |> Iterator +} + +/// Creates an iterator that repeats a given iterator infinitely. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2] +/// > |> from_list +/// > |> cycle +/// > |> take(6) +/// > |> to_list +/// [1, 2, 1, 2, 1, 2] +/// ``` +/// +pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { + repeat(iterator) + |> flatten +} + +/// Creates an iterator of ints, starting at a given start int and stepping by +/// one to a given end int. +/// +/// ## Examples +/// +/// ```gleam +/// > range(from: 1, to: 5) |> to_list +/// [1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(from: 1, to: -2) |> to_list +/// [1, 0, -1, -2] +/// ``` +/// +/// ```gleam +/// > range(from: 0, to: 0) |> to_list +/// [0] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { + case int.compare(start, stop) { + order.Eq -> once(fn() { start }) + order.Gt -> + unfold( + from: start, + with: fn(current) { + case current < stop { + False -> Next(current, current - 1) + True -> Done + } + }, + ) + + order.Lt -> + unfold( + from: start, + with: fn(current) { + case current > stop { + False -> Next(current, current + 1) + True -> Done + } + }, + ) + } +} + +fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { + case continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + case f(e) { + True -> Ok(e) + False -> do_find(next, f) + } + } +} + +/// Finds the first element in a given iterator for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if the function does not return `True` for any of the +/// elements. +/// +/// ## Examples +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find(empty(), fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: Iterator(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + haystack.continuation + |> do_find(is_desired) +} + +fn do_index( + continuation: fn() -> Action(element), + next: Int, +) -> fn() -> Action(#(Int, element)) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, continuation) -> + Continue(#(next, e), do_index(continuation, next + 1)) + } + } +} + +/// Wraps values yielded from an iterator with indices, starting from 0. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) |> index |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +/// +pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { + iterator.continuation + |> do_index(0) + |> Iterator +} + +/// Creates an iterator that inifinitely applies a function to a value. +/// +/// ## Examples +/// +/// ```gleam +/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list +/// [1, 3, 9, 27, 81] +/// ``` +/// +pub fn iterate( + from initial: element, + with f: fn(element) -> element, +) -> Iterator(element) { + unfold(initial, fn(element) { Next(element, f(element)) }) +} + +fn do_take_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> fn() -> Action(element) { + fn() { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Stop + True -> Continue(e, do_take_while(next, predicate)) + } + } + } +} + +/// Creates an iterator that yields elements while the predicate returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 2, 4]) +/// > |> take_while(satisfying: fn(x) { x < 3 }) +/// > |> to_list +/// [1, 2] +/// ``` +/// +pub fn take_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + iterator.continuation + |> do_take_while(predicate) + |> Iterator +} + +fn do_drop_while( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> + case predicate(e) { + False -> Continue(e, next) + True -> do_drop_while(next, predicate) + } + } +} + +/// Creates an iterator that drops elements while the predicate returns `True`, +/// and then yields the remaining elements. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 2, 5]) +/// > |> drop_while(satisfying: fn(x) { x < 4 }) +/// > |> to_list +/// [4, 2, 5] +/// ``` +/// +pub fn drop_while( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Iterator(element) { + fn() { do_drop_while(iterator.continuation, predicate) } + |> Iterator +} + +fn do_scan( + continuation: fn() -> Action(element), + f: fn(acc, element) -> acc, + accumulator: acc, +) -> fn() -> Action(acc) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> { + let accumulated = f(accumulator, el) + Continue(accumulated, do_scan(next, f, accumulated)) + } + } + } +} + +/// Creates an iterator from an existing iterator and a stateful function. +/// +/// Specifically, this behaves like `fold`, but yields intermediate results. +/// +/// ## Examples +/// +/// ```gleam +/// // Generate a sequence of partial sums +/// > from_list([1, 2, 3, 4, 5]) +/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) +/// > |> to_list +/// [1, 3, 6, 10, 15] +/// ``` +/// +pub fn scan( + over iterator: Iterator(element), + from initial: acc, + with f: fn(acc, element) -> acc, +) -> Iterator(acc) { + iterator.continuation + |> do_scan(f, initial) + |> Iterator +} + +fn do_zip( + left: fn() -> Action(a), + right: fn() -> Action(b), +) -> fn() -> Action(#(a, b)) { + fn() { + case left() { + Stop -> Stop + Continue(el_left, next_left) -> + case right() { + Stop -> Stop + Continue(el_right, next_right) -> + Continue(#(el_left, el_right), do_zip(next_left, next_right)) + } + } + } +} + +/// Zips two iterators together, emitting values from both +/// until the shorter one runs out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> zip(range(20, 30)) +/// > |> to_list +/// [#("a", 20), #("b", 21), #("c", 22)] +/// ``` +/// +pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { + do_zip(left.continuation, right.continuation) + |> Iterator +} + +// Result of collecting a single chunk by key +type Chunk(element, key) { + AnotherBy(List(element), key, element, fn() -> Action(element)) + LastBy(List(element)) +} + +fn next_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + current_chunk: List(element), +) -> Chunk(element, key) { + case continuation() { + Stop -> LastBy(list.reverse(current_chunk)) + Continue(e, next) -> { + let key = f(e) + case key == previous_key { + True -> next_chunk(next, f, key, [e, ..current_chunk]) + False -> AnotherBy(list.reverse(current_chunk), key, e, next) + } + } + } +} + +fn do_chunk( + continuation: fn() -> Action(element), + f: fn(element) -> key, + previous_key: key, + previous_element: element, +) -> Action(List(element)) { + case next_chunk(continuation, f, previous_key, [previous_element]) { + LastBy(chunk) -> Continue(chunk, stop) + AnotherBy(chunk, key, el, next) -> + Continue(chunk, fn() { do_chunk(next, f, key, el) }) + } +} + +/// Creates an iterator that emits chunks of elements +/// for which `f` returns the same value. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) +/// > |> chunk(by: fn(n) { n % 2 }) +/// > |> to_list +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk( + over iterator: Iterator(element), + by f: fn(element) -> key, +) -> Iterator(List(element)) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> do_chunk(next, f, f(e), e) + } + } + |> Iterator +} + +// Result of collecting a single sized chunk +type SizedChunk(element) { + Another(List(element), fn() -> Action(element)) + Last(List(element)) + NoMore +} + +fn next_sized_chunk( + continuation: fn() -> Action(element), + left: Int, + current_chunk: List(element), +) -> SizedChunk(element) { + case continuation() { + Stop -> + case current_chunk { + [] -> NoMore + remaining -> Last(list.reverse(remaining)) + } + Continue(e, next) -> { + let chunk = [e, ..current_chunk] + case left > 1 { + False -> Another(list.reverse(chunk), next) + True -> next_sized_chunk(next, left - 1, chunk) + } + } + } +} + +fn do_sized_chunk( + continuation: fn() -> Action(element), + count: Int, +) -> fn() -> Action(List(element)) { + fn() { + case next_sized_chunk(continuation, count, []) { + NoMore -> Stop + Last(chunk) -> Continue(chunk, stop) + Another(chunk, next_element) -> + Continue(chunk, do_sized_chunk(next_element, count)) + } + } +} + +/// Creates an iterator that emits chunks of given size. +/// +/// If the last chunk does not have `count` elements, it is yielded +/// as a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) +/// > |> sized_chunk(into: 2) +/// > |> to_list +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) +/// > |> sized_chunk(into: 3) +/// > |> to_list +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk( + over iterator: Iterator(element), + into count: Int, +) -> Iterator(List(element)) { + iterator.continuation + |> do_sized_chunk(count) + |> Iterator +} + +fn do_intersperse( + continuation: fn() -> Action(element), + separator: element, +) -> Action(element) { + case continuation() { + Stop -> Stop + Continue(e, next) -> { + let next_interspersed = fn() { do_intersperse(next, separator) } + Continue(separator, fn() { Continue(e, next_interspersed) }) + } + } +} + +/// Creates an iterator that yields the given `elem` element +/// between elements emitted by the underlying iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() +/// > |> intersperse(with: 0) +/// > |> to_list +/// [] +/// +/// > from_list([1]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1] +/// +/// > from_list([1, 2, 3, 4, 5]) +/// > |> intersperse(with: 0) +/// > |> to_list +/// [1, 0, 2, 0, 3, 0, 4, 0, 5] +/// ``` +/// +pub fn intersperse( + over iterator: Iterator(element), + with elem: element, +) -> Iterator(element) { + fn() { + case iterator.continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) + } + } + |> Iterator +} + +fn do_any( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> False + Continue(e, next) -> + case predicate(e) { + True -> True + False -> do_any(next, predicate) + } + } +} + +/// Returns `True` if any element emitted by the iterator satisfies the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a satisfying element. +/// +/// An empty iterator results in `False`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn any( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_any(predicate) +} + +fn do_all( + continuation: fn() -> Action(element), + predicate: fn(element) -> Bool, +) -> Bool { + case continuation() { + Stop -> True + Continue(e, next) -> + case predicate(e) { + True -> do_all(next, predicate) + False -> False + } + } +} + +/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, +/// `False` otherwise. +/// +/// This function short-circuits once it finds a non-satisfying element. +/// +/// An empty iterator results in `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) +/// True +/// ``` +/// +/// ```gleam +/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) +/// False +/// ``` +/// +pub fn all( + in iterator: Iterator(element), + satisfying predicate: fn(element) -> Bool, +) -> Bool { + iterator.continuation + |> do_all(predicate) +} + +fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { + fn(maybe_group) { + case maybe_group { + Some(group) -> [el, ..group] + None -> [el] + } + } +} + +fn group_updater( + f: fn(element) -> key, +) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { + fn(groups, elem) { + groups + |> dict.update(f(elem), update_group_with(elem)) + } +} + +/// Returns a `Dict(k, List(element))` of elements from the given iterator +/// grouped with the given key function. +/// +/// The order within each group is preserved from the iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) +/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) +/// ``` +/// +pub fn group( + in iterator: Iterator(element), + by key: fn(element) -> key, +) -> Dict(key, List(element)) { + iterator + |> fold(dict.new(), group_updater(key)) + |> dict.map_values(fn(_, group) { list.reverse(group) }) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first yielded element +/// and combines it with each subsequent element in turn using the given function. +/// The function is called as `f(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce( + over iterator: Iterator(e), + with f: fn(e, e) -> e, +) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, next) -> + do_fold(next, f, e) + |> Ok + } +} + +/// Returns the last element in the given iterator. +/// +/// Returns `Error(Nil)` if the iterator is empty. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> last +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > range(1, 10) |> last +/// Ok(9) +/// ``` +/// +pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { + iterator + |> reduce(fn(_, elem) { elem }) +} + +/// Creates an iterator that yields no elements. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> to_list +/// [] +/// ``` +/// +pub fn empty() -> Iterator(element) { + Iterator(stop) +} + +/// Creates an iterator that yields exactly one element provided by calling the given function. +/// +/// ## Examples +/// +/// ```gleam +/// > once(fn() { 1 }) |> to_list +/// [1] +/// ``` +/// +pub fn once(f: fn() -> element) -> Iterator(element) { + fn() { Continue(f(), stop) } + |> Iterator +} + +/// Creates an iterator that yields the given element exactly once. +/// +/// ## Examples +/// +/// ```gleam +/// > single(1) |> to_list +/// [1] +/// ``` +/// +pub fn single(elem: element) -> Iterator(element) { + once(fn() { elem }) +} + +fn do_interleave( + current: fn() -> Action(element), + next: fn() -> Action(element), +) -> Action(element) { + case current() { + Stop -> next() + Continue(e, next_other) -> + Continue(e, fn() { do_interleave(next, next_other) }) + } +} + +/// Creates an iterator that alternates between the two given iterators +/// until both have run out. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list +/// [1, 11, 2, 12, 3, 13, 4, 14] +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list +/// [1, 100, 2, 3, 4] +/// ``` +/// +pub fn interleave( + left: Iterator(element), + with right: Iterator(element), +) -> Iterator(element) { + fn() { do_interleave(left.continuation, right.continuation) } + |> Iterator +} + +fn do_fold_until( + continuation: fn() -> Action(e), + f: fn(acc, e) -> list.ContinueOrStop(acc), + accumulator: acc, +) -> acc { + case continuation() { + Stop -> accumulator + Continue(elem, next) -> + case f(accumulator, elem) { + list.Continue(accumulator) -> do_fold_until(next, f, accumulator) + list.Stop(accumulator) -> accumulator + } + } +} + +/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given +/// function on each element in turn, but uses `list.ContinueOrStop` to determine +/// whether or not to keep iterating. +/// +/// If called on an iterator of infinite length then this function will only ever +/// return if the function returns `list.Stop`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > let f = fn(acc, e) { +/// > case e { +/// > _ if e < 4 -> list.Continue(e + acc) +/// > _ -> list.Stop(acc) +/// > } +/// > } +/// > +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> fold_until(from: acc, with: f) +/// 6 +/// ``` +/// +pub fn fold_until( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> list.ContinueOrStop(acc), +) -> acc { + iterator.continuation + |> do_fold_until(f, initial) +} + +fn do_try_fold( + over continuation: fn() -> Action(a), + with f: fn(acc, a) -> Result(acc, err), + from accumulator: acc, +) -> Result(acc, err) { + case continuation() { + Stop -> Ok(accumulator) + Continue(elem, next) -> { + use accumulator <- result.try(f(accumulator, elem)) + do_try_fold(next, f, accumulator) + } + } +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4] +/// > |> iterator.from_list() +/// > |> try_fold(0, fn(acc, i) { +/// > case i < 3 { +/// > True -> Ok(acc + i) +/// > False -> Error(Nil) +/// > } +/// > }) +/// Error(Nil) +/// ``` +/// +pub fn try_fold( + over iterator: Iterator(e), + from initial: acc, + with f: fn(acc, e) -> Result(acc, err), +) -> Result(acc, err) { + iterator.continuation + |> do_try_fold(f, initial) +} + +/// Returns the first element yielded by the given iterator, if it exists, +/// or `Error(Nil)` otherwise. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) |> first +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > empty() |> first +/// Error(Nil) +/// ``` +pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { + case iterator.continuation() { + Stop -> Error(Nil) + Continue(e, _) -> Ok(e) + } +} + +/// Returns nth element yielded by the given iterator, where `0` means the first element. +/// +/// If there are not enough elements in the iterator, `Error(Nil)` is returned. +/// +/// For any `index` less than `0` this function behaves as if it was set to `0`. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(2) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> at(4) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > empty() |> at(0) +/// Error(Nil) +/// ``` +/// +pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { + iterator + |> drop(index) + |> first +} + +fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { + case continuation() { + Stop -> length + Continue(_, next) -> do_length(next, length + 1) + } +} + +/// Counts the number of elements in the given iterator. +/// +/// This function has to traverse the entire iterator to count its elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> length +/// 0 +/// ``` +/// +/// ```gleam +/// > from_list([1, 2, 3, 4]) |> length +/// 4 +/// ``` +/// +pub fn length(over iterator: Iterator(e)) -> Int { + iterator.continuation + |> do_length(0) +} + +/// Traverse an iterator, calling a function on each element. +/// +/// ## Examples +/// +/// ```gleam +/// > empty() |> each(io.println) +/// Nil +/// ``` +/// +/// ```gleam +/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) +/// // -> Tom +/// // -> Malory +/// // -> Louis +/// Nil +/// ``` +/// +pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { + iterator + |> map(f) + |> run +} + +/// Add a new element to the start of an iterator. +/// +/// This function is for use with `use` expressions, to replicate the behaviour +/// of the `yield` keyword found in other languages. +/// +/// ## Examples +/// +/// ```gleam +/// > use <- iterator.yield(1) +/// > use <- iterator.yield(2) +/// > use <- iterator.yield(3) +/// > iterator.empty() +/// iterator.from_list([1, 2, 3]) +/// ``` +/// +pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { + Iterator(fn() { Continue(element, next().continuation) }) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam new file mode 100644 index 00000000000..a5cffa9b951 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/list.gleam @@ -0,0 +1,2154 @@ +//// Lists are an ordered sequence of elements and are one of the most common +//// data types in Gleam. +//// +//// New elements can be added and removed from the front of a list in +//// constant time, while adding and removing from the end requires traversing +//// the copying the whole list, so keep this in mind when designing your +//// programs. +//// +//// There is a dedicated syntax for prefixing to a list: +//// +//// ```gleam +//// let new_list = [1, 2, ..existing_list] +//// ``` +//// +//// And a matching syntax for getting the first elements of a list: +//// +//// ```gleam +//// case list { +//// [first_element, ..rest] -> first_element +//// _ -> "this pattern matches when the list is empty" +//// } +//// ``` +//// + +import gleam/int +import gleam/float +import gleam/order.{type Order} +import gleam/pair +import gleam/dict.{type Dict} + +/// An error value returned by the `strict_zip` function. +/// +pub type LengthMismatch { + LengthMismatch +} + +/// Counts the number of elements in a given list. +/// +/// This function has to traverse the list to determine the number of elements, +/// so it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > length([]) +/// 0 +/// ``` +/// +/// ```gleam +/// > length([1]) +/// 1 +/// ``` +/// +/// ```gleam +/// > length([1, 2]) +/// 2 +/// ``` +/// +pub fn length(of list: List(a)) -> Int { + do_length(list) +} + +@target(erlang) +@external(erlang, "erlang", "length") +fn do_length(a: List(a)) -> Int + +@target(javascript) +fn do_length(list: List(a)) -> Int { + do_length_acc(list, 0) +} + +@target(javascript) +fn do_length_acc(list: List(a), count: Int) -> Int { + case list { + [_, ..list] -> do_length_acc(list, count + 1) + _ -> count + } +} + +/// Creates a new list from a given list containing the same elements but in the +/// opposite order. +/// +/// This function has to traverse the list to create the new reversed list, so +/// it runs in linear time. +/// +/// This function is natively implemented by the virtual machine and is highly +/// optimised. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse([]) +/// [] +/// ``` +/// +/// ```gleam +/// > reverse([1]) +/// [1] +/// ``` +/// +/// ```gleam +/// > reverse([1, 2]) +/// [2, 1] +/// ``` +/// +pub fn reverse(xs: List(a)) -> List(a) { + do_reverse(xs) +} + +@target(erlang) +@external(erlang, "lists", "reverse") +fn do_reverse(a: List(a)) -> List(a) + +@target(javascript) +fn do_reverse(list) { + do_reverse_acc(list, []) +} + +@target(javascript) +fn do_reverse_acc(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) + } +} + +/// Determines whether or not the list is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty([]) +/// True +/// ``` +/// +/// ```gleam +/// > is_empty([1]) +/// False +/// ``` +/// +/// ```gleam +/// > is_empty([1, 1]) +/// False +/// ``` +/// +pub fn is_empty(list: List(a)) -> Bool { + list == [] +} + +/// Determines whether or not a given element exists within a given list. +/// +/// This function traverses the list to find the element, so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [0] |> contains(any: 0) +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 1] |> contains(any: 0) +/// False +/// ``` +/// +/// ```gleam +/// > [1, 0] |> contains(any: 0) +/// True +/// ``` +/// +pub fn contains(list: List(a), any elem: a) -> Bool { + case list { + [] -> False + [first, ..] if first == elem -> True + [_, ..rest] -> contains(rest, elem) + } +} + +/// Gets the first element from the start of the list, if there is one. +/// +/// ## Examples +/// +/// ```gleam +/// > first([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first([0]) +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > first([1, 2]) +/// Ok(1) +/// ``` +/// +pub fn first(list: List(a)) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [x, ..] -> Ok(x) + } +} + +/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is +/// returned. +/// +/// This function runs in constant time and does not make a copy of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > rest([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > rest([0]) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > rest([1, 2]) +/// Ok([2]) +/// ``` +/// +pub fn rest(list: List(a)) -> Result(List(a), Nil) { + case list { + [] -> Error(Nil) + [_, ..xs] -> Ok(xs) + } +} + +fn update_group( + f: fn(element) -> key, +) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { + fn(groups, elem) { + case dict.get(groups, f(elem)) { + Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) + Error(_) -> dict.insert(groups, f(elem), [elem]) + } + } +} + +/// Takes a list and groups the values by a key +/// which is built from a key function. +/// +/// Does not preserve the initial value order. +/// +/// ## Examples +/// +/// ```gleam +/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] +/// |> group(by: fn(i) { +/// case i { +/// Ok(_) -> "Successful" +/// Error(_) -> "Failed" +/// } +/// }) +/// |> dict.to_list +/// +/// [ +/// #("Failed", [Error("Wrong")]), +/// #("Successful", [Ok(73), Ok(200), Ok(3)]) +/// ] +/// +/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) +/// |> dict.to_list +/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] +/// ``` +/// +pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { + fold(list, dict.new(), update_group(key)) +} + +fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + True -> [x, ..acc] + False -> acc + } + do_filter(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) +/// [4, 6] +/// ``` +/// +/// ```gleam +/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) +/// [] +/// ``` +/// +pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { + do_filter(list, predicate, []) +} + +fn do_filter_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let new_acc = case fun(x) { + Ok(x) -> [x, ..acc] + Error(_) -> acc + } + do_filter_map(xs, fun, new_acc) + } + } +} + +/// Returns a new list containing only the elements from the first list for +/// which the given functions returns `Ok(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], Error) +/// [] +/// ``` +/// +/// ```gleam +/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) +/// [3, 5, 7, 2] +/// ``` +/// +pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { + do_filter_map(list, fun, []) +} + +fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one. +/// +/// ## Examples +/// +/// ```gleam +/// > map([2, 4, 6], fn(x) { x * 2 }) +/// [4, 8, 12] +/// ``` +/// +pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { + do_map(list, fun, []) +} + +/// Combines two lists into a single list using the given function. +/// +/// If a list is longer than the other the extra elements are dropped. +/// +/// ## Examples +/// +/// ```gleam +/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) +/// [5, 7, 9] +/// ``` +/// +/// ```gleam +/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) +/// [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { + do_map2(list1, list2, fun, []) +} + +fn do_map2( + list1: List(a), + list2: List(b), + fun: fn(a, b) -> c, + acc: List(c), +) -> List(c) { + case list1, list2 { + [], _ | _, [] -> reverse(acc) + [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) + } +} + +/// Similar to `map` but also lets you pass around an accumulated value. +/// +/// ## Examples +/// +/// ```gleam +/// > map_fold( +/// over: [1, 2, 3], +/// from: 100, +/// with: fn(memo, i) { #(memo + i, i * 2) } +/// ) +/// #(106, [2, 4, 6]) +/// ``` +/// +pub fn map_fold( + over list: List(a), + from acc: acc, + with fun: fn(acc, a) -> #(acc, b), +) -> #(acc, List(b)) { + fold( + over: list, + from: #(acc, []), + with: fn(acc, item) { + let #(current_acc, items) = acc + let #(next_acc, next_item) = fun(current_acc, item) + #(next_acc, [next_item, ..items]) + }, + ) + |> pair.map_second(reverse) +} + +fn do_index_map( + list: List(a), + fun: fn(Int, a) -> b, + index: Int, + acc: List(b), +) -> List(b) { + case list { + [] -> reverse(acc) + [x, ..xs] -> { + let acc = [fun(index, x), ..acc] + do_index_map(xs, fun, index + 1, acc) + } + } +} + +/// Returns a new list containing only the elements of the first list after the +/// function has been applied to each one and their index. +/// +/// The index starts at 0, so the first element is 0, the second is 1, and so +/// on. +/// +/// ## Examples +/// +/// ```gleam +/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) +/// [#(0, "a"), #(1, "b")] +/// ``` +/// +pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { + do_index_map(list, fun, 0, []) +} + +fn do_try_map( + list: List(a), + fun: fn(a) -> Result(b, e), + acc: List(b), +) -> Result(List(b), e) { + case list { + [] -> Ok(reverse(acc)) + [x, ..xs] -> + case fun(x) { + Ok(y) -> do_try_map(xs, fun, [y, ..acc]) + Error(error) -> Error(error) + } + } +} + +/// Takes a function that returns a `Result` and applies it to each element in a +/// given list in turn. +/// +/// If the function returns `Ok(new_value)` for all elements in the list then a +/// list of the new values is returned. +/// +/// If the function returns `Error(reason)` for any of the elements then it is +/// returned immediately. None of the elements in the list are processed after +/// one returns an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) +/// Ok([3, 4, 5]) +/// ``` +/// +/// ```gleam +/// > try_map([1, 2, 3], fn(_) { Error(0) }) +/// Error(0) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [2, 3]], first) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > try_map([[1], [], [2]], first) +/// Error(Nil) +/// ``` +/// +pub fn try_map( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(List(b), e) { + do_try_map(list, fun, []) +} + +/// Returns a list that is the given list with up to the given number of +/// elements removed from the front of the list. +/// +/// If the element has less than the number of elements an empty list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 2) +/// [3, 4] +/// ``` +/// +/// ```gleam +/// > drop([1, 2, 3, 4], 9) +/// [] +/// ``` +/// +pub fn drop(from list: List(a), up_to n: Int) -> List(a) { + case n <= 0 { + True -> list + False -> + case list { + [] -> [] + [_, ..xs] -> drop(xs, n - 1) + } + } +} + +fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { + case n <= 0 { + True -> reverse(acc) + False -> + case list { + [] -> reverse(acc) + [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) + } + } +} + +/// Returns a list containing the first given number of elements from the given +/// list. +/// +/// If the element has less than the number of elements then the full list is +/// returned. +/// +/// This function runs in linear time but does not copy the list. +/// +/// ## Examples +/// +/// ```gleam +/// > take([1, 2, 3, 4], 2) +/// [1, 2] +/// ``` +/// +/// ```gleam +/// > take([1, 2, 3, 4], 9) +/// [1, 2, 3, 4] +/// ``` +/// +pub fn take(from list: List(a), up_to n: Int) -> List(a) { + do_take(list, n, []) +} + +/// Returns a new empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// [] +/// ``` +/// +pub fn new() -> List(a) { + [] +} + +/// Joins one list onto the end of another. +/// +/// This function runs in linear time, and it traverses and copies the first +/// list. +/// +/// ## Examples +/// +/// ```gleam +/// > append([1, 2], [3]) +/// [1, 2, 3] +/// ``` +/// +pub fn append(first: List(a), second: List(a)) -> List(a) { + do_append(first, second) +} + +@target(erlang) +@external(erlang, "lists", "append") +fn do_append(a: List(a), b: List(a)) -> List(a) + +@target(javascript) +fn do_append(first: List(a), second: List(a)) -> List(a) { + do_append_acc(reverse(first), second) +} + +@target(javascript) +fn do_append_acc(first: List(a), second: List(a)) -> List(a) { + case first { + [] -> second + [item, ..rest] -> do_append_acc(rest, [item, ..second]) + } +} + +/// Prefixes an item to a list. This can also be done using the dedicated +/// syntax instead +/// +/// ```gleam +/// let new_list = [1, ..existing_list] +/// ``` +/// +pub fn prepend(to list: List(a), this item: a) -> List(a) { + [item, ..list] +} + +// Reverses a list and prepends it to another list +fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { + case prefix { + [] -> suffix + [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) + } +} + +fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { + case lists { + [] -> reverse(acc) + [list, ..further_lists] -> + do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) + } +} + +/// Joins a list of lists into a single list. +/// +/// This function traverses all elements twice. +/// +/// ## Examples +/// +/// ```gleam +/// > concat([[1], [2, 3], []]) +/// [1, 2, 3] +/// ``` +/// +pub fn concat(lists: List(List(a))) -> List(a) { + do_concat(lists, []) +} + +/// This is the same as `concat`: it joins a list of lists into a single +/// list. +/// +/// This function traverses all elements twice. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten([[1], [2, 3], []]) +/// [1, 2, 3] +/// ``` +/// +pub fn flatten(lists: List(List(a))) -> List(a) { + do_concat(lists, []) +} + +/// Maps the list with the given function into a list of lists, and then flattens it. +/// +/// ## Examples +/// +/// ```gleam +/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) +/// [2, 3, 4, 5, 6, 7] +/// ``` +/// +pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { + map(list, fun) + |> concat +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from left to right. +/// +/// `fold([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 1), 2), 3)`. +/// +/// This function runs in linear time. +/// +pub fn fold( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fold(rest, fun(initial, x), fun) + } +} + +/// Reduces a list of elements into a single value by calling a given function +/// on each element, going from right to left. +/// +/// `fold_right([1, 2, 3], 0, add)` is the equivalent of +/// `add(add(add(0, 3), 2), 1)`. +/// +/// This function runs in linear time. +/// +/// Unlike `fold` this function is not tail recursive. Where possible use +/// `fold` instead as it will use less memory. +/// +pub fn fold_right( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> acc { + case list { + [] -> initial + [x, ..rest] -> fun(fold_right(rest, initial, fun), x) + } +} + +fn do_index_fold( + over: List(a), + acc: acc, + with: fn(acc, a, Int) -> acc, + index: Int, +) -> acc { + case over { + [] -> acc + [first, ..rest] -> + do_index_fold(rest, with(acc, first, index), with, index + 1) + } +} + +/// Like fold but the folding function also receives the index of the current element. +/// +/// ## Examples +/// +/// ```gleam +/// ["a", "b", "c"] +/// |> index_fold([], fn(acc, item, index) { ... }) +/// ``` +/// +pub fn index_fold( + over over: List(a), + from initial: acc, + with fun: fn(acc, a, Int) -> acc, +) -> acc { + do_index_fold(over, initial, fun, 0) +} + +/// A variant of fold that might fail. +/// +/// The folding function should return `Result(accumulator, error)`. +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. +/// If the returned value is `Error(error)` try_fold will stop and return that error. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> try_fold(0, fn(acc, i) { +/// case i < 3 { +/// True -> Ok(acc + i) +/// False -> Error(Nil) +/// } +/// }) +/// ``` +/// +pub fn try_fold( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> Result(acc, e), +) -> Result(acc, e) { + case collection { + [] -> Ok(accumulator) + [first, ..rest] -> + case fun(accumulator, first) { + Ok(result) -> try_fold(rest, result, fun) + Error(_) as error -> error + } + } +} + +pub type ContinueOrStop(a) { + Continue(a) + Stop(a) +} + +/// A variant of fold that allows to stop folding earlier. +/// +/// The folding function should return `ContinueOrStop(accumulator)`. +/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. +/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. +/// +/// ## Examples +/// +/// ```gleam +/// [1, 2, 3, 4] +/// |> fold_until(0, fn(acc, i) { +/// case i < 3 { +/// True -> Continue(acc + i) +/// False -> Stop(acc) +/// } +/// }) +/// ``` +/// +pub fn fold_until( + over collection: List(a), + from accumulator: acc, + with fun: fn(acc, a) -> ContinueOrStop(acc), +) -> acc { + case collection { + [] -> accumulator + [first, ..rest] -> + case fun(accumulator, first) { + Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) + Stop(b) -> b + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 2 }) +/// Ok(3) +/// ``` +/// +/// ```gleam +/// > find([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn find( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(a, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case is_desired(x) { + True -> Ok(x) + _ -> find(in: rest, one_that: is_desired) + } + } +} + +/// Finds the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > find_map([[], [2], [3]], first) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > find_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > find_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn find_map( + in haystack: List(a), + with fun: fn(a) -> Result(b, c), +) -> Result(b, Nil) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case fun(x) { + Ok(x) -> Ok(x) + _ -> find_map(in: rest, with: fun) + } + } +} + +/// Returns `True` if the given function returns `True` for all the elements in +/// the given list. If the function returns `False` for any of the elements it +/// immediately returns `False` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > all([], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > all([4, 3], fn(x) { x > 3 }) +/// False +/// ``` +/// +pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> True + [first, ..rest] -> + case predicate(first) { + True -> all(rest, predicate) + False -> False + } + } +} + +/// Returns `True` if the given function returns `True` for any the elements in +/// the given list. If the function returns `True` for any of the elements it +/// immediately returns `True` without checking the rest of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > any([], fn(x) { x > 3 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([4, 5], fn(x) { x > 3 }) +/// True +/// ``` +/// +/// ```gleam +/// > any([4, 3], fn(x) { x > 4 }) +/// False +/// ``` +/// +/// ```gleam +/// > any([3, 4], fn(x) { x > 3 }) +/// True +/// ``` +/// +pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { + case list { + [] -> False + [first, ..rest] -> + case predicate(first) { + True -> True + False -> any(rest, predicate) + } + } +} + +fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { + case xs, ys { + [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) + _, _ -> reverse(acc) + } +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, the remaining elements from +/// the longer list are not used. +/// +/// ## Examples +/// +/// ```gleam +/// > zip([], []) +/// [] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1], [3, 4]) +/// [#(1, 3)] +/// ``` +/// +/// ```gleam +/// > zip([1, 2], [3, 4]) +/// [#(1, 3), #(2, 4)] +/// ``` +/// +pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { + do_zip(list, other, []) +} + +/// Takes two lists and returns a single list of 2-element tuples. +/// +/// If one of the lists is longer than the other, an `Error` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > strict_zip([], []) +/// Ok([]) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1], [3, 4]) +/// Error(LengthMismatch) +/// ``` +/// +/// ```gleam +/// > strict_zip([1, 2], [3, 4]) +/// Ok([#(1, 3), #(2, 4)]) +/// ``` +/// +pub fn strict_zip( + list: List(a), + with other: List(b), +) -> Result(List(#(a, b)), LengthMismatch) { + case length(of: list) == length(of: other) { + True -> Ok(zip(list, other)) + False -> Error(LengthMismatch) + } +} + +fn do_unzip(input, xs, ys) { + case input { + [] -> #(reverse(xs), reverse(ys)) + [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) + } +} + +/// Takes a single list of 2-element tuples and returns two lists. +/// +/// ## Examples +/// +/// ```gleam +/// > unzip([#(1, 2), #(3, 4)]) +/// #([1, 3], [2, 4]) +/// ``` +/// +/// ```gleam +/// > unzip([]) +/// #([], []) +/// ``` +/// +pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { + do_unzip(input, [], []) +} + +fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { + case list { + [] -> reverse(acc) + [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) + } +} + +/// Inserts a given value between each existing element in a given list. +/// +/// This function runs in linear time and copies the list. +/// +/// ## Examples +/// +/// ```gleam +/// > intersperse([1, 1, 1], 2) +/// [1, 2, 1, 2, 1] +/// ``` +/// +/// ```gleam +/// > intersperse([], 2) +/// [] +/// ``` +/// +pub fn intersperse(list: List(a), with elem: a) -> List(a) { + case list { + [] | [_] -> list + [x, ..rest] -> do_intersperse(rest, elem, [x]) + } +} + +/// Returns the element in the Nth position in the list, with 0 being the first +/// position. +/// +/// `Error(Nil)` is returned if the list is not long enough for the given index +/// or if the index is less than 0. +/// +/// ## Examples +/// +/// ```gleam +/// > at([1, 2, 3], 1) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > at([1, 2, 3], 5) +/// Error(Nil) +/// ``` +/// +pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { + case index >= 0 { + True -> + list + |> drop(index) + |> first + False -> Error(Nil) + } +} + +/// Removes any duplicate elements from a given list. +/// +/// This function returns in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) +/// [1, 4, 7, 3] +/// ``` +/// +pub fn unique(list: List(a)) -> List(a) { + case list { + [] -> [] + [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] + } +} + +/// Merge lists `a` and `b` in ascending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_up( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(ax, bx) { + order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) + _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) + } + _, _, _, _ -> acc + } +} + +/// Merge lists `a` and `b` in descending order +/// but only up to `na` and `nb` number of items respectively. +/// +fn merge_down( + na: Int, + nb: Int, + a: List(a), + b: List(a), + acc: List(a), + compare: fn(a, a) -> Order, +) { + case na, nb, a, b { + 0, 0, _, _ -> acc + _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + _, _, [ax, ..ar], [bx, ..br] -> + case compare(bx, ax) { + order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) + _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) + } + _, _, _, _ -> acc + } +} + +/// Merge sort that alternates merging in ascending and descending order +/// because the merge process also reverses the list. +/// +/// Some copying is avoided by merging only a subset of the lists +/// instead of creating and merging new smaller lists. +/// +fn merge_sort( + l: List(a), + ln: Int, + compare: fn(a, a) -> Order, + down: Bool, +) -> List(a) { + let n = ln / 2 + let a = l + let b = drop(l, n) + case ln < 3 { + True -> + case down { + True -> merge_down(n, ln - n, a, b, [], compare) + False -> merge_up(n, ln - n, a, b, [], compare) + } + False -> + case down { + True -> + merge_down( + n, + ln - n, + merge_sort(a, n, compare, False), + merge_sort(b, ln - n, compare, False), + [], + compare, + ) + False -> + merge_up( + n, + ln - n, + merge_sort(a, n, compare, True), + merge_sort(b, ln - n, compare, True), + [], + compare, + ) + } + } +} + +/// Sorts from smallest to largest based upon the ordering specified by a given +/// function. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) +/// [1, 2, 3, 4, 4, 5, 6] +/// ``` +/// +pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { + merge_sort(list, length(list), compare, True) +} + +/// Creates a list of ints ranging from a given start and finish. +/// +/// ## Examples +/// +/// ```gleam +/// > range(0, 0) +/// [0] +/// ``` +/// +/// ```gleam +/// > range(0, 5) +/// [0, 1, 2, 3, 4, 5] +/// ``` +/// +/// ```gleam +/// > range(1, -5) +/// [1, 0, -1, -2, -3, -4, -5] +/// ``` +/// +pub fn range(from start: Int, to stop: Int) -> List(Int) { + tail_recursive_range(start, stop, []) +} + +fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { + case int.compare(start, stop) { + order.Eq -> [stop, ..acc] + order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) + order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) + } +} + +fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { + case times <= 0 { + True -> acc + False -> do_repeat(a, times - 1, [a, ..acc]) + } +} + +/// Builds a list of a given value a given number of times. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("a", times: 0) +/// [] +/// ``` +/// +/// ```gleam +/// > repeat("a", times: 5) +/// ["a", "a", "a", "a", "a"] +/// ``` +/// +pub fn repeat(item a: a, times times: Int) -> List(a) { + do_repeat(a, times, []) +} + +fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { + case n <= 0 { + True -> #(reverse(taken), list) + False -> + case list { + [] -> #(reverse(taken), []) + [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) + } + } +} + +/// Splits a list in two before the given index. +/// +/// If the list is not long enough to have the given index the before list will +/// be the input list, and the after list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split([6, 7, 8, 9], 0) +/// #([], [6, 7, 8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 2) +/// #([6, 7], [8, 9]) +/// ``` +/// +/// ```gleam +/// > split([6, 7, 8, 9], 4) +/// #([6, 7, 8, 9], []) +/// ``` +/// +pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { + do_split(list, index, []) +} + +fn do_split_while( + list: List(a), + f: fn(a) -> Bool, + acc: List(a), +) -> #(List(a), List(a)) { + case list { + [] -> #(reverse(acc), []) + [x, ..xs] -> + case f(x) { + False -> #(reverse(acc), list) + _ -> do_split_while(xs, f, [x, ..acc]) + } + } +} + +/// Splits a list in two before the first element that a given function returns +/// `False` for. +/// +/// If the function returns `True` for all elements the first list will be the +/// input list, and the second list will be empty. +/// +/// ## Examples +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) +/// #([1, 2, 3], [4, 5]) +/// ``` +/// +/// ```gleam +/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) +/// #([1, 2, 3, 4, 5], []) +/// ``` +/// +pub fn split_while( + list list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_split_while(list, predicate, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element and returns the second element. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// This function may be useful for interacting with Erlang code where lists of +/// tuples are common. +/// +/// ## Examples +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "a") +/// Ok(0) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "b") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > key_find([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_find( + in keyword_list: List(#(k, v)), + find desired_key: k, +) -> Result(v, Nil) { + find_map( + keyword_list, + fn(keyword) { + let #(key, value) = keyword + case key == desired_key { + True -> Ok(value) + False -> Error(Nil) + } + }, + ) +} + +/// Given a list of 2-element tuples, finds all tuples that have a given +/// key as the first element and returns the second element. +/// +/// This function may be useful for interacting with Erlang code where lists of +/// tuples are common. +/// +/// ## Examples +/// +/// ```gleam +/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") +/// [0, 2] +/// ``` +/// +/// ```gleam +/// > key_filter([#("a", 0), #("b", 1)], "c") +/// [] +/// ``` +/// +pub fn key_filter( + in keyword_list: List(#(k, v)), + find desired_key: k, +) -> List(v) { + filter_map( + keyword_list, + fn(keyword) { + let #(key, value) = keyword + case key == desired_key { + True -> Ok(value) + False -> Error(Nil) + } + }, + ) +} + +fn do_pop(haystack, predicate, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case predicate(x) { + True -> Ok(#(x, append(reverse(checked), rest))) + False -> do_pop(rest, predicate, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the predicate function returns `True`. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 2 }) +/// Ok(#(3, [1, 2])) +/// ``` +/// +/// ```gleam +/// > pop([1, 2, 3], fn(x) { x > 4 }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop([], fn(_) { True }) +/// Error(Nil) +/// ``` +/// +pub fn pop( + in haystack: List(a), + one_that is_desired: fn(a) -> Bool, +) -> Result(#(a, List(a)), Nil) { + do_pop(haystack, is_desired, []) +} + +fn do_pop_map(haystack, mapper, checked) { + case haystack { + [] -> Error(Nil) + [x, ..rest] -> + case mapper(x) { + Ok(y) -> Ok(#(y, append(reverse(checked), rest))) + Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) + } + } +} + +/// Removes the first element in a given list for which the given function returns +/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. +/// +/// Returns `Error(Nil)` if no such element is found. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_map([[], [2], [3]], first) +/// Ok(#(2, [[], [3]])) +/// ``` +/// +/// ```gleam +/// > pop_map([[], []], first) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > pop_map([], first) +/// Error(Nil) +/// ``` +/// +pub fn pop_map( + in haystack: List(a), + one_that is_desired: fn(a) -> Result(b, c), +) -> Result(#(b, List(a)), Nil) { + do_pop_map(haystack, is_desired, []) +} + +/// Given a list of 2-element tuples, finds the first tuple that has a given +/// key as the first element. This function will return the second element +/// of the found tuple and list with tuple removed. +/// +/// If no tuple is found with the given key then `Error(Nil)` is returned. +/// +/// ## Examples +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "a") +/// Ok(#(0, [#("b", 1)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "b") +/// Ok(#(1, [#("a", 0)])) +/// ``` +/// +/// ```gleam +/// > key_pop([#("a", 0), #("b", 1)], "c") +/// Error(Nil) +/// ``` +/// +pub fn key_pop( + haystack: List(#(k, v)), + key: k, +) -> Result(#(v, List(#(k, v))), Nil) { + pop_map( + haystack, + fn(entry) { + let #(k, v) = entry + case k { + k if k == key -> Ok(v) + _ -> Error(Nil) + } + }, + ) +} + +/// Given a list of 2-element tuples, inserts a key and value into the list. +/// +/// If there was already a tuple with the key then it is replaced, otherwise it +/// is added to the end of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 4, 100) +/// [#(5, 0), #(4, 100)] +/// ``` +/// +/// ```gleam +/// > key_set([#(5, 0), #(4, 1)], 1, 100) +/// [#(5, 0), #(4, 1), #(1, 100)] +/// ``` +/// +pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { + case list { + [] -> [#(key, value)] + [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] + [first, ..rest] -> [first, ..key_set(rest, key, value)] + } +} + +/// Calls a function for each element in a list, discarding the return value. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ```gleam +/// > list.each([1, 2, 3], io.println) +/// Nil +/// ``` +/// +pub fn each(list: List(a), f: fn(a) -> b) -> Nil { + case list { + [] -> Nil + [x, ..xs] -> { + f(x) + each(xs, f) + } + } +} + +/// Calls a `Result` returning function for each element in a list, discarding +/// the return value. If the function returns `Error` then the iteration is +/// stopped and the error is returned. +/// +/// Useful for calling a side effect for every item of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > try_each( +/// > over: [1, 2, 3], +/// > with: function_that_might_fail, +/// > ) +/// Ok(Nil) +/// ``` +/// +pub fn try_each( + over list: List(a), + with fun: fn(a) -> Result(b, e), +) -> Result(Nil, e) { + case list { + [] -> Ok(Nil) + [x, ..xs] -> + case fun(x) { + Ok(_) -> try_each(over: xs, with: fun) + Error(e) -> Error(e) + } + } +} + +fn do_partition(list, categorise, trues, falses) { + case list { + [] -> #(reverse(trues), reverse(falses)) + [x, ..xs] -> + case categorise(x) { + True -> do_partition(xs, categorise, [x, ..trues], falses) + False -> do_partition(xs, categorise, trues, [x, ..falses]) + } + } +} + +/// Partitions a list into a tuple/pair of lists +/// by a given categorisation function. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) +/// #([1, 3, 5], [2, 4]) +/// ``` +/// +pub fn partition( + list: List(a), + with categorise: fn(a) -> Bool, +) -> #(List(a), List(a)) { + do_partition(list, categorise, [], []) +} + +/// Returns all the permutations of a list. +/// +/// ## Examples +/// +/// ```gleam +/// > permutations([1, 2]) +/// [[1, 2], [2, 1]] +/// ``` +/// +pub fn permutations(l: List(a)) -> List(List(a)) { + case l { + [] -> [[]] + _ -> + l + |> index_map(fn(i_idx, i) { + l + |> index_fold( + [], + fn(acc, j, j_idx) { + case i_idx == j_idx { + True -> acc + False -> [j, ..acc] + } + }, + ) + |> reverse + |> permutations + |> map(fn(permutation) { [i, ..permutation] }) + }) + |> concat + } +} + +fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { + let window = take(l, n) + + case length(window) == n { + True -> do_window([window, ..acc], drop(l, 1), n) + False -> acc + } +} + +/// Returns a list of sliding windows. +/// +/// ## Examples +/// +/// ```gleam +/// > window([1,2,3,4,5], 3) +/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] +/// ``` +/// +/// ```gleam +/// > window([1, 2], 4) +/// [] +/// ``` +/// +pub fn window(l: List(a), by n: Int) -> List(List(a)) { + do_window([], l, n) + |> reverse +} + +/// Returns a list of tuples containing two contiguous elements. +/// +/// ## Examples +/// +/// ```gleam +/// > window_by_2([1,2,3,4]) +/// [#(1, 2), #(2, 3), #(3, 4)] +/// ``` +/// +/// ```gleam +/// > window_by_2([1]) +/// [] +/// ``` +/// +pub fn window_by_2(l: List(a)) -> List(#(a, a)) { + zip(l, drop(l, 1)) +} + +/// Drops the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) +/// [3, 4] +/// ``` +/// +pub fn drop_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + case list { + [] -> [] + [x, ..xs] -> + case predicate(x) { + True -> drop_while(xs, predicate) + False -> [x, ..xs] + } + } +} + +fn do_take_while( + list: List(a), + predicate: fn(a) -> Bool, + acc: List(a), +) -> List(a) { + case list { + [] -> reverse(acc) + [first, ..rest] -> + case predicate(first) { + True -> do_take_while(rest, predicate, [first, ..acc]) + False -> reverse(acc) + } + } +} + +/// Takes the first elements in a given list for which the predicate function returns `True`. +/// +/// ## Examples +/// +/// ```gleam +/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) +/// [1, 2] +/// ``` +/// +pub fn take_while( + in list: List(a), + satisfying predicate: fn(a) -> Bool, +) -> List(a) { + do_take_while(list, predicate, []) +} + +fn do_chunk( + list: List(a), + f: fn(a) -> key, + previous_key: key, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [first, ..rest] -> { + let key = f(first) + case key == previous_key { + False -> { + let new_acc = [reverse(current_chunk), ..acc] + do_chunk(rest, f, key, [first], new_acc) + } + _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) + } + } + _empty -> reverse([reverse(current_chunk), ..acc]) + } +} + +/// Returns a list of chunks in which +/// the return value of calling `f` on each element is the same. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) +/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] +/// ``` +/// +pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { + case list { + [] -> [] + [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) + } +} + +fn do_sized_chunk( + list: List(a), + count: Int, + left: Int, + current_chunk: List(a), + acc: List(List(a)), +) -> List(List(a)) { + case list { + [] -> + case current_chunk { + [] -> reverse(acc) + remaining -> reverse([reverse(remaining), ..acc]) + } + [first, ..rest] -> { + let chunk = [first, ..current_chunk] + case left > 1 { + False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) + True -> do_sized_chunk(rest, count, left - 1, chunk, acc) + } + } + } +} + +/// Returns a list of chunks containing `count` elements each. +/// +/// If the last chunk does not have `count` elements, it is instead +/// a partial chunk, with less than `count` elements. +/// +/// For any `count` less than 1 this function behaves as if it was set to 1. +/// +/// ## Examples +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) +/// [[1, 2], [3, 4], [5, 6]] +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) +/// [[1, 2, 3], [4, 5, 6], [7, 8]] +/// ``` +/// +pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { + do_sized_chunk(list, count, count, [], []) +} + +/// This function acts similar to fold, but does not take an initial state. +/// Instead, it starts from the first element in the list +/// and combines it with each subsequent element in turn using the given +/// function. The function is called as `fun(accumulator, current_element)`. +/// +/// Returns `Ok` to indicate a successful run, and `Error` if called on an +/// empty list. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> reduce(fn(acc, x) { acc + x }) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) +/// Ok(15) +/// ``` +/// +pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { + case list { + [] -> Error(Nil) + [first, ..rest] -> Ok(fold(rest, first, fun)) + } +} + +fn do_scan( + list: List(a), + accumulator: acc, + accumulated: List(acc), + fun: fn(acc, a) -> acc, +) -> List(acc) { + case list { + [] -> reverse(accumulated) + [x, ..xs] -> { + let next = fun(accumulator, x) + do_scan(xs, next, [next, ..accumulated], fun) + } + } +} + +/// Similar to `fold`, but yields the state of the accumulator at each stage. +/// +/// ## Examples +/// +/// ```gleam +/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) +/// [101, 103, 106] +/// ``` +/// +pub fn scan( + over list: List(a), + from initial: acc, + with fun: fn(acc, a) -> acc, +) -> List(acc) { + do_scan(list, initial, [], fun) +} + +/// Returns the last element in the given list. +/// +/// Returns `Error(Nil)` if the list is empty. +/// +/// This function runs in linear time. +/// For a collection oriented around performant access at either end, +/// see `gleam/queue.Queue`. +/// +/// ## Examples +/// +/// ```gleam +/// > last([]) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last([1, 2, 3, 4, 5]) +/// Ok(5) +/// ``` +/// +pub fn last(list: List(a)) -> Result(a, Nil) { + list + |> reduce(fn(_, elem) { elem }) +} + +/// Return unique combinations of elements in the list. +/// +/// ## Examples +/// +/// ```gleam +/// > combinations([1, 2, 3], 2) +/// [[1, 2], [1, 3], [2, 3]] +/// ``` +/// +/// ```gleam +/// > combinations([1, 2, 3, 4], 3) +/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] +/// ``` +/// +pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { + case n { + 0 -> [[]] + _ -> + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = + map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) + |> reverse + fold( + first_combinations, + combinations(xs, n), + fn(acc, c) { [c, ..acc] }, + ) + } + } + } +} + +fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { + case items { + [] -> [] + [x, ..xs] -> { + let first_combinations = map(xs, with: fn(other) { #(x, other) }) + [first_combinations, ..do_combination_pairs(xs)] + } + } +} + +/// Return unique pair combinations of elements in the list +/// +/// ## Examples +/// +/// ```gleam +/// > combination_pairs([1, 2, 3]) +/// [#(1, 2), #(1, 3), #(2, 3)] +/// ``` +/// +pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { + do_combination_pairs(items) + |> concat +} + +/// Make a list alternating the elements from the given lists +/// +/// ## Examples +/// +/// ```gleam +/// > list.interleave([[1, 2], [101, 102], [201, 202]]) +/// [1, 101, 201, 2, 102, 202] +/// ``` +/// +pub fn interleave(list: List(List(a))) -> List(a) { + transpose(list) + |> concat +} + +/// Transpose rows and columns of the list of lists. +/// +/// Notice: This function is not tail recursive, +/// and thus may exceed stack size if called, +/// with large lists (on target JavaScript). +/// +/// ## Examples +/// +/// ```gleam +/// > transpose([[1, 2, 3], [101, 102, 103]]) +/// [[1, 101], [2, 102], [3, 103]] +/// ``` +/// +pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { + let take_first = fn(list) { + case list { + [] -> [] + [f] -> [f] + [f, ..] -> [f] + } + } + + case list_of_list { + [] -> [] + [[], ..xss] -> transpose(xss) + rows -> { + let firsts = + rows + |> map(take_first) + |> concat + let rest = transpose(map(rows, drop(_, 1))) + [firsts, ..rest] + } + } +} + +fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + [elem_pair, ..enumerable] -> + do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) + } +} + +fn do_shuffle_by_pair_indexes( + list_of_pairs: List(#(Float, a)), +) -> List(#(Float, a)) { + sort( + list_of_pairs, + fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { + float.compare(a_pair.0, b_pair.0) + }, + ) +} + +/// Takes a list, randomly sorts all items and returns the shuffled list. +/// +/// This function uses Erlang's `:rand` module or Javascript's +/// `Math.random()` to calculate the index shuffling. +/// +/// ## Example +/// +/// ```gleam +/// > range(1, 10) +/// > |> shuffle() +/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] +/// ``` +/// +pub fn shuffle(list: List(a)) -> List(a) { + list + |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) + |> do_shuffle_by_pair_indexes() + |> do_shuffle_pair_unwrap([]) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam new file mode 100644 index 00000000000..1f8b228eb90 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/map.gleam @@ -0,0 +1,127 @@ +import gleam/option.{type Option} +import gleam/dict + +@deprecated("Please use the `gleam/dict` module instead") +pub type Map(key, value) = + dict.Dict(key, value) + +@deprecated("Please use the `gleam/dict` module instead") +pub fn size(map) -> Int { + dict.size(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn to_list(map) -> List(#(key, value)) { + dict.to_list(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn from_list(list: List(#(k, v))) { + dict.from_list(list) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn has_key(map, key: k) -> Bool { + dict.has_key(map, key) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn new() { + dict.new() +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn get(from, get: key) -> Result(value, Nil) { + dict.get(from, get) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn insert(into map, for key: k, insert value: v) { + dict.insert(map, key, value) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn map_values(in map, with fun: fn(k, v) -> w) { + dict.map_values(map, fun) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn keys(map) -> List(keys) { + dict.keys(map) +} + +@target(javascript) +fn reverse_and_concat(remaining, accumulator) { + case remaining { + [] -> accumulator + [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) + } +} + +@target(javascript) +fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { + case list { + [] -> reverse_and_concat(acc, []) + [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) + } +} + +@target(javascript) +fn do_keys(map) -> List(k) { + let list_of_pairs = + map + |> to_list + do_keys_acc(list_of_pairs, []) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn values(map) -> List(values) { + dict.values(map) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { + dict.filter(map, predicate) +} + +@target(javascript) +fn do_filter(f: fn(key, value) -> Bool, map) { + let insert = fn(map, k, v) { + case f(k, v) { + True -> insert(map, k, v) + _ -> map + } + } + map + |> fold(from: new(), with: insert) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn take(from map, keeping desired_keys: List(k)) { + dict.take(map, desired_keys) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn merge(into map, from new_entries) { + dict.merge(map, new_entries) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn delete(from map, delete key: k) { + dict.delete(map, key) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn drop(from map, drop disallowed_keys: List(k)) { + dict.drop(map, disallowed_keys) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { + dict.update(map, key, fun) +} + +@deprecated("Please use the `gleam/dict` module instead") +pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { + dict.fold(map, initial, fun) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam new file mode 100644 index 00000000000..6015c0fff8f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/option.gleam @@ -0,0 +1,346 @@ +/// `Option` represents a value that may be present or not. `Some` means the value is +/// present, `None` means the value is not. +/// +/// This is Gleam's alternative to having a value that could be Null, as is +/// possible in some other languages. +/// +pub type Option(a) { + Some(a) + None +} + +fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { + case list { + [] -> Some(acc) + [x, ..rest] -> { + let accumulate = fn(acc, item) { + case acc, item { + Some(values), Some(value) -> Some([value, ..values]) + _, _ -> None + } + } + accumulate(do_all(rest, acc), x) + } + } +} + +/// Combines a list of `Option`s into a single `Option`. +/// If all elements in the list are `Some` then returns a `Some` holding the list of values. +/// If any element is `None` then returns`None`. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Some(1), Some(2)]) +/// Some([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Some(1), None]) +/// None +/// ``` +/// +pub fn all(list: List(Option(a))) -> Option(List(a)) { + do_all(list, []) +} + +/// Checks whether the `Option` is a `Some` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_some(Some(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_some(None) +/// False +/// ``` +/// +pub fn is_some(option: Option(a)) -> Bool { + option != None +} + +/// Checks whether the `Option` is a `None` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_none(Some(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_none(None) +/// True +/// ``` +/// +pub fn is_none(option: Option(a)) -> Bool { + option == None +} + +/// Converts an `Option` type to a `Result` type. +/// +/// ## Examples +/// +/// ```gleam +/// > to_result(Some(1), "some_error") +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > to_result(None, "some_error") +/// Error("some_error") +/// ``` +/// +pub fn to_result(option: Option(a), e) -> Result(a, e) { + case option { + Some(a) -> Ok(a) + _ -> Error(e) + } +} + +/// Converts a `Result` type to an `Option` type. +/// +/// ## Examples +/// +/// ```gleam +/// > from_result(Ok(1)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > from_result(Error("some_error")) +/// None +/// ``` +/// +pub fn from_result(result: Result(a, e)) -> Option(a) { + case result { + Ok(a) -> Some(a) + _ -> None + } +} + +/// Extracts the value from an `Option`, returning a default value if there is none. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Some(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(None, 0) +/// 0 +/// ``` +/// +pub fn unwrap(option: Option(a), or default: a) -> a { + case option { + Some(x) -> x + None -> default + } +} + +/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Some(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(None, fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { + case option { + Some(x) -> x + None -> default() + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it. +/// +/// If the `Option` is a `None` rather than `Some`, the function is not called and the +/// `Option` stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Some(1), with: fn(x) { x + 1 }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > map(over: None, with: fn(x) { x + 1 }) +/// None +/// ``` +/// +pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { + case option { + Some(x) -> Some(fun(x)) + None -> None + } +} + +/// Merges a nested `Option` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Some(Some(1))) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > flatten(Some(None)) +/// None +/// ``` +/// +/// ```gleam +/// > flatten(None) +/// None +/// ``` +/// +pub fn flatten(option: Option(Option(a))) -> Option(a) { + case option { + Some(x) -> x + None -> None + } +} + +/// Updates a value held within the `Some` of an `Option` by calling a given function +/// on it, where the given function also returns an `Option`. The two options are +/// then merged together into one `Option`. +/// +/// If the `Option` is a `None` rather than `Some` the function is not called and the +/// option stays the same. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that return `Option`. +/// +/// ## Examples +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(x + 1) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(x) { Some(#("a", x)) }) +/// Some(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > then(Some(1), fn(_) { None }) +/// None +/// ``` +/// +/// ```gleam +/// > then(None, fn(x) { Some(x + 1) }) +/// None +/// ``` +/// +pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { + case option { + Some(x) -> fun(x) + None -> None + } +} + +/// Returns the first value if it is `Some`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Some(1), Some(2)) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(Some(1), None) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > or(None, Some(2)) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > or(None, None) +/// None +/// ``` +/// +pub fn or(first: Option(a), second: Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second + } +} + +/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { Some(2) }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Some(1), fn() { None }) +/// Some(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { Some(2) }) +/// Some(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(None, fn() { None }) +/// None +/// ``` +/// +pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { + case first { + Some(_) -> first + None -> second() + } +} + +fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { + case list { + [] -> acc + [x, ..xs] -> { + let accumulate = fn(acc, item) { + case item { + Some(value) -> [value, ..acc] + None -> acc + } + } + accumulate(do_values(xs, acc), x) + } + } +} + +/// Given a list of `Option`s, +/// returns only the values inside `Some`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Some(1), None, Some(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(options: List(Option(a))) -> List(a) { + do_values(options, []) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam new file mode 100644 index 00000000000..12ce01136ca --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/order.gleam @@ -0,0 +1,133 @@ +/// Represents the result of a single comparison to determine the precise +/// ordering of two values. +/// +pub type Order { + /// Less-than + Lt + + /// Equal + Eq + + /// Greater than + Gt +} + +/// Inverts an order, so less-than becomes greater-than and greater-than +/// becomes less-than. +/// +/// ## Examples +/// +/// ```gleam +/// > negate(Lt) +/// Gt +/// ``` +/// +/// ```gleam +/// > negate(Eq) +/// Eq +/// ``` +/// +/// ```gleam +/// > negate(Lt) +/// Gt +/// ``` +/// +pub fn negate(order: Order) -> Order { + case order { + Lt -> Gt + Eq -> Eq + Gt -> Lt + } +} + +/// Produces a numeric representation of the order. +/// +/// ## Examples +/// +/// ```gleam +/// > to_int(Lt) +/// -1 +/// ``` +/// +/// ```gleam +/// > to_int(Eq) +/// 0 +/// ``` +/// +/// ```gleam +/// > to_int(Gt) +/// 1 +/// ``` +/// +pub fn to_int(order: Order) -> Int { + case order { + Lt -> -1 + Eq -> 0 + Gt -> 1 + } +} + +/// Compares two `Order` values to one another, producing a new `Order`. +/// +/// ## Examples +/// +/// ```gleam +/// > compare(Eq, with: Lt) +/// Gt +/// ``` +/// +pub fn compare(a: Order, with b: Order) -> Order { + case a, b { + x, y if x == y -> Eq + Lt, _ | Eq, Gt -> Lt + _, _ -> Gt + } +} + +/// Returns the largest of two orders given that `Gt > Eq > Lt`. +/// +/// ## Examples +/// +/// ```gleam +/// > max(Eq, Lt) +/// Eq +/// ``` +/// +pub fn max(a: Order, b: Order) -> Order { + case a, b { + Gt, _ -> Gt + Eq, Lt -> Eq + _, _ -> b + } +} + +/// Returns the smallest of two orders given that `Gt > Eq > Lt`. +/// +/// ## Examples +/// +/// ```gleam +/// > min(Eq, Lt) +/// Lt +/// ``` +/// +pub fn min(a: Order, b: Order) -> Order { + case a, b { + Lt, _ -> Lt + Eq, Gt -> Eq + _, _ -> b + } +} + +/// Inverts an ordering function, so less-than becomes greater-than and greater-than +/// becomes less-than. +/// +/// ## Examples +/// +/// ```gleam +/// > list.sort([1, 5, 4], by: reverse(int.compare)) +/// [5, 4, 1] +/// ``` +/// +pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { + fn(a, b) { orderer(b, a) } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam new file mode 100644 index 00000000000..894e6a8d9f1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/pair.gleam @@ -0,0 +1,85 @@ +/// Returns the first element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > first(#(1, 2)) +/// 1 +/// ``` +/// +pub fn first(pair: #(a, b)) -> a { + let #(a, _) = pair + a +} + +/// Returns the second element in a pair. +/// +/// ## Examples +/// +/// ```gleam +/// > second(#(1, 2)) +/// 2 +/// ``` +/// +pub fn second(pair: #(a, b)) -> b { + let #(_, a) = pair + a +} + +/// Returns a new pair with the elements swapped. +/// +/// ## Examples +/// +/// ```gleam +/// > swap(#(1, 2)) +/// #(2, 1) +/// ``` +/// +pub fn swap(pair: #(a, b)) -> #(b, a) { + let #(a, b) = pair + #(b, a) +} + +/// Returns a new pair with the first element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_first(fn(n) { n * 2 }) +/// #(2, 2) +/// ``` +/// +pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { + let #(a, b) = pair + #(fun(a), b) +} + +/// Returns a new pair with the second element having had `with` applied to +/// it. +/// +/// ## Examples +/// +/// ```gleam +/// > #(1, 2) |> map_second(fn(n) { n * 2 }) +/// #(1, 4) +/// ``` +/// +pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { + let #(a, b) = pair + #(a, fun(b)) +} + +/// Returns a new pair with the given elements. This can also be done using the dedicated +/// syntax instead: `new(1, 2) == #(1, 2)`. +/// +/// ## Examples +/// +/// ```gleam +/// > new(1, 2) +/// #(1, 2) +/// ``` +/// +pub fn new(first: a, second: b) -> #(a, b) { + #(first, second) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam new file mode 100644 index 00000000000..5bf60c8a529 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/queue.gleam @@ -0,0 +1,292 @@ +import gleam/list + +/// A queue is an ordered collection of elements. It is similar to a list, but +/// unlike a list elements can be added to or removed from either the front or +/// the back in a performant fashion. +/// +/// The internal representation may be different for two queues with the same +/// elements in the same order if the queues were constructed in different +/// ways. This is the price paid for a queue's fast access at both the front +/// and the back. +/// +/// Because of unpredictable internal representation the equality operator `==` +/// may return surprising results, and the `is_equal` and `is_logically_equal` +/// functions are the recommended way to test queues for equality. +/// +pub opaque type Queue(element) { + Queue(in: List(element), out: List(element)) +} + +/// Creates a fresh queue that contains no values. +/// +pub fn new() -> Queue(a) { + Queue(in: [], out: []) +} + +/// Converts a list of elements into a queue of the same elements in the same +/// order. The first element in the list becomes the front element in the queue. +/// +/// This function runs in constant time. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2, 3] |> from_list |> length +/// 3 +/// ``` +/// +pub fn from_list(list: List(a)) -> Queue(a) { + Queue(in: [], out: list) +} + +/// Converts a queue of elements into a list of the same elements in the same +/// order. The front element in the queue becomes the first element in the list. +/// +/// This function runs in linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() |> push_back(1) |> push_back(2) |> to_list +/// [1, 2] +/// ``` +/// +pub fn to_list(queue: Queue(a)) -> List(a) { + queue.out + |> list.append(list.reverse(queue.in)) +} + +/// Determines whether or not the queue is empty. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> is_empty +/// False +/// ``` +/// +pub fn is_empty(queue: Queue(a)) -> Bool { + queue.in == [] && queue.out == [] +} + +/// Counts the number of elements in a given queue. +/// +/// This function has to traverse the queue to determine the number of elements, +/// so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length(from_list([])) +/// 0 +/// ``` +/// +/// ```gleam +/// > length(from_list([1])) +/// 1 +/// ``` +/// +/// ```gleam +/// > length(from_list([1, 2])) +/// 2 +/// ``` +/// +pub fn length(queue: Queue(a)) -> Int { + list.length(queue.in) + list.length(queue.out) +} + +/// Pushes an element onto the back of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [1, 2] |> from_list |> push_back(3) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: [item, ..queue.in], out: queue.out) +} + +/// Pushes an element onto the front of the queue. +/// +/// # Examples +/// +/// ```gleam +/// > [0, 0] |> from_list |> push_front(1) |> to_list +/// [1, 0, 0] +/// ``` +/// +pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { + Queue(in: queue.in, out: [item, ..queue.out]) +} + +/// Gets the last element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > new() +/// > |> push_back(0) +/// > |> push_back(1) +/// > |> pop_back() +/// Ok(#(1, push_front(new(), 0))) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> push_front(0) +/// > |> pop_back() +/// Ok(#(0, new())) +/// ``` +/// +/// ```gleam +/// > new() +/// > |> pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) + Queue(in: [first, ..rest], out: out) -> { + let queue = Queue(in: rest, out: out) + Ok(#(first, queue)) + } + } +} + +/// Gets the first element from the queue, returning the +/// element and a new queue without that element. +/// +/// This function typically runs in constant time, but will occasionally run in +/// linear time. +/// +/// # Examples +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_front(1) +/// > |> queue.push_front(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.push_back(queue.new(), 1))) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.push_back(0) +/// > |> queue.pop_front() +/// Ok(#(0, queue.new())) +/// ``` +/// +/// ```gleam +/// > queue.new() +/// > |> queue.pop_back() +/// Error(Nil) +/// ``` +/// +pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { + case queue { + Queue(in: [], out: []) -> Error(Nil) + Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) + Queue(in: in, out: [first, ..rest]) -> { + let queue = Queue(in: in, out: rest) + Ok(#(first, queue)) + } + } +} + +/// Creates a new queue from a given queue containing the same elements, but in +/// the opposite order. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > [] |> from_list |> reverse |> to_list +/// [] +/// ``` +/// +/// ```gleam +/// > [1] |> from_list |> reverse |> to_list +/// [1] +/// ``` +/// +/// ```gleam +/// > [1, 2] |> from_list |> reverse |> to_list +/// [2, 1] +/// ``` +/// +pub fn reverse(queue: Queue(a)) -> Queue(a) { + Queue(in: queue.out, out: queue.in) +} + +fn check_equal( + xs: List(t), + x_tail: List(t), + ys: List(t), + y_tail: List(t), + eq: fn(t, t) -> Bool, +) -> Bool { + case xs, x_tail, ys, y_tail { + [], [], [], [] -> True + [x, ..xs], _, [y, ..ys], _ -> + case eq(x, y) { + False -> False + True -> check_equal(xs, x_tail, ys, y_tail, eq) + } + [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) + _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) + _, _, _, _ -> False + } +} + +/// Checks whether two queues have equal elements in the same order, where the +/// equality of elements is determined by a given equality checking function. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time multiplied by the time taken by the +/// element equality checking function. +/// +pub fn is_logically_equal( + a: Queue(t), + to b: Queue(t), + checking element_is_equal: fn(t, t) -> Bool, +) -> Bool { + check_equal(a.out, a.in, b.out, b.in, element_is_equal) +} + +/// Checks whether two queues have the same elements in the same order. +/// +/// This function is useful as the internal representation may be different for +/// two queues with the same elements in the same order depending on how they +/// were constructed, so the equality operator `==` may return surprising +/// results. +/// +/// This function runs in linear time. +/// +pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { + check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam new file mode 100644 index 00000000000..9ffda789f6a --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/regex.gleam @@ -0,0 +1,214 @@ +//// This module contains regular expression matching functions for strings. +//// The matching algorithms of the library are based on the PCRE library, but not +//// all of the PCRE library is interfaced and some parts of the library go beyond +//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. + +import gleam/option.{type Option} + +pub type Regex + +/// The details about a particular match: +/// +pub type Match { + Match( + /// The full string of the match. + content: String, + /// A `Regex` can have subpatterns, sup-parts that are in parentheses. + submatches: List(Option(String)), + ) +} + +/// When a regular expression fails to compile: +/// +pub type CompileError { + CompileError( + /// The problem encountered that caused the compilation to fail + error: String, + /// The byte index into the string to where the problem was found + /// This value may not be correct in JavaScript environments. + byte_index: Int, + ) +} + +pub type Options { + Options(case_insensitive: Bool, multi_line: Bool) +} + +/// Creates a `Regex` with some additional options. +/// +/// ## Examples +/// +/// ```gleam +/// > let options = Options(case_insensitive: False, multi_line: True) +/// > let assert Ok(re) = compile("^[0-9]", with: options) +/// > check(re, "abc\n123") +/// True +/// ``` +/// +/// ```gleam +/// > let options = Options(case_insensitive: True, multi_line: False) +/// > let assert Ok(re) = compile("[A-Z]", with: options) +/// > check(re, "abc123") +/// True +/// ``` +/// +pub fn compile( + pattern: String, + with options: Options, +) -> Result(Regex, CompileError) { + do_compile(pattern, options) +} + +@external(erlang, "gleam_stdlib", "compile_regex") +@external(javascript, "../gleam_stdlib.mjs", "compile_regex") +fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) + +/// Creates a new `Regex`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[0-9]") +/// > check(re, "abc123") +/// True +/// ``` +/// +/// ```gleam +/// > check(re, "abcxyz") +/// False +/// ``` +/// +/// ```gleam +/// > from_string("[0-9") +/// Error( +/// CompileError( +/// error: "missing terminating ] for character class", +/// byte_index: 4 +/// ) +/// ) +/// ``` +/// +pub fn from_string(pattern: String) -> Result(Regex, CompileError) { + compile(pattern, Options(case_insensitive: False, multi_line: False)) +} + +/// Returns a boolean indicating whether there was a match or not. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("^f.o.?") +/// > check(with: re, content: "foo") +/// True +/// ``` +/// +/// ```gleam +/// > check(with: re, content: "boo") +/// False +/// ``` +/// +pub fn check(with regex: Regex, content content: String) -> Bool { + do_check(regex, content) +} + +@external(erlang, "gleam_stdlib", "regex_check") +@external(javascript, "../gleam_stdlib.mjs", "regex_check") +fn do_check(a: Regex, b: String) -> Bool + +/// Splits a string. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string(" *, *") +/// > split(with: re, content: "foo,32, 4, 9 ,0") +/// ["foo", "32", "4", "9", "0"] +/// ``` +/// +pub fn split(with regex: Regex, content string: String) -> List(String) { + do_split(regex, string) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "regex_split") +fn do_split(a: Regex, b: String) -> List(String) + +@target(javascript) +fn do_split(regex, string) -> List(String) { + js_split(string, regex) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split") +fn js_split(a: String, b: Regex) -> List(String) + +/// Collects all matches of the regular expression. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") +/// > scan(with: re, content: "I am on a boat in a lake.") +/// [ +/// Match( +/// content: "on a boat", +/// submatches: [Some("boat")] +/// ), +/// Match( +/// content: "in a lake", +/// submatches: [Some("lake")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") +/// > scan(with: re, content: "-36") +/// [ +/// Match( +/// content: "-36", +/// submatches: [Some("-"), Some("36")] +/// ) +/// ] +/// +/// > scan(with: re, content: "36") +/// [ +/// Match( +/// content: "36", +/// submatches: [None, Some("36")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") +/// > scan(with: re, content: "var age = 32") +/// [ +/// Match( +/// content: "var age = 32", +/// submatches: [Some("age"), None, Some("32")] +/// ) +/// ] +/// ``` +/// +/// ```gleam +/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") +/// > scan(with: re, content: "let age = 32") +/// [ +/// Match( +/// content: "let age = 32", +/// submatches: [Some("age"), Some("32")] +/// ) +/// ] +/// +/// > scan(with: re, content: "const age = 32") +/// [] +/// ``` +/// +pub fn scan(with regex: Regex, content string: String) -> List(Match) { + do_scan(regex, string) +} + +@external(erlang, "gleam_stdlib", "regex_scan") +@external(javascript, "../gleam_stdlib.mjs", "regex_scan") +fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam new file mode 100644 index 00000000000..fb6dddb3110 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/result.gleam @@ -0,0 +1,482 @@ +//// Result represents the result of something that may succeed or not. +//// `Ok` means it was successful, `Error` means it was not successful. + +import gleam/list + +/// Checks whether the result is an `Ok` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_ok(Ok(1)) +/// True +/// ``` +/// +/// ```gleam +/// > is_ok(Error(Nil)) +/// False +/// ``` +/// +pub fn is_ok(result: Result(a, e)) -> Bool { + case result { + Error(_) -> False + Ok(_) -> True + } +} + +/// Checks whether the result is an `Error` value. +/// +/// ## Examples +/// +/// ```gleam +/// > is_error(Ok(1)) +/// False +/// ``` +/// +/// ```gleam +/// > is_error(Error(Nil)) +/// True +/// ``` +/// +pub fn is_error(result: Result(a, e)) -> Bool { + case result { + Ok(_) -> False + Error(_) -> True + } +} + +/// Updates a value held within the `Ok` of a result by calling a given function +/// on it. +/// +/// If the result is an `Error` rather than `Ok` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > map(over: Error(1), with: fn(x) { x + 1 }) +/// Error(1) +/// ``` +/// +pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { + case result { + Ok(x) -> Ok(fun(x)) + Error(e) -> Error(e) + } +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it. +/// +/// If the result is `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// ## Examples +/// +/// ```gleam +/// > map_error(over: Error(1), with: fn(x) { x + 1 }) +/// Error(2) +/// ``` +/// +/// ```gleam +/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) +/// Ok(1) +/// ``` +/// +pub fn map_error( + over result: Result(a, e), + with fun: fn(e) -> f, +) -> Result(a, f) { + case result { + Ok(x) -> Ok(x) + Error(error) -> Error(fun(error)) + } +} + +/// Merges a nested `Result` into a single layer. +/// +/// ## Examples +/// +/// ```gleam +/// > flatten(Ok(Ok(1))) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > flatten(Ok(Error(""))) +/// Error("") +/// ``` +/// +/// ```gleam +/// > flatten(Error(Nil)) +/// Error(Nil) +/// ``` +/// +pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { + case result { + Ok(x) -> x + Error(error) -> Error(error) + } +} + +/// "Updates" an `Ok` result by passing its value to a function that yields a result, +/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) +/// +/// If the input is an `Error` rather than an `Ok`, the function is not called and +/// the original `Error` is returned. +/// +/// This function is the equivalent of calling `map` followed by `flatten`, and +/// it is useful for chaining together multiple functions that may fail. +/// +/// ## Examples +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(x + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) +/// Ok(#("a", 1)) +/// ``` +/// +/// ```gleam +/// > try(Ok(1), fn(_) { Error("Oh no") }) +/// Error("Oh no") +/// ``` +/// +/// ```gleam +/// > try(Error(Nil), fn(x) { Ok(x + 1) }) +/// Error(Nil) +/// ``` +/// +pub fn try( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + case result { + Ok(x) -> fun(x) + Error(e) -> Error(e) + } +} + +/// An alias for `try`. See the documentation for that function for more information. +/// +pub fn then( + result: Result(a, e), + apply fun: fn(a) -> Result(b, e), +) -> Result(b, e) { + try(result, fun) +} + +/// Extracts the `Ok` value from a result, returning a default value if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap(Ok(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap(Error(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap(result: Result(a, e), or default: a) -> a { + case result { + Ok(v) -> v + Error(_) -> default + } +} + +/// Extracts the `Ok` value from a result, evaluating the default function if the result +/// is an `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_unwrap(Ok(1), fn() { 0 }) +/// 1 +/// ``` +/// +/// ```gleam +/// > lazy_unwrap(Error(""), fn() { 0 }) +/// 0 +/// ``` +/// +pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { + case result { + Ok(v) -> v + Error(_) -> default() + } +} + +/// Extracts the `Error` value from a result, returning a default value if the result +/// is an `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_error(Error(1), 0) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_error(Ok(""), 0) +/// 0 +/// ``` +/// +pub fn unwrap_error(result: Result(a, e), or default: e) -> e { + case result { + Ok(_) -> default + Error(e) -> e + } +} + +/// Extracts the inner value from a result. Both the value and error must be of +/// the same type. +/// +/// ## Examples +/// +/// ```gleam +/// > unwrap_both(Error(1)) +/// 1 +/// ``` +/// +/// ```gleam +/// > unwrap_both(Ok(2)) +/// 2 +/// ``` +/// +pub fn unwrap_both(result: Result(a, a)) -> a { + case result { + Ok(a) -> a + Error(a) -> a + } +} + +/// Transforms any error into `Error(Nil)`. +/// +/// ## Examples +/// +/// ```gleam +/// > nil_error(Error(1)) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > nil_error(Ok(1)) +/// Ok(1) +/// ``` +/// +pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { + map_error(result, fn(_) { Nil }) +} + +/// Returns the first value if it is `Ok`, otherwise returns the second value. +/// +/// ## Examples +/// +/// ```gleam +/// > or(Ok(1), Ok(2)) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Ok(1), Error("Error 2")) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Ok(2)) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > or(Error("Error 1"), Error("Error 2")) +/// Error("Error 2") +/// ``` +/// +pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second + } +} + +/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. +/// +/// ## Examples +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Ok(2) }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Ok(1), fn() { Error("Error 2") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) +/// Error("Error 2") +/// ``` +/// +pub fn lazy_or( + first: Result(a, e), + second: fn() -> Result(a, e), +) -> Result(a, e) { + case first { + Ok(_) -> first + Error(_) -> second() + } +} + +/// Combines a list of results into a single result. +/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. +/// If any element is `Error` then returns the first error. +/// +/// ## Examples +/// +/// ```gleam +/// > all([Ok(1), Ok(2)]) +/// Ok([1, 2]) +/// ``` +/// +/// ```gleam +/// > all([Ok(1), Error("e")]) +/// Error("e") +/// ``` +/// +pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { + list.try_map(results, fn(x) { x }) +} + +/// Given a list of results, returns a pair where the first element is a list +/// of all the values inside `Ok` and the second element is a list with all the +/// values inside `Error`. The values in both lists appear in reverse order with +/// respect to their position in the original list of results. +/// +/// ## Examples +/// +/// ```gleam +/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) +/// #([2, 1], ["b", "a"]) +/// ``` +/// +pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { + do_partition(results, [], []) +} + +fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { + case results { + [] -> #(oks, errors) + [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) + [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) + } +} + +/// Replace the value within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace(Ok(1), Nil) +/// Ok(Nil) +/// ``` +/// +/// ```gleam +/// > replace(Error(1), Nil) +/// Error(1) +/// ``` +/// +pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { + case result { + Ok(_) -> Ok(value) + Error(error) -> Error(error) + } +} + +/// Replace the error within a result +/// +/// ## Examples +/// +/// ```gleam +/// > replace_error(Error(1), Nil) +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > replace_error(Ok(1), Nil) +/// Ok(1) +/// ``` +/// +pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { + case result { + Ok(x) -> Ok(x) + Error(_) -> Error(error) + } +} + +/// Given a list of results, returns only the values inside `Ok`. +/// +/// ## Examples +/// +/// ```gleam +/// > values([Ok(1), Error("a"), Ok(3)]) +/// [1, 3] +/// ``` +/// +pub fn values(results: List(Result(a, e))) -> List(a) { + list.filter_map(results, fn(r) { r }) +} + +/// Updates a value held within the `Error` of a result by calling a given function +/// on it, where the given function also returns a result. The two results are +/// then merged together into one result. +/// +/// If the result is an `Ok` rather than `Error` the function is not called and the +/// result stays the same. +/// +/// This function is useful for chaining together computations that may fail +/// and trying to recover from possible errors. +/// +/// ## Examples +/// +/// ```gleam +/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) +/// Ok(1) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) +/// Ok(2) +/// ``` +/// +/// ```gleam +/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) +/// Error("failed to recover") +/// ``` +/// +pub fn try_recover( + result: Result(a, e), + with fun: fn(e) -> Result(a, f), +) -> Result(a, f) { + case result { + Ok(value) -> Ok(value) + Error(error) -> fun(error) + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam new file mode 100644 index 00000000000..df8d500e804 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/set.gleam @@ -0,0 +1,264 @@ +import gleam/list +import gleam/dict.{type Dict} +import gleam/result + +// A list is used as the map value as an empty list has the smallest +// representation in Erlang's binary format +@target(erlang) +type Token = + List(Nil) + +@target(erlang) +const token = [] + +@target(javascript) +type Token = + Nil + +@target(javascript) +const token = Nil + +/// A set is a collection of unique members of the same type. +/// +/// It is implemented using the `gleam/map` module, so inserts and lookups have +/// logarithmic time complexity. +/// +pub opaque type Set(member) { + Set(map: Dict(member, Token)) +} + +/// Creates a new empty set. +/// +pub fn new() -> Set(member) { + Set(dict.new()) +} + +/// Gets the number of members in a set. +/// +/// This function runs in constant time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn size(set: Set(member)) -> Int { + dict.size(set.map) +} + +/// Inserts an member into the set. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(1) +/// > |> insert(2) +/// > |> size +/// 2 +/// ``` +/// +pub fn insert(into set: Set(member), this member: member) -> Set(member) { + Set(map: dict.insert(set.map, member, token)) +} + +/// Checks whether a set contains a given member. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(2) +/// True +/// ``` +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn contains(in set: Set(member), this member: member) -> Bool { + set.map + |> dict.get(member) + |> result.is_ok +} + +/// Removes a member from a set. If the set does not contain the member then +/// the set is returned unchanged. +/// +/// This function runs in logarithmic time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() +/// > |> insert(2) +/// > |> delete(2) +/// > |> contains(1) +/// False +/// ``` +/// +pub fn delete(from set: Set(member), this member: member) -> Set(member) { + Set(map: dict.delete(set.map, member)) +} + +/// Converts the set into a list of the contained members. +/// +/// The list has no specific ordering, any unintentional ordering may change in +/// future versions of Gleam or Erlang. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > new() |> insert(2) |> to_list +/// [2] +/// ``` +/// +pub fn to_list(set: Set(member)) -> List(member) { + dict.keys(set.map) +} + +/// Creates a new set of the members in a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/list +/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort +/// [1, 3, 3, 4] +/// ``` +/// +pub fn from_list(members: List(member)) -> Set(member) { + let map = + list.fold( + over: members, + from: dict.new(), + with: fn(m, k) { dict.insert(m, k, token) }, + ) + Set(map) +} + +/// Combines all entries into a single value by calling a given function on each +/// one. +/// +/// Sets are not ordered so the values are not returned in any specific order. +/// Do not write code that relies on the order entries are used by this +/// function as it may change in later versions of Gleam or Erlang. +/// +/// # Examples +/// +/// ```gleam +/// > from_list([1, 3, 9]) +/// > |> fold(0, fn(member, accumulator) { accumulator + member }) +/// 13 +/// ``` +/// +pub fn fold( + over set: Set(member), + from initial: acc, + with reducer: fn(acc, member) -> acc, +) -> acc { + dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) +} + +/// Creates a new set from an existing set, minus any members that a given +/// function returns `False` for. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/int +/// > from_list([1, 4, 6, 3, 675, 44, 67]) +/// > |> filter(for: int.is_even) +/// > |> to_list +/// [4, 6, 44] +/// ``` +/// +pub fn filter( + in set: Set(member), + keeping predicate: fn(member) -> Bool, +) -> Set(member) { + Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) +} + +pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { + list.fold(over: disallowed, from: set, with: delete) +} + +/// Creates a new map from a given map, only including any members which are in +/// a given list. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > from_list([1, 2, 3]) +/// > |> take([1, 3, 5]) +/// > |> to_list +/// [1, 3] +/// ``` +/// +pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { + Set(dict.take(from: set.map, keeping: desired)) +} + +fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { + case dict.size(first.map) > dict.size(second.map) { + True -> #(first, second) + False -> #(second, first) + } +} + +/// Creates a new set that contains all members of both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [1, 2, 3] +/// ``` +/// +pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { + let #(larger, smaller) = order(first, second) + fold(over: smaller, from: larger, with: insert) +} + +/// Creates a new set that contains members that are present in both given sets. +/// +/// This function runs in loglinear time. +/// +/// ## Examples +/// +/// ```gleam +/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list +/// [2] +/// ``` +/// +pub fn intersection( + of first: Set(member), + and second: Set(member), +) -> Set(member) { + let #(larger, smaller) = order(first, second) + take(from: larger, keeping: to_list(smaller)) +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam new file mode 100644 index 00000000000..7254fd9fd1c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string.gleam @@ -0,0 +1,913 @@ +//// Strings in Gleam are UTF-8 binaries. They can be written in your code as +//// text surrounded by `"double quotes"`. + +import gleam/iterator.{type Iterator} +import gleam/list +import gleam/option.{type Option, None, Some} +import gleam/order +import gleam/string_builder.{type StringBuilder} + +/// Determines if a `String` is empty. +/// +/// ## Examples +/// +/// ```gleam +/// > is_empty("") +/// True +/// ``` +/// +/// ```gleam +/// > is_empty("the world") +/// False +/// ``` +/// +pub fn is_empty(str: String) -> Bool { + str == "" +} + +/// Gets the number of grapheme clusters in a given `String`. +/// +/// This function has to iterate across the whole string to count the number of +/// graphemes, so it runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > length("Gleam") +/// 5 +/// ``` +/// +/// ```gleam +/// > length("ß↑e̊") +/// 3 +/// ``` +/// +/// ```gleam +/// > length("") +/// 0 +/// ``` +/// +pub fn length(string: String) -> Int { + do_length(string) +} + +@external(erlang, "string", "length") +@external(javascript, "../gleam_stdlib.mjs", "string_length") +fn do_length(a: String) -> Int + +/// Reverses a `String`. +/// +/// This function has to iterate across the whole `String` so it runs in linear +/// time. +/// +/// ## Examples +/// +/// ```gleam +/// > reverse("stressed") +/// "desserts" +/// ``` +/// +pub fn reverse(string: String) -> String { + do_reverse(string) +} + +@target(erlang) +fn do_reverse(string: String) -> String { + string + |> string_builder.from_string + |> string_builder.reverse + |> string_builder.to_string +} + +@target(javascript) +fn do_reverse(string: String) -> String { + string + |> to_graphemes + |> list.reverse + |> concat +} + +/// Creates a new `String` by replacing all occurrences of a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > replace("www.example.com", each: ".", with: "-") +/// "www-example-com" +/// ``` +/// +/// ```gleam +/// > replace("a,b,c,d,e", each: ",", with: "/") +/// "a/b/c/d/e" +/// ``` +/// +pub fn replace( + in string: String, + each pattern: String, + with substitute: String, +) -> String { + string + |> string_builder.from_string + |> string_builder.replace(each: pattern, with: substitute) + |> string_builder.to_string +} + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// lowercase. +/// +/// Useful for case-insensitive comparisons. +/// +/// ## Examples +/// +/// ```gleam +/// > lowercase("X-FILES") +/// "x-files" +/// ``` +/// +pub fn lowercase(string: String) -> String { + do_lowercase(string) +} + +@external(erlang, "string", "lowercase") +@external(javascript, "../gleam_stdlib.mjs", "lowercase") +fn do_lowercase(a: String) -> String + +/// Creates a new `String` with all the graphemes in the input `String` converted to +/// uppercase. +/// +/// Useful for case-insensitive comparisons and VIRTUAL YELLING. +/// +/// ## Examples +/// +/// ```gleam +/// > uppercase("skinner") +/// "SKINNER" +/// ``` +/// +pub fn uppercase(string: String) -> String { + do_uppercase(string) +} + +@external(erlang, "string", "uppercase") +@external(javascript, "../gleam_stdlib.mjs", "uppercase") +fn do_uppercase(a: String) -> String + +/// Compares two `String`s to see which is "larger" by comparing their graphemes. +/// +/// This does not compare the size or length of the given `String`s. +/// +/// ## Examples +/// +/// ```gleam +/// > compare("Anthony", "Anthony") +/// order.Eq +/// ``` +/// +/// ```gleam +/// > compare("A", "B") +/// order.Lt +/// ``` +/// +pub fn compare(a: String, b: String) -> order.Order { + case a == b { + True -> order.Eq + _ -> + case less_than(a, b) { + True -> order.Lt + _ -> order.Gt + } + } +} + +@external(erlang, "gleam_stdlib", "less_than") +@external(javascript, "../gleam_stdlib.mjs", "less_than") +fn less_than(a: String, b: String) -> Bool + +/// Takes a substring given a start grapheme index and a length. Negative indexes +/// are taken starting from the *end* of the list. +/// +/// ## Examples +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 2) +/// "le" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 1, length: 10) +/// "leam" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: 10, length: 3) +/// "" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -2, length: 2) +/// "am" +/// ``` +/// +/// ```gleam +/// > slice(from: "gleam", at_index: -12, length: 2) +/// "" +/// ``` +/// +pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { + case len < 0 { + True -> "" + False -> + case idx < 0 { + True -> { + let translated_idx = length(string) + idx + case translated_idx < 0 { + True -> "" + False -> do_slice(string, translated_idx, len) + } + } + False -> do_slice(string, idx, len) + } + } +} + +@target(erlang) +@external(erlang, "string", "slice") +fn do_slice(a: String, b: Int, c: Int) -> String + +@target(javascript) +fn do_slice(string: String, idx: Int, len: Int) -> String { + string + |> to_graphemes + |> list.drop(idx) + |> list.take(len) + |> concat +} + +/// Drops contents of the first `String` that occur before the second `String`. +/// If the `from` string does not contain the `before` string, `from` is returned unchanged. +/// +/// ## Examples +/// +/// ```gleam +/// > crop(from: "The Lone Gunmen", before: "Lone") +/// "Lone Gunmen" +/// ``` +/// +@external(erlang, "gleam_stdlib", "crop_string") +@external(javascript, "../gleam_stdlib.mjs", "crop_string") +pub fn crop(from string: String, before substring: String) -> String + +/// Drops *n* graphemes from the left side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_left(from: "The Lone Gunmen", up_to: 2) +/// "e Lone Gunmen" +/// ``` +/// +pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, num_graphemes, length(string) - num_graphemes) + } +} + +/// Drops *n* graphemes from the right side of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) +/// "Cigarette Smoking M" +/// ``` +/// +pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { + case num_graphemes < 0 { + True -> string + False -> slice(string, 0, length(string) - num_graphemes) + } +} + +/// Checks if the first `String` contains the second. +/// +/// ## Examples +/// +/// ```gleam +/// > contains(does: "theory", contain: "ory") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "the") +/// True +/// ``` +/// +/// ```gleam +/// > contains(does: "theory", contain: "THE") +/// False +/// ``` +/// +@external(erlang, "gleam_stdlib", "contains_string") +@external(javascript, "../gleam_stdlib.mjs", "contains_string") +pub fn contains(does haystack: String, contain needle: String) -> Bool + +/// Checks whether the first `String` starts with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > starts_with("theory", "ory") +/// False +/// ``` +/// +pub fn starts_with(string: String, prefix: String) -> Bool { + do_starts_with(string, prefix) +} + +@external(erlang, "gleam_stdlib", "string_starts_with") +@external(javascript, "../gleam_stdlib.mjs", "starts_with") +fn do_starts_with(a: String, b: String) -> Bool + +/// Checks whether the first `String` ends with the second one. +/// +/// ## Examples +/// +/// ```gleam +/// > ends_with("theory", "ory") +/// True +/// ``` +/// +pub fn ends_with(string: String, suffix: String) -> Bool { + do_ends_with(string, suffix) +} + +@external(erlang, "gleam_stdlib", "string_ends_with") +@external(javascript, "../gleam_stdlib.mjs", "ends_with") +fn do_ends_with(a: String, b: String) -> Bool + +/// Creates a list of `String`s by splitting a given string on a given substring. +/// +/// ## Examples +/// +/// ```gleam +/// > split("home/gleam/desktop/", on: "/") +/// ["home", "gleam", "desktop", ""] +/// ``` +/// +pub fn split(x: String, on substring: String) -> List(String) { + case substring { + "" -> to_graphemes(x) + _ -> + x + |> string_builder.from_string + |> string_builder.split(on: substring) + |> list.map(with: string_builder.to_string) + } +} + +/// Splits a `String` a single time on the given substring. +/// +/// Returns an `Error` if substring not present. +/// +/// ## Examples +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "/") +/// Ok(#("home", "gleam/desktop/")) +/// ``` +/// +/// ```gleam +/// > split_once("home/gleam/desktop/", on: "?") +/// Error(Nil) +/// ``` +/// +pub fn split_once( + x: String, + on substring: String, +) -> Result(#(String, String), Nil) { + do_split_once(x, substring) +} + +@target(erlang) +@external(erlang, "string", "split") +fn erl_split(a: String, b: String) -> List(String) + +@target(erlang) +fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { + case erl_split(x, substring) { + [first, rest] -> Ok(#(first, rest)) + _ -> Error(Nil) + } +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split_once") +fn do_split_once( + x x: String, + substring substring: String, +) -> Result(#(String, String), Nil) + +/// Creates a new `String` by joining two `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > append(to: "butter", suffix: "fly") +/// "butterfly" +/// ``` +/// +pub fn append(to first: String, suffix second: String) -> String { + first + |> string_builder.from_string + |> string_builder.append(second) + |> string_builder.to_string +} + +/// Creates a new `String` by joining many `String`s together. +/// +/// This function copies both `String`s and runs in linear time. If you find +/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) +/// module as it can append `String`s much faster! +/// +/// ## Examples +/// +/// ```gleam +/// > concat(["never", "the", "less"]) +/// "nevertheless" +/// ``` +/// +pub fn concat(strings: List(String)) -> String { + strings + |> string_builder.from_strings + |> string_builder.to_string +} + +/// Creates a new `String` by repeating a `String` a given number of times. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > repeat("ha", times: 3) +/// "hahaha" +/// ``` +/// +pub fn repeat(string: String, times times: Int) -> String { + iterator.repeat(string) + |> iterator.take(times) + |> iterator.to_list + |> concat +} + +/// Joins many `String`s together with a given separator. +/// +/// This function runs in linear time. +/// +/// ## Examples +/// +/// ```gleam +/// > join(["home","evan","Desktop"], with: "/") +/// "home/evan/Desktop" +/// ``` +/// +pub fn join(strings: List(String), with separator: String) -> String { + do_join(strings, separator) +} + +@target(erlang) +fn do_join(strings: List(String), separator: String) -> String { + strings + |> list.intersperse(with: separator) + |> concat +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "join") +fn do_join(strings strings: List(String), string string: String) -> String + +/// Pads a `String` on the left until it has at least given number of graphemes. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_left("121", to: 5, with: ".") +/// "..121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 3, with: ".") +/// "121" +/// ``` +/// +/// ```gleam +/// > pad_left("121", to: 2, with: ".") +/// "121" +/// ``` +/// +pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + padding(to_pad_length, pad_string) + |> iterator.append(iterator.single(string)) + |> iterator.to_list + |> concat +} + +/// Pads a `String` on the right until it has a given length. +/// +/// ## Examples +/// +/// ```gleam +/// > pad_right("123", to: 5, with: ".") +/// "123.." +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 3, with: ".") +/// "123" +/// ``` +/// +/// ```gleam +/// > pad_right("123", to: 2, with: ".") +/// "123" +/// ``` +/// +pub fn pad_right( + string: String, + to desired_length: Int, + with pad_string: String, +) { + let current_length = length(string) + let to_pad_length = desired_length - current_length + iterator.single(string) + |> iterator.append(padding(to_pad_length, pad_string)) + |> iterator.to_list + |> concat +} + +fn padding(size: Int, pad_string: String) -> Iterator(String) { + let pad_length = length(pad_string) + let num_pads = size / pad_length + let extra = size % pad_length + iterator.repeat(pad_string) + |> iterator.take(num_pads) + |> iterator.append(iterator.single(slice(pad_string, 0, extra))) +} + +/// Removes whitespace on both sides of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim(" hats \n") +/// "hats" +/// ``` +/// +pub fn trim(string: String) -> String { + do_trim(string) +} + +@target(erlang) +fn do_trim(string: String) -> String { + erl_trim(string, Both) +} + +@target(erlang) +type Direction { + Leading + Trailing + Both +} + +@target(erlang) +@external(erlang, "string", "trim") +fn erl_trim(a: String, b: Direction) -> String + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim") +fn do_trim(string string: String) -> String + +/// Removes whitespace on the left of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_left(" hats \n") +/// "hats \n" +/// ``` +/// +pub fn trim_left(string: String) -> String { + do_trim_left(string) +} + +@target(erlang) +fn do_trim_left(string: String) -> String { + erl_trim(string, Leading) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim_left") +fn do_trim_left(string string: String) -> String + +/// Removes whitespace on the right of a `String`. +/// +/// ## Examples +/// +/// ```gleam +/// > trim_right(" hats \n") +/// " hats" +/// ``` +/// +pub fn trim_right(string: String) -> String { + do_trim_right(string) +} + +@target(erlang) +fn do_trim_right(string: String) -> String { + erl_trim(string, Trailing) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "trim_right") +fn do_trim_right(string string: String) -> String + +/// Splits a non-empty `String` into its first element (head) and rest (tail). +/// This lets you pattern match on `String`s exactly as you would with lists. +/// +/// Note on JavaScript using the function to iterate over a string will likely +/// be slower than using `to_graphemes` due to string slicing being more +/// expensive on JavaScript than Erlang. +/// +/// ## Examples +/// +/// ```gleam +/// > pop_grapheme("gleam") +/// Ok(#("g", "leam")) +/// ``` +/// +/// ```gleam +/// > pop_grapheme("") +/// Error(Nil) +/// ``` +/// +pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { + do_pop_grapheme(string) +} + +@external(erlang, "gleam_stdlib", "string_pop_grapheme") +@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") +fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) + +/// Converts a `String` to a list of +/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). +/// +/// ```gleam +/// > to_graphemes("abc") +/// ["a", "b", "c"] +/// ``` +/// +@external(javascript, "../gleam_stdlib.mjs", "graphemes") +pub fn to_graphemes(string: String) -> List(String) { + do_to_graphemes(string, []) + |> list.reverse +} + +fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { + case pop_grapheme(string) { + Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) + _ -> acc + } +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "codepoint") +fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint + +/// Converts a `String` to a `List` of `UtfCodepoint`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > "a" |> to_utf_codepoints +/// [UtfCodepoint(97)] +/// ``` +/// +/// ```gleam +/// // Semantically the same as: +/// // ["🏳", "️", "‍", "🌈"] or: +/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] +/// > "🏳️‍🌈" |> to_utf_codepoints +/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] +/// ``` +/// +pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints(string) +} + +@target(erlang) +fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + do_to_utf_codepoints_impl(<>, []) + |> list.reverse +} + +@target(erlang) +fn do_to_utf_codepoints_impl( + bit_array: BitArray, + acc: List(UtfCodepoint), +) -> List(UtfCodepoint) { + case bit_array { + <> -> + do_to_utf_codepoints_impl(rest, [first, ..acc]) + _ -> acc + } +} + +@target(javascript) +fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { + string + |> string_to_codepoint_integer_list + |> list.map(unsafe_int_to_utf_codepoint) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") +fn string_to_codepoint_integer_list(a: String) -> List(Int) + +/// Converts a `List` of `UtfCodepoint`s to a `String`. +/// +/// See and +/// for an +/// explanation on code points. +/// +/// ## Examples +/// +/// ```gleam +/// > { +/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( +/// > utf_codepoint(97), +/// > utf_codepoint(98), +/// > utf_codepoint(99), +/// > ) +/// > [a, b, c] +/// > } +/// > |> from_utf_codepoints +/// "abc" +/// ``` +/// +@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") +@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") +pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String + +/// Converts an integer to a `UtfCodepoint`. +/// +/// Returns an `Error` if the integer does not represent a valid UTF codepoint. +/// +pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { + case value { + i if i > 1_114_111 -> Error(Nil) + 65_534 | 65_535 -> Error(Nil) + i if i >= 55_296 && i <= 57_343 -> Error(Nil) + i -> Ok(unsafe_int_to_utf_codepoint(i)) + } +} + +/// Converts an UtfCodepoint to its ordinal code point value. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") +/// > utf_codepoint_to_int(utf_codepoint) +/// 128156 +/// ``` +/// +pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { + do_utf_codepoint_to_int(cp) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") +fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int + +/// Converts a `String` into `Option(String)` where an empty `String` becomes +/// `None`. +/// +/// ## Examples +/// +/// ```gleam +/// > to_option("") +/// None +/// ``` +/// +/// ```gleam +/// > to_option("hats") +/// Some("hats") +/// ``` +/// +pub fn to_option(s: String) -> Option(String) { + case s { + "" -> None + _ -> Some(s) + } +} + +/// Returns the first grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > first("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > first("icecream") +/// Ok("i") +/// ``` +/// +pub fn first(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, _)) -> Ok(first) + Error(e) -> Error(e) + } +} + +/// Returns the last grapheme cluster in a given `String` and wraps it in a +/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. +/// Otherwise, it returns `Ok(String)`. +/// +/// ## Examples +/// +/// ```gleam +/// > last("") +/// Error(Nil) +/// ``` +/// +/// ```gleam +/// > last("icecream") +/// Ok("m") +/// ``` +/// +pub fn last(s: String) -> Result(String, Nil) { + case pop_grapheme(s) { + Ok(#(first, "")) -> Ok(first) + Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) + Error(e) -> Error(e) + } +} + +/// Creates a new `String` with the first grapheme in the input `String` +/// converted to uppercase and the remaining graphemes to lowercase. +/// +/// ## Examples +/// +/// ```gleam +/// > capitalise("mamouna") +/// "Mamouna" +/// ``` +/// +pub fn capitalise(s: String) -> String { + case pop_grapheme(s) { + Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) + _ -> "" + } +} + +/// Returns a `String` representation of a term in Gleam syntax. +/// +pub fn inspect(term: anything) -> String { + do_inspect(term) + |> string_builder.to_string +} + +@external(erlang, "gleam_stdlib", "inspect") +@external(javascript, "../gleam_stdlib.mjs", "inspect") +fn do_inspect(term term: anything) -> StringBuilder + +/// Returns the number of bytes in a `String`. +/// +/// This function runs in constant time on Erlang and in linear time on +/// JavaScript. +/// +/// ## Examples +/// +/// ```gleam +/// > byte_size("🏳️‍⚧️🏳️‍🌈👩🏾‍❤️‍👨🏻") +/// 58 +/// ``` +/// +@external(erlang, "erlang", "byte_size") +@external(javascript, "../gleam_stdlib.mjs", "byte_size") +pub fn byte_size(string: String) -> Int diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam new file mode 100644 index 00000000000..5792ca8699d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/string_builder.gleam @@ -0,0 +1,298 @@ +import gleam/list + +/// `StringBuilder` is a type used for efficiently building strings. +/// +/// When we append one string to another the strings must be copied to a +/// new location in memory so that they can sit together. This behaviour +/// enables efficient reading of the string but copying can be expensive, +/// especially if we want to join many strings together. +/// +/// `StringBuilder` is different in that it can be joined together in constant time +/// using minimal memory, and then can be efficiently converted to a string +/// using the `to_string` function. +/// +/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this +/// type is compatible with normal strings. +/// +pub type StringBuilder + +/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many +/// builders together. +/// +pub fn new() -> StringBuilder { + do_from_strings([]) +} + +/// Prepends a `String` onto the start of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn prepend( + to builder: StringBuilder, + prefix prefix: String, +) -> StringBuilder { + append_builder(from_string(prefix), builder) +} + +/// Appends a `String` onto the end of some `StringBuilder`. +/// +/// Runs in constant time. +/// +pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { + append_builder(builder, from_string(second)) +} + +/// Prepends some `StringBuilder` onto the start of another. +/// +/// Runs in constant time. +/// +pub fn prepend_builder( + to builder: StringBuilder, + prefix prefix: StringBuilder, +) -> StringBuilder { + do_append(prefix, builder) +} + +/// Appends some `StringBuilder` onto the end of another. +/// +/// Runs in constant time. +/// +pub fn append_builder( + to builder: StringBuilder, + suffix suffix: StringBuilder, +) -> StringBuilder { + do_append(builder, suffix) +} + +@external(erlang, "gleam_stdlib", "iodata_append") +@external(javascript, "../gleam_stdlib.mjs", "add") +fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder + +/// Converts a list of strings into a builder. +/// +/// Runs in constant time. +/// +pub fn from_strings(strings: List(String)) -> StringBuilder { + do_from_strings(strings) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "concat") +fn do_from_strings(a: List(String)) -> StringBuilder + +/// Joins a list of builders into a single builder. +/// +/// Runs in constant time. +/// +pub fn concat(builders: List(StringBuilder)) -> StringBuilder { + do_concat(builders) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "concat") +fn do_concat(a: List(StringBuilder)) -> StringBuilder + +/// Converts a string into a builder. +/// +/// Runs in constant time. +/// +pub fn from_string(string: String) -> StringBuilder { + do_from_string(string) +} + +@external(erlang, "gleam_stdlib", "identity") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_from_string(a: String) -> StringBuilder + +/// Turns an `StringBuilder` into a `String` +/// +/// This function is implemented natively by the virtual machine and is highly +/// optimised. +/// +pub fn to_string(builder: StringBuilder) -> String { + do_to_string(builder) +} + +@external(erlang, "unicode", "characters_to_binary") +@external(javascript, "../gleam_stdlib.mjs", "identity") +fn do_to_string(a: StringBuilder) -> String + +/// Returns the size of the `StringBuilder` in bytes. +/// +pub fn byte_size(builder: StringBuilder) -> Int { + do_byte_size(builder) +} + +@external(erlang, "erlang", "iolist_size") +@external(javascript, "../gleam_stdlib.mjs", "length") +fn do_byte_size(a: StringBuilder) -> Int + +/// Joins the given builders into a new builder separated with the given string +/// +pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { + builders + |> list.intersperse(from_string(sep)) + |> concat +} + +/// Converts a builder to a new builder where the contents have been +/// lowercased. +/// +pub fn lowercase(builder: StringBuilder) -> StringBuilder { + do_lowercase(builder) +} + +@external(erlang, "string", "lowercase") +@external(javascript, "../gleam_stdlib.mjs", "lowercase") +fn do_lowercase(a: StringBuilder) -> StringBuilder + +/// Converts a builder to a new builder where the contents have been +/// uppercased. +/// +pub fn uppercase(builder: StringBuilder) -> StringBuilder { + do_uppercase(builder) +} + +@external(erlang, "string", "uppercase") +@external(javascript, "../gleam_stdlib.mjs", "uppercase") +fn do_uppercase(a: StringBuilder) -> StringBuilder + +/// Converts a builder to a new builder with the contents reversed. +/// +pub fn reverse(builder: StringBuilder) -> StringBuilder { + do_reverse(builder) +} + +@target(erlang) +@external(erlang, "string", "reverse") +fn do_reverse(a: StringBuilder) -> StringBuilder + +@target(javascript) +fn do_reverse(builder: StringBuilder) -> StringBuilder { + builder + |> to_string + |> do_to_graphemes + |> list.reverse + |> from_strings +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "graphemes") +fn do_to_graphemes(string string: String) -> List(String) + +/// Splits a builder on a given pattern into a list of builders. +/// +pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { + do_split(iodata, pattern) +} + +@target(erlang) +type Direction { + All +} + +@target(erlang) +@external(erlang, "string", "split") +fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) + +@target(erlang) +fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { + erl_split(iodata, pattern, All) +} + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "split") +fn do_split( + builder builder: StringBuilder, + pattern pattern: String, +) -> List(StringBuilder) + +/// Replaces all instances of a pattern with a given string substitute. +/// +pub fn replace( + in builder: StringBuilder, + each pattern: String, + with substitute: String, +) -> StringBuilder { + do_replace(builder, pattern, substitute) +} + +@target(erlang) +fn do_replace( + iodata: StringBuilder, + pattern: String, + substitute: String, +) -> StringBuilder { + erl_replace(iodata, pattern, substitute, All) +} + +@target(erlang) +@external(erlang, "string", "replace") +fn erl_replace( + a: StringBuilder, + b: String, + c: String, + d: Direction, +) -> StringBuilder + +@target(javascript) +@external(javascript, "../gleam_stdlib.mjs", "string_replace") +fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder + +/// Compares two builders to determine if they have the same textual content. +/// +/// Comparing two iodata using the `==` operator may return `False` even if they +/// have the same content as they may have been build in different ways, so +/// using this function is often preferred. +/// +/// ## Examples +/// +/// ```gleam +/// > from_strings(["a", "b"]) == from_string("ab") +/// False +/// ``` +/// +/// ```gleam +/// > is_equal(from_strings(["a", "b"]), from_string("ab")) +/// True +/// ``` +/// +pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { + do_is_equal(a, b) +} + +@external(erlang, "string", "equal") +@external(javascript, "../gleam_stdlib.mjs", "equal") +fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool + +/// Inspects a builder to determine if it is equivalent to an empty string. +/// +/// ## Examples +/// +/// ```gleam +/// > from_string("ok") |> is_empty +/// False +/// ``` +/// +/// ```gleam +/// > from_string("") |> is_empty +/// True +/// ``` +/// +/// ```gleam +/// > from_strings([]) |> is_empty +/// True +/// ``` +/// +pub fn is_empty(builder: StringBuilder) -> Bool { + do_is_empty(builder) +} + +@target(erlang) +@external(erlang, "string", "is_empty") +fn do_is_empty(a: StringBuilder) -> Bool + +@target(javascript) +fn do_is_empty(builder: StringBuilder) -> Bool { + from_string("") == builder +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam new file mode 100644 index 00000000000..11f6ea68cd2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam/uri.gleam @@ -0,0 +1,462 @@ +//// Utilities for working with URIs +//// +//// This module provides functions for working with URIs (for example, parsing +//// URIs or encoding query strings). The functions in this module are implemented +//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). +//// +//// Query encoding (Form encoding) is defined in the +//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). + +import gleam/int +import gleam/list +import gleam/option.{type Option, None, Some} +import gleam/string +import gleam/string_builder.{type StringBuilder} +@target(javascript) +import gleam/pair +@target(javascript) +import gleam/regex +@target(javascript) +import gleam/result + +/// Type representing holding the parsed components of an URI. +/// All components of a URI are optional, except the path. +/// +pub type Uri { + Uri( + scheme: Option(String), + userinfo: Option(String), + host: Option(String), + port: Option(Int), + path: String, + query: Option(String), + fragment: Option(String), + ) +} + +/// Parses a compliant URI string into the `Uri` Type. +/// If the string is not a valid URI string then an error is returned. +/// +/// The opposite operation is `uri.to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse("https://example.com:1234/a/b?query=true#fragment") +/// Ok( +/// Uri( +/// scheme: Some("https"), +/// userinfo: None, +/// host: Some("example.com"), +/// port: Some(1234), +/// path: "/a/b", +/// query: Some("query=true"), +/// fragment: Some("fragment") +/// ) +/// ) +/// ``` +/// +pub fn parse(uri_string: String) -> Result(Uri, Nil) { + do_parse(uri_string) +} + +@target(erlang) +@external(erlang, "gleam_stdlib", "uri_parse") +fn do_parse(a: String) -> Result(Uri, Nil) + +@target(javascript) +fn do_parse(uri_string: String) -> Result(Uri, Nil) { + // From https://tools.ietf.org/html/rfc3986#appendix-B + let pattern = + // 12 3 4 5 6 7 8 + "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" + let matches = + pattern + |> regex_submatches(uri_string) + |> pad_list(8) + + let #(scheme, authority, path, query, fragment) = case matches { + [ + _scheme_with_colon, + scheme, + authority_with_slashes, + _authority, + path, + query_with_question_mark, + _query, + fragment, + ] -> #( + scheme, + authority_with_slashes, + path, + query_with_question_mark, + fragment, + ) + _ -> #(None, None, None, None, None) + } + + let scheme = noneify_empty_string(scheme) + let path = option.unwrap(path, "") + let query = noneify_query(query) + let #(userinfo, host, port) = split_authority(authority) + let fragment = + fragment + |> option.to_result(Nil) + |> result.try(string.pop_grapheme) + |> result.map(pair.second) + |> option.from_result + let scheme = + scheme + |> noneify_empty_string + |> option.map(string.lowercase) + Ok(Uri( + scheme: scheme, + userinfo: userinfo, + host: host, + port: port, + path: path, + query: query, + fragment: fragment, + )) +} + +@target(javascript) +fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { + pattern + |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) + |> result.nil_error + |> result.map(regex.scan(_, string)) + |> result.try(list.first) + |> result.map(fn(m: regex.Match) { m.submatches }) + |> result.unwrap([]) +} + +@target(javascript) +fn noneify_query(x: Option(String)) -> Option(String) { + case x { + None -> None + Some(x) -> + case string.pop_grapheme(x) { + Ok(#("?", query)) -> Some(query) + _ -> None + } + } +} + +@target(javascript) +fn noneify_empty_string(x: Option(String)) -> Option(String) { + case x { + Some("") | None -> None + Some(_) -> x + } +} + +// Split an authority into its userinfo, host and port parts. +@target(javascript) +fn split_authority( + authority: Option(String), +) -> #(Option(String), Option(String), Option(Int)) { + case option.unwrap(authority, "") { + "" -> #(None, None, None) + "//" -> #(None, Some(""), None) + authority -> { + let matches = + "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" + |> regex_submatches(authority) + |> pad_list(6) + case matches { + [_, _, userinfo, host, _, port] -> { + let userinfo = noneify_empty_string(userinfo) + let host = noneify_empty_string(host) + let port = + port + |> option.unwrap("") + |> int.parse + |> option.from_result + #(userinfo, host, port) + } + _ -> #(None, None, None) + } + } + } +} + +@target(javascript) +fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { + list + |> list.append(list.repeat(None, extra_required(list, size))) +} + +@target(javascript) +fn extra_required(list: List(a), remaining: Int) -> Int { + case list { + _ if remaining == 0 -> 0 + [] -> remaining + [_, ..xs] -> extra_required(xs, remaining - 1) + } +} + +/// Parses an urlencoded query string into a list of key value pairs. +/// Returns an error for invalid encoding. +/// +/// The opposite operation is `uri.query_to_string`. +/// +/// ## Examples +/// +/// ```gleam +/// > parse_query("a=1&b=2") +/// Ok([#("a", "1"), #("b", "2")]) +/// ``` +/// +pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { + do_parse_query(query) +} + +@external(erlang, "gleam_stdlib", "parse_query") +@external(javascript, "../gleam_stdlib.mjs", "parse_query") +fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) + +/// Encodes a list of key value pairs as a URI query string. +/// +/// The opposite operation is `uri.parse_query`. +/// +/// ## Examples +/// +/// ```gleam +/// > query_to_string([#("a", "1"), #("b", "2")]) +/// "a=1&b=2" +/// ``` +/// +pub fn query_to_string(query: List(#(String, String))) -> String { + query + |> list.map(query_pair) + |> list.intersperse(string_builder.from_string("&")) + |> string_builder.concat + |> string_builder.to_string +} + +fn query_pair(pair: #(String, String)) -> StringBuilder { + string_builder.from_strings([ + percent_encode(pair.0), + "=", + percent_encode(pair.1), + ]) +} + +/// Encodes a string into a percent encoded representation. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_encode("100% great") +/// "100%25%20great" +/// ``` +/// +pub fn percent_encode(value: String) -> String { + do_percent_encode(value) +} + +@external(erlang, "gleam_stdlib", "percent_encode") +@external(javascript, "../gleam_stdlib.mjs", "percent_encode") +fn do_percent_encode(a: String) -> String + +/// Decodes a percent encoded string. +/// +/// ## Examples +/// +/// ```gleam +/// > percent_decode("100%25+great") +/// Ok("100% great") +/// ``` +/// +pub fn percent_decode(value: String) -> Result(String, Nil) { + do_percent_decode(value) +} + +@external(erlang, "gleam_stdlib", "percent_decode") +@external(javascript, "../gleam_stdlib.mjs", "percent_decode") +fn do_percent_decode(a: String) -> Result(String, Nil) + +fn do_remove_dot_segments( + input: List(String), + accumulator: List(String), +) -> List(String) { + case input { + [] -> list.reverse(accumulator) + [segment, ..rest] -> { + let accumulator = case segment, accumulator { + "", accumulator -> accumulator + ".", accumulator -> accumulator + "..", [] -> [] + "..", [_, ..accumulator] -> accumulator + segment, accumulator -> [segment, ..accumulator] + } + do_remove_dot_segments(rest, accumulator) + } + } +} + +fn remove_dot_segments(input: List(String)) -> List(String) { + do_remove_dot_segments(input, []) +} + +/// Splits the path section of a URI into it's constituent segments. +/// +/// Removes empty segments and resolves dot-segments as specified in +/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. +/// +/// ## Examples +/// +/// ```gleam +/// > path_segments("/users/1") +/// ["users" ,"1"] +/// ``` +/// +pub fn path_segments(path: String) -> List(String) { + remove_dot_segments(string.split(path, "/")) +} + +/// Encodes a `Uri` value as a URI string. +/// +/// The opposite operation is `uri.parse`. +/// +/// ## Examples +/// +/// ```gleam +/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) +/// > to_string(uri) +/// "http://example.com" +/// ``` +/// +pub fn to_string(uri: Uri) -> String { + let parts = case uri.fragment { + Some(fragment) -> ["#", fragment] + _ -> [] + } + let parts = case uri.query { + Some(query) -> ["?", query, ..parts] + _ -> parts + } + let parts = [uri.path, ..parts] + let parts = case uri.host, string.starts_with(uri.path, "/") { + Some(host), False if host != "" -> ["/", ..parts] + _, _ -> parts + } + let parts = case uri.host, uri.port { + Some(_), Some(port) -> [":", int.to_string(port), ..parts] + _, _ -> parts + } + let parts = case uri.scheme, uri.userinfo, uri.host { + Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] + Some(s), None, Some(h) -> [s, "://", h, ..parts] + Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] + None, None, Some(h) -> ["//", h, ..parts] + _, _, _ -> parts + } + string.concat(parts) +} + +/// Fetches the origin of a URI. +/// +/// Returns the origin of a uri as defined in +/// [RFC 6454](https://tools.ietf.org/html/rfc6454) +/// +/// The supported URI schemes are `http` and `https`. +/// URLs without a scheme will return `Error`. +/// +/// ## Examples +/// +/// ```gleam +/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") +/// > origin(uri) +/// Ok("http://example.com") +/// ``` +/// +pub fn origin(uri: Uri) -> Result(String, Nil) { + let Uri(scheme: scheme, host: host, port: port, ..) = uri + case scheme { + Some("https") if port == Some(443) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some("http") if port == Some(80) -> { + let origin = Uri(scheme, None, host, None, "", None, None) + Ok(to_string(origin)) + } + Some(s) if s == "http" || s == "https" -> { + let origin = Uri(scheme, None, host, port, "", None, None) + Ok(to_string(origin)) + } + _ -> Error(Nil) + } +} + +fn drop_last(elements: List(a)) -> List(a) { + list.take(from: elements, up_to: list.length(elements) - 1) +} + +fn join_segments(segments: List(String)) -> String { + string.join(["", ..segments], "/") +} + +/// Resolves a URI with respect to the given base URI. +/// +/// The base URI must be an absolute URI or this function will return an error. +/// The algorithm for merging uris is described in +/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). +/// +pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { + case base { + Uri(scheme: Some(_), host: Some(_), ..) -> + case relative { + Uri(host: Some(_), ..) -> { + let path = + string.split(relative.path, "/") + |> remove_dot_segments() + |> join_segments() + let resolved = + Uri( + option.or(relative.scheme, base.scheme), + None, + relative.host, + option.or(relative.port, base.port), + path, + relative.query, + relative.fragment, + ) + Ok(resolved) + } + _ -> { + let #(new_path, new_query) = case relative.path { + "" -> #(base.path, option.or(relative.query, base.query)) + _ -> { + let path_segments = case string.starts_with(relative.path, "/") { + True -> string.split(relative.path, "/") + False -> + string.split(base.path, "/") + |> drop_last() + |> list.append(string.split(relative.path, "/")) + } + let path = + path_segments + |> remove_dot_segments() + |> join_segments() + #(path, relative.query) + } + } + let resolved = + Uri( + base.scheme, + None, + base.host, + base.port, + new_path, + new_query, + relative.fragment, + ) + Ok(resolved) + } + } + _ -> Error(Nil) + } +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl new file mode 100644 index 00000000000..65bc3f63e4d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@base.erl @@ -0,0 +1,20 @@ +-module(gleam@base). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). + +-spec encode64(bitstring(), boolean()) -> binary(). +encode64(Input, Padding) -> + gleam@bit_array:base64_encode(Input, Padding). + +-spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. +decode64(Encoded) -> + gleam@bit_array:base64_decode(Encoded). + +-spec url_encode64(bitstring(), boolean()) -> binary(). +url_encode64(Input, Padding) -> + gleam@bit_array:base64_url_encode(Input, Padding). + +-spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. +url_decode64(Encoded) -> + gleam@bit_array:base64_url_decode(Encoded). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl new file mode 100644 index 00000000000..ba18dfaabdd --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_array.erl @@ -0,0 +1,102 @@ +-module(gleam@bit_array). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). + +-spec from_string(binary()) -> bitstring(). +from_string(X) -> + gleam_stdlib:identity(X). + +-spec byte_size(bitstring()) -> integer(). +byte_size(X) -> + erlang:byte_size(X). + +-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | + {error, nil}. +slice(String, Position, Length) -> + gleam_stdlib:bit_array_slice(String, Position, Length). + +-spec do_is_utf8(bitstring()) -> boolean(). +do_is_utf8(Bits) -> + case Bits of + <<>> -> + true; + + <<_/utf8, Rest/binary>> -> + do_is_utf8(Rest); + + _ -> + false + end. + +-spec is_utf8(bitstring()) -> boolean(). +is_utf8(Bits) -> + do_is_utf8(Bits). + +-spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. +do_to_string(Bits) -> + case is_utf8(Bits) of + true -> + {ok, gleam_stdlib:identity(Bits)}; + + false -> + {error, nil} + end. + +-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. +to_string(Bits) -> + do_to_string(Bits). + +-spec concat(list(bitstring())) -> bitstring(). +concat(Bit_arrays) -> + gleam_stdlib:bit_array_concat(Bit_arrays). + +-spec append(bitstring(), bitstring()) -> bitstring(). +append(First, Second) -> + gleam_stdlib:bit_array_concat([First, Second]). + +-spec base64_encode(bitstring(), boolean()) -> binary(). +base64_encode(Input, Padding) -> + Encoded = base64:encode(Input), + case Padding of + true -> + Encoded; + + false -> + gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) + end. + +-spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base64_decode(Encoded) -> + Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of + 0 -> + Encoded; + + N -> + gleam@string:append( + Encoded, + gleam@string:repeat(<<"="/utf8>>, 4 - N) + ) + end, + gleam_stdlib:base_decode64(Padded). + +-spec base64_url_encode(bitstring(), boolean()) -> binary(). +base64_url_encode(Input, Padding) -> + _pipe = base64_encode(Input, Padding), + _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), + gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). + +-spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base64_url_decode(Encoded) -> + _pipe = Encoded, + _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), + _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), + base64_decode(_pipe@2). + +-spec base16_encode(bitstring()) -> binary(). +base16_encode(Input) -> + binary:encode_hex(Input). + +-spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. +base16_decode(Input) -> + gleam_stdlib:base16_decode(Input). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl new file mode 100644 index 00000000000..284c6d46cc3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_builder.erl @@ -0,0 +1,66 @@ +-module(gleam@bit_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). + +-spec new() -> gleam@bytes_builder:bytes_builder(). +new() -> + gleam@bytes_builder:new(). + +-spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). +prepend(To, Prefix) -> + gleam@bytes_builder:prepend(To, Prefix). + +-spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). +append(To, Suffix) -> + gleam@bytes_builder:append(To, Suffix). + +-spec prepend_builder( + gleam@bytes_builder:bytes_builder(), + gleam@bytes_builder:bytes_builder() +) -> gleam@bytes_builder:bytes_builder(). +prepend_builder(To, Prefix) -> + gleam@bytes_builder:prepend_builder(To, Prefix). + +-spec append_builder( + gleam@bytes_builder:bytes_builder(), + gleam@bytes_builder:bytes_builder() +) -> gleam@bytes_builder:bytes_builder(). +append_builder(First, Second) -> + gleam_stdlib:iodata_append(First, Second). + +-spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). +prepend_string(To, Prefix) -> + gleam@bytes_builder:prepend_string(To, Prefix). + +-spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). +append_string(To, Suffix) -> + gleam@bytes_builder:append_string(To, Suffix). + +-spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). +concat_bit_strings(Bits) -> + gleam_stdlib:identity(Bits). + +-spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). +from_string(String) -> + gleam_stdlib:wrap_list(String). + +-spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). +from_string_builder(Builder) -> + gleam_stdlib:wrap_list(Builder). + +-spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). +from_bit_string(Bits) -> + gleam_stdlib:wrap_list(Bits). + +-spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). +to_bit_string(Builder) -> + erlang:list_to_bitstring(Builder). + +-spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl new file mode 100644 index 00000000000..7dabaa3bbc1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bit_string.erl @@ -0,0 +1,33 @@ +-module(gleam@bit_string). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). + +-spec from_string(binary()) -> bitstring(). +from_string(X) -> + gleam_stdlib:identity(X). + +-spec byte_size(bitstring()) -> integer(). +byte_size(X) -> + erlang:byte_size(X). + +-spec append(bitstring(), bitstring()) -> bitstring(). +append(First, Second) -> + gleam@bit_array:append(First, Second). + +-spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | + {error, nil}. +slice(String, Position, Length) -> + gleam_stdlib:bit_array_slice(String, Position, Length). + +-spec is_utf8(bitstring()) -> boolean(). +is_utf8(Bits) -> + gleam@bit_array:is_utf8(Bits). + +-spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. +to_string(Bits) -> + gleam@bit_array:to_string(Bits). + +-spec concat(list(bitstring())) -> bitstring(). +concat(Bit_strings) -> + gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl new file mode 100644 index 00000000000..5f95f4d8314 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bool.erl @@ -0,0 +1,162 @@ +-module(gleam@bool). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). + +-spec 'and'(boolean(), boolean()) -> boolean(). +'and'(A, B) -> + A andalso B. + +-spec 'or'(boolean(), boolean()) -> boolean(). +'or'(A, B) -> + A orelse B. + +-spec negate(boolean()) -> boolean(). +negate(Bool) -> + case Bool of + true -> + false; + + false -> + true + end. + +-spec nor(boolean(), boolean()) -> boolean(). +nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + false + end. + +-spec nand(boolean(), boolean()) -> boolean(). +nand(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_or(boolean(), boolean()) -> boolean(). +exclusive_or(A, B) -> + case {A, B} of + {false, false} -> + false; + + {false, true} -> + true; + + {true, false} -> + true; + + {true, true} -> + false + end. + +-spec exclusive_nor(boolean(), boolean()) -> boolean(). +exclusive_nor(A, B) -> + case {A, B} of + {false, false} -> + true; + + {false, true} -> + false; + + {true, false} -> + false; + + {true, true} -> + true + end. + +-spec compare(boolean(), boolean()) -> gleam@order:order(). +compare(A, B) -> + case {A, B} of + {true, true} -> + eq; + + {true, false} -> + gt; + + {false, false} -> + eq; + + {false, true} -> + lt + end. + +-spec max(boolean(), boolean()) -> boolean(). +max(A, B) -> + case A of + true -> + true; + + false -> + B + end. + +-spec min(boolean(), boolean()) -> boolean(). +min(A, B) -> + case A of + false -> + false; + + true -> + B + end. + +-spec to_int(boolean()) -> integer(). +to_int(Bool) -> + case Bool of + false -> + 0; + + true -> + 1 + end. + +-spec to_string(boolean()) -> binary(). +to_string(Bool) -> + case Bool of + false -> + <<"False"/utf8>>; + + true -> + <<"True"/utf8>> + end. + +-spec guard(boolean(), FGU, fun(() -> FGU)) -> FGU. +guard(Requirement, Consequence, Alternative) -> + case Requirement of + true -> + Consequence; + + false -> + Alternative() + end. + +-spec lazy_guard(boolean(), fun(() -> FGV), fun(() -> FGV)) -> FGV. +lazy_guard(Requirement, Consequence, Alternative) -> + case Requirement of + true -> + Consequence(); + + false -> + Alternative() + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl new file mode 100644 index 00000000000..2f6dd93a9f3 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl @@ -0,0 +1,87 @@ +-module(gleam@bytes_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). +-export_type([bytes_builder/0]). + +-opaque bytes_builder() :: {bytes, bitstring()} | + {text, gleam@string_builder:string_builder()} | + {many, list(bytes_builder())}. + +-spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). +append_builder(First, Second) -> + gleam_stdlib:iodata_append(First, Second). + +-spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). +prepend_builder(Second, First) -> + gleam_stdlib:iodata_append(First, Second). + +-spec concat(list(bytes_builder())) -> bytes_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec new() -> bytes_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec from_string(binary()) -> bytes_builder(). +from_string(String) -> + gleam_stdlib:wrap_list(String). + +-spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). +prepend_string(Second, First) -> + gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). + +-spec append_string(bytes_builder(), binary()) -> bytes_builder(). +append_string(First, Second) -> + gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). + +-spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). +from_string_builder(Builder) -> + gleam_stdlib:wrap_list(Builder). + +-spec from_bit_array(bitstring()) -> bytes_builder(). +from_bit_array(Bits) -> + gleam_stdlib:wrap_list(Bits). + +-spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). +prepend(Second, First) -> + gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). + +-spec append(bytes_builder(), bitstring()) -> bytes_builder(). +append(First, Second) -> + gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). + +-spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). +concat_bit_arrays(Bits) -> + gleam_stdlib:identity(Bits). + +-spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). +to_list(Stack, Acc) -> + case Stack of + [] -> + Acc; + + [[] | Remaining_stack] -> + to_list(Remaining_stack, Acc); + + [[{bytes, Bits} | Rest] | Remaining_stack@1] -> + to_list([Rest | Remaining_stack@1], [Bits | Acc]); + + [[{text, Builder} | Rest@1] | Remaining_stack@2] -> + Bits@1 = gleam_stdlib:identity( + gleam@string_builder:to_string(Builder) + ), + to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); + + [[{many, Builders} | Rest@2] | Remaining_stack@3] -> + to_list([Builders, Rest@2 | Remaining_stack@3], Acc) + end. + +-spec to_bit_array(bytes_builder()) -> bitstring(). +to_bit_array(Builder) -> + erlang:list_to_bitstring(Builder). + +-spec byte_size(bytes_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl new file mode 100644 index 00000000000..99c231e18cc --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dict.erl @@ -0,0 +1,97 @@ +-module(gleam@dict). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). +-export_type([dict/2]). + +-type dict(NP, NQ) :: any() | {gleam_phantom, NP, NQ}. + +-spec size(dict(any(), any())) -> integer(). +size(Dict) -> + maps:size(Dict). + +-spec to_list(dict(NZ, OA)) -> list({NZ, OA}). +to_list(Dict) -> + maps:to_list(Dict). + +-spec from_list(list({OJ, OK})) -> dict(OJ, OK). +from_list(List) -> + maps:from_list(List). + +-spec has_key(dict(OT, any()), OT) -> boolean(). +has_key(Dict, Key) -> + maps:is_key(Key, Dict). + +-spec new() -> dict(any(), any()). +new() -> + maps:new(). + +-spec get(dict(PJ, PK), PJ) -> {ok, PK} | {error, nil}. +get(From, Get) -> + gleam_stdlib:map_get(From, Get). + +-spec insert(dict(PV, PW), PV, PW) -> dict(PV, PW). +insert(Dict, Key, Value) -> + maps:put(Key, Value, Dict). + +-spec map_values(dict(QH, QI), fun((QH, QI) -> QL)) -> dict(QH, QL). +map_values(Dict, Fun) -> + maps:map(Fun, Dict). + +-spec keys(dict(QV, any())) -> list(QV). +keys(Dict) -> + maps:keys(Dict). + +-spec values(dict(any(), RG)) -> list(RG). +values(Dict) -> + maps:values(Dict). + +-spec filter(dict(RP, RQ), fun((RP, RQ) -> boolean())) -> dict(RP, RQ). +filter(Dict, Predicate) -> + maps:filter(Predicate, Dict). + +-spec take(dict(SB, SC), list(SB)) -> dict(SB, SC). +take(Dict, Desired_keys) -> + maps:with(Desired_keys, Dict). + +-spec merge(dict(SP, SQ), dict(SP, SQ)) -> dict(SP, SQ). +merge(Dict, New_entries) -> + maps:merge(Dict, New_entries). + +-spec delete(dict(TF, TG), TF) -> dict(TF, TG). +delete(Dict, Key) -> + maps:remove(Key, Dict). + +-spec drop(dict(TR, TS), list(TR)) -> dict(TR, TS). +drop(Dict, Disallowed_keys) -> + case Disallowed_keys of + [] -> + Dict; + + [X | Xs] -> + drop(delete(Dict, X), Xs) + end. + +-spec update(dict(TY, TZ), TY, fun((gleam@option:option(TZ)) -> TZ)) -> dict(TY, TZ). +update(Dict, Key, Fun) -> + _pipe = Dict, + _pipe@1 = get(_pipe, Key), + _pipe@2 = gleam@option:from_result(_pipe@1), + _pipe@3 = Fun(_pipe@2), + insert(Dict, Key, _pipe@3). + +-spec do_fold(list({UF, UG}), UI, fun((UI, UF, UG) -> UI)) -> UI. +do_fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [{K, V} | Rest] -> + do_fold(Rest, Fun(Initial, K, V), Fun) + end. + +-spec fold(dict(UJ, UK), UN, fun((UN, UJ, UK) -> UN)) -> UN. +fold(Dict, Initial, Fun) -> + _pipe = Dict, + _pipe@1 = to_list(_pipe), + do_fold(_pipe@1, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl new file mode 100644 index 00000000000..2c6016f4222 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@dynamic.erl @@ -0,0 +1,808 @@ +-module(gleam@dynamic). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). +-export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). + +-type dynamic_() :: any(). + +-type decode_error() :: {decode_error, binary(), binary(), list(binary())}. + +-type unknown_tuple() :: any(). + +-spec from(any()) -> dynamic_(). +from(A) -> + gleam_stdlib:identity(A). + +-spec unsafe_coerce(dynamic_()) -> any(). +unsafe_coerce(A) -> + gleam_stdlib:identity(A). + +-spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. +dynamic(Value) -> + {ok, Value}. + +-spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. +bit_array(Data) -> + gleam_stdlib:decode_bit_array(Data). + +-spec bit_string(dynamic_()) -> {ok, bitstring()} | + {error, list(decode_error())}. +bit_string(Data) -> + bit_array(Data). + +-spec put_expected(decode_error(), binary()) -> decode_error(). +put_expected(Error, Expected) -> + erlang:setelement(2, Error, Expected). + +-spec classify(dynamic_()) -> binary(). +classify(Data) -> + gleam_stdlib:classify_dynamic(Data). + +-spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. +int(Data) -> + gleam_stdlib:decode_int(Data). + +-spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. +float(Data) -> + gleam_stdlib:decode_float(Data). + +-spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. +bool(Data) -> + gleam_stdlib:decode_bool(Data). + +-spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | + {error, list(decode_error())}. +shallow_list(Value) -> + gleam_stdlib:decode_list(Value). + +-spec optional(fun((dynamic_()) -> {ok, DGM} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, + gleam@option:option(DGM)} | + {error, list(decode_error())}). +optional(Decode) -> + fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. + +-spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | + {error, list(decode_error())}. +at_least_decode_tuple_error(Size, Data) -> + S = case Size of + 1 -> + <<""/utf8>>; + + _ -> + <<"s"/utf8>> + end, + Error = begin + _pipe = [<<"Tuple of at least "/utf8>>, + gleam@int:to_string(Size), + <<" element"/utf8>>, + S], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + _pipe@2 = gleam@string_builder:to_string(_pipe@1), + {decode_error, _pipe@2, classify(Data), []} + end, + {error, [Error]}. + +-spec any(list(fun((dynamic_()) -> {ok, DKT} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, + DKT} | + {error, list(decode_error())}). +any(Decoders) -> + fun(Data) -> case Decoders of + [] -> + {error, + [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; + + [Decoder | Decoders@1] -> + case Decoder(Data) of + {ok, Decoded} -> + {ok, Decoded}; + + {error, _} -> + (any(Decoders@1))(Data) + end + end end. + +-spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). +all_errors(Result) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + Errors + end. + +-spec decode1( + fun((DKX) -> DKY), + fun((dynamic_()) -> {ok, DKX} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DKY} | {error, list(decode_error())}). +decode1(Constructor, T1) -> + fun(Value) -> case T1(Value) of + {ok, A} -> + {ok, Constructor(A)}; + + A@1 -> + {error, all_errors(A@1)} + end end. + +-spec push_path(decode_error(), any()) -> decode_error(). +push_path(Error, Name) -> + Name@1 = from(Name), + Decoder = any( + [fun string/1, + fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] + ), + Name@3 = case Decoder(Name@1) of + {ok, Name@2} -> + Name@2; + + {error, _} -> + _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1) + end, + erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). + +-spec result( + fun((dynamic_()) -> {ok, DGA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DGC} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {ok, DGA} | {error, DGC}} | + {error, list(decode_error())}). +result(Decode_ok, Decode_error) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_result(Value), + fun(Inner_result) -> case Inner_result of + {ok, Raw} -> + gleam@result:'try'( + begin + _pipe = Decode_ok(Raw), + map_errors( + _pipe, + fun(_capture) -> + push_path(_capture, <<"ok"/utf8>>) + end + ) + end, + fun(Value@1) -> {ok, {ok, Value@1}} end + ); + + {error, Raw@1} -> + gleam@result:'try'( + begin + _pipe@1 = Decode_error(Raw@1), + map_errors( + _pipe@1, + fun(_capture@1) -> + push_path(_capture@1, <<"error"/utf8>>) + end + ) + end, + fun(Value@2) -> {ok, {error, Value@2}} end + ) + end end + ) + end. + +-spec list(fun((dynamic_()) -> {ok, DGH} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, + list(DGH)} | + {error, list(decode_error())}). +list(Decoder_type) -> + fun(Dynamic) -> + gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, + _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end + ) end) + end. + +-spec map_errors( + {ok, DEV} | {error, list(decode_error())}, + fun((decode_error()) -> decode_error()) +) -> {ok, DEV} | {error, list(decode_error())}. +map_errors(Result, F) -> + gleam@result:map_error( + Result, + fun(_capture) -> gleam@list:map(_capture, F) end + ). + +-spec decode_string(dynamic_()) -> {ok, binary()} | + {error, list(decode_error())}. +decode_string(Data) -> + _pipe = bit_array(Data), + _pipe@1 = map_errors( + _pipe, + fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end + ), + gleam@result:'try'( + _pipe@1, + fun(Raw) -> case gleam@bit_array:to_string(Raw) of + {ok, String} -> + {ok, String}; + + {error, nil} -> + {error, + [{decode_error, + <<"String"/utf8>>, + <<"BitArray"/utf8>>, + []}]} + end end + ). + +-spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. +string(Data) -> + decode_string(Data). + +-spec field( + any(), + fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DGW} | {error, list(decode_error())}). +field(Name, Inner_type) -> + fun(Value) -> + Missing_field_error = {decode_error, + <<"field"/utf8>>, + <<"nothing"/utf8>>, + []}, + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> _pipe = Maybe_inner, + _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), + _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), + map_errors( + _pipe@2, + fun(_capture) -> push_path(_capture, Name) end + ) end + ) + end. + +-spec optional_field( + any(), + fun((dynamic_()) -> {ok, DHA} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@option:option(DHA)} | + {error, list(decode_error())}). +optional_field(Name, Inner_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_field(Value, Name), + fun(Maybe_inner) -> case Maybe_inner of + none -> + {ok, none}; + + {some, Dynamic_inner} -> + _pipe = Dynamic_inner, + _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), + map_errors( + _pipe@1, + fun(_capture) -> push_path(_capture, Name) end + ) + end end + ) + end. + +-spec element( + integer(), + fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DHI} | {error, list(decode_error())}). +element(Index, Inner_type) -> + fun(Data) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple(Data), + fun(Tuple) -> + Size = gleam_stdlib:size_of_tuple(Tuple), + gleam@result:'try'(case Index >= 0 of + true -> + case Index < Size of + true -> + gleam_stdlib:tuple_get(Tuple, Index); + + false -> + at_least_decode_tuple_error(Index + 1, Data) + end; + + false -> + case gleam@int:absolute_value(Index) =< Size of + true -> + gleam_stdlib:tuple_get(Tuple, Size + Index); + + false -> + at_least_decode_tuple_error( + gleam@int:absolute_value(Index), + Data + ) + end + end, fun(Data@1) -> _pipe = Inner_type(Data@1), + map_errors( + _pipe, + fun(_capture) -> push_path(_capture, Index) end + ) end) + end + ) + end. + +-spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). +tuple_errors(Result, Name) -> + case Result of + {ok, _} -> + []; + + {error, Errors} -> + gleam@list:map( + Errors, + fun(_capture) -> push_path(_capture, Name) end + ) + end. + +-spec tuple2( + fun((dynamic_()) -> {ok, DII} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIK} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DII, DIK}} | {error, list(decode_error())}). +tuple2(Decode1, Decode2) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple2(Value), + fun(_use0) -> + {A, B} = _use0, + case {Decode1(A), Decode2(B)} of + {{ok, A@1}, {ok, B@1}} -> + {ok, {A@1, B@1}}; + + {A@2, B@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + {error, _pipe@1} + end + end + ) + end. + +-spec tuple3( + fun((dynamic_()) -> {ok, DIN} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIR} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DIN, DIP, DIR}} | {error, list(decode_error())}). +tuple3(Decode1, Decode2, Decode3) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple3(Value), + fun(_use0) -> + {A, B, C} = _use0, + case {Decode1(A), Decode2(B), Decode3(C)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> + {ok, {A@1, B@1, C@1}}; + + {A@2, B@2, C@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + {error, _pipe@2} + end + end + ) + end. + +-spec tuple4( + fun((dynamic_()) -> {ok, DIU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIW} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DIY} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJA} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DIU, DIW, DIY, DJA}} | + {error, list(decode_error())}). +tuple4(Decode1, Decode2, Decode3, Decode4) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple4(Value), + fun(_use0) -> + {A, B, C, D} = _use0, + case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> + {ok, {A@1, B@1, C@1, D@1}}; + + {A@2, B@2, C@2, D@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + {error, _pipe@3} + end + end + ) + end. + +-spec tuple5( + fun((dynamic_()) -> {ok, DJD} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJF} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJJ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJL} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DJD, DJF, DJH, DJJ, DJL}} | + {error, list(decode_error())}). +tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple5(Value), + fun(_use0) -> + {A, B, C, D, E} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E)} of + {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1}}; + + {A@2, B@2, C@2, D@2, E@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + {error, _pipe@4} + end + end + ) + end. + +-spec tuple6( + fun((dynamic_()) -> {ok, DJO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJS} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJW} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DJY} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, {DJO, DJQ, DJS, DJU, DJW, DJY}} | + {error, list(decode_error())}). +tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_tuple6(Value), + fun(_use0) -> + {A, B, C, D, E, F} = _use0, + case {Decode1(A), + Decode2(B), + Decode3(C), + Decode4(D), + Decode5(E), + Decode6(F)} of + {{ok, A@1}, + {ok, B@1}, + {ok, C@1}, + {ok, D@1}, + {ok, E@1}, + {ok, F@1}} -> + {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; + + {A@2, B@2, C@2, D@2, E@2, F@2} -> + _pipe = tuple_errors(A@2, <<"0"/utf8>>), + _pipe@1 = gleam@list:append( + _pipe, + tuple_errors(B@2, <<"1"/utf8>>) + ), + _pipe@2 = gleam@list:append( + _pipe@1, + tuple_errors(C@2, <<"2"/utf8>>) + ), + _pipe@3 = gleam@list:append( + _pipe@2, + tuple_errors(D@2, <<"3"/utf8>>) + ), + _pipe@4 = gleam@list:append( + _pipe@3, + tuple_errors(E@2, <<"4"/utf8>>) + ), + _pipe@5 = gleam@list:append( + _pipe@4, + tuple_errors(F@2, <<"5"/utf8>>) + ), + {error, _pipe@5} + end + end + ) + end. + +-spec dict( + fun((dynamic_()) -> {ok, DKB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DKD} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKB, DKD)} | + {error, list(decode_error())}). +dict(Key_type, Value_type) -> + fun(Value) -> + gleam@result:'try'( + gleam_stdlib:decode_map(Value), + fun(Map) -> + gleam@result:'try'( + begin + _pipe = Map, + _pipe@1 = gleam@dict:to_list(_pipe), + gleam@list:try_map( + _pipe@1, + fun(Pair) -> + {K, V} = Pair, + gleam@result:'try'( + begin + _pipe@2 = Key_type(K), + map_errors( + _pipe@2, + fun(_capture) -> + push_path( + _capture, + <<"keys"/utf8>> + ) + end + ) + end, + fun(K@1) -> + gleam@result:'try'( + begin + _pipe@3 = Value_type(V), + map_errors( + _pipe@3, + fun(_capture@1) -> + push_path( + _capture@1, + <<"values"/utf8>> + ) + end + ) + end, + fun(V@1) -> {ok, {K@1, V@1}} end + ) + end + ) + end + ) + end, + fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end + ) + end + ) + end. + +-spec map( + fun((dynamic_()) -> {ok, DKI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DKK} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, gleam@dict:dict(DKI, DKK)} | + {error, list(decode_error())}). +map(Key_type, Value_type) -> + dict(Key_type, Value_type). + +-spec decode2( + fun((DLB, DLC) -> DLD), + fun((dynamic_()) -> {ok, DLB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLC} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLD} | {error, list(decode_error())}). +decode2(Constructor, T1, T2) -> + fun(Value) -> case {T1(Value), T2(Value)} of + {{ok, A}, {ok, B}} -> + {ok, Constructor(A, B)}; + + {A@1, B@1} -> + {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} + end end. + +-spec decode3( + fun((DLH, DLI, DLJ) -> DLK), + fun((dynamic_()) -> {ok, DLH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLJ} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLK} | {error, list(decode_error())}). +decode3(Constructor, T1, T2, T3) -> + fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of + {{ok, A}, {ok, B}, {ok, C}} -> + {ok, Constructor(A, B, C)}; + + {A@1, B@1, C@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), all_errors(B@1), all_errors(C@1)] + )} + end end. + +-spec decode4( + fun((DLP, DLQ, DLR, DLS) -> DLT), + fun((dynamic_()) -> {ok, DLP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLR} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DLS} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DLT} | {error, list(decode_error())}). +decode4(Constructor, T1, T2, T3, T4) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> + {ok, Constructor(A, B, C, D)}; + + {A@1, B@1, C@1, D@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1)] + )} + end end. + +-spec decode5( + fun((DLZ, DMA, DMB, DMC, DMD) -> DME), + fun((dynamic_()) -> {ok, DLZ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMC} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMD} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DME} | {error, list(decode_error())}). +decode5(Constructor, T1, T2, T3, T4, T5) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> + {ok, Constructor(A, B, C, D, E)}; + + {A@1, B@1, C@1, D@1, E@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1)] + )} + end end. + +-spec decode6( + fun((DML, DMM, DMN, DMO, DMP, DMQ) -> DMR), + fun((dynamic_()) -> {ok, DML} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMM} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMN} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DMQ} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DMR} | {error, list(decode_error())}). +decode6(Constructor, T1, T2, T3, T4, T5, T6) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> + {ok, Constructor(A, B, C, D, E, F)}; + + {A@1, B@1, C@1, D@1, E@1, F@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1)] + )} + end end. + +-spec decode7( + fun((DMZ, DNA, DNB, DNC, DND, DNE, DNF) -> DNG), + fun((dynamic_()) -> {ok, DMZ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNA} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNB} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNC} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DND} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNE} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNF} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DNG} | {error, list(decode_error())}). +decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of + {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> + {ok, Constructor(A, B, C, D, E, F, G)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1)] + )} + end end. + +-spec decode8( + fun((DNP, DNQ, DNR, DNS, DNT, DNU, DNV, DNW) -> DNX), + fun((dynamic_()) -> {ok, DNP} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNQ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNR} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNS} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNT} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNU} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNV} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DNW} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DNX} | {error, list(decode_error())}). +decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> + fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}} -> + {ok, Constructor(A, B, C, D, E, F, G, H)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1)] + )} + end end. + +-spec decode9( + fun((DOH, DOI, DOJ, DOK, DOL, DOM, DON, DOO, DOP) -> DOQ), + fun((dynamic_()) -> {ok, DOH} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOI} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOJ} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOK} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOL} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOM} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DON} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOO} | {error, list(decode_error())}), + fun((dynamic_()) -> {ok, DOP} | {error, list(decode_error())}) +) -> fun((dynamic_()) -> {ok, DOQ} | {error, list(decode_error())}). +decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> + fun(X) -> + case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of + {{ok, A}, + {ok, B}, + {ok, C}, + {ok, D}, + {ok, E}, + {ok, F}, + {ok, G}, + {ok, H}, + {ok, I}} -> + {ok, Constructor(A, B, C, D, E, F, G, H, I)}; + + {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> + {error, + gleam@list:concat( + [all_errors(A@1), + all_errors(B@1), + all_errors(C@1), + all_errors(D@1), + all_errors(E@1), + all_errors(F@1), + all_errors(G@1), + all_errors(H@1), + all_errors(I@1)] + )} + end + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl new file mode 100644 index 00000000000..33b3d4a3e3f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@float.erl @@ -0,0 +1,181 @@ +-module(gleam@float). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). + +-spec parse(binary()) -> {ok, float()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_float(String). + +-spec to_string(float()) -> binary(). +to_string(X) -> + gleam_stdlib:float_to_string(X). + +-spec compare(float(), float()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(float(), float()) -> float(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(float(), float()) -> float(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(float(), float(), float()) -> float(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec ceiling(float()) -> float(). +ceiling(X) -> + math:ceil(X). + +-spec floor(float()) -> float(). +floor(X) -> + math:floor(X). + +-spec round(float()) -> integer(). +round(X) -> + erlang:round(X). + +-spec truncate(float()) -> integer(). +truncate(X) -> + erlang:trunc(X). + +-spec absolute_value(float()) -> float(). +absolute_value(X) -> + case X >= +0.0 of + true -> + X; + + _ -> + +0.0 - X + end. + +-spec loosely_compare(float(), float(), float()) -> gleam@order:order(). +loosely_compare(A, B, Tolerance) -> + Difference = absolute_value(A - B), + case Difference =< Tolerance of + true -> + eq; + + false -> + compare(A, B) + end. + +-spec loosely_equals(float(), float(), float()) -> boolean(). +loosely_equals(A, B, Tolerance) -> + Difference = absolute_value(A - B), + Difference =< Tolerance. + +-spec power(float(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + Fractional = (ceiling(Exponent) - Exponent) > +0.0, + case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent + < +0.0)) of + true -> + {error, nil}; + + false -> + {ok, math:pow(Base, Exponent)} + end. + +-spec square_root(float()) -> {ok, float()} | {error, nil}. +square_root(X) -> + power(X, 0.5). + +-spec negate(float()) -> float(). +negate(X) -> + -1.0 * X. + +-spec do_sum(list(float()), float()) -> float(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(float())) -> float(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, +0.0). + +-spec do_product(list(float()), float()) -> float(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(float())) -> float(). +product(Numbers) -> + case Numbers of + [] -> + 1.0; + + _ -> + do_product(Numbers, 1.0) + end. + +-spec random(float(), float()) -> float(). +random(Min, Max) -> + (rand:uniform() * (Max - Min)) + Min. + +-spec divide(float(), float()) -> {ok, float()} | {error, nil}. +divide(A, B) -> + case B of + +0.0 -> + {error, nil}; + + B@1 -> + {ok, case B@1 of + +0.0 -> +0.0; + -0.0 -> -0.0; + Gleam@denominator -> A / Gleam@denominator + end} + end. + +-spec add(float(), float()) -> float(). +add(A, B) -> + A + B. + +-spec multiply(float(), float()) -> float(). +multiply(A, B) -> + A * B. + +-spec subtract(float(), float()) -> float(). +subtract(A, B) -> + A - B. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl new file mode 100644 index 00000000000..c58c0fe151b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@function.erl @@ -0,0 +1,67 @@ +-module(gleam@function). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). + +-spec compose(fun((I) -> J), fun((J) -> K)) -> fun((I) -> K). +compose(Fun1, Fun2) -> + fun(A) -> Fun2(Fun1(A)) end. + +-spec curry2(fun((L, M) -> N)) -> fun((L) -> fun((M) -> N)). +curry2(Fun) -> + fun(A) -> fun(B) -> Fun(A, B) end end. + +-spec curry3(fun((P, Q, R) -> S)) -> fun((P) -> fun((Q) -> fun((R) -> S))). +curry3(Fun) -> + fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. + +-spec curry4(fun((U, V, W, X) -> Y)) -> fun((U) -> fun((V) -> fun((W) -> fun((X) -> Y)))). +curry4(Fun) -> + fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. + +-spec curry5(fun((AA, AB, AC, AD, AE) -> AF)) -> fun((AA) -> fun((AB) -> fun((AC) -> fun((AD) -> fun((AE) -> AF))))). +curry5(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end + end + end. + +-spec curry6(fun((AH, AI, AJ, AK, AL, AM) -> AN)) -> fun((AH) -> fun((AI) -> fun((AJ) -> fun((AK) -> fun((AL) -> fun((AM) -> AN)))))). +curry6(Fun) -> + fun(A) -> + fun(B) -> + fun(C) -> + fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end + end + end + end. + +-spec flip(fun((AP, AQ) -> AR)) -> fun((AQ, AP) -> AR). +flip(Fun) -> + fun(B, A) -> Fun(A, B) end. + +-spec identity(AS) -> AS. +identity(X) -> + X. + +-spec constant(AT) -> fun((any()) -> AT). +constant(Value) -> + fun(_) -> Value end. + +-spec tap(AV, fun((AV) -> any())) -> AV. +tap(Arg, Effect) -> + Effect(Arg), + Arg. + +-spec apply1(fun((AX) -> AY), AX) -> AY. +apply1(Fun, Arg1) -> + Fun(Arg1). + +-spec apply2(fun((AZ, BA) -> BB), AZ, BA) -> BB. +apply2(Fun, Arg1, Arg2) -> + Fun(Arg1, Arg2). + +-spec apply3(fun((BC, BD, BE) -> BF), BC, BD, BE) -> BF. +apply3(Fun, Arg1, Arg2, Arg3) -> + Fun(Arg1, Arg2, Arg3). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl new file mode 100644 index 00000000000..2a5dd2c8a1d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@int.erl @@ -0,0 +1,332 @@ +-module(gleam@int). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). +-export_type([invalid_base/0]). + +-type invalid_base() :: invalid_base. + +-spec absolute_value(integer()) -> integer(). +absolute_value(X) -> + case X >= 0 of + true -> + X; + + false -> + X * -1 + end. + +-spec parse(binary()) -> {ok, integer()} | {error, nil}. +parse(String) -> + gleam_stdlib:parse_int(String). + +-spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. +base_parse(String, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + gleam_stdlib:int_from_base_string(String, Base); + + false -> + {error, nil} + end. + +-spec to_string(integer()) -> binary(). +to_string(X) -> + erlang:integer_to_binary(X). + +-spec to_base_string(integer(), integer()) -> {ok, binary()} | + {error, invalid_base()}. +to_base_string(X, Base) -> + case (Base >= 2) andalso (Base =< 36) of + true -> + {ok, erlang:integer_to_binary(X, Base)}; + + false -> + {error, invalid_base} + end. + +-spec to_base2(integer()) -> binary(). +to_base2(X) -> + erlang:integer_to_binary(X, 2). + +-spec to_base8(integer()) -> binary(). +to_base8(X) -> + erlang:integer_to_binary(X, 8). + +-spec to_base16(integer()) -> binary(). +to_base16(X) -> + erlang:integer_to_binary(X, 16). + +-spec to_base36(integer()) -> binary(). +to_base36(X) -> + erlang:integer_to_binary(X, 36). + +-spec to_float(integer()) -> float(). +to_float(X) -> + erlang:float(X). + +-spec power(integer(), float()) -> {ok, float()} | {error, nil}. +power(Base, Exponent) -> + _pipe = Base, + _pipe@1 = to_float(_pipe), + gleam@float:power(_pipe@1, Exponent). + +-spec square_root(integer()) -> {ok, float()} | {error, nil}. +square_root(X) -> + _pipe = X, + _pipe@1 = to_float(_pipe), + gleam@float:square_root(_pipe@1). + +-spec compare(integer(), integer()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + false -> + case A < B of + true -> + lt; + + false -> + gt + end + end. + +-spec min(integer(), integer()) -> integer(). +min(A, B) -> + case A < B of + true -> + A; + + false -> + B + end. + +-spec max(integer(), integer()) -> integer(). +max(A, B) -> + case A > B of + true -> + A; + + false -> + B + end. + +-spec clamp(integer(), integer(), integer()) -> integer(). +clamp(X, Min_bound, Max_bound) -> + _pipe = X, + _pipe@1 = min(_pipe, Max_bound), + max(_pipe@1, Min_bound). + +-spec is_even(integer()) -> boolean(). +is_even(X) -> + (X rem 2) =:= 0. + +-spec is_odd(integer()) -> boolean(). +is_odd(X) -> + (X rem 2) /= 0. + +-spec negate(integer()) -> integer(). +negate(X) -> + -1 * X. + +-spec do_sum(list(integer()), integer()) -> integer(). +do_sum(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_sum(Rest, X + Initial) + end. + +-spec sum(list(integer())) -> integer(). +sum(Numbers) -> + _pipe = Numbers, + do_sum(_pipe, 0). + +-spec do_product(list(integer()), integer()) -> integer(). +do_product(Numbers, Initial) -> + case Numbers of + [] -> + Initial; + + [X | Rest] -> + do_product(Rest, X * Initial) + end. + +-spec product(list(integer())) -> integer(). +product(Numbers) -> + case Numbers of + [] -> + 1; + + _ -> + do_product(Numbers, 1) + end. + +-spec do_digits(integer(), integer(), list(integer())) -> list(integer()). +do_digits(X, Base, Acc) -> + case absolute_value(X) < Base of + true -> + [X | Acc]; + + false -> + do_digits(case Base of + 0 -> 0; + Gleam@denominator -> X div Gleam@denominator + end, Base, [case Base of + 0 -> 0; + Gleam@denominator@1 -> X rem Gleam@denominator@1 + end | Acc]) + end. + +-spec digits(integer(), integer()) -> {ok, list(integer())} | + {error, invalid_base()}. +digits(X, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + {ok, do_digits(X, Base, [])} + end. + +-spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | + {error, invalid_base()}. +do_undigits(Numbers, Base, Acc) -> + case Numbers of + [] -> + {ok, Acc}; + + [Digit | _] when Digit >= Base -> + {error, invalid_base}; + + [Digit@1 | Rest] -> + do_undigits(Rest, Base, (Acc * Base) + Digit@1) + end. + +-spec undigits(list(integer()), integer()) -> {ok, integer()} | + {error, invalid_base()}. +undigits(Numbers, Base) -> + case Base < 2 of + true -> + {error, invalid_base}; + + false -> + do_undigits(Numbers, Base, 0) + end. + +-spec random(integer(), integer()) -> integer(). +random(Min, Max) -> + _pipe = gleam@float:random(to_float(Min), to_float(Max)), + _pipe@1 = gleam@float:floor(_pipe), + gleam@float:round(_pipe@1). + +-spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend div Gleam@denominator + end} + end. + +-spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. +remainder(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end} + end. + +-spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. +modulo(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + _ -> + Remainder = case Divisor of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end, + case (Remainder * Divisor) < 0 of + true -> + {ok, Remainder + Divisor}; + + false -> + {ok, Remainder} + end + end. + +-spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. +floor_divide(Dividend, Divisor) -> + case Divisor of + 0 -> + {error, nil}; + + Divisor@1 -> + case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of + 0 -> 0; + Gleam@denominator -> Dividend rem Gleam@denominator + end) /= 0) of + true -> + {ok, (case Divisor@1 of + 0 -> 0; + Gleam@denominator@1 -> Dividend div Gleam@denominator@1 + end) - 1}; + + false -> + {ok, case Divisor@1 of + 0 -> 0; + Gleam@denominator@2 -> Dividend div Gleam@denominator@2 + end} + end + end. + +-spec add(integer(), integer()) -> integer(). +add(A, B) -> + A + B. + +-spec multiply(integer(), integer()) -> integer(). +multiply(A, B) -> + A * B. + +-spec subtract(integer(), integer()) -> integer(). +subtract(A, B) -> + A - B. + +-spec bitwise_and(integer(), integer()) -> integer(). +bitwise_and(X, Y) -> + erlang:'band'(X, Y). + +-spec bitwise_not(integer()) -> integer(). +bitwise_not(X) -> + erlang:'bnot'(X). + +-spec bitwise_or(integer(), integer()) -> integer(). +bitwise_or(X, Y) -> + erlang:'bor'(X, Y). + +-spec bitwise_exclusive_or(integer(), integer()) -> integer(). +bitwise_exclusive_or(X, Y) -> + erlang:'bxor'(X, Y). + +-spec bitwise_shift_left(integer(), integer()) -> integer(). +bitwise_shift_left(X, Y) -> + erlang:'bsl'(X, Y). + +-spec bitwise_shift_right(integer(), integer()) -> integer(). +bitwise_shift_right(X, Y) -> + erlang:'bsr'(X, Y). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl new file mode 100644 index 00000000000..82865bbafa6 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@io.erl @@ -0,0 +1,27 @@ +-module(gleam@io). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([print/1, print_error/1, println/1, println_error/1, debug/1]). + +-spec print(binary()) -> nil. +print(String) -> + gleam_stdlib:print(String). + +-spec print_error(binary()) -> nil. +print_error(String) -> + gleam_stdlib:print_error(String). + +-spec println(binary()) -> nil. +println(String) -> + gleam_stdlib:println(String). + +-spec println_error(binary()) -> nil. +println_error(String) -> + gleam_stdlib:println_error(String). + +-spec debug(ENH) -> ENH. +debug(Term) -> + _pipe = Term, + _pipe@1 = gleam@string:inspect(_pipe), + gleam_stdlib:println_error(_pipe@1), + Term. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl new file mode 100644 index 00000000000..a667ae1ac4b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@iterator.erl @@ -0,0 +1,744 @@ +-module(gleam@iterator). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). +-export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). + +-type action(BSC) :: stop | {continue, BSC, fun(() -> action(BSC))}. + +-opaque iterator(BSD) :: {iterator, fun(() -> action(BSD))}. + +-type step(BSE, BSF) :: {next, BSE, BSF} | done. + +-type chunk(BSG, BSH) :: {another_by, + list(BSG), + BSH, + BSG, + fun(() -> action(BSG))} | + {last_by, list(BSG)}. + +-type sized_chunk(BSI) :: {another, list(BSI), fun(() -> action(BSI))} | + {last, list(BSI)} | + no_more. + +-spec stop() -> action(any()). +stop() -> + stop. + +-spec do_unfold(BSL, fun((BSL) -> step(BSM, BSL))) -> fun(() -> action(BSM)). +do_unfold(Initial, F) -> + fun() -> case F(Initial) of + {next, X, Acc} -> + {continue, X, do_unfold(Acc, F)}; + + done -> + stop + end end. + +-spec unfold(BSQ, fun((BSQ) -> step(BSR, BSQ))) -> iterator(BSR). +unfold(Initial, F) -> + _pipe = Initial, + _pipe@1 = do_unfold(_pipe, F), + {iterator, _pipe@1}. + +-spec repeatedly(fun(() -> BSV)) -> iterator(BSV). +repeatedly(F) -> + unfold(nil, fun(_) -> {next, F(), nil} end). + +-spec repeat(BSX) -> iterator(BSX). +repeat(X) -> + repeatedly(fun() -> X end). + +-spec from_list(list(BSZ)) -> iterator(BSZ). +from_list(List) -> + Yield = fun(Acc) -> case Acc of + [] -> + done; + + [Head | Tail] -> + {next, Head, Tail} + end end, + unfold(List, Yield). + +-spec do_transform( + fun(() -> action(BTC)), + BTE, + fun((BTE, BTC) -> step(BTF, BTE)) +) -> fun(() -> action(BTF)). +do_transform(Continuation, State, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + case F(State, El) of + done -> + stop; + + {next, Yield, Next_state} -> + {continue, Yield, do_transform(Next, Next_state, F)} + end + end end. + +-spec transform(iterator(BTJ), BTL, fun((BTL, BTJ) -> step(BTM, BTL))) -> iterator(BTM). +transform(Iterator, Initial, F) -> + _pipe = do_transform(erlang:element(2, Iterator), Initial, F), + {iterator, _pipe}. + +-spec do_fold(fun(() -> action(BTQ)), fun((BTS, BTQ) -> BTS), BTS) -> BTS. +do_fold(Continuation, F, Accumulator) -> + case Continuation() of + {continue, Elem, Next} -> + do_fold(Next, F, F(Accumulator, Elem)); + + stop -> + Accumulator + end. + +-spec fold(iterator(BTT), BTV, fun((BTV, BTT) -> BTV)) -> BTV. +fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold(_pipe, F, Initial). + +-spec run(iterator(any())) -> nil. +run(Iterator) -> + fold(Iterator, nil, fun(_, _) -> nil end). + +-spec to_list(iterator(BTY)) -> list(BTY). +to_list(Iterator) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), + gleam@list:reverse(_pipe@1). + +-spec step(iterator(BUB)) -> step(BUB, iterator(BUB)). +step(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + done; + + {continue, E, A} -> + {next, E, {iterator, A}} + end. + +-spec do_take(fun(() -> action(BUG)), integer()) -> fun(() -> action(BUG)). +do_take(Continuation, Desired) -> + fun() -> case Desired > 0 of + false -> + stop; + + true -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, do_take(Next, Desired - 1)} + end + end end. + +-spec take(iterator(BUJ), integer()) -> iterator(BUJ). +take(Iterator, Desired) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take(_pipe, Desired), + {iterator, _pipe@1}. + +-spec do_drop(fun(() -> action(BUM)), integer()) -> action(BUM). +do_drop(Continuation, Desired) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Desired > 0 of + true -> + do_drop(Next, Desired - 1); + + false -> + {continue, E, Next} + end + end. + +-spec drop(iterator(BUP), integer()) -> iterator(BUP). +drop(Iterator, Desired) -> + _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, + {iterator, _pipe}. + +-spec do_map(fun(() -> action(BUS)), fun((BUS) -> BUU)) -> fun(() -> action(BUU)). +do_map(Continuation, F) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, F(E), do_map(Continuation@1, F)} + end end. + +-spec map(iterator(BUW), fun((BUW) -> BUY)) -> iterator(BUY). +map(Iterator, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_map(_pipe, F), + {iterator, _pipe@1}. + +-spec do_map2( + fun(() -> action(BVA)), + fun(() -> action(BVC)), + fun((BVA, BVC) -> BVE) +) -> fun(() -> action(BVE)). +do_map2(Continuation1, Continuation2, Fun) -> + fun() -> case Continuation1() of + stop -> + stop; + + {continue, A, Next_a} -> + case Continuation2() of + stop -> + stop; + + {continue, B, Next_b} -> + {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} + end + end end. + +-spec map2(iterator(BVG), iterator(BVI), fun((BVG, BVI) -> BVK)) -> iterator(BVK). +map2(Iterator1, Iterator2, Fun) -> + _pipe = do_map2( + erlang:element(2, Iterator1), + erlang:element(2, Iterator2), + Fun + ), + {iterator, _pipe}. + +-spec do_append(fun(() -> action(BVM)), fun(() -> action(BVM))) -> action(BVM). +do_append(First, Second) -> + case First() of + {continue, E, First@1} -> + {continue, E, fun() -> do_append(First@1, Second) end}; + + stop -> + Second() + end. + +-spec append(iterator(BVQ), iterator(BVQ)) -> iterator(BVQ). +append(First, Second) -> + _pipe = fun() -> + do_append(erlang:element(2, First), erlang:element(2, Second)) + end, + {iterator, _pipe}. + +-spec do_flatten(fun(() -> action(iterator(BVU)))) -> action(BVU). +do_flatten(Flattened) -> + case Flattened() of + stop -> + stop; + + {continue, It, Next_iterator} -> + do_append( + erlang:element(2, It), + fun() -> do_flatten(Next_iterator) end + ) + end. + +-spec flatten(iterator(iterator(BVY))) -> iterator(BVY). +flatten(Iterator) -> + _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, + {iterator, _pipe}. + +-spec concat(list(iterator(BWC))) -> iterator(BWC). +concat(Iterators) -> + flatten(from_list(Iterators)). + +-spec flat_map(iterator(BWG), fun((BWG) -> iterator(BWI))) -> iterator(BWI). +flat_map(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + flatten(_pipe@1). + +-spec do_filter(fun(() -> action(BWL)), fun((BWL) -> boolean())) -> action(BWL). +do_filter(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Iterator} -> + case Predicate(E) of + true -> + {continue, E, fun() -> do_filter(Iterator, Predicate) end}; + + false -> + do_filter(Iterator, Predicate) + end + end. + +-spec filter(iterator(BWO), fun((BWO) -> boolean())) -> iterator(BWO). +filter(Iterator, Predicate) -> + _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec cycle(iterator(BWR)) -> iterator(BWR). +cycle(Iterator) -> + _pipe = repeat(Iterator), + flatten(_pipe). + +-spec do_find(fun(() -> action(BWV)), fun((BWV) -> boolean())) -> {ok, BWV} | + {error, nil}. +do_find(Continuation, F) -> + case Continuation() of + stop -> + {error, nil}; + + {continue, E, Next} -> + case F(E) of + true -> + {ok, E}; + + false -> + do_find(Next, F) + end + end. + +-spec find(iterator(BWZ), fun((BWZ) -> boolean())) -> {ok, BWZ} | {error, nil}. +find(Haystack, Is_desired) -> + _pipe = erlang:element(2, Haystack), + do_find(_pipe, Is_desired). + +-spec do_index(fun(() -> action(BXD)), integer()) -> fun(() -> action({integer(), + BXD})). +do_index(Continuation, Next) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Continuation@1} -> + {continue, {Next, E}, do_index(Continuation@1, Next + 1)} + end end. + +-spec index(iterator(BXG)) -> iterator({integer(), BXG}). +index(Iterator) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_index(_pipe, 0), + {iterator, _pipe@1}. + +-spec iterate(BXJ, fun((BXJ) -> BXJ)) -> iterator(BXJ). +iterate(Initial, F) -> + unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). + +-spec do_take_while(fun(() -> action(BXL)), fun((BXL) -> boolean())) -> fun(() -> action(BXL)). +do_take_while(Continuation, Predicate) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + stop; + + true -> + {continue, E, do_take_while(Next, Predicate)} + end + end end. + +-spec take_while(iterator(BXO), fun((BXO) -> boolean())) -> iterator(BXO). +take_while(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_take_while(_pipe, Predicate), + {iterator, _pipe@1}. + +-spec do_drop_while(fun(() -> action(BXR)), fun((BXR) -> boolean())) -> action(BXR). +do_drop_while(Continuation, Predicate) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + case Predicate(E) of + false -> + {continue, E, Next}; + + true -> + do_drop_while(Next, Predicate) + end + end. + +-spec drop_while(iterator(BXU), fun((BXU) -> boolean())) -> iterator(BXU). +drop_while(Iterator, Predicate) -> + _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, + {iterator, _pipe}. + +-spec do_scan(fun(() -> action(BXX)), fun((BXZ, BXX) -> BXZ), BXZ) -> fun(() -> action(BXZ)). +do_scan(Continuation, F, Accumulator) -> + fun() -> case Continuation() of + stop -> + stop; + + {continue, El, Next} -> + Accumulated = F(Accumulator, El), + {continue, Accumulated, do_scan(Next, F, Accumulated)} + end end. + +-spec scan(iterator(BYB), BYD, fun((BYD, BYB) -> BYD)) -> iterator(BYD). +scan(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_scan(_pipe, F, Initial), + {iterator, _pipe@1}. + +-spec do_zip(fun(() -> action(BYF)), fun(() -> action(BYH))) -> fun(() -> action({BYF, + BYH})). +do_zip(Left, Right) -> + fun() -> case Left() of + stop -> + stop; + + {continue, El_left, Next_left} -> + case Right() of + stop -> + stop; + + {continue, El_right, Next_right} -> + {continue, + {El_left, El_right}, + do_zip(Next_left, Next_right)} + end + end end. + +-spec zip(iterator(BYK), iterator(BYM)) -> iterator({BYK, BYM}). +zip(Left, Right) -> + _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), + {iterator, _pipe}. + +-spec next_chunk(fun(() -> action(BYP)), fun((BYP) -> BYR), BYR, list(BYP)) -> chunk(BYP, BYR). +next_chunk(Continuation, F, Previous_key, Current_chunk) -> + case Continuation() of + stop -> + {last_by, gleam@list:reverse(Current_chunk)}; + + {continue, E, Next} -> + Key = F(E), + case Key =:= Previous_key of + true -> + next_chunk(Next, F, Key, [E | Current_chunk]); + + false -> + {another_by, + gleam@list:reverse(Current_chunk), + Key, + E, + Next} + end + end. + +-spec do_chunk(fun(() -> action(BYV)), fun((BYV) -> BYX), BYX, BYV) -> action(list(BYV)). +do_chunk(Continuation, F, Previous_key, Previous_element) -> + case next_chunk(Continuation, F, Previous_key, [Previous_element]) of + {last_by, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another_by, Chunk@1, Key, El, Next} -> + {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} + end. + +-spec chunk(iterator(BZA), fun((BZA) -> any())) -> iterator(list(BZA)). +chunk(Iterator, F) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + do_chunk(Next, F, F(E), E) + end end, + {iterator, _pipe}. + +-spec next_sized_chunk(fun(() -> action(BZF)), integer(), list(BZF)) -> sized_chunk(BZF). +next_sized_chunk(Continuation, Left, Current_chunk) -> + case Continuation() of + stop -> + case Current_chunk of + [] -> + no_more; + + Remaining -> + {last, gleam@list:reverse(Remaining)} + end; + + {continue, E, Next} -> + Chunk = [E | Current_chunk], + case Left > 1 of + false -> + {another, gleam@list:reverse(Chunk), Next}; + + true -> + next_sized_chunk(Next, Left - 1, Chunk) + end + end. + +-spec do_sized_chunk(fun(() -> action(BZJ)), integer()) -> fun(() -> action(list(BZJ))). +do_sized_chunk(Continuation, Count) -> + fun() -> case next_sized_chunk(Continuation, Count, []) of + no_more -> + stop; + + {last, Chunk} -> + {continue, Chunk, fun stop/0}; + + {another, Chunk@1, Next_element} -> + {continue, Chunk@1, do_sized_chunk(Next_element, Count)} + end end. + +-spec sized_chunk(iterator(BZN), integer()) -> iterator(list(BZN)). +sized_chunk(Iterator, Count) -> + _pipe = erlang:element(2, Iterator), + _pipe@1 = do_sized_chunk(_pipe, Count), + {iterator, _pipe@1}. + +-spec do_intersperse(fun(() -> action(BZR)), BZR) -> action(BZR). +do_intersperse(Continuation, Separator) -> + case Continuation() of + stop -> + stop; + + {continue, E, Next} -> + Next_interspersed = fun() -> do_intersperse(Next, Separator) end, + {continue, Separator, fun() -> {continue, E, Next_interspersed} end} + end. + +-spec intersperse(iterator(BZU), BZU) -> iterator(BZU). +intersperse(Iterator, Elem) -> + _pipe = fun() -> case (erlang:element(2, Iterator))() of + stop -> + stop; + + {continue, E, Next} -> + {continue, E, fun() -> do_intersperse(Next, Elem) end} + end end, + {iterator, _pipe}. + +-spec do_any(fun(() -> action(BZX)), fun((BZX) -> boolean())) -> boolean(). +do_any(Continuation, Predicate) -> + case Continuation() of + stop -> + false; + + {continue, E, Next} -> + case Predicate(E) of + true -> + true; + + false -> + do_any(Next, Predicate) + end + end. + +-spec any(iterator(BZZ), fun((BZZ) -> boolean())) -> boolean(). +any(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_any(_pipe, Predicate). + +-spec do_all(fun(() -> action(CAB)), fun((CAB) -> boolean())) -> boolean(). +do_all(Continuation, Predicate) -> + case Continuation() of + stop -> + true; + + {continue, E, Next} -> + case Predicate(E) of + true -> + do_all(Next, Predicate); + + false -> + false + end + end. + +-spec all(iterator(CAD), fun((CAD) -> boolean())) -> boolean(). +all(Iterator, Predicate) -> + _pipe = erlang:element(2, Iterator), + do_all(_pipe, Predicate). + +-spec update_group_with(CAF) -> fun((gleam@option:option(list(CAF))) -> list(CAF)). +update_group_with(El) -> + fun(Maybe_group) -> case Maybe_group of + {some, Group} -> + [El | Group]; + + none -> + [El] + end end. + +-spec group_updater(fun((CAJ) -> CAK)) -> fun((gleam@dict:dict(CAK, list(CAJ)), CAJ) -> gleam@dict:dict(CAK, list(CAJ))). +group_updater(F) -> + fun(Groups, Elem) -> _pipe = Groups, + gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. + +-spec group(iterator(CAR), fun((CAR) -> CAT)) -> gleam@dict:dict(CAT, list(CAR)). +group(Iterator, Key) -> + _pipe = Iterator, + _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), + gleam@dict:map_values( + _pipe@1, + fun(_, Group) -> gleam@list:reverse(Group) end + ). + +-spec reduce(iterator(CAX), fun((CAX, CAX) -> CAX)) -> {ok, CAX} | {error, nil}. +reduce(Iterator, F) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, Next} -> + _pipe = do_fold(Next, F, E), + {ok, _pipe} + end. + +-spec last(iterator(CBB)) -> {ok, CBB} | {error, nil}. +last(Iterator) -> + _pipe = Iterator, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec empty() -> iterator(any()). +empty() -> + {iterator, fun stop/0}. + +-spec once(fun(() -> CBH)) -> iterator(CBH). +once(F) -> + _pipe = fun() -> {continue, F(), fun stop/0} end, + {iterator, _pipe}. + +-spec range(integer(), integer()) -> iterator(integer()). +range(Start, Stop) -> + case gleam@int:compare(Start, Stop) of + eq -> + once(fun() -> Start end); + + gt -> + unfold(Start, fun(Current) -> case Current < Stop of + false -> + {next, Current, Current - 1}; + + true -> + done + end end); + + lt -> + unfold(Start, fun(Current@1) -> case Current@1 > Stop of + false -> + {next, Current@1, Current@1 + 1}; + + true -> + done + end end) + end. + +-spec single(CBJ) -> iterator(CBJ). +single(Elem) -> + once(fun() -> Elem end). + +-spec do_interleave(fun(() -> action(CBL)), fun(() -> action(CBL))) -> action(CBL). +do_interleave(Current, Next) -> + case Current() of + stop -> + Next(); + + {continue, E, Next_other} -> + {continue, E, fun() -> do_interleave(Next, Next_other) end} + end. + +-spec interleave(iterator(CBP), iterator(CBP)) -> iterator(CBP). +interleave(Left, Right) -> + _pipe = fun() -> + do_interleave(erlang:element(2, Left), erlang:element(2, Right)) + end, + {iterator, _pipe}. + +-spec do_fold_until( + fun(() -> action(CBT)), + fun((CBV, CBT) -> gleam@list:continue_or_stop(CBV)), + CBV +) -> CBV. +do_fold_until(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + Accumulator; + + {continue, Elem, Next} -> + case F(Accumulator, Elem) of + {continue, Accumulator@1} -> + do_fold_until(Next, F, Accumulator@1); + + {stop, Accumulator@2} -> + Accumulator@2 + end + end. + +-spec fold_until( + iterator(CBX), + CBZ, + fun((CBZ, CBX) -> gleam@list:continue_or_stop(CBZ)) +) -> CBZ. +fold_until(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_fold_until(_pipe, F, Initial). + +-spec do_try_fold( + fun(() -> action(CCB)), + fun((CCD, CCB) -> {ok, CCD} | {error, CCE}), + CCD +) -> {ok, CCD} | {error, CCE}. +do_try_fold(Continuation, F, Accumulator) -> + case Continuation() of + stop -> + {ok, Accumulator}; + + {continue, Elem, Next} -> + gleam@result:'try'( + F(Accumulator, Elem), + fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end + ) + end. + +-spec try_fold(iterator(CCJ), CCL, fun((CCL, CCJ) -> {ok, CCL} | {error, CCM})) -> {ok, + CCL} | + {error, CCM}. +try_fold(Iterator, Initial, F) -> + _pipe = erlang:element(2, Iterator), + do_try_fold(_pipe, F, Initial). + +-spec first(iterator(CCR)) -> {ok, CCR} | {error, nil}. +first(Iterator) -> + case (erlang:element(2, Iterator))() of + stop -> + {error, nil}; + + {continue, E, _} -> + {ok, E} + end. + +-spec at(iterator(CCV), integer()) -> {ok, CCV} | {error, nil}. +at(Iterator, Index) -> + _pipe = Iterator, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1). + +-spec do_length(fun(() -> action(any())), integer()) -> integer(). +do_length(Continuation, Length) -> + case Continuation() of + stop -> + Length; + + {continue, _, Next} -> + do_length(Next, Length + 1) + end. + +-spec length(iterator(any())) -> integer(). +length(Iterator) -> + _pipe = erlang:element(2, Iterator), + do_length(_pipe, 0). + +-spec each(iterator(CDD), fun((CDD) -> any())) -> nil. +each(Iterator, F) -> + _pipe = Iterator, + _pipe@1 = map(_pipe, F), + run(_pipe@1). + +-spec yield(CDG, fun(() -> iterator(CDG))) -> iterator(CDG). +yield(Element, Next) -> + {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl new file mode 100644 index 00000000000..cb6c9e44af2 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@list.erl @@ -0,0 +1,1136 @@ +-module(gleam@list). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). +-export_type([length_mismatch/0, continue_or_stop/1]). + +-type length_mismatch() :: length_mismatch. + +-type continue_or_stop(XA) :: {continue, XA} | {stop, XA}. + +-spec length(list(any())) -> integer(). +length(List) -> + erlang:length(List). + +-spec reverse(list(XF)) -> list(XF). +reverse(Xs) -> + lists:reverse(Xs). + +-spec is_empty(list(any())) -> boolean(). +is_empty(List) -> + List =:= []. + +-spec contains(list(XN), XN) -> boolean(). +contains(List, Elem) -> + case List of + [] -> + false; + + [First | _] when First =:= Elem -> + true; + + [_ | Rest] -> + contains(Rest, Elem) + end. + +-spec first(list(XP)) -> {ok, XP} | {error, nil}. +first(List) -> + case List of + [] -> + {error, nil}; + + [X | _] -> + {ok, X} + end. + +-spec rest(list(XT)) -> {ok, list(XT)} | {error, nil}. +rest(List) -> + case List of + [] -> + {error, nil}; + + [_ | Xs] -> + {ok, Xs} + end. + +-spec update_group(fun((XY) -> XZ)) -> fun((gleam@dict:dict(XZ, list(XY)), XY) -> gleam@dict:dict(XZ, list(XY))). +update_group(F) -> + fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of + {ok, Existing} -> + gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); + + {error, _} -> + gleam@dict:insert(Groups, F(Elem), [Elem]) + end end. + +-spec do_filter(list(YM), fun((YM) -> boolean()), list(YM)) -> list(YM). +do_filter(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + true -> + [X | Acc]; + + false -> + Acc + end, + do_filter(Xs, Fun, New_acc) + end. + +-spec filter(list(YQ), fun((YQ) -> boolean())) -> list(YQ). +filter(List, Predicate) -> + do_filter(List, Predicate, []). + +-spec do_filter_map(list(YT), fun((YT) -> {ok, YV} | {error, any()}), list(YV)) -> list(YV). +do_filter_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + New_acc = case Fun(X) of + {ok, X@1} -> + [X@1 | Acc]; + + {error, _} -> + Acc + end, + do_filter_map(Xs, Fun, New_acc) + end. + +-spec filter_map(list(AAB), fun((AAB) -> {ok, AAD} | {error, any()})) -> list(AAD). +filter_map(List, Fun) -> + do_filter_map(List, Fun, []). + +-spec do_map(list(AAI), fun((AAI) -> AAK), list(AAK)) -> list(AAK). +do_map(List, Fun, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_map(Xs, Fun, [Fun(X) | Acc]) + end. + +-spec map(list(AAN), fun((AAN) -> AAP)) -> list(AAP). +map(List, Fun) -> + do_map(List, Fun, []). + +-spec do_map2(list(AAX), list(AAZ), fun((AAX, AAZ) -> ABB), list(ABB)) -> list(ABB). +do_map2(List1, List2, Fun, Acc) -> + case {List1, List2} of + {[], _} -> + reverse(Acc); + + {_, []} -> + reverse(Acc); + + {[A | As_], [B | Bs]} -> + do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) + end. + +-spec map2(list(AAR), list(AAT), fun((AAR, AAT) -> AAV)) -> list(AAV). +map2(List1, List2, Fun) -> + do_map2(List1, List2, Fun, []). + +-spec do_index_map( + list(ABJ), + fun((integer(), ABJ) -> ABL), + integer(), + list(ABL) +) -> list(ABL). +do_index_map(List, Fun, Index, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + Acc@1 = [Fun(Index, X) | Acc], + do_index_map(Xs, Fun, Index + 1, Acc@1) + end. + +-spec index_map(list(ABO), fun((integer(), ABO) -> ABQ)) -> list(ABQ). +index_map(List, Fun) -> + do_index_map(List, Fun, 0, []). + +-spec do_try_map(list(ABS), fun((ABS) -> {ok, ABU} | {error, ABV}), list(ABU)) -> {ok, + list(ABU)} | + {error, ABV}. +do_try_map(List, Fun, Acc) -> + case List of + [] -> + {ok, reverse(Acc)}; + + [X | Xs] -> + case Fun(X) of + {ok, Y} -> + do_try_map(Xs, Fun, [Y | Acc]); + + {error, Error} -> + {error, Error} + end + end. + +-spec try_map(list(ACC), fun((ACC) -> {ok, ACE} | {error, ACF})) -> {ok, + list(ACE)} | + {error, ACF}. +try_map(List, Fun) -> + do_try_map(List, Fun, []). + +-spec drop(list(ACL), integer()) -> list(ACL). +drop(List, N) -> + case N =< 0 of + true -> + List; + + false -> + case List of + [] -> + []; + + [_ | Xs] -> + drop(Xs, N - 1) + end + end. + +-spec do_take(list(ACO), integer(), list(ACO)) -> list(ACO). +do_take(List, N, Acc) -> + case N =< 0 of + true -> + reverse(Acc); + + false -> + case List of + [] -> + reverse(Acc); + + [X | Xs] -> + do_take(Xs, N - 1, [X | Acc]) + end + end. + +-spec take(list(ACS), integer()) -> list(ACS). +take(List, N) -> + do_take(List, N, []). + +-spec new() -> list(any()). +new() -> + []. + +-spec append(list(ACX), list(ACX)) -> list(ACX). +append(First, Second) -> + lists:append(First, Second). + +-spec prepend(list(ADF), ADF) -> list(ADF). +prepend(List, Item) -> + [Item | List]. + +-spec reverse_and_prepend(list(ADI), list(ADI)) -> list(ADI). +reverse_and_prepend(Prefix, Suffix) -> + case Prefix of + [] -> + Suffix; + + [First | Rest] -> + reverse_and_prepend(Rest, [First | Suffix]) + end. + +-spec do_concat(list(list(ADM)), list(ADM)) -> list(ADM). +do_concat(Lists, Acc) -> + case Lists of + [] -> + reverse(Acc); + + [List | Further_lists] -> + do_concat(Further_lists, reverse_and_prepend(List, Acc)) + end. + +-spec concat(list(list(ADR))) -> list(ADR). +concat(Lists) -> + do_concat(Lists, []). + +-spec flatten(list(list(ADV))) -> list(ADV). +flatten(Lists) -> + do_concat(Lists, []). + +-spec flat_map(list(ADZ), fun((ADZ) -> list(AEB))) -> list(AEB). +flat_map(List, Fun) -> + _pipe = map(List, Fun), + concat(_pipe). + +-spec fold(list(AEE), AEG, fun((AEG, AEE) -> AEG)) -> AEG. +fold(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + fold(Rest, Fun(Initial, X), Fun) + end. + +-spec group(list(YG), fun((YG) -> YI)) -> gleam@dict:dict(YI, list(YG)). +group(List, Key) -> + fold(List, gleam@dict:new(), update_group(Key)). + +-spec map_fold(list(ABE), ABG, fun((ABG, ABE) -> {ABG, ABH})) -> {ABG, + list(ABH)}. +map_fold(List, Acc, Fun) -> + _pipe = fold( + List, + {Acc, []}, + fun(Acc@1, Item) -> + {Current_acc, Items} = Acc@1, + {Next_acc, Next_item} = Fun(Current_acc, Item), + {Next_acc, [Next_item | Items]} + end + ), + gleam@pair:map_second(_pipe, fun reverse/1). + +-spec fold_right(list(AEH), AEJ, fun((AEJ, AEH) -> AEJ)) -> AEJ. +fold_right(List, Initial, Fun) -> + case List of + [] -> + Initial; + + [X | Rest] -> + Fun(fold_right(Rest, Initial, Fun), X) + end. + +-spec do_index_fold( + list(AEK), + AEM, + fun((AEM, AEK, integer()) -> AEM), + integer() +) -> AEM. +do_index_fold(Over, Acc, With, Index) -> + case Over of + [] -> + Acc; + + [First | Rest] -> + do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) + end. + +-spec index_fold(list(AEN), AEP, fun((AEP, AEN, integer()) -> AEP)) -> AEP. +index_fold(Over, Initial, Fun) -> + do_index_fold(Over, Initial, Fun, 0). + +-spec try_fold(list(AEQ), AES, fun((AES, AEQ) -> {ok, AES} | {error, AET})) -> {ok, + AES} | + {error, AET}. +try_fold(Collection, Accumulator, Fun) -> + case Collection of + [] -> + {ok, Accumulator}; + + [First | Rest] -> + case Fun(Accumulator, First) of + {ok, Result} -> + try_fold(Rest, Result, Fun); + + {error, _} = Error -> + Error + end + end. + +-spec fold_until(list(AEY), AFA, fun((AFA, AEY) -> continue_or_stop(AFA))) -> AFA. +fold_until(Collection, Accumulator, Fun) -> + case Collection of + [] -> + Accumulator; + + [First | Rest] -> + case Fun(Accumulator, First) of + {continue, Next_accumulator} -> + fold_until(Rest, Next_accumulator, Fun); + + {stop, B} -> + B + end + end. + +-spec find(list(AFC), fun((AFC) -> boolean())) -> {ok, AFC} | {error, nil}. +find(Haystack, Is_desired) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Is_desired(X) of + true -> + {ok, X}; + + _ -> + find(Rest, Is_desired) + end + end. + +-spec find_map(list(AFG), fun((AFG) -> {ok, AFI} | {error, any()})) -> {ok, AFI} | + {error, nil}. +find_map(Haystack, Fun) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Fun(X) of + {ok, X@1} -> + {ok, X@1}; + + _ -> + find_map(Rest, Fun) + end + end. + +-spec all(list(AFO), fun((AFO) -> boolean())) -> boolean(). +all(List, Predicate) -> + case List of + [] -> + true; + + [First | Rest] -> + case Predicate(First) of + true -> + all(Rest, Predicate); + + false -> + false + end + end. + +-spec any(list(AFQ), fun((AFQ) -> boolean())) -> boolean(). +any(List, Predicate) -> + case List of + [] -> + false; + + [First | Rest] -> + case Predicate(First) of + true -> + true; + + false -> + any(Rest, Predicate) + end + end. + +-spec do_zip(list(AFS), list(AFU), list({AFS, AFU})) -> list({AFS, AFU}). +do_zip(Xs, Ys, Acc) -> + case {Xs, Ys} of + {[X | Xs@1], [Y | Ys@1]} -> + do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); + + {_, _} -> + reverse(Acc) + end. + +-spec zip(list(AFY), list(AGA)) -> list({AFY, AGA}). +zip(List, Other) -> + do_zip(List, Other, []). + +-spec strict_zip(list(AGD), list(AGF)) -> {ok, list({AGD, AGF})} | + {error, length_mismatch()}. +strict_zip(List, Other) -> + case length(List) =:= length(Other) of + true -> + {ok, zip(List, Other)}; + + false -> + {error, length_mismatch} + end. + +-spec do_unzip(list({AVX, AVY}), list(AVX), list(AVY)) -> {list(AVX), list(AVY)}. +do_unzip(Input, Xs, Ys) -> + case Input of + [] -> + {reverse(Xs), reverse(Ys)}; + + [{X, Y} | Rest] -> + do_unzip(Rest, [X | Xs], [Y | Ys]) + end. + +-spec unzip(list({AGO, AGP})) -> {list(AGO), list(AGP)}. +unzip(Input) -> + do_unzip(Input, [], []). + +-spec do_intersperse(list(AGT), AGT, list(AGT)) -> list(AGT). +do_intersperse(List, Separator, Acc) -> + case List of + [] -> + reverse(Acc); + + [X | Rest] -> + do_intersperse(Rest, Separator, [X, Separator | Acc]) + end. + +-spec intersperse(list(AGX), AGX) -> list(AGX). +intersperse(List, Elem) -> + case List of + [] -> + List; + + [_] -> + List; + + [X | Rest] -> + do_intersperse(Rest, Elem, [X]) + end. + +-spec at(list(AHA), integer()) -> {ok, AHA} | {error, nil}. +at(List, Index) -> + case Index >= 0 of + true -> + _pipe = List, + _pipe@1 = drop(_pipe, Index), + first(_pipe@1); + + false -> + {error, nil} + end. + +-spec unique(list(AHE)) -> list(AHE). +unique(List) -> + case List of + [] -> + []; + + [X | Rest] -> + [X | unique(filter(Rest, fun(Y) -> Y /= X end))] + end. + +-spec merge_up( + integer(), + integer(), + list(AHH), + list(AHH), + list(AHH), + fun((AHH, AHH) -> gleam@order:order()) +) -> list(AHH). +merge_up(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Ax@1, Bx@1) of + gt -> + merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); + + _ -> + merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) + end; + + {_, _, _, _} -> + Acc + end. + +-spec merge_down( + integer(), + integer(), + list(AHM), + list(AHM), + list(AHM), + fun((AHM, AHM) -> gleam@order:order()) +) -> list(AHM). +merge_down(Na, Nb, A, B, Acc, Compare) -> + case {Na, Nb, A, B} of + {0, 0, _, _} -> + Acc; + + {_, 0, [Ax | Ar], _} -> + merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); + + {0, _, _, [Bx | Br]} -> + merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); + + {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> + case Compare(Bx@1, Ax@1) of + lt -> + merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); + + _ -> + merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) + end; + + {_, _, _, _} -> + Acc + end. + +-spec merge_sort( + list(AHR), + integer(), + fun((AHR, AHR) -> gleam@order:order()), + boolean() +) -> list(AHR). +merge_sort(L, Ln, Compare, Down) -> + N = Ln div 2, + A = L, + B = drop(L, N), + case Ln < 3 of + true -> + case Down of + true -> + merge_down(N, Ln - N, A, B, [], Compare); + + false -> + merge_up(N, Ln - N, A, B, [], Compare) + end; + + false -> + case Down of + true -> + merge_down( + N, + Ln - N, + merge_sort(A, N, Compare, false), + merge_sort(B, Ln - N, Compare, false), + [], + Compare + ); + + false -> + merge_up( + N, + Ln - N, + merge_sort(A, N, Compare, true), + merge_sort(B, Ln - N, Compare, true), + [], + Compare + ) + end + end. + +-spec sort(list(AHU), fun((AHU, AHU) -> gleam@order:order())) -> list(AHU). +sort(List, Compare) -> + merge_sort(List, length(List), Compare, true). + +-spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). +tail_recursive_range(Start, Stop, Acc) -> + case gleam@int:compare(Start, Stop) of + eq -> + [Stop | Acc]; + + gt -> + tail_recursive_range(Start, Stop + 1, [Stop | Acc]); + + lt -> + tail_recursive_range(Start, Stop - 1, [Stop | Acc]) + end. + +-spec range(integer(), integer()) -> list(integer()). +range(Start, Stop) -> + tail_recursive_range(Start, Stop, []). + +-spec do_repeat(AIA, integer(), list(AIA)) -> list(AIA). +do_repeat(A, Times, Acc) -> + case Times =< 0 of + true -> + Acc; + + false -> + do_repeat(A, Times - 1, [A | Acc]) + end. + +-spec repeat(AID, integer()) -> list(AID). +repeat(A, Times) -> + do_repeat(A, Times, []). + +-spec do_split(list(AIF), integer(), list(AIF)) -> {list(AIF), list(AIF)}. +do_split(List, N, Taken) -> + case N =< 0 of + true -> + {reverse(Taken), List}; + + false -> + case List of + [] -> + {reverse(Taken), []}; + + [X | Xs] -> + do_split(Xs, N - 1, [X | Taken]) + end + end. + +-spec split(list(AIK), integer()) -> {list(AIK), list(AIK)}. +split(List, Index) -> + do_split(List, Index, []). + +-spec do_split_while(list(AIO), fun((AIO) -> boolean()), list(AIO)) -> {list(AIO), + list(AIO)}. +do_split_while(List, F, Acc) -> + case List of + [] -> + {reverse(Acc), []}; + + [X | Xs] -> + case F(X) of + false -> + {reverse(Acc), List}; + + _ -> + do_split_while(Xs, F, [X | Acc]) + end + end. + +-spec split_while(list(AIT), fun((AIT) -> boolean())) -> {list(AIT), list(AIT)}. +split_while(List, Predicate) -> + do_split_while(List, Predicate, []). + +-spec key_find(list({AIX, AIY}), AIX) -> {ok, AIY} | {error, nil}. +key_find(Keyword_list, Desired_key) -> + find_map( + Keyword_list, + fun(Keyword) -> + {Key, Value} = Keyword, + case Key =:= Desired_key of + true -> + {ok, Value}; + + false -> + {error, nil} + end + end + ). + +-spec key_filter(list({AJC, AJD}), AJC) -> list(AJD). +key_filter(Keyword_list, Desired_key) -> + filter_map( + Keyword_list, + fun(Keyword) -> + {Key, Value} = Keyword, + case Key =:= Desired_key of + true -> + {ok, Value}; + + false -> + {error, nil} + end + end + ). + +-spec do_pop(list(AZQ), fun((AZQ) -> boolean()), list(AZQ)) -> {ok, + {AZQ, list(AZQ)}} | + {error, nil}. +do_pop(Haystack, Predicate, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Predicate(X) of + true -> + {ok, {X, append(reverse(Checked), Rest)}}; + + false -> + do_pop(Rest, Predicate, [X | Checked]) + end + end. + +-spec pop(list(AJK), fun((AJK) -> boolean())) -> {ok, {AJK, list(AJK)}} | + {error, nil}. +pop(Haystack, Is_desired) -> + do_pop(Haystack, Is_desired, []). + +-spec do_pop_map(list(BAE), fun((BAE) -> {ok, BAR} | {error, any()}), list(BAE)) -> {ok, + {BAR, list(BAE)}} | + {error, nil}. +do_pop_map(Haystack, Mapper, Checked) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Mapper(X) of + {ok, Y} -> + {ok, {Y, append(reverse(Checked), Rest)}}; + + {error, _} -> + do_pop_map(Rest, Mapper, [X | Checked]) + end + end. + +-spec pop_map(list(AJT), fun((AJT) -> {ok, AJV} | {error, any()})) -> {ok, + {AJV, list(AJT)}} | + {error, nil}. +pop_map(Haystack, Is_desired) -> + do_pop_map(Haystack, Is_desired, []). + +-spec key_pop(list({AKC, AKD}), AKC) -> {ok, {AKD, list({AKC, AKD})}} | + {error, nil}. +key_pop(Haystack, Key) -> + pop_map( + Haystack, + fun(Entry) -> + {K, V} = Entry, + case K of + K@1 when K@1 =:= Key -> + {ok, V}; + + _ -> + {error, nil} + end + end + ). + +-spec key_set(list({AKI, AKJ}), AKI, AKJ) -> list({AKI, AKJ}). +key_set(List, Key, Value) -> + case List of + [] -> + [{Key, Value}]; + + [{K, _} | Rest] when K =:= Key -> + [{Key, Value} | Rest]; + + [First | Rest@1] -> + [First | key_set(Rest@1, Key, Value)] + end. + +-spec each(list(AKM), fun((AKM) -> any())) -> nil. +each(List, F) -> + case List of + [] -> + nil; + + [X | Xs] -> + F(X), + each(Xs, F) + end. + +-spec try_each(list(AKP), fun((AKP) -> {ok, any()} | {error, AKS})) -> {ok, nil} | + {error, AKS}. +try_each(List, Fun) -> + case List of + [] -> + {ok, nil}; + + [X | Xs] -> + case Fun(X) of + {ok, _} -> + try_each(Xs, Fun); + + {error, E} -> + {error, E} + end + end. + +-spec do_partition(list(BBY), fun((BBY) -> boolean()), list(BBY), list(BBY)) -> {list(BBY), + list(BBY)}. +do_partition(List, Categorise, Trues, Falses) -> + case List of + [] -> + {reverse(Trues), reverse(Falses)}; + + [X | Xs] -> + case Categorise(X) of + true -> + do_partition(Xs, Categorise, [X | Trues], Falses); + + false -> + do_partition(Xs, Categorise, Trues, [X | Falses]) + end + end. + +-spec partition(list(ALC), fun((ALC) -> boolean())) -> {list(ALC), list(ALC)}. +partition(List, Categorise) -> + do_partition(List, Categorise, [], []). + +-spec permutations(list(ALG)) -> list(list(ALG)). +permutations(L) -> + case L of + [] -> + [[]]; + + _ -> + _pipe = L, + _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, + _pipe@2 = index_fold( + _pipe@1, + [], + fun(Acc, J, J_idx) -> case I_idx =:= J_idx of + true -> + Acc; + + false -> + [J | Acc] + end end + ), + _pipe@3 = reverse(_pipe@2), + _pipe@4 = permutations(_pipe@3), + map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), + concat(_pipe@5) + end. + +-spec do_window(list(list(ALK)), list(ALK), integer()) -> list(list(ALK)). +do_window(Acc, L, N) -> + Window = take(L, N), + case length(Window) =:= N of + true -> + do_window([Window | Acc], drop(L, 1), N); + + false -> + Acc + end. + +-spec window(list(ALQ), integer()) -> list(list(ALQ)). +window(L, N) -> + _pipe = do_window([], L, N), + reverse(_pipe). + +-spec window_by_2(list(ALU)) -> list({ALU, ALU}). +window_by_2(L) -> + zip(L, drop(L, 1)). + +-spec drop_while(list(ALX), fun((ALX) -> boolean())) -> list(ALX). +drop_while(List, Predicate) -> + case List of + [] -> + []; + + [X | Xs] -> + case Predicate(X) of + true -> + drop_while(Xs, Predicate); + + false -> + [X | Xs] + end + end. + +-spec do_take_while(list(AMA), fun((AMA) -> boolean()), list(AMA)) -> list(AMA). +do_take_while(List, Predicate, Acc) -> + case List of + [] -> + reverse(Acc); + + [First | Rest] -> + case Predicate(First) of + true -> + do_take_while(Rest, Predicate, [First | Acc]); + + false -> + reverse(Acc) + end + end. + +-spec take_while(list(AME), fun((AME) -> boolean())) -> list(AME). +take_while(List, Predicate) -> + do_take_while(List, Predicate, []). + +-spec do_chunk(list(AMH), fun((AMH) -> AMJ), AMJ, list(AMH), list(list(AMH))) -> list(list(AMH)). +do_chunk(List, F, Previous_key, Current_chunk, Acc) -> + case List of + [First | Rest] -> + Key = F(First), + case Key =:= Previous_key of + false -> + New_acc = [reverse(Current_chunk) | Acc], + do_chunk(Rest, F, Key, [First], New_acc); + + _ -> + do_chunk(Rest, F, Key, [First | Current_chunk], Acc) + end; + + _ -> + reverse([reverse(Current_chunk) | Acc]) + end. + +-spec chunk(list(AMP), fun((AMP) -> any())) -> list(list(AMP)). +chunk(List, F) -> + case List of + [] -> + []; + + [First | Rest] -> + do_chunk(Rest, F, F(First), [First], []) + end. + +-spec do_sized_chunk( + list(AMU), + integer(), + integer(), + list(AMU), + list(list(AMU)) +) -> list(list(AMU)). +do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> + case List of + [] -> + case Current_chunk of + [] -> + reverse(Acc); + + Remaining -> + reverse([reverse(Remaining) | Acc]) + end; + + [First | Rest] -> + Chunk = [First | Current_chunk], + case Left > 1 of + false -> + do_sized_chunk( + Rest, + Count, + Count, + [], + [reverse(Chunk) | Acc] + ); + + true -> + do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) + end + end. + +-spec sized_chunk(list(ANB), integer()) -> list(list(ANB)). +sized_chunk(List, Count) -> + do_sized_chunk(List, Count, Count, [], []). + +-spec reduce(list(ANF), fun((ANF, ANF) -> ANF)) -> {ok, ANF} | {error, nil}. +reduce(List, Fun) -> + case List of + [] -> + {error, nil}; + + [First | Rest] -> + {ok, fold(Rest, First, Fun)} + end. + +-spec do_scan(list(ANJ), ANL, list(ANL), fun((ANL, ANJ) -> ANL)) -> list(ANL). +do_scan(List, Accumulator, Accumulated, Fun) -> + case List of + [] -> + reverse(Accumulated); + + [X | Xs] -> + Next = Fun(Accumulator, X), + do_scan(Xs, Next, [Next | Accumulated], Fun) + end. + +-spec scan(list(ANO), ANQ, fun((ANQ, ANO) -> ANQ)) -> list(ANQ). +scan(List, Initial, Fun) -> + do_scan(List, Initial, [], Fun). + +-spec last(list(ANS)) -> {ok, ANS} | {error, nil}. +last(List) -> + _pipe = List, + reduce(_pipe, fun(_, Elem) -> Elem end). + +-spec combinations(list(ANW), integer()) -> list(list(ANW)). +combinations(Items, N) -> + case N of + 0 -> + [[]]; + + _ -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = begin + _pipe = map( + combinations(Xs, N - 1), + fun(Com) -> [X | Com] end + ), + reverse(_pipe) + end, + fold( + First_combinations, + combinations(Xs, N), + fun(Acc, C) -> [C | Acc] end + ) + end + end. + +-spec do_combination_pairs(list(AOA)) -> list(list({AOA, AOA})). +do_combination_pairs(Items) -> + case Items of + [] -> + []; + + [X | Xs] -> + First_combinations = map(Xs, fun(Other) -> {X, Other} end), + [First_combinations | do_combination_pairs(Xs)] + end. + +-spec combination_pairs(list(AOE)) -> list({AOE, AOE}). +combination_pairs(Items) -> + _pipe = do_combination_pairs(Items), + concat(_pipe). + +-spec transpose(list(list(AOL))) -> list(list(AOL)). +transpose(List_of_list) -> + Take_first = fun(List) -> case List of + [] -> + []; + + [F] -> + [F]; + + [F@1 | _] -> + [F@1] + end end, + case List_of_list of + [] -> + []; + + [[] | Xss] -> + transpose(Xss); + + Rows -> + Firsts = begin + _pipe = Rows, + _pipe@1 = map(_pipe, Take_first), + concat(_pipe@1) + end, + Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), + [Firsts | Rest] + end. + +-spec interleave(list(list(AOH))) -> list(AOH). +interleave(List) -> + _pipe = transpose(List), + concat(_pipe). + +-spec do_shuffle_pair_unwrap(list({float(), AOQ}), list(AOQ)) -> list(AOQ). +do_shuffle_pair_unwrap(List, Acc) -> + case List of + [] -> + Acc; + + [Elem_pair | Enumerable] -> + do_shuffle_pair_unwrap( + Enumerable, + [erlang:element(2, Elem_pair) | Acc] + ) + end. + +-spec do_shuffle_by_pair_indexes(list({float(), AOU})) -> list({float(), AOU}). +do_shuffle_by_pair_indexes(List_of_pairs) -> + sort( + List_of_pairs, + fun(A_pair, B_pair) -> + gleam@float:compare( + erlang:element(1, A_pair), + erlang:element(1, B_pair) + ) + end + ). + +-spec shuffle(list(AOX)) -> list(AOX). +shuffle(List) -> + _pipe = List, + _pipe@1 = fold( + _pipe, + [], + fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end + ), + _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), + do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl new file mode 100644 index 00000000000..9f45b107384 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@map.erl @@ -0,0 +1,76 @@ +-module(gleam@map). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). + +-spec size(gleam@dict:dict(any(), any())) -> integer(). +size(Map) -> + gleam@dict:size(Map). + +-spec to_list(gleam@dict:dict(FDE, FDF)) -> list({FDE, FDF}). +to_list(Map) -> + gleam@dict:to_list(Map). + +-spec from_list(list({FDH, FDI})) -> gleam@dict:dict(FDH, FDI). +from_list(List) -> + gleam@dict:from_list(List). + +-spec has_key(gleam@dict:dict(FDM, any()), FDM) -> boolean(). +has_key(Map, Key) -> + gleam@dict:has_key(Map, Key). + +-spec new() -> gleam@dict:dict(any(), any()). +new() -> + gleam@dict:new(). + +-spec get(gleam@dict:dict(FDP, FDQ), FDP) -> {ok, FDQ} | {error, nil}. +get(From, Get) -> + gleam@dict:get(From, Get). + +-spec insert(gleam@dict:dict(FDU, FDV), FDU, FDV) -> gleam@dict:dict(FDU, FDV). +insert(Map, Key, Value) -> + gleam@dict:insert(Map, Key, Value). + +-spec map_values(gleam@dict:dict(FDY, FDZ), fun((FDY, FDZ) -> FEA)) -> gleam@dict:dict(FDY, FEA). +map_values(Map, Fun) -> + gleam@dict:map_values(Map, Fun). + +-spec keys(gleam@dict:dict(FED, any())) -> list(FED). +keys(Map) -> + gleam@dict:keys(Map). + +-spec values(gleam@dict:dict(any(), FEG)) -> list(FEG). +values(Map) -> + gleam@dict:values(Map). + +-spec filter(gleam@dict:dict(FEJ, FEK), fun((FEJ, FEK) -> boolean())) -> gleam@dict:dict(FEJ, FEK). +filter(Map, Predicate) -> + gleam@dict:filter(Map, Predicate). + +-spec take(gleam@dict:dict(FEN, FGH), list(FEN)) -> gleam@dict:dict(FEN, FGH). +take(Map, Desired_keys) -> + gleam@dict:take(Map, Desired_keys). + +-spec merge(gleam@dict:dict(FGI, FGJ), gleam@dict:dict(FGI, FGJ)) -> gleam@dict:dict(FGI, FGJ). +merge(Map, New_entries) -> + gleam@dict:merge(Map, New_entries). + +-spec delete(gleam@dict:dict(FEU, FGL), FEU) -> gleam@dict:dict(FEU, FGL). +delete(Map, Key) -> + gleam@dict:delete(Map, Key). + +-spec drop(gleam@dict:dict(FEX, FGN), list(FEX)) -> gleam@dict:dict(FEX, FGN). +drop(Map, Disallowed_keys) -> + gleam@dict:drop(Map, Disallowed_keys). + +-spec update( + gleam@dict:dict(FFB, FFC), + FFB, + fun((gleam@option:option(FFC)) -> FFC) +) -> gleam@dict:dict(FFB, FFC). +update(Map, Key, Fun) -> + gleam@dict:update(Map, Key, Fun). + +-spec fold(gleam@dict:dict(FFH, FFI), FFG, fun((FFG, FFH, FFI) -> FFG)) -> FFG. +fold(Map, Initial, Fun) -> + gleam@dict:fold(Map, Initial, Fun). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl new file mode 100644 index 00000000000..812aa1fe854 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@option.erl @@ -0,0 +1,147 @@ +-module(gleam@option). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). +-export_type([option/1]). + +-type option(IY) :: {some, IY} | none. + +-spec do_all(list(option(IZ)), list(IZ)) -> option(list(IZ)). +do_all(List, Acc) -> + case List of + [] -> + {some, Acc}; + + [X | Rest] -> + Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of + {{some, Values}, {some, Value}} -> + {some, [Value | Values]}; + + {_, _} -> + none + end end, + Accumulate(do_all(Rest, Acc), X) + end. + +-spec all(list(option(JF))) -> option(list(JF)). +all(List) -> + do_all(List, []). + +-spec is_some(option(any())) -> boolean(). +is_some(Option) -> + Option /= none. + +-spec is_none(option(any())) -> boolean(). +is_none(Option) -> + Option =:= none. + +-spec to_result(option(JO), JR) -> {ok, JO} | {error, JR}. +to_result(Option, E) -> + case Option of + {some, A} -> + {ok, A}; + + _ -> + {error, E} + end. + +-spec from_result({ok, JU} | {error, any()}) -> option(JU). +from_result(Result) -> + case Result of + {ok, A} -> + {some, A}; + + _ -> + none + end. + +-spec unwrap(option(JZ), JZ) -> JZ. +unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default + end. + +-spec lazy_unwrap(option(KB), fun(() -> KB)) -> KB. +lazy_unwrap(Option, Default) -> + case Option of + {some, X} -> + X; + + none -> + Default() + end. + +-spec map(option(KD), fun((KD) -> KF)) -> option(KF). +map(Option, Fun) -> + case Option of + {some, X} -> + {some, Fun(X)}; + + none -> + none + end. + +-spec flatten(option(option(KH))) -> option(KH). +flatten(Option) -> + case Option of + {some, X} -> + X; + + none -> + none + end. + +-spec then(option(KL), fun((KL) -> option(KN))) -> option(KN). +then(Option, Fun) -> + case Option of + {some, X} -> + Fun(X); + + none -> + none + end. + +-spec 'or'(option(KQ), option(KQ)) -> option(KQ). +'or'(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second + end. + +-spec lazy_or(option(KU), fun(() -> option(KU))) -> option(KU). +lazy_or(First, Second) -> + case First of + {some, _} -> + First; + + none -> + Second() + end. + +-spec do_values(list(option(KY)), list(KY)) -> list(KY). +do_values(List, Acc) -> + case List of + [] -> + Acc; + + [X | Xs] -> + Accumulate = fun(Acc@1, Item) -> case Item of + {some, Value} -> + [Value | Acc@1]; + + none -> + Acc@1 + end end, + Accumulate(do_values(Xs, Acc), X) + end. + +-spec values(list(option(LD))) -> list(LD). +values(Options) -> + do_values(Options, []). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl new file mode 100644 index 00000000000..a9eed8f39c1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@order.erl @@ -0,0 +1,79 @@ +-module(gleam@order). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). +-export_type([order/0]). + +-type order() :: lt | eq | gt. + +-spec negate(order()) -> order(). +negate(Order) -> + case Order of + lt -> + gt; + + eq -> + eq; + + gt -> + lt + end. + +-spec to_int(order()) -> integer(). +to_int(Order) -> + case Order of + lt -> + -1; + + eq -> + 0; + + gt -> + 1 + end. + +-spec compare(order(), order()) -> order(). +compare(A, B) -> + case {A, B} of + {X, Y} when X =:= Y -> + eq; + + {lt, _} -> + lt; + + {eq, gt} -> + lt; + + {_, _} -> + gt + end. + +-spec max(order(), order()) -> order(). +max(A, B) -> + case {A, B} of + {gt, _} -> + gt; + + {eq, lt} -> + eq; + + {_, _} -> + B + end. + +-spec min(order(), order()) -> order(). +min(A, B) -> + case {A, B} of + {lt, _} -> + lt; + + {eq, gt} -> + eq; + + {_, _} -> + B + end. + +-spec reverse(fun((CF, CF) -> order())) -> fun((CF, CF) -> order()). +reverse(Orderer) -> + fun(A, B) -> Orderer(B, A) end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl new file mode 100644 index 00000000000..2452a9817e1 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@pair.erl @@ -0,0 +1,33 @@ +-module(gleam@pair). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). + +-spec first({IJ, any()}) -> IJ. +first(Pair) -> + {A, _} = Pair, + A. + +-spec second({any(), IM}) -> IM. +second(Pair) -> + {_, A} = Pair, + A. + +-spec swap({IN, IO}) -> {IO, IN}. +swap(Pair) -> + {A, B} = Pair, + {B, A}. + +-spec map_first({IP, IQ}, fun((IP) -> IR)) -> {IR, IQ}. +map_first(Pair, Fun) -> + {A, B} = Pair, + {Fun(A), B}. + +-spec map_second({IS, IT}, fun((IT) -> IU)) -> {IS, IU}. +map_second(Pair, Fun) -> + {A, B} = Pair, + {A, Fun(B)}. + +-spec new(IV, IW) -> {IV, IW}. +new(First, Second) -> + {First, Second}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl new file mode 100644 index 00000000000..faec6923a14 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@queue.erl @@ -0,0 +1,121 @@ +-module(gleam@queue). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). +-export_type([queue/1]). + +-opaque queue(EYK) :: {queue, list(EYK), list(EYK)}. + +-spec new() -> queue(any()). +new() -> + {queue, [], []}. + +-spec from_list(list(EYN)) -> queue(EYN). +from_list(List) -> + {queue, [], List}. + +-spec to_list(queue(EYQ)) -> list(EYQ). +to_list(Queue) -> + _pipe = erlang:element(3, Queue), + gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). + +-spec is_empty(queue(any())) -> boolean(). +is_empty(Queue) -> + (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). + +-spec length(queue(any())) -> integer(). +length(Queue) -> + gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( + erlang:element(3, Queue) + ). + +-spec push_back(queue(EYX), EYX) -> queue(EYX). +push_back(Queue, Item) -> + {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. + +-spec push_front(queue(EZA), EZA) -> queue(EZA). +push_front(Queue, Item) -> + {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. + +-spec pop_back(queue(EZD)) -> {ok, {EZD, queue(EZD)}} | {error, nil}. +pop_back(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, [], Out} -> + pop_back({queue, gleam@list:reverse(Out), []}); + + {queue, [First | Rest], Out@1} -> + Queue@1 = {queue, Rest, Out@1}, + {ok, {First, Queue@1}} + end. + +-spec pop_front(queue(EZI)) -> {ok, {EZI, queue(EZI)}} | {error, nil}. +pop_front(Queue) -> + case Queue of + {queue, [], []} -> + {error, nil}; + + {queue, In, []} -> + pop_front({queue, [], gleam@list:reverse(In)}); + + {queue, In@1, [First | Rest]} -> + Queue@1 = {queue, In@1, Rest}, + {ok, {First, Queue@1}} + end. + +-spec reverse(queue(EZN)) -> queue(EZN). +reverse(Queue) -> + {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. + +-spec check_equal( + list(EZQ), + list(EZQ), + list(EZQ), + list(EZQ), + fun((EZQ, EZQ) -> boolean()) +) -> boolean(). +check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> + case {Xs, X_tail, Ys, Y_tail} of + {[], [], [], []} -> + true; + + {[X | Xs@1], _, [Y | Ys@1], _} -> + case Eq(X, Y) of + false -> + false; + + true -> + check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) + end; + + {[], [_ | _], _, _} -> + check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); + + {_, _, [], [_ | _]} -> + check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); + + {_, _, _, _} -> + false + end. + +-spec is_logically_equal(queue(EZV), queue(EZV), fun((EZV, EZV) -> boolean())) -> boolean(). +is_logically_equal(A, B, Element_is_equal) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + Element_is_equal + ). + +-spec is_equal(queue(EZY), queue(EZY)) -> boolean(). +is_equal(A, B) -> + check_equal( + erlang:element(3, A), + erlang:element(2, A), + erlang:element(3, B), + erlang:element(2, B), + fun(A@1, B@1) -> A@1 =:= B@1 end + ). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl new file mode 100644 index 00000000000..2d1c5fc870e --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@regex.erl @@ -0,0 +1,33 @@ +-module(gleam@regex). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([compile/2, from_string/1, check/2, split/2, scan/2]). +-export_type([regex/0, match/0, compile_error/0, options/0]). + +-type regex() :: any(). + +-type match() :: {match, binary(), list(gleam@option:option(binary()))}. + +-type compile_error() :: {compile_error, binary(), integer()}. + +-type options() :: {options, boolean(), boolean()}. + +-spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. +compile(Pattern, Options) -> + gleam_stdlib:compile_regex(Pattern, Options). + +-spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. +from_string(Pattern) -> + compile(Pattern, {options, false, false}). + +-spec check(regex(), binary()) -> boolean(). +check(Regex, Content) -> + gleam_stdlib:regex_check(Regex, Content). + +-spec split(regex(), binary()) -> list(binary()). +split(Regex, String) -> + gleam_stdlib:regex_split(Regex, String). + +-spec scan(regex(), binary()) -> list(match()). +scan(Regex, String) -> + gleam_stdlib:regex_scan(Regex, String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl new file mode 100644 index 00000000000..c80a7048303 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@result.erl @@ -0,0 +1,201 @@ +-module(gleam@result). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). + +-spec is_ok({ok, any()} | {error, any()}) -> boolean(). +is_ok(Result) -> + case Result of + {error, _} -> + false; + + {ok, _} -> + true + end. + +-spec is_error({ok, any()} | {error, any()}) -> boolean(). +is_error(Result) -> + case Result of + {ok, _} -> + false; + + {error, _} -> + true + end. + +-spec map({ok, BIJ} | {error, BIK}, fun((BIJ) -> BIN)) -> {ok, BIN} | + {error, BIK}. +map(Result, Fun) -> + case Result of + {ok, X} -> + {ok, Fun(X)}; + + {error, E} -> + {error, E} + end. + +-spec map_error({ok, BIQ} | {error, BIR}, fun((BIR) -> BIU)) -> {ok, BIQ} | + {error, BIU}. +map_error(Result, Fun) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, Error} -> + {error, Fun(Error)} + end. + +-spec flatten({ok, {ok, BIX} | {error, BIY}} | {error, BIY}) -> {ok, BIX} | + {error, BIY}. +flatten(Result) -> + case Result of + {ok, X} -> + X; + + {error, Error} -> + {error, Error} + end. + +-spec 'try'({ok, BJF} | {error, BJG}, fun((BJF) -> {ok, BJJ} | {error, BJG})) -> {ok, + BJJ} | + {error, BJG}. +'try'(Result, Fun) -> + case Result of + {ok, X} -> + Fun(X); + + {error, E} -> + {error, E} + end. + +-spec then({ok, BJO} | {error, BJP}, fun((BJO) -> {ok, BJS} | {error, BJP})) -> {ok, + BJS} | + {error, BJP}. +then(Result, Fun) -> + 'try'(Result, Fun). + +-spec unwrap({ok, BJX} | {error, any()}, BJX) -> BJX. +unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default + end. + +-spec lazy_unwrap({ok, BKB} | {error, any()}, fun(() -> BKB)) -> BKB. +lazy_unwrap(Result, Default) -> + case Result of + {ok, V} -> + V; + + {error, _} -> + Default() + end. + +-spec unwrap_error({ok, any()} | {error, BKG}, BKG) -> BKG. +unwrap_error(Result, Default) -> + case Result of + {ok, _} -> + Default; + + {error, E} -> + E + end. + +-spec unwrap_both({ok, BKJ} | {error, BKJ}) -> BKJ. +unwrap_both(Result) -> + case Result of + {ok, A} -> + A; + + {error, A@1} -> + A@1 + end. + +-spec nil_error({ok, BKM} | {error, any()}) -> {ok, BKM} | {error, nil}. +nil_error(Result) -> + map_error(Result, fun(_) -> nil end). + +-spec 'or'({ok, BKS} | {error, BKT}, {ok, BKS} | {error, BKT}) -> {ok, BKS} | + {error, BKT}. +'or'(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second + end. + +-spec lazy_or({ok, BLA} | {error, BLB}, fun(() -> {ok, BLA} | {error, BLB})) -> {ok, + BLA} | + {error, BLB}. +lazy_or(First, Second) -> + case First of + {ok, _} -> + First; + + {error, _} -> + Second() + end. + +-spec all(list({ok, BLI} | {error, BLJ})) -> {ok, list(BLI)} | {error, BLJ}. +all(Results) -> + gleam@list:try_map(Results, fun(X) -> X end). + +-spec do_partition(list({ok, BLX} | {error, BLY}), list(BLX), list(BLY)) -> {list(BLX), + list(BLY)}. +do_partition(Results, Oks, Errors) -> + case Results of + [] -> + {Oks, Errors}; + + [{ok, A} | Rest] -> + do_partition(Rest, [A | Oks], Errors); + + [{error, E} | Rest@1] -> + do_partition(Rest@1, Oks, [E | Errors]) + end. + +-spec partition(list({ok, BLQ} | {error, BLR})) -> {list(BLQ), list(BLR)}. +partition(Results) -> + do_partition(Results, [], []). + +-spec replace({ok, any()} | {error, BMG}, BMJ) -> {ok, BMJ} | {error, BMG}. +replace(Result, Value) -> + case Result of + {ok, _} -> + {ok, Value}; + + {error, Error} -> + {error, Error} + end. + +-spec replace_error({ok, BMM} | {error, any()}, BMQ) -> {ok, BMM} | {error, BMQ}. +replace_error(Result, Error) -> + case Result of + {ok, X} -> + {ok, X}; + + {error, _} -> + {error, Error} + end. + +-spec values(list({ok, BMT} | {error, any()})) -> list(BMT). +values(Results) -> + gleam@list:filter_map(Results, fun(R) -> R end). + +-spec try_recover( + {ok, BMZ} | {error, BNA}, + fun((BNA) -> {ok, BMZ} | {error, BND}) +) -> {ok, BMZ} | {error, BND}. +try_recover(Result, Fun) -> + case Result of + {ok, Value} -> + {ok, Value}; + + {error, Error} -> + Fun(Error) + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl new file mode 100644 index 00000000000..3374ebc293f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@set.erl @@ -0,0 +1,85 @@ +-module(gleam@set). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). +-export_type([set/1]). + +-opaque set(EOK) :: {set, gleam@dict:dict(EOK, list(nil))}. + +-spec new() -> set(any()). +new() -> + {set, gleam@dict:new()}. + +-spec size(set(any())) -> integer(). +size(Set) -> + gleam@dict:size(erlang:element(2, Set)). + +-spec insert(set(EOQ), EOQ) -> set(EOQ). +insert(Set, Member) -> + {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. + +-spec contains(set(EOT), EOT) -> boolean(). +contains(Set, Member) -> + _pipe = erlang:element(2, Set), + _pipe@1 = gleam@dict:get(_pipe, Member), + gleam@result:is_ok(_pipe@1). + +-spec delete(set(EOV), EOV) -> set(EOV). +delete(Set, Member) -> + {set, gleam@dict:delete(erlang:element(2, Set), Member)}. + +-spec to_list(set(EOY)) -> list(EOY). +to_list(Set) -> + gleam@dict:keys(erlang:element(2, Set)). + +-spec from_list(list(EPB)) -> set(EPB). +from_list(Members) -> + Map = gleam@list:fold( + Members, + gleam@dict:new(), + fun(M, K) -> gleam@dict:insert(M, K, []) end + ), + {set, Map}. + +-spec fold(set(EPE), EPG, fun((EPG, EPE) -> EPG)) -> EPG. +fold(Set, Initial, Reducer) -> + gleam@dict:fold( + erlang:element(2, Set), + Initial, + fun(A, K, _) -> Reducer(A, K) end + ). + +-spec filter(set(EPH), fun((EPH) -> boolean())) -> set(EPH). +filter(Set, Predicate) -> + {set, + gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. + +-spec drop(set(EPK), list(EPK)) -> set(EPK). +drop(Set, Disallowed) -> + gleam@list:fold(Disallowed, Set, fun delete/2). + +-spec take(set(EPO), list(EPO)) -> set(EPO). +take(Set, Desired) -> + {set, gleam@dict:take(erlang:element(2, Set), Desired)}. + +-spec order(set(EPS), set(EPS)) -> {set(EPS), set(EPS)}. +order(First, Second) -> + case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( + erlang:element(2, Second) + ) of + true -> + {First, Second}; + + false -> + {Second, First} + end. + +-spec union(set(EPX), set(EPX)) -> set(EPX). +union(First, Second) -> + {Larger, Smaller} = order(First, Second), + fold(Smaller, Larger, fun insert/2). + +-spec intersection(set(EQB), set(EQB)) -> set(EQB). +intersection(First, Second) -> + {Larger, Smaller} = order(First, Second), + take(Larger, to_list(Smaller)). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl new file mode 100644 index 00000000000..6cba31d1895 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string.erl @@ -0,0 +1,352 @@ +-module(gleam@string). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). +-export_type([direction/0]). + +-type direction() :: leading | trailing | both. + +-spec is_empty(binary()) -> boolean(). +is_empty(Str) -> + Str =:= <<""/utf8>>. + +-spec length(binary()) -> integer(). +length(String) -> + string:length(String). + +-spec do_reverse(binary()) -> binary(). +do_reverse(String) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:reverse(_pipe@1), + gleam@string_builder:to_string(_pipe@2). + +-spec reverse(binary()) -> binary(). +reverse(String) -> + do_reverse(String). + +-spec replace(binary(), binary(), binary()) -> binary(). +replace(String, Pattern, Substitute) -> + _pipe = String, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), + gleam@string_builder:to_string(_pipe@2). + +-spec lowercase(binary()) -> binary(). +lowercase(String) -> + string:lowercase(String). + +-spec uppercase(binary()) -> binary(). +uppercase(String) -> + string:uppercase(String). + +-spec compare(binary(), binary()) -> gleam@order:order(). +compare(A, B) -> + case A =:= B of + true -> + eq; + + _ -> + case gleam_stdlib:less_than(A, B) of + true -> + lt; + + _ -> + gt + end + end. + +-spec slice(binary(), integer(), integer()) -> binary(). +slice(String, Idx, Len) -> + case Len < 0 of + true -> + <<""/utf8>>; + + false -> + case Idx < 0 of + true -> + Translated_idx = length(String) + Idx, + case Translated_idx < 0 of + true -> + <<""/utf8>>; + + false -> + string:slice(String, Translated_idx, Len) + end; + + false -> + string:slice(String, Idx, Len) + end + end. + +-spec crop(binary(), binary()) -> binary(). +crop(String, Substring) -> + gleam_stdlib:crop_string(String, Substring). + +-spec drop_left(binary(), integer()) -> binary(). +drop_left(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, Num_graphemes, length(String) - Num_graphemes) + end. + +-spec drop_right(binary(), integer()) -> binary(). +drop_right(String, Num_graphemes) -> + case Num_graphemes < 0 of + true -> + String; + + false -> + slice(String, 0, length(String) - Num_graphemes) + end. + +-spec contains(binary(), binary()) -> boolean(). +contains(Haystack, Needle) -> + gleam_stdlib:contains_string(Haystack, Needle). + +-spec starts_with(binary(), binary()) -> boolean(). +starts_with(String, Prefix) -> + gleam_stdlib:string_starts_with(String, Prefix). + +-spec ends_with(binary(), binary()) -> boolean(). +ends_with(String, Suffix) -> + gleam_stdlib:string_ends_with(String, Suffix). + +-spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +do_split_once(X, Substring) -> + case string:split(X, Substring) of + [First, Rest] -> + {ok, {First, Rest}}; + + _ -> + {error, nil} + end. + +-spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | + {error, nil}. +split_once(X, Substring) -> + do_split_once(X, Substring). + +-spec append(binary(), binary()) -> binary(). +append(First, Second) -> + _pipe = First, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:append(_pipe@1, Second), + gleam@string_builder:to_string(_pipe@2). + +-spec concat(list(binary())) -> binary(). +concat(Strings) -> + _pipe = Strings, + _pipe@1 = gleam@string_builder:from_strings(_pipe), + gleam@string_builder:to_string(_pipe@1). + +-spec repeat(binary(), integer()) -> binary(). +repeat(String, Times) -> + _pipe = gleam@iterator:repeat(String), + _pipe@1 = gleam@iterator:take(_pipe, Times), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec do_join(list(binary()), binary()) -> binary(). +do_join(Strings, Separator) -> + _pipe = Strings, + _pipe@1 = gleam@list:intersperse(_pipe, Separator), + concat(_pipe@1). + +-spec join(list(binary()), binary()) -> binary(). +join(Strings, Separator) -> + do_join(Strings, Separator). + +-spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). +padding(Size, Pad_string) -> + Pad_length = length(Pad_string), + Num_pads = case Pad_length of + 0 -> 0; + Gleam@denominator -> Size div Gleam@denominator + end, + Extra = case Pad_length of + 0 -> 0; + Gleam@denominator@1 -> Size rem Gleam@denominator@1 + end, + _pipe = gleam@iterator:repeat(Pad_string), + _pipe@1 = gleam@iterator:take(_pipe, Num_pads), + gleam@iterator:append( + _pipe@1, + gleam@iterator:single(slice(Pad_string, 0, Extra)) + ). + +-spec pad_left(binary(), integer(), binary()) -> binary(). +pad_left(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = padding(To_pad_length, Pad_string), + _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec pad_right(binary(), integer(), binary()) -> binary(). +pad_right(String, Desired_length, Pad_string) -> + Current_length = length(String), + To_pad_length = Desired_length - Current_length, + _pipe = gleam@iterator:single(String), + _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), + _pipe@2 = gleam@iterator:to_list(_pipe@1), + concat(_pipe@2). + +-spec do_trim(binary()) -> binary(). +do_trim(String) -> + string:trim(String, both). + +-spec trim(binary()) -> binary(). +trim(String) -> + do_trim(String). + +-spec do_trim_left(binary()) -> binary(). +do_trim_left(String) -> + string:trim(String, leading). + +-spec trim_left(binary()) -> binary(). +trim_left(String) -> + do_trim_left(String). + +-spec do_trim_right(binary()) -> binary(). +do_trim_right(String) -> + string:trim(String, trailing). + +-spec trim_right(binary()) -> binary(). +trim_right(String) -> + do_trim_right(String). + +-spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. +pop_grapheme(String) -> + gleam_stdlib:string_pop_grapheme(String). + +-spec do_to_graphemes(binary(), list(binary())) -> list(binary()). +do_to_graphemes(String, Acc) -> + case pop_grapheme(String) of + {ok, {Grapheme, Rest}} -> + do_to_graphemes(Rest, [Grapheme | Acc]); + + _ -> + Acc + end. + +-spec to_graphemes(binary()) -> list(binary()). +to_graphemes(String) -> + _pipe = do_to_graphemes(String, []), + gleam@list:reverse(_pipe). + +-spec split(binary(), binary()) -> list(binary()). +split(X, Substring) -> + case Substring of + <<""/utf8>> -> + to_graphemes(X); + + _ -> + _pipe = X, + _pipe@1 = gleam@string_builder:from_string(_pipe), + _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), + gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) + end. + +-spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). +do_to_utf_codepoints_impl(Bit_array, Acc) -> + case Bit_array of + <> -> + do_to_utf_codepoints_impl(Rest, [First | Acc]); + + _ -> + Acc + end. + +-spec do_to_utf_codepoints(binary()) -> list(integer()). +do_to_utf_codepoints(String) -> + _pipe = do_to_utf_codepoints_impl(<>, []), + gleam@list:reverse(_pipe). + +-spec to_utf_codepoints(binary()) -> list(integer()). +to_utf_codepoints(String) -> + do_to_utf_codepoints(String). + +-spec from_utf_codepoints(list(integer())) -> binary(). +from_utf_codepoints(Utf_codepoints) -> + gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). + +-spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. +utf_codepoint(Value) -> + case Value of + I when I > 1114111 -> + {error, nil}; + + 65534 -> + {error, nil}; + + 65535 -> + {error, nil}; + + I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> + {error, nil}; + + I@2 -> + {ok, gleam_stdlib:identity(I@2)} + end. + +-spec utf_codepoint_to_int(integer()) -> integer(). +utf_codepoint_to_int(Cp) -> + gleam_stdlib:identity(Cp). + +-spec to_option(binary()) -> gleam@option:option(binary()). +to_option(S) -> + case S of + <<""/utf8>> -> + none; + + _ -> + {some, S} + end. + +-spec first(binary()) -> {ok, binary()} | {error, nil}. +first(S) -> + case pop_grapheme(S) of + {ok, {First, _}} -> + {ok, First}; + + {error, E} -> + {error, E} + end. + +-spec last(binary()) -> {ok, binary()} | {error, nil}. +last(S) -> + case pop_grapheme(S) of + {ok, {First, <<""/utf8>>}} -> + {ok, First}; + + {ok, {_, Rest}} -> + {ok, slice(Rest, -1, 1)}; + + {error, E} -> + {error, E} + end. + +-spec capitalise(binary()) -> binary(). +capitalise(S) -> + case pop_grapheme(S) of + {ok, {First, Rest}} -> + append(uppercase(First), lowercase(Rest)); + + _ -> + <<""/utf8>> + end. + +-spec inspect(any()) -> binary(). +inspect(Term) -> + _pipe = gleam_stdlib:inspect(Term), + gleam@string_builder:to_string(_pipe). + +-spec byte_size(binary()) -> integer(). +byte_size(String) -> + erlang:byte_size(String). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl new file mode 100644 index 00000000000..693e840f370 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@string_builder.erl @@ -0,0 +1,91 @@ +-module(gleam@string_builder). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). +-export_type([string_builder/0, direction/0]). + +-type string_builder() :: any(). + +-type direction() :: all. + +-spec prepend_builder(string_builder(), string_builder()) -> string_builder(). +prepend_builder(Builder, Prefix) -> + gleam_stdlib:iodata_append(Prefix, Builder). + +-spec append_builder(string_builder(), string_builder()) -> string_builder(). +append_builder(Builder, Suffix) -> + gleam_stdlib:iodata_append(Builder, Suffix). + +-spec new() -> string_builder(). +new() -> + gleam_stdlib:identity([]). + +-spec from_strings(list(binary())) -> string_builder(). +from_strings(Strings) -> + gleam_stdlib:identity(Strings). + +-spec concat(list(string_builder())) -> string_builder(). +concat(Builders) -> + gleam_stdlib:identity(Builders). + +-spec from_string(binary()) -> string_builder(). +from_string(String) -> + gleam_stdlib:identity(String). + +-spec prepend(string_builder(), binary()) -> string_builder(). +prepend(Builder, Prefix) -> + append_builder(from_string(Prefix), Builder). + +-spec append(string_builder(), binary()) -> string_builder(). +append(Builder, Second) -> + append_builder(Builder, from_string(Second)). + +-spec to_string(string_builder()) -> binary(). +to_string(Builder) -> + unicode:characters_to_binary(Builder). + +-spec byte_size(string_builder()) -> integer(). +byte_size(Builder) -> + erlang:iolist_size(Builder). + +-spec join(list(string_builder()), binary()) -> string_builder(). +join(Builders, Sep) -> + _pipe = Builders, + _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), + concat(_pipe@1). + +-spec lowercase(string_builder()) -> string_builder(). +lowercase(Builder) -> + string:lowercase(Builder). + +-spec uppercase(string_builder()) -> string_builder(). +uppercase(Builder) -> + string:uppercase(Builder). + +-spec reverse(string_builder()) -> string_builder(). +reverse(Builder) -> + string:reverse(Builder). + +-spec do_split(string_builder(), binary()) -> list(string_builder()). +do_split(Iodata, Pattern) -> + string:split(Iodata, Pattern, all). + +-spec split(string_builder(), binary()) -> list(string_builder()). +split(Iodata, Pattern) -> + do_split(Iodata, Pattern). + +-spec do_replace(string_builder(), binary(), binary()) -> string_builder(). +do_replace(Iodata, Pattern, Substitute) -> + string:replace(Iodata, Pattern, Substitute, all). + +-spec replace(string_builder(), binary(), binary()) -> string_builder(). +replace(Builder, Pattern, Substitute) -> + do_replace(Builder, Pattern, Substitute). + +-spec is_equal(string_builder(), string_builder()) -> boolean(). +is_equal(A, B) -> + string:equal(A, B). + +-spec is_empty(string_builder()) -> boolean(). +is_empty(Builder) -> + string:is_empty(Builder). diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl new file mode 100644 index 00000000000..a36df375281 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam@uri.erl @@ -0,0 +1,252 @@ +-module(gleam@uri). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). + +-export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). +-export_type([uri/0]). + +-type uri() :: {uri, + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(binary()), + gleam@option:option(integer()), + binary(), + gleam@option:option(binary()), + gleam@option:option(binary())}. + +-spec parse(binary()) -> {ok, uri()} | {error, nil}. +parse(Uri_string) -> + gleam_stdlib:uri_parse(Uri_string). + +-spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. +parse_query(Query) -> + gleam_stdlib:parse_query(Query). + +-spec percent_encode(binary()) -> binary(). +percent_encode(Value) -> + gleam_stdlib:percent_encode(Value). + +-spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). +query_pair(Pair) -> + gleam@string_builder:from_strings( + [percent_encode(erlang:element(1, Pair)), + <<"="/utf8>>, + percent_encode(erlang:element(2, Pair))] + ). + +-spec query_to_string(list({binary(), binary()})) -> binary(). +query_to_string(Query) -> + _pipe = Query, + _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), + _pipe@2 = gleam@list:intersperse( + _pipe@1, + gleam@string_builder:from_string(<<"&"/utf8>>) + ), + _pipe@3 = gleam@string_builder:concat(_pipe@2), + gleam@string_builder:to_string(_pipe@3). + +-spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. +percent_decode(Value) -> + gleam_stdlib:percent_decode(Value). + +-spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). +do_remove_dot_segments(Input, Accumulator) -> + case Input of + [] -> + gleam@list:reverse(Accumulator); + + [Segment | Rest] -> + Accumulator@5 = case {Segment, Accumulator} of + {<<""/utf8>>, Accumulator@1} -> + Accumulator@1; + + {<<"."/utf8>>, Accumulator@2} -> + Accumulator@2; + + {<<".."/utf8>>, []} -> + []; + + {<<".."/utf8>>, [_ | Accumulator@3]} -> + Accumulator@3; + + {Segment@1, Accumulator@4} -> + [Segment@1 | Accumulator@4] + end, + do_remove_dot_segments(Rest, Accumulator@5) + end. + +-spec remove_dot_segments(list(binary())) -> list(binary()). +remove_dot_segments(Input) -> + do_remove_dot_segments(Input, []). + +-spec path_segments(binary()) -> list(binary()). +path_segments(Path) -> + remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). + +-spec to_string(uri()) -> binary(). +to_string(Uri) -> + Parts = case erlang:element(8, Uri) of + {some, Fragment} -> + [<<"#"/utf8>>, Fragment]; + + _ -> + [] + end, + Parts@1 = case erlang:element(7, Uri) of + {some, Query} -> + [<<"?"/utf8>>, Query | Parts]; + + _ -> + Parts + end, + Parts@2 = [erlang:element(6, Uri) | Parts@1], + Parts@3 = case {erlang:element(4, Uri), + gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of + {{some, Host}, false} when Host =/= <<""/utf8>> -> + [<<"/"/utf8>> | Parts@2]; + + {_, _} -> + Parts@2 + end, + Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of + {{some, _}, {some, Port}} -> + [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; + + {_, _} -> + Parts@3 + end, + Parts@5 = case {erlang:element(2, Uri), + erlang:element(3, Uri), + erlang:element(4, Uri)} of + {{some, S}, {some, U}, {some, H}} -> + [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; + + {{some, S@1}, none, {some, H@1}} -> + [S@1, <<"://"/utf8>>, H@1 | Parts@4]; + + {{some, S@2}, {some, _}, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {{some, S@2}, none, none} -> + [S@2, <<":"/utf8>> | Parts@4]; + + {none, none, {some, H@2}} -> + [<<"//"/utf8>>, H@2 | Parts@4]; + + {_, _, _} -> + Parts@4 + end, + gleam@string:concat(Parts@5). + +-spec origin(uri()) -> {ok, binary()} | {error, nil}. +origin(Uri) -> + {uri, Scheme, _, Host, Port, _, _, _} = Uri, + case Scheme of + {some, <<"https"/utf8>>} when Port =:= {some, 443} -> + Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin)}; + + {some, <<"http"/utf8>>} when Port =:= {some, 80} -> + Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, + {ok, to_string(Origin@1)}; + + {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> + Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, + {ok, to_string(Origin@2)}; + + _ -> + {error, nil} + end. + +-spec drop_last(list(ETW)) -> list(ETW). +drop_last(Elements) -> + gleam@list:take(Elements, gleam@list:length(Elements) - 1). + +-spec join_segments(list(binary())) -> binary(). +join_segments(Segments) -> + gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). + +-spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. +merge(Base, Relative) -> + case Base of + {uri, {some, _}, _, {some, _}, _, _, _, _} -> + case Relative of + {uri, _, _, {some, _}, _, _, _, _} -> + Path = begin + _pipe = gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ), + _pipe@1 = remove_dot_segments(_pipe), + join_segments(_pipe@1) + end, + Resolved = {uri, + gleam@option:'or'( + erlang:element(2, Relative), + erlang:element(2, Base) + ), + none, + erlang:element(4, Relative), + gleam@option:'or'( + erlang:element(5, Relative), + erlang:element(5, Base) + ), + Path, + erlang:element(7, Relative), + erlang:element(8, Relative)}, + {ok, Resolved}; + + _ -> + {New_path, New_query} = case erlang:element(6, Relative) of + <<""/utf8>> -> + {erlang:element(6, Base), + gleam@option:'or'( + erlang:element(7, Relative), + erlang:element(7, Base) + )}; + + _ -> + Path_segments = case gleam@string:starts_with( + erlang:element(6, Relative), + <<"/"/utf8>> + ) of + true -> + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ); + + false -> + _pipe@2 = gleam@string:split( + erlang:element(6, Base), + <<"/"/utf8>> + ), + _pipe@3 = drop_last(_pipe@2), + gleam@list:append( + _pipe@3, + gleam@string:split( + erlang:element(6, Relative), + <<"/"/utf8>> + ) + ) + end, + Path@1 = begin + _pipe@4 = Path_segments, + _pipe@5 = remove_dot_segments(_pipe@4), + join_segments(_pipe@5) + end, + {Path@1, erlang:element(7, Relative)} + end, + Resolved@1 = {uri, + erlang:element(2, Base), + none, + erlang:element(4, Base), + erlang:element(5, Base), + New_path, + New_query, + erlang:element(8, Relative)}, + {ok, Resolved@1} + end; + + _ -> + {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src new file mode 100644 index 00000000000..76aa1ea673c --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.app.src @@ -0,0 +1,31 @@ +{application, gleam_stdlib, [ + {vsn, "0.33.1"}, + {applications, []}, + {description, "A standard library for the Gleam programming language"}, + {modules, [gleam@base, + gleam@bit_array, + gleam@bit_builder, + gleam@bit_string, + gleam@bool, + gleam@bytes_builder, + gleam@dict, + gleam@dynamic, + gleam@float, + gleam@function, + gleam@int, + gleam@io, + gleam@iterator, + gleam@list, + gleam@map, + gleam@option, + gleam@order, + gleam@pair, + gleam@queue, + gleam@regex, + gleam@result, + gleam@set, + gleam@string, + gleam@string_builder, + gleam@uri]}, + {registered, []} +]}. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl new file mode 100644 index 00000000000..c6ea1257110 --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.erl @@ -0,0 +1,529 @@ +-module(gleam_stdlib). + +-export([ + map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, + decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, + parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, + wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, + bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, + bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, + percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, + base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, + decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, + decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, + println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, + int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, + crop_string/2, base16_decode/1 +]). + +%% Taken from OTP's uri_string module +-define(DEC2HEX(X), + if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; + ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 + end). + +%% Taken from OTP's uri_string module +-define(HEX2DEC(X), + if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; + ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; + ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 + end). + +-define(is_lowercase_char(X), (X > 96 andalso X < 123)). +-define(is_underscore_char(X), (X == 95)). +-define(is_digit_char(X), (X > 47 andalso X < 58)). + +uppercase(X) -> X - 32. + +map_get(Map, Key) -> + case maps:find(Key, Map) of + error -> {error, nil}; + OkFound -> OkFound + end. + +iodata_append(Iodata, String) -> [Iodata, String]. + +identity(X) -> X. + +decode_error_msg(Expected, Data) when is_binary(Expected) -> + decode_error(Expected, classify_dynamic(Data)). +decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> + {error, [{decode_error, Expected, Got, []}]}. + +classify_dynamic(nil) -> <<"Nil">>; +classify_dynamic(X) when is_atom(X) -> <<"Atom">>; +classify_dynamic(X) when is_binary(X) -> <<"String">>; +classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; +classify_dynamic(X) when is_integer(X) -> <<"Int">>; +classify_dynamic(X) when is_float(X) -> <<"Float">>; +classify_dynamic(X) when is_list(X) -> <<"List">>; +classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; +classify_dynamic(X) when is_map(X) -> <<"Map">>; +classify_dynamic(X) when is_tuple(X) -> + iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); +classify_dynamic(X) when + is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse + is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse + is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse + is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse + is_function(X, 12) -> <<"Function">>; +classify_dynamic(_) -> <<"Some other type">>. + +decode_map(Data) when is_map(Data) -> {ok, Data}; +decode_map(Data) -> decode_error_msg(<<"Map">>, Data). + +decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; +decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). + +decode_int(Data) when is_integer(Data) -> {ok, Data}; +decode_int(Data) -> decode_error_msg(<<"Int">>, Data). + +decode_float(Data) when is_float(Data) -> {ok, Data}; +decode_float(Data) -> decode_error_msg(<<"Float">>, Data). + +decode_bool(Data) when is_boolean(Data) -> {ok, Data}; +decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). + +decode_list(Data) when is_list(Data) -> {ok, Data}; +decode_list(Data) -> decode_error_msg(<<"List">>, Data). + +decode_field(Data, Key) when is_map(Data) -> + case Data of + #{Key := Value} -> {ok, {some, Value}}; + _ -> + {ok, none} + end; +decode_field(Data, _) -> + decode_error_msg(<<"Map">>, Data). + +size_of_tuple(Data) -> tuple_size(Data). + +tuple_get(_tup, Index) when Index < 0 -> {error, nil}; +tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; +tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. + +decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; +decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). + +decode_tuple2({_,_} = A) -> {ok, A}; +decode_tuple2([A,B]) -> {ok, {A,B}}; +decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). + +decode_tuple3({_,_,_} = A) -> {ok, A}; +decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; +decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). + +decode_tuple4({_,_,_,_} = A) -> {ok, A}; +decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; +decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). + +decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; +decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; +decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). + +decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; +decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; +decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). + +decode_option(Term, F) -> + Decode = fun(Inner) -> + case F(Inner) of + {ok, Decoded} -> {ok, {some, Decoded}}; + Error -> Error + end + end, + case Term of + undefined -> {ok, none}; + error -> {ok, none}; + null -> {ok, none}; + none -> {ok, none}; + nil -> {ok, none}; + {some, Inner} -> Decode(Inner); + _ -> Decode(Term) + end. + +decode_result(Term) -> + case Term of + {ok, Inner} -> {ok, {ok, Inner}}; + ok -> {ok, {ok, nil}}; + {error, Inner} -> {ok, {error, Inner}}; + error -> {ok, {error, nil}}; + _ -> decode_error_msg(<<"Result">>, Term) + end. + +int_from_base_string(String, Base) -> + case catch binary_to_integer(String, Base) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_int(String) -> + case catch binary_to_integer(String) of + Int when is_integer(Int) -> {ok, Int}; + _ -> {error, nil} + end. + +parse_float(String) -> + case catch binary_to_float(String) of + Float when is_float(Float) -> {ok, Float}; + _ -> {error, nil} + end. + +less_than(Lhs, Rhs) -> + Lhs < Rhs. + +string_starts_with(_, <<>>) -> true; +string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; +string_starts_with(String, Prefix) -> + PrefixSize = byte_size(Prefix), + Prefix == binary_part(String, 0, PrefixSize). + +string_ends_with(_, <<>>) -> true; +string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; +string_ends_with(String, Suffix) -> + SuffixSize = byte_size(Suffix), + Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). + +string_pad(String, Length, Dir, PadString) -> + Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), + case unicode:characters_to_binary(Chars) of + Bin when is_binary(Bin) -> Bin; + Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) + end. + +string_pop_grapheme(String) -> + case string:next_grapheme(String) of + [ Next | Rest ] -> + {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; + _ -> {error, nil} + end. + +bit_array_concat(BitArrays) -> + list_to_bitstring(BitArrays). + +bit_array_slice(Bin, Pos, Len) -> + try {ok, binary:part(Bin, Pos, Len)} + catch error:badarg -> {error, nil} + end. + +bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> + {ok, <>}; +bit_array_int_to_u32(_) -> + {error, nil}. + +bit_array_int_from_u32(<>) -> + {ok, I}; +bit_array_int_from_u32(_) -> + {error, nil}. + +compile_regex(String, Options) -> + {options, Caseless, Multiline} = Options, + OptionsList = [ + unicode, + ucp, + Caseless andalso caseless, + Multiline andalso multiline + ], + FilteredOptions = [Option || Option <- OptionsList, Option /= false], + case re:compile(String, FilteredOptions) of + {ok, MP} -> {ok, MP}; + {error, {Str, Pos}} -> + {error, {compile_error, unicode:characters_to_binary(Str), Pos}} + end. + +regex_check(Regex, String) -> + re:run(String, Regex) /= nomatch. + +regex_split(Regex, String) -> + re:split(String, Regex). + +regex_submatches(_, {-1, 0}) -> none; +regex_submatches(String, {Start, Length}) -> + BinarySlice = binary:part(String, {Start, Length}), + case string:is_empty(binary_to_list(BinarySlice)) of + true -> none; + false -> {some, BinarySlice} + end. + +regex_matches(String, [{Start, Length} | Submatches]) -> + Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), + {match, binary:part(String, Start, Length), Submatches1}. + +regex_scan(Regex, String) -> + case re:run(String, Regex, [global]) of + {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); + nomatch -> [] + end. + +base_decode64(S) -> + try {ok, base64:decode(S)} + catch error:_ -> {error, nil} + end. + +wrap_list(X) when is_list(X) -> X; +wrap_list(X) -> [X]. + +parse_query(Query) -> + case uri_string:dissect_query(Query) of + {error, _, _} -> {error, nil}; + Pairs -> + Pairs1 = lists:map(fun + ({K, true}) -> {K, <<"">>}; + (Pair) -> Pair + end, Pairs), + {ok, Pairs1} + end. + +percent_encode(B) -> percent_encode(B, <<>>). +percent_encode(<<>>, Acc) -> + Acc; +percent_encode(<>, Acc) -> + case percent_ok(H) of + true -> + percent_encode(T, <>); + false -> + <> = <>, + percent_encode(T, <>) + end. + +percent_decode(Cs) -> percent_decode(Cs, <<>>). +percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> + case is_hex_digit(C0) andalso is_hex_digit(C1) of + true -> + B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), + percent_decode(Cs, <>); + false -> + {error, nil} + end; +percent_decode(<>, Acc) -> + percent_decode(Cs, <>); +percent_decode(<<>>, Acc) -> + check_utf8(Acc). + +percent_ok($!) -> true; +percent_ok($$) -> true; +percent_ok($') -> true; +percent_ok($() -> true; +percent_ok($)) -> true; +percent_ok($*) -> true; +percent_ok($+) -> true; +percent_ok($-) -> true; +percent_ok($.) -> true; +percent_ok($_) -> true; +percent_ok($~) -> true; +percent_ok(C) when $0 =< C, C =< $9 -> true; +percent_ok(C) when $A =< C, C =< $Z -> true; +percent_ok(C) when $a =< C, C =< $z -> true; +percent_ok(_) -> false. + +is_hex_digit(C) -> + ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). + +check_utf8(Cs) -> + case unicode:characters_to_list(Cs) of + {incomplete, _, _} -> {error, nil}; + {error, _, _} -> {error, nil}; + _ -> {ok, Cs} + end. + +uri_parse(String) -> + case uri_string:parse(String) of + {error, _, _} -> {error, nil}; + Uri -> + {ok, {uri, + maps_get_optional(Uri, scheme), + maps_get_optional(Uri, userinfo), + maps_get_optional(Uri, host), + maps_get_optional(Uri, port), + maps_get_or(Uri, path, <<>>), + maps_get_optional(Uri, query), + maps_get_optional(Uri, fragment) + }} + end. + +maps_get_optional(Map, Key) -> + try {some, maps:get(Key, Map)} + catch _:_ -> none + end. + +maps_get_or(Map, Key, Default) -> + try maps:get(Key, Map) + catch _:_ -> Default + end. + +print(String) -> + io:put_chars(String), + nil. + +println(String) -> + io:put_chars([String, $\n]), + nil. + +print_error(String) -> + io:put_chars(standard_error, String), + nil. + +println_error(String) -> + io:put_chars(standard_error, [String, $\n]), + nil. + +inspect(true) -> + "True"; +inspect(false) -> + "False"; +inspect(nil) -> + "Nil"; +inspect(Data) when is_map(Data) -> + Fields = [ + [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] + || {Key, Value} <- maps:to_list(Data) + ], + ["dict.from_list([", lists:join(", ", Fields), "])"]; +inspect(Atom) when is_atom(Atom) -> + Binary = erlang:atom_to_binary(Atom), + case inspect_maybe_gleam_atom(Binary, none, <<>>) of + {ok, Inspected} -> Inspected; + {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] + end; +inspect(Any) when is_integer(Any) -> + erlang:integer_to_list(Any); +inspect(Any) when is_float(Any) -> + io_lib_format:fwrite_g(Any); +inspect(Binary) when is_binary(Binary) -> + case inspect_maybe_utf8_string(Binary, <<>>) of + {ok, InspectedUtf8String} -> InspectedUtf8String; + {error, not_a_utf8_string} -> + Segments = [erlang:integer_to_list(X) || <> <= Binary], + ["<<", lists:join(", ", Segments), ">>"] + end; +inspect(Bits) when is_bitstring(Bits) -> + inspect_bit_array(Bits); +inspect(List) when is_list(List) -> + case inspect_list(List) of + {proper, Elements} -> ["[", Elements, "]"]; + {improper, Elements} -> ["//erl([", Elements, "])"] + end; +inspect(Any) when is_tuple(Any) % Record constructors + andalso is_atom(element(1, Any)) + andalso element(1, Any) =/= false + andalso element(1, Any) =/= true + andalso element(1, Any) =/= nil +-> + [Atom | ArgsList] = erlang:tuple_to_list(Any), + Args = lists:join(<<", ">>, + lists:map(fun inspect/1, ArgsList) + ), + [inspect(Atom), "(", Args, ")"]; +inspect(Tuple) when is_tuple(Tuple) -> + Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), + ["#(", lists:join(", ", Elements), ")"]; +inspect(Any) when is_function(Any) -> + {arity, Arity} = erlang:fun_info(Any, arity), + ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), + Args = lists:join(<<", ">>, + lists:map(fun(Arg) -> <> end, ArgsAsciiCodes) + ), + ["//fn(", Args, ") { ... }"]; +inspect(Any) -> + ["//erl(", io_lib:format("~p", [Any]), ")"]. + + +inspect_maybe_gleam_atom(<<>>, none, _) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, none, _) when ?is_digit_char(First) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> + {error, nil}; +inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, _PrevChar, _Acc) + when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> + {error, nil}; +inspect_maybe_gleam_atom(<>, none, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> + inspect_maybe_gleam_atom(Rest, $_, Acc); +inspect_maybe_gleam_atom(<>, $_, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<>, _PrevChar, Acc) -> + inspect_maybe_gleam_atom(Rest, First, <>); +inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> + {ok, Acc}; +inspect_maybe_gleam_atom(A, B, C) -> + erlang:display({A, B, C}), + throw({gleam_error, A, B, C}). + +inspect_list([]) -> + {proper, []}; +inspect_list([First]) -> + {proper, [inspect(First)]}; +inspect_list([First | Rest]) when is_list(Rest) -> + {Kind, Inspected} = inspect_list(Rest), + {Kind, [inspect(First), <<", ">> | Inspected]}; +inspect_list([First | ImproperTail]) -> + {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. + +inspect_bit_array(Bits) -> + Text = inspect_bit_array(Bits, <<"<<">>), + <>">>. + +inspect_bit_array(<<>>, Acc) -> + Acc; +inspect_bit_array(<>, Acc) -> + inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); +inspect_bit_array(Rest, Acc) -> + Size = bit_size(Rest), + <> = Rest, + X1 = erlang:integer_to_binary(X), + Size1 = erlang:integer_to_binary(Size), + Segment = <>, + inspect_bit_array(<<>>, append_segment(Acc, Segment)). + +append_segment(<<"<<">>, Segment) -> + <<"<<", Segment/binary>>; +append_segment(Acc, Segment) -> + <>. + + +inspect_maybe_utf8_string(Binary, Acc) -> + case Binary of + <<>> -> {ok, <<$", Acc/binary, $">>}; + <> -> + Escaped = case First of + $" -> <<$\\, $">>; + $\\ -> <<$\\, $\\>>; + $\r -> <<$\\, $r>>; + $\n -> <<$\\, $n>>; + $\t -> <<$\\, $t>>; + Other -> <> + end, + inspect_maybe_utf8_string(Rest, <>); + _ -> {error, not_a_utf8_string} + end. + +float_to_string(Float) when is_float(Float) -> + erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). + +utf_codepoint_list_to_string(List) -> + case unicode:characters_to_binary(List) of + {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); + Binary -> Binary + end. + +crop_string(String, Prefix) -> + case string:find(String, Prefix) of + nomatch -> String; + New -> New + end. + +contains_string(String, Substring) -> + is_bitstring(string:find(String, Substring)). + +base16_decode(String) -> + try + {ok, binary:decode_hex(String)} + catch + _:_ -> {error, nil} + end. diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs new file mode 100644 index 00000000000..45c28cfc87b --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleam_stdlib/src/gleam_stdlib.mjs @@ -0,0 +1,878 @@ +import { + BitArray, + Error, + List, + Ok, + Result, + UtfCodepoint, + stringBits, + toBitArray, + NonEmpty, + CustomType, +} from "./gleam.mjs"; +import { + CompileError as RegexCompileError, + Match as RegexMatch, +} from "./gleam/regex.mjs"; +import { DecodeError } from "./gleam/dynamic.mjs"; +import { Some, None } from "./gleam/option.mjs"; +import Dict from "./dict.mjs"; + +const Nil = undefined; +const NOT_FOUND = {}; + +export function identity(x) { + return x; +} + +export function parse_int(value) { + if (/^[-+]?(\d+)$/.test(value)) { + return new Ok(parseInt(value)); + } else { + return new Error(Nil); + } +} + +export function parse_float(value) { + if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { + return new Ok(parseFloat(value)); + } else { + return new Error(Nil); + } +} + +export function to_string(term) { + return term.toString(); +} + +export function float_to_string(float) { + const string = float.toString(); + if (string.indexOf(".") >= 0) { + return string; + } else { + return string + ".0"; + } +} + +export function int_to_base_string(int, base) { + return int.toString(base).toUpperCase(); +} + +const int_base_patterns = { + 2: /[^0-1]/, + 3: /[^0-2]/, + 4: /[^0-3]/, + 5: /[^0-4]/, + 6: /[^0-5]/, + 7: /[^0-6]/, + 8: /[^0-7]/, + 9: /[^0-8]/, + 10: /[^0-9]/, + 11: /[^0-9a]/, + 12: /[^0-9a-b]/, + 13: /[^0-9a-c]/, + 14: /[^0-9a-d]/, + 15: /[^0-9a-e]/, + 16: /[^0-9a-f]/, + 17: /[^0-9a-g]/, + 18: /[^0-9a-h]/, + 19: /[^0-9a-i]/, + 20: /[^0-9a-j]/, + 21: /[^0-9a-k]/, + 22: /[^0-9a-l]/, + 23: /[^0-9a-m]/, + 24: /[^0-9a-n]/, + 25: /[^0-9a-o]/, + 26: /[^0-9a-p]/, + 27: /[^0-9a-q]/, + 28: /[^0-9a-r]/, + 29: /[^0-9a-s]/, + 30: /[^0-9a-t]/, + 31: /[^0-9a-u]/, + 32: /[^0-9a-v]/, + 33: /[^0-9a-w]/, + 34: /[^0-9a-x]/, + 35: /[^0-9a-y]/, + 36: /[^0-9a-z]/, +}; + +export function int_from_base_string(string, base) { + if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { + return new Error(Nil); + } + + const result = parseInt(string, base); + + if (isNaN(result)) { + return new Error(Nil); + } + + return new Ok(result); +} + +export function string_replace(string, target, substitute) { + if (typeof string.replaceAll !== "undefined") { + return string.replaceAll(target, substitute); + } + // Fallback for older Node.js versions: + // 1. + // 2. + // TODO: This fallback could be remove once Node.js 14 is EOL + // aka on or after 2024-04-30 + return string.replace( + // $& means the whole matched string + new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), + substitute + ); +} + +export function string_reverse(string) { + return [...string].reverse().join(""); +} + +export function string_length(string) { + if (string === "") { + return 0; + } + const iterator = graphemes_iterator(string); + if (iterator) { + let i = 0; + for (const _ of iterator) { + i++; + } + return i; + } else { + return string.match(/./gsu).length; + } +} + +export function graphemes(string) { + const iterator = graphemes_iterator(string); + if (iterator) { + return List.fromArray(Array.from(iterator).map((item) => item.segment)); + } else { + return List.fromArray(string.match(/./gsu)); + } +} + +function graphemes_iterator(string) { + if (Intl && Intl.Segmenter) { + return new Intl.Segmenter().segment(string)[Symbol.iterator](); + } +} + +export function pop_grapheme(string) { + let first; + const iterator = graphemes_iterator(string); + if (iterator) { + first = iterator.next().value?.segment; + } else { + first = string.match(/./su)?.[0]; + } + if (first) { + return new Ok([first, string.slice(first.length)]); + } else { + return new Error(Nil); + } +} + +export function lowercase(string) { + return string.toLowerCase(); +} + +export function uppercase(string) { + return string.toUpperCase(); +} + +export function less_than(a, b) { + return a < b; +} + +export function add(a, b) { + return a + b; +} + +export function equal(a, b) { + return a === b; +} + +export function split(xs, pattern) { + return List.fromArray(xs.split(pattern)); +} + +export function join(xs, separator) { + const iterator = xs[Symbol.iterator](); + let result = iterator.next().value || ""; + let current = iterator.next(); + while (!current.done) { + result = result + separator + current.value; + current = iterator.next(); + } + return result; +} + +export function concat(xs) { + let result = ""; + for (const x of xs) { + result = result + x; + } + return result; +} + +export function length(data) { + return data.length; +} + +export function crop_string(string, substring) { + return string.substring(string.indexOf(substring)); +} + +export function contains_string(haystack, needle) { + return haystack.indexOf(needle) >= 0; +} + +export function starts_with(haystack, needle) { + return haystack.startsWith(needle); +} + +export function ends_with(haystack, needle) { + return haystack.endsWith(needle); +} + +export function split_once(haystack, needle) { + const index = haystack.indexOf(needle); + if (index >= 0) { + const before = haystack.slice(0, index); + const after = haystack.slice(index + needle.length); + return new Ok([before, after]); + } else { + return new Error(Nil); + } +} + +export function trim(string) { + return string.trim(); +} + +export function trim_left(string) { + return string.trimLeft(); +} + +export function trim_right(string) { + return string.trimRight(); +} + +export function bit_array_from_string(string) { + return toBitArray([stringBits(string)]); +} + +export function bit_array_concat(bit_arrays) { + return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); +} + +export function console_log(term) { + console.log(term); +} + +export function console_error(term) { + console.error(term); +} + +export function crash(message) { + throw new globalThis.Error(message); +} + +export function bit_array_to_string(bit_array) { + try { + const decoder = new TextDecoder("utf-8", { fatal: true }); + return new Ok(decoder.decode(bit_array.buffer)); + } catch (_error) { + return new Error(Nil); + } +} + +export function print(string) { + if (typeof process === "object") { + process.stdout.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.log(string); // We're in a browser. Newlines are mandated + } +} + +export function print_error(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string); // We can write without a trailing newline + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline + } else { + console.error(string); // We're in a browser. Newlines are mandated + } +} + +export function print_debug(string) { + if (typeof process === "object" && process.stderr?.write) { + process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` + } else if (typeof Deno === "object") { + Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` + } else { + console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) + } +} + +export function ceiling(float) { + return Math.ceil(float); +} + +export function floor(float) { + return Math.floor(float); +} + +export function round(float) { + return Math.round(float); +} + +export function truncate(float) { + return Math.trunc(float); +} + +export function power(base, exponent) { + // It is checked in Gleam that: + // - The base is non-negative and that the exponent is not fractional. + // - The base is non-zero and the exponent is non-negative (otherwise + // the result will essentially be division by zero). + // It can thus be assumed that valid input is passed to the Math.pow + // function and a NaN or Infinity value will not be produced. + return Math.pow(base, exponent); +} + +export function random_uniform() { + const random_uniform_result = Math.random(); + // With round-to-nearest-even behavior, the ranges claimed for the functions below + // (excluding the one for Math.random() itself) aren't exact. + // If extremely large bounds are chosen (2^53 or higher), + // it's possible in extremely rare cases to calculate the usually-excluded upper bound. + // Note that as numbers in JavaScript are IEEE 754 floating point numbers + // See: + // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: + if (random_uniform_result === 1.0) { + return random_uniform(); + } + return random_uniform_result; +} + +export function bit_array_slice(bits, position, length) { + const start = Math.min(position, position + length); + const end = Math.max(position, position + length); + if (start < 0 || end > bits.length) return new Error(Nil); + const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); + return new Ok(new BitArray(buffer)); +} + +export function codepoint(int) { + return new UtfCodepoint(int); +} + +export function string_to_codepoint_integer_list(string) { + return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); +} + +export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { + return utf_codepoint_integer_list + .toArray() + .map((x) => String.fromCodePoint(x.value)) + .join(""); +} + +export function utf_codepoint_to_int(utf_codepoint) { + return utf_codepoint.value; +} + +export function regex_check(regex, string) { + regex.lastIndex = 0; + return regex.test(string); +} + +export function compile_regex(pattern, options) { + try { + let flags = "gu"; + if (options.case_insensitive) flags += "i"; + if (options.multi_line) flags += "m"; + return new Ok(new RegExp(pattern, flags)); + } catch (error) { + const number = (error.columnNumber || 0) | 0; + return new Error(new RegexCompileError(error.message, number)); + } +} + +export function regex_scan(regex, string) { + const matches = Array.from(string.matchAll(regex)).map((match) => { + const content = match[0]; + const submatches = []; + for (let n = match.length - 1; n > 0; n--) { + if (match[n]) { + submatches[n - 1] = new Some(match[n]); + continue; + } + if (submatches.length > 0) { + submatches[n - 1] = new None(); + } + } + return new RegexMatch(content, List.fromArray(submatches)); + }); + return List.fromArray(matches); +} + +export function new_map() { + return Dict.new(); +} + +export function map_size(map) { + return map.size; +} + +export function map_to_list(map) { + return List.fromArray(map.entries()); +} + +export function map_remove(key, map) { + return map.delete(key); +} + +export function map_get(map, key) { + const value = map.get(key, NOT_FOUND); + if (value === NOT_FOUND) { + return new Error(Nil); + } + return new Ok(value); +} + +export function map_insert(key, value, map) { + return map.set(key, value); +} + +function unsafe_percent_decode(string) { + return decodeURIComponent((string || "").replace("+", " ")); +} + +export function percent_decode(string) { + try { + return new Ok(unsafe_percent_decode(string)); + } catch (_error) { + return new Error(Nil); + } +} + +export function percent_encode(string) { + return encodeURIComponent(string); +} + +export function parse_query(query) { + try { + const pairs = []; + for (const section of query.split("&")) { + const [key, value] = section.split("="); + if (!key) continue; + pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); + } + return new Ok(List.fromArray(pairs)); + } catch (_error) { + return new Error(Nil); + } +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function encode64(bit_array) { + const aBytes = bit_array.buffer; + let nMod3 = 2; + let sB64Enc = ""; + + for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { + nMod3 = nIdx % 3; + if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { + sB64Enc += "\r\n"; + } + nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); + if (nMod3 === 2 || aBytes.length - nIdx === 1) { + sB64Enc += String.fromCharCode( + uint6ToB64((nUint24 >>> 18) & 63), + uint6ToB64((nUint24 >>> 12) & 63), + uint6ToB64((nUint24 >>> 6) & 63), + uint6ToB64(nUint24 & 63) + ); + nUint24 = 0; + } + } + + return ( + sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + + (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") + ); +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function uint6ToB64(nUint6) { + return nUint6 < 26 + ? nUint6 + 65 + : nUint6 < 52 + ? nUint6 + 71 + : nUint6 < 62 + ? nUint6 - 4 + : nUint6 === 62 + ? 43 + : nUint6 === 63 + ? 47 + : 65; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +function b64ToUint6(nChr) { + return nChr > 64 && nChr < 91 + ? nChr - 65 + : nChr > 96 && nChr < 123 + ? nChr - 71 + : nChr > 47 && nChr < 58 + ? nChr + 4 + : nChr === 43 + ? 62 + : nChr === 47 + ? 63 + : 0; +} + +// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 +export function decode64(sBase64) { + if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); + const sB64Enc = sBase64.replace(/=/g, ""); + const nInLen = sB64Enc.length; + const nOutLen = (nInLen * 3 + 1) >> 2; + const taBytes = new Uint8Array(nOutLen); + + for ( + let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; + nInIdx < nInLen; + nInIdx++ + ) { + nMod4 = nInIdx & 3; + nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); + if (nMod4 === 3 || nInLen - nInIdx === 1) { + for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { + taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; + } + nUint24 = 0; + } + } + + return new Ok(new BitArray(taBytes)); +} + +export function classify_dynamic(data) { + if (typeof data === "string") { + return "String"; + } else if (data instanceof Result) { + return "Result"; + } else if (data instanceof List) { + return "List"; + } else if (data instanceof BitArray) { + return "BitArray"; + } else if (data instanceof Dict) { + return "Map"; + } else if (Number.isInteger(data)) { + return "Int"; + } else if (Array.isArray(data)) { + return `Tuple of ${data.length} elements`; + } else if (typeof data === "number") { + return "Float"; + } else if (data === null) { + return "Null"; + } else if (data === undefined) { + return "Nil"; + } else { + const type = typeof data; + return type.charAt(0).toUpperCase() + type.slice(1); + } +} + +function decoder_error(expected, got) { + return decoder_error_no_classify(expected, classify_dynamic(got)); +} + +function decoder_error_no_classify(expected, got) { + return new Error( + List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) + ); +} + +export function decode_string(data) { + return typeof data === "string" + ? new Ok(data) + : decoder_error("String", data); +} + +export function decode_int(data) { + return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); +} + +export function decode_float(data) { + return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); +} + +export function decode_bool(data) { + return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); +} + +export function decode_bit_array(data) { + if (data instanceof BitArray) { + return new Ok(data); + } + if (data instanceof Uint8Array) { + return new Ok(new BitArray(data)); + } + return decoder_error("BitArray", data); +} + +export function decode_tuple(data) { + return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); +} + +export function decode_tuple2(data) { + return decode_tupleN(data, 2); +} + +export function decode_tuple3(data) { + return decode_tupleN(data, 3); +} + +export function decode_tuple4(data) { + return decode_tupleN(data, 4); +} + +export function decode_tuple5(data) { + return decode_tupleN(data, 5); +} + +export function decode_tuple6(data) { + return decode_tupleN(data, 6); +} + +function decode_tupleN(data, n) { + if (Array.isArray(data) && data.length == n) { + return new Ok(data); + } + + const list = decode_exact_length_list(data, n); + if (list) return new Ok(list); + + return decoder_error(`Tuple of ${n} elements`, data); +} + +function decode_exact_length_list(data, n) { + if (!(data instanceof List)) return; + + const elements = []; + let current = data; + + for (let i = 0; i < n; i++) { + if (!(current instanceof NonEmpty)) break; + elements.push(current.head); + current = current.tail; + } + + if (elements.length === n && !(current instanceof NonEmpty)) return elements; +} + +export function tuple_get(data, index) { + return index >= 0 && data.length > index + ? new Ok(data[index]) + : new Error(Nil); +} + +export function decode_list(data) { + if (Array.isArray(data)) { + return new Ok(List.fromArray(data)); + } + return data instanceof List ? new Ok(data) : decoder_error("List", data); +} + +export function decode_result(data) { + return data instanceof Result ? new Ok(data) : decoder_error("Result", data); +} + +export function decode_map(data) { + if (data instanceof Dict) { + return new Ok(Dict.fromMap(data)); + } + if (data == null) { + return decoder_error("Map", data); + } + if (typeof data !== "object") { + return decoder_error("Map", data); + } + const proto = Object.getPrototypeOf(data); + if (proto === Object.prototype || proto === null) { + return new Ok(Dict.fromObject(data)); + } + return decoder_error("Map", data); +} + +export function decode_option(data, decoder) { + if (data === null || data === undefined || data instanceof None) + return new Ok(new None()); + if (data instanceof Some) data = data[0]; + const result = decoder(data); + if (result.isOk()) { + return new Ok(new Some(result[0])); + } else { + return result; + } +} + +export function decode_field(value, name) { + const not_a_map_error = () => decoder_error("Map", value); + + if ( + value instanceof Dict || + value instanceof WeakMap || + value instanceof Map + ) { + const entry = map_get(value, name); + return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); + } else if (Object.getPrototypeOf(value) == Object.prototype) { + return try_get_field(value, name, () => new Ok(new None())); + } else { + return try_get_field(value, name, not_a_map_error); + } +} + +function try_get_field(value, field, or_else) { + try { + return field in value ? new Ok(new Some(value[field])) : or_else(); + } catch { + return or_else(); + } +} + +export function byte_size(string) { + return new TextEncoder().encode(string).length; +} + +// In Javascript bitwise operations convert numbers to a sequence of 32 bits +// while Erlang uses arbitrary precision. +// To get around this problem and get consistent results use BigInt and then +// downcast the value back to a Number value. + +export function bitwise_and(x, y) { + return Number(BigInt(x) & BigInt(y)); +} + +export function bitwise_not(x) { + return Number(~BigInt(x)); +} + +export function bitwise_or(x, y) { + return Number(BigInt(x) | BigInt(y)); +} + +export function bitwise_exclusive_or(x, y) { + return Number(BigInt(x) ^ BigInt(y)); +} + +export function bitwise_shift_left(x, y) { + return Number(BigInt(x) << BigInt(y)); +} + +export function bitwise_shift_right(x, y) { + return Number(BigInt(x) >> BigInt(y)); +} + +export function inspect(v) { + const t = typeof v; + if (v === true) return "True"; + if (v === false) return "False"; + if (v === null) return "//js(null)"; + if (v === undefined) return "Nil"; + if (t === "string") return JSON.stringify(v); + if (t === "bigint" || t === "number") return v.toString(); + if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; + if (v instanceof List) return inspectList(v); + if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); + if (v instanceof BitArray) return inspectBitArray(v); + if (v instanceof CustomType) return inspectCustomType(v); + if (v instanceof Dict) return inspectDict(v); + if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; + if (v instanceof RegExp) return `//js(${v})`; + if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; + if (v instanceof Function) { + const args = []; + for (const i of Array(v.length).keys()) + args.push(String.fromCharCode(i + 97)); + return `//fn(${args.join(", ")}) { ... }`; + } + return inspectObject(v); +} + +function inspectDict(map) { + let body = "dict.from_list(["; + let first = true; + map.forEach((value, key) => { + if (!first) body = body + ", "; + body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; + first = false; + }); + return body + "])"; +} + +function inspectObject(v) { + const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; + const props = []; + for (const k of Object.keys(v)) { + props.push(`${inspect(k)}: ${inspect(v[k])}`); + } + const body = props.length ? " " + props.join(", ") + " " : ""; + const head = name === "Object" ? "" : name + " "; + return `//js(${head}{${body}})`; +} + +function inspectCustomType(record) { + const props = Object.keys(record) + .map((label) => { + const value = inspect(record[label]); + return isNaN(parseInt(label)) ? `${label}: ${value}` : value; + }) + .join(", "); + return props + ? `${record.constructor.name}(${props})` + : record.constructor.name; +} + +export function inspectList(list) { + return `[${list.toArray().map(inspect).join(", ")}]`; +} + +export function inspectBitArray(bits) { + return `<<${Array.from(bits.buffer).join(", ")}>>`; +} + +export function inspectUtfCodepoint(codepoint) { + return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; +} + +export function base16_encode(bit_array) { + let result = ""; + for (const byte of bit_array.buffer) { + result += byte.toString(16).padStart(2, "0").toUpperCase(); + } + return result; +} + +export function base16_decode(string) { + const bytes = new Uint8Array(string.length / 2); + for (let i = 0; i < string.length; i += 2) { + const a = parseInt(string[i], 16); + const b = parseInt(string[i + 1], 16); + if (isNaN(a) || isNaN(b)) return new Error(Nil); + bytes[i / 2] = a * 16 + b; + } + return new Ok(new BitArray(bytes)); +} diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE new file mode 100644 index 00000000000..c7967c32d6f --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/LICENCE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2021, Louis Pilfold . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md new file mode 100644 index 00000000000..3ca1c63e98d --- /dev/null +++ b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/README.md @@ -0,0 +1,52 @@ +# gleeunit + +Gleam bindings to the Erlang EUnit test framework. + +A custom test runner is included for when compiled to JavaScript running on +either NodeJS or Deno. + +Documentation is available on [HexDocs](https://hexdocs.pm/gleeunit/index.html). + +## Usage + +Add this package to your Gleam project. + +```sh +gleam add gleeunit --dev +``` + +And then call the `gleeunit.main` function from your test main function. + +```gleam +// In test/yourapp_test.gleam +import gleeunit + +pub fn main() { + gleeunit.main() +} +``` + +Now any public function with a name ending in `_test` in the `test` directory +will be found and run as a test. + +```gleam +pub fn the_universe_test() { + let assert 1 = 1 +} +``` + +Run the tests by entering `gleam test` in the command line. + +### Deno + +If using the Deno JavaScript runtime, you will need to add the following to your +`gleam.toml`. + +```toml +[javascript.deno] +allow_read = [ + "gleam.toml", + "test", + "build", +] +``` diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@base.cache new file mode 100644 index 0000000000000000000000000000000000000000..586f1012e4134ddac35bb64f7e3e8fb5b2db969d GIT binary patch literal 1223 zcmc(f-%8^^6vpSwG)%it+Cy0}3(_b^m$Il^ix=K#3+{p}uCapPO`DoQQ_}|W=fd~# z!Uyp|_GX_Wdy-UBgO>GX_hvXVb8lMN9M_Ib14KiE<3SlHsPf66&MEjPCWBQ0B3832&sKX~ z#u$M4g$wf@w6Czi<5MagC?k@zjK&o1b%$B@$Z%#xctgkY2Aptc`Mz~GGNzs#xr*+C zP)W<)0$>a)7v>Kx7&FVX0yTx}9bA_b>TT3JsLQzTguSE!wb4wAo^ny^d!GBeqwLB) zRytUb2ZPXeX4lVG8gRr!DIi{=LFKd>lIiVOJKTpOje=pIB6sSa~RVQ|S4i@O1$44h+Wt literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache new file mode 100644 index 0000000000000000000000000000000000000000..9c2b842a84992053ebb351c077d0fcde43d77669 GIT binary patch literal 4962 zcmd5=L2nyH6yDj5S!Zk48PZfuX_cu<)HG_^#z{+MD%=EuAc`Oxx2jr%?6p0PH+6Qc z-EmX*K&7Y$gg`=74;(-O#D$6<07Xa~$`J_(Dj_ahxx$SDGH+&f*Ky*cEu~Tqb;q;W z-8b)j-}k=fL#PjZc}~Z}>v&Y396f>t@AM&zR|fC)p}}knwU_JET0K#+RaUS(&uS@R zqu{etrEZtbsWY#s_=9=#L!=E(pj-KA1dF5Ud-;>~AAbfGqxwpIOov4>KATU(VevyelfTCopBR_(pBk{3+m+3~vI`a; zB)t5G3BE|)%HK}H;>+Dj`LA}vB8?z&_@`=UaKDDy)G50adU{$>keN_5vw~t68So7$ z3hqB)9#b_%G5g>X;r@A?%;2Qnp0(MGIIg0Mh!Zc$>sj2N!TowJ&pg{%jxNOzBrR+1 zga49Qybm5^c|}4v*vE3?A+sVQSWO>rqhrJln>rVtmV7gm{P6@gkZW`c3T>TU7o;Sbj1m(&-b6 z6vHGHiR~~KcKGSY>1iU5ULn575?QlZja*n-AeK`hRl80dYn2k;s#0Rr8#Sv$*>TM< z6g2gB^2Oclro%547;*t-Jk3wKaPubN^;^LNK8?0rp$@ZIOHmYgeh5PmaEB^>q<^iq zE3_L@Uv$;(ggGW^7eH#85_GC_F}FnhW}V5xnOjSq-l63B8+NDS0)}4qX?RTv5U?^L zSg`d(wd6ZVQTxf$1*(jQ@&=fEVpO?o9uSPd2Y@g}K+!@?(de~Y$#yKS1*wh?OboQE zp1aCnpy&XEZNhrkbnirNk-B;Fj0D0NG>Pw^9gxr_FT2iF>aiGS!iDp%PMje{DGEix zS`8XfA|gquc$`B#gASrF+ZAO*04X@u(~cs*M;P%|6x|v4aUfTAowCJ(__oj*is?~{QGXBA(xGbv zZXu%Eky4ASxV8h>Bdb7ByHTfb6#!~eAL>aCA0~6xtX0_d;ajm-6wSgQFA@2!vA041 z!z0Ghr6yz4OCLQ(y0)wJR{H4MM~&`X`N!g#cr?HVB=V$j$!J&H0^{naq=Y^yqOonp z&wpray`?CN4`%Q|-hGDBcqoI1w)DTPDzqY1Xg$!>?tmqHz*V5ItpMGB(T(^G+b=X( z6dOO0$T2=h8CLh zumJ~k*(~`F>x85y?XC73W{pQRp29t?WA2{rN|$qbdXr}W(eKFXE5iP8jo4;#269YMJ>W<4-94>442@u0a1QXuWQz*f|)#gHmzO5S>wC~JD4>d+ym=eZuStD+rrwRhXu z(BMhMVis@mV8r5jPRGa#VHl21i%1K|d2^F!E^H&3|KCLK$@xVx5ayTQ*M=~(C`}y( zcBc8+;1`b&G(8!aT9yvyGvjvyqop?Qq6Oc+t{~bucctsxkN5*iTK>S&?~>zV_yokvWbh Ic*Fqu7vZABoB#j- literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_array.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..09e2f8acc9336bce7885613638b9b2af3ff95002 GIT binary patch literal 49 ncmd;&v`S@w0Y)f;2TG^sq$cL-7nc-e=B0~Ie!%wp&?033h=d8> literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_builder.cache new file mode 100644 index 0000000000000000000000000000000000000000..6c81f153248d383a02df47ba397294ba9f23d5dd GIT binary patch literal 4184 zcmd^CO=}xh6n%F_qtPfHs~6)Gg#^jQ#vim*E4NTYi(-Kb35I$+E-s}YYof6`sw}B* zMzr>(#bnVg3PsC6HiAM36jGW+7wx*6_Aj&)0{IKsP49d;mLdgPnN>f1D+F`-4z^NKtt64XJ2WwT^VVQc< zGS(9UN}p&cNVpZtsd!&vqR9cYtAdCdGDXsnVYyDjT4@+7T#F-jY^gW>BBcY`42vlr{cl1q>iuV)q`g;i~{!MWG zkyrdI9qSJzZzZ{{KT1;ZlYFc{kg51FW$5=(RD7Xu-BGBp(tW*?rsBq>6Mgd%71^m1 z{pu8mw(10LK@hcvAiV|m!QCR7Y%|}L=;C~4=J!J0JX9fZd@q04u6LVe-fG!S z#;n!f0ALK2UF~B*WK2uZ74TXE=lZxJQ#p4N7mK)fZgM>S*Ez2pF~)NK28b^DpNo<# zfq+=j@&KszFb|075cTLTuDv60;p+}JUkYL>1H?qI$1w99`~l@#?bfZD6DsCG42mge zJHBEPL3>wGDWX!yY+AMx^j!--x!`n7q!p6KkX8b`V;K2cnoYXFH>w6$4*3YTTH=8n z@^dd1em2j?&rMW|sM3JNH8@1Z9c`HgXSRpSfZ6m&sAH)4Ci#0(Zkb<(Ow?mwLiSyS zP38jx1Lp_S?(J^O<}UQ1cdYwAG=VC=eGFg=fYJt*)>8tiC7hzjxkA^n-QC}}zM^b*+KjE;6`zQ%K>(_@b>rUz#>wP}>nDfuPRperDA4>cg@@fwWe*Bw@tg-bWplN>*9x> L=QcQR^H<VJMxRlbV>TpHx|rS{$ELnwgW5S|oxZRa{b(nU@Zen|}6C_NKBU FlK|fM7iRzf literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache new file mode 100644 index 0000000000000000000000000000000000000000..3657f591620fbb1984bcdfb66fd54bb8557a179c GIT binary patch literal 1934 zcmb`IUvJV-7>Cb$N>f-y@C~wr#f6SQ=7pye&EHd4A`4PamDbx`62cE(^H)A^B1e zFtwlD6qb@-1Yx*mXzF3HrGwM79ZT=+5#rxtmn6|K^wv79+@rWAE02LoZh+i)2CT@_ zR^vWp#W|H4XKtZIs*O&B6^nemk>gqMhZSe6D62%ziis`V zcKigC;Ge5#uTO&oaFK@SrQu_Qq`{T;Bd3vJ*D?=Xvxval3TQu1PkVoyR`zIxa>En& zV#ogrr={fB=HdWzfT@|u<%Ut=x8E7t(A%2NQio|-P87pqne}#VwT5dFuDLd^WN}5p z6}QZ1F)v|0+)-h(7wj>!eB#0lz|Ur>K@=VUQ0Vfr60c%>T`p|W;Hltvx# z)^)(oBP6V#AvlC5m060Z0^VgI`{O*T6RsSDBpmfX1IoGGP&%T&=!tGO`%d@i?dkGh zT$k%wz;7NQQ8mqRZiZSNaf>eZXqh48TgjaagNYfNat zyTaEey&qd?C{7vLFmz1+8$n>y$=|27zo^^@=PH|J|L|whr?QxmFm>rb5GF;woWdAj zXbL~MXoP(Z-NU_r@i|P(n4a@ILB4>zlz3zHwajzXu(hD!ke_Gwxz`7o4a+jEJMb4j C2;Lw7 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bit_string.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..e7f013d77b779ab53ac19ad95a796aa2567c499e GIT binary patch literal 52 qcmX^5A|sUn1{k3Xekh%ulbV>TpOje=pIB6sSb3*r>%_Bl>7@YmW(`6B literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bool.cache new file mode 100644 index 0000000000000000000000000000000000000000..5ae07b5b49a7571a716a53505f89508a787320ea GIT binary patch literal 7078 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@bytes_builder.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..701db1ffe1dd588340d9500aba145a8b33520324 GIT binary patch literal 98 zcmd<{vr1)v0cI#e1WKppq$cL-7nc-e=B39cm1gFoq!w|Z$mL`fm++&ABxRPwCl(bY ORz`h4w=v2;suuuDoEL!r literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dict.cache new file mode 100644 index 0000000000000000000000000000000000000000..1cff4b455788b7653d5f4a93ecb7c07c9ab1a00e GIT binary patch literal 12268 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@dynamic.cache new file mode 100644 index 0000000000000000000000000000000000000000..b0e4f1fe8d576f972851f3c8c264f7658c3c7d3c GIT binary patch literal 49216 zcmd^o4Qw3Oedo?BDT*{{>S-leQbcpKmTYoMamA%biL_*i8_Bj5Db{kO(2}B%OYTry zX}L?!E+tWQA)gyxUDrX~G`Vww1PF{2Zi57HeJRjO`V|8`1V-E#xf*rT6m5M8t~DGW zIMf%PuQ}fD|K6L={oqoZmDdTtd7RmqdGnt)@BP0&b_Scm>o){Hx8X<&+h(xc6N7)K z{?B0O2TueUyBvDq*Mp(Yemb~(DXXXEqv@qUcP=%bnGwg6g<_yHoy|;-ZBp6pcw(2* z#4?u?S^RrrI`O8`6xyl8lbV8^4)tq|jBe-uY z{}smGQ$s&dBFT3YB^dg=dLsF}ik)|x&nMq&#!jLooIKrvou8~Xl0RLKou}HylTWu{ z=hPkNlc(>%&TqD#NIu(+o&VE5%HCE&@3zN7Pj)DwXSOS$7qF>2l+Z?O+wW0AF>J5y zRzh!KYwJ-$VQgQBD50-ndwH)CdIj6~VI_1KTUb>?F>D(d{$n#Xs-b7Fy&Y0R>LxW5 z*`kKx*xI(Mq3zh-?#8tmt_$NjY?0k+XcXJqL%4oe4ZXZy4ZVs@9mVz7+779qFt!_q zaXq&GmBhI-`0XO@!}irlHS`L$w^M59eQYOmHFO?Zd>;R?jTY6=IJWn%;=`8NU zw*4Be$7U=ALr*RRJ7PE4-prvw4+CzjEwREbO(lWVXUYnBWZHoWa-$q~!eog%= zbveIK%;a;aY=8hIxRc*dJb?eD1$aFcHkKpCV(m-24p;{mscV#VU1mF@*xeIhdtz)) z^zb8m$mA!;F9bSi1O;Zn%cyI>;QV`^NM;rK?ndZoMHyhPZgPI3G9P|UpSe=d#_^R4 zx~^qrwUpy?Url8f@gru1mRrnbQ`1>p!#pVfVl7XXE~JcNW@a&)GTOA_(t_TH`IFWR zy|`%P=&qT(Vd#a0d@h~IUDBq+yHC+$GDY-@sifU=k9O>OY94sBfTO9YDNeoGvgiD} zoaCbw?$c)TfCWDs&lPdBkSflNY8Ni{UNpyt@X2XRWQ8erjWwyPc{^)Tg8A7%VDLA0 zzqWfh%^9T0`9LtW0QyUqXR8UG_-B5Q4?@m%x*v(+?6_%Y5~HR z6zIDiMDFu&hFMn(nkBe>#R3TP~cjSyPfiWm)-_He95O9)dPxJxXiQjBF? zY9c^fUVUvH=S#_4Sk_8&uC2oYHF}m-1WSwa1z23)+VHbSm? zAejEH7Xv}|r3m{{jD0DZ*uYoPu{b+su;VmM#^P+uV8>|pP@Eky*ck1O#My`e-n+^o z^8M6W=cZA1Rhq+Hx-kEFzj|PKVX-hbiH{jj=EMg{eA=}@ClW_FrzJ7aG}{TWw*}l{ zFrcm|{9zz#78IKmm9cU03Wh{14&c1242WgJ!G{knPiKmpSO$W*OG30v{E%MY{pHhO zHw(J9sG^yo%Tk7sS^}4FI9Dj@sdSxqvlDD*OycMW+ZJQnqRa72ag3e~cGfpUBvG)z z4ssOi9EOsi@)AAg%DlS%&(<%`WK)GgW|jaHSemJzkPb27mXUPJVSzEM_dZVYB$UDbdgnjid0Gidd8EC`wMt%0{)@_&3D66l zSI44>Ir@Pgyb(>jXC8!fC7OI%u@2wG;Z||4)U2#kDWNp^BfI#eBvG0h44!oj22YDW z@YDgH+4S>bgk6lWi=2J}`8Nerw9UL-$J>@Q%9u@zjV8ZKoOy>4+Ny%PihM-kic$n1 z8LTTSikJKL=vjSU2P?(VPM?;AB2&wQ7bAQOIWkvFWpcn9ZCU}+L}nIfB%5907$mL9 zdux#=@97!n(_($vV4t?n64wN(>jBTzCzw2QPw;5odrG-A&eVy^`uFx};Xw#B<-4EF z=2Lizz=!;4&S$u9uJD`-_8XAA#N}dt-r#~@PJ1Drk?bAo-)rvTjm+JBTuLi>st+$F z2C(c`Dcif`hubtws~~TlAsR*$W}h`j9Kxq{Hs(BQG0c5!nkA3As1YBWu%(l5j(uI= zEal}*&^k%eA=vpQraUyZK_#hb2iH7NYwvf@W(*iM0*4EboO9r*x{GreBdw^1Au$-m zIVCvwwU3=VX%WuxW*6Q3S#mE?J+A5I_-p=qiPufq$ZDgTbYJKxHJbbbPDc6R=3q2= zAjo^(M9Ot#Jx5Zlylvy{9lUMlZAU=$joPjE2b=o_Piuq0)7D_{+|gk0wEF`OUrm17 zyOa)pfNNIPF&0mLQj&Z8ALs~gGG&5NdN0th_Q;T6;|rXQlwCSU986U+x7e(Di$I!t|1^%_4>k`o1fZ;Oc6r@ZRu68t#e|{6XTE95mZY3&R7V z13{@m*IR;uFGlR5A#Yx&l+SXudE)kl!i2Mv(2B6iv%yyw| zvm|6?Qi`~NfLJ(A-K)|0Y$sD9oy7K9G&uQ^SLIe`W7?hmV2wJUG$^P@0S}Ea8Pj?r ztT)Dbz3vWRAMRYEbOY5!B>9{~cV8oPcj7MoQA%;0lx;p)lk!-~Gj5xiZ8B@KY-U`g z%!MDPk?af3kYqhM$}&%;CEHwMl|^s?F*hpm7ah4fNzf zI7NtcnwlA)3@JBJhdue(Q4_&)oqXxF6)?6biB;*Yy3XFhW~SO+U`r{2gd+g7nh27= zVhJIoFH-%WxYx^VYkc<~0*;ivBZ+Wky9Z<<+P zILr~wm&EDAZFVbfaOAI8O7w29-(^fO%z-ch-Q01@9*ckTi%^&Pgb_ipC*Yw7I}~Gw zqU9#w1}=HBwG)=|W*_sdONS@D?TKwn3Aex{rwU8(Pkc#9m2~+TT?cv$QoGTgh1t-+ zaegkG+#nf(K4J*YchVQ}uIpv(L>|;gn?DHG!whMiBxxr433?3QkA7`pPS0t^BB!TI zpoBzaQ!{g*s2Ut2K)8wc!F8rhTg(+RS-MG3T0LFpBW)d8Ga<`A`7k-CqKg_|q+amAps8^y`p}v>=vaRzXx43iB#N(DW?O&tGcH8c>1iRB0?ZZ~+&-!fr+3(@-PyMw@h5T99 zzUjp_H5fdb8w{Q;4F=C${=icYx&R)Fb$t(BCXYop!x>EorE`dr_)Was%-b!zy=#p` zznN@h??~eDFxkpBc1he&N}>MhQe<7$ zY*y(>rKXjV$Jyqy>W?(#HW=w}p(VX>&fT~7s?nGxZEc*sm4&3-dlQAk*MR?+*XY=% znUu2XaF_j-<(>rQ#Uh?y4=U>E&X|_AAxm-KAf(pW@|HHz09KQ8Eh*Reg;s>N0Nm*%v z8=&ADi**P^;BIAk_^87Cg*c+=&_ z8R33UQLjMkJuc(qCgN*Kl%6EQ2{zM;q=L85W|;FBo941{nnxhO0oC=6-kVHC172bO zSi4G2p_{mOD77cpR;8P3Nff1%zKx>o87nX_^?e#xMC@ry+BowOdL4 zyRc*;qJq4*J1ipVaL6AOI?yw^+iVHcRKBR22#bsWBKA0C1!bBeQd)NSZB z9R5^rd58{zytI{*lx@7-&fAahb_Z{}czd^x_RX#S&|%;BxNQvv&-Mm`=OYaU&yEIz zr^_FB>cLm4%H93|*Q~UVz4dX)GU7k%ty@f_=0%vx((Of?7_OJS725J)uhDh5p^UD! zwRdRs)>!NHDl$uMb1beW1Hy-QL>kjx`~K3mZZPE;vez!=3aME|pPb3-#tcGhLCB?I z+#3^u4;O>AbeVAQQF_|>{4l_k^sunBEX_(#8JOqaCyfkqXpvk_W+c3>}6x4g2 z%GjENe!-QshI#CAiz^0(1MATm7cw{W$^7hOpqul;r2yZ1|4~>METwt@7gB_p4Rf6h z3___+oTeGqQv+vNYaqFEM9kQOv)mauCX`o;lk{xAvk;b43Mj$1_Ii6067a2QSoI=;|ueiHB6 zMBurIz#CXm>BX^~hCt&>x~Avyi9t>sj4k^`YmN-WGj6FdQ=4nvaee{!MMiNr}xCf(}~sBLqcZ8q38HxaCYdvHr- zw5uvR{aJ2&M!%Kl!Hh;EZx7nG>hJBH<)A<>4F3BdIZDV;nhkVj^laKDK3?o>C0|PXC6et>oEn zWBBLSIcC^E>qAQNJI#CqHKF7g_&oGJ4#m!HD0UvU6+3^7!#C~2V^HkO*@~SvaQL2m zs6(;yw5{iP7l&K9Mv3rp=&2_7x7!LPRk?>Nc6RZ0H*fFd?R~uM;cYK(BR(pB?(t{t z`$qb9H5fd*8w{R%8w{TN8VsJE27{;9A9x65_@3-aiTDFtv$CF)QO`?d6#fr%ynmNe zM(y`fIZGM!sr|Q88MXhzp^UP%RKvHZrGnaNKi500QdLz(UG)nvW{srBl36uig!(Tx zf9nZi^A;A1lf<(JIw|js#pWfRb8soFbs_d!OjU{-Ztn^QAKTwybU64}BuXT+ul<65<9fk0L{^k{*hDTZN@_tvB!dAwsrbAg zV~p0sqQZh%o<)^!Udp1rIP}U;sjg|z8lvQ0H>>aK7?DDYb=`!nX(_^%Vr(gDnu6nO zz+gi(a(m)zk0GtXan@_FJ^rhb);i`Mou?^VihMMKrGtLg{sa3-NejJZ~m(J9_Trn4|Tp}6{AcZ)Q9a|?--GR*8i*|r&{=!^hjyx&+As#(%A2vfC>apda&*Sh&4cpk7B&)>)4claTR zH86(^bN+5WZx8Tx#7ACl*dKJ}8?U#&!QeUI4?OjuMI-(I*NmzUEIuws(MF;~Pu?jh zk(5InYRGKoN?H=KPr%TtL6FQY6{iSP^^(z5+i7i#lWnFH;BspZ1%NQ8~V*oZgf1*s6~ zY^Jrm_`PYQ#aNVTV_w?&>Q+*LaaTTg@&&rNFP}vaN@^Rd(%TA%e^h$%89d7~vXOoc z*+`#k@jkMYS3FDZg?hFNDFxv>K`H8GZ3F2e!ee!*27(hBtjiKeZ0`G9jAQwlovzXmDW-O9MZj_FSvOu8c1V@Bpo~Ld>WLBBXu>ON#iLc zc{loyZUfiS48GL#yT}a}>*nz?_D86*8zA)8q{7DhG~EEZAEZ=1-F_wbjwN7_qQVy6 z08)OnMZ8|=2bT^;cS{GO>M6cOUMR2s5I!d#JGczN!>ES31@xXG+L)r<>Hlj z&#t845)U5b2uB<^{D1f$f)h4V58QFiyK>5(a& z>Q7)_W=R4P1?CidlYz8Ez}NghAWY;Ne?;7frOB7tl*zfttkg2=0kG~0bxJ6ezr_`a zyL$3hM#;MmTp9u8&M{Y>pqM)&v{$bP(!!g`zmzrDB-bEr=rJ71wF=jR*0(j z$W?T}<5n0Wx5E4tq+91h1kb|u9fciCxnWnWIXpQledVM$`5m_bZ6fhET$&^tr7DLo z-|OO2@j#;^gVod-dSLDN;6@VlAix?Lp(lV3*o{!h7psUFPOj+eizFk+j#8Wh2V`b@ z*7z*w=h?(4hZ$Xx&g%u9Q;fR-)35SsWK!Xm_gQJxz$;;?_wW)ts4O7Th7s1GL@GcA z_X~y($;ouM#F_<+s7rx6WQT%@6Ny@;c-f)J-lUs=NIm}n zV8M~utYid@*F@gPqE?T*hWv=lU0M=7s5!{1>WC6aND$-6VWTtA5dfN15UhccFr_^E}16L%YL)zU4 z$5$awSnMZYu|FGOXJhPa)N}`tPQM`aA8ZMss1zKv0PXbxE zILyR5Ch~UhG#rCJ7EL@)=gOtzI_wWJHaW#wZSVlGW_vwdTQMX^ReX8_?wjuM3UCg* z7YD;D;O;wq=MGyy^LZ$HZ0qdw|wkN7(~R#va9@U6!_FnHi0CK$AC zE_IvpJzHQ&a~8))FL>YeIJA+6C@wp znW@$;$(&6fR*+=8NwXW|Z6pIzC1H+G+?Z+{Z`zsqrVdaah7&?0?YW_l|6x7LA}+!ISs3W{g&0?ss!Gx$=}tkre}u1i6BZo z9AaFZ{B?2k_eM*_70NX!#g*%B7P}7O3T4pyc7%O9#=gxn=wZCfsC4X}jkB``J4dSj zM4TlIc9wQe#n~x?C203}oEYsWp8((twEc&*sMyRCH2?sSlNY zz;7IQX+fIiAY27-vqDC!tdviuwTo^}XF)LN1;PdQw`ie{)+!v(n z%+5F|yWtiyXGg-uR-r4N>d~E7an<0I$>dnJ$JIe5MgbWz%MO;=*UF4!*(iU@K4_hF zrU|eMZm%lwqUQrtSJGJzb|xRN!1D6DvfhBBo|(ltjB>plY47Z$in5s5;5$b?HpXq+ zZWF;*+$7L#A~=p^S{D<+iN-})s^SxHT;UW;{F^WZYJ{F%=|Cz=sH44P+)C~-ydri2 z16f|*?=r=U;wA1}9{kC!Tprw2gQr%fY9qW(3H0@-jFN&{pK3%^7m{n!h}T73Z>#$& z;Ig_a&NcpEFY8`OasKB$YA;isT$UV9URj_DG^wnev&)-UX(I6>Qt5hB+>U0QlyMF<+1+b3LsKaVG#6~gMXKvt2Ko3aX5DY`n!J#Gpg0j8Le zUSZN5ph_7#j&96qN8BQryANnbha=ck-B>a`z{rP)3UKym(~IyRD#HDY3Mo-x+pBsm zg9LPK!b^-QCFOKrEFjHGr%SJ&AVfC1~PCtvrF&G8cNpS`q1`FaJ{`zT+_h~C5GJ;{0BQ$A|( zPx`Y+>qF{K`2(Cxmh}xWKgp5po2^m_JWy$VYP$#gQUcp9zrqI1=l_7EhAr_f_G)Qs zRLffYt(cD0AFwjNTbtq(47wec{~NP^J!{YS1NMwhw>S{pKr6ytKWE3Af=L|sL!=UN zBnmnOjJ~u%NZ)^ zp_vCh2&1eW`st~2Y@hI?+_q16vK-kbJmIBYmV(rNH4IG!0oiK|HiJgZ|Gz||>K7kX zvEYk05W%a_D_fZP|33Bhe{|#znhkVPtOWQmVY^Cv*n?8aCkv9VSt@^jIrJ^WVO(A| z%iCf&M0A-j2_=3xqRTGhJ-H__94!Y}yu&jbrN~%XJ@!ex;tDZ6G^8#)qKMF&`9weB3;F^^nDRog+k)l7}!BX4aAsP2F7ILA~)dpjJG45rRX0ggjGh2&hh2)oG zdU>2^4Q#E4gU@Eu85 zEO^R7Ywz_F%;8-;Ux2*Er*G7mxtc)ApY3XKFRxH_&3HeFRE z<~`*Pf9RXMGu>eD%=iOO-S}s!D{(x+j>p(>URMJAbBgoH)4ZKoBex8#-e?j5FPvM3 zc5k3#e4F5w%VgS=CZP0+-16XU=a$_J(x9731|tCVip3SvwN<$-$)%O;)5UZ-J9gYu zp>vbhb+fp)3~O~(w(LXJ0K6SOWV62#bZ@V#U_4#%F=kk{#pso1JXgng)(OT^cGD5m zqqGUb3#h~Xv38Yhj^t~NxF;jsN&#M=xim6yy?<=!L0*)byM<0pE0UcA zBWDx4UkrBgnFNyCvCWs+F0^fCK!fv*OX>f~)+?=K!K6?Si@i=h;Wk;_=E(W9KNQ3_ z3ak4APaP;4Se4a8&Zjwr)7MDh5a}IByeSA=6A`%Y-@&I(MUka{Me@c2k*a1VTp^%I zd;9?r-GKiH!|D-Y2-m0xlER<1i@fohd-oG3U29e< zj@BcIO~|#7I+1{?fPFp&M+CK#WIILWJ&r}F$I4Zx1lQi;ttZF3ST+?Oi2UH4?L1*K z`X#qGt`2l_G74WN8j+o`DtC!1k%ee%lgf6-+3t00=QP`WC!@%zEo@|zjcj4ZF0TpP5&}g(8rXS&SxgQ6zCpd>Rt4^^xvwYW5= rL|71ouk$X4Pg&q|XfOY0lCZ4}3mZOL{Mk=3!=q>V}2C<<$rELcy{v-}cC zPkrwxjj%=98KeYjk-)~6de@BgXYyA! zqVdJvnf&2iGPaLshHcoElkdRY9YxGrsE z@z-#fn_2t{uIv^TKZz^R$Kq+aw&EUKuiS@wa3!|mJ6zXyu=q!~u73glah-k;W8j+R zxF6Sa0^i|!a{$l56?~Y*`*0=p;C@`uK^EUR$S#*Oy{gwMjO8{3L%9MAD=ZoaFct_X zJ;S+VFcb*ny711Fp0s#H`j1v2;eH|S6PeV$KU{G`#W zmo46F&ujdGT5W3FHaLB#YZq-kuUFM}a5R)mSqES9Dz>i#1 zYmKUA;Zvbd5HpPO$GEe`WIC1E8|9hQNR;>E_h>Z0GCxp0P?l^1P%-s-fZe7bvQk8o zc^a*-E zVHy|ovR1x1LAdLzIHE{EA_>SU<_IGc-VK4?qFs}ot^J*RLr(TKjGol9#cEZr>Ha}K_ zHcPq%Rh~`G+jhgs4i9Vf)PjCqZ)jy*O&Mlom_7}=ckXY{owIm=Jzvvoy)-aYDm6{D zv^WbC6suaz+DmrujDg>@EI*1BJLX{ttSm2%FBtVbHZN*iyQr4zED$iB%JBVsJT+3_ zSYF+*ZW;%9OQrMoU?x50pTG;|~8^k+Ijnr!Efe<`hFh=TTEc4yXEOuGy zOmjf~vIpeP<(?8C?-n3`Ag$1gkbPfTyl#MOf--z&QR$8JKWmmX)4`@;1|s+b-x+2> z@{rf0hx`N{@_N*r(F!07aA||kWgB#dd@vQyDUe2w+XYUb2R`8}Z9s8|7mmCjzm%F9 z;slW=osJb#Q*Ec~4g9H`3Y-WOEuHFd+tueOL&6?vxl5pr@M_(s2&Q zj_a25jN6Lci5$Ev#qK94b_Zz|epKe0H44K$RXma0s_SsP0P>kR#z~$TmEcJaAs}bY z!j>me<85(yQ~!AXl7#?dYO}Bx!?0J4LpM!PWMqDB@}y=ptFCZX8g^n;!;U#PxckY2N~$am9iml4Ge6$nM$mWQ=GC zT0`&4xgL@W)h2%cffao34QN@Up=s-7A>RNw6(zGte|0z(AS?AUTPO$ zBD~_k9cAdw(xHkD7rIq3x}(UICijn~MR1~js|nKAeRL$1hWO|o^^Qn7`P=Oq?(c7q z%XK98zQ4&kP&^-xeug`{}DFcw^7c04dL$-00s+%1z9e5iz=LMQ6p+&s=5U# z>M(a91*caObfRI@!Cr@M0q0@_8D;jvT}Yfu2C)+7ZJnhlz$T<|tkw4bd7x3DbF!aw zY9jsU*yzN;gO47ZI5?gr?XJ8PL-H3Np`)vF` z$;*k35IpJ{pQB8X&zVLI9NIuSXHr}^X77=NbeTnij_7bVfQO5!!v0i&8x3M@25#bB z)(wh^P(RnKB96=C&;*qMr&=cFc)rOSpwgB%68Td@SF%ZDg#-rDB{aI4=Ji^`Fl{dD z3>5DuwWR;4Iip%$4rmw#W1YodBQ&J@0E`RhtTrxs6QbOX$ywr5G!M+?X8NP^5T8YV zLYQ*{c*EBR-yK}CO(ZH{buHk0PEWojd6_}YKxDNAfTORg{fT~XIAJg*yogNlDThaL z1xi!^y_b_EPlB|HmysXURQ%T~x_tvRy6c3q7|V#i17nY74xo8}6e^{H!UoHn+4j|K z%Sj`1D57gsZ+M*b9nEoXlo%k{y^`A{MSGknLAE^UpgU=a#JMUJynMOOpt1?XjWQsI z$@)^D%r`gwW8-99s{k9)qr^W7vgOiGd^(7#R1ifV$wo)nTgnoDT+;p{-V9{5#LP%5kD8AqTo^c$kgC!w7Wi7c@7dNRQ(d z%sPh!X&Ffw4_bazc#v}szVhG+7P>uVyrw@*3xA573;wkCT$i-J73-AM(k-i0OOY?F zRw#9xZ0A*r%o8q@s-%w36hK+dCEN~F!^z+$w{H0K)^l4GmWZh3a!WFIlcFSYS0y~I zLTZ2Np^5lqHdRJ_*V6= z*Zwi?vT_|BLXVgH19iMM9slr=Up%6)B2_~~v<*ZMJD_ds58TGiK?ghV6h*`%TSbw- zZtLEzu-8Os1~pcL)n=P@9X^ZIT2nggiRO_UW&44S-iE^MbPmB(=^a#THrn%9__7?g z7DHLMyu=+2vkf&5`U1pOa$Khu9A_Df(A0~_q07WhTPBMB6%@sw2>!)G{CR$e2p;H9 znKv6{$Wn4*3-x`?y%El;q*)fm6xC+cTm%))Ybfp>a%;v53kxY(D-spsvQZkYsr6x+ zTx#B~RR`qECTsgg9usN)hXa2YP}s~;4N08ds4jvU-W!{p5p_@Ohg<`5d?ngGA;0ZD zE$6ydCn2HwDP;aREO_wlSgtZ=S&aQ${t})>Glo4Z-wLo{R%$War=)-*sBFKx7ye_ zs)-f4QO(hUta$yoFB(_aY4Relv~n{LD%maf@w&%-Jm+k9IVHnEu@^9m690HwydpPU zbX{e`Yc27iK65(9$tx8Vj`yf%s$L;Nr+?=oyA?KlSu92@Wz}lIoh=$qi)~I27;JO) zUJtpG@lJM$J0`uEOj;FbH1RaId@S6e+<=pA(OHsL)4sB@( z$)qM6>w}nHdW_$GbRL5(NH>L zC#1gQ1K?BZuo(rU`FE{EjVIxmV+50Nr}(2?Ki@@;qEyA+ddpFGt>aFo%BxNrDRSBc z+snlJLUNLRsG;PKh+Nu?qSW$%0aPsQ1x=$pU%5dh<1h+Nyhy&t3p9V#NXP;t4G630 z^(_4I7+UH@YE1xd`0O$#Ut*pRi8;MTa3{mNdXWV)jScT^AOej~EfL>c{bLV|wt7xL zke5O<5x*Fn^na5K!LFsYZ$J{)sj6lLLUc;<2-ck?iRZ{D>0}+LOmvb9wu@TLds{x) zLeRsexuZG^omb!FNqz8|S`X5n6Q3lC#PLLFg=>werg#@5@}*eujXakAm&txd0ctGWPG7!p>1F66b^hF*?Hp z3Ef_Xw}wHAs?HU!-UO}3!-MiPRwW>CiVxxtA2j#l@P{~`Ca@@2od=5rPq_5Ch1D6B zb3$X)=prm!3J{rz3W9Tv@k3-2l!6+i7DHnep+1>4^geCq~i- zTmlBD9ZH-_knqYn9bRh*?|qL7*I`#{JzYM?cs7S~Llh;6ZhYM3%-=6?r$*3+wEcoO z;pN(=*q{ap5j;d5M7Y7pDk-3(DBj3oB%HZytaRp1XOSf04zELp+ovsR-&q&2&sbc< zKI7XDefp44364TG+lnY&4}Y(+psd&mf#7#R{Lx9cs1;{X;2yrz|7yR&B8Rb!Dvy8- uD!tp39a&|^HgT4a&h~`Uu~RsG)-O(uIj2FC@J@UmdiH$3h=3Sk3;QnzwnHQU literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@float.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..8778fabea0ecfb1bba5f2d9f8f7571f6199c8f09 GIT binary patch literal 48 mcmdOB@lR!d0Y)f;8%n3=q$cL-=NF}<7S-Fo4sU6B@gD$?t_rOH literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@function.cache new file mode 100644 index 0000000000000000000000000000000000000000..62d17d5507a4009f069cda23c024a55a73932d0e GIT binary patch literal 5806 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@int.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..7c99d5d905225ba7c564dd44324b01b038d7953b GIT binary patch literal 67 tcmdOB@lR!d0VXJe8%n3=q$cL-r{&})mY@pd7p0^Y`APm?)gxqm8vr+L4cPzy literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache new file mode 100644 index 0000000000000000000000000000000000000000..a9d1867658d08f494777bb0f35f85d4e32891791 GIT binary patch literal 2856 zcmcIm&ube;6yDh%mbAn;gQ<&4Ko6Tx*;VXlRZ41%lo*n_rft04K%pi`tL|7{d$qgl zu4+5BNv{pL_|RK(357y??WzAkp{GKRg&uS0q32$lH?u3nN)?lUB+%;V&CHuO-}kC?iy)4vsRXKjz!on<$WBq_BUaUxAQp4+-9-zv%U zQ^Wj(DAP~Kn)N+F<3!%DzLC-RP%*3<3L4kc$hxkgF{?eYKttm%?Sb_-H=ay9vVNFA z!_KuVC&!KamzI+!O3`7hZkrJElB}5PM59EPBtj&K7M9H`vLZ>QDl0^m#8)GPQp0?P zKa(5u8L3SEcPWi9kUwljuAjtU*zmRObr~c9#EI=YcH{tyq9B4&oH%GLz@f`L$MxIr z5eER`LqD+(mUJEN?XYaM8$-mBZsaou?Cpd_&|-W=$ag_s9Dtj^SGJFS=*H-AeF)u< zd9Kf59&3IcZXej4&|~{>T1tbtLf0Q#nPbx z?(UT;3;oqc!Co0ECprlCuvKm+459=)H%@pKTa_{x_qlak6V9cM9hSEJ(!l~8!2!Gn z6*$50VqB#B>bZ+xh`H%Owu~}VG4j^?W%%H}Ugw9`b%|6T=YPpR6aadD#(wi9_DenX zB|-};v|!Leu5Kj=db=n9+{6huG?xzLK6AakUlhuk*-Q(iiG}h&?QJ($Dqloy!eY2= zV}0fXZxI2J}UDz(yjw$eh!*>bzMDk zf`(XzVi3|8IXH%Sg@dz8Z{Sleip^4F`oiZz+$8v+TA8*59(1m^5Pq-05$}A@lH7gE}vJHF`aty(~ zk19ZlW5%GFvDbVpmM`WQt3M~ozw*x%Im-e!q@uWz#sy+z?jVSCgYJ+DeX72^?NBw) zp>T>cM zap8rS>*=wvsquC=F`I{B)@9MuQzOd$HI=M(EXXxw-ot>Fl3j&X7i&QhF?nPZzykmPY YtAEbou9r~l9rP=A_lmdqo8e{h9N?G1z5oCK literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@io.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..48ca73e0ee43502e40d1b8b70f34ddf19d858229 GIT binary patch literal 49 ncmb15HB4oI0Y)f;2TG^sq$cL-7nc-e=A~QQ^zyyy|K%?LjF}3z literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache new file mode 100644 index 0000000000000000000000000000000000000000..15bdf1d6fc3e94574986445cf04af8d55763504a GIT binary patch literal 37904 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%0D{^F9^Fo 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@iterator.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..fb52d575e15e87bdb03fca9fb3c0bcfa695274fc GIT binary patch literal 141 zcmX@|G$oY*2H2ns9w?ojlbV>TUzA#0np47wB9@s~!i6G`lUa-=l9HKRf@)BHK}lwQ W9yf}<{Gyc9A~`$9l9Mx2rUL+KULRxt literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@list.cache new file mode 100644 index 0000000000000000000000000000000000000000..3b60c9cc8ecef600ef12d93823c7681a0177ed00 GIT binary patch literal 46259 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 Lc~|2ZcNPEuC=VMA literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache new file mode 100644 index 0000000000000000000000000000000000000000..cc21458a0295aa759f1cded53fa46236b5d63ded GIT binary patch literal 4737 zcmb_fPi)&%829(=;5tp>y}8}ive7hSfUKdYjSx~US*jKR8mx{d1?AFZi`#ll<0x@9 zm?o72NL-Pa1W1S-IE*XWfj>tMlhA|^64G{<#BmZJfwbeM@%j1LsnaB+DTls3$Dg0x z@Atm%_j}(wNa7!GMy4|*dg|!HgQK8*p8`rRYd@txdsBs{8+EI?o!zbq(DdhPZC6lh zb^BsbA~cpUB#`8{s!agnG!bd1Ok<@5r4s#c6&Gn+>5hbhyJ@8__^a0JOYVjAwo~iW zt+d@}yOvn32|yK{DixY6tIHU`cTlqh@sevy5D|!ge*glBJ{6Y<{ZKbP08vYlB{M;A z@`UK-V{h`8m@)qpaq_j4H*ZNe`6re!|Bm5gT3$4#WSrcX(9KUKaPmaSn~xQod^fpd zemjYi-x3w`UIHgpN;hjMoP3eWYu5;9pQUu|Vhpq!_^ivIeT@HS70^lv&@LxHU3cm= zUzuB z22hd zfbTHk89`!Mwn!COU2>fI9Lva6BF2DFx)gvv?tu?B9Kla=1#*$7h@*XAAX(!)10pdX z|CRk9GYAu12wC;4-FAHl1}=gCF(!uR*F8ptgl)G6#t+hcNp4tIIg0nkJ`UL{M?pXi zM<`)X7>GEIxXVn0Z*MofnOqO)dc5!m^eWYiU)wH zlnOtl)ZT8=1*n3%i+wQ5Xo|8r_5iUq>N?aD_wyo9%KWOvV_^Mep zZnCPE;X{pZ&_5r%tOzvKZn%yh zqQJ?$qOVfh33m89_!~aO=b({ zny&3MI7X)_sNN%&a13W3jgVpC`pmjR$zj&bY3RpeXx_8Tyz`-ji*^HLC*UtI@BHNT z$sN~OtE1T*ScUiLdDD!HBSSn7`A0<(z`qni@PTiGJ%-LfL^vV26>#9`cD1>7rCRR@ zqQ#BfOpl*BW#d+#!t#@b`_RCoIm#d(!=&+rHGIabm>H$E{10Zln*bV7#XuaCmgrd= z;}M(@9(v_xmf4XfKP)T!WPseu(wd~Y)h#a5+BX2>-EHv>eb^(UfDM4va@Dqd%_?{& zV6_YDcHOmF6w2&s(Y@nw2_LFVvy8rH`zaH?8u6AAF0u--ehTFgFqFNekiDHP%WB$< z4ZIV3S7X%ggmOk%1(BE1qp{7LU;Xzs2gex&Cx*CK5HW(r1fiHs*dFv~jDL3hm9rnjRwEiu&!Y5UD`|3 z2x3AXJnC+J{Jv(NTTipC&kvDC0`t5b2#<}m1H8U(4UYf>q8e3G)w>s9`Yt?$&;%x$r&EoIkxvjaCR?9(Imk+_eGLq}A literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@map.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..0b52486cfc5f05044b9b56a9fe4cd784dca2c15b GIT binary patch literal 67 ucmX^5A|sUn2AH4>9w?ojlbV>TpI=atnV-jnB9@YwTyl8YK_6zJ8wUW1PY+E1 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache new file mode 100644 index 0000000000000000000000000000000000000000..c6e2cffcfb0cfe07a04e05fe48d595584a3bab4d GIT binary patch literal 7261 zcmcIpPiz}m8J{<{dIrg07kizRK!f{-Zf#6dY!t9TNR8>i!$ zFf(ovSkx5~5>y;khyx%Fi`2tv#Q~(Cz3q90_JCF#ITW}o5_>^=>Lq;N_ulx=*m0*) zIm8*;@9+2fz2EnHpXXUJabLfg=5HMEE7PmLpJs(!&Nx3POir@GUnbev1KTp2EAF9| z4;ro`-|qNCD-pB;`fXhuj>hZXN9K@cqSX^t?4{d=9vSYTT$&J z4UD9oV7itF|KIwi&VRaV{EQ_E|7J6l&lx zO|gQPW`!s4_dEmdv#jvX94q`6{+>^;!epME+2#*Vc3RGnmiEj;*zmZXFn-NaoMknQ zF-_x{ZNt_Rnr4i`E90|eK6}9DSLnNIX=53`8@7LFsNcgt;DdZkF`e^W;};CE;UBP7 z{@F{p1Bvy_#)W1#3R#gS)%T_O<_8sD$%Mg3k$z6gNE~fn$@hj*|Gys zZ#jF2r)bpabC=K+4PR8h=Q>vPdNwOAUxqo%=Amu*@UB{|5>>L|8zPJl#AmVMHm$|g zrDaif7MH}2#0~M|rL0(`4nw-(ERjApWFMAg>>gtf5H?Nxo8dqL*JEsLYHWLqo(Pjq zBA6Txzy#pAR_50Z`07wb0w?vMi0N7~7PWC8!g9uV3Rvb2_*1r;`|T*Kx(~ojD`(peQ;dr@T2PVR+v;-I_w;6 z=pvsj@!1ss`c9GGDSAWFW-0djmR%D^jbOjwNGN3R-FkNh z5W6R056%)M08>0@JhGg&_-6$sfM8hwpq@oz^fnL>YqzaAU3ulY*n*rB9JxX!4#3_6 zP!I;uw7dsaO$6=($&!W>Kr_c`CneOX@5r!3XVCBhwr=pk2W{ zCP*NB4SSI(%n!^HnG$`oY2jR3`_QA4@Z^`)4_XZfqvZqw0v1N7+B6TVqVC$Zdjw-c z?5cI!3X6gN4nH@5~<;4YaVObn6bq%6ETgAlCui1Tr?cizy%rDp64k@Bh+hkI3NZlqF$Mpa6kbg7_GboL!O*5{ucx$Q89%i;!vXP_Zf z4G|sLN?A}c`saAi_cMRXoCWTVXZbB#W3YWnJE!rYn|(oaGb(w2mDpb2#3@2219uIG zdxoM9qfqoWjdw7AAMkhJ!k~|IFRKrN+phD-@`7oQ>dyT@1Sf}}<1VIdIa`%J8g3`U z-3OfzFZiHLJC^6U-U3AX?nAf|3=|R-xIlTpNWZsmfW^p%Bu8-dS{qMqq#r9i9vJo& zqxMqPD6Taei<{EN5Eyb)2n@J?047%&2^ZZ5${oy=zL++JWBCDOoK8Z-tZ51#P6K2T z+dQ$n;h?CvNJuCzfR+OW>TwVlJzek+V0-*OtTD9a6RFiq=UX1**OVErduLH z0_PUZm%1Ouxx~Zz7Vj%|EK8b{mfj8-bANSNl<-}@8R+eZlVdx@n>^n4;H*ANTuA0| zbcnFd_-BmDCs_5M3d)LcDWn8knNzWDXjbTwEeX(u3tkgH}V5c0;+tar_DL&vSNK0Nnn)-N(v+}w;j~!0^p@&niRPiQ| zGJ{1Ecru~HtZY;zPpZI^pCr`+`)KlQx&fNJEi9pE`ODc*J>a%xpAaSFEyg_qH-Ma?Ve9==Kf~VR@^{%QfoXS;QpyEfjgCbKEFoaetdHSZ`$DejAXgzF6WPS8s)HarFISgXmSWqkr4KGlgeOe&mnP1?!@$lL zT`=tB(7-{J21-3;EVEN7fT{o;SsW~Fol)d5Ja33libu2jp{sCE348uy1FuJ>ni958}9Wb;`z57~V43`)ZUyT*K&RhEd2 zXh#44REP_MD#V4M>I_}fO-)Eu0nfs--J9s&DVu(CI{fXU48MS=0wqcw|5`ex(a;h% z;Rlqj-Wu2W#Uj5r#pla>eu{n!nW7RfPZfEpl*g*;9Mu@qb(5!N;Pb@YhjXMVYI15_ NB%?)ubC!OM{SS_5Wpn@l literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@option.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..8b36f47ca8f554f7005ebbf3285be4ae7326420d GIT binary patch literal 29 Wcmb15HB4nd2j3JWvxAEZ-T?qDmIT-U literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache new file mode 100644 index 0000000000000000000000000000000000000000..35d8d06fca9acd52e4037705e4606d9f169c2f46 GIT binary patch literal 2704 zcmd6p-*4Mg6vuu2BVMdk;VSC721;+cP3kJQYm=dE5u$5Yh$dB9y;S01OpBA;B?iY% zu5a274RzuXfslCN5y4-95c~m1@E^cCJnU~6$M-q~TdYB4nkFUI_4T>;9)Hd`-{XzG zdeg-7ZG34CKl-}(=b1T-KP)cguN6PZo6mYabq7~MrkGvIKiwD2zrRFa>3~m_9&Fe-y$km$Hb1?YHEH!^Lk!B9uL-6aY zsyUw{10zdO5K6WV;Bq1^YS^)!@?=AXCM{hWoHi| zJk!Q|XmjQ>;a!@;Gjf;mF$7R$e!1#!)963|&TF zAy_r%0}1O8V3qWVhgo3nO2-S4K-3bc*dqI`Kc+AR&;m-_AOxJuCPNl>#~m-|5tjt? zfF$N8gGXO^ZC`Cs>d!mj*`o+53BCpm0O z&{Ks6gJ|KBLx9;uC}WVQHf)l`wIjhOrW;rghcCX|;^6}?m>kyqe^Ff)@?n~{1HLE< z7SzcAhai@|jHM5;Ts4wIv(D{`w5G)%|s?r0Z1%Fh&E0zXv9hr?@(y9Kxt6L(ris@OqiWMKp(>C1M^6v%Nw@ArWs~4sJUhud6??~~opd+HnZ0_yc5u>07(L|;G z$mFv>QK?D$+z=DcK9Q=#e`8t$JoQ3R2Q}xhtb@mKGdT7(i!Twixnog_rT*bK=)^Vf zQUuQTBEBAljIZ3=w8>jGxq9Cw?MGFpN5OXmG-EyKD3_r;?!_iH*}Ok#CJ>K~`JJiN zN2k-VH-Hn7I#z>C(u9tn@sC|URWb#CuFUcS1 LEw~Cr{TliUU~H-r literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@order.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..2395015401100f34736675fe98225d853098d534 GIT binary patch literal 29 Wcmb15HB4nd2bKbJ8axwU)&Kx1)C7$H literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@pair.cache new file mode 100644 index 0000000000000000000000000000000000000000..a4cfdb824fecc15d2d2a334101ddf6014065c30a GIT binary patch literal 1880 zcmb`I&ubGw6vy|?X1jH5h-0AGg7nc+nntZA(M!R$3Q7^dZc`8fV%F}oUEOX%c4I5* zz5jsV!9y<|{5L!)=*63&;91m@ColEQ>?TdxMO3^@=I5JvpZ&gXkS&;eq{b&rKDnNM zVVa!Z%|AD%@}Ep|Z`~Kp=GmsB>0T=y+zulx=lb5A1$OBK<7aC2IneWOVZ8bVsPm1L zt6v#)UhBo`E1f#;Gt1SF8S1nLW~3hP(s9~WO%~%#rOyHGmXS3;xkVf@-UBR_*4krqw(^#IyM|0R=6S#%7pb$*s zLkzHpWqdqM5#+w})S<(cqP0X^7>B7#gN$d3d~O5lSSWG7-0kwF zaWC-hsf1}cVTzFG|+x^pIOqIsqVKK-l z2DGg5E7~MNDTXD=@0zZzN>6VnRSiiAg(%DR%3b(mN! zX$C_$sTk&ChXLsG7wIgq%P3<>Os4XKmGt@85C67ah7`AKr&W5I?X8zDEQy>BE-sh@ zUi^m@6QAnQQkhC7r;HUUr{Fr!A6)FJ*7&-72eq;MRE1#F{31QVrVQkC`B-qNTx_&)UoB%O(LX;D5g+l!;qHLNZe?- zOYJT#tBqlxw*ox`0Rpr+C56!hy)-Ct3Q(Yj9)jjjAjckx7Dy4GK!FxWZvoWzW_HP4 zE-BMcFGUZchO;xXGw*%#z3)AqCn@bKay3KG)ag@?(f7a1{b`y|`bO^W(2&IC-Kz%f(r*1n#C#%Yb@3h?)fF_QZP{{A+7 zDOb;uoIXi%^OHnwPf@Cqs#g6SNmHUL3L%O@v+LEis=4B2ijr|UJ|UIAsFT`JyW=%C>qbK%d*CcQ-~GPxy&gRu9Ij5!FA^0_uMT>*JR>|! zjc_DfBn{i7Yt?Ny6Rp#?NQvG^MRyek#SvSD4Rep3GHk{z-r}~;9NTx8-{cI=vB#Vp z(cVY=UDS1UfnC32wAvQ;;LFz5mT-m6o@X~pMOMDW-h7_zxK3-+0zcuG&?0;J$^w4( z9q~w)Z`#|mKvSR{Z+dTw3O=*B$VDASD$A{5*vWXy8_?i zwAc3X7xI8S0W&a%?dQdUMYgoC0M7xTeK<|LPtNMSuz&TXBAPBg%5ssZ*In0f^Wb!` zi45#Q;+s(NnBesSO_3RNAVB*2(?6fS7u<{h&ObdFoHc}VLBKi5nE+=X3c%jA>WA=e zs!l&7rKvxRhg;}J-wTd?o4fwJ2Pl#V0#*nxh`<28Fu>mc%z!OCqs5~G1V*t_XO6qg z-HQM)~D!E_Au!bFUEN0Yo2k z?3%Z^9T*<2xNn#tg|L_-<&DR?jc#$;ZO1cxXb6uc=p*z+j5Guj3=bj6@DZ3c9yvn$ z_r;$PXP1Ud9~iy{zQ0^#;UXYiNabITJUN>IjtBtogBSors8AGO{m}wZS^+gc>3sDW z>DOn#uWu7veuz)g;KCi3d(FUwg4F{*ddzm%ZNutt@1idD`l7a}9hu%HZ?*lyUi7>Z z+w((5&#@leWM-~8PJgHa8HAyZ-iJt6ACJDj|4`rIK6hItP_D-gnjDbk0>a=J7_LHk zfG{QYKb!$hhPu!`5E9)EkXAB^+$<&0)|>TR!}5kq8;G(2GcjTSwEmnK8$W6^d1G&r z?<<*(VM*OwYm=DA{#bjC2*LA+z}ZGY$P`r0yg+%Ga%}Dw=zf{*WAko--YwI+i$Zq) zWWD+kPEIIkl2OzXb_PNT76Q4H8444;8!}ua@RJ7MRGGvN0~G0Td&B_*l>E}{Z)b&; z!uX;P(B}UQeK?L=e`tLuW<6LRjt|m@Yqf6#0`V#e#2=oD9x8t7BNhn6tNr0pP<;2| z{BJ5mnR`Tao9u~bzOFV*Jn8DX;0Z`Hp*ytq?U9QvXl0K^I)jLQZ$0V@XW7AuB8qfr^fF`m-Y2u2-?Onea1k-_p zu}acVxuEpj+T(bAX6w0^;QGw|cxK?C`|r^UNVOij9EKkMz>)CqSkt%-qIMrBIMl2n zDZFR)bk(G$OZf|9i(49Qpn18LGjPk*}qZ6s8z{sCl$=kXJWg$K)v zi6B>8tG*|(@g88KJRaRi0vj^rpTm?t%JE$;*1;Ilbz8chm3I1S7nR&bcr&xtGSxcMYDuc?%WK(xB`rIkqGQmqr|nNfs_% zhVe640R%_>GW%JUk{hxZ4!ck^J97U1=_{K1$DDqURqKad29c3TV0jzjDoBradPT=b-#f(`TVydu?w{)KaCoq@)}+ IGN;IY0K=$vTL1t6 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@queue.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..6ec02d279a3395e477453db0c144ac488b739524 GIT binary patch literal 47 lcmb15HB4oI0Y)f;3reTwq$cL-=VTU_bR9jJtXtml004Xk377x? literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@regex.cache new file mode 100644 index 0000000000000000000000000000000000000000..343c2a25e00043bb30d972f6b9f5560a0ea10a7e GIT binary patch literal 6607 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 bqwF-rc}MTY8H1Dff8gS^DV`itjEnyQt>}2n literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@result.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..f4e887486561f8be3945fd8b61344d52d6d64401 GIT binary patch literal 47 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@set.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..e4e832bc82346f74985f18beddf6b6e9edaf3e83 GIT binary patch literal 85 zcmX@|G$oY*2AH7?E-0OzlbV>TpOaZ!f+~`dnOwqyqNXUdxHP9^J2!7>&uOdk0COD@ A*Z=?k literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache new file mode 100644 index 0000000000000000000000000000000000000000..56a8556be6c6c82cc50b9ad602ee216107ebe941 GIT binary patch literal 21832 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 literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string.cache_meta new file mode 100644 index 0000000000000000000000000000000000000000..7c72b25579dddf57ca0f1d52e021b5c2d8247d4f GIT binary patch literal 136 zcmdnCHanF823VmCJ}8}@lbV>TpIMSxlvt8q#DyZ7lUZECgCde&P?DLS$Bimhl#*H` bf+AF0Qk0pO9-ma2nFErmv~E_(?PdS~Dm@>h literal 0 HcmV?d00001 diff --git a/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache b/test-community-packages-javascript/build/packages/glx/build/packages/gleeunit/build/lsp/erlang/gleam_stdlib/_gleam_artefacts/gleam@string_builder.cache new file mode 100644 index 0000000000000000000000000000000000000000..75483550b0448e42f84a11e245d390d4d392040f GIT binary patch literal 10562 zcmdT~U1%KF6`nh*)o53eS63_9ifmO^YrB?&f9hQ;#Y+@fik(KnQ17mdTbFb-tG$v& zSpHk`*k2N4{F^+_~r6bH4MP@6Hfu3A`9Qr_dM5bmZ9SFOJF4_%NZpOVJ0zBzkv* zR2B+cT|Q;m#MJbKY_6n53VCiiA7?FFisTDgZn90Loo1?wv`{sj%9EB##>VeYm83xp zzfVZ&kQ|^F6dEkk&als{l1xJ;?JUz?rFjCMJ1)rq_*XfvnS9RH42kHHwACl2-6z%E z{Me^V{!or~l60nvkU;eBB$xRd2fvYXnfo#fw7`0%5P-oiTauYyw7}rwU^??j5Wmy9 zl)2vugOak8SyfGezgkbPRD3|#s4rqHi)6))vf447X9^v3#M?CXh z2Mj*$yq5W-lLTl#p>YyT$|O1iSGa{l`{8=fN}`{^^(TcyAHuaBCehn){imHoyE{nq z+CCCpg6m-f?&%^?lalD$aE(SubPBEy_mk-F;Cj$UqW^&Fc0Y-h;p!fM@4yuwgzv#s z9wO0?;QG~J_&!{BkHYvUspO69oT1OD60uWf!_~Q)MAnA`D{*_D0$F=q4r+GTA$e-Y}+eh zf7VkM(fBf5C8v9D%NuO;!KDhD6wa_h%rcfaoAppvIA)d^x@|Cfkuz`@Gv=A98}OTX zG8|^NDLT6sLFJ{QvF~BB9x1$h1j$KjxDyR zUgs>wxgKVoLwFus3E1`B$WJ1OUE*^o0?2=Yz48@sh)_TB7)s;-aPXs1h$4HlIU-{(uNx?yhPkNfNTf=-78+& z4k!Aw?SE|*ZWgj8FBT+4o%7P~Zw*`i^VA)&KHPXwF(s0B zxBR(gEoKvUHu9>iW>slWkP^qs00mBq2w43C<<|=OAh%}otQ4`dbuUJ$=uoD0 zx3>^f7$6{*YJg+Sz=Y0Pk^-xlfIwFD1z768I`{7zw2B4Ib`k7@hH(Cp$&EiE?x0o+ z`u~zcd%gvK^QQXz0S9g+;l_AP-Eo z$TZkbp%*rELJ~^Pl^)!GlLHHo0(-7fPf=M=u`XTSH*jOX2r`3a zi0}aHzC;3UHb2)vGLt&u)W##A|A;=k-K!eGJx@)_>^{cJ8ltGpyrmw0J)K}MNx$234-dh zNyo}`9LwKWl8(jc7!FS)>52HZG=t{K*Zez7x|8lHfHlr_=3C&*Bsx===j+V0^LKP+ zp#X@1jpiJ;L?>DWk`;8Ohb|5wVpb_qA%g<5u=aUdKt#`JcSKLiCD6QvF^BUA>N2